diff --git a/CHANGELOG.md b/CHANGELOG.md index 03b3a3f145..2989d0396c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,61 @@ ## Changelog +* Version 6.2.0 + + * Features + * xmhf-64: initial commit, copied from xmhf + * xmhf-64: fix compile errors found in high GCC version + * xmhf-64: support running XMHF in 64-bit mode + * xmhf-64: support continuous integration testing + * xmhf-64: support running XMHF in QEMU + * xmhf-64: support running XMHF with modern guest operating systems + * xmhf-64: support running guests that use PAE paging + * xmhf-64: provide ``pal_demo``, which compiles TrustVisor PALs in + Windows and Linux, without using linker scripts + * xmhf-64: decrease compilation artifact size (e.g. object files) + * xmhf-64: support optimized compile (e.g. ``-O3``) + * xmhf-64: support DMAP in Intel + * xmhf-64: allow the guest OS to change MTRR + * xmhf-64: support x2APIC + * xmhf-64: support Intel microcode update + + * Logic Fixes + * xmhf-64: check `grube820list_numentries` in `dealwithE820()` to + prevent possible buffer overflow + * xmhf-64: fix Makefile dependencies problems + * xmhf-64: fix unsigned overflow in `udelay()`. This bug causes sleep + to be shorter than expected + * xmhf-64: fix the CR0 intercept handler + * xmhf-64: fix WRMSR intercept handler when MSR comes from + `vmx_msr_area_msrs`. This bug leads to unexpected values read by the + guest + * xmhf-64: block guests' access to x2APIC. This bug may allow guests to + to send INIT to a CPU + * xmhf-64: fix incorrect assert in hpt.c for long mode paging. This bug + is on a code path that is likely unused by 32-bit guests + * xmhf-64: fix logic in NMI quiesce handling. This bug can cause + deadlock and lose of guest NMIs + * xmhf-64: fix the problem that `HALT()` does not halt forever. This + bug can cause troubles during debugging + * xmhf-64: fix the problem that the last entry of E820 is dropped + * xmhf-64: unset CR4.VMXE, which is incorrectly set + * xmhf-64: fix logic in booting, which causes problems for single CPU + machines + * xmhf-64: fix guest initial state (e.g. DX, CR0, ...) + * xmhf-64: truncate RSP in `_vmx_int15_handleintercept()` + * xmhf-64: fix incorrect assumption about default MTRR type. This bug + causes strange cache errors in Windows 10 + * xmhf-64: block guests' change to MTRRs. This bug allows guests to + change host's memory cache settings + * xmhf-64: block guest microcode update. This bug allows guests to + update microcode arbitrarily + * xmhf-64: fix NULL pointer reference in the VGA driver. This bug is on + a code path that only happens when debugging + * xmhf-64: fix incorrect use of .fill in `xmhf_xcphandler_idt_start()`. + This bug leads to less area allocated for IDT than expected + * xmhf-64: remove two unused nmm functions that may contain bugs + * Version 6.1.0 * Features @@ -153,4 +208,4 @@ * Version 0.1 * Initial Release - \ No newline at end of file + diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000000..a68f222d0c --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,3 @@ +/_build +/_temp +/_themes diff --git a/docs/index.rst b/docs/index.rst index 15f9331423..fed65ba185 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -57,6 +57,19 @@ framework and associated components. rpi3-cortex_a53-armv8_32/debugging +.. toctree:: + :maxdepth: 2 + :caption: PC Intel x86 64-bit: + + pc-intel-x86_64/introduction + pc-intel-x86_64/hw-requirements + pc-intel-x86_64/supported-os + pc-intel-x86_64/build + pc-intel-x86_64/installing + pc-intel-x86_64/debugging + pc-intel-x86_64/uberapp-trustvisor + + .. toctree:: :maxdepth: 2 :caption: Legacy PC AMD/Intel x86 32-bit: diff --git a/docs/pc-intel-x86_64/build.rst b/docs/pc-intel-x86_64/build.rst new file mode 100644 index 0000000000..66bebfde30 --- /dev/null +++ b/docs/pc-intel-x86_64/build.rst @@ -0,0 +1,248 @@ +.. include:: /macros.rst + +.. _pc-intel-x86_64-building: + +Building +======== + +uberXMHF (pc-intel-x86_64) and uberapps (e.g., :doc:`TrustVisor `\ ) get built +in a Linux environment with +a recent version of gcc. uberXMHF (pc-intel-x86_64) has been verified to +build on Debian 11 and Fedora 35, both 32 and 64 bit. + +It is also possible to build uberXMHF in docker. The ``debian:11`` Docker tag is known to work. + +Build tools +----------- + +A (partial) list of packages to install on Ubuntu / Debian: + +.. code-block:: bash + + apt-get install pbuilder texinfo ruby build-essential autoconf libtool + +A (partial) list of packages to install on Fedora: + +.. code-block:: bash + + dnf install autoconf automake make gcc + # The next line installs fallocate, which is recommended + dnf install util-linux + +On 64-bit Debian, you will also need to install 32-bit libraries: + +.. code-block:: bash + + apt-get install build-essential crossbuild-essential-i386 + +On 32-bit Debian, to compile XMHF in 64-bit, install 64-bit cross compiler: + +.. code-block:: bash + + apt-get install build-essential crossbuild-essential-amd64 + +High-level Build Summary +------------------------ + +One "drives" the build from the root directory of uberXMHF (pc-intel-x86_64): + +The interesting high-level build commands include: + +.. code-block:: bash + + ./autogen.sh # creates ./configure + ./configure # creates Makefile from Makefile.in + make # builds the selected hypapp and the XMHF core + make install # installs binaries + make install-dev # (hypapp specific) installs dev headers and libs + make test # (hypapp specific) runs various automated tests + make clean # cleanup + make htmldoc # generates the HTML documentation you are reading in the `./doc` sub-folder + + +The functioning of ``make install-dev`` and ``make test`` are +uberapp-specific. For example, in the TrustVisor uberapp, the primary prerequisite +for tee-sdk and PAL development is having successfully run +``make install-dev``. + +How do I build a uberXMHF (pc-intel-x86_64) uberapp? +----------------------------------------------------- + +The method for building different uberapps (e.g., TrustVisor) is by specifying +which uberapp to build using ``./configure``. +The following describes the sequence of steps for building a +uberXMHF (pc-intel-x86_64) uberapp using the helloworld +uberapp as a running example. + +Change working directory to the uberXMHF (pc-intel-x86_64) root directory. + +.. code-block:: bash + + cd ./xmhf-64 + + +Generate the ``./configure`` script. + +.. code-block:: bash + + ./autogen.sh + + +Configure the uberXMHF (pc-intel-x86_64) uberapp (see below for the +``--with-target-subarch=`` configuration option). + +.. code-block:: bash + + ./configure --with-approot=hypapps/helloworld --with-target-subarch=... + + +Generate and install the binaries: + +.. code-block:: bash + + make + make install + make install-dev # optional (hypapp-specific) + make test # optional (hypapp-specific) + + +To use multiple processors on the compiling machine, try ``make -j $(nproc)``. + +Note that ``make install`` is only useful if the development system and +the target system (on which uberXMHF (pc-intel-x86_64) is installed) are +the same. If not, +you will need to manually copy the files ``./xmhf/init-x86.bin`` +and ``./xmhf/hypervisor-x86.bin.gz`` to the ``/boot`` folder of the +target system (see :doc:`Installing uberXMHF (pc-intel-x86_64) ` ). + +Build configuration options +--------------------------- + +To change configuration options, run ``make distclean`` before executing the +new ``./configure`` command. Otherwise the build may fail. + +Mandatory arguments +^^^^^^^^^^^^^^^^^^^ + +* + --with-approot=[UBERAPP_PATH], specifies the uberapp source root; must be provided + +* + --with-target-subarch=[TARGET_SUBARCH], specify which subarch of uberXMHF to + build (32-bit or 64-bit); must be provided + + * + When building 32-bit uberXMHF on 32-bit Debian or Fedora: + ``--with-target-subarch=i386`` + * + When building 64-bit uberXMHF on 32-bit Debian: + ``--with-target-subarch=amd64 CC=x86_64-linux-gnu-gcc LD=x86_64-linux-gnu-ld`` + * + When building 64-bit uberXMHF on 32-bit Fedora: + ``--with-target-subarch=amd64`` + * + When building 32-bit uberXMHF on 64-bit Debian: + ``--with-target-subarch=i386 CC=i686-linux-gnu-gcc LD=i686-linux-gnu-ld`` + * + When building 32-bit uberXMHF on 64-bit Fedora: + ``--with-target-subarch=i386`` + * + When building 64-bit uberXMHF on 64-bit Debian or Fedora: + ``--with-target-subarch=amd64`` + * + If these argument is not added correctly, an error message like + ``ld: cannot find -lgcc`` may appear when building. + +* + --with-target-platform=[PLATFORM], specifies the target platform for the build; + optional, current options are: x86pc (x86 hardware virtualized platforms, default) + +* + --with-target-arch=[ARCH], specifies the target CPU architecture; + optional, current options are: x86vmx (Intel, default) + +Recommended arguments +^^^^^^^^^^^^^^^^^^^^^ + +* + --enable-debug-symbols, adds debug info to generated ELF files. With this + configuration, GDB can print symbols in ``*.exe`` files. + +* + --enable-debug-qemu, allows XMHF to run in QEMU (disables some unused VMCS + fields) + +* + --disable-drt, disables Dynamic Root-of-Trust (DRT); optional, useful for builds + targeting platforms without support for DRT and/or TPM + +* + --disable-dmap, disables DMA protection; optional, useful for builds targeting + platforms without DMA protection capabilities + +* + --with-amd64-max-phys-addr=[MAX_PHYS_ADDR], configures maximum physical + address (in bytes) supported by 64-bit uberXMHF + + * + For example, ``--with-amd64-max-phys-addr=0x140000000`` sets physical + address to 5 GiB. The default is 16 GiB. When XMHF runs on a machine that + has more physical memory than this value, XMHF will halt. This + configuration is ignored in i386 XMHF + +* + --enable-update-intel-ucode, allows the guest to perform microcode update + +Other arguments +^^^^^^^^^^^^^^^ + +* + --disable-debug-serial --enable-debug-vga, print debug messages on VGA, not + serial port. This is useful for builds targeting platforms without serial + ports + +* + --with-opt=[COMPILER_FLAGS], compiles XMHF with optimization. For example, + ``--with-opt='-O3 -Wno-stringop-overflow'`` adds ``-O3`` and + ``-Wno-stringop-overflow`` to GCC's arguments to compile in optimization + ``-O3``. As of writing of this documentation, ``-Wno-stringop-overflow`` is + needed due to a `bug `_ + in GCC: + +* + --enable-optimize-nested-virt, enables some risky optimizations in intercept + handling + + * + When running XMHF under many levels of nested virtualization, VMREAD and + VMWRITE instructions become expensive. This configuration enables + manually optimized intercept handling for some cases to prevent XMHF from + running too slow to boot the guest OS. However, these optimizations need + to be manually maintained and may be incorrect. + +Configuration examples +^^^^^^^^^^^^^^^^^^^^^^ + +``xmhf-64/.github/build.sh`` can be used to generate configuration options. It +automatically detects the compiling machine's bit size and can be especially +helpful to figure out cross-compile options. See comments at the start of this +file. The following will print sample configuration commands: + +.. code-block:: bash + + ./.github/build.sh i386 release -n + ./.github/build.sh amd64 release -n + +Other examples: + +.. code-block:: bash + + # Build i386 XMHF on i386 Ubuntu, without DRT and DMAP + ./configure --with-approot=hypapps/trustvisor --disable-dmap --disable-drt + + # Build i386 on amd64 Debian + ./configure --with-approot=hypapps/trustvisor --enable-debug-symbols --enable-debug-qemu CC=i686-linux-gnu-gcc LD=i686-linux-gnu-ld + + # Build amd64 on amd64 Debian, with 8 GiB memory, and use VGA instead of serial + ./configure --with-approot=hypapps/trustvisor --with-target-subarch=amd64 --enable-debug-symbols --enable-debug-qemu --with-amd64-max-phys-addr=0x200000000 --disable-debug-serial --enable-debug-vga + diff --git a/docs/pc-intel-x86_64/debugging.rst b/docs/pc-intel-x86_64/debugging.rst new file mode 100644 index 0000000000..07589ec434 --- /dev/null +++ b/docs/pc-intel-x86_64/debugging.rst @@ -0,0 +1,159 @@ +.. include:: /macros.rst + + +Debugging +========= + +Debugging in real hardware +-------------------------- + +Terminology +^^^^^^^^^^^ + + +* ``host system`` -- system where the serial log is collected and examined. +* ``target system`` -- system where uberXMHF (pc-intel-x86_64) runs and + ouputs debug information via the serial port. + +Debugging Setup +^^^^^^^^^^^^^^^ + +uberXMHF (pc-intel-x86_64) debugging is done primarily via the serial port. +See :doc:`Installing uberXMHF (pc-intel-x86_64) ` for how to pass serial +port configuration parameters to uberXMHF (pc-intel-x86_64). +You can use ``dmesg | grep ttyS`` on a Linux guest OS on the target +system to examine the serial ports that the target system recognizes. + +For machines without a physical +serial port (e.g., laptops), you may leverage Intel Active Management +Technology (AMT) Serial-Over-LAN (SOL) capability. AMT SOL exposes +a serial port to the underlying platform once enabled (typically in +the BIOS). + +Serial Debuging without AMT +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +* + Connect the ``host system`` and the ``target system`` via a NULL serial + cable. + +* + On the ``target system`` ensure that you pass the correct serial port + configuration parameters to uberXMHF (pc-intel-x86_64) (see :doc:`Installing uberXMHF (pc-intel-x86_64) `\ ). + A typical non-AMT configuration parameter will be similar to this: ``serial=115200,8n1,0x3f8`` + +* + On the ``host system`` run a terminal emulation program such as ``minicom`` (Ubuntu) + or ``hyperterminal`` (Windows). Ensure that the serial port configuration baud rate, parity, data and stop bits match (e.g., ``115200, 8n1``\ ) + +Serial Debugging with AMT +^^^^^^^^^^^^^^^^^^^^^^^^^ + +You will typically need to enable AMT in the BIOS/firmware of the ``target system`` . +Since various BIOSes expose AMT in different ways, we will use the +HP EliteBook 8540p/2540p laptop as a running example; the AMT specific instructions +probably need a little adaptation on other platforms running AMT. + + +* + Connect the ``host system`` and the ``target system`` via an ethernet + cable. This can be a cross-over cable (for direct connection) or a + straight cable (if going via a switch/router). + +* + It is best not to make AMT accessible from an open network, since by default there is no encryption for password authentication. + It seems possible to enable encryption and stronger authentication, but for our example we will assume a private network setup. + In our example, we statically configure the ``host system`` and + ``target system`` to be on the private ``192.168.0.0`` network. + +* + Enable AMT in the BIOS/firmware on the ``target system``. On the 8540p, you need to turn on + ``system_config -> amt_options -> firmware_verbosity -> setup_prompt``. + +* + Once AMT is enabled, you should see an AMT prompt during boot of the ``target system``. + Enter the AMT configuration; on the 8540p, hit + ``Ctrl-p`` to enter AMT configuration. The default password is + 'admin'. Once you've logged in: + + + * **You'll be forced to change the admin password**. Take care not + lose or compromise this password! The system will enforce some + password rules. See this `AMT Howto `_ for more information. + * **Setup the AMT IP**. In our example, we statically configure the + ``target system`` to have the IP ``192.168.0.2`` + * **Activate the network** + * **Ensure serial-over-lan (SOL) is enabled** + * **Enable ``legacy redirection mode`` (or ``SMB (Small Business) + management mode``\ )** This enables a simpler network + protocol. You'll need it to use ``amtterm``. + +* + On the ``target system`` ensure that you pass the correct serial port + configuration parameters to XMHF (see :doc:`Installing uberXMHF (pc-intel-x86_64) `\ ). + A typical AMT serial configuration parameter will be similar to this: ``serial=115200,8n1,0x6080`` + +* + On the ``host system``\ , install ``amtterm`` to obtain the serial debugging + messages + + + * + Use amtterm 1.3 or higher. Older versions have bugs that effect + the ability to log output, and have more frequent disconnections. + It is available from the `amtterm git repository `_ + or `amtterm releases directory `_. + + * + Connect to the ``target system`` by using the following command: ``./amtterm 192.168.0.2 -p 'YourAMTpassword' | tee output-log.txt``. + Note: you may have to bring up the ethernet interface on the ``host system`` prior to issuing the above command. This can be done + via ``sudo ifconfig eth0 192.168.0.1`` (assuming the ``host system`` IP is ``192.168.0.1``\ ). + +Debugging in QEMU +----------------- + +Print debugging +^^^^^^^^^^^^^^^ + +Print debugging in QEMU is similar to real hardware. QEMU supports serial port +using the ``-serial`` argument. For example, ``-serial stdio`` prints the +serial output to the terminal. ``-serial file:FILENAME`` redirects the serial +output to ``FILENAME``. + +GDB debugging +^^^^^^^^^^^^^ + +QEMU can act as a debug server, which accepts GDB as a client. Use +``-gdb tcp::1234`` to let QEMU listen to port 1234, then use the GDB command +``target remote :::1234`` to connect to QEMU. + +When building XMHF, ``--enable-debug-symbols`` should be used during configure +to add symbol tables to the built ELF files. + +XMHF has a number of memory spaces, but GDB does not recognize memory spaces. +So when a memory space changes, the symbol file need to be changed. Use the GDB +command ``symbol-file`` to change symbol files. + +* + XMHF bootloader: + ``symbol-file xmhf/src/xmhf-core/xmhf-bootloader/init_syms.exe`` + (paging not enabled, so physical address = virtual address) +* + XMHF secureloader 1: + ``symbol-file -o 0x10000000 xmhf/src/xmhf-core/xmhf-secureloader/sl_syms.exe`` + (physical address = virtual address, this only happens when entering / + leaving secureloader) +* + XMHF secureloader 2: + ``symbol-file -o 0 xmhf/src/xmhf-core/xmhf-secureloader/sl_syms.exe`` + (physical address = virtual address + ``__TARGET_BASE_SL``, this happens + during the C part of secureloader) +* + XMHF runtime: + ``symbol-file xmhf/src/xmhf-core/xmhf-runtime/runtime.exe`` + (physical address = virtual address) +* + Guest OS: e.g. Linux may use + ``symbol-file usr/lib/debug/boot/vmlinux-5.10.0-10-amd64`` + diff --git a/docs/pc-intel-x86_64/hw-requirements.rst b/docs/pc-intel-x86_64/hw-requirements.rst new file mode 100644 index 0000000000..97b04909f4 --- /dev/null +++ b/docs/pc-intel-x86_64/hw-requirements.rst @@ -0,0 +1,51 @@ +.. include:: /macros.rst + + +Hardware Requirements +===================== + +Real hardware +------------- + +* An **Intel** CPU (AMD is not supported) + + * Note: CPUs newer than Haswell have not been tested yet + +* **A TPM (v1.2)** The BIOS feature is often called something like "embedded security device" + +* **Hardware Virtualization extensions** + + * **Intel**\ : Virtualization Technology (VT-x) + +* **Hardware Support for DMA Isolation** + + * **Intel**\ : Virtualization Technology for Directed I/O (VT-d) + +* **2nd-level page tables** Typically turned on implicitly along with Virtualization extensions, if the processor supports it. + + * **Intel**\ : Extended Page Tables (EPT) + +* **Dynamic root of trust** + + * **Intel**\ : Trusted Execution Technology (TXT). This feature is implemented partially by a signed software + module, called an SINIT module. Some processors exist that have the TXT hardware support but do not (yet) have + an SINIT module. Look for the SINIT module here: http://software.intel.com/en-us/articles/intel-trusted-execution-technology/ + +.. note:: + When purchasing a new machine, do *not* take it for granted that any + newer Intel processor will have the necessary capabilities. + + * Check Intel processor capabilities: http://ark.intel.com/ + +Hypervisor +---------- + +Running uberXMHF in a hypervisor helps debugging. However, some features are +not available. + +* + QEMU / KVM: supported for Intel CPU, require ``--enable-kvm`` and ``vmx`` + flag in the CPU. Does not support DRT and DMAP. +* + VMWare: probably supported. + diff --git a/docs/pc-intel-x86_64/installing.rst b/docs/pc-intel-x86_64/installing.rst new file mode 100644 index 0000000000..2a1e98130d --- /dev/null +++ b/docs/pc-intel-x86_64/installing.rst @@ -0,0 +1,260 @@ +.. include:: /macros.rst + + +Installing +========== + +This section covers installing XMHF. The instructions for real hardware and +QEMU are the same. + +Prerequisites +------------- + +As a first step, check the :doc:`uberXMHF (pc-intel-x86_64) Hardware Requirements `\ , and +be sure to enable the corresponding BIOS options. Also make sure your +BIOS is up to date; you could ruin your motherboard if your BIOS is +buggy. Secondly, ensure that you are running one of the supported +guest operating systems (see :doc:`uberXMHF (pc-intel-x86_64) Supported Guest +Operating Systems `\ ). +Lastly, configure your system to boot uberXMHF (pc-intel-x86_64) as +described below. + +Installing OS +------------- + +You need to install the guest operating system on hardware. The guest operating +system need to be able to be booted by GRUB. + +Installing OS on real hardware +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Many laptops are shipped with pre-installed OS. You can also install your own +OS. Usually you can write an ISO image to a USB stick, then boot the laptop +using the USB. + +Installing OS on QEMU +^^^^^^^^^^^^^^^^^^^^^ + +For this section, there are many alternative tutorials online. For example, +search for "qemu install iso" in a search engine. + +First create a virtual disk called ``a.qcow2`` + +.. code-block:: bash + + qemu-img create -f qcow2 a.qcow2 32G + +Then run QEMU with the installation ISO file (Debian 11 in this example) and +the disk just created. + +.. code-block:: bash + + qemu-system-x86_64 -m 512M \ + --drive media=cdrom,file=debian-11.1.0-i386-netinst.iso,index=1 \ + --drive media=disk,file=a.qcow2,index=2 \ + --enable-kvm -smp 4 -serial stdio -cpu Haswell,vmx=yes + +After installing, the cdrom argument is no longer needed. + +.. code-block:: bash + + qemu-system-x86_64 -m 512M \ + --drive media=disk,file=a.qcow2,index=2 \ + --enable-kvm -smp 4 -serial stdio -cpu Haswell,vmx=yes + +Configure target system to boot uberXMHF +---------------------------------------- + +You will need to install Grub 2, if you haven't already. On most +modern Linux distributions, you already have Grub 2. On +Windows machines without a Linux installation, you will need to +install Grub. This can be done by installing a minimal Linux +installation, which will typically take care of non-destructively +repartitioning for you. + +Get the correct SINIT module (Intel only) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +uberXMHF (pc-intel-x86_64) launches itself with a *dynamic root of trust*. +On Intel +platforms, this requires a signed SINIT module provided by Intel, that +matches your platform CPU and chipset. + +SINIT modules can be found here: +http://software.intel.com/en-us/articles/intel-trusted-execution-technology/ + +Building and Installing uberXMHF (pc-intel-x86_64) binaries +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you haven't already built and installed uberXMHF (pc-intel-x86_64), +see :doc:`Building uberXMHF (pc-intel-x86_64) ` + +Booting sequence +^^^^^^^^^^^^^^^^ + +GRUB 2 will be used to launch XMHF-64 and to launch the guest operating system. +This usually requires the user to select different menu entries in GRUB. + +GRUB 2 needs to be launched by BIOS. EFI / UEFI is not supported. This means +that XMHF likely does not work on disks formatted as GPT (XMHF works on MBR). + +The boot sequence is: + +1. The machine starts, BIOS starts running +2. BIOS launches GRUB +3. GRUB launches XMHF-64 (selected by the user) +4. XMHF-64 launches GRUB in virtual machine mode (e.g. Intel VMX) +5. GRUB launches guest OS (selected by the user) + +Install files +^^^^^^^^^^^^^ + +The build process will generate the following files, where ``$(SUBARCH)`` is +``i386`` (for 32-bit uberXMHF) or ``amd64`` (for 64-bit uberXMHF). Copy these +files to ``/boot/`` of the operating system. These files will be accessed by +GRUB. + +.. code-block:: text + + init-x86-$(SUBARCH).bin + hypervisor-x86-$(SUBARCH).bin.gz + +Adding a Grub entry +^^^^^^^^^^^^^^^^^^^ + +A menuentry needs to be added to GRUB. For Debian it is done by adding a file +with execute permission in ``/etc/grub.d/``. For example, create a file at +``/etc/grub.d/42_xmhf_i386``: + +.. code-block:: bash + + #!/bin/sh + exec tail -n +3 $0 + # This file provides an easy way to add custom menu entries. Simply type the + # menu entries you want to add after this comment. Be careful not to change + # the 'exec tail' line above. + + menuentry "XMHF-i386" { + set root='(hd0,msdos1)' # point to file system for / + set kernel='/boot/init-x86-i386.bin' + set boot_drive='0x80' # should point to where grub is installed + echo "Loading ${kernel}..." + multiboot ${kernel} serial=115200,8n1,0x5080 boot_drive=${boot_drive} + module /boot/hypervisor-x86-i386.bin.gz + module --nounzip (hd0)+1 # should point to where grub is installed + module /boot/i5_i7_DUAL_SINIT_51.BIN + } + +Please following the line by line explanation of the file above to edit it + +* + ``#!/bin/sh`` and ``exec tail -n +3 $0``: this executable file will print the + content starting at line 3. Don't touch them. + +* + ``menuentry "XMHF-i386" {``: "XMHF-i386" will be the entry name in GRUB. This + name can be changed freely. + +* + ``set root='(hd0,msdos1)'``: set partition of the operating system. This + partition is used to access XMHF files. ``(hd0,msdos1)`` is first disk's + first MBR partition. See GRUB's documentation. + +* ``set kernel='/boot/init-x86-i386.bin'``: set XMHF bootloader file. Change + ``init-x86-i386.bin`` to ``init-x86-amd64.bin`` for amd64 XMHF. + + * + In the example configuration, GRUB should find a MBR partition on the + first hard drive (hd0). The partition should contain a file system with + a directory called ``boot`` at the root, and this directory should + contain the file ``init-x86-i386.bin``. + +* + ``set boot_drive='0x80'``: specify the disk where XMHF can find GRUB. + ``0x80`` is the first hard disk (corresponding to ``hd0``), ``0x81`` is the + second hard disk (``hd1``), etc. Usually this does not need to change if you + are only working with only one hard disk. + +* + ``echo "Loading ${kernel}..."``: just printing a message, no need to change. + +* + ``multiboot ${kernel} serial=115200,8n1,0x5080 boot_drive=${boot_drive}``: + specify multiboot kernel to be the XMHF bootloader + + * + ``serial=115200,8n1,0x5080``: specify serial parameters. The parameters + can usually be found by running ``dmesg | grep ttyS`` in Linux. For + example you may see + ``... ttyS0 at I/O 0x5080 (irq = 17, base_baud = 115200) is a 16550A``. + +* + ``module /boot/hypervisor-x86-i386.bin.gz``: load the first multiboot module, + which must be XMHF secureloader and runtime. Again change it to + ``hypervisor-x86-amd64.bin.gz`` if running amd64 XMHF. + +* + ``module --nounzip (hd0)+1``: specify the disk where XMHF can find GRUB. + ``(hd0)`` is the first hard disk, and ``+1`` means 1 block since offset 0 + (this is GRUB's block list syntax). Usually this does not need to change if + you are only working with only one hard disk. + +* + ``module /boot/i5_i7_DUAL_SINIT_51.BIN``: For a Intel machine with DRT + enabled, this is the SINIT AC Module downloaded from Intel's website. Make + sure to select the file that matches your machine's CPU. When DRT is + disabled, this line can be removed. + +After the modification is done, make sure it is executable and update GRUB. + +.. code-block:: bash + + sudo chmod +x /etc/grub.d/42_xmhf_i386 + sudo update-grub + +Multiple disks +^^^^^^^^^^^^^^ + +It may be convenient to install GRUB on one disk and the guest operating system +on another. Consider this scenario: we have installed XMHF on a USB, and we +want to test it on an OS installed on a HDD. + +The partition table of USB looks like: + ++------------+---------------------------------------------+ +| MBR header | Partition 1: ext4 | ++------------+---------------------------------------------+ +| GRUB | XMHF installed in /boot/ | ++------------+---------------------------------------------+ + +The partition table of HDD looks like: + ++------------+-----------------------+---------------------+ +| MBR header | Partition 1: ??? | Partition 2: ??? | ++------------+-----------------------+---------------------+ +| Bootloader | Guest OS | ... | ++------------+-----------------------+---------------------+ + +The target computer by default only has the HDD connected. When a BIOS boots +the HDD, it will set DL=0x80, and ``(hd0)`` is HDD. When a USB is inserted, the +USB is ``(hd1)``. + +However, if the BIOS boots the USB, then the USB becomes ``(hd0)`` and the HDD +becomes ``(hd1)``. The BIOS will still set DL=0x80. + +Suppose we want to make the boot sequence "BIOS -> USB GRUB -> XMHF -> HDD +Bootloader". Then USB GRUB should find the HDD Bootloader at ``(hd1)``, and HDD +bootloader should be passed DL=0x81. So the configuration file should be + +.. code-block:: bash + + #!/bin/sh + ... + menuentry "XMHF-i386" { + ... + set boot_drive='0x81' + ... + module --nounzip (hd1)+1 + ... + } + diff --git a/docs/pc-intel-x86_64/introduction.rst b/docs/pc-intel-x86_64/introduction.rst new file mode 100644 index 0000000000..73b268a160 --- /dev/null +++ b/docs/pc-intel-x86_64/introduction.rst @@ -0,0 +1,31 @@ +.. include:: /macros.rst + + +Introduction +============ + +XMHF-64 is branch of XMHF that supports running XMHF in both 32-bit and 64-bit. +32-bit is called "i386" and 64-bit is called "amd64". This bit width difference +is called "subarch". + +XMHF-64 has 3 phases: bootloader, secureloader, and runtime. Bootloader will +always run in i386. Secureloader and runtime will run in the subarch as +configured by the user (i386 or amd64). Only amd64 XMHF-64 can run amd64 guest +operating systems. A comparision is below. + +=============== =============== ======================= +Name XMHF-64 in i386 XMHF-64 in amd64 +=============== =============== ======================= +bootloader i386 i386 +secureloader i386 amd64 +runtime i386 amd64 +guest OS i386 (no PAE) i386 or amd64 +physical memory 4 GiB >= 4 GiB (configurable) +=============== =============== ======================= + +Compared to XMHF, XMHF-64 supports more guest operating system features, such +as PAE paging, 64-bit mode, x2APIC, MTRR change. It also supports later +compiler versions and can be compiled with optimization (e.g. GCC's ``-O3``). +XMHF-64 also adds various other logic refinements and fixes to XMHF. However, +XMHF-64 is not formally verified yet. + diff --git a/docs/pc-intel-x86_64/supported-os.rst b/docs/pc-intel-x86_64/supported-os.rst new file mode 100644 index 0000000000..8e7522557c --- /dev/null +++ b/docs/pc-intel-x86_64/supported-os.rst @@ -0,0 +1,83 @@ +.. include:: /macros.rst + + +Supported OS +============ + +In principle, any guest operating system should work, as long as it: + +* + Uses 32-bit paging / PAE paging / 4-level paging (5-level paging is not + supported). +* + Does not require hardware virtualization features, does not require TPM. +* + Is stored in a MBR disk and booted by BIOS (GPT partition and EFI are not + supported). + +The following OS are known to work: + +* Ubuntu 12.04 LTS +* Debian 11 with kernel 5.10.0-9 +* Fedora 35 +* Windows XP +* Windows 7 +* Windows 8.1 +* Windows 10 + +Test matrix +----------- + +We have tested XMHF + TrustVisor + pal_demo on the following configurations. + ++-------+-----+-------------------+---------------+---------------------------+ +| | | | | Status | +| | | | +-------+-------------------+ +| XMHF | DRT | Operating System | Application | HP | QEMU | ++=======+=====+===================+===============+=======+===================+ +| \* | \# | Ubuntu 12.04 i386 | pal_demo i386 | good | good (no DRT) | ++-------+ +-------------------+---------------+ | | +| \* | | Debian 11 i386 | pal_demo i386 | | | ++-------+ +-------------------+---------------+ | | +| amd64 | | Debian 11 amd64 | pal_demo \* | | | ++-------+ +-------------------+---------------+ | | +| amd64 | | Fedora 35 amd64 | pal_demo \* | | | ++-------+ +-------------------+---------------+ +-------------------+ +| \* | | WinXP i386 SP3 | pal_demo i386 | | VMCALL workaround | ++-------+ +-------------------+---------------+ +-------------------+ +| amd64 | | WinXP amd64 | pal_demo \* | | good (no DRT) | ++-------+ +-------------------+---------------+ | | +| \* | | Win7 i386 | pal_demo i386 | | | ++-------+ +-------------------+---------------+ | | +| amd64 | | Win7 amd64 | pal_demo \* | | | ++-------+ +-------------------+---------------+ | | +| amd64 | | Win8.1 amd64 | pal_demo \* | | | ++-------+ +-------------------+---------------+ | | +| \* | | Win10 i386 | pal_demo i386 | | | ++-------+ +-------------------+---------------+ +-------------------+ +| amd64 | | Win10 amd64 | pal_demo \* | | PAL not tested | ++-------+-----+-------------------+---------------+-------+-------------------+ + +Column explanations + +* + XMHF: subarch of XMHF secureloader and runtime. amd64 for 64-bit, \* for + 32-bit and 64-bit. +* + DRT: \# for both DRT enabled and DRT disabled. For QEMU only DRT disabled. +* + Operating System: operating system and subarch. +* + Application: the application run in XMHF (e.g. pal_demo for TrustVisor). + +Test result explanations + +* + VMCALL workaround: Windows XP makes strange VMCALLs, which prevents + TrustVisor from working correctly. To workaround the problem, the VMCALLs + from Windows XP need to be ignored, and TrustVisor's VMCALL numbers need to + be changed. After that, TrustVisor can run correctly. +* + PAL not tested: Windows 10 amd64 is very slow when running in QEMU (due to + slowness from nested virtualization). So this configuration is not tested. + diff --git a/docs/pc-intel-x86_64/uberapp-trustvisor.rst b/docs/pc-intel-x86_64/uberapp-trustvisor.rst new file mode 100644 index 0000000000..f0b518ab84 --- /dev/null +++ b/docs/pc-intel-x86_64/uberapp-trustvisor.rst @@ -0,0 +1,570 @@ +.. include:: /macros.rst + + +|uberapp| - TrustVisor +====================== + +Introduction +------------ + +TrustVisor is a special-purpose hypervisor that provides measured, +isolated execution environments for security-sensitive +code modules (Pieces of Application Logic - PALs) +without trusting the OS or the application that invokes the code modules. + +The isolated execution environment protects the code +integrity, execution integrity, as well as data integrity and secrecy +for PALs. TrustVisor produces evidence of +its initialization in the TPM's Platform Configuration Registers. +This evidence (in the form of a hash chain) can be used to generate a +TPM-based attestation that TrustVisor has loaded on a platform. +Further, TrustVisor implements a software-based, micro-TPM (uTPM) +that can execute at higher speed on the platform's primary CPU than +hardware TPM. It also generates and manages its own identity keypair +that can be used to generate subsequent attestations to the isolation +and execution of individual PALs, leveraging the uTPM. + +The implementation of TrustVisor contained herein leverages +uberXMHF (pc-intel-x86_64).\ +The original design and implementation of TrustVisor is described in: + +*TrustVisor: Efficient TCB Reduction and Attestation*. Jonathan +M. McCune, Yanlin Li, Ning Qu, Zongwei Zhou, Anupam Datta, Virgil +Gligor, and Adrian Perrig. IEEE Symposium on Security and Privacy, May +2010.\ `(pdf) `_ + +.. _building: + +Building +-------- + +The TrustVisor build is primarily driven from the uberXMHF (pc-intel-x86_64) build process; +see :doc:`Building uberXMHF (pc-intel-x86_64) `. When +running ``configure`` , you will need to set ``--with-approot=hypapps/trustvisor`` +to point to the TrustVisor source code. To install trustvisor +development headers (for :ref:`teesdk` ), please +use ``./configure --prefix=...`` to specify +the install path, and run ``make install-dev``. + + +Installing +---------- + +To *run* TrustVisor on a given machine, installation is similar to that +of any other hypapp. See :doc:`Installing uberXMHF (pc-intel-x86_64) `. + +Note that for certain platforms (e.g., HP EliteBook 2540p), if the TPM locality +are not properly configured, trustvisor crashes at startup when attempting to +clear all TPM localities. An intrusive work-around is to restore +the TPM to factory state via BIOS. + +TrustVisor uses TPM NVRAM to securely store a master secret that is +used to derive its long-term encryption and MAC keys. During startup, if no NVRAM +Index is found, Trustvisor will downgrade to a 'ephemeral'mode, generating a +new MasterSecret. Please following the below guideline to define NVRAM spaces +for TrustVisor using TPM tools. + +Disable the infineon driver +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Modern Ubuntu has a tendency to load the Infineon-specific v1.1b TPM +driver, when it should be using ``tpm_tis``. Thus, we blacklist +``tpm_infineon``. Don't forget to reboot after making this change. It +is possible to manually remove this driver (\ ``modprobe -r +tpm_infineon``\ ) and ``modprobe tpm_tis``\ , if you know what you're +doing. In ``/etc/modprobe.d/blacklist.conf`` add + +.. code-block:: c + + blacklist tpm_infineon + + +Shut down trousers, if it is running +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +See if trousers is running first, shut down if necessary. It will +probably start up again after the next reboot. You may wish to +uninstall it or disable it more permanently if you're not otherwise +using it. + +.. code-block:: c + + /etc/init.d/trousers status + /etc/init.d/trousers stop + + +Install jTpmTools +^^^^^^^^^^^^^^^^^ + +Our current testing has been with v0.6 but we will soon move to +v0.7. https://sourceforge.net/projects/trustedjava/files/jTPM%20Tools/ + +.. code-block:: c + + sudo dpkg -i jtpmtools_0.6.deb + + +Set the tpm device to be accessible by jtss +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: bash + + chown jtss:tss /dev/tpm0 + /etc/init.d/jtss start + /etc/init.d/jtss status + + cat /var/log/jtss/tcs_daemon.log + + +Take ownership of the TPM +^^^^^^^^^^^^^^^^^^^^^^^^^ + +You will need to take ownership of the TPM, and set an owner +password. It is important not to lose the owner password that you +set. In TrustVisor's security model it is *not* security critical that +the owner password is not compromised, so feel free to use a well +known password or empty string if you are not using the TPM for other +purposes that might require a strong TPM owner password. + +.. code-block:: bash + + jtt take_owner -e ASCII -o 'owner_password' + + +Define the NV spaces +^^^^^^^^^^^^^^^^^^^^ + +We actually define two nv spaces. One stores TrustVisor's master +secret. The other stores the root of a hash chain used for replay +protection (see [Memoir]) + +.. code-block:: bash + + jtt nv_definespace \ + --index 0x00015213 \ + --size 20 \ + -o 'owner_password' \ + -e ASCII \ + -p 11,12 \ + -w \ + --permission 0x00000000 \ + --writelocality 2 \ + --readlocality 2 + jtt nv_definespace \ + --index 0x00014e56 \ + --size 32 \ + -o 'owner_password' \ + -e ASCII \ + -p 11,12 \ + -w \ + --permission 0x00000000 \ + --writelocality 2 \ + --readlocality 2 + + +Unload Linux TPM driver +^^^^^^^^^^^^^^^^^^^^^^^ + +Before running Trustvisor or PAL code that requires access to the NV +RAM, we need to ensure the Linux TPM device driver is indeed +removed. Hence, we want to stop all the drivers that rely on the Linux +TPM device driver. This requirement will go away once issue 15 is +closed. https://sourceforge.net/p/xmhf/tickets/15/ + +.. code-block:: bash + + /etc/init.d/jtss stop + modprobe -r tpm_tis + +.. _teesdk: + +Trusted Execution Environment (TEE) SDK +--------------------------------------- + +Overview +^^^^^^^^ + +The Trusted-Execution-Environment Software-Development-Kit +(tee-sdk) comprises tools and documentation for developing +*services* that run in a trusted environments, and *clients* that +communicate with those services, in Linux system. +Initially, this means writing PALs that run under TrustVisor, +and applications that use PALs. However, +the APIs provided here are intended to provide sufficient abstraction +such that additional back-ends can be implemented, allowing services +and applications to be ported to use alternative trusted environments +with little or no modification. + +Terminology +^^^^^^^^^^^ + +Service + ~ A piece of code running in a trusted execution environment + provided by a *device*. (e.g., a PAL) +Client + ~ An application that communicates with one or more *services*. +Device + ~ A module providing a trusted execution environment (e.g., TrustVisor) + +Files (relative to ``xmhf/hypapps/trustvisor/tee-sdk/``\ ) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +* tz/: TrustZone API. This library is to be used by *clients* + to communicate with *services*. This library supports multiple + *device* back-ends, abstracting them in such a way that most *client* + code can be oblivious to which back-end is in use. +* toolchain/: A cross-compiling toolchain for compiling + and linking PALs. Implemented as wrappers around gcc. +* ports/: Support libraries for *services*. These have been + ported to run in a trusted environment provided by some *device*. + i.e., they do not make system calls, and all dependencies should + be satisfied by other ports, svcapi, or other libraries provided + as part of this package. +* examples/: Examples and tests. + + +Installing TEE-SDK +------------------ + +Installing TrustVisor Headers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +On a machine where you are planning to develop PALs, you will also +need to install the TrustVisor development headers. The +tee-sdk currently expects those headers to be +installed in two places. + +*First*\ , install the headers in a 'normal' system location. This can be +installed by ``make install-dev``\ , when you build +:ref:`building`. +If you directly install TrustVisor binary on your platform without building +it, please download and uncompress the uberXMHF package, go to the ``xmhf`` +directory +and run the following commands: + +.. code-block:: bash + + ./autogen.sh + ./configure --with-approot=hypapps/trustvisor + make install-dev + + +*Second*\ , you will then need to reconfigure to point to the Trustvisor PAL +cross-compilation environment and install the headers again: + +.. code-block:: bash + + ./configure --with-approot=hypapps/trustvisor --prefix=$(SYSROOT)/usr + make install-dev + + +Note: $(SYSROOT) depends on your configuration of building TEE-SDK, +see below for more details. The default $(SYSROOT) is ``/usr/local/i586-tsvc`` + +Downloading and Patching Third Party Libraries +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Before installing TEE-SDK, you need to download a few third party +libraries (e.g., newlib, openssl), and apply patches to them so +that they could be used for PAL development. + +For newlib library, we use newlib-1.19.0 version. +Download the ``newlib-1.19.0.tar.gz`` from ftp://sourceware.org/pub/newlib/index.html, +untar it to ../ports/newlib/ directory, then execute the following commands: + +.. code-block:: bash + + cd ../ports/newlib/newlib-1.19.0 + patch -p1 < ../newlib-tee-sdk-131021.patch + + +For openssl library, we use openssl-1.0.0d version. +Download the ``openssl-1.0.0d.tar.gz`` from http://www.openssl.org/source/, +untar it to ../ports/openssl/ directory, then execute the following commands: + +.. code-block:: bash + + cd ../ports/openssl/openssl-1.0.0d + patch -p1 < ../openssl-tee-sdk-131021.patch + + +Note that you would have prompts as follows: + +.. code-block:: bash + + Reversed (or previously applied) patch detected! Assume -R? [n] + Apply anyway? [n] + + +This is caused by trying to patch the symbolic link file in +include/openssl/opensslconf.h, which is unnecessary. +Just press Enter twice to skip them, and ignore the .rej file created. + +Building and Installing TEE-SDK +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +After installing TrustVisor headers, downloading and patching third party +libraries, go to TEE-SDK directory and run +``make`` to build and install TEE-SDK. + +If you would like to override the default paths, specify your overrides +as parameters to ``make``\ : + +.. code-block:: bash + + make PREFIX=$(PREFIX) HOST=$(HOST) SYSROOT=$(SYSROOT) + + +$(PREFIX) specifies where you will install various utilities, +libraries, and headers. The default $(PREFIX) is ``/usr/local``. + +$(HOST) is the host-name to use for PAL code. The default $(HOST) +is ``i586-tsvc``. + +$(SYSROOT) points to the path where libraries to be linked against PAL +code will be installed. The default $(SYSROOT) is ``$(PREFIX)/$(HOST)`` + +Of course, you may install each tee-sdk component individually, +either by specifying a target to ``make``\ , or by manually performing the +steps in the corresponding make recipe. At the time of this writing, +the components installed by ``make`` are: + + +* + toolchain : these are wrappers to utilities such as gcc, with names + like ``i586-tsvc-gcc``. They mostly serve to override the system paths + with paths in $(SYSROOT). + +* + tz : This implements the TrustZone API for managing and + communicating with services (pals) running the trusted execution + environment (trustvisor). + +* + newlib : this is an implementation of libc targeted for + PALs. Functions that do not involve IO should work as expected. IO + functions currently fail gracefully. The toolchain ``i586-tsvc-gcc`` + will link against this library by default, unless ``-nostdlib`` is used. + +* + openssl : This is the well-known openssl library, ported for use + with pals. It is not installed by default, but can be installed with + ``make openssl`` + + +Using TEE-SDK +------------- + +Compiling applications +^^^^^^^^^^^^^^^^^^^^^^ + +The TEE-SDK installs several libraries to the development machine. +There is a front-end library for applications (tee-sdk-app), a +front-end library for services (tee-sdk-svc), and for each device +there are application and service back-end libraries +(tee-sdk-app-devname and tee-sdk-svc-devname). + +We use `pkgconfig `_ to simplify management of these libraries. The +compile time flags needed to link against a package can be obtained +using ``pkg-config --cflags packagename``. The linking flags can be +obtained using ``pkg-config --libs --static packagename``. Note that we +only support static linking for now. If you installed ``tz`` to a +non-standard location ``$tzinstallprefix``\ , you may need to set +``PKG_CONFIG_LIBDIR`` to include ``$tzinstallprefix/lib/pkgconfig``. + +An application using the tee-sdk to communicate with a service running +in a trusted environment must link against at least one application +back-end. It is also permissable to link against multiple back-ends; a +single application can communicate with services running on multiple +devices. + +Compiling services (PALs) +^^^^^^^^^^^^^^^^^^^^^^^^^ + +You must compile and link using exactly one service back-end +package. At the time of this writing, there is only one anyways: +``tee-sdk-svc-tv``. pkgconfig will automatically pull in the service +front-end ``tee-sdk-svc`` as a dependency. Using the compile and link +flags from those packages is important not only to link against the +corresponding libraries; they also reference compiler options to +eliminate code-constructs that are unsupported inside services, and +linker options to ensure the necessary layout in the final binary. + +Services to be run under TrustVisor need to be compiled somewhat +specially. A PAL is linked together into the same binary with the +application that runs it. At run-time, the application registers the +PAL with TrustVisor. Using the raw TrustVisor interfaces for PAL +management, you would need to keep track of which address ranges belong to +PAL code, data, etc., and make sure those sections are page-aligned. +Things can get tricky if you want some code to be accessible to both +the PAL code and the application code, and trickier still if you want +to use different implementations for the same function in PAL and +application code (such as linking the PAL against a version of libc +that does not make system calls while linking the regular code with the +standard version of libc). + +The TEE-SDK has some tools to take care of these details for you. The +basic approach is use *partial linking* to link all PAL code into a +single object file (.o), rewrite all symbols except for the PAL +entry-point in that object file to be private, and then use a linker +script to link this object file with the regular application while +mapping the code and data of the PAL to special page-aligned sections. The +TrustVisor back-end provides simplified functions for registering a +PAL that has been built and linked this way. + +The TEE-SDK includes ``pkg-config`` files that specify the necessary +compilation and link flags, and Makefile snippets that can be included +in your own Makefiles to automate most of the process. Pointing your +makefile at those makefile snippets and\or ``pkg-config`` files (rather +than copying and modifying a monolithic Makefile with these things +hard-coded) will help keep your pal up to date as the build process +evolves. See ``examples/newlib/Makefile`` for +a good starting point of a Makefile that dynamically incorporates the +TEE-SDK-provided Makefile snippets and pkg-config files. + +Compiling and running the test example +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +After installation in ``tz``\ , you should be able to compile and run +the test example in ``../examples/test``. Remember to set +the ``PKG_CONFIG_LIBDIR`` environment variable if you installed to a +non-system directory. + +Loading and unloading services +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Services are loaded and unloaded through the TrustZone service manager: + +.. code-block:: c + + tz_return_t tzRet; + tz_device_t tzDevice; + tz_session_t tzManagerSession; + tz_uuid_t tzSvcId; + + /* open isolated execution environment device */ + /* Use NULL for default device, or 'tv' to specify trustvisor */ + tzRet = TZDeviceOpen(NULL, NULL, &tzDevice); + assert(tzRet == TZ_SUCCESS); + + /* prepare service descriptor */ + /* this is currently device-specific (i.e., trustvisor-specific). + eventually it would be good to provide a common abstraction here. */ + scode_sections_info_init(&scode_info, + &__scode_start, scode_ptr_diff(&__scode_end, &__scode_start), + NULL, 0, + PAGE_SIZE, PAGE_SIZE); + + /* open session with device manager */ + tzRet = TZManagerOpen(&tzDevice, NULL, &tzManagerSession); + assert(tzRet == TZ_SUCCESS); + + /* download */ + tzRet = TZManagerDownloadService(&tzManagerSession, + &pal, + sizeof(pal), + &tzSvcId); + assert(tzRet == TZ_SUCCESS); + + /* do useful work with the service */ + + /* unload the service. */ + /* This is currently CRITICAL when using TrustVisor. Exiting the + application without unloading the service will lead to system + instability. */ + tzRet = TZManagerRemoveService(&tzManagerSession, + &tzSvcId); + assert(tzRet == TZ_SUCCESS); + + /* close session */ + tzRet = TZManagerClose(&tzManagerSession); + assert(tzRet == TZ_SUCCESS); + + +The TrustVisor back-end provides some convenience functions for an +application to load an unload a single PAL: + +.. code-block:: c + + tz_device_t tzDevice; + tz_session_t tzPalSession; + tz_uuid_t tzSvcId; + tz_return_t rv; + int rv=0; + + /* configurable options */ + pal_fn_t *pal_fn = &pal_entry_point; + size_t param_size = PAGE_SIZE; + size_t stack_size = PAGE_SIZE; + + /* register the pal */ + rv = tv_tz_init(&tzDevice, + &tzPalSession, + &tzSvcId, + pal_entry_point, + param_size, + stack_size); + assert(rv == TZ_SUCCESS); + + /* do useful work with the pal */ + /* .... */ + + /* register the pal */ + rv = tv_tz_teardown(&tzDevice, + &tzPalSession, + &tzSvcId); + assert(rv == TZ_SUCCESS); + + +Calling services +^^^^^^^^^^^^^^^^ + +Services are called through the TrustZone API. You must open a session +with a currently-loaded service. A session can be used for multiple +invocations of a service. See the +`TrustZone API specification `_ for details. + +Developing services +^^^^^^^^^^^^^^^^^^^ + +Service development is currently very trustvisor-specific. + +Memory Layout +^^^^^^^^^^^^^ + +While eventually services will be compiled as standalone binaries, +currently they are compiled together with the application that calls +them. When loading the service, memory pages that contain service code +and data are registered with trustvisor to be measured and protected. +This means that service code and data must be on separate memory +pages from application code and data, and that you must be able to identify +the relevant memory ranges. This is most easily done by putting service +code in separate object files or in separate sections, e.g. + +A linker script must then be used to ensure page-alignment, and to +identify the beginning and end of the relevant sections. See +``../tz/conf/pal-template.ld`` for an example of such a linker script. + +Service entry point +^^^^^^^^^^^^^^^^^^^ + +The service entry point should have the following prototype: + +.. code-block:: c + + void pal_entry(uint32_t uiCommand, + tzi_encode_buffer_t *psInBuf, + tzi_encode_buffer_t *psOutBuf, + tz_return_t *puiRv) + + + +* ``uiCommand`` will contain command specified in the call to + ``TZOperationPrepareInvoke`` +* ``psInBuf`` will contain the parameters marshalled by ``TZEncode*``. + Use the API in [tz/include/marshal.h] to decode this buffer. +* ``psOutBuf`` is an output buffer for marshalled data. Use the + API in [tz/include/marshal.h] to encode this buffer. +* ``puiRv`` is a status code to be returned. Success should be indicated + by setting this to ``TZ_SUCCESS``. diff --git a/xmhf-64/.gitignore b/xmhf-64/.gitignore new file mode 100644 index 0000000000..678f8eca9a --- /dev/null +++ b/xmhf-64/.gitignore @@ -0,0 +1,25 @@ +*.a +*.d +*.o +*.*~ +*~ +*.log +*.status +*.bin +*.elf +*.img +*.cache +*.0 +*.ls +*.tmp +*.exe +*.lds +*.sha1 +/build-aux/ +/Makefile +/configure +/hypapps/trustvisor/configure +/hypapps/trustvisor/trustvisor.pc +hypervisor-x86-i386.bin.gz +hypervisor-x86-amd64.bin.gz +typescript diff --git a/xmhf-64/CHANGELOG.md b/xmhf-64/CHANGELOG.md new file mode 100644 index 0000000000..bc1bf2f246 --- /dev/null +++ b/xmhf-64/CHANGELOG.md @@ -0,0 +1,73 @@ +Introduction +============ + +XMHF is an eXtensible and Modular Hypervisor Framework +that strives to be a +comprehensible and flexible platform for performing +hypervisor research and development. The framework allows others to +build custom (security-sensitive) hypervisor-based solutions +(called "hypapps"). + +XMHF is designed to achieve three goals – modular extensibility, +automated verification, and high performance. XMHF includes a +core that provides functionality common to many hypervisor-based security +architectures and supports extensions that augment the core with +additional security or functional properties while preserving the +fundamental hypervisor security property of memory integrity +(i.e., ensuring that the hypervisor’s memory is not modified by +software running at a lower privilege level). + +XMHF advocates a "rich" single-guest execution model where the +hypervisor framework supports only a single-guest and allows the +guest direct access to all performance-critical system devices and +device interrupts. + +XMHF currently runs on recent multicore x86 hardware +virtualized platforms with support for dynamic root of trust +and nested (2-dimensional) paging. The framework is capable of +running unmodified legacy multiprocessor capable OSes such as +Windows and Linux. + +Documentation is automatically generated from markdown files in the +code repository, and is viewable at http://xmhf.sourceforge.net/doc/ + + +Changelog +========= + + * 0.1 Initial Release + * 0.1.1 + * Added TPM performance profiling. + * Stability improvements (ticket-28 fixed). + * Intercept handling now serialized in the core. + * XMHF now builds and runs on Ubuntu 12.04 (precise). + * Replaced LGPL tlsf implementation with public domain implementation. + * Added design-documents. + * 0.1.2 + * xmhf-core: stability improvements (ticket-73 fixed) - we can now handle guest NMIs gracefully + * xmhf-core: stability improvements (ticket-10 fixed) - we now support stock MTRR-enabled (linux) guest kernels on Intel platforms + * test-bed fixes, refactoring and improvements - now supporting 3.2.0-27-generic (and below) with ubuntu + * added documentation generator which takes in-tree markdown files and generates html output + * fixed build target install-bin to include correct destination path + * 0.2 + * xmhf-core: clarify documentation and add description for build configuration options and verification + * xmhf-core: add build configuration options --with-target-platform and --with-target-arch to choose target platform and CPU arch. + * xmhf-core: restructure core components and general cleanup + * xmhf-core: add XMHF/hypapp verification harness for verifying core memory integrity + * xmhf-core: fix build error with --enable-debug-vga configure option + * 0.2.1 + * tools: add scripts to deal with release tasks + * xmhf-core: refactor runtime build harness + * xmhf-core: add build debug information within generated binaries + * xmhf-core: segregate Dynamic Root-of-Trust and DMA protection logic and build configuration options + * xmhf-core: add support for upto 8 CPU cores (ticket-74) + * xmhf-core: add XSETBV intercept handling on Intel platforms for CPUs with XSAVE capabilities (ticket-74) + * xmhf-core: fix MTRR logic on Intel platforms to obtain required variable range MTRRs (ticket-74) + * xmhf-core: fix issue related to physical/virtual address overlap for runtime (ticket-31) + * 0.2.2 + * various general documentation fixes and cleanup + * tee-sdk: added patches for newlib and openssl libraries and removed deprecated/non-working examples + * re-organized framework components and revised configuration/build harness and related documentation + * fixed build errors with gcc 4.6.3 + * xmhf-core: re-factored verification harness and added support for 64-bit CBMC + diff --git a/xmhf-64/COPYING.md b/xmhf-64/COPYING.md new file mode 100644 index 0000000000..0be5260ecf --- /dev/null +++ b/xmhf-64/COPYING.md @@ -0,0 +1,1075 @@ +This repository includes several sub-projects, many of which use code +from multiple sources, under different licenses. The AUTHORITATIVE +licenses and conditions are in file-headers and notices in the +individual sub-projects. + +For CONVENIENCE, we here attempt to summarize the state of +licensing for this repository. + +Our view on licensing +===================== + +Our preference is for permissive licenses allowing binary +distribution, though possibly requiring attribution. This is motivated +by several factors: + +1. This project is partially sponsored with government funding. For +this reason it makes sense to make it a "public good" with very few +restrictions. + +2. This project is partially sponsored by independent corporations. We +would like them to be able to view and use the code without fear of +legal entanglements. + +3. We believe that placing fewer restrictions on this code will help +it be used more widely and have greater impact. + +For these reasons, code generated specifically for this project is +placed under a BSD-style license, as in the accompanying [LICENSE](LICENSE) +file. + +We have attempted to minimize the incorporation of third party code +that would place additional restrictions on how our code is used. We +currently use some GPL code, though we continue to seek non-GPL +alternatives. See below for more details. + +Unmodified distribution +======================= + +All software in this repository is under some form of open source +license. You are free to use and distribute the unmodified source code. + +Derived works +============= + +Most of the source licenses have some form of attribution clause +requiring that any modifications leave the copyright and license +information place, and that distributed binaries be accompanied with +that copyright and license information. + +We attempt to avoid GPL-style licenses requiring that derived works +also be under GPL-style licenses. However, there is currently some GPL +code in this repository. See below. + +Binary distribution +=================== + +There is currently some GPL-licensed code in this repository. See below. + +GPL status of sub-projects +========================== + +* xmhf: + No GPL. + + * libbaremetal: + No GPL. + + * third-party: + No GPL. + +* trustvisor: + No GPL. + + * tee-sdk: + hypapps/trustvisor/tee-sdk/ports/newlib is GPLv2. Therefore, PALs + that link with newlib are necessarily GPLv2, including some of the + examples in hypapps/trustvisor/tee-sdk/examples. + +* lockdown: + The lockdown hypervisor itself is not GPL. Some third-party + tools may be, though. See lockdown/src/COPYING for a summary. + +* tools: + No GPL. + +Third party code in repository history +====================================== + +We attempt to summarize third-party code and their respective +licenses that appear somewhere in the history of this repository. +Note that these are no longer present in a checkout of the current +HEAD of the repository, but git always retrieves the exhaustive history. + +* OSLO (GPLv2), +* Putty (MIT license), +* OpenSSH (BSD), +* Linux kernel (GPLv2), +* Xen (GPLv2) +* Google Protocol Buffers (Apache 2.0) +* amtterm (GPLv2) (NOTE: A copy of amtterm's source code was accidentally + updated with our own headers in a now-defunct demo subdirectory of + TrustVisor. This was in error.) +* tlsf_malloc (special LGPL) + +Third party code in current HEAD as of 2013-10-21 +================================================= + +We attempt to summarize third-party code and their respective +license that appear in the current repository HEAD. + +* libtommath (WTFPL) +* libtomcrypto (WTFPL) +* Tboot (BSD-style) +* OpenSSL (BSD-style), +* newlib (GPL) +* tlsf.baisoku.org (public domain) + +Lockdown-specific: + +* RTFM Inc ssldump (http://www.rtfm.com/ssldump/) (BSD) +* LPCUSB, an USB device driver for LPC microcontrollers (BSD) +* LPC ARM processor runtime environment (no restrictions) +* Generic ARM CRC module by Gary S. Brown (no restrictions) + +Notices that must be reproduced +=============================== + +We attempt to catalogue license headers in source files that are +required to be included in any binary-only distribution (i.e., typical +BSD-style requirement): + +XMHF +---- + +---------------------------------------------------------------------- + + Copyright (c) 2003-2010, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- + + Copyright (c) 2007 Henric Jungheim + + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +---------------------------------------------------------------------- + +Lockdown +-------- + +---------------------------------------------------------------------- + /** + + Copyright (C) 1999-2000 RTFM, Inc. + All Rights Reserved + + This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla + and licensed by RTFM, Inc. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. All advertising materials mentioning features or use of this software + must display the following acknowledgement: + + This product includes software developed by Eric Rescorla for + RTFM, Inc. + + 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be + used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE. + + */ + +---------------------------------------------------------------------- + + /*- + ****************************************************************************** + * + * $RCSfile: $ + * $Revision: $ + * + * Header file for Philips LPC ARM Processors. + * Copyright 2004 R O SoftWare + * + * No guarantees, warrantees, or promises, implied or otherwise. + * May be used for hobby or commercial purposes provided copyright + * notice remains intact. + * + *****************************************************************************/ + +---------------------------------------------------------------------- + + /*- + LPCUSB, an USB device driver for LPC microcontrollers + Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +------------------------------------------------------------------- + +Automatically extracted +----------------------- + +The following are automatically extracted headers from files with +FreeBSD-style C-style license header comments starting with `/*-` (note +the dash). One way to identify such files: `egrep -rl '^\/\*-' > +filelist.txt` One way to do most of the heavy lifting (w/ a few false +positives): + + for i in `cat filelist.txt`; do \ + perl -n -e 'print "$_" if /\/\*-/ .. /\*\//;' $i; \ + done + +-------------------------------------------------------------------- + + /*- + ** Two Level Segregated Fit memory allocator, version 1.9. + ** Written by Matthew Conte, and placed in the Public Domain. + ** http://tlsf.baisoku.org + ** + ** Based on the original documentation by Miguel Masmano: + ** http://rtportal.upv.es/rtmalloc/allocators/tlsf/index.shtml + ** + ** Please see the accompanying Readme.txt for implementation + ** notes and caveats. + ** + ** This implementation was written to the specification + ** of the document, therefore no GPL restrictions apply. + */ + /*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz and Don Ahn. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 + */ + /*- + * Copyright (c) 1991 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)ns16550.h 7.1 (Berkeley) 5/9/91 + * $FreeBSD: src/sys/dev/ic/ns16550.h,v 1.20 2010/01/11 04:13:06 imp Exp $ + */ + /*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + /*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + /*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * From: @(#)strtoul.c 8.1 (Berkeley) 6/4/93 + */ + /*- + * Copyright (c) 2001 Mike Barcroft + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: stable/8/sys/sys/stdint.h 199583 2009-11-20 15:27:52Z jhb $ + */ + /*- + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)limits.h 8.3 (Berkeley) 1/4/94 + * $FreeBSD: stable/8/sys/i386/include/_limits.h 199583 2009-11-20 15:27:52Z jhb $ + */ + /*- + * Copyright (c) 1987, 1991 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)endian.h 7.8 (Berkeley) 4/3/91 + * $FreeBSD: stable/8/sys/i386/include/endian.h 199583 2009-11-20 15:27:52Z jhb $ + */ + /*- + * Copyright (c) 2001, 2002 Mike Barcroft + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Klaus Klein. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: stable/8/sys/i386/include/_stdint.h 199583 2009-11-20 15:27:52Z jhb $ + */ + /*- + * Copyright (c) 2003 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: stable/8/sys/sys/_null.h 199583 2009-11-20 15:27:52Z jhb $ + */ + /*- + * Copyright (c) 1982, 1986, 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)types.h 8.6 (Berkeley) 2/19/95 + * $FreeBSD: stable/8/sys/sys/types.h 199583 2009-11-20 15:27:52Z jhb $ + */ + /*- + * Copyright (c) 2002 Mike Barcroft + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * From: @(#)ansi.h 8.2 (Berkeley) 1/4/94 + * From: @(#)types.h 8.3 (Berkeley) 1/5/94 + * $FreeBSD: stable/8/sys/i386/include/_types.h 199583 2009-11-20 15:27:52Z jhb $ + */ + /*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)libkern.h 8.1 (Berkeley) 6/10/93 + * $FreeBSD: src/sys/sys/libkern.h,v 1.60.2.1.6.1 2010/12/21 17:09:25 kensmith Exp $ + */ + /*- + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)limits.h 8.3 (Berkeley) 1/4/94 + * $FreeBSD: stable/8/sys/i386/include/limits.h 199583 2009-11-20 15:27:52Z jhb $ + */ + /*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Berkeley Software Design, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)cdefs.h 8.8 (Berkeley) 1/9/95 + * $FreeBSD: src/sys/sys/cdefs.h,v 1.102.2.2.2.1 2010/12/21 17:09:25 kensmith Exp $ + */ + /*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Klaus Klein. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * From: $NetBSD: int_fmtio.h,v 1.2 2001/04/26 16:25:21 kleink Exp $ + * $FreeBSD: stable/8/sys/i386/include/_inttypes.h 213956 2010-10-17 12:11:42Z marius $ + */ + /*- + * Copyright (c) 2002 Maxime Henrion + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: stable/8/sys/sys/stddef.h 199583 2009-11-20 15:27:52Z jhb $ + */ + /*- + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: stable/8/sys/sys/limits.h 219757 2011-03-18 22:35:48Z jilles $ + */ + /*- + * Copyright (c) 1982, 1988, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: stable/8/sys/sys/ctype.h 199583 2009-11-20 15:27:52Z jhb $ + */ + /*- + * Copyright (c) 2002 Thomas Moestl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: stable/8/sys/sys/endian.h 199583 2009-11-20 15:27:52Z jhb $ + */ + /*- + * Copyright (c) 1986, 1988, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94 + */ + /*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + /*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + /*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + /*- + * Copyright (c) 2008 Damien Bergamini + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +------------------------------------------------------------ diff --git a/xmhf-64/LICENSE b/xmhf-64/LICENSE new file mode 100644 index 0000000000..43ad96f45c --- /dev/null +++ b/xmhf-64/LICENSE @@ -0,0 +1,46 @@ +The following license and copyright notice applies to all content in +this repository where some other license does not take precedence. In +particular, notices in sub-project directories and individual source +files take precedence over this file. + +See COPYING for more information. + +eXtensible, Modular Hypervisor Framework (XMHF) +Copyright (c) 2009-2012 Carnegie Mellon University +Copyright (c) 2010-2012 VDG Inc. +All Rights Reserved. + +Developed by: XMHF Team + Carnegie Mellon University / CyLab + VDG Inc + http://xmhf.org + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +Neither the names of Carnegie Mellon or VDG Inc, nor the names of +its contributors may be used to endorse or promote products derived +from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/xmhf-64/Makefile.in b/xmhf-64/Makefile.in new file mode 100644 index 0000000000..ef35a281f9 --- /dev/null +++ b/xmhf-64/Makefile.in @@ -0,0 +1,508 @@ +# Rootest Makefile for XMHF and an App +# Builds a bunch of subdirectories here, and then builds the app + +EMHF_TOPDIR := $(dir $(lastword $(MAKEFILE_LIST))) +EMHF_ABSTOPDIR := $(realpath $(EMHF_TOPDIR)) + +# define XMHF root directory and XMHF core include directory for +# apps +export EMHF_INCLUDE := $(EMHF_ABSTOPDIR)/xmhf/src/xmhf-core/include + +# define CMOCK and UNITY for app unit test support +export CMOCKDIR := @CMOCKDIR@ +export UNITYDIR := @UNITYDIR@ + +# Options that aspire to be automatically controlled, but are currently +# basically required and everything breaks without them. FIXME! +export NESTED_PAGING := y + +#where you want loader and runtime binaries to go +export HYPOUTDIR = $(CURDIR) + +# App's source tree root ( +export APP_ROOT := $(realpath @APP_ROOT@) + +# The APP_ARCHIVE is what MUST contain ALL of the App's binary code +# 'make install-dev' is handled indepdendently +export builddir=@builddir@ + +export APP_ARCHIVE := $(APP_ROOT)/xmhfhypapp.a + +################################################################################## +### BEGIN Variables controlled using autoconf +################################################################################## +# Build-time configuration options; our project IS UNIQUE in this aspect +# For an explanation of these options, see configure.ac or run: +# ./configure --help +export MP_VERSION := @MP_VERSION@ +export DEBUG_SYMBOLS := @DEBUG_SYMBOLS@ +export DEBUG_QEMU := @DEBUG_QEMU@ +export DEBUG_SERIAL := @DEBUG_SERIAL@ +export DEBUG_SERIAL_PORT := @DEBUG_SERIAL_PORT@ +export DEBUG_VGA := @DEBUG_VGA@ +export DRT := @DRT@ +export DMAP := @DMAP@ +export TARGET_HWPLATFORM := x86 +export XMHF_TARGET_PLATFORM := @TARGET_PLATFORM@ +export XMHF_TARGET_ARCH := @TARGET_ARCH@ +export TARGET_SUBARCH := @TARGET_SUBARCH@ +export AMD64_MAX_PHYS_ADDR := @AMD64_MAX_PHYS_ADDR@ +export OPT_FLAGS := @OPT_FLAGS@ +export OPTIMIZE_NESTED_VIRT := @OPTIMIZE_NESTED_VIRT@ +export UPDATE_INTEL_UCODE := @UPDATE_INTEL_UCODE@ + +# Path settings; our project is not unique in this aspect +export prefix=@prefix@ +export exec_prefix=@exec_prefix@ +export libdir=@libdir@ +export includedir=@includedir@ +export pkgconfigdir=@pkgconfigdir@ +export pkgincludedir=@pkgincludedir@ + +# Tool settings; our project is not unique in this aspect +export CC = @CC@ +export AS = @AS@ +export LD = @LD@ +export OBJDUMP = @OBJDUMP@ +export OBJCOPY = @OBJCOPY@ +export STRIP = @STRIP@ +export RM = @RM@ +export CP = @CP@ +export TAR = @TAR@ +export SED = @SED@ +export MKDIR = @MKDIR@ +export CAT = @CAT@ + +export CCLIB = @CCLIB@ +export BCCLIB = @BCCLIB@ + +ifeq ($(TARGET_SUBARCH), amd64) +export CC32 = @CC32@ +endif + +################################################################################ +### Configure libraries (depends on TARGET_SUBARCH) +################################################################################ + +# libtommath +export LIBTOMMATH_SRC := $(realpath @LIBTOMMATH_SRC@) +LIBTOMMATH_BUILD = $(CURDIR)/_build_libtommath +LIBTOMMATH_ARCHIVE = libtommath.a + +# libtomcrypt +export LIBTOMCRYPT_SRC := $(realpath @LIBTOMCRYPT_SRC@) +LIBTOMCRYPT_BUILD = $(CURDIR)/_build_libtomcrypt +LIBTOMCRYPT_ARCHIVE = libtomcrypt.a + +# libbaremetal "source" location, currently hard-coded +# TODO: specify via configure +# LIBBAREMETAL_SRC = $(CURDIR)/libbaremetal +export LIBBAREMETAL_SRC := $(realpath @LIBBAREMETAL_SRC@) + +# libbaremetal archive +# TODO: specify via configure +LIBBAREMETAL_ARCHIVE = libbaremetal.a + +# libbaremetal includes +LIBBAREMETAL_SUBLIBS = $(wildcard $(LIBBAREMETAL_SRC)/lib*) +LIBBAREMETAL_INC = $(foreach dir,$(LIBBAREMETAL_SUBLIBS),-I$(dir)/include) + +# libbaremetal build directory +LIBBAREMETAL_BUILD = $(CURDIR)/_build_libbaremetal + +# For bootloader (always i386 regardless of runtime subarch), compile separate +# i386 versions of libraries if runtime is amd64. +ifeq ($(TARGET_SUBARCH), amd64) +LIBBAREMETAL_BUILD32 = $(CURDIR)/_build_libbaremetal32 +LIBTOMCRYPT_BUILD32 = $(CURDIR)/_build_libtomcrypt32 +endif + +# Libraries for secureloader and runtime: libbaremetal, tomcrypt, tommath +export ADDL_LIBS := +ADDL_LIBS += $(LIBBAREMETAL_BUILD)/_objects/$(LIBBAREMETAL_ARCHIVE) +ADDL_LIBS += $(LIBTOMCRYPT_BUILD)/$(LIBTOMCRYPT_ARCHIVE) +ADDL_LIBS += $(LIBTOMMATH_BUILD)/$(LIBTOMMATH_ARCHIVE) +# link libbaremetal *again* to resolve more dependencies +ADDL_LIBS += $(LIBBAREMETAL_BUILD)/_objects/$(LIBBAREMETAL_ARCHIVE) + +# Includes for secureloader and runtime +export ADDL_INCLUDES := +ADDL_INCLUDES += -I$(EMHF_INCLUDE) $(LIBBAREMETAL_INC) +ADDL_INCLUDES += -I$(LIBTOMCRYPT_SRC)/src/headers/ +ADDL_INCLUDES += -I$(LIBTOMMATH_SRC) + +# Libraries for bootloader (always i386): libbaremetal, tomcrypt +export ADDL_LIBS_BOOTLOADER := +ifeq ($(TARGET_SUBARCH), amd64) +ADDL_LIBS_BOOTLOADER += $(LIBBAREMETAL_BUILD32)/_objects/$(LIBBAREMETAL_ARCHIVE) +ADDL_LIBS_BOOTLOADER += $(LIBTOMCRYPT_BUILD32)/$(LIBTOMCRYPT_ARCHIVE) +ADDL_LIBS_BOOTLOADER += $(LIBBAREMETAL_BUILD32)/_objects/$(LIBBAREMETAL_ARCHIVE) +else +ADDL_LIBS_BOOTLOADER += $(LIBBAREMETAL_BUILD)/_objects/$(LIBBAREMETAL_ARCHIVE) +ADDL_LIBS_BOOTLOADER += $(LIBTOMCRYPT_BUILD)/$(LIBTOMCRYPT_ARCHIVE) +ADDL_LIBS_BOOTLOADER += $(LIBBAREMETAL_BUILD)/_objects/$(LIBBAREMETAL_ARCHIVE) +endif + +# Includes for bootloader +export ADDL_INCLUDES_BOOTLOADER := +ADDL_INCLUDES_BOOTLOADER += -I$(EMHF_INCLUDE) $(LIBBAREMETAL_INC) +ADDL_INCLUDES_BOOTLOADER += -I$(LIBTOMCRYPT_SRC)/src/headers/ + +# List of subdirs need to be built +export LIB_SUBDIRS := +LIB_SUBDIRS += $(LIBBAREMETAL_BUILD) +LIB_SUBDIRS += $(LIBTOMCRYPT_BUILD) +LIB_SUBDIRS += $(LIBTOMMATH_BUILD) +ifeq ($(TARGET_SUBARCH), amd64) +LIB_SUBDIRS += $(LIBBAREMETAL_BUILD32) +LIB_SUBDIRS += $(LIBTOMCRYPT_BUILD32) +endif + + +##CFLAGS and ASFLAGS population +# experimental support +export INIT_LATE := n +export E820_UG_TEST := n +export TEST_CPU_QUIESCE := n + +# relatively stable support +# TODO: FIXME: Build breaks with some combinations of these options. +# They aren't really "options" anymore +# TODO: Control these with autoconf +export NESTED_PAGING := y + + +#-----build configuration + +#----- build information (version) +export XMHF_BUILD_VERSION := $(shell git describe --abbrev=0) + +#----- build information (revision) +export XMHF_BUILD_REVISION_BRANCH := $(shell git rev-parse --abbrev-ref HEAD) +export XMHF_BUILD_REVISION_COMMIT := $(shell git log --pretty=format:'%H' -n 1) +export XMHF_BUILD_REVISION := $(XMHF_BUILD_REVISION_BRANCH)-$(XMHF_BUILD_REVISION_COMMIT) + +#-----basic flags for compiling and assembling +CFLAGS = -fno-builtin -fno-common -fno-strict-aliasing -iwithprefix include +CFLAGS += -fno-stack-protector +CFLAGS += -Wstrict-prototypes -Wdeclaration-after-statement +CFLAGS += -Wno-pointer-arith -Wextra -Wfloat-equal +CFLAGS += -Werror +CFLAGS += -Wsign-compare +CFLAGS += -Wno-bad-function-cast -Wall +CFLAGS += -Waggregate-return +CFLAGS += -Winline +CFLAGS += -march=k8 +CFLAGS += -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-ssse3 +CFLAGS += -mno-sse4.1 -mno-sse4.2 -mno-sse4 -mno-avx -mno-aes +CFLAGS += -mno-pclmul -mno-sse4a -mno-3dnow -mno-popcnt -mno-abm +# CFLAGS += -mno-sse5 +CFLAGS += -nostdinc -pipe +CFLAGS += -Wno-address-of-packed-member +CFLAGS += -fno-pie -fno-pic -mno-red-zone + +# Compiler optimization (-O1, -O3, ...) +CFLAGS += $(OPT_FLAGS) + +CFLAGS += $(ADDL_INCLUDES) +VFLAGS = $(ADDL_INCLUDES) + +ifeq ($(DEBUG_SYMBOLS), y) + CFLAGS += -g +endif + +#-----generate compiler/assembler defines from configuration options selected +CFLAGS += -D___XMHF_BUILD_VERSION___=\"$(XMHF_BUILD_VERSION)\" +VFLAGS += -D___XMHF_BUILD_VERSION___=\"$(XMHF_BUILD_VERSION)\" + +CFLAGS += -D___XMHF_BUILD_REVISION___=\"$(XMHF_BUILD_REVISION)\" +VFLAGS += -D___XMHF_BUILD_REVISION___=\"$(XMHF_BUILD_REVISION)\" + +ifeq ($(XMHF_TARGET_ARCH), x86-svm) + VFLAGS += -D__XMHF_TARGET_ARCH_X86_SVM__ +endif +ifeq ($(XMHF_TARGET_ARCH), x86-vmx) + VFLAGS += -D__XMHF_TARGET_ARCH_X86_VMX__ +endif + +ifeq ($(DEBUG_QEMU), y) + CFLAGS += -D__DEBUG_QEMU__ + VFLAGS += -D__DEBUG_QEMU__ +endif + +ifeq ($(OPTIMIZE_NESTED_VIRT), y) + CFLAGS += -D__OPTIMIZE_NESTED_VIRT__ + VFLAGS += -D__OPTIMIZE_NESTED_VIRT__ +endif + +ifeq ($(UPDATE_INTEL_UCODE), y) + CFLAGS += -D__UPDATE_INTEL_UCODE__ + VFLAGS += -D__UPDATE_INTEL_UCODE__ +endif + +ifeq ($(NESTED_PAGING), y) + CFLAGS += -D__NESTED_PAGING__ + VFLAGS += -D__NESTED_PAGING__ +endif +ifeq ($(DEBUG_SERIAL), y) + CFLAGS += -D__DEBUG_SERIAL__ + VFLAGS += -D__DEBUG_SERIAL__ + CFLAGS += -DDEBUG_PORT=$(DEBUG_SERIAL_PORT) + VFLAGS += -DDEBUG_PORT=$(DEBUG_SERIAL_PORT) +endif +ifeq ($(DEBUG_VGA), y) + CFLAGS += -D__DEBUG_VGA__ + VFLAGS += -D__DEBUG_VGA__ +endif +ifeq ($(MP_VERSION), y) + CFLAGS += -D__MP_VERSION__ + VFLAGS += -D__MP_VERSION__ +endif +ifeq ($(DRT), y) + CFLAGS += -D__DRT__ + VFLAGS += -D__DRT__ +endif +ifeq ($(DMAP), y) + CFLAGS += -D__DMAP__ + VFLAGS += -D__DMAP__ +endif + + + +CFLAGS += -D__DO_SENTER__ +VFLAGS += -D__DO_SENTER__ + +ifeq ($(E820_UG_TEST), y) + CFLAGS += -D__E820_UG_TEST__ + VFLAGS += -D__E820_UG_TEST__ +endif +ifeq ($(TEST_CPU_QUIESCE), y) + CFLAGS += -D__TEST_CPU_QUIESCE__ + VFLAGS += -D__TEST_CPU_QUIESCE__ +endif + # late initialization support (experimental) +ifeq ($(INIT_LATE), y) + CFLAGS += -D__INIT_LATE__ + VFLAGS += -D__INIT_LATE__ + CFLAGS += -DPERF_CRIT + VFLAGS += -DPERF_CRIT +endif + +# Bootloader flags +BCFLAGS := $(CFLAGS) + +# __I386__: code in this component will run in i386 (32-bit) +# __AMD64__: code in this component will run in amd64 (64-bit) +# __XMHF_I386__: XMHF runtime will run in i386 (32-bit) +# __XMHF_AMD64__: XMHF runtime will run in amd64 (64-bit) + +ifeq ($(TARGET_SUBARCH), amd64) + CFLAGS += -D__AMD64__ -D__XMHF_AMD64__ + BCFLAGS += -D__I386__ -D__XMHF_AMD64__ + VFLAGS += -D__AMD64__ -D__XMHF_AMD64__ + CFLAGS += -DAMD64_MAX_PHYS_ADDR=$(AMD64_MAX_PHYS_ADDR) + BCFLAGS += -DAMD64_MAX_PHYS_ADDR=$(AMD64_MAX_PHYS_ADDR) + VFLAGS += -DAMD64_MAX_PHYS_ADDR=$(AMD64_MAX_PHYS_ADDR) + CFLAGS += -m64 + BCFLAGS += -m32 +endif +ifeq ($(TARGET_SUBARCH), i386) + CFLAGS += -D__I386__ -D__XMHF_I386__ + BCFLAGS += -D__I386__ -D__XMHF_I386__ + VFLAGS += -D__I386__ -D__XMHF_I386__ + CFLAGS += -m32 + BCFLAGS += -m32 +endif + +#-----export CFLAGS and ASFLAGS +ASFLAGS = $(CFLAGS) -D__ASSEMBLY__ +BASFLAGS = $(BCFLAGS) -D__ASSEMBLY__ + +export CFLAGS +export BCFLAGS +export ASFLAGS +export BASFLAGS +export VFLAGS + +.PHONY: all $(APP_ARCHIVE) $(LIB_SUBDIRS) core +all: core + +$(APP_ARCHIVE): + @echo --------------------------------------------------------------- + @echo Building primary hyperapp... + @echo --------------------------------------------------------------- + cd $(APP_ROOT) && $(MAKE) -w all + @echo --------------------------------------------------------------- + @echo primary hyperapp build SUCCESS + @echo --------------------------------------------------------------- + +$(LIBTOMMATH_BUILD): + @echo --------------------------------------------------------------- + @echo Building libtommath... + @echo --------------------------------------------------------------- + mkdir -p $(LIBTOMMATH_BUILD) + cd $(LIBTOMMATH_BUILD) && $(MAKE) -f $(LIBTOMMATH_SRC)/makefile CFLAGS="$(filter-out -Werror,$(CFLAGS))" -w $(LIBTOMMATH_ARCHIVE) + @echo --------------------------------------------------------------- + @echo libtommath.a build SUCCESS + @echo --------------------------------------------------------------- + +$(LIBTOMCRYPT_BUILD): + @echo --------------------------------------------------------------- + @echo Building libtomcrypt... + @echo --------------------------------------------------------------- + mkdir -p $(LIBTOMCRYPT_BUILD) + cd $(LIBTOMCRYPT_BUILD) && $(MAKE) -f $(LIBTOMCRYPT_SRC)/makefile CFLAGS="$(filter-out -Werror,$(CFLAGS)) -DLTC_SOURCE" -w $(LIBTOMCRYPT_ARCHIVE) + @echo --------------------------------------------------------------- + @echo libtomcrypt.a build SUCCESS + @echo --------------------------------------------------------------- + +$(LIBBAREMETAL_BUILD): + @echo --------------------------------------------------------------- + @echo Building libbaremetal... + @echo --------------------------------------------------------------- + mkdir -p $(LIBBAREMETAL_BUILD) + cd $(LIBBAREMETAL_BUILD) && $(MAKE) -f $(LIBBAREMETAL_SRC)/Makefile -w all + @echo --------------------------------------------------------------- + @echo libbaremetal.a build SUCCESS + @echo --------------------------------------------------------------- + +ifeq ($(TARGET_SUBARCH), amd64) + +$(LIBTOMCRYPT_BUILD32): + @echo --------------------------------------------------------------- + @echo Building libtomcrypt 32-bits... + @echo --------------------------------------------------------------- + mkdir -p $(LIBTOMCRYPT_BUILD32) + cd $(LIBTOMCRYPT_BUILD32) && $(MAKE) -f $(LIBTOMCRYPT_SRC)/makefile CFLAGS="$(filter-out -Werror,$(BCFLAGS)) -DLTC_SOURCE" -w $(LIBTOMCRYPT_ARCHIVE) + @echo --------------------------------------------------------------- + @echo libtomcrypt.a 32-bits build SUCCESS + @echo --------------------------------------------------------------- + +$(LIBBAREMETAL_BUILD32): + @echo --------------------------------------------------------------- + @echo Building libbaremetal 32-bits... + @echo --------------------------------------------------------------- + mkdir -p $(LIBBAREMETAL_BUILD32) + cd $(LIBBAREMETAL_BUILD32) && $(MAKE) -f $(LIBBAREMETAL_SRC)/Makefile CFLAGS="$(BCFLAGS)" -w all + @echo --------------------------------------------------------------- + @echo libbaremetal.a 32-bits build SUCCESS + @echo --------------------------------------------------------------- + +endif + +core: $(APP_ARCHIVE) $(LIB_SUBDIRS) + @echo --------------------------------------------------------------- + @echo Building XMHF core/hyperapp... + @echo --------------------------------------------------------------- + cd xmhf/src/xmhf-core && $(MAKE) -w all + @echo --------------------------------------------------------------- + @echo XMHF core/hyperapp build SUCCESS + @echo --------------------------------------------------------------- + +.PHONY: install +install: install-bin + +.PHONY: install-bin +install-bin: + # Install the _actual_ final product + install -d $(DESTDIR)/boot + install --mode=644 $(HYPOUTDIR)/hypervisor-$(TARGET_HWPLATFORM)-$(TARGET_SUBARCH).bin.gz $(DESTDIR)/boot + install --mode=644 $(HYPOUTDIR)/init-$(TARGET_HWPLATFORM)-$(TARGET_SUBARCH).bin $(DESTDIR)/boot + +.PHONY: install-dev +install-dev: + cd $(APP_ROOT) && $(MAKE) -w install-dev + @for i in $(SUBDIRS) ;\ + do \ + (cd $$i && echo "making install-dev in $$i..." && $(MAKE) -w install-dev) || exit 1; \ + done; + +# Currently the only tests we have are in the TrustVisor tree +.PHONY: test +test: + cd $(APP_ROOT) && $(MAKE) -w test + +#.PHONY: clean distclean init-late-clean +.PHONY: clean distclean +clean: + @echo --------------------------------------------------------------- + @echo Cleaning primary hyperapp... + @echo --------------------------------------------------------------- + cd $(APP_ROOT) && $(MAKE) -w clean + @echo --------------------------------------------------------------- + @echo primary hyperapp clean SUCCESS + @echo --------------------------------------------------------------- + @echo --------------------------------------------------------------- + @echo Cleaning libbaremetal... + @echo --------------------------------------------------------------- + mkdir -p $(LIBBAREMETAL_BUILD) + cd $(LIBBAREMETAL_BUILD) && $(MAKE) -f $(LIBBAREMETAL_SRC)/Makefile -w clean + rm -rf $(LIBBAREMETAL_BUILD) + @echo --------------------------------------------------------------- + @echo libbaremetal.a clean SUCCESS + @echo --------------------------------------------------------------- + @echo --------------------------------------------------------------- + @echo Cleaning libtommath and libtomcrypt... + @echo --------------------------------------------------------------- + rm -rf $(LIBTOMMATH_BUILD) + rm -rf $(LIBTOMCRYPT_BUILD) + @echo --------------------------------------------------------------- + @echo libtommath and libtomcrypt clean SUCCESS... + @echo --------------------------------------------------------------- +ifeq ($(TARGET_SUBARCH), amd64) + @echo --------------------------------------------------------------- + @echo Cleaning 32-bits external libraries... + @echo --------------------------------------------------------------- + rm -rf $(LIBTOMCRYPT_BUILD32) + rm -rf $(LIBBAREMETAL_BUILD32) + @echo --------------------------------------------------------------- + @echo 32-bits external libraries clean SUCCESS... + @echo --------------------------------------------------------------- +endif + @echo --------------------------------------------------------------- + @echo Cleaning XMHF core/hyperapp... + @echo --------------------------------------------------------------- + cd xmhf/src/xmhf-core && $(MAKE) -w clean + @echo --------------------------------------------------------------- + @echo XMHF core/hyperapp cleanup SUCCESS + @echo --------------------------------------------------------------- + @echo --------------------------------------------------------------- + @echo Cleaning auto-generated docs... + @echo --------------------------------------------------------------- + rm -rf *.html + rm -rf doc + @echo --------------------------------------------------------------- + @echo auto-generated docs cleanup SUCCESS + @echo --------------------------------------------------------------- + +distclean: clean + $(RM) config.log config.status + # http://www.gnu.org/software/automake/manual/automake.html#Clean + $(RM) -rf Makefile + cd $(APP_ROOT) && $(MAKE) -w distclean + + +verify: + cd xmhf/src/xmhf-core && make -w verify + +verifyinit: + cd xmhf/src/xmhf-core && make -w verifyinit + +verifyall: + cd xmhf/src/xmhf-core && make -w verifyall + +.PHONY: htmldoc +htmldoc: + tools/docgen/render-doc.sh + + +#-----autoconf rules +Makefile: Makefile.in config.status + ./config.status $@ + +config.status: configure + ./config.status --recheck + +configure: configure.ac + ./autogen.sh + diff --git a/xmhf-64/autogen.sh b/xmhf-64/autogen.sh new file mode 100755 index 0000000000..66887dab27 --- /dev/null +++ b/xmhf-64/autogen.sh @@ -0,0 +1,5 @@ +#!/bin/sh +autoreconf --install +automake --add-missing --copy >/dev/null 2>&1 + +exit 0 \ No newline at end of file diff --git a/xmhf-64/configure.ac b/xmhf-64/configure.ac new file mode 100644 index 0000000000..016099baf3 --- /dev/null +++ b/xmhf-64/configure.ac @@ -0,0 +1,258 @@ +AC_INIT([xmhf], [6.1.0]) +AC_CONFIG_AUX_DIR([build-aux]) # use this if\when switching to automake + +AC_PROG_INSTALL + +#AC_PROG_CC +# disabled for now. this macro would test gcc with compiling a +# 'normal' program, which fails with the 'tools' gcc because +# it doesn't have its -lgcc etc. + +# simple configuration of tools. (just looks for matching binary +# on PATH) +AC_CHECK_PROG([CC], [gcc], [gcc]) +AC_CHECK_PROG([AS], [as], [as]) +AC_CHECK_PROG([LD], [ld], [ld]) +AC_CHECK_PROG([OBJDUMP], [objdump], [objdump]) +AC_CHECK_PROG([OBJCOPY], [objcopy], [objcopy]) +AC_CHECK_PROG([STRIP], [strip], [strip]) +AC_CHECK_PROG([RM], [rm -f], [rm -f]) +AC_CHECK_PROG([CP], [cp], [cp]) +AC_CHECK_PROG([TAR], [tar], [tar]) +AC_CHECK_PROG([SED], [sed], [sed]) +AC_CHECK_PROG([MKDIR], [mkdir], [mkdir]) +AC_CHECK_PROG([CAT], [cat], [cat]) + +# user-defined options + +# 64-bit? +AC_SUBST([TARGET_SUBARCH]) +AC_ARG_WITH([target_subarch], + AS_HELP_STRING([--with-target-subarch=@<:@SUBARCH@:>@], + [select target hardware platform (i386, amd64)]), + , [with_target_subarch=i386]) +TARGET_SUBARCH=$[]with_target_subarch + +# When 64-bit, set maximum physical address (default 0x400000000 is 16 GiB) +AC_SUBST([AMD64_MAX_PHYS_ADDR]) +AC_ARG_WITH([amd64_max_phys_addr], + AS_HELP_STRING([--with-amd64-max-phys-addr=@<:@MAX_PHYS_ADDR@:>@], + [select max physical address when using subarch amd64]), + , [with_amd64_max_phys_addr=0x400000000]) +AMD64_MAX_PHYS_ADDR=$[]with_amd64_max_phys_addr + +# find path to -lgcc +AC_SUBST([CCLIB]) +AS_IF([test "x${with_target_subarch}" != "xamd64"], + [CCLIB=`$CC -m32 --print-file-name=`], + [CCLIB=`$CC -m64 --print-file-name=`]) + +# find path to -lgcc in x86 (for bootloader) +# TODO: this is a workaround. Should cross-compile everything in bootloader +# (i.e. use i686-linux-gnu-gcc, i686-linux-gnu-ld, etc.) +AC_CHECK_PROG([CC32], [i686-linux-gnu-gcc], [i686-linux-gnu-gcc], [gcc]) +AC_SUBST([BCCLIB], [`$CC32 -m32 --print-file-name=`]) + +# target platform +AC_SUBST([TARGET_PLATFORM]) +AC_ARG_WITH([target_platform], + AS_HELP_STRING([--with-target-platform=@<:@PLATFORM@:>@], + [select target platform (x86-pc)]), + , [with_target_platform=x86-pc]) +TARGET_PLATFORM=$[]with_target_platform + +# target architecture +AC_SUBST([TARGET_ARCH]) +AC_ARG_WITH([target_arch], + AS_HELP_STRING([--with-target-arch=@<:@ARCH@:>@], + [select target architecture (x86-vmx, x86-svm)]), + , [with_target_arch=x86-vmx]) +TARGET_ARCH=$[]with_target_arch + +# debug symbols (-g in gcc) +AC_SUBST([DEBUG_SYMBOLS]) +AC_ARG_ENABLE([debug_symbols], + AS_HELP_STRING([--enable-debug-symbols@<:@=yes|no@:>@], + [enable debug symbols]), + , [enable_debug_symbols=no]) +AS_IF([test "x${enable_debug_symbols}" != "xno"], + [DEBUG_SYMBOLS=y], + [DEBUG_SYMBOLS=n]) + +# Workaround to run in QEMU +AC_SUBST([DEBUG_QEMU]) +AC_ARG_ENABLE([debug_qemu], + AS_HELP_STRING([--enable-debug-qemu@<:@=yes|no@:>@], + [enable QEMU workaround for debugging]), + , [enable_debug_qemu=no]) +AS_IF([test "x${enable_debug_qemu}" != "xno"], + [DEBUG_QEMU=y], + [DEBUG_QEMU=n]) + +# Optimization when running in nested virtualization +AC_SUBST([OPTIMIZE_NESTED_VIRT]) +AC_ARG_ENABLE([optimize_nested_virt], + AS_HELP_STRING([--enable-optimize-nested-virt@<:@=yes|no@:>@], + [enable optimization for running in nested virtualization]), + , [enable_optimize_nested_virt=no]) +AS_IF([test "x${enable_optimize_nested_virt}" != "xno"], + [OPTIMIZE_NESTED_VIRT=y], + [OPTIMIZE_NESTED_VIRT=n]) + +# Support for updating Intel microcode (a.k.a. ucode) +AC_SUBST([UPDATE_INTEL_UCODE]) +AC_ARG_ENABLE([update_intel_ucode], + AS_HELP_STRING([--enable-update-intel-ucode@<:@=yes|no@:>@], + [enable support for updating Intel microcode]), + , [enable_update_intel_ucode=no]) +AS_IF([test "x${enable_update_intel_ucode}" != "xno"], + [UPDATE_INTEL_UCODE=y], + [UPDATE_INTEL_UCODE=n]) + +AC_SUBST([DEBUG_SERIAL]) +AC_SUBST([DEBUG_SERIAL_PORT]) +AC_ARG_ENABLE([debug_serial], + AS_HELP_STRING([--enable-debug-serial@<:@=PORT|no@:>@], + [enable serial debugging on specified port]), + , [enable_debug_serial=0x3f8]) +AS_IF([test "x${enable_debug_serial}" != "xno"], + [DEBUG_SERIAL=y + DEBUG_SERIAL_PORT=$[]enable_debug_serial], + [DEBUG_SERIAL=n]) + +AC_SUBST([DEBUG_VGA]) +AC_ARG_ENABLE([debug_vga], + AS_HELP_STRING([--enable-debug-vga@<:@=yes|no@:>@], + [enable vga debugging]), + , [enable_debug_vga=no]) +AS_IF([test "x${enable_debug_vga}" != "xno"], + [DEBUG_VGA=y], + [DEBUG_VGA=n]) + +AC_SUBST([MP_VERSION]) +AC_ARG_ENABLE([mp], + AS_HELP_STRING([--enable-mp@<:@=yes|no@:>@], + [enable multiprocessor]), + , [enable_mp=yes]) +AS_IF([test "x${enable_mp}" != "xno"], + [MP_VERSION=y], + [MP_VERSION=n]) + + +# selectively enable/disable Dynamic Root-of-Trust (DRT) +AC_SUBST([DRT]) +AC_ARG_ENABLE([drt], + AS_HELP_STRING([--enable-drt@<:@=yes|no@:>@], + [enable Dynamic Root-of-Trust (DRT)]), + , [enable_drt=yes]) +AS_IF([test "x${enable_drt}" != "xno"], + [DRT=y], + [DRT=n]) + +# selectively enable/disable DMA protection (DMAP) +AC_SUBST([DMAP]) +AC_ARG_ENABLE([dmap], + AS_HELP_STRING([--enable-dmap@<:@=yes|no@:>@], + [enable DMA protection]), + , [enable_dmap=yes]) +AS_IF([test "x${enable_dmap}" != "xno"], + [DMAP=y], + [DMAP=n]) + +# select optimization level +AC_SUBST([OPT_FLAGS]) +AC_ARG_WITH([opt], + AS_HELP_STRING([--with-opt=@<:@OPT@:>@], + [select optimization level (-O1, -O3, ...)]), + , [with_opt=]) +OPT_FLAGS=$[]with_opt + +# libbaremetal source directory +AC_SUBST([LIBBAREMETAL_SRC]) +AC_ARG_WITH([libbaremetalsrc], + AS_HELP_STRING([--with-libbaremetalsrc=@<:@path@:>@], + [path to libbaremetal source directory]), + , [with_libbaremetalsrc=./xmhf/src/libbaremetal]) +LIBBAREMETAL_SRC=$[]with_libbaremetalsrc +# make absolute +dnl AS_IF([test "x${LIBBAREMETAL_SRC:0:1}" != "x/"], +dnl [EMHFCOREDIR=$ac_abs_top_builddir/$LIBBAREMETAL_SRC]) + +AC_CHECK_FILE([${LIBBAREMETAL_SRC}/libxmhfc], + , + AC_MSG_FAILURE([libbaremetal not found at "${LIBBAREMETAL_SRC}"])) + +# libtommath source directory +AC_SUBST([LIBTOMMATH_SRC]) +AC_ARG_WITH([libtommathsrc], + AS_HELP_STRING([--with-libtommathsrc=@<:@path@:>@], + [path to libtommath source directory]), + , [with_libtommathsrc=./xmhf/third-party/libtommath]) +LIBTOMMATH_SRC=$[]with_libtommathsrc +AC_CHECK_FILE([${LIBTOMMATH_SRC}/tommath.h], + , + AC_MSG_FAILURE([libtommath not found at "${LIBTOMMATH_SRC}"])) + +# libtomcrypt source directory +AC_SUBST([LIBTOMCRYPT_SRC]) +AC_ARG_WITH([libtomcryptsrc], + AS_HELP_STRING([--with-libtomcryptsrc=@<:@path@:>@], + [path to libtomcrypt source directory]), + , [with_libtomcryptsrc=./xmhf/third-party/libtomcrypt]) +LIBTOMCRYPT_SRC=$[]with_libtomcryptsrc +AC_CHECK_FILE([${LIBTOMCRYPT_SRC}/src/headers/tomcrypt.h], + , + AC_MSG_FAILURE([libtomcrypt not found at "${LIBTOMCRYPT_SRC}"])) + +# EMHF app root directory +AC_SUBST([APP_ROOT]) +AC_ARG_WITH([approot], + AS_HELP_STRING([--with-approot=@<:@path@:>@], + [path to EMHF app source directory]), + , [with_approot=./hypapps/app]) +APP_ROOT=$[]with_approot +# AC_CONFIG_SUBDIRS fails silently on absolute paths +AS_IF([test "x${APP_ROOT:0:1}" == "x/"], + AC_MSG_FAILURE([approot must be a relative path.])) +# make absolute +dnl AS_IF([test "x${APP_ROOT:0:1}" != "x/"], +dnl [EMHFCOREDIR=$ac_abs_top_builddir/$APP_ROOT]) + +AC_SUBST([EMHFCOREDIR]) +AC_ARG_WITH([emhfcore], + AS_HELP_STRING([--with-emhfcore=@<:@path@:>@], + [path to NO emhfcore XXX FIXME app]), + , [with_emhfcore=./emhfcore/x86]) + + +# todo- maybe test here if configured path actually has emhfcore in it +EMHFCOREDIR=$[]with_emhfcore +# make absolute +dnl AS_IF([test "x${EMHFCOREDIR:0:1}" != "x/"], +dnl [EMHFCOREDIR=$ac_abs_top_builddir/$EMHFCOREDIR]) + +AC_SUBST([CMOCKDIR]) +AC_ARG_WITH([cmock], + AS_HELP_STRING([--with-cmock=@<:@path@:>@], + [path to cmock]), + , [with_cmock=./tools/cmock]) +CMOCKDIR=$[]with_cmock + +AC_SUBST([UNITYDIR]) +AC_ARG_WITH([unity], + AS_HELP_STRING([--with-unity=@<:@path@:>@], + [path to unity]), + , [with_unity=./tools/cmock/vendor/unity]) +UNITYDIR=$[]with_unity + +AC_SUBST([prefix]) +AC_SUBST([exec_prefix]) +AC_SUBST([datadir]) +AC_SUBST([libdir]) +AC_SUBST([includedir]) +AC_SUBST([pkgdatadir], ['${datadir}/AC_PACKAGE_NAME']) +AC_SUBST([pkgconfigdir], ['${libdir}/pkgconfig']) +AC_SUBST([pkgincludedir], ['${includedir}/AC_PACKAGE_NAME']) + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/xmhf-64/hypapps/helloworld/Makefile b/xmhf-64/hypapps/helloworld/Makefile new file mode 100644 index 0000000000..bf50445eb3 --- /dev/null +++ b/xmhf-64/hypapps/helloworld/Makefile @@ -0,0 +1,49 @@ +#------------------------------------------------------------------------------- +# Makefile for XMHF apps +# author: amit vasudevan (amitvasudevan@acm.org) + +# change this to whatever you want your EMHF app to be called +export TARGET_ARCHIVE = xmhfhypapp.a + +# generate app INCLUDE and OBJECT directories +export APP_INCLUDEDIR = $(CURDIR)/app/include +export APPOBJECTSDIR = $(CURDIR)/app/objects + +CFLAGS += -I$(APP_INCLUDEDIR) + +export CFLAGS +export ASFLAGS + +.PHONY: all +all: + # make app components + mkdir -p $(APPOBJECTSDIR) + cd app && $(MAKE) -w all + mv ./app/$(TARGET_ARCHIVE) . + +# There is no binary installation; only the XMHF core +# produces a complete binary of some sort. All libraries +# are at the root level as well. +.PHONY: install +install: + +# install development headers (if any) +.PHONY: install-dev +install-dev: + +# perform unit tests (if any) +.PHONY: test +test: + +# cleanup +.PHONY: clean +clean: + cd app && $(MAKE) -w clean + rm -rf $(APPOBJECTSDIR) $(TARGET_ARCHIVE) + rm -f *.bin + rm -f *.bin.gz + +.PHONY: distclean +distclean: clean + + diff --git a/xmhf-64/hypapps/helloworld/app/Makefile b/xmhf-64/hypapps/helloworld/app/Makefile new file mode 100644 index 0000000000..754d23c471 --- /dev/null +++ b/xmhf-64/hypapps/helloworld/app/Makefile @@ -0,0 +1,32 @@ +#------------------------------------------------------------------------------- +# makefile for XMHF apps +# author: amit vasudevan (amitvasudevan@acm.org) + +# source files +AS_SOURCES = +C_SOURCES = $(wildcard *.c) + +OBJECTS = $(patsubst %.S, $(APPOBJECTSDIR)/%.o, $(AS_SOURCES)) +OBJECTS += $(patsubst %.c, $(APPOBJECTSDIR)/%.o, $(C_SOURCES)) + +I_SOURCES = $(wildcard $(EMHF_INCLUDE)/*.h) +I_SOURCES += $(wildcard $(APP_INCLUDEDIR)/*.h) + +# targets +.PHONY: all +all: $(TARGET_ARCHIVE) + +$(TARGET_ARCHIVE): $(OBJECTS) + mkdir -p $(APPOBJECTSDIR) + $(AR) -rcs $(TARGET_ARCHIVE) $(OBJECTS) + +$(APPBOJECTSDIR)/%.o: %.S $(I_SOURCES) Makefile ../Makefile + $(CC) -c $(ASFLAGS) -o $@ $< +$(APPOBJECTSDIR)/%.o: %.c $(I_SOURCES) Makefile ../Makefile + $(CC) -c $(CFLAGS) -o $@ $< + +.PHONY: clean +clean: + $(RM) -f $(OBJECTS) $(TARGET_ARCHIVE) + + diff --git a/xmhf-64/hypapps/helloworld/app/appmain.c b/xmhf-64/hypapps/helloworld/app/appmain.c new file mode 100644 index 0000000000..8d9245ddec --- /dev/null +++ b/xmhf-64/hypapps/helloworld/app/appmain.c @@ -0,0 +1,111 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// appmain.c +// xmhf application main module +// author: amit vasudevan (amitvasudevan@acm.org) + +#include + +// application main +u32 xmhf_app_main(VCPU *vcpu, APP_PARAM_BLOCK *apb){ + (void)apb; //unused + printf("\nCPU(0x%02x): Hello world from XMHF hyperapp!", vcpu->id); + return APP_INIT_SUCCESS; //successful +} + +//returns APP_SUCCESS if we handled the hypercall else APP_ERROR +u32 xmhf_app_handlehypercall(VCPU *vcpu, struct regs *r){ + u32 status=APP_SUCCESS; + (void)r; //unused + printf("\nCPU(0x%02x): hypercall unhandled, simply returning!", vcpu->id); + return status; +} + +//returns APP_SUCCESS if we allow EPT to change in response to MTRR +u32 xmhf_app_handlemtrr(VCPU *vcpu, u32 msr, u64 val) { + (void) vcpu; + (void) msr; + (void) val; + return APP_SUCCESS; +} + +//handles XMHF shutdown callback +//note: should not return +void xmhf_app_handleshutdown(VCPU *vcpu, struct regs *r){ + (void)r; //unused + xmhf_baseplatform_reboot(vcpu); +} + +//handles h/w pagetable violations +//for now this always returns APP_SUCCESS +u32 xmhf_app_handleintercept_hwpgtblviolation(VCPU *vcpu, + struct regs *r, + gpa_t gpa, gva_t gva, u64 violationcode){ + u32 status = APP_SUCCESS; + + (void)vcpu; //unused + (void)r; //unused + (void)gpa; //unused + (void)gva; //unused + (void)violationcode; //unused + + return status; +} + + +//handles i/o port intercepts +//returns either APP_IOINTERCEPT_SKIP or APP_IOINTERCEPT_CHAIN +u32 xmhf_app_handleintercept_portaccess(VCPU *vcpu, struct regs *r, + u32 portnum, u32 access_type, u32 access_size){ + (void)vcpu; //unused + (void)r; //unused + (void)portnum; //unused + (void)access_type; //unused + (void)access_size; //unused + + return APP_IOINTERCEPT_CHAIN; +} diff --git a/xmhf-64/hypapps/quiesce/Makefile b/xmhf-64/hypapps/quiesce/Makefile new file mode 100644 index 0000000000..bc1383625b --- /dev/null +++ b/xmhf-64/hypapps/quiesce/Makefile @@ -0,0 +1,47 @@ +#------------------------------------------------------------------------------- +# Makefile for XMHF apps +# author: amit vasudevan (amitvasudevan@acm.org) + +# change this to whatever you want your EMHF app to be called +export TARGET_ARCHIVE = xmhfhypapp.a + +# generate app INCLUDE and OBJECT directories +export APP_INCLUDEDIR = $(CURDIR)/app/include +export APPOBJECTSDIR = $(CURDIR)/app/objects + +CFLAGS += -I$(APP_INCLUDEDIR) + +export CFLAGS +export ASFLAGS + +.PHONY: all +all: + # make app components + mkdir -p $(APPOBJECTSDIR) + cd app && $(MAKE) -w all + mv ./app/$(TARGET_ARCHIVE) . + +# There is no binary installation; only the XMHF core +# produces a complete binary of some sort. All libraries +# are at the root level as well. +.PHONY: install +install: + +# install development headers (if any) +.PHONY: install-dev +install-dev: + +# perform unit tests (if any) +.PHONY: test +test: + +# cleanup +.PHONY: clean +clean: + cd app && $(MAKE) -w clean + rm -rf $(APPOBJECTSDIR) $(TARGET_ARCHIVE) + rm -f *.bin + rm -f *.bin.gz + +.PHONY: distclean +distclean: clean diff --git a/xmhf-64/hypapps/quiesce/app/Makefile b/xmhf-64/hypapps/quiesce/app/Makefile new file mode 100644 index 0000000000..754d23c471 --- /dev/null +++ b/xmhf-64/hypapps/quiesce/app/Makefile @@ -0,0 +1,32 @@ +#------------------------------------------------------------------------------- +# makefile for XMHF apps +# author: amit vasudevan (amitvasudevan@acm.org) + +# source files +AS_SOURCES = +C_SOURCES = $(wildcard *.c) + +OBJECTS = $(patsubst %.S, $(APPOBJECTSDIR)/%.o, $(AS_SOURCES)) +OBJECTS += $(patsubst %.c, $(APPOBJECTSDIR)/%.o, $(C_SOURCES)) + +I_SOURCES = $(wildcard $(EMHF_INCLUDE)/*.h) +I_SOURCES += $(wildcard $(APP_INCLUDEDIR)/*.h) + +# targets +.PHONY: all +all: $(TARGET_ARCHIVE) + +$(TARGET_ARCHIVE): $(OBJECTS) + mkdir -p $(APPOBJECTSDIR) + $(AR) -rcs $(TARGET_ARCHIVE) $(OBJECTS) + +$(APPBOJECTSDIR)/%.o: %.S $(I_SOURCES) Makefile ../Makefile + $(CC) -c $(ASFLAGS) -o $@ $< +$(APPOBJECTSDIR)/%.o: %.c $(I_SOURCES) Makefile ../Makefile + $(CC) -c $(CFLAGS) -o $@ $< + +.PHONY: clean +clean: + $(RM) -f $(OBJECTS) $(TARGET_ARCHIVE) + + diff --git a/xmhf-64/hypapps/quiesce/app/appmain.c b/xmhf-64/hypapps/quiesce/app/appmain.c new file mode 100644 index 0000000000..255f5721ea --- /dev/null +++ b/xmhf-64/hypapps/quiesce/app/appmain.c @@ -0,0 +1,123 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// appmain.c +// xmhf application main module +// author: amit vasudevan (amitvasudevan@acm.org) + +#include + +#define QUIESCE_HYPERCALL 0x44550002 + +// application main +u32 xmhf_app_main(VCPU *vcpu, APP_PARAM_BLOCK *apb){ + (void)apb; //unused + printf("\nCPU(0x%02x): Hello world from Quiesce XMHF hyperapp!", vcpu->id); + return APP_INIT_SUCCESS; //successful +} + +//returns APP_SUCCESS if we handled the hypercall else APP_ERROR +u32 xmhf_app_handlehypercall(VCPU *vcpu, struct regs *r){ + u32 status=APP_SUCCESS; + u32 hypercall_number = r->ebx; + + switch(hypercall_number){ + case QUIESCE_HYPERCALL: + printf("\nCPU(0x%02x): this is an ATOMIC printf :)", vcpu->id); + break; + + default: + printf("\nCPU(0x%02x): unhandled hypercall (0x%08x)!", vcpu->id, r->ebx); + break; + } + + return status; +} + +//returns APP_SUCCESS if we allow EPT to change in response to MTRR +u32 xmhf_app_handlemtrr(VCPU *vcpu, u32 msr, u64 val) { + (void) vcpu; + (void) msr; + (void) val; + return APP_SUCCESS; +} + +//handles XMHF shutdown callback +//note: should not return +void xmhf_app_handleshutdown(VCPU *vcpu, struct regs *r){ + (void)r; //unused + xmhf_baseplatform_reboot(vcpu); +} + +//handles h/w pagetable violations +//for now this always returns APP_SUCCESS +u32 xmhf_app_handleintercept_hwpgtblviolation(VCPU *vcpu, + struct regs *r, + gpa_t gpa, gva_t gva, u64 violationcode){ + u32 status = APP_SUCCESS; + + (void)vcpu; //unused + (void)r; //unused + (void)gpa; //unused + (void)gva; //unused + (void)violationcode; //unused + + return status; +} + + +//handles i/o port intercepts +//returns either APP_IOINTERCEPT_SKIP or APP_IOINTERCEPT_CHAIN +u32 xmhf_app_handleintercept_portaccess(VCPU *vcpu, struct regs *r, + u32 portnum, u32 access_type, u32 access_size){ + (void)vcpu; //unused + (void)r; //unused + (void)portnum; //unused + (void)access_type; //unused + (void)access_size; //unused + + return APP_IOINTERCEPT_CHAIN; +} diff --git a/xmhf-64/hypapps/quiesce/guestos/linux/Makefile b/xmhf-64/hypapps/quiesce/guestos/linux/Makefile new file mode 100644 index 0000000000..c7e88d4469 --- /dev/null +++ b/xmhf-64/hypapps/quiesce/guestos/linux/Makefile @@ -0,0 +1,24 @@ +#------------------------------------------------------------------------------- +# Makefile for quiesce XMHF hypapp - guest OS control +# author: amit vasudevan (amitvasudevan@acm.org) + +# target arch: valid values are x86svm and x86vmx +export TARGET_CPU = x86vmx + +#-----generate compiler/assembler defines from configuration options selected +ifeq ($(TARGET_CPU), x86vmx) +CFLAGS += -D__X86VMX__ +endif +ifeq ($(TARGET_CPU), x86svm) +CFLAGS += -D__X86SVM__ +endif + +.PHONY: all +all: + gcc $(CFLAGS) qcontrol.c -o qcontrol + +# cleanup +.PHONY: clean +clean: + rm -rf qcontrol + diff --git a/xmhf-64/hypapps/quiesce/guestos/linux/qcontrol.c b/xmhf-64/hypapps/quiesce/guestos/linux/qcontrol.c new file mode 100644 index 0000000000..f928b737a6 --- /dev/null +++ b/xmhf-64/hypapps/quiesce/guestos/linux/qcontrol.c @@ -0,0 +1,93 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * Quiesce XMHF hyperapp guest OS controller for Linux + * author: amit vasudevan (amitvasudevan@acm.org) + */ +#include + + +#define QUIESCE_HYPERCALL 0x44550002 + + +#if defined(__X86VMX__) + static void do_quiescehypercall(void){ + asm volatile ("vmcall\r\n" + : /* no output registers */ + : "b" (QUIESCE_HYPERCALL) + : "memory" + ); + } +#elif defined(__X86SVM__) + static void do_quiescehypercall(void){ + asm volatile ("vmmcall\r\n" + : /* no output registers */ + : "b" (QUIESCE_HYPERCALL) + : "memory" + ); + } + +#else + +#error MUST choose proper TARGET_CPU in Makefile (x86svm or x86vmx) + +#endif + +#define MAX_ITERATIONS 1 + +int main(void){ + int i; + printf("\nStarting qcontrol..."); + + for(i=0; i < MAX_ITERATIONS; i++){ + printf("\n#%u --> quiesce-call", i); + do_quiescehypercall(); + printf(" --> done"); + } + printf("\nDone."); + printf("\n"); +} diff --git a/xmhf-64/hypapps/trustvisor/Makefile b/xmhf-64/hypapps/trustvisor/Makefile new file mode 100644 index 0000000000..9cd3abb6ad --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/Makefile @@ -0,0 +1,70 @@ +# export EMHFCOREDIR := $(CURDIR)/../../../emhf/trunk/code/$(EMHFROOTDIR)/x86 +# export EMHF_INCLUDEDIR = $(EMHFCOREDIR)/include + +SRCDIR := $(dir $(lastword $(MAKEFILE_LIST))) +SRCDIR := $(realpath $(SRCDIR)) + +# TODO: Control via configuration +export THE_ARCHIVE = xmhfhypapp.a + +export APP_INCLUDEDIR = $(SRCDIR)/src/include +export APPOBJECTSDIR = $(SRCDIR)/src/objects + +#-----basic flags for compiling +CFLAGS += -I$(APP_INCLUDEDIR) + +# app-specific configuration options +export LDN_TV_INTEGRATION := n + +#lockdown-trustvisor integration demo +ifeq ($(LDN_TV_INTEGRATION), y) + CFLAGS += -D__LDN_TV_INTEGRATION__ +endif + +export CFLAGS +export ASFLAGS + +.PHONY: all +all: config.status + # make app components + mkdir -p $(APPOBJECTSDIR) + cd src && $(MAKE) -w all + +# There is no binary installation; only the EMHF core +# produces a complete binary of some sort. All libraries +# are at the root level as well. +.PHONY: install +install: install-dev + +# install development components +.PHONY: install-dev +install-dev: + install -d $(DESTDIR)$(pkgconfigdir) + install --mode=644 trustvisor.pc $(DESTDIR)$(pkgconfigdir) + + install -d $(DESTDIR)$(includedir)/trustvisor + install $(SRCDIR)/src/include/trustvisor.h $(DESTDIR)$(includedir)/trustvisor + install $(LIBBAREMETAL_SRC)/libtv_utpm/include/tv_utpm.h $(DESTDIR)$(includedir)/trustvisor + +.PHONY: test +test: + cd test && $(MAKE) -w all + +.PHONY: clean +clean: + cd src && $(MAKE) -w clean + rm -rf $(APPOBJECTSDIR) $(THE_ARCHIVE) + cd test && $(MAKE) -w clean + rm -f *.bin + rm -f *.bin.gz + +.PHONY: distclean +distclean: clean + $(RM) config.log config.status + $(RM) -rf trustvisor.pc + +config.status: configure + ./configure + +configure: configure.ac + ./autogen.sh diff --git a/xmhf-64/hypapps/trustvisor/autogen.sh b/xmhf-64/hypapps/trustvisor/autogen.sh new file mode 100755 index 0000000000..66887dab27 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/autogen.sh @@ -0,0 +1,5 @@ +#!/bin/sh +autoreconf --install +automake --add-missing --copy >/dev/null 2>&1 + +exit 0 \ No newline at end of file diff --git a/xmhf-64/hypapps/trustvisor/configure.ac b/xmhf-64/hypapps/trustvisor/configure.ac new file mode 100644 index 0000000000..955191adeb --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/configure.ac @@ -0,0 +1,26 @@ +AC_INIT([trustvisor], [0.2]) +#AC_CONFIG_AUX_DIR([build-aux]) # use this if\when switching to automake + +AC_SUBST([prefix]) +AC_SUBST([exec_prefix]) +AC_SUBST([datadir]) +AC_SUBST([libdir]) +AC_SUBST([includedir]) +AC_SUBST([pkgdatadir], ['${datadir}/AC_PACKAGE_NAME']) +AC_SUBST([pkgconfigdir], ['${libdir}/pkgconfig']) +AC_SUBST([pkgincludedir], ['${includedir}/AC_PACKAGE_NAME']) + +AC_CONFIG_FILES([trustvisor.pc]) +AC_OUTPUT + +# libbaremetal source directory +AC_SUBST([LIBBAREMETAL_SRC]) +AC_ARG_WITH([libbaremetalsrc], + AS_HELP_STRING([--with-libbaremetalsrc=@<:@path@:>@], + [path to libbaremetal source directory]), + , [with_libbaremetalsrc=./libbaremetal]) +LIBBAREMETAL_SRC=$[]with_libbaremetalsrc +# make absolute +dnl AS_IF([test "x${LIBBAREMETAL_SRC:0:1}" != "x/"], +dnl [EMHFCOREDIR=$ac_abs_top_builddir/$LIBBAREMETAL_SRC]) + diff --git a/xmhf-64/hypapps/trustvisor/create-deb.sh b/xmhf-64/hypapps/trustvisor/create-deb.sh new file mode 100755 index 0000000000..a66a60c7c8 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/create-deb.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +if [ -d .svn ] ; then +SVNREV=`svn info | grep Revision | cut -d ' ' -f 2` +else +SVNREV=`git log --max-count=1 | perl -ne 'if (m/@(.*) /) { print "$1\n"; } '` +fi + +echo "Detected SVN Revision: $SVNREV" + +debuild -us -uc -b + +#sudo checkinstall -y --pkgname=trustvisor --pkgversion=0.0.$SVNREV --pkgarch=i386 --pkglicense=Commercial --maintainer=jonmccune@cmu.edu + diff --git a/xmhf-64/hypapps/trustvisor/pal_demo/.gitignore b/xmhf-64/hypapps/trustvisor/pal_demo/.gitignore new file mode 100644 index 0000000000..50ea27fb43 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/pal_demo/.gitignore @@ -0,0 +1,4 @@ +main +test +test_args +*.o diff --git a/xmhf-64/hypapps/trustvisor/pal_demo/Makefile b/xmhf-64/hypapps/trustvisor/pal_demo/Makefile new file mode 100644 index 0000000000..ac3d1fea2e --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/pal_demo/Makefile @@ -0,0 +1,30 @@ +# Compile: make +# Cross compile on x64 Debian: CC=i686-linux-gnu-gcc LD=i686-linux-gnu-ld make + +CFLAGS := -g -I../src/include -Wall -Werror + +BINS = main test test_args +PAL_OBJS = pal.o caller.o + +ifeq ($(WINDOWS), y) + CFLAGS += -DWINDOWS +endif + +ifeq ($(CC), x86_64-w64-mingw32-gcc) +PAL_OBJS += translate.o +CFLAGS += -DTRANSLATE +endif + +all: $(BINS) + +main: main.o $(PAL_OBJS) +test_args: test_args.o $(PAL_OBJS) +test: test.c + +pal.o: pal.c + $(CC) $(CFLAGS) -fno-pic -c -o $@ $^ + +.PHONY: clean +clean: + rm -rf *.o $(patsubst %,%.exe,$(BINS)) $(BINS) + diff --git a/xmhf-64/hypapps/trustvisor/pal_demo/caller.c b/xmhf-64/hypapps/trustvisor/pal_demo/caller.c new file mode 100644 index 0000000000..0056714eb1 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/pal_demo/caller.c @@ -0,0 +1,242 @@ +#include +#include +#include + +#ifdef WINDOWS +#include +#include +#else /* !WINDOWS */ +#include +#endif /* WINDOWS */ + +#include "vmcall.h" +#include "caller.h" + +#define PAGE_SIZE ((uintptr_t) 4096) + +#define MAX_PAL_RECORDS 10 + +/* Record PALs in user level */ +typedef struct pal_record_t { + /* Where the user should call, NULL if invalid record */ + void *user_entry; + /* Boundary between untrusted app and PAL */ + uintptr_t pal_entry; + void *mmap_code; + void *mmap_data; + void *mmap_stack; + void *mmap_param; +#ifdef TRANSLATE + void *mmap_code2; +#endif /* TRANSLATE */ +} pal_record_t; + +static pal_record_t pal_records[MAX_PAL_RECORDS]; + +static pal_record_t *get_pal_record(void *user_entry) { + for (int i = 0; i < MAX_PAL_RECORDS; i++) { + if (pal_records[i].user_entry == user_entry) { + return &pal_records[i]; + } + } + while (1) { + assert(0 && "PAL record not found"); + } +} + + +#ifdef TRANSLATE +extern void *windows2linux(); +extern void *windows2linux_call(); +extern void *windows2linux_call_end(); +extern void *windows2linux_end(); +extern void *linux2windows(); +extern void *linux2windows_call(); +extern void *linux2windows_call_end(); +extern void *linux2windows_end(); + +/* + * Relocate a function (callee) that calls another function (callee). The + * caller's template is defined by plt*. The caller should be relocated to + * address starting at target. After relocating, the caller should call callee. + * + * Between plt_call and plt_call_end, there should be a movabs function. + * For example: + * 48 b8 10 32 54 76 98 movabs $0xfedcba9876543210,%rax + * ba dc fe + * + * plt: start of template function + * plt_call: before call instruction + * plt_call_end: after call instruction + * plt_end: end of template function + * plt_magic: magic number in template call instruction + * target: target memory to relocate function to + * callee: function to call after relocation + * return: relocated function entry point + */ +static void *relocate_func(void *plt, void *plt_call, void *plt_call_end, + void *plt_end, uintptr_t plt_magic, void *target, + void *callee) { + assert(plt < plt_call); + assert(plt_call + 10 == plt_call_end); + assert(plt_call_end < plt_end); + memcpy(target, plt, plt_end - plt); + uintptr_t *callee_addr = target + (plt_call - plt) + 2; + assert(*callee_addr == plt_magic); + *callee_addr = (uintptr_t)callee; + return target; +} +#endif /* TRANSLATE */ + +static int lock_and_touch_page(void *addr, size_t len) { +#ifdef WINDOWS + if (!VirtualLock(addr, len)) { + DWORD err = GetLastError(); + printf("VirtualLock error: %lx\n", err); + return 1; + } +#else /* !WINDOWS */ + // Call mlock() and then write to page + // similar to tv_lock_range() and tv_touch_range() in tee-sdk + if (mlock(addr, len)) { + perror("mlock"); + return 1; + } +#endif /* WINDOWS */ + // If do not memset, XMHF will see a NULL page + memset(addr, 0x90, len); + return 0; +} + +/* Call VirtualAlloc on Windows and mmap on Linux */ +static void *mmap_wrap(size_t length) { +#ifdef WINDOWS + DWORD prot = PAGE_EXECUTE_READWRITE; + DWORD va_flags = MEM_COMMIT | MEM_RESERVE; + return VirtualAlloc(NULL, PAGE_SIZE, va_flags, prot); +#else /* !WINDOWS */ + int prot = PROT_EXEC | PROT_READ | PROT_WRITE; + int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS; + return mmap(NULL, PAGE_SIZE, prot, mmap_flags, -1, 0); +#endif /* WINDOWS */ +} + +/* Call VirtualFree on Windows and munmap on Linux */ +static int munmap_wrap(void *addr) { +#ifdef WINDOWS + return !(VirtualFree(addr, 0, MEM_RELEASE)); +#else /* !WINDOWS */ + return munmap(addr, PAGE_SIZE); +#endif /* WINDOWS */ +} + +/* + * Auto-register a PAL + * params: parameters description for TrustVisor + * entry: entry function + * begin_pal, end_pal: upper and lower bound of PAL + * verbose: print mmap info + * return: relocated entry point + */ +void *register_pal(struct tv_pal_params *params, void *entry, void *begin_pal, + void *end_pal, int verbose) { + // Call mmap(), construct struct tv_pal_sections + void *code = mmap_wrap(PAGE_SIZE); + void *data = mmap_wrap(PAGE_SIZE); + void *stack = mmap_wrap(PAGE_SIZE); + void *param = mmap_wrap(PAGE_SIZE); + struct tv_pal_sections sections = { + num_sections: 4, + sections: { + { TV_PAL_SECTION_CODE, 1, (uintptr_t) code }, + { TV_PAL_SECTION_DATA, 1, (uintptr_t) data }, + { TV_PAL_SECTION_STACK, 1, (uintptr_t) stack }, + { TV_PAL_SECTION_PARAM, 1, (uintptr_t) param } + } + }; + for (uint32_t i = 0; i < sections.num_sections; i++) { + struct tv_pal_section *a = &(sections.sections[i]); + assert(a->start_addr); + // Lock and touch page (prevent page getting swapping) + void *start = (void *)(uintptr_t)(a->start_addr); + size_t size = PAGE_SIZE * a->page_num; + assert(!lock_and_touch_page(start, size)); + if (verbose) { + printf("Mmap: %u %p %u\n", a->type, (void*)(uintptr_t)a->start_addr, + a->page_num); + } + } + // Copy function .text + uintptr_t begin_pal_off = (uintptr_t)begin_pal; + uintptr_t end_pal_off = (uintptr_t)end_pal; + uintptr_t entry_off = (uintptr_t)entry; + memcpy(code, begin_pal, end_pal_off - begin_pal_off); + /* Boundary between untrusted app and PAL */ + uintptr_t pal_entry = (uintptr_t)code + (entry_off - begin_pal_off); + /* Where the user should call */ + void *user_entry = (void *)pal_entry; +#ifdef TRANSLATE + void *code2 = mmap_wrap(PAGE_SIZE); + { + // Relocate linux2windows + void *target = code + end_pal_off - begin_pal_off; + user_entry = relocate_func( + linux2windows, linux2windows_call, linux2windows_call_end, + linux2windows_end, 0xfedcba9876543210UL, target, user_entry); + // PAL boundary between windows2linux() and linux2windows_call() + pal_entry = (uintptr_t)user_entry; + // Relocate windows2linux + target = code2; + assert(target); + if (verbose) { + printf("Mmap: %p\n", target); + } + user_entry = relocate_func( + windows2linux, windows2linux_call, windows2linux_call_end, + windows2linux_end, 0x0123456789abcdefUL, target, user_entry); + // Currently the wrapper has to read 10 arguments, so if params is not + // large enough there will be pagefault on accessing stack. + while (params->num_params < TV_MAX_PARAMS) { + params->params[params->num_params].type = TV_PAL_PM_INTEGER; + params->params[params->num_params].size = 0; + params->num_params++; + } + } +#endif /* TRANSLATE */ + if (verbose) { + printf("\n"); + fflush(stdout); + } + // Register PAL locally + pal_record_t *pal_record = get_pal_record(NULL); + pal_record->user_entry = user_entry; + pal_record->pal_entry = pal_entry; + pal_record->mmap_code = code; + pal_record->mmap_data = data; + pal_record->mmap_stack = stack; + pal_record->mmap_param = param; +#ifdef TRANSLATE + pal_record->mmap_code2 = code2; +#endif /* TRANSLATE */ + // Register scode + assert(!vmcall(TV_HC_REG, (uintptr_t)§ions, 0, (uintptr_t)params, + pal_entry)); + return user_entry; +} + +/* + * Auto-unregister a PAL + * user_entry: relocated entry point (return value of register_pal()) + */ +void unregister_pal(void *user_entry) { + pal_record_t *pal_record = get_pal_record(user_entry); + assert(!vmcall(TV_HC_UNREG, pal_record->pal_entry, 0, 0, 0)); + assert(!munmap_wrap(pal_record->mmap_code)); + assert(!munmap_wrap(pal_record->mmap_data)); + assert(!munmap_wrap(pal_record->mmap_stack)); + assert(!munmap_wrap(pal_record->mmap_param)); +#ifdef TRANSLATE + assert(!munmap_wrap(pal_record->mmap_code2)); +#endif /* TRANSLATE */ + pal_record->user_entry = NULL; +} diff --git a/xmhf-64/hypapps/trustvisor/pal_demo/caller.h b/xmhf-64/hypapps/trustvisor/pal_demo/caller.h new file mode 100644 index 0000000000..44508a05c0 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/pal_demo/caller.h @@ -0,0 +1,5 @@ +#include "trustvisor.h" + +void *register_pal(struct tv_pal_params *params, void *entry, void *begin_pal, + void *end_pal, int verbose); +void unregister_pal(void *reloc_entry); diff --git a/xmhf-64/hypapps/trustvisor/pal_demo/main.c b/xmhf-64/hypapps/trustvisor/pal_demo/main.c new file mode 100644 index 0000000000..a7827c3a20 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/pal_demo/main.c @@ -0,0 +1,49 @@ +#include +#include + +#include "pal.h" +#include "caller.h" +#include "trustvisor.h" + +void call_pal(uintptr_t a, uintptr_t b) { + uintptr_t b2 = b; + // Construct struct tv_pal_params + struct tv_pal_params params = { + num_params: 2, + params: { + { TV_PAL_PM_INTEGER, 4 }, + { TV_PAL_PM_POINTER, 4 } + } + }; + // Register scode + void *entry = register_pal(¶ms, my_pal, begin_pal_c, end_pal_c, 1); + typeof(my_pal) *func = (typeof(my_pal) *)entry; + // Call function + printf("With PAL:\n"); + printf(" %p = *%p\n", (void *)b2, &b2); + fflush(stdout); + uintptr_t ret = func(a, &b2); + printf(" %p = my_pal(%p, %p)\n", (void *)ret, (void *)a, &b2); + printf(" %p = *%p\n\n", (void *)b2, &b2); + fflush(stdout); + // Unregister scode + unregister_pal(entry); +} + +int main(int argc, char *argv[]) { + uintptr_t a, b, b2; + uintptr_t ret; + assert(argc > 2); + assert(sscanf(argv[1], "%p", (void **)&a) == 1); + assert(sscanf(argv[2], "%p", (void **)&b) == 1); + b2 = b; + printf("Without PAL:\n"); + printf(" %p = *%p\n", (void *)b2, &b2); + fflush(stdout); + ret = my_pal(a, &b2); + printf(" %p = my_pal(%p, %p)\n", (void *)ret, (void *)a, &b2); + printf(" %p = *%p\n\n", (void *)b2, &b2); + fflush(stdout); + call_pal(a, b); + return 0; +} diff --git a/xmhf-64/hypapps/trustvisor/pal_demo/pal.c b/xmhf-64/hypapps/trustvisor/pal_demo/pal.c new file mode 100644 index 0000000000..ef1198d53c --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/pal_demo/pal.c @@ -0,0 +1,64 @@ +#include "pal.h" + +void begin_pal_c() {} + +uintptr_t my_pal(uintptr_t arg1, uintptr_t *arg2) { + return arg1 + ((*arg2)++); +} + +uintptr_t pal_10_int(uintptr_t arg0, uintptr_t arg1, uintptr_t arg2, + uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, + uintptr_t arg6, uintptr_t arg7, uintptr_t arg8, + uintptr_t arg9) { + uintptr_t ans = 0; + ans += arg0 * 1; + ans += arg1 * 2; + ans += arg2 * 3; + ans += arg3 * 4; + ans += arg4 * 5; + ans += arg5 * 6; + ans += arg6 * 7; + ans += arg7 * 8; + ans += arg8 * 9; + ans += arg9 * 10; + return ans; +} + +uintptr_t pal_10_ptr(uintptr_t *arg0, uintptr_t *arg1, uintptr_t *arg2, + uintptr_t *arg3, uintptr_t *arg4, uintptr_t *arg5, + uintptr_t *arg6, uintptr_t *arg7, uintptr_t *arg8, + uintptr_t *arg9) { + uintptr_t ans = 0; + ans += ((*arg0)++) * 1; + ans += ((*arg1)++) * 2; + ans += ((*arg2)++) * 3; + ans += ((*arg3)++) * 4; + ans += ((*arg4)++) * 5; + ans += ((*arg5)++) * 6; + ans += ((*arg6)++) * 7; + ans += ((*arg7)++) * 8; + ans += ((*arg8)++) * 9; + ans += ((*arg9)++) * 10; + return ans; +} + +uintptr_t pal_5_ptr(uintptr_t size0, uintptr_t *ptr0, uintptr_t size1, + uintptr_t *ptr1, uintptr_t size2, uintptr_t *ptr2, + uintptr_t size3, uintptr_t *ptr3, uintptr_t size4, + uintptr_t *ptr4) { + uintptr_t ans = 0; + uintptr_t sizes[] = {size0, size1, size2, size3, size4}; + uintptr_t *ptrs[] = {ptr0, ptr1, ptr2, ptr3, ptr4}; + uintptr_t coeff = 1; + for (int i = 0; i < 5; i++) { + uintptr_t size = sizes[i]; + uintptr_t *ptr = ptrs[i]; + for (int j = 0; j < size; j++) { + ans += ptr[j] * (coeff++); + ptr[j] += (uintptr_t)0x3141592653589793ULL; + } + } + return ans; +} + +void end_pal_c() {} diff --git a/xmhf-64/hypapps/trustvisor/pal_demo/pal.h b/xmhf-64/hypapps/trustvisor/pal_demo/pal.h new file mode 100644 index 0000000000..e3398de1d7 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/pal_demo/pal.h @@ -0,0 +1,17 @@ +#include + +extern void begin_pal_c(); +extern uintptr_t my_pal(uintptr_t arg1, uintptr_t *arg2); +extern uintptr_t pal_10_int(uintptr_t arg0, uintptr_t arg1, uintptr_t arg2, + uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, + uintptr_t arg6, uintptr_t arg7, uintptr_t arg8, + uintptr_t arg9); +extern uintptr_t pal_10_ptr(uintptr_t *arg0, uintptr_t *arg1, uintptr_t *arg2, + uintptr_t *arg3, uintptr_t *arg4, uintptr_t *arg5, + uintptr_t *arg6, uintptr_t *arg7, uintptr_t *arg8, + uintptr_t *arg9); +extern uintptr_t pal_5_ptr(uintptr_t size0, uintptr_t *ptr0, uintptr_t size1, + uintptr_t *ptr1, uintptr_t size2, uintptr_t *ptr2, + uintptr_t size3, uintptr_t *ptr3, uintptr_t size4, + uintptr_t *ptr4); +extern void end_pal_c(); diff --git a/xmhf-64/hypapps/trustvisor/pal_demo/test.c b/xmhf-64/hypapps/trustvisor/pal_demo/test.c new file mode 100644 index 0000000000..f58e130d32 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/pal_demo/test.c @@ -0,0 +1,13 @@ +#include +#include +#include "vmcall.h" +#include "trustvisor.h" + +int main(int argc, char *argv[]) { + unsigned long eax, result; + assert(argc > 1); + assert(sscanf(argv[1], "%lu", &eax) == 1); + result = vmcall(TV_HC_TEST, eax, 0, 0, 0); + printf("%lu = vmcall(TV_HC_TEST, %lu)\n", result, eax); + return (int)result; +} diff --git a/xmhf-64/hypapps/trustvisor/pal_demo/test_args.c b/xmhf-64/hypapps/trustvisor/pal_demo/test_args.c new file mode 100644 index 0000000000..6eb13885e0 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/pal_demo/test_args.c @@ -0,0 +1,263 @@ +#include +#include +#include + +#include "pal.h" +#include "caller.h" +#include "trustvisor.h" + +#define PASS_ARGS(args) args[0], args[1], args[2], args[3], args[4], \ + args[5], args[6], args[7], args[8], args[9] +#define PASS_ARGS_5(args1, args2) args1[0], args2[0], args1[1], args2[1], \ + args1[2], args2[2], args1[3], args2[3], \ + args1[4], args2[4] + +uintptr_t rand_long(void) { + switch (0) { case 0:; case (RAND_MAX >= 0xff):; }; + uintptr_t ans = 0; + for (int i = 0; i < sizeof(uintptr_t) * 8 / 8; i++) { + ans <<= 8; + ans |= ((uintptr_t)rand()) & 0xff; + } + return ans; +} + +unsigned int test_10_int(unsigned int iters) { + unsigned int result = 0; + // Construct struct tv_pal_params + struct tv_pal_params params = { + num_params: 10, + params: { + { TV_PAL_PM_INTEGER, 0 }, { TV_PAL_PM_INTEGER, 0 }, + { TV_PAL_PM_INTEGER, 0 }, { TV_PAL_PM_INTEGER, 0 }, + { TV_PAL_PM_INTEGER, 0 }, { TV_PAL_PM_INTEGER, 0 }, + { TV_PAL_PM_INTEGER, 0 }, { TV_PAL_PM_INTEGER, 0 }, + { TV_PAL_PM_INTEGER, 0 }, { TV_PAL_PM_INTEGER, 0 }, + } + }; + // Register scode + void *entry = register_pal(¶ms, pal_10_int, begin_pal_c, end_pal_c, 0); + typeof(pal_10_int) *func = (typeof(pal_10_int) *)entry; + // Call function + for (unsigned int iter = 0; iter < iters; iter++) { + uintptr_t args[10]; + for (int i = 0; i < 10; i++) { + args[i] = rand_long(); + } + printf("."); + fflush(stdout); + uintptr_t expected = pal_10_int(PASS_ARGS(args)); + uintptr_t actual = func(PASS_ARGS(args)); + if (actual != expected) { + result++; + printf("Error: args = {%p, %p, %p, %p, %p, %p, %p, %p, %p, %p}, " + "expected %p, actual %p\n", PASS_ARGS((void *)args), + (void *)expected, (void *)actual); + fflush(stdout); + } + } + // Unregister scode + unregister_pal(entry); + return result; +} + +unsigned int test_10_ptr(unsigned int iters) { + unsigned int result = 0; + // Construct struct tv_pal_params + struct tv_pal_params params = { + num_params: 10, + params: { + { TV_PAL_PM_POINTER, 1 }, { TV_PAL_PM_POINTER, 1 }, + { TV_PAL_PM_POINTER, 1 }, { TV_PAL_PM_POINTER, 1 }, + { TV_PAL_PM_POINTER, 1 }, { TV_PAL_PM_POINTER, 1 }, + { TV_PAL_PM_POINTER, 1 }, { TV_PAL_PM_POINTER, 1 }, + { TV_PAL_PM_POINTER, 1 }, { TV_PAL_PM_POINTER, 1 }, + } + }; + // Register scode + void *entry = register_pal(¶ms, pal_10_ptr, begin_pal_c, end_pal_c, 0); + typeof(pal_10_ptr) *func = (typeof(pal_10_ptr) *)entry; + // Call function + for (unsigned int iter = 0; iter < iters; iter++) { + uintptr_t *args_expected[10]; + uintptr_t *args_actual[10]; + uintptr_t nums_original[21]; + uintptr_t nums_expected[21]; + uintptr_t nums_actual[21]; + for (int i = 0; i < 21; i++) { + nums_original[i] = nums_expected[i] = nums_actual[i] = rand_long(); + } + for (int i = 0; i < 10; i++) { + args_expected[i] = &nums_expected[i * 2 + 1]; + args_actual[i] = &nums_actual[i * 2 + 1]; + } + printf("."); + fflush(stdout); + uintptr_t expected = pal_10_ptr(PASS_ARGS(args_expected)); + uintptr_t actual = func(PASS_ARGS(args_actual)); + if (actual != expected) { + result++; + printf("Error: expected return %p, actual %p\n", + (void *)expected, (void *)actual); + fflush(stdout); + continue; + } + for (int i = 0; i < 21; i++) { + if (nums_expected[i] != nums_actual[i]) { + result++; + printf("Error: expected [%d] %p, actual %p, original %p\n", i, + (void *)nums_expected[i], (void *)nums_actual[i], + (void *)nums_original[i]); + fflush(stdout); + break; + } + } + } + // Unregister scode + unregister_pal(entry); + return result; +} + +unsigned int test_5_ptr(unsigned int iters) { + unsigned int result = 0; + // Call function + for (unsigned int iter = 0; iter < iters; iter++) { + printf("."); + fflush(stdout); + // Generate pointer lengths + uintptr_t args_i[5]; + size_t array_size = 1; + for (int i = 0; i < 5; i++) { + args_i[i] = rand_long() % 100; + array_size += args_i[i] + 1; + } + // Allocate nums array + uintptr_t *nums_original = malloc(array_size * sizeof(uintptr_t)); + uintptr_t *nums_expected = malloc(array_size * sizeof(uintptr_t)); + uintptr_t *nums_actual = malloc(array_size * sizeof(uintptr_t)); + for (int i = 0; i < array_size; i++) { + nums_original[i] = nums_expected[i] = nums_actual[i] = rand_long(); + } + // Set up pointers + uintptr_t *args_p_expected[5]; + uintptr_t *args_p_actual[5]; + size_t cur_index = 1; + for (int i = 0; i < 5; i++) { + args_p_expected[i] = &nums_expected[cur_index]; + args_p_actual[i] = &nums_actual[cur_index]; + cur_index += args_i[i] + 1; + } + assert(cur_index == array_size); + // Construct struct tv_pal_params + struct tv_pal_params params = { + num_params: 10, + params: { + { TV_PAL_PM_INTEGER, 0 }, { TV_PAL_PM_POINTER, args_i[0] }, + { TV_PAL_PM_INTEGER, 0 }, { TV_PAL_PM_POINTER, args_i[1] }, + { TV_PAL_PM_INTEGER, 0 }, { TV_PAL_PM_POINTER, args_i[2] }, + { TV_PAL_PM_INTEGER, 0 }, { TV_PAL_PM_POINTER, args_i[3] }, + { TV_PAL_PM_INTEGER, 0 }, { TV_PAL_PM_POINTER, args_i[4] }, + } + }; + // Dump info + if (0) { + printf("\narray_size = %p\n", (void *)array_size); + for (int i = 0; i < 5; i++) { + printf("args_i[%d] = %p\n", i, (void *)args_i[i]); + } + for (int i = 0; i < 5; i++) { + printf("args_p_actual[%d] = %p\n", i, args_p_actual[i]); + } + for (int i = 0; i < 5; i++) { + printf("args_p_expected[%d] = %p\n", i, args_p_expected[i]); + } + printf("nums_original = %p\n", nums_original); + for (int i = 0; i < array_size; i++) { + printf("nums_original[%d] = %p\n", i, + (void *)nums_original[i]); + } + printf("nums_expected = %p\n", nums_expected); + for (int i = 0; i < array_size; i++) { + printf("pre nums_expected[%d] = %p\n", i, + (void *)nums_expected[i]); + } + printf("nums_actual = %p\n", nums_actual); + for (int i = 0; i < array_size; i++) { + printf("pre nums_actual[%d] = %p\n", i, + (void *)nums_actual[i]); + } + } + // Register scode + void *entry = register_pal(¶ms, pal_5_ptr, begin_pal_c, end_pal_c, + 0); + typeof(pal_5_ptr) *func = (typeof(pal_5_ptr) *)entry; + uintptr_t expected = pal_5_ptr(PASS_ARGS_5(args_i, + args_p_expected)); + uintptr_t actual = func(PASS_ARGS_5(args_i, args_p_actual)); + // Unregister scode + unregister_pal(entry); + // Dump info after calling + if (0) { + printf("nums_expected = %p\n", nums_expected); + for (int i = 0; i < array_size; i++) { + printf("post nums_expected[%d] = %p\n", i, + (void *)nums_expected[i]); + } + printf("nums_actual = %p\n", nums_actual); + for (int i = 0; i < array_size; i++) { + printf("post nums_actual[%d] = %p\n", i, + (void *)nums_actual[i]); + } + } + // Check results + if (actual != expected) { + result++; + printf("Error: expected return %p, actual %p\n", + (void *)expected, (void *)actual); + fflush(stdout); + continue; + } + for (int i = 0; i < array_size; i++) { + if (nums_expected[i] != nums_actual[i]) { + result++; + printf("Error: expected [%d] %p, actual %p, original %p\n", i, + (void *)nums_expected[i], (void *)nums_actual[i], + (void *)nums_original[i]); + fflush(stdout); + break; + } + } + // Free + free(nums_expected); + free(nums_actual); + } + return result; +} + +int main(int argc, char *argv[]) { + unsigned int funcs, iters, seed; + assert(argc > 3); + assert(sscanf(argv[1], "%u", &funcs) == 1); + assert(sscanf(argv[2], "%u", &iters) == 1); + assert(sscanf(argv[3], "%u", &seed) == 1); + srand(seed); + unsigned result = 0; + if (funcs & 1) { + result += test_10_int(iters); + } + if (funcs & 2) { + result += test_10_ptr(iters); + } + if (funcs & 4) { + result += test_5_ptr(iters); + } + if (result) { + printf("\nTest failed\n"); + fflush(stdout); + return 1; + } else { + printf("\nTest pass\n"); + fflush(stdout); + return 0; + } +} diff --git a/xmhf-64/hypapps/trustvisor/pal_demo/translate.S b/xmhf-64/hypapps/trustvisor/pal_demo/translate.S new file mode 100644 index 0000000000..669f05e349 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/pal_demo/translate.S @@ -0,0 +1,131 @@ +/* + * Translate between Windows calling convention and Linux for amd64 + * + * Registers: + * + * | Register name | Windows | Linux | + * |---------------|---------|---------| + * | RAX | return | return | + * | RBX | callee | callee | + * | RCX | arg1 | arg4 | + * | RDX | arg2 | arg3 | + * | RSI | callee | arg2 | + * | RDI | callee | arg1 | + * | RBP | callee | callee | + * | RSP | callee | callee | + * | R8 | arg3 | arg5 | + * | R9 | arg4 | arg6 | + * | R10 | caller | caller | + * | R11 | caller | caller | + * | R12 | callee | callee | + * | R13 | callee | callee | + * | R14 | callee | callee | + * | R15 | callee | callee | + * + * Stack: + * * Windows: arg1 - arg10 + * * Linux: arg7 - arg10 + */ + +/* + * A Windows function calls this function, this function calls a Linux function + * + * The stack looks like + * | Addr | Addr | Content | Pointer | + * |------|------|---------|---------| + * | 96 | 128 | arg10 | | + * | 88 | 120 | arg9 | | + * | 80 | 112 | arg8 | | + * | 72 | 104 | arg7 | | + * | 64 | 96 | arg6 | | + * | 56 | 88 | arg5 | | + * | 48 | 80 | (arg4) | | + * | 40 | 72 | (arg3) | | + * | 32 | 64 | (arg2) | | + * | 24 | 56 | (arg1) | | + * | 16 | 48 | return | old rsp | + * | 8 | 40 | rsi | | + * | 0 | 32 | rdi | | + * | | 24 | arg10 | | + * | | 16 | arg9 | | + * | | 8 | arg8 | | + * | | 0 | arg7 | | + */ +.global windows2linux +.global windows2linux_call +.global windows2linux_call_end +.global windows2linux_end + +windows2linux: + pushq %rsi + pushq %rdi + pushq 96(%rsp) + pushq 96(%rsp) + pushq 96(%rsp) + pushq 96(%rsp) + movq %rcx, %rdi + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + movq 96(%rsp), %r9 + movq 88(%rsp), %r8 +windows2linux_call: + movq $0x0123456789abcdef, %rax +windows2linux_call_end: + call *%rax + addq $32, %rsp + popq %rdi + popq %rsi + ret +windows2linux_end: + + +/* + * A Linux function calls this function, this function calls a Windows function + * + * The stack looks like + * | Addr | Addr | Content | Pointer | + * |------|------|---------|---------| + * | 32 | 112 | arg10 | | + * | 24 | 104 | arg9 | | + * | 16 | 96 | arg8 | | + * | 8 | 88 | arg7 | | + * | 0 | 80 | return | old rsp | + * | | 72 | arg10 | | + * | | 64 | arg9 | | + * | | 56 | arg8 | | + * | | 48 | arg7 | | + * | | 40 | arg6 | | + * | | 32 | arg5 | | + * | | 24 | (arg4) | | + * | | 16 | (arg3) | | + * | | 8 | (arg2) | | + * | | 0 | (arg1) | | + */ +.global linux2windows +.global linux2windows_call +.global linux2windows_call_end +.global linux2windows_end + +linux2windows: + pushq 32(%rsp) + pushq 32(%rsp) + pushq 32(%rsp) + pushq 32(%rsp) + pushq %r9 + pushq %r8 + movq %rcx, %r9 + movq %rdx, %r8 + movq %rsi, %rdx + movq %rdi, %rcx + pushq %r9 + pushq %r8 + pushq %rdx + pushq %rcx +linux2windows_call: + movq $0xfedcba9876543210, %rax +linux2windows_call_end: + call *%rax + addq $80, %rsp + ret +linux2windows_end: diff --git a/xmhf-64/hypapps/trustvisor/pal_demo/vmcall.h b/xmhf-64/hypapps/trustvisor/pal_demo/vmcall.h new file mode 100644 index 0000000000..058df9b6ef --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/pal_demo/vmcall.h @@ -0,0 +1,8 @@ +#include + +static inline uintptr_t vmcall(uintptr_t eax, uintptr_t ecx, uintptr_t edx, + uintptr_t esi, uintptr_t edi) { + asm volatile ("vmcall\n\t" : "=a"(eax) : "a"(eax), "c"(ecx), "d"(edx), + "S"(esi), "D"(edi)); + return eax; +} diff --git a/xmhf-64/hypapps/trustvisor/src/Makefile b/xmhf-64/hypapps/trustvisor/src/Makefile new file mode 100644 index 0000000000..0f4c589246 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/Makefile @@ -0,0 +1,26 @@ +# source files +AS_SOURCES = +C_SOURCES = $(wildcard *.c) + +OBJECTS = $(patsubst %.S, $(APPOBJECTSDIR)/%.o, $(AS_SOURCES)) +OBJECTS += $(patsubst %.c, $(APPOBJECTSDIR)/%.o, $(C_SOURCES)) + +I_SOURCES = $(wildcard $(EMHF_INCLUDE)/*.h) +I_SOURCES += $(wildcard $(APP_INCLUDEDIR)/*.h) + +# targets +.PHONY: all +all: ../$(THE_ARCHIVE) + +../$(THE_ARCHIVE): $(OBJECTS) + mkdir -p $(APPOBJECTSDIR) + $(AR) -rcs ../$(THE_ARCHIVE) $(OBJECTS) + +$(APPBOJECTSDIR)/%.o: %.S $(I_SOURCES) Makefile ../Makefile + $(CC) -c $(ASFLAGS) -o $@ $< +$(APPOBJECTSDIR)/%.o: %.c $(I_SOURCES) Makefile ../Makefile + $(CC) -c $(CFLAGS) -o $@ $< + +.PHONY: clean +clean: + $(RM) -f $(OBJECTS) diff --git a/xmhf-64/hypapps/trustvisor/src/appmain.c b/xmhf-64/hypapps/trustvisor/src/appmain.c new file mode 100644 index 0000000000..71905ca288 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/appmain.c @@ -0,0 +1,736 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + */ + +/** + * appmain.c + * Primary TrustVisor entry point from the EMHF core + * authors: amit vasudevan (amitvasudevan@acm.org) + * jnewsome@cmu.edu, jonmccune@cmu.edu + */ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +/* + * When this variable is 0, allow the guest to changing MTRRs (which will + * change EPTs). When PALs have started, do not allow MTRR change (because + * PALs need to duplicate MTRRs). + */ +static u32 started_business = 0; + +const cmdline_option_t gc_trustvisor_available_cmdline_options[] = { + { "nvpalpcr0", "0000000000000000000000000000000000000000"}, /* Req'd PCR[0] of NvMuxPal */ + { "nvenforce", "true" }, /* true|false - actually enforce nvpalpcr0? */ + { NULL, NULL } +}; + +bool cmdline_get_nvenforce(char param_vals[][MAX_VALUE_LEN]) { + const char *nvenforce = cmdline_get_option_val(gc_trustvisor_available_cmdline_options, + param_vals, + "nvenforce"); + if ( nvenforce == NULL || *nvenforce == '\0' ) + return true; /* desired default behavior is YES, DO ENFORCE */ + + if ( strncmp(nvenforce, "false", 6 ) == 0 ) + return false; + + return true; +} + +/* lazy translation table to go from ascii hex to binary, one nibble + * at a time */ +const uint8_t gc_asc2nib[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, + 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, + 13, 14, 15 }; /* don't bother going past 'f' */ +#define ASC2NIB(x) ((x) < 103 ? gc_asc2nib[x] : 0) + +/* allow caller to query whether param exists on cmdline by invoking + * with NULL reqd_pcr0 */ +bool cmdline_get_nvpalpcr0(char param_vals[][MAX_VALUE_LEN], /* in */ + uint8_t *reqd_pcr0) { /* out */ + int i; + const char *ascii = cmdline_get_option_val(gc_trustvisor_available_cmdline_options, + param_vals, + "nvpalpcr0"); + if ( ascii == NULL || *ascii == '\0' ) + return false; /* no param found */ + + if ( reqd_pcr0 == NULL ) + return true; + + for(i=0; i<20; i++) + reqd_pcr0[i] = (ASC2NIB((uint8_t)ascii[2*i]) << 4) | ASC2NIB((uint8_t)ascii[2*i+1]); + + return true; +} + +void parse_boot_cmdline(const char *cmdline) { + char param_vals[ARRAY_SIZE(gc_trustvisor_available_cmdline_options)][MAX_VALUE_LEN]; + + cmdline_parse(cmdline, gc_trustvisor_available_cmdline_options, param_vals); + g_nvenforce = cmdline_get_nvenforce(param_vals); + if(!cmdline_get_nvpalpcr0(param_vals, g_nvpalpcr0) && g_nvenforce) { + /* Emit warning that enforcing uPCR[0] for NV access doesn't make + * sense without specifying which PAL _should_ have access */ + eu_warn("WARNING: NV enforcement ENABLED, but NVPAL's uPCR[0] UNSPECIFIED!"); + } + + eu_trace("NV Enforcement %s", g_nvenforce ? "ENABLED" : "DISABLED"); + print_hex("NV uPCR[0] required to be: ", g_nvpalpcr0, sizeof(g_nvpalpcr0)); +} + +/** + * This is the primary entry-point from the EMHF Core during + * hypervisor initialization. + */ +u32 tv_app_main(VCPU *vcpu, APP_PARAM_BLOCK *apb){ + HALT_ON_ERRORCOND(NULL != vcpu); + HALT_ON_ERRORCOND(NULL != apb); + + eu_trace("CPU(0x%02x)", vcpu->id); + + if (vcpu->isbsp) { + eu_trace("CPU(0x%02x): init\n", vcpu->id); + + eu_trace("CPU(0x%02x) apb->cmdline: \"%s\"", vcpu->id, apb->cmdline); + parse_boot_cmdline(apb->cmdline); + + init_scode(vcpu); + } + + /* force these to be linked in */ + emhfc_log_error(""); + + return APP_INIT_SUCCESS; //successful +} + +struct inbuf_s { + u32 gva; + u32 len; +}; +struct outbuf_s { + u32 gva; + u32 len_gva; +}; + +static u32 do_TV_HC_SHARE(VCPU *vcpu, struct regs *r) +{ + u32 scode_entry, addrs_gva, lens_gva, count; + u32 *addrs=NULL, *lens=NULL; + u32 ret = 1; + +#ifdef __XMHF_AMD64__ + HALT_ON_ERRORCOND(0 && "Not implemented yet for amd64"); +#endif /* __XMHF_AMD64__ */ + + scode_entry = r->ecx; + + addrs_gva = r->edx; + lens_gva = r->esi; + count = r->edi; + + EU_CHK( addrs = malloc(count * sizeof(addrs[0]))); + EU_CHK( lens = malloc(count * sizeof(lens[0]))); + + EU_CHKN( copy_from_current_guest( vcpu, + addrs, + addrs_gva, + sizeof(addrs[0])*count)); + EU_CHKN( copy_from_current_guest( vcpu, + lens, + lens_gva, + sizeof(lens[0])*count)); + + ret = scode_share_ranges(vcpu, scode_entry, addrs, lens, count); + + out: + free(addrs); + free(lens); + return ret; +} + +static u64 do_TV_HC_TEST(VCPU *vcpu, struct regs *r) +{ + (void)r; +#ifdef __XMHF_AMD64__ + eu_trace("CPU(0x%02x): test hypercall, rcx=0x%016x", vcpu->id, r->rcx); +#else /* !__XMHF_AMD64__ */ + eu_trace("CPU(0x%02x): test hypercall, ecx=0x%08x", vcpu->id, r->ecx); +#endif /* __XMHF_AMD64__ */ + return 0; +} + +static u64 do_TV_HC_REG(VCPU *vcpu, struct regs *r) +{ + u64 scode_info, scode_pm, scode_en; + u64 ret; + +#ifdef __XMHF_AMD64__ + scode_info = r->rcx; /* sensitive code as guest virtual address */ + scode_pm = r->rsi; /* sensitive code params information address */ + scode_en = r->rdi; /* sensitive code entry point in edi */ +#else /* !__XMHF_AMD64__ */ + scode_info = r->ecx; /* sensitive code as guest virtual address */ + scode_pm = r->esi; /* sensitive code params information address */ + scode_en = r->edi; /* sensitive code entry point in edi */ +#endif /* __XMHF_AMD64__ */ + + /* do atomic scode registration */ + ret = scode_register(vcpu, scode_info, scode_pm, scode_en); + + return ret; +} + +static u64 do_TV_HC_UNREG(VCPU *vcpu, struct regs *r) +{ + u64 scode_gva; + u64 ret; + /* sensitive code as guest virtual address in ecx */ +#ifdef __XMHF_AMD64__ + scode_gva = r->rcx; +#else /* !__XMHF_AMD64__ */ + scode_gva = r->ecx; +#endif /* __XMHF_AMD64__ */ + + /* do atomic scode unregistration */ + ret = scode_unregister(vcpu, scode_gva); + + return ret; +} + +static u32 do_TV_HC_UTPM_SEAL_DEPRECATED(VCPU *vcpu, struct regs *r) +{ + struct inbuf_s plainbuf_s; + struct outbuf_s sealedbuf_s; + gva_t plainbuf_s_gva; + gva_t sealedbuf_s_gva; + gva_t pcr_gva; + u32 ret = 1; + +#ifdef __XMHF_AMD64__ + HALT_ON_ERRORCOND(0 && "Not implemented yet for amd64"); +#endif /* __XMHF_AMD64__ */ + + plainbuf_s_gva = r->ecx; + sealedbuf_s_gva = r->esi; + pcr_gva = r->edx; + + EU_CHKN( copy_from_current_guest( vcpu, + &plainbuf_s, + plainbuf_s_gva, + sizeof(plainbuf_s))); + + EU_CHKN( copy_from_current_guest( vcpu, + &sealedbuf_s, + sealedbuf_s_gva, + sizeof(sealedbuf_s))); + + ret = hc_utpm_seal_deprecated(vcpu, + plainbuf_s.gva, plainbuf_s.len, + pcr_gva, + sealedbuf_s.gva, sealedbuf_s.len_gva); + + out: + return ret; +} + +static u32 do_TV_HC_UTPM_UNSEAL(VCPU *vcpu, struct regs *r) +{ + struct inbuf_s sealedbuf_s; + struct outbuf_s plainbuf_s; + gva_t sealedbuf_s_gva, plainbuf_s_gva; + gva_t digestAtCreation_gva; + u32 ret = 1; + +#ifdef __XMHF_AMD64__ + HALT_ON_ERRORCOND(0 && "Not implemented yet for amd64"); +#endif /* __XMHF_AMD64__ */ + + sealedbuf_s_gva = r->ecx; + plainbuf_s_gva = r->edx; + digestAtCreation_gva = r->esi; + + EU_CHKN( copy_from_current_guest( vcpu, + &sealedbuf_s, + sealedbuf_s_gva, + sizeof(sealedbuf_s))); + EU_CHKN( copy_from_current_guest( vcpu, + &plainbuf_s, + plainbuf_s_gva, + sizeof(plainbuf_s))); + + ret = hc_utpm_unseal( vcpu, + sealedbuf_s.gva, sealedbuf_s.len, + plainbuf_s.gva, plainbuf_s.len_gva, + digestAtCreation_gva); + + out: + return ret; +} + +static u32 do_TV_HC_UTPM_SEAL(VCPU *vcpu, struct regs *r) +{ + struct inbuf_s plainbuf_s; + struct outbuf_s sealedbuf_s; + gva_t sealedbuf_s_gva, plainbuf_s_gva; + gva_t pcrinfo_gva; + u32 ret=1; + +#ifdef __XMHF_AMD64__ + HALT_ON_ERRORCOND(0 && "Not implemented yet for amd64"); +#endif /* __XMHF_AMD64__ */ + + plainbuf_s_gva = r->ecx; + sealedbuf_s_gva = r->esi; + pcrinfo_gva = r->edx; + + ret = 1; + EU_CHKN( copy_from_current_guest( vcpu, + &plainbuf_s, + plainbuf_s_gva, + sizeof(plainbuf_s))); + EU_CHKN( copy_from_current_guest( vcpu, + &sealedbuf_s, + sealedbuf_s_gva, + sizeof(sealedbuf_s))); + + ret = hc_utpm_seal( vcpu, + plainbuf_s.gva, plainbuf_s.len, + pcrinfo_gva, + sealedbuf_s.gva, sealedbuf_s.len_gva); + out: + return ret; +} + +static u32 do_TV_HC_UTPM_UNSEAL_DEPRECATED(VCPU *vcpu, struct regs *r) +{ + struct inbuf_s sealedbuf_s; + struct outbuf_s plainbuf_s; + gva_t plainbuf_s_gva, sealedbuf_s_gva; + u32 ret=1; + +#ifdef __XMHF_AMD64__ + HALT_ON_ERRORCOND(0 && "Not implemented yet for amd64"); +#endif /* __XMHF_AMD64__ */ + + sealedbuf_s_gva = r->ecx; + plainbuf_s_gva = r->edx; + + EU_CHKN( copy_from_current_guest( vcpu, + &sealedbuf_s, + sealedbuf_s_gva, + sizeof(sealedbuf_s))); + + EU_CHKN( copy_from_current_guest( vcpu, + &plainbuf_s, + plainbuf_s_gva, + sizeof(plainbuf_s))); + + ret = hc_utpm_unseal_deprecated(vcpu, + sealedbuf_s.gva, sealedbuf_s.len, + plainbuf_s.gva, plainbuf_s.len_gva); + + out: + return ret; +} + +static u32 do_TV_HC_UTPM_QUOTE(VCPU *vcpu, struct regs *r) +{ + gva_t nonce_gva, tpmsel_gva; + struct outbuf_s sigbuf_s; + gva_t sigbuf_s_gva; + struct outbuf_s pcr_comp_buf_s; + gva_t pcr_comp_buf_s_gva; + u32 ret = 1; + + eu_trace("TV_HC_UTPM_QUOTE hypercall received."); + +#ifdef __XMHF_AMD64__ + HALT_ON_ERRORCOND(0 && "Not implemented yet for amd64"); +#endif /* __XMHF_AMD64__ */ + + nonce_gva = r->esi; /* address of nonce to be sealed */ + tpmsel_gva = r->ecx; /* tpm selection data address */ + pcr_comp_buf_s_gva = r->edi; /* PCR Composite buffer and its length */ + sigbuf_s_gva = r->edx; /* signature buffer and its length */ + + EU_CHKN( copy_from_current_guest( vcpu, + &sigbuf_s, + sigbuf_s_gva, + sizeof(sigbuf_s))); + + EU_CHKN( copy_from_current_guest( vcpu, + &pcr_comp_buf_s, + pcr_comp_buf_s_gva, + sizeof(sigbuf_s))); + + ret = hc_utpm_quote( vcpu, + nonce_gva, + tpmsel_gva, + sigbuf_s.gva, sigbuf_s.len_gva, + pcr_comp_buf_s.gva, pcr_comp_buf_s.len_gva); + + out: + return ret; +} + +static u32 do_TV_HC_UTPM_ID_GETPUB(VCPU *vcpu, struct regs *r) +{ + u32 dst_gva; + u32 dst_sz_gva; + u32 ret; + +#ifdef __XMHF_AMD64__ + HALT_ON_ERRORCOND(0 && "Not implemented yet for amd64"); +#endif /* __XMHF_AMD64__ */ + + dst_gva = r->ecx; + dst_sz_gva = r->edx; + ret = hc_utpm_utpm_id_getpub( vcpu, dst_gva, dst_sz_gva); + + return ret; +} + +static u32 do_TV_HC_UTPM_QUOTE_DEPRECATED(VCPU *vcpu, struct regs *r) +{ + struct outbuf_s sigbuf_s; + gva_t sigbuf_s_gva; + gva_t nonce_gva, tpmsel_gva; + u32 ret = 1; + +#ifdef __XMHF_AMD64__ + HALT_ON_ERRORCOND(0 && "Not implemented yet for amd64"); +#endif /* __XMHF_AMD64__ */ + + nonce_gva = r->esi; /* address of nonce to be sealed */ + tpmsel_gva = r->ecx; /* tpm selection data address */ + sigbuf_s_gva = r->edx; + + EU_CHKN( copy_from_current_guest( vcpu, + &sigbuf_s, + sigbuf_s_gva, + sizeof(sigbuf_s))); + + ret = hc_utpm_quote_deprecated( vcpu, + nonce_gva, + tpmsel_gva, + sigbuf_s.gva, sigbuf_s.len_gva); + + out: + return ret; +} + +static u32 do_TV_HC_UTPM_PCRREAD(VCPU *vcpu, struct regs *r) +{ + u32 addr, num; + u32 ret=1; + +#ifdef __XMHF_AMD64__ + HALT_ON_ERRORCOND(0 && "Not implemented yet for amd64"); +#endif /* __XMHF_AMD64__ */ + + addr = r->edx; + num = r->ecx; + + ret = hc_utpm_pcrread(vcpu, addr, num); + + return ret; +} + +static u32 do_TV_HC_UTPM_PCREXT(VCPU *vcpu, struct regs *r) +{ + u32 meas_addr, idx; + u32 ret=1; + +#ifdef __XMHF_AMD64__ + HALT_ON_ERRORCOND(0 && "Not implemented yet for amd64"); +#endif /* __XMHF_AMD64__ */ + + meas_addr = r->edx; + idx = r->ecx; + + ret = hc_utpm_pcrextend(vcpu, idx, meas_addr); + + return ret; +} + +static u32 do_TV_HC_UTPM_GENRAND(VCPU *vcpu, struct regs *r) +{ + u32 addr, len_addr; + u32 ret=1; + +#ifdef __XMHF_AMD64__ + HALT_ON_ERRORCOND(0 && "Not implemented yet for amd64"); +#endif /* __XMHF_AMD64__ */ + + addr = r->ecx; + len_addr = r->edx; + + ret = hc_utpm_rand(vcpu, addr, len_addr); + + return ret; +} + +static u32 do_TV_HC_TPMNVRAM_GETSIZE(VCPU *vcpu, struct regs *r) +{ + u32 size_addr; + u32 ret=1; + + eu_trace("TV_HC_TPMNVRAM_GETSIZE invoked."); +#ifdef __XMHF_AMD64__ + HALT_ON_ERRORCOND(0 && "Not implemented yet for amd64"); +#endif /* __XMHF_AMD64__ */ + + size_addr = r->ecx; + ret = hc_tpmnvram_getsize(vcpu, size_addr); + return ret; +} + +static u32 do_TV_HC_TPMNVRAM_READALL(VCPU *vcpu, struct regs *r) +{ + u32 out_addr; + u32 ret; + + eu_trace("TV_HC_TPMNVRAM_READALL invoked."); +#ifdef __XMHF_AMD64__ + HALT_ON_ERRORCOND(0 && "Not implemented yet for amd64"); +#endif /* __XMHF_AMD64__ */ + + out_addr = r->ecx; + ret = hc_tpmnvram_readall(vcpu, out_addr); + eu_trace("TV_HC_TPMNVRAM_READALL returning %d (%s)", ret, ret ? "FAILURE" : "Success"); + return ret; +} + +static u32 do_TV_HC_TPMNVRAM_WRITEALL(VCPU *vcpu, struct regs *r) +{ + u32 in_addr; + u32 ret = 1; + + eu_trace("TV_HC_TPMNVRAM_WRITEALL invoked."); +#ifdef __XMHF_AMD64__ + HALT_ON_ERRORCOND(0 && "Not implemented yet for amd64"); +#endif /* __XMHF_AMD64__ */ + + in_addr = r->ecx; + ret = hc_tpmnvram_writeall(vcpu, in_addr); + return ret; +} + +u32 tv_app_handlehypercall(VCPU *vcpu, struct regs *r) +{ + struct _svm_vmcbfields * linux_vmcb; + u32 cmd; + + u32 status = APP_SUCCESS; + u64 ret = 0; + + started_business = 1; + +//#ifdef __MP_VERSION__ +// xmhf_smpguest_quiesce(vcpu); +//#endif + + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { +#ifdef __XMHF_AMD64__ + cmd = (u32)r->rax; +#else /* !__XMHF_AMD64__ */ + cmd = (u32)r->eax; +#endif /* __XMHF_AMD64__ */ + linux_vmcb = 0; + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + linux_vmcb = (struct _svm_vmcbfields *)(vcpu->vmcb_vaddr_ptr); + cmd = (u32)linux_vmcb->rax; + } else { + printf("unknown cpu vendor type!\n"); + HALT(); + } + +#define HANDLE(hc) case hc: ret = do_ ## hc (vcpu, r); break + + switch (cmd) { + HANDLE( TV_HC_TEST ); + HANDLE( TV_HC_REG ); + HANDLE( TV_HC_UNREG ); + HANDLE( TV_HC_UTPM_SEAL_DEPRECATED ); + HANDLE( TV_HC_UTPM_UNSEAL ); + HANDLE( TV_HC_UTPM_SEAL ); + HANDLE( TV_HC_UTPM_UNSEAL_DEPRECATED ); + HANDLE( TV_HC_UTPM_QUOTE ); + HANDLE( TV_HC_UTPM_ID_GETPUB ); + HANDLE( TV_HC_UTPM_QUOTE_DEPRECATED ); + HANDLE( TV_HC_SHARE ); + HANDLE( TV_HC_UTPM_PCRREAD ); + HANDLE( TV_HC_UTPM_PCREXT ); + HANDLE( TV_HC_UTPM_GENRAND ); + HANDLE( TV_HC_TPMNVRAM_GETSIZE ); + HANDLE( TV_HC_TPMNVRAM_READALL ); + HANDLE( TV_HC_TPMNVRAM_WRITEALL ); + default: + { + eu_err("FATAL ERROR: Invalid vmmcall cmd (%d)", cmd); + status = APP_ERROR; + ret = 1; + } + } + +#undef HANDLE + + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { +#ifdef __XMHF_AMD64__ + r->rax = ret; +#else /* !__XMHF_AMD64__ */ + r->eax = (u32)ret; +#endif /* __XMHF_AMD64__ */ + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + linux_vmcb->rax = ret; + } else { + printf("unknow cpu vendor type!\n"); + HALT(); + } + +//#ifdef __MP_VERSION__ +// xmhf_smpguest_endquiesce(vcpu); +//#endif + + return status; +} + +u32 tv_app_handlemtrr(VCPU *vcpu, u32 msr, u64 val) +{ + (void) vcpu; + (void) msr; + (void) val; + if (started_business) { + return APP_ERROR; + } + return APP_SUCCESS; +} + +/* EPT violation handler */ +u32 tv_app_handleintercept_hwpgtblviolation(VCPU *vcpu, + struct regs *r, u64 gpa, u64 gva, u64 violationcode) +{ + u32 ret; +#if defined(__LDN_TV_INTEGRATION__) + (void)gva; +#endif //__LDN_TV_INTEGRATION__ + + started_business = 1; + +//#ifdef __MP_VERSION__ +// xmhf_smpguest_quiesce(vcpu); +//#endif + +#if !defined(__LDN_TV_INTEGRATION__) + eu_trace("CPU(0x%02x): gva=%#llx, gpa=%#llx, code=%#llx", (int)vcpu->id, + gva, gpa, violationcode); + if ((ret = hpt_scode_npf(vcpu, gpa, violationcode, r)) != 0) { + eu_trace("FATAL ERROR: Unexpected return value from page fault handling"); + HALT(); + } +#else + ret = hpt_scode_npf(vcpu, gpa, violationcode, r); +#endif //__LDN_TV_INTEGRATION__ + +//#ifdef __MP_VERSION__ +// xmhf_smpguest_endquiesce(vcpu); +//#endif + + return ret; +} + +u32 tv_app_handleintercept_portaccess(VCPU *vcpu, struct regs __attribute__((unused)) *r, + u32 portnum, u32 access_type, u32 access_size) +{ +//#ifdef __MP_VERSION__ +// xmhf_smpguest_quiesce(vcpu); +//#endif + + started_business = 1; + + eu_err("CPU(0x%02x): Port access intercept feature unimplemented. Halting!", vcpu->id); + eu_trace("CPU(0x%02x): portnum=0x%08x, access_type=0x%08x, access_size=0x%08x", vcpu->id, + (u32)portnum, (u32)access_type, (u32)access_size); + HALT(); + //return APP_IOINTERCEPT_SKIP; + //return APP_IOINTERCEPT_CHAIN; //chain and do the required I/O + +//#ifdef __MP_VERSION__ +// xmhf_smpguest_endquiesce(vcpu); +//#endif + + return 0; /* XXX DUMMY; keeps compiler happy */ +} + +void tv_app_handleshutdown(VCPU *vcpu, struct regs __attribute__((unused)) *r) +{ + // TODO: can we do `started_business = 0;`? + eu_trace("CPU(0x%02x): Shutdown intercept!", vcpu->id); + //g_libemhf->xmhf_reboot(vcpu); + xmhf_baseplatform_reboot(vcpu); +} + +/* Local Variables: */ +/* mode:c */ +/* indent-tabs-mode:nil */ +/* c-basic-offset:2 */ +/* End: */ diff --git a/xmhf-64/hypapps/trustvisor/src/crypto_init.c b/xmhf-64/hypapps/trustvisor/src/crypto_init.c new file mode 100644 index 0000000000..566025a625 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/crypto_init.c @@ -0,0 +1,347 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/** + * Initialize critical TrustVisor cryptography. + * + * Author: Jonathan McCune + */ + +#include + +#include + +#include +#include +#include + +#include +#include + +#include + +#include + +/* FIXME: make them static (i.e., only inside this file) */ +/* extern */ bool g_master_prng_init_completed = false; +/* extern */ bool g_master_crypto_init_completed = false; + +/** + * These two are set by the boot cmdline-parsing code in appmain.c, + * and used primarily from within nv.c. Defining them here so as to + * have such globals in one place. */ +/* extern */ bool g_nvenforce = true; +/* extern */ uint8_t g_nvpalpcr0[20]; + +/* XXX FIXME: needs spinlock protection in MP mode */ +/* extern */ NIST_CTR_DRBG g_drbg; + +/* Don't want to get optimized out. */ +void zeroize(uint8_t* _p, unsigned int len) { + volatile uint8_t *p = _p; + unsigned int i; + + for(i=0; i= 0); + + rv=0; + out: + return rv; +} + +/** + * Do a measurement of the "quick and dirty" RSA public key from the + * keypair used to sign uTPM quotes, effectively "bridging" trust from + * the hardware TPM to the software keys in TrustVisor. + * + * returns 0 on success. + */ +#define QND_BRIDGE_PUBKEY_PCR 19 + +static int trustvisor_measure_qnd_bridge_signing_pubkey( void ) { + int rv=1; + uint32_t serial_pubkey_len=0; + uint8_t *serial_pubkey = NULL; + tpm_digest_t digest; + tpm_pcr_value_t pcr_out; + + /** + * 1. Serialize RSA key into byte blob for purposes of measurement. + */ + EU_CHKN( utpm_id_getpub( NULL, &serial_pubkey_len)); /* query for size needed */ + EU_CHK( serial_pubkey = malloc(serial_pubkey_len)); + EU_CHKN( utpm_id_getpub( serial_pubkey, &serial_pubkey_len)); + eu_trace("Serialized RSA key: %*D", serial_pubkey_len, serial_pubkey, " "); + + /** + * 2. Hash serialized RSA key. + */ + EU_CHKN( sha1_buffer( serial_pubkey, serial_pubkey_len, digest.digest)); + + /** + * 3. Extend PCR with hash. + */ + EU_CHKN( rv = tpm_pcr_extend(CRYPTO_INIT_LOCALITY, QND_BRIDGE_PUBKEY_PCR, + &digest, &pcr_out), + eu_err_e("FATAL ERROR: Could not extend HW TPM PCR %d.", QND_BRIDGE_PUBKEY_PCR)); + + eu_trace( "Successfully extended HW TPM PCR %d.", QND_BRIDGE_PUBKEY_PCR); + eu_trace( "New PCR value: ", TPM_HASH_SIZE, pcr_out.digest, " "); + + rv=0; + out: + free( serial_pubkey); + return rv; +} + +/* involves accessing TPM NV RAM. */ +/* depends on PRNG already being initialized. */ +/* returns 0 on success. */ +static int trustvisor_long_term_secret_init(void) { + int rv = 1; + uint8_t mss[HW_TPM_MASTER_SEALING_SECRET_SIZE]; + /* The actual AES key is smaller than this, so we need a temporary + * buffer. */ + uint8_t aeskey_temp[HW_TPM_MASTER_SEALING_SECRET_SIZE]; + unsigned long aeskey_temp_len = sizeof(aeskey_temp); + uint8_t hmackey_temp[HW_TPM_MASTER_SEALING_SECRET_SIZE]; + unsigned long hmackey_temp_len = sizeof(hmackey_temp); + const uint8_t sealingaes[10] = {0x73, 0x65, 0x61, 0x6c, 0x69, 0x6e, + 0x67, 0x61, 0x65, 0x73}; + const uint8_t sealinghmac[11] = {0x73, 0x65, 0x61, 0x6c, 0x69, 0x6e, + 0x67, 0x68, 0x6d, 0x61, 0x63}; + rsa_key rsakey; + int hash_id = register_hash( &sha1_desc); + + EU_VERIFY( g_master_prng_init_completed); + + rv = trustvisor_nv_get_mss(CRYPTO_INIT_LOCALITY, + HW_TPM_MASTER_SEALING_SECRET_INDEX, + mss, + HW_TPM_MASTER_SEALING_SECRET_SIZE); + if(0 != rv) { + eu_err("FATAL ERROR: trustvisor_nv_get_mss FAILED (%d).\n", + rv); + /* TODO: Support degraded operation during development. */ + /* XXX SECURITY XXX: continuing anyways for now */ + //HALT_ON_ERRORCOND(false); + eu_err( "VULNERABILITY:VULNERABILITY:VULNERABILITY:VULNERABILITY\n" + " Reading / initializing master sealing secret FAILED!!\n" + " Continuing anyways...\n" + "VULNERABILITY:VULNERABILITY:VULNERABILITY:VULNERABILITY\n"); + } + + HALT_ON_ERRORCOND( HW_TPM_MASTER_SEALING_SECRET_SIZE == hash_descriptor[hash_id].hashsize); + + /* Derive encryption and MAC keys for sealed storage */ + EU_VERIFYN( hmac_memory( hash_id, + mss, HW_TPM_MASTER_SEALING_SECRET_SIZE, + sealingaes, sizeof(sealingaes), + aeskey_temp, &aeskey_temp_len)); + + EU_VERIFYN( hmac_memory( hash_id, + mss, HW_TPM_MASTER_SEALING_SECRET_SIZE, + sealinghmac, sizeof(sealinghmac), + hmackey_temp, &hmackey_temp_len)); + + EU_VERIFY( TPM_AES_KEY_LEN_BYTES <= HW_TPM_MASTER_SEALING_SECRET_SIZE); + + eu_trace( "Sealing AES key derived from MSS."); + eu_trace( "Sealing HMAC key derived from MSS."); + + /* /\* SECURITY: Delete these print_hex()'s ASAP! *\/ */ + /* print_hex("XXX mss: ", mss, 20); */ + /* print_hex("XXX g_aeskey: ", g_aeskey, (TPM_AES_KEY_LEN>>3)); */ + /* print_hex("XXX g_hmackey: ", g_hmackey, 20); */ + + /* Initialize RSA key required in uTPM Quote */ + /* FIXME: Having a single key here is a privacy-invading, + * session-linkable, PAL-linkable hack to get things off the + * ground. */ + eu_trace( "Generating RSA keypair..."); + + /* If someday, somebody decides to keep things going during + development or debugging, don't forget that we MUST zero + sensitive keys upon failure. */ + EU_VERIFYN( rsa_make_key( &g_ltc_prng, g_ltc_prng_id, TPM_RSA_KEY_LEN, 65537, &rsakey)); + eu_trace("RSA key pair generated"); + + /* same story as above. */ + EU_VERIFYN( utpm_init_master_entropy(aeskey_temp, hmackey_temp, &rsakey)); + + rv = 0; + /* out: */ + memset(mss, 0, HW_TPM_MASTER_SEALING_SECRET_SIZE); + memset(aeskey_temp, 0, HW_TPM_MASTER_SEALING_SECRET_SIZE); + memset(hmackey_temp, 0, HW_TPM_MASTER_SEALING_SECRET_SIZE); + /* Measure the Identity key used to sign Micro-TPM Quotes. */ + /* prefer not to depend on the globals */ + if(0 != (rv = trustvisor_measure_qnd_bridge_signing_pubkey())) { + eu_err("trustvisor_long_term_secret_init FAILED with rv %d!!!!", rv); + } + /* Intentionally not a proper free. Responsibility for this + * structure has been transferred to the utpm implementation. */ + memset(&rsakey, 0, sizeof(rsakey)); + + return rv; +} + +/* returns 0 on success. */ +/* TODO: take ciphertext input, e.g., from a multiboot_t */ +int trustvisor_master_crypto_init(void) { + int rv=1; + bool opened_tpm=false; + + /* ensure libtomcrypto's math descriptor is initialized */ + if (!ltc_mp.name) { + ltc_mp = ltm_desc; + } + + EU_CHKN( rv = xmhf_tpm_open_locality(CRYPTO_INIT_LOCALITY), + eu_err_e( "FATAL ERROR: Could not access HW TPM.")); + opened_tpm=true; + + /* PRNG */ + EU_CHKN( rv = master_prng_init(), + eu_err_e( "AES-256 CTR_DRBG PRNG init FAILED with rv %d!!!!\n", rv)); + + g_master_prng_init_completed = true; + + eu_trace( "AES-256 CTR_DRBG PRNG successfully seeded with TPM RNG."); + + /* NV space used to support Micro-TPM Long-Term sealing */ + EU_CHKN( rv = trustvisor_long_term_secret_init()); + + eu_trace( "long term secrets initialized successfully."); + + /* Confirm that the NV space that will be used for anti-rollback + by the NvMuxPal has appropriate controls in place. */ + EU_CHKN( rv = validate_trustvisor_nv_region( TRUSTVISOR_HWTPM_NV_LOCALITY, + HW_TPM_ROLLBACK_PROT_INDEX, + HW_TPM_ROLLBACK_PROT_SIZE), + eu_err_e( "ERROR: " + " validate_trustvisor_nv_region(%d, 0x%08x, %d)" + " FAILED with rv %d\n", + TRUSTVISOR_HWTPM_NV_LOCALITY, + HW_TPM_ROLLBACK_PROT_INDEX, + HW_TPM_ROLLBACK_PROT_SIZE, + rv), + rv = 0); /* XXX maintaining old behavior here. is this really what we want? */ + + eu_trace( "NvMuxPal anti-rollback NV Region: " + "Access Controls validated successfully."); + + g_master_crypto_init_completed = true; + + /* We're now done with the TPM for a while. Make sure it is + * available to the legacy OS. */ + rv=0; + out: + if (opened_tpm) { + xmhf_tpm_deactivate_all_localities(); + } + + return rv; +} + +/* Local Variables: */ +/* mode:c */ +/* indent-tabs-mode:nil */ +/* c-basic-offset:2 */ +/* End: */ diff --git a/xmhf-64/hypapps/trustvisor/src/dump.c b/xmhf-64/hypapps/trustvisor/src/dump.c new file mode 100644 index 0000000000..ef9c58a9af --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/dump.c @@ -0,0 +1,119 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * Copyright (c) 2007 Henric Jungheim + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "nist_ctr_drbg.h" + +void +nist_dump_simple_hex(const void* data, int length) +{ + int i; + const unsigned char* p = data; + for (i = 0; i < length; ++i) + printf("%02X", *p++); +} + +void +nist_dump_hex(const void* data, int length) +{ + int i; + const unsigned char* p = data; + for (i = 0; i < length; ++i) { + if (i && !(i & 3)) { + printf((i & 31) ? "-" : "\n"); + } + printf("%02x", *p++); + } +} + +void +nist_dump_named_hex(const char* name, const void* data, int length) +{ + printf(" %s: ", name); + nist_dump_hex(data, length); + printf("\n"); +} + +void +nist_dump_ctr_drbg(const NIST_CTR_DRBG* drbg) +{ + printf(" reseed_counter = %d\n", drbg->reseed_counter); + printf(" V: "); + nist_dump_hex(&drbg->V[0], sizeof(drbg->V)); + printf("\n"); +} + +void +nist_dump_aes_ctx(const rijndael_ctx* ctx) +{ + printf(" Nr = %d\n ek:\n", ctx->Nr); + nist_dump_hex(ctx->ek, sizeof(ctx->ek)); + + printf("\n"); + + if (!ctx->enc_only) { + printf(" dk:\n"); + nist_dump_hex(ctx->dk, sizeof(ctx->dk)); + printf("\n"); + } +} diff --git a/xmhf-64/hypapps/trustvisor/src/emhf_callbacks.c b/xmhf-64/hypapps/trustvisor/src/emhf_callbacks.c new file mode 100644 index 0000000000..9329c1ac48 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/emhf_callbacks.c @@ -0,0 +1,80 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include +#include + +u32 xmhf_app_main(VCPU *vcpu, APP_PARAM_BLOCK *apb) +{ + return tv_app_main(vcpu, apb); +} + +u32 xmhf_app_handlehypercall(VCPU *vcpu, struct regs *r) +{ + return tv_app_handlehypercall(vcpu, r); +} + +u32 xmhf_app_handlemtrr(VCPU *vcpu, u32 msr, u64 val) +{ + return tv_app_handlemtrr(vcpu, msr, val); +} + +u32 xmhf_app_handleintercept_hwpgtblviolation(VCPU *vcpu, + struct regs *r, gpa_t gpa, gva_t gva, u64 violationcode) +{ + return tv_app_handleintercept_hwpgtblviolation(vcpu, r, gpa, gva, violationcode); +} + +u32 xmhf_app_handleintercept_portaccess(VCPU *vcpu, struct regs *r, + u32 portnum, u32 access_type, u32 access_size) +{ + return tv_app_handleintercept_portaccess(vcpu, r, portnum, access_type, access_size); +} + +void xmhf_app_handleshutdown(VCPU *vcpu, struct regs *r) +{ + tv_app_handleshutdown(vcpu, r); +} diff --git a/xmhf-64/hypapps/trustvisor/src/emhfc_log_error.c b/xmhf-64/hypapps/trustvisor/src/emhfc_log_error.c new file mode 100644 index 0000000000..28dfd5dffb --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/emhfc_log_error.c @@ -0,0 +1,56 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include + +void emhfc_log_error(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + dvprintf(LOG_ERROR, fmt, args); + va_end(args); +} diff --git a/xmhf-64/hypapps/trustvisor/src/hc_utpm.c b/xmhf-64/hypapps/trustvisor/src/hc_utpm.c new file mode 100644 index 0000000000..d130389b53 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/hc_utpm.c @@ -0,0 +1,606 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/** + * hc_utpm.c: Handle hypercalls from PALs that invoke uTPM operations. + * + * Intention is that TrustVisor needs to contain some "glue" code to + * connect hypercalls from individual PALs to the uTPM implementation + * that goes with that PAL. However, the utpm.[ch] implementation + * should be sufficiently standalone as to eventually support + * independent testing. + * + * Thus, the purpose of hc_utpm.[ch] is to be the plumbing that + * connects hypercalls in PALs to the right uTPM operation(s). + * + * author: Jon McCune, July 2011 + */ + +#include + +#include +#include /* formerly utpm.h */ +#include +#include /* copy_from_guest */ +#include /* malloc */ + +#include + +/** + * FIXME: Ugly circular dependency. hc_utpm.c doesn't work without + * scode.h, and scode.c doesn't work without hc_utpm.h. Figure out + * the hierarchy of dependencies and refactor things more + * intelligently. + */ + +/* defined in scode.c */ +/* TODO: more elegant organization of these data structures */ +extern int *scode_curr; +extern whitelist_entry_t *whitelist; + +uint32_t hc_utpm_seal(VCPU * vcpu, uint32_t input_addr, uint32_t input_len, uint32_t tpmPcrInfo_addr, uint32_t output_addr, uint32_t output_len_addr) +{ + uint8_t indata[MAX_SEALDATA_LEN]; + uint8_t output[MAX_SEALDATA_LEN]; + uint32_t outlen; + uint32_t rv=1; + + TPM_PCR_INFO tpmPcrInfo; + + eu_trace("********** uTPM seal **********"); + eu_trace("input_addr: %x, input_len %d, tpmPcrInfo_addr: %x, output_addr: %x!", input_addr, input_len, tpmPcrInfo_addr, output_addr); + + EU_CHK( vcpu ); + EU_CHK( input_addr ); + EU_CHK( tpmPcrInfo_addr ); + EU_CHK( output_addr ); + EU_CHK( output_len_addr ); + + /** + * check input data length + */ + /* include seal data header and possible AES encryption padding */ + EU_CHK ( input_len <= (MAX_SEALDATA_LEN - SEALDATA_HEADER_LEN - 16), + eu_err_e( "Seal ERROR: input data length is too large, length %#x", input_len)); + + /* make sure that this vmmcall can only be executed when a PAL is running */ + EU_CHK ( scode_curr[vcpu->id] != -1, + eu_err_e( "Seal ERROR: no PAL is running!")); + + /* copy input data to host */ + EU_CHKN( copy_from_current_guest(vcpu, indata, input_addr, input_len)); + EU_CHKN( copy_from_current_guest(vcpu, (uint8_t*)&tpmPcrInfo, tpmPcrInfo_addr, sizeof(TPM_PCR_INFO))); + + eu_trace("input len = %d!", input_len); + eu_trace("indata: %*D", input_len, indata, " "); + eu_trace("tpmPcrInfo: %*D", sizeof(TPM_PCR_INFO), &tpmPcrInfo, " "); + + /* seal, verifying output is not too large */ + EU_CHKN( rv = utpm_seal(&whitelist[scode_curr[vcpu->id]].utpm, + &tpmPcrInfo, + indata, input_len, + output, &outlen)); + EU_CHK( outlen <= MAX_SEALDATA_LEN, + eu_err_e("Seal ERROR: output data length is too large, lenth %#x", outlen)); + eu_trace("sealedData: %*D", outlen, output, " "); + + /*copy output to guest */ + EU_CHKN( copy_to_current_guest(vcpu, output_addr, output, outlen)); + + /* copy out length to guest */ + EU_CHKN( copy_to_current_guest(vcpu, + output_len_addr, + &outlen, + sizeof(outlen))); + + rv = 0; + out: + return rv; +} + +uint32_t hc_utpm_unseal(VCPU * vcpu, uint32_t input_addr, uint32_t input_len, + uint32_t output_addr, uint32_t output_len_addr, + uint32_t digestAtCreation_addr) +{ + uint8_t indata[MAX_SEALDATA_LEN]; + uint8_t outdata[MAX_SEALDATA_LEN]; + uint32_t outlen; + uint32_t ret=1; + TPM_COMPOSITE_HASH digestAtCreation; + + eu_trace("********** uTPM unseal **********"); + + EU_CHK( vcpu); + EU_CHK( input_addr); + EU_CHK( output_addr); + EU_CHK( output_len_addr); + EU_CHK( digestAtCreation_addr); + + eu_trace("input addr: %x, len %d, output addr: %x!", + input_addr, input_len, output_addr); + /* check input data length */ + EU_CHK( input_len <= MAX_SEALDATA_LEN, + eu_err_e("Unseal ERROR: input data length is too large, length %#x", input_len)); + + /* make sure that this vmmcall can only be executed when a PAL is running */ + EU_CHK( scode_curr[vcpu->id] != -1, + eu_err_e("Unseal ERROR: no PAL is running!")); + + /* copy input data from guest */ + EU_CHKN( copy_from_current_guest( vcpu, indata, input_addr, input_len)); + + eu_trace("input data: %*D", input_len, indata, " "); + + /* unseal */ + EU_CHKN( ret = utpm_unseal(&whitelist[scode_curr[vcpu->id]].utpm, indata, input_len, + outdata, &outlen, &digestAtCreation)); + + eu_trace("output (unsealed) data: %*D", outlen, outdata, " "); + + /* check output data length */ + EU_CHK( outlen <= MAX_SEALDATA_LEN, + eu_err_e("Unseal ERROR: output data length is too large, length %#x", outlen)); + + /* copy output to guest */ + EU_CHKN( copy_to_current_guest(vcpu, output_addr, outdata, outlen)); + EU_CHKN( copy_to_current_guest(vcpu, digestAtCreation_addr, (uint8_t*)&digestAtCreation, TPM_HASH_SIZE)); + + /* copy out length to guest */ + EU_CHKN( copy_to_current_guest( vcpu, output_len_addr, &outlen, sizeof(outlen))); + + ret = 0; + out: + return ret; +} + + +u32 hc_utpm_seal_deprecated(VCPU * vcpu, u32 input_addr, u32 input_len, u32 pcrAtRelease_addr, u32 output_addr, u32 output_len_addr) +{ + unsigned int i; + u32 outlen; + u8 pcr[TPM_PCR_SIZE]; + u8 indata[MAX_SEALDATA_LEN]; + u8 output[MAX_SEALDATA_LEN]; + u32 rv = 1; + + eu_trace("********** uTPM seal DEPRECATED **********"); + eu_trace("input addr: %x, len %d, pcr addr: %x, output addr: %x!", + input_addr, input_len, pcrAtRelease_addr, output_addr); + + /* check input data length */ + /* include seal data header and possible AES encryption padding */ + EU_CHK( input_len <= (MAX_SEALDATA_LEN-SEALDATA_HEADER_LEN - 16), + eu_err_e("Seal ERROR: input data length is too large, length %#x", input_len)); + + /* make sure that this vmmcall can only be executed when a PAL is running */ + EU_CHK( scode_curr[vcpu->id] != -1, + eu_err_e("Seal ERROR: no PAL is running!")); + + /* copy input data to host */ + EU_CHKN( copy_from_current_guest(vcpu, indata, input_addr, input_len)); + +#if 0 + eu_trace("input len = %d!", input_len); + eu_trace("input data is:"); + for(i=0;iid]].utpm.pcr_bank, TPM_PCR_SIZE); + } + +#if 1 + eu_trace("pcr value is:"); + for(i=0;iid] != -1, + eu_err_e("Seal ERROR: no PAL is running!")); + + /* copy input data from guest */ + EU_CHKN( copy_from_current_guest(vcpu, indata, input_addr, input_len)); + +#if 0 + eu_trace("input len = %d!", input_len); + eu_trace("input data is:"); + for(i=0;iid]].utpm, indata, input_len, outdata, &outlen)); + +#if 1 + eu_trace("unsealed data len = %d!", outlen); + eu_trace("unsealed data is: "); + for(i=0;iid] != -1, + eu_err_e("Quote ERROR: no PAL is running!")); + + /* get TPM PCR selection from guest */ + EU_CHKN( copy_from_current_guest( vcpu, &num, tpmsel_addr, sizeof(num))); + EU_CHK( num <= MAX_PCR_SEL_NUM, + eu_err_e("Quote ERROR: select too many PCR!")); + tpmsel_len = 4+4*num; + eu_trace("%d pcrs are selected!", num); + + EU_CHKN( copy_from_current_guest(vcpu, tpmsel, tpmsel_addr, tpmsel_len)); + for( i=0 ; i< num ; i++ ) { + EU_CHK( *(((u32 *)(tpmsel+4))+i) < TPM_PCR_NUM, + eu_err_e("Quote ERROR: bad format of TPM PCR num!")); + } + + /* get external nonce from guest */ + EU_CHKN( copy_from_current_guest(vcpu, nonce, nonce_addr, TPM_NONCE_SIZE)); + +#if 1 + eu_trace("external nonce is: "); + for(i=0;iid]].utpm, tpmsel, tpmsel_len) != 0); + +#if 0 + eu_trace("quote data len = %d!", outlen); + eu_trace("quote data is: "); + for(i=0;iid] != -1, + eu_err_e("Quote ERROR: no PAL is running!")); + + /* get external nonce from guest */ + EU_CHKN( copy_from_current_guest(vcpu, &nonce, nonce_addr, sizeof(TPM_NONCE))); + + /* get TPM PCR selection from guest */ + /* FIXME: sizeof(TPM_PCR_SELECTION) may eventually change dynamically */ + EU_CHKN( copy_from_current_guest(vcpu, &tpmsel, tpmsel_addr, sizeof(TPM_PCR_SELECTION))); + + /* Get size of guest's sig buffer */ + EU_CHKN( copy_from_current_guest(vcpu, &siglen, sig_len_addr, sizeof(uint32_t))); + eu_trace("Guest provided sig buffer of %d bytes", siglen); + + /* FIXME: This is just a rough sanity check that catches some uninitialized variables. */ + EU_CHK( siglen <= 5*TPM_QUOTE_SIZE, + eu_err_e("ERROR: Guest-provided siglen value of %d seems ridiculous", siglen)); + + /* Get size of guest's pcrComp buffer */ + EU_CHKN( copy_from_current_guest(vcpu, &pcrCompLen, pcrCompLen_addr, sizeof(gva_t))); + eu_trace("Guest provided pcrComp buffer of %ld bytes", pcrCompLen); + + /** + * Allocate space to do internal processing + */ + EU_CHK( sigdata = malloc(siglen)); + EU_CHK( pcrComp = malloc(pcrCompLen)); + + /* FIXME: Still want to return a modified "siglen" in case the input buffer was too small. + I.e., this fails too aggressively. */ + EU_CHKN( ret = utpm_quote(&nonce, &tpmsel, sigdata, &siglen, + pcrComp, &pcrCompLen, + &whitelist[scode_curr[vcpu->id]].utpm)); + + /* Some sanity-checking. TODO: replace with asserts & use tighter bound */ + if (siglen > 2*TPM_QUOTE_SIZE) { + eu_err_e("ERROR: siglen (%d) > 2*TPM_QUOTE_SIZE", siglen); + siglen = TPM_QUOTE_SIZE; /* FIXME: We should return some kind of error code */ + /* return 1; */ /* Don't return from here; it causes some kind of crash in the PAL */ + } + + eu_trace("quote sigdata len = %d!", siglen); + //print_hex(" QD: ", sigdata, siglen); + + /* copy quote sig to guest */ + EU_CHKN( copy_to_current_guest(vcpu, sig_addr, sigdata, siglen)); + eu_trace("hc_utpm_quote: Survived copy_to_current_guest of %d bytes", siglen); + + /* copy pcrComp to guest */ + EU_CHKN( copy_to_current_guest(vcpu, pcrComp_addr, pcrComp, pcrCompLen)); + + /* copy quote sig length to guest */ + EU_CHKN( copy_to_current_guest( vcpu, sig_len_addr, &siglen, sizeof(siglen))); + eu_trace("hc_utpm_quote: Survived put_32bit_aligned_value_to_current_guest"); + + ret=0; + out: + free(sigdata); sigdata = NULL; + free(pcrComp); pcrComp = NULL; + + return ret; +} + +uint32_t hc_utpm_utpm_id_getpub(VCPU * vcpu, gva_t dst_gva, gva_t dst_sz_gva) +{ + uint8_t *rsaModulus=NULL; + uint32_t rv = 1; + uint32_t dst_sz; + + eu_trace("********** uTPM id_getpub **********"); + + /* make sure that this vmmcall can only be executed when a PAL is running */ + EU_CHK( scode_curr[vcpu->id] != -1, + eu_err_e("ID_GETPUB ERROR: no PAL is running!")); + + EU_CHKN( copy_from_current_guest( vcpu, &dst_sz, dst_sz_gva, sizeof(dst_sz))); + + rsaModulus = malloc( dst_sz); + EU_CHK( rsaModulus || (dst_sz == 0)); + + EU_CHKN( rv = utpm_id_getpub(rsaModulus, &dst_sz)); + + //print_hex(" N : ", rsaModulus, TPM_RSA_KEY_LEN); + EU_CHKN( copy_to_current_guest( vcpu, dst_gva, rsaModulus, dst_sz)); + EU_CHKN( copy_to_current_guest( vcpu, dst_sz_gva, &dst_sz, sizeof(dst_sz))); + + rv = 0; + out: + free(rsaModulus); + return rv; +} + +u32 hc_utpm_pcrread(VCPU * vcpu, u32 gvaddr, u32 num) +{ + TPM_DIGEST pcr; + u32 rv = 1; + + eu_trace("********** uTPM pcrread **********"); + + /* make sure that this vmmcall can only be executed when a PAL is running */ + EU_CHK( scode_curr[vcpu->id] != -1, + eu_err_e("PCRRead ERROR: no PAL is running!")); + + /* make sure requested PCR number is in reasonable range */ + EU_CHK( num < TPM_PCR_NUM, + eu_err_e("PCRRead ERROR: pcr num %d not correct!", num)); + + /* read pcr value */ + EU_CHKN( rv = utpm_pcrread(&pcr, &whitelist[scode_curr[vcpu->id]].utpm, num)); + + /* return pcr value to guest */ + EU_CHKN( copy_to_current_guest(vcpu, gvaddr, pcr.value, TPM_PCR_SIZE)); + + rv = 0; + out: + return rv; +} + + +u32 hc_utpm_pcrextend(VCPU * vcpu, u32 idx, u32 meas_gvaddr) +{ + TPM_DIGEST measurement; + u32 rv = 1; + + eu_trace("********** uTPM pcrextend **********"); + + /* make sure that this vmmcall can only be executed when a PAL is running */ + EU_CHK( scode_curr[vcpu->id] != -1, + eu_err_e("PCRExtend ERROR: no PAL is running!")); + + /* make sure requested PCR number is in reasonable range */ + EU_CHK( idx < TPM_PCR_NUM, + eu_err_e("PCRExtend ERROR: pcr idx %d not correct!", idx)); + + /* get data from guest */ + EU_CHKN( copy_from_current_guest(vcpu, (u8 *)measurement.value, meas_gvaddr, TPM_HASH_SIZE)); + + /* extend pcr */ + //print_hex("PCRExtend data from guest: ", measurement.value, TPM_HASH_SIZE); + EU_CHKN( rv = utpm_extend(&measurement, &whitelist[scode_curr[vcpu->id]].utpm, idx)); + + rv = 0; + out: + return rv; +} + +u32 hc_utpm_rand(VCPU * vcpu, u32 buffer_addr, u32 numbytes_addr) +{ + u32 ret = 1; + u8 buffer[MAX_TPM_RAND_DATA_LEN]; + u32 numbytes; + + /* make sure that this vmmcall can only be executed when a PAL is running */ + EU_CHK( scode_curr[vcpu->id] != -1, + eu_err_e("PCRExtend ERROR: no PAL is running!")); + + // get the byte number requested + EU_CHKN( copy_from_current_guest( vcpu, &numbytes, numbytes_addr, sizeof(numbytes))); + EU_CHK( numbytes <= MAX_TPM_RAND_DATA_LEN, + eu_err_e("GenRandom ERROR: requested rand data len %d too large!", numbytes)); + + EU_CHKN( ret = utpm_rand(buffer, &numbytes), + eu_err_e("GenRandom ERROR: rand byte error; numbytes=%d!", + numbytes)); + + /* copy random data to guest */ + EU_CHKN( copy_to_current_guest(vcpu, buffer_addr, buffer, numbytes)); + + /* copy data length to guest */ + EU_CHKN( copy_to_current_guest( vcpu, numbytes_addr, &numbytes, sizeof(numbytes))); + + ret = 0; + out: + return ret; +} + +/* Local Variables: */ +/* mode:c */ +/* indent-tabs-mode:'t */ +/* c-basic-offset:8 */ +/* End: */ diff --git a/xmhf-64/hypapps/trustvisor/src/hptw_emhf.c b/xmhf-64/hypapps/trustvisor/src/hptw_emhf.c new file mode 100644 index 0000000000..6eaf40874a --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/hptw_emhf.c @@ -0,0 +1,179 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include +#include +#include + +static hpt_pa_t hptw_emhf_host_ctx_ptr2pa(void *vctx, void *ptr) +{ + (void)vctx; + return hva2spa(ptr); +} + +static void* hptw_emhf_host_ctx_pa2ptr(void *vctx, hpt_pa_t spa, size_t sz, hpt_prot_t access_type, hptw_cpl_t cpl, size_t *avail_sz) +{ + (void)vctx; + (void)access_type; + (void)cpl; + *avail_sz = sz; + return spa2hva(spa); +} + +static void* hptw_emhf_host_ctx_gzp(void *vctx, size_t alignment, size_t sz) +{ + hptw_emhf_host_ctx_t *ctx = vctx; + pagelist_t *pl = ctx->pl; + HALT_ON_ERRORCOND(PAGE_SIZE_4K % alignment == 0); + HALT_ON_ERRORCOND(sz <= PAGE_SIZE_4K); + return pagelist_get_zeroedpage(pl); +} + +/* Context for EPT paging */ +int hptw_emhf_host_ctx_init(hptw_emhf_host_ctx_t *ctx, hpt_pa_t root_pa, hpt_type_t t, pagelist_t *pl) +{ + *ctx = (hptw_emhf_host_ctx_t) { + .super = (hptw_ctx_t) { + .ptr2pa = hptw_emhf_host_ctx_ptr2pa, + .pa2ptr = hptw_emhf_host_ctx_pa2ptr, + .gzp = hptw_emhf_host_ctx_gzp, + .root_pa = root_pa, + .t = t, + }, + .pl = pl, + }; + return 0; +} + +static hpt_pa_t hptw_emhf_checked_guest_ctx_ptr2pa(void __attribute__((unused)) *ctx, void *ptr) +{ + return hva2gpa(ptr); +} + +static void* hptw_emhf_checked_guest_ctx_pa2ptr(void *vctx, hpt_pa_t gpa, size_t sz, hpt_prot_t access_type, hptw_cpl_t cpl, size_t *avail_sz) +{ + hptw_emhf_checked_guest_ctx_t *ctx = vctx; + HALT_ON_ERRORCOND(ctx); + + return hptw_checked_access_va(&ctx->hptw_host_ctx.super, + access_type, + cpl, + gpa, + sz, + avail_sz); +} + +static void* hptw_emhf_checked_guest_ctx_gzp(void *vctx, size_t alignment, size_t sz) +{ + hptw_emhf_checked_guest_ctx_t *ctx = vctx; + pagelist_t *pl = ctx->pl; + HALT_ON_ERRORCOND(PAGE_SIZE_4K % alignment == 0); + HALT_ON_ERRORCOND(sz <= PAGE_SIZE_4K); + return pagelist_get_zeroedpage(pl); +} + +/* Context for guest paging (e.g. guest CR3) */ +int hptw_emhf_checked_guest_ctx_init(hptw_emhf_checked_guest_ctx_t *ctx, + hpt_pa_t root_pa, + hpt_type_t t, + hptw_cpl_t cpl, + const hptw_emhf_host_ctx_t *host_ctx, + pagelist_t *pl) +{ + /* FIXME: check that guest root is accessible in host pts here? */ + + *ctx = (hptw_emhf_checked_guest_ctx_t) { + .super = (hptw_ctx_t) { + .ptr2pa = hptw_emhf_checked_guest_ctx_ptr2pa, + .pa2ptr = hptw_emhf_checked_guest_ctx_pa2ptr, + .gzp = hptw_emhf_checked_guest_ctx_gzp, + + .root_pa = root_pa, + .t = t, + }, + .cpl = cpl, + .hptw_host_ctx = *host_ctx, + .pl = pl, + }; + + return 0; +} + +int hptw_emhf_host_ctx_init_of_vcpu(hptw_emhf_host_ctx_t *rv, VCPU *vcpu) +{ + hpt_pa_t root_pa; + hpt_type_t t; + + t = hpt_emhf_get_hpt_type( vcpu); + root_pa = hva2spa( hpt_emhf_get_root_pm( vcpu)); + + hptw_emhf_host_ctx_init( rv, root_pa, t, NULL); + return 0; +} + +/* static int construct_checked_walk_ctx(VCPU *vcpu, checked_guest_walk_ctx_t *rv) */ +int hptw_emhf_checked_guest_ctx_init_of_vcpu(hptw_emhf_checked_guest_ctx_t *rv, VCPU *vcpu) +{ + int err=1; + hptw_emhf_host_ctx_t host_ctx; + hpt_pa_t root_pa; + hpt_type_t t; + + root_pa = hpt_emhf_get_guest_root_pm_pa( vcpu); + t = hpt_emhf_get_guest_hpt_type( vcpu); + + EU_CHKN( hptw_emhf_host_ctx_init_of_vcpu( &host_ctx, vcpu)); + EU_CHKN( hptw_emhf_checked_guest_ctx_init( rv, + root_pa, + t, + HPTW_CPL3, /* FIXME - extract cpl from vcpu */ + &host_ctx, + NULL)); + + err = 0; + out: + return err; +} diff --git a/xmhf-64/hypapps/trustvisor/src/include/crypto_init.h b/xmhf-64/hypapps/trustvisor/src/include/crypto_init.h new file mode 100644 index 0000000000..314d9f4beb --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/include/crypto_init.h @@ -0,0 +1,71 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef _CRYPTO_INIT_H_ +#define _CRYPTO_INIT_H_ + +#include + +#define CTR_DRBG_SEED_BITS 256 +#define CTR_DRBG_NONCE_BITS 64 + +extern bool g_master_prng_init_completed; +extern bool g_master_crypto_init_completed; +extern bool g_nvenforce; +extern uint8_t g_nvpalpcr0[20]; + +extern NIST_CTR_DRBG g_drbg; + +int get_hw_tpm_entropy(uint8_t* buf, unsigned int requested_len /* bytes */); +int trustvisor_master_crypto_init(void); + +#endif /* _CRYPTO_INIT_H_ */ + +/* Local Variables: */ +/* mode:c */ +/* indent-tabs-mode:nil */ +/* c-basic-offset:2 */ +/* End: */ diff --git a/xmhf-64/hypapps/trustvisor/src/include/hc_utpm.h b/xmhf-64/hypapps/trustvisor/src/include/hc_utpm.h new file mode 100644 index 0000000000..2eb76c77a0 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/include/hc_utpm.h @@ -0,0 +1,62 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef _PAL_UTPM_H_ +#define _PAL_UTPM_H_ + +/* PAL uTPM operations */ +uint32_t hc_utpm_seal(VCPU * vcpu, uint32_t input_addr, uint32_t input_len, uint32_t tpmPcrInfo_addr, uint32_t output_addr, uint32_t output_len_addr); +uint32_t hc_utpm_unseal(VCPU * vcpu, uint32_t input_addr, uint32_t input_len, uint32_t output_addr, uint32_t output_len_addr, uint32_t digestAtCreation_addr); +u32 hc_utpm_seal_deprecated(VCPU * vcpu, u32 input_addr, u32 input_len, u32 pcrAtRelease_addr, u32 output_addr, u32 output_len_addr); +u32 hc_utpm_unseal_deprecated(VCPU * vcpu, u32 input_addr, u32 input_len, u32 output_addr, u32 output_len_addr); +u32 hc_utpm_quote_deprecated(VCPU * vcpu, u32 nonce_addr, u32 tpmsel_addr, u32 out_addr, u32 out_len_addr); +u32 hc_utpm_quote(VCPU * vcpu, u32 nonce_addr, u32 tpmsel_addr, u32 out_addr, u32 out_len_addr, u32 pcrComp_addr, u32 pcrCompLen_addr); +uint32_t hc_utpm_utpm_id_getpub(VCPU * vcpu, gva_t dst_gva, gva_t dst_sz_gva); +u32 hc_utpm_pcrread(VCPU * vcpu, u32 gvaddr, u32 num); +u32 hc_utpm_pcrextend(VCPU * vcpu, u32 idx, u32 meas_gvaddr); +u32 hc_utpm_rand(VCPU * vcpu, u32 buffer_addr, u32 numbytes_addr); + +#endif /* _PAL_UTPM_H_ */ diff --git a/xmhf-64/hypapps/trustvisor/src/include/hptw_emhf.h b/xmhf-64/hypapps/trustvisor/src/include/hptw_emhf.h new file mode 100644 index 0000000000..df36bdc2fc --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/include/hptw_emhf.h @@ -0,0 +1,78 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef HPTW_EMHF_H +#define HPTW_EMHF_H + +#include +#include +#include + +typedef struct { + hptw_ctx_t super; + + pagelist_t *pl; +} hptw_emhf_host_ctx_t; +int hptw_emhf_host_ctx_init(hptw_emhf_host_ctx_t *ctx, hpt_pa_t root_pa, hpt_type_t t, pagelist_t *pl); +int hptw_emhf_host_ctx_init_of_vcpu(hptw_emhf_host_ctx_t *rv, VCPU *vcpu); + +typedef struct { + hptw_ctx_t super; + + hptw_cpl_t cpl; + + hptw_emhf_host_ctx_t hptw_host_ctx; + pagelist_t *pl; +} hptw_emhf_checked_guest_ctx_t; +int hptw_emhf_checked_guest_ctx_init(hptw_emhf_checked_guest_ctx_t *ctx, + hpt_pa_t root_pa, + hpt_type_t t, + hptw_cpl_t cpl, + const hptw_emhf_host_ctx_t *host_ctx, + pagelist_t *pl); +int hptw_emhf_checked_guest_ctx_init_of_vcpu(hptw_emhf_checked_guest_ctx_t *rv, VCPU *vcpu); + +#endif diff --git a/xmhf-64/hypapps/trustvisor/src/include/malloc.h b/xmhf-64/hypapps/trustvisor/src/include/malloc.h new file mode 100644 index 0000000000..904621d341 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/include/malloc.h @@ -0,0 +1,60 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef _HEAPMEM_H_ +#define _HEAPMEM_H_ + +#define HEAPMEM_POOLSIZE (4*(1<<20)) + +void *malloc(size_t); +void *calloc(size_t nmemb, size_t size); +void *realloc(void *ptr, size_t size); +void free(void *); + +void mem_init(void); +size_t heapmem_get_used_size(void); + +#endif diff --git a/xmhf-64/hypapps/trustvisor/src/include/nv.h b/xmhf-64/hypapps/trustvisor/src/include/nv.h new file mode 100644 index 0000000000..276b4248ea --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/include/nv.h @@ -0,0 +1,77 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef _NV_H_ +#define _NV_H_ + +/* Currently this file depends on tpm.h having been included earlier + * (for tpm_nv_index_t). Given that there are also such dependencies + * for uint32_t, VCPU, etc., I choose to do nothing in here. */ + +/* TODO: Make the index a boot-time parameter with a sane default */ +#define HW_TPM_MASTER_SEALING_SECRET_INDEX 0x00015213 +#define HW_TPM_MASTER_SEALING_SECRET_SIZE 20 +/* TODO: Make this a build-time config option */ +#define HALT_UPON_NV_PROBLEM 0 + +/* Use Locality 2 for hardware TPM operations involving NV RAM */ +#define TRUSTVISOR_HWTPM_NV_LOCALITY 2 + +#define HW_TPM_ROLLBACK_PROT_INDEX 0x00014E56 /* "NV" */ +#define HW_TPM_ROLLBACK_PROT_SIZE 32 /* SHA-256 */ + +int validate_trustvisor_nv_region(unsigned int locality, + tpm_nv_index_t idx, + unsigned int expected_size); + +int trustvisor_nv_get_mss(unsigned int locality, uint32_t idx, + uint8_t *mss, unsigned int mss_size); + +uint32_t hc_tpmnvram_getsize(VCPU* vcpu, uint32_t size_addr); +uint32_t hc_tpmnvram_readall(VCPU* vcpu, uint32_t out_addr); +uint32_t hc_tpmnvram_writeall(VCPU* vcpu, uint32_t in_addr); + +#endif /* _NV_H_ */ diff --git a/xmhf-64/hypapps/trustvisor/src/include/pages.h b/xmhf-64/hypapps/trustvisor/src/include/pages.h new file mode 100644 index 0000000000..2fd8df1849 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/include/pages.h @@ -0,0 +1,64 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef PAGES_H +#define PAGES_H + +#include + +typedef struct { + void *buf; + void *page_base; + size_t num_allocd; + size_t num_used; +} pagelist_t; + +void pagelist_init(pagelist_t *pl); +void* pagelist_get_page(pagelist_t *pl); +void* pagelist_get_zeroedpage(pagelist_t *pl); +void pagelist_free_all(pagelist_t *pl); + +#endif diff --git a/xmhf-64/hypapps/trustvisor/src/include/random.h b/xmhf-64/hypapps/trustvisor/src/include/random.h new file mode 100644 index 0000000000..fb3477ce12 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/include/random.h @@ -0,0 +1,63 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef _RANDOM_H_ +#define _RANDOM_H_ + +#include +#include + +/* interface exposed to the rest of TrustVisor */ +uint8_t rand_byte_or_die(void); +void rand_bytes_or_die(uint8_t *out, unsigned int len); +int rand_bytes(uint8_t *out, unsigned int *len); + +/* libtomcrypt prng. this is just a wrapper for our internal drbg */ +extern const struct ltc_prng_descriptor tv_sprng_desc; +extern prng_state g_ltc_prng; +extern int g_ltc_prng_id; + +#endif /* _RANDOM_H_ */ diff --git a/xmhf-64/hypapps/trustvisor/src/include/scode.h b/xmhf-64/hypapps/trustvisor/src/include/scode.h new file mode 100644 index 0000000000..dbb026ad63 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/include/scode.h @@ -0,0 +1,194 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* scode.h - Module specific definitions + * Written for TrustVisor by Ning Qu and Mark Luk + * Edited by Zongwei Zhou for EMHF project + */ + +#ifndef __SCODE_H_ +#define __SCODE_H_ + +#include + +#include + +#include +#include +#include /* formerly utpm.h */ + +#include + +#include +#include +#include /* from libemhfutil */ +#include + +/* XXX TEMP */ +#define CHK(x) HALT_ON_ERRORCOND(x) +#define CHK_RV(x) HALT_ON_ERRORCOND(!(x)) + +/* + * definition for scode whitelist + * */ +/* in order to support 4GB memory */ +#define PFN_BITMAP_LIMIT 512*1024 +#define PFN_BITMAP_2M_LIMIT 2*1024 + +/* TODO: separate perf ctrs from scode.* */ +extern perf_ctr_t g_tv_perf_ctrs[]; +extern char *g_tv_perf_ctr_strings[]; +#define TV_PERF_CTR_NPF 0 +#define TV_PERF_CTR_SWITCH_SCODE 1 +#define TV_PERF_CTR_SWITCH_REGULAR 2 +#define TV_PERF_CTR_SAFEMALLOC 3 +#define TV_PERF_CTR_MARSHALL 4 +#define TV_PERF_CTR_EXPOSE_ARCH 5 +#define TV_PERF_CTR_NESTED_SWITCH_SCODE 6 +/* insert new counters here, and update count below */ +#define TV_PERF_CTRS_COUNT 7 + +typedef struct { + hpt_va_t reg_gva; + hpt_va_t pal_gva; + size_t size; + hpt_prot_t pal_prot; + hpt_prot_t reg_prot; + u32 section_type; +} tv_pal_section_int_t; + +/* scode state struct */ +typedef struct whitelist_entry{ + u64 gcr3; + u32 id; + u32 g64; /* whether running in 64-bit mode */ + uintptr_t grsp; /* guest reguar stack */ + uintptr_t gssp; /* guest sensitive code stack */ + uintptr_t gss_size; /* guest sensitive code stack page number */ + uintptr_t entry_v; /* entry point virtual address */ + uintptr_t entry_p; /* entry point physical address */ + uintptr_t return_v; /* return point virtual address */ + + uintptr_t gpmp; /* guest parameter page address */ + uintptr_t gpm_size; /* guest parameter page number */ + u64 gpm_num; /* guest parameter number */ + + u32 saved_exception_intercepts; + + tv_pal_section_int_t sections[TV_MAX_SECTIONS]; + size_t sections_num; + + struct tv_pal_sections scode_info; /* scode_info struct for registration function inpu */ + struct tv_pal_params params_info; /* param info struct */ + pte_t* scode_pages; /* registered pte's (copied from guest page tables and additional info added) */ + + pte_t * pte_page; /* holder for guest page table entry to access scode and GDT */ +//#ifdef __MP_VERSION__ + u32 pal_running_lock; /* PAL running lock */ + u32 pal_running_vcpu_id; /* the cpu that is running this PAL */ +//#endif + + /* Micro-TPM related */ + utpm_master_state_t utpm; + + /* pal page tables */ + pagelist_t *gpl; + pagelist_t *npl; + hptw_emhf_host_ctx_t hptw_pal_host_ctx; + hptw_emhf_checked_guest_ctx_t hptw_pal_checked_guest_ctx; + + hpt_pa_t reg_gpt_root_pa; + hpt_type_t reg_gpt_type; + + u64 pal_gcr3; +} __attribute__ ((packed)) whitelist_entry_t; + +/* max size of memory that holds scode state */ +#define WHITELIST_LIMIT (sizeof(whitelist_entry_t)*100) + +/* nested paging handlers (hpt) */ +hpt_prot_t pal_prot_of_type(int type); +hpt_prot_t reg_prot_of_type(int type); + +/* operations from hypervisor to guest paging */ +int copy_from_current_guest(VCPU * vcpu, void *dst, gva_t gvaddr, size_t len); + +int copy_to_current_guest(VCPU * vcpu, gva_t gvaddr, void *src, size_t len); + +/* PAL operations (HPT) */ +u32 hpt_scode_switch_scode(VCPU * vcpu, struct regs *r); +u32 hpt_scode_switch_regular(VCPU * vcpu); +u32 hpt_scode_npf(VCPU * vcpu, uintptr_t gpaddr, u64 errorcode, struct regs *r); +u32 scode_share(VCPU * vcpu, u32 scode_entry, u32 addr, u32 len); +u32 scode_share_ranges(VCPU * vcpu, u32 scode_entry, u32 gva_base[], u32 gva_len[], u32 count); + +u64 scode_register(VCPU * vcpu, u64 scode_info, u64 scode_pm, u64 gventry); +u64 scode_unregister(VCPU * vcpu, u64 gvaddr); +void init_scode(VCPU * vcpu); + +void scode_lend_section( hptw_ctx_t *reg_npm_ctx, + hptw_ctx_t *reg_gpm_ctx, + hptw_ctx_t *pal_npm_ctx, + hptw_ctx_t *pal_gpm_ctx, + const tv_pal_section_int_t *section); +void scode_return_section( hptw_ctx_t *reg_npm_ctx, + hptw_ctx_t *pal_npm_ctx, + hptw_ctx_t *pal_gpm_ctx, + const tv_pal_section_int_t *section); + +int scode_clone_gdt(VCPU *vcpu, + gva_t gdtr_base, size_t gdtr_lim, + hptw_ctx_t *pal_gpm_ctx, + pagelist_t *pl + ); + +#endif /* __SCODE_H_ */ + +/* Local Variables: */ +/* mode:c */ +/* indent-tabs-mode:nil */ +/* c-basic-offset:2 */ +/* End: */ diff --git a/xmhf-64/hypapps/trustvisor/src/include/tlsf.h b/xmhf-64/hypapps/trustvisor/src/include/tlsf.h new file mode 100644 index 0000000000..bfe40aaa9b --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/include/tlsf.h @@ -0,0 +1,53 @@ +#ifndef INCLUDED_tlsf +#define INCLUDED_tlsf + +/* +** Two Level Segregated Fit memory allocator, version 1.9. +** Written by Matthew Conte, and placed in the Public Domain. +** http://tlsf.baisoku.org +** +** Based on the original documentation by Miguel Masmano: +** http://rtportal.upv.es/rtmalloc/allocators/tlsf/index.shtml +** +** Please see the accompanying Readme.txt for implementation +** notes and caveats. +** +** This implementation was written to the specification +** of the document, therefore no GPL restrictions apply. +*/ + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Create/destroy a memory pool. */ +typedef void* tlsf_pool; +tlsf_pool tlsf_create(void* mem, size_t bytes); +void tlsf_destroy(tlsf_pool pool); + +/* malloc/memalign/realloc/free replacements. */ +void* tlsf_malloc(tlsf_pool pool, size_t bytes); +void* tlsf_memalign(tlsf_pool pool, size_t align, size_t bytes); +void* tlsf_realloc(tlsf_pool pool, void* ptr, size_t size); +void tlsf_free(tlsf_pool pool, void* ptr); + +/* Debugging. */ +typedef void (*tlsf_walker)(void* ptr, size_t size, int used, void* user); +void tlsf_walk_heap(tlsf_pool pool, tlsf_walker walker, void* user); +/* Returns nonzero if heap check fails. */ +int tlsf_check_heap(tlsf_pool pool); + +/* Returns internal block size, not original request size */ +size_t tlsf_block_size(void* ptr); + +/* Overhead of per-pool internal structures. */ +size_t tlsf_overhead(void); + +#if defined(__cplusplus) +}; +#endif + +#endif diff --git a/xmhf-64/hypapps/trustvisor/src/include/tlsfbits.h b/xmhf-64/hypapps/trustvisor/src/include/tlsfbits.h new file mode 100644 index 0000000000..3e5c82af24 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/include/tlsfbits.h @@ -0,0 +1,180 @@ +#ifndef INCLUDED_tlsfbits +#define INCLUDED_tlsfbits + +#if defined(__cplusplus) +#define tlsf_decl inline +#else +#define tlsf_decl static +#endif + +/* +** Architecture-specific bit manipulation routines. +** +** TLSF achieves O(1) cost for malloc and free operations by limiting +** the search for a free block to a free list of guaranteed size +** adequate to fulfill the request, combined with efficient free list +** queries using bitmasks and architecture-specific bit-manipulation +** routines. +** +** Most modern processors provide instructions to count leading zeroes +** in a word, find the lowest and highest set bit, etc. These +** specific implementations will be used when available, falling back +** to a reasonably efficient generic implementation. +** +** NOTE: TLSF spec relies on ffs/fls returning value 0..31. +** ffs/fls return 1-32 by default, returning 0 for error. +*/ + +/* +** Detect whether or not we are building for a 32- or 64-bit (LP/LLP) +** architecture. There is no reliable portable method at compile-time. +*/ +#if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) \ + || defined (_WIN64) || defined (__LP64__) || defined (__LLP64__) +#define TLSF_64BIT +#endif + +/* +** gcc 3.4 and above have builtin support, specialized for architecture. +** Some compilers masquerade as gcc; patchlevel test filters them out. +*/ +#if defined (__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) \ + && defined (__GNUC_PATCHLEVEL__) + +tlsf_decl int tlsf_ffs(unsigned int word) +{ + return __builtin_ffs(word) - 1; +} + +tlsf_decl int tlsf_fls(unsigned int word) +{ + const int bit = word ? 32 - __builtin_clz(word) : 0; + return bit - 1; +} + +#elif defined (_MSC_VER) && defined (_M_IX86) && (_MSC_VER >= 1400) +/* Microsoft Visual C++ 2005 support on x86 architectures. */ + +#include + +#pragma intrinsic(_BitScanReverse) +#pragma intrinsic(_BitScanForward) + +tlsf_decl int tlsf_fls(unsigned int word) +{ + unsigned long index; + return _BitScanReverse(&index, word) ? index : -1; +} + +tlsf_decl int tlsf_ffs(unsigned int word) +{ + unsigned long index; + return _BitScanForward(&index, word) ? index : -1; +} + +#elif defined (_MSC_VER) && defined (_M_PPC) +/* Microsoft Visual C++ support on PowerPC architectures. */ + +#include + +tlsf_decl int tlsf_fls(unsigned int word) +{ + const int bit = 32 - _CountLeadingZeros(word); + return bit - 1; +} + +tlsf_decl int tlsf_ffs(unsigned int word) +{ + const unsigned int reverse = word & (~word + 1); + const int bit = 32 - _CountLeadingZeros(reverse); + return bit - 1; +} + +#elif defined (__ARMCC_VERSION) +/* RealView Compilation Tools for ARM */ + +tlsf_decl int tlsf_ffs(unsigned int word) +{ + const unsigned int reverse = word & (~word + 1); + const int bit = 32 - __clz(reverse); + return bit - 1; +} + +tlsf_decl int tlsf_fls(unsigned int word) +{ + const int bit = word ? 32 - __clz(word) : 0; + return bit - 1; +} + +#elif defined (__ghs__) +/* Green Hills support for PowerPC */ + +#include + +tlsf_decl int tlsf_ffs(unsigned int word) +{ + const unsigned int reverse = word & (~word + 1); + const int bit = 32 - __CLZ32(reverse); + return bit - 1; +} + +tlsf_decl int tlsf_fls(unsigned int word) +{ + const int bit = word ? 32 - __CLZ32(word) : 0; + return bit - 1; +} + +#else +/* Fall back to generic implementation. */ + +tlsf_decl int tlsf_fls_generic(unsigned int word) +{ + int bit = 32; + + if (!word) bit -= 1; + if (!(word & 0xffff0000)) { word <<= 16; bit -= 16; } + if (!(word & 0xff000000)) { word <<= 8; bit -= 8; } + if (!(word & 0xf0000000)) { word <<= 4; bit -= 4; } + if (!(word & 0xc0000000)) { word <<= 2; bit -= 2; } + if (!(word & 0x80000000)) { word <<= 1; bit -= 1; } + + return bit; +} + +/* Implement ffs in terms of fls. */ +tlsf_decl int tlsf_ffs(unsigned int word) +{ + return tlsf_fls_generic(word & (~word + 1)) - 1; +} + +tlsf_decl int tlsf_fls(unsigned int word) +{ + return tlsf_fls_generic(word) - 1; +} + +#endif + +/* Possibly 64-bit version of tlsf_fls. */ +#if defined (TLSF_64BIT) +tlsf_decl int tlsf_fls_sizet(size_t size) +{ + int high = (int)(size >> 32); + int bits = 0; + if (high) + { + bits = 32 + tlsf_fls(high); + } + else + { + bits = tlsf_fls((int)size & 0xffffffff); + + } + return bits; +} +#else +#define tlsf_fls_sizet tlsf_fls +#endif + +#undef tlsf_decl + +#endif diff --git a/xmhf-64/hypapps/trustvisor/src/include/trustvisor.h b/xmhf-64/hypapps/trustvisor/src/include/trustvisor.h new file mode 100644 index 0000000000..ba5756caf0 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/include/trustvisor.h @@ -0,0 +1,135 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef TRUSTVISOR_H +#define TRUSTVISOR_H + +/* + * Hyper-Call constants + */ +enum HCcmd { + /* pal manipulation ops */ + TV_HC_REG =1, + TV_HC_UNREG =2, + TV_HC_SHARE =6, + + /* uTPM ops */ + TV_HC_UTPM_SEAL_DEPRECATED =3, + TV_HC_UTPM_UNSEAL_DEPRECATED =4, + TV_HC_UTPM_QUOTE_DEPRECATED =5, + TV_HC_UTPM_PCRREAD =7, + TV_HC_UTPM_PCREXT =8, + TV_HC_UTPM_GENRAND =9, + TV_HC_UTPM_SEAL =10, + TV_HC_UTPM_UNSEAL =11, + TV_HC_UTPM_QUOTE =12, + TV_HC_UTPM_ID_GETPUB =13, + /* Reserving up through 20 for more UTPM stuff; don't touch! */ + + /* These are privileged commands; only a special PAL can use them */ + TV_HC_TPMNVRAM_GETSIZE = 21, + TV_HC_TPMNVRAM_READALL = 22, + TV_HC_TPMNVRAM_WRITEALL = 23, + + /* misc */ + TV_HC_TEST =255, +}; + +/* + * structs for pal-registration descriptor + */ + +enum tv_pal_section_type { + TV_PAL_SECTION_CODE =1, + TV_PAL_SECTION_DATA =2, + TV_PAL_SECTION_PARAM =3, + TV_PAL_SECTION_STACK =4, + TV_PAL_SECTION_SHARED_CODE =5, + + /* for internal use. */ + TV_PAL_SECTION_SHARED =6, + TV_PAL_SECTION_GUEST_PAGE_TABLES =7, +}; + +struct tv_pal_section { + enum tv_pal_section_type type; + uint32_t page_num; /* size of section in pages */ + uint64_t start_addr; +} __attribute__((packed)); + +#define TV_MAX_SECTIONS 10 /* max sections that are allowed in pal registration */ +struct tv_pal_sections { + uint32_t num_sections; + uint32_t :32; /* Padding */ + struct tv_pal_section sections[TV_MAX_SECTIONS]; +} __attribute__((packed)); + +/* parameter type */ +enum tv_pal_param_type { + TV_PAL_PM_INTEGER =1, + TV_PAL_PM_POINTER =2, +}; + +struct tv_pal_param { + enum tv_pal_param_type type; /* 1: integer ; 2:pointer*/ + uint32_t :32; /* Padding */ + uint64_t size; +} __attribute__((packed)); + +#define TV_MAX_PARAMS 10 +struct tv_pal_params { + uint32_t num_params; + uint32_t :32; /* Padding */ + struct tv_pal_param params[TV_MAX_PARAMS]; +} __attribute__((packed)); + +#endif + +/* Local Variables: */ +/* mode:c */ +/* indent-tabs-mode:nil */ +/* c-basic-offset:2 */ +/* End: */ diff --git a/xmhf-64/hypapps/trustvisor/src/include/tv_emhf.h b/xmhf-64/hypapps/trustvisor/src/include/tv_emhf.h new file mode 100644 index 0000000000..e43a78c49a --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/include/tv_emhf.h @@ -0,0 +1,61 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef TV_EMHF_H +#define TV_EMHF_H + +#include + +u32 tv_app_main(VCPU *vcpu, APP_PARAM_BLOCK *apb); +u32 tv_app_handlehypercall(VCPU *vcpu, struct regs *r); +u32 tv_app_handlemtrr(VCPU *vcpu, u32 msr, u64 val); +u32 tv_app_handleintercept_hwpgtblviolation(VCPU *vcpu, + struct regs *r, u64 gpa, u64 gva, u64 violationcode); +u32 tv_app_handleintercept_portaccess(VCPU *vcpu, struct regs *r, + u32 portnum, u32 access_type, u32 access_size); +void tv_app_handleshutdown(VCPU *vcpu, struct regs *r); + +#endif diff --git a/xmhf-64/hypapps/trustvisor/src/include/tv_log.h b/xmhf-64/hypapps/trustvisor/src/include/tv_log.h new file mode 100644 index 0000000000..9d2f757f65 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/include/tv_log.h @@ -0,0 +1,61 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef TV_LOG_H +#define TV_LOG_H + +#ifndef EU_LOG_LVL +#define EU_LOG_LVL EU_TRACE +#endif + +#ifndef EU_LOG_PREFIX +#define EU_LOG_PREFIX "TV" +#endif + +#include +#include + +#endif diff --git a/xmhf-64/hypapps/trustvisor/src/linuxrelc.c b/xmhf-64/hypapps/trustvisor/src/linuxrelc.c new file mode 100644 index 0000000000..372747f10f --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/linuxrelc.c @@ -0,0 +1,259 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// linuxrelc.c +// linux kernel/initrd relocate and bootstrap +// author: amit vasudevan (amitvasudevan@acm.org) + +#include + +/* + grub_debug + linux_data_real_addr=0x00090000 + LINUX_BZIMAGE_ADDR=0x00100000 + lh->version=0x020a + lh->heap_end_ptr=0x8e00; + lh->loadflags=0x81 + lh->cmd_line_ptr=0x00099000 + setup size=0x3400; + system size = 0x3384c0 + initrd size = 0xd1e47c + initrd base= 0x372d1000 + + +*/ + +// setup header for the Linux/i386 boot protocol version 2.04 +// requires kernel version 2.6.14 or later. starts at offset 0x1f1 +// in the kernel image. + +#define OFFSET 0x1f1 //offset of setup header in setup code +#define SECTOR_SIZE 512 //size of a disk sector +#define HEADER 0x53726448 //linux kernel magic header +#define MIN_BOOTPROTO_VER 0x0204 //minimum boot-protocol version we support is 2.04 +#define SETUP_RELOCATE 0x10000 //physical memory address where setup code goes +#define SYSTEM_RELOCATE 0x100000 //physical memory address where 32-bit kernel goes + +//we assume guest to be allocated 1GB (1024M) of physical memory +//we further assume that initrd/initramfs does not exceed 48M in size +//#define INITRD_RELOCATE 0x372d1000 //1GB - 48M +#define INITRD_RELOCATE 0x4000000 +//#define INITRD_MAXADDR 0x37ffffff +#define INITRD_MAXADDR 0x4FFFFFF + +#define NORMAL 0xffff //vga mode +#define OTHER 0xff //bootloader type +#define CAN_USE_HEAP 0x81 //loadflag to indicate that heap is usable + +//kernel command line to be passed +//char linux_kernel_cmdline[] = "ro root=/dev/sda8 resume=/dev/sda10 maxcpus=1 mem=1024M no_console_suspend earlyprintk=1"; +char linux_kernel_cmdline[] = "ro root=/dev/sda2 maxcpus=1 mem=1024M"; + +struct linux_setup_header { + u8 setup_sects; + u16 root_flags; + u32 syssize; + u16 ramsize; + u16 vid_mode; + u16 root_dev; + u16 boot_flag; + u16 jump; + u32 header; + u16 version; + u32 realmode_switch; + u16 start_sys; + u16 kernel_version; + u8 type_of_loader; + u8 loadflags; + u16 setup_move_size; + u32 code32_start; + u32 ramdisk_image; + u32 ramdisk_size; + u32 bootsect_kludge; + u16 heap_end_ptr; + u16 pad1; + u32 cmd_line_ptr; + u32 initrd_addr_max; +} __attribute__ ((packed)); + + +/* +void linux_store_setupandinitrd(u32 setupbase, u32 setupsize, u32 initrdbase, + u32 initrdsize, char *cmdline_untrusted, char *cmdline_trusted){ + extern u32 __linux_setup_image[], __linux_initrd_image[]; + extern u32 __linux_kernel_cmdline_untrusted[], __linux_kernel_cmdline_trusted[]; + + HALT_ON_ERRORCOND(setupsize < __LINUX_OS_SETUP_SIZE); + HALT_ON_ERRORCOND(initrdsize < __LINUX_OS_INITRD_SIZE); + + memcpy((void *)__linux_setup_image, setupbase, setupsize); + memcpy((void *)__linux_initrd_image, initrdbase, initrdsize); + strncpy((char *)__linux_kernel_cmdline_untrusted, cmdline_untrusted, (u32)256); + strncpy((char *)__linux_kernel_cmdline_trusted, cmdline_trusted, (u32)256); + +}*/ + +//---relocate linux kernel +//void relocate_kernel(u32 setupbase, u32 setupsize, u32 initrdbase, u32 initrdsize){ +void relocate_kernel(uintptr_t vmlinuz_base, uintptr_t vmlinuz_size, + uintptr_t initrd_base, uintptr_t initrd_size){ + + struct linux_setup_header *h; + uintptr_t setup_size, setup_base= SETUP_RELOCATE; + uintptr_t system_size, system_base = SYSTEM_RELOCATE; + + //initialize linux kernel header located at OFFSET from vmlinuz_base + h = (struct linux_setup_header*)(vmlinuz_base + OFFSET); + + //some sanity checks + if ( (h->header != HEADER) ){ + printf("\nHeader mismatch. Halting"); + HALT(); + } + if ( (h->version < MIN_BOOTPROTO_VER) ){ + printf("\nBoot-protocol version mismatch. Halting!"); + HALT(); + } + + //determine "setup" size + //the "setup" code executes in real mode. all of the setup (code, + //header, command line, heap, and stack) is designed to occupy one + //segment (64K). + //offset 0x0000 - 0x7fff: setup code and header + //offset 0x8000 - 0x8fff: stack and heap + //offset 0x9000 - 0x90ff: command line + + if ( h->setup_sects == 0 ) + setup_size = 4; + else + setup_size = h->setup_sects + 1; + setup_size *= SECTOR_SIZE; + + HALT_ON_ERRORCOND(setup_size < (64*1024) ); //setup_size _MUST_ be within 64K + printf("\n setup at 0x%08x, size=0x%08x", setup_base, setup_size); + + //copy 16-bit setup code to setup_base + memcpy((void *)setup_base, (void *)(vmlinuz_base), setup_size); + + //determine "system" size + system_size = vmlinuz_size - setup_size; + printf("\n system at 0x%08x, size=0x%08x", system_base, system_size); + + //copy 32-bit kernel code to system_base i.e 0x100000 (1MB) + memcpy((void *)system_base, (void*)(vmlinuz_base + setup_size), system_size); + + + printf("\n initrd at 0x%08x, size=0x%08x", INITRD_RELOCATE, initrd_size); + + //copy initrd + memcpy((void*)INITRD_RELOCATE, (void*)initrd_base, initrd_size); + + //copy the kernel command line to offset 0x9000. max size of command line is + //255 bytes, excluding the trailing '\0' + memset((void *)(setup_base+0x9000), 0, 256); + memcpy((void *)(setup_base+0x9000), &linux_kernel_cmdline, sizeof(linux_kernel_cmdline)); + printf("\n cmdline at 0x%08x, size=%u bytes", (setup_base+0x9000), sizeof(linux_kernel_cmdline)); + + //re-initialize linux kernel header pointer to the new setup code + //at setup_base + h = (struct linux_setup_header*)(setup_base + OFFSET); + + //write location of command line in setup header. note that command line + //is at physical address 0x19000 and thus will not get overwritten when + //setup relocates itself to 0x90000 + h->cmd_line_ptr = (u32)(setup_base + 0x9000); + + //write location and size of initrd in setup header + h->ramdisk_image = INITRD_RELOCATE; + h->ramdisk_size = initrd_size; + h->initrd_addr_max = INITRD_MAXADDR; + + // initialize other required fields of the setup header + // see Documentation/x86/boot.txt for details + h->vid_mode = (u16)NORMAL; + h->type_of_loader = (u8)OTHER; + + //offset limit of heap in real mode segment. leave space for a + //512 byte stack at the end of heap, as recommended by + //Documentation/x86/boot.txt. + h->heap_end_ptr = (u16)(0x9000 - 0x200); + h->loadflags = (u8)CAN_USE_HEAP; + + if( h->setup_sects == 0) + h->setup_sects = 4; + + return; +} + +//---setuplinuxboot +void setuplinuxboot(VCPU *vcpu, uintptr_t vmlinuz_base, uintptr_t vmlinuz_size, + uintptr_t initrd_base, uintptr_t initrd_size){ + + + relocate_kernel(vmlinuz_base, vmlinuz_size, initrd_base, initrd_size); + printf("\nCPU(0x%02x): relocated and setup linux kernel...", vcpu->id); + + //setup VMCS for linux real-mode setup code + vcpu->vmcs.guest_DS_selector = 0x1000; + vcpu->vmcs.guest_DS_base = vcpu->vmcs.guest_DS_selector * 16; + vcpu->vmcs.guest_ES_selector = 0x1000; + vcpu->vmcs.guest_ES_base = vcpu->vmcs.guest_ES_selector * 16; + vcpu->vmcs.guest_FS_selector = 0x1000; + vcpu->vmcs.guest_FS_base = vcpu->vmcs.guest_FS_selector * 16; + vcpu->vmcs.guest_GS_selector = 0x1000; + vcpu->vmcs.guest_GS_base = vcpu->vmcs.guest_GS_selector * 16; + vcpu->vmcs.guest_SS_selector = 0x1000; + vcpu->vmcs.guest_SS_base = vcpu->vmcs.guest_SS_selector * 16; + vcpu->vmcs.guest_RSP = 0x9000; + vcpu->vmcs.guest_CS_selector = 0x1020; + vcpu->vmcs.guest_CS_base = vcpu->vmcs.guest_CS_selector * 16; + vcpu->vmcs.guest_IDTR_base = 0x0; + vcpu->vmcs.guest_IDTR_limit = 0xffff; + vcpu->vmcs.guest_RIP=0; + vcpu->vmcs.guest_RFLAGS &= ~(EFLAGS_IF); + + return; +} diff --git a/xmhf-64/hypapps/trustvisor/src/ltc_rng_get_bytes.c b/xmhf-64/hypapps/trustvisor/src/ltc_rng_get_bytes.c new file mode 100644 index 0000000000..0b25ac1283 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/ltc_rng_get_bytes.c @@ -0,0 +1,64 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include + +/* this function overrides libtomcrypt's internal rng with our own */ + +/** + Read the system RNG + @param out Destination + @param outlen Length desired (octets) + @param callback Pointer to void function to act as "callback" when RNG is slow. This can be NULL + @return Number of octets read +*/ +unsigned long rng_get_bytes(unsigned char *out, unsigned long outlen, + void (*callback)(void)) +{ + (void)callback; + rand_bytes_or_die( out, outlen); + return outlen; +} diff --git a/xmhf-64/hypapps/trustvisor/src/ltc_sprng.c b/xmhf-64/hypapps/trustvisor/src/ltc_sprng.c new file mode 100644 index 0000000000..01dc6b00ac --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/ltc_sprng.c @@ -0,0 +1,171 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include +#include + +/* A secure PRNG using trustvisor's internal RNG + */ + +/** + Start the PRNG + @param prng [out] The PRNG state to initialize + @return CRYPT_OK if successful +*/ +static int tv_sprng_start(prng_state *prng) +{ + (void)prng; + return CRYPT_OK; +} + +/** + Add entropy to the PRNG state + @param in The data to add + @param inlen Length of the data to add + @param prng PRNG state to update + @return CRYPT_OK if successful +*/ +static int tv_sprng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + (void)prng; + (void)in; + (void)inlen; + return CRYPT_OK; +} + +/** + Make the PRNG ready to read from + @param prng The PRNG to make active + @return CRYPT_OK if successful +*/ +static int tv_sprng_ready(prng_state *prng) +{ + (void)prng; + return CRYPT_OK; +} + +/** + Read from the PRNG + @param out Destination + @param outlen Length of output + @param prng The active PRNG to read from + @return Number of octets read +*/ +static unsigned long tv_sprng_read(unsigned char *out, unsigned long outlen, prng_state *prng) +{ + (void)prng; + LTC_ARGCHK(out != NULL); + + rand_bytes_or_die( out, outlen); + + return outlen; +} + +/** + Terminate the PRNG + @param prng The PRNG to terminate + @return CRYPT_OK if successful +*/ +static int tv_sprng_done(prng_state *prng) +{ + (void)prng; + return CRYPT_OK; +} + +/** + Export the PRNG state + @param out [out] Destination + @param outlen [in/out] Max size and resulting size of the state + @param prng The PRNG to export + @return CRYPT_OK if successful +*/ +static int tv_sprng_export(unsigned char *out, unsigned long *outlen, prng_state *prng) +{ + (void)prng; + (void)out; + LTC_ARGCHK(outlen != NULL); + + *outlen = 0; + return CRYPT_OK; +} + +/** + Import a PRNG state + @param in The PRNG state + @param inlen Size of the state + @param prng The PRNG to import + @return CRYPT_OK if successful +*/ +static int tv_sprng_import(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + (void)in; + (void)inlen; + (void)prng; + + return CRYPT_OK; +} + +/** + PRNG self-test + @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled +*/ +static int tv_sprng_test(void) +{ + return CRYPT_OK; +} + +const struct ltc_prng_descriptor tv_sprng_desc = +{ + "tv_sprng", 0, + &tv_sprng_start, + &tv_sprng_add_entropy, + &tv_sprng_ready, + &tv_sprng_read, + &tv_sprng_done, + &tv_sprng_export, + &tv_sprng_import, + &tv_sprng_test +}; diff --git a/xmhf-64/hypapps/trustvisor/src/malloc.c b/xmhf-64/hypapps/trustvisor/src/malloc.c new file mode 100644 index 0000000000..b94dac8628 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/malloc.c @@ -0,0 +1,105 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/** + * malloc.[ch] serve as a layer of indirection between the specific + * malloc implementation used, and actual calls to malloc() and + * free(). + * + * TODO: Move this functionality into libemhfc once it exists, and + * name it consistently with libc, i.e., malloc.[ch]. + */ +#include +#include /* only for perf ctr stuff */ +#include + +#include + +tlsf_pool g_pool; +void mem_init(void){ + static uint8_t memory_pool[HEAPMEM_POOLSIZE]; + g_pool = tlsf_create(memory_pool, HEAPMEM_POOLSIZE); +} + +/* size_t heapmem_get_used_size(void) */ +/* { */ +/* return get_used_size(memory_pool); */ +/* } */ + +void *malloc(size_t size) +{ + void *p; + perf_ctr_timer_start(&g_tv_perf_ctrs[TV_PERF_CTR_SAFEMALLOC], 0/*FIXME*/); + + EU_CHK_W( p = tlsf_malloc(g_pool, size), + eu_warn_e( "malloc: allocation of size %d failed.", size)); + + out: + perf_ctr_timer_record(&g_tv_perf_ctrs[TV_PERF_CTR_SAFEMALLOC], 0/*FIXME*/); + return p; +} + +void *calloc(size_t nmemb, size_t size) +{ + void *p; + p = tlsf_malloc(g_pool, nmemb * size); + + if(NULL != p) { + memset(p, 0, nmemb * size); + } + + return p; +} + +void *realloc(void *ptr, size_t size) +{ + return tlsf_realloc(g_pool, ptr, size); +} + +void free(void *ptr) +{ + tlsf_free(g_pool, ptr); +} diff --git a/xmhf-64/hypapps/trustvisor/src/nv.c b/xmhf-64/hypapps/trustvisor/src/nv.c new file mode 100644 index 0000000000..2479cd8895 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/nv.c @@ -0,0 +1,490 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include + +#include + +#include /* copy_from_guest */ +#include /* rand_bytes_or_die() */ +#include + +#include + +/* defined in scode.c */ +/* TODO: more elegant organization of these data structures */ +extern int *scode_curr; +extern whitelist_entry_t *whitelist; + + +/** + * XXX REDUNDANT; identical logic exists in tv_utpm.h. Useful + * primitives may exist in bitfield.h. + * + * TODO: Consolidate. + */ +static inline bool pcr_is_selected(tpm_pcr_selection_t *tpmsel, uint32_t i) { + HALT_ON_ERRORCOND(NULL != tpmsel); + + if(i/8 >= tpmsel->size_of_select) return false; + + return (tpmsel->pcr_select[i/8] & (1 << (i%8))); +} + +static void dump_pcr_info_short(tpm_pcr_info_short_t *info) { + unsigned int i; + HALT_ON_ERRORCOND(NULL != info); + + /* pcr_selection */ + eu_trace("selected PCRs:"); + for(i=0; i<24; i++) { + if(pcr_is_selected(&info->pcr_selection, i)) { + eu_trace("pcr %d, ", i); + } + } + + /* locality_at_release */ + eu_trace("localityAtRelease "); + for(i=0; i<=4; i++) { + if(1<locality_at_release) { + eu_trace("locality %d, ", i); + } + } + /* digest_at_release */ + eu_trace("digestAtRelease %*D", + sizeof(info->digest_at_release), + info->digest_at_release.digest, + " "); + +} + +static void dump_nv_data_public(tpm_nv_data_public_t *pub) { + HALT_ON_ERRORCOND(NULL != pub); + + eu_trace("nvIndex " + "0x%08x", pub->nv_index); + + /* pcrInfoRead, pcrInfoWrite */ + eu_trace("pcrInfoRead: "); + dump_pcr_info_short(&pub->pcr_info_read); + eu_trace("pcrInfoWrite: "); + dump_pcr_info_short(&pub->pcr_info_write); + + eu_trace(" permission 0x%08x", pub->permission.attributes); + + eu_trace("bReadSTClear %s", + pub->b_read_st_clear ? "true" : "false"); + eu_trace("bWriteSTClear %s", + pub->b_write_st_clear ? "true" : "false"); + eu_trace("bWriteDefine %s", + pub->b_write_define ? "true" : "false"); + + eu_trace("data_size %d", pub->data_size); +} + +/** + * Ensure that the provided NV index is access controlled based on + * Locality 2 and PCRs 17 and 18. FIXME: PCR access control is almost + * certainly not this simple! + * + * Returns: 0 on success. + */ +static int validate_nv_access_controls(unsigned int locality, + tpm_nv_index_t idx) { + tpm_nv_data_public_t pub; + int rv = 1; + + /* Basic sanity-check to protect logic below; we really don't ever + * expect anything outside of 1--3, and we will probably only ever + * use 2. */ + HALT_ON_ERRORCOND(locality <= 4); + + EU_CHKN( rv = tpm_get_nv_data_public(locality, idx, &pub)); + + dump_nv_data_public(&pub); + + /* Confirm a single EXCLUSIVE locality for both reading and writing. */ + EU_CHK((1<= 20); /* Sanity-check security level wrt SHA-1 */ + + eu_trace("locality %d, idx 0x%08x, mss@%p, mss_size %d", + locality, idx, mss, mss_size); + + EU_CHKN( rv = _trustvisor_nv_get_mss(locality, idx, mss, mss_size)); + + rv = 0; + out: + if (rv) { + /** + * Something went wrong in the optimistic attempt to read / + * initialize the MSS. If configured conservatively, halt now! + */ + if(HALT_UPON_NV_PROBLEM) { + eu_err("MasterSealingSeed initialization FAILED! SECURITY HALT!"); + + HALT(); + } + + /** + * If we're still here, then we're configured to attempt to run in a + * degraded "ephemeral" mode where there is no long-term (across + * reboots) sealing support. Complain loudly. We will still halt + * if random keys are not available. + */ + eu_err("MasterSealingSeed initialization FAILED!\n" + "Continuing to operate in degraded mode. EPHEMERAL SEALING ONLY!"); + rand_bytes_or_die(mss, mss_size); + + /* XXX TODO: Eliminate degraded mode once we are sufficiently robust + to support development and testing without it. */ + } + return 0; +} + + +/** + * ********************************************************** + * NV functions specific to Rollback Resistance follow. + * + * This includes functions that handle hypercalls. + * + * jtt nv_definespace --index 0x00014e56 --size 32 \ + * -o tpm -e ASCII \ + * -p 11,12 \ + * -w --permission 0x00000000 --writelocality 2 --readlocality 2 + * + * ********************************************************** + */ + +/** + * Only one PAL on the entire system is granted privileges to + * {getsize|readall|writeall} the actual hardware TPM NV Index + * dedicated to rollback resistance. This is the NVRAM Multiplexor + * PAL, or NvMuxPal. + * + * The purpose of this function is to make sure that a PAL that is + * trying to make one of those hypercalls is actually the PAL that is + * authorized to do so. + * + * Returns: 0 on success, non-zero otherwise. + * TODO: Define some more meaningful failure codes. + */ +static uint32_t authenticate_nv_mux_pal(VCPU *vcpu) { + uint32_t rv = 1; + TPM_DIGEST pcr; + const int pcr_idx = 0; + eu_pulse(); + + /* make sure that this vmmcall can only be executed when a PAL is + * running */ + EU_CHK( scode_curr[vcpu->id] != -1, + eu_err_e("GenRandom ERROR: no PAL is running!")); + + /* Read uTPM PCR[0] */ + EU_CHKN( rv = utpm_pcrread(&pcr, &whitelist[scode_curr[vcpu->id]].utpm, pcr_idx)); + + if(!g_nvenforce) { + /* Boot param (cmdline) explicitly said not to enforce that only + * one anointed PAL shall be the NvMuxPal. Make some warning + * noise in the log anyways, just in case this is accidental. */ + eu_warn("\n\n" + "WARNING:WARNING:WARNING:WARNING:WARNING:WARNING\n" + " NvMuxPal Authentication DISABLED!!!\n" + " Any PAL can manipulate sensitive NV areas!!!\n" + " This may be a VULNERABILITY!!!\n" + " Continuing anyways...\n" + "WARNING:WARNING:WARNING:WARNING:WARNING:WARNING\n"); + + /* Useful to see whether enforcement would have allowed access */ + print_hex("g_nvpalpcr0: ", g_nvpalpcr0, sizeof(g_nvpalpcr0)); + print_hex("actual PCR[0]: ", pcr.value, sizeof(pcr.value)); + + return 0; /* "success" */ + } + + /** + * If we are here, then g_nvenforce is true, and we must ensure that + * the PAL attempting to access the hardware TPM's NV-RAM matches + * the one specified in g_nvpalpcr0. + */ + + EU_CHKN( rv = memcmp(g_nvpalpcr0, pcr.value, sizeof(pcr.value)), + eu_warn_e("SECURITY WARNING: Disallowed PAL Attempted to access TPM NV-RAM")); + + eu_trace("Attempt to access TPM NV-RAM APPROVED."); + rv = 0; + out: + return rv; +} + +uint32_t hc_tpmnvram_getsize(VCPU* vcpu, uint32_t size_addr) { + uint32_t rv = 1; + uint32_t actual_size; + + eu_pulse(); + + /* Make sure the asking PAL is authorized */ + EU_CHKN( rv = authenticate_nv_mux_pal(vcpu)); + + /* Open TPM */ + /* TODO: Make sure this plays nice with guest OS */ + EU_CHKN( rv = xmhf_tpm_open_locality(TRUSTVISOR_HWTPM_NV_LOCALITY), + eu_err_e("FATAL ERROR: Could not access HW TPM.")); + + /* Make the actual TPM call */ + EU_CHKN( rv = tpm_get_nvindex_size(TRUSTVISOR_HWTPM_NV_LOCALITY, + HW_TPM_ROLLBACK_PROT_INDEX, &actual_size)); + + /* Close TPM */ + xmhf_tpm_deactivate_all_localities(); + + eu_trace("HW_TPM_ROLLBACK_PROT_INDEX 0x%08x size" + " = %d", HW_TPM_ROLLBACK_PROT_INDEX, actual_size); + + EU_CHKN( copy_to_current_guest(vcpu, size_addr, &actual_size, sizeof(actual_size))); + + rv = 0; + out: + return rv; +} + +uint32_t hc_tpmnvram_readall(VCPU* vcpu, uint32_t out_addr) { + uint32_t rv = 1; + uint32_t data_size = HW_TPM_ROLLBACK_PROT_SIZE; + uint8_t data[HW_TPM_ROLLBACK_PROT_SIZE]; + bool opened_tpm = false; + + eu_pulse(); + + /* Make sure the asking PAL is authorized */ + EU_CHKN( rv = authenticate_nv_mux_pal(vcpu)); + + /* Open TPM */ + /* TODO: Make sure this plays nice with guest OS */ + EU_CHKN( rv = xmhf_tpm_open_locality(TRUSTVISOR_HWTPM_NV_LOCALITY)); + opened_tpm = true; + + /* Make the actual TPM call */ + EU_CHKN( rv = tpm_nv_read_value(TRUSTVISOR_HWTPM_NV_LOCALITY, + HW_TPM_ROLLBACK_PROT_INDEX, 0, + data, + &data_size)); + + EU_CHK( HW_TPM_ROLLBACK_PROT_SIZE == data_size, + rv = 1, /* TODO: define some meaningful error values */ + eu_err_e("ERROR: HW_TPM_ROLLBACK_PROT_SIZE (%d) !=" + " data_size (%d)", + HW_TPM_ROLLBACK_PROT_SIZE, data_size)); + + EU_CHKN( copy_to_current_guest(vcpu, out_addr, data, HW_TPM_ROLLBACK_PROT_SIZE)); + + rv = 0; + out: + /* Close TPM */ + if (opened_tpm) { + xmhf_tpm_deactivate_all_localities(); + } + + return rv; +} + +uint32_t hc_tpmnvram_writeall(VCPU* vcpu, uint32_t in_addr) { + uint32_t rv = 1; + uint8_t data[HW_TPM_ROLLBACK_PROT_SIZE]; + bool opened_tpm = false; + + eu_pulse(); + + /* Make sure the asking PAL is authorized */ + EU_CHKN( rv = authenticate_nv_mux_pal(vcpu)); + + /* Open TPM */ + /* TODO: Make sure this plays nice with guest OS */ + EU_CHKN( rv = xmhf_tpm_open_locality(TRUSTVISOR_HWTPM_NV_LOCALITY)); + opened_tpm = true; + + /* copy input data to host */ + EU_CHKN( copy_from_current_guest(vcpu, data, in_addr, HW_TPM_ROLLBACK_PROT_SIZE)); + + /* Make the actual TPM call */ + EU_CHKN( rv = tpm_nv_write_value(TRUSTVISOR_HWTPM_NV_LOCALITY, + HW_TPM_ROLLBACK_PROT_INDEX, 0, + data, + HW_TPM_ROLLBACK_PROT_SIZE)); + + rv = 0; + out: + /* Close TPM */ + if (opened_tpm) { + xmhf_tpm_deactivate_all_localities(); + } + + return rv; +} + +/* Local Variables: */ +/* mode:c */ +/* indent-tabs-mode:nil */ +/* c-basic-offset:2 */ +/* End: */ diff --git a/xmhf-64/hypapps/trustvisor/src/pages.c b/xmhf-64/hypapps/trustvisor/src/pages.c new file mode 100644 index 0000000000..63bd56f165 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/pages.c @@ -0,0 +1,95 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include + +#include +#include + +#include + +void pagelist_init(pagelist_t *pl) +{ + const int pages = 128; + pl->buf = malloc(pages*PAGE_SIZE_4K); + EU_VERIFY(pl->buf != NULL); + + pl->page_base = (void*)PAGE_ALIGN_UP_4K((uintptr_t)pl->buf); + pl->num_allocd = + (pl->page_base == pl->buf) + ? pages + : pages-1; + + pl->num_used = 0; +} + +void* pagelist_get_page(pagelist_t *pl) +{ + void *page; + eu_trace("num_used:%d num_alocd:%d", pl->num_used, pl->num_allocd); + + /* we'll handle allocating more on-demand later */ + EU_VERIFY(pl->num_used < pl->num_allocd); + + page = pl->page_base + (pl->num_used*PAGE_SIZE_4K); + pl->num_used++; + + return page; +} + +void* pagelist_get_zeroedpage(pagelist_t *pl) +{ + void *page = pagelist_get_page(pl); + memset(page, 0, PAGE_SIZE_4K); + return page; +} + +void pagelist_free_all(pagelist_t *pl) +{ + free(pl->buf); + pl->buf=NULL; + pl->num_allocd=0; +} diff --git a/xmhf-64/hypapps/trustvisor/src/pt.c b/xmhf-64/hypapps/trustvisor/src/pt.c new file mode 100644 index 0000000000..9029331f7e --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/pt.c @@ -0,0 +1,393 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* nested_pt.c routines for handling nested page tables + * Written for TrustVisor by Arvind Seshadri and Ning Qu + * + * Edited by Zongwei Zhou for EMHF/TrustVisor project + * + * EPT or NPT page table operations + * guest page table operations + */ +#include +#include +#include "./include/scode.h" +#include + +#include + +/* ********************************* */ +/* HPT related NPT operations */ +/* ********************************* */ + +hpt_prot_t pal_prot_of_type(int type) +{ + switch(type) { + case TV_PAL_SECTION_CODE: + return HPT_PROTS_RX; + break; + case TV_PAL_SECTION_SHARED_CODE: + return HPT_PROTS_RX; + break; + case TV_PAL_SECTION_DATA: + return HPT_PROTS_RW; + break; + case TV_PAL_SECTION_PARAM: + case TV_PAL_SECTION_STACK: + return HPT_PROTS_RW; + break; + case TV_PAL_SECTION_SHARED: + return HPT_PROTS_RW; + break; + case TV_PAL_SECTION_GUEST_PAGE_TABLES: + return HPT_PROTS_RWX; + break; + } + HALT_ON_ERRORCOND(0); return 0; /* unreachable; appeases compiler */ +} + +hpt_prot_t reg_prot_of_type(int type) +{ + switch(type) { + case TV_PAL_SECTION_CODE: + return HPT_PROTS_NONE; + break; + case TV_PAL_SECTION_SHARED_CODE: + return HPT_PROTS_RX; + break; + case TV_PAL_SECTION_DATA: + return HPT_PROTS_NONE; + break; + case TV_PAL_SECTION_PARAM: + case TV_PAL_SECTION_STACK: + return HPT_PROTS_NONE; + break; + case TV_PAL_SECTION_SHARED: + return HPT_PROTS_NONE; + break; + case TV_PAL_SECTION_GUEST_PAGE_TABLES: + return HPT_PROTS_RWX; + break; + } + HALT_ON_ERRORCOND(0); return 0; /* unreachable; appeases compiler */ +} + +int copy_from_current_guest(VCPU * vcpu, void *dst, gva_t gvaddr, size_t len) +{ + hptw_emhf_checked_guest_ctx_t ctx; + int rv=1; + + EU_CHKN( hptw_emhf_checked_guest_ctx_init_of_vcpu( &ctx, vcpu)); + + EU_CHKN( hptw_checked_copy_from_va( &ctx.super, ctx.cpl, dst, gvaddr, len)); + + rv=0; + out: + return rv; +} + +int copy_to_current_guest(VCPU * vcpu, gva_t gvaddr, void *src, size_t len) +{ + hptw_emhf_checked_guest_ctx_t ctx; + int rv=1; + + EU_CHKN( hptw_emhf_checked_guest_ctx_init_of_vcpu( &ctx, vcpu)); + + EU_CHKN( hptw_checked_copy_to_va( &ctx.super, ctx.cpl, gvaddr, src, len)); + + rv=0; + out: + return rv; +} + +/* clone pal's gdt from 'reg' gdt, and add to pal's guest page tables. + gdt is allocted using passed-in-pl, whose pages should already be + accessible to pal's nested page tables. XXX SECURITY need to build + a trusted gdt instead. */ +int scode_clone_gdt(VCPU *vcpu, + gva_t gdtr_base, size_t gdtr_lim, + hptw_ctx_t *pal_gpm_ctx, + pagelist_t *pl + ) +{ + void *gdt_pal_page; + u64 *gdt=NULL; + size_t gdt_size = (gdtr_lim+1)*sizeof(*gdt); + size_t gdt_page_offset = gdtr_base & MASKRANGE64(11, 0); /* XXX */ + gva_t gdt_reg_page_gva = gdtr_base & MASKRANGE64(63, 12); /* XXX */ + int err=1; + + eu_trace("scode_clone_gdt base:%x size:%d", gdtr_base, gdt_size); + + /* rest of fn assumes gdt is all on one page */ + EU_VERIFY((gdt_page_offset+gdt_size) <= PAGE_SIZE_4K); + + EU_CHK( gdt_pal_page = pagelist_get_zeroedpage(pl)); + gdt = gdt_pal_page + gdt_page_offset; + + eu_trace("copying gdt from gva:%x to hva:%p", gdtr_base, gdt); + EU_CHKN( copy_from_current_guest(vcpu, gdt, gdtr_base, gdt_size)); + + /* add to guest page tables */ + { + hpt_pmeo_t gdt_g_pmeo = { .t = pal_gpm_ctx->t, .lvl = 1 }; + hpt_pa_t gdt_gpa; + + gdt_gpa = hva2gpa(gdt); + + eu_trace("mapping gdt into guest page tables"); + /* XXX SECURITY check to ensure we're not clobbering some existing + mapping */ + /* add access to pal guest page tables */ + hpt_pmeo_set_address(&gdt_g_pmeo, gdt_gpa); + hpt_pmeo_setprot(&gdt_g_pmeo, HPT_PROTS_RWX); + EU_CHKN( hptw_insert_pmeo_alloc(pal_gpm_ctx, + &gdt_g_pmeo, + gdt_reg_page_gva)); + } + + err=0; + out: + return err; +} + +/* lend a section of memory from a user-space process (on the + commodity OS) to a pal */ +void scode_lend_section( hptw_ctx_t *reg_npm_ctx, + hptw_ctx_t *reg_gpm_ctx, + hptw_ctx_t *pal_npm_ctx, + hptw_ctx_t *pal_gpm_ctx, + const tv_pal_section_int_t *section) +{ + size_t offset; + int hpt_err; + + eu_trace("Mapping from %016llx to %016llx, size %u, pal_prot %u", + section->reg_gva, section->pal_gva, section->size, (u32)section->pal_prot); + + /* XXX don't hard-code page size here. */ + /* XXX fail gracefully */ + HALT_ON_ERRORCOND((section->size % PAGE_SIZE_4K) == 0); + + for (offset=0; offset < section->size; offset += PAGE_SIZE_4K) { + hpt_va_t page_reg_gva = section->reg_gva + offset; + hpt_va_t page_pal_gva = section->pal_gva + offset; + + /* XXX we don't use hpt_va_t or hpt_pa_t for gpa's because these + get used as both */ + u64 page_reg_gpa, page_pal_gpa; /* guest-physical-addresses */ + + hpt_pmeo_t page_reg_gpmeo; /* reg's guest page-map-entry and lvl */ + hpt_pmeo_t page_pal_gpmeo; /* pal's guest page-map-entry and lvl */ + + hpt_pmeo_t page_reg_npmeo; /* reg's nested page-map-entry and lvl */ + hpt_pmeo_t page_pal_npmeo; /* pal's nested page-map-entry and lvl */ + + /* lock? quiesce? */ + + hptw_get_pmeo(&page_reg_gpmeo, + reg_gpm_ctx, + 1, + page_reg_gva); + eu_trace("got pme %016llx, level %d, type %d", + page_reg_gpmeo.pme, page_reg_gpmeo.lvl, page_reg_gpmeo.t); + HALT_ON_ERRORCOND(page_reg_gpmeo.lvl==1); /* we don't handle large pages */ + page_reg_gpa = hpt_pmeo_get_address(&page_reg_gpmeo); + + hptw_get_pmeo(&page_reg_npmeo, + reg_npm_ctx, + 1, + page_reg_gpa); + HALT_ON_ERRORCOND(page_reg_npmeo.lvl==1); /* we don't handle large pages */ + + /* no reason to go with a different mapping */ + page_pal_gpa = page_reg_gpa; + + /* check that this VM is allowed to access this system-physical mem */ + { + hpt_prot_t effective_prots; + bool user_accessible=false; + effective_prots = hptw_get_effective_prots(reg_npm_ctx, + page_reg_gpa, + &user_accessible); + CHK((effective_prots & section->reg_prot) == section->reg_prot); + CHK(user_accessible); + } + + /* check that this guest process is allowed to access this guest-physical mem */ + { + hpt_prot_t effective_prots; + bool user_accessible=false; + effective_prots = hptw_get_effective_prots(reg_gpm_ctx, + page_reg_gva, + &user_accessible); + eu_trace("got reg gpt prots:0x%x, user:%d", + (u32)effective_prots, (int)user_accessible); + CHK((effective_prots & section->pal_prot) == section->pal_prot); + CHK(user_accessible); + } + + /* check that the requested virtual address isn't already mapped + into PAL's address space */ + { + hpt_pmeo_t existing_pmeo; + hptw_get_pmeo(&existing_pmeo, + pal_gpm_ctx, + 1, + page_pal_gva); + CHK(!hpt_pmeo_is_present(&existing_pmeo)); + } + + /* revoke access from 'reg' VM */ + hpt_pmeo_setprot(&page_reg_npmeo, section->reg_prot); + hpt_err = hptw_insert_pmeo(reg_npm_ctx, + &page_reg_npmeo, + page_reg_gpa); + CHK_RV(hpt_err); + + /* for simplicity, we don't bother removing from guest page + tables. removing from nested page tables is sufficient */ + + /* add access to pal guest page tables */ + page_pal_gpmeo = page_reg_gpmeo; /* XXX SECURITY should build from scratch */ + hpt_pmeo_set_address(&page_pal_gpmeo, page_pal_gpa); + hpt_pmeo_setprot (&page_pal_gpmeo, HPT_PROTS_RWX); + hpt_err = hptw_insert_pmeo_alloc(pal_gpm_ctx, + &page_pal_gpmeo, + page_pal_gva); + CHK_RV(hpt_err); + + /* add access to pal nested page tables */ + page_pal_npmeo = page_reg_npmeo; + hpt_pmeo_setprot(&page_pal_npmeo, section->pal_prot); + hpt_err = hptw_insert_pmeo_alloc(pal_npm_ctx, + &page_pal_npmeo, + page_pal_gpa); + CHK_RV(hpt_err); + +#ifdef __DMAP__ + /* Disable device accesses to these memory (via IOMMU) */ + xmhf_dmaprot_protect(page_reg_gpa, PAGE_SIZE_4K); +#endif /* __DMAP__ */ + + /* unlock? unquiesce? */ + } +} + +/* lend a section of memory from a user-space process (on the + commodity OS) to a pal. + PRE: assumes section was already successfully lent using scode_lend_section + PRE: assumes no concurrent access to page tables (e.g., quiesce other cpus) +*/ +void scode_return_section(hptw_ctx_t *reg_npm_ctx, + hptw_ctx_t *pal_npm_ctx, + hptw_ctx_t *pal_gpm_ctx, + const tv_pal_section_int_t *section) +{ + size_t offset; + + for (offset=0; offset < section->size; offset += PAGE_SIZE_4K) { + hpt_va_t page_pal_gva = section->pal_gva + offset; + + /* XXX we don't use hpt_va_t or hpt_pa_t for gpa's because these + get used as both */ + u64 page_reg_gpa, page_pal_gpa; /* guest-physical-addresses */ + hpt_pmeo_t page_pal_gpmeo; /* pal's guest page-map-entry and lvl */ + + hptw_get_pmeo(&page_pal_gpmeo, + pal_gpm_ctx, + 1, + page_pal_gva); + HALT_ON_ERRORCOND(page_pal_gpmeo.lvl==1); /* we don't handle large pages */ + page_pal_gpa = hpt_pmeo_get_address(&page_pal_gpmeo); + + /* lend_section always uses the same gpas between reg and pal */ + page_reg_gpa = page_pal_gpa; + + /* check that this pal VM is allowed to access this system-physical mem. + we only check that it's readable; trustvisor-wide we maintain the invariant + that a page is readable in a PAL's npt iff it is not readable in the guest npt + or other PALs' npts. + */ + { + hpt_prot_t effective_prots; + bool user_accessible=false; + effective_prots = hptw_get_effective_prots(pal_npm_ctx, + page_pal_gpa, + &user_accessible); + CHK(effective_prots & HPT_PROTS_R); + } + + /* revoke access from 'pal' VM */ + hptw_set_prot(pal_npm_ctx, + page_pal_gpa, + HPT_PROTS_NONE); + + /* scode_lend_section leaves reg guest page tables intact, so no + need to restore anything in them here. */ + + /* revoke access from pal guest page tables */ + hptw_set_prot(pal_gpm_ctx, + page_pal_gva, + HPT_PROTS_NONE); + + /* add access to reg nested page tables */ + hptw_set_prot(reg_npm_ctx, + page_reg_gpa, + HPT_PROTS_RWX); + +#ifdef __DMAP__ + /* Enable device accesses to these memory (via IOMMU) */ + xmhf_dmaprot_unprotect(page_reg_gpa, PAGE_SIZE_4K); +#endif /* __DMAP__ */ + } +} + +/* Local Variables: */ +/* mode:c */ +/* indent-tabs-mode:nil */ +/* c-basic-offset:2 */ +/* End: */ diff --git a/xmhf-64/hypapps/trustvisor/src/random.c b/xmhf-64/hypapps/trustvisor/src/random.c new file mode 100644 index 0000000000..ddfc1a5744 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/random.c @@ -0,0 +1,149 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/** + * Consumable interface to CTR_DRBG PRNG. + * + * TODO: Support re-seeding. + */ + +#include + +#include +#include + +#include + +/* libtomcrypt prng. this is just a wrapper for our internal drbg */ +prng_state g_ltc_prng; +int g_ltc_prng_id; + +/** + * Reseed the CTR_DRBG if needed. This function is structured to do + * nothing if a reseed is not required, to simplify the logic in the + * functions that actually service requests for random bytes. + * + * returns: 0 on success + */ +int reseed_ctr_drbg_using_tpm_entropy_if_needed(void) { + uint8_t EntropyInput[CTR_DRBG_SEED_BITS/8]; + + HALT_ON_ERRORCOND(true == g_master_prng_init_completed); + + if (g_drbg.reseed_counter < NIST_CTR_DRBG_RESEED_INTERVAL) + return 0; /* nothing to do */ + + eu_err("Low Entropy: Attemping TPM-based PRNG reseed."); + + /* Get CTR_DRBG_SEED_BITS of entropy from the hardware TPM */ + EU_VERIFYN( get_hw_tpm_entropy(EntropyInput, CTR_DRBG_SEED_BITS/8), + eu_err_e("FATAL ERROR: Could not access TPM to reseed PRNG.")); + + EU_VERIFYN( nist_ctr_drbg_reseed( &g_drbg, EntropyInput, sizeof(EntropyInput), NULL, 0)); + + eu_trace("master_crypto_init: PRNG reseeded successfully."); + + return 0; +} + + +/** + * Returns a pseudo-random byte or HALT's the whole system if one + * cannot be generated. + */ +uint8_t rand_byte_or_die(void) { + uint8_t byte; + + EU_VERIFY( g_master_prng_init_completed); + + EU_VERIFYN( reseed_ctr_drbg_using_tpm_entropy_if_needed()); + EU_VERIFYN( nist_ctr_drbg_generate( &g_drbg, &byte, sizeof(byte), NULL, 0)); + + return byte; +} + +/** + * Populates a buffer of pseudo-random bytes or HALT's the whole + * system if they cannot be generated. + */ +void rand_bytes_or_die(uint8_t *out, unsigned int len) { + EU_VERIFY( g_master_prng_init_completed); + EU_VERIFY( out); + EU_VERIFY( len >= 1); + + EU_VERIFYN( reseed_ctr_drbg_using_tpm_entropy_if_needed()); + + EU_VERIFYN( nist_ctr_drbg_generate(&g_drbg, out, len, NULL, 0)); +} + +/** + * Best effort to populate an array of *len random-bytes. Returns 0 + * on success, otherwise returns the number of bytes that were + * actually available (and updates *len). + */ +int rand_bytes(uint8_t *out, unsigned int *len) { + int rv=1; + + /* even here we do not want to tolerate failure to initialize */ + EU_VERIFY( g_master_prng_init_completed); + + EU_VERIFY( out); + EU_VERIFY( len); + EU_VERIFY( *len >= 1); + + /* at the present time this will either give all requested bytes + * or fail completely. no support for partial returns, though + * that may one day be desirable. */ + EU_VERIFYN( reseed_ctr_drbg_using_tpm_entropy_if_needed()); + + EU_CHKN( rv = nist_ctr_drbg_generate(&g_drbg, out, *len, NULL, 0)); + + eu_trace("Successfully generated %d pseudo-random bytes", *len); + + rv=0; + out: + return rv; +} diff --git a/xmhf-64/hypapps/trustvisor/src/scode.c b/xmhf-64/hypapps/trustvisor/src/scode.c new file mode 100644 index 0000000000..b850318c9e --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/src/scode.c @@ -0,0 +1,1478 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* scode.c routines to handle all scode loading and unloading, also + * whitelist, hash value verification for both shadow paging and nested + * paging. + * Written for TrustVisor by Ning Qu, Zongwei Zhou, and Yanlin Li + * Edited for TrustVisor on EMHF by Zongwei Zhou + */ + +#include + +#include +#include +#include /* formerly utpm.h */ +#include +#include + +#include +#include + +/* #define EU_DOWNCAST(vctx, t) assert(((t)vctx)->magic == t ## _MAGIC), (t)vctx */ + +hpt_pmo_t g_reg_npmo_root; +hptw_emhf_host_ctx_t g_hptw_reg_host_ctx; + +/* this is the return address we push onto the stack when entering the + pal. We return to the reg world on a nested page fault on + instruction fetch of this address */ +#define RETURN_FROM_PAL_ADDRESS 0x00000004 + +/* whitelist of all approved sensitive code regions */ +/* whitelist_max and *whitelist is set up by BSP, no need to apply lock + * whitelist_size will only be updated in scode_register() and scode_unreg(), no need to apply lock + * + * scode_whitelist entry is created in scode_register(), and cleaned up in scode_unregister() + * no need to apply lock on it during those time + * + * scode_whitelist entry can also be edited during PAL running(during context switch), + * However, one PAL can only be run on the CPU where the registration is done, + * which means there is no possibility that multiple CPU will run a same PAL simultaneously, + * thus no need to apply lock to whitelist entry. + * */ +whitelist_entry_t *whitelist=NULL; +size_t whitelist_size=0, whitelist_max=0; + +perf_ctr_t g_tv_perf_ctrs[TV_PERF_CTRS_COUNT]; +char *g_tv_perf_ctr_strings[] = { + "npf", "switch_scode", "switch_regular", "safemalloc", "marshall", "expose_arch", "nested_switch_scode" +}; /* careful to keep this consistent with actual macros */ + +/* This two bitmaps are only updated in scode_register() and scode_unreg(), no need to apply lock */ +/* bitmap of all physical page numer containing sensitive code */ +u8 * scode_pfn_bitmap; +/* bitmap helps to maintain the physical pages of sensitive code + * in one 2M physical page range + */ +u16 * scode_pfn_bitmap_2M; + +/* identify which scode are running on every CPU, -1 for not running any scode */ +/* each CPU has its own scode_curr value, no need to apply a lock on it */ +int * scode_curr = NULL; + +void scode_release_all_shared_pages(VCPU *vcpu, whitelist_entry_t* entry); + +/* search scode in whitelist */ +int scode_in_list(u64 gcr3, uintptr_t gvaddr, u32 g64) +{ + size_t i, j; + + for (i = 0; i < whitelist_max; i ++) + { + hpt_type_t t = whitelist[i].hptw_pal_checked_guest_ctx.super.t; + if ((hpt_cr3_get_address(t, gcr3) == whitelist[i].gcr3) && + (g64 == whitelist[i].g64)) { + for( j=0 ; j<(u32)(whitelist[i].scode_info.num_sections) ; j++ ) { + if( (gvaddr >= whitelist[i].scode_info.sections[j].start_addr) && + (gvaddr < ((whitelist[i].scode_info.sections[j].start_addr)+((whitelist[i].scode_info.sections[j].page_num)<section_type, sizeof(section->section_type))); + + /* measure the address where the section is mapped. this prevents, + for example, that a section is mapped with a different alignment + to change the effective entry point, or switch some static data + for other static data, etc. */ + /* XXX we currently don't do this for PARAM and STACK sections, + though it wouldn't be a bad idea to do so. this will break + existing client code, though, which dynamically allocates those + sections and doesn't request a fixed location to map into the + pal's virtual address space. + */ + if (section->section_type != TV_PAL_SECTION_STACK + && section->section_type != TV_PAL_SECTION_PARAM) { + EU_CHKN( sha1_process( &ctx, (const uint8_t*)§ion->pal_gva, sizeof(section->pal_gva))); + } + + /* measure section size. not clear that this is strictly necessary, + since giving a pal more memory shouldn't hurt anything, and less + memory should result in no worse than the pal crashing, but seems + like good hygiene. */ + EU_CHKN( sha1_process( &ctx, (const uint8_t*)§ion->size, sizeof(section->size))); + + /* measure contents. we could consider making this optional for, + e.g., PARAM and STACK sections, but seems like good hygiene to + always do it. client ought to ensure that those sections are + consistent (e.g., 0'd). an alternative to consider is to enforce + that the hypervisor either measures or zeroes each section.*/ + { + size_t measured=0; + + while(measured < section->size) { + size_t to_measure; + uint8_t *ptr=NULL; + + /* we just constructed these page tables, so in principle the + * additional checks here should be unnecessary. leaving them in + * to avoid potential future TOCTTOU vulnerabilities. + */ + EU_VERIFY( ptr = hptw_checked_access_va( &wle->hptw_pal_checked_guest_ctx.super, + HPT_PROTS_R, + HPTW_CPL3, + section->pal_gva + measured, + section->size - measured, + &to_measure)); + + EU_CHKN( sha1_process( &ctx, ptr, to_measure)); + measured += to_measure; + } + } + + EU_CHKN( sha1_done( &ctx, sha1sum.value)); + +#ifdef __DRT__ + /* extend pcr 0 */ + utpm_extend(&sha1sum, utpm, 0); +#else /* !__DRT__ */ + (void) utpm; // unused +#endif /* __DRT__ */ + + rv=0; + out: + return rv; +} + +int scode_measure_sections(utpm_master_state_t *utpm, + whitelist_entry_t *wle) +{ + size_t i; + int err=0; + + for(i=0; i < wle->sections_num; i++) { + err = scode_measure_section(utpm, wle, &wle->sections[i]); + if (err) { + return err; + } + } + + return 0; +} + + +/* initialize all the scode related variables and buffers */ +void init_scode(VCPU * vcpu) +{ + size_t inum, max; + (void)vcpu; + + /* initialize perf counters. this needs to happen before anythings gets profiled + * to prevent deadlock. + */ + { + int j; + for(j=0; j max) + max = g_midtable[inum].cpu_lapic_id; + } + scode_curr = malloc((max+1) * sizeof(*scode_curr)); + memset(scode_curr, 0xFF, ((max+1) * sizeof(*scode_curr))); + +#ifdef __DRT__ + /* init PRNG and long-term crypto keys */ + EU_VERIFYN(trustvisor_master_crypto_init()); + eu_trace("trustvisor_master_crypto_init successful."); +#else /* !__DRT__ */ + eu_trace("DEVELOPMENT ONLY: skipping trustvisor_master_crypto_init()."); +#endif /* __DRT__ */ +} + +/* parse scode paramter info ( scode registration input) */ +int parse_params_info(VCPU * vcpu, struct tv_pal_params* pm_info, uintptr_t pm_addr) +{ + size_t i, num; + uintptr_t addr; + int rv=1; + + /* get number of parameters */ + EU_CHKN( copy_from_current_guest(vcpu, + &pm_info->num_params, + pm_addr, + sizeof(pm_info->num_params))); + num = pm_info->num_params; + + eu_trace("pm_info %#x, # of parameters is %d", pm_addr, num); + EU_CHK( num <= TV_MAX_PARAMS); + + addr = pm_addr + offsetof(struct tv_pal_params, params); + EU_CHKN( copy_from_current_guest(vcpu, + &pm_info->params[0], + addr, + sizeof(pm_info->params[0]) * num)); + + for (i = 0; i < num; i++) { + eu_trace("parameter %d type %d size %ld", i, pm_info->params[i].type, pm_info->params[i].size); + } + + rv=0; +out: + return rv; +} + +int memsect_info_copy_from_guest(VCPU * vcpu, struct tv_pal_sections *ps_scode_info, uintptr_t gva_scode_info) +{ + size_t gva_scode_info_offset = 0; + int rv=1; + + /* get number of sections */ + EU_CHKN( copy_from_current_guest(vcpu, + &ps_scode_info->num_sections, + gva_scode_info, + sizeof(ps_scode_info->num_sections))); + + gva_scode_info_offset = offsetof(struct tv_pal_sections, sections); + eu_trace("scode_info addr %x, # of section is %d", gva_scode_info, ps_scode_info->num_sections); + + /* copy array of section descriptors */ + EU_CHK( ps_scode_info->num_sections <= TV_MAX_SECTIONS); + + EU_CHKN( copy_from_current_guest(vcpu, + &(ps_scode_info->sections[0]), + gva_scode_info+gva_scode_info_offset, + ps_scode_info->num_sections*sizeof(ps_scode_info->sections[0]))); + + rv=0; + out: + if(rv) { + eu_err("failed with params: ps_scode_info:%p gva_scode_info:%#x", ps_scode_info, gva_scode_info); + } + return rv; +} + +/* parse scode sections info (scode registration input) */ +int memsect_info_register(VCPU * vcpu, struct tv_pal_sections *ps_scode_info, whitelist_entry_t * wle) +{ + size_t i; + int is_get_param, is_get_stack; + int type; + uintptr_t size, start; + int rv=1; + + (void)vcpu; + + /* parse section type, start address and size */ + is_get_param=0; + is_get_stack=0; + for (i = 0; i < ps_scode_info->num_sections; i++) { + size = ps_scode_info->sections[i].page_num; + type = ps_scode_info->sections[i].type; + start = ps_scode_info->sections[i].start_addr; + + /* make sure the addr is 4kb page aligned */ + EU_CHK( PAGE_ALIGNED_4K(start)); + + switch ( type ) { + case TV_PAL_SECTION_PARAM : + { + /* set param page num and addr */ + if (!is_get_param) { + wle->gpm_size=size; + wle->gpmp=start+0x10; + is_get_param=1; + } + } + break; + case TV_PAL_SECTION_STACK : + { + /* set stack page num and addr */ + if (!is_get_stack) { + wle->gss_size=size; + wle->gssp=start+(size<id, scode_info, scode_pm, gventry); + + /* ATTN: we should assign a ID for each registered sensitive code + * so we know what to verify each time + */ + whitelist_new.id = 0; + whitelist_new.g64 = VCPU_g64(vcpu); + whitelist_new.gcr3 = gcr3; /* Will clear lower bits for CR3 later */ + whitelist_new.grsp = (uintptr_t)-1; + + /* store scode entry point */ + whitelist_new.entry_v = gventry; + whitelist_new.entry_p = hptw_va_to_pa( ®_guest_walk_ctx.super, gventry); + eu_trace("CR3 value is %#llx, entry point vaddr is %#lx, paddr is %#lx", gcr3, whitelist_new.entry_v, whitelist_new.entry_p); + + /* parse parameter structure */ + EU_CHKN( parse_params_info(vcpu, &(whitelist_new.params_info), scode_pm)); + + whitelist_new.gpm_num = whitelist_new.params_info.num_params; + /* register scode sections into whitelist entry */ + EU_CHKN( memsect_info_copy_from_guest(vcpu, &(whitelist_new.scode_info), scode_info)); + EU_CHKN( memsect_info_register(vcpu, &(whitelist_new.scode_info), &whitelist_new)); + + EU_CHK( whitelist_new.npl = malloc(sizeof(pagelist_t))); + pagelist_init(whitelist_new.npl); + + EU_CHK( whitelist_new.gpl = malloc(sizeof(pagelist_t))); + pagelist_init(whitelist_new.gpl); + + whitelist_new.reg_gpt_root_pa = hpt_emhf_get_guest_root_pm_pa( vcpu); + whitelist_new.reg_gpt_type = hpt_emhf_get_guest_hpt_type( vcpu); + pal_npmo_root = (hpt_pmo_t) { + .t = g_reg_npmo_root.t, + .lvl = g_reg_npmo_root.lvl, + .pm = pagelist_get_zeroedpage(whitelist_new.npl), + }; + pal_gpmo_root = (hpt_pmo_t) { + .t = whitelist_new.reg_gpt_type, + .lvl = hpt_root_lvl( whitelist_new.reg_gpt_type), + .pm = pagelist_get_zeroedpage( whitelist_new.gpl), + }; + + EU_CHKN( hptw_emhf_host_ctx_init( &whitelist_new.hptw_pal_host_ctx, + hva2spa( pal_npmo_root.pm), + pal_npmo_root.t, + whitelist_new.npl)); + + EU_CHKN( hptw_emhf_checked_guest_ctx_init( &whitelist_new.hptw_pal_checked_guest_ctx, + hva2gpa( pal_gpmo_root.pm), + pal_gpmo_root.t, + HPTW_CPL3, + &whitelist_new.hptw_pal_host_ctx, + whitelist_new.gpl)); + + /* add all gpl pages to pal's nested page tables, ensuring that + the guest page tables allocated from it will be accessible to the + pal */ + /* XXX breaks pagelist abstraction. will break if pagelist ever dynamically + allocates more buffers. consider doing this on-demand inside pal's gzp fn instead. */ + eu_trace("adding gpl to pal's npt:"); + for (i=0; i < whitelist_new.gpl->num_allocd; i++) { + hpt_pmeo_t pmeo = { + .pme = 0, + .t = pal_npmo_root.t, + .lvl = 1, + }; + void *page = whitelist_new.gpl->page_base + i*PAGE_SIZE_4K; + hpt_pmeo_setprot(&pmeo, HPT_PROTS_RWX); + hpt_pmeo_setuser(&pmeo, true); + hpt_pmeo_set_address(&pmeo, hva2spa(page)); + EU_CHKN( hptw_insert_pmeo_alloc( &whitelist_new.hptw_pal_host_ctx.super, + &pmeo, + hva2gpa(page))); + } + + eu_trace("adding sections to pal's npts and gpts:"); + /* map each requested section into the pal */ + whitelist_new.sections_num = whitelist_new.scode_info.num_sections; + for (i=0; iid, gcr3, gvaddr); + + for (i = 0; i < whitelist_max; i ++) { + /* find scode with correct cr3 and entry point */ + hpt_type_t t = whitelist[i].hptw_pal_checked_guest_ctx.super.t; + if ((whitelist[i].gcr3 == hpt_cr3_get_address(t, gcr3)) && + (g64 == whitelist[i].g64) && + (whitelist[i].entry_v == gvaddr)) + break; + } + + EU_CHK( i < whitelist_max); + + /* dump perf counters */ + eu_perf("performance counters:"); + for(j=0; jid]; + u32 err=1; + hptw_emhf_checked_guest_ctx_t vcpu_guest_walk_ctx; + + perf_ctr_timer_start(&g_tv_perf_ctrs[TV_PERF_CTR_MARSHALL], vcpu->idx); + + EU_CHKN( hptw_emhf_checked_guest_ctx_init_of_vcpu( &vcpu_guest_walk_ctx, vcpu)); + + eu_trace("marshalling scode parameters!"); + EU_CHK(whitelist[curr].gpm_num != 0); + + /* memory address for input parameter in sensitive code */ + pm_addr_base = whitelist[curr].gpmp; + eu_trace("parameter page base address is %#lx", pm_addr_base); + + /* address for parameters in guest stack */ + grsp = (uintptr_t)whitelist[curr].grsp + 8; /*the stack pointer of parameters in guest stack*/ + + /* save params number */ + pm_addr = pm_addr_base; + EU_CHKN( hptw_checked_copy_to_va( &whitelist[curr].hptw_pal_checked_guest_ctx.super, + HPTW_CPL3, + pm_addr, + &whitelist[curr].gpm_num, + sizeof(whitelist[curr].gpm_num))); + pm_addr += sizeof(whitelist[curr].gpm_num); + pm_size_sum = sizeof(whitelist[curr].gpm_num); /*memory used in input pms section*/ + eu_trace("params number is %d", whitelist[curr].gpm_num); + + EU_CHK( whitelist[curr].gpm_num <= TV_MAX_PARAMS); + + /* begin to process the params*/ + for (pm_i = whitelist[curr].gpm_num-1; pm_i >= 0; pm_i--) /*the last parameter should be pushed in stack first*/ + { + /* get param information*/ + pm_type = whitelist[curr].params_info.params[pm_i].type; + pm_size = whitelist[curr].params_info.params[pm_i].size * 8; + /* get param value from guest registers / stack */ + switch (pm_i) { + case 0: pm_value = r->rdi; break; + case 1: pm_value = r->rsi; break; + case 2: pm_value = r->rdx; break; + case 3: pm_value = r->rcx; break; + case 4: pm_value = r->r8; break; + case 5: pm_value = r->r9; break; + default: + eu_trace("copying param %d", pm_i); + EU_CHKN( copy_from_current_guest(vcpu, &pm_value, grsp + (pm_i-6)*8, sizeof(pm_value))); + break; + } + + + pm_size_sum += sizeof(pm_type)+sizeof(pm_size)+sizeof(pm_value); + EU_CHK( pm_size_sum <= (whitelist[curr].gpm_size*PAGE_SIZE_4K)); + + /* save input params in input params memory for sensitive code */ + EU_CHKN( hptw_checked_copy_to_va(&whitelist[curr].hptw_pal_checked_guest_ctx.super, + HPTW_CPL3, + pm_addr, + &pm_type, sizeof(pm_type))); + pm_addr += sizeof(pm_type); + EU_CHKN( hptw_checked_copy_to_va(&whitelist[curr].hptw_pal_checked_guest_ctx.super, + HPTW_CPL3, + pm_addr, + &pm_size, sizeof(pm_size))); + pm_addr += sizeof(pm_size); + EU_CHKN( hptw_checked_copy_to_va(&whitelist[curr].hptw_pal_checked_guest_ctx.super, + HPTW_CPL3, + pm_addr, + &pm_value, sizeof(pm_value))); + pm_addr += sizeof(pm_value); + eu_trace("scode_marshal copied metadata to params area"); + + switch (pm_type) + { + case TV_PAL_PM_INTEGER: /* integer */ + { + /* put the parameter value in sensitive code stack */ + pm_tmp = pm_value; + eu_trace("PM %d is a integer (size %d, value %#lx)", pm_i, pm_size, pm_value); + break; + } + case TV_PAL_PM_POINTER: /* pointer */ + { + /*copy data from guest space to sensitive code*/ + pm_size_sum += pm_size; + EU_CHK( pm_size_sum <= (whitelist[curr].gpm_size*PAGE_SIZE_4K)); + + eu_trace("PM %d is a pointer (size %d, value %#lx)", pm_i, pm_size, pm_value); + + EU_CHKN( hptw_checked_copy_va_to_va(&whitelist[curr].hptw_pal_checked_guest_ctx.super, + HPTW_CPL3, + pm_addr, + &vcpu_guest_walk_ctx.super, + HPTW_CPL3, + pm_value, + pm_size)); + + /* put pointer address in sensitive code stack*/ + pm_tmp = pm_addr; + pm_addr += pm_size; + break; + } + default: /* other */ + eu_err("Fail: unknown parameter %d type %d ", pm_i, pm_type); + err=7; + goto out; + } + switch (pm_i) { + case 0: r->rdi = pm_tmp; break; + case 1: r->rsi = pm_tmp; break; + case 2: r->rdx = pm_tmp; break; + case 3: r->rcx = pm_tmp; break; + case 4: r->r8 = pm_tmp; break; + case 5: r->r9 = pm_tmp; break; + default: + new_rsp -= sizeof(pm_tmp); + EU_CHKN( hptw_checked_copy_to_va( &whitelist[curr].hptw_pal_checked_guest_ctx.super, + HPTW_CPL3, + new_rsp, + &pm_tmp, + sizeof(pm_tmp))); + break; + } + } + VCPU_grsp_set(vcpu, new_rsp); + + err=0; + out: + perf_ctr_timer_record(&g_tv_perf_ctrs[TV_PERF_CTR_MARSHALL], vcpu->idx); + return err; +#else /* !__XMHF_AMD64__ */ + (void)vcpu; + (void)r; + /* Not supported */ + return 1; +#endif /* __XMHF_AMD64__ */ +} + +u32 scode_marshall32(VCPU * vcpu) +{ + uintptr_t pm_addr, pm_addr_base; /*parameter stack base address*/ + u64 pm_value; + u32 pm_tmp; /* For x86 calling convention, need to be u32 */ + u64 pm_type; + u64 pm_size, pm_size_sum; /*save pm information*/ + int pm_i; + uintptr_t grsp; + uintptr_t new_rsp = VCPU_grsp(vcpu); + int curr=scode_curr[vcpu->id]; + u32 err=1; + hptw_emhf_checked_guest_ctx_t vcpu_guest_walk_ctx; + + perf_ctr_timer_start(&g_tv_perf_ctrs[TV_PERF_CTR_MARSHALL], vcpu->idx); + + EU_CHKN( hptw_emhf_checked_guest_ctx_init_of_vcpu( &vcpu_guest_walk_ctx, vcpu)); + + eu_trace("marshalling scode parameters!"); + EU_CHK(whitelist[curr].gpm_num != 0); + + /* memory address for input parameter in sensitive code */ + pm_addr_base = whitelist[curr].gpmp; + eu_trace("parameter page base address is %#lx", pm_addr_base); + + /* address for parameters in guest stack */ + grsp = (uintptr_t)whitelist[curr].grsp + 4; /*the stack pointer of parameters in guest stack*/ + + /* save params number */ + pm_addr = pm_addr_base; + EU_CHKN( hptw_checked_copy_to_va( &whitelist[curr].hptw_pal_checked_guest_ctx.super, + HPTW_CPL3, + pm_addr, + &whitelist[curr].gpm_num, + sizeof(whitelist[curr].gpm_num))); + pm_addr += sizeof(whitelist[curr].gpm_num); + pm_size_sum = sizeof(whitelist[curr].gpm_num); /*memory used in input pms section*/ + eu_trace("params number is %d", whitelist[curr].gpm_num); + + EU_CHK( whitelist[curr].gpm_num <= TV_MAX_PARAMS); + + /* begin to process the params*/ + for (pm_i = whitelist[curr].gpm_num-1; pm_i >= 0; pm_i--) /*the last parameter should be pushed in stack first*/ + { + /* get param information*/ + pm_type = whitelist[curr].params_info.params[pm_i].type; + pm_size = whitelist[curr].params_info.params[pm_i].size * 4; + /* get param value from guest stack */ + eu_trace("copying param %d", pm_i); + /* Make sure upper bits of pm_value are clear */ + pm_value = 0; + /* Cannot use sizeof() because pm_value is u64 */ + EU_CHKN( copy_from_current_guest(vcpu, &pm_value, grsp + pm_i*4, 4)); + + pm_size_sum += sizeof(pm_type)+sizeof(pm_size)+sizeof(pm_value); + EU_CHK( pm_size_sum <= (whitelist[curr].gpm_size*PAGE_SIZE_4K)); + + /* save input params in input params memory for sensitive code */ + EU_CHKN( hptw_checked_copy_to_va(&whitelist[curr].hptw_pal_checked_guest_ctx.super, + HPTW_CPL3, + pm_addr, + &pm_type, sizeof(pm_type))); + pm_addr += sizeof(pm_type); + EU_CHKN( hptw_checked_copy_to_va(&whitelist[curr].hptw_pal_checked_guest_ctx.super, + HPTW_CPL3, + pm_addr, + &pm_size, sizeof(pm_size))); + pm_addr += sizeof(pm_size); + EU_CHKN( hptw_checked_copy_to_va(&whitelist[curr].hptw_pal_checked_guest_ctx.super, + HPTW_CPL3, + pm_addr, + &pm_value, sizeof(pm_value))); + pm_addr += sizeof(pm_value); + eu_trace("scode_marshal copied metadata to params area"); + + switch (pm_type) + { + case TV_PAL_PM_INTEGER: /* integer */ + { + /* put the parameter value in sensitive code stack */ + pm_tmp = (u32)pm_value; + eu_trace("PM %d is a integer (size %d, value %#lx)", pm_i, pm_size, pm_value); + break; + } + case TV_PAL_PM_POINTER: /* pointer */ + { + /*copy data from guest space to sensitive code*/ + pm_size_sum += pm_size; + EU_CHK( pm_size_sum <= (whitelist[curr].gpm_size*PAGE_SIZE_4K)); + + eu_trace("PM %d is a pointer (size %d, value %#lx)", pm_i, pm_size, pm_value); + + EU_CHKN( hptw_checked_copy_va_to_va(&whitelist[curr].hptw_pal_checked_guest_ctx.super, + HPTW_CPL3, + pm_addr, + &vcpu_guest_walk_ctx.super, + HPTW_CPL3, + pm_value, + pm_size)); + + /* put pointer address in sensitive code stack*/ + pm_tmp = pm_addr; + pm_addr += pm_size; + break; + } + default: /* other */ + eu_err("Fail: unknown parameter %d type %d ", pm_i, pm_type); + err=7; + goto out; + } + new_rsp -= sizeof(pm_tmp); + EU_CHKN( hptw_checked_copy_to_va( &whitelist[curr].hptw_pal_checked_guest_ctx.super, + HPTW_CPL3, + new_rsp, + &pm_tmp, + sizeof(pm_tmp))); + } + VCPU_grsp_set(vcpu, new_rsp); + + err=0; + out: + perf_ctr_timer_record(&g_tv_perf_ctrs[TV_PERF_CTR_MARSHALL], vcpu->idx); + return err; +} + + + +//todo: switch from regular code to sensitive code +u32 hpt_scode_switch_scode(VCPU * vcpu, struct regs *r) +{ + int curr=scode_curr[vcpu->id]; + int err=1; + bool swapped_grsp=false; + bool pushed_return=false; + u64 sentinel_return; /* In x86, only use 4 bytes */ + u64 regular_return = 0; /* In x86, only use 4 bytes */ + u32 word_size = VCPU_g64(vcpu) ? 8 : 4; + + perf_ctr_timer_start(&g_tv_perf_ctrs[TV_PERF_CTR_SWITCH_SCODE], vcpu->idx); + + eu_trace("*** to scode ***"); + + spin_lock(&(whitelist[curr].pal_running_lock)); + whitelist[curr].pal_running_vcpu_id=vcpu->id; + eu_trace("got pal_running lock!"); + + EU_CHKN( copy_from_current_guest(vcpu, + ®ular_return, + VCPU_grsp(vcpu), + word_size)); + whitelist[curr].return_v = (uintptr_t)regular_return; + eu_trace("scode return vaddr is %#lx", whitelist[curr].return_v); + + /* save the guest stack pointer and set new stack pointer to scode stack */ + eu_trace("saved guest regular stack %#lx, switch to sensitive code stack %#lx", + (uintptr_t)VCPU_grsp(vcpu), whitelist[curr].gssp); + whitelist[curr].grsp = (uintptr_t)VCPU_grsp(vcpu); + VCPU_grsp_set(vcpu, whitelist[curr].gssp); + swapped_grsp=true; + + /* input parameter marshalling */ + if (whitelist[curr].g64) { + EU_CHKN( scode_marshall64(vcpu, r)); + } else { + EU_CHKN( scode_marshall32(vcpu)); + } + + /* write the sentinel return address to scode stack */ + sentinel_return = RETURN_FROM_PAL_ADDRESS; + EU_CHKN( hptw_checked_copy_to_va( &whitelist[curr].hptw_pal_checked_guest_ctx.super, + HPTW_CPL3, + VCPU_grsp(vcpu)-word_size, + &sentinel_return, + word_size)); + VCPU_grsp_set(vcpu, VCPU_grsp(vcpu)-word_size); + pushed_return=true; + + eu_trace("host stack pointer before running scode is %#lx",(uintptr_t)VCPU_grsp(vcpu)); + + /* nothing below here can fail. (i.e., don't have to cleanup code + below in case of error) */ + + eu_trace("change NPT permission to run PAL!"); + eu_trace("vcpu=%#x, guest_RIP=%#lx, guest_RSP=%#lx", vcpu->id, + VCPU_grip(vcpu), VCPU_grsp(vcpu)); + hpt_emhf_set_root_pm_pa( vcpu, whitelist[curr].hptw_pal_host_ctx.super.root_pa); + VCPU_gcr3_set(vcpu, whitelist[curr].pal_gcr3); + xmhf_memprot_flushmappings(vcpu); /* XXX */ + if (whitelist[curr].hptw_pal_checked_guest_ctx.super.t == HPT_TYPE_PAE) { + /* For PAE paging, need to update VMCS PDPTEs manually */ + hptw_ctx_t *ctx = &whitelist[curr].hptw_pal_host_ctx.super; + size_t avail_sz; + u64 *pdptes = ctx->pa2ptr(ctx, VCPU_gcr3(vcpu), sizeof(u64) * 4, + HPT_PROTS_R, HPTW_CPL3, &avail_sz); + EU_CHK(avail_sz == sizeof(u64) * 4); + VCPU_gpdpte_set(vcpu, pdptes); + } + + /* disable interrupts, assume regular code has interrupts enabled */ + { + u64 rflags = VCPU_grflags(vcpu); + EU_CHK((rflags & EFLAGS_IF) == EFLAGS_IF); + VCPU_grflags_set(vcpu, rflags & ~EFLAGS_IF); + } + + /* disable NMIs, assume regular code has NMIs enabled */ + { + EU_CHK(VCPU_gnmiblock(vcpu) == 0); + VCPU_gnmiblock_set(vcpu, 1); + } + + /* XXX FIXME- what's the right thing here? Keeping 'legacy' behavior + of setting this flag for AMD only and doing nothing for INTEL for + now */ + if(vcpu->cpu_vendor == CPU_VENDOR_AMD) { + /* set the sensitive code to run in ring 3 */ + ((struct _svm_vmcbfields *)(vcpu->vmcb_vaddr_ptr))->cpl = 3; + } + + perf_ctr_timer_record(&g_tv_perf_ctrs[TV_PERF_CTR_SWITCH_SCODE], vcpu->idx); + + /* intercept all exceptions. (otherwise they'll result in a triple-fault, + * since the PAL doesn't have any exception handlers installed). + */ + if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + whitelist[curr].saved_exception_intercepts = + ((struct _svm_vmcbfields *)(vcpu->vmcb_vaddr_ptr))->exception_intercepts_bitmask; + ((struct _svm_vmcbfields *)(vcpu->vmcb_vaddr_ptr))->exception_intercepts_bitmask = 0xffffffff; + } else if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + whitelist[curr].saved_exception_intercepts = vcpu->vmcs.control_exception_bitmap; + vcpu->vmcs.control_exception_bitmap = 0xffffffff; + } + + err=0; + out: + if(err) { + if (swapped_grsp) { + VCPU_grsp_set(vcpu, whitelist[curr].grsp); + whitelist[curr].grsp = (uintptr_t)-1; + } + if (pushed_return) { + VCPU_grsp_set(vcpu, VCPU_grsp(vcpu)+word_size); + } + + whitelist[curr].pal_running_vcpu_id=-1; + spin_unlock(&(whitelist[curr].pal_running_lock)); + eu_trace("released pal_running lock!"); + } + return err; +} + +u32 scode_unmarshall(VCPU * vcpu) +{ + uintptr_t pm_addr_base, pm_addr; + size_t i; + u64 pm_num, pm_value; /* Need to be consistent with scode_marshall */ + u64 pm_type; + u64 pm_size; /* Need to be consistent with scode_marshall */ + + int curr=scode_curr[vcpu->id]; + + hptw_emhf_checked_guest_ctx_t reg_guest_walk_ctx; + u32 err=1; + + + EU_CHKN( hptw_emhf_checked_guest_ctx_init( ®_guest_walk_ctx, + whitelist[curr].reg_gpt_root_pa, + whitelist[curr].reg_gpt_type, + HPTW_CPL3, + &g_hptw_reg_host_ctx, + NULL)); + + eu_trace("unmarshalling scode parameters!"); + EU_CHK( whitelist[curr].gpm_num != 0); + + /* memory address for input parameter in sensitive code */ + pm_addr_base = whitelist[curr].gpmp; + eu_trace("parameter page base address is %#x", pm_addr_base); + + /* get params number */ + pm_addr = pm_addr_base; + EU_CHKN( hptw_checked_copy_from_va( &whitelist[curr].hptw_pal_checked_guest_ctx.super, + HPTW_CPL3, + &pm_num, + pm_addr, + sizeof(pm_num))); + pm_addr += sizeof(pm_num); + eu_trace("params number is %d", pm_num); + EU_CHK( pm_num <= TV_MAX_PARAMS); + + /* begin to process the params*/ + for (i = 0; i < pm_num; i++) /*the last parameter should be pushed in stack first*/ + { + /* get param information*/ + EU_CHKN( hptw_checked_copy_from_va( &whitelist[curr].hptw_pal_checked_guest_ctx.super, + HPTW_CPL3, + &pm_type, + pm_addr, + sizeof(pm_type))); + pm_addr += sizeof(pm_type); + + switch (pm_type) + { + case TV_PAL_PM_INTEGER: /*integer*/ + { + /* don't need to put integer back to regular code stack */ + pm_addr += sizeof(pm_size) + sizeof(pm_value); + eu_trace("skip an integer parameter!"); + break; + } + case TV_PAL_PM_POINTER: /* pointer */ + { + EU_CHKN( hptw_checked_copy_from_va( &whitelist[curr].hptw_pal_checked_guest_ctx.super, + HPTW_CPL3, + &pm_size, + pm_addr, + sizeof(pm_size))); + pm_addr += sizeof(pm_size); + /* get pointer adddress in regular code */ + EU_CHKN( hptw_checked_copy_from_va( &whitelist[curr].hptw_pal_checked_guest_ctx.super, + HPTW_CPL3, + &pm_value, + pm_addr, + sizeof(pm_value))); + pm_addr += sizeof(pm_value); + + eu_trace("PM %d is a pointer (size %d, addr %#x)", i, pm_size, pm_value); + /* copy data from sensitive code (param space) to guest */ + EU_CHKN( hptw_checked_copy_va_to_va( ®_guest_walk_ctx.super, + HPTW_CPL3, + pm_value, + &whitelist[curr].hptw_pal_checked_guest_ctx.super, + HPTW_CPL3, + pm_addr, + pm_size)); + pm_addr += pm_size; + break; + } + + default: /* other */ + eu_err("Fail: unknown parameter %d type %d ", i, pm_type); + err=5; + goto out; + } // end switch + + } //end for loop + + err=0; + out: + return err; +} + +//switch from sensitive code to regular code +u32 hpt_scode_switch_regular(VCPU * vcpu) +{ + int curr=scode_curr[vcpu->id]; + u32 rv=1; + u32 word_size = VCPU_g64(vcpu) ? 8 : 4; + + perf_ctr_timer_start(&g_tv_perf_ctrs[TV_PERF_CTR_SWITCH_REGULAR], vcpu->idx); + + eu_trace("************************************"); + eu_trace("***** switch to regular code ******"); + eu_trace("************************************"); + + /* marshalling parameters back to regular code */ + EU_CHKN( scode_unmarshall(vcpu)); + + /* whether or not marshalling succeeded, we switch back to reg world. + * nothing below can fail. + */ + rv=0; + out: + + /* restore exception intercept vector */ + if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + ((struct _svm_vmcbfields *)(vcpu->vmcb_vaddr_ptr))->exception_intercepts_bitmask + = whitelist[curr].saved_exception_intercepts; + } else if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + vcpu->vmcs.control_exception_bitmap + = whitelist[curr].saved_exception_intercepts; + } + + /* release shared pages */ + scode_release_all_shared_pages(vcpu, &whitelist[curr]); + + /* clear the NPT permission setting in switching into scode */ + eu_trace("change NPT permission to exit PAL!"); + hpt_emhf_set_root_pm(vcpu, g_reg_npmo_root.pm); + VCPU_gcr3_set(vcpu, whitelist[curr].gcr3); + xmhf_memprot_flushmappings(vcpu); /* XXX */ + if (whitelist[curr].hptw_pal_checked_guest_ctx.super.t == HPT_TYPE_PAE) { + /* For PAE paging, need to update VMCS PDPTEs manually */ + hptw_ctx_t *ctx = &whitelist[curr].hptw_pal_host_ctx.super; + size_t avail_sz; + u64 *pdptes = ctx->pa2ptr(ctx, VCPU_gcr3(vcpu), sizeof(u64) * 4, + HPT_PROTS_R, HPTW_CPL3, &avail_sz); + EU_CHK(avail_sz == sizeof(u64) * 4); + VCPU_gpdpte_set(vcpu, pdptes); + } + + /* switch back to regular stack */ + eu_trace("switch from scode stack %#x back to regular stack %#lx", (uintptr_t)VCPU_grsp(vcpu), (uintptr_t)whitelist[curr].grsp); + VCPU_grsp_set(vcpu, whitelist[curr].grsp + word_size); + whitelist[curr].grsp = (uintptr_t)-1; + + /* enable interrupts, check that scode has interrupts disabled */ + { + u64 rflags = VCPU_grflags(vcpu); + EU_CHK((rflags & EFLAGS_IF) == 0); + VCPU_grflags_set(vcpu, rflags | EFLAGS_IF); + } + + /* enable NMIs, check that scode has NMIs disabled */ + { + EU_CHK(VCPU_gnmiblock(vcpu) == 1); + VCPU_gnmiblock_set(vcpu, 0); + } + + eu_trace("stack pointer before exiting scode is %#lx",(uintptr_t)VCPU_grsp(vcpu)); + + /* return to actual return address */ + VCPU_grip_set(vcpu, whitelist[curr].return_v); + + whitelist[curr].pal_running_vcpu_id=-1; + spin_unlock(&(whitelist[curr].pal_running_lock)); + eu_trace("released pal_running lock!"); + + perf_ctr_timer_record(&g_tv_perf_ctrs[TV_PERF_CTR_SWITCH_REGULAR], vcpu->idx); + + return rv; +} + +#if !defined(__LDN_TV_INTEGRATION__) +static bool hpt_error_wasInsnFetch(VCPU *vcpu, u64 errorcode) +{ + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + return (errorcode & EPT_ERRORCODE_EXEC); + } else if (vcpu->cpu_vendor != CPU_VENDOR_AMD) { + HALT_ON_ERRORCOND(0); + } + return (errorcode & VMCB_NPT_ERRORCODE_ID); +} +#endif //__LDN_TV_INTEGRATION__ + +/* EPT violation handler */ +u32 hpt_scode_npf(VCPU * vcpu, uintptr_t gpaddr, u64 errorcode, struct regs *r) +{ + int index = -1; + + int * curr=&(scode_curr[vcpu->id]); + u64 gcr3 = VCPU_gcr3(vcpu); + uintptr_t rip = (uintptr_t)VCPU_grip(vcpu); + u32 g64; + u32 err=1; + +#if defined(__LDN_TV_INTEGRATION__) + (void)errorcode; +#endif //__LDN_TV_INTEGRATION__ + + perf_ctr_timer_start(&g_tv_perf_ctrs[TV_PERF_CTR_NPF], vcpu->idx); + +#if !defined(__LDN_TV_INTEGRATION__) + eu_trace("CPU(%02x): nested page fault!(rip %#lx, gcr3 %#llx, gpaddr %#lx, errorcode %llx)", + vcpu->id, rip, gcr3, gpaddr, errorcode); + + EU_CHK( hpt_error_wasInsnFetch(vcpu, errorcode)); +#endif //__LDN_TV_INTEGRATION__ + + g64 = VCPU_g64(vcpu); + index = scode_in_list(gcr3, rip, g64); + if ((*curr == -1) && (index >= 0)) { + /* regular code to sensitive code */ + + *curr = index; + EU_CHK( ((whitelist[*curr].entry_v == rip) + && (whitelist[*curr].entry_p == gpaddr)), + eu_err_e("Invalid entry point")); + + /* valid entry point, switch from regular code to sensitive code */ + EU_CHKN( hpt_scode_switch_scode(vcpu, r)); + + } else if ((*curr >=0) && (index < 0)) { + /* sensitive code to regular code */ + + EU_CHK( RETURN_FROM_PAL_ADDRESS == rip, + eu_err_e("SECURITY: invalid scode return point!")); + + /* valid return point, switch from sensitive code to regular code */ + + /* XXX FIXME: now return ponit is extracted from regular code stack, only support one scode function call */ + EU_CHKN( hpt_scode_switch_regular(vcpu)); + *curr = -1; + } else if ((*curr >=0) && (index >= 0)) { + /* sensitive code to sensitive code */ + if (*curr == index) + eu_err("SECURITY: incorrect scode EPT configuration!"); + else + eu_err("SECURITY: invalid access to scode mem region from other scodes!"); + goto out; + } else { +#if !defined(__LDN_TV_INTEGRATION__) + /* regular code to regular code */ + eu_err("incorrect regular code EPT configuration!"); +#endif //__LDN_TV_INTEGRATION__ + goto out; + } + + /* no errors, pseodu page fault canceled by nested paging */ + if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + ((struct _svm_vmcbfields*)vcpu->vmcb_vaddr_ptr)->eventinj.v = 0; + } /* FIXME - equivalent for intel? */ + + err=0; + out: + perf_ctr_timer_record(&g_tv_perf_ctrs[TV_PERF_CTR_NPF], vcpu->idx); + if(err) { + if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + /* errors, inject segfault to guest */ + struct _svm_vmcbfields* vmcb = (struct _svm_vmcbfields*)(vcpu->vmcb_vaddr_ptr); + vmcb->eventinj.vector=0xd; + vmcb->eventinj.type=EVENTINJ_TYPE_EXCEPTION; + vmcb->eventinj.ev=0x1; + vmcb->eventinj.v=0x1; + vmcb->eventinj.errorcode = 0; + } /* FIXME - equivalent for intel? */ + + *curr = -1; + } + return err; +} + +/* caller is responsible for flushing TLB */ +void scode_release_all_shared_pages(VCPU *vcpu, whitelist_entry_t* wle) +{ + int i; + + (void)vcpu; + + /* restore permissions for remapped sections */ + /* assumes that SHARED sections are contiguous and on the end of the sections array */ + for(i = wle->sections_num-1; + i >= 0 && wle->sections[i].section_type == TV_PAL_SECTION_SHARED; + i--) { + eu_trace("returning shared section num %d at 0x%08llx", i, wle->sections[i].pal_gva); + scode_return_section( &g_hptw_reg_host_ctx.super, + &wle->hptw_pal_host_ctx.super, + &wle->hptw_pal_checked_guest_ctx.super, + &wle->sections[i]); + wle->sections_num--; + } +} + +/* note- caller is responsible for flushing page tables afterwards */ +u32 scode_share_range(VCPU * vcpu, whitelist_entry_t *wle, u32 gva_base, u32 gva_len) +{ + u32 err=1; + hptw_emhf_checked_guest_ctx_t vcpu_guest_walk_ctx; + EU_CHKN( hptw_emhf_checked_guest_ctx_init_of_vcpu( &vcpu_guest_walk_ctx, vcpu)); + + EU_CHK( wle->sections_num < TV_MAX_SECTIONS); + + wle->sections[wle->sections_num] = (tv_pal_section_int_t) { + .reg_gva = gva_base, + .pal_gva = gva_base, + .size = gva_len, + .pal_prot = pal_prot_of_type(TV_PAL_SECTION_SHARED), + .reg_prot = reg_prot_of_type(TV_PAL_SECTION_SHARED), + .section_type = TV_PAL_SECTION_SHARED, + }; + + scode_lend_section( &g_hptw_reg_host_ctx.super, + &vcpu_guest_walk_ctx.super, + &wle->hptw_pal_host_ctx.super, + &wle->hptw_pal_checked_guest_ctx.super, + &wle->sections[wle->sections_num]); + + wle->sections_num++; + + err=0; + out: + return err; +} + +u32 scode_share_ranges(VCPU * vcpu, u32 scode_entry, u32 gva_base[], u32 gva_len[], u32 count) +{ + size_t i; + whitelist_entry_t* entry; + u32 g64; + u32 err=1; + + g64 = VCPU_g64(vcpu); + EU_CHK( entry = find_scode_by_entry(VCPU_gcr3(vcpu), scode_entry, g64)); + + for(i=0; i +#include +#include +#include +#include +#include + +#include "tlsf.h" +#include "tlsfbits.h" + +/*- +** Two Level Segregated Fit memory allocator, version 1.9. +** Written by Matthew Conte, and placed in the Public Domain. +** http://tlsf.baisoku.org +** +** Based on the original documentation by Miguel Masmano: +** http://rtportal.upv.es/rtmalloc/allocators/tlsf/index.shtml +** +** Please see the accompanying Readme.txt for implementation +** notes and caveats. +** +** This implementation was written to the specification +** of the document, therefore no GPL restrictions apply. +*/ + +/** + * Modified for TrustVisor. + */ + +/* +** Constants. +*/ + +/* Public constants: may be modified. */ +enum tlsf_public +{ + /* log2 of number of linear subdivisions of block sizes. */ + SL_INDEX_COUNT_LOG2 = 5, +}; + +/* Private constants: do not modify. */ +enum tlsf_private +{ +#if defined (TLSF_64BIT) + /* All allocation sizes and addresses are aligned to 8 bytes. */ + ALIGN_SIZE_LOG2 = 3, +#else + /* All allocation sizes and addresses are aligned to 4 bytes. */ + ALIGN_SIZE_LOG2 = 2, +#endif + ALIGN_SIZE = (1 << ALIGN_SIZE_LOG2), + + /* + ** We support allocations of sizes up to (1 << FL_INDEX_MAX) bits. + ** However, because we linearly subdivide the second-level lists, and + ** our minimum size granularity is 4 bytes, it doesn't make sense to + ** create first-level lists for sizes smaller than SL_INDEX_COUNT * 4, + ** or (1 << (SL_INDEX_COUNT_LOG2 + 2)) bytes, as there we will be + ** trying to split size ranges into more slots than we have available. + ** Instead, we calculate the minimum threshold size, and place all + ** blocks below that size into the 0th first-level list. + */ + +#if defined (TLSF_64BIT) + /* + ** TODO: We can increase this to support larger sizes, at the expense + ** of more overhead in the TLSF structure. + */ + FL_INDEX_MAX = 32, +#else + FL_INDEX_MAX = 30, +#endif + SL_INDEX_COUNT = (1 << SL_INDEX_COUNT_LOG2), + FL_INDEX_SHIFT = (SL_INDEX_COUNT_LOG2 + ALIGN_SIZE_LOG2), + FL_INDEX_COUNT = (FL_INDEX_MAX - FL_INDEX_SHIFT + 1), + + SMALL_BLOCK_SIZE = (1 << FL_INDEX_SHIFT), +}; + +/* +** Cast and min/max macros. +*/ + +#define tlsf_cast(t, exp) ((t) (exp)) +#define tlsf_min(a, b) ((a) < (b) ? (a) : (b)) +#define tlsf_max(a, b) ((a) > (b) ? (a) : (b)) + +/* +** Set assert macro, if it has not been provided by the user. +*/ +#if !defined (tlsf_assert) +#define tlsf_assert assert +#endif + +/* +** Static assertion mechanism. +*/ + +#define _tlsf_glue2(x, y) x ## y +#define _tlsf_glue(x, y) _tlsf_glue2(x, y) +#define tlsf_static_assert(exp) \ + typedef char _tlsf_glue(static_assert, __LINE__) [(exp) ? 1 : -1] + +/* This code has been tested on 32- and 64-bit (LP/LLP) architectures. */ +tlsf_static_assert(sizeof(int) * CHAR_BIT == 32); +tlsf_static_assert(sizeof(size_t) * CHAR_BIT >= 32); +tlsf_static_assert(sizeof(size_t) * CHAR_BIT <= 64); + +/* SL_INDEX_COUNT must be <= number of bits in sl_bitmap's storage type. */ +tlsf_static_assert(sizeof(unsigned int) * CHAR_BIT >= SL_INDEX_COUNT); + +/* Ensure we've properly tuned our sizes. */ +tlsf_static_assert(ALIGN_SIZE == SMALL_BLOCK_SIZE / SL_INDEX_COUNT); + +/* +** Data structures and associated constants. +*/ + +/* +** Block header structure. +** +** There are several implementation subtleties involved: +** - The prev_phys_block field is only valid if the previous block is free. +** - The prev_phys_block field is actually stored at the end of the +** previous block. It appears at the beginning of this structure only to +** simplify the implementation. +** - The next_free / prev_free fields are only valid if the block is free. +*/ +typedef struct block_header_t +{ + /* Points to the previous physical block. */ + struct block_header_t* prev_phys_block; + + /* The size of this block, excluding the block header. */ + size_t size; + + /* Next and previous free blocks. */ + struct block_header_t* next_free; + struct block_header_t* prev_free; +} block_header_t; + +/* +** Since block sizes are always at least a multiple of 4, the two least +** significant bits of the size field are used to store the block status: +** - bit 0: whether block is busy or free +** - bit 1: whether previous block is busy or free +*/ +static const size_t block_header_free_bit = 1 << 0; +static const size_t block_header_prev_free_bit = 1 << 1; + +/* +** The size of the block header exposed to used blocks is the size field. +** The prev_phys_block field is stored *inside* the previous free block. +*/ +static const size_t block_header_overhead = sizeof(size_t); + +/* User data starts directly after the size field in a used block. */ +static const size_t block_start_offset = + offsetof(block_header_t, size) + sizeof(size_t); + +/* +** A free block must be large enough to store its header minus the size of +** the prev_phys_block field, and no larger than the number of addressable +** bits for FL_INDEX. +*/ +static const size_t block_size_min = + sizeof(block_header_t) - sizeof(block_header_t*); +static const size_t block_size_max = tlsf_cast(size_t, 1) << FL_INDEX_MAX; + + +/* The TLSF pool structure. */ +typedef struct pool_t +{ + /* Empty lists point at this block to indicate they are free. */ + block_header_t block_null; + + /* Bitmaps for free lists. */ + unsigned int fl_bitmap; + unsigned int sl_bitmap[FL_INDEX_COUNT]; + + /* Head of free lists. */ + block_header_t* blocks[FL_INDEX_COUNT][SL_INDEX_COUNT]; +} pool_t; + +/* A type used for casting when doing pointer arithmetic. */ +typedef ptrdiff_t tlsfptr_t; + +/* +** block_header_t member functions. +*/ + +static size_t block_size(const block_header_t* block) +{ + return block->size & ~(block_header_free_bit | block_header_prev_free_bit); +} + +static void block_set_size(block_header_t* block, size_t size) +{ + const size_t oldsize = block->size; + block->size = size | (oldsize & (block_header_free_bit | block_header_prev_free_bit)); +} + +static int block_is_last(const block_header_t* block) +{ + return 0 == block_size(block); +} + +static int block_is_free(const block_header_t* block) +{ + return tlsf_cast(int, block->size & block_header_free_bit); +} + +static void block_set_free(block_header_t* block) +{ + block->size |= block_header_free_bit; +} + +static void block_set_used(block_header_t* block) +{ + block->size &= ~block_header_free_bit; +} + +static int block_is_prev_free(const block_header_t* block) +{ + return tlsf_cast(int, block->size & block_header_prev_free_bit); +} + +static void block_set_prev_free(block_header_t* block) +{ + block->size |= block_header_prev_free_bit; +} + +static void block_set_prev_used(block_header_t* block) +{ + block->size &= ~block_header_prev_free_bit; +} + +static block_header_t* block_from_ptr(const void* ptr) +{ + return tlsf_cast(block_header_t*, + tlsf_cast(unsigned char*, ptr) - block_start_offset); +} + +static void* block_to_ptr(const block_header_t* block) +{ + return tlsf_cast(void*, + tlsf_cast(unsigned char*, block) + block_start_offset); +} + +/* Return location of next block after block of given size. */ +static block_header_t* offset_to_block(const void* ptr, size_t size) +{ + return tlsf_cast(block_header_t*, tlsf_cast(tlsfptr_t, ptr) + size); +} + +/* Return location of previous block. */ +static block_header_t* block_prev(const block_header_t* block) +{ + return block->prev_phys_block; +} + +/* Return location of next existing block. */ +static block_header_t* block_next(const block_header_t* block) +{ + block_header_t* next = offset_to_block(block_to_ptr(block), + block_size(block) - block_header_overhead); + tlsf_assert(!block_is_last(block)); + return next; +} + +/* Link a new block with its physical neighbor, return the neighbor. */ +static block_header_t* block_link_next(block_header_t* block) +{ + block_header_t* next = block_next(block); + next->prev_phys_block = block; + return next; +} + +static void block_mark_as_free(block_header_t* block) +{ + /* Link the block to the next block, first. */ + block_header_t* next = block_link_next(block); + block_set_prev_free(next); + block_set_free(block); +} + +static void block_mark_as_used(block_header_t* block) +{ + block_header_t* next = block_next(block); + block_set_prev_used(next); + block_set_used(block); +} + +static size_t align_up(size_t x, size_t align) +{ + tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two"); + return (x + (align - 1)) & ~(align - 1); +} + +static size_t align_down(size_t x, size_t align) +{ + tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two"); + return x - (x & (align - 1)); +} + +static void* align_ptr(const void* ptr, size_t align) +{ + const tlsfptr_t aligned = + (tlsf_cast(tlsfptr_t, ptr) + (align - 1)) & ~(align - 1); + tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two"); + return tlsf_cast(void*, aligned); +} + +/* +** Adjust an allocation size to be aligned to word size, and no smaller +** than internal minimum. +*/ +static size_t adjust_request_size(size_t size, size_t align) +{ + size_t adjust = 0; + if (size && size < block_size_max) + { + const size_t aligned = align_up(size, align); + adjust = tlsf_max(aligned, block_size_min); + } + return adjust; +} + +/* +** TLSF utility functions. In most cases, these are direct translations of +** the documentation found in the white paper. +*/ + +static void mapping_insert(size_t size, int* fli, int* sli) +{ + int fl, sl; + if (size < SMALL_BLOCK_SIZE) + { + /* Store small blocks in first list. */ + fl = 0; + sl = tlsf_cast(int, size) / (SMALL_BLOCK_SIZE / SL_INDEX_COUNT); + } + else + { + fl = tlsf_fls_sizet(size); + sl = tlsf_cast(int, size >> (fl - SL_INDEX_COUNT_LOG2)) ^ (1 << SL_INDEX_COUNT_LOG2); + fl -= (FL_INDEX_SHIFT - 1); + } + *fli = fl; + *sli = sl; +} + +/* This version rounds up to the next block size (for allocations) */ +static void mapping_search(size_t size, int* fli, int* sli) +{ + if (size >= (1 << SL_INDEX_COUNT_LOG2)) + { + const size_t round = (1 << (tlsf_fls_sizet(size) - SL_INDEX_COUNT_LOG2)) - 1; + size += round; + } + mapping_insert(size, fli, sli); +} + +static block_header_t* search_suitable_block(pool_t* pool, int* fli, int* sli) +{ + int fl = *fli; + int sl = *sli; + + /* + ** First, search for a block in the list associated with the given + ** fl/sl index. + */ + unsigned int sl_map = pool->sl_bitmap[fl] & (~0UL << sl); + if (!sl_map) + { + /* No block exists. Search in the next largest first-level list. */ + const unsigned int fl_map = pool->fl_bitmap & (~0UL << (fl + 1)); + if (!fl_map) + { + /* No free blocks available, memory has been exhausted. */ + return 0; + } + + fl = tlsf_ffs(fl_map); + *fli = fl; + sl_map = pool->sl_bitmap[fl]; + } + tlsf_assert(sl_map && "internal error - second level bitmap is null"); + sl = tlsf_ffs(sl_map); + *sli = sl; + + /* Return the first block in the free list. */ + return pool->blocks[fl][sl]; +} + +/* Remove a free block from the free list.*/ +static void remove_free_block(pool_t* pool, block_header_t* block, int fl, int sl) +{ + block_header_t* prev = block->prev_free; + block_header_t* next = block->next_free; + tlsf_assert(prev && "prev_free field can not be null"); + tlsf_assert(next && "next_free field can not be null"); + next->prev_free = prev; + prev->next_free = next; + + /* If this block is the head of the free list, set new head. */ + if (pool->blocks[fl][sl] == block) + { + pool->blocks[fl][sl] = next; + + /* If the new head is null, clear the bitmap. */ + if (next == &pool->block_null) + { + pool->sl_bitmap[fl] &= ~(1 << sl); + + /* If the second bitmap is now empty, clear the fl bitmap. */ + if (!pool->sl_bitmap[fl]) + { + pool->fl_bitmap &= ~(1 << fl); + } + } + } +} + +/* Insert a free block into the free block list. */ +static void insert_free_block(pool_t* pool, block_header_t* block, int fl, int sl) +{ + block_header_t* current = pool->blocks[fl][sl]; + tlsf_assert(current && "free list cannot have a null entry"); + tlsf_assert(block && "cannot insert a null entry into the free list"); + block->next_free = current; + block->prev_free = &pool->block_null; + current->prev_free = block; + + tlsf_assert(block_to_ptr(block) == align_ptr(block_to_ptr(block), ALIGN_SIZE) + && "block not aligned properly"); + /* + ** Insert the new block at the head of the list, and mark the first- + ** and second-level bitmaps appropriately. + */ + pool->blocks[fl][sl] = block; + pool->fl_bitmap |= (1 << fl); + pool->sl_bitmap[fl] |= (1 << sl); +} + +/* Remove a given block from the free list. */ +static void block_remove(pool_t* pool, block_header_t* block) +{ + int fl, sl; + mapping_insert(block_size(block), &fl, &sl); + remove_free_block(pool, block, fl, sl); +} + +/* Insert a given block into the free list. */ +static void block_insert(pool_t* pool, block_header_t* block) +{ + int fl, sl; + mapping_insert(block_size(block), &fl, &sl); + insert_free_block(pool, block, fl, sl); +} + +static int block_can_split(block_header_t* block, size_t size) +{ + return block_size(block) >= sizeof(block_header_t) + size; +} + +/* Split a block into two, the second of which is free. */ +static block_header_t* block_split(block_header_t* block, size_t size) +{ + /* Calculate the amount of space left in the remaining block. */ + block_header_t* remaining = + offset_to_block(block_to_ptr(block), size - block_header_overhead); + + const size_t remain_size = block_size(block) - (size + block_header_overhead); + + tlsf_assert(block_to_ptr(remaining) == align_ptr(block_to_ptr(remaining), ALIGN_SIZE) + && "remaining block not aligned properly"); + + tlsf_assert(block_size(block) == remain_size + size + block_header_overhead); + block_set_size(remaining, remain_size); + tlsf_assert(block_size(remaining) >= block_size_min && "block split with invalid size"); + + block_set_size(block, size); + block_mark_as_free(remaining); + + return remaining; +} + +/* Absorb a free block's storage into an adjacent previous free block. */ +static block_header_t* block_absorb(block_header_t* prev, block_header_t* block) +{ + tlsf_assert(!block_is_last(prev) && "previous block can't be last!"); + /* Note: Leaves flags untouched. */ + prev->size += block_size(block) + block_header_overhead; + block_link_next(prev); + return prev; +} + +/* Merge a just-freed block with an adjacent previous free block. */ +static block_header_t* block_merge_prev(pool_t* pool, block_header_t* block) +{ + if (block_is_prev_free(block)) + { + block_header_t* prev = block_prev(block); + tlsf_assert(prev && "prev physical block can't be null"); + tlsf_assert(block_is_free(prev) && "prev block is not free though marked as such"); + block_remove(pool, prev); + block = block_absorb(prev, block); + } + + return block; +} + +/* Merge a just-freed block with an adjacent free block. */ +static block_header_t* block_merge_next(pool_t* pool, block_header_t* block) +{ + block_header_t* next = block_next(block); + tlsf_assert(next && "next physical block can't be null"); + + if (block_is_free(next)) + { + tlsf_assert(!block_is_last(block) && "previous block can't be last!"); + block_remove(pool, next); + block = block_absorb(block, next); + } + + return block; +} + +/* Trim any trailing block space off the end of a block, return to pool. */ +static void block_trim_free(pool_t* pool, block_header_t* block, size_t size) +{ + tlsf_assert(block_is_free(block) && "block must be free"); + if (block_can_split(block, size)) + { + block_header_t* remaining_block = block_split(block, size); + block_link_next(block); + block_set_prev_free(remaining_block); + block_insert(pool, remaining_block); + } +} + +/* Trim any trailing block space off the end of a used block, return to pool. */ +static void block_trim_used(pool_t* pool, block_header_t* block, size_t size) +{ + tlsf_assert(!block_is_free(block) && "block must be used"); + if (block_can_split(block, size)) + { + /* If the next block is free, we must coalesce. */ + block_header_t* remaining_block = block_split(block, size); + block_set_prev_used(remaining_block); + + remaining_block = block_merge_next(pool, remaining_block); + block_insert(pool, remaining_block); + } +} + +static block_header_t* block_trim_free_leading(pool_t* pool, block_header_t* block, size_t size) +{ + block_header_t* remaining_block = block; + if (block_can_split(block, size)) + { + /* We want the 2nd block. */ + remaining_block = block_split(block, size - block_header_overhead); + block_set_prev_free(remaining_block); + + block_link_next(block); + block_insert(pool, block); + } + + return remaining_block; +} + +static block_header_t* block_locate_free(pool_t* pool, size_t size) +{ + int fl = 0, sl = 0; + block_header_t* block = 0; + + if (size) + { + mapping_search(size, &fl, &sl); + block = search_suitable_block(pool, &fl, &sl); + } + + if (block) + { + tlsf_assert(block_size(block) >= size); + remove_free_block(pool, block, fl, sl); + } + + return block; +} + +static void* block_prepare_used(pool_t* pool, block_header_t* block, size_t size) +{ + void* p = 0; + if (block) + { + block_trim_free(pool, block, size); + block_mark_as_used(block); + p = block_to_ptr(block); + } + return p; +} + +/* Clear structure and point all empty lists at the null block. */ +static void pool_construct(pool_t* pool) +{ + int i, j; + + pool->block_null.next_free = &pool->block_null; + pool->block_null.prev_free = &pool->block_null; + + pool->fl_bitmap = 0; + for (i = 0; i < FL_INDEX_COUNT; ++i) + { + pool->sl_bitmap[i] = 0; + for (j = 0; j < SL_INDEX_COUNT; ++j) + { + pool->blocks[i][j] = &pool->block_null; + } + } +} + +/* +** Debugging utilities. +*/ + +typedef struct integrity_t +{ + int prev_status; + int status; +} integrity_t; + +#define tlsf_insist(x) { tlsf_assert(x); if (!(x)) { status--; } } + +static void integrity_walker(void* ptr, size_t size, int used, void* user) +{ + block_header_t* block = block_from_ptr(ptr); + integrity_t* integ = tlsf_cast(integrity_t*, user); + const int this_prev_status = block_is_prev_free(block) ? 1 : 0; + const int this_status = block_is_free(block) ? 1 : 0; + const size_t this_block_size = block_size(block); + + int status = 0; + tlsf_insist(integ->prev_status == this_prev_status && "prev status incorrect"); + tlsf_insist(size == this_block_size && "block size incorrect"); + + integ->prev_status = this_status; + integ->status += status; + + used = used; /* appease compiler */ +} + +int tlsf_check_heap(tlsf_pool tlsf) +{ + int i, j; + + pool_t* pool = tlsf_cast(pool_t*, tlsf); + int status = 0; + + /* Check that the blocks are physically correct. */ + integrity_t integ = { 0, 0 }; + tlsf_walk_heap(tlsf, integrity_walker, &integ); + status = integ.status; + + /* Check that the free lists and bitmaps are accurate. */ + for (i = 0; i < FL_INDEX_COUNT; ++i) + { + for (j = 0; j < SL_INDEX_COUNT; ++j) + { + const int fl_map = pool->fl_bitmap & (1 << i); + const int sl_list = pool->sl_bitmap[i]; + const int sl_map = sl_list & (1 << j); + const block_header_t* block = pool->blocks[i][j]; + + /* Check that first- and second-level lists agree. */ + if (!fl_map) + { + tlsf_insist(!sl_map && "second-level map must be null"); + } + + if (!sl_map) + { + tlsf_insist(block == &pool->block_null && "block list must be null"); + continue; + } + + /* Check that there is at least one free block. */ + tlsf_insist(sl_list && "no free blocks in second-level map"); + tlsf_insist(block != &pool->block_null && "block should not be null"); + + while (block != &pool->block_null) + { + int fli, sli; + tlsf_insist(block_is_free(block) && "block should be free"); + tlsf_insist(!block_is_prev_free(block) && "blocks should have coalesced"); + tlsf_insist(!block_is_free(block_next(block)) && "blocks should have coalesced"); + tlsf_insist(block_is_prev_free(block_next(block)) && "block should be free"); + tlsf_insist(block_size(block) >= block_size_min && "block not minimum size"); + + mapping_insert(block_size(block), &fli, &sli); + tlsf_insist(fli == i && sli == j && "block size indexed in wrong list"); + block = block->next_free; + } + } + } + + return status; +} + +#undef tlsf_insist + +static void default_walker(void* ptr, size_t size, int used, void* user) +{ + (void)user; + printf("\t%p %s size: %x (%p)\n", ptr, used ? "used" : "free", (unsigned int)size, block_from_ptr(ptr)); +} + +void tlsf_walk_heap(tlsf_pool pool, tlsf_walker walker, void* user) +{ + tlsf_walker heap_walker = walker ? walker : default_walker; + block_header_t* block = + offset_to_block(pool, sizeof(pool_t) - block_header_overhead); + + while (block && !block_is_last(block)) + { + heap_walker( + block_to_ptr(block), + block_size(block), + !block_is_free(block), + user); + block = block_next(block); + } +} + +size_t tlsf_block_size(void* ptr) +{ + size_t size = 0; + if (ptr) + { + const block_header_t* block = block_from_ptr(ptr); + size = block_size(block); + } + return size; +} + +/* +** Overhead of the TLSF structures in a given memory block passed to +** tlsf_create, equal to the size of a pool_t plus overhead of the initial +** free block and the sentinel block. +*/ +size_t tlsf_overhead() +{ + const size_t pool_overhead = sizeof(pool_t) + 2 * block_header_overhead; + return pool_overhead; +} + +/* +** TLSF main interface. Right out of the white paper. +*/ + +tlsf_pool tlsf_create(void* mem, size_t bytes) +{ + block_header_t* block; + block_header_t* next; + + const size_t pool_overhead = tlsf_overhead(); + const size_t pool_bytes = align_down(bytes - pool_overhead, ALIGN_SIZE); + pool_t* pool = tlsf_cast(pool_t*, mem); + +#if _DEBUG + /* Verify ffs/fls work properly. */ + int rv = 0; + rv += (tlsf_ffs(0) == -1) ? 0 : 0x1; + rv += (tlsf_fls(0) == -1) ? 0 : 0x2; + rv += (tlsf_ffs(1) == 0) ? 0 : 0x4; + rv += (tlsf_fls(1) == 0) ? 0 : 0x8; + rv += (tlsf_ffs(0x80000000) == 31) ? 0 : 0x10; + rv += (tlsf_ffs(0x80008000) == 15) ? 0 : 0x20; + rv += (tlsf_fls(0x80000008) == 31) ? 0 : 0x40; + rv += (tlsf_fls(0x7FFFFFFF) == 30) ? 0 : 0x80; + +#if defined (TLSF_64BIT) + rv += (tlsf_fls_sizet(0x80000000) == 31) ? 0 : 0x100; + rv += (tlsf_fls_sizet(0x100000000) == 32) ? 0 : 0x200; + rv += (tlsf_fls_sizet(0xffffffffffffffff) == 63) ? 0 : 0x400; + if (rv) + { + printf("tlsf_create: %x ffs/fls tests failed!\n", rv); + return 0; + } +#endif +#endif + + if (pool_bytes < block_size_min || pool_bytes > block_size_max) + { +#if defined (TLSF_64BIT) + printf("tlsf_create: Pool size must be at least %d bytes.\n", + (unsigned int)(pool_overhead + block_size_min)); +#else + printf("tlsf_create: Pool size must be between %u and %u bytes.\n", + (unsigned int)(pool_overhead + block_size_min), + (unsigned int)(pool_overhead + block_size_max)); +#endif + return 0; + } + + /* Construct a valid pool object. */ + pool_construct(pool); + + /* + ** Create the main free block. Offset the start of the block slightly + ** so that the prev_phys_block field falls inside of the pool + ** structure - it will never be used. + */ + block = offset_to_block( + tlsf_cast(void*, pool), sizeof(pool_t) - block_header_overhead); + block_set_size(block, pool_bytes); + block_set_free(block); + block_set_prev_used(block); + block_insert(pool, block); + + /* Split the block to create a zero-size pool sentinel block. */ + next = block_link_next(block); + block_set_size(next, 0); + block_set_used(next); + block_set_prev_free(next); + + return tlsf_cast(tlsf_pool, pool); +} + +void tlsf_destroy(tlsf_pool pool) +{ + /* Nothing to do. */ + pool = pool; +} + +void* tlsf_malloc(tlsf_pool tlsf, size_t size) +{ + pool_t* pool = tlsf_cast(pool_t*, tlsf); + const size_t adjust = adjust_request_size(size, ALIGN_SIZE); + block_header_t* block = block_locate_free(pool, adjust); + return block_prepare_used(pool, block, adjust); +} + +void* tlsf_memalign(tlsf_pool tlsf, size_t align, size_t size) +{ + pool_t* pool = tlsf_cast(pool_t*, tlsf); + const size_t adjust = adjust_request_size(size, ALIGN_SIZE); + + /* + ** We must allocate an additional minimum block size bytes so that if + ** our free block will leave an alignment gap which is smaller, we can + ** trim a leading free block and release it back to the heap. We must + ** do this because the previous physical block is in use, therefore + ** the prev_phys_block field is not valid, and we can't simply adjust + ** the size of that block. + */ + const size_t gap_minimum = sizeof(block_header_t); + const size_t size_with_gap = adjust_request_size(adjust + align + gap_minimum, align); + + /* If alignment is less than or equals base alignment, we're done. */ + const size_t aligned_size = (align <= ALIGN_SIZE) ? adjust : size_with_gap; + + block_header_t* block = block_locate_free(pool, aligned_size); + + /* This can't be a static assert. */ + tlsf_assert(sizeof(block_header_t) == block_size_min + block_header_overhead); + + if (block) + { + void* ptr = block_to_ptr(block); + void* aligned = align_ptr(ptr, align); + size_t gap = tlsf_cast(size_t, + tlsf_cast(tlsfptr_t, aligned) - tlsf_cast(tlsfptr_t, ptr)); + + /* If gap size is too small, offset to next aligned boundary. */ + if (gap && gap < gap_minimum) + { + const size_t gap_remain = gap_minimum - gap; + const size_t offset = tlsf_max(gap_remain, align); + const void* next_aligned = tlsf_cast(void*, + tlsf_cast(tlsfptr_t, aligned) + offset); + + aligned = align_ptr(next_aligned, align); + gap = tlsf_cast(size_t, + tlsf_cast(tlsfptr_t, aligned) - tlsf_cast(tlsfptr_t, ptr)); + } + + if (gap) + { + tlsf_assert(gap >= gap_minimum && "gap size too small"); + block = block_trim_free_leading(pool, block, gap); + } + } + + return block_prepare_used(pool, block, adjust); +} + +void tlsf_free(tlsf_pool tlsf, void* ptr) +{ + /* Don't attempt to free a NULL pointer. */ + if (ptr) + { + pool_t* pool = tlsf_cast(pool_t*, tlsf); + block_header_t* block = block_from_ptr(ptr); + block_mark_as_free(block); + block = block_merge_prev(pool, block); + block = block_merge_next(pool, block); + block_insert(pool, block); + } +} + +/* +** The TLSF block information provides us with enough information to +** provide a reasonably intelligent implementation of realloc, growing or +** shrinking the currently allocated block as required. +** +** This routine handles the somewhat esoteric edge cases of realloc: +** - a non-zero size with a null pointer will behave like malloc +** - a zero size with a non-null pointer will behave like free +** - a request that cannot be satisfied will leave the original buffer +** untouched +** - an extended buffer size will leave the newly-allocated area with +** contents undefined +*/ +void* tlsf_realloc(tlsf_pool tlsf, void* ptr, size_t size) +{ + pool_t* pool = tlsf_cast(pool_t*, tlsf); + void* p = 0; + + /* Zero-size requests are treated as free. */ + if (ptr && size == 0) + { + tlsf_free(tlsf, ptr); + } + /* Requests with NULL pointers are treated as malloc. */ + else if (!ptr) + { + p = tlsf_malloc(tlsf, size); + } + else + { + block_header_t* block = block_from_ptr(ptr); + block_header_t* next = block_next(block); + + const size_t cursize = block_size(block); + const size_t combined = cursize + block_size(next) + block_header_overhead; + const size_t adjust = adjust_request_size(size, ALIGN_SIZE); + + /* + ** If the next block is used, or when combined with the current + ** block, does not offer enough space, we must reallocate and copy. + */ + if (adjust > cursize && (!block_is_free(next) || adjust > combined)) + { + p = tlsf_malloc(tlsf, size); + if (p) + { + const size_t minsize = tlsf_min(cursize, size); + memcpy(p, ptr, minsize); + tlsf_free(tlsf, ptr); + } + } + else + { + /* Do we need to expand to the next block? */ + if (adjust > cursize) + { + block_merge_next(pool, block); + block_mark_as_used(block); + } + + /* Trim the resulting block and return the original pointer. */ + block_trim_used(pool, block, adjust); + p = ptr; + } + } + + return p; +} diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/Makefile b/xmhf-64/hypapps/trustvisor/tee-sdk/Makefile new file mode 100644 index 0000000000..66376bba13 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/Makefile @@ -0,0 +1,55 @@ +# target platform when building a compiler (tsvc) +TARGET=i586-tsvc +# machine where software will run (for pal-code) +TSVC_HOST=$(TARGET) +# machine where software will run (for reg-world code) +HOST=i686-pc-linux-gnu +# machine where software will be built +BUILD=i686-pc-linux-gnu +# where reg-world software will be installed +PREFIX=/usr/local +# where pal software (libraries, headers, etc.) will be installed +TSVC_SYSROOT=$(PREFIX)/$(TSVC_HOST) + +all: toolchain newlib tz_host tz_cross + +toolchain: + cd toolchain && \ + ./autogen.sh && \ + ./configure --prefix=$(PREFIX) --host=$(HOST) --target=$(TARGET) --build=$(BUILD) && \ + make && \ + make install + +newlib: toolchain + export PATH=$(PREFIX)/bin:$(PATH) && \ + cd ports/newlib && \ + PREFIX=$(PREFIX) HOST=$(TSVC_HOST) ./build.sh + +tz_autoreconf: + cd tz && autoreconf -i + +tz_host: tz_autoreconf + export PKG_CONFIG_PATH=$(PREFIX)/lib/pkgconfig && \ + export PATH=$(PREFIX)/bin:$(PATH) && \ + cd tz && \ + mkdir -p build-$(HOST) && \ + cd build-$(HOST) && \ + ../configure --prefix=$(PREFIX) --host=$(HOST) --build=$(BUILD) && \ + make && \ + make install + +tz_cross: tz_autoreconf toolchain newlib + export PATH=$(PREFIX)/bin:$(PATH) && \ + cd tz && \ + mkdir -p build-$(TSVC_HOST) && \ + cd build-$(TSVC_HOST) && \ + ../configure --prefix=$(TSVC_SYSROOT)/usr --host=$(TSVC_HOST) --build=$(BUILD) && \ + make && \ + make install + +openssl: toolchain newlib + export PATH=$(PREFIX)/bin:$(PATH) && \ + cd ports/openssl && \ + PREFIX=$(TSVC_SYSROOT)/usr HOST=$(TSVC_HOST) ./build.sh + +.PHONY: toolchain newlib openssl tz_host tz_cross tz_autoreconf diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/examples/newlib/Makefile b/xmhf-64/hypapps/trustvisor/tee-sdk/examples/newlib/Makefile new file mode 100644 index 0000000000..155a28c978 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/examples/newlib/Makefile @@ -0,0 +1,32 @@ +# Makefile made with help from http://www.hsrl.rutgers.edu/ug/make_help.html +# $@ is the name of the file to be made. +# $? is the names of the changed dependents. +# $< the name of the related file that caused the action. +# $* the prefix shared by target and dependent files. + +PROG_NAME=hello +PROG_OBJS=hello.o +CFLAGS+=-g -Wall +PKGCONFIG_DEPS=tee-sdk-app tee-sdk-app-tv + +PAL_NAME=hellopal +PAL_OBJS=hellopal.o pal-aux.o +PAL_CFLAGS+=-g -Wall +PAL_PKGCONFIG_DEPS=tee-sdk-svc tee-sdk-svc-tv + +all: $(PROG_NAME) +clean: + $(RM) .*.cmd *.o *.ko *~ -r .tmp* $(PROG_NAME) $(PROG_OBJS) +.PHONY: clean all + +TEESDK_DATA_DIR=$(shell pkg-config --variable=pkgdatadir tee-sdk-app) + +# pkgconfig helpers +include $(TEESDK_DATA_DIR)/pkgconfig.mk + +# rules for compiling pal intermediate objects +include $(TEESDK_DATA_DIR)/pal.mk + +# rules for compiling a program PROG_NAME that uses one pal PAL_NAME +include $(TEESDK_DATA_DIR)/onepal.mk + diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/examples/newlib/hello.c b/xmhf-64/hypapps/trustvisor/tee-sdk/examples/newlib/hello.c new file mode 100644 index 0000000000..68db3248f8 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/examples/newlib/hello.c @@ -0,0 +1,120 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * Author - Jim Newsome (jnewsome@no-fuss.com) + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "rtassert.h" + +#include "pal.h" + +#define rtassert_tzs(x) rtassert_eq(x, TZ_SUCCESS) + +static int call_pal(tz_session_t *tzPalSession) +{ + tz_operation_t tzOp; + tz_return_t tzRet, serviceReturn; + int rv=0; + + rtassert_tzs( + TZOperationPrepareInvoke(tzPalSession, + PAL_HELLO, + NULL, + &tzOp)); + + tzRet = TZOperationPerform(&tzOp, &serviceReturn); + if (tzRet != TZ_SUCCESS) { + if (tzRet == TZ_ERROR_SERVICE) { + printf("withoutparam pal returned error %d\n", + serviceReturn); + rv = 1; + } else { + printf("tz system returned error %d\n", + tzRet); + rv = 1; + } + } + TZOperationRelease(&tzOp); + + return rv; +} + +int main(void) +{ + tz_device_t tzDevice; + tz_session_t tzPalSession; + tz_uuid_t tzSvcId; + int rv=0; + + /* tz_return_t trv; */ + /* hellopal(PAL_HELLO, NULL, NULL, &trv); */ + /* printf("got trv=%d\n", trv); */ + + rtassert_tzs(tv_tz_init(&tzDevice, + &tzPalSession, + &tzSvcId, + hellopal, + PAGE_SIZE, + PAGE_SIZE)); + + rv = call_pal(&tzPalSession); + + rtassert_tzs(tv_tz_teardown(&tzDevice, + &tzPalSession, + &tzSvcId)); + + return rv; +} diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/examples/newlib/hellopal.c b/xmhf-64/hypapps/trustvisor/tee-sdk/examples/newlib/hellopal.c new file mode 100644 index 0000000000..3ea71a4c41 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/examples/newlib/hellopal.c @@ -0,0 +1,65 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include +#include +#include "pal.h" + +#include +#include + +char end[10*4096]; /* define the end of the data segment and some + buffer spacefor libnosys's sbrk */ + +int test(); + +void hellopal(uint32_t uiCommand, tzi_encode_buffer_t *psInBuf, tzi_encode_buffer_t *psOutBuf, tz_return_t *puiRv) +{ + printf("test, %d\n", 5); + test(); + *puiRv = TZ_SUCCESS; + return; +} diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/examples/newlib/pal-aux.c b/xmhf-64/hypapps/trustvisor/tee-sdk/examples/newlib/pal-aux.c new file mode 100644 index 0000000000..4822edcc36 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/examples/newlib/pal-aux.c @@ -0,0 +1,50 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +int test() +{ + return 5; +} diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/examples/newlib/pal.h b/xmhf-64/hypapps/trustvisor/tee-sdk/examples/newlib/pal.h new file mode 100644 index 0000000000..d2e7bdda9b --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/examples/newlib/pal.h @@ -0,0 +1,61 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef PAL_H +#define PAL_H + +#include +#include + +#include + +typedef enum { + PAL_HELLO, +} PAL_CMD; + +void hellopal(uint32_t uiCommand, tzi_encode_buffer_t *psInBuf, tzi_encode_buffer_t *psOutBuf, tz_return_t *puiRv); + +#endif diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/examples/newlib/rtassert.h b/xmhf-64/hypapps/trustvisor/tee-sdk/examples/newlib/rtassert.h new file mode 100644 index 0000000000..f615fd8624 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/examples/newlib/rtassert.h @@ -0,0 +1,90 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * Author - Jim Newsome (jnewsome@no-fuss.com) + */ + +#ifndef RTASSERT_H +#define RTASSERT_H + +#ifndef RTA_PRINT +#include +#define RTA_PRINT(fmt, args...) fprintf(stderr, fmt , ## args) /* the spaces are important */ +#endif + +#ifndef RTA_EXIT +#define RTA_EXIT(x) exit(x) +#endif + +/* distinguish from regular assert, which are for conditions that + should always hold unless there was a programming error. This is + for unhandled run-time errors that could conceivably happen. (e.g., + out of memory, system call returns an error, etc.), and therefore + should never be disabled, unlike regular assert which may be + disabled in production. also add an error string. */ + +#define rtassert_eq(got, expected) \ + do { \ + int _got = (got); \ + int _expected = (expected); \ + if(_got != _expected) { \ + RTA_PRINT("unhandled run-time error." \ + " expected %d got %d" \ + " at %s:%d", \ + _expected, \ + _got, \ + __FILE__, \ + __LINE__); \ + RTA_EXIT(1); \ + } \ + } while(0) + +#define rtassert_not(x) rtassert_eq(x, 0) + +#define rtassert(x) rtassert_not(!(x), 0) + +#endif diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/examples/test/Makefile b/xmhf-64/hypapps/trustvisor/tee-sdk/examples/test/Makefile new file mode 100644 index 0000000000..afbdd385a9 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/examples/test/Makefile @@ -0,0 +1,83 @@ +# Makefile made with help from http://www.hsrl.rutgers.edu/ug/make_help.html +# $@ is the name of the file to be made. +# $? is the names of the changed dependents. +# $< the name of the related file that caused the action. +# $* the prefix shared by target and dependent files. + +TESTS= +TESTS+=-DTEST_VMMCALL +TESTS+=-DTEST_WITHOUTPARAM +TESTS+=-DTEST_PARAM +TESTS+=-DTEST_SEAL +TESTS+=-DTEST_LTSEAL +TESTS+=-DTEST_QUOTE +TESTS+=-DTEST_PCR_EXTEND +TESTS+=-DTEST_PCR_READ +TESTS+=-DTEST_RAND +TESTS+=-DTEST_TIME +#TESTS+=-DTEST_NV_ROLLBACK + +# Set to 1 to use 'null' backend and test in userspace +# Set to 0 to use TrustVisor backend and run 'for real' +DO_USERSPACE_ONLY=0 + +ifeq ($(MINGW), 1) + CROSS=i686-pc-mingw32- +endif +PKG_CONFIG=pkg-config +CC:=gcc +LD:=ld +NM:=nm +OBJCOPY:=objcopy +CC:=$(CROSS)$(CC) +LD:=$(CROSS)$(LD) +NM:=$(CROSS)$(NM) +PKG_CONFIG:=$(CROSS)$(PKG_CONFIG) +OBJCOPY:=$(CROSS)$(OBJCOPY) + +PROG_NAME=test +CFLAGS=-g -Wall -Wextra -Werror +ifeq ($(MINGW), 1) + # workaround - mingw's format string checking is buggy, + # leading to false warnings, which get upgraded to errors + CFLAGS += -Wno-format +endif + +CFLAGS+=-DUSERSPACE_ONLY=$(DO_USERSPACE_ONLY) +CFLAGS+=-m32 +LDFLAGS=-m32 -L/usr/lib32 +CPPFLAGS=$(TESTS) +PKGCONFIG_DEPS=tee-sdk-app tee-sdk-app-tv libssl libcrypto +PROG_OBJS=test.o + +# Set the backend appropriately based on desire for userspace testing +ifeq ($(DO_USERSPACE_ONLY), 1) + PAL_BACKEND=tee-sdk-svc-null +else + PAL_BACKEND=tee-sdk-svc-tv +endif + +PAL_NAME=pals +PAL_PKGCONFIG_DEPS=tee-sdk-svc $(PAL_BACKEND) +PAL_OBJS=pals.o +PAL_CFLAGS=-Wall -Wextra -Werror -m32 +PAL_LDFLAGS=-m32 + +.PHONY: all +all: $(PROG_NAME) Makefile + +.PHONY: clean +clean: + $(RM) .*.cmd *.o *.ko *~ -r .tmp* test test.D + +TEESDK_DATA_DIR=$(shell $(PKG_CONFIG) --variable=pkgdatadir tee-sdk-app) + +# pkgconfig helpers +include $(TEESDK_DATA_DIR)/pkgconfig.mk + +# rules for compiling pal intermediate objects +include $(TEESDK_DATA_DIR)/pal.mk + +# rules for compiling a program PROG_NAME that uses one pal PAL_NAME +include $(TEESDK_DATA_DIR)/onepal.mk + diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/examples/test/pals.c b/xmhf-64/hypapps/trustvisor/tee-sdk/examples/test/pals.c new file mode 100644 index 0000000000..66c143de33 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/examples/test/pals.c @@ -0,0 +1,479 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include +#include +#include "pals.h" + +#include +#include + +#include + +__attribute__ ((section (".scode"))) +void pals(uint32_t uiCommand, tzi_encode_buffer_t *psInBuf, tzi_encode_buffer_t *psOutBuf, tz_return_t *puiRv) +{ + switch(uiCommand) { + case PAL_WITHOUTPARAM: + *puiRv = TZ_SUCCESS; + pal_withoutparam(); + break; + + case PAL_PARAM: + { + uint32_t input; + uint32_t out; + *puiRv = TZ_SUCCESS; + + if((*puiRv = TZIDecodeBufF(psInBuf, "%"TZI_DU32, &input))) + break; + + out = pal_param(input); + + if((*puiRv = TZIEncodeBufF(psOutBuf, "%"TZI_EU32, out))) + break; + } + break; + + case PAL_SEAL: + { + uint8_t *in, *out; + size_t inLen, outLen; + TPM_PCR_INFO *tpmPcrInfo; + size_t tpmPcrInfoLen; + *puiRv = TZ_SUCCESS; + + { + uint32_t inLen32, tpmPcrInfoLen32; + if((*puiRv = TZIDecodeBufF(psInBuf, + "%"TZI_DARRSPC "%"TZI_DARRSPC, + &tpmPcrInfo, &tpmPcrInfoLen32, + &in, &inLen32))) + break; + tpmPcrInfoLen = tpmPcrInfoLen32; + (void)tpmPcrInfoLen; /* pacify compiler that this is unused */ + inLen = inLen32; + } + + outLen = inLen + 100; /* XXX guessing at seal overhead (real overhead is sizeof(IV + HMAC)) */ + + if((*puiRv = TZIEncodeBufF(psOutBuf, "%"TZI_EARRSPC, + &out, (uint32_t)outLen))) + break; + + if((*puiRv = pal_seal(tpmPcrInfo, in, inLen, out, &outLen))) + break; + + /* actual size of previous array */ + if((*puiRv = TZIEncodeBufF(psOutBuf, "%"TZI_EU32, (uint32_t)outLen))) + break; + } + break; + + case PAL_UNSEAL: + { + uint8_t *in, *out, *digestAtCreation; + size_t inLen, outLen; + *puiRv = TZ_SUCCESS; + + { + uint32_t inLen32; + if((*puiRv = TZIDecodeBufF(psInBuf, + "%"TZI_DARRSPC, + &in, &inLen32))) + break; + inLen = inLen32; + } + + outLen = inLen + 100; /* XXX guessing at unseal overhead, though should actually be negative */ + + if((*puiRv = TZIEncodeBufF(psOutBuf, + "%"TZI_EARRSPC "%"TZI_EARRSPC, + &out, (uint32_t)outLen, + &digestAtCreation, (uint32_t)TPM_HASH_SIZE))) + break; + + if((*puiRv = pal_unseal(in, inLen, out, &outLen, digestAtCreation))) + break; + + /* actual size of previous array */ + if((*puiRv = TZIEncodeBufF(psOutBuf, "%"TZI_EU32, (uint32_t)outLen))) + break; + } + break; + + case PAL_QUOTE: + { + TPM_NONCE *nonce = NULL; + size_t nonceLen = 0; + TPM_PCR_SELECTION *tpmsel = NULL; + size_t tpmselLen = 0; + uint8_t *quote = NULL; + size_t maxQuoteLen = TPM_MAX_QUOTE_LEN; + size_t actualQuoteLen = 0; + uint8_t *pcrComp = NULL; + size_t pcrCompLen = 3+4+8*20; /* XXX */ + + *puiRv = TZ_SUCCESS; + + /* Decode input parameters from legacy userspace's test.c */ + { + uint32_t nonceLen32, tpmselLen32; + if((*puiRv = TZIDecodeBufF(psInBuf, + "%"TZI_DARRSPC "%"TZI_DARRSPC, + &nonce, &nonceLen32, + &tpmsel, &tpmselLen32))) + break; + nonceLen = nonceLen32; + tpmselLen = tpmselLen32; + } + + /* Sanity-check input parameters */ + if (tpmselLen != sizeof(TPM_PCR_SELECTION) + || nonceLen != sizeof(TPM_NONCE)) { + *puiRv = TZ_ERROR_ENCODE_FORMAT; + break; + } + + /* Prepare the output buffer to hold the response back to userspace. */ + if((*puiRv = TZIEncodeBufF(psOutBuf, + "%"TZI_EARRSPC "%"TZI_EARRSPC, + "e, (uint32_t)maxQuoteLen, + &pcrComp, (uint32_t)pcrCompLen))) + break; + + /* Make the hypercall to invoke the uTPM operation */ + actualQuoteLen = maxQuoteLen; + if((*puiRv = pal_quote(nonce, tpmsel, quote, &actualQuoteLen, pcrComp, &pcrCompLen))) + break; + + /* Also encode the actual length of the result */ + if((*puiRv = TZIEncodeBufF(psOutBuf, "%"TZI_EU32, (uint32_t)actualQuoteLen))) + break; + } + break; + + case PAL_ID_GETPUB: + { + uint8_t *rsaModulus; + size_t sz = TPM_RSA_KEY_LEN + 100; + + /* Prepare the output buffer to hold the response back to userspace. */ + if((*puiRv = TZIEncodeBufF(psOutBuf, "%"TZI_EARRSPC, + &rsaModulus, (uint32_t)sz))) + break; + + if((*puiRv = pal_id_getpub(rsaModulus, &sz))) + break; + + /* actual size of previous array */ + if((*puiRv = TZIEncodeBufF(psOutBuf, "%"TZI_EU32, (uint32_t)sz))) + break; + } + break; + + case PAL_PCR_EXTEND: + { + uint8_t *measIn; + size_t measLen; + uint32_t idx; + *puiRv = TZ_SUCCESS; + + { + uint32_t measLen32; + if((*puiRv = TZIDecodeBufF(psInBuf, + "%"TZI_DU32 "%"TZI_DARRSPC, + &idx, + &measIn, &measLen32))) + break; + measLen = measLen32; + } + + if(measLen != TPM_HASH_SIZE) { + *puiRv = TZ_ERROR_GENERIC; + break; + } + + if((*puiRv = pal_pcr_extend(idx, measIn))) + break; + } + break; + + case PAL_PCR_READ: + { + uint8_t *valOut; + uint32_t idx; + *puiRv = TZ_SUCCESS; + + if((*puiRv = TZIDecodeBufF(psInBuf, "%"TZI_DU32, &idx))) + break; + + if((*puiRv = TZIEncodeBufF(psOutBuf, + "%"TZI_EARRSPC, + &valOut, (uint32_t)TPM_HASH_SIZE))) + break; + + if((*puiRv = pal_pcr_read(idx, valOut))) + break; + } + break; + + case PAL_RAND: + { + uint32_t len; + uint8_t *bytes; + + if((*puiRv = TZIDecodeBufF(psInBuf, "%"TZI_DU32, &len))) + break; + + if((*puiRv = TZIEncodeBufF(psOutBuf, "%"TZI_EARRSPC, + &bytes, len))) + break; + + if((*puiRv = pal_rand(len, bytes))) + break; + } + break; + + case PAL_TIME_INIT: + *puiRv = pal_time_init(); + break; + + case PAL_TIME_ELAPSED: + { + uint64_t dt; + uint32_t dt_hi, dt_lo; + + if((*puiRv = pal_time_elapsed(&dt))) + break; + + dt_hi = (uint32_t)(dt>>32); + dt_lo = (uint32_t)dt; + if((*puiRv = TZIEncodeBufF(psOutBuf, "%"TZI_EU32 "%"TZI_EU32, + dt_hi, dt_lo))) + break; + } + break; + case PAL_NV_ROLLBACK: + { + uint8_t *old; + uint8_t *new; + uint32_t len = 32; /* XXX bad magic XXX */ + + if((*puiRv = TZIEncodeBufF(psOutBuf, "%"TZI_EARRSPC, + &old, len))) + break; + + if((*puiRv = TZIDecodeBufF(psInBuf, + "%"TZI_DARRSPC, + &new, &len))) + break; + + if((*puiRv = pal_nv_rollback(new, &len, old))) + break; + } + break; + } + return; +} + +/* sensitive code */ +__attribute__ ((section (".scode"))) +void pal_withoutparam(void) +{ + asm("nop"::); + asm("nop"::); + asm("nop"::); + asm("nop"::); +} + +__attribute__ ((section (".scode"))) +uint32_t pal_param(uint32_t input) +{ + return input + 1; +} + +__attribute__ ((section (".scode"))) +tz_return_t pal_seal(TPM_PCR_INFO *pcrInfo, uint8_t *input, uint32_t inputLen, uint8_t *output, size_t *outputLen) +{ + if (svc_utpm_seal(pcrInfo, input, inputLen, output, outputLen) == 0) { + return TZ_SUCCESS; + } else { + return TZ_ERROR_GENERIC; + } +} + +__attribute__ ((section (".scode"))) +tz_return_t pal_unseal(uint8_t *input, uint8_t inputLen, uint8_t *output, size_t *outputLen, uint8_t *digestAtCreation) +{ + if (svc_utpm_unseal(input, inputLen, output, outputLen, digestAtCreation) == 0) { + return TZ_SUCCESS; + } else { + return TZ_ERROR_GENERIC; + } +} + +__attribute__ ((section (".scode"))) +tz_return_t pal_quote(IN TPM_NONCE *nonce, + IN TPM_PCR_SELECTION *tpmsel, + OUT uint8_t *quote, INOUT size_t *quote_len, + OUT uint8_t *pcrComp, INOUT size_t *pcrCompLen) +{ + if (!svc_utpm_quote(nonce, tpmsel, quote, quote_len, pcrComp, pcrCompLen)) { + return TZ_SUCCESS; + } else { + return TZ_ERROR_GENERIC; + } +} + +__attribute__ ((section (".scode"))) +tz_return_t pal_id_getpub(OUT uint8_t* rsaModulus, INOUT size_t *sz) +{ + if(!svc_utpm_id_getpub(rsaModulus, sz)) { + return TZ_SUCCESS; + } else { + return TZ_ERROR_GENERIC; + } +} + +__attribute__ ((section (".scode"))) +tz_return_t pal_pcr_extend(IN uint32_t idx, + IN uint8_t *meas) +{ + if((idx >= TPM_PCR_NUM) || (NULL == meas)) { + return TZ_ERROR_GENERIC; + } + + if(svc_utpm_pcr_extend(idx, meas) == 0) { + return TZ_SUCCESS; + } else { + return TZ_ERROR_GENERIC; + } +} + +__attribute__ ((section (".scode"))) +tz_return_t pal_pcr_read(IN uint32_t idx, + OUT uint8_t *val) +{ + if((idx >= TPM_PCR_NUM) || (NULL == val)) { + return TZ_ERROR_GENERIC; + } + + if(svc_utpm_pcr_read(idx, val) == 0) { + return TZ_SUCCESS; + } else { + return TZ_ERROR_GENERIC; + } +} + +__attribute__ ((section (".scode"))) +tz_return_t pal_rand(IN size_t len, + OUT uint8_t *bytes) +{ + if (svc_utpm_rand_block(bytes, len) == 0) { + return TZ_SUCCESS; + } else { + return TZ_ERROR_GENERIC; + } +} + +static uint64_t t0; +static uint64_t t0_nonce; +static bool t0_initd=false; +tz_return_t pal_time_init() +{ + if (svc_time_elapsed_us(&t0_nonce, &t0)) { + return TZ_ERROR_GENERIC; + } + t0_initd=true; + return TZ_SUCCESS; +} + +__attribute__ ((section (".scode"))) +tz_return_t pal_time_elapsed(OUT uint64_t *us) +{ + uint64_t t; + uint64_t t_nonce; + + if (!t0_initd) + return TZ_ERROR_GENERIC; + + if (svc_time_elapsed_us(&t_nonce, &t)) { + return TZ_ERROR_GENERIC; + } + + if (t_nonce != t0_nonce) { + return TZ_ERROR_GENERIC; + } + + *us = t - t0; + + return TZ_SUCCESS; +} + +__attribute__ ((section (".scode"))) +tz_return_t pal_nv_rollback(IN uint8_t *newval, + OUT uint32_t *nv_size, + OUT uint8_t *oldval) +{ + size_t size; + + if(svc_tpmnvram_getsize(&size)) { + return TZ_ERROR_GENERIC; + } + + *nv_size = (uint32_t)size; + + if(svc_tpmnvram_readall(oldval)) { + return TZ_ERROR_GENERIC; + } + + if(svc_tpmnvram_writeall(newval)) { + return TZ_ERROR_GENERIC; + } + + return TZ_SUCCESS; +} diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/examples/test/pals.h b/xmhf-64/hypapps/trustvisor/tee-sdk/examples/test/pals.h new file mode 100644 index 0000000000..6a8913917a --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/examples/test/pals.h @@ -0,0 +1,89 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include +#include + +#include + +#include + +typedef enum { + PAL_WITHOUTPARAM, + PAL_PARAM, + PAL_SEAL, + PAL_UNSEAL, + PAL_QUOTE, + PAL_ID_GETPUB, + PAL_PCR_READ, + PAL_PCR_EXTEND, + PAL_RAND, + PAL_TIME_INIT, + PAL_TIME_ELAPSED, + PAL_NV_ROLLBACK, +} PAL_CMD; + +void pals(uint32_t uiCommand, tzi_encode_buffer_t *psInBuf, tzi_encode_buffer_t *psOutBuf, tz_return_t *puiRv); +void pal_withoutparam(); +uint32_t pal_param(uint32_t input); +tz_return_t pal_seal(TPM_PCR_INFO *pcrInfo, uint8_t *input, uint32_t inputLen, uint8_t *output, size_t *outputLen); +tz_return_t pal_unseal(uint8_t *input, uint8_t inputLen, uint8_t *output, size_t *outputLen, uint8_t *digestAtCreation); +tz_return_t pal_quote(IN TPM_NONCE *nonce, + IN TPM_PCR_SELECTION *tpmsel, + OUT uint8_t *quote, INOUT size_t *quote_len, + OUT uint8_t *pcrComp, INOUT size_t *pcrCompLen); +tz_return_t pal_id_getpub(OUT uint8_t* rsaModulus, INOUT size_t *sz); +tz_return_t pal_pcr_extend(IN uint32_t idx, + IN uint8_t *meas); +tz_return_t pal_pcr_read(IN uint32_t idx, + OUT uint8_t *val); +tz_return_t pal_rand(IN size_t len, + OUT uint8_t *bytes); +tz_return_t pal_time_init(); +tz_return_t pal_time_elapsed(OUT uint64_t *us); +tz_return_t pal_nv_rollback(IN uint8_t *newval, + OUT uint32_t *nv_size, + OUT uint8_t *oldval); diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/examples/test/test.c b/xmhf-64/hypapps/trustvisor/tee-sdk/examples/test/test.c new file mode 100644 index 0000000000..c3a9a85308 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/examples/test/test.c @@ -0,0 +1,1282 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include "pals.h" +//#include "config.h" +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +/* + * if 'prefix' != NULL, print it before each line of hex string + */ +void print_hex(const char *prefix, const void *prtptr, size_t size) +{ + size_t i; + for ( i = 0; i < size; i++ ) { + if ( i % 16 == 0 && prefix != NULL ) + printf("\n%s", prefix); + printf("%02x ", *(const uint8_t *)prtptr++); + } + printf("\n"); +} + + +/* int test_marshal() */ +/* { */ +/* tzi_encode_buffer_t *psEnc, *psEnc2; */ +/* char *in, *out; */ +/* uint32_t inLen, outLen; */ +/* uint32_t inI, outI; */ + +/* in = "hello pal-ly boy"; */ +/* inLen = strlen(in); */ +/* inI = 42; */ + +/* posix_memalign((void**)&psEnc, 8, 1000); */ +/* posix_memalign((void**)&psEnc2, 8, 1000); */ +/* TZIEncodeBufInit(psEnc, 1000); */ +/* TZIEncodeBufInit(psEnc2, 1000); */ + +/* TZIEncodeArray(psEnc, in, inLen); */ +/* TZIEncodeUint32(psEnc, inI); */ + +/* TZIEncodeToDecode(psEnc); */ +/* memcpy(psEnc2, psEnc, 1000); */ + +/* out = TZIDecodeArraySpace(psEnc2, &outLen); */ +/* printf("returned string (%d): %s\n", outLen, out); */ + +/* outI = TZIDecodeUint32(psEnc2); */ +/* printf("returned int %u\n", outI); */ + +/* return 0; */ +/* } */ + +int test_vmcall() +{ + printf("VMMCALL\n"); + tv_test(); + printf("VMMCALL returned\n"); + return 0; +} + +int test_withoutparam(tz_session_t *tzPalSession) +{ + tz_return_t tzRet; + tz_operation_t tzOp; + tz_return_t serviceReturn; + int rv=0; + + printf("\nWITHOUTPARAM\n"); + + tzRet = TZOperationPrepareInvoke(tzPalSession, + PAL_WITHOUTPARAM, + NULL, + &tzOp); + assert(tzRet == TZ_SUCCESS); + + printf("running PAL\n"); + tzRet = TZOperationPerform(&tzOp, &serviceReturn); + if (tzRet != TZ_SUCCESS) { + if (tzRet == TZ_ERROR_SERVICE) { + printf("withoutparam pal returned error %d\n", + serviceReturn); + rv = 1; + } else { + printf("tz system returned error %d\n", + tzRet); + rv = 1; + } + } + TZOperationRelease(&tzOp); + + return rv; +} + +int test_param(tz_session_t *tzPalSession) +{ + unsigned int i; + uint32_t output; + tz_return_t tzRet; + tz_operation_t tzOp; + tz_return_t serviceReturn; + int rv=0; + + printf("\nPARAM\n"); + + for(i=0;i<3; i++) { /* FIXME: bump this up when performance issue is addressed */ + tzRet = TZOperationPrepareInvoke(tzPalSession, + PAL_PARAM, + NULL, + &tzOp); + assert(tzRet == TZ_SUCCESS); + TZEncodeUint32(&tzOp, i); + + printf("running PAL\n"); + tzRet = TZOperationPerform(&tzOp, &serviceReturn); + if (tzRet != TZ_SUCCESS) { + if (tzRet == TZ_ERROR_SERVICE) { + printf("withoutparam pal returned error %d\n", + serviceReturn); + rv = 1; + } else { + printf("tz system returned error %d\n", + tzRet); + rv = 1; + } + } + + output = TZDecodeUint32(&tzOp); + if (TZDecodeGetError(&tzOp) != TZ_SUCCESS) { + printf("error: tz decoder returned status %d\n", TZDecodeGetError(&tzOp)); + rv = 1; + } + + if(output != i+1) { + printf("error: output=%d, i=%d\n", output, i); + rv=1; + } + + TZOperationRelease(&tzOp); + } + + return rv; +} + +/** + * Need some support for expected PCR digest values. Let's test while + * including only a single PCR: #7. Its value is expected to be all + * zeros for unseal to succeed. + * + * PcrComposite that selects PCR #7 with expected contents all zeros: + * 01 00 // sizeOfSelect (little-endian) + * 80 // pcrSelection (bit vector) + * 00 00 00 14 // length of PCR values (big-endian) + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // 20 bytes of zeros + * + * TPM_COMPOSITE_HASH (i.e., compute sha-1 over the above data): + * c6 08 a1 e6 eb 7d 0f 88 6b 15 75 6b 29 83 be d2 e5 86 19 cb + */ +const uint8_t digestAtRelease[] = {0xc6, 0x08, 0xa1, 0xe6, 0xeb, 0x7d, 0x0f, 0x88, 0x6b, 0x15, + 0x75, 0x6b, 0x29, 0x83, 0xbe, 0xd2, 0xe5, 0x86, 0x19, 0xcb}; +int test_seal2(tz_session_t *tzPalSession) +{ + int rv=0; + tz_return_t tzRet, serviceReturn; + tz_operation_t tz_sealOp, tz_unsealOp; + char *in = "hello pal-ly boy"; + uint32_t inLen = strlen(in)+1; + char *sealOut, *unsealOut; + uint32_t sealOutLen, unsealOutLen; + uint8_t *digestAtCreationOut; + uint32_t digestAtCreationLen; + + TPM_PCR_INFO *pcrInfo=NULL; + + printf("\nSEAL with PCRs\n"); + + printf(" sizeof(TPM_PCR_INFO) %d, sizeof(TPM_PCR_SELECTION) %d\n", + sizeof(TPM_PCR_INFO), sizeof(TPM_PCR_SELECTION)); + tzRet = TZOperationPrepareInvoke(tzPalSession, + PAL_SEAL, + NULL, + &tz_sealOp); + assert(tzRet == TZ_SUCCESS); + tzRet = TZOperationPrepareInvoke(tzPalSession, + PAL_UNSEAL, + NULL, + &tz_unsealOp); + assert(tzRet == TZ_SUCCESS); + + tzRet = TZIEncodeF(&tz_sealOp, + "%"TZI_EARRSPC "%"TZI_ESTR, + &pcrInfo, sizeof(TPM_PCR_INFO), + in); + if (tzRet) { + printf("SEAL encoder returned error %d\n", tzRet); + rv=1; + goto out; + } + + memset(pcrInfo, 0, sizeof(TPM_PCR_INFO)); + /* utpm_pcr_select_i(&pcrInfo.pcrSelection, 0); */ + /* utpm_pcr_select_i(&pcrInfo.pcrSelection, 1); */ + /* utpm_pcr_select_i(&pcrInfo.pcrSelection, 2); */ + /* utpm_pcr_select_i(&pcrInfo.pcrSelection, 3); */ + /* utpm_pcr_select_i(&pcrInfo.pcrSelection, 4); */ + /* utpm_pcr_select_i(&pcrInfo.pcrSelection, 5); */ + /* utpm_pcr_select_i(&pcrInfo.pcrSelection, 6); */ + utpm_pcr_select_i(&pcrInfo->pcrSelection, 7); + memcpy(pcrInfo->digestAtRelease.value, digestAtRelease, TPM_HASH_SIZE); + print_hex(" pcrInfo: ", (uint8_t*)pcrInfo, sizeof(TPM_PCR_INFO)); + + tzRet = TZOperationPerform(&tz_sealOp, &serviceReturn); + + if (tzRet != TZ_SUCCESS) { + if (tzRet == TZ_ERROR_SERVICE) { + printf("SEAL pal returned error %d\n", + serviceReturn); + rv = 1; + goto out; + } else { + printf("tz system returned error %d\n", + tzRet); + rv = 1; + goto out; + } + } + tzRet = TZIDecodeF(&tz_sealOp, + "%"TZI_DARRSPC_NOLEN "%"TZI_DU32, + &sealOut, /*skip*/ + &sealOutLen); + if (tzRet) { + printf("SEAL decoder returned error %d\n", tzRet); + rv = 1; + goto out; + } + + print_hex(" sealed data: ", sealOut, sealOutLen); + + TZEncodeArray(&tz_unsealOp, sealOut, sealOutLen); + tzRet = TZOperationPerform(&tz_unsealOp, &serviceReturn); + unsealOut = TZDecodeArraySpace(&tz_unsealOp, &unsealOutLen); + digestAtCreationOut = TZDecodeArraySpace(&tz_unsealOp, &digestAtCreationLen); + unsealOutLen = TZDecodeUint32(&tz_unsealOp); + + if (tzRet != TZ_SUCCESS) { + if (tzRet == TZ_ERROR_SERVICE) { + printf("UNSEAL pal returned error %d\n", + serviceReturn); + rv = 1; + goto out; + } else { + printf("tz system returned error %d\n", + tzRet); + rv = 1; + goto out; + } + } + if (TZDecodeGetError(&tz_sealOp)) { + printf("SEAL decoder returned error %d\n", TZDecodeGetError(&tz_sealOp)); + rv = 1; + goto out; + } + + if(inLen != unsealOutLen + || memcmp(in, unsealOut, inLen) != 0) { + printf("error- unsealed data doesn't match\n"); + printf("in (%d): %s\n", inLen, in); + printf("out (%d): %s\n", unsealOutLen, unsealOut); + rv = 1; + goto out; + } else { + print_hex(" digestAtCreation: ", digestAtCreationOut, digestAtCreationLen); + printf("Success: unsealed data matches input\n"); + } + + out: + TZOperationRelease(&tz_sealOp); + TZOperationRelease(&tz_unsealOp); + return rv; +} + +/** + * Test Seal without PCR bindings. + */ +int test_seal(tz_session_t *tzPalSession) +{ + int rv=0; + tz_return_t tzRet, serviceReturn; + tz_operation_t tz_sealOp, tz_unsealOp; + char *in = "hello pal-ly boy"; + uint32_t inLen = strlen(in)+1; + char *sealOut, *unsealOut; + uint32_t sealOutLen, unsealOutLen; + uint8_t *digestAtCreationOut; + uint32_t digestAtCreationLen; + + TPM_PCR_INFO *pcrInfo=NULL; + + printf("\nSEAL withOUT PCRs\n"); + + tzRet = TZOperationPrepareInvoke(tzPalSession, + PAL_SEAL, + NULL, + &tz_sealOp); + assert(tzRet == TZ_SUCCESS); + tzRet = TZOperationPrepareInvoke(tzPalSession, + PAL_UNSEAL, + NULL, + &tz_unsealOp); + assert(tzRet == TZ_SUCCESS); + + tzRet = TZIEncodeF(&tz_sealOp, + "%"TZI_EARRSPC "%"TZI_ESTR, + &pcrInfo, sizeof(TPM_PCR_INFO), + in); + if (tzRet) { + printf("SEAL encoder returned error %d\n", tzRet); + rv=1; + goto out; + } + memset(pcrInfo, 0, sizeof(TPM_PCR_INFO)); + + tzRet = TZOperationPerform(&tz_sealOp, &serviceReturn); + if (tzRet != TZ_SUCCESS) { + printf("SEAL Op FAILED\n"); + rv = 1; + goto out; + } + + tzRet = TZIDecodeF(&tz_sealOp, + "%"TZI_DARRSPC_NOLEN "%"TZI_DU32, + &sealOut, + &sealOutLen); + if (tzRet != TZ_SUCCESS) { + printf("SEAL Op decode FAILED with %d\n", tzRet); + rv = 1; + goto out; + } + + print_hex(" sealed data: ", sealOut, sealOutLen); + + assert(!TZIEncodeF(&tz_unsealOp, "%"TZI_EARR, sealOut, sealOutLen)); + tzRet = TZOperationPerform(&tz_unsealOp, &serviceReturn); + + if (tzRet != TZ_SUCCESS) { + if (tzRet == TZ_ERROR_SERVICE) { + printf("UNSEAL pal returned error %d\n", + serviceReturn); + rv = 1; + goto out; + } else { + printf("tz system returned error %d\n", + tzRet); + rv = 1; + goto out; + } + } + tzRet = TZIDecodeF(&tz_unsealOp, + "%"TZI_DARRSPC_NOLEN "%"TZI_DARRSPC "%"TZI_DU32, + &unsealOut, /*ignore */ + &digestAtCreationOut, &digestAtCreationLen, + &unsealOutLen); + if (tzRet) { + printf("UNSEAL decoder returned error %d\n", tzRet); + rv = 1; + goto out; + } + + if(inLen != unsealOutLen + || memcmp(in, unsealOut, inLen) != 0) { + printf("error- unsealed data doesn't match\n"); + printf("in (%d): %s\n", inLen, in); + printf("out (%d): %s\n", unsealOutLen, unsealOut); + rv = 1; + goto out; + } else { + print_hex(" digestAtCreation: ", digestAtCreationOut, digestAtCreationLen); + printf("Success: unsealed data matches input\n"); + } + + out: + TZOperationRelease(&tz_sealOp); + TZOperationRelease(&tz_unsealOp); + return rv; +} + + +int test_id_getpub(tz_session_t *tzPalSession, uint8_t *rsaPubDER, uint32_t *rsaPubDER_sz) +{ + tz_return_t tzRet, serviceReturn; + tz_operation_t tzOp; + uint8_t *buf; + uint32_t rv = 0; + + printf("ID_GETPUB\n"); + + assert(NULL != rsaPubDER); + + /* prep operation */ + tzRet = TZOperationPrepareInvoke(tzPalSession, + PAL_ID_GETPUB, + NULL, + &tzOp); + assert(tzRet == TZ_SUCCESS); + + /* Call PAL */ + tzRet = TZOperationPerform(&tzOp, &serviceReturn); + if (tzRet != TZ_SUCCESS) { + rv = 1; + printf("Failure at %s:%d\n", __FILE__, __LINE__); + printf("tzRet 0x%08x\n", tzRet); + goto out; + } + + /* read out RSA public key modulus */ + tzRet = TZIDecodeF(&tzOp, "%"TZI_DARRSPC_NOLEN "%"TZI_DU32, + &buf, + rsaPubDER_sz); + if (tzRet) { + rv = 1; + goto out; + } + memcpy( rsaPubDER, buf, *rsaPubDER_sz); + + print_hex(" rsaMod: ", rsaPubDER, *rsaPubDER_sz); + + out: + TZOperationRelease(&tzOp); + + if(0 != rv) { printf("...FAILED rv %d\n", rv); } + return rv; +} + + +/* Read entire file into a newly-allocated buffer. */ +/* Returns positive integer representing number of bytes read, or + * negative value on error. Don't care about size 0 files. */ +static long slurp_file(const char *filename, unsigned char **buf) { + if(!filename || !buf) return -1; + + FILE *fh = fopen(filename, "rb"); + if(NULL == fh) return -2; + + /* how big is the file? */ + fseek(fh, 0L, SEEK_END); + long s = ftell(fh); + rewind(fh); + + /* get some space for its bytes */ + *buf = malloc(s); + if(NULL == *buf) { + fclose(fh); fh = NULL; + return -3; + } + + fread(*buf, s, 1, fh); + fclose(fh); fh = NULL; + + printf(" slurp_file successfully read %ld bytes from %s\n", + s, filename); + + return s; +} + +/* Create a file (clobbering any existing file) and write the contents + * of 'bytes' to it. Returns the number of bytes written on success, + * or a negative value on error. */ +static long puke_file(const char *filename, const unsigned char + *bytes, long len) { + if(!filename || !bytes || len < 1) return -1; + + FILE *fh = fopen(filename, "wb"); + if(NULL == fh) return -2; + + if(fwrite(bytes, len, 1, fh) != 1) return -3; + fclose(fh); fh = NULL; + + printf(" puke_file successfully wrote %ld bytes to %s\n", + len, filename); + + return len; +} + +#define LT_SEAL_FILENAME "sealed.dat" + +int just_seal(tz_session_t *tzPalSession) { + int rv=0; + tz_return_t tzRet, serviceReturn; + tz_operation_t tz_sealOp; + char *in = "hello pal-ly boy"; + unsigned char *sealOut; + uint32_t sealOutLen; + + TPM_PCR_INFO *pcrInfo=NULL; + + printf("\nLong-Term SEAL withOUT PCRs\n"); + + tzRet = TZOperationPrepareInvoke(tzPalSession, + PAL_SEAL, + NULL, + &tz_sealOp); + assert(tzRet == TZ_SUCCESS); + + tzRet = TZIEncodeF(&tz_sealOp, + "%"TZI_EARRSPC "%"TZI_ESTR, + &pcrInfo, sizeof(TPM_PCR_INFO), + in); + if (tzRet) { + printf("SEAL encoder returned error %d\n", tzRet); + rv=1; + goto out; + } + memset(pcrInfo, 0, sizeof(TPM_PCR_INFO)); + + tzRet = TZOperationPerform(&tz_sealOp, &serviceReturn); + if (tzRet != TZ_SUCCESS) { + printf("SEAL Op FAILED\n"); + rv = 1; + goto out; + } + + tzRet = TZIDecodeF(&tz_sealOp, + "%"TZI_DARRSPC_NOLEN "%"TZI_DU32, + &sealOut, + &sealOutLen); + if (tzRet != TZ_SUCCESS) { + printf("SEAL Op decode FAILED with %d\n", tzRet); + rv = 1; + goto out; + } + + print_hex(" sealed data: ", sealOut, sealOutLen); + if((rv = puke_file(LT_SEAL_FILENAME, sealOut, sealOutLen)) < 0) { + printf("puke_file() FAILED with rv %d\n", rv); + rv = 1; + goto out; + } else { + rv = 0; + } + + out: + TZOperationRelease(&tz_sealOp); + return rv; + +} + +int just_unseal(tz_session_t *tzPalSession) { + int rv=0; + tz_return_t tzRet, serviceReturn; + tz_operation_t tz_unsealOp; + unsigned char *sealOut, *unsealOut; + long sealOutLen, unsealOutLen; + uint8_t *digestAtCreationOut; + uint32_t digestAtCreationLen; + + printf("\nLong-Term UnSEAL withOUT PCRs\n"); + + tzRet = TZOperationPrepareInvoke(tzPalSession, + PAL_UNSEAL, + NULL, + &tz_unsealOp); + assert(tzRet == TZ_SUCCESS); + + sealOutLen = slurp_file(LT_SEAL_FILENAME, &sealOut); + if(sealOutLen < 0) { + printf("slurp_file() FAILED\n"); + rv = 1; + goto out; + } + + print_hex(" sealed data: ", sealOut, sealOutLen); + + assert(!TZIEncodeF(&tz_unsealOp, "%"TZI_EARR, sealOut, (uint32_t)sealOutLen)); + tzRet = TZOperationPerform(&tz_unsealOp, &serviceReturn); + + if (tzRet != TZ_SUCCESS) { + if (tzRet == TZ_ERROR_SERVICE) { + printf("UNSEAL pal returned error %d\n", + serviceReturn); + rv = 1; + goto out; + } else { + printf("tz system returned error %d\n", + tzRet); + rv = 1; + goto out; + } + } + tzRet = TZIDecodeF(&tz_unsealOp, + "%"TZI_DARRSPC_NOLEN "%"TZI_DARRSPC "%"TZI_DU32, + &unsealOut, /*ignore */ + &digestAtCreationOut, &digestAtCreationLen, + (uint32_t*)&unsealOutLen); + if (tzRet) { + printf("UNSEAL decoder returned error %d\n", tzRet); + rv = 1; + goto out; + } + + printf(" out (%ld): %s\n", unsealOutLen, unsealOut); + print_hex(" digestAtCreation: ", digestAtCreationOut, digestAtCreationLen); + + out: + if(NULL != sealOut) { free(sealOut); sealOut = NULL; } + TZOperationRelease(&tz_unsealOp); + return rv; + +} + +/** + * Test LONG-TERM Seal (i.e., persistent TrustVisor sealing keys). If + * file LT_SEAL_FILENAME exists, it is assumed to be ciphertext and an + * attempt to is made to unseal it. If it does not exist, then some + * plaintext is sealed and the resulting ciphertext is written to that + * file. To fully exercise this, the program must be run twice. This + * is because a proper test is impossible with a reboot (or at least a + * hypervisor reload someday down the road). + */ +int test_longterm_seal(tz_session_t *tzPalSession) +{ + unsigned char *buf = NULL; + /* Sloppy; wastes a read of the file if it already exists. */ + if(slurp_file(LT_SEAL_FILENAME, &buf) > 0) { + /* File does exist. */ + free(buf); buf = NULL; + return just_unseal(tzPalSession); + } + + return just_seal(tzPalSession); +} + +int verify_quote(uint8_t *tpm_pcr_composite, uint32_t tpc_len, uint8_t *sig, uint32_t sig_len, + TPM_NONCE *externalnonce, uint8_t* rsaPubDER, long rsaPubDER_sz) { + TPM_QUOTE_INFO quote_info; + RSA *rsa = NULL; + int rv=0; + + /* 1) 1.1.0.0 for consistency w/ TPM 1.2 spec */ + *((uint32_t*)"e_info.version) = 0x00000101; + /* 2) 'QUOT' */ + *((uint32_t*)quote_info.fixed) = 0x544f5551; + + /* 3) SHA-1 hash of TPM_PCR_COMPOSITE */ + SHA1(tpm_pcr_composite, tpc_len, quote_info.digestValue.value); + + print_hex(" tpm_pcr_composite: ", tpm_pcr_composite, tpc_len); + + print_hex(" COMPOSITE_HASH: ", quote_info.digestValue.value, TPM_HASH_SIZE); + + /* 4) external nonce */ + memcpy(quote_info.externalData.nonce, externalnonce->nonce, TPM_HASH_SIZE); + + print_hex(" quote_info: ", (uint8_t*)"e_info, sizeof(TPM_QUOTE_INFO)); + + /** + * Import the public key used to check the quote. + */ + if (NULL == d2i_RSAPublicKey( &rsa, (const unsigned char**)&rsaPubDER, rsaPubDER_sz)) { + printf("ERROR: d2i_RSAPublicKey failed\n"); + rv = 1; + goto out; + } + + /** + * Verify the signature! + */ + + uint8_t valData[TPM_HASH_SIZE]; + SHA1((uint8_t*)"e_info, sizeof(TPM_QUOTE_INFO), valData); + print_hex(" valData: ", valData, TPM_HASH_SIZE); + + if(1 != RSA_verify(NID_sha1, valData, TPM_HASH_SIZE, sig, sig_len, rsa)) { + printf("ERROR: Quote verification FAILED!\n"); + ERR_print_errors_fp(stdout); + rv = 1; + goto out; + } else { + printf(" RSA_verify: SUCCESSfully verified quote\n"); + rv = 0; + } + + out: + /* RSA_free() frees the RSA structure and its components. The key + * is erased before the memory is returned to the system. */ + if(rsa) { RSA_free(rsa); rsa = NULL; } + + return rv; +} + +int test_quote(tz_session_t *tzPalSession) +{ + TPM_NONCE *nonce; + TPM_PCR_SELECTION *tpmsel; + uint8_t *quote; + uint32_t quoteLen = TPM_MAX_QUOTE_LEN; + uint32_t maxQuoteLen; + uint8_t *pcrComp = NULL; + uint32_t pcrCompLen = 0; + + tz_return_t tzRet, serviceReturn; + tz_operation_t tz_quoteOp; + + unsigned int i; + int rv = 0; + + uint32_t rsaPubDER_sz = TPM_RSA_KEY_LEN + 100; + uint8_t *rsaPubDER = NULL; + + /** + * First get the public key that will eventually be used to verify the quote. + */ + + rsaPubDER = malloc(rsaPubDER_sz); + assert(rsaPubDER); + if(0 != test_id_getpub(tzPalSession, rsaPubDER, &rsaPubDER_sz)) { + printf("test_id_getpub FAILED!\n"); + goto out; + } + + printf("\nQUOTE\n"); + + /* prep operation */ + tzRet = TZOperationPrepareInvoke(tzPalSession, + PAL_QUOTE, + NULL, + &tz_quoteOp); + assert(tzRet == TZ_SUCCESS); + + /* setup encoded space */ + assert(!(TZIEncodeF(&tz_quoteOp, + "%"TZI_EARRSPC "%"TZI_EARRSPC, + &nonce, sizeof(TPM_NONCE), + &tpmsel, sizeof(TPM_PCR_SELECTION)))); + + /* setup nonce */ + for(i=0; inonce[i] = (uint8_t)i; + } + + /* setup tpmsel */ + /* select all PCRs for inclusion in test quote */ + assert(8 == TPM_PCR_NUM); /* want this test to fail if uTPM's grow more uPCRs */ + tpmsel->sizeOfSelect = 1; /* 1 byte to select 8 PCRs */ + for(i=0; i<8; i++) { + utpm_pcr_select_i(tpmsel, i); + } + + /* call pal */ + tzRet = TZOperationPerform(&tz_quoteOp, &serviceReturn); + if (tzRet != TZ_SUCCESS) { + rv = 1; + goto out; + } + + /* get quote */ + if((tzRet = TZIDecodeF(&tz_quoteOp, + "%"TZI_DARRSPC "%"TZI_DARRSPC "%"TZI_DU32, + "e, &maxQuoteLen, + &pcrComp, &pcrCompLen, + "eLen))) { + rv = 1; + goto out; + } + printf(" max quoteLen = %d\n", quoteLen); + printf(" actual quoteLen = %d\n", quoteLen); + + printf(" pcrCompLen = %d\n", pcrCompLen); + print_hex(" pcrComp: ", pcrComp, pcrCompLen); + + /* Verify the signature in the Quote */ + print_hex(" sig: ", quote, quoteLen); + + if((rv = verify_quote(pcrComp, pcrCompLen, quote, quoteLen, nonce, rsaPubDER, rsaPubDER_sz)) != 0) { + printf("verify_quote FAILED\n"); + } + + out: + free(rsaPubDER); + TZOperationRelease(&tz_quoteOp); + + return rv; +} + +int test_pcr_extend(tz_session_t *tzPalSession) +{ + tz_return_t tzRet, serviceReturn; + tz_operation_t tzOp; + uint8_t *meas_ptr; + uint32_t pcr_idx = 3; /* arbitrary; eventually loop through them all */ + int rv = 0; + uint32_t i; + + printf("\nPCR_EXTEND\n"); + + /* prep operation */ + tzRet = TZOperationPrepareInvoke(tzPalSession, + PAL_PCR_EXTEND, + NULL, + &tzOp); + assert(tzRet == TZ_SUCCESS); + + /* encode PCR index */ + assert(!(TZIEncodeF(&tzOp, + "%"TZI_EU32 "%"TZI_EARRSPC, + pcr_idx, + &meas_ptr, TPM_HASH_SIZE))); + + /* Fake the measurement */ + for(i=0; i + +int main(int argc, char **argv) +{ + printf("hello world!\n"); + return 1; +} diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/ports/newlib/newlib-tee-sdk-131021.patch b/xmhf-64/hypapps/trustvisor/tee-sdk/ports/newlib/newlib-tee-sdk-131021.patch new file mode 100644 index 0000000000..335c0a2430 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/ports/newlib/newlib-tee-sdk-131021.patch @@ -0,0 +1,33028 @@ +diff -Naur newlib-1.19.0/config.sub newlib-1.19.0-tee-sdk/config.sub +--- newlib-1.19.0/config.sub 2010-06-01 13:53:40.000000000 -0400 ++++ newlib-1.19.0-tee-sdk/config.sub 2013-10-21 15:44:33.000000000 -0400 +@@ -4,7 +4,7 @@ + # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + # Free Software Foundation, Inc. + +-timestamp='2010-05-21' ++timestamp='2011-07-21' + + # This file is (in principle) common to ALL GNU software. + # The presence of a machine in this file suggests that SOME GNU software +@@ -1452,6 +1452,8 @@ + ;; + -nacl*) + ;; ++ -tsvc*) ++ ;; + -none) + ;; + *) +diff -Naur newlib-1.19.0/newlib/configure.host newlib-1.19.0-tee-sdk/newlib/configure.host +--- newlib-1.19.0/newlib/configure.host 2010-12-02 14:30:46.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/configure.host 2013-10-21 15:44:33.000000000 -0400 +@@ -426,6 +426,11 @@ + sys_dir=sysvi386 + unix_dir=unix + ;; ++ i[34567]86-*-tsvc*) ++ syscall_dir=syscalls ++ sys_dir=tsvc ++ have_crt0="no" ++ ;; + i[34567]86-pc-linux-*) + sys_dir=linux + unix_dir=unix +diff -Naur newlib-1.19.0/newlib/libc/include/sys/config.h newlib-1.19.0-tee-sdk/newlib/libc/include/sys/config.h +--- newlib-1.19.0/newlib/libc/include/sys/config.h 2010-12-02 14:30:46.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/include/sys/config.h 2013-10-21 15:44:33.000000000 -0400 +@@ -86,9 +86,9 @@ + #define HAVE_GETDATE + #define _HAVE_SYSTYPES + #define _READ_WRITE_RETURN_TYPE _ssize_t +-#define __LARGE64_FILES 1 +-/* we use some glibc header files so turn on glibc large file feature */ +-#define _LARGEFILE64_SOURCE 1 ++/* #define __LARGE64_FILES 1 */ ++/* /\* we use some glibc header files so turn on glibc large file feature *\/ */ ++/* #define _LARGEFILE64_SOURCE 1 */ + #endif + #endif + +diff -Naur newlib-1.19.0/newlib/libc/stdlib/mallocr.c newlib-1.19.0-tee-sdk/newlib/libc/stdlib/mallocr.c +--- newlib-1.19.0/newlib/libc/stdlib/mallocr.c 2010-05-31 15:15:41.000000000 -0400 ++++ newlib-1.19.0-tee-sdk/newlib/libc/stdlib/mallocr.c 2013-10-21 15:44:33.000000000 -0400 +@@ -651,6 +651,9 @@ + # include + #endif + ++/* XXX ugly hack for tee-sdk */ ++#define malloc_getpagesize (4096) ++ + #ifndef malloc_getpagesize + # ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */ + # ifndef _SC_PAGE_SIZE +diff -Naur newlib-1.19.0/newlib/libc/sys/aclocal.m4 newlib-1.19.0-tee-sdk/newlib/libc/sys/aclocal.m4 +--- newlib-1.19.0/newlib/libc/sys/aclocal.m4 2010-12-16 16:59:03.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/aclocal.m4 2013-10-21 15:44:33.000000000 -0400 +@@ -989,9 +989,10 @@ + AC_SUBST([am__untar]) + ]) # _AM_PROG_TAR + +-m4_include([../../../libtool.m4]) +-m4_include([../../../ltoptions.m4]) +-m4_include([../../../ltsugar.m4]) +-m4_include([../../../ltversion.m4]) + m4_include([../../../lt~obsolete.m4]) + m4_include([../../acinclude.m4]) ++m4_include([../../libtool.m4]) ++m4_include([../../ltoptions.m4]) ++m4_include([../../ltsugar.m4]) ++m4_include([../../ltversion.m4]) ++m4_include([../../lt~obsolete.m4]) +diff -Naur newlib-1.19.0/newlib/libc/sys/configure newlib-1.19.0-tee-sdk/newlib/libc/sys/configure +--- newlib-1.19.0/newlib/libc/sys/configure 2010-12-16 16:59:03.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/configure 2013-10-21 15:44:33.000000000 -0400 +@@ -171,15 +171,7 @@ + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +-test \$(( 1 + 1 )) = 2 || exit 1 +- +- test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( +- ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +- ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO +- ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO +- PATH=/empty FPATH=/empty; export PATH FPATH +- test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ +- || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" ++test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes + else +@@ -533,8 +525,304 @@ + # Sed expression to map a string onto a valid variable name. + as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + ++ ++ ++# Check that we are running under the correct shell. + SHELL=${CONFIG_SHELL-/bin/sh} + ++case X$lt_ECHO in ++X*--fallback-echo) ++ # Remove one level of quotation (which was required for Make). ++ ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` ++ ;; ++esac ++ ++ECHO=${lt_ECHO-echo} ++if test "X$1" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++elif test "X$1" = X--fallback-echo; then ++ # Avoid inline document here, it may be left over ++ : ++elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then ++ # Yippee, $ECHO works! ++ : ++else ++ # Restart under the correct shell. ++ exec $SHELL "$0" --no-reexec ${1+"$@"} ++fi ++ ++if test "X$1" = X--fallback-echo; then ++ # used as fallback echo ++ shift ++ cat <<_LT_EOF ++$* ++_LT_EOF ++ exit 0 ++fi ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++if test -z "$lt_ECHO"; then ++ if test "X${echo_test_string+set}" != Xset; then ++ # find a string as large as possible, as long as the shell can cope with it ++ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do ++ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... ++ if { echo_test_string=`eval $cmd`; } 2>/dev/null && ++ { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null ++ then ++ break ++ fi ++ done ++ fi ++ ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ : ++ else ++ # The Solaris, AIX, and Digital Unix default echo programs unquote ++ # backslashes. This makes it impossible to quote backslashes using ++ # echo "$something" | sed 's/\\/\\\\/g' ++ # ++ # So, first we look for a working echo in the user's PATH. ++ ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for dir in $PATH /usr/ucb; do ++ IFS="$lt_save_ifs" ++ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && ++ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$dir/echo" ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ if test "X$ECHO" = Xecho; then ++ # We didn't find a better echo, so look for alternatives. ++ if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # This shell has a builtin print -r that does the trick. ++ ECHO='print -r' ++ elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && ++ test "X$CONFIG_SHELL" != X/bin/ksh; then ++ # If we have ksh, try running configure again with it. ++ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} ++ export ORIGINAL_CONFIG_SHELL ++ CONFIG_SHELL=/bin/ksh ++ export CONFIG_SHELL ++ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} ++ else ++ # Try using printf. ++ ECHO='printf %s\n' ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # Cool, printf works ++ : ++ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL ++ export CONFIG_SHELL ++ SHELL="$CONFIG_SHELL" ++ export SHELL ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ else ++ # maybe with a smaller string... ++ prev=: ++ ++ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do ++ if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null ++ then ++ break ++ fi ++ prev="$cmd" ++ done ++ ++ if test "$prev" != 'sed 50q "$0"'; then ++ echo_test_string=`eval $prev` ++ export echo_test_string ++ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} ++ else ++ # Oops. We lost completely, so just stick with echo. ++ ECHO=echo ++ fi ++ fi ++ fi ++ fi ++ fi ++fi ++ ++# Copy echo and quote the copy suitably for passing to libtool from ++# the Makefile, instead of quoting the original, which is used later. ++lt_ECHO=$ECHO ++if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then ++ lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" ++fi ++ ++ ++ ++ ++ ++# Check that we are running under the correct shell. ++SHELL=${CONFIG_SHELL-/bin/sh} ++ ++case X$lt_ECHO in ++X*--fallback-echo) ++ # Remove one level of quotation (which was required for Make). ++ ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` ++ ;; ++esac ++ ++ECHO=${lt_ECHO-echo} ++if test "X$1" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++elif test "X$1" = X--fallback-echo; then ++ # Avoid inline document here, it may be left over ++ : ++elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then ++ # Yippee, $ECHO works! ++ : ++else ++ # Restart under the correct shell. ++ exec $SHELL "$0" --no-reexec ${1+"$@"} ++fi ++ ++if test "X$1" = X--fallback-echo; then ++ # used as fallback echo ++ shift ++ cat <<_LT_EOF ++$* ++_LT_EOF ++ exit 0 ++fi ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++if test -z "$lt_ECHO"; then ++ if test "X${echo_test_string+set}" != Xset; then ++ # find a string as large as possible, as long as the shell can cope with it ++ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do ++ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... ++ if { echo_test_string=`eval $cmd`; } 2>/dev/null && ++ { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null ++ then ++ break ++ fi ++ done ++ fi ++ ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ : ++ else ++ # The Solaris, AIX, and Digital Unix default echo programs unquote ++ # backslashes. This makes it impossible to quote backslashes using ++ # echo "$something" | sed 's/\\/\\\\/g' ++ # ++ # So, first we look for a working echo in the user's PATH. ++ ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for dir in $PATH /usr/ucb; do ++ IFS="$lt_save_ifs" ++ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && ++ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$dir/echo" ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ if test "X$ECHO" = Xecho; then ++ # We didn't find a better echo, so look for alternatives. ++ if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # This shell has a builtin print -r that does the trick. ++ ECHO='print -r' ++ elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && ++ test "X$CONFIG_SHELL" != X/bin/ksh; then ++ # If we have ksh, try running configure again with it. ++ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} ++ export ORIGINAL_CONFIG_SHELL ++ CONFIG_SHELL=/bin/ksh ++ export CONFIG_SHELL ++ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} ++ else ++ # Try using printf. ++ ECHO='printf %s\n' ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # Cool, printf works ++ : ++ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL ++ export CONFIG_SHELL ++ SHELL="$CONFIG_SHELL" ++ export SHELL ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ else ++ # maybe with a smaller string... ++ prev=: ++ ++ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do ++ if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null ++ then ++ break ++ fi ++ prev="$cmd" ++ done ++ ++ if test "$prev" != 'sed 50q "$0"'; then ++ echo_test_string=`eval $prev` ++ export echo_test_string ++ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} ++ else ++ # Oops. We lost completely, so just stick with echo. ++ ECHO=echo ++ fi ++ fi ++ fi ++ fi ++ fi ++fi ++ ++# Copy echo and quote the copy suitably for passing to libtool from ++# the Makefile, instead of quoting the original, which is used later. ++lt_ECHO=$ECHO ++if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then ++ lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" ++fi ++ ++ ++ + + test -n "$DJDIR" || exec 7<&0 &1 +@@ -631,6 +919,7 @@ + LIBTOOL + OBJDUMP + DLLTOOL ++lt_ECHO + SED + sys_dir + machine_dir +@@ -797,6 +1086,7 @@ + sysvi386 + sysvnecv70 + tic80 ++tsvc + w65 + z8ksim' + +@@ -3823,45 +4113,6 @@ + + + +-ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +-ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +-ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +-$as_echo_n "checking how to print strings... " >&6; } +-# Test print first, because it will be a builtin if present. +-if test "X`print -r -- -n 2>/dev/null`" = X-n && \ +- test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then +- ECHO='print -r --' +-elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then +- ECHO='printf %s\n' +-else +- # Use this function as a fallback that always works. +- func_fallback_echo () +- { +- eval 'cat <<_LTECHO_EOF +-$1 +-_LTECHO_EOF' +- } +- ECHO='func_fallback_echo' +-fi +- +-# func_echo_all arg... +-# Invoke $ECHO with all args, space-separated. +-func_echo_all () +-{ +- $ECHO "" +-} +- +-case "$ECHO" in +- printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +-$as_echo "printf" >&6; } ;; +- print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +-$as_echo "print -r" >&6; } ;; +- *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +-$as_echo "cat" >&6; } ;; +-esac +- + + + +@@ -3879,7 +4130,7 @@ + enable_win32_dll=yes + + case $host in +-*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) ++*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. + set dummy ${ac_tool_prefix}as; ac_word=$2 +@@ -4187,8 +4438,8 @@ + + + +-macro_version='2.2.7a' +-macro_revision='1.3134' ++macro_version='2.2.6b' ++macro_revision='1.3017' + + + +@@ -4204,23 +4455,6 @@ + + ltmain="$ac_aux_dir/ltmain.sh" + +-# Backslashify metacharacters that are still active within +-# double-quoted strings. +-sed_quote_subst='s/\(["`$\\]\)/\\\1/g' +- +-# Same as above, but do not quote variable references. +-double_quote_subst='s/\(["`\\]\)/\\\1/g' +- +-# Sed substitution to delay expansion of an escaped shell variable in a +-# double_quote_subst'ed string. +-delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' +- +-# Sed substitution to delay expansion of an escaped single quote. +-delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' +- +-# Sed substitution to avoid accidental globbing in evaled expressions +-no_glob_subst='s/\*/\\\*/g' +- + ac_ext=c + ac_cpp='$CPP $CPPFLAGS' + ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +@@ -5522,11 +5756,8 @@ + NM="$lt_cv_path_NM" + else + # Didn't find any BSD compatible name lister, look for dumpbin. +- if test -n "$DUMPBIN"; then : +- # Let the user override the test. +- else +- if test -n "$ac_tool_prefix"; then +- for ac_prog in dumpbin "link -dump" ++ if test -n "$ac_tool_prefix"; then ++ for ac_prog in "dumpbin -symbols" "link -dump -symbols" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. + set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +@@ -5570,7 +5801,7 @@ + fi + if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN +- for ac_prog in dumpbin "link -dump" ++ for ac_prog in "dumpbin -symbols" "link -dump -symbols" + do + # Extract the first word of "$ac_prog", so it can be a program name with args. + set dummy $ac_prog; ac_word=$2 +@@ -5625,15 +5856,6 @@ + fi + fi + +- case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in +- *COFF*) +- DUMPBIN="$DUMPBIN -symbols" +- ;; +- *) +- DUMPBIN=: +- ;; +- esac +- fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" +@@ -5653,13 +5875,13 @@ + else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext +- (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) ++ (eval echo "\"\$as_me:5878: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 +- (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) ++ (eval echo "\"\$as_me:5881: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 +- (eval echo "\"\$as_me:$LINENO: output\"" >&5) ++ (eval echo "\"\$as_me:5884: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" +@@ -5716,11 +5938,6 @@ + lt_cv_sys_max_cmd_len=8192; + ;; + +- mint*) +- # On MiNT this can take a long time and run out of memory. +- lt_cv_sys_max_cmd_len=8192; +- ;; +- + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. +@@ -5785,8 +6002,8 @@ + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. +- while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ +- = "X$teststring$teststring"; } >/dev/null 2>&1 && ++ while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ ++ = "XX$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` +@@ -6054,8 +6271,7 @@ + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. +- # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. +- if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then ++ if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else +@@ -6064,7 +6280,7 @@ + fi + ;; + +-cegcc*) ++cegcc) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' +@@ -6094,10 +6310,6 @@ + lt_cv_deplibs_check_method=pass_all + ;; + +-haiku*) +- lt_cv_deplibs_check_method=pass_all +- ;; +- + hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in +@@ -6106,11 +6318,11 @@ + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) +- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) +- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac +@@ -6136,7 +6348,7 @@ + lt_cv_deplibs_check_method=pass_all + ;; + +-netbsd*) ++netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else +@@ -6548,18 +6760,6 @@ + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" + fi + +-case $host_os in +- darwin*) +- lock_old_archive_extraction=yes ;; +- *) +- lock_old_archive_extraction=no ;; +-esac +- +- +- +- +- +- + + + +@@ -6729,8 +6929,8 @@ + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm +- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 +- (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5 ++ (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then +@@ -6884,7 +7084,7 @@ + ;; + *-*-irix6*) + # Find out which ABI we are using. +- echo '#line '$LINENO' "configure"' > conftest.$ac_ext ++ echo '#line 7087 "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? +@@ -7596,36 +7796,6 @@ + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 + $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +-$as_echo_n "checking for -force_load linker flag... " >&6; } +-if test "${lt_cv_ld_force_load+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- lt_cv_ld_force_load=no +- cat > conftest.c << _LT_EOF +-int forced_loaded() { return 2;} +-_LT_EOF +- echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 +- $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 +- echo "$AR cru libconftest.a conftest.o" >&5 +- $AR cru libconftest.a conftest.o 2>&5 +- cat > conftest.c << _LT_EOF +-int main() { return 0;} +-_LT_EOF +- echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 +- $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err +- _lt_result=$? +- if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then +- lt_cv_ld_force_load=yes +- else +- cat conftest.err >&5 +- fi +- rm -f conftest.err libconftest.a conftest conftest.c +- rm -rf conftest.dSYM +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +-$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; +@@ -7653,7 +7823,7 @@ + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi +- if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then ++ if test "$DSYMUTIL" != ":"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= +@@ -7944,8 +8114,6 @@ + + + +- +- + # Set options + + +@@ -8096,7 +8264,6 @@ + + + +- + test -z "$LN_S" && LN_S="ln -s" + + +@@ -8146,6 +8313,13 @@ + + + ++ ++ ++ ++ ++ ++ ++ + case $host_os in + aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some +@@ -8158,6 +8332,23 @@ + ;; + esac + ++# Sed substitution that helps us do robust quoting. It backslashifies ++# metacharacters that are still active within double-quoted strings. ++sed_quote_subst='s/\(["`$\\]\)/\\\1/g' ++ ++# Same as above, but do not quote variable references. ++double_quote_subst='s/\(["`\\]\)/\\\1/g' ++ ++# Sed substitution to delay expansion of an escaped shell variable in a ++# double_quote_subst'ed string. ++delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' ++ ++# Sed substitution to delay expansion of an escaped single quote. ++delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' ++ ++# Sed substitution to avoid accidental globbing in evaled expressions ++no_glob_subst='s/\*/\\\*/g' ++ + # Global variables: + ofile=libtool + can_build_shared=yes +@@ -8186,7 +8377,7 @@ + *) break;; + esac + done +-cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ++cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + + # Only perform the check for file, if the check method requires it +@@ -8395,12 +8586,7 @@ + lt_prog_compiler_no_builtin_flag= + + if test "$GCC" = yes; then +- case $cc_basename in +- nvcc*) +- lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; +- *) +- lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; +- esac ++ lt_prog_compiler_no_builtin_flag=' -fno-builtin' + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 + $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +@@ -8420,15 +8606,15 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:8609: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:8613: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes +@@ -8506,12 +8692,6 @@ + lt_prog_compiler_pic='-fno-common' + ;; + +- haiku*) +- # PIC is the default for Haiku. +- # The "-static" flag exists, but is broken. +- lt_prog_compiler_static= +- ;; +- + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag +@@ -8554,13 +8734,6 @@ + lt_prog_compiler_pic='-fPIC' + ;; + esac +- +- case $cc_basename in +- nvcc*) # Cuda Compiler Driver 2.2 +- lt_prog_compiler_wl='-Xlinker ' +- lt_prog_compiler_pic='-Xcompiler -fPIC' +- ;; +- esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in +@@ -8623,7 +8796,7 @@ + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; +- pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) ++ pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' +@@ -8635,26 +8808,26 @@ + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; +- xl* | bgxl* | bgf* | mpixl*) +- # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene ++ xl*) ++ # IBM XL C 8.0/Fortran 10.1 on PPC + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in +- *Sun\ F* | *Sun*Fortran*) +- # Sun Fortran 8.3 passes all unrecognized flags to the linker +- lt_prog_compiler_pic='-KPIC' +- lt_prog_compiler_static='-Bstatic' +- lt_prog_compiler_wl='' +- ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; ++ *Sun\ F*) ++ # Sun Fortran 8.3 passes all unrecognized flags to the linker ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ lt_prog_compiler_wl='' ++ ;; + esac + ;; + esac +@@ -8772,15 +8945,15 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:8948: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:8952: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes +@@ -8828,7 +9001,7 @@ + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 +- $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp ++ $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes +@@ -8877,16 +9050,16 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:9053: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:9057: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes +@@ -8932,16 +9105,16 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:9108: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:9112: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes +@@ -9051,36 +9224,13 @@ + openbsd*) + with_gnu_ld=no + ;; ++ linux* | k*bsd*-gnu) ++ link_all_deplibs=no ++ ;; + esac + + ld_shlibs=yes +- +- # On some targets, GNU ld is compatible enough with the native linker +- # that we're better off using the native interface for both. +- lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then +- case $host_os in +- aix*) +- # The AIX port of GNU ld has always aspired to compatibility +- # with the native linker. However, as the warning in the GNU ld +- # block says, versions before 2.19.5* couldn't really create working +- # shared libraries, regardless of the interface used. +- case `$LD -v 2>&1` in +- *\ \(GNU\ Binutils\)\ 2.19.5*) ;; +- *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; +- *\ \(GNU\ Binutils\)\ [3-9]*) ;; +- *) +- lt_use_gnu_ld_interface=yes +- ;; +- esac +- ;; +- *) +- lt_use_gnu_ld_interface=yes +- ;; +- esac +- fi +- +- if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + +@@ -9114,12 +9264,11 @@ + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +-*** Warning: the GNU linker, at least up to release 2.19, is reported ++*** Warning: the GNU linker, at least up to release 2.9.1, is reported + *** to be unable to reliably create shared libraries on AIX. + *** Therefore, libtool is disabling shared libraries support. If you +-*** really care for shared libraries, you may want to install binutils +-*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +-*** You will then need to restart the configuration process. ++*** really care for shared libraries, you may want to modify your PATH ++*** so that a non-GNU linker is found, and then restart. + + _LT_EOF + fi +@@ -9155,7 +9304,6 @@ + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' +- export_dynamic_flag_spec='${wl}--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes +@@ -9177,11 +9325,6 @@ + fi + ;; + +- haiku*) +- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' +- link_all_deplibs=yes +- ;; +- + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no +@@ -9211,12 +9354,11 @@ + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler +- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; +- pgf77* | pgf90* | pgf95* | pgfortran*) +- # Portland Group f77 and f90 compilers +- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers ++ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; +@@ -9227,17 +9369,13 @@ + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; +- xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) ++ xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; +- nvcc*) # Cuda Compiler Driver 2.2 +- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' +- compiler_needs_object=yes +- ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 +- whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 +@@ -9253,7 +9391,7 @@ + fi + + case $cc_basename in +- xlf* | bgf* | bgxlf* | mpixlf*) ++ xlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec= +@@ -9272,7 +9410,7 @@ + fi + ;; + +- netbsd*) ++ netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= +@@ -9384,10 +9522,8 @@ + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm +- # Also, AIX nm treats weak defined symbols like other global +- # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then +- export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' ++ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi +@@ -9449,6 +9585,7 @@ + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi ++ link_all_deplibs=no + else + # not using gcc + if test "$host_cpu" = ia64; then +@@ -9505,7 +9642,7 @@ + if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" +- archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" ++ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' +@@ -9549,13 +9686,8 @@ + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' +- if test "$with_gnu_ld" = yes; then +- # We only use this code for GNU lds that support --whole-archive. +- whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' +- else +- # Exported symbols can be pulled into shared objects from archives +- whole_archive_flag_spec='$convenience' +- fi ++ # Exported symbols can be pulled into shared objects from archives ++ whole_archive_flag_spec='$convenience' + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' +@@ -9594,7 +9726,7 @@ + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. +- archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' ++ archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. +@@ -9610,11 +9742,7 @@ + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported +- if test "$lt_cv_ld_force_load" = "yes"; then +- whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' +- else +- whole_archive_flag_spec='' +- fi ++ whole_archive_flag_spec='' + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in +@@ -9622,7 +9750,7 @@ + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then +- output_verbose_link_cmd=func_echo_all ++ output_verbose_link_cmd=echo + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +@@ -9688,7 +9816,7 @@ + ;; + + hpux10*) +- if test "$GCC" = yes && test "$with_gnu_ld" = no; then ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +@@ -9707,7 +9835,7 @@ + ;; + + hpux11*) +- if test "$GCC" = yes && test "$with_gnu_ld" = no; then ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' +@@ -9728,46 +9856,7 @@ + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) +- +- # Older versions of the 11.00 compiler do not understand -b yet +- # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +-$as_echo_n "checking if $CC understands -b... " >&6; } +-if test "${lt_cv_prog_compiler__b+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- lt_cv_prog_compiler__b=no +- save_LDFLAGS="$LDFLAGS" +- LDFLAGS="$LDFLAGS -b" +- echo "$lt_simple_link_test_code" > conftest.$ac_ext +- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then +- # The linker can only warn and ignore the option if not recognized +- # So say no if there are warnings +- if test -s conftest.err; then +- # Append any errors to the config.log. +- cat conftest.err 1>&5 +- $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp +- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 +- if diff conftest.exp conftest.er2 >/dev/null; then +- lt_cv_prog_compiler__b=yes +- fi +- else +- lt_cv_prog_compiler__b=yes +- fi +- fi +- $RM -r conftest* +- LDFLAGS="$save_LDFLAGS" +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +-$as_echo "$lt_cv_prog_compiler__b" >&6; } +- +-if test x"$lt_cv_prog_compiler__b" = xyes; then +- archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +-else +- archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +-fi +- ++ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi +@@ -9795,7 +9884,7 @@ + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then +- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. +@@ -9806,15 +9895,15 @@ + int foo(void) {} + _ACEOF + if ac_fn_c_try_link "$LINENO"; then : +- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + + fi + rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + else +- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' +- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' +@@ -9823,7 +9912,7 @@ + link_all_deplibs=yes + ;; + +- netbsd*) ++ netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else +@@ -9876,17 +9965,17 @@ + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported +- archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' ++ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' +@@ -9896,13 +9985,13 @@ + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ +- $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' ++ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' +@@ -10105,50 +10194,44 @@ + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 + $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +-if test "${lt_cv_archive_cmds_need_lc+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- $RM conftest* +- echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ $RM conftest* ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext + +- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then +- soname=conftest +- lib=conftest +- libobjs=conftest.$ac_objext +- deplibs= +- wl=$lt_prog_compiler_wl +- pic_flag=$lt_prog_compiler_pic +- compiler_flags=-v +- linker_flags=-v +- verstring= +- output_objdir=. +- libname=conftest +- lt_save_allow_undefined_flag=$allow_undefined_flag +- allow_undefined_flag= +- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 ++ soname=conftest ++ lib=conftest ++ libobjs=conftest.$ac_objext ++ deplibs= ++ wl=$lt_prog_compiler_wl ++ pic_flag=$lt_prog_compiler_pic ++ compiler_flags=-v ++ linker_flags=-v ++ verstring= ++ output_objdir=. ++ libname=conftest ++ lt_save_allow_undefined_flag=$allow_undefined_flag ++ allow_undefined_flag= ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +- then +- lt_cv_archive_cmds_need_lc=no +- else +- lt_cv_archive_cmds_need_lc=yes +- fi +- allow_undefined_flag=$lt_save_allow_undefined_flag +- else +- cat conftest.err 1>&5 +- fi +- $RM conftest* +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +-$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } +- archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ++ then ++ archive_cmds_need_lc=no ++ else ++ archive_cmds_need_lc=yes ++ fi ++ allow_undefined_flag=$lt_save_allow_undefined_flag ++ else ++ cat conftest.err 1>&5 ++ fi ++ $RM conftest* ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5 ++$as_echo "$archive_cmds_need_lc" >&6; } + ;; + esac + fi +@@ -10319,23 +10402,16 @@ + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac +- case $host_os in +- mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; +- *) lt_sed_strip_eq="s,=/,/,g" ;; +- esac +- lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` +- case $lt_search_path_spec in +- *\;*) ++ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. +- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` +- ;; +- *) +- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` +- ;; +- esac ++ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= +@@ -10348,7 +10424,7 @@ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done +- lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' ++ lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' + BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; +@@ -10368,13 +10444,7 @@ + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } + }'` +- # AWK program above erroneously prepends '/' to C:/dos/paths +- # for these hosts. +- case $host_os in +- mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ +- $SED 's,/\([A-Za-z]:\),\1,g'` ;; +- esac +- sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` ++ sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` + else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + fi +@@ -10462,7 +10532,7 @@ + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. +- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ++ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; +@@ -10515,12 +10585,23 @@ + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' +- +- sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ++ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then ++ # It is most probably a Windows format PATH printed by ++ # mingw gcc, but we are running on Cygwin. Gcc prints its search ++ # path with ; separators, and with drive letters. We can handle the ++ # drive letters (cygwin fileutils understands them), so leave them, ++ # especially as we might pass files found there to a mingw objdump, ++ # which wouldn't understand a cygwinified path. Ahh. ++ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' +@@ -10620,19 +10701,6 @@ + hardcode_into_libs=yes + ;; + +-haiku*) +- version_type=linux +- need_lib_prefix=no +- need_version=no +- dynamic_linker="$host_os runtime_loader" +- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' +- soname_spec='${libname}${release}${shared_ext}$major' +- shlibpath_var=LIBRARY_PATH +- shlibpath_overrides_runpath=yes +- sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib' +- hardcode_into_libs=yes +- ;; +- + hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. +@@ -10675,10 +10743,8 @@ + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac +- # HP-UX runs *really* slowly unless shared libraries are mode 555, ... ++ # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' +- # or fails outright, so override atomically: +- install_override_mode=555 + ;; + + interix[3-9]*) +@@ -10745,17 +10811,12 @@ + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no +- + # Some binutils ld are patched to set DT_RUNPATH +- if test "${lt_cv_shlibpath_overrides_runpath+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- lt_cv_shlibpath_overrides_runpath=no +- save_LDFLAGS=$LDFLAGS +- save_libdir=$libdir +- eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ +- LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++ save_LDFLAGS=$LDFLAGS ++ save_libdir=$libdir ++ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ ++ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + + int +@@ -10768,17 +10829,13 @@ + _ACEOF + if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : +- lt_cv_shlibpath_overrides_runpath=yes ++ shlibpath_overrides_runpath=yes + fi + fi + rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +- LDFLAGS=$save_LDFLAGS +- libdir=$save_libdir +- +-fi +- +- shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath ++ LDFLAGS=$save_LDFLAGS ++ libdir=$save_libdir + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install +@@ -10787,7 +10844,7 @@ + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then +- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + +@@ -10800,6 +10857,18 @@ + dynamic_linker='GNU/Linux ld.so' + ;; + ++netbsdelf*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='NetBSD ld.elf_so' ++ ;; ++ + netbsd*) + version_type=sunos + need_lib_prefix=no +@@ -11090,11 +11159,6 @@ + + + +- +- +- +- +- + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 + $as_echo_n "checking how to hardcode library paths into programs... " >&6; } + hardcode_action= +@@ -11425,7 +11489,7 @@ + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11428 "configure" ++#line 11492 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11466,13 +11530,7 @@ + # endif + #endif + +-/* When -fvisbility=hidden is used, assume the code has been annotated +- correspondingly for the symbols needed. */ +-#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +-void fnord () __attribute__((visibility("default"))); +-#endif +- +-void fnord () { int i=42; } ++void fnord() { int i=42;} + int main () + { + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); +@@ -11481,11 +11539,7 @@ + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; +- else +- { +- if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; +- else puts (dlerror ()); +- } ++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else +@@ -11531,7 +11585,7 @@ + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11534 "configure" ++#line 11588 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11572,13 +11626,7 @@ + # endif + #endif + +-/* When -fvisbility=hidden is used, assume the code has been annotated +- correspondingly for the symbols needed. */ +-#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +-void fnord () __attribute__((visibility("default"))); +-#endif +- +-void fnord () { int i=42; } ++void fnord() { int i=42;} + int main () + { + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); +@@ -11587,11 +11635,7 @@ + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; +- else +- { +- if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; +- else puts (dlerror ()); +- } ++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else +@@ -11818,6 +11862,8 @@ + ;; + tic80) subdirs="$subdirs tic80" + ;; ++ tsvc) subdirs="$subdirs tsvc" ++ ;; + w65) subdirs="$subdirs w65" + ;; + z8ksim) subdirs="$subdirs z8ksim" +@@ -12608,148 +12654,135 @@ + sed_quote_subst='$sed_quote_subst' + double_quote_subst='$double_quote_subst' + delay_variable_subst='$delay_variable_subst' +-SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +-Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +-SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +-ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +-AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' +-DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +-OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +-macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +-macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +-enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +-enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +-pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +-enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +-host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +-host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +-host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +-build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +-build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +-build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +-GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +-EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +-FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +-LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +-NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +-LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +-max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +-ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +-exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +-lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +-lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +-lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +-reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +-reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +-deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +-file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +-AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +-AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +-STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +-RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +-old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +-old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +-old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +-lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +-CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +-CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +-compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +-GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +-objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +-MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +-lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +-need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +-DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +-NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +-LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +-OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +-OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +-libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +-shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +-extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +-archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +-enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +-export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +-whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +-compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +-old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +-old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +-archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +-archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +-module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +-module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +-with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +-allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +-no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +-hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +-hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`' +-hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +-hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +-hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +-hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +-hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +-hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +-inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +-link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +-fix_srcfile_path='`$ECHO "$fix_srcfile_path" | $SED "$delay_single_quote_subst"`' +-always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +-export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +-exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +-include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +-prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +-file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +-variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +-need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +-need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +-version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +-runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +-shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +-shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +-libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +-library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +-soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +-install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +-postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +-postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +-finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +-finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +-hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +-sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +-sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +-hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +-enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +-enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +-enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +-old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +-striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' ++SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`' ++Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`' ++SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`' ++ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`' ++AS='`$ECHO "X$AS" | $Xsed -e "$delay_single_quote_subst"`' ++DLLTOOL='`$ECHO "X$DLLTOOL" | $Xsed -e "$delay_single_quote_subst"`' ++OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`' ++macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`' ++macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`' ++enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`' ++enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`' ++pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`' ++enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`' ++host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`' ++host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`' ++host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`' ++build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`' ++build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`' ++build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`' ++GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`' ++EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`' ++FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`' ++LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`' ++NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`' ++LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`' ++max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`' ++ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`' ++exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`' ++lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`' ++lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`' ++lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`' ++reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`' ++reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`' ++file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`' ++AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`' ++AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`' ++STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`' ++RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`' ++old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`' ++CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`' ++compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`' ++GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' ++objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`' ++MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`' ++need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`' ++DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`' ++NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`' ++LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`' ++OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`' ++OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`' ++libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`' ++shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`' ++enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`' ++export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`' ++allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' ++no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`' ++inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`' ++link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`' ++fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`' ++always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`' ++export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`' ++include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`' ++prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`' ++variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`' ++need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' ++need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`' ++version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`' ++runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`' ++libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`' ++library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`' ++soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`' ++postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`' ++sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`' ++sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`' ++old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`' ++striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`' + + LTCC='$LTCC' + LTCFLAGS='$LTCFLAGS' + compiler='$compiler_DEFAULT' + +-# A function that is used when there is no print builtin or printf. +-func_fallback_echo () +-{ +- eval 'cat <<_LTECHO_EOF +-\$1 +-_LTECHO_EOF' +-} +- + # Quote evaled strings. + for var in SED \ + SHELL \ + ECHO \ +-AS \ +-DLLTOOL \ +-OBJDUMP \ + GREP \ + EGREP \ + FGREP \ +@@ -12801,13 +12834,12 @@ + libname_spec \ + library_names_spec \ + soname_spec \ +-install_override_mode \ + finish_eval \ + old_striplib \ + striplib; do +- case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in ++ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) +- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ++ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" +@@ -12834,9 +12866,9 @@ + finish_cmds \ + sys_lib_search_path_spec \ + sys_lib_dlsearch_path_spec; do +- case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in ++ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) +- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ++ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" +@@ -12844,6 +12876,12 @@ + esac + done + ++# Fix-up fallback echo if it was mangled by the above quoting rules. ++case \$lt_ECHO in ++*'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\` ++ ;; ++esac ++ + ac_aux_dir='$ac_aux_dir' + xsi_shell='$xsi_shell' + lt_shell_append='$lt_shell_append' +@@ -13409,7 +13447,7 @@ + # NOTE: Changes made to this file will be lost: look at ltmain.sh. + # + # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +-# 2006, 2007, 2008, 2009 Free Software Foundation, Inc. ++# 2006, 2007, 2008 Free Software Foundation, Inc. + # Written by Gordon Matzigkeit, 1996 + # + # This file is part of GNU Libtool. +@@ -13450,17 +13488,17 @@ + # Shell to use when invoking shell scripts. + SHELL=$lt_SHELL + +-# An echo program that protects backslashes. ++# An echo program that does not interpret backslashes. + ECHO=$lt_ECHO + + # Assembler program. +-AS=$lt_AS ++AS=$AS + + # DLL creation program. +-DLLTOOL=$lt_DLLTOOL ++DLLTOOL=$DLLTOOL + + # Object dumper program. +-OBJDUMP=$lt_OBJDUMP ++OBJDUMP=$OBJDUMP + + # Which release of libtool.m4 was used? + macro_version=$macro_version +@@ -13521,6 +13559,10 @@ + # turn newlines into spaces. + NL2SP=$lt_lt_NL2SP + ++# How to create reloadable object files. ++reload_flag=$lt_reload_flag ++reload_cmds=$lt_reload_cmds ++ + # Method to check whether dependent libraries are shared objects. + deplibs_check_method=$lt_deplibs_check_method + +@@ -13539,9 +13581,6 @@ + old_postinstall_cmds=$lt_old_postinstall_cmds + old_postuninstall_cmds=$lt_old_postuninstall_cmds + +-# Whether to use a lock for old archive extraction. +-lock_old_archive_extraction=$lock_old_archive_extraction +- + # A C compiler. + LTCC=$lt_CC + +@@ -13625,9 +13664,6 @@ + # The coded name of the library, if different from the real name. + soname_spec=$lt_soname_spec + +-# Permission mode override for installation of shared libraries. +-install_override_mode=$lt_install_override_mode +- + # Command to use after installation of a shared archive. + postinstall_cmds=$lt_postinstall_cmds + +@@ -13667,10 +13703,6 @@ + # The linker used to build libraries. + LD=$lt_LD + +-# How to create reloadable object files. +-reload_flag=$lt_reload_flag +-reload_cmds=$lt_reload_cmds +- + # Commands used to build an old-style archive. + old_archive_cmds=$lt_old_archive_cmds + +@@ -13930,7 +13962,7 @@ + func_dirname () + { + # Extract subdirectory from the argument. +- func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` ++ func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else +@@ -13941,7 +13973,7 @@ + # func_basename file + func_basename () + { +- func_basename_result=`$ECHO "${1}" | $SED "$basename"` ++ func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` + } + + +@@ -13954,8 +13986,10 @@ + func_stripname () + { + case ${2} in +- .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; +- *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; ++ .*) func_stripname_result=`$ECHO "X${3}" \ ++ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; ++ *) func_stripname_result=`$ECHO "X${3}" \ ++ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; + esac + } + +@@ -13966,20 +14000,20 @@ + # func_opt_split + func_opt_split () + { +- func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"` +- func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"` ++ func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` ++ func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` + } + + # func_lo2o object + func_lo2o () + { +- func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` ++ func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` + } + + # func_xform libobj-or-source + func_xform () + { +- func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` ++ func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'` + } + + # func_arith arithmetic-term... +diff -Naur newlib-1.19.0/newlib/libc/sys/configure.in newlib-1.19.0-tee-sdk/newlib/libc/sys/configure.in +--- newlib-1.19.0/newlib/libc/sys/configure.in 2010-02-24 15:59:55.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/configure.in 2013-10-21 15:44:33.000000000 -0400 +@@ -44,6 +44,7 @@ + sysvi386) AC_CONFIG_SUBDIRS(sysvi386) ;; + sysvnecv70) AC_CONFIG_SUBDIRS(sysvnecv70) ;; + tic80) AC_CONFIG_SUBDIRS(tic80) ;; ++ tsvc) AC_CONFIG_SUBDIRS(tsvc) ;; + w65) AC_CONFIG_SUBDIRS(w65) ;; + z8ksim) AC_CONFIG_SUBDIRS(z8ksim) ;; + esac; +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/aclocal.m4 newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/aclocal.m4 +--- newlib-1.19.0/newlib/libc/sys/linux/aclocal.m4 2010-12-16 16:59:06.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/aclocal.m4 2013-10-21 15:44:33.000000000 -0400 +@@ -989,9 +989,10 @@ + AC_SUBST([am__untar]) + ]) # _AM_PROG_TAR + +-m4_include([../../../../libtool.m4]) +-m4_include([../../../../ltoptions.m4]) +-m4_include([../../../../ltsugar.m4]) +-m4_include([../../../../ltversion.m4]) + m4_include([../../../../lt~obsolete.m4]) + m4_include([../../../acinclude.m4]) ++m4_include([../../../libtool.m4]) ++m4_include([../../../ltoptions.m4]) ++m4_include([../../../ltsugar.m4]) ++m4_include([../../../ltversion.m4]) ++m4_include([../../../lt~obsolete.m4]) +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/argp/Makefile.in newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/argp/Makefile.in +--- newlib-1.19.0/newlib/libc/sys/linux/argp/Makefile.in 2010-12-16 16:59:07.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/argp/Makefile.in 2013-10-21 15:44:33.000000000 -0400 +@@ -40,12 +40,14 @@ + $(srcdir)/Makefile.in $(srcdir)/Makefile.am + subdir = argp + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +-am__aclocal_m4_deps = $(top_srcdir)/../../../../libtool.m4 \ +- $(top_srcdir)/../../../../ltoptions.m4 \ +- $(top_srcdir)/../../../../ltsugar.m4 \ +- $(top_srcdir)/../../../../ltversion.m4 \ +- $(top_srcdir)/../../../../lt~obsolete.m4 \ +- $(top_srcdir)/../../../acinclude.m4 $(top_srcdir)/configure.in ++am__aclocal_m4_deps = $(top_srcdir)/../../../../lt~obsolete.m4 \ ++ $(top_srcdir)/../../../acinclude.m4 \ ++ $(top_srcdir)/../../../libtool.m4 \ ++ $(top_srcdir)/../../../ltoptions.m4 \ ++ $(top_srcdir)/../../../ltsugar.m4 \ ++ $(top_srcdir)/../../../ltversion.m4 \ ++ $(top_srcdir)/../../../lt~obsolete.m4 \ ++ $(top_srcdir)/configure.in + am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) + mkinstalldirs = $(SHELL) $(top_srcdir)/../../../../mkinstalldirs +@@ -197,6 +199,7 @@ + localedir = @localedir@ + localstatedir = @localstatedir@ + lpfx = @lpfx@ ++lt_ECHO = @lt_ECHO@ + machine_dir = @machine_dir@ + mandir = @mandir@ + mkdir_p = @mkdir_p@ +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/cmath/Makefile.in newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/cmath/Makefile.in +--- newlib-1.19.0/newlib/libc/sys/linux/cmath/Makefile.in 2010-12-16 16:59:07.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/cmath/Makefile.in 2013-10-21 15:44:33.000000000 -0400 +@@ -40,12 +40,14 @@ + $(srcdir)/Makefile.in $(srcdir)/Makefile.am + subdir = cmath + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +-am__aclocal_m4_deps = $(top_srcdir)/../../../../libtool.m4 \ +- $(top_srcdir)/../../../../ltoptions.m4 \ +- $(top_srcdir)/../../../../ltsugar.m4 \ +- $(top_srcdir)/../../../../ltversion.m4 \ +- $(top_srcdir)/../../../../lt~obsolete.m4 \ +- $(top_srcdir)/../../../acinclude.m4 $(top_srcdir)/configure.in ++am__aclocal_m4_deps = $(top_srcdir)/../../../../lt~obsolete.m4 \ ++ $(top_srcdir)/../../../acinclude.m4 \ ++ $(top_srcdir)/../../../libtool.m4 \ ++ $(top_srcdir)/../../../ltoptions.m4 \ ++ $(top_srcdir)/../../../ltsugar.m4 \ ++ $(top_srcdir)/../../../ltversion.m4 \ ++ $(top_srcdir)/../../../lt~obsolete.m4 \ ++ $(top_srcdir)/configure.in + am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) + mkinstalldirs = $(SHELL) $(top_srcdir)/../../../../mkinstalldirs +@@ -215,6 +217,7 @@ + localedir = @localedir@ + localstatedir = @localstatedir@ + lpfx = @lpfx@ ++lt_ECHO = @lt_ECHO@ + machine_dir = @machine_dir@ + mandir = @mandir@ + mkdir_p = @mkdir_p@ +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/configure newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/configure +--- newlib-1.19.0/newlib/libc/sys/linux/configure 2010-12-16 16:59:06.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/configure 2013-10-21 15:44:33.000000000 -0400 +@@ -171,15 +171,7 @@ + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +-test \$(( 1 + 1 )) = 2 || exit 1 +- +- test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( +- ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +- ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO +- ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO +- PATH=/empty FPATH=/empty; export PATH FPATH +- test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ +- || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" ++test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes + else +@@ -533,8 +525,304 @@ + # Sed expression to map a string onto a valid variable name. + as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + ++ ++ ++# Check that we are running under the correct shell. + SHELL=${CONFIG_SHELL-/bin/sh} + ++case X$lt_ECHO in ++X*--fallback-echo) ++ # Remove one level of quotation (which was required for Make). ++ ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` ++ ;; ++esac ++ ++ECHO=${lt_ECHO-echo} ++if test "X$1" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++elif test "X$1" = X--fallback-echo; then ++ # Avoid inline document here, it may be left over ++ : ++elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then ++ # Yippee, $ECHO works! ++ : ++else ++ # Restart under the correct shell. ++ exec $SHELL "$0" --no-reexec ${1+"$@"} ++fi ++ ++if test "X$1" = X--fallback-echo; then ++ # used as fallback echo ++ shift ++ cat <<_LT_EOF ++$* ++_LT_EOF ++ exit 0 ++fi ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++if test -z "$lt_ECHO"; then ++ if test "X${echo_test_string+set}" != Xset; then ++ # find a string as large as possible, as long as the shell can cope with it ++ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do ++ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... ++ if { echo_test_string=`eval $cmd`; } 2>/dev/null && ++ { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null ++ then ++ break ++ fi ++ done ++ fi ++ ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ : ++ else ++ # The Solaris, AIX, and Digital Unix default echo programs unquote ++ # backslashes. This makes it impossible to quote backslashes using ++ # echo "$something" | sed 's/\\/\\\\/g' ++ # ++ # So, first we look for a working echo in the user's PATH. ++ ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for dir in $PATH /usr/ucb; do ++ IFS="$lt_save_ifs" ++ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && ++ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$dir/echo" ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ if test "X$ECHO" = Xecho; then ++ # We didn't find a better echo, so look for alternatives. ++ if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # This shell has a builtin print -r that does the trick. ++ ECHO='print -r' ++ elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && ++ test "X$CONFIG_SHELL" != X/bin/ksh; then ++ # If we have ksh, try running configure again with it. ++ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} ++ export ORIGINAL_CONFIG_SHELL ++ CONFIG_SHELL=/bin/ksh ++ export CONFIG_SHELL ++ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} ++ else ++ # Try using printf. ++ ECHO='printf %s\n' ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # Cool, printf works ++ : ++ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL ++ export CONFIG_SHELL ++ SHELL="$CONFIG_SHELL" ++ export SHELL ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ else ++ # maybe with a smaller string... ++ prev=: ++ ++ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do ++ if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null ++ then ++ break ++ fi ++ prev="$cmd" ++ done ++ ++ if test "$prev" != 'sed 50q "$0"'; then ++ echo_test_string=`eval $prev` ++ export echo_test_string ++ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} ++ else ++ # Oops. We lost completely, so just stick with echo. ++ ECHO=echo ++ fi ++ fi ++ fi ++ fi ++ fi ++fi ++ ++# Copy echo and quote the copy suitably for passing to libtool from ++# the Makefile, instead of quoting the original, which is used later. ++lt_ECHO=$ECHO ++if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then ++ lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" ++fi ++ ++ ++ ++ ++ ++# Check that we are running under the correct shell. ++SHELL=${CONFIG_SHELL-/bin/sh} ++ ++case X$lt_ECHO in ++X*--fallback-echo) ++ # Remove one level of quotation (which was required for Make). ++ ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` ++ ;; ++esac ++ ++ECHO=${lt_ECHO-echo} ++if test "X$1" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++elif test "X$1" = X--fallback-echo; then ++ # Avoid inline document here, it may be left over ++ : ++elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then ++ # Yippee, $ECHO works! ++ : ++else ++ # Restart under the correct shell. ++ exec $SHELL "$0" --no-reexec ${1+"$@"} ++fi ++ ++if test "X$1" = X--fallback-echo; then ++ # used as fallback echo ++ shift ++ cat <<_LT_EOF ++$* ++_LT_EOF ++ exit 0 ++fi ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++if test -z "$lt_ECHO"; then ++ if test "X${echo_test_string+set}" != Xset; then ++ # find a string as large as possible, as long as the shell can cope with it ++ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do ++ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... ++ if { echo_test_string=`eval $cmd`; } 2>/dev/null && ++ { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null ++ then ++ break ++ fi ++ done ++ fi ++ ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ : ++ else ++ # The Solaris, AIX, and Digital Unix default echo programs unquote ++ # backslashes. This makes it impossible to quote backslashes using ++ # echo "$something" | sed 's/\\/\\\\/g' ++ # ++ # So, first we look for a working echo in the user's PATH. ++ ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for dir in $PATH /usr/ucb; do ++ IFS="$lt_save_ifs" ++ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && ++ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$dir/echo" ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ if test "X$ECHO" = Xecho; then ++ # We didn't find a better echo, so look for alternatives. ++ if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # This shell has a builtin print -r that does the trick. ++ ECHO='print -r' ++ elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && ++ test "X$CONFIG_SHELL" != X/bin/ksh; then ++ # If we have ksh, try running configure again with it. ++ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} ++ export ORIGINAL_CONFIG_SHELL ++ CONFIG_SHELL=/bin/ksh ++ export CONFIG_SHELL ++ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} ++ else ++ # Try using printf. ++ ECHO='printf %s\n' ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # Cool, printf works ++ : ++ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL ++ export CONFIG_SHELL ++ SHELL="$CONFIG_SHELL" ++ export SHELL ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ else ++ # maybe with a smaller string... ++ prev=: ++ ++ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do ++ if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null ++ then ++ break ++ fi ++ prev="$cmd" ++ done ++ ++ if test "$prev" != 'sed 50q "$0"'; then ++ echo_test_string=`eval $prev` ++ export echo_test_string ++ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} ++ else ++ # Oops. We lost completely, so just stick with echo. ++ ECHO=echo ++ fi ++ fi ++ fi ++ fi ++ fi ++fi ++ ++# Copy echo and quote the copy suitably for passing to libtool from ++# the Makefile, instead of quoting the original, which is used later. ++lt_ECHO=$ECHO ++if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then ++ lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" ++fi ++ ++ ++ + + test -n "$DJDIR" || exec 7<&0 &1 +@@ -631,6 +919,7 @@ + LIBTOOL + OBJDUMP + DLLTOOL ++lt_ECHO + SED + sys_dir + machine_dir +@@ -3801,45 +4090,6 @@ + + + +-ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +-ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +-ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +-$as_echo_n "checking how to print strings... " >&6; } +-# Test print first, because it will be a builtin if present. +-if test "X`print -r -- -n 2>/dev/null`" = X-n && \ +- test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then +- ECHO='print -r --' +-elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then +- ECHO='printf %s\n' +-else +- # Use this function as a fallback that always works. +- func_fallback_echo () +- { +- eval 'cat <<_LTECHO_EOF +-$1 +-_LTECHO_EOF' +- } +- ECHO='func_fallback_echo' +-fi +- +-# func_echo_all arg... +-# Invoke $ECHO with all args, space-separated. +-func_echo_all () +-{ +- $ECHO "" +-} +- +-case "$ECHO" in +- printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +-$as_echo "printf" >&6; } ;; +- print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +-$as_echo "print -r" >&6; } ;; +- *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +-$as_echo "cat" >&6; } ;; +-esac +- + + + +@@ -3899,7 +4149,7 @@ + enable_win32_dll=yes + + case $host in +-*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) ++*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. + set dummy ${ac_tool_prefix}as; ac_word=$2 +@@ -4207,8 +4457,8 @@ + + + +-macro_version='2.2.7a' +-macro_revision='1.3134' ++macro_version='2.2.6b' ++macro_revision='1.3017' + + + +@@ -4224,23 +4474,6 @@ + + ltmain="$ac_aux_dir/ltmain.sh" + +-# Backslashify metacharacters that are still active within +-# double-quoted strings. +-sed_quote_subst='s/\(["`$\\]\)/\\\1/g' +- +-# Same as above, but do not quote variable references. +-double_quote_subst='s/\(["`\\]\)/\\\1/g' +- +-# Sed substitution to delay expansion of an escaped shell variable in a +-# double_quote_subst'ed string. +-delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' +- +-# Sed substitution to delay expansion of an escaped single quote. +-delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' +- +-# Sed substitution to avoid accidental globbing in evaled expressions +-no_glob_subst='s/\*/\\\*/g' +- + ac_ext=c + ac_cpp='$CPP $CPPFLAGS' + ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +@@ -5542,11 +5775,8 @@ + NM="$lt_cv_path_NM" + else + # Didn't find any BSD compatible name lister, look for dumpbin. +- if test -n "$DUMPBIN"; then : +- # Let the user override the test. +- else +- if test -n "$ac_tool_prefix"; then +- for ac_prog in dumpbin "link -dump" ++ if test -n "$ac_tool_prefix"; then ++ for ac_prog in "dumpbin -symbols" "link -dump -symbols" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. + set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +@@ -5590,7 +5820,7 @@ + fi + if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN +- for ac_prog in dumpbin "link -dump" ++ for ac_prog in "dumpbin -symbols" "link -dump -symbols" + do + # Extract the first word of "$ac_prog", so it can be a program name with args. + set dummy $ac_prog; ac_word=$2 +@@ -5645,15 +5875,6 @@ + fi + fi + +- case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in +- *COFF*) +- DUMPBIN="$DUMPBIN -symbols" +- ;; +- *) +- DUMPBIN=: +- ;; +- esac +- fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" +@@ -5673,13 +5894,13 @@ + else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext +- (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) ++ (eval echo "\"\$as_me:5897: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 +- (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) ++ (eval echo "\"\$as_me:5900: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 +- (eval echo "\"\$as_me:$LINENO: output\"" >&5) ++ (eval echo "\"\$as_me:5903: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" +@@ -5736,11 +5957,6 @@ + lt_cv_sys_max_cmd_len=8192; + ;; + +- mint*) +- # On MiNT this can take a long time and run out of memory. +- lt_cv_sys_max_cmd_len=8192; +- ;; +- + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. +@@ -5805,8 +6021,8 @@ + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. +- while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ +- = "X$teststring$teststring"; } >/dev/null 2>&1 && ++ while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ ++ = "XX$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` +@@ -6074,8 +6290,7 @@ + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. +- # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. +- if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then ++ if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else +@@ -6084,7 +6299,7 @@ + fi + ;; + +-cegcc*) ++cegcc) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' +@@ -6114,10 +6329,6 @@ + lt_cv_deplibs_check_method=pass_all + ;; + +-haiku*) +- lt_cv_deplibs_check_method=pass_all +- ;; +- + hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in +@@ -6126,11 +6337,11 @@ + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) +- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) +- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac +@@ -6156,7 +6367,7 @@ + lt_cv_deplibs_check_method=pass_all + ;; + +-netbsd*) ++netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else +@@ -6568,18 +6779,6 @@ + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" + fi + +-case $host_os in +- darwin*) +- lock_old_archive_extraction=yes ;; +- *) +- lock_old_archive_extraction=no ;; +-esac +- +- +- +- +- +- + + + +@@ -6749,8 +6948,8 @@ + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm +- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 +- (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5 ++ (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then +@@ -6904,7 +7103,7 @@ + ;; + *-*-irix6*) + # Find out which ABI we are using. +- echo '#line '$LINENO' "configure"' > conftest.$ac_ext ++ echo '#line 7106 "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? +@@ -7616,36 +7815,6 @@ + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 + $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +-$as_echo_n "checking for -force_load linker flag... " >&6; } +-if test "${lt_cv_ld_force_load+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- lt_cv_ld_force_load=no +- cat > conftest.c << _LT_EOF +-int forced_loaded() { return 2;} +-_LT_EOF +- echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 +- $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 +- echo "$AR cru libconftest.a conftest.o" >&5 +- $AR cru libconftest.a conftest.o 2>&5 +- cat > conftest.c << _LT_EOF +-int main() { return 0;} +-_LT_EOF +- echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 +- $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err +- _lt_result=$? +- if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then +- lt_cv_ld_force_load=yes +- else +- cat conftest.err >&5 +- fi +- rm -f conftest.err libconftest.a conftest conftest.c +- rm -rf conftest.dSYM +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +-$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; +@@ -7673,7 +7842,7 @@ + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi +- if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then ++ if test "$DSYMUTIL" != ":"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= +@@ -7964,8 +8133,6 @@ + + + +- +- + # Set options + + +@@ -8116,7 +8283,6 @@ + + + +- + test -z "$LN_S" && LN_S="ln -s" + + +@@ -8166,6 +8332,13 @@ + + + ++ ++ ++ ++ ++ ++ ++ + case $host_os in + aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some +@@ -8178,6 +8351,23 @@ + ;; + esac + ++# Sed substitution that helps us do robust quoting. It backslashifies ++# metacharacters that are still active within double-quoted strings. ++sed_quote_subst='s/\(["`$\\]\)/\\\1/g' ++ ++# Same as above, but do not quote variable references. ++double_quote_subst='s/\(["`\\]\)/\\\1/g' ++ ++# Sed substitution to delay expansion of an escaped shell variable in a ++# double_quote_subst'ed string. ++delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' ++ ++# Sed substitution to delay expansion of an escaped single quote. ++delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' ++ ++# Sed substitution to avoid accidental globbing in evaled expressions ++no_glob_subst='s/\*/\\\*/g' ++ + # Global variables: + ofile=libtool + can_build_shared=yes +@@ -8206,7 +8396,7 @@ + *) break;; + esac + done +-cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ++cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + + # Only perform the check for file, if the check method requires it +@@ -8415,12 +8605,7 @@ + lt_prog_compiler_no_builtin_flag= + + if test "$GCC" = yes; then +- case $cc_basename in +- nvcc*) +- lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; +- *) +- lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; +- esac ++ lt_prog_compiler_no_builtin_flag=' -fno-builtin' + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 + $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +@@ -8440,15 +8625,15 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:8628: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:8632: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes +@@ -8526,12 +8711,6 @@ + lt_prog_compiler_pic='-fno-common' + ;; + +- haiku*) +- # PIC is the default for Haiku. +- # The "-static" flag exists, but is broken. +- lt_prog_compiler_static= +- ;; +- + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag +@@ -8574,13 +8753,6 @@ + lt_prog_compiler_pic='-fPIC' + ;; + esac +- +- case $cc_basename in +- nvcc*) # Cuda Compiler Driver 2.2 +- lt_prog_compiler_wl='-Xlinker ' +- lt_prog_compiler_pic='-Xcompiler -fPIC' +- ;; +- esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in +@@ -8643,7 +8815,7 @@ + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; +- pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) ++ pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' +@@ -8655,26 +8827,26 @@ + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; +- xl* | bgxl* | bgf* | mpixl*) +- # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene ++ xl*) ++ # IBM XL C 8.0/Fortran 10.1 on PPC + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in +- *Sun\ F* | *Sun*Fortran*) +- # Sun Fortran 8.3 passes all unrecognized flags to the linker +- lt_prog_compiler_pic='-KPIC' +- lt_prog_compiler_static='-Bstatic' +- lt_prog_compiler_wl='' +- ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; ++ *Sun\ F*) ++ # Sun Fortran 8.3 passes all unrecognized flags to the linker ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ lt_prog_compiler_wl='' ++ ;; + esac + ;; + esac +@@ -8792,15 +8964,15 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:8967: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:8971: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes +@@ -8848,7 +9020,7 @@ + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 +- $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp ++ $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes +@@ -8897,16 +9069,16 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:9072: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:9076: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes +@@ -8952,16 +9124,16 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:9127: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:9131: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes +@@ -9071,36 +9243,13 @@ + openbsd*) + with_gnu_ld=no + ;; ++ linux* | k*bsd*-gnu) ++ link_all_deplibs=no ++ ;; + esac + + ld_shlibs=yes +- +- # On some targets, GNU ld is compatible enough with the native linker +- # that we're better off using the native interface for both. +- lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then +- case $host_os in +- aix*) +- # The AIX port of GNU ld has always aspired to compatibility +- # with the native linker. However, as the warning in the GNU ld +- # block says, versions before 2.19.5* couldn't really create working +- # shared libraries, regardless of the interface used. +- case `$LD -v 2>&1` in +- *\ \(GNU\ Binutils\)\ 2.19.5*) ;; +- *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; +- *\ \(GNU\ Binutils\)\ [3-9]*) ;; +- *) +- lt_use_gnu_ld_interface=yes +- ;; +- esac +- ;; +- *) +- lt_use_gnu_ld_interface=yes +- ;; +- esac +- fi +- +- if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + +@@ -9134,12 +9283,11 @@ + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +-*** Warning: the GNU linker, at least up to release 2.19, is reported ++*** Warning: the GNU linker, at least up to release 2.9.1, is reported + *** to be unable to reliably create shared libraries on AIX. + *** Therefore, libtool is disabling shared libraries support. If you +-*** really care for shared libraries, you may want to install binutils +-*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +-*** You will then need to restart the configuration process. ++*** really care for shared libraries, you may want to modify your PATH ++*** so that a non-GNU linker is found, and then restart. + + _LT_EOF + fi +@@ -9175,7 +9323,6 @@ + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' +- export_dynamic_flag_spec='${wl}--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes +@@ -9197,11 +9344,6 @@ + fi + ;; + +- haiku*) +- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' +- link_all_deplibs=yes +- ;; +- + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no +@@ -9231,12 +9373,11 @@ + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler +- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; +- pgf77* | pgf90* | pgf95* | pgfortran*) +- # Portland Group f77 and f90 compilers +- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers ++ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; +@@ -9247,17 +9388,13 @@ + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; +- xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) ++ xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; +- nvcc*) # Cuda Compiler Driver 2.2 +- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' +- compiler_needs_object=yes +- ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 +- whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 +@@ -9273,7 +9410,7 @@ + fi + + case $cc_basename in +- xlf* | bgf* | bgxlf* | mpixlf*) ++ xlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec= +@@ -9292,7 +9429,7 @@ + fi + ;; + +- netbsd*) ++ netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= +@@ -9404,10 +9541,8 @@ + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm +- # Also, AIX nm treats weak defined symbols like other global +- # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then +- export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' ++ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi +@@ -9469,6 +9604,7 @@ + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi ++ link_all_deplibs=no + else + # not using gcc + if test "$host_cpu" = ia64; then +@@ -9525,7 +9661,7 @@ + if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" +- archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" ++ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' +@@ -9569,13 +9705,8 @@ + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' +- if test "$with_gnu_ld" = yes; then +- # We only use this code for GNU lds that support --whole-archive. +- whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' +- else +- # Exported symbols can be pulled into shared objects from archives +- whole_archive_flag_spec='$convenience' +- fi ++ # Exported symbols can be pulled into shared objects from archives ++ whole_archive_flag_spec='$convenience' + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' +@@ -9614,7 +9745,7 @@ + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. +- archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' ++ archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. +@@ -9630,11 +9761,7 @@ + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported +- if test "$lt_cv_ld_force_load" = "yes"; then +- whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' +- else +- whole_archive_flag_spec='' +- fi ++ whole_archive_flag_spec='' + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in +@@ -9642,7 +9769,7 @@ + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then +- output_verbose_link_cmd=func_echo_all ++ output_verbose_link_cmd=echo + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +@@ -9708,7 +9835,7 @@ + ;; + + hpux10*) +- if test "$GCC" = yes && test "$with_gnu_ld" = no; then ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +@@ -9727,7 +9854,7 @@ + ;; + + hpux11*) +- if test "$GCC" = yes && test "$with_gnu_ld" = no; then ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' +@@ -9748,46 +9875,7 @@ + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) +- +- # Older versions of the 11.00 compiler do not understand -b yet +- # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +-$as_echo_n "checking if $CC understands -b... " >&6; } +-if test "${lt_cv_prog_compiler__b+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- lt_cv_prog_compiler__b=no +- save_LDFLAGS="$LDFLAGS" +- LDFLAGS="$LDFLAGS -b" +- echo "$lt_simple_link_test_code" > conftest.$ac_ext +- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then +- # The linker can only warn and ignore the option if not recognized +- # So say no if there are warnings +- if test -s conftest.err; then +- # Append any errors to the config.log. +- cat conftest.err 1>&5 +- $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp +- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 +- if diff conftest.exp conftest.er2 >/dev/null; then +- lt_cv_prog_compiler__b=yes +- fi +- else +- lt_cv_prog_compiler__b=yes +- fi +- fi +- $RM -r conftest* +- LDFLAGS="$save_LDFLAGS" +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +-$as_echo "$lt_cv_prog_compiler__b" >&6; } +- +-if test x"$lt_cv_prog_compiler__b" = xyes; then +- archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +-else +- archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +-fi +- ++ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi +@@ -9815,7 +9903,7 @@ + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then +- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. +@@ -9826,15 +9914,15 @@ + int foo(void) {} + _ACEOF + if ac_fn_c_try_link "$LINENO"; then : +- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + + fi + rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + else +- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' +- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' +@@ -9843,7 +9931,7 @@ + link_all_deplibs=yes + ;; + +- netbsd*) ++ netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else +@@ -9896,17 +9984,17 @@ + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported +- archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' ++ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' +@@ -9916,13 +10004,13 @@ + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ +- $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' ++ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' +@@ -10125,50 +10213,44 @@ + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 + $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +-if test "${lt_cv_archive_cmds_need_lc+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- $RM conftest* +- echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ $RM conftest* ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext + +- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then +- soname=conftest +- lib=conftest +- libobjs=conftest.$ac_objext +- deplibs= +- wl=$lt_prog_compiler_wl +- pic_flag=$lt_prog_compiler_pic +- compiler_flags=-v +- linker_flags=-v +- verstring= +- output_objdir=. +- libname=conftest +- lt_save_allow_undefined_flag=$allow_undefined_flag +- allow_undefined_flag= +- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 ++ soname=conftest ++ lib=conftest ++ libobjs=conftest.$ac_objext ++ deplibs= ++ wl=$lt_prog_compiler_wl ++ pic_flag=$lt_prog_compiler_pic ++ compiler_flags=-v ++ linker_flags=-v ++ verstring= ++ output_objdir=. ++ libname=conftest ++ lt_save_allow_undefined_flag=$allow_undefined_flag ++ allow_undefined_flag= ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +- then +- lt_cv_archive_cmds_need_lc=no +- else +- lt_cv_archive_cmds_need_lc=yes +- fi +- allow_undefined_flag=$lt_save_allow_undefined_flag +- else +- cat conftest.err 1>&5 +- fi +- $RM conftest* +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +-$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } +- archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ++ then ++ archive_cmds_need_lc=no ++ else ++ archive_cmds_need_lc=yes ++ fi ++ allow_undefined_flag=$lt_save_allow_undefined_flag ++ else ++ cat conftest.err 1>&5 ++ fi ++ $RM conftest* ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5 ++$as_echo "$archive_cmds_need_lc" >&6; } + ;; + esac + fi +@@ -10339,23 +10421,16 @@ + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac +- case $host_os in +- mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; +- *) lt_sed_strip_eq="s,=/,/,g" ;; +- esac +- lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` +- case $lt_search_path_spec in +- *\;*) ++ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. +- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` +- ;; +- *) +- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` +- ;; +- esac ++ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= +@@ -10368,7 +10443,7 @@ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done +- lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' ++ lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' + BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; +@@ -10388,13 +10463,7 @@ + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } + }'` +- # AWK program above erroneously prepends '/' to C:/dos/paths +- # for these hosts. +- case $host_os in +- mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ +- $SED 's,/\([A-Za-z]:\),\1,g'` ;; +- esac +- sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` ++ sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` + else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + fi +@@ -10482,7 +10551,7 @@ + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. +- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ++ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; +@@ -10535,12 +10604,23 @@ + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' +- +- sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ++ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then ++ # It is most probably a Windows format PATH printed by ++ # mingw gcc, but we are running on Cygwin. Gcc prints its search ++ # path with ; separators, and with drive letters. We can handle the ++ # drive letters (cygwin fileutils understands them), so leave them, ++ # especially as we might pass files found there to a mingw objdump, ++ # which wouldn't understand a cygwinified path. Ahh. ++ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' +@@ -10640,19 +10720,6 @@ + hardcode_into_libs=yes + ;; + +-haiku*) +- version_type=linux +- need_lib_prefix=no +- need_version=no +- dynamic_linker="$host_os runtime_loader" +- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' +- soname_spec='${libname}${release}${shared_ext}$major' +- shlibpath_var=LIBRARY_PATH +- shlibpath_overrides_runpath=yes +- sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib' +- hardcode_into_libs=yes +- ;; +- + hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. +@@ -10695,10 +10762,8 @@ + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac +- # HP-UX runs *really* slowly unless shared libraries are mode 555, ... ++ # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' +- # or fails outright, so override atomically: +- install_override_mode=555 + ;; + + interix[3-9]*) +@@ -10765,17 +10830,12 @@ + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no +- + # Some binutils ld are patched to set DT_RUNPATH +- if test "${lt_cv_shlibpath_overrides_runpath+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- lt_cv_shlibpath_overrides_runpath=no +- save_LDFLAGS=$LDFLAGS +- save_libdir=$libdir +- eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ +- LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++ save_LDFLAGS=$LDFLAGS ++ save_libdir=$libdir ++ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ ++ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + + int +@@ -10788,17 +10848,13 @@ + _ACEOF + if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : +- lt_cv_shlibpath_overrides_runpath=yes ++ shlibpath_overrides_runpath=yes + fi + fi + rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +- LDFLAGS=$save_LDFLAGS +- libdir=$save_libdir +- +-fi +- +- shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath ++ LDFLAGS=$save_LDFLAGS ++ libdir=$save_libdir + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install +@@ -10807,7 +10863,7 @@ + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then +- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + +@@ -10820,6 +10876,18 @@ + dynamic_linker='GNU/Linux ld.so' + ;; + ++netbsdelf*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='NetBSD ld.elf_so' ++ ;; ++ + netbsd*) + version_type=sunos + need_lib_prefix=no +@@ -11110,11 +11178,6 @@ + + + +- +- +- +- +- + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 + $as_echo_n "checking how to hardcode library paths into programs... " >&6; } + hardcode_action= +@@ -11445,7 +11508,7 @@ + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11448 "configure" ++#line 11511 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11486,13 +11549,7 @@ + # endif + #endif + +-/* When -fvisbility=hidden is used, assume the code has been annotated +- correspondingly for the symbols needed. */ +-#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +-void fnord () __attribute__((visibility("default"))); +-#endif +- +-void fnord () { int i=42; } ++void fnord() { int i=42;} + int main () + { + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); +@@ -11501,11 +11558,7 @@ + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; +- else +- { +- if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; +- else puts (dlerror ()); +- } ++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else +@@ -11551,7 +11604,7 @@ + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11554 "configure" ++#line 11607 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11592,13 +11645,7 @@ + # endif + #endif + +-/* When -fvisbility=hidden is used, assume the code has been annotated +- correspondingly for the symbols needed. */ +-#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +-void fnord () __attribute__((visibility("default"))); +-#endif +- +-void fnord () { int i=42; } ++void fnord() { int i=42;} + int main () + { + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); +@@ -11607,11 +11654,7 @@ + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; +- else +- { +- if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; +- else puts (dlerror ()); +- } ++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else +@@ -12587,148 +12630,135 @@ + sed_quote_subst='$sed_quote_subst' + double_quote_subst='$double_quote_subst' + delay_variable_subst='$delay_variable_subst' +-SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +-Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +-SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +-ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +-AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' +-DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +-OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +-macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +-macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +-enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +-enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +-pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +-enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +-host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +-host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +-host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +-build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +-build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +-build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +-GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +-EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +-FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +-LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +-NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +-LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +-max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +-ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +-exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +-lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +-lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +-lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +-reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +-reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +-deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +-file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +-AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +-AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +-STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +-RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +-old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +-old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +-old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +-lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +-CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +-CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +-compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +-GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +-objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +-MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +-lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +-need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +-DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +-NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +-LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +-OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +-OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +-libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +-shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +-extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +-archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +-enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +-export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +-whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +-compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +-old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +-old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +-archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +-archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +-module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +-module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +-with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +-allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +-no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +-hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +-hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`' +-hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +-hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +-hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +-hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +-hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +-hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +-inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +-link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +-fix_srcfile_path='`$ECHO "$fix_srcfile_path" | $SED "$delay_single_quote_subst"`' +-always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +-export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +-exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +-include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +-prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +-file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +-variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +-need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +-need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +-version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +-runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +-shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +-shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +-libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +-library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +-soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +-install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +-postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +-postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +-finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +-finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +-hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +-sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +-sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +-hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +-enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +-enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +-enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +-old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +-striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' ++SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`' ++Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`' ++SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`' ++ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`' ++AS='`$ECHO "X$AS" | $Xsed -e "$delay_single_quote_subst"`' ++DLLTOOL='`$ECHO "X$DLLTOOL" | $Xsed -e "$delay_single_quote_subst"`' ++OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`' ++macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`' ++macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`' ++enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`' ++enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`' ++pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`' ++enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`' ++host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`' ++host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`' ++host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`' ++build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`' ++build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`' ++build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`' ++GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`' ++EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`' ++FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`' ++LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`' ++NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`' ++LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`' ++max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`' ++ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`' ++exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`' ++lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`' ++lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`' ++lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`' ++reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`' ++reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`' ++file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`' ++AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`' ++AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`' ++STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`' ++RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`' ++old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`' ++CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`' ++compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`' ++GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' ++objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`' ++MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`' ++need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`' ++DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`' ++NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`' ++LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`' ++OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`' ++OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`' ++libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`' ++shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`' ++enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`' ++export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`' ++allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' ++no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`' ++inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`' ++link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`' ++fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`' ++always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`' ++export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`' ++include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`' ++prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`' ++variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`' ++need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' ++need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`' ++version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`' ++runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`' ++libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`' ++library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`' ++soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`' ++postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`' ++sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`' ++sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`' ++old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`' ++striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`' + + LTCC='$LTCC' + LTCFLAGS='$LTCFLAGS' + compiler='$compiler_DEFAULT' + +-# A function that is used when there is no print builtin or printf. +-func_fallback_echo () +-{ +- eval 'cat <<_LTECHO_EOF +-\$1 +-_LTECHO_EOF' +-} +- + # Quote evaled strings. + for var in SED \ + SHELL \ + ECHO \ +-AS \ +-DLLTOOL \ +-OBJDUMP \ + GREP \ + EGREP \ + FGREP \ +@@ -12780,13 +12810,12 @@ + libname_spec \ + library_names_spec \ + soname_spec \ +-install_override_mode \ + finish_eval \ + old_striplib \ + striplib; do +- case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in ++ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) +- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ++ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" +@@ -12813,9 +12842,9 @@ + finish_cmds \ + sys_lib_search_path_spec \ + sys_lib_dlsearch_path_spec; do +- case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in ++ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) +- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ++ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" +@@ -12823,6 +12852,12 @@ + esac + done + ++# Fix-up fallback echo if it was mangled by the above quoting rules. ++case \$lt_ECHO in ++*'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\` ++ ;; ++esac ++ + ac_aux_dir='$ac_aux_dir' + xsi_shell='$xsi_shell' + lt_shell_append='$lt_shell_append' +@@ -13394,7 +13429,7 @@ + # NOTE: Changes made to this file will be lost: look at ltmain.sh. + # + # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +-# 2006, 2007, 2008, 2009 Free Software Foundation, Inc. ++# 2006, 2007, 2008 Free Software Foundation, Inc. + # Written by Gordon Matzigkeit, 1996 + # + # This file is part of GNU Libtool. +@@ -13435,17 +13470,17 @@ + # Shell to use when invoking shell scripts. + SHELL=$lt_SHELL + +-# An echo program that protects backslashes. ++# An echo program that does not interpret backslashes. + ECHO=$lt_ECHO + + # Assembler program. +-AS=$lt_AS ++AS=$AS + + # DLL creation program. +-DLLTOOL=$lt_DLLTOOL ++DLLTOOL=$DLLTOOL + + # Object dumper program. +-OBJDUMP=$lt_OBJDUMP ++OBJDUMP=$OBJDUMP + + # Which release of libtool.m4 was used? + macro_version=$macro_version +@@ -13506,6 +13541,10 @@ + # turn newlines into spaces. + NL2SP=$lt_lt_NL2SP + ++# How to create reloadable object files. ++reload_flag=$lt_reload_flag ++reload_cmds=$lt_reload_cmds ++ + # Method to check whether dependent libraries are shared objects. + deplibs_check_method=$lt_deplibs_check_method + +@@ -13524,9 +13563,6 @@ + old_postinstall_cmds=$lt_old_postinstall_cmds + old_postuninstall_cmds=$lt_old_postuninstall_cmds + +-# Whether to use a lock for old archive extraction. +-lock_old_archive_extraction=$lock_old_archive_extraction +- + # A C compiler. + LTCC=$lt_CC + +@@ -13610,9 +13646,6 @@ + # The coded name of the library, if different from the real name. + soname_spec=$lt_soname_spec + +-# Permission mode override for installation of shared libraries. +-install_override_mode=$lt_install_override_mode +- + # Command to use after installation of a shared archive. + postinstall_cmds=$lt_postinstall_cmds + +@@ -13652,10 +13685,6 @@ + # The linker used to build libraries. + LD=$lt_LD + +-# How to create reloadable object files. +-reload_flag=$lt_reload_flag +-reload_cmds=$lt_reload_cmds +- + # Commands used to build an old-style archive. + old_archive_cmds=$lt_old_archive_cmds + +@@ -13915,7 +13944,7 @@ + func_dirname () + { + # Extract subdirectory from the argument. +- func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` ++ func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else +@@ -13926,7 +13955,7 @@ + # func_basename file + func_basename () + { +- func_basename_result=`$ECHO "${1}" | $SED "$basename"` ++ func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` + } + + +@@ -13939,8 +13968,10 @@ + func_stripname () + { + case ${2} in +- .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; +- *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; ++ .*) func_stripname_result=`$ECHO "X${3}" \ ++ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; ++ *) func_stripname_result=`$ECHO "X${3}" \ ++ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; + esac + } + +@@ -13951,20 +13982,20 @@ + # func_opt_split + func_opt_split () + { +- func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"` +- func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"` ++ func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` ++ func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` + } + + # func_lo2o object + func_lo2o () + { +- func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` ++ func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` + } + + # func_xform libobj-or-source + func_xform () + { +- func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` ++ func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'` + } + + # func_arith arithmetic-term... +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/dl/Makefile.in newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/dl/Makefile.in +--- newlib-1.19.0/newlib/libc/sys/linux/dl/Makefile.in 2010-12-16 16:59:07.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/dl/Makefile.in 2013-10-21 15:44:33.000000000 -0400 +@@ -40,12 +40,14 @@ + $(srcdir)/Makefile.in $(srcdir)/Makefile.am + subdir = dl + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +-am__aclocal_m4_deps = $(top_srcdir)/../../../../libtool.m4 \ +- $(top_srcdir)/../../../../ltoptions.m4 \ +- $(top_srcdir)/../../../../ltsugar.m4 \ +- $(top_srcdir)/../../../../ltversion.m4 \ +- $(top_srcdir)/../../../../lt~obsolete.m4 \ +- $(top_srcdir)/../../../acinclude.m4 $(top_srcdir)/configure.in ++am__aclocal_m4_deps = $(top_srcdir)/../../../../lt~obsolete.m4 \ ++ $(top_srcdir)/../../../acinclude.m4 \ ++ $(top_srcdir)/../../../libtool.m4 \ ++ $(top_srcdir)/../../../ltoptions.m4 \ ++ $(top_srcdir)/../../../ltsugar.m4 \ ++ $(top_srcdir)/../../../ltversion.m4 \ ++ $(top_srcdir)/../../../lt~obsolete.m4 \ ++ $(top_srcdir)/configure.in + am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) + mkinstalldirs = $(SHELL) $(top_srcdir)/../../../../mkinstalldirs +@@ -205,6 +207,7 @@ + localedir = @localedir@ + localstatedir = @localstatedir@ + lpfx = @lpfx@ ++lt_ECHO = @lt_ECHO@ + machine_dir = @machine_dir@ + mandir = @mandir@ + mkdir_p = @mkdir_p@ +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/iconv/Makefile.in newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/iconv/Makefile.in +--- newlib-1.19.0/newlib/libc/sys/linux/iconv/Makefile.in 2010-12-16 16:59:07.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/iconv/Makefile.in 2013-10-21 15:44:33.000000000 -0400 +@@ -40,12 +40,14 @@ + $(srcdir)/Makefile.in $(srcdir)/Makefile.am + subdir = iconv + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +-am__aclocal_m4_deps = $(top_srcdir)/../../../../libtool.m4 \ +- $(top_srcdir)/../../../../ltoptions.m4 \ +- $(top_srcdir)/../../../../ltsugar.m4 \ +- $(top_srcdir)/../../../../ltversion.m4 \ +- $(top_srcdir)/../../../../lt~obsolete.m4 \ +- $(top_srcdir)/../../../acinclude.m4 $(top_srcdir)/configure.in ++am__aclocal_m4_deps = $(top_srcdir)/../../../../lt~obsolete.m4 \ ++ $(top_srcdir)/../../../acinclude.m4 \ ++ $(top_srcdir)/../../../libtool.m4 \ ++ $(top_srcdir)/../../../ltoptions.m4 \ ++ $(top_srcdir)/../../../ltsugar.m4 \ ++ $(top_srcdir)/../../../ltversion.m4 \ ++ $(top_srcdir)/../../../lt~obsolete.m4 \ ++ $(top_srcdir)/configure.in + am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) + mkinstalldirs = $(SHELL) $(top_srcdir)/../../../../mkinstalldirs +@@ -203,6 +205,7 @@ + localedir = @localedir@ + localstatedir = @localstatedir@ + lpfx = @lpfx@ ++lt_ECHO = @lt_ECHO@ + machine_dir = @machine_dir@ + mandir = @mandir@ + mkdir_p = @mkdir_p@ +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/intl/Makefile.in newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/intl/Makefile.in +--- newlib-1.19.0/newlib/libc/sys/linux/intl/Makefile.in 2010-12-16 16:59:07.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/intl/Makefile.in 2013-10-21 15:44:33.000000000 -0400 +@@ -40,12 +40,14 @@ + $(srcdir)/Makefile.in $(srcdir)/Makefile.am + subdir = intl + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +-am__aclocal_m4_deps = $(top_srcdir)/../../../../libtool.m4 \ +- $(top_srcdir)/../../../../ltoptions.m4 \ +- $(top_srcdir)/../../../../ltsugar.m4 \ +- $(top_srcdir)/../../../../ltversion.m4 \ +- $(top_srcdir)/../../../../lt~obsolete.m4 \ +- $(top_srcdir)/../../../acinclude.m4 $(top_srcdir)/configure.in ++am__aclocal_m4_deps = $(top_srcdir)/../../../../lt~obsolete.m4 \ ++ $(top_srcdir)/../../../acinclude.m4 \ ++ $(top_srcdir)/../../../libtool.m4 \ ++ $(top_srcdir)/../../../ltoptions.m4 \ ++ $(top_srcdir)/../../../ltsugar.m4 \ ++ $(top_srcdir)/../../../ltversion.m4 \ ++ $(top_srcdir)/../../../lt~obsolete.m4 \ ++ $(top_srcdir)/configure.in + am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) + mkinstalldirs = $(SHELL) $(top_srcdir)/../../../../mkinstalldirs +@@ -203,6 +205,7 @@ + localedir = @localedir@ + localstatedir = @localstatedir@ + lpfx = @lpfx@ ++lt_ECHO = @lt_ECHO@ + machine_dir = @machine_dir@ + mandir = @mandir@ + mkdir_p = @mkdir_p@ +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/linuxthreads/aclocal.m4 newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/linuxthreads/aclocal.m4 +--- newlib-1.19.0/newlib/libc/sys/linux/linuxthreads/aclocal.m4 2010-12-16 16:59:07.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/linuxthreads/aclocal.m4 2013-10-21 15:44:33.000000000 -0400 +@@ -989,9 +989,10 @@ + AC_SUBST([am__untar]) + ]) # _AM_PROG_TAR + +-m4_include([../../../../../libtool.m4]) +-m4_include([../../../../../ltoptions.m4]) +-m4_include([../../../../../ltsugar.m4]) +-m4_include([../../../../../ltversion.m4]) + m4_include([../../../../../lt~obsolete.m4]) + m4_include([../../../../acinclude.m4]) ++m4_include([../../../../libtool.m4]) ++m4_include([../../../../ltoptions.m4]) ++m4_include([../../../../ltsugar.m4]) ++m4_include([../../../../ltversion.m4]) ++m4_include([../../../../lt~obsolete.m4]) +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/linuxthreads/configure newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/linuxthreads/configure +--- newlib-1.19.0/newlib/libc/sys/linux/linuxthreads/configure 2010-12-16 16:59:07.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/linuxthreads/configure 2013-10-21 15:44:33.000000000 -0400 +@@ -171,15 +171,7 @@ + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +-test \$(( 1 + 1 )) = 2 || exit 1 +- +- test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( +- ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +- ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO +- ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO +- PATH=/empty FPATH=/empty; export PATH FPATH +- test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ +- || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" ++test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes + else +@@ -533,8 +525,304 @@ + # Sed expression to map a string onto a valid variable name. + as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + ++ ++ ++# Check that we are running under the correct shell. + SHELL=${CONFIG_SHELL-/bin/sh} + ++case X$lt_ECHO in ++X*--fallback-echo) ++ # Remove one level of quotation (which was required for Make). ++ ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` ++ ;; ++esac ++ ++ECHO=${lt_ECHO-echo} ++if test "X$1" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++elif test "X$1" = X--fallback-echo; then ++ # Avoid inline document here, it may be left over ++ : ++elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then ++ # Yippee, $ECHO works! ++ : ++else ++ # Restart under the correct shell. ++ exec $SHELL "$0" --no-reexec ${1+"$@"} ++fi ++ ++if test "X$1" = X--fallback-echo; then ++ # used as fallback echo ++ shift ++ cat <<_LT_EOF ++$* ++_LT_EOF ++ exit 0 ++fi ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++if test -z "$lt_ECHO"; then ++ if test "X${echo_test_string+set}" != Xset; then ++ # find a string as large as possible, as long as the shell can cope with it ++ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do ++ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... ++ if { echo_test_string=`eval $cmd`; } 2>/dev/null && ++ { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null ++ then ++ break ++ fi ++ done ++ fi ++ ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ : ++ else ++ # The Solaris, AIX, and Digital Unix default echo programs unquote ++ # backslashes. This makes it impossible to quote backslashes using ++ # echo "$something" | sed 's/\\/\\\\/g' ++ # ++ # So, first we look for a working echo in the user's PATH. ++ ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for dir in $PATH /usr/ucb; do ++ IFS="$lt_save_ifs" ++ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && ++ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$dir/echo" ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ if test "X$ECHO" = Xecho; then ++ # We didn't find a better echo, so look for alternatives. ++ if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # This shell has a builtin print -r that does the trick. ++ ECHO='print -r' ++ elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && ++ test "X$CONFIG_SHELL" != X/bin/ksh; then ++ # If we have ksh, try running configure again with it. ++ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} ++ export ORIGINAL_CONFIG_SHELL ++ CONFIG_SHELL=/bin/ksh ++ export CONFIG_SHELL ++ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} ++ else ++ # Try using printf. ++ ECHO='printf %s\n' ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # Cool, printf works ++ : ++ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL ++ export CONFIG_SHELL ++ SHELL="$CONFIG_SHELL" ++ export SHELL ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ else ++ # maybe with a smaller string... ++ prev=: ++ ++ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do ++ if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null ++ then ++ break ++ fi ++ prev="$cmd" ++ done ++ ++ if test "$prev" != 'sed 50q "$0"'; then ++ echo_test_string=`eval $prev` ++ export echo_test_string ++ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} ++ else ++ # Oops. We lost completely, so just stick with echo. ++ ECHO=echo ++ fi ++ fi ++ fi ++ fi ++ fi ++fi ++ ++# Copy echo and quote the copy suitably for passing to libtool from ++# the Makefile, instead of quoting the original, which is used later. ++lt_ECHO=$ECHO ++if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then ++ lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" ++fi ++ ++ ++ ++ ++ ++# Check that we are running under the correct shell. ++SHELL=${CONFIG_SHELL-/bin/sh} ++ ++case X$lt_ECHO in ++X*--fallback-echo) ++ # Remove one level of quotation (which was required for Make). ++ ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` ++ ;; ++esac ++ ++ECHO=${lt_ECHO-echo} ++if test "X$1" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++elif test "X$1" = X--fallback-echo; then ++ # Avoid inline document here, it may be left over ++ : ++elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then ++ # Yippee, $ECHO works! ++ : ++else ++ # Restart under the correct shell. ++ exec $SHELL "$0" --no-reexec ${1+"$@"} ++fi ++ ++if test "X$1" = X--fallback-echo; then ++ # used as fallback echo ++ shift ++ cat <<_LT_EOF ++$* ++_LT_EOF ++ exit 0 ++fi ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++if test -z "$lt_ECHO"; then ++ if test "X${echo_test_string+set}" != Xset; then ++ # find a string as large as possible, as long as the shell can cope with it ++ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do ++ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... ++ if { echo_test_string=`eval $cmd`; } 2>/dev/null && ++ { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null ++ then ++ break ++ fi ++ done ++ fi ++ ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ : ++ else ++ # The Solaris, AIX, and Digital Unix default echo programs unquote ++ # backslashes. This makes it impossible to quote backslashes using ++ # echo "$something" | sed 's/\\/\\\\/g' ++ # ++ # So, first we look for a working echo in the user's PATH. ++ ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for dir in $PATH /usr/ucb; do ++ IFS="$lt_save_ifs" ++ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && ++ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$dir/echo" ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ if test "X$ECHO" = Xecho; then ++ # We didn't find a better echo, so look for alternatives. ++ if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # This shell has a builtin print -r that does the trick. ++ ECHO='print -r' ++ elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && ++ test "X$CONFIG_SHELL" != X/bin/ksh; then ++ # If we have ksh, try running configure again with it. ++ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} ++ export ORIGINAL_CONFIG_SHELL ++ CONFIG_SHELL=/bin/ksh ++ export CONFIG_SHELL ++ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} ++ else ++ # Try using printf. ++ ECHO='printf %s\n' ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # Cool, printf works ++ : ++ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL ++ export CONFIG_SHELL ++ SHELL="$CONFIG_SHELL" ++ export SHELL ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ else ++ # maybe with a smaller string... ++ prev=: ++ ++ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do ++ if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null ++ then ++ break ++ fi ++ prev="$cmd" ++ done ++ ++ if test "$prev" != 'sed 50q "$0"'; then ++ echo_test_string=`eval $prev` ++ export echo_test_string ++ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} ++ else ++ # Oops. We lost completely, so just stick with echo. ++ ECHO=echo ++ fi ++ fi ++ fi ++ fi ++ fi ++fi ++ ++# Copy echo and quote the copy suitably for passing to libtool from ++# the Makefile, instead of quoting the original, which is used later. ++lt_ECHO=$ECHO ++if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then ++ lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" ++fi ++ ++ ++ + + test -n "$DJDIR" || exec 7<&0 &1 +@@ -630,6 +918,7 @@ + LIBTOOL + OBJDUMP + DLLTOOL ++lt_ECHO + SED + sys_dir + machine_dir +@@ -3799,45 +4088,6 @@ + + + +-ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +-ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +-ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +-$as_echo_n "checking how to print strings... " >&6; } +-# Test print first, because it will be a builtin if present. +-if test "X`print -r -- -n 2>/dev/null`" = X-n && \ +- test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then +- ECHO='print -r --' +-elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then +- ECHO='printf %s\n' +-else +- # Use this function as a fallback that always works. +- func_fallback_echo () +- { +- eval 'cat <<_LTECHO_EOF +-$1 +-_LTECHO_EOF' +- } +- ECHO='func_fallback_echo' +-fi +- +-# func_echo_all arg... +-# Invoke $ECHO with all args, space-separated. +-func_echo_all () +-{ +- $ECHO "" +-} +- +-case "$ECHO" in +- printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +-$as_echo "printf" >&6; } ;; +- print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +-$as_echo "print -r" >&6; } ;; +- *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +-$as_echo "cat" >&6; } ;; +-esac +- + + + +@@ -3897,7 +4147,7 @@ + enable_win32_dll=yes + + case $host in +-*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) ++*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. + set dummy ${ac_tool_prefix}as; ac_word=$2 +@@ -4205,8 +4455,8 @@ + + + +-macro_version='2.2.7a' +-macro_revision='1.3134' ++macro_version='2.2.6b' ++macro_revision='1.3017' + + + +@@ -4222,23 +4472,6 @@ + + ltmain="$ac_aux_dir/ltmain.sh" + +-# Backslashify metacharacters that are still active within +-# double-quoted strings. +-sed_quote_subst='s/\(["`$\\]\)/\\\1/g' +- +-# Same as above, but do not quote variable references. +-double_quote_subst='s/\(["`\\]\)/\\\1/g' +- +-# Sed substitution to delay expansion of an escaped shell variable in a +-# double_quote_subst'ed string. +-delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' +- +-# Sed substitution to delay expansion of an escaped single quote. +-delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' +- +-# Sed substitution to avoid accidental globbing in evaled expressions +-no_glob_subst='s/\*/\\\*/g' +- + ac_ext=c + ac_cpp='$CPP $CPPFLAGS' + ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +@@ -5540,11 +5773,8 @@ + NM="$lt_cv_path_NM" + else + # Didn't find any BSD compatible name lister, look for dumpbin. +- if test -n "$DUMPBIN"; then : +- # Let the user override the test. +- else +- if test -n "$ac_tool_prefix"; then +- for ac_prog in dumpbin "link -dump" ++ if test -n "$ac_tool_prefix"; then ++ for ac_prog in "dumpbin -symbols" "link -dump -symbols" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. + set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +@@ -5588,7 +5818,7 @@ + fi + if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN +- for ac_prog in dumpbin "link -dump" ++ for ac_prog in "dumpbin -symbols" "link -dump -symbols" + do + # Extract the first word of "$ac_prog", so it can be a program name with args. + set dummy $ac_prog; ac_word=$2 +@@ -5643,15 +5873,6 @@ + fi + fi + +- case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in +- *COFF*) +- DUMPBIN="$DUMPBIN -symbols" +- ;; +- *) +- DUMPBIN=: +- ;; +- esac +- fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" +@@ -5671,13 +5892,13 @@ + else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext +- (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) ++ (eval echo "\"\$as_me:5895: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 +- (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) ++ (eval echo "\"\$as_me:5898: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 +- (eval echo "\"\$as_me:$LINENO: output\"" >&5) ++ (eval echo "\"\$as_me:5901: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" +@@ -5734,11 +5955,6 @@ + lt_cv_sys_max_cmd_len=8192; + ;; + +- mint*) +- # On MiNT this can take a long time and run out of memory. +- lt_cv_sys_max_cmd_len=8192; +- ;; +- + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. +@@ -5803,8 +6019,8 @@ + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. +- while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ +- = "X$teststring$teststring"; } >/dev/null 2>&1 && ++ while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ ++ = "XX$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` +@@ -6072,8 +6288,7 @@ + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. +- # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. +- if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then ++ if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else +@@ -6082,7 +6297,7 @@ + fi + ;; + +-cegcc*) ++cegcc) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' +@@ -6112,10 +6327,6 @@ + lt_cv_deplibs_check_method=pass_all + ;; + +-haiku*) +- lt_cv_deplibs_check_method=pass_all +- ;; +- + hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in +@@ -6124,11 +6335,11 @@ + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) +- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) +- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac +@@ -6154,7 +6365,7 @@ + lt_cv_deplibs_check_method=pass_all + ;; + +-netbsd*) ++netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else +@@ -6566,18 +6777,6 @@ + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" + fi + +-case $host_os in +- darwin*) +- lock_old_archive_extraction=yes ;; +- *) +- lock_old_archive_extraction=no ;; +-esac +- +- +- +- +- +- + + + +@@ -6747,8 +6946,8 @@ + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm +- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 +- (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5 ++ (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then +@@ -6902,7 +7101,7 @@ + ;; + *-*-irix6*) + # Find out which ABI we are using. +- echo '#line '$LINENO' "configure"' > conftest.$ac_ext ++ echo '#line 7104 "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? +@@ -7614,36 +7813,6 @@ + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 + $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +-$as_echo_n "checking for -force_load linker flag... " >&6; } +-if test "${lt_cv_ld_force_load+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- lt_cv_ld_force_load=no +- cat > conftest.c << _LT_EOF +-int forced_loaded() { return 2;} +-_LT_EOF +- echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 +- $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 +- echo "$AR cru libconftest.a conftest.o" >&5 +- $AR cru libconftest.a conftest.o 2>&5 +- cat > conftest.c << _LT_EOF +-int main() { return 0;} +-_LT_EOF +- echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 +- $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err +- _lt_result=$? +- if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then +- lt_cv_ld_force_load=yes +- else +- cat conftest.err >&5 +- fi +- rm -f conftest.err libconftest.a conftest conftest.c +- rm -rf conftest.dSYM +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +-$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; +@@ -7671,7 +7840,7 @@ + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi +- if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then ++ if test "$DSYMUTIL" != ":"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= +@@ -7962,8 +8131,6 @@ + + + +- +- + # Set options + + +@@ -8114,7 +8281,6 @@ + + + +- + test -z "$LN_S" && LN_S="ln -s" + + +@@ -8164,6 +8330,13 @@ + + + ++ ++ ++ ++ ++ ++ ++ + case $host_os in + aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some +@@ -8176,6 +8349,23 @@ + ;; + esac + ++# Sed substitution that helps us do robust quoting. It backslashifies ++# metacharacters that are still active within double-quoted strings. ++sed_quote_subst='s/\(["`$\\]\)/\\\1/g' ++ ++# Same as above, but do not quote variable references. ++double_quote_subst='s/\(["`\\]\)/\\\1/g' ++ ++# Sed substitution to delay expansion of an escaped shell variable in a ++# double_quote_subst'ed string. ++delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' ++ ++# Sed substitution to delay expansion of an escaped single quote. ++delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' ++ ++# Sed substitution to avoid accidental globbing in evaled expressions ++no_glob_subst='s/\*/\\\*/g' ++ + # Global variables: + ofile=libtool + can_build_shared=yes +@@ -8204,7 +8394,7 @@ + *) break;; + esac + done +-cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ++cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + + # Only perform the check for file, if the check method requires it +@@ -8413,12 +8603,7 @@ + lt_prog_compiler_no_builtin_flag= + + if test "$GCC" = yes; then +- case $cc_basename in +- nvcc*) +- lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; +- *) +- lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; +- esac ++ lt_prog_compiler_no_builtin_flag=' -fno-builtin' + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 + $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +@@ -8438,15 +8623,15 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:8626: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:8630: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes +@@ -8524,12 +8709,6 @@ + lt_prog_compiler_pic='-fno-common' + ;; + +- haiku*) +- # PIC is the default for Haiku. +- # The "-static" flag exists, but is broken. +- lt_prog_compiler_static= +- ;; +- + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag +@@ -8572,13 +8751,6 @@ + lt_prog_compiler_pic='-fPIC' + ;; + esac +- +- case $cc_basename in +- nvcc*) # Cuda Compiler Driver 2.2 +- lt_prog_compiler_wl='-Xlinker ' +- lt_prog_compiler_pic='-Xcompiler -fPIC' +- ;; +- esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in +@@ -8641,7 +8813,7 @@ + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; +- pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) ++ pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' +@@ -8653,26 +8825,26 @@ + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; +- xl* | bgxl* | bgf* | mpixl*) +- # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene ++ xl*) ++ # IBM XL C 8.0/Fortran 10.1 on PPC + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in +- *Sun\ F* | *Sun*Fortran*) +- # Sun Fortran 8.3 passes all unrecognized flags to the linker +- lt_prog_compiler_pic='-KPIC' +- lt_prog_compiler_static='-Bstatic' +- lt_prog_compiler_wl='' +- ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; ++ *Sun\ F*) ++ # Sun Fortran 8.3 passes all unrecognized flags to the linker ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ lt_prog_compiler_wl='' ++ ;; + esac + ;; + esac +@@ -8790,15 +8962,15 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:8965: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:8969: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes +@@ -8846,7 +9018,7 @@ + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 +- $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp ++ $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes +@@ -8895,16 +9067,16 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:9070: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:9074: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes +@@ -8950,16 +9122,16 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:9125: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:9129: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes +@@ -9069,36 +9241,13 @@ + openbsd*) + with_gnu_ld=no + ;; ++ linux* | k*bsd*-gnu) ++ link_all_deplibs=no ++ ;; + esac + + ld_shlibs=yes +- +- # On some targets, GNU ld is compatible enough with the native linker +- # that we're better off using the native interface for both. +- lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then +- case $host_os in +- aix*) +- # The AIX port of GNU ld has always aspired to compatibility +- # with the native linker. However, as the warning in the GNU ld +- # block says, versions before 2.19.5* couldn't really create working +- # shared libraries, regardless of the interface used. +- case `$LD -v 2>&1` in +- *\ \(GNU\ Binutils\)\ 2.19.5*) ;; +- *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; +- *\ \(GNU\ Binutils\)\ [3-9]*) ;; +- *) +- lt_use_gnu_ld_interface=yes +- ;; +- esac +- ;; +- *) +- lt_use_gnu_ld_interface=yes +- ;; +- esac +- fi +- +- if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + +@@ -9132,12 +9281,11 @@ + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +-*** Warning: the GNU linker, at least up to release 2.19, is reported ++*** Warning: the GNU linker, at least up to release 2.9.1, is reported + *** to be unable to reliably create shared libraries on AIX. + *** Therefore, libtool is disabling shared libraries support. If you +-*** really care for shared libraries, you may want to install binutils +-*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +-*** You will then need to restart the configuration process. ++*** really care for shared libraries, you may want to modify your PATH ++*** so that a non-GNU linker is found, and then restart. + + _LT_EOF + fi +@@ -9173,7 +9321,6 @@ + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' +- export_dynamic_flag_spec='${wl}--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes +@@ -9195,11 +9342,6 @@ + fi + ;; + +- haiku*) +- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' +- link_all_deplibs=yes +- ;; +- + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no +@@ -9229,12 +9371,11 @@ + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler +- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; +- pgf77* | pgf90* | pgf95* | pgfortran*) +- # Portland Group f77 and f90 compilers +- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers ++ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; +@@ -9245,17 +9386,13 @@ + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; +- xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) ++ xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; +- nvcc*) # Cuda Compiler Driver 2.2 +- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' +- compiler_needs_object=yes +- ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 +- whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 +@@ -9271,7 +9408,7 @@ + fi + + case $cc_basename in +- xlf* | bgf* | bgxlf* | mpixlf*) ++ xlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec= +@@ -9290,7 +9427,7 @@ + fi + ;; + +- netbsd*) ++ netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= +@@ -9402,10 +9539,8 @@ + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm +- # Also, AIX nm treats weak defined symbols like other global +- # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then +- export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' ++ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi +@@ -9467,6 +9602,7 @@ + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi ++ link_all_deplibs=no + else + # not using gcc + if test "$host_cpu" = ia64; then +@@ -9523,7 +9659,7 @@ + if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" +- archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" ++ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' +@@ -9567,13 +9703,8 @@ + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' +- if test "$with_gnu_ld" = yes; then +- # We only use this code for GNU lds that support --whole-archive. +- whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' +- else +- # Exported symbols can be pulled into shared objects from archives +- whole_archive_flag_spec='$convenience' +- fi ++ # Exported symbols can be pulled into shared objects from archives ++ whole_archive_flag_spec='$convenience' + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' +@@ -9612,7 +9743,7 @@ + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. +- archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' ++ archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. +@@ -9628,11 +9759,7 @@ + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported +- if test "$lt_cv_ld_force_load" = "yes"; then +- whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' +- else +- whole_archive_flag_spec='' +- fi ++ whole_archive_flag_spec='' + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in +@@ -9640,7 +9767,7 @@ + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then +- output_verbose_link_cmd=func_echo_all ++ output_verbose_link_cmd=echo + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +@@ -9706,7 +9833,7 @@ + ;; + + hpux10*) +- if test "$GCC" = yes && test "$with_gnu_ld" = no; then ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +@@ -9725,7 +9852,7 @@ + ;; + + hpux11*) +- if test "$GCC" = yes && test "$with_gnu_ld" = no; then ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' +@@ -9746,46 +9873,7 @@ + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) +- +- # Older versions of the 11.00 compiler do not understand -b yet +- # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +-$as_echo_n "checking if $CC understands -b... " >&6; } +-if test "${lt_cv_prog_compiler__b+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- lt_cv_prog_compiler__b=no +- save_LDFLAGS="$LDFLAGS" +- LDFLAGS="$LDFLAGS -b" +- echo "$lt_simple_link_test_code" > conftest.$ac_ext +- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then +- # The linker can only warn and ignore the option if not recognized +- # So say no if there are warnings +- if test -s conftest.err; then +- # Append any errors to the config.log. +- cat conftest.err 1>&5 +- $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp +- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 +- if diff conftest.exp conftest.er2 >/dev/null; then +- lt_cv_prog_compiler__b=yes +- fi +- else +- lt_cv_prog_compiler__b=yes +- fi +- fi +- $RM -r conftest* +- LDFLAGS="$save_LDFLAGS" +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +-$as_echo "$lt_cv_prog_compiler__b" >&6; } +- +-if test x"$lt_cv_prog_compiler__b" = xyes; then +- archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +-else +- archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +-fi +- ++ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi +@@ -9813,7 +9901,7 @@ + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then +- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. +@@ -9824,15 +9912,15 @@ + int foo(void) {} + _ACEOF + if ac_fn_c_try_link "$LINENO"; then : +- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + + fi + rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + else +- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' +- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' +@@ -9841,7 +9929,7 @@ + link_all_deplibs=yes + ;; + +- netbsd*) ++ netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else +@@ -9894,17 +9982,17 @@ + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported +- archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' ++ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' +@@ -9914,13 +10002,13 @@ + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ +- $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' ++ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' +@@ -10123,50 +10211,44 @@ + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 + $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +-if test "${lt_cv_archive_cmds_need_lc+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- $RM conftest* +- echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ $RM conftest* ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext + +- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then +- soname=conftest +- lib=conftest +- libobjs=conftest.$ac_objext +- deplibs= +- wl=$lt_prog_compiler_wl +- pic_flag=$lt_prog_compiler_pic +- compiler_flags=-v +- linker_flags=-v +- verstring= +- output_objdir=. +- libname=conftest +- lt_save_allow_undefined_flag=$allow_undefined_flag +- allow_undefined_flag= +- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 ++ soname=conftest ++ lib=conftest ++ libobjs=conftest.$ac_objext ++ deplibs= ++ wl=$lt_prog_compiler_wl ++ pic_flag=$lt_prog_compiler_pic ++ compiler_flags=-v ++ linker_flags=-v ++ verstring= ++ output_objdir=. ++ libname=conftest ++ lt_save_allow_undefined_flag=$allow_undefined_flag ++ allow_undefined_flag= ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +- then +- lt_cv_archive_cmds_need_lc=no +- else +- lt_cv_archive_cmds_need_lc=yes +- fi +- allow_undefined_flag=$lt_save_allow_undefined_flag +- else +- cat conftest.err 1>&5 +- fi +- $RM conftest* +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +-$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } +- archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ++ then ++ archive_cmds_need_lc=no ++ else ++ archive_cmds_need_lc=yes ++ fi ++ allow_undefined_flag=$lt_save_allow_undefined_flag ++ else ++ cat conftest.err 1>&5 ++ fi ++ $RM conftest* ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5 ++$as_echo "$archive_cmds_need_lc" >&6; } + ;; + esac + fi +@@ -10337,23 +10419,16 @@ + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac +- case $host_os in +- mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; +- *) lt_sed_strip_eq="s,=/,/,g" ;; +- esac +- lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` +- case $lt_search_path_spec in +- *\;*) ++ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. +- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` +- ;; +- *) +- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` +- ;; +- esac ++ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= +@@ -10366,7 +10441,7 @@ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done +- lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' ++ lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' + BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; +@@ -10386,13 +10461,7 @@ + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } + }'` +- # AWK program above erroneously prepends '/' to C:/dos/paths +- # for these hosts. +- case $host_os in +- mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ +- $SED 's,/\([A-Za-z]:\),\1,g'` ;; +- esac +- sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` ++ sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` + else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + fi +@@ -10480,7 +10549,7 @@ + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. +- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ++ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; +@@ -10533,12 +10602,23 @@ + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' +- +- sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ++ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then ++ # It is most probably a Windows format PATH printed by ++ # mingw gcc, but we are running on Cygwin. Gcc prints its search ++ # path with ; separators, and with drive letters. We can handle the ++ # drive letters (cygwin fileutils understands them), so leave them, ++ # especially as we might pass files found there to a mingw objdump, ++ # which wouldn't understand a cygwinified path. Ahh. ++ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' +@@ -10638,19 +10718,6 @@ + hardcode_into_libs=yes + ;; + +-haiku*) +- version_type=linux +- need_lib_prefix=no +- need_version=no +- dynamic_linker="$host_os runtime_loader" +- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' +- soname_spec='${libname}${release}${shared_ext}$major' +- shlibpath_var=LIBRARY_PATH +- shlibpath_overrides_runpath=yes +- sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib' +- hardcode_into_libs=yes +- ;; +- + hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. +@@ -10693,10 +10760,8 @@ + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac +- # HP-UX runs *really* slowly unless shared libraries are mode 555, ... ++ # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' +- # or fails outright, so override atomically: +- install_override_mode=555 + ;; + + interix[3-9]*) +@@ -10763,17 +10828,12 @@ + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no +- + # Some binutils ld are patched to set DT_RUNPATH +- if test "${lt_cv_shlibpath_overrides_runpath+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- lt_cv_shlibpath_overrides_runpath=no +- save_LDFLAGS=$LDFLAGS +- save_libdir=$libdir +- eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ +- LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++ save_LDFLAGS=$LDFLAGS ++ save_libdir=$libdir ++ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ ++ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + + int +@@ -10786,17 +10846,13 @@ + _ACEOF + if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : +- lt_cv_shlibpath_overrides_runpath=yes ++ shlibpath_overrides_runpath=yes + fi + fi + rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +- LDFLAGS=$save_LDFLAGS +- libdir=$save_libdir +- +-fi +- +- shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath ++ LDFLAGS=$save_LDFLAGS ++ libdir=$save_libdir + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install +@@ -10805,7 +10861,7 @@ + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then +- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + +@@ -10818,6 +10874,18 @@ + dynamic_linker='GNU/Linux ld.so' + ;; + ++netbsdelf*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='NetBSD ld.elf_so' ++ ;; ++ + netbsd*) + version_type=sunos + need_lib_prefix=no +@@ -11108,11 +11176,6 @@ + + + +- +- +- +- +- + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 + $as_echo_n "checking how to hardcode library paths into programs... " >&6; } + hardcode_action= +@@ -11443,7 +11506,7 @@ + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11446 "configure" ++#line 11509 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11484,13 +11547,7 @@ + # endif + #endif + +-/* When -fvisbility=hidden is used, assume the code has been annotated +- correspondingly for the symbols needed. */ +-#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +-void fnord () __attribute__((visibility("default"))); +-#endif +- +-void fnord () { int i=42; } ++void fnord() { int i=42;} + int main () + { + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); +@@ -11499,11 +11556,7 @@ + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; +- else +- { +- if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; +- else puts (dlerror ()); +- } ++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else +@@ -11549,7 +11602,7 @@ + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11552 "configure" ++#line 11605 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11590,13 +11643,7 @@ + # endif + #endif + +-/* When -fvisbility=hidden is used, assume the code has been annotated +- correspondingly for the symbols needed. */ +-#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +-void fnord () __attribute__((visibility("default"))); +-#endif +- +-void fnord () { int i=42; } ++void fnord() { int i=42;} + int main () + { + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); +@@ -11605,11 +11652,7 @@ + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; +- else +- { +- if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; +- else puts (dlerror ()); +- } ++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else +@@ -12564,148 +12607,135 @@ + sed_quote_subst='$sed_quote_subst' + double_quote_subst='$double_quote_subst' + delay_variable_subst='$delay_variable_subst' +-SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +-Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +-SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +-ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +-AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' +-DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +-OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +-macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +-macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +-enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +-enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +-pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +-enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +-host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +-host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +-host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +-build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +-build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +-build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +-GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +-EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +-FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +-LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +-NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +-LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +-max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +-ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +-exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +-lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +-lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +-lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +-reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +-reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +-deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +-file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +-AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +-AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +-STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +-RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +-old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +-old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +-old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +-lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +-CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +-CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +-compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +-GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +-objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +-MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +-lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +-need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +-DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +-NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +-LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +-OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +-OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +-libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +-shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +-extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +-archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +-enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +-export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +-whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +-compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +-old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +-old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +-archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +-archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +-module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +-module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +-with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +-allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +-no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +-hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +-hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`' +-hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +-hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +-hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +-hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +-hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +-hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +-inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +-link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +-fix_srcfile_path='`$ECHO "$fix_srcfile_path" | $SED "$delay_single_quote_subst"`' +-always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +-export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +-exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +-include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +-prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +-file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +-variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +-need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +-need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +-version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +-runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +-shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +-shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +-libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +-library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +-soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +-install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +-postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +-postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +-finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +-finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +-hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +-sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +-sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +-hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +-enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +-enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +-enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +-old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +-striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' ++SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`' ++Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`' ++SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`' ++ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`' ++AS='`$ECHO "X$AS" | $Xsed -e "$delay_single_quote_subst"`' ++DLLTOOL='`$ECHO "X$DLLTOOL" | $Xsed -e "$delay_single_quote_subst"`' ++OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`' ++macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`' ++macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`' ++enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`' ++enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`' ++pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`' ++enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`' ++host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`' ++host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`' ++host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`' ++build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`' ++build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`' ++build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`' ++GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`' ++EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`' ++FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`' ++LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`' ++NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`' ++LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`' ++max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`' ++ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`' ++exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`' ++lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`' ++lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`' ++lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`' ++reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`' ++reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`' ++file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`' ++AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`' ++AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`' ++STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`' ++RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`' ++old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`' ++CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`' ++compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`' ++GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' ++objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`' ++MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`' ++need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`' ++DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`' ++NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`' ++LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`' ++OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`' ++OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`' ++libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`' ++shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`' ++enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`' ++export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`' ++allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' ++no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`' ++inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`' ++link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`' ++fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`' ++always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`' ++export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`' ++include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`' ++prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`' ++variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`' ++need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' ++need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`' ++version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`' ++runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`' ++libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`' ++library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`' ++soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`' ++postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`' ++sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`' ++sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`' ++old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`' ++striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`' + + LTCC='$LTCC' + LTCFLAGS='$LTCFLAGS' + compiler='$compiler_DEFAULT' + +-# A function that is used when there is no print builtin or printf. +-func_fallback_echo () +-{ +- eval 'cat <<_LTECHO_EOF +-\$1 +-_LTECHO_EOF' +-} +- + # Quote evaled strings. + for var in SED \ + SHELL \ + ECHO \ +-AS \ +-DLLTOOL \ +-OBJDUMP \ + GREP \ + EGREP \ + FGREP \ +@@ -12757,13 +12787,12 @@ + libname_spec \ + library_names_spec \ + soname_spec \ +-install_override_mode \ + finish_eval \ + old_striplib \ + striplib; do +- case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in ++ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) +- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ++ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" +@@ -12790,9 +12819,9 @@ + finish_cmds \ + sys_lib_search_path_spec \ + sys_lib_dlsearch_path_spec; do +- case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in ++ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) +- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ++ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" +@@ -12800,6 +12829,12 @@ + esac + done + ++# Fix-up fallback echo if it was mangled by the above quoting rules. ++case \$lt_ECHO in ++*'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\` ++ ;; ++esac ++ + ac_aux_dir='$ac_aux_dir' + xsi_shell='$xsi_shell' + lt_shell_append='$lt_shell_append' +@@ -13365,7 +13400,7 @@ + # NOTE: Changes made to this file will be lost: look at ltmain.sh. + # + # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +-# 2006, 2007, 2008, 2009 Free Software Foundation, Inc. ++# 2006, 2007, 2008 Free Software Foundation, Inc. + # Written by Gordon Matzigkeit, 1996 + # + # This file is part of GNU Libtool. +@@ -13406,17 +13441,17 @@ + # Shell to use when invoking shell scripts. + SHELL=$lt_SHELL + +-# An echo program that protects backslashes. ++# An echo program that does not interpret backslashes. + ECHO=$lt_ECHO + + # Assembler program. +-AS=$lt_AS ++AS=$AS + + # DLL creation program. +-DLLTOOL=$lt_DLLTOOL ++DLLTOOL=$DLLTOOL + + # Object dumper program. +-OBJDUMP=$lt_OBJDUMP ++OBJDUMP=$OBJDUMP + + # Which release of libtool.m4 was used? + macro_version=$macro_version +@@ -13477,6 +13512,10 @@ + # turn newlines into spaces. + NL2SP=$lt_lt_NL2SP + ++# How to create reloadable object files. ++reload_flag=$lt_reload_flag ++reload_cmds=$lt_reload_cmds ++ + # Method to check whether dependent libraries are shared objects. + deplibs_check_method=$lt_deplibs_check_method + +@@ -13495,9 +13534,6 @@ + old_postinstall_cmds=$lt_old_postinstall_cmds + old_postuninstall_cmds=$lt_old_postuninstall_cmds + +-# Whether to use a lock for old archive extraction. +-lock_old_archive_extraction=$lock_old_archive_extraction +- + # A C compiler. + LTCC=$lt_CC + +@@ -13581,9 +13617,6 @@ + # The coded name of the library, if different from the real name. + soname_spec=$lt_soname_spec + +-# Permission mode override for installation of shared libraries. +-install_override_mode=$lt_install_override_mode +- + # Command to use after installation of a shared archive. + postinstall_cmds=$lt_postinstall_cmds + +@@ -13623,10 +13656,6 @@ + # The linker used to build libraries. + LD=$lt_LD + +-# How to create reloadable object files. +-reload_flag=$lt_reload_flag +-reload_cmds=$lt_reload_cmds +- + # Commands used to build an old-style archive. + old_archive_cmds=$lt_old_archive_cmds + +@@ -13886,7 +13915,7 @@ + func_dirname () + { + # Extract subdirectory from the argument. +- func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` ++ func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else +@@ -13897,7 +13926,7 @@ + # func_basename file + func_basename () + { +- func_basename_result=`$ECHO "${1}" | $SED "$basename"` ++ func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` + } + + +@@ -13910,8 +13939,10 @@ + func_stripname () + { + case ${2} in +- .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; +- *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; ++ .*) func_stripname_result=`$ECHO "X${3}" \ ++ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; ++ *) func_stripname_result=`$ECHO "X${3}" \ ++ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; + esac + } + +@@ -13922,20 +13953,20 @@ + # func_opt_split + func_opt_split () + { +- func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"` +- func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"` ++ func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` ++ func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` + } + + # func_lo2o object + func_lo2o () + { +- func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` ++ func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` + } + + # func_xform libobj-or-source + func_xform () + { +- func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` ++ func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'` + } + + # func_arith arithmetic-term... +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/linuxthreads/machine/aclocal.m4 newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/linuxthreads/machine/aclocal.m4 +--- newlib-1.19.0/newlib/libc/sys/linux/linuxthreads/machine/aclocal.m4 2010-12-16 16:59:08.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/linuxthreads/machine/aclocal.m4 2013-10-21 15:44:33.000000000 -0400 +@@ -989,9 +989,10 @@ + AC_SUBST([am__untar]) + ]) # _AM_PROG_TAR + +-m4_include([../../../../../../libtool.m4]) +-m4_include([../../../../../../ltoptions.m4]) +-m4_include([../../../../../../ltsugar.m4]) +-m4_include([../../../../../../ltversion.m4]) + m4_include([../../../../../../lt~obsolete.m4]) + m4_include([../../../../../acinclude.m4]) ++m4_include([../../../../../libtool.m4]) ++m4_include([../../../../../ltoptions.m4]) ++m4_include([../../../../../ltsugar.m4]) ++m4_include([../../../../../ltversion.m4]) ++m4_include([../../../../../lt~obsolete.m4]) +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/linuxthreads/machine/configure newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/linuxthreads/machine/configure +--- newlib-1.19.0/newlib/libc/sys/linux/linuxthreads/machine/configure 2010-12-16 16:59:08.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/linuxthreads/machine/configure 2013-10-21 15:44:33.000000000 -0400 +@@ -171,15 +171,7 @@ + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +-test \$(( 1 + 1 )) = 2 || exit 1 +- +- test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( +- ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +- ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO +- ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO +- PATH=/empty FPATH=/empty; export PATH FPATH +- test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ +- || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" ++test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes + else +@@ -533,8 +525,304 @@ + # Sed expression to map a string onto a valid variable name. + as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + ++ ++ ++# Check that we are running under the correct shell. + SHELL=${CONFIG_SHELL-/bin/sh} + ++case X$lt_ECHO in ++X*--fallback-echo) ++ # Remove one level of quotation (which was required for Make). ++ ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` ++ ;; ++esac ++ ++ECHO=${lt_ECHO-echo} ++if test "X$1" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++elif test "X$1" = X--fallback-echo; then ++ # Avoid inline document here, it may be left over ++ : ++elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then ++ # Yippee, $ECHO works! ++ : ++else ++ # Restart under the correct shell. ++ exec $SHELL "$0" --no-reexec ${1+"$@"} ++fi ++ ++if test "X$1" = X--fallback-echo; then ++ # used as fallback echo ++ shift ++ cat <<_LT_EOF ++$* ++_LT_EOF ++ exit 0 ++fi ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++if test -z "$lt_ECHO"; then ++ if test "X${echo_test_string+set}" != Xset; then ++ # find a string as large as possible, as long as the shell can cope with it ++ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do ++ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... ++ if { echo_test_string=`eval $cmd`; } 2>/dev/null && ++ { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null ++ then ++ break ++ fi ++ done ++ fi ++ ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ : ++ else ++ # The Solaris, AIX, and Digital Unix default echo programs unquote ++ # backslashes. This makes it impossible to quote backslashes using ++ # echo "$something" | sed 's/\\/\\\\/g' ++ # ++ # So, first we look for a working echo in the user's PATH. ++ ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for dir in $PATH /usr/ucb; do ++ IFS="$lt_save_ifs" ++ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && ++ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$dir/echo" ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ if test "X$ECHO" = Xecho; then ++ # We didn't find a better echo, so look for alternatives. ++ if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # This shell has a builtin print -r that does the trick. ++ ECHO='print -r' ++ elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && ++ test "X$CONFIG_SHELL" != X/bin/ksh; then ++ # If we have ksh, try running configure again with it. ++ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} ++ export ORIGINAL_CONFIG_SHELL ++ CONFIG_SHELL=/bin/ksh ++ export CONFIG_SHELL ++ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} ++ else ++ # Try using printf. ++ ECHO='printf %s\n' ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # Cool, printf works ++ : ++ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL ++ export CONFIG_SHELL ++ SHELL="$CONFIG_SHELL" ++ export SHELL ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ else ++ # maybe with a smaller string... ++ prev=: ++ ++ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do ++ if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null ++ then ++ break ++ fi ++ prev="$cmd" ++ done ++ ++ if test "$prev" != 'sed 50q "$0"'; then ++ echo_test_string=`eval $prev` ++ export echo_test_string ++ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} ++ else ++ # Oops. We lost completely, so just stick with echo. ++ ECHO=echo ++ fi ++ fi ++ fi ++ fi ++ fi ++fi ++ ++# Copy echo and quote the copy suitably for passing to libtool from ++# the Makefile, instead of quoting the original, which is used later. ++lt_ECHO=$ECHO ++if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then ++ lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" ++fi ++ ++ ++ ++ ++ ++# Check that we are running under the correct shell. ++SHELL=${CONFIG_SHELL-/bin/sh} ++ ++case X$lt_ECHO in ++X*--fallback-echo) ++ # Remove one level of quotation (which was required for Make). ++ ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` ++ ;; ++esac ++ ++ECHO=${lt_ECHO-echo} ++if test "X$1" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++elif test "X$1" = X--fallback-echo; then ++ # Avoid inline document here, it may be left over ++ : ++elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then ++ # Yippee, $ECHO works! ++ : ++else ++ # Restart under the correct shell. ++ exec $SHELL "$0" --no-reexec ${1+"$@"} ++fi ++ ++if test "X$1" = X--fallback-echo; then ++ # used as fallback echo ++ shift ++ cat <<_LT_EOF ++$* ++_LT_EOF ++ exit 0 ++fi ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++if test -z "$lt_ECHO"; then ++ if test "X${echo_test_string+set}" != Xset; then ++ # find a string as large as possible, as long as the shell can cope with it ++ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do ++ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... ++ if { echo_test_string=`eval $cmd`; } 2>/dev/null && ++ { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null ++ then ++ break ++ fi ++ done ++ fi ++ ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ : ++ else ++ # The Solaris, AIX, and Digital Unix default echo programs unquote ++ # backslashes. This makes it impossible to quote backslashes using ++ # echo "$something" | sed 's/\\/\\\\/g' ++ # ++ # So, first we look for a working echo in the user's PATH. ++ ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for dir in $PATH /usr/ucb; do ++ IFS="$lt_save_ifs" ++ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && ++ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$dir/echo" ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ if test "X$ECHO" = Xecho; then ++ # We didn't find a better echo, so look for alternatives. ++ if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # This shell has a builtin print -r that does the trick. ++ ECHO='print -r' ++ elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && ++ test "X$CONFIG_SHELL" != X/bin/ksh; then ++ # If we have ksh, try running configure again with it. ++ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} ++ export ORIGINAL_CONFIG_SHELL ++ CONFIG_SHELL=/bin/ksh ++ export CONFIG_SHELL ++ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} ++ else ++ # Try using printf. ++ ECHO='printf %s\n' ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # Cool, printf works ++ : ++ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL ++ export CONFIG_SHELL ++ SHELL="$CONFIG_SHELL" ++ export SHELL ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ else ++ # maybe with a smaller string... ++ prev=: ++ ++ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do ++ if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null ++ then ++ break ++ fi ++ prev="$cmd" ++ done ++ ++ if test "$prev" != 'sed 50q "$0"'; then ++ echo_test_string=`eval $prev` ++ export echo_test_string ++ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} ++ else ++ # Oops. We lost completely, so just stick with echo. ++ ECHO=echo ++ fi ++ fi ++ fi ++ fi ++ fi ++fi ++ ++# Copy echo and quote the copy suitably for passing to libtool from ++# the Makefile, instead of quoting the original, which is used later. ++lt_ECHO=$ECHO ++if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then ++ lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" ++fi ++ ++ ++ + + test -n "$DJDIR" || exec 7<&0 &1 +@@ -630,6 +918,7 @@ + LIBTOOL + OBJDUMP + DLLTOOL ++lt_ECHO + SED + sys_dir + machine_dir +@@ -3799,45 +4088,6 @@ + + + +-ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +-ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +-ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +-$as_echo_n "checking how to print strings... " >&6; } +-# Test print first, because it will be a builtin if present. +-if test "X`print -r -- -n 2>/dev/null`" = X-n && \ +- test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then +- ECHO='print -r --' +-elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then +- ECHO='printf %s\n' +-else +- # Use this function as a fallback that always works. +- func_fallback_echo () +- { +- eval 'cat <<_LTECHO_EOF +-$1 +-_LTECHO_EOF' +- } +- ECHO='func_fallback_echo' +-fi +- +-# func_echo_all arg... +-# Invoke $ECHO with all args, space-separated. +-func_echo_all () +-{ +- $ECHO "" +-} +- +-case "$ECHO" in +- printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +-$as_echo "printf" >&6; } ;; +- print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +-$as_echo "print -r" >&6; } ;; +- *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +-$as_echo "cat" >&6; } ;; +-esac +- + + + +@@ -3855,7 +4105,7 @@ + enable_win32_dll=yes + + case $host in +-*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) ++*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. + set dummy ${ac_tool_prefix}as; ac_word=$2 +@@ -4163,8 +4413,8 @@ + + + +-macro_version='2.2.7a' +-macro_revision='1.3134' ++macro_version='2.2.6b' ++macro_revision='1.3017' + + + +@@ -4180,23 +4430,6 @@ + + ltmain="$ac_aux_dir/ltmain.sh" + +-# Backslashify metacharacters that are still active within +-# double-quoted strings. +-sed_quote_subst='s/\(["`$\\]\)/\\\1/g' +- +-# Same as above, but do not quote variable references. +-double_quote_subst='s/\(["`\\]\)/\\\1/g' +- +-# Sed substitution to delay expansion of an escaped shell variable in a +-# double_quote_subst'ed string. +-delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' +- +-# Sed substitution to delay expansion of an escaped single quote. +-delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' +- +-# Sed substitution to avoid accidental globbing in evaled expressions +-no_glob_subst='s/\*/\\\*/g' +- + ac_ext=c + ac_cpp='$CPP $CPPFLAGS' + ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +@@ -5498,11 +5731,8 @@ + NM="$lt_cv_path_NM" + else + # Didn't find any BSD compatible name lister, look for dumpbin. +- if test -n "$DUMPBIN"; then : +- # Let the user override the test. +- else +- if test -n "$ac_tool_prefix"; then +- for ac_prog in dumpbin "link -dump" ++ if test -n "$ac_tool_prefix"; then ++ for ac_prog in "dumpbin -symbols" "link -dump -symbols" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. + set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +@@ -5546,7 +5776,7 @@ + fi + if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN +- for ac_prog in dumpbin "link -dump" ++ for ac_prog in "dumpbin -symbols" "link -dump -symbols" + do + # Extract the first word of "$ac_prog", so it can be a program name with args. + set dummy $ac_prog; ac_word=$2 +@@ -5601,15 +5831,6 @@ + fi + fi + +- case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in +- *COFF*) +- DUMPBIN="$DUMPBIN -symbols" +- ;; +- *) +- DUMPBIN=: +- ;; +- esac +- fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" +@@ -5629,13 +5850,13 @@ + else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext +- (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) ++ (eval echo "\"\$as_me:5853: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 +- (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) ++ (eval echo "\"\$as_me:5856: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 +- (eval echo "\"\$as_me:$LINENO: output\"" >&5) ++ (eval echo "\"\$as_me:5859: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" +@@ -5692,11 +5913,6 @@ + lt_cv_sys_max_cmd_len=8192; + ;; + +- mint*) +- # On MiNT this can take a long time and run out of memory. +- lt_cv_sys_max_cmd_len=8192; +- ;; +- + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. +@@ -5761,8 +5977,8 @@ + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. +- while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ +- = "X$teststring$teststring"; } >/dev/null 2>&1 && ++ while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ ++ = "XX$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` +@@ -6030,8 +6246,7 @@ + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. +- # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. +- if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then ++ if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else +@@ -6040,7 +6255,7 @@ + fi + ;; + +-cegcc*) ++cegcc) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' +@@ -6070,10 +6285,6 @@ + lt_cv_deplibs_check_method=pass_all + ;; + +-haiku*) +- lt_cv_deplibs_check_method=pass_all +- ;; +- + hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in +@@ -6082,11 +6293,11 @@ + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) +- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) +- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac +@@ -6112,7 +6323,7 @@ + lt_cv_deplibs_check_method=pass_all + ;; + +-netbsd*) ++netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else +@@ -6524,18 +6735,6 @@ + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" + fi + +-case $host_os in +- darwin*) +- lock_old_archive_extraction=yes ;; +- *) +- lock_old_archive_extraction=no ;; +-esac +- +- +- +- +- +- + + + +@@ -6705,8 +6904,8 @@ + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm +- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 +- (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5 ++ (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then +@@ -6860,7 +7059,7 @@ + ;; + *-*-irix6*) + # Find out which ABI we are using. +- echo '#line '$LINENO' "configure"' > conftest.$ac_ext ++ echo '#line 7062 "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? +@@ -7572,36 +7771,6 @@ + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 + $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +-$as_echo_n "checking for -force_load linker flag... " >&6; } +-if test "${lt_cv_ld_force_load+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- lt_cv_ld_force_load=no +- cat > conftest.c << _LT_EOF +-int forced_loaded() { return 2;} +-_LT_EOF +- echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 +- $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 +- echo "$AR cru libconftest.a conftest.o" >&5 +- $AR cru libconftest.a conftest.o 2>&5 +- cat > conftest.c << _LT_EOF +-int main() { return 0;} +-_LT_EOF +- echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 +- $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err +- _lt_result=$? +- if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then +- lt_cv_ld_force_load=yes +- else +- cat conftest.err >&5 +- fi +- rm -f conftest.err libconftest.a conftest conftest.c +- rm -rf conftest.dSYM +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +-$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; +@@ -7629,7 +7798,7 @@ + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi +- if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then ++ if test "$DSYMUTIL" != ":"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= +@@ -7920,8 +8089,6 @@ + + + +- +- + # Set options + + +@@ -8072,7 +8239,6 @@ + + + +- + test -z "$LN_S" && LN_S="ln -s" + + +@@ -8122,6 +8288,13 @@ + + + ++ ++ ++ ++ ++ ++ ++ + case $host_os in + aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some +@@ -8134,6 +8307,23 @@ + ;; + esac + ++# Sed substitution that helps us do robust quoting. It backslashifies ++# metacharacters that are still active within double-quoted strings. ++sed_quote_subst='s/\(["`$\\]\)/\\\1/g' ++ ++# Same as above, but do not quote variable references. ++double_quote_subst='s/\(["`\\]\)/\\\1/g' ++ ++# Sed substitution to delay expansion of an escaped shell variable in a ++# double_quote_subst'ed string. ++delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' ++ ++# Sed substitution to delay expansion of an escaped single quote. ++delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' ++ ++# Sed substitution to avoid accidental globbing in evaled expressions ++no_glob_subst='s/\*/\\\*/g' ++ + # Global variables: + ofile=libtool + can_build_shared=yes +@@ -8162,7 +8352,7 @@ + *) break;; + esac + done +-cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ++cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + + # Only perform the check for file, if the check method requires it +@@ -8371,12 +8561,7 @@ + lt_prog_compiler_no_builtin_flag= + + if test "$GCC" = yes; then +- case $cc_basename in +- nvcc*) +- lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; +- *) +- lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; +- esac ++ lt_prog_compiler_no_builtin_flag=' -fno-builtin' + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 + $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +@@ -8396,15 +8581,15 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:8584: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:8588: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes +@@ -8482,12 +8667,6 @@ + lt_prog_compiler_pic='-fno-common' + ;; + +- haiku*) +- # PIC is the default for Haiku. +- # The "-static" flag exists, but is broken. +- lt_prog_compiler_static= +- ;; +- + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag +@@ -8530,13 +8709,6 @@ + lt_prog_compiler_pic='-fPIC' + ;; + esac +- +- case $cc_basename in +- nvcc*) # Cuda Compiler Driver 2.2 +- lt_prog_compiler_wl='-Xlinker ' +- lt_prog_compiler_pic='-Xcompiler -fPIC' +- ;; +- esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in +@@ -8599,7 +8771,7 @@ + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; +- pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) ++ pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' +@@ -8611,26 +8783,26 @@ + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; +- xl* | bgxl* | bgf* | mpixl*) +- # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene ++ xl*) ++ # IBM XL C 8.0/Fortran 10.1 on PPC + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in +- *Sun\ F* | *Sun*Fortran*) +- # Sun Fortran 8.3 passes all unrecognized flags to the linker +- lt_prog_compiler_pic='-KPIC' +- lt_prog_compiler_static='-Bstatic' +- lt_prog_compiler_wl='' +- ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; ++ *Sun\ F*) ++ # Sun Fortran 8.3 passes all unrecognized flags to the linker ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ lt_prog_compiler_wl='' ++ ;; + esac + ;; + esac +@@ -8748,15 +8920,15 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:8923: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:8927: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes +@@ -8804,7 +8976,7 @@ + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 +- $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp ++ $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes +@@ -8853,16 +9025,16 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:9028: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:9032: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes +@@ -8908,16 +9080,16 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:9083: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:9087: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes +@@ -9027,36 +9199,13 @@ + openbsd*) + with_gnu_ld=no + ;; ++ linux* | k*bsd*-gnu) ++ link_all_deplibs=no ++ ;; + esac + + ld_shlibs=yes +- +- # On some targets, GNU ld is compatible enough with the native linker +- # that we're better off using the native interface for both. +- lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then +- case $host_os in +- aix*) +- # The AIX port of GNU ld has always aspired to compatibility +- # with the native linker. However, as the warning in the GNU ld +- # block says, versions before 2.19.5* couldn't really create working +- # shared libraries, regardless of the interface used. +- case `$LD -v 2>&1` in +- *\ \(GNU\ Binutils\)\ 2.19.5*) ;; +- *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; +- *\ \(GNU\ Binutils\)\ [3-9]*) ;; +- *) +- lt_use_gnu_ld_interface=yes +- ;; +- esac +- ;; +- *) +- lt_use_gnu_ld_interface=yes +- ;; +- esac +- fi +- +- if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + +@@ -9090,12 +9239,11 @@ + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +-*** Warning: the GNU linker, at least up to release 2.19, is reported ++*** Warning: the GNU linker, at least up to release 2.9.1, is reported + *** to be unable to reliably create shared libraries on AIX. + *** Therefore, libtool is disabling shared libraries support. If you +-*** really care for shared libraries, you may want to install binutils +-*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +-*** You will then need to restart the configuration process. ++*** really care for shared libraries, you may want to modify your PATH ++*** so that a non-GNU linker is found, and then restart. + + _LT_EOF + fi +@@ -9131,7 +9279,6 @@ + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' +- export_dynamic_flag_spec='${wl}--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes +@@ -9153,11 +9300,6 @@ + fi + ;; + +- haiku*) +- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' +- link_all_deplibs=yes +- ;; +- + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no +@@ -9187,12 +9329,11 @@ + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler +- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; +- pgf77* | pgf90* | pgf95* | pgfortran*) +- # Portland Group f77 and f90 compilers +- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers ++ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; +@@ -9203,17 +9344,13 @@ + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; +- xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) ++ xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; +- nvcc*) # Cuda Compiler Driver 2.2 +- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' +- compiler_needs_object=yes +- ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 +- whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 +@@ -9229,7 +9366,7 @@ + fi + + case $cc_basename in +- xlf* | bgf* | bgxlf* | mpixlf*) ++ xlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec= +@@ -9248,7 +9385,7 @@ + fi + ;; + +- netbsd*) ++ netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= +@@ -9360,10 +9497,8 @@ + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm +- # Also, AIX nm treats weak defined symbols like other global +- # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then +- export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' ++ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi +@@ -9425,6 +9560,7 @@ + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi ++ link_all_deplibs=no + else + # not using gcc + if test "$host_cpu" = ia64; then +@@ -9481,7 +9617,7 @@ + if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" +- archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" ++ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' +@@ -9525,13 +9661,8 @@ + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' +- if test "$with_gnu_ld" = yes; then +- # We only use this code for GNU lds that support --whole-archive. +- whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' +- else +- # Exported symbols can be pulled into shared objects from archives +- whole_archive_flag_spec='$convenience' +- fi ++ # Exported symbols can be pulled into shared objects from archives ++ whole_archive_flag_spec='$convenience' + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' +@@ -9570,7 +9701,7 @@ + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. +- archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' ++ archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. +@@ -9586,11 +9717,7 @@ + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported +- if test "$lt_cv_ld_force_load" = "yes"; then +- whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' +- else +- whole_archive_flag_spec='' +- fi ++ whole_archive_flag_spec='' + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in +@@ -9598,7 +9725,7 @@ + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then +- output_verbose_link_cmd=func_echo_all ++ output_verbose_link_cmd=echo + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +@@ -9664,7 +9791,7 @@ + ;; + + hpux10*) +- if test "$GCC" = yes && test "$with_gnu_ld" = no; then ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +@@ -9683,7 +9810,7 @@ + ;; + + hpux11*) +- if test "$GCC" = yes && test "$with_gnu_ld" = no; then ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' +@@ -9704,46 +9831,7 @@ + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) +- +- # Older versions of the 11.00 compiler do not understand -b yet +- # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +-$as_echo_n "checking if $CC understands -b... " >&6; } +-if test "${lt_cv_prog_compiler__b+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- lt_cv_prog_compiler__b=no +- save_LDFLAGS="$LDFLAGS" +- LDFLAGS="$LDFLAGS -b" +- echo "$lt_simple_link_test_code" > conftest.$ac_ext +- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then +- # The linker can only warn and ignore the option if not recognized +- # So say no if there are warnings +- if test -s conftest.err; then +- # Append any errors to the config.log. +- cat conftest.err 1>&5 +- $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp +- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 +- if diff conftest.exp conftest.er2 >/dev/null; then +- lt_cv_prog_compiler__b=yes +- fi +- else +- lt_cv_prog_compiler__b=yes +- fi +- fi +- $RM -r conftest* +- LDFLAGS="$save_LDFLAGS" +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +-$as_echo "$lt_cv_prog_compiler__b" >&6; } +- +-if test x"$lt_cv_prog_compiler__b" = xyes; then +- archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +-else +- archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +-fi +- ++ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi +@@ -9771,7 +9859,7 @@ + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then +- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. +@@ -9782,15 +9870,15 @@ + int foo(void) {} + _ACEOF + if ac_fn_c_try_link "$LINENO"; then : +- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + + fi + rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + else +- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' +- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' +@@ -9799,7 +9887,7 @@ + link_all_deplibs=yes + ;; + +- netbsd*) ++ netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else +@@ -9852,17 +9940,17 @@ + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported +- archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' ++ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' +@@ -9872,13 +9960,13 @@ + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ +- $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' ++ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' +@@ -10081,50 +10169,44 @@ + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 + $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +-if test "${lt_cv_archive_cmds_need_lc+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- $RM conftest* +- echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ $RM conftest* ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext + +- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then +- soname=conftest +- lib=conftest +- libobjs=conftest.$ac_objext +- deplibs= +- wl=$lt_prog_compiler_wl +- pic_flag=$lt_prog_compiler_pic +- compiler_flags=-v +- linker_flags=-v +- verstring= +- output_objdir=. +- libname=conftest +- lt_save_allow_undefined_flag=$allow_undefined_flag +- allow_undefined_flag= +- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 ++ soname=conftest ++ lib=conftest ++ libobjs=conftest.$ac_objext ++ deplibs= ++ wl=$lt_prog_compiler_wl ++ pic_flag=$lt_prog_compiler_pic ++ compiler_flags=-v ++ linker_flags=-v ++ verstring= ++ output_objdir=. ++ libname=conftest ++ lt_save_allow_undefined_flag=$allow_undefined_flag ++ allow_undefined_flag= ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +- then +- lt_cv_archive_cmds_need_lc=no +- else +- lt_cv_archive_cmds_need_lc=yes +- fi +- allow_undefined_flag=$lt_save_allow_undefined_flag +- else +- cat conftest.err 1>&5 +- fi +- $RM conftest* +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +-$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } +- archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ++ then ++ archive_cmds_need_lc=no ++ else ++ archive_cmds_need_lc=yes ++ fi ++ allow_undefined_flag=$lt_save_allow_undefined_flag ++ else ++ cat conftest.err 1>&5 ++ fi ++ $RM conftest* ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5 ++$as_echo "$archive_cmds_need_lc" >&6; } + ;; + esac + fi +@@ -10295,23 +10377,16 @@ + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac +- case $host_os in +- mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; +- *) lt_sed_strip_eq="s,=/,/,g" ;; +- esac +- lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` +- case $lt_search_path_spec in +- *\;*) ++ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. +- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` +- ;; +- *) +- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` +- ;; +- esac ++ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= +@@ -10324,7 +10399,7 @@ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done +- lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' ++ lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' + BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; +@@ -10344,13 +10419,7 @@ + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } + }'` +- # AWK program above erroneously prepends '/' to C:/dos/paths +- # for these hosts. +- case $host_os in +- mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ +- $SED 's,/\([A-Za-z]:\),\1,g'` ;; +- esac +- sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` ++ sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` + else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + fi +@@ -10438,7 +10507,7 @@ + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. +- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ++ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; +@@ -10491,12 +10560,23 @@ + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' +- +- sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ++ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then ++ # It is most probably a Windows format PATH printed by ++ # mingw gcc, but we are running on Cygwin. Gcc prints its search ++ # path with ; separators, and with drive letters. We can handle the ++ # drive letters (cygwin fileutils understands them), so leave them, ++ # especially as we might pass files found there to a mingw objdump, ++ # which wouldn't understand a cygwinified path. Ahh. ++ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' +@@ -10596,19 +10676,6 @@ + hardcode_into_libs=yes + ;; + +-haiku*) +- version_type=linux +- need_lib_prefix=no +- need_version=no +- dynamic_linker="$host_os runtime_loader" +- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' +- soname_spec='${libname}${release}${shared_ext}$major' +- shlibpath_var=LIBRARY_PATH +- shlibpath_overrides_runpath=yes +- sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib' +- hardcode_into_libs=yes +- ;; +- + hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. +@@ -10651,10 +10718,8 @@ + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac +- # HP-UX runs *really* slowly unless shared libraries are mode 555, ... ++ # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' +- # or fails outright, so override atomically: +- install_override_mode=555 + ;; + + interix[3-9]*) +@@ -10721,17 +10786,12 @@ + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no +- + # Some binutils ld are patched to set DT_RUNPATH +- if test "${lt_cv_shlibpath_overrides_runpath+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- lt_cv_shlibpath_overrides_runpath=no +- save_LDFLAGS=$LDFLAGS +- save_libdir=$libdir +- eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ +- LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++ save_LDFLAGS=$LDFLAGS ++ save_libdir=$libdir ++ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ ++ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + + int +@@ -10744,17 +10804,13 @@ + _ACEOF + if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : +- lt_cv_shlibpath_overrides_runpath=yes ++ shlibpath_overrides_runpath=yes + fi + fi + rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +- LDFLAGS=$save_LDFLAGS +- libdir=$save_libdir +- +-fi +- +- shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath ++ LDFLAGS=$save_LDFLAGS ++ libdir=$save_libdir + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install +@@ -10763,7 +10819,7 @@ + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then +- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + +@@ -10776,6 +10832,18 @@ + dynamic_linker='GNU/Linux ld.so' + ;; + ++netbsdelf*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='NetBSD ld.elf_so' ++ ;; ++ + netbsd*) + version_type=sunos + need_lib_prefix=no +@@ -11066,11 +11134,6 @@ + + + +- +- +- +- +- + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 + $as_echo_n "checking how to hardcode library paths into programs... " >&6; } + hardcode_action= +@@ -11401,7 +11464,7 @@ + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11404 "configure" ++#line 11467 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11442,13 +11505,7 @@ + # endif + #endif + +-/* When -fvisbility=hidden is used, assume the code has been annotated +- correspondingly for the symbols needed. */ +-#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +-void fnord () __attribute__((visibility("default"))); +-#endif +- +-void fnord () { int i=42; } ++void fnord() { int i=42;} + int main () + { + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); +@@ -11457,11 +11514,7 @@ + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; +- else +- { +- if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; +- else puts (dlerror ()); +- } ++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else +@@ -11507,7 +11560,7 @@ + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11510 "configure" ++#line 11563 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11548,13 +11601,7 @@ + # endif + #endif + +-/* When -fvisbility=hidden is used, assume the code has been annotated +- correspondingly for the symbols needed. */ +-#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +-void fnord () __attribute__((visibility("default"))); +-#endif +- +-void fnord () { int i=42; } ++void fnord() { int i=42;} + int main () + { + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); +@@ -11563,11 +11610,7 @@ + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; +- else +- { +- if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; +- else puts (dlerror ()); +- } ++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else +@@ -12532,148 +12575,135 @@ + sed_quote_subst='$sed_quote_subst' + double_quote_subst='$double_quote_subst' + delay_variable_subst='$delay_variable_subst' +-SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +-Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +-SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +-ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +-AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' +-DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +-OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +-macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +-macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +-enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +-enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +-pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +-enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +-host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +-host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +-host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +-build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +-build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +-build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +-GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +-EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +-FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +-LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +-NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +-LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +-max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +-ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +-exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +-lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +-lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +-lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +-reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +-reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +-deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +-file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +-AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +-AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +-STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +-RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +-old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +-old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +-old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +-lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +-CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +-CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +-compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +-GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +-objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +-MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +-lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +-need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +-DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +-NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +-LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +-OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +-OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +-libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +-shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +-extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +-archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +-enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +-export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +-whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +-compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +-old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +-old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +-archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +-archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +-module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +-module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +-with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +-allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +-no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +-hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +-hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`' +-hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +-hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +-hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +-hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +-hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +-hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +-inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +-link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +-fix_srcfile_path='`$ECHO "$fix_srcfile_path" | $SED "$delay_single_quote_subst"`' +-always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +-export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +-exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +-include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +-prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +-file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +-variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +-need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +-need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +-version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +-runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +-shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +-shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +-libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +-library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +-soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +-install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +-postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +-postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +-finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +-finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +-hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +-sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +-sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +-hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +-enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +-enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +-enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +-old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +-striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' ++SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`' ++Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`' ++SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`' ++ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`' ++AS='`$ECHO "X$AS" | $Xsed -e "$delay_single_quote_subst"`' ++DLLTOOL='`$ECHO "X$DLLTOOL" | $Xsed -e "$delay_single_quote_subst"`' ++OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`' ++macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`' ++macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`' ++enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`' ++enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`' ++pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`' ++enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`' ++host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`' ++host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`' ++host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`' ++build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`' ++build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`' ++build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`' ++GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`' ++EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`' ++FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`' ++LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`' ++NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`' ++LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`' ++max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`' ++ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`' ++exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`' ++lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`' ++lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`' ++lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`' ++reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`' ++reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`' ++file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`' ++AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`' ++AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`' ++STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`' ++RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`' ++old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`' ++CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`' ++compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`' ++GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' ++objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`' ++MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`' ++need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`' ++DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`' ++NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`' ++LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`' ++OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`' ++OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`' ++libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`' ++shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`' ++enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`' ++export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`' ++allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' ++no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`' ++inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`' ++link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`' ++fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`' ++always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`' ++export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`' ++include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`' ++prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`' ++variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`' ++need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' ++need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`' ++version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`' ++runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`' ++libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`' ++library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`' ++soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`' ++postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`' ++sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`' ++sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`' ++old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`' ++striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`' + + LTCC='$LTCC' + LTCFLAGS='$LTCFLAGS' + compiler='$compiler_DEFAULT' + +-# A function that is used when there is no print builtin or printf. +-func_fallback_echo () +-{ +- eval 'cat <<_LTECHO_EOF +-\$1 +-_LTECHO_EOF' +-} +- + # Quote evaled strings. + for var in SED \ + SHELL \ + ECHO \ +-AS \ +-DLLTOOL \ +-OBJDUMP \ + GREP \ + EGREP \ + FGREP \ +@@ -12725,13 +12755,12 @@ + libname_spec \ + library_names_spec \ + soname_spec \ +-install_override_mode \ + finish_eval \ + old_striplib \ + striplib; do +- case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in ++ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) +- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ++ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" +@@ -12758,9 +12787,9 @@ + finish_cmds \ + sys_lib_search_path_spec \ + sys_lib_dlsearch_path_spec; do +- case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in ++ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) +- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ++ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" +@@ -12768,6 +12797,12 @@ + esac + done + ++# Fix-up fallback echo if it was mangled by the above quoting rules. ++case \$lt_ECHO in ++*'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\` ++ ;; ++esac ++ + ac_aux_dir='$ac_aux_dir' + xsi_shell='$xsi_shell' + lt_shell_append='$lt_shell_append' +@@ -13333,7 +13368,7 @@ + # NOTE: Changes made to this file will be lost: look at ltmain.sh. + # + # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +-# 2006, 2007, 2008, 2009 Free Software Foundation, Inc. ++# 2006, 2007, 2008 Free Software Foundation, Inc. + # Written by Gordon Matzigkeit, 1996 + # + # This file is part of GNU Libtool. +@@ -13374,17 +13409,17 @@ + # Shell to use when invoking shell scripts. + SHELL=$lt_SHELL + +-# An echo program that protects backslashes. ++# An echo program that does not interpret backslashes. + ECHO=$lt_ECHO + + # Assembler program. +-AS=$lt_AS ++AS=$AS + + # DLL creation program. +-DLLTOOL=$lt_DLLTOOL ++DLLTOOL=$DLLTOOL + + # Object dumper program. +-OBJDUMP=$lt_OBJDUMP ++OBJDUMP=$OBJDUMP + + # Which release of libtool.m4 was used? + macro_version=$macro_version +@@ -13445,6 +13480,10 @@ + # turn newlines into spaces. + NL2SP=$lt_lt_NL2SP + ++# How to create reloadable object files. ++reload_flag=$lt_reload_flag ++reload_cmds=$lt_reload_cmds ++ + # Method to check whether dependent libraries are shared objects. + deplibs_check_method=$lt_deplibs_check_method + +@@ -13463,9 +13502,6 @@ + old_postinstall_cmds=$lt_old_postinstall_cmds + old_postuninstall_cmds=$lt_old_postuninstall_cmds + +-# Whether to use a lock for old archive extraction. +-lock_old_archive_extraction=$lock_old_archive_extraction +- + # A C compiler. + LTCC=$lt_CC + +@@ -13549,9 +13585,6 @@ + # The coded name of the library, if different from the real name. + soname_spec=$lt_soname_spec + +-# Permission mode override for installation of shared libraries. +-install_override_mode=$lt_install_override_mode +- + # Command to use after installation of a shared archive. + postinstall_cmds=$lt_postinstall_cmds + +@@ -13591,10 +13624,6 @@ + # The linker used to build libraries. + LD=$lt_LD + +-# How to create reloadable object files. +-reload_flag=$lt_reload_flag +-reload_cmds=$lt_reload_cmds +- + # Commands used to build an old-style archive. + old_archive_cmds=$lt_old_archive_cmds + +@@ -13854,7 +13883,7 @@ + func_dirname () + { + # Extract subdirectory from the argument. +- func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` ++ func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else +@@ -13865,7 +13894,7 @@ + # func_basename file + func_basename () + { +- func_basename_result=`$ECHO "${1}" | $SED "$basename"` ++ func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` + } + + +@@ -13878,8 +13907,10 @@ + func_stripname () + { + case ${2} in +- .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; +- *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; ++ .*) func_stripname_result=`$ECHO "X${3}" \ ++ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; ++ *) func_stripname_result=`$ECHO "X${3}" \ ++ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; + esac + } + +@@ -13890,20 +13921,20 @@ + # func_opt_split + func_opt_split () + { +- func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"` +- func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"` ++ func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` ++ func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` + } + + # func_lo2o object + func_lo2o () + { +- func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` ++ func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` + } + + # func_xform libobj-or-source + func_xform () + { +- func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` ++ func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'` + } + + # func_arith arithmetic-term... +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/linuxthreads/machine/i386/aclocal.m4 newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/linuxthreads/machine/i386/aclocal.m4 +--- newlib-1.19.0/newlib/libc/sys/linux/linuxthreads/machine/i386/aclocal.m4 2010-12-16 16:59:09.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/linuxthreads/machine/i386/aclocal.m4 2013-10-21 15:44:33.000000000 -0400 +@@ -989,9 +989,10 @@ + AC_SUBST([am__untar]) + ]) # _AM_PROG_TAR + +-m4_include([../../../../../../../libtool.m4]) +-m4_include([../../../../../../../ltoptions.m4]) +-m4_include([../../../../../../../ltsugar.m4]) +-m4_include([../../../../../../../ltversion.m4]) + m4_include([../../../../../../../lt~obsolete.m4]) + m4_include([../../../../../../acinclude.m4]) ++m4_include([../../../../../../libtool.m4]) ++m4_include([../../../../../../ltoptions.m4]) ++m4_include([../../../../../../ltsugar.m4]) ++m4_include([../../../../../../ltversion.m4]) ++m4_include([../../../../../../lt~obsolete.m4]) +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/linuxthreads/machine/i386/configure newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/linuxthreads/machine/i386/configure +--- newlib-1.19.0/newlib/libc/sys/linux/linuxthreads/machine/i386/configure 2010-12-16 16:59:09.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/linuxthreads/machine/i386/configure 2013-10-21 15:44:33.000000000 -0400 +@@ -171,15 +171,7 @@ + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +-test \$(( 1 + 1 )) = 2 || exit 1 +- +- test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( +- ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +- ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO +- ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO +- PATH=/empty FPATH=/empty; export PATH FPATH +- test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ +- || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" ++test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes + else +@@ -533,8 +525,304 @@ + # Sed expression to map a string onto a valid variable name. + as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + ++ ++ ++# Check that we are running under the correct shell. + SHELL=${CONFIG_SHELL-/bin/sh} + ++case X$lt_ECHO in ++X*--fallback-echo) ++ # Remove one level of quotation (which was required for Make). ++ ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` ++ ;; ++esac ++ ++ECHO=${lt_ECHO-echo} ++if test "X$1" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++elif test "X$1" = X--fallback-echo; then ++ # Avoid inline document here, it may be left over ++ : ++elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then ++ # Yippee, $ECHO works! ++ : ++else ++ # Restart under the correct shell. ++ exec $SHELL "$0" --no-reexec ${1+"$@"} ++fi ++ ++if test "X$1" = X--fallback-echo; then ++ # used as fallback echo ++ shift ++ cat <<_LT_EOF ++$* ++_LT_EOF ++ exit 0 ++fi ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++if test -z "$lt_ECHO"; then ++ if test "X${echo_test_string+set}" != Xset; then ++ # find a string as large as possible, as long as the shell can cope with it ++ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do ++ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... ++ if { echo_test_string=`eval $cmd`; } 2>/dev/null && ++ { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null ++ then ++ break ++ fi ++ done ++ fi ++ ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ : ++ else ++ # The Solaris, AIX, and Digital Unix default echo programs unquote ++ # backslashes. This makes it impossible to quote backslashes using ++ # echo "$something" | sed 's/\\/\\\\/g' ++ # ++ # So, first we look for a working echo in the user's PATH. ++ ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for dir in $PATH /usr/ucb; do ++ IFS="$lt_save_ifs" ++ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && ++ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$dir/echo" ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ if test "X$ECHO" = Xecho; then ++ # We didn't find a better echo, so look for alternatives. ++ if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # This shell has a builtin print -r that does the trick. ++ ECHO='print -r' ++ elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && ++ test "X$CONFIG_SHELL" != X/bin/ksh; then ++ # If we have ksh, try running configure again with it. ++ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} ++ export ORIGINAL_CONFIG_SHELL ++ CONFIG_SHELL=/bin/ksh ++ export CONFIG_SHELL ++ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} ++ else ++ # Try using printf. ++ ECHO='printf %s\n' ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # Cool, printf works ++ : ++ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL ++ export CONFIG_SHELL ++ SHELL="$CONFIG_SHELL" ++ export SHELL ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ else ++ # maybe with a smaller string... ++ prev=: ++ ++ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do ++ if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null ++ then ++ break ++ fi ++ prev="$cmd" ++ done ++ ++ if test "$prev" != 'sed 50q "$0"'; then ++ echo_test_string=`eval $prev` ++ export echo_test_string ++ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} ++ else ++ # Oops. We lost completely, so just stick with echo. ++ ECHO=echo ++ fi ++ fi ++ fi ++ fi ++ fi ++fi ++ ++# Copy echo and quote the copy suitably for passing to libtool from ++# the Makefile, instead of quoting the original, which is used later. ++lt_ECHO=$ECHO ++if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then ++ lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" ++fi ++ ++ ++ ++ ++ ++# Check that we are running under the correct shell. ++SHELL=${CONFIG_SHELL-/bin/sh} ++ ++case X$lt_ECHO in ++X*--fallback-echo) ++ # Remove one level of quotation (which was required for Make). ++ ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` ++ ;; ++esac ++ ++ECHO=${lt_ECHO-echo} ++if test "X$1" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++elif test "X$1" = X--fallback-echo; then ++ # Avoid inline document here, it may be left over ++ : ++elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then ++ # Yippee, $ECHO works! ++ : ++else ++ # Restart under the correct shell. ++ exec $SHELL "$0" --no-reexec ${1+"$@"} ++fi ++ ++if test "X$1" = X--fallback-echo; then ++ # used as fallback echo ++ shift ++ cat <<_LT_EOF ++$* ++_LT_EOF ++ exit 0 ++fi ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++if test -z "$lt_ECHO"; then ++ if test "X${echo_test_string+set}" != Xset; then ++ # find a string as large as possible, as long as the shell can cope with it ++ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do ++ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... ++ if { echo_test_string=`eval $cmd`; } 2>/dev/null && ++ { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null ++ then ++ break ++ fi ++ done ++ fi ++ ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ : ++ else ++ # The Solaris, AIX, and Digital Unix default echo programs unquote ++ # backslashes. This makes it impossible to quote backslashes using ++ # echo "$something" | sed 's/\\/\\\\/g' ++ # ++ # So, first we look for a working echo in the user's PATH. ++ ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for dir in $PATH /usr/ucb; do ++ IFS="$lt_save_ifs" ++ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && ++ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$dir/echo" ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ if test "X$ECHO" = Xecho; then ++ # We didn't find a better echo, so look for alternatives. ++ if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # This shell has a builtin print -r that does the trick. ++ ECHO='print -r' ++ elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && ++ test "X$CONFIG_SHELL" != X/bin/ksh; then ++ # If we have ksh, try running configure again with it. ++ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} ++ export ORIGINAL_CONFIG_SHELL ++ CONFIG_SHELL=/bin/ksh ++ export CONFIG_SHELL ++ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} ++ else ++ # Try using printf. ++ ECHO='printf %s\n' ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # Cool, printf works ++ : ++ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL ++ export CONFIG_SHELL ++ SHELL="$CONFIG_SHELL" ++ export SHELL ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ else ++ # maybe with a smaller string... ++ prev=: ++ ++ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do ++ if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null ++ then ++ break ++ fi ++ prev="$cmd" ++ done ++ ++ if test "$prev" != 'sed 50q "$0"'; then ++ echo_test_string=`eval $prev` ++ export echo_test_string ++ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} ++ else ++ # Oops. We lost completely, so just stick with echo. ++ ECHO=echo ++ fi ++ fi ++ fi ++ fi ++ fi ++fi ++ ++# Copy echo and quote the copy suitably for passing to libtool from ++# the Makefile, instead of quoting the original, which is used later. ++lt_ECHO=$ECHO ++if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then ++ lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" ++fi ++ ++ ++ + + test -n "$DJDIR" || exec 7<&0 &1 +@@ -626,6 +914,7 @@ + LIBTOOL + OBJDUMP + DLLTOOL ++lt_ECHO + SED + sys_dir + machine_dir +@@ -3795,45 +4084,6 @@ + + + +-ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +-ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +-ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +-$as_echo_n "checking how to print strings... " >&6; } +-# Test print first, because it will be a builtin if present. +-if test "X`print -r -- -n 2>/dev/null`" = X-n && \ +- test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then +- ECHO='print -r --' +-elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then +- ECHO='printf %s\n' +-else +- # Use this function as a fallback that always works. +- func_fallback_echo () +- { +- eval 'cat <<_LTECHO_EOF +-$1 +-_LTECHO_EOF' +- } +- ECHO='func_fallback_echo' +-fi +- +-# func_echo_all arg... +-# Invoke $ECHO with all args, space-separated. +-func_echo_all () +-{ +- $ECHO "" +-} +- +-case "$ECHO" in +- printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +-$as_echo "printf" >&6; } ;; +- print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +-$as_echo "print -r" >&6; } ;; +- *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +-$as_echo "cat" >&6; } ;; +-esac +- + + + +@@ -3893,7 +4143,7 @@ + enable_win32_dll=yes + + case $host in +-*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) ++*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. + set dummy ${ac_tool_prefix}as; ac_word=$2 +@@ -4201,8 +4451,8 @@ + + + +-macro_version='2.2.7a' +-macro_revision='1.3134' ++macro_version='2.2.6b' ++macro_revision='1.3017' + + + +@@ -4218,23 +4468,6 @@ + + ltmain="$ac_aux_dir/ltmain.sh" + +-# Backslashify metacharacters that are still active within +-# double-quoted strings. +-sed_quote_subst='s/\(["`$\\]\)/\\\1/g' +- +-# Same as above, but do not quote variable references. +-double_quote_subst='s/\(["`\\]\)/\\\1/g' +- +-# Sed substitution to delay expansion of an escaped shell variable in a +-# double_quote_subst'ed string. +-delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' +- +-# Sed substitution to delay expansion of an escaped single quote. +-delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' +- +-# Sed substitution to avoid accidental globbing in evaled expressions +-no_glob_subst='s/\*/\\\*/g' +- + ac_ext=c + ac_cpp='$CPP $CPPFLAGS' + ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +@@ -5536,11 +5769,8 @@ + NM="$lt_cv_path_NM" + else + # Didn't find any BSD compatible name lister, look for dumpbin. +- if test -n "$DUMPBIN"; then : +- # Let the user override the test. +- else +- if test -n "$ac_tool_prefix"; then +- for ac_prog in dumpbin "link -dump" ++ if test -n "$ac_tool_prefix"; then ++ for ac_prog in "dumpbin -symbols" "link -dump -symbols" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. + set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +@@ -5584,7 +5814,7 @@ + fi + if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN +- for ac_prog in dumpbin "link -dump" ++ for ac_prog in "dumpbin -symbols" "link -dump -symbols" + do + # Extract the first word of "$ac_prog", so it can be a program name with args. + set dummy $ac_prog; ac_word=$2 +@@ -5639,15 +5869,6 @@ + fi + fi + +- case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in +- *COFF*) +- DUMPBIN="$DUMPBIN -symbols" +- ;; +- *) +- DUMPBIN=: +- ;; +- esac +- fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" +@@ -5667,13 +5888,13 @@ + else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext +- (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) ++ (eval echo "\"\$as_me:5891: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 +- (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) ++ (eval echo "\"\$as_me:5894: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 +- (eval echo "\"\$as_me:$LINENO: output\"" >&5) ++ (eval echo "\"\$as_me:5897: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" +@@ -5730,11 +5951,6 @@ + lt_cv_sys_max_cmd_len=8192; + ;; + +- mint*) +- # On MiNT this can take a long time and run out of memory. +- lt_cv_sys_max_cmd_len=8192; +- ;; +- + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. +@@ -5799,8 +6015,8 @@ + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. +- while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ +- = "X$teststring$teststring"; } >/dev/null 2>&1 && ++ while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ ++ = "XX$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` +@@ -6068,8 +6284,7 @@ + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. +- # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. +- if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then ++ if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else +@@ -6078,7 +6293,7 @@ + fi + ;; + +-cegcc*) ++cegcc) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' +@@ -6108,10 +6323,6 @@ + lt_cv_deplibs_check_method=pass_all + ;; + +-haiku*) +- lt_cv_deplibs_check_method=pass_all +- ;; +- + hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in +@@ -6120,11 +6331,11 @@ + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) +- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) +- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac +@@ -6150,7 +6361,7 @@ + lt_cv_deplibs_check_method=pass_all + ;; + +-netbsd*) ++netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else +@@ -6562,18 +6773,6 @@ + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" + fi + +-case $host_os in +- darwin*) +- lock_old_archive_extraction=yes ;; +- *) +- lock_old_archive_extraction=no ;; +-esac +- +- +- +- +- +- + + + +@@ -6743,8 +6942,8 @@ + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm +- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 +- (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5 ++ (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then +@@ -6898,7 +7097,7 @@ + ;; + *-*-irix6*) + # Find out which ABI we are using. +- echo '#line '$LINENO' "configure"' > conftest.$ac_ext ++ echo '#line 7100 "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? +@@ -7610,36 +7809,6 @@ + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 + $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +-$as_echo_n "checking for -force_load linker flag... " >&6; } +-if test "${lt_cv_ld_force_load+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- lt_cv_ld_force_load=no +- cat > conftest.c << _LT_EOF +-int forced_loaded() { return 2;} +-_LT_EOF +- echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 +- $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 +- echo "$AR cru libconftest.a conftest.o" >&5 +- $AR cru libconftest.a conftest.o 2>&5 +- cat > conftest.c << _LT_EOF +-int main() { return 0;} +-_LT_EOF +- echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 +- $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err +- _lt_result=$? +- if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then +- lt_cv_ld_force_load=yes +- else +- cat conftest.err >&5 +- fi +- rm -f conftest.err libconftest.a conftest conftest.c +- rm -rf conftest.dSYM +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +-$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; +@@ -7667,7 +7836,7 @@ + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi +- if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then ++ if test "$DSYMUTIL" != ":"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= +@@ -7958,8 +8127,6 @@ + + + +- +- + # Set options + + +@@ -8110,7 +8277,6 @@ + + + +- + test -z "$LN_S" && LN_S="ln -s" + + +@@ -8160,6 +8326,13 @@ + + + ++ ++ ++ ++ ++ ++ ++ + case $host_os in + aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some +@@ -8172,6 +8345,23 @@ + ;; + esac + ++# Sed substitution that helps us do robust quoting. It backslashifies ++# metacharacters that are still active within double-quoted strings. ++sed_quote_subst='s/\(["`$\\]\)/\\\1/g' ++ ++# Same as above, but do not quote variable references. ++double_quote_subst='s/\(["`\\]\)/\\\1/g' ++ ++# Sed substitution to delay expansion of an escaped shell variable in a ++# double_quote_subst'ed string. ++delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' ++ ++# Sed substitution to delay expansion of an escaped single quote. ++delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' ++ ++# Sed substitution to avoid accidental globbing in evaled expressions ++no_glob_subst='s/\*/\\\*/g' ++ + # Global variables: + ofile=libtool + can_build_shared=yes +@@ -8200,7 +8390,7 @@ + *) break;; + esac + done +-cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ++cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + + # Only perform the check for file, if the check method requires it +@@ -8409,12 +8599,7 @@ + lt_prog_compiler_no_builtin_flag= + + if test "$GCC" = yes; then +- case $cc_basename in +- nvcc*) +- lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; +- *) +- lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; +- esac ++ lt_prog_compiler_no_builtin_flag=' -fno-builtin' + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 + $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +@@ -8434,15 +8619,15 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:8622: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:8626: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes +@@ -8520,12 +8705,6 @@ + lt_prog_compiler_pic='-fno-common' + ;; + +- haiku*) +- # PIC is the default for Haiku. +- # The "-static" flag exists, but is broken. +- lt_prog_compiler_static= +- ;; +- + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag +@@ -8568,13 +8747,6 @@ + lt_prog_compiler_pic='-fPIC' + ;; + esac +- +- case $cc_basename in +- nvcc*) # Cuda Compiler Driver 2.2 +- lt_prog_compiler_wl='-Xlinker ' +- lt_prog_compiler_pic='-Xcompiler -fPIC' +- ;; +- esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in +@@ -8637,7 +8809,7 @@ + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; +- pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) ++ pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' +@@ -8649,26 +8821,26 @@ + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; +- xl* | bgxl* | bgf* | mpixl*) +- # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene ++ xl*) ++ # IBM XL C 8.0/Fortran 10.1 on PPC + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in +- *Sun\ F* | *Sun*Fortran*) +- # Sun Fortran 8.3 passes all unrecognized flags to the linker +- lt_prog_compiler_pic='-KPIC' +- lt_prog_compiler_static='-Bstatic' +- lt_prog_compiler_wl='' +- ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; ++ *Sun\ F*) ++ # Sun Fortran 8.3 passes all unrecognized flags to the linker ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ lt_prog_compiler_wl='' ++ ;; + esac + ;; + esac +@@ -8786,15 +8958,15 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:8961: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:8965: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes +@@ -8842,7 +9014,7 @@ + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 +- $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp ++ $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes +@@ -8891,16 +9063,16 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:9066: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:9070: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes +@@ -8946,16 +9118,16 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:9121: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:9125: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes +@@ -9065,36 +9237,13 @@ + openbsd*) + with_gnu_ld=no + ;; ++ linux* | k*bsd*-gnu) ++ link_all_deplibs=no ++ ;; + esac + + ld_shlibs=yes +- +- # On some targets, GNU ld is compatible enough with the native linker +- # that we're better off using the native interface for both. +- lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then +- case $host_os in +- aix*) +- # The AIX port of GNU ld has always aspired to compatibility +- # with the native linker. However, as the warning in the GNU ld +- # block says, versions before 2.19.5* couldn't really create working +- # shared libraries, regardless of the interface used. +- case `$LD -v 2>&1` in +- *\ \(GNU\ Binutils\)\ 2.19.5*) ;; +- *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; +- *\ \(GNU\ Binutils\)\ [3-9]*) ;; +- *) +- lt_use_gnu_ld_interface=yes +- ;; +- esac +- ;; +- *) +- lt_use_gnu_ld_interface=yes +- ;; +- esac +- fi +- +- if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + +@@ -9128,12 +9277,11 @@ + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +-*** Warning: the GNU linker, at least up to release 2.19, is reported ++*** Warning: the GNU linker, at least up to release 2.9.1, is reported + *** to be unable to reliably create shared libraries on AIX. + *** Therefore, libtool is disabling shared libraries support. If you +-*** really care for shared libraries, you may want to install binutils +-*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +-*** You will then need to restart the configuration process. ++*** really care for shared libraries, you may want to modify your PATH ++*** so that a non-GNU linker is found, and then restart. + + _LT_EOF + fi +@@ -9169,7 +9317,6 @@ + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' +- export_dynamic_flag_spec='${wl}--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes +@@ -9191,11 +9338,6 @@ + fi + ;; + +- haiku*) +- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' +- link_all_deplibs=yes +- ;; +- + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no +@@ -9225,12 +9367,11 @@ + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler +- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; +- pgf77* | pgf90* | pgf95* | pgfortran*) +- # Portland Group f77 and f90 compilers +- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers ++ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; +@@ -9241,17 +9382,13 @@ + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; +- xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) ++ xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; +- nvcc*) # Cuda Compiler Driver 2.2 +- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' +- compiler_needs_object=yes +- ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 +- whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 +@@ -9267,7 +9404,7 @@ + fi + + case $cc_basename in +- xlf* | bgf* | bgxlf* | mpixlf*) ++ xlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec= +@@ -9286,7 +9423,7 @@ + fi + ;; + +- netbsd*) ++ netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= +@@ -9398,10 +9535,8 @@ + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm +- # Also, AIX nm treats weak defined symbols like other global +- # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then +- export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' ++ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi +@@ -9463,6 +9598,7 @@ + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi ++ link_all_deplibs=no + else + # not using gcc + if test "$host_cpu" = ia64; then +@@ -9519,7 +9655,7 @@ + if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" +- archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" ++ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' +@@ -9563,13 +9699,8 @@ + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' +- if test "$with_gnu_ld" = yes; then +- # We only use this code for GNU lds that support --whole-archive. +- whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' +- else +- # Exported symbols can be pulled into shared objects from archives +- whole_archive_flag_spec='$convenience' +- fi ++ # Exported symbols can be pulled into shared objects from archives ++ whole_archive_flag_spec='$convenience' + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' +@@ -9608,7 +9739,7 @@ + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. +- archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' ++ archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. +@@ -9624,11 +9755,7 @@ + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported +- if test "$lt_cv_ld_force_load" = "yes"; then +- whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' +- else +- whole_archive_flag_spec='' +- fi ++ whole_archive_flag_spec='' + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in +@@ -9636,7 +9763,7 @@ + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then +- output_verbose_link_cmd=func_echo_all ++ output_verbose_link_cmd=echo + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +@@ -9702,7 +9829,7 @@ + ;; + + hpux10*) +- if test "$GCC" = yes && test "$with_gnu_ld" = no; then ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +@@ -9721,7 +9848,7 @@ + ;; + + hpux11*) +- if test "$GCC" = yes && test "$with_gnu_ld" = no; then ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' +@@ -9742,46 +9869,7 @@ + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) +- +- # Older versions of the 11.00 compiler do not understand -b yet +- # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +-$as_echo_n "checking if $CC understands -b... " >&6; } +-if test "${lt_cv_prog_compiler__b+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- lt_cv_prog_compiler__b=no +- save_LDFLAGS="$LDFLAGS" +- LDFLAGS="$LDFLAGS -b" +- echo "$lt_simple_link_test_code" > conftest.$ac_ext +- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then +- # The linker can only warn and ignore the option if not recognized +- # So say no if there are warnings +- if test -s conftest.err; then +- # Append any errors to the config.log. +- cat conftest.err 1>&5 +- $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp +- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 +- if diff conftest.exp conftest.er2 >/dev/null; then +- lt_cv_prog_compiler__b=yes +- fi +- else +- lt_cv_prog_compiler__b=yes +- fi +- fi +- $RM -r conftest* +- LDFLAGS="$save_LDFLAGS" +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +-$as_echo "$lt_cv_prog_compiler__b" >&6; } +- +-if test x"$lt_cv_prog_compiler__b" = xyes; then +- archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +-else +- archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +-fi +- ++ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi +@@ -9809,7 +9897,7 @@ + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then +- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. +@@ -9820,15 +9908,15 @@ + int foo(void) {} + _ACEOF + if ac_fn_c_try_link "$LINENO"; then : +- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + + fi + rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + else +- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' +- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' +@@ -9837,7 +9925,7 @@ + link_all_deplibs=yes + ;; + +- netbsd*) ++ netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else +@@ -9890,17 +9978,17 @@ + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported +- archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' ++ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' +@@ -9910,13 +9998,13 @@ + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ +- $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' ++ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' +@@ -10119,50 +10207,44 @@ + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 + $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +-if test "${lt_cv_archive_cmds_need_lc+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- $RM conftest* +- echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ $RM conftest* ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext + +- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then +- soname=conftest +- lib=conftest +- libobjs=conftest.$ac_objext +- deplibs= +- wl=$lt_prog_compiler_wl +- pic_flag=$lt_prog_compiler_pic +- compiler_flags=-v +- linker_flags=-v +- verstring= +- output_objdir=. +- libname=conftest +- lt_save_allow_undefined_flag=$allow_undefined_flag +- allow_undefined_flag= +- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 ++ soname=conftest ++ lib=conftest ++ libobjs=conftest.$ac_objext ++ deplibs= ++ wl=$lt_prog_compiler_wl ++ pic_flag=$lt_prog_compiler_pic ++ compiler_flags=-v ++ linker_flags=-v ++ verstring= ++ output_objdir=. ++ libname=conftest ++ lt_save_allow_undefined_flag=$allow_undefined_flag ++ allow_undefined_flag= ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +- then +- lt_cv_archive_cmds_need_lc=no +- else +- lt_cv_archive_cmds_need_lc=yes +- fi +- allow_undefined_flag=$lt_save_allow_undefined_flag +- else +- cat conftest.err 1>&5 +- fi +- $RM conftest* +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +-$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } +- archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ++ then ++ archive_cmds_need_lc=no ++ else ++ archive_cmds_need_lc=yes ++ fi ++ allow_undefined_flag=$lt_save_allow_undefined_flag ++ else ++ cat conftest.err 1>&5 ++ fi ++ $RM conftest* ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5 ++$as_echo "$archive_cmds_need_lc" >&6; } + ;; + esac + fi +@@ -10333,23 +10415,16 @@ + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac +- case $host_os in +- mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; +- *) lt_sed_strip_eq="s,=/,/,g" ;; +- esac +- lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` +- case $lt_search_path_spec in +- *\;*) ++ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. +- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` +- ;; +- *) +- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` +- ;; +- esac ++ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= +@@ -10362,7 +10437,7 @@ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done +- lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' ++ lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' + BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; +@@ -10382,13 +10457,7 @@ + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } + }'` +- # AWK program above erroneously prepends '/' to C:/dos/paths +- # for these hosts. +- case $host_os in +- mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ +- $SED 's,/\([A-Za-z]:\),\1,g'` ;; +- esac +- sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` ++ sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` + else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + fi +@@ -10476,7 +10545,7 @@ + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. +- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ++ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; +@@ -10529,12 +10598,23 @@ + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' +- +- sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ++ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then ++ # It is most probably a Windows format PATH printed by ++ # mingw gcc, but we are running on Cygwin. Gcc prints its search ++ # path with ; separators, and with drive letters. We can handle the ++ # drive letters (cygwin fileutils understands them), so leave them, ++ # especially as we might pass files found there to a mingw objdump, ++ # which wouldn't understand a cygwinified path. Ahh. ++ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' +@@ -10634,19 +10714,6 @@ + hardcode_into_libs=yes + ;; + +-haiku*) +- version_type=linux +- need_lib_prefix=no +- need_version=no +- dynamic_linker="$host_os runtime_loader" +- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' +- soname_spec='${libname}${release}${shared_ext}$major' +- shlibpath_var=LIBRARY_PATH +- shlibpath_overrides_runpath=yes +- sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib' +- hardcode_into_libs=yes +- ;; +- + hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. +@@ -10689,10 +10756,8 @@ + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac +- # HP-UX runs *really* slowly unless shared libraries are mode 555, ... ++ # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' +- # or fails outright, so override atomically: +- install_override_mode=555 + ;; + + interix[3-9]*) +@@ -10759,17 +10824,12 @@ + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no +- + # Some binutils ld are patched to set DT_RUNPATH +- if test "${lt_cv_shlibpath_overrides_runpath+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- lt_cv_shlibpath_overrides_runpath=no +- save_LDFLAGS=$LDFLAGS +- save_libdir=$libdir +- eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ +- LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++ save_LDFLAGS=$LDFLAGS ++ save_libdir=$libdir ++ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ ++ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + + int +@@ -10782,17 +10842,13 @@ + _ACEOF + if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : +- lt_cv_shlibpath_overrides_runpath=yes ++ shlibpath_overrides_runpath=yes + fi + fi + rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +- LDFLAGS=$save_LDFLAGS +- libdir=$save_libdir +- +-fi +- +- shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath ++ LDFLAGS=$save_LDFLAGS ++ libdir=$save_libdir + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install +@@ -10801,7 +10857,7 @@ + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then +- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + +@@ -10814,6 +10870,18 @@ + dynamic_linker='GNU/Linux ld.so' + ;; + ++netbsdelf*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='NetBSD ld.elf_so' ++ ;; ++ + netbsd*) + version_type=sunos + need_lib_prefix=no +@@ -11104,11 +11172,6 @@ + + + +- +- +- +- +- + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 + $as_echo_n "checking how to hardcode library paths into programs... " >&6; } + hardcode_action= +@@ -11439,7 +11502,7 @@ + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11442 "configure" ++#line 11505 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11480,13 +11543,7 @@ + # endif + #endif + +-/* When -fvisbility=hidden is used, assume the code has been annotated +- correspondingly for the symbols needed. */ +-#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +-void fnord () __attribute__((visibility("default"))); +-#endif +- +-void fnord () { int i=42; } ++void fnord() { int i=42;} + int main () + { + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); +@@ -11495,11 +11552,7 @@ + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; +- else +- { +- if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; +- else puts (dlerror ()); +- } ++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else +@@ -11545,7 +11598,7 @@ + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11548 "configure" ++#line 11601 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11586,13 +11639,7 @@ + # endif + #endif + +-/* When -fvisbility=hidden is used, assume the code has been annotated +- correspondingly for the symbols needed. */ +-#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +-void fnord () __attribute__((visibility("default"))); +-#endif +- +-void fnord () { int i=42; } ++void fnord() { int i=42;} + int main () + { + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); +@@ -11601,11 +11648,7 @@ + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; +- else +- { +- if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; +- else puts (dlerror ()); +- } ++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else +@@ -12548,148 +12591,135 @@ + sed_quote_subst='$sed_quote_subst' + double_quote_subst='$double_quote_subst' + delay_variable_subst='$delay_variable_subst' +-SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +-Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +-SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +-ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +-AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' +-DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +-OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +-macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +-macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +-enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +-enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +-pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +-enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +-host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +-host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +-host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +-build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +-build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +-build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +-GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +-EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +-FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +-LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +-NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +-LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +-max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +-ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +-exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +-lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +-lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +-lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +-reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +-reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +-deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +-file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +-AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +-AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +-STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +-RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +-old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +-old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +-old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +-lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +-CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +-CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +-compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +-GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +-objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +-MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +-lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +-need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +-DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +-NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +-LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +-OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +-OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +-libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +-shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +-extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +-archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +-enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +-export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +-whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +-compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +-old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +-old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +-archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +-archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +-module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +-module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +-with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +-allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +-no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +-hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +-hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`' +-hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +-hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +-hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +-hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +-hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +-hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +-inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +-link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +-fix_srcfile_path='`$ECHO "$fix_srcfile_path" | $SED "$delay_single_quote_subst"`' +-always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +-export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +-exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +-include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +-prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +-file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +-variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +-need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +-need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +-version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +-runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +-shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +-shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +-libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +-library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +-soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +-install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +-postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +-postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +-finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +-finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +-hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +-sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +-sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +-hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +-enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +-enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +-enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +-old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +-striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' ++SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`' ++Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`' ++SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`' ++ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`' ++AS='`$ECHO "X$AS" | $Xsed -e "$delay_single_quote_subst"`' ++DLLTOOL='`$ECHO "X$DLLTOOL" | $Xsed -e "$delay_single_quote_subst"`' ++OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`' ++macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`' ++macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`' ++enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`' ++enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`' ++pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`' ++enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`' ++host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`' ++host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`' ++host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`' ++build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`' ++build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`' ++build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`' ++GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`' ++EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`' ++FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`' ++LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`' ++NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`' ++LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`' ++max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`' ++ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`' ++exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`' ++lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`' ++lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`' ++lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`' ++reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`' ++reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`' ++file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`' ++AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`' ++AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`' ++STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`' ++RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`' ++old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`' ++CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`' ++compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`' ++GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' ++objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`' ++MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`' ++need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`' ++DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`' ++NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`' ++LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`' ++OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`' ++OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`' ++libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`' ++shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`' ++enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`' ++export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`' ++allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' ++no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`' ++inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`' ++link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`' ++fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`' ++always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`' ++export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`' ++include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`' ++prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`' ++variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`' ++need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' ++need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`' ++version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`' ++runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`' ++libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`' ++library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`' ++soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`' ++postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`' ++sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`' ++sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`' ++old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`' ++striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`' + + LTCC='$LTCC' + LTCFLAGS='$LTCFLAGS' + compiler='$compiler_DEFAULT' + +-# A function that is used when there is no print builtin or printf. +-func_fallback_echo () +-{ +- eval 'cat <<_LTECHO_EOF +-\$1 +-_LTECHO_EOF' +-} +- + # Quote evaled strings. + for var in SED \ + SHELL \ + ECHO \ +-AS \ +-DLLTOOL \ +-OBJDUMP \ + GREP \ + EGREP \ + FGREP \ +@@ -12741,13 +12771,12 @@ + libname_spec \ + library_names_spec \ + soname_spec \ +-install_override_mode \ + finish_eval \ + old_striplib \ + striplib; do +- case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in ++ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) +- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ++ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" +@@ -12774,9 +12803,9 @@ + finish_cmds \ + sys_lib_search_path_spec \ + sys_lib_dlsearch_path_spec; do +- case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in ++ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) +- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ++ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" +@@ -12784,6 +12813,12 @@ + esac + done + ++# Fix-up fallback echo if it was mangled by the above quoting rules. ++case \$lt_ECHO in ++*'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\` ++ ;; ++esac ++ + ac_aux_dir='$ac_aux_dir' + xsi_shell='$xsi_shell' + lt_shell_append='$lt_shell_append' +@@ -13349,7 +13384,7 @@ + # NOTE: Changes made to this file will be lost: look at ltmain.sh. + # + # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +-# 2006, 2007, 2008, 2009 Free Software Foundation, Inc. ++# 2006, 2007, 2008 Free Software Foundation, Inc. + # Written by Gordon Matzigkeit, 1996 + # + # This file is part of GNU Libtool. +@@ -13390,17 +13425,17 @@ + # Shell to use when invoking shell scripts. + SHELL=$lt_SHELL + +-# An echo program that protects backslashes. ++# An echo program that does not interpret backslashes. + ECHO=$lt_ECHO + + # Assembler program. +-AS=$lt_AS ++AS=$AS + + # DLL creation program. +-DLLTOOL=$lt_DLLTOOL ++DLLTOOL=$DLLTOOL + + # Object dumper program. +-OBJDUMP=$lt_OBJDUMP ++OBJDUMP=$OBJDUMP + + # Which release of libtool.m4 was used? + macro_version=$macro_version +@@ -13461,6 +13496,10 @@ + # turn newlines into spaces. + NL2SP=$lt_lt_NL2SP + ++# How to create reloadable object files. ++reload_flag=$lt_reload_flag ++reload_cmds=$lt_reload_cmds ++ + # Method to check whether dependent libraries are shared objects. + deplibs_check_method=$lt_deplibs_check_method + +@@ -13479,9 +13518,6 @@ + old_postinstall_cmds=$lt_old_postinstall_cmds + old_postuninstall_cmds=$lt_old_postuninstall_cmds + +-# Whether to use a lock for old archive extraction. +-lock_old_archive_extraction=$lock_old_archive_extraction +- + # A C compiler. + LTCC=$lt_CC + +@@ -13565,9 +13601,6 @@ + # The coded name of the library, if different from the real name. + soname_spec=$lt_soname_spec + +-# Permission mode override for installation of shared libraries. +-install_override_mode=$lt_install_override_mode +- + # Command to use after installation of a shared archive. + postinstall_cmds=$lt_postinstall_cmds + +@@ -13607,10 +13640,6 @@ + # The linker used to build libraries. + LD=$lt_LD + +-# How to create reloadable object files. +-reload_flag=$lt_reload_flag +-reload_cmds=$lt_reload_cmds +- + # Commands used to build an old-style archive. + old_archive_cmds=$lt_old_archive_cmds + +@@ -13870,7 +13899,7 @@ + func_dirname () + { + # Extract subdirectory from the argument. +- func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` ++ func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else +@@ -13881,7 +13910,7 @@ + # func_basename file + func_basename () + { +- func_basename_result=`$ECHO "${1}" | $SED "$basename"` ++ func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` + } + + +@@ -13894,8 +13923,10 @@ + func_stripname () + { + case ${2} in +- .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; +- *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; ++ .*) func_stripname_result=`$ECHO "X${3}" \ ++ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; ++ *) func_stripname_result=`$ECHO "X${3}" \ ++ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; + esac + } + +@@ -13906,20 +13937,20 @@ + # func_opt_split + func_opt_split () + { +- func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"` +- func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"` ++ func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` ++ func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` + } + + # func_lo2o object + func_lo2o () + { +- func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` ++ func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` + } + + # func_xform libobj-or-source + func_xform () + { +- func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` ++ func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'` + } + + # func_arith arithmetic-term... +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/linuxthreads/machine/i386/Makefile.in newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/linuxthreads/machine/i386/Makefile.in +--- newlib-1.19.0/newlib/libc/sys/linux/linuxthreads/machine/i386/Makefile.in 2010-12-16 16:59:09.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/linuxthreads/machine/i386/Makefile.in 2013-10-21 15:44:33.000000000 -0400 +@@ -42,12 +42,14 @@ + $(srcdir)/../../../../../../../mkinstalldirs + subdir = . + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +-am__aclocal_m4_deps = $(top_srcdir)/../../../../../../../libtool.m4 \ +- $(top_srcdir)/../../../../../../../ltoptions.m4 \ +- $(top_srcdir)/../../../../../../../ltsugar.m4 \ +- $(top_srcdir)/../../../../../../../ltversion.m4 \ ++am__aclocal_m4_deps = \ + $(top_srcdir)/../../../../../../../lt~obsolete.m4 \ + $(top_srcdir)/../../../../../../acinclude.m4 \ ++ $(top_srcdir)/../../../../../../libtool.m4 \ ++ $(top_srcdir)/../../../../../../ltoptions.m4 \ ++ $(top_srcdir)/../../../../../../ltsugar.m4 \ ++ $(top_srcdir)/../../../../../../ltversion.m4 \ ++ $(top_srcdir)/../../../../../../lt~obsolete.m4 \ + $(top_srcdir)/configure.in + am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +@@ -201,6 +203,7 @@ + localedir = @localedir@ + localstatedir = @localstatedir@ + lpfx = @lpfx@ ++lt_ECHO = @lt_ECHO@ + machine_dir = @machine_dir@ + mandir = @mandir@ + mkdir_p = @mkdir_p@ +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/linuxthreads/machine/Makefile.in newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/linuxthreads/machine/Makefile.in +--- newlib-1.19.0/newlib/libc/sys/linux/linuxthreads/machine/Makefile.in 2010-12-16 16:59:08.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/linuxthreads/machine/Makefile.in 2013-10-21 15:44:33.000000000 -0400 +@@ -38,12 +38,13 @@ + $(top_srcdir)/configure $(am__configure_deps) \ + $(srcdir)/../../../../../../mkinstalldirs + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +-am__aclocal_m4_deps = $(top_srcdir)/../../../../../../libtool.m4 \ +- $(top_srcdir)/../../../../../../ltoptions.m4 \ +- $(top_srcdir)/../../../../../../ltsugar.m4 \ +- $(top_srcdir)/../../../../../../ltversion.m4 \ +- $(top_srcdir)/../../../../../../lt~obsolete.m4 \ ++am__aclocal_m4_deps = $(top_srcdir)/../../../../../../lt~obsolete.m4 \ + $(top_srcdir)/../../../../../acinclude.m4 \ ++ $(top_srcdir)/../../../../../libtool.m4 \ ++ $(top_srcdir)/../../../../../ltoptions.m4 \ ++ $(top_srcdir)/../../../../../ltsugar.m4 \ ++ $(top_srcdir)/../../../../../ltversion.m4 \ ++ $(top_srcdir)/../../../../../lt~obsolete.m4 \ + $(top_srcdir)/configure.in + am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +@@ -174,6 +175,7 @@ + localedir = @localedir@ + localstatedir = @localstatedir@ + lpfx = @lpfx@ ++lt_ECHO = @lt_ECHO@ + machine_dir = @machine_dir@ + mandir = @mandir@ + mkdir_p = @mkdir_p@ +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/linuxthreads/Makefile.in newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/linuxthreads/Makefile.in +--- newlib-1.19.0/newlib/libc/sys/linux/linuxthreads/Makefile.in 2010-12-16 16:59:07.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/linuxthreads/Makefile.in 2013-10-21 15:44:33.000000000 -0400 +@@ -42,12 +42,13 @@ + $(srcdir)/../../../../../mkinstalldirs + subdir = . + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +-am__aclocal_m4_deps = $(top_srcdir)/../../../../../libtool.m4 \ +- $(top_srcdir)/../../../../../ltoptions.m4 \ +- $(top_srcdir)/../../../../../ltsugar.m4 \ +- $(top_srcdir)/../../../../../ltversion.m4 \ +- $(top_srcdir)/../../../../../lt~obsolete.m4 \ ++am__aclocal_m4_deps = $(top_srcdir)/../../../../../lt~obsolete.m4 \ + $(top_srcdir)/../../../../acinclude.m4 \ ++ $(top_srcdir)/../../../../libtool.m4 \ ++ $(top_srcdir)/../../../../ltoptions.m4 \ ++ $(top_srcdir)/../../../../ltsugar.m4 \ ++ $(top_srcdir)/../../../../ltversion.m4 \ ++ $(top_srcdir)/../../../../lt~obsolete.m4 \ + $(top_srcdir)/configure.in + am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +@@ -333,6 +334,7 @@ + localedir = @localedir@ + localstatedir = @localstatedir@ + lpfx = @lpfx@ ++lt_ECHO = @lt_ECHO@ + machine_dir = @machine_dir@ + mandir = @mandir@ + mkdir_p = @mkdir_p@ +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/machine/aclocal.m4 newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/machine/aclocal.m4 +--- newlib-1.19.0/newlib/libc/sys/linux/machine/aclocal.m4 2010-12-16 16:59:09.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/machine/aclocal.m4 2013-10-21 15:44:33.000000000 -0400 +@@ -989,9 +989,10 @@ + AC_SUBST([am__untar]) + ]) # _AM_PROG_TAR + +-m4_include([../../../../../libtool.m4]) +-m4_include([../../../../../ltoptions.m4]) +-m4_include([../../../../../ltsugar.m4]) +-m4_include([../../../../../ltversion.m4]) + m4_include([../../../../../lt~obsolete.m4]) + m4_include([../../../../acinclude.m4]) ++m4_include([../../../../libtool.m4]) ++m4_include([../../../../ltoptions.m4]) ++m4_include([../../../../ltsugar.m4]) ++m4_include([../../../../ltversion.m4]) ++m4_include([../../../../lt~obsolete.m4]) +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/machine/configure newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/machine/configure +--- newlib-1.19.0/newlib/libc/sys/linux/machine/configure 2010-12-16 16:59:09.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/machine/configure 2013-10-21 15:44:33.000000000 -0400 +@@ -171,15 +171,7 @@ + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +-test \$(( 1 + 1 )) = 2 || exit 1 +- +- test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( +- ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +- ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO +- ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO +- PATH=/empty FPATH=/empty; export PATH FPATH +- test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ +- || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" ++test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes + else +@@ -533,8 +525,304 @@ + # Sed expression to map a string onto a valid variable name. + as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + ++ ++ ++# Check that we are running under the correct shell. + SHELL=${CONFIG_SHELL-/bin/sh} + ++case X$lt_ECHO in ++X*--fallback-echo) ++ # Remove one level of quotation (which was required for Make). ++ ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` ++ ;; ++esac ++ ++ECHO=${lt_ECHO-echo} ++if test "X$1" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++elif test "X$1" = X--fallback-echo; then ++ # Avoid inline document here, it may be left over ++ : ++elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then ++ # Yippee, $ECHO works! ++ : ++else ++ # Restart under the correct shell. ++ exec $SHELL "$0" --no-reexec ${1+"$@"} ++fi ++ ++if test "X$1" = X--fallback-echo; then ++ # used as fallback echo ++ shift ++ cat <<_LT_EOF ++$* ++_LT_EOF ++ exit 0 ++fi ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++if test -z "$lt_ECHO"; then ++ if test "X${echo_test_string+set}" != Xset; then ++ # find a string as large as possible, as long as the shell can cope with it ++ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do ++ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... ++ if { echo_test_string=`eval $cmd`; } 2>/dev/null && ++ { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null ++ then ++ break ++ fi ++ done ++ fi ++ ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ : ++ else ++ # The Solaris, AIX, and Digital Unix default echo programs unquote ++ # backslashes. This makes it impossible to quote backslashes using ++ # echo "$something" | sed 's/\\/\\\\/g' ++ # ++ # So, first we look for a working echo in the user's PATH. ++ ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for dir in $PATH /usr/ucb; do ++ IFS="$lt_save_ifs" ++ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && ++ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$dir/echo" ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ if test "X$ECHO" = Xecho; then ++ # We didn't find a better echo, so look for alternatives. ++ if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # This shell has a builtin print -r that does the trick. ++ ECHO='print -r' ++ elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && ++ test "X$CONFIG_SHELL" != X/bin/ksh; then ++ # If we have ksh, try running configure again with it. ++ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} ++ export ORIGINAL_CONFIG_SHELL ++ CONFIG_SHELL=/bin/ksh ++ export CONFIG_SHELL ++ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} ++ else ++ # Try using printf. ++ ECHO='printf %s\n' ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # Cool, printf works ++ : ++ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL ++ export CONFIG_SHELL ++ SHELL="$CONFIG_SHELL" ++ export SHELL ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ else ++ # maybe with a smaller string... ++ prev=: ++ ++ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do ++ if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null ++ then ++ break ++ fi ++ prev="$cmd" ++ done ++ ++ if test "$prev" != 'sed 50q "$0"'; then ++ echo_test_string=`eval $prev` ++ export echo_test_string ++ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} ++ else ++ # Oops. We lost completely, so just stick with echo. ++ ECHO=echo ++ fi ++ fi ++ fi ++ fi ++ fi ++fi ++ ++# Copy echo and quote the copy suitably for passing to libtool from ++# the Makefile, instead of quoting the original, which is used later. ++lt_ECHO=$ECHO ++if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then ++ lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" ++fi ++ ++ ++ ++ ++ ++# Check that we are running under the correct shell. ++SHELL=${CONFIG_SHELL-/bin/sh} ++ ++case X$lt_ECHO in ++X*--fallback-echo) ++ # Remove one level of quotation (which was required for Make). ++ ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` ++ ;; ++esac ++ ++ECHO=${lt_ECHO-echo} ++if test "X$1" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++elif test "X$1" = X--fallback-echo; then ++ # Avoid inline document here, it may be left over ++ : ++elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then ++ # Yippee, $ECHO works! ++ : ++else ++ # Restart under the correct shell. ++ exec $SHELL "$0" --no-reexec ${1+"$@"} ++fi ++ ++if test "X$1" = X--fallback-echo; then ++ # used as fallback echo ++ shift ++ cat <<_LT_EOF ++$* ++_LT_EOF ++ exit 0 ++fi ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++if test -z "$lt_ECHO"; then ++ if test "X${echo_test_string+set}" != Xset; then ++ # find a string as large as possible, as long as the shell can cope with it ++ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do ++ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... ++ if { echo_test_string=`eval $cmd`; } 2>/dev/null && ++ { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null ++ then ++ break ++ fi ++ done ++ fi ++ ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ : ++ else ++ # The Solaris, AIX, and Digital Unix default echo programs unquote ++ # backslashes. This makes it impossible to quote backslashes using ++ # echo "$something" | sed 's/\\/\\\\/g' ++ # ++ # So, first we look for a working echo in the user's PATH. ++ ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for dir in $PATH /usr/ucb; do ++ IFS="$lt_save_ifs" ++ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && ++ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$dir/echo" ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ if test "X$ECHO" = Xecho; then ++ # We didn't find a better echo, so look for alternatives. ++ if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # This shell has a builtin print -r that does the trick. ++ ECHO='print -r' ++ elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && ++ test "X$CONFIG_SHELL" != X/bin/ksh; then ++ # If we have ksh, try running configure again with it. ++ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} ++ export ORIGINAL_CONFIG_SHELL ++ CONFIG_SHELL=/bin/ksh ++ export CONFIG_SHELL ++ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} ++ else ++ # Try using printf. ++ ECHO='printf %s\n' ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # Cool, printf works ++ : ++ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL ++ export CONFIG_SHELL ++ SHELL="$CONFIG_SHELL" ++ export SHELL ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ else ++ # maybe with a smaller string... ++ prev=: ++ ++ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do ++ if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null ++ then ++ break ++ fi ++ prev="$cmd" ++ done ++ ++ if test "$prev" != 'sed 50q "$0"'; then ++ echo_test_string=`eval $prev` ++ export echo_test_string ++ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} ++ else ++ # Oops. We lost completely, so just stick with echo. ++ ECHO=echo ++ fi ++ fi ++ fi ++ fi ++ fi ++fi ++ ++# Copy echo and quote the copy suitably for passing to libtool from ++# the Makefile, instead of quoting the original, which is used later. ++lt_ECHO=$ECHO ++if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then ++ lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" ++fi ++ ++ ++ + + test -n "$DJDIR" || exec 7<&0 &1 +@@ -631,6 +919,7 @@ + LIBTOOL + OBJDUMP + DLLTOOL ++lt_ECHO + SED + sys_dir + machine_dir +@@ -3800,45 +4089,6 @@ + + + +-ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +-ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +-ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +-$as_echo_n "checking how to print strings... " >&6; } +-# Test print first, because it will be a builtin if present. +-if test "X`print -r -- -n 2>/dev/null`" = X-n && \ +- test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then +- ECHO='print -r --' +-elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then +- ECHO='printf %s\n' +-else +- # Use this function as a fallback that always works. +- func_fallback_echo () +- { +- eval 'cat <<_LTECHO_EOF +-$1 +-_LTECHO_EOF' +- } +- ECHO='func_fallback_echo' +-fi +- +-# func_echo_all arg... +-# Invoke $ECHO with all args, space-separated. +-func_echo_all () +-{ +- $ECHO "" +-} +- +-case "$ECHO" in +- printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +-$as_echo "printf" >&6; } ;; +- print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +-$as_echo "print -r" >&6; } ;; +- *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +-$as_echo "cat" >&6; } ;; +-esac +- + + + +@@ -3856,7 +4106,7 @@ + enable_win32_dll=yes + + case $host in +-*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) ++*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. + set dummy ${ac_tool_prefix}as; ac_word=$2 +@@ -4164,8 +4414,8 @@ + + + +-macro_version='2.2.7a' +-macro_revision='1.3134' ++macro_version='2.2.6b' ++macro_revision='1.3017' + + + +@@ -4181,23 +4431,6 @@ + + ltmain="$ac_aux_dir/ltmain.sh" + +-# Backslashify metacharacters that are still active within +-# double-quoted strings. +-sed_quote_subst='s/\(["`$\\]\)/\\\1/g' +- +-# Same as above, but do not quote variable references. +-double_quote_subst='s/\(["`\\]\)/\\\1/g' +- +-# Sed substitution to delay expansion of an escaped shell variable in a +-# double_quote_subst'ed string. +-delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' +- +-# Sed substitution to delay expansion of an escaped single quote. +-delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' +- +-# Sed substitution to avoid accidental globbing in evaled expressions +-no_glob_subst='s/\*/\\\*/g' +- + ac_ext=c + ac_cpp='$CPP $CPPFLAGS' + ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +@@ -5499,11 +5732,8 @@ + NM="$lt_cv_path_NM" + else + # Didn't find any BSD compatible name lister, look for dumpbin. +- if test -n "$DUMPBIN"; then : +- # Let the user override the test. +- else +- if test -n "$ac_tool_prefix"; then +- for ac_prog in dumpbin "link -dump" ++ if test -n "$ac_tool_prefix"; then ++ for ac_prog in "dumpbin -symbols" "link -dump -symbols" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. + set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +@@ -5547,7 +5777,7 @@ + fi + if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN +- for ac_prog in dumpbin "link -dump" ++ for ac_prog in "dumpbin -symbols" "link -dump -symbols" + do + # Extract the first word of "$ac_prog", so it can be a program name with args. + set dummy $ac_prog; ac_word=$2 +@@ -5602,15 +5832,6 @@ + fi + fi + +- case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in +- *COFF*) +- DUMPBIN="$DUMPBIN -symbols" +- ;; +- *) +- DUMPBIN=: +- ;; +- esac +- fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" +@@ -5630,13 +5851,13 @@ + else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext +- (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) ++ (eval echo "\"\$as_me:5854: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 +- (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) ++ (eval echo "\"\$as_me:5857: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 +- (eval echo "\"\$as_me:$LINENO: output\"" >&5) ++ (eval echo "\"\$as_me:5860: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" +@@ -5693,11 +5914,6 @@ + lt_cv_sys_max_cmd_len=8192; + ;; + +- mint*) +- # On MiNT this can take a long time and run out of memory. +- lt_cv_sys_max_cmd_len=8192; +- ;; +- + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. +@@ -5762,8 +5978,8 @@ + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. +- while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ +- = "X$teststring$teststring"; } >/dev/null 2>&1 && ++ while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ ++ = "XX$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` +@@ -6031,8 +6247,7 @@ + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. +- # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. +- if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then ++ if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else +@@ -6041,7 +6256,7 @@ + fi + ;; + +-cegcc*) ++cegcc) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' +@@ -6071,10 +6286,6 @@ + lt_cv_deplibs_check_method=pass_all + ;; + +-haiku*) +- lt_cv_deplibs_check_method=pass_all +- ;; +- + hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in +@@ -6083,11 +6294,11 @@ + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) +- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) +- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac +@@ -6113,7 +6324,7 @@ + lt_cv_deplibs_check_method=pass_all + ;; + +-netbsd*) ++netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else +@@ -6525,18 +6736,6 @@ + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" + fi + +-case $host_os in +- darwin*) +- lock_old_archive_extraction=yes ;; +- *) +- lock_old_archive_extraction=no ;; +-esac +- +- +- +- +- +- + + + +@@ -6706,8 +6905,8 @@ + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm +- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 +- (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5 ++ (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then +@@ -6861,7 +7060,7 @@ + ;; + *-*-irix6*) + # Find out which ABI we are using. +- echo '#line '$LINENO' "configure"' > conftest.$ac_ext ++ echo '#line 7063 "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? +@@ -7573,36 +7772,6 @@ + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 + $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +-$as_echo_n "checking for -force_load linker flag... " >&6; } +-if test "${lt_cv_ld_force_load+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- lt_cv_ld_force_load=no +- cat > conftest.c << _LT_EOF +-int forced_loaded() { return 2;} +-_LT_EOF +- echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 +- $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 +- echo "$AR cru libconftest.a conftest.o" >&5 +- $AR cru libconftest.a conftest.o 2>&5 +- cat > conftest.c << _LT_EOF +-int main() { return 0;} +-_LT_EOF +- echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 +- $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err +- _lt_result=$? +- if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then +- lt_cv_ld_force_load=yes +- else +- cat conftest.err >&5 +- fi +- rm -f conftest.err libconftest.a conftest conftest.c +- rm -rf conftest.dSYM +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +-$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; +@@ -7630,7 +7799,7 @@ + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi +- if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then ++ if test "$DSYMUTIL" != ":"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= +@@ -7921,8 +8090,6 @@ + + + +- +- + # Set options + + +@@ -8073,7 +8240,6 @@ + + + +- + test -z "$LN_S" && LN_S="ln -s" + + +@@ -8123,6 +8289,13 @@ + + + ++ ++ ++ ++ ++ ++ ++ + case $host_os in + aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some +@@ -8135,6 +8308,23 @@ + ;; + esac + ++# Sed substitution that helps us do robust quoting. It backslashifies ++# metacharacters that are still active within double-quoted strings. ++sed_quote_subst='s/\(["`$\\]\)/\\\1/g' ++ ++# Same as above, but do not quote variable references. ++double_quote_subst='s/\(["`\\]\)/\\\1/g' ++ ++# Sed substitution to delay expansion of an escaped shell variable in a ++# double_quote_subst'ed string. ++delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' ++ ++# Sed substitution to delay expansion of an escaped single quote. ++delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' ++ ++# Sed substitution to avoid accidental globbing in evaled expressions ++no_glob_subst='s/\*/\\\*/g' ++ + # Global variables: + ofile=libtool + can_build_shared=yes +@@ -8163,7 +8353,7 @@ + *) break;; + esac + done +-cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ++cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + + # Only perform the check for file, if the check method requires it +@@ -8372,12 +8562,7 @@ + lt_prog_compiler_no_builtin_flag= + + if test "$GCC" = yes; then +- case $cc_basename in +- nvcc*) +- lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; +- *) +- lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; +- esac ++ lt_prog_compiler_no_builtin_flag=' -fno-builtin' + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 + $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +@@ -8397,15 +8582,15 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:8585: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:8589: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes +@@ -8483,12 +8668,6 @@ + lt_prog_compiler_pic='-fno-common' + ;; + +- haiku*) +- # PIC is the default for Haiku. +- # The "-static" flag exists, but is broken. +- lt_prog_compiler_static= +- ;; +- + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag +@@ -8531,13 +8710,6 @@ + lt_prog_compiler_pic='-fPIC' + ;; + esac +- +- case $cc_basename in +- nvcc*) # Cuda Compiler Driver 2.2 +- lt_prog_compiler_wl='-Xlinker ' +- lt_prog_compiler_pic='-Xcompiler -fPIC' +- ;; +- esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in +@@ -8600,7 +8772,7 @@ + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; +- pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) ++ pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' +@@ -8612,26 +8784,26 @@ + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; +- xl* | bgxl* | bgf* | mpixl*) +- # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene ++ xl*) ++ # IBM XL C 8.0/Fortran 10.1 on PPC + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in +- *Sun\ F* | *Sun*Fortran*) +- # Sun Fortran 8.3 passes all unrecognized flags to the linker +- lt_prog_compiler_pic='-KPIC' +- lt_prog_compiler_static='-Bstatic' +- lt_prog_compiler_wl='' +- ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; ++ *Sun\ F*) ++ # Sun Fortran 8.3 passes all unrecognized flags to the linker ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ lt_prog_compiler_wl='' ++ ;; + esac + ;; + esac +@@ -8749,15 +8921,15 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:8924: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:8928: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes +@@ -8805,7 +8977,7 @@ + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 +- $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp ++ $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes +@@ -8854,16 +9026,16 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:9029: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:9033: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes +@@ -8909,16 +9081,16 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:9084: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:9088: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes +@@ -9028,36 +9200,13 @@ + openbsd*) + with_gnu_ld=no + ;; ++ linux* | k*bsd*-gnu) ++ link_all_deplibs=no ++ ;; + esac + + ld_shlibs=yes +- +- # On some targets, GNU ld is compatible enough with the native linker +- # that we're better off using the native interface for both. +- lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then +- case $host_os in +- aix*) +- # The AIX port of GNU ld has always aspired to compatibility +- # with the native linker. However, as the warning in the GNU ld +- # block says, versions before 2.19.5* couldn't really create working +- # shared libraries, regardless of the interface used. +- case `$LD -v 2>&1` in +- *\ \(GNU\ Binutils\)\ 2.19.5*) ;; +- *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; +- *\ \(GNU\ Binutils\)\ [3-9]*) ;; +- *) +- lt_use_gnu_ld_interface=yes +- ;; +- esac +- ;; +- *) +- lt_use_gnu_ld_interface=yes +- ;; +- esac +- fi +- +- if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + +@@ -9091,12 +9240,11 @@ + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +-*** Warning: the GNU linker, at least up to release 2.19, is reported ++*** Warning: the GNU linker, at least up to release 2.9.1, is reported + *** to be unable to reliably create shared libraries on AIX. + *** Therefore, libtool is disabling shared libraries support. If you +-*** really care for shared libraries, you may want to install binutils +-*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +-*** You will then need to restart the configuration process. ++*** really care for shared libraries, you may want to modify your PATH ++*** so that a non-GNU linker is found, and then restart. + + _LT_EOF + fi +@@ -9132,7 +9280,6 @@ + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' +- export_dynamic_flag_spec='${wl}--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes +@@ -9154,11 +9301,6 @@ + fi + ;; + +- haiku*) +- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' +- link_all_deplibs=yes +- ;; +- + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no +@@ -9188,12 +9330,11 @@ + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler +- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; +- pgf77* | pgf90* | pgf95* | pgfortran*) +- # Portland Group f77 and f90 compilers +- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers ++ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; +@@ -9204,17 +9345,13 @@ + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; +- xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) ++ xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; +- nvcc*) # Cuda Compiler Driver 2.2 +- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' +- compiler_needs_object=yes +- ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 +- whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 +@@ -9230,7 +9367,7 @@ + fi + + case $cc_basename in +- xlf* | bgf* | bgxlf* | mpixlf*) ++ xlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec= +@@ -9249,7 +9386,7 @@ + fi + ;; + +- netbsd*) ++ netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= +@@ -9361,10 +9498,8 @@ + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm +- # Also, AIX nm treats weak defined symbols like other global +- # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then +- export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' ++ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi +@@ -9426,6 +9561,7 @@ + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi ++ link_all_deplibs=no + else + # not using gcc + if test "$host_cpu" = ia64; then +@@ -9482,7 +9618,7 @@ + if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" +- archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" ++ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' +@@ -9526,13 +9662,8 @@ + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' +- if test "$with_gnu_ld" = yes; then +- # We only use this code for GNU lds that support --whole-archive. +- whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' +- else +- # Exported symbols can be pulled into shared objects from archives +- whole_archive_flag_spec='$convenience' +- fi ++ # Exported symbols can be pulled into shared objects from archives ++ whole_archive_flag_spec='$convenience' + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' +@@ -9571,7 +9702,7 @@ + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. +- archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' ++ archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. +@@ -9587,11 +9718,7 @@ + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported +- if test "$lt_cv_ld_force_load" = "yes"; then +- whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' +- else +- whole_archive_flag_spec='' +- fi ++ whole_archive_flag_spec='' + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in +@@ -9599,7 +9726,7 @@ + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then +- output_verbose_link_cmd=func_echo_all ++ output_verbose_link_cmd=echo + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +@@ -9665,7 +9792,7 @@ + ;; + + hpux10*) +- if test "$GCC" = yes && test "$with_gnu_ld" = no; then ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +@@ -9684,7 +9811,7 @@ + ;; + + hpux11*) +- if test "$GCC" = yes && test "$with_gnu_ld" = no; then ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' +@@ -9705,46 +9832,7 @@ + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) +- +- # Older versions of the 11.00 compiler do not understand -b yet +- # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +-$as_echo_n "checking if $CC understands -b... " >&6; } +-if test "${lt_cv_prog_compiler__b+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- lt_cv_prog_compiler__b=no +- save_LDFLAGS="$LDFLAGS" +- LDFLAGS="$LDFLAGS -b" +- echo "$lt_simple_link_test_code" > conftest.$ac_ext +- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then +- # The linker can only warn and ignore the option if not recognized +- # So say no if there are warnings +- if test -s conftest.err; then +- # Append any errors to the config.log. +- cat conftest.err 1>&5 +- $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp +- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 +- if diff conftest.exp conftest.er2 >/dev/null; then +- lt_cv_prog_compiler__b=yes +- fi +- else +- lt_cv_prog_compiler__b=yes +- fi +- fi +- $RM -r conftest* +- LDFLAGS="$save_LDFLAGS" +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +-$as_echo "$lt_cv_prog_compiler__b" >&6; } +- +-if test x"$lt_cv_prog_compiler__b" = xyes; then +- archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +-else +- archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +-fi +- ++ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi +@@ -9772,7 +9860,7 @@ + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then +- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. +@@ -9783,15 +9871,15 @@ + int foo(void) {} + _ACEOF + if ac_fn_c_try_link "$LINENO"; then : +- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + + fi + rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + else +- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' +- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' +@@ -9800,7 +9888,7 @@ + link_all_deplibs=yes + ;; + +- netbsd*) ++ netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else +@@ -9853,17 +9941,17 @@ + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported +- archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' ++ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' +@@ -9873,13 +9961,13 @@ + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ +- $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' ++ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' +@@ -10082,50 +10170,44 @@ + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 + $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +-if test "${lt_cv_archive_cmds_need_lc+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- $RM conftest* +- echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ $RM conftest* ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext + +- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then +- soname=conftest +- lib=conftest +- libobjs=conftest.$ac_objext +- deplibs= +- wl=$lt_prog_compiler_wl +- pic_flag=$lt_prog_compiler_pic +- compiler_flags=-v +- linker_flags=-v +- verstring= +- output_objdir=. +- libname=conftest +- lt_save_allow_undefined_flag=$allow_undefined_flag +- allow_undefined_flag= +- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 ++ soname=conftest ++ lib=conftest ++ libobjs=conftest.$ac_objext ++ deplibs= ++ wl=$lt_prog_compiler_wl ++ pic_flag=$lt_prog_compiler_pic ++ compiler_flags=-v ++ linker_flags=-v ++ verstring= ++ output_objdir=. ++ libname=conftest ++ lt_save_allow_undefined_flag=$allow_undefined_flag ++ allow_undefined_flag= ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +- then +- lt_cv_archive_cmds_need_lc=no +- else +- lt_cv_archive_cmds_need_lc=yes +- fi +- allow_undefined_flag=$lt_save_allow_undefined_flag +- else +- cat conftest.err 1>&5 +- fi +- $RM conftest* +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +-$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } +- archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ++ then ++ archive_cmds_need_lc=no ++ else ++ archive_cmds_need_lc=yes ++ fi ++ allow_undefined_flag=$lt_save_allow_undefined_flag ++ else ++ cat conftest.err 1>&5 ++ fi ++ $RM conftest* ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5 ++$as_echo "$archive_cmds_need_lc" >&6; } + ;; + esac + fi +@@ -10296,23 +10378,16 @@ + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac +- case $host_os in +- mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; +- *) lt_sed_strip_eq="s,=/,/,g" ;; +- esac +- lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` +- case $lt_search_path_spec in +- *\;*) ++ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. +- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` +- ;; +- *) +- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` +- ;; +- esac ++ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= +@@ -10325,7 +10400,7 @@ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done +- lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' ++ lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' + BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; +@@ -10345,13 +10420,7 @@ + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } + }'` +- # AWK program above erroneously prepends '/' to C:/dos/paths +- # for these hosts. +- case $host_os in +- mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ +- $SED 's,/\([A-Za-z]:\),\1,g'` ;; +- esac +- sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` ++ sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` + else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + fi +@@ -10439,7 +10508,7 @@ + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. +- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ++ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; +@@ -10492,12 +10561,23 @@ + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' +- +- sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ++ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then ++ # It is most probably a Windows format PATH printed by ++ # mingw gcc, but we are running on Cygwin. Gcc prints its search ++ # path with ; separators, and with drive letters. We can handle the ++ # drive letters (cygwin fileutils understands them), so leave them, ++ # especially as we might pass files found there to a mingw objdump, ++ # which wouldn't understand a cygwinified path. Ahh. ++ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' +@@ -10597,19 +10677,6 @@ + hardcode_into_libs=yes + ;; + +-haiku*) +- version_type=linux +- need_lib_prefix=no +- need_version=no +- dynamic_linker="$host_os runtime_loader" +- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' +- soname_spec='${libname}${release}${shared_ext}$major' +- shlibpath_var=LIBRARY_PATH +- shlibpath_overrides_runpath=yes +- sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib' +- hardcode_into_libs=yes +- ;; +- + hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. +@@ -10652,10 +10719,8 @@ + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac +- # HP-UX runs *really* slowly unless shared libraries are mode 555, ... ++ # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' +- # or fails outright, so override atomically: +- install_override_mode=555 + ;; + + interix[3-9]*) +@@ -10722,17 +10787,12 @@ + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no +- + # Some binutils ld are patched to set DT_RUNPATH +- if test "${lt_cv_shlibpath_overrides_runpath+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- lt_cv_shlibpath_overrides_runpath=no +- save_LDFLAGS=$LDFLAGS +- save_libdir=$libdir +- eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ +- LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++ save_LDFLAGS=$LDFLAGS ++ save_libdir=$libdir ++ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ ++ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + + int +@@ -10745,17 +10805,13 @@ + _ACEOF + if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : +- lt_cv_shlibpath_overrides_runpath=yes ++ shlibpath_overrides_runpath=yes + fi + fi + rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +- LDFLAGS=$save_LDFLAGS +- libdir=$save_libdir +- +-fi +- +- shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath ++ LDFLAGS=$save_LDFLAGS ++ libdir=$save_libdir + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install +@@ -10764,7 +10820,7 @@ + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then +- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + +@@ -10777,6 +10833,18 @@ + dynamic_linker='GNU/Linux ld.so' + ;; + ++netbsdelf*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='NetBSD ld.elf_so' ++ ;; ++ + netbsd*) + version_type=sunos + need_lib_prefix=no +@@ -11067,11 +11135,6 @@ + + + +- +- +- +- +- + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 + $as_echo_n "checking how to hardcode library paths into programs... " >&6; } + hardcode_action= +@@ -11402,7 +11465,7 @@ + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11405 "configure" ++#line 11468 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11443,13 +11506,7 @@ + # endif + #endif + +-/* When -fvisbility=hidden is used, assume the code has been annotated +- correspondingly for the symbols needed. */ +-#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +-void fnord () __attribute__((visibility("default"))); +-#endif +- +-void fnord () { int i=42; } ++void fnord() { int i=42;} + int main () + { + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); +@@ -11458,11 +11515,7 @@ + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; +- else +- { +- if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; +- else puts (dlerror ()); +- } ++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else +@@ -11508,7 +11561,7 @@ + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11511 "configure" ++#line 11564 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11549,13 +11602,7 @@ + # endif + #endif + +-/* When -fvisbility=hidden is used, assume the code has been annotated +- correspondingly for the symbols needed. */ +-#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +-void fnord () __attribute__((visibility("default"))); +-#endif +- +-void fnord () { int i=42; } ++void fnord() { int i=42;} + int main () + { + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); +@@ -11564,11 +11611,7 @@ + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; +- else +- { +- if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; +- else puts (dlerror ()); +- } ++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else +@@ -12539,148 +12582,135 @@ + sed_quote_subst='$sed_quote_subst' + double_quote_subst='$double_quote_subst' + delay_variable_subst='$delay_variable_subst' +-SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +-Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +-SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +-ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +-AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' +-DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +-OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +-macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +-macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +-enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +-enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +-pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +-enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +-host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +-host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +-host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +-build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +-build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +-build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +-GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +-EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +-FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +-LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +-NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +-LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +-max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +-ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +-exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +-lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +-lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +-lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +-reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +-reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +-deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +-file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +-AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +-AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +-STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +-RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +-old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +-old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +-old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +-lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +-CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +-CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +-compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +-GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +-objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +-MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +-lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +-need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +-DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +-NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +-LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +-OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +-OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +-libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +-shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +-extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +-archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +-enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +-export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +-whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +-compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +-old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +-old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +-archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +-archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +-module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +-module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +-with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +-allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +-no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +-hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +-hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`' +-hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +-hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +-hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +-hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +-hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +-hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +-inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +-link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +-fix_srcfile_path='`$ECHO "$fix_srcfile_path" | $SED "$delay_single_quote_subst"`' +-always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +-export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +-exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +-include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +-prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +-file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +-variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +-need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +-need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +-version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +-runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +-shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +-shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +-libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +-library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +-soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +-install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +-postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +-postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +-finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +-finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +-hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +-sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +-sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +-hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +-enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +-enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +-enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +-old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +-striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' ++SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`' ++Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`' ++SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`' ++ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`' ++AS='`$ECHO "X$AS" | $Xsed -e "$delay_single_quote_subst"`' ++DLLTOOL='`$ECHO "X$DLLTOOL" | $Xsed -e "$delay_single_quote_subst"`' ++OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`' ++macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`' ++macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`' ++enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`' ++enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`' ++pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`' ++enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`' ++host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`' ++host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`' ++host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`' ++build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`' ++build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`' ++build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`' ++GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`' ++EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`' ++FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`' ++LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`' ++NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`' ++LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`' ++max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`' ++ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`' ++exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`' ++lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`' ++lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`' ++lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`' ++reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`' ++reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`' ++file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`' ++AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`' ++AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`' ++STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`' ++RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`' ++old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`' ++CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`' ++compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`' ++GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' ++objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`' ++MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`' ++need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`' ++DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`' ++NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`' ++LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`' ++OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`' ++OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`' ++libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`' ++shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`' ++enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`' ++export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`' ++allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' ++no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`' ++inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`' ++link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`' ++fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`' ++always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`' ++export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`' ++include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`' ++prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`' ++variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`' ++need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' ++need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`' ++version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`' ++runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`' ++libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`' ++library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`' ++soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`' ++postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`' ++sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`' ++sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`' ++old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`' ++striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`' + + LTCC='$LTCC' + LTCFLAGS='$LTCFLAGS' + compiler='$compiler_DEFAULT' + +-# A function that is used when there is no print builtin or printf. +-func_fallback_echo () +-{ +- eval 'cat <<_LTECHO_EOF +-\$1 +-_LTECHO_EOF' +-} +- + # Quote evaled strings. + for var in SED \ + SHELL \ + ECHO \ +-AS \ +-DLLTOOL \ +-OBJDUMP \ + GREP \ + EGREP \ + FGREP \ +@@ -12732,13 +12762,12 @@ + libname_spec \ + library_names_spec \ + soname_spec \ +-install_override_mode \ + finish_eval \ + old_striplib \ + striplib; do +- case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in ++ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) +- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ++ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" +@@ -12765,9 +12794,9 @@ + finish_cmds \ + sys_lib_search_path_spec \ + sys_lib_dlsearch_path_spec; do +- case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in ++ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) +- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ++ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" +@@ -12775,6 +12804,12 @@ + esac + done + ++# Fix-up fallback echo if it was mangled by the above quoting rules. ++case \$lt_ECHO in ++*'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\` ++ ;; ++esac ++ + ac_aux_dir='$ac_aux_dir' + xsi_shell='$xsi_shell' + lt_shell_append='$lt_shell_append' +@@ -13340,7 +13375,7 @@ + # NOTE: Changes made to this file will be lost: look at ltmain.sh. + # + # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +-# 2006, 2007, 2008, 2009 Free Software Foundation, Inc. ++# 2006, 2007, 2008 Free Software Foundation, Inc. + # Written by Gordon Matzigkeit, 1996 + # + # This file is part of GNU Libtool. +@@ -13381,17 +13416,17 @@ + # Shell to use when invoking shell scripts. + SHELL=$lt_SHELL + +-# An echo program that protects backslashes. ++# An echo program that does not interpret backslashes. + ECHO=$lt_ECHO + + # Assembler program. +-AS=$lt_AS ++AS=$AS + + # DLL creation program. +-DLLTOOL=$lt_DLLTOOL ++DLLTOOL=$DLLTOOL + + # Object dumper program. +-OBJDUMP=$lt_OBJDUMP ++OBJDUMP=$OBJDUMP + + # Which release of libtool.m4 was used? + macro_version=$macro_version +@@ -13452,6 +13487,10 @@ + # turn newlines into spaces. + NL2SP=$lt_lt_NL2SP + ++# How to create reloadable object files. ++reload_flag=$lt_reload_flag ++reload_cmds=$lt_reload_cmds ++ + # Method to check whether dependent libraries are shared objects. + deplibs_check_method=$lt_deplibs_check_method + +@@ -13470,9 +13509,6 @@ + old_postinstall_cmds=$lt_old_postinstall_cmds + old_postuninstall_cmds=$lt_old_postuninstall_cmds + +-# Whether to use a lock for old archive extraction. +-lock_old_archive_extraction=$lock_old_archive_extraction +- + # A C compiler. + LTCC=$lt_CC + +@@ -13556,9 +13592,6 @@ + # The coded name of the library, if different from the real name. + soname_spec=$lt_soname_spec + +-# Permission mode override for installation of shared libraries. +-install_override_mode=$lt_install_override_mode +- + # Command to use after installation of a shared archive. + postinstall_cmds=$lt_postinstall_cmds + +@@ -13598,10 +13631,6 @@ + # The linker used to build libraries. + LD=$lt_LD + +-# How to create reloadable object files. +-reload_flag=$lt_reload_flag +-reload_cmds=$lt_reload_cmds +- + # Commands used to build an old-style archive. + old_archive_cmds=$lt_old_archive_cmds + +@@ -13861,7 +13890,7 @@ + func_dirname () + { + # Extract subdirectory from the argument. +- func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` ++ func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else +@@ -13872,7 +13901,7 @@ + # func_basename file + func_basename () + { +- func_basename_result=`$ECHO "${1}" | $SED "$basename"` ++ func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` + } + + +@@ -13885,8 +13914,10 @@ + func_stripname () + { + case ${2} in +- .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; +- *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; ++ .*) func_stripname_result=`$ECHO "X${3}" \ ++ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; ++ *) func_stripname_result=`$ECHO "X${3}" \ ++ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; + esac + } + +@@ -13897,20 +13928,20 @@ + # func_opt_split + func_opt_split () + { +- func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"` +- func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"` ++ func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` ++ func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` + } + + # func_lo2o object + func_lo2o () + { +- func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` ++ func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` + } + + # func_xform libobj-or-source + func_xform () + { +- func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` ++ func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'` + } + + # func_arith arithmetic-term... +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/machine/i386/aclocal.m4 newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/machine/i386/aclocal.m4 +--- newlib-1.19.0/newlib/libc/sys/linux/machine/i386/aclocal.m4 2010-12-16 16:59:09.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/machine/i386/aclocal.m4 2013-10-21 15:44:33.000000000 -0400 +@@ -989,9 +989,10 @@ + AC_SUBST([am__untar]) + ]) # _AM_PROG_TAR + +-m4_include([../../../../../../libtool.m4]) +-m4_include([../../../../../../ltoptions.m4]) +-m4_include([../../../../../../ltsugar.m4]) +-m4_include([../../../../../../ltversion.m4]) + m4_include([../../../../../../lt~obsolete.m4]) + m4_include([../../../../../acinclude.m4]) ++m4_include([../../../../../libtool.m4]) ++m4_include([../../../../../ltoptions.m4]) ++m4_include([../../../../../ltsugar.m4]) ++m4_include([../../../../../ltversion.m4]) ++m4_include([../../../../../lt~obsolete.m4]) +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/machine/i386/configure newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/machine/i386/configure +--- newlib-1.19.0/newlib/libc/sys/linux/machine/i386/configure 2010-12-16 16:59:09.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/machine/i386/configure 2013-10-21 15:44:33.000000000 -0400 +@@ -171,15 +171,7 @@ + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +-test \$(( 1 + 1 )) = 2 || exit 1 +- +- test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( +- ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +- ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO +- ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO +- PATH=/empty FPATH=/empty; export PATH FPATH +- test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ +- || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" ++test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes + else +@@ -533,8 +525,304 @@ + # Sed expression to map a string onto a valid variable name. + as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + ++ ++ ++# Check that we are running under the correct shell. + SHELL=${CONFIG_SHELL-/bin/sh} + ++case X$lt_ECHO in ++X*--fallback-echo) ++ # Remove one level of quotation (which was required for Make). ++ ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` ++ ;; ++esac ++ ++ECHO=${lt_ECHO-echo} ++if test "X$1" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++elif test "X$1" = X--fallback-echo; then ++ # Avoid inline document here, it may be left over ++ : ++elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then ++ # Yippee, $ECHO works! ++ : ++else ++ # Restart under the correct shell. ++ exec $SHELL "$0" --no-reexec ${1+"$@"} ++fi ++ ++if test "X$1" = X--fallback-echo; then ++ # used as fallback echo ++ shift ++ cat <<_LT_EOF ++$* ++_LT_EOF ++ exit 0 ++fi ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++if test -z "$lt_ECHO"; then ++ if test "X${echo_test_string+set}" != Xset; then ++ # find a string as large as possible, as long as the shell can cope with it ++ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do ++ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... ++ if { echo_test_string=`eval $cmd`; } 2>/dev/null && ++ { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null ++ then ++ break ++ fi ++ done ++ fi ++ ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ : ++ else ++ # The Solaris, AIX, and Digital Unix default echo programs unquote ++ # backslashes. This makes it impossible to quote backslashes using ++ # echo "$something" | sed 's/\\/\\\\/g' ++ # ++ # So, first we look for a working echo in the user's PATH. ++ ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for dir in $PATH /usr/ucb; do ++ IFS="$lt_save_ifs" ++ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && ++ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$dir/echo" ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ if test "X$ECHO" = Xecho; then ++ # We didn't find a better echo, so look for alternatives. ++ if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # This shell has a builtin print -r that does the trick. ++ ECHO='print -r' ++ elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && ++ test "X$CONFIG_SHELL" != X/bin/ksh; then ++ # If we have ksh, try running configure again with it. ++ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} ++ export ORIGINAL_CONFIG_SHELL ++ CONFIG_SHELL=/bin/ksh ++ export CONFIG_SHELL ++ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} ++ else ++ # Try using printf. ++ ECHO='printf %s\n' ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # Cool, printf works ++ : ++ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL ++ export CONFIG_SHELL ++ SHELL="$CONFIG_SHELL" ++ export SHELL ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ else ++ # maybe with a smaller string... ++ prev=: ++ ++ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do ++ if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null ++ then ++ break ++ fi ++ prev="$cmd" ++ done ++ ++ if test "$prev" != 'sed 50q "$0"'; then ++ echo_test_string=`eval $prev` ++ export echo_test_string ++ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} ++ else ++ # Oops. We lost completely, so just stick with echo. ++ ECHO=echo ++ fi ++ fi ++ fi ++ fi ++ fi ++fi ++ ++# Copy echo and quote the copy suitably for passing to libtool from ++# the Makefile, instead of quoting the original, which is used later. ++lt_ECHO=$ECHO ++if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then ++ lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" ++fi ++ ++ ++ ++ ++ ++# Check that we are running under the correct shell. ++SHELL=${CONFIG_SHELL-/bin/sh} ++ ++case X$lt_ECHO in ++X*--fallback-echo) ++ # Remove one level of quotation (which was required for Make). ++ ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` ++ ;; ++esac ++ ++ECHO=${lt_ECHO-echo} ++if test "X$1" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++elif test "X$1" = X--fallback-echo; then ++ # Avoid inline document here, it may be left over ++ : ++elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then ++ # Yippee, $ECHO works! ++ : ++else ++ # Restart under the correct shell. ++ exec $SHELL "$0" --no-reexec ${1+"$@"} ++fi ++ ++if test "X$1" = X--fallback-echo; then ++ # used as fallback echo ++ shift ++ cat <<_LT_EOF ++$* ++_LT_EOF ++ exit 0 ++fi ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++if test -z "$lt_ECHO"; then ++ if test "X${echo_test_string+set}" != Xset; then ++ # find a string as large as possible, as long as the shell can cope with it ++ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do ++ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... ++ if { echo_test_string=`eval $cmd`; } 2>/dev/null && ++ { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null ++ then ++ break ++ fi ++ done ++ fi ++ ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ : ++ else ++ # The Solaris, AIX, and Digital Unix default echo programs unquote ++ # backslashes. This makes it impossible to quote backslashes using ++ # echo "$something" | sed 's/\\/\\\\/g' ++ # ++ # So, first we look for a working echo in the user's PATH. ++ ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for dir in $PATH /usr/ucb; do ++ IFS="$lt_save_ifs" ++ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && ++ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$dir/echo" ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ if test "X$ECHO" = Xecho; then ++ # We didn't find a better echo, so look for alternatives. ++ if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # This shell has a builtin print -r that does the trick. ++ ECHO='print -r' ++ elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && ++ test "X$CONFIG_SHELL" != X/bin/ksh; then ++ # If we have ksh, try running configure again with it. ++ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} ++ export ORIGINAL_CONFIG_SHELL ++ CONFIG_SHELL=/bin/ksh ++ export CONFIG_SHELL ++ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} ++ else ++ # Try using printf. ++ ECHO='printf %s\n' ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # Cool, printf works ++ : ++ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL ++ export CONFIG_SHELL ++ SHELL="$CONFIG_SHELL" ++ export SHELL ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ else ++ # maybe with a smaller string... ++ prev=: ++ ++ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do ++ if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null ++ then ++ break ++ fi ++ prev="$cmd" ++ done ++ ++ if test "$prev" != 'sed 50q "$0"'; then ++ echo_test_string=`eval $prev` ++ export echo_test_string ++ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} ++ else ++ # Oops. We lost completely, so just stick with echo. ++ ECHO=echo ++ fi ++ fi ++ fi ++ fi ++ fi ++fi ++ ++# Copy echo and quote the copy suitably for passing to libtool from ++# the Makefile, instead of quoting the original, which is used later. ++lt_ECHO=$ECHO ++if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then ++ lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" ++fi ++ ++ ++ + + test -n "$DJDIR" || exec 7<&0 &1 +@@ -626,6 +914,7 @@ + LIBTOOL + OBJDUMP + DLLTOOL ++lt_ECHO + SED + sys_dir + machine_dir +@@ -3795,45 +4084,6 @@ + + + +-ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +-ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +-ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +-$as_echo_n "checking how to print strings... " >&6; } +-# Test print first, because it will be a builtin if present. +-if test "X`print -r -- -n 2>/dev/null`" = X-n && \ +- test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then +- ECHO='print -r --' +-elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then +- ECHO='printf %s\n' +-else +- # Use this function as a fallback that always works. +- func_fallback_echo () +- { +- eval 'cat <<_LTECHO_EOF +-$1 +-_LTECHO_EOF' +- } +- ECHO='func_fallback_echo' +-fi +- +-# func_echo_all arg... +-# Invoke $ECHO with all args, space-separated. +-func_echo_all () +-{ +- $ECHO "" +-} +- +-case "$ECHO" in +- printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +-$as_echo "printf" >&6; } ;; +- print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +-$as_echo "print -r" >&6; } ;; +- *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +-$as_echo "cat" >&6; } ;; +-esac +- + + + +@@ -3893,7 +4143,7 @@ + enable_win32_dll=yes + + case $host in +-*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) ++*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. + set dummy ${ac_tool_prefix}as; ac_word=$2 +@@ -4201,8 +4451,8 @@ + + + +-macro_version='2.2.7a' +-macro_revision='1.3134' ++macro_version='2.2.6b' ++macro_revision='1.3017' + + + +@@ -4218,23 +4468,6 @@ + + ltmain="$ac_aux_dir/ltmain.sh" + +-# Backslashify metacharacters that are still active within +-# double-quoted strings. +-sed_quote_subst='s/\(["`$\\]\)/\\\1/g' +- +-# Same as above, but do not quote variable references. +-double_quote_subst='s/\(["`\\]\)/\\\1/g' +- +-# Sed substitution to delay expansion of an escaped shell variable in a +-# double_quote_subst'ed string. +-delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' +- +-# Sed substitution to delay expansion of an escaped single quote. +-delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' +- +-# Sed substitution to avoid accidental globbing in evaled expressions +-no_glob_subst='s/\*/\\\*/g' +- + ac_ext=c + ac_cpp='$CPP $CPPFLAGS' + ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +@@ -5536,11 +5769,8 @@ + NM="$lt_cv_path_NM" + else + # Didn't find any BSD compatible name lister, look for dumpbin. +- if test -n "$DUMPBIN"; then : +- # Let the user override the test. +- else +- if test -n "$ac_tool_prefix"; then +- for ac_prog in dumpbin "link -dump" ++ if test -n "$ac_tool_prefix"; then ++ for ac_prog in "dumpbin -symbols" "link -dump -symbols" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. + set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +@@ -5584,7 +5814,7 @@ + fi + if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN +- for ac_prog in dumpbin "link -dump" ++ for ac_prog in "dumpbin -symbols" "link -dump -symbols" + do + # Extract the first word of "$ac_prog", so it can be a program name with args. + set dummy $ac_prog; ac_word=$2 +@@ -5639,15 +5869,6 @@ + fi + fi + +- case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in +- *COFF*) +- DUMPBIN="$DUMPBIN -symbols" +- ;; +- *) +- DUMPBIN=: +- ;; +- esac +- fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" +@@ -5667,13 +5888,13 @@ + else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext +- (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) ++ (eval echo "\"\$as_me:5891: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 +- (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) ++ (eval echo "\"\$as_me:5894: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 +- (eval echo "\"\$as_me:$LINENO: output\"" >&5) ++ (eval echo "\"\$as_me:5897: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" +@@ -5730,11 +5951,6 @@ + lt_cv_sys_max_cmd_len=8192; + ;; + +- mint*) +- # On MiNT this can take a long time and run out of memory. +- lt_cv_sys_max_cmd_len=8192; +- ;; +- + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. +@@ -5799,8 +6015,8 @@ + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. +- while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ +- = "X$teststring$teststring"; } >/dev/null 2>&1 && ++ while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ ++ = "XX$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` +@@ -6068,8 +6284,7 @@ + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. +- # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. +- if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then ++ if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else +@@ -6078,7 +6293,7 @@ + fi + ;; + +-cegcc*) ++cegcc) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' +@@ -6108,10 +6323,6 @@ + lt_cv_deplibs_check_method=pass_all + ;; + +-haiku*) +- lt_cv_deplibs_check_method=pass_all +- ;; +- + hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in +@@ -6120,11 +6331,11 @@ + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) +- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) +- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac +@@ -6150,7 +6361,7 @@ + lt_cv_deplibs_check_method=pass_all + ;; + +-netbsd*) ++netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else +@@ -6562,18 +6773,6 @@ + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" + fi + +-case $host_os in +- darwin*) +- lock_old_archive_extraction=yes ;; +- *) +- lock_old_archive_extraction=no ;; +-esac +- +- +- +- +- +- + + + +@@ -6743,8 +6942,8 @@ + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm +- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 +- (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5 ++ (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then +@@ -6898,7 +7097,7 @@ + ;; + *-*-irix6*) + # Find out which ABI we are using. +- echo '#line '$LINENO' "configure"' > conftest.$ac_ext ++ echo '#line 7100 "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? +@@ -7610,36 +7809,6 @@ + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 + $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +-$as_echo_n "checking for -force_load linker flag... " >&6; } +-if test "${lt_cv_ld_force_load+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- lt_cv_ld_force_load=no +- cat > conftest.c << _LT_EOF +-int forced_loaded() { return 2;} +-_LT_EOF +- echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 +- $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 +- echo "$AR cru libconftest.a conftest.o" >&5 +- $AR cru libconftest.a conftest.o 2>&5 +- cat > conftest.c << _LT_EOF +-int main() { return 0;} +-_LT_EOF +- echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 +- $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err +- _lt_result=$? +- if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then +- lt_cv_ld_force_load=yes +- else +- cat conftest.err >&5 +- fi +- rm -f conftest.err libconftest.a conftest conftest.c +- rm -rf conftest.dSYM +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +-$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; +@@ -7667,7 +7836,7 @@ + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi +- if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then ++ if test "$DSYMUTIL" != ":"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= +@@ -7958,8 +8127,6 @@ + + + +- +- + # Set options + + +@@ -8110,7 +8277,6 @@ + + + +- + test -z "$LN_S" && LN_S="ln -s" + + +@@ -8160,6 +8326,13 @@ + + + ++ ++ ++ ++ ++ ++ ++ + case $host_os in + aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some +@@ -8172,6 +8345,23 @@ + ;; + esac + ++# Sed substitution that helps us do robust quoting. It backslashifies ++# metacharacters that are still active within double-quoted strings. ++sed_quote_subst='s/\(["`$\\]\)/\\\1/g' ++ ++# Same as above, but do not quote variable references. ++double_quote_subst='s/\(["`\\]\)/\\\1/g' ++ ++# Sed substitution to delay expansion of an escaped shell variable in a ++# double_quote_subst'ed string. ++delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' ++ ++# Sed substitution to delay expansion of an escaped single quote. ++delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' ++ ++# Sed substitution to avoid accidental globbing in evaled expressions ++no_glob_subst='s/\*/\\\*/g' ++ + # Global variables: + ofile=libtool + can_build_shared=yes +@@ -8200,7 +8390,7 @@ + *) break;; + esac + done +-cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ++cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + + # Only perform the check for file, if the check method requires it +@@ -8409,12 +8599,7 @@ + lt_prog_compiler_no_builtin_flag= + + if test "$GCC" = yes; then +- case $cc_basename in +- nvcc*) +- lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; +- *) +- lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; +- esac ++ lt_prog_compiler_no_builtin_flag=' -fno-builtin' + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 + $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +@@ -8434,15 +8619,15 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:8622: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:8626: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes +@@ -8520,12 +8705,6 @@ + lt_prog_compiler_pic='-fno-common' + ;; + +- haiku*) +- # PIC is the default for Haiku. +- # The "-static" flag exists, but is broken. +- lt_prog_compiler_static= +- ;; +- + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag +@@ -8568,13 +8747,6 @@ + lt_prog_compiler_pic='-fPIC' + ;; + esac +- +- case $cc_basename in +- nvcc*) # Cuda Compiler Driver 2.2 +- lt_prog_compiler_wl='-Xlinker ' +- lt_prog_compiler_pic='-Xcompiler -fPIC' +- ;; +- esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in +@@ -8637,7 +8809,7 @@ + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; +- pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) ++ pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' +@@ -8649,26 +8821,26 @@ + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; +- xl* | bgxl* | bgf* | mpixl*) +- # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene ++ xl*) ++ # IBM XL C 8.0/Fortran 10.1 on PPC + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in +- *Sun\ F* | *Sun*Fortran*) +- # Sun Fortran 8.3 passes all unrecognized flags to the linker +- lt_prog_compiler_pic='-KPIC' +- lt_prog_compiler_static='-Bstatic' +- lt_prog_compiler_wl='' +- ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; ++ *Sun\ F*) ++ # Sun Fortran 8.3 passes all unrecognized flags to the linker ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ lt_prog_compiler_wl='' ++ ;; + esac + ;; + esac +@@ -8786,15 +8958,15 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:8961: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:8965: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes +@@ -8842,7 +9014,7 @@ + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 +- $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp ++ $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes +@@ -8891,16 +9063,16 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:9066: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:9070: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes +@@ -8946,16 +9118,16 @@ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` +- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval echo "\"\$as_me:9121: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ echo "$as_me:9125: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings +- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes +@@ -9065,36 +9237,13 @@ + openbsd*) + with_gnu_ld=no + ;; ++ linux* | k*bsd*-gnu) ++ link_all_deplibs=no ++ ;; + esac + + ld_shlibs=yes +- +- # On some targets, GNU ld is compatible enough with the native linker +- # that we're better off using the native interface for both. +- lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then +- case $host_os in +- aix*) +- # The AIX port of GNU ld has always aspired to compatibility +- # with the native linker. However, as the warning in the GNU ld +- # block says, versions before 2.19.5* couldn't really create working +- # shared libraries, regardless of the interface used. +- case `$LD -v 2>&1` in +- *\ \(GNU\ Binutils\)\ 2.19.5*) ;; +- *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; +- *\ \(GNU\ Binutils\)\ [3-9]*) ;; +- *) +- lt_use_gnu_ld_interface=yes +- ;; +- esac +- ;; +- *) +- lt_use_gnu_ld_interface=yes +- ;; +- esac +- fi +- +- if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + +@@ -9128,12 +9277,11 @@ + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +-*** Warning: the GNU linker, at least up to release 2.19, is reported ++*** Warning: the GNU linker, at least up to release 2.9.1, is reported + *** to be unable to reliably create shared libraries on AIX. + *** Therefore, libtool is disabling shared libraries support. If you +-*** really care for shared libraries, you may want to install binutils +-*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +-*** You will then need to restart the configuration process. ++*** really care for shared libraries, you may want to modify your PATH ++*** so that a non-GNU linker is found, and then restart. + + _LT_EOF + fi +@@ -9169,7 +9317,6 @@ + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' +- export_dynamic_flag_spec='${wl}--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes +@@ -9191,11 +9338,6 @@ + fi + ;; + +- haiku*) +- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' +- link_all_deplibs=yes +- ;; +- + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no +@@ -9225,12 +9367,11 @@ + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler +- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; +- pgf77* | pgf90* | pgf95* | pgfortran*) +- # Portland Group f77 and f90 compilers +- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers ++ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; +@@ -9241,17 +9382,13 @@ + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; +- xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) ++ xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; +- nvcc*) # Cuda Compiler Driver 2.2 +- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' +- compiler_needs_object=yes +- ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 +- whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 +@@ -9267,7 +9404,7 @@ + fi + + case $cc_basename in +- xlf* | bgf* | bgxlf* | mpixlf*) ++ xlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec= +@@ -9286,7 +9423,7 @@ + fi + ;; + +- netbsd*) ++ netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= +@@ -9398,10 +9535,8 @@ + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm +- # Also, AIX nm treats weak defined symbols like other global +- # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then +- export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' ++ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi +@@ -9463,6 +9598,7 @@ + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi ++ link_all_deplibs=no + else + # not using gcc + if test "$host_cpu" = ia64; then +@@ -9519,7 +9655,7 @@ + if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" +- archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" ++ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' +@@ -9563,13 +9699,8 @@ + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' +- if test "$with_gnu_ld" = yes; then +- # We only use this code for GNU lds that support --whole-archive. +- whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' +- else +- # Exported symbols can be pulled into shared objects from archives +- whole_archive_flag_spec='$convenience' +- fi ++ # Exported symbols can be pulled into shared objects from archives ++ whole_archive_flag_spec='$convenience' + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' +@@ -9608,7 +9739,7 @@ + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. +- archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' ++ archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. +@@ -9624,11 +9755,7 @@ + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported +- if test "$lt_cv_ld_force_load" = "yes"; then +- whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' +- else +- whole_archive_flag_spec='' +- fi ++ whole_archive_flag_spec='' + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in +@@ -9636,7 +9763,7 @@ + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then +- output_verbose_link_cmd=func_echo_all ++ output_verbose_link_cmd=echo + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +@@ -9702,7 +9829,7 @@ + ;; + + hpux10*) +- if test "$GCC" = yes && test "$with_gnu_ld" = no; then ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +@@ -9721,7 +9848,7 @@ + ;; + + hpux11*) +- if test "$GCC" = yes && test "$with_gnu_ld" = no; then ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' +@@ -9742,46 +9869,7 @@ + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) +- +- # Older versions of the 11.00 compiler do not understand -b yet +- # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +-$as_echo_n "checking if $CC understands -b... " >&6; } +-if test "${lt_cv_prog_compiler__b+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- lt_cv_prog_compiler__b=no +- save_LDFLAGS="$LDFLAGS" +- LDFLAGS="$LDFLAGS -b" +- echo "$lt_simple_link_test_code" > conftest.$ac_ext +- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then +- # The linker can only warn and ignore the option if not recognized +- # So say no if there are warnings +- if test -s conftest.err; then +- # Append any errors to the config.log. +- cat conftest.err 1>&5 +- $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp +- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 +- if diff conftest.exp conftest.er2 >/dev/null; then +- lt_cv_prog_compiler__b=yes +- fi +- else +- lt_cv_prog_compiler__b=yes +- fi +- fi +- $RM -r conftest* +- LDFLAGS="$save_LDFLAGS" +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +-$as_echo "$lt_cv_prog_compiler__b" >&6; } +- +-if test x"$lt_cv_prog_compiler__b" = xyes; then +- archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +-else +- archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +-fi +- ++ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi +@@ -9809,7 +9897,7 @@ + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then +- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. +@@ -9820,15 +9908,15 @@ + int foo(void) {} + _ACEOF + if ac_fn_c_try_link "$LINENO"; then : +- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + + fi + rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + else +- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' +- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' +@@ -9837,7 +9925,7 @@ + link_all_deplibs=yes + ;; + +- netbsd*) ++ netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else +@@ -9890,17 +9978,17 @@ + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported +- archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' ++ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' +@@ -9910,13 +9998,13 @@ + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' +- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ +- $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' ++ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' +@@ -10119,50 +10207,44 @@ + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 + $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +-if test "${lt_cv_archive_cmds_need_lc+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- $RM conftest* +- echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ $RM conftest* ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext + +- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then +- soname=conftest +- lib=conftest +- libobjs=conftest.$ac_objext +- deplibs= +- wl=$lt_prog_compiler_wl +- pic_flag=$lt_prog_compiler_pic +- compiler_flags=-v +- linker_flags=-v +- verstring= +- output_objdir=. +- libname=conftest +- lt_save_allow_undefined_flag=$allow_undefined_flag +- allow_undefined_flag= +- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 ++ soname=conftest ++ lib=conftest ++ libobjs=conftest.$ac_objext ++ deplibs= ++ wl=$lt_prog_compiler_wl ++ pic_flag=$lt_prog_compiler_pic ++ compiler_flags=-v ++ linker_flags=-v ++ verstring= ++ output_objdir=. ++ libname=conftest ++ lt_save_allow_undefined_flag=$allow_undefined_flag ++ allow_undefined_flag= ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +- then +- lt_cv_archive_cmds_need_lc=no +- else +- lt_cv_archive_cmds_need_lc=yes +- fi +- allow_undefined_flag=$lt_save_allow_undefined_flag +- else +- cat conftest.err 1>&5 +- fi +- $RM conftest* +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +-$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } +- archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ++ then ++ archive_cmds_need_lc=no ++ else ++ archive_cmds_need_lc=yes ++ fi ++ allow_undefined_flag=$lt_save_allow_undefined_flag ++ else ++ cat conftest.err 1>&5 ++ fi ++ $RM conftest* ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5 ++$as_echo "$archive_cmds_need_lc" >&6; } + ;; + esac + fi +@@ -10333,23 +10415,16 @@ + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac +- case $host_os in +- mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; +- *) lt_sed_strip_eq="s,=/,/,g" ;; +- esac +- lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` +- case $lt_search_path_spec in +- *\;*) ++ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. +- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` +- ;; +- *) +- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` +- ;; +- esac ++ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= +@@ -10362,7 +10437,7 @@ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done +- lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' ++ lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' + BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; +@@ -10382,13 +10457,7 @@ + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } + }'` +- # AWK program above erroneously prepends '/' to C:/dos/paths +- # for these hosts. +- case $host_os in +- mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ +- $SED 's,/\([A-Za-z]:\),\1,g'` ;; +- esac +- sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` ++ sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` + else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + fi +@@ -10476,7 +10545,7 @@ + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. +- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ++ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; +@@ -10529,12 +10598,23 @@ + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' +- +- sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ++ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then ++ # It is most probably a Windows format PATH printed by ++ # mingw gcc, but we are running on Cygwin. Gcc prints its search ++ # path with ; separators, and with drive letters. We can handle the ++ # drive letters (cygwin fileutils understands them), so leave them, ++ # especially as we might pass files found there to a mingw objdump, ++ # which wouldn't understand a cygwinified path. Ahh. ++ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' +@@ -10634,19 +10714,6 @@ + hardcode_into_libs=yes + ;; + +-haiku*) +- version_type=linux +- need_lib_prefix=no +- need_version=no +- dynamic_linker="$host_os runtime_loader" +- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' +- soname_spec='${libname}${release}${shared_ext}$major' +- shlibpath_var=LIBRARY_PATH +- shlibpath_overrides_runpath=yes +- sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib' +- hardcode_into_libs=yes +- ;; +- + hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. +@@ -10689,10 +10756,8 @@ + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac +- # HP-UX runs *really* slowly unless shared libraries are mode 555, ... ++ # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' +- # or fails outright, so override atomically: +- install_override_mode=555 + ;; + + interix[3-9]*) +@@ -10759,17 +10824,12 @@ + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no +- + # Some binutils ld are patched to set DT_RUNPATH +- if test "${lt_cv_shlibpath_overrides_runpath+set}" = set; then : +- $as_echo_n "(cached) " >&6 +-else +- lt_cv_shlibpath_overrides_runpath=no +- save_LDFLAGS=$LDFLAGS +- save_libdir=$libdir +- eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ +- LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++ save_LDFLAGS=$LDFLAGS ++ save_libdir=$libdir ++ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ ++ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + + int +@@ -10782,17 +10842,13 @@ + _ACEOF + if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : +- lt_cv_shlibpath_overrides_runpath=yes ++ shlibpath_overrides_runpath=yes + fi + fi + rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +- LDFLAGS=$save_LDFLAGS +- libdir=$save_libdir +- +-fi +- +- shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath ++ LDFLAGS=$save_LDFLAGS ++ libdir=$save_libdir + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install +@@ -10801,7 +10857,7 @@ + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then +- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + +@@ -10814,6 +10870,18 @@ + dynamic_linker='GNU/Linux ld.so' + ;; + ++netbsdelf*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='NetBSD ld.elf_so' ++ ;; ++ + netbsd*) + version_type=sunos + need_lib_prefix=no +@@ -11104,11 +11172,6 @@ + + + +- +- +- +- +- + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 + $as_echo_n "checking how to hardcode library paths into programs... " >&6; } + hardcode_action= +@@ -11439,7 +11502,7 @@ + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11442 "configure" ++#line 11505 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11480,13 +11543,7 @@ + # endif + #endif + +-/* When -fvisbility=hidden is used, assume the code has been annotated +- correspondingly for the symbols needed. */ +-#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +-void fnord () __attribute__((visibility("default"))); +-#endif +- +-void fnord () { int i=42; } ++void fnord() { int i=42;} + int main () + { + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); +@@ -11495,11 +11552,7 @@ + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; +- else +- { +- if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; +- else puts (dlerror ()); +- } ++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else +@@ -11545,7 +11598,7 @@ + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11548 "configure" ++#line 11601 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11586,13 +11639,7 @@ + # endif + #endif + +-/* When -fvisbility=hidden is used, assume the code has been annotated +- correspondingly for the symbols needed. */ +-#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +-void fnord () __attribute__((visibility("default"))); +-#endif +- +-void fnord () { int i=42; } ++void fnord() { int i=42;} + int main () + { + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); +@@ -11601,11 +11648,7 @@ + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; +- else +- { +- if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; +- else puts (dlerror ()); +- } ++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else +@@ -12548,148 +12591,135 @@ + sed_quote_subst='$sed_quote_subst' + double_quote_subst='$double_quote_subst' + delay_variable_subst='$delay_variable_subst' +-SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +-Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +-SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +-ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +-AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' +-DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +-OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +-macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +-macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +-enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +-enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +-pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +-enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +-host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +-host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +-host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +-build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +-build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +-build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +-GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +-EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +-FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +-LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +-NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +-LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +-max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +-ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +-exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +-lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +-lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +-lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +-reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +-reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +-deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +-file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +-AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +-AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +-STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +-RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +-old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +-old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +-old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +-lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +-CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +-CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +-compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +-GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +-objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +-MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +-lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +-lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +-need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +-DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +-NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +-LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +-OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +-OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +-libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +-shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +-extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +-archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +-enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +-export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +-whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +-compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +-old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +-old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +-archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +-archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +-module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +-module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +-with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +-allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +-no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +-hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +-hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`' +-hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +-hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +-hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +-hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +-hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +-hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +-inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +-link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +-fix_srcfile_path='`$ECHO "$fix_srcfile_path" | $SED "$delay_single_quote_subst"`' +-always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +-export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +-exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +-include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +-prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +-file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +-variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +-need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +-need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +-version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +-runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +-shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +-shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +-libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +-library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +-soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +-install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +-postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +-postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +-finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +-finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +-hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +-sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +-sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +-hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +-enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +-enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +-enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +-old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +-striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' ++SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`' ++Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`' ++SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`' ++ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`' ++AS='`$ECHO "X$AS" | $Xsed -e "$delay_single_quote_subst"`' ++DLLTOOL='`$ECHO "X$DLLTOOL" | $Xsed -e "$delay_single_quote_subst"`' ++OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`' ++macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`' ++macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`' ++enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`' ++enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`' ++pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`' ++enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`' ++host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`' ++host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`' ++host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`' ++build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`' ++build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`' ++build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`' ++GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`' ++EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`' ++FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`' ++LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`' ++NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`' ++LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`' ++max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`' ++ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`' ++exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`' ++lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`' ++lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`' ++lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`' ++reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`' ++reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`' ++file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`' ++AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`' ++AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`' ++STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`' ++RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`' ++old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`' ++CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`' ++compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`' ++GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' ++objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`' ++MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`' ++need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`' ++DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`' ++NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`' ++LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`' ++OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`' ++OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`' ++libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`' ++shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`' ++enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`' ++export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`' ++allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' ++no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`' ++inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`' ++link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`' ++fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`' ++always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`' ++export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`' ++include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`' ++prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`' ++variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`' ++need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' ++need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`' ++version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`' ++runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`' ++libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`' ++library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`' ++soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`' ++postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`' ++sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`' ++sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`' ++old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`' ++striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`' + + LTCC='$LTCC' + LTCFLAGS='$LTCFLAGS' + compiler='$compiler_DEFAULT' + +-# A function that is used when there is no print builtin or printf. +-func_fallback_echo () +-{ +- eval 'cat <<_LTECHO_EOF +-\$1 +-_LTECHO_EOF' +-} +- + # Quote evaled strings. + for var in SED \ + SHELL \ + ECHO \ +-AS \ +-DLLTOOL \ +-OBJDUMP \ + GREP \ + EGREP \ + FGREP \ +@@ -12741,13 +12771,12 @@ + libname_spec \ + library_names_spec \ + soname_spec \ +-install_override_mode \ + finish_eval \ + old_striplib \ + striplib; do +- case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in ++ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) +- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ++ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" +@@ -12774,9 +12803,9 @@ + finish_cmds \ + sys_lib_search_path_spec \ + sys_lib_dlsearch_path_spec; do +- case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in ++ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) +- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ++ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" +@@ -12784,6 +12813,12 @@ + esac + done + ++# Fix-up fallback echo if it was mangled by the above quoting rules. ++case \$lt_ECHO in ++*'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\` ++ ;; ++esac ++ + ac_aux_dir='$ac_aux_dir' + xsi_shell='$xsi_shell' + lt_shell_append='$lt_shell_append' +@@ -13349,7 +13384,7 @@ + # NOTE: Changes made to this file will be lost: look at ltmain.sh. + # + # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +-# 2006, 2007, 2008, 2009 Free Software Foundation, Inc. ++# 2006, 2007, 2008 Free Software Foundation, Inc. + # Written by Gordon Matzigkeit, 1996 + # + # This file is part of GNU Libtool. +@@ -13390,17 +13425,17 @@ + # Shell to use when invoking shell scripts. + SHELL=$lt_SHELL + +-# An echo program that protects backslashes. ++# An echo program that does not interpret backslashes. + ECHO=$lt_ECHO + + # Assembler program. +-AS=$lt_AS ++AS=$AS + + # DLL creation program. +-DLLTOOL=$lt_DLLTOOL ++DLLTOOL=$DLLTOOL + + # Object dumper program. +-OBJDUMP=$lt_OBJDUMP ++OBJDUMP=$OBJDUMP + + # Which release of libtool.m4 was used? + macro_version=$macro_version +@@ -13461,6 +13496,10 @@ + # turn newlines into spaces. + NL2SP=$lt_lt_NL2SP + ++# How to create reloadable object files. ++reload_flag=$lt_reload_flag ++reload_cmds=$lt_reload_cmds ++ + # Method to check whether dependent libraries are shared objects. + deplibs_check_method=$lt_deplibs_check_method + +@@ -13479,9 +13518,6 @@ + old_postinstall_cmds=$lt_old_postinstall_cmds + old_postuninstall_cmds=$lt_old_postuninstall_cmds + +-# Whether to use a lock for old archive extraction. +-lock_old_archive_extraction=$lock_old_archive_extraction +- + # A C compiler. + LTCC=$lt_CC + +@@ -13565,9 +13601,6 @@ + # The coded name of the library, if different from the real name. + soname_spec=$lt_soname_spec + +-# Permission mode override for installation of shared libraries. +-install_override_mode=$lt_install_override_mode +- + # Command to use after installation of a shared archive. + postinstall_cmds=$lt_postinstall_cmds + +@@ -13607,10 +13640,6 @@ + # The linker used to build libraries. + LD=$lt_LD + +-# How to create reloadable object files. +-reload_flag=$lt_reload_flag +-reload_cmds=$lt_reload_cmds +- + # Commands used to build an old-style archive. + old_archive_cmds=$lt_old_archive_cmds + +@@ -13870,7 +13899,7 @@ + func_dirname () + { + # Extract subdirectory from the argument. +- func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` ++ func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else +@@ -13881,7 +13910,7 @@ + # func_basename file + func_basename () + { +- func_basename_result=`$ECHO "${1}" | $SED "$basename"` ++ func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` + } + + +@@ -13894,8 +13923,10 @@ + func_stripname () + { + case ${2} in +- .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; +- *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; ++ .*) func_stripname_result=`$ECHO "X${3}" \ ++ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; ++ *) func_stripname_result=`$ECHO "X${3}" \ ++ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; + esac + } + +@@ -13906,20 +13937,20 @@ + # func_opt_split + func_opt_split () + { +- func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"` +- func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"` ++ func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` ++ func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` + } + + # func_lo2o object + func_lo2o () + { +- func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` ++ func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` + } + + # func_xform libobj-or-source + func_xform () + { +- func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` ++ func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'` + } + + # func_arith arithmetic-term... +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/machine/i386/Makefile.in newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/machine/i386/Makefile.in +--- newlib-1.19.0/newlib/libc/sys/linux/machine/i386/Makefile.in 2010-12-16 16:59:09.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/machine/i386/Makefile.in 2013-10-21 15:44:33.000000000 -0400 +@@ -42,12 +42,13 @@ + $(srcdir)/../../../../../../mkinstalldirs + subdir = . + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +-am__aclocal_m4_deps = $(top_srcdir)/../../../../../../libtool.m4 \ +- $(top_srcdir)/../../../../../../ltoptions.m4 \ +- $(top_srcdir)/../../../../../../ltsugar.m4 \ +- $(top_srcdir)/../../../../../../ltversion.m4 \ +- $(top_srcdir)/../../../../../../lt~obsolete.m4 \ ++am__aclocal_m4_deps = $(top_srcdir)/../../../../../../lt~obsolete.m4 \ + $(top_srcdir)/../../../../../acinclude.m4 \ ++ $(top_srcdir)/../../../../../libtool.m4 \ ++ $(top_srcdir)/../../../../../ltoptions.m4 \ ++ $(top_srcdir)/../../../../../ltsugar.m4 \ ++ $(top_srcdir)/../../../../../ltversion.m4 \ ++ $(top_srcdir)/../../../../../lt~obsolete.m4 \ + $(top_srcdir)/configure.in + am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +@@ -202,6 +203,7 @@ + localedir = @localedir@ + localstatedir = @localstatedir@ + lpfx = @lpfx@ ++lt_ECHO = @lt_ECHO@ + machine_dir = @machine_dir@ + mandir = @mandir@ + mkdir_p = @mkdir_p@ +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/machine/Makefile.in newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/machine/Makefile.in +--- newlib-1.19.0/newlib/libc/sys/linux/machine/Makefile.in 2010-12-16 16:59:09.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/machine/Makefile.in 2013-10-21 15:44:33.000000000 -0400 +@@ -39,12 +39,13 @@ + $(top_srcdir)/configure $(am__configure_deps) \ + $(srcdir)/../../../../../mkinstalldirs + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +-am__aclocal_m4_deps = $(top_srcdir)/../../../../../libtool.m4 \ +- $(top_srcdir)/../../../../../ltoptions.m4 \ +- $(top_srcdir)/../../../../../ltsugar.m4 \ +- $(top_srcdir)/../../../../../ltversion.m4 \ +- $(top_srcdir)/../../../../../lt~obsolete.m4 \ ++am__aclocal_m4_deps = $(top_srcdir)/../../../../../lt~obsolete.m4 \ + $(top_srcdir)/../../../../acinclude.m4 \ ++ $(top_srcdir)/../../../../libtool.m4 \ ++ $(top_srcdir)/../../../../ltoptions.m4 \ ++ $(top_srcdir)/../../../../ltsugar.m4 \ ++ $(top_srcdir)/../../../../ltversion.m4 \ ++ $(top_srcdir)/../../../../lt~obsolete.m4 \ + $(top_srcdir)/configure.in + am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +@@ -177,6 +178,7 @@ + localedir = @localedir@ + localstatedir = @localstatedir@ + lpfx = @lpfx@ ++lt_ECHO = @lt_ECHO@ + machine_dir = @machine_dir@ + mandir = @mandir@ + mkdir_p = @mkdir_p@ +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/Makefile.in newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/Makefile.in +--- newlib-1.19.0/newlib/libc/sys/linux/Makefile.in 2010-12-16 16:59:06.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/Makefile.in 2013-10-21 15:44:33.000000000 -0400 +@@ -41,12 +41,14 @@ + $(top_srcdir)/configure $(am__configure_deps) \ + $(srcdir)/../../../../mkinstalldirs + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +-am__aclocal_m4_deps = $(top_srcdir)/../../../../libtool.m4 \ +- $(top_srcdir)/../../../../ltoptions.m4 \ +- $(top_srcdir)/../../../../ltsugar.m4 \ +- $(top_srcdir)/../../../../ltversion.m4 \ +- $(top_srcdir)/../../../../lt~obsolete.m4 \ +- $(top_srcdir)/../../../acinclude.m4 $(top_srcdir)/configure.in ++am__aclocal_m4_deps = $(top_srcdir)/../../../../lt~obsolete.m4 \ ++ $(top_srcdir)/../../../acinclude.m4 \ ++ $(top_srcdir)/../../../libtool.m4 \ ++ $(top_srcdir)/../../../ltoptions.m4 \ ++ $(top_srcdir)/../../../ltsugar.m4 \ ++ $(top_srcdir)/../../../ltversion.m4 \ ++ $(top_srcdir)/../../../lt~obsolete.m4 \ ++ $(top_srcdir)/configure.in + am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) + am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ +@@ -309,6 +311,7 @@ + localedir = @localedir@ + localstatedir = @localstatedir@ + lpfx = @lpfx@ ++lt_ECHO = @lt_ECHO@ + machine_dir = @machine_dir@ + mandir = @mandir@ + mkdir_p = @mkdir_p@ +diff -Naur newlib-1.19.0/newlib/libc/sys/linux/net/Makefile.in newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/net/Makefile.in +--- newlib-1.19.0/newlib/libc/sys/linux/net/Makefile.in 2010-12-16 16:59:09.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/linux/net/Makefile.in 2013-10-21 15:44:33.000000000 -0400 +@@ -40,12 +40,14 @@ + $(srcdir)/Makefile.in $(srcdir)/Makefile.am + subdir = net + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +-am__aclocal_m4_deps = $(top_srcdir)/../../../../libtool.m4 \ +- $(top_srcdir)/../../../../ltoptions.m4 \ +- $(top_srcdir)/../../../../ltsugar.m4 \ +- $(top_srcdir)/../../../../ltversion.m4 \ +- $(top_srcdir)/../../../../lt~obsolete.m4 \ +- $(top_srcdir)/../../../acinclude.m4 $(top_srcdir)/configure.in ++am__aclocal_m4_deps = $(top_srcdir)/../../../../lt~obsolete.m4 \ ++ $(top_srcdir)/../../../acinclude.m4 \ ++ $(top_srcdir)/../../../libtool.m4 \ ++ $(top_srcdir)/../../../ltoptions.m4 \ ++ $(top_srcdir)/../../../ltsugar.m4 \ ++ $(top_srcdir)/../../../ltversion.m4 \ ++ $(top_srcdir)/../../../lt~obsolete.m4 \ ++ $(top_srcdir)/configure.in + am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) + mkinstalldirs = $(SHELL) $(top_srcdir)/../../../../mkinstalldirs +@@ -300,6 +302,7 @@ + localedir = @localedir@ + localstatedir = @localstatedir@ + lpfx = @lpfx@ ++lt_ECHO = @lt_ECHO@ + machine_dir = @machine_dir@ + mandir = @mandir@ + mkdir_p = @mkdir_p@ +diff -Naur newlib-1.19.0/newlib/libc/sys/Makefile.in newlib-1.19.0-tee-sdk/newlib/libc/sys/Makefile.in +--- newlib-1.19.0/newlib/libc/sys/Makefile.in 2010-12-16 16:59:03.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/Makefile.in 2013-10-21 15:44:33.000000000 -0400 +@@ -40,12 +40,13 @@ + $(top_srcdir)/configure $(am__configure_deps) \ + $(srcdir)/../../../mkinstalldirs + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +-am__aclocal_m4_deps = $(top_srcdir)/../../../libtool.m4 \ +- $(top_srcdir)/../../../ltoptions.m4 \ +- $(top_srcdir)/../../../ltsugar.m4 \ +- $(top_srcdir)/../../../ltversion.m4 \ +- $(top_srcdir)/../../../lt~obsolete.m4 \ +- $(top_srcdir)/../../acinclude.m4 $(top_srcdir)/configure.in ++am__aclocal_m4_deps = $(top_srcdir)/../../../lt~obsolete.m4 \ ++ $(top_srcdir)/../../acinclude.m4 \ ++ $(top_srcdir)/../../libtool.m4 \ ++ $(top_srcdir)/../../ltoptions.m4 \ ++ $(top_srcdir)/../../ltsugar.m4 \ ++ $(top_srcdir)/../../ltversion.m4 \ ++ $(top_srcdir)/../../lt~obsolete.m4 $(top_srcdir)/configure.in + am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) + am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ +@@ -193,6 +194,7 @@ + localedir = @localedir@ + localstatedir = @localstatedir@ + lpfx = @lpfx@ ++lt_ECHO = @lt_ECHO@ + machine_dir = @machine_dir@ + mandir = @mandir@ + mkdir_p = @mkdir_p@ +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/aclocal.m4 newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/aclocal.m4 +--- newlib-1.19.0/newlib/libc/sys/tsvc/aclocal.m4 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/aclocal.m4 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,998 @@ ++# generated automatically by aclocal 1.11.1 -*- Autoconf -*- ++ ++# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, ++# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without ++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A ++# PARTICULAR PURPOSE. ++ ++m4_ifndef([AC_AUTOCONF_VERSION], ++ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl ++m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.65],, ++[m4_warning([this file was generated for autoconf 2.65. ++You have another version of autoconf. It may work, but is not guaranteed to. ++If you have problems, you may need to regenerate the build system entirely. ++To do so, use the procedure documented by the package, typically `autoreconf'.])]) ++ ++# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# AM_AUTOMAKE_VERSION(VERSION) ++# ---------------------------- ++# Automake X.Y traces this macro to ensure aclocal.m4 has been ++# generated from the m4 files accompanying Automake X.Y. ++# (This private macro should not be called outside this file.) ++AC_DEFUN([AM_AUTOMAKE_VERSION], ++[am__api_version='1.11' ++dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to ++dnl require some minimum version. Point them to the right macro. ++m4_if([$1], [1.11.1], [], ++ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ++]) ++ ++# _AM_AUTOCONF_VERSION(VERSION) ++# ----------------------------- ++# aclocal traces this macro to find the Autoconf version. ++# This is a private macro too. Using m4_define simplifies ++# the logic in aclocal, which can simply ignore this definition. ++m4_define([_AM_AUTOCONF_VERSION], []) ++ ++# AM_SET_CURRENT_AUTOMAKE_VERSION ++# ------------------------------- ++# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. ++# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. ++AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], ++[AM_AUTOMAKE_VERSION([1.11.1])dnl ++m4_ifndef([AC_AUTOCONF_VERSION], ++ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl ++_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) ++ ++# AM_AUX_DIR_EXPAND -*- Autoconf -*- ++ ++# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets ++# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to ++# `$srcdir', `$srcdir/..', or `$srcdir/../..'. ++# ++# Of course, Automake must honor this variable whenever it calls a ++# tool from the auxiliary directory. The problem is that $srcdir (and ++# therefore $ac_aux_dir as well) can be either absolute or relative, ++# depending on how configure is run. This is pretty annoying, since ++# it makes $ac_aux_dir quite unusable in subdirectories: in the top ++# source directory, any form will work fine, but in subdirectories a ++# relative path needs to be adjusted first. ++# ++# $ac_aux_dir/missing ++# fails when called from a subdirectory if $ac_aux_dir is relative ++# $top_srcdir/$ac_aux_dir/missing ++# fails if $ac_aux_dir is absolute, ++# fails when called from a subdirectory in a VPATH build with ++# a relative $ac_aux_dir ++# ++# The reason of the latter failure is that $top_srcdir and $ac_aux_dir ++# are both prefixed by $srcdir. In an in-source build this is usually ++# harmless because $srcdir is `.', but things will broke when you ++# start a VPATH build or use an absolute $srcdir. ++# ++# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, ++# iff we strip the leading $srcdir from $ac_aux_dir. That would be: ++# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` ++# and then we would define $MISSING as ++# MISSING="\${SHELL} $am_aux_dir/missing" ++# This will work as long as MISSING is not called from configure, because ++# unfortunately $(top_srcdir) has no meaning in configure. ++# However there are other variables, like CC, which are often used in ++# configure, and could therefore not use this "fixed" $ac_aux_dir. ++# ++# Another solution, used here, is to always expand $ac_aux_dir to an ++# absolute PATH. The drawback is that using absolute paths prevent a ++# configured tree to be moved without reconfiguration. ++ ++AC_DEFUN([AM_AUX_DIR_EXPAND], ++[dnl Rely on autoconf to set up CDPATH properly. ++AC_PREREQ([2.50])dnl ++# expand $ac_aux_dir to an absolute path ++am_aux_dir=`cd $ac_aux_dir && pwd` ++]) ++ ++# AM_CONDITIONAL -*- Autoconf -*- ++ ++# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 ++# Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 9 ++ ++# AM_CONDITIONAL(NAME, SHELL-CONDITION) ++# ------------------------------------- ++# Define a conditional. ++AC_DEFUN([AM_CONDITIONAL], ++[AC_PREREQ(2.52)dnl ++ ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], ++ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl ++AC_SUBST([$1_TRUE])dnl ++AC_SUBST([$1_FALSE])dnl ++_AM_SUBST_NOTMAKE([$1_TRUE])dnl ++_AM_SUBST_NOTMAKE([$1_FALSE])dnl ++m4_define([_AM_COND_VALUE_$1], [$2])dnl ++if $2; then ++ $1_TRUE= ++ $1_FALSE='#' ++else ++ $1_TRUE='#' ++ $1_FALSE= ++fi ++AC_CONFIG_COMMANDS_PRE( ++[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then ++ AC_MSG_ERROR([[conditional "$1" was never defined. ++Usually this means the macro was only invoked conditionally.]]) ++fi])]) ++ ++# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 ++# Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 10 ++ ++# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be ++# written in clear, in which case automake, when reading aclocal.m4, ++# will think it sees a *use*, and therefore will trigger all it's ++# C support machinery. Also note that it means that autoscan, seeing ++# CC etc. in the Makefile, will ask for an AC_PROG_CC use... ++ ++ ++# _AM_DEPENDENCIES(NAME) ++# ---------------------- ++# See how the compiler implements dependency checking. ++# NAME is "CC", "CXX", "GCJ", or "OBJC". ++# We try a few techniques and use that to set a single cache variable. ++# ++# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was ++# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular ++# dependency, and given that the user is not expected to run this macro, ++# just rely on AC_PROG_CC. ++AC_DEFUN([_AM_DEPENDENCIES], ++[AC_REQUIRE([AM_SET_DEPDIR])dnl ++AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl ++AC_REQUIRE([AM_MAKE_INCLUDE])dnl ++AC_REQUIRE([AM_DEP_TRACK])dnl ++ ++ifelse([$1], CC, [depcc="$CC" am_compiler_list=], ++ [$1], CXX, [depcc="$CXX" am_compiler_list=], ++ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], ++ [$1], UPC, [depcc="$UPC" am_compiler_list=], ++ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], ++ [depcc="$$1" am_compiler_list=]) ++ ++AC_CACHE_CHECK([dependency style of $depcc], ++ [am_cv_$1_dependencies_compiler_type], ++[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then ++ # We make a subdir and do the tests there. Otherwise we can end up ++ # making bogus files that we don't know about and never remove. For ++ # instance it was reported that on HP-UX the gcc test will end up ++ # making a dummy file named `D' -- because `-MD' means `put the output ++ # in D'. ++ mkdir conftest.dir ++ # Copy depcomp to subdir because otherwise we won't find it if we're ++ # using a relative directory. ++ cp "$am_depcomp" conftest.dir ++ cd conftest.dir ++ # We will build objects and dependencies in a subdirectory because ++ # it helps to detect inapplicable dependency modes. For instance ++ # both Tru64's cc and ICC support -MD to output dependencies as a ++ # side effect of compilation, but ICC will put the dependencies in ++ # the current directory while Tru64 will put them in the object ++ # directory. ++ mkdir sub ++ ++ am_cv_$1_dependencies_compiler_type=none ++ if test "$am_compiler_list" = ""; then ++ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` ++ fi ++ am__universal=false ++ m4_case([$1], [CC], ++ [case " $depcc " in #( ++ *\ -arch\ *\ -arch\ *) am__universal=true ;; ++ esac], ++ [CXX], ++ [case " $depcc " in #( ++ *\ -arch\ *\ -arch\ *) am__universal=true ;; ++ esac]) ++ ++ for depmode in $am_compiler_list; do ++ # Setup a source with many dependencies, because some compilers ++ # like to wrap large dependency lists on column 80 (with \), and ++ # we should not choose a depcomp mode which is confused by this. ++ # ++ # We need to recreate these files for each test, as the compiler may ++ # overwrite some of them when testing with obscure command lines. ++ # This happens at least with the AIX C compiler. ++ : > sub/conftest.c ++ for i in 1 2 3 4 5 6; do ++ echo '#include "conftst'$i'.h"' >> sub/conftest.c ++ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with ++ # Solaris 8's {/usr,}/bin/sh. ++ touch sub/conftst$i.h ++ done ++ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf ++ ++ # We check with `-c' and `-o' for the sake of the "dashmstdout" ++ # mode. It turns out that the SunPro C++ compiler does not properly ++ # handle `-M -o', and we need to detect this. Also, some Intel ++ # versions had trouble with output in subdirs ++ am__obj=sub/conftest.${OBJEXT-o} ++ am__minus_obj="-o $am__obj" ++ case $depmode in ++ gcc) ++ # This depmode causes a compiler race in universal mode. ++ test "$am__universal" = false || continue ++ ;; ++ nosideeffect) ++ # after this tag, mechanisms are not by side-effect, so they'll ++ # only be used when explicitly requested ++ if test "x$enable_dependency_tracking" = xyes; then ++ continue ++ else ++ break ++ fi ++ ;; ++ msvisualcpp | msvcmsys) ++ # This compiler won't grok `-c -o', but also, the minuso test has ++ # not run yet. These depmodes are late enough in the game, and ++ # so weak that their functioning should not be impacted. ++ am__obj=conftest.${OBJEXT-o} ++ am__minus_obj= ++ ;; ++ none) break ;; ++ esac ++ if depmode=$depmode \ ++ source=sub/conftest.c object=$am__obj \ ++ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ ++ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ ++ >/dev/null 2>conftest.err && ++ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && ++ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && ++ grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ++ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then ++ # icc doesn't choke on unknown options, it will just issue warnings ++ # or remarks (even with -Werror). So we grep stderr for any message ++ # that says an option was ignored or not supported. ++ # When given -MP, icc 7.0 and 7.1 complain thusly: ++ # icc: Command line warning: ignoring option '-M'; no argument required ++ # The diagnosis changed in icc 8.0: ++ # icc: Command line remark: option '-MP' not supported ++ if (grep 'ignoring option' conftest.err || ++ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else ++ am_cv_$1_dependencies_compiler_type=$depmode ++ break ++ fi ++ fi ++ done ++ ++ cd .. ++ rm -rf conftest.dir ++else ++ am_cv_$1_dependencies_compiler_type=none ++fi ++]) ++AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) ++AM_CONDITIONAL([am__fastdep$1], [ ++ test "x$enable_dependency_tracking" != xno \ ++ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ++]) ++ ++ ++# AM_SET_DEPDIR ++# ------------- ++# Choose a directory name for dependency files. ++# This macro is AC_REQUIREd in _AM_DEPENDENCIES ++AC_DEFUN([AM_SET_DEPDIR], ++[AC_REQUIRE([AM_SET_LEADING_DOT])dnl ++AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ++]) ++ ++ ++# AM_DEP_TRACK ++# ------------ ++AC_DEFUN([AM_DEP_TRACK], ++[AC_ARG_ENABLE(dependency-tracking, ++[ --disable-dependency-tracking speeds up one-time build ++ --enable-dependency-tracking do not reject slow dependency extractors]) ++if test "x$enable_dependency_tracking" != xno; then ++ am_depcomp="$ac_aux_dir/depcomp" ++ AMDEPBACKSLASH='\' ++fi ++AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) ++AC_SUBST([AMDEPBACKSLASH])dnl ++_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl ++]) ++ ++# Generate code to set up dependency tracking. -*- Autoconf -*- ++ ++# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 ++# Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++#serial 5 ++ ++# _AM_OUTPUT_DEPENDENCY_COMMANDS ++# ------------------------------ ++AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], ++[{ ++ # Autoconf 2.62 quotes --file arguments for eval, but not when files ++ # are listed without --file. Let's play safe and only enable the eval ++ # if we detect the quoting. ++ case $CONFIG_FILES in ++ *\'*) eval set x "$CONFIG_FILES" ;; ++ *) set x $CONFIG_FILES ;; ++ esac ++ shift ++ for mf ++ do ++ # Strip MF so we end up with the name of the file. ++ mf=`echo "$mf" | sed -e 's/:.*$//'` ++ # Check whether this is an Automake generated Makefile or not. ++ # We used to match only the files named `Makefile.in', but ++ # some people rename them; so instead we look at the file content. ++ # Grep'ing the first line is not enough: some people post-process ++ # each Makefile.in and add a new line on top of each file to say so. ++ # Grep'ing the whole file is not good either: AIX grep has a line ++ # limit of 2048, but all sed's we know have understand at least 4000. ++ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then ++ dirpart=`AS_DIRNAME("$mf")` ++ else ++ continue ++ fi ++ # Extract the definition of DEPDIR, am__include, and am__quote ++ # from the Makefile without running `make'. ++ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` ++ test -z "$DEPDIR" && continue ++ am__include=`sed -n 's/^am__include = //p' < "$mf"` ++ test -z "am__include" && continue ++ am__quote=`sed -n 's/^am__quote = //p' < "$mf"` ++ # When using ansi2knr, U may be empty or an underscore; expand it ++ U=`sed -n 's/^U = //p' < "$mf"` ++ # Find all dependency output files, they are included files with ++ # $(DEPDIR) in their names. We invoke sed twice because it is the ++ # simplest approach to changing $(DEPDIR) to its actual value in the ++ # expansion. ++ for file in `sed -n " ++ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ ++ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do ++ # Make sure the directory exists. ++ test -f "$dirpart/$file" && continue ++ fdir=`AS_DIRNAME(["$file"])` ++ AS_MKDIR_P([$dirpart/$fdir]) ++ # echo "creating $dirpart/$file" ++ echo '# dummy' > "$dirpart/$file" ++ done ++ done ++} ++])# _AM_OUTPUT_DEPENDENCY_COMMANDS ++ ++ ++# AM_OUTPUT_DEPENDENCY_COMMANDS ++# ----------------------------- ++# This macro should only be invoked once -- use via AC_REQUIRE. ++# ++# This code is only required when automatic dependency tracking ++# is enabled. FIXME. This creates each `.P' file that we will ++# need in order to bootstrap the dependency handling code. ++AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], ++[AC_CONFIG_COMMANDS([depfiles], ++ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], ++ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ++]) ++ ++# Do all the work for Automake. -*- Autoconf -*- ++ ++# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, ++# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 16 ++ ++# This macro actually does too much. Some checks are only needed if ++# your package does certain things. But this isn't really a big deal. ++ ++# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) ++# AM_INIT_AUTOMAKE([OPTIONS]) ++# ----------------------------------------------- ++# The call with PACKAGE and VERSION arguments is the old style ++# call (pre autoconf-2.50), which is being phased out. PACKAGE ++# and VERSION should now be passed to AC_INIT and removed from ++# the call to AM_INIT_AUTOMAKE. ++# We support both call styles for the transition. After ++# the next Automake release, Autoconf can make the AC_INIT ++# arguments mandatory, and then we can depend on a new Autoconf ++# release and drop the old call support. ++AC_DEFUN([AM_INIT_AUTOMAKE], ++[AC_PREREQ([2.62])dnl ++dnl Autoconf wants to disallow AM_ names. We explicitly allow ++dnl the ones we care about. ++m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl ++AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl ++AC_REQUIRE([AC_PROG_INSTALL])dnl ++if test "`cd $srcdir && pwd`" != "`pwd`"; then ++ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output ++ # is not polluted with repeated "-I." ++ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl ++ # test to see if srcdir already configured ++ if test -f $srcdir/config.status; then ++ AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) ++ fi ++fi ++ ++# test whether we have cygpath ++if test -z "$CYGPATH_W"; then ++ if (cygpath --version) >/dev/null 2>/dev/null; then ++ CYGPATH_W='cygpath -w' ++ else ++ CYGPATH_W=echo ++ fi ++fi ++AC_SUBST([CYGPATH_W]) ++ ++# Define the identity of the package. ++dnl Distinguish between old-style and new-style calls. ++m4_ifval([$2], ++[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl ++ AC_SUBST([PACKAGE], [$1])dnl ++ AC_SUBST([VERSION], [$2])], ++[_AM_SET_OPTIONS([$1])dnl ++dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. ++m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, ++ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl ++ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl ++ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl ++ ++_AM_IF_OPTION([no-define],, ++[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) ++ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl ++ ++# Some tools Automake needs. ++AC_REQUIRE([AM_SANITY_CHECK])dnl ++AC_REQUIRE([AC_ARG_PROGRAM])dnl ++AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) ++AM_MISSING_PROG(AUTOCONF, autoconf) ++AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) ++AM_MISSING_PROG(AUTOHEADER, autoheader) ++AM_MISSING_PROG(MAKEINFO, makeinfo) ++AC_REQUIRE([AM_PROG_INSTALL_SH])dnl ++AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl ++AC_REQUIRE([AM_PROG_MKDIR_P])dnl ++# We need awk for the "check" target. The system "awk" is bad on ++# some platforms. ++AC_REQUIRE([AC_PROG_AWK])dnl ++AC_REQUIRE([AC_PROG_MAKE_SET])dnl ++AC_REQUIRE([AM_SET_LEADING_DOT])dnl ++_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], ++ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], ++ [_AM_PROG_TAR([v7])])]) ++_AM_IF_OPTION([no-dependencies],, ++[AC_PROVIDE_IFELSE([AC_PROG_CC], ++ [_AM_DEPENDENCIES(CC)], ++ [define([AC_PROG_CC], ++ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl ++AC_PROVIDE_IFELSE([AC_PROG_CXX], ++ [_AM_DEPENDENCIES(CXX)], ++ [define([AC_PROG_CXX], ++ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl ++AC_PROVIDE_IFELSE([AC_PROG_OBJC], ++ [_AM_DEPENDENCIES(OBJC)], ++ [define([AC_PROG_OBJC], ++ defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ++]) ++_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl ++dnl The `parallel-tests' driver may need to know about EXEEXT, so add the ++dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro ++dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. ++AC_CONFIG_COMMANDS_PRE(dnl ++[m4_provide_if([_AM_COMPILER_EXEEXT], ++ [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl ++]) ++ ++dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not ++dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further ++dnl mangled by Autoconf and run in a shell conditional statement. ++m4_define([_AC_COMPILER_EXEEXT], ++m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) ++ ++ ++# When config.status generates a header, we must update the stamp-h file. ++# This file resides in the same directory as the config header ++# that is generated. The stamp files are numbered to have different names. ++ ++# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the ++# loop where config.status creates the headers, so we can generate ++# our stamp files there. ++AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], ++[# Compute $1's index in $config_headers. ++_am_arg=$1 ++_am_stamp_count=1 ++for _am_header in $config_headers :; do ++ case $_am_header in ++ $_am_arg | $_am_arg:* ) ++ break ;; ++ * ) ++ _am_stamp_count=`expr $_am_stamp_count + 1` ;; ++ esac ++done ++echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) ++ ++# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# AM_PROG_INSTALL_SH ++# ------------------ ++# Define $install_sh. ++AC_DEFUN([AM_PROG_INSTALL_SH], ++[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl ++if test x"${install_sh}" != xset; then ++ case $am_aux_dir in ++ *\ * | *\ *) ++ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; ++ *) ++ install_sh="\${SHELL} $am_aux_dir/install-sh" ++ esac ++fi ++AC_SUBST(install_sh)]) ++ ++# Copyright (C) 2003, 2005 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 2 ++ ++# Check whether the underlying file-system supports filenames ++# with a leading dot. For instance MS-DOS doesn't. ++AC_DEFUN([AM_SET_LEADING_DOT], ++[rm -rf .tst 2>/dev/null ++mkdir .tst 2>/dev/null ++if test -d .tst; then ++ am__leading_dot=. ++else ++ am__leading_dot=_ ++fi ++rmdir .tst 2>/dev/null ++AC_SUBST([am__leading_dot])]) ++ ++# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- ++# From Jim Meyering ++ ++# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008 ++# Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 5 ++ ++# AM_MAINTAINER_MODE([DEFAULT-MODE]) ++# ---------------------------------- ++# Control maintainer-specific portions of Makefiles. ++# Default is to disable them, unless `enable' is passed literally. ++# For symmetry, `disable' may be passed as well. Anyway, the user ++# can override the default with the --enable/--disable switch. ++AC_DEFUN([AM_MAINTAINER_MODE], ++[m4_case(m4_default([$1], [disable]), ++ [enable], [m4_define([am_maintainer_other], [disable])], ++ [disable], [m4_define([am_maintainer_other], [enable])], ++ [m4_define([am_maintainer_other], [enable]) ++ m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) ++AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles]) ++ dnl maintainer-mode's default is 'disable' unless 'enable' is passed ++ AC_ARG_ENABLE([maintainer-mode], ++[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful ++ (and sometimes confusing) to the casual installer], ++ [USE_MAINTAINER_MODE=$enableval], ++ [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) ++ AC_MSG_RESULT([$USE_MAINTAINER_MODE]) ++ AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) ++ MAINT=$MAINTAINER_MODE_TRUE ++ AC_SUBST([MAINT])dnl ++] ++) ++ ++AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) ++ ++# Check to see how 'make' treats includes. -*- Autoconf -*- ++ ++# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 4 ++ ++# AM_MAKE_INCLUDE() ++# ----------------- ++# Check to see how make treats includes. ++AC_DEFUN([AM_MAKE_INCLUDE], ++[am_make=${MAKE-make} ++cat > confinc << 'END' ++am__doit: ++ @echo this is the am__doit target ++.PHONY: am__doit ++END ++# If we don't find an include directive, just comment out the code. ++AC_MSG_CHECKING([for style of include used by $am_make]) ++am__include="#" ++am__quote= ++_am_result=none ++# First try GNU make style include. ++echo "include confinc" > confmf ++# Ignore all kinds of additional output from `make'. ++case `$am_make -s -f confmf 2> /dev/null` in #( ++*the\ am__doit\ target*) ++ am__include=include ++ am__quote= ++ _am_result=GNU ++ ;; ++esac ++# Now try BSD make style include. ++if test "$am__include" = "#"; then ++ echo '.include "confinc"' > confmf ++ case `$am_make -s -f confmf 2> /dev/null` in #( ++ *the\ am__doit\ target*) ++ am__include=.include ++ am__quote="\"" ++ _am_result=BSD ++ ;; ++ esac ++fi ++AC_SUBST([am__include]) ++AC_SUBST([am__quote]) ++AC_MSG_RESULT([$_am_result]) ++rm -f confinc confmf ++]) ++ ++# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- ++ ++# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 ++# Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 6 ++ ++# AM_MISSING_PROG(NAME, PROGRAM) ++# ------------------------------ ++AC_DEFUN([AM_MISSING_PROG], ++[AC_REQUIRE([AM_MISSING_HAS_RUN]) ++$1=${$1-"${am_missing_run}$2"} ++AC_SUBST($1)]) ++ ++ ++# AM_MISSING_HAS_RUN ++# ------------------ ++# Define MISSING if not defined so far and test if it supports --run. ++# If it does, set am_missing_run to use it, otherwise, to nothing. ++AC_DEFUN([AM_MISSING_HAS_RUN], ++[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl ++AC_REQUIRE_AUX_FILE([missing])dnl ++if test x"${MISSING+set}" != xset; then ++ case $am_aux_dir in ++ *\ * | *\ *) ++ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; ++ *) ++ MISSING="\${SHELL} $am_aux_dir/missing" ;; ++ esac ++fi ++# Use eval to expand $SHELL ++if eval "$MISSING --run true"; then ++ am_missing_run="$MISSING --run " ++else ++ am_missing_run= ++ AC_MSG_WARN([`missing' script is too old or missing]) ++fi ++]) ++ ++# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# AM_PROG_MKDIR_P ++# --------------- ++# Check for `mkdir -p'. ++AC_DEFUN([AM_PROG_MKDIR_P], ++[AC_PREREQ([2.60])dnl ++AC_REQUIRE([AC_PROG_MKDIR_P])dnl ++dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, ++dnl while keeping a definition of mkdir_p for backward compatibility. ++dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. ++dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of ++dnl Makefile.ins that do not define MKDIR_P, so we do our own ++dnl adjustment using top_builddir (which is defined more often than ++dnl MKDIR_P). ++AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl ++case $mkdir_p in ++ [[\\/$]]* | ?:[[\\/]]*) ;; ++ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; ++esac ++]) ++ ++# Helper functions for option handling. -*- Autoconf -*- ++ ++# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 4 ++ ++# _AM_MANGLE_OPTION(NAME) ++# ----------------------- ++AC_DEFUN([_AM_MANGLE_OPTION], ++[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) ++ ++# _AM_SET_OPTION(NAME) ++# ------------------------------ ++# Set option NAME. Presently that only means defining a flag for this option. ++AC_DEFUN([_AM_SET_OPTION], ++[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) ++ ++# _AM_SET_OPTIONS(OPTIONS) ++# ---------------------------------- ++# OPTIONS is a space-separated list of Automake options. ++AC_DEFUN([_AM_SET_OPTIONS], ++[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) ++ ++# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) ++# ------------------------------------------- ++# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. ++AC_DEFUN([_AM_IF_OPTION], ++[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) ++ ++# Check to make sure that the build environment is sane. -*- Autoconf -*- ++ ++# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 ++# Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 5 ++ ++# AM_SANITY_CHECK ++# --------------- ++AC_DEFUN([AM_SANITY_CHECK], ++[AC_MSG_CHECKING([whether build environment is sane]) ++# Just in case ++sleep 1 ++echo timestamp > conftest.file ++# Reject unsafe characters in $srcdir or the absolute working directory ++# name. Accept space and tab only in the latter. ++am_lf=' ++' ++case `pwd` in ++ *[[\\\"\#\$\&\'\`$am_lf]]*) ++ AC_MSG_ERROR([unsafe absolute working directory name]);; ++esac ++case $srcdir in ++ *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) ++ AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; ++esac ++ ++# Do `set' in a subshell so we don't clobber the current shell's ++# arguments. Must try -L first in case configure is actually a ++# symlink; some systems play weird games with the mod time of symlinks ++# (eg FreeBSD returns the mod time of the symlink's containing ++# directory). ++if ( ++ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` ++ if test "$[*]" = "X"; then ++ # -L didn't work. ++ set X `ls -t "$srcdir/configure" conftest.file` ++ fi ++ rm -f conftest.file ++ if test "$[*]" != "X $srcdir/configure conftest.file" \ ++ && test "$[*]" != "X conftest.file $srcdir/configure"; then ++ ++ # If neither matched, then we have a broken ls. This can happen ++ # if, for instance, CONFIG_SHELL is bash and it inherits a ++ # broken ls alias from the environment. This has actually ++ # happened. Such a system could not be considered "sane". ++ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken ++alias in your environment]) ++ fi ++ ++ test "$[2]" = conftest.file ++ ) ++then ++ # Ok. ++ : ++else ++ AC_MSG_ERROR([newly created file is older than distributed files! ++Check your system clock]) ++fi ++AC_MSG_RESULT(yes)]) ++ ++# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# AM_PROG_INSTALL_STRIP ++# --------------------- ++# One issue with vendor `install' (even GNU) is that you can't ++# specify the program used to strip binaries. This is especially ++# annoying in cross-compiling environments, where the build's strip ++# is unlikely to handle the host's binaries. ++# Fortunately install-sh will honor a STRIPPROG variable, so we ++# always use install-sh in `make install-strip', and initialize ++# STRIPPROG with the value of the STRIP variable (set by the user). ++AC_DEFUN([AM_PROG_INSTALL_STRIP], ++[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl ++# Installed binaries are usually stripped using `strip' when the user ++# run `make install-strip'. However `strip' might not be the right ++# tool to use in cross-compilation environments, therefore Automake ++# will honor the `STRIP' environment variable to overrule this program. ++dnl Don't test for $cross_compiling = yes, because it might be `maybe'. ++if test "$cross_compiling" != no; then ++ AC_CHECK_TOOL([STRIP], [strip], :) ++fi ++INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" ++AC_SUBST([INSTALL_STRIP_PROGRAM])]) ++ ++# Copyright (C) 2006, 2008 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 2 ++ ++# _AM_SUBST_NOTMAKE(VARIABLE) ++# --------------------------- ++# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. ++# This macro is traced by Automake. ++AC_DEFUN([_AM_SUBST_NOTMAKE]) ++ ++# AM_SUBST_NOTMAKE(VARIABLE) ++# --------------------------- ++# Public sister of _AM_SUBST_NOTMAKE. ++AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) ++ ++# Check how to create a tarball. -*- Autoconf -*- ++ ++# Copyright (C) 2004, 2005 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 2 ++ ++# _AM_PROG_TAR(FORMAT) ++# -------------------- ++# Check how to create a tarball in format FORMAT. ++# FORMAT should be one of `v7', `ustar', or `pax'. ++# ++# Substitute a variable $(am__tar) that is a command ++# writing to stdout a FORMAT-tarball containing the directory ++# $tardir. ++# tardir=directory && $(am__tar) > result.tar ++# ++# Substitute a variable $(am__untar) that extract such ++# a tarball read from stdin. ++# $(am__untar) < result.tar ++AC_DEFUN([_AM_PROG_TAR], ++[# Always define AMTAR for backward compatibility. ++AM_MISSING_PROG([AMTAR], [tar]) ++m4_if([$1], [v7], ++ [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], ++ [m4_case([$1], [ustar],, [pax],, ++ [m4_fatal([Unknown tar format])]) ++AC_MSG_CHECKING([how to create a $1 tar archive]) ++# Loop over all known methods to create a tar archive until one works. ++_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' ++_am_tools=${am_cv_prog_tar_$1-$_am_tools} ++# Do not fold the above two line into one, because Tru64 sh and ++# Solaris sh will not grok spaces in the rhs of `-'. ++for _am_tool in $_am_tools ++do ++ case $_am_tool in ++ gnutar) ++ for _am_tar in tar gnutar gtar; ++ do ++ AM_RUN_LOG([$_am_tar --version]) && break ++ done ++ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' ++ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' ++ am__untar="$_am_tar -xf -" ++ ;; ++ plaintar) ++ # Must skip GNU tar: if it does not support --format= it doesn't create ++ # ustar tarball either. ++ (tar --version) >/dev/null 2>&1 && continue ++ am__tar='tar chf - "$$tardir"' ++ am__tar_='tar chf - "$tardir"' ++ am__untar='tar xf -' ++ ;; ++ pax) ++ am__tar='pax -L -x $1 -w "$$tardir"' ++ am__tar_='pax -L -x $1 -w "$tardir"' ++ am__untar='pax -r' ++ ;; ++ cpio) ++ am__tar='find "$$tardir" -print | cpio -o -H $1 -L' ++ am__tar_='find "$tardir" -print | cpio -o -H $1 -L' ++ am__untar='cpio -i -H $1 -d' ++ ;; ++ none) ++ am__tar=false ++ am__tar_=false ++ am__untar=false ++ ;; ++ esac ++ ++ # If the value was cached, stop now. We just wanted to have am__tar ++ # and am__untar set. ++ test -n "${am_cv_prog_tar_$1}" && break ++ ++ # tar/untar a dummy directory, and stop if the command works ++ rm -rf conftest.dir ++ mkdir conftest.dir ++ echo GrepMe > conftest.dir/file ++ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) ++ rm -rf conftest.dir ++ if test -s conftest.tar; then ++ AM_RUN_LOG([$am__untar /dev/null 2>&1 && break ++ fi ++done ++rm -rf conftest.dir ++ ++AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) ++AC_MSG_RESULT([$am_cv_prog_tar_$1])]) ++AC_SUBST([am__tar]) ++AC_SUBST([am__untar]) ++]) # _AM_PROG_TAR ++ ++m4_include([../../../../lt~obsolete.m4]) ++m4_include([../../../acinclude.m4]) ++m4_include([../../../libtool.m4]) ++m4_include([../../../ltoptions.m4]) ++m4_include([../../../ltsugar.m4]) ++m4_include([../../../ltversion.m4]) ++m4_include([../../../lt~obsolete.m4]) +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/configure newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/configure +--- newlib-1.19.0/newlib/libc/sys/tsvc/configure 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/configure 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,14046 @@ ++#! /bin/sh ++# Guess values for system-dependent variables and create Makefiles. ++# Generated by GNU Autoconf 2.65 for newlib 1.19.0. ++# ++# ++# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, ++# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, ++# Inc. ++# ++# ++# This configure script is free software; the Free Software Foundation ++# gives unlimited permission to copy, distribute and modify it. ++## -------------------- ## ++## M4sh Initialization. ## ++## -------------------- ## ++ ++# Be more Bourne compatible ++DUALCASE=1; export DUALCASE # for MKS sh ++if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : ++ emulate sh ++ NULLCMD=: ++ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which ++ # is contrary to our usage. Disable this feature. ++ alias -g '${1+"$@"}'='"$@"' ++ setopt NO_GLOB_SUBST ++else ++ case `(set -o) 2>/dev/null` in #( ++ *posix*) : ++ set -o posix ;; #( ++ *) : ++ ;; ++esac ++fi ++ ++ ++as_nl=' ++' ++export as_nl ++# Printing a long string crashes Solaris 7 /usr/bin/printf. ++as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ++as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo ++as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo ++# Prefer a ksh shell builtin over an external printf program on Solaris, ++# but without wasting forks for bash or zsh. ++if test -z "$BASH_VERSION$ZSH_VERSION" \ ++ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then ++ as_echo='print -r --' ++ as_echo_n='print -rn --' ++elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then ++ as_echo='printf %s\n' ++ as_echo_n='printf %s' ++else ++ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then ++ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' ++ as_echo_n='/usr/ucb/echo -n' ++ else ++ as_echo_body='eval expr "X$1" : "X\\(.*\\)"' ++ as_echo_n_body='eval ++ arg=$1; ++ case $arg in #( ++ *"$as_nl"*) ++ expr "X$arg" : "X\\(.*\\)$as_nl"; ++ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; ++ esac; ++ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ++ ' ++ export as_echo_n_body ++ as_echo_n='sh -c $as_echo_n_body as_echo' ++ fi ++ export as_echo_body ++ as_echo='sh -c $as_echo_body as_echo' ++fi ++ ++# The user is always right. ++if test "${PATH_SEPARATOR+set}" != set; then ++ PATH_SEPARATOR=: ++ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { ++ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || ++ PATH_SEPARATOR=';' ++ } ++fi ++ ++ ++# IFS ++# We need space, tab and new line, in precisely that order. Quoting is ++# there to prevent editors from complaining about space-tab. ++# (If _AS_PATH_WALK were called with IFS unset, it would disable word ++# splitting by setting IFS to empty value.) ++IFS=" "" $as_nl" ++ ++# Find who we are. Look in the path if we contain no directory separator. ++case $0 in #(( ++ *[\\/]* ) as_myself=$0 ;; ++ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break ++ done ++IFS=$as_save_IFS ++ ++ ;; ++esac ++# We did not find ourselves, most probably we were run as `sh COMMAND' ++# in which case we are not to be found in the path. ++if test "x$as_myself" = x; then ++ as_myself=$0 ++fi ++if test ! -f "$as_myself"; then ++ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 ++ exit 1 ++fi ++ ++# Unset variables that we do not need and which cause bugs (e.g. in ++# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" ++# suppresses any "Segmentation fault" message there. '((' could ++# trigger a bug in pdksh 5.2.14. ++for as_var in BASH_ENV ENV MAIL MAILPATH ++do eval test x\${$as_var+set} = xset \ ++ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : ++done ++PS1='$ ' ++PS2='> ' ++PS4='+ ' ++ ++# NLS nuisances. ++LC_ALL=C ++export LC_ALL ++LANGUAGE=C ++export LANGUAGE ++ ++# CDPATH. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++if test "x$CONFIG_SHELL" = x; then ++ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : ++ emulate sh ++ NULLCMD=: ++ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which ++ # is contrary to our usage. Disable this feature. ++ alias -g '\${1+\"\$@\"}'='\"\$@\"' ++ setopt NO_GLOB_SUBST ++else ++ case \`(set -o) 2>/dev/null\` in #( ++ *posix*) : ++ set -o posix ;; #( ++ *) : ++ ;; ++esac ++fi ++" ++ as_required="as_fn_return () { (exit \$1); } ++as_fn_success () { as_fn_return 0; } ++as_fn_failure () { as_fn_return 1; } ++as_fn_ret_success () { return 0; } ++as_fn_ret_failure () { return 1; } ++ ++exitcode=0 ++as_fn_success || { exitcode=1; echo as_fn_success failed.; } ++as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } ++as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } ++as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } ++if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : ++ ++else ++ exitcode=1; echo positional parameters were not saved. ++fi ++test x\$exitcode = x0 || exit 1" ++ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO ++ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO ++ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && ++ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 ++test \$(( 1 + 1 )) = 2 || exit 1" ++ if (eval "$as_required") 2>/dev/null; then : ++ as_have_required=yes ++else ++ as_have_required=no ++fi ++ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : ++ ++else ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++as_found=false ++for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ as_found=: ++ case $as_dir in #( ++ /*) ++ for as_base in sh bash ksh sh5; do ++ # Try only shells that exist, to save several forks. ++ as_shell=$as_dir/$as_base ++ if { test -f "$as_shell" || test -f "$as_shell.exe"; } && ++ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : ++ CONFIG_SHELL=$as_shell as_have_required=yes ++ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : ++ break 2 ++fi ++fi ++ done;; ++ esac ++ as_found=false ++done ++$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && ++ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : ++ CONFIG_SHELL=$SHELL as_have_required=yes ++fi; } ++IFS=$as_save_IFS ++ ++ ++ if test "x$CONFIG_SHELL" != x; then : ++ # We cannot yet assume a decent shell, so we have to provide a ++ # neutralization value for shells without unset; and this also ++ # works around shells that cannot unset nonexistent variables. ++ BASH_ENV=/dev/null ++ ENV=/dev/null ++ (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV ++ export CONFIG_SHELL ++ exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} ++fi ++ ++ if test x$as_have_required = xno; then : ++ $as_echo "$0: This script requires a shell more modern than all" ++ $as_echo "$0: the shells that I found on your system." ++ if test x${ZSH_VERSION+set} = xset ; then ++ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" ++ $as_echo "$0: be upgraded to zsh 4.3.4 or later." ++ else ++ $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, ++$0: including any error possibly output before this ++$0: message. Then install a modern shell, or manually run ++$0: the script under such a shell if you do have one." ++ fi ++ exit 1 ++fi ++fi ++fi ++SHELL=${CONFIG_SHELL-/bin/sh} ++export SHELL ++# Unset more variables known to interfere with behavior of common tools. ++CLICOLOR_FORCE= GREP_OPTIONS= ++unset CLICOLOR_FORCE GREP_OPTIONS ++ ++## --------------------- ## ++## M4sh Shell Functions. ## ++## --------------------- ## ++# as_fn_unset VAR ++# --------------- ++# Portably unset VAR. ++as_fn_unset () ++{ ++ { eval $1=; unset $1;} ++} ++as_unset=as_fn_unset ++ ++# as_fn_set_status STATUS ++# ----------------------- ++# Set $? to STATUS, without forking. ++as_fn_set_status () ++{ ++ return $1 ++} # as_fn_set_status ++ ++# as_fn_exit STATUS ++# ----------------- ++# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. ++as_fn_exit () ++{ ++ set +e ++ as_fn_set_status $1 ++ exit $1 ++} # as_fn_exit ++ ++# as_fn_mkdir_p ++# ------------- ++# Create "$as_dir" as a directory, including parents if necessary. ++as_fn_mkdir_p () ++{ ++ ++ case $as_dir in #( ++ -*) as_dir=./$as_dir;; ++ esac ++ test -d "$as_dir" || eval $as_mkdir_p || { ++ as_dirs= ++ while :; do ++ case $as_dir in #( ++ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( ++ *) as_qdir=$as_dir;; ++ esac ++ as_dirs="'$as_qdir' $as_dirs" ++ as_dir=`$as_dirname -- "$as_dir" || ++$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$as_dir" : 'X\(//\)[^/]' \| \ ++ X"$as_dir" : 'X\(//\)$' \| \ ++ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || ++$as_echo X"$as_dir" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)[^/].*/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\).*/{ ++ s//\1/ ++ q ++ } ++ s/.*/./; q'` ++ test -d "$as_dir" && break ++ done ++ test -z "$as_dirs" || eval "mkdir $as_dirs" ++ } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" ++ ++ ++} # as_fn_mkdir_p ++# as_fn_append VAR VALUE ++# ---------------------- ++# Append the text in VALUE to the end of the definition contained in VAR. Take ++# advantage of any shell optimizations that allow amortized linear growth over ++# repeated appends, instead of the typical quadratic growth present in naive ++# implementations. ++if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : ++ eval 'as_fn_append () ++ { ++ eval $1+=\$2 ++ }' ++else ++ as_fn_append () ++ { ++ eval $1=\$$1\$2 ++ } ++fi # as_fn_append ++ ++# as_fn_arith ARG... ++# ------------------ ++# Perform arithmetic evaluation on the ARGs, and store the result in the ++# global $as_val. Take advantage of shells that can avoid forks. The arguments ++# must be portable across $(()) and expr. ++if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : ++ eval 'as_fn_arith () ++ { ++ as_val=$(( $* )) ++ }' ++else ++ as_fn_arith () ++ { ++ as_val=`expr "$@" || test $? -eq 1` ++ } ++fi # as_fn_arith ++ ++ ++# as_fn_error ERROR [LINENO LOG_FD] ++# --------------------------------- ++# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are ++# provided, also output the error to LOG_FD, referencing LINENO. Then exit the ++# script with status $?, using 1 if that was 0. ++as_fn_error () ++{ ++ as_status=$?; test $as_status -eq 0 && as_status=1 ++ if test "$3"; then ++ as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 ++ fi ++ $as_echo "$as_me: error: $1" >&2 ++ as_fn_exit $as_status ++} # as_fn_error ++ ++if expr a : '\(a\)' >/dev/null 2>&1 && ++ test "X`expr 00001 : '.*\(...\)'`" = X001; then ++ as_expr=expr ++else ++ as_expr=false ++fi ++ ++if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then ++ as_basename=basename ++else ++ as_basename=false ++fi ++ ++if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then ++ as_dirname=dirname ++else ++ as_dirname=false ++fi ++ ++as_me=`$as_basename -- "$0" || ++$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ ++ X"$0" : 'X\(//\)$' \| \ ++ X"$0" : 'X\(/\)' \| . 2>/dev/null || ++$as_echo X/"$0" | ++ sed '/^.*\/\([^/][^/]*\)\/*$/{ ++ s//\1/ ++ q ++ } ++ /^X\/\(\/\/\)$/{ ++ s//\1/ ++ q ++ } ++ /^X\/\(\/\).*/{ ++ s//\1/ ++ q ++ } ++ s/.*/./; q'` ++ ++# Avoid depending upon Character Ranges. ++as_cr_letters='abcdefghijklmnopqrstuvwxyz' ++as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' ++as_cr_Letters=$as_cr_letters$as_cr_LETTERS ++as_cr_digits='0123456789' ++as_cr_alnum=$as_cr_Letters$as_cr_digits ++ ++ ++ as_lineno_1=$LINENO as_lineno_1a=$LINENO ++ as_lineno_2=$LINENO as_lineno_2a=$LINENO ++ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && ++ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { ++ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) ++ sed -n ' ++ p ++ /[$]LINENO/= ++ ' <$as_myself | ++ sed ' ++ s/[$]LINENO.*/&-/ ++ t lineno ++ b ++ :lineno ++ N ++ :loop ++ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ ++ t loop ++ s/-\n.*// ++ ' >$as_me.lineno && ++ chmod +x "$as_me.lineno" || ++ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } ++ ++ # Don't try to exec as it changes $[0], causing all sort of problems ++ # (the dirname of $[0] is not the place where we might find the ++ # original and so on. Autoconf is especially sensitive to this). ++ . "./$as_me.lineno" ++ # Exit status is that of the last command. ++ exit ++} ++ ++ECHO_C= ECHO_N= ECHO_T= ++case `echo -n x` in #((((( ++-n*) ++ case `echo 'xy\c'` in ++ *c*) ECHO_T=' ';; # ECHO_T is single tab character. ++ xy) ECHO_C='\c';; ++ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ++ ECHO_T=' ';; ++ esac;; ++*) ++ ECHO_N='-n';; ++esac ++ ++rm -f conf$$ conf$$.exe conf$$.file ++if test -d conf$$.dir; then ++ rm -f conf$$.dir/conf$$.file ++else ++ rm -f conf$$.dir ++ mkdir conf$$.dir 2>/dev/null ++fi ++if (echo >conf$$.file) 2>/dev/null; then ++ if ln -s conf$$.file conf$$ 2>/dev/null; then ++ as_ln_s='ln -s' ++ # ... but there are two gotchas: ++ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. ++ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. ++ # In both cases, we have to default to `cp -p'. ++ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || ++ as_ln_s='cp -p' ++ elif ln conf$$.file conf$$ 2>/dev/null; then ++ as_ln_s=ln ++ else ++ as_ln_s='cp -p' ++ fi ++else ++ as_ln_s='cp -p' ++fi ++rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file ++rmdir conf$$.dir 2>/dev/null ++ ++if mkdir -p . 2>/dev/null; then ++ as_mkdir_p='mkdir -p "$as_dir"' ++else ++ test -d ./-p && rmdir ./-p ++ as_mkdir_p=false ++fi ++ ++if test -x / >/dev/null 2>&1; then ++ as_test_x='test -x' ++else ++ if ls -dL / >/dev/null 2>&1; then ++ as_ls_L_option=L ++ else ++ as_ls_L_option= ++ fi ++ as_test_x=' ++ eval sh -c '\'' ++ if test -d "$1"; then ++ test -d "$1/."; ++ else ++ case $1 in #( ++ -*)set "./$1";; ++ esac; ++ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ++ ???[sx]*):;;*)false;;esac;fi ++ '\'' sh ++ ' ++fi ++as_executable_p=$as_test_x ++ ++# Sed expression to map a string onto a valid CPP name. ++as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" ++ ++# Sed expression to map a string onto a valid variable name. ++as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" ++ ++ ++ ++# Check that we are running under the correct shell. ++SHELL=${CONFIG_SHELL-/bin/sh} ++ ++case X$lt_ECHO in ++X*--fallback-echo) ++ # Remove one level of quotation (which was required for Make). ++ ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` ++ ;; ++esac ++ ++ECHO=${lt_ECHO-echo} ++if test "X$1" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++elif test "X$1" = X--fallback-echo; then ++ # Avoid inline document here, it may be left over ++ : ++elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then ++ # Yippee, $ECHO works! ++ : ++else ++ # Restart under the correct shell. ++ exec $SHELL "$0" --no-reexec ${1+"$@"} ++fi ++ ++if test "X$1" = X--fallback-echo; then ++ # used as fallback echo ++ shift ++ cat <<_LT_EOF ++$* ++_LT_EOF ++ exit 0 ++fi ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++if test -z "$lt_ECHO"; then ++ if test "X${echo_test_string+set}" != Xset; then ++ # find a string as large as possible, as long as the shell can cope with it ++ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do ++ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... ++ if { echo_test_string=`eval $cmd`; } 2>/dev/null && ++ { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null ++ then ++ break ++ fi ++ done ++ fi ++ ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ : ++ else ++ # The Solaris, AIX, and Digital Unix default echo programs unquote ++ # backslashes. This makes it impossible to quote backslashes using ++ # echo "$something" | sed 's/\\/\\\\/g' ++ # ++ # So, first we look for a working echo in the user's PATH. ++ ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for dir in $PATH /usr/ucb; do ++ IFS="$lt_save_ifs" ++ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && ++ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$dir/echo" ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ if test "X$ECHO" = Xecho; then ++ # We didn't find a better echo, so look for alternatives. ++ if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # This shell has a builtin print -r that does the trick. ++ ECHO='print -r' ++ elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && ++ test "X$CONFIG_SHELL" != X/bin/ksh; then ++ # If we have ksh, try running configure again with it. ++ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} ++ export ORIGINAL_CONFIG_SHELL ++ CONFIG_SHELL=/bin/ksh ++ export CONFIG_SHELL ++ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} ++ else ++ # Try using printf. ++ ECHO='printf %s\n' ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # Cool, printf works ++ : ++ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL ++ export CONFIG_SHELL ++ SHELL="$CONFIG_SHELL" ++ export SHELL ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ else ++ # maybe with a smaller string... ++ prev=: ++ ++ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do ++ if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null ++ then ++ break ++ fi ++ prev="$cmd" ++ done ++ ++ if test "$prev" != 'sed 50q "$0"'; then ++ echo_test_string=`eval $prev` ++ export echo_test_string ++ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} ++ else ++ # Oops. We lost completely, so just stick with echo. ++ ECHO=echo ++ fi ++ fi ++ fi ++ fi ++ fi ++fi ++ ++# Copy echo and quote the copy suitably for passing to libtool from ++# the Makefile, instead of quoting the original, which is used later. ++lt_ECHO=$ECHO ++if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then ++ lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" ++fi ++ ++ ++ ++ ++ ++# Check that we are running under the correct shell. ++SHELL=${CONFIG_SHELL-/bin/sh} ++ ++case X$lt_ECHO in ++X*--fallback-echo) ++ # Remove one level of quotation (which was required for Make). ++ ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` ++ ;; ++esac ++ ++ECHO=${lt_ECHO-echo} ++if test "X$1" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++elif test "X$1" = X--fallback-echo; then ++ # Avoid inline document here, it may be left over ++ : ++elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then ++ # Yippee, $ECHO works! ++ : ++else ++ # Restart under the correct shell. ++ exec $SHELL "$0" --no-reexec ${1+"$@"} ++fi ++ ++if test "X$1" = X--fallback-echo; then ++ # used as fallback echo ++ shift ++ cat <<_LT_EOF ++$* ++_LT_EOF ++ exit 0 ++fi ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++if test -z "$lt_ECHO"; then ++ if test "X${echo_test_string+set}" != Xset; then ++ # find a string as large as possible, as long as the shell can cope with it ++ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do ++ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... ++ if { echo_test_string=`eval $cmd`; } 2>/dev/null && ++ { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null ++ then ++ break ++ fi ++ done ++ fi ++ ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ : ++ else ++ # The Solaris, AIX, and Digital Unix default echo programs unquote ++ # backslashes. This makes it impossible to quote backslashes using ++ # echo "$something" | sed 's/\\/\\\\/g' ++ # ++ # So, first we look for a working echo in the user's PATH. ++ ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for dir in $PATH /usr/ucb; do ++ IFS="$lt_save_ifs" ++ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && ++ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$dir/echo" ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ if test "X$ECHO" = Xecho; then ++ # We didn't find a better echo, so look for alternatives. ++ if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # This shell has a builtin print -r that does the trick. ++ ECHO='print -r' ++ elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && ++ test "X$CONFIG_SHELL" != X/bin/ksh; then ++ # If we have ksh, try running configure again with it. ++ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} ++ export ORIGINAL_CONFIG_SHELL ++ CONFIG_SHELL=/bin/ksh ++ export CONFIG_SHELL ++ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} ++ else ++ # Try using printf. ++ ECHO='printf %s\n' ++ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # Cool, printf works ++ : ++ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL ++ export CONFIG_SHELL ++ SHELL="$CONFIG_SHELL" ++ export SHELL ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ ECHO="$CONFIG_SHELL $0 --fallback-echo" ++ else ++ # maybe with a smaller string... ++ prev=: ++ ++ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do ++ if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null ++ then ++ break ++ fi ++ prev="$cmd" ++ done ++ ++ if test "$prev" != 'sed 50q "$0"'; then ++ echo_test_string=`eval $prev` ++ export echo_test_string ++ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} ++ else ++ # Oops. We lost completely, so just stick with echo. ++ ECHO=echo ++ fi ++ fi ++ fi ++ fi ++ fi ++fi ++ ++# Copy echo and quote the copy suitably for passing to libtool from ++# the Makefile, instead of quoting the original, which is used later. ++lt_ECHO=$ECHO ++if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then ++ lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" ++fi ++ ++ ++ ++ ++test -n "$DJDIR" || exec 7<&0 &1 ++ ++# Name of the host. ++# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, ++# so uname gets run too. ++ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` ++ ++# ++# Initializations. ++# ++ac_default_prefix=/usr/local ++ac_clean_files= ++ac_config_libobj_dir=. ++LIBOBJS= ++cross_compiling=no ++subdirs= ++MFLAGS= ++MAKEFLAGS= ++ ++# Identity of this package. ++PACKAGE_NAME='newlib' ++PACKAGE_TARNAME='newlib' ++PACKAGE_VERSION='1.19.0' ++PACKAGE_STRING='newlib 1.19.0' ++PACKAGE_BUGREPORT='' ++PACKAGE_URL='' ++ ++ac_unique_file="dummysys.c" ++# Factoring default headers for most tests. ++ac_includes_default="\ ++#include ++#ifdef HAVE_SYS_TYPES_H ++# include ++#endif ++#ifdef HAVE_SYS_STAT_H ++# include ++#endif ++#ifdef STDC_HEADERS ++# include ++# include ++#else ++# ifdef HAVE_STDLIB_H ++# include ++# endif ++#endif ++#ifdef HAVE_STRING_H ++# if !defined STDC_HEADERS && defined HAVE_MEMORY_H ++# include ++# endif ++# include ++#endif ++#ifdef HAVE_STRINGS_H ++# include ++#endif ++#ifdef HAVE_INTTYPES_H ++# include ++#endif ++#ifdef HAVE_STDINT_H ++# include ++#endif ++#ifdef HAVE_UNISTD_H ++# include ++#endif" ++ ++ac_subst_vars='am__EXEEXT_FALSE ++am__EXEEXT_TRUE ++LTLIBOBJS ++LIBOBJS ++CPP ++OTOOL64 ++OTOOL ++LIPO ++NMEDIT ++DSYMUTIL ++LN_S ++NM ++ac_ct_DUMPBIN ++DUMPBIN ++LD ++FGREP ++EGREP ++GREP ++EXEEXT ++ac_ct_CC ++CPPFLAGS ++CFLAGS ++LIBTOOL ++OBJDUMP ++DLLTOOL ++lt_ECHO ++SED ++sys_dir ++machine_dir ++libm_machine_dir ++lpfx ++aext ++oext ++OBJEXT ++USE_LIBTOOL_FALSE ++USE_LIBTOOL_TRUE ++ELIX_LEVEL_4_FALSE ++ELIX_LEVEL_4_TRUE ++ELIX_LEVEL_3_FALSE ++ELIX_LEVEL_3_TRUE ++ELIX_LEVEL_2_FALSE ++ELIX_LEVEL_2_TRUE ++ELIX_LEVEL_1_FALSE ++ELIX_LEVEL_1_TRUE ++ELIX_LEVEL_0_FALSE ++ELIX_LEVEL_0_TRUE ++LDFLAGS ++NEWLIB_CFLAGS ++CCASFLAGS ++CCAS ++MAINT ++MAINTAINER_MODE_FALSE ++MAINTAINER_MODE_TRUE ++READELF ++RANLIB ++AR ++AS ++am__fastdepCC_FALSE ++am__fastdepCC_TRUE ++CCDEPMODE ++AMDEPBACKSLASH ++AMDEP_FALSE ++AMDEP_TRUE ++am__quote ++am__include ++DEPDIR ++CC ++am__untar ++am__tar ++AMTAR ++am__leading_dot ++SET_MAKE ++AWK ++mkdir_p ++MKDIR_P ++INSTALL_STRIP_PROGRAM ++STRIP ++install_sh ++MAKEINFO ++AUTOHEADER ++AUTOMAKE ++AUTOCONF ++ACLOCAL ++VERSION ++PACKAGE ++CYGPATH_W ++am__isrc ++INSTALL_DATA ++INSTALL_SCRIPT ++INSTALL_PROGRAM ++host_os ++host_vendor ++host_cpu ++host ++build_os ++build_vendor ++build_cpu ++build ++newlib_basedir ++MAY_SUPPLY_SYSCALLS_FALSE ++MAY_SUPPLY_SYSCALLS_TRUE ++target_alias ++host_alias ++build_alias ++LIBS ++ECHO_T ++ECHO_N ++ECHO_C ++DEFS ++mandir ++localedir ++libdir ++psdir ++pdfdir ++dvidir ++htmldir ++infodir ++docdir ++oldincludedir ++includedir ++localstatedir ++sharedstatedir ++sysconfdir ++datadir ++datarootdir ++libexecdir ++sbindir ++bindir ++program_transform_name ++prefix ++exec_prefix ++PACKAGE_URL ++PACKAGE_BUGREPORT ++PACKAGE_STRING ++PACKAGE_VERSION ++PACKAGE_TARNAME ++PACKAGE_NAME ++PATH_SEPARATOR ++SHELL' ++ac_subst_files='' ++ac_user_opts=' ++enable_option_checking ++enable_multilib ++enable_target_optspace ++enable_malloc_debugging ++enable_newlib_multithread ++enable_newlib_iconv ++enable_newlib_elix_level ++enable_newlib_io_float ++enable_newlib_supplied_syscalls ++enable_dependency_tracking ++enable_maintainer_mode ++enable_shared ++enable_static ++with_pic ++enable_fast_install ++with_gnu_ld ++enable_libtool_lock ++' ++ ac_precious_vars='build_alias ++host_alias ++target_alias ++CCAS ++CCASFLAGS ++CC ++CFLAGS ++LDFLAGS ++LIBS ++CPPFLAGS ++CPP' ++ ++ ++# Initialize some variables set by options. ++ac_init_help= ++ac_init_version=false ++ac_unrecognized_opts= ++ac_unrecognized_sep= ++# The variables have the same names as the options, with ++# dashes changed to underlines. ++cache_file=/dev/null ++exec_prefix=NONE ++no_create= ++no_recursion= ++prefix=NONE ++program_prefix=NONE ++program_suffix=NONE ++program_transform_name=s,x,x, ++silent= ++site= ++srcdir= ++verbose= ++x_includes=NONE ++x_libraries=NONE ++ ++# Installation directory options. ++# These are left unexpanded so users can "make install exec_prefix=/foo" ++# and all the variables that are supposed to be based on exec_prefix ++# by default will actually change. ++# Use braces instead of parens because sh, perl, etc. also accept them. ++# (The list follows the same order as the GNU Coding Standards.) ++bindir='${exec_prefix}/bin' ++sbindir='${exec_prefix}/sbin' ++libexecdir='${exec_prefix}/libexec' ++datarootdir='${prefix}/share' ++datadir='${datarootdir}' ++sysconfdir='${prefix}/etc' ++sharedstatedir='${prefix}/com' ++localstatedir='${prefix}/var' ++includedir='${prefix}/include' ++oldincludedir='/usr/include' ++docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' ++infodir='${datarootdir}/info' ++htmldir='${docdir}' ++dvidir='${docdir}' ++pdfdir='${docdir}' ++psdir='${docdir}' ++libdir='${exec_prefix}/lib' ++localedir='${datarootdir}/locale' ++mandir='${datarootdir}/man' ++ ++ac_prev= ++ac_dashdash= ++for ac_option ++do ++ # If the previous option needs an argument, assign it. ++ if test -n "$ac_prev"; then ++ eval $ac_prev=\$ac_option ++ ac_prev= ++ continue ++ fi ++ ++ case $ac_option in ++ *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; ++ *) ac_optarg=yes ;; ++ esac ++ ++ # Accept the important Cygnus configure options, so we can diagnose typos. ++ ++ case $ac_dashdash$ac_option in ++ --) ++ ac_dashdash=yes ;; ++ ++ -bindir | --bindir | --bindi | --bind | --bin | --bi) ++ ac_prev=bindir ;; ++ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) ++ bindir=$ac_optarg ;; ++ ++ -build | --build | --buil | --bui | --bu) ++ ac_prev=build_alias ;; ++ -build=* | --build=* | --buil=* | --bui=* | --bu=*) ++ build_alias=$ac_optarg ;; ++ ++ -cache-file | --cache-file | --cache-fil | --cache-fi \ ++ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ++ ac_prev=cache_file ;; ++ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ ++ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) ++ cache_file=$ac_optarg ;; ++ ++ --config-cache | -C) ++ cache_file=config.cache ;; ++ ++ -datadir | --datadir | --datadi | --datad) ++ ac_prev=datadir ;; ++ -datadir=* | --datadir=* | --datadi=* | --datad=*) ++ datadir=$ac_optarg ;; ++ ++ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ ++ | --dataroo | --dataro | --datar) ++ ac_prev=datarootdir ;; ++ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ ++ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) ++ datarootdir=$ac_optarg ;; ++ ++ -disable-* | --disable-*) ++ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` ++ # Reject names that are not valid shell variable names. ++ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && ++ as_fn_error "invalid feature name: $ac_useropt" ++ ac_useropt_orig=$ac_useropt ++ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` ++ case $ac_user_opts in ++ *" ++"enable_$ac_useropt" ++"*) ;; ++ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ++ ac_unrecognized_sep=', ';; ++ esac ++ eval enable_$ac_useropt=no ;; ++ ++ -docdir | --docdir | --docdi | --doc | --do) ++ ac_prev=docdir ;; ++ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) ++ docdir=$ac_optarg ;; ++ ++ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ++ ac_prev=dvidir ;; ++ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) ++ dvidir=$ac_optarg ;; ++ ++ -enable-* | --enable-*) ++ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` ++ # Reject names that are not valid shell variable names. ++ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && ++ as_fn_error "invalid feature name: $ac_useropt" ++ ac_useropt_orig=$ac_useropt ++ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` ++ case $ac_user_opts in ++ *" ++"enable_$ac_useropt" ++"*) ;; ++ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ++ ac_unrecognized_sep=', ';; ++ esac ++ eval enable_$ac_useropt=\$ac_optarg ;; ++ ++ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ ++ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ ++ | --exec | --exe | --ex) ++ ac_prev=exec_prefix ;; ++ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ ++ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ ++ | --exec=* | --exe=* | --ex=*) ++ exec_prefix=$ac_optarg ;; ++ ++ -gas | --gas | --ga | --g) ++ # Obsolete; use --with-gas. ++ with_gas=yes ;; ++ ++ -help | --help | --hel | --he | -h) ++ ac_init_help=long ;; ++ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ++ ac_init_help=recursive ;; ++ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ++ ac_init_help=short ;; ++ ++ -host | --host | --hos | --ho) ++ ac_prev=host_alias ;; ++ -host=* | --host=* | --hos=* | --ho=*) ++ host_alias=$ac_optarg ;; ++ ++ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ++ ac_prev=htmldir ;; ++ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ ++ | --ht=*) ++ htmldir=$ac_optarg ;; ++ ++ -includedir | --includedir | --includedi | --included | --include \ ++ | --includ | --inclu | --incl | --inc) ++ ac_prev=includedir ;; ++ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ ++ | --includ=* | --inclu=* | --incl=* | --inc=*) ++ includedir=$ac_optarg ;; ++ ++ -infodir | --infodir | --infodi | --infod | --info | --inf) ++ ac_prev=infodir ;; ++ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) ++ infodir=$ac_optarg ;; ++ ++ -libdir | --libdir | --libdi | --libd) ++ ac_prev=libdir ;; ++ -libdir=* | --libdir=* | --libdi=* | --libd=*) ++ libdir=$ac_optarg ;; ++ ++ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ ++ | --libexe | --libex | --libe) ++ ac_prev=libexecdir ;; ++ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ ++ | --libexe=* | --libex=* | --libe=*) ++ libexecdir=$ac_optarg ;; ++ ++ -localedir | --localedir | --localedi | --localed | --locale) ++ ac_prev=localedir ;; ++ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) ++ localedir=$ac_optarg ;; ++ ++ -localstatedir | --localstatedir | --localstatedi | --localstated \ ++ | --localstate | --localstat | --localsta | --localst | --locals) ++ ac_prev=localstatedir ;; ++ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ ++ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) ++ localstatedir=$ac_optarg ;; ++ ++ -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ++ ac_prev=mandir ;; ++ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) ++ mandir=$ac_optarg ;; ++ ++ -nfp | --nfp | --nf) ++ # Obsolete; use --without-fp. ++ with_fp=no ;; ++ ++ -no-create | --no-create | --no-creat | --no-crea | --no-cre \ ++ | --no-cr | --no-c | -n) ++ no_create=yes ;; ++ ++ -no-recursion | --no-recursion | --no-recursio | --no-recursi \ ++ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ++ no_recursion=yes ;; ++ ++ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ ++ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ ++ | --oldin | --oldi | --old | --ol | --o) ++ ac_prev=oldincludedir ;; ++ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ ++ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ ++ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) ++ oldincludedir=$ac_optarg ;; ++ ++ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ++ ac_prev=prefix ;; ++ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) ++ prefix=$ac_optarg ;; ++ ++ -program-prefix | --program-prefix | --program-prefi | --program-pref \ ++ | --program-pre | --program-pr | --program-p) ++ ac_prev=program_prefix ;; ++ -program-prefix=* | --program-prefix=* | --program-prefi=* \ ++ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) ++ program_prefix=$ac_optarg ;; ++ ++ -program-suffix | --program-suffix | --program-suffi | --program-suff \ ++ | --program-suf | --program-su | --program-s) ++ ac_prev=program_suffix ;; ++ -program-suffix=* | --program-suffix=* | --program-suffi=* \ ++ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) ++ program_suffix=$ac_optarg ;; ++ ++ -program-transform-name | --program-transform-name \ ++ | --program-transform-nam | --program-transform-na \ ++ | --program-transform-n | --program-transform- \ ++ | --program-transform | --program-transfor \ ++ | --program-transfo | --program-transf \ ++ | --program-trans | --program-tran \ ++ | --progr-tra | --program-tr | --program-t) ++ ac_prev=program_transform_name ;; ++ -program-transform-name=* | --program-transform-name=* \ ++ | --program-transform-nam=* | --program-transform-na=* \ ++ | --program-transform-n=* | --program-transform-=* \ ++ | --program-transform=* | --program-transfor=* \ ++ | --program-transfo=* | --program-transf=* \ ++ | --program-trans=* | --program-tran=* \ ++ | --progr-tra=* | --program-tr=* | --program-t=*) ++ program_transform_name=$ac_optarg ;; ++ ++ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ++ ac_prev=pdfdir ;; ++ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) ++ pdfdir=$ac_optarg ;; ++ ++ -psdir | --psdir | --psdi | --psd | --ps) ++ ac_prev=psdir ;; ++ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) ++ psdir=$ac_optarg ;; ++ ++ -q | -quiet | --quiet | --quie | --qui | --qu | --q \ ++ | -silent | --silent | --silen | --sile | --sil) ++ silent=yes ;; ++ ++ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ++ ac_prev=sbindir ;; ++ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ ++ | --sbi=* | --sb=*) ++ sbindir=$ac_optarg ;; ++ ++ -sharedstatedir | --sharedstatedir | --sharedstatedi \ ++ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ ++ | --sharedst | --shareds | --shared | --share | --shar \ ++ | --sha | --sh) ++ ac_prev=sharedstatedir ;; ++ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ ++ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ ++ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ ++ | --sha=* | --sh=*) ++ sharedstatedir=$ac_optarg ;; ++ ++ -site | --site | --sit) ++ ac_prev=site ;; ++ -site=* | --site=* | --sit=*) ++ site=$ac_optarg ;; ++ ++ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ++ ac_prev=srcdir ;; ++ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) ++ srcdir=$ac_optarg ;; ++ ++ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ ++ | --syscon | --sysco | --sysc | --sys | --sy) ++ ac_prev=sysconfdir ;; ++ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ ++ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) ++ sysconfdir=$ac_optarg ;; ++ ++ -target | --target | --targe | --targ | --tar | --ta | --t) ++ ac_prev=target_alias ;; ++ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) ++ target_alias=$ac_optarg ;; ++ ++ -v | -verbose | --verbose | --verbos | --verbo | --verb) ++ verbose=yes ;; ++ ++ -version | --version | --versio | --versi | --vers | -V) ++ ac_init_version=: ;; ++ ++ -with-* | --with-*) ++ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` ++ # Reject names that are not valid shell variable names. ++ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && ++ as_fn_error "invalid package name: $ac_useropt" ++ ac_useropt_orig=$ac_useropt ++ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` ++ case $ac_user_opts in ++ *" ++"with_$ac_useropt" ++"*) ;; ++ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ++ ac_unrecognized_sep=', ';; ++ esac ++ eval with_$ac_useropt=\$ac_optarg ;; ++ ++ -without-* | --without-*) ++ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` ++ # Reject names that are not valid shell variable names. ++ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && ++ as_fn_error "invalid package name: $ac_useropt" ++ ac_useropt_orig=$ac_useropt ++ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` ++ case $ac_user_opts in ++ *" ++"with_$ac_useropt" ++"*) ;; ++ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ++ ac_unrecognized_sep=', ';; ++ esac ++ eval with_$ac_useropt=no ;; ++ ++ --x) ++ # Obsolete; use --with-x. ++ with_x=yes ;; ++ ++ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ ++ | --x-incl | --x-inc | --x-in | --x-i) ++ ac_prev=x_includes ;; ++ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ ++ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) ++ x_includes=$ac_optarg ;; ++ ++ -x-libraries | --x-libraries | --x-librarie | --x-librari \ ++ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ++ ac_prev=x_libraries ;; ++ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ ++ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) ++ x_libraries=$ac_optarg ;; ++ ++ -*) as_fn_error "unrecognized option: \`$ac_option' ++Try \`$0 --help' for more information." ++ ;; ++ ++ *=*) ++ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` ++ # Reject names that are not valid shell variable names. ++ case $ac_envvar in #( ++ '' | [0-9]* | *[!_$as_cr_alnum]* ) ++ as_fn_error "invalid variable name: \`$ac_envvar'" ;; ++ esac ++ eval $ac_envvar=\$ac_optarg ++ export $ac_envvar ;; ++ ++ *) ++ # FIXME: should be removed in autoconf 3.0. ++ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 ++ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && ++ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 ++ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ++ ;; ++ ++ esac ++done ++ ++if test -n "$ac_prev"; then ++ ac_option=--`echo $ac_prev | sed 's/_/-/g'` ++ as_fn_error "missing argument to $ac_option" ++fi ++ ++if test -n "$ac_unrecognized_opts"; then ++ case $enable_option_checking in ++ no) ;; ++ fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;; ++ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; ++ esac ++fi ++ ++# Check all directory arguments for consistency. ++for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ ++ datadir sysconfdir sharedstatedir localstatedir includedir \ ++ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ ++ libdir localedir mandir ++do ++ eval ac_val=\$$ac_var ++ # Remove trailing slashes. ++ case $ac_val in ++ */ ) ++ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` ++ eval $ac_var=\$ac_val;; ++ esac ++ # Be sure to have absolute directory names. ++ case $ac_val in ++ [\\/$]* | ?:[\\/]* ) continue;; ++ NONE | '' ) case $ac_var in *prefix ) continue;; esac;; ++ esac ++ as_fn_error "expected an absolute directory name for --$ac_var: $ac_val" ++done ++ ++# There might be people who depend on the old broken behavior: `$host' ++# used to hold the argument of --host etc. ++# FIXME: To remove some day. ++build=$build_alias ++host=$host_alias ++target=$target_alias ++ ++# FIXME: To remove some day. ++if test "x$host_alias" != x; then ++ if test "x$build_alias" = x; then ++ cross_compiling=maybe ++ $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. ++ If a cross compiler is detected then cross compile mode will be used." >&2 ++ elif test "x$build_alias" != "x$host_alias"; then ++ cross_compiling=yes ++ fi ++fi ++ ++ac_tool_prefix= ++test -n "$host_alias" && ac_tool_prefix=$host_alias- ++ ++test "$silent" = yes && exec 6>/dev/null ++ ++ ++ac_pwd=`pwd` && test -n "$ac_pwd" && ++ac_ls_di=`ls -di .` && ++ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || ++ as_fn_error "working directory cannot be determined" ++test "X$ac_ls_di" = "X$ac_pwd_ls_di" || ++ as_fn_error "pwd does not report name of working directory" ++ ++ ++# Find the source files, if location was not specified. ++if test -z "$srcdir"; then ++ ac_srcdir_defaulted=yes ++ # Try the directory containing this script, then the parent directory. ++ ac_confdir=`$as_dirname -- "$as_myself" || ++$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$as_myself" : 'X\(//\)[^/]' \| \ ++ X"$as_myself" : 'X\(//\)$' \| \ ++ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || ++$as_echo X"$as_myself" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)[^/].*/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\).*/{ ++ s//\1/ ++ q ++ } ++ s/.*/./; q'` ++ srcdir=$ac_confdir ++ if test ! -r "$srcdir/$ac_unique_file"; then ++ srcdir=.. ++ fi ++else ++ ac_srcdir_defaulted=no ++fi ++if test ! -r "$srcdir/$ac_unique_file"; then ++ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." ++ as_fn_error "cannot find sources ($ac_unique_file) in $srcdir" ++fi ++ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ++ac_abs_confdir=`( ++ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg" ++ pwd)` ++# When building in place, set srcdir=. ++if test "$ac_abs_confdir" = "$ac_pwd"; then ++ srcdir=. ++fi ++# Remove unnecessary trailing slashes from srcdir. ++# Double slashes in file names in object file debugging info ++# mess up M-x gdb in Emacs. ++case $srcdir in ++*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; ++esac ++for ac_var in $ac_precious_vars; do ++ eval ac_env_${ac_var}_set=\${${ac_var}+set} ++ eval ac_env_${ac_var}_value=\$${ac_var} ++ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} ++ eval ac_cv_env_${ac_var}_value=\$${ac_var} ++done ++ ++# ++# Report the --help message. ++# ++if test "$ac_init_help" = "long"; then ++ # Omit some internal or obsolete options to make the list less imposing. ++ # This message is too long to be a string in the A/UX 3.1 sh. ++ cat <<_ACEOF ++\`configure' configures newlib 1.19.0 to adapt to many kinds of systems. ++ ++Usage: $0 [OPTION]... [VAR=VALUE]... ++ ++To assign environment variables (e.g., CC, CFLAGS...), specify them as ++VAR=VALUE. See below for descriptions of some of the useful variables. ++ ++Defaults for the options are specified in brackets. ++ ++Configuration: ++ -h, --help display this help and exit ++ --help=short display options specific to this package ++ --help=recursive display the short help of all the included packages ++ -V, --version display version information and exit ++ -q, --quiet, --silent do not print \`checking...' messages ++ --cache-file=FILE cache test results in FILE [disabled] ++ -C, --config-cache alias for \`--cache-file=config.cache' ++ -n, --no-create do not create output files ++ --srcdir=DIR find the sources in DIR [configure dir or \`..'] ++ ++Installation directories: ++ --prefix=PREFIX install architecture-independent files in PREFIX ++ [$ac_default_prefix] ++ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX ++ [PREFIX] ++ ++By default, \`make install' will install all the files in ++\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify ++an installation prefix other than \`$ac_default_prefix' using \`--prefix', ++for instance \`--prefix=\$HOME'. ++ ++For better control, use the options below. ++ ++Fine tuning of the installation directories: ++ --bindir=DIR user executables [EPREFIX/bin] ++ --sbindir=DIR system admin executables [EPREFIX/sbin] ++ --libexecdir=DIR program executables [EPREFIX/libexec] ++ --sysconfdir=DIR read-only single-machine data [PREFIX/etc] ++ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] ++ --localstatedir=DIR modifiable single-machine data [PREFIX/var] ++ --libdir=DIR object code libraries [EPREFIX/lib] ++ --includedir=DIR C header files [PREFIX/include] ++ --oldincludedir=DIR C header files for non-gcc [/usr/include] ++ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] ++ --datadir=DIR read-only architecture-independent data [DATAROOTDIR] ++ --infodir=DIR info documentation [DATAROOTDIR/info] ++ --localedir=DIR locale-dependent data [DATAROOTDIR/locale] ++ --mandir=DIR man documentation [DATAROOTDIR/man] ++ --docdir=DIR documentation root [DATAROOTDIR/doc/newlib] ++ --htmldir=DIR html documentation [DOCDIR] ++ --dvidir=DIR dvi documentation [DOCDIR] ++ --pdfdir=DIR pdf documentation [DOCDIR] ++ --psdir=DIR ps documentation [DOCDIR] ++_ACEOF ++ ++ cat <<\_ACEOF ++ ++Program names: ++ --program-prefix=PREFIX prepend PREFIX to installed program names ++ --program-suffix=SUFFIX append SUFFIX to installed program names ++ --program-transform-name=PROGRAM run sed PROGRAM on installed program names ++ ++System types: ++ --build=BUILD configure for building on BUILD [guessed] ++ --host=HOST cross-compile to build programs to run on HOST [BUILD] ++_ACEOF ++fi ++ ++if test -n "$ac_init_help"; then ++ case $ac_init_help in ++ short | recursive ) echo "Configuration of newlib 1.19.0:";; ++ esac ++ cat <<\_ACEOF ++ ++Optional Features: ++ --disable-option-checking ignore unrecognized --enable/--with options ++ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) ++ --enable-FEATURE[=ARG] include FEATURE [ARG=yes] ++ --enable-multilib build many library versions (default) ++ --enable-target-optspace optimize for space ++ --enable-malloc-debugging indicate malloc debugging requested ++ --enable-newlib-multithread enable support for multiple threads ++ --enable-newlib-iconv enable iconv library support ++ --enable-newlib-elix-level supply desired elix library level (1-4) ++ --disable-newlib-io-float disable printf/scanf family float support ++ --disable-newlib-supplied-syscalls disable newlib from supplying syscalls ++ --disable-dependency-tracking speeds up one-time build ++ --enable-dependency-tracking do not reject slow dependency extractors ++ --enable-maintainer-mode enable make rules and dependencies not useful ++ (and sometimes confusing) to the casual installer ++ --enable-shared[=PKGS] build shared libraries [default=yes] ++ --enable-static[=PKGS] build static libraries [default=yes] ++ --enable-fast-install[=PKGS] ++ optimize for fast installation [default=yes] ++ --disable-libtool-lock avoid locking (might break parallel builds) ++ ++Optional Packages: ++ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] ++ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) ++ --with-pic try to use only PIC/non-PIC objects [default=use ++ both] ++ --with-gnu-ld assume the C compiler uses GNU ld [default=no] ++ ++Some influential environment variables: ++ CCAS assembler compiler command (defaults to CC) ++ CCASFLAGS assembler compiler flags (defaults to CFLAGS) ++ CC C compiler command ++ CFLAGS C compiler flags ++ LDFLAGS linker flags, e.g. -L if you have libraries in a ++ nonstandard directory ++ LIBS libraries to pass to the linker, e.g. -l ++ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if ++ you have headers in a nonstandard directory ++ CPP C preprocessor ++ ++Use these variables to override the choices made by `configure' or to help ++it to find libraries and programs with nonstandard names/locations. ++ ++Report bugs to the package provider. ++_ACEOF ++ac_status=$? ++fi ++ ++if test "$ac_init_help" = "recursive"; then ++ # If there are subdirs, report their specific --help. ++ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue ++ test -d "$ac_dir" || ++ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || ++ continue ++ ac_builddir=. ++ ++case "$ac_dir" in ++.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; ++*) ++ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` ++ # A ".." for each directory in $ac_dir_suffix. ++ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` ++ case $ac_top_builddir_sub in ++ "") ac_top_builddir_sub=. ac_top_build_prefix= ;; ++ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; ++ esac ;; ++esac ++ac_abs_top_builddir=$ac_pwd ++ac_abs_builddir=$ac_pwd$ac_dir_suffix ++# for backward compatibility: ++ac_top_builddir=$ac_top_build_prefix ++ ++case $srcdir in ++ .) # We are building in place. ++ ac_srcdir=. ++ ac_top_srcdir=$ac_top_builddir_sub ++ ac_abs_top_srcdir=$ac_pwd ;; ++ [\\/]* | ?:[\\/]* ) # Absolute name. ++ ac_srcdir=$srcdir$ac_dir_suffix; ++ ac_top_srcdir=$srcdir ++ ac_abs_top_srcdir=$srcdir ;; ++ *) # Relative name. ++ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ++ ac_top_srcdir=$ac_top_build_prefix$srcdir ++ ac_abs_top_srcdir=$ac_pwd/$srcdir ;; ++esac ++ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix ++ ++ cd "$ac_dir" || { ac_status=$?; continue; } ++ # Check for guested configure. ++ if test -f "$ac_srcdir/configure.gnu"; then ++ echo && ++ $SHELL "$ac_srcdir/configure.gnu" --help=recursive ++ elif test -f "$ac_srcdir/configure"; then ++ echo && ++ $SHELL "$ac_srcdir/configure" --help=recursive ++ else ++ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 ++ fi || ac_status=$? ++ cd "$ac_pwd" || { ac_status=$?; break; } ++ done ++fi ++ ++test -n "$ac_init_help" && exit $ac_status ++if $ac_init_version; then ++ cat <<\_ACEOF ++newlib configure 1.19.0 ++generated by GNU Autoconf 2.65 ++ ++Copyright (C) 2009 Free Software Foundation, Inc. ++This configure script is free software; the Free Software Foundation ++gives unlimited permission to copy, distribute and modify it. ++_ACEOF ++ exit ++fi ++ ++## ------------------------ ## ++## Autoconf initialization. ## ++## ------------------------ ## ++ ++# ac_fn_c_try_compile LINENO ++# -------------------------- ++# Try to compile conftest.$ac_ext, and return whether this succeeded. ++ac_fn_c_try_compile () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ rm -f conftest.$ac_objext ++ if { { ac_try="$ac_compile" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_compile") 2>conftest.err ++ ac_status=$? ++ if test -s conftest.err; then ++ grep -v '^ *+' conftest.err >conftest.er1 ++ cat conftest.er1 >&5 ++ mv -f conftest.er1 conftest.err ++ fi ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && { ++ test -z "$ac_c_werror_flag" || ++ test ! -s conftest.err ++ } && test -s conftest.$ac_objext; then : ++ ac_retval=0 ++else ++ $as_echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ ac_retval=1 ++fi ++ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} ++ as_fn_set_status $ac_retval ++ ++} # ac_fn_c_try_compile ++ ++# ac_fn_c_try_link LINENO ++# ----------------------- ++# Try to link conftest.$ac_ext, and return whether this succeeded. ++ac_fn_c_try_link () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ rm -f conftest.$ac_objext conftest$ac_exeext ++ if { { ac_try="$ac_link" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_link") 2>conftest.err ++ ac_status=$? ++ if test -s conftest.err; then ++ grep -v '^ *+' conftest.err >conftest.er1 ++ cat conftest.er1 >&5 ++ mv -f conftest.er1 conftest.err ++ fi ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && { ++ test -z "$ac_c_werror_flag" || ++ test ! -s conftest.err ++ } && test -s conftest$ac_exeext && { ++ test "$cross_compiling" = yes || ++ $as_test_x conftest$ac_exeext ++ }; then : ++ ac_retval=0 ++else ++ $as_echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ ac_retval=1 ++fi ++ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information ++ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would ++ # interfere with the next link command; also delete a directory that is ++ # left behind by Apple's compiler. We do this before executing the actions. ++ rm -rf conftest.dSYM conftest_ipa8_conftest.oo ++ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} ++ as_fn_set_status $ac_retval ++ ++} # ac_fn_c_try_link ++ ++# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES ++# ------------------------------------------------------- ++# Tests whether HEADER exists and can be compiled using the include files in ++# INCLUDES, setting the cache variable VAR accordingly. ++ac_fn_c_check_header_compile () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 ++$as_echo_n "checking for $2... " >&6; } ++if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++$4 ++#include <$2> ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ eval "$3=yes" ++else ++ eval "$3=no" ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++eval ac_res=\$$3 ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 ++$as_echo "$ac_res" >&6; } ++ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} ++ ++} # ac_fn_c_check_header_compile ++ ++# ac_fn_c_try_cpp LINENO ++# ---------------------- ++# Try to preprocess conftest.$ac_ext, and return whether this succeeded. ++ac_fn_c_try_cpp () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ if { { ac_try="$ac_cpp conftest.$ac_ext" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ++ ac_status=$? ++ if test -s conftest.err; then ++ grep -v '^ *+' conftest.err >conftest.er1 ++ cat conftest.er1 >&5 ++ mv -f conftest.er1 conftest.err ++ fi ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } >/dev/null && { ++ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || ++ test ! -s conftest.err ++ }; then : ++ ac_retval=0 ++else ++ $as_echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ ac_retval=1 ++fi ++ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} ++ as_fn_set_status $ac_retval ++ ++} # ac_fn_c_try_cpp ++ ++# ac_fn_c_try_run LINENO ++# ---------------------- ++# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes ++# that executables *can* be run. ++ac_fn_c_try_run () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ if { { ac_try="$ac_link" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_link") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' ++ { { case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_try") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; }; then : ++ ac_retval=0 ++else ++ $as_echo "$as_me: program exited with status $ac_status" >&5 ++ $as_echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ ac_retval=$ac_status ++fi ++ rm -rf conftest.dSYM conftest_ipa8_conftest.oo ++ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} ++ as_fn_set_status $ac_retval ++ ++} # ac_fn_c_try_run ++ ++# ac_fn_c_check_func LINENO FUNC VAR ++# ---------------------------------- ++# Tests whether FUNC exists, setting the cache variable VAR accordingly ++ac_fn_c_check_func () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 ++$as_echo_n "checking for $2... " >&6; } ++if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++/* Define $2 to an innocuous variant, in case declares $2. ++ For example, HP-UX 11i declares gettimeofday. */ ++#define $2 innocuous_$2 ++ ++/* System header to define __stub macros and hopefully few prototypes, ++ which can conflict with char $2 (); below. ++ Prefer to if __STDC__ is defined, since ++ exists even on freestanding compilers. */ ++ ++#ifdef __STDC__ ++# include ++#else ++# include ++#endif ++ ++#undef $2 ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char $2 (); ++/* The GNU C library defines this for functions which it implements ++ to always fail with ENOSYS. Some functions are actually named ++ something starting with __ and the normal name is an alias. */ ++#if defined __stub_$2 || defined __stub___$2 ++choke me ++#endif ++ ++int ++main () ++{ ++return $2 (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ eval "$3=yes" ++else ++ eval "$3=no" ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++fi ++eval ac_res=\$$3 ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 ++$as_echo "$ac_res" >&6; } ++ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} ++ ++} # ac_fn_c_check_func ++cat >config.log <<_ACEOF ++This file contains any messages produced by compilers while ++running configure, to aid debugging if configure makes a mistake. ++ ++It was created by newlib $as_me 1.19.0, which was ++generated by GNU Autoconf 2.65. Invocation command line was ++ ++ $ $0 $@ ++ ++_ACEOF ++exec 5>>config.log ++{ ++cat <<_ASUNAME ++## --------- ## ++## Platform. ## ++## --------- ## ++ ++hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` ++uname -m = `(uname -m) 2>/dev/null || echo unknown` ++uname -r = `(uname -r) 2>/dev/null || echo unknown` ++uname -s = `(uname -s) 2>/dev/null || echo unknown` ++uname -v = `(uname -v) 2>/dev/null || echo unknown` ++ ++/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` ++/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` ++ ++/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` ++/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` ++/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` ++/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` ++/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` ++/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` ++/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` ++ ++_ASUNAME ++ ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ $as_echo "PATH: $as_dir" ++ done ++IFS=$as_save_IFS ++ ++} >&5 ++ ++cat >&5 <<_ACEOF ++ ++ ++## ----------- ## ++## Core tests. ## ++## ----------- ## ++ ++_ACEOF ++ ++ ++# Keep a trace of the command line. ++# Strip out --no-create and --no-recursion so they do not pile up. ++# Strip out --silent because we don't want to record it for future runs. ++# Also quote any args containing shell meta-characters. ++# Make two passes to allow for proper duplicate-argument suppression. ++ac_configure_args= ++ac_configure_args0= ++ac_configure_args1= ++ac_must_keep_next=false ++for ac_pass in 1 2 ++do ++ for ac_arg ++ do ++ case $ac_arg in ++ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; ++ -q | -quiet | --quiet | --quie | --qui | --qu | --q \ ++ | -silent | --silent | --silen | --sile | --sil) ++ continue ;; ++ *\'*) ++ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; ++ esac ++ case $ac_pass in ++ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; ++ 2) ++ as_fn_append ac_configure_args1 " '$ac_arg'" ++ if test $ac_must_keep_next = true; then ++ ac_must_keep_next=false # Got value, back to normal. ++ else ++ case $ac_arg in ++ *=* | --config-cache | -C | -disable-* | --disable-* \ ++ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ ++ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ ++ | -with-* | --with-* | -without-* | --without-* | --x) ++ case "$ac_configure_args0 " in ++ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; ++ esac ++ ;; ++ -* ) ac_must_keep_next=true ;; ++ esac ++ fi ++ as_fn_append ac_configure_args " '$ac_arg'" ++ ;; ++ esac ++ done ++done ++{ ac_configure_args0=; unset ac_configure_args0;} ++{ ac_configure_args1=; unset ac_configure_args1;} ++ ++# When interrupted or exit'd, cleanup temporary files, and complete ++# config.log. We remove comments because anyway the quotes in there ++# would cause problems or look ugly. ++# WARNING: Use '\'' to represent an apostrophe within the trap. ++# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. ++trap 'exit_status=$? ++ # Save into config.log some information that might help in debugging. ++ { ++ echo ++ ++ cat <<\_ASBOX ++## ---------------- ## ++## Cache variables. ## ++## ---------------- ## ++_ASBOX ++ echo ++ # The following way of writing the cache mishandles newlines in values, ++( ++ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do ++ eval ac_val=\$$ac_var ++ case $ac_val in #( ++ *${as_nl}*) ++ case $ac_var in #( ++ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 ++$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; ++ esac ++ case $ac_var in #( ++ _ | IFS | as_nl) ;; #( ++ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( ++ *) { eval $ac_var=; unset $ac_var;} ;; ++ esac ;; ++ esac ++ done ++ (set) 2>&1 | ++ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( ++ *${as_nl}ac_space=\ *) ++ sed -n \ ++ "s/'\''/'\''\\\\'\'''\''/g; ++ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ++ ;; #( ++ *) ++ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ++ ;; ++ esac | ++ sort ++) ++ echo ++ ++ cat <<\_ASBOX ++## ----------------- ## ++## Output variables. ## ++## ----------------- ## ++_ASBOX ++ echo ++ for ac_var in $ac_subst_vars ++ do ++ eval ac_val=\$$ac_var ++ case $ac_val in ++ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; ++ esac ++ $as_echo "$ac_var='\''$ac_val'\''" ++ done | sort ++ echo ++ ++ if test -n "$ac_subst_files"; then ++ cat <<\_ASBOX ++## ------------------- ## ++## File substitutions. ## ++## ------------------- ## ++_ASBOX ++ echo ++ for ac_var in $ac_subst_files ++ do ++ eval ac_val=\$$ac_var ++ case $ac_val in ++ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; ++ esac ++ $as_echo "$ac_var='\''$ac_val'\''" ++ done | sort ++ echo ++ fi ++ ++ if test -s confdefs.h; then ++ cat <<\_ASBOX ++## ----------- ## ++## confdefs.h. ## ++## ----------- ## ++_ASBOX ++ echo ++ cat confdefs.h ++ echo ++ fi ++ test "$ac_signal" != 0 && ++ $as_echo "$as_me: caught signal $ac_signal" ++ $as_echo "$as_me: exit $exit_status" ++ } >&5 ++ rm -f core *.core core.conftest.* && ++ rm -f -r conftest* confdefs* conf$$* $ac_clean_files && ++ exit $exit_status ++' 0 ++for ac_signal in 1 2 13 15; do ++ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal ++done ++ac_signal=0 ++ ++# confdefs.h avoids OS command line length limits that DEFS can exceed. ++rm -f -r conftest* confdefs.h ++ ++$as_echo "/* confdefs.h */" > confdefs.h ++ ++# Predefined preprocessor variables. ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE_NAME "$PACKAGE_NAME" ++_ACEOF ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE_TARNAME "$PACKAGE_TARNAME" ++_ACEOF ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE_VERSION "$PACKAGE_VERSION" ++_ACEOF ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE_STRING "$PACKAGE_STRING" ++_ACEOF ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" ++_ACEOF ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE_URL "$PACKAGE_URL" ++_ACEOF ++ ++ ++# Let the site file select an alternate cache file if it wants to. ++# Prefer an explicitly selected file to automatically selected ones. ++ac_site_file1=NONE ++ac_site_file2=NONE ++if test -n "$CONFIG_SITE"; then ++ ac_site_file1=$CONFIG_SITE ++elif test "x$prefix" != xNONE; then ++ ac_site_file1=$prefix/share/config.site ++ ac_site_file2=$prefix/etc/config.site ++else ++ ac_site_file1=$ac_default_prefix/share/config.site ++ ac_site_file2=$ac_default_prefix/etc/config.site ++fi ++for ac_site_file in "$ac_site_file1" "$ac_site_file2" ++do ++ test "x$ac_site_file" = xNONE && continue ++ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 ++$as_echo "$as_me: loading site script $ac_site_file" >&6;} ++ sed 's/^/| /' "$ac_site_file" >&5 ++ . "$ac_site_file" ++ fi ++done ++ ++if test -r "$cache_file"; then ++ # Some versions of bash will fail to source /dev/null (special files ++ # actually), so we avoid doing that. DJGPP emulates it as a regular file. ++ if test /dev/null != "$cache_file" && test -f "$cache_file"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 ++$as_echo "$as_me: loading cache $cache_file" >&6;} ++ case $cache_file in ++ [\\/]* | ?:[\\/]* ) . "$cache_file";; ++ *) . "./$cache_file";; ++ esac ++ fi ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 ++$as_echo "$as_me: creating cache $cache_file" >&6;} ++ >$cache_file ++fi ++ ++# Check that the precious variables saved in the cache have kept the same ++# value. ++ac_cache_corrupted=false ++for ac_var in $ac_precious_vars; do ++ eval ac_old_set=\$ac_cv_env_${ac_var}_set ++ eval ac_new_set=\$ac_env_${ac_var}_set ++ eval ac_old_val=\$ac_cv_env_${ac_var}_value ++ eval ac_new_val=\$ac_env_${ac_var}_value ++ case $ac_old_set,$ac_new_set in ++ set,) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 ++$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ++ ac_cache_corrupted=: ;; ++ ,set) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 ++$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ++ ac_cache_corrupted=: ;; ++ ,);; ++ *) ++ if test "x$ac_old_val" != "x$ac_new_val"; then ++ # differences in whitespace do not lead to failure. ++ ac_old_val_w=`echo x $ac_old_val` ++ ac_new_val_w=`echo x $ac_new_val` ++ if test "$ac_old_val_w" != "$ac_new_val_w"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 ++$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ++ ac_cache_corrupted=: ++ else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 ++$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} ++ eval $ac_var=\$ac_old_val ++ fi ++ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 ++$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} ++ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 ++$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} ++ fi;; ++ esac ++ # Pass precious variables to config.status. ++ if test "$ac_new_set" = set; then ++ case $ac_new_val in ++ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; ++ *) ac_arg=$ac_var=$ac_new_val ;; ++ esac ++ case " $ac_configure_args " in ++ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. ++ *) as_fn_append ac_configure_args " '$ac_arg'" ;; ++ esac ++ fi ++done ++if $ac_cache_corrupted; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 ++$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} ++ as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 ++fi ++## -------------------- ## ++## Main body of script. ## ++## -------------------- ## ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ ++ ++ ++ac_aux_dir= ++for ac_dir in ../../../.. "$srcdir"/../../../..; do ++ for ac_t in install-sh install.sh shtool; do ++ if test -f "$ac_dir/$ac_t"; then ++ ac_aux_dir=$ac_dir ++ ac_install_sh="$ac_aux_dir/$ac_t -c" ++ break 2 ++ fi ++ done ++done ++if test -z "$ac_aux_dir"; then ++ as_fn_error "cannot find install-sh, install.sh, or shtool in ../../../.. \"$srcdir\"/../../../.." "$LINENO" 5 ++fi ++ ++# These three variables are undocumented and unsupported, ++# and are intended to be withdrawn in a future Autoconf release. ++# They can cause serious problems if a builder's source tree is in a directory ++# whose full name contains unusual characters. ++ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ++ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ++ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. ++ ++ ++ ++ ++# Make sure we can run config.sub. ++$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || ++ as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 ++$as_echo_n "checking build system type... " >&6; } ++if test "${ac_cv_build+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_build_alias=$build_alias ++test "x$ac_build_alias" = x && ++ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` ++test "x$ac_build_alias" = x && ++ as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5 ++ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || ++ as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 ++$as_echo "$ac_cv_build" >&6; } ++case $ac_cv_build in ++*-*-*) ;; ++*) as_fn_error "invalid value of canonical build" "$LINENO" 5;; ++esac ++build=$ac_cv_build ++ac_save_IFS=$IFS; IFS='-' ++set x $ac_cv_build ++shift ++build_cpu=$1 ++build_vendor=$2 ++shift; shift ++# Remember, the first character of IFS is used to create $*, ++# except with old shells: ++build_os=$* ++IFS=$ac_save_IFS ++case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 ++$as_echo_n "checking host system type... " >&6; } ++if test "${ac_cv_host+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test "x$host_alias" = x; then ++ ac_cv_host=$ac_cv_build ++else ++ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || ++ as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 ++fi ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 ++$as_echo "$ac_cv_host" >&6; } ++case $ac_cv_host in ++*-*-*) ;; ++*) as_fn_error "invalid value of canonical host" "$LINENO" 5;; ++esac ++host=$ac_cv_host ++ac_save_IFS=$IFS; IFS='-' ++set x $ac_cv_host ++shift ++host_cpu=$1 ++host_vendor=$2 ++shift; shift ++# Remember, the first character of IFS is used to create $*, ++# except with old shells: ++host_os=$* ++IFS=$ac_save_IFS ++case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac ++ ++ ++am__api_version='1.11' ++ ++# Find a good install program. We prefer a C program (faster), ++# so one script is as good as another. But avoid the broken or ++# incompatible versions: ++# SysV /etc/install, /usr/sbin/install ++# SunOS /usr/etc/install ++# IRIX /sbin/install ++# AIX /bin/install ++# AmigaOS /C/install, which installs bootblocks on floppy discs ++# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag ++# AFS /usr/afsws/bin/install, which mishandles nonexistent args ++# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" ++# OS/2's system install, which has a completely different semantic ++# ./install, which can be erroneously created by make from ./install.sh. ++# Reject install programs that cannot install multiple files. ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 ++$as_echo_n "checking for a BSD-compatible install... " >&6; } ++if test -z "$INSTALL"; then ++if test "${ac_cv_path_install+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ # Account for people who put trailing slashes in PATH elements. ++case $as_dir/ in #(( ++ ./ | .// | /[cC]/* | \ ++ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ++ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ ++ /usr/ucb/* ) ;; ++ *) ++ # OSF1 and SCO ODT 3.0 have their own names for install. ++ # Don't use installbsd from OSF since it installs stuff as root ++ # by default. ++ for ac_prog in ginstall scoinst install; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then ++ if test $ac_prog = install && ++ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then ++ # AIX install. It has an incompatible calling convention. ++ : ++ elif test $ac_prog = install && ++ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then ++ # program-specific install script used by HP pwplus--don't use. ++ : ++ else ++ rm -rf conftest.one conftest.two conftest.dir ++ echo one > conftest.one ++ echo two > conftest.two ++ mkdir conftest.dir ++ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && ++ test -s conftest.one && test -s conftest.two && ++ test -s conftest.dir/conftest.one && ++ test -s conftest.dir/conftest.two ++ then ++ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" ++ break 3 ++ fi ++ fi ++ fi ++ done ++ done ++ ;; ++esac ++ ++ done ++IFS=$as_save_IFS ++ ++rm -rf conftest.one conftest.two conftest.dir ++ ++fi ++ if test "${ac_cv_path_install+set}" = set; then ++ INSTALL=$ac_cv_path_install ++ else ++ # As a last resort, use the slow shell script. Don't cache a ++ # value for INSTALL within a source directory, because that will ++ # break other packages using the cache if that directory is ++ # removed, or if the value is a relative name. ++ INSTALL=$ac_install_sh ++ fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 ++$as_echo "$INSTALL" >&6; } ++ ++# Use test -z because SunOS4 sh mishandles braces in ${var-val}. ++# It thinks the first close brace ends the variable substitution. ++test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' ++ ++test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' ++ ++test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 ++$as_echo_n "checking whether build environment is sane... " >&6; } ++# Just in case ++sleep 1 ++echo timestamp > conftest.file ++# Reject unsafe characters in $srcdir or the absolute working directory ++# name. Accept space and tab only in the latter. ++am_lf=' ++' ++case `pwd` in ++ *[\\\"\#\$\&\'\`$am_lf]*) ++ as_fn_error "unsafe absolute working directory name" "$LINENO" 5;; ++esac ++case $srcdir in ++ *[\\\"\#\$\&\'\`$am_lf\ \ ]*) ++ as_fn_error "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; ++esac ++ ++# Do `set' in a subshell so we don't clobber the current shell's ++# arguments. Must try -L first in case configure is actually a ++# symlink; some systems play weird games with the mod time of symlinks ++# (eg FreeBSD returns the mod time of the symlink's containing ++# directory). ++if ( ++ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` ++ if test "$*" = "X"; then ++ # -L didn't work. ++ set X `ls -t "$srcdir/configure" conftest.file` ++ fi ++ rm -f conftest.file ++ if test "$*" != "X $srcdir/configure conftest.file" \ ++ && test "$*" != "X conftest.file $srcdir/configure"; then ++ ++ # If neither matched, then we have a broken ls. This can happen ++ # if, for instance, CONFIG_SHELL is bash and it inherits a ++ # broken ls alias from the environment. This has actually ++ # happened. Such a system could not be considered "sane". ++ as_fn_error "ls -t appears to fail. Make sure there is not a broken ++alias in your environment" "$LINENO" 5 ++ fi ++ ++ test "$2" = conftest.file ++ ) ++then ++ # Ok. ++ : ++else ++ as_fn_error "newly created file is older than distributed files! ++Check your system clock" "$LINENO" 5 ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++test "$program_prefix" != NONE && ++ program_transform_name="s&^&$program_prefix&;$program_transform_name" ++# Use a double $ so make ignores it. ++test "$program_suffix" != NONE && ++ program_transform_name="s&\$&$program_suffix&;$program_transform_name" ++# Double any \ or $. ++# By default was `s,x,x', remove it if useless. ++ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' ++program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` ++ ++# expand $ac_aux_dir to an absolute path ++am_aux_dir=`cd $ac_aux_dir && pwd` ++ ++if test x"${MISSING+set}" != xset; then ++ case $am_aux_dir in ++ *\ * | *\ *) ++ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; ++ *) ++ MISSING="\${SHELL} $am_aux_dir/missing" ;; ++ esac ++fi ++# Use eval to expand $SHELL ++if eval "$MISSING --run true"; then ++ am_missing_run="$MISSING --run " ++else ++ am_missing_run= ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 ++$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} ++fi ++ ++if test x"${install_sh}" != xset; then ++ case $am_aux_dir in ++ *\ * | *\ *) ++ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; ++ *) ++ install_sh="\${SHELL} $am_aux_dir/install-sh" ++ esac ++fi ++ ++# Installed binaries are usually stripped using `strip' when the user ++# run `make install-strip'. However `strip' might not be the right ++# tool to use in cross-compilation environments, therefore Automake ++# will honor the `STRIP' environment variable to overrule this program. ++if test "$cross_compiling" != no; then ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. ++set dummy ${ac_tool_prefix}strip; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_STRIP+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$STRIP"; then ++ ac_cv_prog_STRIP="$STRIP" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_STRIP="${ac_tool_prefix}strip" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++STRIP=$ac_cv_prog_STRIP ++if test -n "$STRIP"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 ++$as_echo "$STRIP" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_STRIP"; then ++ ac_ct_STRIP=$STRIP ++ # Extract the first word of "strip", so it can be a program name with args. ++set dummy strip; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_STRIP"; then ++ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_ac_ct_STRIP="strip" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP ++if test -n "$ac_ct_STRIP"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 ++$as_echo "$ac_ct_STRIP" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_STRIP" = x; then ++ STRIP=":" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ STRIP=$ac_ct_STRIP ++ fi ++else ++ STRIP="$ac_cv_prog_STRIP" ++fi ++ ++fi ++INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 ++$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } ++if test -z "$MKDIR_P"; then ++ if test "${ac_cv_path_mkdir+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_prog in mkdir gmkdir; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue ++ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( ++ 'mkdir (GNU coreutils) '* | \ ++ 'mkdir (coreutils) '* | \ ++ 'mkdir (fileutils) '4.1*) ++ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext ++ break 3;; ++ esac ++ done ++ done ++ done ++IFS=$as_save_IFS ++ ++fi ++ ++ test -d ./--version && rmdir ./--version ++ if test "${ac_cv_path_mkdir+set}" = set; then ++ MKDIR_P="$ac_cv_path_mkdir -p" ++ else ++ # As a last resort, use the slow shell script. Don't cache a ++ # value for MKDIR_P within a source directory, because that will ++ # break other packages using the cache if that directory is ++ # removed, or if the value is a relative name. ++ MKDIR_P="$ac_install_sh -d" ++ fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 ++$as_echo "$MKDIR_P" >&6; } ++ ++mkdir_p="$MKDIR_P" ++case $mkdir_p in ++ [\\/$]* | ?:[\\/]*) ;; ++ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; ++esac ++ ++for ac_prog in gawk mawk nawk awk ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_AWK+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$AWK"; then ++ ac_cv_prog_AWK="$AWK" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_AWK="$ac_prog" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++AWK=$ac_cv_prog_AWK ++if test -n "$AWK"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 ++$as_echo "$AWK" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ test -n "$AWK" && break ++done ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 ++$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } ++set x ${MAKE-make} ++ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` ++if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat >conftest.make <<\_ACEOF ++SHELL = /bin/sh ++all: ++ @echo '@@@%%%=$(MAKE)=@@@%%%' ++_ACEOF ++# GNU make sometimes prints "make[1]: Entering...", which would confuse us. ++case `${MAKE-make} -f conftest.make 2>/dev/null` in ++ *@@@%%%=?*=@@@%%%*) ++ eval ac_cv_prog_make_${ac_make}_set=yes;; ++ *) ++ eval ac_cv_prog_make_${ac_make}_set=no;; ++esac ++rm -f conftest.make ++fi ++if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++ SET_MAKE= ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ SET_MAKE="MAKE=${MAKE-make}" ++fi ++ ++rm -rf .tst 2>/dev/null ++mkdir .tst 2>/dev/null ++if test -d .tst; then ++ am__leading_dot=. ++else ++ am__leading_dot=_ ++fi ++rmdir .tst 2>/dev/null ++ ++DEPDIR="${am__leading_dot}deps" ++ ++ac_config_commands="$ac_config_commands depfiles" ++ ++ ++am_make=${MAKE-make} ++cat > confinc << 'END' ++am__doit: ++ @echo this is the am__doit target ++.PHONY: am__doit ++END ++# If we don't find an include directive, just comment out the code. ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 ++$as_echo_n "checking for style of include used by $am_make... " >&6; } ++am__include="#" ++am__quote= ++_am_result=none ++# First try GNU make style include. ++echo "include confinc" > confmf ++# Ignore all kinds of additional output from `make'. ++case `$am_make -s -f confmf 2> /dev/null` in #( ++*the\ am__doit\ target*) ++ am__include=include ++ am__quote= ++ _am_result=GNU ++ ;; ++esac ++# Now try BSD make style include. ++if test "$am__include" = "#"; then ++ echo '.include "confinc"' > confmf ++ case `$am_make -s -f confmf 2> /dev/null` in #( ++ *the\ am__doit\ target*) ++ am__include=.include ++ am__quote="\"" ++ _am_result=BSD ++ ;; ++ esac ++fi ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 ++$as_echo "$_am_result" >&6; } ++rm -f confinc confmf ++ ++# Check whether --enable-dependency-tracking was given. ++if test "${enable_dependency_tracking+set}" = set; then : ++ enableval=$enable_dependency_tracking; ++fi ++ ++if test "x$enable_dependency_tracking" != xno; then ++ am_depcomp="$ac_aux_dir/depcomp" ++ AMDEPBACKSLASH='\' ++fi ++ if test "x$enable_dependency_tracking" != xno; then ++ AMDEP_TRUE= ++ AMDEP_FALSE='#' ++else ++ AMDEP_TRUE='#' ++ AMDEP_FALSE= ++fi ++ ++ ++ ++# Check whether --enable-multilib was given. ++if test "${enable_multilib+set}" = set; then : ++ enableval=$enable_multilib; case "${enableval}" in ++ yes) multilib=yes ;; ++ no) multilib=no ;; ++ *) as_fn_error "bad value ${enableval} for multilib option" "$LINENO" 5 ;; ++ esac ++else ++ multilib=yes ++fi ++ ++# Check whether --enable-target-optspace was given. ++if test "${enable_target_optspace+set}" = set; then : ++ enableval=$enable_target_optspace; case "${enableval}" in ++ yes) target_optspace=yes ;; ++ no) target_optspace=no ;; ++ *) as_fn_error "bad value ${enableval} for target-optspace option" "$LINENO" 5 ;; ++ esac ++else ++ target_optspace= ++fi ++ ++# Check whether --enable-malloc-debugging was given. ++if test "${enable_malloc_debugging+set}" = set; then : ++ enableval=$enable_malloc_debugging; case "${enableval}" in ++ yes) malloc_debugging=yes ;; ++ no) malloc_debugging=no ;; ++ *) as_fn_error "bad value ${enableval} for malloc-debugging option" "$LINENO" 5 ;; ++ esac ++else ++ malloc_debugging= ++fi ++ ++# Check whether --enable-newlib-multithread was given. ++if test "${enable_newlib_multithread+set}" = set; then : ++ enableval=$enable_newlib_multithread; case "${enableval}" in ++ yes) newlib_multithread=yes ;; ++ no) newlib_multithread=no ;; ++ *) as_fn_error "bad value ${enableval} for newlib-multithread option" "$LINENO" 5 ;; ++ esac ++else ++ newlib_multithread=yes ++fi ++ ++# Check whether --enable-newlib-iconv was given. ++if test "${enable_newlib_iconv+set}" = set; then : ++ enableval=$enable_newlib_iconv; if test "${newlib_iconv+set}" != set; then ++ case "${enableval}" in ++ yes) newlib_iconv=yes ;; ++ no) newlib_iconv=no ;; ++ *) as_fn_error "bad value ${enableval} for newlib-iconv option" "$LINENO" 5 ;; ++ esac ++ fi ++else ++ newlib_iconv=${newlib_iconv} ++fi ++ ++# Check whether --enable-newlib-elix-level was given. ++if test "${enable_newlib_elix_level+set}" = set; then : ++ enableval=$enable_newlib_elix_level; case "${enableval}" in ++ 0) newlib_elix_level=0 ;; ++ 1) newlib_elix_level=1 ;; ++ 2) newlib_elix_level=2 ;; ++ 3) newlib_elix_level=3 ;; ++ 4) newlib_elix_level=4 ;; ++ *) as_fn_error "bad value ${enableval} for newlib-elix-level option" "$LINENO" 5 ;; ++ esac ++else ++ newlib_elix_level=0 ++fi ++ ++# Check whether --enable-newlib-io-float was given. ++if test "${enable_newlib_io_float+set}" = set; then : ++ enableval=$enable_newlib_io_float; case "${enableval}" in ++ yes) newlib_io_float=yes ;; ++ no) newlib_io_float=no ;; ++ *) as_fn_error "bad value ${enableval} for newlib-io-float option" "$LINENO" 5 ;; ++ esac ++else ++ newlib_io_float=yes ++fi ++ ++# Check whether --enable-newlib-supplied-syscalls was given. ++if test "${enable_newlib_supplied_syscalls+set}" = set; then : ++ enableval=$enable_newlib_supplied_syscalls; case "${enableval}" in ++ yes) newlib_may_supply_syscalls=yes ;; ++ no) newlib_may_supply_syscalls=no ;; ++ *) as_fn_error "bad value ${enableval} for newlib-supplied-syscalls option" "$LINENO" 5 ;; ++ esac ++else ++ newlib_may_supply_syscalls=yes ++fi ++ ++ if test x${newlib_may_supply_syscalls} = xyes; then ++ MAY_SUPPLY_SYSCALLS_TRUE= ++ MAY_SUPPLY_SYSCALLS_FALSE='#' ++else ++ MAY_SUPPLY_SYSCALLS_TRUE='#' ++ MAY_SUPPLY_SYSCALLS_FALSE= ++fi ++ ++ ++ ++test -z "${with_target_subdir}" && with_target_subdir=. ++ ++if test "${srcdir}" = "."; then ++ if test "${with_target_subdir}" != "."; then ++ newlib_basedir="${srcdir}/${with_multisrctop}../../../.." ++ else ++ newlib_basedir="${srcdir}/${with_multisrctop}../../.." ++ fi ++else ++ newlib_basedir="${srcdir}/../../.." ++fi ++ ++ ++ ++ ++if test "`cd $srcdir && pwd`" != "`pwd`"; then ++ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output ++ # is not polluted with repeated "-I." ++ am__isrc=' -I$(srcdir)' ++ # test to see if srcdir already configured ++ if test -f $srcdir/config.status; then ++ as_fn_error "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 ++ fi ++fi ++ ++# test whether we have cygpath ++if test -z "$CYGPATH_W"; then ++ if (cygpath --version) >/dev/null 2>/dev/null; then ++ CYGPATH_W='cygpath -w' ++ else ++ CYGPATH_W=echo ++ fi ++fi ++ ++ ++# Define the identity of the package. ++ PACKAGE='newlib' ++ VERSION='1.19.0' ++ ++ ++# Some tools Automake needs. ++ ++ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} ++ ++ ++AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} ++ ++ ++AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} ++ ++ ++AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} ++ ++ ++MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} ++ ++# We need awk for the "check" target. The system "awk" is bad on ++# some platforms. ++# Always define AMTAR for backward compatibility. ++ ++AMTAR=${AMTAR-"${am_missing_run}tar"} ++ ++am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' ++ ++ ++ ++ ++ ++ ++# FIXME: We temporarily define our own version of AC_PROG_CC. This is ++# copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We ++# are probably using a cross compiler, which will not be able to fully ++# link an executable. This should really be fixed in autoconf ++# itself. ++ ++ ++ ++ ++ ++ ++ ++# Extract the first word of "gcc", so it can be a program name with args. ++set dummy gcc; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_CC+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$CC"; then ++ ac_cv_prog_CC="$CC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_CC="gcc" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++CC=$ac_cv_prog_CC ++if test -n "$CC"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 ++$as_echo "$CC" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ ++depcc="$CC" am_compiler_list= ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 ++$as_echo_n "checking dependency style of $depcc... " >&6; } ++if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then ++ # We make a subdir and do the tests there. Otherwise we can end up ++ # making bogus files that we don't know about and never remove. For ++ # instance it was reported that on HP-UX the gcc test will end up ++ # making a dummy file named `D' -- because `-MD' means `put the output ++ # in D'. ++ mkdir conftest.dir ++ # Copy depcomp to subdir because otherwise we won't find it if we're ++ # using a relative directory. ++ cp "$am_depcomp" conftest.dir ++ cd conftest.dir ++ # We will build objects and dependencies in a subdirectory because ++ # it helps to detect inapplicable dependency modes. For instance ++ # both Tru64's cc and ICC support -MD to output dependencies as a ++ # side effect of compilation, but ICC will put the dependencies in ++ # the current directory while Tru64 will put them in the object ++ # directory. ++ mkdir sub ++ ++ am_cv_CC_dependencies_compiler_type=none ++ if test "$am_compiler_list" = ""; then ++ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` ++ fi ++ am__universal=false ++ case " $depcc " in #( ++ *\ -arch\ *\ -arch\ *) am__universal=true ;; ++ esac ++ ++ for depmode in $am_compiler_list; do ++ # Setup a source with many dependencies, because some compilers ++ # like to wrap large dependency lists on column 80 (with \), and ++ # we should not choose a depcomp mode which is confused by this. ++ # ++ # We need to recreate these files for each test, as the compiler may ++ # overwrite some of them when testing with obscure command lines. ++ # This happens at least with the AIX C compiler. ++ : > sub/conftest.c ++ for i in 1 2 3 4 5 6; do ++ echo '#include "conftst'$i'.h"' >> sub/conftest.c ++ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with ++ # Solaris 8's {/usr,}/bin/sh. ++ touch sub/conftst$i.h ++ done ++ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf ++ ++ # We check with `-c' and `-o' for the sake of the "dashmstdout" ++ # mode. It turns out that the SunPro C++ compiler does not properly ++ # handle `-M -o', and we need to detect this. Also, some Intel ++ # versions had trouble with output in subdirs ++ am__obj=sub/conftest.${OBJEXT-o} ++ am__minus_obj="-o $am__obj" ++ case $depmode in ++ gcc) ++ # This depmode causes a compiler race in universal mode. ++ test "$am__universal" = false || continue ++ ;; ++ nosideeffect) ++ # after this tag, mechanisms are not by side-effect, so they'll ++ # only be used when explicitly requested ++ if test "x$enable_dependency_tracking" = xyes; then ++ continue ++ else ++ break ++ fi ++ ;; ++ msvisualcpp | msvcmsys) ++ # This compiler won't grok `-c -o', but also, the minuso test has ++ # not run yet. These depmodes are late enough in the game, and ++ # so weak that their functioning should not be impacted. ++ am__obj=conftest.${OBJEXT-o} ++ am__minus_obj= ++ ;; ++ none) break ;; ++ esac ++ if depmode=$depmode \ ++ source=sub/conftest.c object=$am__obj \ ++ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ ++ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ ++ >/dev/null 2>conftest.err && ++ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && ++ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && ++ grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ++ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then ++ # icc doesn't choke on unknown options, it will just issue warnings ++ # or remarks (even with -Werror). So we grep stderr for any message ++ # that says an option was ignored or not supported. ++ # When given -MP, icc 7.0 and 7.1 complain thusly: ++ # icc: Command line warning: ignoring option '-M'; no argument required ++ # The diagnosis changed in icc 8.0: ++ # icc: Command line remark: option '-MP' not supported ++ if (grep 'ignoring option' conftest.err || ++ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else ++ am_cv_CC_dependencies_compiler_type=$depmode ++ break ++ fi ++ fi ++ done ++ ++ cd .. ++ rm -rf conftest.dir ++else ++ am_cv_CC_dependencies_compiler_type=none ++fi ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 ++$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } ++CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type ++ ++ if ++ test "x$enable_dependency_tracking" != xno \ ++ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then ++ am__fastdepCC_TRUE= ++ am__fastdepCC_FALSE='#' ++else ++ am__fastdepCC_TRUE='#' ++ am__fastdepCC_FALSE= ++fi ++ ++ ++if test -z "$CC"; then ++ # Extract the first word of "cc", so it can be a program name with args. ++set dummy cc; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_CC+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$CC"; then ++ ac_cv_prog_CC="$CC" # Let the user override the test. ++else ++ ac_prog_rejected=no ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ++ ac_prog_rejected=yes ++ continue ++ fi ++ ac_cv_prog_CC="cc" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++if test $ac_prog_rejected = yes; then ++ # We found a bogon in the path, so make sure we never use it. ++ set dummy $ac_cv_prog_CC ++ shift ++ if test $# != 0; then ++ # We chose a different compiler from the bogus one. ++ # However, it has the same basename, so the bogon will be chosen ++ # first if we set CC to just the basename; use the full file name. ++ shift ++ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" ++ fi ++fi ++fi ++fi ++CC=$ac_cv_prog_CC ++if test -n "$CC"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 ++$as_echo "$CC" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ test -z "$CC" && as_fn_error "no acceptable cc found in \$PATH" "$LINENO" 5 ++fi ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using GNU C" >&5 ++$as_echo_n "checking whether we are using GNU C... " >&6; } ++if test "${ac_cv_c_compiler_gnu+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat > conftest.c <&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; } | egrep yes >/dev/null 2>&1; then ++ ac_cv_c_compiler_gnu=yes ++else ++ ac_cv_c_compiler_gnu=no ++fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 ++$as_echo "$ac_cv_c_compiler_gnu" >&6; } ++ ++if test $ac_cv_c_compiler_gnu = yes; then ++ GCC=yes ++ ac_test_CFLAGS="${CFLAGS+set}" ++ ac_save_CFLAGS="$CFLAGS" ++ ac_test_CFLAGS=${CFLAGS+set} ++ac_save_CFLAGS=$CFLAGS ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 ++$as_echo_n "checking whether $CC accepts -g... " >&6; } ++if test "${ac_cv_prog_cc_g+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_save_c_werror_flag=$ac_c_werror_flag ++ ac_c_werror_flag=yes ++ ac_cv_prog_cc_g=no ++ CFLAGS="-g" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_cv_prog_cc_g=yes ++else ++ CFLAGS="" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ++else ++ ac_c_werror_flag=$ac_save_c_werror_flag ++ CFLAGS="-g" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_cv_prog_cc_g=yes ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ ac_c_werror_flag=$ac_save_c_werror_flag ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 ++$as_echo "$ac_cv_prog_cc_g" >&6; } ++if test "$ac_test_CFLAGS" = set; then ++ CFLAGS=$ac_save_CFLAGS ++elif test $ac_cv_prog_cc_g = yes; then ++ if test "$GCC" = yes; then ++ CFLAGS="-g -O2" ++ else ++ CFLAGS="-g" ++ fi ++else ++ if test "$GCC" = yes; then ++ CFLAGS="-O2" ++ else ++ CFLAGS= ++ fi ++fi ++ if test "$ac_test_CFLAGS" = set; then ++ CFLAGS="$ac_save_CFLAGS" ++ elif test $ac_cv_prog_cc_g = yes; then ++ CFLAGS="-g -O2" ++ else ++ CFLAGS="-O2" ++ fi ++else ++ GCC= ++ test "${CFLAGS+set}" = set || CFLAGS="-g" ++fi ++ ++ ++if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. ++set dummy ${ac_tool_prefix}as; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_AS+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$AS"; then ++ ac_cv_prog_AS="$AS" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_AS="${ac_tool_prefix}as" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++AS=$ac_cv_prog_AS ++if test -n "$AS"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 ++$as_echo "$AS" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_AS"; then ++ ac_ct_AS=$AS ++ # Extract the first word of "as", so it can be a program name with args. ++set dummy as; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_ac_ct_AS+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_AS"; then ++ ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_ac_ct_AS="as" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_AS=$ac_cv_prog_ac_ct_AS ++if test -n "$ac_ct_AS"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 ++$as_echo "$ac_ct_AS" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_AS" = x; then ++ AS="" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ AS=$ac_ct_AS ++ fi ++else ++ AS="$ac_cv_prog_AS" ++fi ++ ++if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. ++set dummy ${ac_tool_prefix}ar; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_AR+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$AR"; then ++ ac_cv_prog_AR="$AR" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_AR="${ac_tool_prefix}ar" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++AR=$ac_cv_prog_AR ++if test -n "$AR"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 ++$as_echo "$AR" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_AR"; then ++ ac_ct_AR=$AR ++ # Extract the first word of "ar", so it can be a program name with args. ++set dummy ar; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_ac_ct_AR+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_AR"; then ++ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_ac_ct_AR="ar" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_AR=$ac_cv_prog_ac_ct_AR ++if test -n "$ac_ct_AR"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 ++$as_echo "$ac_ct_AR" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_AR" = x; then ++ AR="" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ AR=$ac_ct_AR ++ fi ++else ++ AR="$ac_cv_prog_AR" ++fi ++ ++if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. ++set dummy ${ac_tool_prefix}ranlib; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_RANLIB+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$RANLIB"; then ++ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++RANLIB=$ac_cv_prog_RANLIB ++if test -n "$RANLIB"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 ++$as_echo "$RANLIB" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_RANLIB"; then ++ ac_ct_RANLIB=$RANLIB ++ # Extract the first word of "ranlib", so it can be a program name with args. ++set dummy ranlib; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_RANLIB"; then ++ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_ac_ct_RANLIB="ranlib" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB ++if test -n "$ac_ct_RANLIB"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 ++$as_echo "$ac_ct_RANLIB" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_RANLIB" = x; then ++ RANLIB=":" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ RANLIB=$ac_ct_RANLIB ++ fi ++else ++ RANLIB="$ac_cv_prog_RANLIB" ++fi ++ ++if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}readelf", so it can be a program name with args. ++set dummy ${ac_tool_prefix}readelf; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_READELF+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$READELF"; then ++ ac_cv_prog_READELF="$READELF" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_READELF="${ac_tool_prefix}readelf" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++READELF=$ac_cv_prog_READELF ++if test -n "$READELF"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $READELF" >&5 ++$as_echo "$READELF" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_READELF"; then ++ ac_ct_READELF=$READELF ++ # Extract the first word of "readelf", so it can be a program name with args. ++set dummy readelf; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_ac_ct_READELF+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_READELF"; then ++ ac_cv_prog_ac_ct_READELF="$ac_ct_READELF" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_ac_ct_READELF="readelf" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_READELF=$ac_cv_prog_ac_ct_READELF ++if test -n "$ac_ct_READELF"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_READELF" >&5 ++$as_echo "$ac_ct_READELF" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_READELF" = x; then ++ READELF=":" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ READELF=$ac_ct_READELF ++ fi ++else ++ READELF="$ac_cv_prog_READELF" ++fi ++ ++ ++ ++ ++# Hack to ensure that INSTALL won't be set to "../" with autoconf 2.13. */ ++ac_given_INSTALL=$INSTALL ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 ++$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } ++ # Check whether --enable-maintainer-mode was given. ++if test "${enable_maintainer_mode+set}" = set; then : ++ enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval ++else ++ USE_MAINTAINER_MODE=no ++fi ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 ++$as_echo "$USE_MAINTAINER_MODE" >&6; } ++ if test $USE_MAINTAINER_MODE = yes; then ++ MAINTAINER_MODE_TRUE= ++ MAINTAINER_MODE_FALSE='#' ++else ++ MAINTAINER_MODE_TRUE='#' ++ MAINTAINER_MODE_FALSE= ++fi ++ ++ MAINT=$MAINTAINER_MODE_TRUE ++ ++ ++# By default we simply use the C compiler to build assembly code. ++ ++test "${CCAS+set}" = set || CCAS=$CC ++test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS ++ ++ ++ ++ ++# We need AC_EXEEXT to keep automake happy in cygnus mode. However, ++# at least currently, we never actually build a program, so we never ++# need to use $(EXEEXT). Moreover, the test for EXEEXT normally ++# fails, because we are probably configuring with a cross compiler ++# which can't create executables. So we include AC_EXEEXT to keep ++# automake happy, but we don't execute it, since we don't care about ++# the result. ++if false; then ++ ++ dummy_var=1 ++fi ++ ++. ${newlib_basedir}/configure.host ++ ++newlib_cflags="${newlib_cflags} -fno-builtin" ++ ++NEWLIB_CFLAGS=${newlib_cflags} ++ ++ ++LDFLAGS=${ldflags} ++ ++ ++ if test x${newlib_elix_level} = x0; then ++ ELIX_LEVEL_0_TRUE= ++ ELIX_LEVEL_0_FALSE='#' ++else ++ ELIX_LEVEL_0_TRUE='#' ++ ELIX_LEVEL_0_FALSE= ++fi ++ ++ if test x${newlib_elix_level} = x1; then ++ ELIX_LEVEL_1_TRUE= ++ ELIX_LEVEL_1_FALSE='#' ++else ++ ELIX_LEVEL_1_TRUE='#' ++ ELIX_LEVEL_1_FALSE= ++fi ++ ++ if test x${newlib_elix_level} = x2; then ++ ELIX_LEVEL_2_TRUE= ++ ELIX_LEVEL_2_FALSE='#' ++else ++ ELIX_LEVEL_2_TRUE='#' ++ ELIX_LEVEL_2_FALSE= ++fi ++ ++ if test x${newlib_elix_level} = x3; then ++ ELIX_LEVEL_3_TRUE= ++ ELIX_LEVEL_3_FALSE='#' ++else ++ ELIX_LEVEL_3_TRUE='#' ++ ELIX_LEVEL_3_FALSE= ++fi ++ ++ if test x${newlib_elix_level} = x4; then ++ ELIX_LEVEL_4_TRUE= ++ ELIX_LEVEL_4_FALSE='#' ++else ++ ELIX_LEVEL_4_TRUE='#' ++ ELIX_LEVEL_4_FALSE= ++fi ++ ++ ++ if test x${use_libtool} = xyes; then ++ USE_LIBTOOL_TRUE= ++ USE_LIBTOOL_FALSE='#' ++else ++ USE_LIBTOOL_TRUE='#' ++ USE_LIBTOOL_FALSE= ++fi ++ ++ ++# Hard-code OBJEXT. Normally it is set by AC_OBJEXT, but we ++# use oext, which is set in configure.host based on the target platform. ++OBJEXT=${oext} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 ++$as_echo_n "checking for a sed that does not truncate output... " >&6; } ++if test "${ac_cv_path_SED+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ ++ for ac_i in 1 2 3 4 5 6 7; do ++ ac_script="$ac_script$as_nl$ac_script" ++ done ++ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed ++ { ac_script=; unset ac_script;} ++ if test -z "$SED"; then ++ ac_path_SED_found=false ++ # Loop through the user's path and test for each of PROGNAME-LIST ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_prog in sed gsed; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" ++ { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue ++# Check for GNU ac_path_SED and select it if it is found. ++ # Check for GNU $ac_path_SED ++case `"$ac_path_SED" --version 2>&1` in ++*GNU*) ++ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; ++*) ++ ac_count=0 ++ $as_echo_n 0123456789 >"conftest.in" ++ while : ++ do ++ cat "conftest.in" "conftest.in" >"conftest.tmp" ++ mv "conftest.tmp" "conftest.in" ++ cp "conftest.in" "conftest.nl" ++ $as_echo '' >> "conftest.nl" ++ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break ++ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ++ as_fn_arith $ac_count + 1 && ac_count=$as_val ++ if test $ac_count -gt ${ac_path_SED_max-0}; then ++ # Best one so far, save it but keep looking for a better one ++ ac_cv_path_SED="$ac_path_SED" ++ ac_path_SED_max=$ac_count ++ fi ++ # 10*(2^10) chars as input seems more than enough ++ test $ac_count -gt 10 && break ++ done ++ rm -f conftest.in conftest.tmp conftest.nl conftest.out;; ++esac ++ ++ $ac_path_SED_found && break 3 ++ done ++ done ++ done ++IFS=$as_save_IFS ++ if test -z "$ac_cv_path_SED"; then ++ as_fn_error "no acceptable sed could be found in \$PATH" "$LINENO" 5 ++ fi ++else ++ ac_cv_path_SED=$SED ++fi ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 ++$as_echo "$ac_cv_path_SED" >&6; } ++ SED="$ac_cv_path_SED" ++ rm -f conftest.sed ++ ++test -z "$SED" && SED=sed ++Xsed="$SED -e 1s/^X//" ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++for ac_prog in gawk mawk nawk awk ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_AWK+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$AWK"; then ++ ac_cv_prog_AWK="$AWK" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_AWK="$ac_prog" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++AWK=$ac_cv_prog_AWK ++if test -n "$AWK"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 ++$as_echo "$AWK" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ test -n "$AWK" && break ++done ++ ++if test "${use_libtool}" = "yes"; then ++enable_win32_dll=yes ++ ++case $host in ++*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*) ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. ++set dummy ${ac_tool_prefix}as; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_AS+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$AS"; then ++ ac_cv_prog_AS="$AS" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_AS="${ac_tool_prefix}as" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++AS=$ac_cv_prog_AS ++if test -n "$AS"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 ++$as_echo "$AS" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_AS"; then ++ ac_ct_AS=$AS ++ # Extract the first word of "as", so it can be a program name with args. ++set dummy as; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_ac_ct_AS+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_AS"; then ++ ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_ac_ct_AS="as" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_AS=$ac_cv_prog_ac_ct_AS ++if test -n "$ac_ct_AS"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 ++$as_echo "$ac_ct_AS" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_AS" = x; then ++ AS="false" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ AS=$ac_ct_AS ++ fi ++else ++ AS="$ac_cv_prog_AS" ++fi ++ ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. ++set dummy ${ac_tool_prefix}dlltool; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_DLLTOOL+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$DLLTOOL"; then ++ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++DLLTOOL=$ac_cv_prog_DLLTOOL ++if test -n "$DLLTOOL"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 ++$as_echo "$DLLTOOL" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_DLLTOOL"; then ++ ac_ct_DLLTOOL=$DLLTOOL ++ # Extract the first word of "dlltool", so it can be a program name with args. ++set dummy dlltool; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_ac_ct_DLLTOOL+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_DLLTOOL"; then ++ ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_ac_ct_DLLTOOL="dlltool" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL ++if test -n "$ac_ct_DLLTOOL"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 ++$as_echo "$ac_ct_DLLTOOL" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_DLLTOOL" = x; then ++ DLLTOOL="false" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ DLLTOOL=$ac_ct_DLLTOOL ++ fi ++else ++ DLLTOOL="$ac_cv_prog_DLLTOOL" ++fi ++ ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. ++set dummy ${ac_tool_prefix}objdump; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_OBJDUMP+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$OBJDUMP"; then ++ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++OBJDUMP=$ac_cv_prog_OBJDUMP ++if test -n "$OBJDUMP"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 ++$as_echo "$OBJDUMP" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_OBJDUMP"; then ++ ac_ct_OBJDUMP=$OBJDUMP ++ # Extract the first word of "objdump", so it can be a program name with args. ++set dummy objdump; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_OBJDUMP"; then ++ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_ac_ct_OBJDUMP="objdump" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP ++if test -n "$ac_ct_OBJDUMP"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 ++$as_echo "$ac_ct_OBJDUMP" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_OBJDUMP" = x; then ++ OBJDUMP="false" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ OBJDUMP=$ac_ct_OBJDUMP ++ fi ++else ++ OBJDUMP="$ac_cv_prog_OBJDUMP" ++fi ++ ++ ;; ++esac ++ ++test -z "$AS" && AS=as ++ ++ ++ ++ ++ ++test -z "$DLLTOOL" && DLLTOOL=dlltool ++ ++ ++ ++ ++ ++test -z "$OBJDUMP" && OBJDUMP=objdump ++ ++ ++ ++ ++ ++ ++ ++case `pwd` in ++ *\ * | *\ *) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 ++$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; ++esac ++ ++ ++ ++macro_version='2.2.6b' ++macro_revision='1.3017' ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ltmain="$ac_aux_dir/ltmain.sh" ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. ++set dummy ${ac_tool_prefix}gcc; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_CC+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$CC"; then ++ ac_cv_prog_CC="$CC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_CC="${ac_tool_prefix}gcc" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++CC=$ac_cv_prog_CC ++if test -n "$CC"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 ++$as_echo "$CC" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_CC"; then ++ ac_ct_CC=$CC ++ # Extract the first word of "gcc", so it can be a program name with args. ++set dummy gcc; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_CC"; then ++ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_ac_ct_CC="gcc" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_CC=$ac_cv_prog_ac_ct_CC ++if test -n "$ac_ct_CC"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 ++$as_echo "$ac_ct_CC" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_CC" = x; then ++ CC="" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ CC=$ac_ct_CC ++ fi ++else ++ CC="$ac_cv_prog_CC" ++fi ++ ++if test -z "$CC"; then ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. ++set dummy ${ac_tool_prefix}cc; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_CC+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$CC"; then ++ ac_cv_prog_CC="$CC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_CC="${ac_tool_prefix}cc" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++CC=$ac_cv_prog_CC ++if test -n "$CC"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 ++$as_echo "$CC" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ fi ++fi ++if test -z "$CC"; then ++ # Extract the first word of "cc", so it can be a program name with args. ++set dummy cc; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_CC+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$CC"; then ++ ac_cv_prog_CC="$CC" # Let the user override the test. ++else ++ ac_prog_rejected=no ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ++ ac_prog_rejected=yes ++ continue ++ fi ++ ac_cv_prog_CC="cc" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++if test $ac_prog_rejected = yes; then ++ # We found a bogon in the path, so make sure we never use it. ++ set dummy $ac_cv_prog_CC ++ shift ++ if test $# != 0; then ++ # We chose a different compiler from the bogus one. ++ # However, it has the same basename, so the bogon will be chosen ++ # first if we set CC to just the basename; use the full file name. ++ shift ++ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" ++ fi ++fi ++fi ++fi ++CC=$ac_cv_prog_CC ++if test -n "$CC"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 ++$as_echo "$CC" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$CC"; then ++ if test -n "$ac_tool_prefix"; then ++ for ac_prog in cl.exe ++ do ++ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. ++set dummy $ac_tool_prefix$ac_prog; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_CC+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$CC"; then ++ ac_cv_prog_CC="$CC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_CC="$ac_tool_prefix$ac_prog" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++CC=$ac_cv_prog_CC ++if test -n "$CC"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 ++$as_echo "$CC" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ test -n "$CC" && break ++ done ++fi ++if test -z "$CC"; then ++ ac_ct_CC=$CC ++ for ac_prog in cl.exe ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_CC"; then ++ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_ac_ct_CC="$ac_prog" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_CC=$ac_cv_prog_ac_ct_CC ++if test -n "$ac_ct_CC"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 ++$as_echo "$ac_ct_CC" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ test -n "$ac_ct_CC" && break ++done ++ ++ if test "x$ac_ct_CC" = x; then ++ CC="" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ CC=$ac_ct_CC ++ fi ++fi ++ ++fi ++ ++ ++test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++as_fn_error "no acceptable C compiler found in \$PATH ++See \`config.log' for more details." "$LINENO" 5; } ++ ++# Provide some information about the compiler. ++$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 ++set X $ac_compile ++ac_compiler=$2 ++for ac_option in --version -v -V -qversion; do ++ { { ac_try="$ac_compiler $ac_option >&5" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_compiler $ac_option >&5") 2>conftest.err ++ ac_status=$? ++ if test -s conftest.err; then ++ sed '10a\ ++... rest of stderr output deleted ... ++ 10q' conftest.err >conftest.er1 ++ cat conftest.er1 >&5 ++ fi ++ rm -f conftest.er1 conftest.err ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } ++done ++ ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++ac_clean_files_save=$ac_clean_files ++ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" ++# Try to create an executable without -o first, disregard a.out. ++# It will help us diagnose broken compilers, and finding out an intuition ++# of exeext. ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 ++$as_echo_n "checking whether the C compiler works... " >&6; } ++ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` ++ ++# The possible output files: ++ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ++ ++ac_rmfiles= ++for ac_file in $ac_files ++do ++ case $ac_file in ++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; ++ * ) ac_rmfiles="$ac_rmfiles $ac_file";; ++ esac ++done ++rm -f $ac_rmfiles ++ ++if { { ac_try="$ac_link_default" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_link_default") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then : ++ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. ++# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' ++# in a Makefile. We should not override ac_cv_exeext if it was cached, ++# so that the user can short-circuit this test for compilers unknown to ++# Autoconf. ++for ac_file in $ac_files '' ++do ++ test -f "$ac_file" || continue ++ case $ac_file in ++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ++ ;; ++ [ab].out ) ++ # We found the default executable, but exeext='' is most ++ # certainly right. ++ break;; ++ *.* ) ++ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; ++ then :; else ++ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` ++ fi ++ # We set ac_cv_exeext here because the later test for it is not ++ # safe: cross compilers may not add the suffix if given an `-o' ++ # argument, so we may need to know it at that point already. ++ # Even if this section looks crufty: it has the advantage of ++ # actually working. ++ break;; ++ * ) ++ break;; ++ esac ++done ++test "$ac_cv_exeext" = no && ac_cv_exeext= ++ ++else ++ ac_file='' ++fi ++if test -z "$ac_file"; then : ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++$as_echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++{ as_fn_set_status 77 ++as_fn_error "C compiler cannot create executables ++See \`config.log' for more details." "$LINENO" 5; }; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 ++$as_echo_n "checking for C compiler default output file name... " >&6; } ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 ++$as_echo "$ac_file" >&6; } ++ac_exeext=$ac_cv_exeext ++ ++rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ++ac_clean_files=$ac_clean_files_save ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 ++$as_echo_n "checking for suffix of executables... " >&6; } ++if { { ac_try="$ac_link" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_link") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then : ++ # If both `conftest.exe' and `conftest' are `present' (well, observable) ++# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will ++# work properly (i.e., refer to `conftest.exe'), while it won't with ++# `rm'. ++for ac_file in conftest.exe conftest conftest.*; do ++ test -f "$ac_file" || continue ++ case $ac_file in ++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; ++ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` ++ break;; ++ * ) break;; ++ esac ++done ++else ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++as_fn_error "cannot compute suffix of executables: cannot compile and link ++See \`config.log' for more details." "$LINENO" 5; } ++fi ++rm -f conftest conftest$ac_cv_exeext ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 ++$as_echo "$ac_cv_exeext" >&6; } ++ ++rm -f conftest.$ac_ext ++EXEEXT=$ac_cv_exeext ++ac_exeext=$EXEEXT ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++int ++main () ++{ ++FILE *f = fopen ("conftest.out", "w"); ++ return ferror (f) || fclose (f) != 0; ++ ++ ; ++ return 0; ++} ++_ACEOF ++ac_clean_files="$ac_clean_files conftest.out" ++# Check that the compiler produces executables we can run. If not, either ++# the compiler is broken, or we cross compile. ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 ++$as_echo_n "checking whether we are cross compiling... " >&6; } ++if test "$cross_compiling" != yes; then ++ { { ac_try="$ac_link" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_link") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } ++ if { ac_try='./conftest$ac_cv_exeext' ++ { { case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_try") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; }; then ++ cross_compiling=no ++ else ++ if test "$cross_compiling" = maybe; then ++ cross_compiling=yes ++ else ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++as_fn_error "cannot run C compiled programs. ++If you meant to cross compile, use \`--host'. ++See \`config.log' for more details." "$LINENO" 5; } ++ fi ++ fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 ++$as_echo "$cross_compiling" >&6; } ++ ++rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ++ac_clean_files=$ac_clean_files_save ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 ++$as_echo_n "checking for suffix of object files... " >&6; } ++if test "${ac_cv_objext+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.o conftest.obj ++if { { ac_try="$ac_compile" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_compile") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then : ++ for ac_file in conftest.o conftest.obj conftest.*; do ++ test -f "$ac_file" || continue; ++ case $ac_file in ++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; ++ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` ++ break;; ++ esac ++done ++else ++ $as_echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++as_fn_error "cannot compute suffix of object files: cannot compile ++See \`config.log' for more details." "$LINENO" 5; } ++fi ++rm -f conftest.$ac_cv_objext conftest.$ac_ext ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 ++$as_echo "$ac_cv_objext" >&6; } ++OBJEXT=$ac_cv_objext ++ac_objext=$OBJEXT ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 ++$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } ++if test "${ac_cv_c_compiler_gnu+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++#ifndef __GNUC__ ++ choke me ++#endif ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_compiler_gnu=yes ++else ++ ac_compiler_gnu=no ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ac_cv_c_compiler_gnu=$ac_compiler_gnu ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 ++$as_echo "$ac_cv_c_compiler_gnu" >&6; } ++if test $ac_compiler_gnu = yes; then ++ GCC=yes ++else ++ GCC= ++fi ++ac_test_CFLAGS=${CFLAGS+set} ++ac_save_CFLAGS=$CFLAGS ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 ++$as_echo_n "checking whether $CC accepts -g... " >&6; } ++if test "${ac_cv_prog_cc_g+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_save_c_werror_flag=$ac_c_werror_flag ++ ac_c_werror_flag=yes ++ ac_cv_prog_cc_g=no ++ CFLAGS="-g" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_cv_prog_cc_g=yes ++else ++ CFLAGS="" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ++else ++ ac_c_werror_flag=$ac_save_c_werror_flag ++ CFLAGS="-g" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_cv_prog_cc_g=yes ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ ac_c_werror_flag=$ac_save_c_werror_flag ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 ++$as_echo "$ac_cv_prog_cc_g" >&6; } ++if test "$ac_test_CFLAGS" = set; then ++ CFLAGS=$ac_save_CFLAGS ++elif test $ac_cv_prog_cc_g = yes; then ++ if test "$GCC" = yes; then ++ CFLAGS="-g -O2" ++ else ++ CFLAGS="-g" ++ fi ++else ++ if test "$GCC" = yes; then ++ CFLAGS="-O2" ++ else ++ CFLAGS= ++ fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 ++$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } ++if test "${ac_cv_prog_cc_c89+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_cv_prog_cc_c89=no ++ac_save_CC=$CC ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++#include ++#include ++#include ++/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ ++struct buf { int x; }; ++FILE * (*rcsopen) (struct buf *, struct stat *, int); ++static char *e (p, i) ++ char **p; ++ int i; ++{ ++ return p[i]; ++} ++static char *f (char * (*g) (char **, int), char **p, ...) ++{ ++ char *s; ++ va_list v; ++ va_start (v,p); ++ s = g (p, va_arg (v,int)); ++ va_end (v); ++ return s; ++} ++ ++/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has ++ function prototypes and stuff, but not '\xHH' hex character constants. ++ These don't provoke an error unfortunately, instead are silently treated ++ as 'x'. The following induces an error, until -std is added to get ++ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an ++ array size at least. It's necessary to write '\x00'==0 to get something ++ that's true only with -std. */ ++int osf4_cc_array ['\x00' == 0 ? 1 : -1]; ++ ++/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters ++ inside strings and character constants. */ ++#define FOO(x) 'x' ++int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; ++ ++int test (int i, double x); ++struct s1 {int (*f) (int a);}; ++struct s2 {int (*f) (double a);}; ++int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); ++int argc; ++char **argv; ++int ++main () ++{ ++return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ++ ; ++ return 0; ++} ++_ACEOF ++for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ ++ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" ++do ++ CC="$ac_save_CC $ac_arg" ++ if ac_fn_c_try_compile "$LINENO"; then : ++ ac_cv_prog_cc_c89=$ac_arg ++fi ++rm -f core conftest.err conftest.$ac_objext ++ test "x$ac_cv_prog_cc_c89" != "xno" && break ++done ++rm -f conftest.$ac_ext ++CC=$ac_save_CC ++ ++fi ++# AC_CACHE_VAL ++case "x$ac_cv_prog_cc_c89" in ++ x) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 ++$as_echo "none needed" >&6; } ;; ++ xno) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 ++$as_echo "unsupported" >&6; } ;; ++ *) ++ CC="$CC $ac_cv_prog_cc_c89" ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 ++$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; ++esac ++if test "x$ac_cv_prog_cc_c89" != xno; then : ++ ++fi ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++depcc="$CC" am_compiler_list= ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 ++$as_echo_n "checking dependency style of $depcc... " >&6; } ++if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then ++ # We make a subdir and do the tests there. Otherwise we can end up ++ # making bogus files that we don't know about and never remove. For ++ # instance it was reported that on HP-UX the gcc test will end up ++ # making a dummy file named `D' -- because `-MD' means `put the output ++ # in D'. ++ mkdir conftest.dir ++ # Copy depcomp to subdir because otherwise we won't find it if we're ++ # using a relative directory. ++ cp "$am_depcomp" conftest.dir ++ cd conftest.dir ++ # We will build objects and dependencies in a subdirectory because ++ # it helps to detect inapplicable dependency modes. For instance ++ # both Tru64's cc and ICC support -MD to output dependencies as a ++ # side effect of compilation, but ICC will put the dependencies in ++ # the current directory while Tru64 will put them in the object ++ # directory. ++ mkdir sub ++ ++ am_cv_CC_dependencies_compiler_type=none ++ if test "$am_compiler_list" = ""; then ++ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` ++ fi ++ am__universal=false ++ case " $depcc " in #( ++ *\ -arch\ *\ -arch\ *) am__universal=true ;; ++ esac ++ ++ for depmode in $am_compiler_list; do ++ # Setup a source with many dependencies, because some compilers ++ # like to wrap large dependency lists on column 80 (with \), and ++ # we should not choose a depcomp mode which is confused by this. ++ # ++ # We need to recreate these files for each test, as the compiler may ++ # overwrite some of them when testing with obscure command lines. ++ # This happens at least with the AIX C compiler. ++ : > sub/conftest.c ++ for i in 1 2 3 4 5 6; do ++ echo '#include "conftst'$i'.h"' >> sub/conftest.c ++ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with ++ # Solaris 8's {/usr,}/bin/sh. ++ touch sub/conftst$i.h ++ done ++ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf ++ ++ # We check with `-c' and `-o' for the sake of the "dashmstdout" ++ # mode. It turns out that the SunPro C++ compiler does not properly ++ # handle `-M -o', and we need to detect this. Also, some Intel ++ # versions had trouble with output in subdirs ++ am__obj=sub/conftest.${OBJEXT-o} ++ am__minus_obj="-o $am__obj" ++ case $depmode in ++ gcc) ++ # This depmode causes a compiler race in universal mode. ++ test "$am__universal" = false || continue ++ ;; ++ nosideeffect) ++ # after this tag, mechanisms are not by side-effect, so they'll ++ # only be used when explicitly requested ++ if test "x$enable_dependency_tracking" = xyes; then ++ continue ++ else ++ break ++ fi ++ ;; ++ msvisualcpp | msvcmsys) ++ # This compiler won't grok `-c -o', but also, the minuso test has ++ # not run yet. These depmodes are late enough in the game, and ++ # so weak that their functioning should not be impacted. ++ am__obj=conftest.${OBJEXT-o} ++ am__minus_obj= ++ ;; ++ none) break ;; ++ esac ++ if depmode=$depmode \ ++ source=sub/conftest.c object=$am__obj \ ++ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ ++ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ ++ >/dev/null 2>conftest.err && ++ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && ++ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && ++ grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ++ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then ++ # icc doesn't choke on unknown options, it will just issue warnings ++ # or remarks (even with -Werror). So we grep stderr for any message ++ # that says an option was ignored or not supported. ++ # When given -MP, icc 7.0 and 7.1 complain thusly: ++ # icc: Command line warning: ignoring option '-M'; no argument required ++ # The diagnosis changed in icc 8.0: ++ # icc: Command line remark: option '-MP' not supported ++ if (grep 'ignoring option' conftest.err || ++ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else ++ am_cv_CC_dependencies_compiler_type=$depmode ++ break ++ fi ++ fi ++ done ++ ++ cd .. ++ rm -rf conftest.dir ++else ++ am_cv_CC_dependencies_compiler_type=none ++fi ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 ++$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } ++CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type ++ ++ if ++ test "x$enable_dependency_tracking" != xno \ ++ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then ++ am__fastdepCC_TRUE= ++ am__fastdepCC_FALSE='#' ++else ++ am__fastdepCC_TRUE='#' ++ am__fastdepCC_FALSE= ++fi ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 ++$as_echo_n "checking for grep that handles long lines and -e... " >&6; } ++if test "${ac_cv_path_GREP+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -z "$GREP"; then ++ ac_path_GREP_found=false ++ # Loop through the user's path and test for each of PROGNAME-LIST ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_prog in grep ggrep; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" ++ { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue ++# Check for GNU ac_path_GREP and select it if it is found. ++ # Check for GNU $ac_path_GREP ++case `"$ac_path_GREP" --version 2>&1` in ++*GNU*) ++ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; ++*) ++ ac_count=0 ++ $as_echo_n 0123456789 >"conftest.in" ++ while : ++ do ++ cat "conftest.in" "conftest.in" >"conftest.tmp" ++ mv "conftest.tmp" "conftest.in" ++ cp "conftest.in" "conftest.nl" ++ $as_echo 'GREP' >> "conftest.nl" ++ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break ++ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ++ as_fn_arith $ac_count + 1 && ac_count=$as_val ++ if test $ac_count -gt ${ac_path_GREP_max-0}; then ++ # Best one so far, save it but keep looking for a better one ++ ac_cv_path_GREP="$ac_path_GREP" ++ ac_path_GREP_max=$ac_count ++ fi ++ # 10*(2^10) chars as input seems more than enough ++ test $ac_count -gt 10 && break ++ done ++ rm -f conftest.in conftest.tmp conftest.nl conftest.out;; ++esac ++ ++ $ac_path_GREP_found && break 3 ++ done ++ done ++ done ++IFS=$as_save_IFS ++ if test -z "$ac_cv_path_GREP"; then ++ as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 ++ fi ++else ++ ac_cv_path_GREP=$GREP ++fi ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 ++$as_echo "$ac_cv_path_GREP" >&6; } ++ GREP="$ac_cv_path_GREP" ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 ++$as_echo_n "checking for egrep... " >&6; } ++if test "${ac_cv_path_EGREP+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 ++ then ac_cv_path_EGREP="$GREP -E" ++ else ++ if test -z "$EGREP"; then ++ ac_path_EGREP_found=false ++ # Loop through the user's path and test for each of PROGNAME-LIST ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_prog in egrep; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" ++ { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue ++# Check for GNU ac_path_EGREP and select it if it is found. ++ # Check for GNU $ac_path_EGREP ++case `"$ac_path_EGREP" --version 2>&1` in ++*GNU*) ++ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; ++*) ++ ac_count=0 ++ $as_echo_n 0123456789 >"conftest.in" ++ while : ++ do ++ cat "conftest.in" "conftest.in" >"conftest.tmp" ++ mv "conftest.tmp" "conftest.in" ++ cp "conftest.in" "conftest.nl" ++ $as_echo 'EGREP' >> "conftest.nl" ++ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break ++ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ++ as_fn_arith $ac_count + 1 && ac_count=$as_val ++ if test $ac_count -gt ${ac_path_EGREP_max-0}; then ++ # Best one so far, save it but keep looking for a better one ++ ac_cv_path_EGREP="$ac_path_EGREP" ++ ac_path_EGREP_max=$ac_count ++ fi ++ # 10*(2^10) chars as input seems more than enough ++ test $ac_count -gt 10 && break ++ done ++ rm -f conftest.in conftest.tmp conftest.nl conftest.out;; ++esac ++ ++ $ac_path_EGREP_found && break 3 ++ done ++ done ++ done ++IFS=$as_save_IFS ++ if test -z "$ac_cv_path_EGREP"; then ++ as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 ++ fi ++else ++ ac_cv_path_EGREP=$EGREP ++fi ++ ++ fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 ++$as_echo "$ac_cv_path_EGREP" >&6; } ++ EGREP="$ac_cv_path_EGREP" ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 ++$as_echo_n "checking for fgrep... " >&6; } ++if test "${ac_cv_path_FGREP+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 ++ then ac_cv_path_FGREP="$GREP -F" ++ else ++ if test -z "$FGREP"; then ++ ac_path_FGREP_found=false ++ # Loop through the user's path and test for each of PROGNAME-LIST ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_prog in fgrep; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" ++ { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue ++# Check for GNU ac_path_FGREP and select it if it is found. ++ # Check for GNU $ac_path_FGREP ++case `"$ac_path_FGREP" --version 2>&1` in ++*GNU*) ++ ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; ++*) ++ ac_count=0 ++ $as_echo_n 0123456789 >"conftest.in" ++ while : ++ do ++ cat "conftest.in" "conftest.in" >"conftest.tmp" ++ mv "conftest.tmp" "conftest.in" ++ cp "conftest.in" "conftest.nl" ++ $as_echo 'FGREP' >> "conftest.nl" ++ "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break ++ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ++ as_fn_arith $ac_count + 1 && ac_count=$as_val ++ if test $ac_count -gt ${ac_path_FGREP_max-0}; then ++ # Best one so far, save it but keep looking for a better one ++ ac_cv_path_FGREP="$ac_path_FGREP" ++ ac_path_FGREP_max=$ac_count ++ fi ++ # 10*(2^10) chars as input seems more than enough ++ test $ac_count -gt 10 && break ++ done ++ rm -f conftest.in conftest.tmp conftest.nl conftest.out;; ++esac ++ ++ $ac_path_FGREP_found && break 3 ++ done ++ done ++ done ++IFS=$as_save_IFS ++ if test -z "$ac_cv_path_FGREP"; then ++ as_fn_error "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 ++ fi ++else ++ ac_cv_path_FGREP=$FGREP ++fi ++ ++ fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 ++$as_echo "$ac_cv_path_FGREP" >&6; } ++ FGREP="$ac_cv_path_FGREP" ++ ++ ++test -z "$GREP" && GREP=grep ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++# Check whether --with-gnu-ld was given. ++if test "${with_gnu_ld+set}" = set; then : ++ withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes ++else ++ with_gnu_ld=no ++fi ++ ++ac_prog=ld ++if test "$GCC" = yes; then ++ # Check if gcc -print-prog-name=ld gives a path. ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 ++$as_echo_n "checking for ld used by $CC... " >&6; } ++ case $host in ++ *-*-mingw*) ++ # gcc leaves a trailing carriage return which upsets mingw ++ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; ++ *) ++ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; ++ esac ++ case $ac_prog in ++ # Accept absolute paths. ++ [\\/]* | ?:[\\/]*) ++ re_direlt='/[^/][^/]*/\.\./' ++ # Canonicalize the pathname of ld ++ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` ++ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ++ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` ++ done ++ test -z "$LD" && LD="$ac_prog" ++ ;; ++ "") ++ # If it fails, then pretend we aren't using GCC. ++ ac_prog=ld ++ ;; ++ *) ++ # If it is relative, then search for the first ld in PATH. ++ with_gnu_ld=unknown ++ ;; ++ esac ++elif test "$with_gnu_ld" = yes; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 ++$as_echo_n "checking for GNU ld... " >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 ++$as_echo_n "checking for non-GNU ld... " >&6; } ++fi ++if test "${lt_cv_path_LD+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -z "$LD"; then ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for ac_dir in $PATH; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then ++ lt_cv_path_LD="$ac_dir/$ac_prog" ++ # Check to see if the program is GNU ld. I'd rather use --version, ++ # but apparently some variants of GNU ld only accept -v. ++ # Break only if it was the GNU/non-GNU ld that we prefer. ++ case `"$lt_cv_path_LD" -v 2>&1 &5 ++$as_echo "$LD" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 ++$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } ++if test "${lt_cv_prog_gnu_ld+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ # I'd rather use --version here, but apparently some GNU lds only accept -v. ++case `$LD -v 2>&1 &5 ++$as_echo "$lt_cv_prog_gnu_ld" >&6; } ++with_gnu_ld=$lt_cv_prog_gnu_ld ++ ++ ++ ++ ++ ++ ++ ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 ++$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } ++if test "${lt_cv_path_NM+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$NM"; then ++ # Let the user override the test. ++ lt_cv_path_NM="$NM" ++else ++ lt_nm_to_check="${ac_tool_prefix}nm" ++ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then ++ lt_nm_to_check="$lt_nm_to_check nm" ++ fi ++ for lt_tmp_nm in $lt_nm_to_check; do ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ tmp_nm="$ac_dir/$lt_tmp_nm" ++ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then ++ # Check to see if the nm accepts a BSD-compat flag. ++ # Adding the `sed 1q' prevents false positives on HP-UX, which says: ++ # nm: unknown option "B" ignored ++ # Tru64's nm complains that /dev/null is an invalid object file ++ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in ++ */dev/null* | *'Invalid file or object type'*) ++ lt_cv_path_NM="$tmp_nm -B" ++ break ++ ;; ++ *) ++ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in ++ */dev/null*) ++ lt_cv_path_NM="$tmp_nm -p" ++ break ++ ;; ++ *) ++ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but ++ continue # so that we can try to find one that supports BSD flags ++ ;; ++ esac ++ ;; ++ esac ++ fi ++ done ++ IFS="$lt_save_ifs" ++ done ++ : ${lt_cv_path_NM=no} ++fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 ++$as_echo "$lt_cv_path_NM" >&6; } ++if test "$lt_cv_path_NM" != "no"; then ++ NM="$lt_cv_path_NM" ++else ++ # Didn't find any BSD compatible name lister, look for dumpbin. ++ if test -n "$ac_tool_prefix"; then ++ for ac_prog in "dumpbin -symbols" "link -dump -symbols" ++ do ++ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. ++set dummy $ac_tool_prefix$ac_prog; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_DUMPBIN+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$DUMPBIN"; then ++ ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++DUMPBIN=$ac_cv_prog_DUMPBIN ++if test -n "$DUMPBIN"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 ++$as_echo "$DUMPBIN" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ test -n "$DUMPBIN" && break ++ done ++fi ++if test -z "$DUMPBIN"; then ++ ac_ct_DUMPBIN=$DUMPBIN ++ for ac_prog in "dumpbin -symbols" "link -dump -symbols" ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_DUMPBIN"; then ++ ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN ++if test -n "$ac_ct_DUMPBIN"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 ++$as_echo "$ac_ct_DUMPBIN" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ test -n "$ac_ct_DUMPBIN" && break ++done ++ ++ if test "x$ac_ct_DUMPBIN" = x; then ++ DUMPBIN=":" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ DUMPBIN=$ac_ct_DUMPBIN ++ fi ++fi ++ ++ ++ if test "$DUMPBIN" != ":"; then ++ NM="$DUMPBIN" ++ fi ++fi ++test -z "$NM" && NM=nm ++ ++ ++ ++ ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 ++$as_echo_n "checking the name lister ($NM) interface... " >&6; } ++if test "${lt_cv_nm_interface+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_nm_interface="BSD nm" ++ echo "int some_variable = 0;" > conftest.$ac_ext ++ (eval echo "\"\$as_me:5891: $ac_compile\"" >&5) ++ (eval "$ac_compile" 2>conftest.err) ++ cat conftest.err >&5 ++ (eval echo "\"\$as_me:5894: $NM \\\"conftest.$ac_objext\\\"\"" >&5) ++ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) ++ cat conftest.err >&5 ++ (eval echo "\"\$as_me:5897: output\"" >&5) ++ cat conftest.out >&5 ++ if $GREP 'External.*some_variable' conftest.out > /dev/null; then ++ lt_cv_nm_interface="MS dumpbin" ++ fi ++ rm -f conftest* ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 ++$as_echo "$lt_cv_nm_interface" >&6; } ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 ++$as_echo_n "checking whether ln -s works... " >&6; } ++LN_S=$as_ln_s ++if test "$LN_S" = "ln -s"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 ++$as_echo "no, using $LN_S" >&6; } ++fi ++ ++# find the maximum length of command line arguments ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 ++$as_echo_n "checking the maximum length of command line arguments... " >&6; } ++if test "${lt_cv_sys_max_cmd_len+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ i=0 ++ teststring="ABCD" ++ ++ case $build_os in ++ msdosdjgpp*) ++ # On DJGPP, this test can blow up pretty badly due to problems in libc ++ # (any single argument exceeding 2000 bytes causes a buffer overrun ++ # during glob expansion). Even if it were fixed, the result of this ++ # check would be larger than it should be. ++ lt_cv_sys_max_cmd_len=12288; # 12K is about right ++ ;; ++ ++ gnu*) ++ # Under GNU Hurd, this test is not required because there is ++ # no limit to the length of command line arguments. ++ # Libtool will interpret -1 as no limit whatsoever ++ lt_cv_sys_max_cmd_len=-1; ++ ;; ++ ++ cygwin* | mingw* | cegcc*) ++ # On Win9x/ME, this test blows up -- it succeeds, but takes ++ # about 5 minutes as the teststring grows exponentially. ++ # Worse, since 9x/ME are not pre-emptively multitasking, ++ # you end up with a "frozen" computer, even though with patience ++ # the test eventually succeeds (with a max line length of 256k). ++ # Instead, let's just punt: use the minimum linelength reported by ++ # all of the supported platforms: 8192 (on NT/2K/XP). ++ lt_cv_sys_max_cmd_len=8192; ++ ;; ++ ++ amigaos*) ++ # On AmigaOS with pdksh, this test takes hours, literally. ++ # So we just punt and use a minimum line length of 8192. ++ lt_cv_sys_max_cmd_len=8192; ++ ;; ++ ++ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) ++ # This has been around since 386BSD, at least. Likely further. ++ if test -x /sbin/sysctl; then ++ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` ++ elif test -x /usr/sbin/sysctl; then ++ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` ++ else ++ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs ++ fi ++ # And add a safety zone ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ++ ;; ++ ++ interix*) ++ # We know the value 262144 and hardcode it with a safety zone (like BSD) ++ lt_cv_sys_max_cmd_len=196608 ++ ;; ++ ++ osf*) ++ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure ++ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not ++ # nice to cause kernel panics so lets avoid the loop below. ++ # First set a reasonable default. ++ lt_cv_sys_max_cmd_len=16384 ++ # ++ if test -x /sbin/sysconfig; then ++ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in ++ *1*) lt_cv_sys_max_cmd_len=-1 ;; ++ esac ++ fi ++ ;; ++ sco3.2v5*) ++ lt_cv_sys_max_cmd_len=102400 ++ ;; ++ sysv5* | sco5v6* | sysv4.2uw2*) ++ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` ++ if test -n "$kargmax"; then ++ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` ++ else ++ lt_cv_sys_max_cmd_len=32768 ++ fi ++ ;; ++ *) ++ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` ++ if test -n "$lt_cv_sys_max_cmd_len"; then ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ++ else ++ # Make teststring a little bigger before we do anything with it. ++ # a 1K string should be a reasonable start. ++ for i in 1 2 3 4 5 6 7 8 ; do ++ teststring=$teststring$teststring ++ done ++ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} ++ # If test is not a shell built-in, we'll probably end up computing a ++ # maximum length that is only half of the actual maximum length, but ++ # we can't tell. ++ while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ ++ = "XX$teststring$teststring"; } >/dev/null 2>&1 && ++ test $i != 17 # 1/2 MB should be enough ++ do ++ i=`expr $i + 1` ++ teststring=$teststring$teststring ++ done ++ # Only check the string length outside the loop. ++ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` ++ teststring= ++ # Add a significant safety factor because C++ compilers can tack on ++ # massive amounts of additional arguments before passing them to the ++ # linker. It appears as though 1/2 is a usable value. ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` ++ fi ++ ;; ++ esac ++ ++fi ++ ++if test -n $lt_cv_sys_max_cmd_len ; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 ++$as_echo "$lt_cv_sys_max_cmd_len" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 ++$as_echo "none" >&6; } ++fi ++max_cmd_len=$lt_cv_sys_max_cmd_len ++ ++ ++ ++ ++ ++ ++: ${CP="cp -f"} ++: ${MV="mv -f"} ++: ${RM="rm -f"} ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 ++$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } ++# Try some XSI features ++xsi_shell=no ++( _lt_dummy="a/b/c" ++ test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ ++ = c,a/b,, \ ++ && eval 'test $(( 1 + 1 )) -eq 2 \ ++ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ ++ && xsi_shell=yes ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 ++$as_echo "$xsi_shell" >&6; } ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 ++$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } ++lt_shell_append=no ++( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ ++ >/dev/null 2>&1 \ ++ && lt_shell_append=yes ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 ++$as_echo "$lt_shell_append" >&6; } ++ ++ ++if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then ++ lt_unset=unset ++else ++ lt_unset=false ++fi ++ ++ ++ ++ ++ ++# test EBCDIC or ASCII ++case `echo X|tr X '\101'` in ++ A) # ASCII based system ++ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr ++ lt_SP2NL='tr \040 \012' ++ lt_NL2SP='tr \015\012 \040\040' ++ ;; ++ *) # EBCDIC based system ++ lt_SP2NL='tr \100 \n' ++ lt_NL2SP='tr \r\n \100\100' ++ ;; ++esac ++ ++ ++ ++ ++ ++ ++ ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 ++$as_echo_n "checking for $LD option to reload object files... " >&6; } ++if test "${lt_cv_ld_reload_flag+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_ld_reload_flag='-r' ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 ++$as_echo "$lt_cv_ld_reload_flag" >&6; } ++reload_flag=$lt_cv_ld_reload_flag ++case $reload_flag in ++"" | " "*) ;; ++*) reload_flag=" $reload_flag" ;; ++esac ++reload_cmds='$LD$reload_flag -o $output$reload_objs' ++case $host_os in ++ darwin*) ++ if test "$GCC" = yes; then ++ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' ++ else ++ reload_cmds='$LD$reload_flag -o $output$reload_objs' ++ fi ++ ;; ++esac ++ ++ ++ ++ ++ ++ ++ ++ ++ ++if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. ++set dummy ${ac_tool_prefix}objdump; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_OBJDUMP+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$OBJDUMP"; then ++ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++OBJDUMP=$ac_cv_prog_OBJDUMP ++if test -n "$OBJDUMP"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 ++$as_echo "$OBJDUMP" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_OBJDUMP"; then ++ ac_ct_OBJDUMP=$OBJDUMP ++ # Extract the first word of "objdump", so it can be a program name with args. ++set dummy objdump; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_OBJDUMP"; then ++ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_ac_ct_OBJDUMP="objdump" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP ++if test -n "$ac_ct_OBJDUMP"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 ++$as_echo "$ac_ct_OBJDUMP" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_OBJDUMP" = x; then ++ OBJDUMP="false" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ OBJDUMP=$ac_ct_OBJDUMP ++ fi ++else ++ OBJDUMP="$ac_cv_prog_OBJDUMP" ++fi ++ ++test -z "$OBJDUMP" && OBJDUMP=objdump ++ ++ ++ ++ ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 ++$as_echo_n "checking how to recognize dependent libraries... " >&6; } ++if test "${lt_cv_deplibs_check_method+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_file_magic_cmd='$MAGIC_CMD' ++lt_cv_file_magic_test_file= ++lt_cv_deplibs_check_method='unknown' ++# Need to set the preceding variable on all platforms that support ++# interlibrary dependencies. ++# 'none' -- dependencies not supported. ++# `unknown' -- same as none, but documents that we really don't know. ++# 'pass_all' -- all dependencies passed with no checks. ++# 'test_compile' -- check by making test program. ++# 'file_magic [[regex]]' -- check by looking for files in library path ++# which responds to the $file_magic_cmd with a given extended regex. ++# If you have `file' or equivalent on your system and you're not sure ++# whether `pass_all' will *always* work, you probably want this one. ++ ++case $host_os in ++aix[4-9]*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++beos*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++bsdi[45]*) ++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' ++ lt_cv_file_magic_cmd='/usr/bin/file -L' ++ lt_cv_file_magic_test_file=/shlib/libc.so ++ ;; ++ ++cygwin*) ++ # func_win32_libid is a shell function defined in ltmain.sh ++ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' ++ lt_cv_file_magic_cmd='func_win32_libid' ++ ;; ++ ++mingw* | pw32*) ++ # Base MSYS/MinGW do not provide the 'file' command needed by ++ # func_win32_libid shell function, so use a weaker test based on 'objdump', ++ # unless we find 'file', for example because we are cross-compiling. ++ if ( file / ) >/dev/null 2>&1; then ++ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' ++ lt_cv_file_magic_cmd='func_win32_libid' ++ else ++ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' ++ lt_cv_file_magic_cmd='$OBJDUMP -f' ++ fi ++ ;; ++ ++cegcc) ++ # use the weaker test based on 'objdump'. See mingw*. ++ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' ++ lt_cv_file_magic_cmd='$OBJDUMP -f' ++ ;; ++ ++darwin* | rhapsody*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++freebsd* | dragonfly*) ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then ++ case $host_cpu in ++ i*86 ) ++ # Not sure whether the presence of OpenBSD here was a mistake. ++ # Let's accept both of them until this is cleared up. ++ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' ++ lt_cv_file_magic_cmd=/usr/bin/file ++ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ++ ;; ++ esac ++ else ++ lt_cv_deplibs_check_method=pass_all ++ fi ++ ;; ++ ++gnu*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++hpux10.20* | hpux11*) ++ lt_cv_file_magic_cmd=/usr/bin/file ++ case $host_cpu in ++ ia64*) ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' ++ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ++ ;; ++ hppa*64*) ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' ++ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ++ ;; ++ *) ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' ++ lt_cv_file_magic_test_file=/usr/lib/libc.sl ++ ;; ++ esac ++ ;; ++ ++interix[3-9]*) ++ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here ++ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ++ ;; ++ ++irix5* | irix6* | nonstopux*) ++ case $LD in ++ *-32|*"-32 ") libmagic=32-bit;; ++ *-n32|*"-n32 ") libmagic=N32;; ++ *-64|*"-64 ") libmagic=64-bit;; ++ *) libmagic=never-match;; ++ esac ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++# This must be Linux ELF. ++linux* | k*bsd*-gnu | kopensolaris*-gnu) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++netbsd* | netbsdelf*-gnu) ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then ++ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' ++ else ++ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' ++ fi ++ ;; ++ ++newos6*) ++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' ++ lt_cv_file_magic_cmd=/usr/bin/file ++ lt_cv_file_magic_test_file=/usr/lib/libnls.so ++ ;; ++ ++*nto* | *qnx*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++openbsd*) ++ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' ++ else ++ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' ++ fi ++ ;; ++ ++osf3* | osf4* | osf5*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++rdos*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++solaris*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++sysv4 | sysv4.3*) ++ case $host_vendor in ++ motorola) ++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' ++ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ++ ;; ++ ncr) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ sequent) ++ lt_cv_file_magic_cmd='/bin/file' ++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ++ ;; ++ sni) ++ lt_cv_file_magic_cmd='/bin/file' ++ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" ++ lt_cv_file_magic_test_file=/lib/libc.so ++ ;; ++ siemens) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ pc) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ esac ++ ;; ++ ++tpf*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++esac ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 ++$as_echo "$lt_cv_deplibs_check_method" >&6; } ++file_magic_cmd=$lt_cv_file_magic_cmd ++deplibs_check_method=$lt_cv_deplibs_check_method ++test -z "$deplibs_check_method" && deplibs_check_method=unknown ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. ++set dummy ${ac_tool_prefix}ar; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_AR+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$AR"; then ++ ac_cv_prog_AR="$AR" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_AR="${ac_tool_prefix}ar" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++AR=$ac_cv_prog_AR ++if test -n "$AR"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 ++$as_echo "$AR" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_AR"; then ++ ac_ct_AR=$AR ++ # Extract the first word of "ar", so it can be a program name with args. ++set dummy ar; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_ac_ct_AR+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_AR"; then ++ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_ac_ct_AR="ar" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_AR=$ac_cv_prog_ac_ct_AR ++if test -n "$ac_ct_AR"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 ++$as_echo "$ac_ct_AR" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_AR" = x; then ++ AR="false" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ AR=$ac_ct_AR ++ fi ++else ++ AR="$ac_cv_prog_AR" ++fi ++ ++test -z "$AR" && AR=ar ++test -z "$AR_FLAGS" && AR_FLAGS=cru ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. ++set dummy ${ac_tool_prefix}strip; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_STRIP+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$STRIP"; then ++ ac_cv_prog_STRIP="$STRIP" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_STRIP="${ac_tool_prefix}strip" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++STRIP=$ac_cv_prog_STRIP ++if test -n "$STRIP"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 ++$as_echo "$STRIP" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_STRIP"; then ++ ac_ct_STRIP=$STRIP ++ # Extract the first word of "strip", so it can be a program name with args. ++set dummy strip; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_STRIP"; then ++ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_ac_ct_STRIP="strip" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP ++if test -n "$ac_ct_STRIP"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 ++$as_echo "$ac_ct_STRIP" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_STRIP" = x; then ++ STRIP=":" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ STRIP=$ac_ct_STRIP ++ fi ++else ++ STRIP="$ac_cv_prog_STRIP" ++fi ++ ++test -z "$STRIP" && STRIP=: ++ ++ ++ ++ ++ ++ ++if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. ++set dummy ${ac_tool_prefix}ranlib; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_RANLIB+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$RANLIB"; then ++ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++RANLIB=$ac_cv_prog_RANLIB ++if test -n "$RANLIB"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 ++$as_echo "$RANLIB" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_RANLIB"; then ++ ac_ct_RANLIB=$RANLIB ++ # Extract the first word of "ranlib", so it can be a program name with args. ++set dummy ranlib; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_RANLIB"; then ++ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_ac_ct_RANLIB="ranlib" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB ++if test -n "$ac_ct_RANLIB"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 ++$as_echo "$ac_ct_RANLIB" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_RANLIB" = x; then ++ RANLIB=":" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ RANLIB=$ac_ct_RANLIB ++ fi ++else ++ RANLIB="$ac_cv_prog_RANLIB" ++fi ++ ++test -z "$RANLIB" && RANLIB=: ++ ++ ++ ++ ++ ++ ++# Determine commands to create old-style static archives. ++old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' ++old_postinstall_cmds='chmod 644 $oldlib' ++old_postuninstall_cmds= ++ ++if test -n "$RANLIB"; then ++ case $host_os in ++ openbsd*) ++ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ++ ;; ++ *) ++ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ++ ;; ++ esac ++ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" ++fi ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++# If no C compiler was specified, use CC. ++LTCC=${LTCC-"$CC"} ++ ++# If no C compiler flags were specified, use CFLAGS. ++LTCFLAGS=${LTCFLAGS-"$CFLAGS"} ++ ++# Allow CC to be a program name with arguments. ++compiler=$CC ++ ++ ++# Check for command to grab the raw symbol name followed by C symbol from nm. ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 ++$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } ++if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ++# These are sane defaults that work on at least a few old systems. ++# [They come from Ultrix. What could be older than Ultrix?!! ;)] ++ ++# Character class describing NM global symbol codes. ++symcode='[BCDEGRST]' ++ ++# Regexp to match symbols that can be accessed directly from C. ++sympat='\([_A-Za-z][_A-Za-z0-9]*\)' ++ ++# Define system-specific variables. ++case $host_os in ++aix*) ++ symcode='[BCDT]' ++ ;; ++cygwin* | mingw* | pw32* | cegcc*) ++ symcode='[ABCDGISTW]' ++ ;; ++hpux*) ++ if test "$host_cpu" = ia64; then ++ symcode='[ABCDEGRST]' ++ fi ++ ;; ++irix* | nonstopux*) ++ symcode='[BCDEGRST]' ++ ;; ++osf*) ++ symcode='[BCDEGQRST]' ++ ;; ++solaris*) ++ symcode='[BDRT]' ++ ;; ++sco3.2v5*) ++ symcode='[DT]' ++ ;; ++sysv4.2uw2*) ++ symcode='[DT]' ++ ;; ++sysv5* | sco5v6* | unixware* | OpenUNIX*) ++ symcode='[ABDT]' ++ ;; ++sysv4) ++ symcode='[DFNSTU]' ++ ;; ++esac ++ ++# If we're using GNU nm, then use its standard symbol codes. ++case `$NM -V 2>&1` in ++*GNU* | *'with BFD'*) ++ symcode='[ABCDGIRSTW]' ;; ++esac ++ ++# Transform an extracted symbol line into a proper C declaration. ++# Some systems (esp. on ia64) link data and code symbols differently, ++# so use this general approach. ++lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" ++ ++# Transform an extracted symbol line into symbol name and symbol address ++lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" ++lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" ++ ++# Handle CRLF in mingw tool chain ++opt_cr= ++case $build_os in ++mingw*) ++ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ++ ;; ++esac ++ ++# Try without a prefix underscore, then with it. ++for ac_symprfx in "" "_"; do ++ ++ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. ++ symxfrm="\\1 $ac_symprfx\\2 \\2" ++ ++ # Write the raw and C identifiers. ++ if test "$lt_cv_nm_interface" = "MS dumpbin"; then ++ # Fake it for dumpbin and say T for any non-static function ++ # and D for any global variable. ++ # Also find C++ and __fastcall symbols from MSVC++, ++ # which start with @ or ?. ++ lt_cv_sys_global_symbol_pipe="$AWK '"\ ++" {last_section=section; section=\$ 3};"\ ++" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ ++" \$ 0!~/External *\|/{next};"\ ++" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ ++" {if(hide[section]) next};"\ ++" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ ++" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ ++" s[1]~/^[@?]/{print s[1], s[1]; next};"\ ++" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ ++" ' prfx=^$ac_symprfx" ++ else ++ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" ++ fi ++ ++ # Check to see that the pipe works correctly. ++ pipe_works=no ++ ++ rm -f conftest* ++ cat > conftest.$ac_ext <<_LT_EOF ++#ifdef __cplusplus ++extern "C" { ++#endif ++char nm_test_var; ++void nm_test_func(void); ++void nm_test_func(void){} ++#ifdef __cplusplus ++} ++#endif ++int main(){nm_test_var='a';nm_test_func();return(0);} ++_LT_EOF ++ ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ # Now try to grab the symbols. ++ nlist=conftest.nm ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5 ++ (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && test -s "$nlist"; then ++ # Try sorting and uniquifying the output. ++ if sort "$nlist" | uniq > "$nlist"T; then ++ mv -f "$nlist"T "$nlist" ++ else ++ rm -f "$nlist"T ++ fi ++ ++ # Make sure that we snagged all the symbols we need. ++ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then ++ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then ++ cat <<_LT_EOF > conftest.$ac_ext ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++_LT_EOF ++ # Now generate the symbol file. ++ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' ++ ++ cat <<_LT_EOF >> conftest.$ac_ext ++ ++/* The mapping between symbol names and symbols. */ ++const struct { ++ const char *name; ++ void *address; ++} ++lt__PROGRAM__LTX_preloaded_symbols[] = ++{ ++ { "@PROGRAM@", (void *) 0 }, ++_LT_EOF ++ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext ++ cat <<\_LT_EOF >> conftest.$ac_ext ++ {0, (void *) 0} ++}; ++ ++/* This works around a problem in FreeBSD linker */ ++#ifdef FREEBSD_WORKAROUND ++static const void *lt_preloaded_setup() { ++ return lt__PROGRAM__LTX_preloaded_symbols; ++} ++#endif ++ ++#ifdef __cplusplus ++} ++#endif ++_LT_EOF ++ # Now try linking the two files. ++ mv conftest.$ac_objext conftstm.$ac_objext ++ lt_save_LIBS="$LIBS" ++ lt_save_CFLAGS="$CFLAGS" ++ LIBS="conftstm.$ac_objext" ++ CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 ++ (eval $ac_link) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && test -s conftest${ac_exeext}; then ++ pipe_works=yes ++ fi ++ LIBS="$lt_save_LIBS" ++ CFLAGS="$lt_save_CFLAGS" ++ else ++ echo "cannot find nm_test_func in $nlist" >&5 ++ fi ++ else ++ echo "cannot find nm_test_var in $nlist" >&5 ++ fi ++ else ++ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 ++ fi ++ else ++ echo "$progname: failed program was:" >&5 ++ cat conftest.$ac_ext >&5 ++ fi ++ rm -rf conftest* conftst* ++ ++ # Do not use the global_symbol_pipe unless it works. ++ if test "$pipe_works" = yes; then ++ break ++ else ++ lt_cv_sys_global_symbol_pipe= ++ fi ++done ++ ++fi ++ ++if test -z "$lt_cv_sys_global_symbol_pipe"; then ++ lt_cv_sys_global_symbol_to_cdecl= ++fi ++if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 ++$as_echo "failed" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 ++$as_echo "ok" >&6; } ++fi ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++# Check whether --enable-libtool-lock was given. ++if test "${enable_libtool_lock+set}" = set; then : ++ enableval=$enable_libtool_lock; ++fi ++ ++test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes ++ ++# Some flags need to be propagated to the compiler or linker for good ++# libtool support. ++case $host in ++ia64-*-hpux*) ++ # Find out which ABI we are using. ++ echo 'int i;' > conftest.$ac_ext ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ case `/usr/bin/file conftest.$ac_objext` in ++ *ELF-32*) ++ HPUX_IA64_MODE="32" ++ ;; ++ *ELF-64*) ++ HPUX_IA64_MODE="64" ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++*-*-irix6*) ++ # Find out which ABI we are using. ++ echo '#line 7100 "configure"' > conftest.$ac_ext ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ if test "$lt_cv_prog_gnu_ld" = yes; then ++ case `/usr/bin/file conftest.$ac_objext` in ++ *32-bit*) ++ LD="${LD-ld} -melf32bsmip" ++ ;; ++ *N32*) ++ LD="${LD-ld} -melf32bmipn32" ++ ;; ++ *64-bit*) ++ LD="${LD-ld} -melf64bmip" ++ ;; ++ esac ++ else ++ case `/usr/bin/file conftest.$ac_objext` in ++ *32-bit*) ++ LD="${LD-ld} -32" ++ ;; ++ *N32*) ++ LD="${LD-ld} -n32" ++ ;; ++ *64-bit*) ++ LD="${LD-ld} -64" ++ ;; ++ esac ++ fi ++ fi ++ rm -rf conftest* ++ ;; ++ ++x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ ++s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ++ # Find out which ABI we are using. ++ echo 'int i;' > conftest.$ac_ext ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ case `/usr/bin/file conftest.o` in ++ *32-bit*) ++ case $host in ++ x86_64-*kfreebsd*-gnu) ++ LD="${LD-ld} -m elf_i386_fbsd" ++ ;; ++ x86_64-*linux*) ++ LD="${LD-ld} -m elf_i386" ++ ;; ++ ppc64-*linux*|powerpc64-*linux*) ++ LD="${LD-ld} -m elf32ppclinux" ++ ;; ++ s390x-*linux*) ++ LD="${LD-ld} -m elf_s390" ++ ;; ++ sparc64-*linux*) ++ LD="${LD-ld} -m elf32_sparc" ++ ;; ++ esac ++ ;; ++ *64-bit*) ++ case $host in ++ x86_64-*kfreebsd*-gnu) ++ LD="${LD-ld} -m elf_x86_64_fbsd" ++ ;; ++ x86_64-*linux*) ++ LD="${LD-ld} -m elf_x86_64" ++ ;; ++ ppc*-*linux*|powerpc*-*linux*) ++ LD="${LD-ld} -m elf64ppc" ++ ;; ++ s390*-*linux*|s390*-*tpf*) ++ LD="${LD-ld} -m elf64_s390" ++ ;; ++ sparc*-*linux*) ++ LD="${LD-ld} -m elf64_sparc" ++ ;; ++ esac ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++ ++*-*-sco3.2v5*) ++ # On SCO OpenServer 5, we need -belf to get full-featured binaries. ++ SAVE_CFLAGS="$CFLAGS" ++ CFLAGS="$CFLAGS -belf" ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 ++$as_echo_n "checking whether the C compiler needs -belf... " >&6; } ++if test "${lt_cv_cc_needs_belf+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ lt_cv_cc_needs_belf=yes ++else ++ lt_cv_cc_needs_belf=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++ ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 ++$as_echo "$lt_cv_cc_needs_belf" >&6; } ++ if test x"$lt_cv_cc_needs_belf" != x"yes"; then ++ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf ++ CFLAGS="$SAVE_CFLAGS" ++ fi ++ ;; ++sparc*-*solaris*) ++ # Find out which ABI we are using. ++ echo 'int i;' > conftest.$ac_ext ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ case `/usr/bin/file conftest.o` in ++ *64-bit*) ++ case $lt_cv_prog_gnu_ld in ++ yes*) LD="${LD-ld} -m elf64_sparc" ;; ++ *) ++ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then ++ LD="${LD-ld} -64" ++ fi ++ ;; ++ esac ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++esac ++ ++need_locks="$enable_libtool_lock" ++ ++ ++ case $host_os in ++ rhapsody* | darwin*) ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. ++set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_DSYMUTIL+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$DSYMUTIL"; then ++ ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++DSYMUTIL=$ac_cv_prog_DSYMUTIL ++if test -n "$DSYMUTIL"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 ++$as_echo "$DSYMUTIL" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_DSYMUTIL"; then ++ ac_ct_DSYMUTIL=$DSYMUTIL ++ # Extract the first word of "dsymutil", so it can be a program name with args. ++set dummy dsymutil; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_DSYMUTIL"; then ++ ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL ++if test -n "$ac_ct_DSYMUTIL"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 ++$as_echo "$ac_ct_DSYMUTIL" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_DSYMUTIL" = x; then ++ DSYMUTIL=":" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ DSYMUTIL=$ac_ct_DSYMUTIL ++ fi ++else ++ DSYMUTIL="$ac_cv_prog_DSYMUTIL" ++fi ++ ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. ++set dummy ${ac_tool_prefix}nmedit; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_NMEDIT+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$NMEDIT"; then ++ ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++NMEDIT=$ac_cv_prog_NMEDIT ++if test -n "$NMEDIT"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 ++$as_echo "$NMEDIT" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_NMEDIT"; then ++ ac_ct_NMEDIT=$NMEDIT ++ # Extract the first word of "nmedit", so it can be a program name with args. ++set dummy nmedit; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_NMEDIT"; then ++ ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_ac_ct_NMEDIT="nmedit" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT ++if test -n "$ac_ct_NMEDIT"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 ++$as_echo "$ac_ct_NMEDIT" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_NMEDIT" = x; then ++ NMEDIT=":" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ NMEDIT=$ac_ct_NMEDIT ++ fi ++else ++ NMEDIT="$ac_cv_prog_NMEDIT" ++fi ++ ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. ++set dummy ${ac_tool_prefix}lipo; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_LIPO+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$LIPO"; then ++ ac_cv_prog_LIPO="$LIPO" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_LIPO="${ac_tool_prefix}lipo" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++LIPO=$ac_cv_prog_LIPO ++if test -n "$LIPO"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 ++$as_echo "$LIPO" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_LIPO"; then ++ ac_ct_LIPO=$LIPO ++ # Extract the first word of "lipo", so it can be a program name with args. ++set dummy lipo; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_LIPO"; then ++ ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_ac_ct_LIPO="lipo" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO ++if test -n "$ac_ct_LIPO"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 ++$as_echo "$ac_ct_LIPO" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_LIPO" = x; then ++ LIPO=":" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ LIPO=$ac_ct_LIPO ++ fi ++else ++ LIPO="$ac_cv_prog_LIPO" ++fi ++ ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. ++set dummy ${ac_tool_prefix}otool; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_OTOOL+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$OTOOL"; then ++ ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_OTOOL="${ac_tool_prefix}otool" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++OTOOL=$ac_cv_prog_OTOOL ++if test -n "$OTOOL"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 ++$as_echo "$OTOOL" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_OTOOL"; then ++ ac_ct_OTOOL=$OTOOL ++ # Extract the first word of "otool", so it can be a program name with args. ++set dummy otool; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_OTOOL"; then ++ ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_ac_ct_OTOOL="otool" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL ++if test -n "$ac_ct_OTOOL"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 ++$as_echo "$ac_ct_OTOOL" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_OTOOL" = x; then ++ OTOOL=":" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ OTOOL=$ac_ct_OTOOL ++ fi ++else ++ OTOOL="$ac_cv_prog_OTOOL" ++fi ++ ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. ++set dummy ${ac_tool_prefix}otool64; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_OTOOL64+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$OTOOL64"; then ++ ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++OTOOL64=$ac_cv_prog_OTOOL64 ++if test -n "$OTOOL64"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 ++$as_echo "$OTOOL64" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_OTOOL64"; then ++ ac_ct_OTOOL64=$OTOOL64 ++ # Extract the first word of "otool64", so it can be a program name with args. ++set dummy otool64; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_OTOOL64"; then ++ ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_prog_ac_ct_OTOOL64="otool64" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 ++if test -n "$ac_ct_OTOOL64"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 ++$as_echo "$ac_ct_OTOOL64" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_OTOOL64" = x; then ++ OTOOL64=":" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ OTOOL64=$ac_ct_OTOOL64 ++ fi ++else ++ OTOOL64="$ac_cv_prog_OTOOL64" ++fi ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 ++$as_echo_n "checking for -single_module linker flag... " >&6; } ++if test "${lt_cv_apple_cc_single_mod+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_apple_cc_single_mod=no ++ if test -z "${LT_MULTI_MODULE}"; then ++ # By default we will add the -single_module flag. You can override ++ # by either setting the environment variable LT_MULTI_MODULE ++ # non-empty at configure time, or by adding -multi_module to the ++ # link flags. ++ rm -rf libconftest.dylib* ++ echo "int foo(void){return 1;}" > conftest.c ++ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ ++-dynamiclib -Wl,-single_module conftest.c" >&5 ++ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ ++ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err ++ _lt_result=$? ++ if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then ++ lt_cv_apple_cc_single_mod=yes ++ else ++ cat conftest.err >&5 ++ fi ++ rm -rf libconftest.dylib* ++ rm -f conftest.* ++ fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 ++$as_echo "$lt_cv_apple_cc_single_mod" >&6; } ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 ++$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } ++if test "${lt_cv_ld_exported_symbols_list+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_ld_exported_symbols_list=no ++ save_LDFLAGS=$LDFLAGS ++ echo "_main" > conftest.sym ++ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ lt_cv_ld_exported_symbols_list=yes ++else ++ lt_cv_ld_exported_symbols_list=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++ LDFLAGS="$save_LDFLAGS" ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 ++$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } ++ case $host_os in ++ rhapsody* | darwin1.[012]) ++ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; ++ darwin1.*) ++ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; ++ darwin*) # darwin 5.x on ++ # if running on 10.5 or later, the deployment target defaults ++ # to the OS version, if on x86, and 10.4, the deployment ++ # target defaults to 10.4. Don't you love it? ++ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in ++ 10.0,*86*-darwin8*|10.0,*-darwin[91]*) ++ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; ++ 10.[012]*) ++ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; ++ 10.*) ++ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; ++ esac ++ ;; ++ esac ++ if test "$lt_cv_apple_cc_single_mod" = "yes"; then ++ _lt_dar_single_mod='$single_module' ++ fi ++ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then ++ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' ++ else ++ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ fi ++ if test "$DSYMUTIL" != ":"; then ++ _lt_dsymutil='~$DSYMUTIL $lib || :' ++ else ++ _lt_dsymutil= ++ fi ++ ;; ++ esac ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 ++$as_echo_n "checking how to run the C preprocessor... " >&6; } ++# On Suns, sometimes $CPP names a directory. ++if test -n "$CPP" && test -d "$CPP"; then ++ CPP= ++fi ++if test -z "$CPP"; then ++ if test "${ac_cv_prog_CPP+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ # Double quotes because CPP needs to be expanded ++ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" ++ do ++ ac_preproc_ok=false ++for ac_c_preproc_warn_flag in '' yes ++do ++ # Use a header file that comes with gcc, so configuring glibc ++ # with a fresh cross-compiler works. ++ # Prefer to if __STDC__ is defined, since ++ # exists even on freestanding compilers. ++ # On the NeXT, cc -E runs the code through the compiler's parser, ++ # not just through cpp. "Syntax error" is here to catch this case. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#ifdef __STDC__ ++# include ++#else ++# include ++#endif ++ Syntax error ++_ACEOF ++if ac_fn_c_try_cpp "$LINENO"; then : ++ ++else ++ # Broken: fails on valid input. ++continue ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++ # OK, works on sane cases. Now check whether nonexistent headers ++ # can be detected and how. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++_ACEOF ++if ac_fn_c_try_cpp "$LINENO"; then : ++ # Broken: success on invalid input. ++continue ++else ++ # Passes both tests. ++ac_preproc_ok=: ++break ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++done ++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. ++rm -f conftest.err conftest.$ac_ext ++if $ac_preproc_ok; then : ++ break ++fi ++ ++ done ++ ac_cv_prog_CPP=$CPP ++ ++fi ++ CPP=$ac_cv_prog_CPP ++else ++ ac_cv_prog_CPP=$CPP ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 ++$as_echo "$CPP" >&6; } ++ac_preproc_ok=false ++for ac_c_preproc_warn_flag in '' yes ++do ++ # Use a header file that comes with gcc, so configuring glibc ++ # with a fresh cross-compiler works. ++ # Prefer to if __STDC__ is defined, since ++ # exists even on freestanding compilers. ++ # On the NeXT, cc -E runs the code through the compiler's parser, ++ # not just through cpp. "Syntax error" is here to catch this case. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#ifdef __STDC__ ++# include ++#else ++# include ++#endif ++ Syntax error ++_ACEOF ++if ac_fn_c_try_cpp "$LINENO"; then : ++ ++else ++ # Broken: fails on valid input. ++continue ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++ # OK, works on sane cases. Now check whether nonexistent headers ++ # can be detected and how. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++_ACEOF ++if ac_fn_c_try_cpp "$LINENO"; then : ++ # Broken: success on invalid input. ++continue ++else ++ # Passes both tests. ++ac_preproc_ok=: ++break ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++done ++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. ++rm -f conftest.err conftest.$ac_ext ++if $ac_preproc_ok; then : ++ ++else ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++as_fn_error "C preprocessor \"$CPP\" fails sanity check ++See \`config.log' for more details." "$LINENO" 5; } ++fi ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 ++$as_echo_n "checking for ANSI C header files... " >&6; } ++if test "${ac_cv_header_stdc+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++#include ++#include ++#include ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_cv_header_stdc=yes ++else ++ ac_cv_header_stdc=no ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ ++if test $ac_cv_header_stdc = yes; then ++ # SunOS 4.x string.h does not declare mem*, contrary to ANSI. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++ ++_ACEOF ++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++ $EGREP "memchr" >/dev/null 2>&1; then : ++ ++else ++ ac_cv_header_stdc=no ++fi ++rm -f conftest* ++ ++fi ++ ++if test $ac_cv_header_stdc = yes; then ++ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++ ++_ACEOF ++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++ $EGREP "free" >/dev/null 2>&1; then : ++ ++else ++ ac_cv_header_stdc=no ++fi ++rm -f conftest* ++ ++fi ++ ++if test $ac_cv_header_stdc = yes; then ++ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. ++ if test "$cross_compiling" = yes; then : ++ : ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++#include ++#if ((' ' & 0x0FF) == 0x020) ++# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') ++# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) ++#else ++# define ISLOWER(c) \ ++ (('a' <= (c) && (c) <= 'i') \ ++ || ('j' <= (c) && (c) <= 'r') \ ++ || ('s' <= (c) && (c) <= 'z')) ++# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) ++#endif ++ ++#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) ++int ++main () ++{ ++ int i; ++ for (i = 0; i < 256; i++) ++ if (XOR (islower (i), ISLOWER (i)) ++ || toupper (i) != TOUPPER (i)) ++ return 2; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_run "$LINENO"; then : ++ ++else ++ ac_cv_header_stdc=no ++fi ++rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ ++ conftest.$ac_objext conftest.beam conftest.$ac_ext ++fi ++ ++fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 ++$as_echo "$ac_cv_header_stdc" >&6; } ++if test $ac_cv_header_stdc = yes; then ++ ++$as_echo "#define STDC_HEADERS 1" >>confdefs.h ++ ++fi ++ ++# On IRIX 5.3, sys/types and inttypes.h are conflicting. ++for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ ++ inttypes.h stdint.h unistd.h ++do : ++ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ++ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default ++" ++eval as_val=\$$as_ac_Header ++ if test "x$as_val" = x""yes; then : ++ cat >>confdefs.h <<_ACEOF ++#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 ++_ACEOF ++ ++fi ++ ++done ++ ++ ++for ac_header in dlfcn.h ++do : ++ ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default ++" ++if test "x$ac_cv_header_dlfcn_h" = x""yes; then : ++ cat >>confdefs.h <<_ACEOF ++#define HAVE_DLFCN_H 1 ++_ACEOF ++ ++fi ++ ++done ++ ++ ++ ++# Set options ++ ++ ++ ++ enable_dlopen=no ++ ++ ++ ++ # Check whether --enable-shared was given. ++if test "${enable_shared+set}" = set; then : ++ enableval=$enable_shared; p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_shared=yes ;; ++ no) enable_shared=no ;; ++ *) ++ enable_shared=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," ++ for pkg in $enableval; do ++ IFS="$lt_save_ifs" ++ if test "X$pkg" = "X$p"; then ++ enable_shared=yes ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ;; ++ esac ++else ++ enable_shared=yes ++fi ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ # Check whether --enable-static was given. ++if test "${enable_static+set}" = set; then : ++ enableval=$enable_static; p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_static=yes ;; ++ no) enable_static=no ;; ++ *) ++ enable_static=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," ++ for pkg in $enableval; do ++ IFS="$lt_save_ifs" ++ if test "X$pkg" = "X$p"; then ++ enable_static=yes ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ;; ++ esac ++else ++ enable_static=yes ++fi ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++# Check whether --with-pic was given. ++if test "${with_pic+set}" = set; then : ++ withval=$with_pic; pic_mode="$withval" ++else ++ pic_mode=default ++fi ++ ++ ++test -z "$pic_mode" && pic_mode=default ++ ++ ++ ++ ++ ++ ++ ++ # Check whether --enable-fast-install was given. ++if test "${enable_fast_install+set}" = set; then : ++ enableval=$enable_fast_install; p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_fast_install=yes ;; ++ no) enable_fast_install=no ;; ++ *) ++ enable_fast_install=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," ++ for pkg in $enableval; do ++ IFS="$lt_save_ifs" ++ if test "X$pkg" = "X$p"; then ++ enable_fast_install=yes ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ;; ++ esac ++else ++ enable_fast_install=yes ++fi ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++# This can be used to rebuild libtool when needed ++LIBTOOL_DEPS="$ltmain" ++ ++# Always use our own libtool. ++LIBTOOL='$(SHELL) $(top_builddir)/libtool' ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++test -z "$LN_S" && LN_S="ln -s" ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++if test -n "${ZSH_VERSION+set}" ; then ++ setopt NO_GLOB_SUBST ++fi ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 ++$as_echo_n "checking for objdir... " >&6; } ++if test "${lt_cv_objdir+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ rm -f .libs 2>/dev/null ++mkdir .libs 2>/dev/null ++if test -d .libs; then ++ lt_cv_objdir=.libs ++else ++ # MS-DOS does not allow filenames that begin with a dot. ++ lt_cv_objdir=_libs ++fi ++rmdir .libs 2>/dev/null ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 ++$as_echo "$lt_cv_objdir" >&6; } ++objdir=$lt_cv_objdir ++ ++ ++ ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define LT_OBJDIR "$lt_cv_objdir/" ++_ACEOF ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++case $host_os in ++aix3*) ++ # AIX sometimes has problems with the GCC collect2 program. For some ++ # reason, if we set the COLLECT_NAMES environment variable, the problems ++ # vanish in a puff of smoke. ++ if test "X${COLLECT_NAMES+set}" != Xset; then ++ COLLECT_NAMES= ++ export COLLECT_NAMES ++ fi ++ ;; ++esac ++ ++# Sed substitution that helps us do robust quoting. It backslashifies ++# metacharacters that are still active within double-quoted strings. ++sed_quote_subst='s/\(["`$\\]\)/\\\1/g' ++ ++# Same as above, but do not quote variable references. ++double_quote_subst='s/\(["`\\]\)/\\\1/g' ++ ++# Sed substitution to delay expansion of an escaped shell variable in a ++# double_quote_subst'ed string. ++delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' ++ ++# Sed substitution to delay expansion of an escaped single quote. ++delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' ++ ++# Sed substitution to avoid accidental globbing in evaled expressions ++no_glob_subst='s/\*/\\\*/g' ++ ++# Global variables: ++ofile=libtool ++can_build_shared=yes ++ ++# All known linkers require a `.a' archive for static linking (except MSVC, ++# which needs '.lib'). ++libext=a ++ ++with_gnu_ld="$lt_cv_prog_gnu_ld" ++ ++old_CC="$CC" ++old_CFLAGS="$CFLAGS" ++ ++# Set sane defaults for various variables ++test -z "$CC" && CC=cc ++test -z "$LTCC" && LTCC=$CC ++test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS ++test -z "$LD" && LD=ld ++test -z "$ac_objext" && ac_objext=o ++ ++for cc_temp in $compiler""; do ++ case $cc_temp in ++ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; ++ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; ++ \-*) ;; ++ *) break;; ++ esac ++done ++cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ++ ++ ++# Only perform the check for file, if the check method requires it ++test -z "$MAGIC_CMD" && MAGIC_CMD=file ++case $deplibs_check_method in ++file_magic*) ++ if test "$file_magic_cmd" = '$MAGIC_CMD'; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 ++$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } ++if test "${lt_cv_path_MAGIC_CMD+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ case $MAGIC_CMD in ++[\\/*] | ?:[\\/]*) ++ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ++ ;; ++*) ++ lt_save_MAGIC_CMD="$MAGIC_CMD" ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" ++ for ac_dir in $ac_dummy; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ if test -f $ac_dir/${ac_tool_prefix}file; then ++ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" ++ if test -n "$file_magic_test_file"; then ++ case $deplibs_check_method in ++ "file_magic "*) ++ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` ++ MAGIC_CMD="$lt_cv_path_MAGIC_CMD" ++ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | ++ $EGREP "$file_magic_regex" > /dev/null; then ++ : ++ else ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: the command libtool uses to detect shared libraries, ++*** $file_magic_cmd, produces output that libtool cannot recognize. ++*** The result is that libtool may fail to recognize shared libraries ++*** as such. This will affect the creation of libtool libraries that ++*** depend on shared libraries, but programs linked with such libtool ++*** libraries will work regardless of this problem. Nevertheless, you ++*** may want to report the problem to your system manager and/or to ++*** bug-libtool@gnu.org ++ ++_LT_EOF ++ fi ;; ++ esac ++ fi ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ MAGIC_CMD="$lt_save_MAGIC_CMD" ++ ;; ++esac ++fi ++ ++MAGIC_CMD="$lt_cv_path_MAGIC_CMD" ++if test -n "$MAGIC_CMD"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 ++$as_echo "$MAGIC_CMD" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ ++ ++ ++if test -z "$lt_cv_path_MAGIC_CMD"; then ++ if test -n "$ac_tool_prefix"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 ++$as_echo_n "checking for file... " >&6; } ++if test "${lt_cv_path_MAGIC_CMD+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ case $MAGIC_CMD in ++[\\/*] | ?:[\\/]*) ++ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ++ ;; ++*) ++ lt_save_MAGIC_CMD="$MAGIC_CMD" ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" ++ for ac_dir in $ac_dummy; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ if test -f $ac_dir/file; then ++ lt_cv_path_MAGIC_CMD="$ac_dir/file" ++ if test -n "$file_magic_test_file"; then ++ case $deplibs_check_method in ++ "file_magic "*) ++ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` ++ MAGIC_CMD="$lt_cv_path_MAGIC_CMD" ++ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | ++ $EGREP "$file_magic_regex" > /dev/null; then ++ : ++ else ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: the command libtool uses to detect shared libraries, ++*** $file_magic_cmd, produces output that libtool cannot recognize. ++*** The result is that libtool may fail to recognize shared libraries ++*** as such. This will affect the creation of libtool libraries that ++*** depend on shared libraries, but programs linked with such libtool ++*** libraries will work regardless of this problem. Nevertheless, you ++*** may want to report the problem to your system manager and/or to ++*** bug-libtool@gnu.org ++ ++_LT_EOF ++ fi ;; ++ esac ++ fi ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ MAGIC_CMD="$lt_save_MAGIC_CMD" ++ ;; ++esac ++fi ++ ++MAGIC_CMD="$lt_cv_path_MAGIC_CMD" ++if test -n "$MAGIC_CMD"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 ++$as_echo "$MAGIC_CMD" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ else ++ MAGIC_CMD=: ++ fi ++fi ++ ++ fi ++ ;; ++esac ++ ++# Use C for the default configuration in the libtool script ++ ++lt_save_CC="$CC" ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ ++# Source file extension for C test sources. ++ac_ext=c ++ ++# Object file extension for compiled C test sources. ++objext=o ++objext=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code="int some_variable = 0;" ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code='int main(){return(0);}' ++ ++ ++ ++ ++ ++ ++ ++# If no C compiler was specified, use CC. ++LTCC=${LTCC-"$CC"} ++ ++# If no C compiler flags were specified, use CFLAGS. ++LTCFLAGS=${LTCFLAGS-"$CFLAGS"} ++ ++# Allow CC to be a program name with arguments. ++compiler=$CC ++ ++# Save the default compiler, since it gets overwritten when the other ++# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. ++compiler_DEFAULT=$CC ++ ++# save warnings/boilerplate of simple test code ++ac_outfile=conftest.$ac_objext ++echo "$lt_simple_compile_test_code" >conftest.$ac_ext ++eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_compiler_boilerplate=`cat conftest.err` ++$RM conftest* ++ ++ac_outfile=conftest.$ac_objext ++echo "$lt_simple_link_test_code" >conftest.$ac_ext ++eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_linker_boilerplate=`cat conftest.err` ++$RM -r conftest* ++ ++ ++## CAVEAT EMPTOR: ++## There is no encapsulation within the following macros, do not change ++## the running order or otherwise move them around unless you know exactly ++## what you are doing... ++if test -n "$compiler"; then ++ ++lt_prog_compiler_no_builtin_flag= ++ ++if test "$GCC" = yes; then ++ lt_prog_compiler_no_builtin_flag=' -fno-builtin' ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 ++$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } ++if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_prog_compiler_rtti_exceptions=no ++ ac_outfile=conftest.$ac_objext ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ lt_compiler_flag="-fno-rtti -fno-exceptions" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ # The option is referenced via a variable to avoid confusing sed. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:8622: $lt_compile\"" >&5) ++ (eval "$lt_compile" 2>conftest.err) ++ ac_status=$? ++ cat conftest.err >&5 ++ echo "$as_me:8626: \$? = $ac_status" >&5 ++ if (exit $ac_status) && test -s "$ac_outfile"; then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings other than the usual output. ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_rtti_exceptions=yes ++ fi ++ fi ++ $RM conftest* ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 ++$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } ++ ++if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then ++ lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" ++else ++ : ++fi ++ ++fi ++ ++ ++ ++ ++ ++ ++ lt_prog_compiler_wl= ++lt_prog_compiler_pic= ++lt_prog_compiler_static= ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 ++$as_echo_n "checking for $compiler option to produce PIC... " >&6; } ++ ++ if test "$GCC" = yes; then ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_static='-static' ++ ++ case $host_os in ++ aix*) ++ # All AIX code is PIC. ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ lt_prog_compiler_static='-Bstatic' ++ fi ++ ;; ++ ++ amigaos*) ++ case $host_cpu in ++ powerpc) ++ # see comment about AmigaOS4 .so support ++ lt_prog_compiler_pic='-fPIC' ++ ;; ++ m68k) ++ # FIXME: we need at least 68020 code to build shared libraries, but ++ # adding the `-m68020' flag to GCC prevents building anything better, ++ # like `-m68040'. ++ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ++ ;; ++ esac ++ ;; ++ ++ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) ++ # PIC is the default for these OSes. ++ ;; ++ ++ mingw* | cygwin* | pw32* | os2* | cegcc*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ # Although the cygwin gcc ignores -fPIC, still need this for old-style ++ # (--disable-auto-import) libraries ++ lt_prog_compiler_pic='-DDLL_EXPORT' ++ ;; ++ ++ darwin* | rhapsody*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ lt_prog_compiler_pic='-fno-common' ++ ;; ++ ++ hpux*) ++ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit ++ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag ++ # sets the default TLS model and affects inlining. ++ case $host_cpu in ++ hppa*64*) ++ # +Z the default ++ ;; ++ *) ++ lt_prog_compiler_pic='-fPIC' ++ ;; ++ esac ++ ;; ++ ++ interix[3-9]*) ++ # Interix 3.x gcc -fpic/-fPIC options generate broken code. ++ # Instead, we relocate shared libraries at runtime. ++ ;; ++ ++ msdosdjgpp*) ++ # Just because we use GCC doesn't mean we suddenly get shared libraries ++ # on systems that don't support them. ++ lt_prog_compiler_can_build_shared=no ++ enable_shared=no ++ ;; ++ ++ *nto* | *qnx*) ++ # QNX uses GNU C++, but need to define -shared option too, otherwise ++ # it will coredump. ++ lt_prog_compiler_pic='-fPIC -shared' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ lt_prog_compiler_pic=-Kconform_pic ++ fi ++ ;; ++ ++ *) ++ lt_prog_compiler_pic='-fPIC' ++ ;; ++ esac ++ else ++ # PORTME Check for flag to pass linker flags through the system compiler. ++ case $host_os in ++ aix*) ++ lt_prog_compiler_wl='-Wl,' ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ lt_prog_compiler_static='-Bstatic' ++ else ++ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' ++ fi ++ ;; ++ ++ mingw* | cygwin* | pw32* | os2* | cegcc*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ lt_prog_compiler_pic='-DDLL_EXPORT' ++ ;; ++ ++ hpux9* | hpux10* | hpux11*) ++ lt_prog_compiler_wl='-Wl,' ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ lt_prog_compiler_pic='+Z' ++ ;; ++ esac ++ # Is there a better lt_prog_compiler_static that works with the bundled CC? ++ lt_prog_compiler_static='${wl}-a ${wl}archive' ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ lt_prog_compiler_wl='-Wl,' ++ # PIC (with -KPIC) is the default. ++ lt_prog_compiler_static='-non_shared' ++ ;; ++ ++ linux* | k*bsd*-gnu | kopensolaris*-gnu) ++ case $cc_basename in ++ # old Intel for x86_64 which still supported -KPIC. ++ ecc*) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-static' ++ ;; ++ # icc used to be incompatible with GCC. ++ # ICC 10 doesn't accept -KPIC any more. ++ icc* | ifort*) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_pic='-fPIC' ++ lt_prog_compiler_static='-static' ++ ;; ++ # Lahey Fortran 8.1. ++ lf95*) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_pic='--shared' ++ lt_prog_compiler_static='--static' ++ ;; ++ pgcc* | pgf77* | pgf90* | pgf95*) ++ # Portland Group compilers (*not* the Pentium gcc compiler, ++ # which looks to be a dead project) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_pic='-fpic' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ccc*) ++ lt_prog_compiler_wl='-Wl,' ++ # All Alpha code is PIC. ++ lt_prog_compiler_static='-non_shared' ++ ;; ++ xl*) ++ # IBM XL C 8.0/Fortran 10.1 on PPC ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_pic='-qpic' ++ lt_prog_compiler_static='-qstaticlink' ++ ;; ++ *) ++ case `$CC -V 2>&1 | sed 5q` in ++ *Sun\ C*) ++ # Sun C 5.9 ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ lt_prog_compiler_wl='-Wl,' ++ ;; ++ *Sun\ F*) ++ # Sun Fortran 8.3 passes all unrecognized flags to the linker ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ lt_prog_compiler_wl='' ++ ;; ++ esac ++ ;; ++ esac ++ ;; ++ ++ newsos6) ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ++ *nto* | *qnx*) ++ # QNX uses GNU C++, but need to define -shared option too, otherwise ++ # it will coredump. ++ lt_prog_compiler_pic='-fPIC -shared' ++ ;; ++ ++ osf3* | osf4* | osf5*) ++ lt_prog_compiler_wl='-Wl,' ++ # All OSF/1 code is PIC. ++ lt_prog_compiler_static='-non_shared' ++ ;; ++ ++ rdos*) ++ lt_prog_compiler_static='-non_shared' ++ ;; ++ ++ solaris*) ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ case $cc_basename in ++ f77* | f90* | f95*) ++ lt_prog_compiler_wl='-Qoption ld ';; ++ *) ++ lt_prog_compiler_wl='-Wl,';; ++ esac ++ ;; ++ ++ sunos4*) ++ lt_prog_compiler_wl='-Qoption ld ' ++ lt_prog_compiler_pic='-PIC' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ++ sysv4 | sysv4.2uw2* | sysv4.3*) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec ;then ++ lt_prog_compiler_pic='-Kconform_pic' ++ lt_prog_compiler_static='-Bstatic' ++ fi ++ ;; ++ ++ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ++ unicos*) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_can_build_shared=no ++ ;; ++ ++ uts4*) ++ lt_prog_compiler_pic='-pic' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ++ *) ++ lt_prog_compiler_can_build_shared=no ++ ;; ++ esac ++ fi ++ ++case $host_os in ++ # For platforms which do not support PIC, -DPIC is meaningless: ++ *djgpp*) ++ lt_prog_compiler_pic= ++ ;; ++ *) ++ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ++ ;; ++esac ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5 ++$as_echo "$lt_prog_compiler_pic" >&6; } ++ ++ ++ ++ ++ ++ ++# ++# Check to make sure the PIC flag actually works. ++# ++if test -n "$lt_prog_compiler_pic"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 ++$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } ++if test "${lt_cv_prog_compiler_pic_works+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_prog_compiler_pic_works=no ++ ac_outfile=conftest.$ac_objext ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ # The option is referenced via a variable to avoid confusing sed. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:8961: $lt_compile\"" >&5) ++ (eval "$lt_compile" 2>conftest.err) ++ ac_status=$? ++ cat conftest.err >&5 ++ echo "$as_me:8965: \$? = $ac_status" >&5 ++ if (exit $ac_status) && test -s "$ac_outfile"; then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings other than the usual output. ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_pic_works=yes ++ fi ++ fi ++ $RM conftest* ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 ++$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } ++ ++if test x"$lt_cv_prog_compiler_pic_works" = xyes; then ++ case $lt_prog_compiler_pic in ++ "" | " "*) ;; ++ *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; ++ esac ++else ++ lt_prog_compiler_pic= ++ lt_prog_compiler_can_build_shared=no ++fi ++ ++fi ++ ++ ++ ++ ++ ++ ++# ++# Check to make sure the static flag actually works. ++# ++wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 ++$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } ++if test "${lt_cv_prog_compiler_static_works+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_prog_compiler_static_works=no ++ save_LDFLAGS="$LDFLAGS" ++ LDFLAGS="$LDFLAGS $lt_tmp_static_flag" ++ echo "$lt_simple_link_test_code" > conftest.$ac_ext ++ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then ++ # The linker can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ if test -s conftest.err; then ++ # Append any errors to the config.log. ++ cat conftest.err 1>&5 ++ $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if diff conftest.exp conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_static_works=yes ++ fi ++ else ++ lt_cv_prog_compiler_static_works=yes ++ fi ++ fi ++ $RM -r conftest* ++ LDFLAGS="$save_LDFLAGS" ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 ++$as_echo "$lt_cv_prog_compiler_static_works" >&6; } ++ ++if test x"$lt_cv_prog_compiler_static_works" = xyes; then ++ : ++else ++ lt_prog_compiler_static= ++fi ++ ++ ++ ++ ++ ++ ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 ++$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } ++if test "${lt_cv_prog_compiler_c_o+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_prog_compiler_c_o=no ++ $RM -r conftest 2>/dev/null ++ mkdir conftest ++ cd conftest ++ mkdir out ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ lt_compiler_flag="-o out/conftest2.$ac_objext" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:9066: $lt_compile\"" >&5) ++ (eval "$lt_compile" 2>out/conftest.err) ++ ac_status=$? ++ cat out/conftest.err >&5 ++ echo "$as_me:9070: \$? = $ac_status" >&5 ++ if (exit $ac_status) && test -s out/conftest2.$ac_objext ++ then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp ++ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 ++ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_c_o=yes ++ fi ++ fi ++ chmod u+w . 2>&5 ++ $RM conftest* ++ # SGI C++ compiler will create directory out/ii_files/ for ++ # template instantiation ++ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files ++ $RM out/* && rmdir out ++ cd .. ++ $RM -r conftest ++ $RM conftest* ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 ++$as_echo "$lt_cv_prog_compiler_c_o" >&6; } ++ ++ ++ ++ ++ ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 ++$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } ++if test "${lt_cv_prog_compiler_c_o+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_prog_compiler_c_o=no ++ $RM -r conftest 2>/dev/null ++ mkdir conftest ++ cd conftest ++ mkdir out ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ lt_compiler_flag="-o out/conftest2.$ac_objext" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:9121: $lt_compile\"" >&5) ++ (eval "$lt_compile" 2>out/conftest.err) ++ ac_status=$? ++ cat out/conftest.err >&5 ++ echo "$as_me:9125: \$? = $ac_status" >&5 ++ if (exit $ac_status) && test -s out/conftest2.$ac_objext ++ then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp ++ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 ++ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_c_o=yes ++ fi ++ fi ++ chmod u+w . 2>&5 ++ $RM conftest* ++ # SGI C++ compiler will create directory out/ii_files/ for ++ # template instantiation ++ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files ++ $RM out/* && rmdir out ++ cd .. ++ $RM -r conftest ++ $RM conftest* ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 ++$as_echo "$lt_cv_prog_compiler_c_o" >&6; } ++ ++ ++ ++ ++hard_links="nottested" ++if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then ++ # do not overwrite the value of need_locks provided by the user ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 ++$as_echo_n "checking if we can lock with hard links... " >&6; } ++ hard_links=yes ++ $RM conftest* ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ touch conftest.a ++ ln conftest.a conftest.b 2>&5 || hard_links=no ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 ++$as_echo "$hard_links" >&6; } ++ if test "$hard_links" = no; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 ++$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} ++ need_locks=warn ++ fi ++else ++ need_locks=no ++fi ++ ++ ++ ++ ++ ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 ++$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } ++ ++ runpath_var= ++ allow_undefined_flag= ++ always_export_symbols=no ++ archive_cmds= ++ archive_expsym_cmds= ++ compiler_needs_object=no ++ enable_shared_with_static_runtimes=no ++ export_dynamic_flag_spec= ++ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ++ hardcode_automatic=no ++ hardcode_direct=no ++ hardcode_direct_absolute=no ++ hardcode_libdir_flag_spec= ++ hardcode_libdir_flag_spec_ld= ++ hardcode_libdir_separator= ++ hardcode_minus_L=no ++ hardcode_shlibpath_var=unsupported ++ inherit_rpath=no ++ link_all_deplibs=unknown ++ module_cmds= ++ module_expsym_cmds= ++ old_archive_from_new_cmds= ++ old_archive_from_expsyms_cmds= ++ thread_safe_flag_spec= ++ whole_archive_flag_spec= ++ # include_expsyms should be a list of space-separated symbols to be *always* ++ # included in the symbol list ++ include_expsyms= ++ # exclude_expsyms can be an extended regexp of symbols to exclude ++ # it will be wrapped by ` (' and `)$', so one must not match beginning or ++ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', ++ # as well as any symbol that contains `d'. ++ exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' ++ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out ++ # platforms (ab)use it in PIC code, but their linkers get confused if ++ # the symbol is explicitly referenced. Since portable code cannot ++ # rely on this symbol name, it's probably fine to never include it in ++ # preloaded symbol tables. ++ # Exclude shared library initialization/finalization symbols. ++ extract_expsyms_cmds= ++ ++ case $host_os in ++ cygwin* | mingw* | pw32* | cegcc*) ++ # FIXME: the MSVC++ port hasn't been tested in a loooong time ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++. ++ if test "$GCC" != yes; then ++ with_gnu_ld=no ++ fi ++ ;; ++ interix*) ++ # we just hope/assume this is gcc and not c89 (= MSVC++) ++ with_gnu_ld=yes ++ ;; ++ openbsd*) ++ with_gnu_ld=no ++ ;; ++ linux* | k*bsd*-gnu) ++ link_all_deplibs=no ++ ;; ++ esac ++ ++ ld_shlibs=yes ++ if test "$with_gnu_ld" = yes; then ++ # If archive_cmds runs LD, not CC, wlarc should be empty ++ wlarc='${wl}' ++ ++ # Set some defaults for GNU ld with shared library support. These ++ # are reset later if shared libraries are not supported. Putting them ++ # here allows them to be overridden if necessary. ++ runpath_var=LD_RUN_PATH ++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' ++ export_dynamic_flag_spec='${wl}--export-dynamic' ++ # ancient GNU ld didn't support --whole-archive et. al. ++ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then ++ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' ++ else ++ whole_archive_flag_spec= ++ fi ++ supports_anon_versioning=no ++ case `$LD -v 2>&1` in ++ *GNU\ gold*) supports_anon_versioning=yes ;; ++ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 ++ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... ++ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... ++ *\ 2.11.*) ;; # other 2.11 versions ++ *) supports_anon_versioning=yes ;; ++ esac ++ ++ # See if GNU ld supports shared libraries. ++ case $host_os in ++ aix[3-9]*) ++ # On AIX/PPC, the GNU linker is very broken ++ if test "$host_cpu" != ia64; then ++ ld_shlibs=no ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: the GNU linker, at least up to release 2.9.1, is reported ++*** to be unable to reliably create shared libraries on AIX. ++*** Therefore, libtool is disabling shared libraries support. If you ++*** really care for shared libraries, you may want to modify your PATH ++*** so that a non-GNU linker is found, and then restart. ++ ++_LT_EOF ++ fi ++ ;; ++ ++ amigaos*) ++ case $host_cpu in ++ powerpc) ++ # see comment about AmigaOS4 .so support ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds='' ++ ;; ++ m68k) ++ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_minus_L=yes ++ ;; ++ esac ++ ;; ++ ++ beos*) ++ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then ++ allow_undefined_flag=unsupported ++ # Joseph Beckenbach says some releases of gcc ++ # support --undefined. This deserves some investigation. FIXME ++ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ ++ cygwin* | mingw* | pw32* | cegcc*) ++ # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, ++ # as there is no search path for DLLs. ++ hardcode_libdir_flag_spec='-L$libdir' ++ allow_undefined_flag=unsupported ++ always_export_symbols=no ++ enable_shared_with_static_runtimes=yes ++ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' ++ ++ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ # If the export-symbols file already is a .def file (1st line ++ # is EXPORTS), use it as is; otherwise, prepend... ++ archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then ++ cp $export_symbols $output_objdir/$soname.def; ++ else ++ echo EXPORTS > $output_objdir/$soname.def; ++ cat $export_symbols >> $output_objdir/$soname.def; ++ fi~ ++ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ ++ interix[3-9]*) ++ hardcode_direct=no ++ hardcode_shlibpath_var=no ++ hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ++ export_dynamic_flag_spec='${wl}-E' ++ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. ++ # Instead, shared libraries are loaded at an image base (0x10000000 by ++ # default) and relocated if they conflict, which is a slow very memory ++ # consuming and fragmenting process. To avoid this, we pick a random, ++ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link ++ # time. Moving up from 0x10000000 also allows more sbrk(2) space. ++ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ ;; ++ ++ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) ++ tmp_diet=no ++ if test "$host_os" = linux-dietlibc; then ++ case $cc_basename in ++ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) ++ esac ++ fi ++ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ ++ && test "$tmp_diet" = no ++ then ++ tmp_addflag= ++ tmp_sharedflag='-shared' ++ case $cc_basename,$host_cpu in ++ pgcc*) # Portland Group C compiler ++ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' ++ tmp_addflag=' $pic_flag' ++ ;; ++ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers ++ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' ++ tmp_addflag=' $pic_flag -Mnomain' ;; ++ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 ++ tmp_addflag=' -i_dynamic' ;; ++ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 ++ tmp_addflag=' -i_dynamic -nofor_main' ;; ++ ifc* | ifort*) # Intel Fortran compiler ++ tmp_addflag=' -nofor_main' ;; ++ lf95*) # Lahey Fortran 8.1 ++ whole_archive_flag_spec= ++ tmp_sharedflag='--shared' ;; ++ xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) ++ tmp_sharedflag='-qmkshrobj' ++ tmp_addflag= ;; ++ esac ++ case `$CC -V 2>&1 | sed 5q` in ++ *Sun\ C*) # Sun C 5.9 ++ whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' ++ compiler_needs_object=yes ++ tmp_sharedflag='-G' ;; ++ *Sun\ F*) # Sun Fortran 8.3 ++ tmp_sharedflag='-G' ;; ++ esac ++ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ ++ if test "x$supports_anon_versioning" = xyes; then ++ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ ++ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ ++ echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' ++ fi ++ ++ case $cc_basename in ++ xlf*) ++ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself ++ whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' ++ hardcode_libdir_flag_spec= ++ hardcode_libdir_flag_spec_ld='-rpath $libdir' ++ archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' ++ if test "x$supports_anon_versioning" = xyes; then ++ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ ++ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ ++ echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' ++ fi ++ ;; ++ esac ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ ++ netbsd* | netbsdelf*-gnu) ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then ++ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' ++ wlarc= ++ else ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ fi ++ ;; ++ ++ solaris*) ++ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ++ ld_shlibs=no ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: The releases 2.8.* of the GNU linker cannot reliably ++*** create shared libraries on Solaris systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.9.1 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++_LT_EOF ++ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) ++ case `$LD -v 2>&1` in ++ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ++ ld_shlibs=no ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not ++*** reliably create shared libraries on SCO systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.16.91.0.3 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++_LT_EOF ++ ;; ++ *) ++ # For security reasons, it is highly recommended that you always ++ # use absolute paths for naming shared libraries, and exclude the ++ # DT_RUNPATH tag from executables and libraries. But doing so ++ # requires that you compile everything twice, which is a pain. ++ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then ++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ esac ++ ;; ++ ++ sunos4*) ++ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ wlarc= ++ hardcode_direct=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ *) ++ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ esac ++ ++ if test "$ld_shlibs" = no; then ++ runpath_var= ++ hardcode_libdir_flag_spec= ++ export_dynamic_flag_spec= ++ whole_archive_flag_spec= ++ fi ++ else ++ # PORTME fill in a description of your system's linker (not GNU ld) ++ case $host_os in ++ aix3*) ++ allow_undefined_flag=unsupported ++ always_export_symbols=yes ++ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' ++ # Note: this linker hardcodes the directories in LIBPATH if there ++ # are no directories specified by -L. ++ hardcode_minus_L=yes ++ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then ++ # Neither direct hardcoding nor static linking is supported with a ++ # broken collect2. ++ hardcode_direct=unsupported ++ fi ++ ;; ++ ++ aix[4-9]*) ++ if test "$host_cpu" = ia64; then ++ # On IA64, the linker does run time linking by default, so we don't ++ # have to do anything special. ++ aix_use_runtimelinking=no ++ exp_sym_flag='-Bexport' ++ no_entry_flag="" ++ else ++ # If we're using GNU nm, then we don't want the "-C" option. ++ # -C means demangle to AIX nm, but means don't demangle with GNU nm ++ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then ++ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' ++ else ++ export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' ++ fi ++ aix_use_runtimelinking=no ++ ++ # Test if we are trying to use run time linking or normal ++ # AIX style linking. If -brtl is somewhere in LDFLAGS, we ++ # need to do runtime linking. ++ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) ++ for ld_flag in $LDFLAGS; do ++ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then ++ aix_use_runtimelinking=yes ++ break ++ fi ++ done ++ ;; ++ esac ++ ++ exp_sym_flag='-bexport' ++ no_entry_flag='-bnoentry' ++ fi ++ ++ # When large executables or shared objects are built, AIX ld can ++ # have problems creating the table of contents. If linking a library ++ # or program results in "error TOC overflow" add -mminimal-toc to ++ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not ++ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. ++ ++ archive_cmds='' ++ hardcode_direct=yes ++ hardcode_direct_absolute=yes ++ hardcode_libdir_separator=':' ++ link_all_deplibs=yes ++ file_list_spec='${wl}-f,' ++ ++ if test "$GCC" = yes; then ++ case $host_os in aix4.[012]|aix4.[012].*) ++ # We only want to do this on AIX 4.2 and lower, the check ++ # below for broken collect2 doesn't work under 4.3+ ++ collect2name=`${CC} -print-prog-name=collect2` ++ if test -f "$collect2name" && ++ strings "$collect2name" | $GREP resolve_lib_name >/dev/null ++ then ++ # We have reworked collect2 ++ : ++ else ++ # We have old collect2 ++ hardcode_direct=unsupported ++ # It fails to find uninstalled libraries when the uninstalled ++ # path is not listed in the libpath. Setting hardcode_minus_L ++ # to unsupported forces relinking ++ hardcode_minus_L=yes ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_libdir_separator= ++ fi ++ ;; ++ esac ++ shared_flag='-shared' ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag="$shared_flag "'${wl}-G' ++ fi ++ link_all_deplibs=no ++ else ++ # not using gcc ++ if test "$host_cpu" = ia64; then ++ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release ++ # chokes on -Wl,-G. The following line is correct: ++ shared_flag='-G' ++ else ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag='${wl}-G' ++ else ++ shared_flag='${wl}-bM:SRE' ++ fi ++ fi ++ fi ++ ++ export_dynamic_flag_spec='${wl}-bexpall' ++ # It seems that -bexpall does not export symbols beginning with ++ # underscore (_), so it is better to generate a list of symbols to export. ++ always_export_symbols=yes ++ if test "$aix_use_runtimelinking" = yes; then ++ # Warning - without using the other runtime loading flags (-brtl), ++ # -berok will link without error, but may produce a broken library. ++ allow_undefined_flag='-berok' ++ # Determine the default libpath from the value encoded in an ++ # empty executable. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ++lt_aix_libpath_sed=' ++ /Import File Strings/,/^$/ { ++ /^0/ { ++ s/^0 *\(.*\)$/\1/ ++ p ++ } ++ }' ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then ++ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` ++fi ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++ ++ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" ++ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" ++ else ++ if test "$host_cpu" = ia64; then ++ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' ++ allow_undefined_flag="-z nodefs" ++ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" ++ else ++ # Determine the default libpath from the value encoded in an ++ # empty executable. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ++lt_aix_libpath_sed=' ++ /Import File Strings/,/^$/ { ++ /^0/ { ++ s/^0 *\(.*\)$/\1/ ++ p ++ } ++ }' ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then ++ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` ++fi ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++ ++ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" ++ # Warning - without using the other run time loading flags, ++ # -berok will link without error, but may produce a broken library. ++ no_undefined_flag=' ${wl}-bernotok' ++ allow_undefined_flag=' ${wl}-berok' ++ # Exported symbols can be pulled into shared objects from archives ++ whole_archive_flag_spec='$convenience' ++ archive_cmds_need_lc=yes ++ # This is similar to how AIX traditionally builds its shared libraries. ++ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' ++ fi ++ fi ++ ;; ++ ++ amigaos*) ++ case $host_cpu in ++ powerpc) ++ # see comment about AmigaOS4 .so support ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds='' ++ ;; ++ m68k) ++ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_minus_L=yes ++ ;; ++ esac ++ ;; ++ ++ bsdi[45]*) ++ export_dynamic_flag_spec=-rdynamic ++ ;; ++ ++ cygwin* | mingw* | pw32* | cegcc*) ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++. ++ # hardcode_libdir_flag_spec is actually meaningless, as there is ++ # no search path for DLLs. ++ hardcode_libdir_flag_spec=' ' ++ allow_undefined_flag=unsupported ++ # Tell ltmain to make .lib files, not .a files. ++ libext=lib ++ # Tell ltmain to make .dll files, not .so files. ++ shrext_cmds=".dll" ++ # FIXME: Setting linknames here is a bad hack. ++ archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' ++ # The linker will automatically build a .lib file if we build a DLL. ++ old_archive_from_new_cmds='true' ++ # FIXME: Should let the user specify the lib program. ++ old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' ++ fix_srcfile_path='`cygpath -w "$srcfile"`' ++ enable_shared_with_static_runtimes=yes ++ ;; ++ ++ darwin* | rhapsody*) ++ ++ ++ archive_cmds_need_lc=no ++ hardcode_direct=no ++ hardcode_automatic=yes ++ hardcode_shlibpath_var=unsupported ++ whole_archive_flag_spec='' ++ link_all_deplibs=yes ++ allow_undefined_flag="$_lt_dar_allow_undefined" ++ case $cc_basename in ++ ifort*) _lt_dar_can_shared=yes ;; ++ *) _lt_dar_can_shared=$GCC ;; ++ esac ++ if test "$_lt_dar_can_shared" = "yes"; then ++ output_verbose_link_cmd=echo ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ ++ else ++ ld_shlibs=no ++ fi ++ ++ ;; ++ ++ dgux*) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_shlibpath_var=no ++ ;; ++ ++ freebsd1*) ++ ld_shlibs=no ++ ;; ++ ++ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor ++ # support. Future versions do this automatically, but an explicit c++rt0.o ++ # does not break anything, and helps significantly (at the cost of a little ++ # extra space). ++ freebsd2.2*) ++ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' ++ hardcode_libdir_flag_spec='-R$libdir' ++ hardcode_direct=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ # Unfortunately, older versions of FreeBSD 2 do not have this feature. ++ freebsd2*) ++ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct=yes ++ hardcode_minus_L=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ # FreeBSD 3 and greater uses gcc -shared to do shared libraries. ++ freebsd* | dragonfly*) ++ archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' ++ hardcode_libdir_flag_spec='-R$libdir' ++ hardcode_direct=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ hpux9*) ++ if test "$GCC" = yes; then ++ archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ else ++ archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ fi ++ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator=: ++ hardcode_direct=yes ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L=yes ++ export_dynamic_flag_spec='${wl}-E' ++ ;; ++ ++ hpux10*) ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then ++ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ if test "$with_gnu_ld" = no; then ++ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' ++ hardcode_libdir_flag_spec_ld='+b $libdir' ++ hardcode_libdir_separator=: ++ hardcode_direct=yes ++ hardcode_direct_absolute=yes ++ export_dynamic_flag_spec='${wl}-E' ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L=yes ++ fi ++ ;; ++ ++ hpux11*) ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then ++ case $host_cpu in ++ hppa*64*) ++ archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ else ++ case $host_cpu in ++ hppa*64*) ++ archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ fi ++ if test "$with_gnu_ld" = no; then ++ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator=: ++ ++ case $host_cpu in ++ hppa*64*|ia64*) ++ hardcode_direct=no ++ hardcode_shlibpath_var=no ++ ;; ++ *) ++ hardcode_direct=yes ++ hardcode_direct_absolute=yes ++ export_dynamic_flag_spec='${wl}-E' ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L=yes ++ ;; ++ esac ++ fi ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ if test "$GCC" = yes; then ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ # Try to use the -exported_symbol ld option, if it does not ++ # work, assume that -exports_file does not work either and ++ # implicitly export all symbols. ++ save_LDFLAGS="$LDFLAGS" ++ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++int foo(void) {} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' ++ ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++ LDFLAGS="$save_LDFLAGS" ++ else ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' ++ fi ++ archive_cmds_need_lc='no' ++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator=: ++ inherit_rpath=yes ++ link_all_deplibs=yes ++ ;; ++ ++ netbsd* | netbsdelf*-gnu) ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then ++ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out ++ else ++ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF ++ fi ++ hardcode_libdir_flag_spec='-R$libdir' ++ hardcode_direct=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ newsos6) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct=yes ++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator=: ++ hardcode_shlibpath_var=no ++ ;; ++ ++ *nto* | *qnx*) ++ ;; ++ ++ openbsd*) ++ if test -f /usr/libexec/ld.so; then ++ hardcode_direct=yes ++ hardcode_shlibpath_var=no ++ hardcode_direct_absolute=yes ++ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' ++ hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ++ export_dynamic_flag_spec='${wl}-E' ++ else ++ case $host_os in ++ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) ++ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec='-R$libdir' ++ ;; ++ *) ++ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ++ ;; ++ esac ++ fi ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ ++ os2*) ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_minus_L=yes ++ allow_undefined_flag=unsupported ++ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' ++ old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ++ ;; ++ ++ osf3*) ++ if test "$GCC" = yes; then ++ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ else ++ allow_undefined_flag=' -expect_unresolved \*' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' ++ fi ++ archive_cmds_need_lc='no' ++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator=: ++ ;; ++ ++ osf4* | osf5*) # as osf3* with the addition of -msym flag ++ if test "$GCC" = yes; then ++ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' ++ else ++ allow_undefined_flag=' -expect_unresolved \*' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ ++ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' ++ ++ # Both c and cxx compiler support -rpath directly ++ hardcode_libdir_flag_spec='-rpath $libdir' ++ fi ++ archive_cmds_need_lc='no' ++ hardcode_libdir_separator=: ++ ;; ++ ++ solaris*) ++ no_undefined_flag=' -z defs' ++ if test "$GCC" = yes; then ++ wlarc='${wl}' ++ archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ ++ $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ++ else ++ case `$CC -V 2>&1` in ++ *"Compilers 5.0"*) ++ wlarc='' ++ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ ++ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ++ ;; ++ *) ++ wlarc='${wl}' ++ archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ ++ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ++ ;; ++ esac ++ fi ++ hardcode_libdir_flag_spec='-R$libdir' ++ hardcode_shlibpath_var=no ++ case $host_os in ++ solaris2.[0-5] | solaris2.[0-5].*) ;; ++ *) ++ # The compiler driver will combine and reorder linker options, ++ # but understands `-z linker_flag'. GCC discards it without `$wl', ++ # but is careful enough not to reorder. ++ # Supported since Solaris 2.6 (maybe 2.5.1?) ++ if test "$GCC" = yes; then ++ whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ++ else ++ whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ++ fi ++ ;; ++ esac ++ link_all_deplibs=yes ++ ;; ++ ++ sunos4*) ++ if test "x$host_vendor" = xsequent; then ++ # Use $CC to link under sequent, because it throws in some extra .o ++ # files that make .init and .fini sections work. ++ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_direct=yes ++ hardcode_minus_L=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ sysv4) ++ case $host_vendor in ++ sni) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct=yes # is this really true??? ++ ;; ++ siemens) ++ ## LD is ld it makes a PLAMLIB ++ ## CC just makes a GrossModule. ++ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' ++ reload_cmds='$CC -r -o $output$reload_objs' ++ hardcode_direct=no ++ ;; ++ motorola) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct=no #Motorola manual says yes, but my tests say they lie ++ ;; ++ esac ++ runpath_var='LD_RUN_PATH' ++ hardcode_shlibpath_var=no ++ ;; ++ ++ sysv4.3*) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_shlibpath_var=no ++ export_dynamic_flag_spec='-Bexport' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_shlibpath_var=no ++ runpath_var=LD_RUN_PATH ++ hardcode_runpath_var=yes ++ ld_shlibs=yes ++ fi ++ ;; ++ ++ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) ++ no_undefined_flag='${wl}-z,text' ++ archive_cmds_need_lc=no ++ hardcode_shlibpath_var=no ++ runpath_var='LD_RUN_PATH' ++ ++ if test "$GCC" = yes; then ++ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6*) ++ # Note: We can NOT use -z defs as we might desire, because we do not ++ # link with -lc, and that would cause any symbols used from libc to ++ # always be unresolved, which means just about no library would ++ # ever link correctly. If we're not using GNU ld we use -z text ++ # though, which does catch some bad symbols but isn't as heavy-handed ++ # as -z defs. ++ no_undefined_flag='${wl}-z,text' ++ allow_undefined_flag='${wl}-z,nodefs' ++ archive_cmds_need_lc=no ++ hardcode_shlibpath_var=no ++ hardcode_libdir_flag_spec='${wl}-R,$libdir' ++ hardcode_libdir_separator=':' ++ link_all_deplibs=yes ++ export_dynamic_flag_spec='${wl}-Bexport' ++ runpath_var='LD_RUN_PATH' ++ ++ if test "$GCC" = yes; then ++ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ uts4*) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_shlibpath_var=no ++ ;; ++ ++ *) ++ ld_shlibs=no ++ ;; ++ esac ++ ++ if test x$host_vendor = xsni; then ++ case $host in ++ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) ++ export_dynamic_flag_spec='${wl}-Blargedynsym' ++ ;; ++ esac ++ fi ++ fi ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 ++$as_echo "$ld_shlibs" >&6; } ++test "$ld_shlibs" = no && can_build_shared=no ++ ++with_gnu_ld=$with_gnu_ld ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++# ++# Do we need to explicitly link libc? ++# ++case "x$archive_cmds_need_lc" in ++x|xyes) ++ # Assume -lc should be added ++ archive_cmds_need_lc=yes ++ ++ if test "$enable_shared" = yes && test "$GCC" = yes; then ++ case $archive_cmds in ++ *'~'*) ++ # FIXME: we may have to deal with multi-command sequences. ++ ;; ++ '$CC '*) ++ # Test whether the compiler implicitly links with -lc since on some ++ # systems, -lgcc has to come before -lc. If gcc already passes -lc ++ # to ld, don't add -lc before -lgcc. ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 ++$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } ++ $RM conftest* ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } 2>conftest.err; then ++ soname=conftest ++ lib=conftest ++ libobjs=conftest.$ac_objext ++ deplibs= ++ wl=$lt_prog_compiler_wl ++ pic_flag=$lt_prog_compiler_pic ++ compiler_flags=-v ++ linker_flags=-v ++ verstring= ++ output_objdir=. ++ libname=conftest ++ lt_save_allow_undefined_flag=$allow_undefined_flag ++ allow_undefined_flag= ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 ++ (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } ++ then ++ archive_cmds_need_lc=no ++ else ++ archive_cmds_need_lc=yes ++ fi ++ allow_undefined_flag=$lt_save_allow_undefined_flag ++ else ++ cat conftest.err 1>&5 ++ fi ++ $RM conftest* ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5 ++$as_echo "$archive_cmds_need_lc" >&6; } ++ ;; ++ esac ++ fi ++ ;; ++esac ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 ++$as_echo_n "checking dynamic linker characteristics... " >&6; } ++ ++if test "$GCC" = yes; then ++ case $host_os in ++ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; ++ *) lt_awk_arg="/^libraries:/" ;; ++ esac ++ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then ++ # if the path contains ";" then we assume it to be the separator ++ # otherwise default to the standard path separator (i.e. ":") - it is ++ # assumed that no part of a normal pathname contains ";" but that should ++ # okay in the real world where ";" in dirpaths is itself problematic. ++ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++ # Ok, now we have the path, separated by spaces, we can step through it ++ # and add multilib dir if necessary. ++ lt_tmp_lt_search_path_spec= ++ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` ++ for lt_sys_path in $lt_search_path_spec; do ++ if test -d "$lt_sys_path/$lt_multi_os_dir"; then ++ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" ++ else ++ test -d "$lt_sys_path" && \ ++ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" ++ fi ++ done ++ lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' ++BEGIN {RS=" "; FS="/|\n";} { ++ lt_foo=""; ++ lt_count=0; ++ for (lt_i = NF; lt_i > 0; lt_i--) { ++ if ($lt_i != "" && $lt_i != ".") { ++ if ($lt_i == "..") { ++ lt_count++; ++ } else { ++ if (lt_count == 0) { ++ lt_foo="/" $lt_i lt_foo; ++ } else { ++ lt_count--; ++ } ++ } ++ } ++ } ++ if (lt_foo != "") { lt_freq[lt_foo]++; } ++ if (lt_freq[lt_foo] == 1) { print lt_foo; } ++}'` ++ sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` ++else ++ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" ++fi ++library_names_spec= ++libname_spec='lib$name' ++soname_spec= ++shrext_cmds=".so" ++postinstall_cmds= ++postuninstall_cmds= ++finish_cmds= ++finish_eval= ++shlibpath_var= ++shlibpath_overrides_runpath=unknown ++version_type=none ++dynamic_linker="$host_os ld.so" ++sys_lib_dlsearch_path_spec="/lib /usr/lib" ++need_lib_prefix=unknown ++hardcode_into_libs=no ++ ++# when you set need_version to no, make sure it does not cause -set_version ++# flags to be left without arguments ++need_version=unknown ++ ++case $host_os in ++aix3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' ++ shlibpath_var=LIBPATH ++ ++ # AIX 3 has no versioning support, so we append a major version to the name. ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ ++aix[4-9]*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ hardcode_into_libs=yes ++ if test "$host_cpu" = ia64; then ++ # AIX 5 supports IA64 ++ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ else ++ # With GCC up to 2.95.x, collect2 would create an import file ++ # for dependence libraries. The import file would start with ++ # the line `#! .'. This would cause the generated library to ++ # depend on `.', always an invalid library. This was fixed in ++ # development snapshots of GCC prior to 3.0. ++ case $host_os in ++ aix4 | aix4.[01] | aix4.[01].*) ++ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' ++ echo ' yes ' ++ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then ++ : ++ else ++ can_build_shared=no ++ fi ++ ;; ++ esac ++ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct ++ # soname into executable. Probably we can add versioning support to ++ # collect2, so additional links can be useful in future. ++ if test "$aix_use_runtimelinking" = yes; then ++ # If using run time linking (on AIX 4.2 or later) use lib.so ++ # instead of lib.a to let people know that these are not ++ # typical AIX shared libraries. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ else ++ # We preserve .a as extension for shared libraries through AIX4.2 ++ # and later when we are not doing run time linking. ++ library_names_spec='${libname}${release}.a $libname.a' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ fi ++ shlibpath_var=LIBPATH ++ fi ++ ;; ++ ++amigaos*) ++ case $host_cpu in ++ powerpc) ++ # Since July 2007 AmigaOS4 officially supports .so libraries. ++ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ ;; ++ m68k) ++ library_names_spec='$libname.ixlibrary $libname.a' ++ # Create ${libname}_ixlibrary.a entries in /sys/libs. ++ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ++ ;; ++ esac ++ ;; ++ ++beos*) ++ library_names_spec='${libname}${shared_ext}' ++ dynamic_linker="$host_os ld.so" ++ shlibpath_var=LIBRARY_PATH ++ ;; ++ ++bsdi[45]*) ++ version_type=linux ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" ++ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" ++ # the default ld.so.conf also contains /usr/contrib/lib and ++ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow ++ # libtool to hard-code these into programs ++ ;; ++ ++cygwin* | mingw* | pw32* | cegcc*) ++ version_type=windows ++ shrext_cmds=".dll" ++ need_version=no ++ need_lib_prefix=no ++ ++ case $GCC,$host_os in ++ yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) ++ library_names_spec='$libname.dll.a' ++ # DLL is installed to $(libdir)/../bin by postinstall_cmds ++ postinstall_cmds='base_file=`basename \${file}`~ ++ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ ++ dldir=$destdir/`dirname \$dlpath`~ ++ test -d \$dldir || mkdir -p \$dldir~ ++ $install_prog $dir/$dlname \$dldir/$dlname~ ++ chmod a+x \$dldir/$dlname~ ++ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then ++ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; ++ fi' ++ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ ++ dlpath=$dir/\$dldll~ ++ $RM \$dlpath' ++ shlibpath_overrides_runpath=yes ++ ++ case $host_os in ++ cygwin*) ++ # Cygwin DLLs use 'cyg' prefix rather than 'lib' ++ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ++ ;; ++ mingw* | cegcc*) ++ # MinGW DLLs use traditional 'lib' prefix ++ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then ++ # It is most probably a Windows format PATH printed by ++ # mingw gcc, but we are running on Cygwin. Gcc prints its search ++ # path with ; separators, and with drive letters. We can handle the ++ # drive letters (cygwin fileutils understands them), so leave them, ++ # especially as we might pass files found there to a mingw objdump, ++ # which wouldn't understand a cygwinified path. Ahh. ++ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++ ;; ++ pw32*) ++ # pw32 DLLs use 'pw' prefix rather than 'lib' ++ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ ;; ++ esac ++ ;; ++ ++ *) ++ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ++ ;; ++ esac ++ dynamic_linker='Win32 ld.exe' ++ # FIXME: first we should search . and the directory the executable is in ++ shlibpath_var=PATH ++ ;; ++ ++darwin* | rhapsody*) ++ dynamic_linker="$host_os dyld" ++ version_type=darwin ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' ++ soname_spec='${libname}${release}${major}$shared_ext' ++ shlibpath_overrides_runpath=yes ++ shlibpath_var=DYLD_LIBRARY_PATH ++ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' ++ ++ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" ++ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ++ ;; ++ ++dgux*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++freebsd1*) ++ dynamic_linker=no ++ ;; ++ ++freebsd* | dragonfly*) ++ # DragonFly does not have aout. When/if they implement a new ++ # versioning mechanism, adjust this. ++ if test -x /usr/bin/objformat; then ++ objformat=`/usr/bin/objformat` ++ else ++ case $host_os in ++ freebsd[123]*) objformat=aout ;; ++ *) objformat=elf ;; ++ esac ++ fi ++ version_type=freebsd-$objformat ++ case $version_type in ++ freebsd-elf*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ need_version=no ++ need_lib_prefix=no ++ ;; ++ freebsd-*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' ++ need_version=yes ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_os in ++ freebsd2*) ++ shlibpath_overrides_runpath=yes ++ ;; ++ freebsd3.[01]* | freebsdelf3.[01]*) ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ ++ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ *) # from 4.6 on, and DragonFly ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ esac ++ ;; ++ ++gnu*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ hardcode_into_libs=yes ++ ;; ++ ++hpux9* | hpux10* | hpux11*) ++ # Give a soname corresponding to the major version so that dld.sl refuses to ++ # link against other versions. ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ case $host_cpu in ++ ia64*) ++ shrext_cmds='.so' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.so" ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ if test "X$HPUX_IA64_MODE" = X32; then ++ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" ++ else ++ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" ++ fi ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ hppa*64*) ++ shrext_cmds='.sl' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ *) ++ shrext_cmds='.sl' ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=SHLIB_PATH ++ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ esac ++ # HP-UX runs *really* slowly unless shared libraries are mode 555. ++ postinstall_cmds='chmod 555 $lib' ++ ;; ++ ++interix[3-9]*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ ++irix5* | irix6* | nonstopux*) ++ case $host_os in ++ nonstopux*) version_type=nonstopux ;; ++ *) ++ if test "$lt_cv_prog_gnu_ld" = yes; then ++ version_type=linux ++ else ++ version_type=irix ++ fi ;; ++ esac ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' ++ case $host_os in ++ irix5* | nonstopux*) ++ libsuff= shlibsuff= ++ ;; ++ *) ++ case $LD in # libtool.m4 will add one of these switches to LD ++ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") ++ libsuff= shlibsuff= libmagic=32-bit;; ++ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") ++ libsuff=32 shlibsuff=N32 libmagic=N32;; ++ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") ++ libsuff=64 shlibsuff=64 libmagic=64-bit;; ++ *) libsuff= shlibsuff= libmagic=never-match;; ++ esac ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" ++ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" ++ hardcode_into_libs=yes ++ ;; ++ ++# No shared lib support for Linux oldld, aout, or coff. ++linux*oldld* | linux*aout* | linux*coff*) ++ dynamic_linker=no ++ ;; ++ ++# This must be Linux ELF. ++linux* | k*bsd*-gnu | kopensolaris*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ # Some binutils ld are patched to set DT_RUNPATH ++ save_LDFLAGS=$LDFLAGS ++ save_libdir=$libdir ++ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ ++ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : ++ shlibpath_overrides_runpath=yes ++fi ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++ LDFLAGS=$save_LDFLAGS ++ libdir=$save_libdir ++ ++ # This implies no fast_install, which is unacceptable. ++ # Some rework will be needed to allow for fast_install ++ # before this can be enabled. ++ hardcode_into_libs=yes ++ ++ # Append ld.so.conf contents to the search path ++ if test -f /etc/ld.so.conf; then ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` ++ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" ++ fi ++ ++ # We used to test for /lib/ld.so.1 and disable shared libraries on ++ # powerpc, because MkLinux only supported shared libraries with the ++ # GNU dynamic linker. Since this was broken with cross compilers, ++ # most powerpc-linux boxes support dynamic linking these days and ++ # people can always --disable-shared, the test was removed, and we ++ # assume the GNU/Linux dynamic linker is in use. ++ dynamic_linker='GNU/Linux ld.so' ++ ;; ++ ++netbsdelf*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='NetBSD ld.elf_so' ++ ;; ++ ++netbsd*) ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' ++ dynamic_linker='NetBSD (a.out) ld.so' ++ else ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='NetBSD ld.elf_so' ++ fi ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ ++newsos6) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++*nto* | *qnx*) ++ version_type=qnx ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='ldqnx.so' ++ ;; ++ ++openbsd*) ++ version_type=sunos ++ sys_lib_dlsearch_path_spec="/usr/lib" ++ need_lib_prefix=no ++ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. ++ case $host_os in ++ openbsd3.3 | openbsd3.3.*) need_version=yes ;; ++ *) need_version=no ;; ++ esac ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ case $host_os in ++ openbsd2.[89] | openbsd2.[89].*) ++ shlibpath_overrides_runpath=no ++ ;; ++ *) ++ shlibpath_overrides_runpath=yes ++ ;; ++ esac ++ else ++ shlibpath_overrides_runpath=yes ++ fi ++ ;; ++ ++os2*) ++ libname_spec='$name' ++ shrext_cmds=".dll" ++ need_lib_prefix=no ++ library_names_spec='$libname${shared_ext} $libname.a' ++ dynamic_linker='OS/2 ld.exe' ++ shlibpath_var=LIBPATH ++ ;; ++ ++osf3* | osf4* | osf5*) ++ version_type=osf ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" ++ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ++ ;; ++ ++rdos*) ++ dynamic_linker=no ++ ;; ++ ++solaris*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ # ldd complains unless libraries are executable ++ postinstall_cmds='chmod +x $lib' ++ ;; ++ ++sunos4*) ++ version_type=sunos ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ if test "$with_gnu_ld" = yes; then ++ need_lib_prefix=no ++ fi ++ need_version=yes ++ ;; ++ ++sysv4 | sysv4.3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_vendor in ++ sni) ++ shlibpath_overrides_runpath=no ++ need_lib_prefix=no ++ runpath_var=LD_RUN_PATH ++ ;; ++ siemens) ++ need_lib_prefix=no ++ ;; ++ motorola) ++ need_lib_prefix=no ++ need_version=no ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ++ ;; ++ esac ++ ;; ++ ++sysv4*MP*) ++ if test -d /usr/nec ;then ++ version_type=linux ++ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' ++ soname_spec='$libname${shared_ext}.$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ fi ++ ;; ++ ++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ version_type=freebsd-elf ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ if test "$with_gnu_ld" = yes; then ++ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' ++ else ++ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' ++ case $host_os in ++ sco3.2v5*) ++ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ++ ;; ++ esac ++ fi ++ sys_lib_dlsearch_path_spec='/usr/lib' ++ ;; ++ ++tpf*) ++ # TPF is a cross-target only. Preferred cross-host = GNU/Linux. ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ ++uts4*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++*) ++ dynamic_linker=no ++ ;; ++esac ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 ++$as_echo "$dynamic_linker" >&6; } ++test "$dynamic_linker" = no && can_build_shared=no ++ ++variables_saved_for_relink="PATH $shlibpath_var $runpath_var" ++if test "$GCC" = yes; then ++ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" ++fi ++ ++if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then ++ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" ++fi ++if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then ++ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" ++fi ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 ++$as_echo_n "checking how to hardcode library paths into programs... " >&6; } ++hardcode_action= ++if test -n "$hardcode_libdir_flag_spec" || ++ test -n "$runpath_var" || ++ test "X$hardcode_automatic" = "Xyes" ; then ++ ++ # We can hardcode non-existent directories. ++ if test "$hardcode_direct" != no && ++ # If the only mechanism to avoid hardcoding is shlibpath_var, we ++ # have to relink, otherwise we might link with an installed library ++ # when we should be linking with a yet-to-be-installed one ++ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && ++ test "$hardcode_minus_L" != no; then ++ # Linking always hardcodes the temporary library directory. ++ hardcode_action=relink ++ else ++ # We can link without hardcoding, and we can hardcode nonexisting dirs. ++ hardcode_action=immediate ++ fi ++else ++ # We cannot hardcode anything, or else we can only hardcode existing ++ # directories. ++ hardcode_action=unsupported ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 ++$as_echo "$hardcode_action" >&6; } ++ ++if test "$hardcode_action" = relink || ++ test "$inherit_rpath" = yes; then ++ # Fast installation is not supported ++ enable_fast_install=no ++elif test "$shlibpath_overrides_runpath" = yes || ++ test "$enable_shared" = no; then ++ # Fast installation is not necessary ++ enable_fast_install=needless ++fi ++ ++ ++ ++ ++ ++ ++ if test "x$enable_dlopen" != xyes; then ++ enable_dlopen=unknown ++ enable_dlopen_self=unknown ++ enable_dlopen_self_static=unknown ++else ++ lt_cv_dlopen=no ++ lt_cv_dlopen_libs= ++ ++ case $host_os in ++ beos*) ++ lt_cv_dlopen="load_add_on" ++ lt_cv_dlopen_libs= ++ lt_cv_dlopen_self=yes ++ ;; ++ ++ mingw* | pw32* | cegcc*) ++ lt_cv_dlopen="LoadLibrary" ++ lt_cv_dlopen_libs= ++ ;; ++ ++ cygwin*) ++ lt_cv_dlopen="dlopen" ++ lt_cv_dlopen_libs= ++ ;; ++ ++ darwin*) ++ # if libdl is installed we need to link against it ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 ++$as_echo_n "checking for dlopen in -ldl... " >&6; } ++if test "${ac_cv_lib_dl_dlopen+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-ldl $LIBS" ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char dlopen (); ++int ++main () ++{ ++return dlopen (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_lib_dl_dlopen=yes ++else ++ ac_cv_lib_dl_dlopen=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 ++$as_echo "$ac_cv_lib_dl_dlopen" >&6; } ++if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : ++ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" ++else ++ ++ lt_cv_dlopen="dyld" ++ lt_cv_dlopen_libs= ++ lt_cv_dlopen_self=yes ++ ++fi ++ ++ ;; ++ ++ *) ++ ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" ++if test "x$ac_cv_func_shl_load" = x""yes; then : ++ lt_cv_dlopen="shl_load" ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 ++$as_echo_n "checking for shl_load in -ldld... " >&6; } ++if test "${ac_cv_lib_dld_shl_load+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-ldld $LIBS" ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char shl_load (); ++int ++main () ++{ ++return shl_load (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_lib_dld_shl_load=yes ++else ++ ac_cv_lib_dld_shl_load=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 ++$as_echo "$ac_cv_lib_dld_shl_load" >&6; } ++if test "x$ac_cv_lib_dld_shl_load" = x""yes; then : ++ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" ++else ++ ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" ++if test "x$ac_cv_func_dlopen" = x""yes; then : ++ lt_cv_dlopen="dlopen" ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 ++$as_echo_n "checking for dlopen in -ldl... " >&6; } ++if test "${ac_cv_lib_dl_dlopen+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-ldl $LIBS" ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char dlopen (); ++int ++main () ++{ ++return dlopen (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_lib_dl_dlopen=yes ++else ++ ac_cv_lib_dl_dlopen=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 ++$as_echo "$ac_cv_lib_dl_dlopen" >&6; } ++if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : ++ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 ++$as_echo_n "checking for dlopen in -lsvld... " >&6; } ++if test "${ac_cv_lib_svld_dlopen+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-lsvld $LIBS" ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char dlopen (); ++int ++main () ++{ ++return dlopen (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_lib_svld_dlopen=yes ++else ++ ac_cv_lib_svld_dlopen=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 ++$as_echo "$ac_cv_lib_svld_dlopen" >&6; } ++if test "x$ac_cv_lib_svld_dlopen" = x""yes; then : ++ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 ++$as_echo_n "checking for dld_link in -ldld... " >&6; } ++if test "${ac_cv_lib_dld_dld_link+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-ldld $LIBS" ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char dld_link (); ++int ++main () ++{ ++return dld_link (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_lib_dld_dld_link=yes ++else ++ ac_cv_lib_dld_dld_link=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 ++$as_echo "$ac_cv_lib_dld_dld_link" >&6; } ++if test "x$ac_cv_lib_dld_dld_link" = x""yes; then : ++ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" ++fi ++ ++ ++fi ++ ++ ++fi ++ ++ ++fi ++ ++ ++fi ++ ++ ++fi ++ ++ ;; ++ esac ++ ++ if test "x$lt_cv_dlopen" != xno; then ++ enable_dlopen=yes ++ else ++ enable_dlopen=no ++ fi ++ ++ case $lt_cv_dlopen in ++ dlopen) ++ save_CPPFLAGS="$CPPFLAGS" ++ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" ++ ++ save_LDFLAGS="$LDFLAGS" ++ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" ++ ++ save_LIBS="$LIBS" ++ LIBS="$lt_cv_dlopen_libs $LIBS" ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 ++$as_echo_n "checking whether a program can dlopen itself... " >&6; } ++if test "${lt_cv_dlopen_self+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test "$cross_compiling" = yes; then : ++ lt_cv_dlopen_self=cross ++else ++ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 ++ lt_status=$lt_dlunknown ++ cat > conftest.$ac_ext <<_LT_EOF ++#line 11505 "configure" ++#include "confdefs.h" ++ ++#if HAVE_DLFCN_H ++#include ++#endif ++ ++#include ++ ++#ifdef RTLD_GLOBAL ++# define LT_DLGLOBAL RTLD_GLOBAL ++#else ++# ifdef DL_GLOBAL ++# define LT_DLGLOBAL DL_GLOBAL ++# else ++# define LT_DLGLOBAL 0 ++# endif ++#endif ++ ++/* We may have to define LT_DLLAZY_OR_NOW in the command line if we ++ find out it does not work in some platform. */ ++#ifndef LT_DLLAZY_OR_NOW ++# ifdef RTLD_LAZY ++# define LT_DLLAZY_OR_NOW RTLD_LAZY ++# else ++# ifdef DL_LAZY ++# define LT_DLLAZY_OR_NOW DL_LAZY ++# else ++# ifdef RTLD_NOW ++# define LT_DLLAZY_OR_NOW RTLD_NOW ++# else ++# ifdef DL_NOW ++# define LT_DLLAZY_OR_NOW DL_NOW ++# else ++# define LT_DLLAZY_OR_NOW 0 ++# endif ++# endif ++# endif ++# endif ++#endif ++ ++void fnord() { int i=42;} ++int main () ++{ ++ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); ++ int status = $lt_dlunknown; ++ ++ if (self) ++ { ++ if (dlsym (self,"fnord")) status = $lt_dlno_uscore; ++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; ++ /* dlclose (self); */ ++ } ++ else ++ puts (dlerror ()); ++ ++ return status; ++} ++_LT_EOF ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 ++ (eval $ac_link) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then ++ (./conftest; exit; ) >&5 2>/dev/null ++ lt_status=$? ++ case x$lt_status in ++ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; ++ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; ++ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; ++ esac ++ else : ++ # compilation failed ++ lt_cv_dlopen_self=no ++ fi ++fi ++rm -fr conftest* ++ ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 ++$as_echo "$lt_cv_dlopen_self" >&6; } ++ ++ if test "x$lt_cv_dlopen_self" = xyes; then ++ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 ++$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } ++if test "${lt_cv_dlopen_self_static+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test "$cross_compiling" = yes; then : ++ lt_cv_dlopen_self_static=cross ++else ++ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 ++ lt_status=$lt_dlunknown ++ cat > conftest.$ac_ext <<_LT_EOF ++#line 11601 "configure" ++#include "confdefs.h" ++ ++#if HAVE_DLFCN_H ++#include ++#endif ++ ++#include ++ ++#ifdef RTLD_GLOBAL ++# define LT_DLGLOBAL RTLD_GLOBAL ++#else ++# ifdef DL_GLOBAL ++# define LT_DLGLOBAL DL_GLOBAL ++# else ++# define LT_DLGLOBAL 0 ++# endif ++#endif ++ ++/* We may have to define LT_DLLAZY_OR_NOW in the command line if we ++ find out it does not work in some platform. */ ++#ifndef LT_DLLAZY_OR_NOW ++# ifdef RTLD_LAZY ++# define LT_DLLAZY_OR_NOW RTLD_LAZY ++# else ++# ifdef DL_LAZY ++# define LT_DLLAZY_OR_NOW DL_LAZY ++# else ++# ifdef RTLD_NOW ++# define LT_DLLAZY_OR_NOW RTLD_NOW ++# else ++# ifdef DL_NOW ++# define LT_DLLAZY_OR_NOW DL_NOW ++# else ++# define LT_DLLAZY_OR_NOW 0 ++# endif ++# endif ++# endif ++# endif ++#endif ++ ++void fnord() { int i=42;} ++int main () ++{ ++ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); ++ int status = $lt_dlunknown; ++ ++ if (self) ++ { ++ if (dlsym (self,"fnord")) status = $lt_dlno_uscore; ++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; ++ /* dlclose (self); */ ++ } ++ else ++ puts (dlerror ()); ++ ++ return status; ++} ++_LT_EOF ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 ++ (eval $ac_link) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then ++ (./conftest; exit; ) >&5 2>/dev/null ++ lt_status=$? ++ case x$lt_status in ++ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; ++ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; ++ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; ++ esac ++ else : ++ # compilation failed ++ lt_cv_dlopen_self_static=no ++ fi ++fi ++rm -fr conftest* ++ ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 ++$as_echo "$lt_cv_dlopen_self_static" >&6; } ++ fi ++ ++ CPPFLAGS="$save_CPPFLAGS" ++ LDFLAGS="$save_LDFLAGS" ++ LIBS="$save_LIBS" ++ ;; ++ esac ++ ++ case $lt_cv_dlopen_self in ++ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; ++ *) enable_dlopen_self=unknown ;; ++ esac ++ ++ case $lt_cv_dlopen_self_static in ++ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; ++ *) enable_dlopen_self_static=unknown ;; ++ esac ++fi ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++striplib= ++old_striplib= ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 ++$as_echo_n "checking whether stripping libraries is possible... " >&6; } ++if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then ++ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" ++ test -z "$striplib" && striplib="$STRIP --strip-unneeded" ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++else ++# FIXME - insert some real tests, host_os isn't really good enough ++ case $host_os in ++ darwin*) ++ if test -n "$STRIP" ; then ++ striplib="$STRIP -x" ++ old_striplib="$STRIP -S" ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++ else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ fi ++ ;; ++ *) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ ;; ++ esac ++fi ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ # Report which library types will actually be built ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 ++$as_echo_n "checking if libtool supports shared libraries... " >&6; } ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 ++$as_echo "$can_build_shared" >&6; } ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 ++$as_echo_n "checking whether to build shared libraries... " >&6; } ++ test "$can_build_shared" = "no" && enable_shared=no ++ ++ # On AIX, shared libraries and static libraries use the same namespace, and ++ # are all built from PIC. ++ case $host_os in ++ aix3*) ++ test "$enable_shared" = yes && enable_static=no ++ if test -n "$RANLIB"; then ++ archive_cmds="$archive_cmds~\$RANLIB \$lib" ++ postinstall_cmds='$RANLIB $lib' ++ fi ++ ;; ++ ++ aix[4-9]*) ++ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then ++ test "$enable_shared" = yes && enable_static=no ++ fi ++ ;; ++ esac ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 ++$as_echo "$enable_shared" >&6; } ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 ++$as_echo_n "checking whether to build static libraries... " >&6; } ++ # Make sure either enable_shared or enable_static is yes. ++ test "$enable_shared" = yes || enable_static=yes ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 ++$as_echo "$enable_static" >&6; } ++ ++ ++ ++ ++fi ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++CC="$lt_save_CC" ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ac_config_commands="$ac_config_commands libtool" ++ ++ ++ ++ ++# Only expand once: ++ ++ ++fi ++ ++ac_config_files="$ac_config_files Makefile net/Makefile gloss/Makefile" ++ ++cat >confcache <<\_ACEOF ++# This file is a shell script that caches the results of configure ++# tests run on this system so they can be shared between configure ++# scripts and configure runs, see configure's option --config-cache. ++# It is not useful on other systems. If it contains results you don't ++# want to keep, you may remove or edit it. ++# ++# config.status only pays attention to the cache file if you give it ++# the --recheck option to rerun configure. ++# ++# `ac_cv_env_foo' variables (set or unset) will be overridden when ++# loading this file, other *unset* `ac_cv_foo' will be assigned the ++# following values. ++ ++_ACEOF ++ ++# The following way of writing the cache mishandles newlines in values, ++# but we know of no workaround that is simple, portable, and efficient. ++# So, we kill variables containing newlines. ++# Ultrix sh set writes to stderr and can't be redirected directly, ++# and sets the high bit in the cache file unless we assign to the vars. ++( ++ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do ++ eval ac_val=\$$ac_var ++ case $ac_val in #( ++ *${as_nl}*) ++ case $ac_var in #( ++ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 ++$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; ++ esac ++ case $ac_var in #( ++ _ | IFS | as_nl) ;; #( ++ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( ++ *) { eval $ac_var=; unset $ac_var;} ;; ++ esac ;; ++ esac ++ done ++ ++ (set) 2>&1 | ++ case $as_nl`(ac_space=' '; set) 2>&1` in #( ++ *${as_nl}ac_space=\ *) ++ # `set' does not quote correctly, so add quotes: double-quote ++ # substitution turns \\\\ into \\, and sed turns \\ into \. ++ sed -n \ ++ "s/'/'\\\\''/g; ++ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ++ ;; #( ++ *) ++ # `set' quotes correctly as required by POSIX, so do not add quotes. ++ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ++ ;; ++ esac | ++ sort ++) | ++ sed ' ++ /^ac_cv_env_/b end ++ t clear ++ :clear ++ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ ++ t end ++ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ ++ :end' >>confcache ++if diff "$cache_file" confcache >/dev/null 2>&1; then :; else ++ if test -w "$cache_file"; then ++ test "x$cache_file" != "x/dev/null" && ++ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 ++$as_echo "$as_me: updating cache $cache_file" >&6;} ++ cat confcache >$cache_file ++ else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 ++$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} ++ fi ++fi ++rm -f confcache ++ ++test "x$prefix" = xNONE && prefix=$ac_default_prefix ++# Let make expand exec_prefix. ++test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' ++ ++# Transform confdefs.h into DEFS. ++# Protect against shell expansion while executing Makefile rules. ++# Protect against Makefile macro expansion. ++# ++# If the first sed substitution is executed (which looks for macros that ++# take arguments), then branch to the quote section. Otherwise, ++# look for a macro that doesn't take arguments. ++ac_script=' ++:mline ++/\\$/{ ++ N ++ s,\\\n,, ++ b mline ++} ++t clear ++:clear ++s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g ++t quote ++s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g ++t quote ++b any ++:quote ++s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g ++s/\[/\\&/g ++s/\]/\\&/g ++s/\$/$$/g ++H ++:any ++${ ++ g ++ s/^\n// ++ s/\n/ /g ++ p ++} ++' ++DEFS=`sed -n "$ac_script" confdefs.h` ++ ++ ++ac_libobjs= ++ac_ltlibobjs= ++for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue ++ # 1. Remove the extension, and $U if already installed. ++ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ++ ac_i=`$as_echo "$ac_i" | sed "$ac_script"` ++ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR ++ # will be set to the directory where LIBOBJS objects are built. ++ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" ++ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' ++done ++LIBOBJS=$ac_libobjs ++ ++LTLIBOBJS=$ac_ltlibobjs ++ ++ ++if test -z "${MAY_SUPPLY_SYSCALLS_TRUE}" && test -z "${MAY_SUPPLY_SYSCALLS_FALSE}"; then ++ as_fn_error "conditional \"MAY_SUPPLY_SYSCALLS\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi ++ if test -n "$EXEEXT"; then ++ am__EXEEXT_TRUE= ++ am__EXEEXT_FALSE='#' ++else ++ am__EXEEXT_TRUE='#' ++ am__EXEEXT_FALSE= ++fi ++ ++if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then ++ as_fn_error "conditional \"AMDEP\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi ++if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then ++ as_fn_error "conditional \"am__fastdepCC\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi ++if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then ++ as_fn_error "conditional \"MAINTAINER_MODE\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi ++if test -z "${ELIX_LEVEL_0_TRUE}" && test -z "${ELIX_LEVEL_0_FALSE}"; then ++ as_fn_error "conditional \"ELIX_LEVEL_0\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi ++if test -z "${ELIX_LEVEL_1_TRUE}" && test -z "${ELIX_LEVEL_1_FALSE}"; then ++ as_fn_error "conditional \"ELIX_LEVEL_1\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi ++if test -z "${ELIX_LEVEL_2_TRUE}" && test -z "${ELIX_LEVEL_2_FALSE}"; then ++ as_fn_error "conditional \"ELIX_LEVEL_2\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi ++if test -z "${ELIX_LEVEL_3_TRUE}" && test -z "${ELIX_LEVEL_3_FALSE}"; then ++ as_fn_error "conditional \"ELIX_LEVEL_3\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi ++if test -z "${ELIX_LEVEL_4_TRUE}" && test -z "${ELIX_LEVEL_4_FALSE}"; then ++ as_fn_error "conditional \"ELIX_LEVEL_4\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi ++if test -z "${USE_LIBTOOL_TRUE}" && test -z "${USE_LIBTOOL_FALSE}"; then ++ as_fn_error "conditional \"USE_LIBTOOL\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi ++if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then ++ as_fn_error "conditional \"am__fastdepCC\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi ++ ++: ${CONFIG_STATUS=./config.status} ++ac_write_fail=0 ++ac_clean_files_save=$ac_clean_files ++ac_clean_files="$ac_clean_files $CONFIG_STATUS" ++{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 ++$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} ++as_write_fail=0 ++cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 ++#! $SHELL ++# Generated by $as_me. ++# Run this file to recreate the current configuration. ++# Compiler output produced by configure, useful for debugging ++# configure, is in config.log if it exists. ++ ++debug=false ++ac_cs_recheck=false ++ac_cs_silent=false ++ ++SHELL=\${CONFIG_SHELL-$SHELL} ++export SHELL ++_ASEOF ++cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ++## -------------------- ## ++## M4sh Initialization. ## ++## -------------------- ## ++ ++# Be more Bourne compatible ++DUALCASE=1; export DUALCASE # for MKS sh ++if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : ++ emulate sh ++ NULLCMD=: ++ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which ++ # is contrary to our usage. Disable this feature. ++ alias -g '${1+"$@"}'='"$@"' ++ setopt NO_GLOB_SUBST ++else ++ case `(set -o) 2>/dev/null` in #( ++ *posix*) : ++ set -o posix ;; #( ++ *) : ++ ;; ++esac ++fi ++ ++ ++as_nl=' ++' ++export as_nl ++# Printing a long string crashes Solaris 7 /usr/bin/printf. ++as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ++as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo ++as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo ++# Prefer a ksh shell builtin over an external printf program on Solaris, ++# but without wasting forks for bash or zsh. ++if test -z "$BASH_VERSION$ZSH_VERSION" \ ++ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then ++ as_echo='print -r --' ++ as_echo_n='print -rn --' ++elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then ++ as_echo='printf %s\n' ++ as_echo_n='printf %s' ++else ++ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then ++ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' ++ as_echo_n='/usr/ucb/echo -n' ++ else ++ as_echo_body='eval expr "X$1" : "X\\(.*\\)"' ++ as_echo_n_body='eval ++ arg=$1; ++ case $arg in #( ++ *"$as_nl"*) ++ expr "X$arg" : "X\\(.*\\)$as_nl"; ++ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; ++ esac; ++ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ++ ' ++ export as_echo_n_body ++ as_echo_n='sh -c $as_echo_n_body as_echo' ++ fi ++ export as_echo_body ++ as_echo='sh -c $as_echo_body as_echo' ++fi ++ ++# The user is always right. ++if test "${PATH_SEPARATOR+set}" != set; then ++ PATH_SEPARATOR=: ++ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { ++ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || ++ PATH_SEPARATOR=';' ++ } ++fi ++ ++ ++# IFS ++# We need space, tab and new line, in precisely that order. Quoting is ++# there to prevent editors from complaining about space-tab. ++# (If _AS_PATH_WALK were called with IFS unset, it would disable word ++# splitting by setting IFS to empty value.) ++IFS=" "" $as_nl" ++ ++# Find who we are. Look in the path if we contain no directory separator. ++case $0 in #(( ++ *[\\/]* ) as_myself=$0 ;; ++ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break ++ done ++IFS=$as_save_IFS ++ ++ ;; ++esac ++# We did not find ourselves, most probably we were run as `sh COMMAND' ++# in which case we are not to be found in the path. ++if test "x$as_myself" = x; then ++ as_myself=$0 ++fi ++if test ! -f "$as_myself"; then ++ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 ++ exit 1 ++fi ++ ++# Unset variables that we do not need and which cause bugs (e.g. in ++# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" ++# suppresses any "Segmentation fault" message there. '((' could ++# trigger a bug in pdksh 5.2.14. ++for as_var in BASH_ENV ENV MAIL MAILPATH ++do eval test x\${$as_var+set} = xset \ ++ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : ++done ++PS1='$ ' ++PS2='> ' ++PS4='+ ' ++ ++# NLS nuisances. ++LC_ALL=C ++export LC_ALL ++LANGUAGE=C ++export LANGUAGE ++ ++# CDPATH. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++ ++# as_fn_error ERROR [LINENO LOG_FD] ++# --------------------------------- ++# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are ++# provided, also output the error to LOG_FD, referencing LINENO. Then exit the ++# script with status $?, using 1 if that was 0. ++as_fn_error () ++{ ++ as_status=$?; test $as_status -eq 0 && as_status=1 ++ if test "$3"; then ++ as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 ++ fi ++ $as_echo "$as_me: error: $1" >&2 ++ as_fn_exit $as_status ++} # as_fn_error ++ ++ ++# as_fn_set_status STATUS ++# ----------------------- ++# Set $? to STATUS, without forking. ++as_fn_set_status () ++{ ++ return $1 ++} # as_fn_set_status ++ ++# as_fn_exit STATUS ++# ----------------- ++# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. ++as_fn_exit () ++{ ++ set +e ++ as_fn_set_status $1 ++ exit $1 ++} # as_fn_exit ++ ++# as_fn_unset VAR ++# --------------- ++# Portably unset VAR. ++as_fn_unset () ++{ ++ { eval $1=; unset $1;} ++} ++as_unset=as_fn_unset ++# as_fn_append VAR VALUE ++# ---------------------- ++# Append the text in VALUE to the end of the definition contained in VAR. Take ++# advantage of any shell optimizations that allow amortized linear growth over ++# repeated appends, instead of the typical quadratic growth present in naive ++# implementations. ++if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : ++ eval 'as_fn_append () ++ { ++ eval $1+=\$2 ++ }' ++else ++ as_fn_append () ++ { ++ eval $1=\$$1\$2 ++ } ++fi # as_fn_append ++ ++# as_fn_arith ARG... ++# ------------------ ++# Perform arithmetic evaluation on the ARGs, and store the result in the ++# global $as_val. Take advantage of shells that can avoid forks. The arguments ++# must be portable across $(()) and expr. ++if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : ++ eval 'as_fn_arith () ++ { ++ as_val=$(( $* )) ++ }' ++else ++ as_fn_arith () ++ { ++ as_val=`expr "$@" || test $? -eq 1` ++ } ++fi # as_fn_arith ++ ++ ++if expr a : '\(a\)' >/dev/null 2>&1 && ++ test "X`expr 00001 : '.*\(...\)'`" = X001; then ++ as_expr=expr ++else ++ as_expr=false ++fi ++ ++if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then ++ as_basename=basename ++else ++ as_basename=false ++fi ++ ++if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then ++ as_dirname=dirname ++else ++ as_dirname=false ++fi ++ ++as_me=`$as_basename -- "$0" || ++$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ ++ X"$0" : 'X\(//\)$' \| \ ++ X"$0" : 'X\(/\)' \| . 2>/dev/null || ++$as_echo X/"$0" | ++ sed '/^.*\/\([^/][^/]*\)\/*$/{ ++ s//\1/ ++ q ++ } ++ /^X\/\(\/\/\)$/{ ++ s//\1/ ++ q ++ } ++ /^X\/\(\/\).*/{ ++ s//\1/ ++ q ++ } ++ s/.*/./; q'` ++ ++# Avoid depending upon Character Ranges. ++as_cr_letters='abcdefghijklmnopqrstuvwxyz' ++as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' ++as_cr_Letters=$as_cr_letters$as_cr_LETTERS ++as_cr_digits='0123456789' ++as_cr_alnum=$as_cr_Letters$as_cr_digits ++ ++ECHO_C= ECHO_N= ECHO_T= ++case `echo -n x` in #((((( ++-n*) ++ case `echo 'xy\c'` in ++ *c*) ECHO_T=' ';; # ECHO_T is single tab character. ++ xy) ECHO_C='\c';; ++ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ++ ECHO_T=' ';; ++ esac;; ++*) ++ ECHO_N='-n';; ++esac ++ ++rm -f conf$$ conf$$.exe conf$$.file ++if test -d conf$$.dir; then ++ rm -f conf$$.dir/conf$$.file ++else ++ rm -f conf$$.dir ++ mkdir conf$$.dir 2>/dev/null ++fi ++if (echo >conf$$.file) 2>/dev/null; then ++ if ln -s conf$$.file conf$$ 2>/dev/null; then ++ as_ln_s='ln -s' ++ # ... but there are two gotchas: ++ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. ++ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. ++ # In both cases, we have to default to `cp -p'. ++ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || ++ as_ln_s='cp -p' ++ elif ln conf$$.file conf$$ 2>/dev/null; then ++ as_ln_s=ln ++ else ++ as_ln_s='cp -p' ++ fi ++else ++ as_ln_s='cp -p' ++fi ++rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file ++rmdir conf$$.dir 2>/dev/null ++ ++ ++# as_fn_mkdir_p ++# ------------- ++# Create "$as_dir" as a directory, including parents if necessary. ++as_fn_mkdir_p () ++{ ++ ++ case $as_dir in #( ++ -*) as_dir=./$as_dir;; ++ esac ++ test -d "$as_dir" || eval $as_mkdir_p || { ++ as_dirs= ++ while :; do ++ case $as_dir in #( ++ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( ++ *) as_qdir=$as_dir;; ++ esac ++ as_dirs="'$as_qdir' $as_dirs" ++ as_dir=`$as_dirname -- "$as_dir" || ++$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$as_dir" : 'X\(//\)[^/]' \| \ ++ X"$as_dir" : 'X\(//\)$' \| \ ++ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || ++$as_echo X"$as_dir" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)[^/].*/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\).*/{ ++ s//\1/ ++ q ++ } ++ s/.*/./; q'` ++ test -d "$as_dir" && break ++ done ++ test -z "$as_dirs" || eval "mkdir $as_dirs" ++ } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" ++ ++ ++} # as_fn_mkdir_p ++if mkdir -p . 2>/dev/null; then ++ as_mkdir_p='mkdir -p "$as_dir"' ++else ++ test -d ./-p && rmdir ./-p ++ as_mkdir_p=false ++fi ++ ++if test -x / >/dev/null 2>&1; then ++ as_test_x='test -x' ++else ++ if ls -dL / >/dev/null 2>&1; then ++ as_ls_L_option=L ++ else ++ as_ls_L_option= ++ fi ++ as_test_x=' ++ eval sh -c '\'' ++ if test -d "$1"; then ++ test -d "$1/."; ++ else ++ case $1 in #( ++ -*)set "./$1";; ++ esac; ++ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ++ ???[sx]*):;;*)false;;esac;fi ++ '\'' sh ++ ' ++fi ++as_executable_p=$as_test_x ++ ++# Sed expression to map a string onto a valid CPP name. ++as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" ++ ++# Sed expression to map a string onto a valid variable name. ++as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" ++ ++ ++exec 6>&1 ++## ----------------------------------- ## ++## Main body of $CONFIG_STATUS script. ## ++## ----------------------------------- ## ++_ASEOF ++test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 ++ ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ++# Save the log message, to keep $0 and so on meaningful, and to ++# report actual input values of CONFIG_FILES etc. instead of their ++# values after options handling. ++ac_log=" ++This file was extended by newlib $as_me 1.19.0, which was ++generated by GNU Autoconf 2.65. Invocation command line was ++ ++ CONFIG_FILES = $CONFIG_FILES ++ CONFIG_HEADERS = $CONFIG_HEADERS ++ CONFIG_LINKS = $CONFIG_LINKS ++ CONFIG_COMMANDS = $CONFIG_COMMANDS ++ $ $0 $@ ++ ++on `(hostname || uname -n) 2>/dev/null | sed 1q` ++" ++ ++_ACEOF ++ ++case $ac_config_files in *" ++"*) set x $ac_config_files; shift; ac_config_files=$*;; ++esac ++ ++ ++ ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ++# Files that config.status was made for. ++config_files="$ac_config_files" ++config_commands="$ac_config_commands" ++ ++_ACEOF ++ ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ++ac_cs_usage="\ ++\`$as_me' instantiates files and other configuration actions ++from templates according to the current configuration. Unless the files ++and actions are specified as TAGs, all are instantiated by default. ++ ++Usage: $0 [OPTION]... [TAG]... ++ ++ -h, --help print this help, then exit ++ -V, --version print version number and configuration settings, then exit ++ --config print configuration, then exit ++ -q, --quiet, --silent ++ do not print progress messages ++ -d, --debug don't remove temporary files ++ --recheck update $as_me by reconfiguring in the same conditions ++ --file=FILE[:TEMPLATE] ++ instantiate the configuration file FILE ++ ++Configuration files: ++$config_files ++ ++Configuration commands: ++$config_commands ++ ++Report bugs to the package provider." ++ ++_ACEOF ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ++ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ++ac_cs_version="\\ ++newlib config.status 1.19.0 ++configured by $0, generated by GNU Autoconf 2.65, ++ with options \\"\$ac_cs_config\\" ++ ++Copyright (C) 2009 Free Software Foundation, Inc. ++This config.status script is free software; the Free Software Foundation ++gives unlimited permission to copy, distribute and modify it." ++ ++ac_pwd='$ac_pwd' ++srcdir='$srcdir' ++INSTALL='$INSTALL' ++MKDIR_P='$MKDIR_P' ++AWK='$AWK' ++test -n "\$AWK" || AWK=awk ++_ACEOF ++ ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ++# The default lists apply if the user does not specify any file. ++ac_need_defaults=: ++while test $# != 0 ++do ++ case $1 in ++ --*=*) ++ ac_option=`expr "X$1" : 'X\([^=]*\)='` ++ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ++ ac_shift=: ++ ;; ++ *) ++ ac_option=$1 ++ ac_optarg=$2 ++ ac_shift=shift ++ ;; ++ esac ++ ++ case $ac_option in ++ # Handling of the options. ++ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ++ ac_cs_recheck=: ;; ++ --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) ++ $as_echo "$ac_cs_version"; exit ;; ++ --config | --confi | --conf | --con | --co | --c ) ++ $as_echo "$ac_cs_config"; exit ;; ++ --debug | --debu | --deb | --de | --d | -d ) ++ debug=: ;; ++ --file | --fil | --fi | --f ) ++ $ac_shift ++ case $ac_optarg in ++ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; ++ esac ++ as_fn_append CONFIG_FILES " '$ac_optarg'" ++ ac_need_defaults=false;; ++ --he | --h | --help | --hel | -h ) ++ $as_echo "$ac_cs_usage"; exit ;; ++ -q | -quiet | --quiet | --quie | --qui | --qu | --q \ ++ | -silent | --silent | --silen | --sile | --sil | --si | --s) ++ ac_cs_silent=: ;; ++ ++ # This is an error. ++ -*) as_fn_error "unrecognized option: \`$1' ++Try \`$0 --help' for more information." ;; ++ ++ *) as_fn_append ac_config_targets " $1" ++ ac_need_defaults=false ;; ++ ++ esac ++ shift ++done ++ ++ac_configure_extra_args= ++ ++if $ac_cs_silent; then ++ exec 6>/dev/null ++ ac_configure_extra_args="$ac_configure_extra_args --silent" ++fi ++ ++_ACEOF ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ++if \$ac_cs_recheck; then ++ set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion ++ shift ++ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 ++ CONFIG_SHELL='$SHELL' ++ export CONFIG_SHELL ++ exec "\$@" ++fi ++ ++_ACEOF ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ++exec 5>>config.log ++{ ++ echo ++ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ++## Running $as_me. ## ++_ASBOX ++ $as_echo "$ac_log" ++} >&5 ++ ++_ACEOF ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ++# ++# INIT-COMMANDS ++# ++AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" ++ ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++sed_quote_subst='$sed_quote_subst' ++double_quote_subst='$double_quote_subst' ++delay_variable_subst='$delay_variable_subst' ++SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`' ++Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`' ++SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`' ++ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`' ++AS='`$ECHO "X$AS" | $Xsed -e "$delay_single_quote_subst"`' ++DLLTOOL='`$ECHO "X$DLLTOOL" | $Xsed -e "$delay_single_quote_subst"`' ++OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`' ++macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`' ++macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`' ++enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`' ++enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`' ++pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`' ++enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`' ++host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`' ++host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`' ++host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`' ++build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`' ++build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`' ++build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`' ++GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`' ++EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`' ++FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`' ++LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`' ++NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`' ++LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`' ++max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`' ++ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`' ++exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`' ++lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`' ++lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`' ++lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`' ++reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`' ++reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`' ++file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`' ++AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`' ++AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`' ++STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`' ++RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`' ++old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`' ++CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`' ++compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`' ++GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' ++objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`' ++MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`' ++lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`' ++lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`' ++need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`' ++DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`' ++NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`' ++LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`' ++OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`' ++OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`' ++libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`' ++shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`' ++enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`' ++export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`' ++allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' ++no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`' ++inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`' ++link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`' ++fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`' ++always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`' ++export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`' ++include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`' ++prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`' ++variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`' ++need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' ++need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`' ++version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`' ++runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' ++shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`' ++libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`' ++library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`' ++soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`' ++postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`' ++finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`' ++sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`' ++sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`' ++hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`' ++enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`' ++old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`' ++striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`' ++ ++LTCC='$LTCC' ++LTCFLAGS='$LTCFLAGS' ++compiler='$compiler_DEFAULT' ++ ++# Quote evaled strings. ++for var in SED \ ++SHELL \ ++ECHO \ ++GREP \ ++EGREP \ ++FGREP \ ++LD \ ++NM \ ++LN_S \ ++lt_SP2NL \ ++lt_NL2SP \ ++reload_flag \ ++deplibs_check_method \ ++file_magic_cmd \ ++AR \ ++AR_FLAGS \ ++STRIP \ ++RANLIB \ ++CC \ ++CFLAGS \ ++compiler \ ++lt_cv_sys_global_symbol_pipe \ ++lt_cv_sys_global_symbol_to_cdecl \ ++lt_cv_sys_global_symbol_to_c_name_address \ ++lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ ++lt_prog_compiler_no_builtin_flag \ ++lt_prog_compiler_wl \ ++lt_prog_compiler_pic \ ++lt_prog_compiler_static \ ++lt_cv_prog_compiler_c_o \ ++need_locks \ ++DSYMUTIL \ ++NMEDIT \ ++LIPO \ ++OTOOL \ ++OTOOL64 \ ++shrext_cmds \ ++export_dynamic_flag_spec \ ++whole_archive_flag_spec \ ++compiler_needs_object \ ++with_gnu_ld \ ++allow_undefined_flag \ ++no_undefined_flag \ ++hardcode_libdir_flag_spec \ ++hardcode_libdir_flag_spec_ld \ ++hardcode_libdir_separator \ ++fix_srcfile_path \ ++exclude_expsyms \ ++include_expsyms \ ++file_list_spec \ ++variables_saved_for_relink \ ++libname_spec \ ++library_names_spec \ ++soname_spec \ ++finish_eval \ ++old_striplib \ ++striplib; do ++ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in ++ *[\\\\\\\`\\"\\\$]*) ++ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ++ ;; ++ *) ++ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ++ ;; ++ esac ++done ++ ++# Double-quote double-evaled strings. ++for var in reload_cmds \ ++old_postinstall_cmds \ ++old_postuninstall_cmds \ ++old_archive_cmds \ ++extract_expsyms_cmds \ ++old_archive_from_new_cmds \ ++old_archive_from_expsyms_cmds \ ++archive_cmds \ ++archive_expsym_cmds \ ++module_cmds \ ++module_expsym_cmds \ ++export_symbols_cmds \ ++prelink_cmds \ ++postinstall_cmds \ ++postuninstall_cmds \ ++finish_cmds \ ++sys_lib_search_path_spec \ ++sys_lib_dlsearch_path_spec; do ++ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in ++ *[\\\\\\\`\\"\\\$]*) ++ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ++ ;; ++ *) ++ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ++ ;; ++ esac ++done ++ ++# Fix-up fallback echo if it was mangled by the above quoting rules. ++case \$lt_ECHO in ++*'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\` ++ ;; ++esac ++ ++ac_aux_dir='$ac_aux_dir' ++xsi_shell='$xsi_shell' ++lt_shell_append='$lt_shell_append' ++ ++# See if we are running on zsh, and set the options which allow our ++# commands through without removal of \ escapes INIT. ++if test -n "\${ZSH_VERSION+set}" ; then ++ setopt NO_GLOB_SUBST ++fi ++ ++ ++ PACKAGE='$PACKAGE' ++ VERSION='$VERSION' ++ TIMESTAMP='$TIMESTAMP' ++ RM='$RM' ++ ofile='$ofile' ++ ++ ++ ++ ++_ACEOF ++ ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ++ ++# Handling of arguments. ++for ac_config_target in $ac_config_targets ++do ++ case $ac_config_target in ++ "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; ++ "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; ++ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; ++ "net/Makefile") CONFIG_FILES="$CONFIG_FILES net/Makefile" ;; ++ "gloss/Makefile") CONFIG_FILES="$CONFIG_FILES gloss/Makefile" ;; ++ ++ *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;; ++ esac ++done ++ ++ ++# If the user did not use the arguments to specify the items to instantiate, ++# then the envvar interface is used. Set only those that are not. ++# We use the long form for the default assignment because of an extremely ++# bizarre bug on SunOS 4.1.3. ++if $ac_need_defaults; then ++ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files ++ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands ++fi ++ ++# Have a temporary directory for convenience. Make it in the build tree ++# simply because there is no reason against having it here, and in addition, ++# creating and moving files from /tmp can sometimes cause problems. ++# Hook for its removal unless debugging. ++# Note that there is a small window in which the directory will not be cleaned: ++# after its creation but before its name has been assigned to `$tmp'. ++$debug || ++{ ++ tmp= ++ trap 'exit_status=$? ++ { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ++' 0 ++ trap 'as_fn_exit 1' 1 2 13 15 ++} ++# Create a (secure) tmp directory for tmp files. ++ ++{ ++ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && ++ test -n "$tmp" && test -d "$tmp" ++} || ++{ ++ tmp=./conf$$-$RANDOM ++ (umask 077 && mkdir "$tmp") ++} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5 ++ ++# Set up the scripts for CONFIG_FILES section. ++# No need to generate them if there are no CONFIG_FILES. ++# This happens for instance with `./config.status config.h'. ++if test -n "$CONFIG_FILES"; then ++ ++ ++ac_cr=`echo X | tr X '\015'` ++# On cygwin, bash can eat \r inside `` if the user requested igncr. ++# But we know of no other shell where ac_cr would be empty at this ++# point, so we can use a bashism as a fallback. ++if test "x$ac_cr" = x; then ++ eval ac_cr=\$\'\\r\' ++fi ++ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` ++if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ++ ac_cs_awk_cr='\r' ++else ++ ac_cs_awk_cr=$ac_cr ++fi ++ ++echo 'BEGIN {' >"$tmp/subs1.awk" && ++_ACEOF ++ ++ ++{ ++ echo "cat >conf$$subs.awk <<_ACEOF" && ++ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && ++ echo "_ACEOF" ++} >conf$$subs.sh || ++ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 ++ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` ++ac_delim='%!_!# ' ++for ac_last_try in false false false false false :; do ++ . ./conf$$subs.sh || ++ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 ++ ++ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` ++ if test $ac_delim_n = $ac_delim_num; then ++ break ++ elif $ac_last_try; then ++ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 ++ else ++ ac_delim="$ac_delim!$ac_delim _$ac_delim!! " ++ fi ++done ++rm -f conf$$subs.sh ++ ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ++cat >>"\$tmp/subs1.awk" <<\\_ACAWK && ++_ACEOF ++sed -n ' ++h ++s/^/S["/; s/!.*/"]=/ ++p ++g ++s/^[^!]*!// ++:repl ++t repl ++s/'"$ac_delim"'$// ++t delim ++:nl ++h ++s/\(.\{148\}\)..*/\1/ ++t more1 ++s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ ++p ++n ++b repl ++:more1 ++s/["\\]/\\&/g; s/^/"/; s/$/"\\/ ++p ++g ++s/.\{148\}// ++t nl ++:delim ++h ++s/\(.\{148\}\)..*/\1/ ++t more2 ++s/["\\]/\\&/g; s/^/"/; s/$/"/ ++p ++b ++:more2 ++s/["\\]/\\&/g; s/^/"/; s/$/"\\/ ++p ++g ++s/.\{148\}// ++t delim ++' >$CONFIG_STATUS || ac_write_fail=1 ++rm -f conf$$subs.awk ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ++_ACAWK ++cat >>"\$tmp/subs1.awk" <<_ACAWK && ++ for (key in S) S_is_set[key] = 1 ++ FS = "" ++ ++} ++{ ++ line = $ 0 ++ nfields = split(line, field, "@") ++ substed = 0 ++ len = length(field[1]) ++ for (i = 2; i < nfields; i++) { ++ key = field[i] ++ keylen = length(key) ++ if (S_is_set[key]) { ++ value = S[key] ++ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) ++ len += length(value) + length(field[++i]) ++ substed = 1 ++ } else ++ len += 1 + keylen ++ } ++ ++ print line ++} ++ ++_ACAWK ++_ACEOF ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ++if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then ++ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" ++else ++ cat ++fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ ++ || as_fn_error "could not setup config files machinery" "$LINENO" 5 ++_ACEOF ++ ++# VPATH may cause trouble with some makes, so we remove $(srcdir), ++# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and ++# trailing colons and then remove the whole line if VPATH becomes empty ++# (actually we leave an empty line to preserve line numbers). ++if test "x$srcdir" = x.; then ++ ac_vpsub='/^[ ]*VPATH[ ]*=/{ ++s/:*\$(srcdir):*/:/ ++s/:*\${srcdir}:*/:/ ++s/:*@srcdir@:*/:/ ++s/^\([^=]*=[ ]*\):*/\1/ ++s/:*$// ++s/^[^=]*=[ ]*$// ++}' ++fi ++ ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ++fi # test -n "$CONFIG_FILES" ++ ++ ++eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS" ++shift ++for ac_tag ++do ++ case $ac_tag in ++ :[FHLC]) ac_mode=$ac_tag; continue;; ++ esac ++ case $ac_mode$ac_tag in ++ :[FHL]*:*);; ++ :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;; ++ :[FH]-) ac_tag=-:-;; ++ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; ++ esac ++ ac_save_IFS=$IFS ++ IFS=: ++ set x $ac_tag ++ IFS=$ac_save_IFS ++ shift ++ ac_file=$1 ++ shift ++ ++ case $ac_mode in ++ :L) ac_source=$1;; ++ :[FH]) ++ ac_file_inputs= ++ for ac_f ++ do ++ case $ac_f in ++ -) ac_f="$tmp/stdin";; ++ *) # Look for the file first in the build tree, then in the source tree ++ # (if the path is not absolute). The absolute path cannot be DOS-style, ++ # because $ac_f cannot contain `:'. ++ test -f "$ac_f" || ++ case $ac_f in ++ [\\/$]*) false;; ++ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; ++ esac || ++ as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;; ++ esac ++ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac ++ as_fn_append ac_file_inputs " '$ac_f'" ++ done ++ ++ # Let's still pretend it is `configure' which instantiates (i.e., don't ++ # use $as_me), people would be surprised to read: ++ # /* config.h. Generated by config.status. */ ++ configure_input='Generated from '` ++ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' ++ `' by configure.' ++ if test x"$ac_file" != x-; then ++ configure_input="$ac_file. $configure_input" ++ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 ++$as_echo "$as_me: creating $ac_file" >&6;} ++ fi ++ # Neutralize special characters interpreted by sed in replacement strings. ++ case $configure_input in #( ++ *\&* | *\|* | *\\* ) ++ ac_sed_conf_input=`$as_echo "$configure_input" | ++ sed 's/[\\\\&|]/\\\\&/g'`;; #( ++ *) ac_sed_conf_input=$configure_input;; ++ esac ++ ++ case $ac_tag in ++ *:-:* | *:-) cat >"$tmp/stdin" \ ++ || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; ++ esac ++ ;; ++ esac ++ ++ ac_dir=`$as_dirname -- "$ac_file" || ++$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$ac_file" : 'X\(//\)[^/]' \| \ ++ X"$ac_file" : 'X\(//\)$' \| \ ++ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || ++$as_echo X"$ac_file" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)[^/].*/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\).*/{ ++ s//\1/ ++ q ++ } ++ s/.*/./; q'` ++ as_dir="$ac_dir"; as_fn_mkdir_p ++ ac_builddir=. ++ ++case "$ac_dir" in ++.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; ++*) ++ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` ++ # A ".." for each directory in $ac_dir_suffix. ++ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` ++ case $ac_top_builddir_sub in ++ "") ac_top_builddir_sub=. ac_top_build_prefix= ;; ++ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; ++ esac ;; ++esac ++ac_abs_top_builddir=$ac_pwd ++ac_abs_builddir=$ac_pwd$ac_dir_suffix ++# for backward compatibility: ++ac_top_builddir=$ac_top_build_prefix ++ ++case $srcdir in ++ .) # We are building in place. ++ ac_srcdir=. ++ ac_top_srcdir=$ac_top_builddir_sub ++ ac_abs_top_srcdir=$ac_pwd ;; ++ [\\/]* | ?:[\\/]* ) # Absolute name. ++ ac_srcdir=$srcdir$ac_dir_suffix; ++ ac_top_srcdir=$srcdir ++ ac_abs_top_srcdir=$srcdir ;; ++ *) # Relative name. ++ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ++ ac_top_srcdir=$ac_top_build_prefix$srcdir ++ ac_abs_top_srcdir=$ac_pwd/$srcdir ;; ++esac ++ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix ++ ++ ++ case $ac_mode in ++ :F) ++ # ++ # CONFIG_FILE ++ # ++ ++ case $INSTALL in ++ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; ++ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; ++ esac ++ ac_MKDIR_P=$MKDIR_P ++ case $MKDIR_P in ++ [\\/$]* | ?:[\\/]* ) ;; ++ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; ++ esac ++_ACEOF ++ ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ++# If the template does not know about datarootdir, expand it. ++# FIXME: This hack should be removed a few years after 2.60. ++ac_datarootdir_hack=; ac_datarootdir_seen= ++ac_sed_dataroot=' ++/datarootdir/ { ++ p ++ q ++} ++/@datadir@/p ++/@docdir@/p ++/@infodir@/p ++/@localedir@/p ++/@mandir@/p' ++case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in ++*datarootdir*) ac_datarootdir_seen=yes;; ++*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 ++$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} ++_ACEOF ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ++ ac_datarootdir_hack=' ++ s&@datadir@&$datadir&g ++ s&@docdir@&$docdir&g ++ s&@infodir@&$infodir&g ++ s&@localedir@&$localedir&g ++ s&@mandir@&$mandir&g ++ s&\\\${datarootdir}&$datarootdir&g' ;; ++esac ++_ACEOF ++ ++# Neutralize VPATH when `$srcdir' = `.'. ++# Shell code in configure.ac might set extrasub. ++# FIXME: do we really want to maintain this feature? ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ++ac_sed_extra="$ac_vpsub ++$extrasub ++_ACEOF ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ++:t ++/@[a-zA-Z_][a-zA-Z_0-9]*@/!b ++s|@configure_input@|$ac_sed_conf_input|;t t ++s&@top_builddir@&$ac_top_builddir_sub&;t t ++s&@top_build_prefix@&$ac_top_build_prefix&;t t ++s&@srcdir@&$ac_srcdir&;t t ++s&@abs_srcdir@&$ac_abs_srcdir&;t t ++s&@top_srcdir@&$ac_top_srcdir&;t t ++s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t ++s&@builddir@&$ac_builddir&;t t ++s&@abs_builddir@&$ac_abs_builddir&;t t ++s&@abs_top_builddir@&$ac_abs_top_builddir&;t t ++s&@INSTALL@&$ac_INSTALL&;t t ++s&@MKDIR_P@&$ac_MKDIR_P&;t t ++$ac_datarootdir_hack ++" ++eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ ++ || as_fn_error "could not create $ac_file" "$LINENO" 5 ++ ++test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && ++ { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && ++ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' ++which seems to be undefined. Please make sure it is defined." >&5 ++$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' ++which seems to be undefined. Please make sure it is defined." >&2;} ++ ++ rm -f "$tmp/stdin" ++ case $ac_file in ++ -) cat "$tmp/out" && rm -f "$tmp/out";; ++ *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; ++ esac \ ++ || as_fn_error "could not create $ac_file" "$LINENO" 5 ++ ;; ++ ++ ++ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 ++$as_echo "$as_me: executing $ac_file commands" >&6;} ++ ;; ++ esac ++ ++ ++ case $ac_file$ac_mode in ++ "depfiles":C) test x"$AMDEP_TRUE" != x"" || { ++ # Autoconf 2.62 quotes --file arguments for eval, but not when files ++ # are listed without --file. Let's play safe and only enable the eval ++ # if we detect the quoting. ++ case $CONFIG_FILES in ++ *\'*) eval set x "$CONFIG_FILES" ;; ++ *) set x $CONFIG_FILES ;; ++ esac ++ shift ++ for mf ++ do ++ # Strip MF so we end up with the name of the file. ++ mf=`echo "$mf" | sed -e 's/:.*$//'` ++ # Check whether this is an Automake generated Makefile or not. ++ # We used to match only the files named `Makefile.in', but ++ # some people rename them; so instead we look at the file content. ++ # Grep'ing the first line is not enough: some people post-process ++ # each Makefile.in and add a new line on top of each file to say so. ++ # Grep'ing the whole file is not good either: AIX grep has a line ++ # limit of 2048, but all sed's we know have understand at least 4000. ++ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then ++ dirpart=`$as_dirname -- "$mf" || ++$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$mf" : 'X\(//\)[^/]' \| \ ++ X"$mf" : 'X\(//\)$' \| \ ++ X"$mf" : 'X\(/\)' \| . 2>/dev/null || ++$as_echo X"$mf" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)[^/].*/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\).*/{ ++ s//\1/ ++ q ++ } ++ s/.*/./; q'` ++ else ++ continue ++ fi ++ # Extract the definition of DEPDIR, am__include, and am__quote ++ # from the Makefile without running `make'. ++ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` ++ test -z "$DEPDIR" && continue ++ am__include=`sed -n 's/^am__include = //p' < "$mf"` ++ test -z "am__include" && continue ++ am__quote=`sed -n 's/^am__quote = //p' < "$mf"` ++ # When using ansi2knr, U may be empty or an underscore; expand it ++ U=`sed -n 's/^U = //p' < "$mf"` ++ # Find all dependency output files, they are included files with ++ # $(DEPDIR) in their names. We invoke sed twice because it is the ++ # simplest approach to changing $(DEPDIR) to its actual value in the ++ # expansion. ++ for file in `sed -n " ++ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ ++ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do ++ # Make sure the directory exists. ++ test -f "$dirpart/$file" && continue ++ fdir=`$as_dirname -- "$file" || ++$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$file" : 'X\(//\)[^/]' \| \ ++ X"$file" : 'X\(//\)$' \| \ ++ X"$file" : 'X\(/\)' \| . 2>/dev/null || ++$as_echo X"$file" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)[^/].*/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\).*/{ ++ s//\1/ ++ q ++ } ++ s/.*/./; q'` ++ as_dir=$dirpart/$fdir; as_fn_mkdir_p ++ # echo "creating $dirpart/$file" ++ echo '# dummy' > "$dirpart/$file" ++ done ++ done ++} ++ ;; ++ "libtool":C) ++ ++ # See if we are running on zsh, and set the options which allow our ++ # commands through without removal of \ escapes. ++ if test -n "${ZSH_VERSION+set}" ; then ++ setopt NO_GLOB_SUBST ++ fi ++ ++ cfgfile="${ofile}T" ++ trap "$RM \"$cfgfile\"; exit 1" 1 2 15 ++ $RM "$cfgfile" ++ ++ cat <<_LT_EOF >> "$cfgfile" ++#! $SHELL ++ ++# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. ++# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION ++# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: ++# NOTE: Changes made to this file will be lost: look at ltmain.sh. ++# ++# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, ++# 2006, 2007, 2008 Free Software Foundation, Inc. ++# Written by Gordon Matzigkeit, 1996 ++# ++# This file is part of GNU Libtool. ++# ++# GNU Libtool 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. ++# ++# As a special exception to the GNU General Public License, ++# if you distribute this file as part of a program or library that ++# is built using GNU Libtool, you may include this file under the ++# same distribution terms that you use for the rest of that program. ++# ++# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy ++# can be downloaded from http://www.gnu.org/licenses/gpl.html, or ++# obtained by writing to the Free Software Foundation, Inc., ++# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ ++ ++# The names of the tagged configurations supported by this script. ++available_tags="" ++ ++# ### BEGIN LIBTOOL CONFIG ++ ++# A sed program that does not truncate output. ++SED=$lt_SED ++ ++# Sed that helps us avoid accidentally triggering echo(1) options like -n. ++Xsed="\$SED -e 1s/^X//" ++ ++# Shell to use when invoking shell scripts. ++SHELL=$lt_SHELL ++ ++# An echo program that does not interpret backslashes. ++ECHO=$lt_ECHO ++ ++# Assembler program. ++AS=$AS ++ ++# DLL creation program. ++DLLTOOL=$DLLTOOL ++ ++# Object dumper program. ++OBJDUMP=$OBJDUMP ++ ++# Which release of libtool.m4 was used? ++macro_version=$macro_version ++macro_revision=$macro_revision ++ ++# Whether or not to build shared libraries. ++build_libtool_libs=$enable_shared ++ ++# Whether or not to build static libraries. ++build_old_libs=$enable_static ++ ++# What type of objects to build. ++pic_mode=$pic_mode ++ ++# Whether or not to optimize for fast installation. ++fast_install=$enable_fast_install ++ ++# The host system. ++host_alias=$host_alias ++host=$host ++host_os=$host_os ++ ++# The build system. ++build_alias=$build_alias ++build=$build ++build_os=$build_os ++ ++# A grep program that handles long lines. ++GREP=$lt_GREP ++ ++# An ERE matcher. ++EGREP=$lt_EGREP ++ ++# A literal string matcher. ++FGREP=$lt_FGREP ++ ++# A BSD- or MS-compatible name lister. ++NM=$lt_NM ++ ++# Whether we need soft or hard links. ++LN_S=$lt_LN_S ++ ++# What is the maximum length of a command? ++max_cmd_len=$max_cmd_len ++ ++# Object file suffix (normally "o"). ++objext=$ac_objext ++ ++# Executable file suffix (normally ""). ++exeext=$exeext ++ ++# whether the shell understands "unset". ++lt_unset=$lt_unset ++ ++# turn spaces into newlines. ++SP2NL=$lt_lt_SP2NL ++ ++# turn newlines into spaces. ++NL2SP=$lt_lt_NL2SP ++ ++# How to create reloadable object files. ++reload_flag=$lt_reload_flag ++reload_cmds=$lt_reload_cmds ++ ++# Method to check whether dependent libraries are shared objects. ++deplibs_check_method=$lt_deplibs_check_method ++ ++# Command to use when deplibs_check_method == "file_magic". ++file_magic_cmd=$lt_file_magic_cmd ++ ++# The archiver. ++AR=$lt_AR ++AR_FLAGS=$lt_AR_FLAGS ++ ++# A symbol stripping program. ++STRIP=$lt_STRIP ++ ++# Commands used to install an old-style archive. ++RANLIB=$lt_RANLIB ++old_postinstall_cmds=$lt_old_postinstall_cmds ++old_postuninstall_cmds=$lt_old_postuninstall_cmds ++ ++# A C compiler. ++LTCC=$lt_CC ++ ++# LTCC compiler flags. ++LTCFLAGS=$lt_CFLAGS ++ ++# Take the output of nm and produce a listing of raw symbols and C names. ++global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe ++ ++# Transform the output of nm in a proper C declaration. ++global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl ++ ++# Transform the output of nm in a C name address pair. ++global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address ++ ++# Transform the output of nm in a C name address pair when lib prefix is needed. ++global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix ++ ++# The name of the directory that contains temporary libtool files. ++objdir=$objdir ++ ++# Used to examine libraries when file_magic_cmd begins with "file". ++MAGIC_CMD=$MAGIC_CMD ++ ++# Must we lock files when doing compilation? ++need_locks=$lt_need_locks ++ ++# Tool to manipulate archived DWARF debug symbol files on Mac OS X. ++DSYMUTIL=$lt_DSYMUTIL ++ ++# Tool to change global to local symbols on Mac OS X. ++NMEDIT=$lt_NMEDIT ++ ++# Tool to manipulate fat objects and archives on Mac OS X. ++LIPO=$lt_LIPO ++ ++# ldd/readelf like tool for Mach-O binaries on Mac OS X. ++OTOOL=$lt_OTOOL ++ ++# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. ++OTOOL64=$lt_OTOOL64 ++ ++# Old archive suffix (normally "a"). ++libext=$libext ++ ++# Shared library suffix (normally ".so"). ++shrext_cmds=$lt_shrext_cmds ++ ++# The commands to extract the exported symbol list from a shared archive. ++extract_expsyms_cmds=$lt_extract_expsyms_cmds ++ ++# Variables whose values should be saved in libtool wrapper scripts and ++# restored at link time. ++variables_saved_for_relink=$lt_variables_saved_for_relink ++ ++# Do we need the "lib" prefix for modules? ++need_lib_prefix=$need_lib_prefix ++ ++# Do we need a version for libraries? ++need_version=$need_version ++ ++# Library versioning type. ++version_type=$version_type ++ ++# Shared library runtime path variable. ++runpath_var=$runpath_var ++ ++# Shared library path variable. ++shlibpath_var=$shlibpath_var ++ ++# Is shlibpath searched before the hard-coded library search path? ++shlibpath_overrides_runpath=$shlibpath_overrides_runpath ++ ++# Format of library name prefix. ++libname_spec=$lt_libname_spec ++ ++# List of archive names. First name is the real one, the rest are links. ++# The last name is the one that the linker finds with -lNAME ++library_names_spec=$lt_library_names_spec ++ ++# The coded name of the library, if different from the real name. ++soname_spec=$lt_soname_spec ++ ++# Command to use after installation of a shared archive. ++postinstall_cmds=$lt_postinstall_cmds ++ ++# Command to use after uninstallation of a shared archive. ++postuninstall_cmds=$lt_postuninstall_cmds ++ ++# Commands used to finish a libtool library installation in a directory. ++finish_cmds=$lt_finish_cmds ++ ++# As "finish_cmds", except a single script fragment to be evaled but ++# not shown. ++finish_eval=$lt_finish_eval ++ ++# Whether we should hardcode library paths into libraries. ++hardcode_into_libs=$hardcode_into_libs ++ ++# Compile-time system search path for libraries. ++sys_lib_search_path_spec=$lt_sys_lib_search_path_spec ++ ++# Run-time system search path for libraries. ++sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec ++ ++# Whether dlopen is supported. ++dlopen_support=$enable_dlopen ++ ++# Whether dlopen of programs is supported. ++dlopen_self=$enable_dlopen_self ++ ++# Whether dlopen of statically linked programs is supported. ++dlopen_self_static=$enable_dlopen_self_static ++ ++# Commands to strip libraries. ++old_striplib=$lt_old_striplib ++striplib=$lt_striplib ++ ++ ++# The linker used to build libraries. ++LD=$lt_LD ++ ++# Commands used to build an old-style archive. ++old_archive_cmds=$lt_old_archive_cmds ++ ++# A language specific compiler. ++CC=$lt_compiler ++ ++# Is the compiler the GNU compiler? ++with_gcc=$GCC ++ ++# Compiler flag to turn off builtin functions. ++no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag ++ ++# How to pass a linker flag through the compiler. ++wl=$lt_lt_prog_compiler_wl ++ ++# Additional compiler flags for building library objects. ++pic_flag=$lt_lt_prog_compiler_pic ++ ++# Compiler flag to prevent dynamic linking. ++link_static_flag=$lt_lt_prog_compiler_static ++ ++# Does compiler simultaneously support -c and -o options? ++compiler_c_o=$lt_lt_cv_prog_compiler_c_o ++ ++# Whether or not to add -lc for building shared libraries. ++build_libtool_need_lc=$archive_cmds_need_lc ++ ++# Whether or not to disallow shared libs when runtime libs are static. ++allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes ++ ++# Compiler flag to allow reflexive dlopens. ++export_dynamic_flag_spec=$lt_export_dynamic_flag_spec ++ ++# Compiler flag to generate shared objects directly from archives. ++whole_archive_flag_spec=$lt_whole_archive_flag_spec ++ ++# Whether the compiler copes with passing no objects directly. ++compiler_needs_object=$lt_compiler_needs_object ++ ++# Create an old-style archive from a shared archive. ++old_archive_from_new_cmds=$lt_old_archive_from_new_cmds ++ ++# Create a temporary old-style archive to link instead of a shared archive. ++old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds ++ ++# Commands used to build a shared archive. ++archive_cmds=$lt_archive_cmds ++archive_expsym_cmds=$lt_archive_expsym_cmds ++ ++# Commands used to build a loadable module if different from building ++# a shared archive. ++module_cmds=$lt_module_cmds ++module_expsym_cmds=$lt_module_expsym_cmds ++ ++# Whether we are building with GNU ld or not. ++with_gnu_ld=$lt_with_gnu_ld ++ ++# Flag that allows shared libraries with undefined symbols to be built. ++allow_undefined_flag=$lt_allow_undefined_flag ++ ++# Flag that enforces no undefined symbols. ++no_undefined_flag=$lt_no_undefined_flag ++ ++# Flag to hardcode \$libdir into a binary during linking. ++# This must work even if \$libdir does not exist ++hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec ++ ++# If ld is used when linking, flag to hardcode \$libdir into a binary ++# during linking. This must work even if \$libdir does not exist. ++hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld ++ ++# Whether we need a single "-rpath" flag with a separated argument. ++hardcode_libdir_separator=$lt_hardcode_libdir_separator ++ ++# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes ++# DIR into the resulting binary. ++hardcode_direct=$hardcode_direct ++ ++# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes ++# DIR into the resulting binary and the resulting library dependency is ++# "absolute",i.e impossible to change by setting \${shlibpath_var} if the ++# library is relocated. ++hardcode_direct_absolute=$hardcode_direct_absolute ++ ++# Set to "yes" if using the -LDIR flag during linking hardcodes DIR ++# into the resulting binary. ++hardcode_minus_L=$hardcode_minus_L ++ ++# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR ++# into the resulting binary. ++hardcode_shlibpath_var=$hardcode_shlibpath_var ++ ++# Set to "yes" if building a shared library automatically hardcodes DIR ++# into the library and all subsequent libraries and executables linked ++# against it. ++hardcode_automatic=$hardcode_automatic ++ ++# Set to yes if linker adds runtime paths of dependent libraries ++# to runtime path list. ++inherit_rpath=$inherit_rpath ++ ++# Whether libtool must link a program against all its dependency libraries. ++link_all_deplibs=$link_all_deplibs ++ ++# Fix the shell variable \$srcfile for the compiler. ++fix_srcfile_path=$lt_fix_srcfile_path ++ ++# Set to "yes" if exported symbols are required. ++always_export_symbols=$always_export_symbols ++ ++# The commands to list exported symbols. ++export_symbols_cmds=$lt_export_symbols_cmds ++ ++# Symbols that should not be listed in the preloaded symbols. ++exclude_expsyms=$lt_exclude_expsyms ++ ++# Symbols that must always be exported. ++include_expsyms=$lt_include_expsyms ++ ++# Commands necessary for linking programs (against libraries) with templates. ++prelink_cmds=$lt_prelink_cmds ++ ++# Specify filename containing input files. ++file_list_spec=$lt_file_list_spec ++ ++# How to hardcode a shared library path into an executable. ++hardcode_action=$hardcode_action ++ ++# ### END LIBTOOL CONFIG ++ ++_LT_EOF ++ ++ case $host_os in ++ aix3*) ++ cat <<\_LT_EOF >> "$cfgfile" ++# AIX sometimes has problems with the GCC collect2 program. For some ++# reason, if we set the COLLECT_NAMES environment variable, the problems ++# vanish in a puff of smoke. ++if test "X${COLLECT_NAMES+set}" != Xset; then ++ COLLECT_NAMES= ++ export COLLECT_NAMES ++fi ++_LT_EOF ++ ;; ++ esac ++ ++ ++ltmain="$ac_aux_dir/ltmain.sh" ++ ++ ++ # We use sed instead of cat because bash on DJGPP gets confused if ++ # if finds mixed CR/LF and LF-only lines. Since sed operates in ++ # text mode, it properly converts lines to CR/LF. This bash problem ++ # is reportedly fixed, but why not run on old versions too? ++ sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ ++ || (rm -f "$cfgfile"; exit 1) ++ ++ case $xsi_shell in ++ yes) ++ cat << \_LT_EOF >> "$cfgfile" ++ ++# func_dirname file append nondir_replacement ++# Compute the dirname of FILE. If nonempty, add APPEND to the result, ++# otherwise set result to NONDIR_REPLACEMENT. ++func_dirname () ++{ ++ case ${1} in ++ */*) func_dirname_result="${1%/*}${2}" ;; ++ * ) func_dirname_result="${3}" ;; ++ esac ++} ++ ++# func_basename file ++func_basename () ++{ ++ func_basename_result="${1##*/}" ++} ++ ++# func_dirname_and_basename file append nondir_replacement ++# perform func_basename and func_dirname in a single function ++# call: ++# dirname: Compute the dirname of FILE. If nonempty, ++# add APPEND to the result, otherwise set result ++# to NONDIR_REPLACEMENT. ++# value returned in "$func_dirname_result" ++# basename: Compute filename of FILE. ++# value retuned in "$func_basename_result" ++# Implementation must be kept synchronized with func_dirname ++# and func_basename. For efficiency, we do not delegate to ++# those functions but instead duplicate the functionality here. ++func_dirname_and_basename () ++{ ++ case ${1} in ++ */*) func_dirname_result="${1%/*}${2}" ;; ++ * ) func_dirname_result="${3}" ;; ++ esac ++ func_basename_result="${1##*/}" ++} ++ ++# func_stripname prefix suffix name ++# strip PREFIX and SUFFIX off of NAME. ++# PREFIX and SUFFIX must not contain globbing or regex special ++# characters, hashes, percent signs, but SUFFIX may contain a leading ++# dot (in which case that matches only a dot). ++func_stripname () ++{ ++ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are ++ # positional parameters, so assign one to ordinary parameter first. ++ func_stripname_result=${3} ++ func_stripname_result=${func_stripname_result#"${1}"} ++ func_stripname_result=${func_stripname_result%"${2}"} ++} ++ ++# func_opt_split ++func_opt_split () ++{ ++ func_opt_split_opt=${1%%=*} ++ func_opt_split_arg=${1#*=} ++} ++ ++# func_lo2o object ++func_lo2o () ++{ ++ case ${1} in ++ *.lo) func_lo2o_result=${1%.lo}.${objext} ;; ++ *) func_lo2o_result=${1} ;; ++ esac ++} ++ ++# func_xform libobj-or-source ++func_xform () ++{ ++ func_xform_result=${1%.*}.lo ++} ++ ++# func_arith arithmetic-term... ++func_arith () ++{ ++ func_arith_result=$(( $* )) ++} ++ ++# func_len string ++# STRING may not start with a hyphen. ++func_len () ++{ ++ func_len_result=${#1} ++} ++ ++_LT_EOF ++ ;; ++ *) # Bourne compatible functions. ++ cat << \_LT_EOF >> "$cfgfile" ++ ++# func_dirname file append nondir_replacement ++# Compute the dirname of FILE. If nonempty, add APPEND to the result, ++# otherwise set result to NONDIR_REPLACEMENT. ++func_dirname () ++{ ++ # Extract subdirectory from the argument. ++ func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` ++ if test "X$func_dirname_result" = "X${1}"; then ++ func_dirname_result="${3}" ++ else ++ func_dirname_result="$func_dirname_result${2}" ++ fi ++} ++ ++# func_basename file ++func_basename () ++{ ++ func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` ++} ++ ++ ++# func_stripname prefix suffix name ++# strip PREFIX and SUFFIX off of NAME. ++# PREFIX and SUFFIX must not contain globbing or regex special ++# characters, hashes, percent signs, but SUFFIX may contain a leading ++# dot (in which case that matches only a dot). ++# func_strip_suffix prefix name ++func_stripname () ++{ ++ case ${2} in ++ .*) func_stripname_result=`$ECHO "X${3}" \ ++ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; ++ *) func_stripname_result=`$ECHO "X${3}" \ ++ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; ++ esac ++} ++ ++# sed scripts: ++my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q' ++my_sed_long_arg='1s/^-[^=]*=//' ++ ++# func_opt_split ++func_opt_split () ++{ ++ func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` ++ func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` ++} ++ ++# func_lo2o object ++func_lo2o () ++{ ++ func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` ++} ++ ++# func_xform libobj-or-source ++func_xform () ++{ ++ func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'` ++} ++ ++# func_arith arithmetic-term... ++func_arith () ++{ ++ func_arith_result=`expr "$@"` ++} ++ ++# func_len string ++# STRING may not start with a hyphen. ++func_len () ++{ ++ func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` ++} ++ ++_LT_EOF ++esac ++ ++case $lt_shell_append in ++ yes) ++ cat << \_LT_EOF >> "$cfgfile" ++ ++# func_append var value ++# Append VALUE to the end of shell variable VAR. ++func_append () ++{ ++ eval "$1+=\$2" ++} ++_LT_EOF ++ ;; ++ *) ++ cat << \_LT_EOF >> "$cfgfile" ++ ++# func_append var value ++# Append VALUE to the end of shell variable VAR. ++func_append () ++{ ++ eval "$1=\$$1\$2" ++} ++ ++_LT_EOF ++ ;; ++ esac ++ ++ ++ sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ ++ || (rm -f "$cfgfile"; exit 1) ++ ++ mv -f "$cfgfile" "$ofile" || ++ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") ++ chmod +x "$ofile" ++ ++ ;; ++ ++ esac ++done # for ac_tag ++ ++ ++as_fn_exit 0 ++_ACEOF ++ac_clean_files=$ac_clean_files_save ++ ++test $ac_write_fail = 0 || ++ as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5 ++ ++ ++# configure is writing to config.log, and then calls config.status. ++# config.status does its own redirection, appending to config.log. ++# Unfortunately, on DOS this fails, as config.log is still kept open ++# by configure, so config.status won't be able to write to it; its ++# output is simply discarded. So we exec the FD to /dev/null, ++# effectively closing config.log, so it can be properly (re)opened and ++# appended to by config.status. When coming back to configure, we ++# need to make the FD available again. ++if test "$no_create" != yes; then ++ ac_cs_success=: ++ ac_config_status_args= ++ test "$silent" = yes && ++ ac_config_status_args="$ac_config_status_args --quiet" ++ exec 5>/dev/null ++ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false ++ exec 5>>config.log ++ # Use ||, not &&, to avoid exiting from the if with $? = 1, which ++ # would make configure fail if this is the last instruction. ++ $ac_cs_success || as_fn_exit $? ++fi ++if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 ++$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} ++fi ++ +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/configure.in newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/configure.in +--- newlib-1.19.0/newlib/libc/sys/tsvc/configure.in 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/configure.in 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,25 @@ ++dnl This is the newlib/libc/sys/tsvc configure.in file. ++dnl Process this file with autoconf to produce a configure script. ++ ++AC_PREREQ(2.59) ++AC_INIT([newlib],[NEWLIB_VERSION]) ++AC_CONFIG_SRCDIR([dummysys.c]) ++ ++dnl Can't be done in NEWLIB_CONFIGURE because that confuses automake. ++AC_CONFIG_AUX_DIR(../../../..) ++ ++NEWLIB_CONFIGURE(../../..) ++ ++dnl We have to enable libtool after NEWLIB_CONFIGURE because if we try and ++dnl add it into NEWLIB_CONFIGURE, executable tests are made before the first ++dnl line of the macro which fail because appropriate LDFLAGS are not set. ++_LT_DECL_SED ++_LT_PROG_ECHO_BACKSLASH ++AC_PROG_AWK ++if test "${use_libtool}" = "yes"; then ++AC_LIBTOOL_WIN32_DLL ++AM_PROG_LIBTOOL ++fi ++ ++AC_CONFIG_FILES([Makefile net/Makefile gloss/Makefile]) ++AC_OUTPUT +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/dummysys.c newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/dummysys.c +--- newlib-1.19.0/newlib/libc/sys/tsvc/dummysys.c 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/dummysys.c 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1 @@ ++void not_required_by_tsvc( void ) {} +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/getuid.c newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/getuid.c +--- newlib-1.19.0/newlib/libc/sys/tsvc/getuid.c 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/getuid.c 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,12 @@ ++#include ++#include ++ ++uid_t getuid(void) ++{ ++ return 0; ++} ++ ++uid_t geteuid(void) ++{ ++ return 0; ++} +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/gloss/cbuf.c newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/gloss/cbuf.c +--- newlib-1.19.0/newlib/libc/sys/tsvc/gloss/cbuf.c 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/gloss/cbuf.c 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,70 @@ ++#include ++#include ++#include ++#include "cbuf.h" ++ ++cbuf_t* cbuf_init(void *buf, size_t sz) ++{ ++ cbuf_t *rv = (cbuf_t*)buf; ++ *rv = (cbuf_t) { ++ .sz=sz-sizeof(cbuf_t), ++ .readi=0, ++ .writei=0, ++ }; ++} ++ ++#define MAX(x, y) (((y) > (x)) ? (y) : (x)) ++ ++static size_t cbuf_read(cbuf_t *cbuf, void *dst) ++{ ++ size_t numread=0; ++ ++ if (cbuf->readi == cbuf->writei) { ++ return 0; /* empty */ ++ } else { ++ *((uint8_t*)dst) = cbuf->buf[cbuf->readi]; ++ cbuf->readi = (cbuf->readi + 1) % cbuf->sz; ++ return 1; ++ } ++} ++ ++static size_t cbuf_write(cbuf_t *cbuf, const void *src) ++{ ++ size_t numread=0; ++ ++ if ((cbuf->writei+1)%cbuf->sz == (cbuf->readi)) { ++ return 0; /* full */ ++ } else { ++ cbuf->buf[cbuf->writei] = *((const uint8_t*)src); ++ cbuf->writei = (cbuf->writei + 1) % cbuf->sz; ++ return 1; ++ } ++} ++ ++size_t cbuf_readn(cbuf_t *cbuf, void *dst, size_t n) ++{ ++ size_t numread=0; ++ ++ while(numread < n) { ++ if (0 == cbuf_read(cbuf, &((uint8_t*)dst)[numread])) { ++ return numread; ++ } else { ++ numread++; ++ } ++ } ++ return numread; ++} ++ ++size_t cbuf_writen(cbuf_t *cbuf, const void *src, size_t n) ++{ ++ size_t numwritten=0; ++ ++ while(numwritten < n) { ++ if (0 == cbuf_write(cbuf, &((const uint8_t*)src)[numwritten])) { ++ return numwritten; ++ } else { ++ numwritten++; ++ } ++ } ++ return numwritten; ++} +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/gloss/cbuf.h newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/gloss/cbuf.h +--- newlib-1.19.0/newlib/libc/sys/tsvc/gloss/cbuf.h 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/gloss/cbuf.h 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,17 @@ ++#ifndef CBUF_H ++#define CBUF_H ++ ++#include ++ ++typedef struct { ++ size_t sz; ++ size_t readi; ++ size_t writei; ++ uint8_t buf[]; ++} cbuf_t; ++ ++cbuf_t* cbuf_init(void *buf, size_t sz); ++size_t cbuf_readn(cbuf_t *cbuf, void *dst, size_t n); ++size_t cbuf_writen(cbuf_t *cbuf, const void *src, size_t n); ++ ++#endif +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/gloss/Makefile.am newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/gloss/Makefile.am +--- newlib-1.19.0/newlib/libc/sys/tsvc/gloss/Makefile.am 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/gloss/Makefile.am 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,12 @@ ++## Process this file with automake to generate Makefile.in ++ ++AUTOMAKE_OPTIONS = cygnus ++ ++INCLUDES = -I$(srcdir)/../include -I$(srcdir)/.. $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) ++ ++noinst_LIBRARIES = lib.a ++lib_a_SOURCES = cbuf.c write.c ++lib_a_CFLAGS = $(AM_CFLAGS) ++noinst_DATA = ++ ++include $(srcdir)/../../../../Makefile.shared +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/gloss/Makefile.in newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/gloss/Makefile.in +--- newlib-1.19.0/newlib/libc/sys/tsvc/gloss/Makefile.in 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/gloss/Makefile.in 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,456 @@ ++# Makefile.in generated by automake 1.11.1 from Makefile.am. ++# @configure_input@ ++ ++# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, ++# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, ++# Inc. ++# This Makefile.in is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without ++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A ++# PARTICULAR PURPOSE. ++ ++@SET_MAKE@ ++ ++ ++VPATH = @srcdir@ ++pkgdatadir = $(datadir)/@PACKAGE@ ++pkgincludedir = $(includedir)/@PACKAGE@ ++pkglibdir = $(libdir)/@PACKAGE@ ++pkglibexecdir = $(libexecdir)/@PACKAGE@ ++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd ++install_sh_DATA = $(install_sh) -c -m 644 ++install_sh_PROGRAM = $(install_sh) -c ++install_sh_SCRIPT = $(install_sh) -c ++INSTALL_HEADER = $(INSTALL_DATA) ++transform = $(program_transform_name) ++NORMAL_INSTALL = : ++PRE_INSTALL = : ++POST_INSTALL = : ++NORMAL_UNINSTALL = : ++PRE_UNINSTALL = : ++POST_UNINSTALL = : ++build_triplet = @build@ ++host_triplet = @host@ ++DIST_COMMON = $(srcdir)/../../../../Makefile.shared \ ++ $(srcdir)/Makefile.in $(srcdir)/Makefile.am ++subdir = gloss ++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ++am__aclocal_m4_deps = $(top_srcdir)/../../../../lt~obsolete.m4 \ ++ $(top_srcdir)/../../../acinclude.m4 \ ++ $(top_srcdir)/../../../libtool.m4 \ ++ $(top_srcdir)/../../../ltoptions.m4 \ ++ $(top_srcdir)/../../../ltsugar.m4 \ ++ $(top_srcdir)/../../../ltversion.m4 \ ++ $(top_srcdir)/../../../lt~obsolete.m4 \ ++ $(top_srcdir)/configure.in ++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ ++ $(ACLOCAL_M4) ++mkinstalldirs = $(SHELL) $(top_srcdir)/../../../../mkinstalldirs ++CONFIG_CLEAN_FILES = ++CONFIG_CLEAN_VPATH_FILES = ++LIBRARIES = $(noinst_LIBRARIES) ++ARFLAGS = cru ++lib_a_AR = $(AR) $(ARFLAGS) ++lib_a_LIBADD = ++am_lib_a_OBJECTS = lib_a-cbuf.$(OBJEXT) lib_a-write.$(OBJEXT) ++lib_a_OBJECTS = $(am_lib_a_OBJECTS) ++DEFAULT_INCLUDES = -I.@am__isrc@ ++depcomp = ++am__depfiles_maybe = ++COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ ++ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) ++LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ ++ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ ++ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) ++CCLD = $(CC) ++LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ ++ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ ++ $(LDFLAGS) -o $@ ++SOURCES = $(lib_a_SOURCES) ++DATA = $(noinst_DATA) ++ETAGS = etags ++CTAGS = ctags ++ACLOCAL = @ACLOCAL@ ++AMTAR = @AMTAR@ ++AR = @AR@ ++AS = @AS@ ++AUTOCONF = @AUTOCONF@ ++AUTOHEADER = @AUTOHEADER@ ++AUTOMAKE = @AUTOMAKE@ ++AWK = @AWK@ ++CC = @CC@ ++CCAS = @CCAS@ ++CCASFLAGS = @CCASFLAGS@ ++CCDEPMODE = @CCDEPMODE@ ++CFLAGS = @CFLAGS@ ++CPP = @CPP@ ++CPPFLAGS = @CPPFLAGS@ ++CYGPATH_W = @CYGPATH_W@ ++DEFS = @DEFS@ ++DEPDIR = @DEPDIR@ ++DLLTOOL = @DLLTOOL@ ++DSYMUTIL = @DSYMUTIL@ ++DUMPBIN = @DUMPBIN@ ++ECHO_C = @ECHO_C@ ++ECHO_N = @ECHO_N@ ++ECHO_T = @ECHO_T@ ++EGREP = @EGREP@ ++EXEEXT = @EXEEXT@ ++FGREP = @FGREP@ ++GREP = @GREP@ ++INSTALL = @INSTALL@ ++INSTALL_DATA = @INSTALL_DATA@ ++INSTALL_PROGRAM = @INSTALL_PROGRAM@ ++INSTALL_SCRIPT = @INSTALL_SCRIPT@ ++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ ++LD = @LD@ ++LDFLAGS = @LDFLAGS@ ++LIBOBJS = @LIBOBJS@ ++LIBS = @LIBS@ ++LIBTOOL = @LIBTOOL@ ++LIPO = @LIPO@ ++LN_S = @LN_S@ ++LTLIBOBJS = @LTLIBOBJS@ ++MAINT = @MAINT@ ++MAKEINFO = @MAKEINFO@ ++MKDIR_P = @MKDIR_P@ ++NEWLIB_CFLAGS = @NEWLIB_CFLAGS@ ++NM = @NM@ ++NMEDIT = @NMEDIT@ ++OBJDUMP = @OBJDUMP@ ++OBJEXT = @OBJEXT@ ++OTOOL = @OTOOL@ ++OTOOL64 = @OTOOL64@ ++PACKAGE = @PACKAGE@ ++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ ++PACKAGE_NAME = @PACKAGE_NAME@ ++PACKAGE_STRING = @PACKAGE_STRING@ ++PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_URL = @PACKAGE_URL@ ++PACKAGE_VERSION = @PACKAGE_VERSION@ ++PATH_SEPARATOR = @PATH_SEPARATOR@ ++RANLIB = @RANLIB@ ++READELF = @READELF@ ++SED = @SED@ ++SET_MAKE = @SET_MAKE@ ++SHELL = @SHELL@ ++STRIP = @STRIP@ ++VERSION = @VERSION@ ++abs_builddir = @abs_builddir@ ++abs_srcdir = @abs_srcdir@ ++abs_top_builddir = @abs_top_builddir@ ++abs_top_srcdir = @abs_top_srcdir@ ++ac_ct_CC = @ac_ct_CC@ ++ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ++aext = @aext@ ++am__include = @am__include@ ++am__leading_dot = @am__leading_dot@ ++am__quote = @am__quote@ ++am__tar = @am__tar@ ++am__untar = @am__untar@ ++bindir = @bindir@ ++build = @build@ ++build_alias = @build_alias@ ++build_cpu = @build_cpu@ ++build_os = @build_os@ ++build_vendor = @build_vendor@ ++builddir = @builddir@ ++datadir = @datadir@ ++datarootdir = @datarootdir@ ++docdir = @docdir@ ++dvidir = @dvidir@ ++exec_prefix = @exec_prefix@ ++host = @host@ ++host_alias = @host_alias@ ++host_cpu = @host_cpu@ ++host_os = @host_os@ ++host_vendor = @host_vendor@ ++htmldir = @htmldir@ ++includedir = @includedir@ ++infodir = @infodir@ ++install_sh = @install_sh@ ++libdir = @libdir@ ++libexecdir = @libexecdir@ ++libm_machine_dir = @libm_machine_dir@ ++localedir = @localedir@ ++localstatedir = @localstatedir@ ++lpfx = @lpfx@ ++lt_ECHO = @lt_ECHO@ ++machine_dir = @machine_dir@ ++mandir = @mandir@ ++mkdir_p = @mkdir_p@ ++newlib_basedir = @newlib_basedir@ ++oext = @oext@ ++oldincludedir = @oldincludedir@ ++pdfdir = @pdfdir@ ++prefix = @prefix@ ++program_transform_name = @program_transform_name@ ++psdir = @psdir@ ++sbindir = @sbindir@ ++sharedstatedir = @sharedstatedir@ ++srcdir = @srcdir@ ++sys_dir = @sys_dir@ ++sysconfdir = @sysconfdir@ ++target_alias = @target_alias@ ++top_build_prefix = @top_build_prefix@ ++top_builddir = @top_builddir@ ++top_srcdir = @top_srcdir@ ++AUTOMAKE_OPTIONS = cygnus ++INCLUDES = -I$(srcdir)/../include -I$(srcdir)/.. $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) ++noinst_LIBRARIES = lib.a ++lib_a_SOURCES = cbuf.c write.c ++lib_a_CFLAGS = $(AM_CFLAGS) ++noinst_DATA = ++all: all-am ++ ++.SUFFIXES: ++.SUFFIXES: .c .lo .o .obj ++$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/../../../../Makefile.shared $(am__configure_deps) ++ @for dep in $?; do \ ++ case '$(am__configure_deps)' in \ ++ *$$dep*) \ ++ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ ++ && { if test -f $@; then exit 0; else break; fi; }; \ ++ exit 1;; \ ++ esac; \ ++ done; \ ++ echo ' cd $(top_srcdir) && $(AUTOMAKE) --cygnus gloss/Makefile'; \ ++ $(am__cd) $(top_srcdir) && \ ++ $(AUTOMAKE) --cygnus gloss/Makefile ++.PRECIOUS: Makefile ++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status ++ @case '$?' in \ ++ *config.status*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ ++ *) \ ++ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ ++ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ ++ esac; ++ ++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++$(am__aclocal_m4_deps): ++ ++clean-noinstLIBRARIES: ++ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) ++lib.a: $(lib_a_OBJECTS) $(lib_a_DEPENDENCIES) ++ -rm -f lib.a ++ $(lib_a_AR) lib.a $(lib_a_OBJECTS) $(lib_a_LIBADD) ++ $(RANLIB) lib.a ++ ++mostlyclean-compile: ++ -rm -f *.$(OBJEXT) ++ ++distclean-compile: ++ -rm -f *.tab.c ++ ++.c.o: ++ $(COMPILE) -c $< ++ ++.c.obj: ++ $(COMPILE) -c `$(CYGPATH_W) '$<'` ++ ++.c.lo: ++ $(LTCOMPILE) -c -o $@ $< ++ ++lib_a-cbuf.o: cbuf.c ++ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-cbuf.o `test -f 'cbuf.c' || echo '$(srcdir)/'`cbuf.c ++ ++lib_a-cbuf.obj: cbuf.c ++ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-cbuf.obj `if test -f 'cbuf.c'; then $(CYGPATH_W) 'cbuf.c'; else $(CYGPATH_W) '$(srcdir)/cbuf.c'; fi` ++ ++lib_a-write.o: write.c ++ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-write.o `test -f 'write.c' || echo '$(srcdir)/'`write.c ++ ++lib_a-write.obj: write.c ++ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-write.obj `if test -f 'write.c'; then $(CYGPATH_W) 'write.c'; else $(CYGPATH_W) '$(srcdir)/write.c'; fi` ++ ++mostlyclean-libtool: ++ -rm -f *.lo ++ ++clean-libtool: ++ -rm -rf .libs _libs ++ ++ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ ++ END { if (nonempty) { for (i in files) print i; }; }'`; \ ++ mkid -fID $$unique ++tags: TAGS ++ ++TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ set x; \ ++ here=`pwd`; \ ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ ++ END { if (nonempty) { for (i in files) print i; }; }'`; \ ++ shift; \ ++ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ ++ test -n "$$unique" || unique=$$empty_fix; \ ++ if test $$# -gt 0; then \ ++ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ ++ "$$@" $$unique; \ ++ else \ ++ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ ++ $$unique; \ ++ fi; \ ++ fi ++ctags: CTAGS ++CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ ++ END { if (nonempty) { for (i in files) print i; }; }'`; \ ++ test -z "$(CTAGS_ARGS)$$unique" \ ++ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ ++ $$unique ++ ++GTAGS: ++ here=`$(am__cd) $(top_builddir) && pwd` \ ++ && $(am__cd) $(top_srcdir) \ ++ && gtags -i $(GTAGS_ARGS) "$$here" ++ ++distclean-tags: ++ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags ++check-am: ++check: check-am ++all-am: Makefile $(LIBRARIES) $(DATA) ++installdirs: ++install: install-am ++install-exec: install-exec-am ++install-data: install-data-am ++uninstall: uninstall-am ++ ++install-am: all-am ++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am ++ ++installcheck: installcheck-am ++install-strip: ++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ ++ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ ++ `test -z '$(STRIP)' || \ ++ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install ++mostlyclean-generic: ++ ++clean-generic: ++ ++distclean-generic: ++ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) ++ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) ++ ++maintainer-clean-generic: ++ @echo "This command is intended for maintainers to use" ++ @echo "it deletes files that may require special tools to rebuild." ++clean: clean-am ++ ++clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ ++ mostlyclean-am ++ ++distclean: distclean-am ++ -rm -f Makefile ++distclean-am: clean-am distclean-compile distclean-generic \ ++ distclean-tags ++ ++dvi: dvi-am ++ ++dvi-am: ++ ++html: html-am ++ ++html-am: ++ ++info: info-am ++ ++info-am: ++ ++install-data-am: ++ ++install-dvi: install-dvi-am ++ ++install-dvi-am: ++ ++install-exec-am: ++ ++install-html: install-html-am ++ ++install-html-am: ++ ++install-info: install-info-am ++ ++install-info-am: ++ ++install-man: ++ ++install-pdf: install-pdf-am ++ ++install-pdf-am: ++ ++install-ps: install-ps-am ++ ++install-ps-am: ++ ++installcheck-am: ++ ++maintainer-clean: maintainer-clean-am ++ -rm -f Makefile ++maintainer-clean-am: distclean-am maintainer-clean-generic ++ ++mostlyclean: mostlyclean-am ++ ++mostlyclean-am: mostlyclean-compile mostlyclean-generic \ ++ mostlyclean-libtool ++ ++pdf: pdf-am ++ ++pdf-am: ++ ++ps: ps-am ++ ++ps-am: ++ ++uninstall-am: ++ ++.MAKE: install-am install-strip ++ ++.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ ++ clean-libtool clean-noinstLIBRARIES ctags distclean \ ++ distclean-compile distclean-generic distclean-libtool \ ++ distclean-tags dvi dvi-am html html-am info info-am install \ ++ install-am install-data install-data-am install-dvi \ ++ install-dvi-am install-exec install-exec-am install-html \ ++ install-html-am install-info install-info-am install-man \ ++ install-pdf install-pdf-am install-ps install-ps-am \ ++ install-strip installcheck installcheck-am installdirs \ ++ maintainer-clean maintainer-clean-generic mostlyclean \ ++ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ ++ pdf pdf-am ps ps-am tags uninstall uninstall-am ++ ++objectlist.awk.in: $(noinst_LTLIBRARIES) ++ -rm -f objectlist.awk.in ++ for i in `ls *.lo` ; \ ++ do \ ++ echo $$i `pwd`/$$i >> objectlist.awk.in ; \ ++ done ++ ++# Tell versions [3.59,3.63) of GNU make to not export all variables. ++# Otherwise a system limit (for SysV at least) may be exceeded. ++.NOEXPORT: +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/gloss/write.c newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/gloss/write.c +--- newlib-1.19.0/newlib/libc/sys/tsvc/gloss/write.c 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/gloss/write.c 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,29 @@ ++#include ++#include ++#include ++#include ++#include "cbuf.h" ++ ++static uint8_t stderr_buf[4096]; ++static cbuf_t *stderr_cbuf = ((cbuf_t*)stderr_buf); ++ ++ssize_t write(int fd, const void *buf, size_t count) ++{ ++ static bool initd_stderr; ++ if (!initd_stderr) { ++ cbuf_init(stderr_buf, 4096); ++ initd_stderr=true; ++ } ++ ++ if (fd == STDERR_FILENO) { ++ return cbuf_writen(stderr_cbuf, buf, count); ++ } else { ++ errno=EBADF; ++ return -1; ++ } ++} ++ ++size_t tsvc_read_stderr(void *buf, size_t count) ++{ ++ return cbuf_readn(stderr_cbuf, buf, count); ++} +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/include/arpa/inet.h newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/include/arpa/inet.h +--- newlib-1.19.0/newlib/libc/sys/tsvc/include/arpa/inet.h 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/include/arpa/inet.h 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,40 @@ ++/* minimal compliance with IEEE Std 1003.1 ++ http://pubs.opengroup.org/onlinepubs/009695399/basedefs/arpa/inet.h.html#tag_13_03 ++*/ ++ ++#ifndef _ARPA_INET_H ++#define _ARPA_INET_H ++ ++/* The uint32_t and uint16_t types shall be defined as described in ++ . */ ++#include ++ ++/* The in_port_t and in_addr_t types shall be defined as described in ++ . */ ++/* The in_addr structure shall be defined as described in ++ . */ ++/* The INET_ADDRSTRLEN [IP6] and INET6_ADDRSTRLEN macros shall be ++ defined as described in . */ ++#include ++ ++/* The following shall either be declared as functions, defined as ++ macros, or both. If functions are declared, function prototypes ++ shall be provided. */ ++ ++uint32_t htonl(uint32_t); ++uint16_t htons(uint16_t); ++uint32_t ntohl(uint32_t); ++uint16_t ntohs(uint16_t); ++ ++/* The following shall be declared as functions and may also be ++ defined as macros. Function prototypes shall be provided. */ ++in_addr_t inet_addr(const char *); ++char *inet_ntoa(struct in_addr); ++const char *inet_ntop(int, const void *, char *, ++ socklen_t); ++int inet_pton(int, const char *, void *); ++ ++/* Inclusion of the header may also make visible all ++ symbols from and . */ ++ ++#endif +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/include/dlfcn.h newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/include/dlfcn.h +--- newlib-1.19.0/newlib/libc/sys/tsvc/include/dlfcn.h 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/include/dlfcn.h 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,41 @@ ++#ifndef _DLFCN_H ++#define _DLFCN_H ++ ++#define RTLD_LAZY 0 ++#define RTLD_NOW 1 ++#define RTLD_GLOBAL 2 ++#define RTLD_LOCAL 3 ++#define RTLD_NODELETE 4 ++#define RTLD_NOLOAD 5 ++#define RTLD_DEEPBIND 6 ++ ++void *dlopen(const char* filename, int flag); ++ ++char *dlerror(void); ++ ++void *dlsym(void *handle, const char *symbol); ++ ++int dlclose(void *handle); ++ ++ ++#ifdef _GNU_SOURCE ++#define RTLD_DEFAULT NULL ++#define RTLD_NEXT NULL ++ ++typedef struct { ++ const char *dli_fname; /* Pathname of shared object that ++ contains address */ ++ void *dli_fbase; /* Address at which shared object ++ is loaded */ ++ const char *dli_sname; /* Name of nearest symbol with address ++ lower than addr */ ++ void *dli_saddr; /* Exact address of symbol named ++ in dli_sname */ ++} Dl_info; ++ ++int dladdr(void *addr, Dl_info *info); ++void *dlvsym(void *handle, char *symbol, char *version); ++#endif ++ ++ ++#endif +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/include/netdb.h newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/include/netdb.h +--- newlib-1.19.0/newlib/libc/sys/tsvc/include/netdb.h 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/include/netdb.h 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,175 @@ ++/* adapted from IEEE Std 1003.1 ++ http://pubs.opengroup.org/onlinepubs/009695399/basedefs/netdb.h.html ++ */ ++ ++#ifndef _NETDB_H ++#define _NETDB_H ++ ++#include ++#include ++ ++/* The header may make available the type in_port_t and the ++ type in_addr_t as defined in the description of . */ ++ ++/* The header defines the hostent structure that includes at ++ least the following members: */ ++struct hostent { ++ char *h_name; /* Official name of the host. */ ++ char **h_aliases; /* A pointer to an array of pointers to ++ alternative host names, terminated by a null ++ pointer. */ ++ int h_addrtype; /* Address type. */ ++ int h_length; /* The length, in bytes, of the address. */ ++ char **h_addr_list; /* A pointer to an array of pointers to network ++ addresses (in network byte order) for the ++ host, terminated by a null pointer. */ ++}; ++ ++/* The header defines the netent structure that includes at ++ least the following members: */ ++ ++struct netent { ++ char *n_name; /* Official, fully-qualified (including the domain) name of the host. */ ++ char **n_aliases; /* A pointer to an array of pointers to ++ alternative network names, terminated by a ++ null pointer. */ ++ int n_addrtype; /* The address type of the network. */ ++ uint32_t n_net; /* The network number, in host byte order. */ ++}; ++/* The uint_32_t type is made available by inclusion of (see referenced document XSH). */ ++ ++/* The header defines the protoent structure that includes ++ at least the following members: */ ++struct protoent { ++ char *p_name; /* Official name of the protocol. */ ++ char **p_aliases; /* A pointer to an array of pointers to ++ alternative protocol names, terminated by a ++ null pointer. */ ++ int p_proto; /* The protocol number. */ ++}; ++ ++/* The header defines the servent structure that includes at ++ least the following members: */ ++struct servent { ++ char *s_name; /* Official name of the service. */ ++ char **s_aliases; /* A pointer to an array of pointers to ++ alternative service names, terminated by a ++ null pointer. */ ++ int s_port; /* The port number at which the service resides, ++ in network byte order. */ ++ char *s_proto; /* The name of the protocol to use when ++ contacting the service. */ ++}; ++ ++/* The header defines the macro IPPORT_RESERVED with the ++ value of the highest reserved Internet port number. */ ++#define IPPORT_RESERVED 1024 ++ ++/* The header provides a declaration of h_errno as a ++ modifiable l-value of type int. For example: */ ++extern int h_errno; ++ ++/* The header defines the following macros for use as error ++ values for gethostbyaddr() and gethostbyname(): */ ++#define HOST_NOT_FOUND 0 ++#define NO_DATA 1 ++#define NO_RECOVERY 2 ++#define TRY_AGAIN 3 ++ ++/* The header shall define the addrinfo structure that ++ includes at least the following members: */ ++struct addrinfo { ++ int ai_flags; /* Input flags. */ ++ int ai_family; /* Address family of socket. */ ++ int ai_socktype; /* Socket type. */ ++ int ai_protocol; /* Protocol of socket. */ ++ socklen_t ai_addrlen; /* Length of socket address. */ ++ struct sockaddr *ai_addr; /* Socket address of socket. */ ++ char *ai_canonname; /* Canonical name of service location. */ ++ struct addrinfo *ai_next; /* Pointer to next in list. */ ++}; ++ ++/* The header shall define the following macros that ++ evaluate to bitwise-distinct integer constants for use in the flags ++ field of the addrinfo structure: */ ++#define AI_PASSIVE (1<<0) /* Socket address is intended for bind(). */ ++#define AI_CANONNAME (1<<1) /* Request for canonical name. */ ++#define AI_NUMERICHOST (1<<2) /* Return numeric host address as ++ name. */ ++#define AI_NUMERICSERV (1<<3) /* Inhibit service name resolution. */ ++#define AI_V4MAPPED (1<<4) /* If no IPv6 addresses are found, query ++ for IPv4 addresses and return them to ++ the caller as IPv4-mapped IPv6 ++ addresses. */ ++#define AI_ALL (1<<5) /* Query for both IPv4 and IPv6 addresses. */ ++#define AI_ADDRCONFIG (1<<6) /* Query for IPv4 addresses only when an ++ IPv4 address is configured; query for ++ IPv6 addresses only when an IPv6 ++ address is configured. */ ++ ++/* The header shall define the following macros that ++ evaluate to bitwise-distinct integer constants for use in the flags ++ argument to getnameinfo(): */ ++#define NI_NOFQDN (1<<0) /* Only the nodename portion of the FQDN is returned for local hosts. */ ++#define NI_NUMERICHOST (1<<1) /* The numeric form of the node's address is returned instead of its name. */ ++#define NI_NAMEREQD (1<<2) /* Return an error if the node's name cannot be located in the database. */ ++#define NI_NUMERICSERV (1<<3) /* The numeric form of the service address is returned instead of its name. */ ++#define NI_NUMERICSCOPE (1<<4) /* For IPv6 addresses, the numeric form of the scope identifier is returned instead of its name. */ ++#define NI_DGRAM (1<<5) /* Indicates that the service is a datagram service (SOCK_DGRAM). */ ++ ++/* The header shall define the following macros for use as ++ error values for getaddrinfo() and getnameinfo(): */ ++ ++#define EAI_AGAIN 1 /* The name could not be resolved at this ++ time. Future attempts may succeed. */ ++#define EAI_BADFLAGS 2 /* The flags had an invalid value. */ ++#define EAI_FAIL 3 /* A non-recoverable error occurred. */ ++#define EAI_FAMILY 4 /* The address family was not recognized or the ++ address length was invalid for the specified ++ family. */ ++#define EAI_MEMORY 5 /* There was a memory allocation failure. */ ++#define EAI_NONAME 6 /* The name does not resolve for the supplied ++ parameters. */ ++#define EAI_SERVICE 7 /* The service passed was not recognized for the ++ specified socket type. */ ++#define EAI_SOCKTYPE 8 /* The intended socket type was not ++ recognized. */ ++#define EAI_SYSTEM 9 /* A system error occurred. The error code can ++ be found in errno. */ ++#define EAI_OVERFLOW 10 /* An argument buffer overflowed. */ ++ ++/* The following are declared as functions, and may also be defined as ++ macros: */ ++void endhostent(void); ++void endnetent(void); ++void endprotoent(void); ++void endservent(void); ++struct hostent *gethostbyaddr(const void *addr, size_t len, int type); ++struct hostent *gethostbyname(const char *name); ++struct hostent *gethostent(void); ++struct netent *getnetbyaddr(uint32_t net, int type); ++struct netent *getnetbyname(const char *name); ++struct netent *getnetent(void); ++struct protoent *getprotobyname(const char *name); ++struct protoent *getprotobynumber(int proto); ++struct protoent *getprotoent(void); ++struct servent *getservbyname(const char *name, const char *proto); ++struct servent *getservbyport(int port, const char *proto); ++struct servent *getservent(void); ++void sethostent(int stayopen); ++void setnetent(int stayopen); ++void setprotoent(int stayopen); ++void setservent(int stayopen); ++ ++/* Inclusion of the header may also make visible all symbols from and . */ ++ ++/**** Not part of IEEE Std 1003.1 standard, but present in bsd ++ implementation and depended upon by some clients ****/ ++ ++/* ++ * Constants for getnameinfo() ++ */ ++#define NI_MAXHOST 1025 ++#define NI_MAXSERV 32 ++ ++#endif +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/include/netinet/in.h newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/include/netinet/in.h +--- newlib-1.19.0/newlib/libc/sys/tsvc/include/netinet/in.h 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/include/netinet/in.h 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,162 @@ ++/* adapted from IEEE Std 1003.1 spec ++ http://pubs.opengroup.org/onlinepubs/009695399/basedefs/netinet/in.h.html ++ */ ++ ++#ifndef _NETINET_IN_H ++#define _NETINET_IN_H ++ ++#include ++#include ++ ++/* The header shall define the following types: */ ++ ++typedef uint16_t in_port_t; /* Equivalent to the type uint16_t as ++ defined in . */ ++typedef uint32_t in_addr_t; /* Equivalent to the type uint32_t as ++ defined in . */ ++ ++/* The sa_family_t type shall be defined as described in ++ . */ ++ ++/* The uint8_t and uint32_t type shall be defined as described in ++ . Inclusion of the header may also make ++ visible all symbols from and . */ ++ ++/* The header shall define the in_addr structure that ++ includes at least the following member: */ ++struct in_addr { ++ in_addr_t s_addr; ++}; ++ ++/* The header shall define the sockaddr_in structure ++ that includes at least the following members: */ ++struct sockaddr_in { ++ sa_family_t sin_family; /* AF_INET. */ ++ in_port_t sin_port; /* Port number. */ ++ struct in_addr sin_addr; /* IP address. */ ++}; ++ ++/* The sin_port and sin_addr members shall be in network byte ++ order. */ ++ ++/* The sockaddr_in structure is used to store addresses for the ++ Internet address family. Values of this type shall be cast by ++ applications to struct sockaddr for use with socket functions. */ ++ ++/* [IP6] The header shall define the in6_addr structure ++ that contains at least the following member: */ ++struct in6_addr { ++ uint8_t s6_addr[16]; ++}; ++/* This array is used to contain a 128-bit IPv6 address, stored in ++ network byte order. */ ++ ++/* The header shall define the sockaddr_in6 structure ++ that includes at least the following members: */ ++struct sockaddr_in6 { ++ sa_family_t sin6_family; /* AF_INET6. */ ++ in_port_t sin6_port; /* Port number. */ ++ uint32_t sin6_flowinfo; /* IPv6 traffic class and flow information. */ ++ struct in6_addr sin6_addr; /* IPv6 address. */ ++ uint32_t sin6_scope_id; /* Set of interfaces for a scope. */ ++}; ++/* The sin6_port and sin6_addr members shall be in network byte order. */ ++ ++ /* The sockaddr_in6 structure shall be set to zero by an application ++ prior to using it, since implementations are free to have ++ additional, implementation-defined fields in sockaddr_in6. */ ++ ++ /* The sin6_scope_id field is a 32-bit integer that identifies a set ++ of interfaces as appropriate for the scope of the address carried ++ in the sin6_addr field. For a link scope sin6_addr, the ++ application shall ensure that sin6_scope_id is a link index. For ++ a site scope sin6_addr, the application shall ensure that ++ sin6_scope_id is a site index. The mapping of sin6_scope_id to an ++ interface or set of interfaces is implementation-defined. */ ++ ++/* The header shall declare the following external ++ variable: */ ++const struct in6_addr in6addr_any; ++/* This variable is initialized by the system to contain the wildcard ++ IPv6 address. The header also defines the ++ IN6ADDR_ANY_INIT macro. This macro must be constant at compile time ++ and can be used to initialize a variable of type struct in6_addr to ++ the IPv6 wildcard address. */ ++ ++/* The header shall declare the following external ++ variable: */ ++const struct in6_addr in6addr_loopback; ++/* This variable is initialized by the system to contain the loopback ++ IPv6 address. The header also defines the ++ IN6ADDR_LOOPBACK_INIT macro. This macro must be constant at compile ++ time and can be used to initialize a variable of type struct ++ in6_addr to the IPv6 loopback address. */ ++ ++/* The header shall define the ipv6_mreq structure that ++ includes at least the following members: */ ++struct ipv6_mreq { ++ struct in6_addr ipv6mr_multiaddr; /* IPv6 multicast address. */ ++ unsigned ipv6mr_interface; /* Interface index. */ ++}; ++ ++/* The header shall define the following macros for use ++ as values of the level argument of getsockopt() and ++ setsockopt(): */ ++ ++#define IPPROTO_IP 1 /* Internet protocol. */ ++#define IPPROTO_IPV6 2 /* [IP6] Internet Protocol Version 6. */ ++#define IPPROTO_ICMP 3 /* Control message protocol. */ ++#define IPPROTO_RAW 4 /* [RS] Raw IP Packets Protocol. */ ++#define IPPROTO_TCP 5 /* Transmission control protocol. */ ++#define IPPROTO_UDP 6 /* User datagram protocol. */ ++ ++/* The header shall define the following macros for use ++ as destination addresses for connect(), sendmsg(), and sendto(): */ ++#define INADDR_ANY 1 /* IPv4 local host address. */ ++#define INADDR_BROADCAST 2 /* IPv4 broadcast address. */ ++ ++/* The header shall define the following macro to help ++ applications declare buffers of the proper size to store IPv4 ++ addresses in string form: */ ++#define INET_ADDRSTRLEN 16 /* Length of the string form for IP. */ ++ ++/* The htonl(), htons(), ntohl(), and ntohs() functions shall be ++ available as defined in . Inclusion of the ++ header may also make visible all symbols from ++ . */ ++#include ++ ++/* IP6] The header shall define the following macro to ++ help applications declare buffers of the proper size to store IPv6 ++ addresses in string form: */ ++#define INET6_ADDRSTRLEN 46 /* Length of the string form for IPv6. */ ++ ++/* The header shall define the following macros, with ++ distinct integer values, for use in the option_name argument in the ++ getsockopt() or setsockopt() functions at protocol level ++ IPPROTO_IPV6: */ ++#define IPV6_JOIN_GROUP 1 /* Join a multicast group. */ ++#define IPV6_LEAVE_GROUP 2 /* Quit a multicast group. */ ++#define IPV6_MULTICAST_HOPS 3 /* Multicast hop limit. */ ++#define IPV6_MULTICAST_IF 4 /* Interface to use for outgoing multicast packets. */ ++#define IPV6_MULTICAST_LOOP 5 /* Multicast packets are delivered back to the local application. */ ++#define IPV6_UNICAST_HOPS 6 /* Unicast hop limit. */ ++#define IPV6_V6ONLY 7 /* Restrict AF_INET6 socket to IPv6 communications only. */ ++ ++/* The header shall define the following macros that ++ test for special IPv6 addresses. Each macro is of type int and ++ takes a single argument of type const struct in6_addr *: */ ++#define IN6_IS_ADDR_UNSPECIFIED(x) 0 /* Unspecified address. */ ++#define IN6_IS_ADDR_LOOPBACK(x) 0 /* Loopback address. */ ++#define IN6_IS_ADDR_MULTICAST(x) 0 /* Multicast address. */ ++#define IN6_IS_ADDR_LINKLOCAL(x) 0 /* Unicast link-local address. */ ++#define IN6_IS_ADDR_SITELOCAL(x) 0 /* Unicast site-local address. */ ++#define IN6_IS_ADDR_V4MAPPED(x) 0 /* IPv4 mapped address. */ ++#define IN6_IS_ADDR_V4COMPAT(x) 0/* IPv4-compatible address. */ ++#define IN6_IS_ADDR_MC_NODELOCAL(x) 0 /* Multicast node-local address. */ ++#define IN6_IS_ADDR_MC_LINKLOCAL(x) 0 /* Multicast link-local address. */ ++#define IN6_IS_ADDR_MC_SITELOCAL(x) 0 /* Multicast site-local address. */ ++#define IN6_IS_ADDR_MC_ORGLOCAL(x) 0 /* Multicast organization-local address. */ ++#define IN6_IS_ADDR_MC_GLOBAL(x) 0 /* Multicast global address. */ ++ ++#endif +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/include/poll.h newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/include/poll.h +--- newlib-1.19.0/newlib/libc/sys/tsvc/include/poll.h 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/include/poll.h 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,45 @@ ++/* based on IEEE Std 1003.1-2008 ++ * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/poll.h.html ++ */ ++#ifndef _POLL_H ++#define _POLL_H ++ ++/* The header shall define the pollfd structure, which shall ++ include at least the following members: */ ++struct pollfd { ++ int fd; /* The following descriptor being polled. */ ++ short events; /* The input event flags (see below). */ ++ short revents; /* The output event flags (see below). */ ++}; ++ ++/* The header shall define the following type through ++ typedef: */ ++ ++typedef unsigned int nfds_t; ++/* An unsigned integer type used for the number of file descriptors. */ ++/* The implementation shall support one or more programming ++ environments in which the width of nfds_t is no greater than the ++ width of type long. The names of these programming environments can ++ be obtained using the confstr() function or the getconf utility. */ ++ ++/* The header shall define the following symbolic constants, ++ zero or more of which may be OR'ed together to form the events or ++ revents members in the pollfd structure: */ ++#define POLLIN (1<<0) /* Data other than high-priority data may be read without blocking. */ ++#define POLLRDNORM (1<<1)/* Normal data may be read without blocking. */ ++#define POLLRDBAND (1<<2)/* Priority data may be read without blocking. */ ++#define POLLPRI (1<<3)/* High priority data may be read without blocking. */ ++#define POLLOUT (1<<4)/* Normal data may be written without blocking. */ ++#define POLLWRNORM (1<<5)/* Equivalent to POLLOUT. */ ++#define POLLWRBAND (1<<6)/* Priority data may be written. */ ++#define POLLERR (1<<7)/* An error has occurred ( revents only). */ ++#define POLLHUP (1<<8)/* Device has been disconnected ( revents only). */ ++#define POLLNVAL (1<<9)/* Invalid fd member ( revents only). */ ++ ++/* The significance and semantics of normal, priority, and high-priority data are file and device-specific. */ ++/* The following shall be declared as a function and may also be ++ defined as a macro. A function prototype shall be provided. */ ++ ++int poll(struct pollfd [], nfds_t, int); ++ ++#endif +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/include/syslog.h newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/include/syslog.h +--- newlib-1.19.0/newlib/libc/sys/tsvc/include/syslog.h 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/include/syslog.h 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,63 @@ ++/* Based on IEEE Std 1003.1-2008 ++ http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/syslog.h.html ++*/ ++ ++#ifndef _SYSLOG_H ++#define _SYSLOG_H ++ ++/* The header shall define the following symbolic ++ constants, zero or more of which may be OR'ed together to form the ++ logopt option of openlog(): */ ++#define LOG_PID (1<<0) /* Log the process ID with each message. */ ++#define LOG_CONS (1<<1) /* Log to the system console on error. */ ++#define LOG_NDELAY (1<<2) /* Connect to syslog daemon immediately. */ ++#define LOG_ODELAY (1<<3) /* Delay open until syslog() is called. */ ++#define LOG_NOWAIT (1<<4) /* Do not wait for child processes. */ ++ ++/* The header shall define the following symbolic constants ++ for use as the facility argument to openlog(): */ ++#define LOG_KERN 1 /* Reserved for message generated by the system. */ ++#define LOG_USER 2 /* Message generated by a process. */ ++#define LOG_MAIL 3 /* Reserved for message generated by mail system. */ ++#define LOG_NEWS 4 /* Reserved for message generated by news system. */ ++#define LOG_UUCP 5 /* Reserved for message generated by UUCP system. */ ++#define LOG_DAEMON 6 /* Reserved for message generated by system daemon. */ ++#define LOG_AUTH 7 /* Reserved for message generated by authorization daemon. */ ++#define LOG_CRON 8 /* Reserved for message generated by clock daemon. */ ++#define LOG_LPR 9 /* Reserved for message generated by printer system. */ ++#define LOG_LOCAL0 10 /* Reserved for local use. */ ++#define LOG_LOCAL1 11 /* Reserved for local use. */ ++#define LOG_LOCAL2 12 /* Reserved for local use. */ ++#define LOG_LOCAL3 13 /* Reserved for local use. */ ++#define LOG_LOCAL4 14 /* Reserved for local use. */ ++#define LOG_LOCAL5 15 /* Reserved for local use. */ ++#define LOG_LOCAL6 16 /* Reserved for local use. */ ++#define LOG_LOCAL7 17 /* Reserved for local use. */ ++ ++/* The header shall define the following macros for ++ constructing the maskpri argument to setlogmask(). The following ++ macros expand to an expression of type int when the argument pri is ++ an expression of type int: */ ++#define LOG_MASK(pri) 0 ++/* A mask for priority pri. */ ++ ++/* The header shall define the following symbolic constants ++ for use as the priority argument of syslog(): */ ++#define LOG_EMERG 1/* A panic condition was reported to all processes. */ ++#define LOG_ALERT 2/* A condition that should be corrected immediately. */ ++#define LOG_CRIT 3/* A critical condition. */ ++#define LOG_ERR 4/* An error message. */ ++#define LOG_WARNING 5/* A warning message. */ ++#define LOG_NOTICE 6/* A condition requiring special handling. */ ++#define LOG_INFO 7/* A general information message. */ ++#define LOG_DEBUG 8/* A message useful for debugging programs. */ ++ ++/* The following shall be declared as functions and may also be ++ defined as macros. Function prototypes shall be provided. */ ++ ++void closelog(void); ++void openlog(const char *, int, int); ++int setlogmask(int); ++void syslog(int, const char *, ...); ++ ++#endif +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/include/termio.h newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/include/termio.h +--- newlib-1.19.0/newlib/libc/sys/tsvc/include/termio.h 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/include/termio.h 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,7 @@ ++#ifndef _SYS_TERMIO_H ++# define _SYS_TERMIO_H ++ ++#include ++ ++#endif /* _SYS_TERMIO_H */ ++ +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/include/tsvc.h newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/include/tsvc.h +--- newlib-1.19.0/newlib/libc/sys/tsvc/include/tsvc.h 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/include/tsvc.h 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,8 @@ ++#ifndef TSVC_H ++#define TSVC_H ++ ++#include ++ ++size_t tsvc_read_stderr(void *buf, size_t count); ++ ++#endif +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/Makefile.am newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/Makefile.am +--- newlib-1.19.0/newlib/libc/sys/tsvc/Makefile.am 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/Makefile.am 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,34 @@ ++## Process this file with automake to generate Makefile.in ++ ++AUTOMAKE_OPTIONS = cygnus ++ ++INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) ++ ++SUBDIRS = net gloss ++ ++AM_CCASFLAGS = $(INCLUDES) ++ ++noinst_LIBRARIES = lib.a ++ ++lib_a_SOURCES = dummysys.c getuid.c poll.c termios.c ++lib_a_CCASFLAGS = $(AM_CCASFLAGS) ++lib_a_CFLAGS = $(AM_CFLAGS) ++ ++SUBLIBS = net/lib.a gloss/lib.a ++ ++lib.a: $(lib_a_OBJECTS) ++ rm -f $@ ++ rm -rf tmp ++ mkdir tmp ++ cd tmp; \ ++ for i in $(SUBLIBS); do \ ++ $(AR) x ../$$i; \ ++ done; ++ $(AR) $(AR_FLAGS) $@ tmp/*.o $(lib_a_OBJECTS) ++ $(RANLIB) $@ ++ rm -rf tmp ++ ++all-local: ++ ++ACLOCAL_AMFLAGS = -I ../../.. -I ../../../.. ++CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/Makefile.in newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/Makefile.in +--- newlib-1.19.0/newlib/libc/sys/tsvc/Makefile.in 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/Makefile.in 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,588 @@ ++# Makefile.in generated by automake 1.11.1 from Makefile.am. ++# @configure_input@ ++ ++# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, ++# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, ++# Inc. ++# This Makefile.in is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without ++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A ++# PARTICULAR PURPOSE. ++ ++@SET_MAKE@ ++ ++VPATH = @srcdir@ ++pkgdatadir = $(datadir)/@PACKAGE@ ++pkgincludedir = $(includedir)/@PACKAGE@ ++pkglibdir = $(libdir)/@PACKAGE@ ++pkglibexecdir = $(libexecdir)/@PACKAGE@ ++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd ++install_sh_DATA = $(install_sh) -c -m 644 ++install_sh_PROGRAM = $(install_sh) -c ++install_sh_SCRIPT = $(install_sh) -c ++INSTALL_HEADER = $(INSTALL_DATA) ++transform = $(program_transform_name) ++NORMAL_INSTALL = : ++PRE_INSTALL = : ++POST_INSTALL = : ++NORMAL_UNINSTALL = : ++PRE_UNINSTALL = : ++POST_UNINSTALL = : ++build_triplet = @build@ ++host_triplet = @host@ ++subdir = . ++DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ ++ $(top_srcdir)/configure $(am__configure_deps) \ ++ $(srcdir)/../../../../mkinstalldirs ++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ++am__aclocal_m4_deps = $(top_srcdir)/../../../../lt~obsolete.m4 \ ++ $(top_srcdir)/../../../acinclude.m4 \ ++ $(top_srcdir)/../../../libtool.m4 \ ++ $(top_srcdir)/../../../ltoptions.m4 \ ++ $(top_srcdir)/../../../ltsugar.m4 \ ++ $(top_srcdir)/../../../ltversion.m4 \ ++ $(top_srcdir)/../../../lt~obsolete.m4 \ ++ $(top_srcdir)/configure.in ++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ ++ $(ACLOCAL_M4) ++am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ ++ configure.lineno config.status.lineno ++mkinstalldirs = $(SHELL) $(top_srcdir)/../../../../mkinstalldirs ++CONFIG_CLEAN_FILES = ++CONFIG_CLEAN_VPATH_FILES = ++LIBRARIES = $(noinst_LIBRARIES) ++ARFLAGS = cru ++lib_a_AR = $(AR) $(ARFLAGS) ++lib_a_LIBADD = ++am_lib_a_OBJECTS = lib_a-dummysys.$(OBJEXT) lib_a-getuid.$(OBJEXT) \ ++ lib_a-poll.$(OBJEXT) lib_a-termios.$(OBJEXT) ++lib_a_OBJECTS = $(am_lib_a_OBJECTS) ++DEFAULT_INCLUDES = -I.@am__isrc@ ++depcomp = ++am__depfiles_maybe = ++COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ ++ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) ++LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ ++ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ ++ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) ++CCLD = $(CC) ++LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ ++ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ ++ $(LDFLAGS) -o $@ ++SOURCES = $(lib_a_SOURCES) ++RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ ++ html-recursive info-recursive install-data-recursive \ ++ install-dvi-recursive install-exec-recursive \ ++ install-html-recursive install-info-recursive \ ++ install-pdf-recursive install-ps-recursive install-recursive \ ++ installcheck-recursive installdirs-recursive pdf-recursive \ ++ ps-recursive uninstall-recursive ++RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ ++ distclean-recursive maintainer-clean-recursive ++AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ ++ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS ++ETAGS = etags ++CTAGS = ctags ++DIST_SUBDIRS = $(SUBDIRS) ++ACLOCAL = @ACLOCAL@ ++AMTAR = @AMTAR@ ++AR = @AR@ ++AS = @AS@ ++AUTOCONF = @AUTOCONF@ ++AUTOHEADER = @AUTOHEADER@ ++AUTOMAKE = @AUTOMAKE@ ++AWK = @AWK@ ++CC = @CC@ ++CCAS = @CCAS@ ++CCASFLAGS = @CCASFLAGS@ ++CCDEPMODE = @CCDEPMODE@ ++CFLAGS = @CFLAGS@ ++CPP = @CPP@ ++CPPFLAGS = @CPPFLAGS@ ++CYGPATH_W = @CYGPATH_W@ ++DEFS = @DEFS@ ++DEPDIR = @DEPDIR@ ++DLLTOOL = @DLLTOOL@ ++DSYMUTIL = @DSYMUTIL@ ++DUMPBIN = @DUMPBIN@ ++ECHO_C = @ECHO_C@ ++ECHO_N = @ECHO_N@ ++ECHO_T = @ECHO_T@ ++EGREP = @EGREP@ ++EXEEXT = @EXEEXT@ ++FGREP = @FGREP@ ++GREP = @GREP@ ++INSTALL = @INSTALL@ ++INSTALL_DATA = @INSTALL_DATA@ ++INSTALL_PROGRAM = @INSTALL_PROGRAM@ ++INSTALL_SCRIPT = @INSTALL_SCRIPT@ ++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ ++LD = @LD@ ++LDFLAGS = @LDFLAGS@ ++LIBOBJS = @LIBOBJS@ ++LIBS = @LIBS@ ++LIBTOOL = @LIBTOOL@ ++LIPO = @LIPO@ ++LN_S = @LN_S@ ++LTLIBOBJS = @LTLIBOBJS@ ++MAINT = @MAINT@ ++MAKEINFO = @MAKEINFO@ ++MKDIR_P = @MKDIR_P@ ++NEWLIB_CFLAGS = @NEWLIB_CFLAGS@ ++NM = @NM@ ++NMEDIT = @NMEDIT@ ++OBJDUMP = @OBJDUMP@ ++OBJEXT = @OBJEXT@ ++OTOOL = @OTOOL@ ++OTOOL64 = @OTOOL64@ ++PACKAGE = @PACKAGE@ ++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ ++PACKAGE_NAME = @PACKAGE_NAME@ ++PACKAGE_STRING = @PACKAGE_STRING@ ++PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_URL = @PACKAGE_URL@ ++PACKAGE_VERSION = @PACKAGE_VERSION@ ++PATH_SEPARATOR = @PATH_SEPARATOR@ ++RANLIB = @RANLIB@ ++READELF = @READELF@ ++SED = @SED@ ++SET_MAKE = @SET_MAKE@ ++SHELL = @SHELL@ ++STRIP = @STRIP@ ++VERSION = @VERSION@ ++abs_builddir = @abs_builddir@ ++abs_srcdir = @abs_srcdir@ ++abs_top_builddir = @abs_top_builddir@ ++abs_top_srcdir = @abs_top_srcdir@ ++ac_ct_CC = @ac_ct_CC@ ++ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ++aext = @aext@ ++am__include = @am__include@ ++am__leading_dot = @am__leading_dot@ ++am__quote = @am__quote@ ++am__tar = @am__tar@ ++am__untar = @am__untar@ ++bindir = @bindir@ ++build = @build@ ++build_alias = @build_alias@ ++build_cpu = @build_cpu@ ++build_os = @build_os@ ++build_vendor = @build_vendor@ ++builddir = @builddir@ ++datadir = @datadir@ ++datarootdir = @datarootdir@ ++docdir = @docdir@ ++dvidir = @dvidir@ ++exec_prefix = @exec_prefix@ ++host = @host@ ++host_alias = @host_alias@ ++host_cpu = @host_cpu@ ++host_os = @host_os@ ++host_vendor = @host_vendor@ ++htmldir = @htmldir@ ++includedir = @includedir@ ++infodir = @infodir@ ++install_sh = @install_sh@ ++libdir = @libdir@ ++libexecdir = @libexecdir@ ++libm_machine_dir = @libm_machine_dir@ ++localedir = @localedir@ ++localstatedir = @localstatedir@ ++lpfx = @lpfx@ ++lt_ECHO = @lt_ECHO@ ++machine_dir = @machine_dir@ ++mandir = @mandir@ ++mkdir_p = @mkdir_p@ ++newlib_basedir = @newlib_basedir@ ++oext = @oext@ ++oldincludedir = @oldincludedir@ ++pdfdir = @pdfdir@ ++prefix = @prefix@ ++program_transform_name = @program_transform_name@ ++psdir = @psdir@ ++sbindir = @sbindir@ ++sharedstatedir = @sharedstatedir@ ++srcdir = @srcdir@ ++sys_dir = @sys_dir@ ++sysconfdir = @sysconfdir@ ++target_alias = @target_alias@ ++top_build_prefix = @top_build_prefix@ ++top_builddir = @top_builddir@ ++top_srcdir = @top_srcdir@ ++AUTOMAKE_OPTIONS = cygnus ++INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) ++SUBDIRS = net gloss ++AM_CCASFLAGS = $(INCLUDES) ++noinst_LIBRARIES = lib.a ++lib_a_SOURCES = dummysys.c getuid.c poll.c termios.c ++lib_a_CCASFLAGS = $(AM_CCASFLAGS) ++lib_a_CFLAGS = $(AM_CFLAGS) ++SUBLIBS = net/lib.a gloss/lib.a ++ACLOCAL_AMFLAGS = -I ../../.. -I ../../../.. ++CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host ++all: all-recursive ++ ++.SUFFIXES: ++.SUFFIXES: .c .lo .o .obj ++am--refresh: ++ @: ++$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) ++ @for dep in $?; do \ ++ case '$(am__configure_deps)' in \ ++ *$$dep*) \ ++ echo ' cd $(srcdir) && $(AUTOMAKE) --cygnus'; \ ++ $(am__cd) $(srcdir) && $(AUTOMAKE) --cygnus \ ++ && exit 0; \ ++ exit 1;; \ ++ esac; \ ++ done; \ ++ echo ' cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile'; \ ++ $(am__cd) $(top_srcdir) && \ ++ $(AUTOMAKE) --cygnus Makefile ++.PRECIOUS: Makefile ++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status ++ @case '$?' in \ ++ *config.status*) \ ++ echo ' $(SHELL) ./config.status'; \ ++ $(SHELL) ./config.status;; \ ++ *) \ ++ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ ++ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ ++ esac; ++ ++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) ++ $(SHELL) ./config.status --recheck ++ ++$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) ++ $(am__cd) $(srcdir) && $(AUTOCONF) ++$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) ++ $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) ++$(am__aclocal_m4_deps): ++ ++clean-noinstLIBRARIES: ++ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) ++ ++mostlyclean-compile: ++ -rm -f *.$(OBJEXT) ++ ++distclean-compile: ++ -rm -f *.tab.c ++ ++.c.o: ++ $(COMPILE) -c $< ++ ++.c.obj: ++ $(COMPILE) -c `$(CYGPATH_W) '$<'` ++ ++.c.lo: ++ $(LTCOMPILE) -c -o $@ $< ++ ++lib_a-dummysys.o: dummysys.c ++ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dummysys.o `test -f 'dummysys.c' || echo '$(srcdir)/'`dummysys.c ++ ++lib_a-dummysys.obj: dummysys.c ++ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dummysys.obj `if test -f 'dummysys.c'; then $(CYGPATH_W) 'dummysys.c'; else $(CYGPATH_W) '$(srcdir)/dummysys.c'; fi` ++ ++lib_a-getuid.o: getuid.c ++ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-getuid.o `test -f 'getuid.c' || echo '$(srcdir)/'`getuid.c ++ ++lib_a-getuid.obj: getuid.c ++ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-getuid.obj `if test -f 'getuid.c'; then $(CYGPATH_W) 'getuid.c'; else $(CYGPATH_W) '$(srcdir)/getuid.c'; fi` ++ ++lib_a-poll.o: poll.c ++ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-poll.o `test -f 'poll.c' || echo '$(srcdir)/'`poll.c ++ ++lib_a-poll.obj: poll.c ++ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-poll.obj `if test -f 'poll.c'; then $(CYGPATH_W) 'poll.c'; else $(CYGPATH_W) '$(srcdir)/poll.c'; fi` ++ ++lib_a-termios.o: termios.c ++ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-termios.o `test -f 'termios.c' || echo '$(srcdir)/'`termios.c ++ ++lib_a-termios.obj: termios.c ++ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-termios.obj `if test -f 'termios.c'; then $(CYGPATH_W) 'termios.c'; else $(CYGPATH_W) '$(srcdir)/termios.c'; fi` ++ ++mostlyclean-libtool: ++ -rm -f *.lo ++ ++clean-libtool: ++ -rm -rf .libs _libs ++ ++distclean-libtool: ++ -rm -f libtool config.lt ++ ++# This directory's subdirectories are mostly independent; you can cd ++# into them and run `make' without going through this Makefile. ++# To change the values of `make' variables: instead of editing Makefiles, ++# (1) if the variable is set in `config.status', edit `config.status' ++# (which will cause the Makefiles to be regenerated when you run `make'); ++# (2) otherwise, pass the desired values on the `make' command line. ++$(RECURSIVE_TARGETS): ++ @fail= failcom='exit 1'; \ ++ for f in x $$MAKEFLAGS; do \ ++ case $$f in \ ++ *=* | --[!k]*);; \ ++ *k*) failcom='fail=yes';; \ ++ esac; \ ++ done; \ ++ dot_seen=no; \ ++ target=`echo $@ | sed s/-recursive//`; \ ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ echo "Making $$target in $$subdir"; \ ++ if test "$$subdir" = "."; then \ ++ dot_seen=yes; \ ++ local_target="$$target-am"; \ ++ else \ ++ local_target="$$target"; \ ++ fi; \ ++ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ ++ || eval $$failcom; \ ++ done; \ ++ if test "$$dot_seen" = "no"; then \ ++ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ ++ fi; test -z "$$fail" ++ ++$(RECURSIVE_CLEAN_TARGETS): ++ @fail= failcom='exit 1'; \ ++ for f in x $$MAKEFLAGS; do \ ++ case $$f in \ ++ *=* | --[!k]*);; \ ++ *k*) failcom='fail=yes';; \ ++ esac; \ ++ done; \ ++ dot_seen=no; \ ++ case "$@" in \ ++ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ ++ *) list='$(SUBDIRS)' ;; \ ++ esac; \ ++ rev=''; for subdir in $$list; do \ ++ if test "$$subdir" = "."; then :; else \ ++ rev="$$subdir $$rev"; \ ++ fi; \ ++ done; \ ++ rev="$$rev ."; \ ++ target=`echo $@ | sed s/-recursive//`; \ ++ for subdir in $$rev; do \ ++ echo "Making $$target in $$subdir"; \ ++ if test "$$subdir" = "."; then \ ++ local_target="$$target-am"; \ ++ else \ ++ local_target="$$target"; \ ++ fi; \ ++ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ ++ || eval $$failcom; \ ++ done && test -z "$$fail" ++tags-recursive: ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ ++ done ++ctags-recursive: ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ ++ done ++ ++ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ ++ END { if (nonempty) { for (i in files) print i; }; }'`; \ ++ mkid -fID $$unique ++tags: TAGS ++ ++TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ set x; \ ++ here=`pwd`; \ ++ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ ++ include_option=--etags-include; \ ++ empty_fix=.; \ ++ else \ ++ include_option=--include; \ ++ empty_fix=; \ ++ fi; \ ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ if test "$$subdir" = .; then :; else \ ++ test ! -f $$subdir/TAGS || \ ++ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ ++ fi; \ ++ done; \ ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ ++ END { if (nonempty) { for (i in files) print i; }; }'`; \ ++ shift; \ ++ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ ++ test -n "$$unique" || unique=$$empty_fix; \ ++ if test $$# -gt 0; then \ ++ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ ++ "$$@" $$unique; \ ++ else \ ++ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ ++ $$unique; \ ++ fi; \ ++ fi ++ctags: CTAGS ++CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ ++ END { if (nonempty) { for (i in files) print i; }; }'`; \ ++ test -z "$(CTAGS_ARGS)$$unique" \ ++ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ ++ $$unique ++ ++GTAGS: ++ here=`$(am__cd) $(top_builddir) && pwd` \ ++ && $(am__cd) $(top_srcdir) \ ++ && gtags -i $(GTAGS_ARGS) "$$here" ++ ++distclean-tags: ++ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags ++check-am: ++check: check-recursive ++all-am: Makefile $(LIBRARIES) all-local ++installdirs: installdirs-recursive ++installdirs-am: ++install: install-recursive ++install-exec: install-exec-recursive ++install-data: install-data-recursive ++uninstall: uninstall-recursive ++ ++install-am: all-am ++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am ++ ++installcheck: installcheck-recursive ++install-strip: ++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ ++ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ ++ `test -z '$(STRIP)' || \ ++ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install ++mostlyclean-generic: ++ ++clean-generic: ++ ++distclean-generic: ++ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) ++ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) ++ ++maintainer-clean-generic: ++ @echo "This command is intended for maintainers to use" ++ @echo "it deletes files that may require special tools to rebuild." ++clean: clean-recursive ++ ++clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ ++ mostlyclean-am ++ ++distclean: distclean-recursive ++ -rm -f $(am__CONFIG_DISTCLEAN_FILES) ++ -rm -f Makefile ++distclean-am: clean-am distclean-compile distclean-generic \ ++ distclean-libtool distclean-tags ++ ++dvi: dvi-recursive ++ ++dvi-am: ++ ++html: html-recursive ++ ++html-am: ++ ++info: info-recursive ++ ++info-am: ++ ++install-data-am: ++ ++install-dvi: install-dvi-recursive ++ ++install-dvi-am: ++ ++install-exec-am: ++ ++install-html: install-html-recursive ++ ++install-html-am: ++ ++install-info: install-info-recursive ++ ++install-info-am: ++ ++install-man: ++ ++install-pdf: install-pdf-recursive ++ ++install-pdf-am: ++ ++install-ps: install-ps-recursive ++ ++install-ps-am: ++ ++installcheck-am: ++ ++maintainer-clean: maintainer-clean-recursive ++ -rm -f $(am__CONFIG_DISTCLEAN_FILES) ++ -rm -rf $(top_srcdir)/autom4te.cache ++ -rm -f Makefile ++maintainer-clean-am: distclean-am maintainer-clean-generic ++ ++mostlyclean: mostlyclean-recursive ++ ++mostlyclean-am: mostlyclean-compile mostlyclean-generic \ ++ mostlyclean-libtool ++ ++pdf: pdf-recursive ++ ++pdf-am: ++ ++ps: ps-recursive ++ ++ps-am: ++ ++uninstall-am: ++ ++.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ ++ install-am install-strip tags-recursive ++ ++.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ ++ all all-am all-local am--refresh check check-am clean \ ++ clean-generic clean-libtool clean-noinstLIBRARIES ctags \ ++ ctags-recursive distclean distclean-compile distclean-generic \ ++ distclean-libtool distclean-tags dvi dvi-am html html-am info \ ++ info-am install install-am install-data install-data-am \ ++ install-dvi install-dvi-am install-exec install-exec-am \ ++ install-html install-html-am install-info install-info-am \ ++ install-man install-pdf install-pdf-am install-ps \ ++ install-ps-am install-strip installcheck installcheck-am \ ++ installdirs installdirs-am maintainer-clean \ ++ maintainer-clean-generic mostlyclean mostlyclean-compile \ ++ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ ++ tags tags-recursive uninstall uninstall-am ++ ++ ++lib.a: $(lib_a_OBJECTS) ++ rm -f $@ ++ rm -rf tmp ++ mkdir tmp ++ cd tmp; \ ++ for i in $(SUBLIBS); do \ ++ $(AR) x ../$$i; \ ++ done; ++ $(AR) $(AR_FLAGS) $@ tmp/*.o $(lib_a_OBJECTS) ++ $(RANLIB) $@ ++ rm -rf tmp ++ ++all-local: ++ ++# Tell versions [3.59,3.63) of GNU make to not export all variables. ++# Otherwise a system limit (for SysV at least) may be exceeded. ++.NOEXPORT: +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/net/Makefile.am newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/net/Makefile.am +--- newlib-1.19.0/newlib/libc/sys/tsvc/net/Makefile.am 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/net/Makefile.am 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,51 @@ ++## Process this file with automake to generate Makefile.in ++ ++AUTOMAKE_OPTIONS = cygnus ++ ++INCLUDES = -I$(srcdir)/../include -I$(srcdir)/.. $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) ++ ++GENERAL_SOURCES = netdb.c socket.c ++ ++#ELIX_4_SOURCES = ++ ++libnet_la_LDFLAGS = ++libnet_la_CFLAGS = ++ ++if USE_LIBTOOL ++noinst_LTLIBRARIES = libnet.la ++libnet_la_SOURCES = $(GENERAL_SOURCES) ++noinst_DATA = objectlist.awk.in ++else ++noinst_LIBRARIES = lib.a ++lib_a_SOURCES = $(GENERAL_SOURCES) ++lib_a_CFLAGS = $(AM_CFLAGS) ++noinst_DATA = ++endif # USE_LIBTOOL ++ ++include $(srcdir)/../../../../Makefile.shared ++ ++install-data-local: ++ $(mkinstalldirs) $(DESTDIR)$(tooldir)/include/netinet; \ ++ for i in $(srcdir)/../include/netinet/*.h; do \ ++ $(INSTALL_DATA) $$i $(DESTDIR)$(tooldir)/include/netinet/`basename $$i`; \ ++ done; \ ++ $(mkinstalldirs) $(DESTDIR)$(tooldir)/include/arpa; \ ++ for i in $(srcdir)/../include/arpa/*.h; do \ ++ $(INSTALL_DATA) $$i $(DESTDIR)$(tooldir)/include/arpa/`basename $$i`; \ ++ done; ++# $(mkinstalldirs) $(DESTDIR)$(tooldir)/include/net; \ ++# for i in $(srcdir)/../include/net/*.h; do \ ++# $(INSTALL_DATA) $$i $(DESTDIR)$(tooldir)/include/net/`basename $$i`; \ ++# done; ++# $(mkinstalldirs) $(DESTDIR)$(tooldir)/include/netinet6; \ ++# for i in $(srcdir)/../include/netinet6/*.h; do \ ++# $(INSTALL_DATA) $$i $(DESTDIR)$(tooldir)/include/netinet6/`basename $$i`; \ ++# done; \ ++# $(mkinstalldirs) $(DESTDIR)$(tooldir)/include/netns; \ ++# for i in $(srcdir)/../include/netns/*.h; do \ ++# $(INSTALL_DATA) $$i $(DESTDIR)$(tooldir)/include/netns/`basename $$i`; \ ++# done; \ ++# $(mkinstalldirs) $(DESTDIR)$(tooldir)/include/rpc; \ ++# for i in $(srcdir)/../include/rpc/*.h; do \ ++# $(INSTALL_DATA) $$i $(DESTDIR)$(tooldir)/include/rpc/`basename $$i`; \ ++# done; +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/net/Makefile.in newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/net/Makefile.in +--- newlib-1.19.0/newlib/libc/sys/tsvc/net/Makefile.in 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/net/Makefile.in 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,519 @@ ++# Makefile.in generated by automake 1.11.1 from Makefile.am. ++# @configure_input@ ++ ++# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, ++# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, ++# Inc. ++# This Makefile.in is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without ++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A ++# PARTICULAR PURPOSE. ++ ++@SET_MAKE@ ++ ++ ++ ++VPATH = @srcdir@ ++pkgdatadir = $(datadir)/@PACKAGE@ ++pkgincludedir = $(includedir)/@PACKAGE@ ++pkglibdir = $(libdir)/@PACKAGE@ ++pkglibexecdir = $(libexecdir)/@PACKAGE@ ++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd ++install_sh_DATA = $(install_sh) -c -m 644 ++install_sh_PROGRAM = $(install_sh) -c ++install_sh_SCRIPT = $(install_sh) -c ++INSTALL_HEADER = $(INSTALL_DATA) ++transform = $(program_transform_name) ++NORMAL_INSTALL = : ++PRE_INSTALL = : ++POST_INSTALL = : ++NORMAL_UNINSTALL = : ++PRE_UNINSTALL = : ++POST_UNINSTALL = : ++build_triplet = @build@ ++host_triplet = @host@ ++DIST_COMMON = $(srcdir)/../../../../Makefile.shared \ ++ $(srcdir)/Makefile.in $(srcdir)/Makefile.am ++subdir = net ++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ++am__aclocal_m4_deps = $(top_srcdir)/../../../../lt~obsolete.m4 \ ++ $(top_srcdir)/../../../acinclude.m4 \ ++ $(top_srcdir)/../../../libtool.m4 \ ++ $(top_srcdir)/../../../ltoptions.m4 \ ++ $(top_srcdir)/../../../ltsugar.m4 \ ++ $(top_srcdir)/../../../ltversion.m4 \ ++ $(top_srcdir)/../../../lt~obsolete.m4 \ ++ $(top_srcdir)/configure.in ++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ ++ $(ACLOCAL_M4) ++mkinstalldirs = $(SHELL) $(top_srcdir)/../../../../mkinstalldirs ++CONFIG_CLEAN_FILES = ++CONFIG_CLEAN_VPATH_FILES = ++LIBRARIES = $(noinst_LIBRARIES) ++ARFLAGS = cru ++lib_a_AR = $(AR) $(ARFLAGS) ++lib_a_LIBADD = ++am__objects_1 = lib_a-netdb.$(OBJEXT) lib_a-socket.$(OBJEXT) ++@USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_1) ++lib_a_OBJECTS = $(am_lib_a_OBJECTS) ++LTLIBRARIES = $(noinst_LTLIBRARIES) ++libnet_la_LIBADD = ++am__objects_2 = libnet_la-netdb.lo libnet_la-socket.lo ++@USE_LIBTOOL_TRUE@am_libnet_la_OBJECTS = $(am__objects_2) ++libnet_la_OBJECTS = $(am_libnet_la_OBJECTS) ++libnet_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ ++ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libnet_la_CFLAGS) \ ++ $(CFLAGS) $(libnet_la_LDFLAGS) $(LDFLAGS) -o $@ ++@USE_LIBTOOL_TRUE@am_libnet_la_rpath = ++DEFAULT_INCLUDES = -I.@am__isrc@ ++depcomp = ++am__depfiles_maybe = ++COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ ++ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) ++LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ ++ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ ++ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) ++CCLD = $(CC) ++LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ ++ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ ++ $(LDFLAGS) -o $@ ++SOURCES = $(lib_a_SOURCES) $(libnet_la_SOURCES) ++DATA = $(noinst_DATA) ++ETAGS = etags ++CTAGS = ctags ++ACLOCAL = @ACLOCAL@ ++AMTAR = @AMTAR@ ++AR = @AR@ ++AS = @AS@ ++AUTOCONF = @AUTOCONF@ ++AUTOHEADER = @AUTOHEADER@ ++AUTOMAKE = @AUTOMAKE@ ++AWK = @AWK@ ++CC = @CC@ ++CCAS = @CCAS@ ++CCASFLAGS = @CCASFLAGS@ ++CCDEPMODE = @CCDEPMODE@ ++CFLAGS = @CFLAGS@ ++CPP = @CPP@ ++CPPFLAGS = @CPPFLAGS@ ++CYGPATH_W = @CYGPATH_W@ ++DEFS = @DEFS@ ++DEPDIR = @DEPDIR@ ++DLLTOOL = @DLLTOOL@ ++DSYMUTIL = @DSYMUTIL@ ++DUMPBIN = @DUMPBIN@ ++ECHO_C = @ECHO_C@ ++ECHO_N = @ECHO_N@ ++ECHO_T = @ECHO_T@ ++EGREP = @EGREP@ ++EXEEXT = @EXEEXT@ ++FGREP = @FGREP@ ++GREP = @GREP@ ++INSTALL = @INSTALL@ ++INSTALL_DATA = @INSTALL_DATA@ ++INSTALL_PROGRAM = @INSTALL_PROGRAM@ ++INSTALL_SCRIPT = @INSTALL_SCRIPT@ ++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ ++LD = @LD@ ++LDFLAGS = @LDFLAGS@ ++LIBOBJS = @LIBOBJS@ ++LIBS = @LIBS@ ++LIBTOOL = @LIBTOOL@ ++LIPO = @LIPO@ ++LN_S = @LN_S@ ++LTLIBOBJS = @LTLIBOBJS@ ++MAINT = @MAINT@ ++MAKEINFO = @MAKEINFO@ ++MKDIR_P = @MKDIR_P@ ++NEWLIB_CFLAGS = @NEWLIB_CFLAGS@ ++NM = @NM@ ++NMEDIT = @NMEDIT@ ++OBJDUMP = @OBJDUMP@ ++OBJEXT = @OBJEXT@ ++OTOOL = @OTOOL@ ++OTOOL64 = @OTOOL64@ ++PACKAGE = @PACKAGE@ ++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ ++PACKAGE_NAME = @PACKAGE_NAME@ ++PACKAGE_STRING = @PACKAGE_STRING@ ++PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_URL = @PACKAGE_URL@ ++PACKAGE_VERSION = @PACKAGE_VERSION@ ++PATH_SEPARATOR = @PATH_SEPARATOR@ ++RANLIB = @RANLIB@ ++READELF = @READELF@ ++SED = @SED@ ++SET_MAKE = @SET_MAKE@ ++SHELL = @SHELL@ ++STRIP = @STRIP@ ++VERSION = @VERSION@ ++abs_builddir = @abs_builddir@ ++abs_srcdir = @abs_srcdir@ ++abs_top_builddir = @abs_top_builddir@ ++abs_top_srcdir = @abs_top_srcdir@ ++ac_ct_CC = @ac_ct_CC@ ++ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ++aext = @aext@ ++am__include = @am__include@ ++am__leading_dot = @am__leading_dot@ ++am__quote = @am__quote@ ++am__tar = @am__tar@ ++am__untar = @am__untar@ ++bindir = @bindir@ ++build = @build@ ++build_alias = @build_alias@ ++build_cpu = @build_cpu@ ++build_os = @build_os@ ++build_vendor = @build_vendor@ ++builddir = @builddir@ ++datadir = @datadir@ ++datarootdir = @datarootdir@ ++docdir = @docdir@ ++dvidir = @dvidir@ ++exec_prefix = @exec_prefix@ ++host = @host@ ++host_alias = @host_alias@ ++host_cpu = @host_cpu@ ++host_os = @host_os@ ++host_vendor = @host_vendor@ ++htmldir = @htmldir@ ++includedir = @includedir@ ++infodir = @infodir@ ++install_sh = @install_sh@ ++libdir = @libdir@ ++libexecdir = @libexecdir@ ++libm_machine_dir = @libm_machine_dir@ ++localedir = @localedir@ ++localstatedir = @localstatedir@ ++lpfx = @lpfx@ ++lt_ECHO = @lt_ECHO@ ++machine_dir = @machine_dir@ ++mandir = @mandir@ ++mkdir_p = @mkdir_p@ ++newlib_basedir = @newlib_basedir@ ++oext = @oext@ ++oldincludedir = @oldincludedir@ ++pdfdir = @pdfdir@ ++prefix = @prefix@ ++program_transform_name = @program_transform_name@ ++psdir = @psdir@ ++sbindir = @sbindir@ ++sharedstatedir = @sharedstatedir@ ++srcdir = @srcdir@ ++sys_dir = @sys_dir@ ++sysconfdir = @sysconfdir@ ++target_alias = @target_alias@ ++top_build_prefix = @top_build_prefix@ ++top_builddir = @top_builddir@ ++top_srcdir = @top_srcdir@ ++AUTOMAKE_OPTIONS = cygnus ++INCLUDES = -I$(srcdir)/../include -I$(srcdir)/.. $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) ++GENERAL_SOURCES = netdb.c socket.c ++ ++#ELIX_4_SOURCES = ++libnet_la_LDFLAGS = ++libnet_la_CFLAGS = ++@USE_LIBTOOL_TRUE@noinst_LTLIBRARIES = libnet.la ++@USE_LIBTOOL_TRUE@libnet_la_SOURCES = $(GENERAL_SOURCES) ++@USE_LIBTOOL_FALSE@noinst_DATA = ++@USE_LIBTOOL_TRUE@noinst_DATA = objectlist.awk.in ++@USE_LIBTOOL_FALSE@noinst_LIBRARIES = lib.a ++@USE_LIBTOOL_FALSE@lib_a_SOURCES = $(GENERAL_SOURCES) ++@USE_LIBTOOL_FALSE@lib_a_CFLAGS = $(AM_CFLAGS) ++all: all-am ++ ++.SUFFIXES: ++.SUFFIXES: .c .lo .o .obj ++$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/../../../../Makefile.shared $(am__configure_deps) ++ @for dep in $?; do \ ++ case '$(am__configure_deps)' in \ ++ *$$dep*) \ ++ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ ++ && { if test -f $@; then exit 0; else break; fi; }; \ ++ exit 1;; \ ++ esac; \ ++ done; \ ++ echo ' cd $(top_srcdir) && $(AUTOMAKE) --cygnus net/Makefile'; \ ++ $(am__cd) $(top_srcdir) && \ ++ $(AUTOMAKE) --cygnus net/Makefile ++.PRECIOUS: Makefile ++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status ++ @case '$?' in \ ++ *config.status*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ ++ *) \ ++ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ ++ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ ++ esac; ++ ++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++$(am__aclocal_m4_deps): ++ ++clean-noinstLIBRARIES: ++ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) ++lib.a: $(lib_a_OBJECTS) $(lib_a_DEPENDENCIES) ++ -rm -f lib.a ++ $(lib_a_AR) lib.a $(lib_a_OBJECTS) $(lib_a_LIBADD) ++ $(RANLIB) lib.a ++ ++clean-noinstLTLIBRARIES: ++ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) ++ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ ++ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ ++ test "$$dir" != "$$p" || dir=.; \ ++ echo "rm -f \"$${dir}/so_locations\""; \ ++ rm -f "$${dir}/so_locations"; \ ++ done ++libnet.la: $(libnet_la_OBJECTS) $(libnet_la_DEPENDENCIES) ++ $(libnet_la_LINK) $(am_libnet_la_rpath) $(libnet_la_OBJECTS) $(libnet_la_LIBADD) $(LIBS) ++ ++mostlyclean-compile: ++ -rm -f *.$(OBJEXT) ++ ++distclean-compile: ++ -rm -f *.tab.c ++ ++.c.o: ++ $(COMPILE) -c $< ++ ++.c.obj: ++ $(COMPILE) -c `$(CYGPATH_W) '$<'` ++ ++.c.lo: ++ $(LTCOMPILE) -c -o $@ $< ++ ++lib_a-netdb.o: netdb.c ++ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-netdb.o `test -f 'netdb.c' || echo '$(srcdir)/'`netdb.c ++ ++lib_a-netdb.obj: netdb.c ++ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-netdb.obj `if test -f 'netdb.c'; then $(CYGPATH_W) 'netdb.c'; else $(CYGPATH_W) '$(srcdir)/netdb.c'; fi` ++ ++lib_a-socket.o: socket.c ++ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-socket.o `test -f 'socket.c' || echo '$(srcdir)/'`socket.c ++ ++lib_a-socket.obj: socket.c ++ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-socket.obj `if test -f 'socket.c'; then $(CYGPATH_W) 'socket.c'; else $(CYGPATH_W) '$(srcdir)/socket.c'; fi` ++ ++libnet_la-netdb.lo: netdb.c ++ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnet_la_CFLAGS) $(CFLAGS) -c -o libnet_la-netdb.lo `test -f 'netdb.c' || echo '$(srcdir)/'`netdb.c ++ ++libnet_la-socket.lo: socket.c ++ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnet_la_CFLAGS) $(CFLAGS) -c -o libnet_la-socket.lo `test -f 'socket.c' || echo '$(srcdir)/'`socket.c ++ ++mostlyclean-libtool: ++ -rm -f *.lo ++ ++clean-libtool: ++ -rm -rf .libs _libs ++ ++ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ ++ END { if (nonempty) { for (i in files) print i; }; }'`; \ ++ mkid -fID $$unique ++tags: TAGS ++ ++TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ set x; \ ++ here=`pwd`; \ ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ ++ END { if (nonempty) { for (i in files) print i; }; }'`; \ ++ shift; \ ++ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ ++ test -n "$$unique" || unique=$$empty_fix; \ ++ if test $$# -gt 0; then \ ++ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ ++ "$$@" $$unique; \ ++ else \ ++ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ ++ $$unique; \ ++ fi; \ ++ fi ++ctags: CTAGS ++CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ ++ END { if (nonempty) { for (i in files) print i; }; }'`; \ ++ test -z "$(CTAGS_ARGS)$$unique" \ ++ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ ++ $$unique ++ ++GTAGS: ++ here=`$(am__cd) $(top_builddir) && pwd` \ ++ && $(am__cd) $(top_srcdir) \ ++ && gtags -i $(GTAGS_ARGS) "$$here" ++ ++distclean-tags: ++ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags ++check-am: ++check: check-am ++all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(DATA) ++installdirs: ++install: install-am ++install-exec: install-exec-am ++install-data: install-data-am ++uninstall: uninstall-am ++ ++install-am: all-am ++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am ++ ++installcheck: installcheck-am ++install-strip: ++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ ++ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ ++ `test -z '$(STRIP)' || \ ++ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install ++mostlyclean-generic: ++ ++clean-generic: ++ ++distclean-generic: ++ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) ++ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) ++ ++maintainer-clean-generic: ++ @echo "This command is intended for maintainers to use" ++ @echo "it deletes files that may require special tools to rebuild." ++clean: clean-am ++ ++clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ ++ clean-noinstLTLIBRARIES mostlyclean-am ++ ++distclean: distclean-am ++ -rm -f Makefile ++distclean-am: clean-am distclean-compile distclean-generic \ ++ distclean-tags ++ ++dvi: dvi-am ++ ++dvi-am: ++ ++html: html-am ++ ++html-am: ++ ++info: info-am ++ ++info-am: ++ ++install-data-am: install-data-local ++ ++install-dvi: install-dvi-am ++ ++install-dvi-am: ++ ++install-exec-am: ++ ++install-html: install-html-am ++ ++install-html-am: ++ ++install-info: install-info-am ++ ++install-info-am: ++ ++install-man: ++ ++install-pdf: install-pdf-am ++ ++install-pdf-am: ++ ++install-ps: install-ps-am ++ ++install-ps-am: ++ ++installcheck-am: ++ ++maintainer-clean: maintainer-clean-am ++ -rm -f Makefile ++maintainer-clean-am: distclean-am maintainer-clean-generic ++ ++mostlyclean: mostlyclean-am ++ ++mostlyclean-am: mostlyclean-compile mostlyclean-generic \ ++ mostlyclean-libtool ++ ++pdf: pdf-am ++ ++pdf-am: ++ ++ps: ps-am ++ ++ps-am: ++ ++uninstall-am: ++ ++.MAKE: install-am install-strip ++ ++.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ ++ clean-libtool clean-noinstLIBRARIES clean-noinstLTLIBRARIES \ ++ ctags distclean distclean-compile distclean-generic \ ++ distclean-libtool distclean-tags dvi dvi-am html html-am info \ ++ info-am install install-am install-data install-data-am \ ++ install-data-local install-dvi install-dvi-am install-exec \ ++ install-exec-am install-html install-html-am install-info \ ++ install-info-am install-man install-pdf install-pdf-am \ ++ install-ps install-ps-am install-strip installcheck \ ++ installcheck-am installdirs maintainer-clean \ ++ maintainer-clean-generic mostlyclean mostlyclean-compile \ ++ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ ++ tags uninstall uninstall-am ++ ++objectlist.awk.in: $(noinst_LTLIBRARIES) ++ -rm -f objectlist.awk.in ++ for i in `ls *.lo` ; \ ++ do \ ++ echo $$i `pwd`/$$i >> objectlist.awk.in ; \ ++ done ++ ++install-data-local: ++ $(mkinstalldirs) $(DESTDIR)$(tooldir)/include/netinet; \ ++ for i in $(srcdir)/../include/netinet/*.h; do \ ++ $(INSTALL_DATA) $$i $(DESTDIR)$(tooldir)/include/netinet/`basename $$i`; \ ++ done; \ ++ $(mkinstalldirs) $(DESTDIR)$(tooldir)/include/arpa; \ ++ for i in $(srcdir)/../include/arpa/*.h; do \ ++ $(INSTALL_DATA) $$i $(DESTDIR)$(tooldir)/include/arpa/`basename $$i`; \ ++ done; ++# $(mkinstalldirs) $(DESTDIR)$(tooldir)/include/net; \ ++# for i in $(srcdir)/../include/net/*.h; do \ ++# $(INSTALL_DATA) $$i $(DESTDIR)$(tooldir)/include/net/`basename $$i`; \ ++# done; ++# $(mkinstalldirs) $(DESTDIR)$(tooldir)/include/netinet6; \ ++# for i in $(srcdir)/../include/netinet6/*.h; do \ ++# $(INSTALL_DATA) $$i $(DESTDIR)$(tooldir)/include/netinet6/`basename $$i`; \ ++# done; \ ++# $(mkinstalldirs) $(DESTDIR)$(tooldir)/include/netns; \ ++# for i in $(srcdir)/../include/netns/*.h; do \ ++# $(INSTALL_DATA) $$i $(DESTDIR)$(tooldir)/include/netns/`basename $$i`; \ ++# done; \ ++# $(mkinstalldirs) $(DESTDIR)$(tooldir)/include/rpc; \ ++# for i in $(srcdir)/../include/rpc/*.h; do \ ++# $(INSTALL_DATA) $$i $(DESTDIR)$(tooldir)/include/rpc/`basename $$i`; \ ++# done; ++ ++# Tell versions [3.59,3.63) of GNU make to not export all variables. ++# Otherwise a system limit (for SysV at least) may be exceeded. ++.NOEXPORT: +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/net/netdb.c newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/net/netdb.c +--- newlib-1.19.0/newlib/libc/sys/tsvc/net/netdb.c 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/net/netdb.c 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,58 @@ ++#include ++ ++void endhostent(void) ++{} ++ ++void endnetent(void) ++{} ++ ++void endprotoent(void) ++{} ++ ++void endservent(void) ++{} ++ ++struct hostent *gethostbyaddr(const void *addr, size_t len, int type) ++{ return NULL; } ++ ++struct hostent *gethostbyname(const char *name) ++{ return NULL; } ++ ++struct hostent *gethostent(void) ++{ return NULL; } ++ ++struct netent *getnetbyaddr(uint32_t net, int type) ++{ return NULL; } ++ ++struct netent *getnetbyname(const char *name) ++{ return NULL; } ++ ++struct netent *getnetent(void) ++{ return NULL; } ++ ++struct protoent *getprotobyname(const char *name) ++{ return NULL; } ++ ++struct protoent *getprotobynumber(int proto) ++{ return NULL; } ++ ++struct protoent *getprotoent(void) ++{ return NULL; } ++ ++struct servent *getservbyname(const char *name, const char *proto) ++{ return NULL; } ++ ++struct servent *getservbyport(int port, const char *proto) ++{ return NULL; } ++ ++struct servent *getservent(void) ++{ return NULL; } ++ ++void sethostent(int stayopen) ++{} ++void setnetent(int stayopen) ++{} ++void setprotoent(int stayopen) ++{} ++void setservent(int stayopen) ++{} +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/net/socket.c newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/net/socket.c +--- newlib-1.19.0/newlib/libc/sys/tsvc/net/socket.c 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/net/socket.c 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,113 @@ ++#include ++#include ++ ++int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) ++{ ++ errno=ENOSYS; ++ return -1; ++} ++ ++int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) ++{ ++ errno=ENOSYS; ++ return -1; ++} ++ ++int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) ++{ ++ errno=ENOSYS; ++ return -1; ++} ++ ++int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen) ++{ ++ errno=ENOSYS; ++ return -1; ++} ++ ++int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen) ++{ ++ errno=ENOSYS; ++ return -1; ++} ++ ++int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen) ++{ ++ errno=ENOSYS; ++ return -1; ++} ++ ++int listen(int sockfd, int backlog) ++{ ++ errno=ENOSYS; ++ return -1; ++} ++ ++ssize_t recv(int sockfd, void *buf, size_t len, int flags) ++{ ++ errno=ENOSYS; ++ return -1; ++} ++ ++ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, ++ struct sockaddr *src_addr, socklen_t *addrlen) ++{ ++ errno=ENOSYS; ++ return -1; ++} ++ ++ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags) ++{ ++ errno=ENOSYS; ++ return -1; ++} ++ ++ssize_t send(int sockfd, const void *buf, size_t len, int flags) ++{ ++ errno=ENOSYS; ++ return -1; ++} ++ ++ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags) ++{ ++ errno=ENOSYS; ++ return -1; ++} ++ ++ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, ++ const struct sockaddr *dest_addr, socklen_t addrlen) ++{ ++ errno=ENOSYS; ++ return -1; ++} ++ ++int setsockopt(int sockfd, int level, int optname, ++ const void *optval, socklen_t optlen) ++{ ++ errno=ENOSYS; ++ return -1; ++} ++ ++int shutdown(int sockfd, int how) ++{ ++ errno=ENOSYS; ++ return -1; ++} ++ ++int socket(int domain, int type, int protocol) ++{ ++ errno=ENOSYS; ++ return -1; ++} ++ ++int sockatmark(int sockfd) ++{ ++ errno=ENOSYS; ++ return -1; ++} ++ ++int socketpair(int domain, int type, int protocol, int sv[2]) ++{ ++ errno=ENOSYS; ++ return -1; ++} +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/poll.c newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/poll.c +--- newlib-1.19.0/newlib/libc/sys/tsvc/poll.c 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/poll.c 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,8 @@ ++#include ++#include ++ ++int poll(struct pollfd fds[], nfds_t ndfs, int timeout) ++{ ++ errno=ENOSYS; ++ return -1; ++} +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/sys/dirent.h newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/sys/dirent.h +--- newlib-1.19.0/newlib/libc/sys/tsvc/sys/dirent.h 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/sys/dirent.h 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,21 @@ ++/* FIXME: From sys/tsvc/sys */ ++#ifndef _SYS_DIRENT_H ++# define _SYS_DIRENT_H ++ ++/* linux-compatible place-holder */ ++ ++#include ++ ++typedef struct { ++} DIR; ++ ++/* copied from 'man readdir' */ ++struct dirent { ++ ino_t d_ino; ++ off_t d_off; ++ unsigned short d_reclen; ++ unsigned char d_type; ++ char d_name[256]; ++}; ++ ++#endif +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/sys/ioctl.h newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/sys/ioctl.h +--- newlib-1.19.0/newlib/libc/sys/tsvc/sys/ioctl.h 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/sys/ioctl.h 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,6 @@ ++#ifndef _IOCTL_H ++#define _IOCTL_H ++ ++int ioctl(int fd,int request,...); ++ ++#endif +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/sys/socket.h newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/sys/socket.h +--- newlib-1.19.0/newlib/libc/sys/tsvc/sys/socket.h 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/sys/socket.h 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,219 @@ ++/* minimal compliance with IEEE Std 1003.1 ++ http://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/socket.h.html ++*/ ++ ++#ifndef _SYS_SOCKET_H ++#define _SYS_SOCKET_H ++ ++#include ++ ++/* The header shall define the type socklen_t, which is ++ an integer type of width of at least 32 bits; see APPLICATION ++ USAGE. */ ++typedef unsigned long int socklen_t; ++ ++/* The header shall define the unsigned integer type ++ sa_family_t. */ ++#ifndef _SA_FAMILY_T_DECLARED ++typedef unsigned int sa_family_t; ++#define _SA_FAMILY_T_DECLARED ++#endif ++ ++/* The header shall define the sockaddr structure that ++ includes at least the following members: */ ++struct sockaddr { ++ sa_family_t sa_family; /* Address family. */ ++ char sa_data[]; /* Socket address (variable-length data). */ ++}; ++/* The sockaddr structure is used to define a socket address which is ++ used in the bind(), connect(), getpeername(), getsockname(), ++ recvfrom(), and sendto() functions. */ ++ ++/* The header shall define the sockaddr_storage ++ structure. This structure shall be: */ ++/* Large enough to accommodate all supported protocol-specific address ++ structures */ ++/* Aligned at an appropriate boundary so that pointers to it can be ++ cast as pointers to protocol-specific address structures and used ++ to access the fields of those structures without alignment ++ problems */ ++/* The sockaddr_storage structure shall contain at least the following ++ members: */ ++struct sockaddr_storage { ++ sa_family_t ss_family; ++ char data[1]; /* FIXME */ ++}; ++/* When a sockaddr_storage structure is cast as a sockaddr structure, ++ the ss_family field of the sockaddr_storage structure shall map ++ onto the sa_family field of the sockaddr structure. When a ++ sockaddr_storage structure is cast as a protocol-specific address ++ structure, the ss_family field shall map onto a field of that ++ structure that is of type sa_family_t and that identifies the ++ protocol's address family. */ ++ ++/* The header shall define the msghdr structure that ++ includes at least the following members: */ ++struct msghdr { ++ void *msg_name; /* Optional address. */ ++ socklen_t msg_namelen; /* Size of address. */ ++ struct iovec *msg_iov; /* Scatter/gather array. */ ++ int msg_iovlen; /* Members in msg_iov. */ ++ void *msg_control; /* Ancillary data; see below. */ ++ socklen_t msg_controllen; /* Ancillary data buffer len. */ ++ int msg_flags; /* Flags on received message. */ ++}; ++/* The msghdr structure is used to minimize the number of directly ++ supplied parameters to the recvmsg() and sendmsg() functions. This ++ structure is used as a value- result parameter in the recvmsg() ++ function and value only for the sendmsg() function. */ ++ ++/* The iovec structure shall be defined as described in ++ . */ ++ ++/* The header shall define the cmsghdr structure that ++ includes at least the following members: */ ++struct cmsghdr { ++ socklen_t cmsg_len; /* Data byte count, including the cmsghdr. */ ++ int cmsg_level; /* Originating protocol. */ ++ int cmsg_type; /* Protocol-specific type. */ ++ unsigned char cmsg_data[]; ++}; ++/* The cmsghdr structure is used for storage of ancillary data object ++ information. */ ++/* Ancillary data consists of a sequence of pairs, each consisting of ++ a cmsghdr structure followed by a data array. The data array ++ contains the ancillary data message, and the cmsghdr structure ++ contains descriptive information that allows an application to ++ correctly parse the data. */ ++/* The values for cmsg_level shall be legal values for the level ++ argument to the getsockopt() and setsockopt() functions. The system ++ documentation shall specify the cmsg_type definitions for the ++ supported protocols. */ ++/* Ancillary data is also possible at the socket level. The ++ header defines the following macro for use as the ++ cmsg_type value when cmsg_level is SOL_SOCKET: */ ++#define SCM_RIGHTS 1 ++/* Indicates that the data array contains the access rights to be sent or received. */ ++ ++/* The header defines the following macros to gain ++ access to the data arrays in the ancillary data associated with a ++ message header: */ ++#define CMSG_DATA(cmsg) (cmsg->cmsg_data)) ++ ++/* If the argument is a pointer to a cmsghdr structure, this macro ++ shall return an unsigned character pointer to the data array ++ associated with the cmsghdr structure. */ ++#define CMSG_NXTHDR(mhdr,cmsg) NULL ++/* If the first argument is a pointer to a msghdr structure and the ++ second argument is a pointer to a cmsghdr structure in the ++ ancillary data pointed to by the msg_control field of that msghdr ++ structure, this macro shall return a pointer to the next cmsghdr ++ structure, or a null pointer if this structure is the last cmsghdr ++ in the ancillary data. */ ++ ++#define CMSG_FIRSTHDR(mhdr) NULL ++/* If the argument is a pointer to a msghdr structure, this macro ++ shall return a pointer to the first cmsghdr structure in the ++ ancillary data associated with this msghdr structure, or a null ++ pointer if there is no ancillary data associated with the msghdr ++ structure. */ ++ ++/* The header shall define the linger structure that ++ includes at least the following members: */ ++struct linger { ++ int l_onoff; /* Indicates whether linger option is enabled. */ ++ int l_linger; /* Linger time, in seconds. */ ++}; ++ ++/* The header shall define the following macros, with ++ distinct integer values: */ ++#define SOCK_DGRAM 1 /* Datagram socket. */ ++#define SOCK_RAW 2 /* [RS] Raw Protocol Interface. */ ++#define SOCK_SEQPACKET 3 /* Sequenced-packet socket. */ ++#define SOCK_STREAM 4 /* Byte-stream socket. */ ++ ++/* The header shall define the following macro for use ++ as the level argument of setsockopt() and getsockopt(). */ ++#define SOL_SOCKET 1 ++/* Options to be accessed at socket level, not protocol level. */ ++ ++/* The header shall define the following macros, with ++ distinct integer values, for use as the option_name argument in ++ getsockopt() or setsockopt() calls: */ ++#define SO_ACCEPTCONN 1 /* Socket is accepting connections. */ ++#define SO_BROADCAST 2 /* Transmission of broadcast messages is supported. */ ++#define SO_DEBUG 3 /* Debugging information is being recorded. */ ++#define SO_DONTROUTE 4 /* Bypass normal routing. */ ++#define SO_ERROR 5 /* Socket error status. */ ++#define SO_KEEPALIVE 6 /* Connections are kept alive with periodic messages. */ ++#define SO_LINGER 7 /* Socket lingers on close. */ ++#define SO_OOBINLINE 8 /* Out-of-band data is transmitted in line. */ ++#define SO_RCVBUF 9 /* Receive buffer size. */ ++#define SO_RCVLOWAT 10 /* Receive ``low water mark''. */ ++#define SO_RCVTIMEO 11 /* Receive timeout. */ ++#define SO_REUSEADDR 12 /* Reuse of local addresses is supported. */ ++#define SO_SNDBUF 13 /* Send buffer size. */ ++#define SO_SNDLOWAT 14 /* Send ``low water mark''. */ ++#define SO_SNDTIMEO 15 /* Send timeout. */ ++#define SO_TYPE 16 /* Socket type. */ ++ ++/* The header shall define the following macro as the ++ maximum backlog queue length which may be specified by the backlog ++ field of the listen() function: */ ++#define SOMAXCONN 128 /* The maximum backlog queue length. */ ++ ++/* The header shall define the following macros, with ++ distinct integer values, for use as the valid values for the ++ msg_flags field in the msghdr structure, or the flags parameter in ++ recvfrom(), recvmsg(), sendmsg(), or sendto() calls: */ ++#define MSG_CTRUNC 1 /* Control data truncated. */ ++#define MSG_DONTROUTE 2 /* Send without using routing tables. */ ++#define MSG_EOR 3 /* Terminates a record (if supported by the ++ protocol). */ ++#define MSG_OOB 4 /* Out-of-band data. */ ++#define MSG_PEEK 5 /* Leave received data in queue. */ ++#define MSG_TRUNC 6 /* Normal data truncated. */ ++#define MSG_WAITALL 7 /* Attempt to fill the read buffer. */ ++ ++/* The header shall define the following macros, with ++ distinct integer values: */ ++#define AF_INET 1 /* Internet domain sockets for use with IPv4 ++ addresses. */ ++#define AF_INET6 2 /* [IP6] Internet domain sockets for use with IPv6 ++ addresses. */ ++#define AF_UNIX 3 /* UNIX domain sockets. */ ++#define AF_UNSPEC 4 /* Unspecified. */ ++ ++/* The header shall define the following macros, with ++ distinct integer values: */ ++#define SHUT_RD 1 /* Disables further receive operations. */ ++#define SHUT_RDWR 2 /* Disables further send and receive operations. */ ++#define SHUT_WR 3 /* Disables further send operations. */ ++ ++/* The following shall be declared as functions and may also be ++ defined as macros. Function prototypes shall be provided. */ ++int accept(int, struct sockaddr *, socklen_t *); ++int bind(int, const struct sockaddr *, socklen_t); ++int connect(int, const struct sockaddr *, socklen_t); ++int getpeername(int, struct sockaddr *, socklen_t *); ++int getsockname(int, struct sockaddr *, socklen_t *); ++int getsockopt(int, int, int, void *, socklen_t *); ++int listen(int, int); ++ssize_t recv(int, void *, size_t, int); ++ssize_t recvfrom(int, void *, size_t, int, ++ struct sockaddr *, socklen_t *); ++ssize_t recvmsg(int, struct msghdr *, int); ++ssize_t send(int, const void *, size_t, int); ++ssize_t sendmsg(int, const struct msghdr *, int); ++ssize_t sendto(int, const void *, size_t, int, const struct sockaddr *, ++ socklen_t); ++int setsockopt(int, int, int, const void *, socklen_t); ++int shutdown(int, int); ++int socket(int, int, int); ++int sockatmark(int); ++int socketpair(int, int, int, int[2]); ++ ++/* Inclusion of may also make visible all symbols from ++ . */ ++ ++#endif +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/sys/termios.h newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/sys/termios.h +--- newlib-1.19.0/newlib/libc/sys/tsvc/sys/termios.h 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/sys/termios.h 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,190 @@ ++/* based on IEEE Std 1003.1-2008 ++ * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/termios.h.html ++ */ ++ ++#ifndef _SYS_TERMIOS_H ++# define _SYS_TERMIOS_H ++ ++typedef unsigned char cc_t; ++typedef unsigned short tcflag_t; ++typedef unsigned char speed_t; ++ ++# define NCCS 13 ++ ++struct termios { ++ tcflag_t c_iflag; ++ tcflag_t c_oflag; ++ tcflag_t c_cflag; ++ tcflag_t c_lflag; ++ cc_t c_cc[NCCS]; ++ ++ /* implementation-specific */ ++ speed_t c_ispeed; ++ speed_t c_ospeed; ++}; ++ ++/* The header shall define the following symbolic ++ constants for use as subscripts for the array c_cc: */ ++# define VEOF 4 /* also VMIN -- thanks, AT&T */ ++# define VEOL 5 /* also VTIME -- thanks again */ ++# define VERASE 2 ++# define VINTR 0 ++# define VKILL 3 ++# define VMIN 4 /* also VEOF */ ++# define VQUIT 1 ++# define VSUSP 10 ++# define VTIME 5 /* also VEOL */ ++# define VSTART 11 ++# define VSTOP 12 ++ ++/* The header shall define the following symbolic ++ constants for use as flags in the c_iflag field. The c_iflag field ++ describes the basic terminal input control. */ ++# define IGNBRK 000001 /* Ignore break condition. */ ++# define BRKINT 000002 /* Signal interrupt on break */ ++# define IGNPAR 000004 /* Ignore characters with parity errors. */ ++# define INPCK 000020 /* Enable input parity check. */ ++# define ISTRIP 000040 /* Strip character. */ ++# define INLCR 000100 /* Map NL to CR on input. */ ++# define IGNCR 000200 /* Ignore CR. */ ++# define ICRNL 000400 /* Map CR to NL on input. */ ++# define IXON 002000 /* Enable start/stop output control. */ ++# define IXOFF 010000 /* Enable start/stop input control. */ ++# define IXANY 020000 /* Enable any character to restart output. */ ++ ++/* The header shall define the following symbolic ++ constants for use as flags in the c_oflag field. The c_oflag field ++ specifies the system treatment of output. */ ++# define OPOST 000001 /* Post-process output. */ ++# define OCRNL 000004 /* Map CR to NL on output. */ ++# define ONLCR 000010 /* Map NL to CR-NL on output. */ ++# define ONOCR 000020 /* No CR output at column 0 */ ++# define ONLRET 000040 /* NL performs CR function. */ ++# define OFDEL 000080 /* Fill is DEL. */ ++# define OFILL 000100 /* Use fill characters for delay */ ++# define NLDLY 0000400 ++# define NL0 0000000 ++# define NL1 0000400 ++# define CRDLY 0003000 ++# define CR0 0000000 ++# define CR1 0001000 ++# define CR2 0002000 ++# define CR3 0003000 ++# define TABDLY 0014000 ++# define TAB0 0000000 ++# define TAB1 0004000 ++# define TAB2 0010000 ++# define TAB3 0014000 ++# define BSDLY 0020000 ++# define BS0 0000000 ++# define BS1 0020000 ++# define VTDLY 0040000 ++# define VT0 0000000 ++# define VT1 0040000 ++# define FFDLY 0100000 ++# define FF0 0000000 ++# define FF1 0100000 ++ ++/* The header shall define the following symbolic ++ constants for use as values of objects of type speed_t. */ ++/* The input and output baud rates are stored in the termios ++ structure. These are the valid values for objects of type ++ speed_t. Not all baud rates need be supported by the underlying ++ hardware. */ ++# define B0 000000 ++# define B50 000001 ++# define B75 000002 ++# define B110 000003 ++# define B134 000004 ++# define B150 000005 ++# define B200 000006 ++# define B300 000007 ++# define B600 000010 ++# define B1200 000011 ++# define B1800 000012 ++# define B2400 000013 ++# define B4800 000014 ++# define B9600 000015 ++# define B19200 000016 ++# define B38400 000017 ++ ++/* The header shall define the following symbolic ++ constants for use as flags in the c_cflag field. The c_cflag field ++ describes the hardware control of the terminal; not all values ++ specified are required to be supported by the underlying ++ hardware. */ ++# define CLOCAL 004000 ++# define CREAD 000200 ++# define CSIZE 000060 ++# define CS5 0 ++# define CS6 020 ++# define CS7 040 ++# define CS8 060 ++# define CSTOPB 000100 ++# define HUPCL 002000 ++# define PARENB 000400 ++# define PAODD 001000 ++ ++/* The header shall define the following symbolic ++ constants for use as flags in the c_lflag field. The c_lflag field ++ of the argument structure is used to control various terminal ++ functions. */ ++# define ECHO 0000010 ++# define ECHOE 0000020 ++# define ECHOK 0000040 ++# define ECHONL 0000100 ++# define ICANON 0000002 ++# define IEXTEN 0000400 ++# define ISIG 0000001 ++# define NOFLSH 0000200 ++# define TOSTOP 0001000 ++ ++/* XXX implementation-specific */ ++# define _XCGETA (('x'<<8)|1) ++# define _XCSETA (('x'<<8)|2) ++# define _XCSETAW (('x'<<8)|3) ++# define _XCSETAF (('x'<<8)|4) ++# define _TCSBRK (('T'<<8)|5) ++# define _TCFLSH (('T'<<8)|7) ++# define _TCXONC (('T'<<8)|6) ++ ++/* The header shall define the following symbolic ++ constants for use with tcsetattr(): */ ++# define TCSAFLUSH _XCSETAF ++# define TCSANOW _XCSETA ++# define TCSADRAIN _XCSETAW ++# define TCSADFLUSH _XCSETAF /* non-standard */ ++ ++/* The header shall define the following symbolic ++ constants for use with tcflush(): */ ++# define TCIFLUSH 0 ++# define TCOFLUSH 1 ++# define TCIOFLUSH 2 ++ ++/* The header shall define the following symbolic ++ constants for use with tcflow(): */ ++# define TCOOFF 0 ++# define TCOON 1 ++# define TCIOFF 2 ++# define TCION 3 ++ ++/* The header shall define the pid_t type as described in ++ . */ ++/* XXX */ ++ ++/* The following shall be declared as functions and may also be ++ defined as macros. Function prototypes shall be provided. */ ++speed_t cfgetispeed(const struct termios *); ++speed_t cfgetospeed(const struct termios *); ++int cfsetispeed(struct termios *, speed_t); ++int cfsetospeed(struct termios *, speed_t); ++int tcdrain(int); ++int tcflow(int, int); ++int tcflush(int, int); ++int tcgetattr(int, struct termios *); ++/* pid_t tcgetsid(int); XXX */ ++int tcsendbreak(int, int); ++int tcsetattr(int, int, const struct termios *); ++ ++#endif /* _SYS_TERMIOS_H */ ++ +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/sys/uio.h newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/sys/uio.h +--- newlib-1.19.0/newlib/libc/sys/tsvc/sys/uio.h 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/sys/uio.h 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,27 @@ ++/* minimal compliance with IEEE Std 1003.1 ++ http://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/uio.h.html#tag_13_68 */ ++#ifndef _SYS_UIO_H ++#define _SYS_UIO_H ++ ++#include /* FIXME non-compliant. makes symbols from ++ sys/types.h visible */ ++ ++/* The header shall define the iovec structure that ++ includes at least the following members: */ ++struct iovec { ++ void *iov_base; /* Base address of a memory region for input or output. */ ++ size_t iov_len; /* The size of the memory pointed to by iov_base. */ ++}; ++ ++/* The header uses the iovec structure for scatter/gather ++ I/O. */ ++ ++/* The ssize_t and size_t types shall be defined as described in ++ . */ ++ ++/* The following shall be declared as functions and may also be ++ defined as macros. Function prototypes shall be provided. */ ++ssize_t readv(int, const struct iovec *, int); ++ssize_t writev(int, const struct iovec *, int); ++ ++#endif +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/sys/un.h newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/sys/un.h +--- newlib-1.19.0/newlib/libc/sys/tsvc/sys/un.h 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/sys/un.h 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,21 @@ ++/* based on IEEE Std 1003.1-2008 ++ * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_un.h.html ++ */ ++ ++/* The header shall define the sockaddr_un structure, which ++ shall include at least the following members: */ ++struct sockaddr_un { ++ sa_family_t sun_family; /* Address family. */ ++ char sun_path[100]; /* Socket pathname. */ ++}; ++/* The sockaddr_un structure is used to store addresses for UNIX ++ domain sockets. Values of this type shall be cast by applications ++ to struct sockaddr for use with socket functions. */ ++ ++/* The header shall define the sa_family_t type as ++ described in . */ ++#ifndef _SA_FAMILY_T_DECLARED ++typedef __sa_family_t sa_family_t; ++#define _SA_FAMILY_T_DECLARED ++#endif ++ +diff -Naur newlib-1.19.0/newlib/libc/sys/tsvc/termios.c newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/termios.c +--- newlib-1.19.0/newlib/libc/sys/tsvc/termios.c 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0-tee-sdk/newlib/libc/sys/tsvc/termios.c 2013-10-21 15:44:33.000000000 -0400 +@@ -0,0 +1,67 @@ ++#include ++#include ++#include ++ ++speed_t cfgetispeed(const struct termios *termios_p) ++{ ++ return termios_p->c_ispeed; ++} ++speed_t cfgetospeed(const struct termios *termios_p) ++{ ++ return termios_p->c_ospeed; ++} ++ ++int cfsetispeed(struct termios *termios_p, speed_t speed) ++{ ++ termios_p->c_ispeed = speed; ++ return 0; ++} ++ ++int cfsetospeed(struct termios *termios_p, speed_t speed) ++{ ++ termios_p->c_ospeed = speed; ++ return 0; ++} ++ ++int tcdrain(int fd) ++{ ++ errno = ENOSYS; ++ return -1; ++} ++ ++int tcflow(int fd, int action) ++{ ++ errno = ENOSYS; ++ return -1; ++} ++ ++int tcflush(int fd, int queue_selector) ++{ ++ errno = ENOSYS; ++ return -1; ++} ++ ++int tcgetattr(int fd, struct termios *termios_p) ++{ ++ errno = ENOSYS; ++ return -1; ++} ++ ++/* pid_t tcgetsid(int fd) */ ++/* { */ ++/* errno = ENOSYS; */ ++/* return -1; */ ++/* } */ ++ ++int tcsendbreak(int fd, int duration) ++{ ++ errno = ENOSYS; ++ return -1; ++} ++ ++int tcsetattr(int fd, int optional_actions, ++ const struct termios *termios_p) ++{ ++ errno = ENOSYS; ++ return -1; ++} diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/ports/openssl/build.sh b/xmhf-64/hypapps/trustvisor/tee-sdk/ports/openssl/build.sh new file mode 100755 index 0000000000..88aee54f19 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/ports/openssl/build.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +if [ -z "$HOST" ] +then + HOST=i586-tsvc +fi + +if [ -z "$PREFIX" ] +then + PREFIX=/usr/local/$HOST/usr +fi + +if [ -z "$CC" ] +then + CC=${HOST}-cc +fi +export CC + +if [ -z "$RANLIB" ] +then + RANLIB=${HOST}-ranlib +fi +export RANLIB + +if [ -z "$AR" ] +then + AR=${HOST}-ar +fi +export AR + +CFLAGS="-DOPENSSL_NO_DGRAM -DOPENSSL_NO_SOCK -UWINDOWS -UWIN32 -U_WIN32 -DOPENSSL_SYS_LINUX" + +cd openssl-1.0.0d +./Configure tsvc-elf --prefix="$PREFIX" no-threads no-zlib no-shared no-sse2 no-dso no-hw no-asm $CFLAGS +make +sudo make install + diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/ports/openssl/openssl-tee-sdk-131021.patch b/xmhf-64/hypapps/trustvisor/tee-sdk/ports/openssl/openssl-tee-sdk-131021.patch new file mode 100644 index 0000000000..6dcdb07814 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/ports/openssl/openssl-tee-sdk-131021.patch @@ -0,0 +1,346 @@ +diff -Naur openssl-1.0.0d/Configure openssl-1.0.0d-tee-sdk/Configure +--- openssl-1.0.0d/Configure 2010-11-30 17:19:26.000000000 -0500 ++++ openssl-1.0.0d-tee-sdk/Configure 2013-10-21 16:16:49.000000000 -0400 +@@ -331,6 +331,9 @@ + "osf1-alpha-cc", "cc:-std1 -tune host -O4 -readonly_strings::(unknown):::SIXTY_FOUR_BIT_LONG RC4_CHUNK:${alpha_asm}:dlfcn:alpha-osf1-shared:::.so", + "tru64-alpha-cc", "cc:-std1 -tune host -fast -readonly_strings::-pthread:::SIXTY_FOUR_BIT_LONG RC4_CHUNK:${alpha_asm}:dlfcn:alpha-osf1-shared::-msym:.so", + ++# i586-tsvc-elf ++"tsvc-elf", "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT:::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++ + #### + #### Variety of LINUX:-) + #### +diff -Naur openssl-1.0.0d/crypto/asn1/bio_ndef.c openssl-1.0.0d-tee-sdk/crypto/asn1/bio_ndef.c +--- openssl-1.0.0d/crypto/asn1/bio_ndef.c 2008-12-26 10:32:59.000000000 -0500 ++++ openssl-1.0.0d-tee-sdk/crypto/asn1/bio_ndef.c 2013-10-21 16:16:49.000000000 -0400 +@@ -58,7 +58,7 @@ + #include + + #ifndef OPENSSL_SYSNAME_NETWARE +-#include ++/* #include */ + #endif + #include + +diff -Naur openssl-1.0.0d/crypto/bio/bss_dgram.c openssl-1.0.0d-tee-sdk/crypto/bio/bss_dgram.c +--- openssl-1.0.0d/crypto/bio/bss_dgram.c 2011-01-02 20:07:03.000000000 -0500 ++++ openssl-1.0.0d-tee-sdk/crypto/bio/bss_dgram.c 2013-10-21 16:16:49.000000000 -0400 +@@ -810,7 +810,6 @@ + } + return(0); + } +-#endif + + static void get_current_time(struct timeval *t) + { +@@ -828,3 +827,5 @@ + gettimeofday(t, NULL); + #endif + } ++ ++#endif +diff -Naur openssl-1.0.0d/crypto/opensslconf.h openssl-1.0.0d-tee-sdk/crypto/opensslconf.h +--- openssl-1.0.0d/crypto/opensslconf.h 2011-02-08 12:13:20.000000000 -0500 ++++ openssl-1.0.0d-tee-sdk/crypto/opensslconf.h 2013-10-21 16:16:49.000000000 -0400 +@@ -29,6 +29,12 @@ + + #endif /* OPENSSL_DOING_MAKEDEPEND */ + ++#ifndef OPENSSL_NO_ASM ++# define OPENSSL_NO_ASM ++#endif ++#ifndef OPENSSL_NO_HW ++# define OPENSSL_NO_HW ++#endif + #ifndef OPENSSL_NO_DYNAMIC_ENGINE + # define OPENSSL_NO_DYNAMIC_ENGINE + #endif +@@ -68,8 +74,8 @@ + + #if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */ + #if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +-#define ENGINESDIR "/usr/local/ssl/lib/engines" +-#define OPENSSLDIR "/usr/local/ssl" ++#define ENGINESDIR "/user/local/i586-tsvc/usr/lib/engines" ++#define OPENSSLDIR "/user/local/i586-tsvc/usr/ssl" + #endif + #endif + +@@ -121,7 +127,7 @@ + + #if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) + #define CONFIG_HEADER_BN_H +-#undef BN_LLONG ++#define BN_LLONG + + /* Should we define BN_DIV2W here? */ + +@@ -135,7 +141,7 @@ + #define CONFIG_HEADER_RC4_LOCL_H + /* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +-#undef RC4_INDEX ++#define RC4_INDEX + #endif + + #if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +@@ -149,14 +155,14 @@ + /* the following is tweaked from a config script, that is why it is a + * protected undef/define */ + #ifndef DES_PTR +-#undef DES_PTR ++#define DES_PTR + #endif + + /* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependancies at the expense of 2 more + * registers */ + #ifndef DES_RISC1 +-#undef DES_RISC1 ++#define DES_RISC1 + #endif + + #ifndef DES_RISC2 +@@ -170,7 +176,7 @@ + /* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very mucy CPU dependant */ + #ifndef DES_UNROLL +-#undef DES_UNROLL ++#define DES_UNROLL + #endif + + /* These default values were supplied by +diff -Naur openssl-1.0.0d/crypto/pkcs7/bio_pk7.c openssl-1.0.0d-tee-sdk/crypto/pkcs7/bio_pk7.c +--- openssl-1.0.0d/crypto/pkcs7/bio_pk7.c 2008-03-12 17:14:25.000000000 -0400 ++++ openssl-1.0.0d-tee-sdk/crypto/pkcs7/bio_pk7.c 2013-10-21 16:16:49.000000000 -0400 +@@ -57,7 +57,7 @@ + #include + + #ifndef OPENSSL_SYSNAME_NETWARE +-#include ++/* #include */ + #endif + #include + +diff -Naur openssl-1.0.0d/crypto/ui/ui_openssl.c openssl-1.0.0d-tee-sdk/crypto/ui/ui_openssl.c +--- openssl-1.0.0d/crypto/ui/ui_openssl.c 2009-10-04 12:43:21.000000000 -0400 ++++ openssl-1.0.0d-tee-sdk/crypto/ui/ui_openssl.c 2013-10-21 16:16:49.000000000 -0400 +@@ -184,9 +184,9 @@ + # undef SGTTY + #endif + +-#if defined(linux) && !defined(TERMIO) +-# undef TERMIOS +-# define TERMIO ++#if defined(linux) && !defined(TERMIOS) ++# define TERMIOS ++# undef TERMIO + # undef SGTTY + #endif + +@@ -214,6 +214,9 @@ + #undef SGTTY + #endif + ++#undef TERMIO ++#define TERMIOS ++ + #ifdef TERMIOS + # include + # define TTY_STRUCT struct termios +diff -Naur openssl-1.0.0d/include/openssl/opensslconf.h openssl-1.0.0d-tee-sdk/include/openssl/opensslconf.h +--- openssl-1.0.0d/include/openssl/opensslconf.h 2011-02-08 12:13:20.000000000 -0500 ++++ openssl-1.0.0d-tee-sdk/include/openssl/opensslconf.h 2013-10-21 16:16:49.000000000 -0400 +@@ -29,6 +29,12 @@ + + #endif /* OPENSSL_DOING_MAKEDEPEND */ + ++#ifndef OPENSSL_NO_ASM ++# define OPENSSL_NO_ASM ++#endif ++#ifndef OPENSSL_NO_HW ++# define OPENSSL_NO_HW ++#endif + #ifndef OPENSSL_NO_DYNAMIC_ENGINE + # define OPENSSL_NO_DYNAMIC_ENGINE + #endif +@@ -68,8 +74,8 @@ + + #if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */ + #if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +-#define ENGINESDIR "/usr/local/ssl/lib/engines" +-#define OPENSSLDIR "/usr/local/ssl" ++#define ENGINESDIR "/user/local/i586-tsvc/usr/lib/engines" ++#define OPENSSLDIR "/user/local/i586-tsvc/usr/ssl" + #endif + #endif + +@@ -121,7 +127,7 @@ + + #if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) + #define CONFIG_HEADER_BN_H +-#undef BN_LLONG ++#define BN_LLONG + + /* Should we define BN_DIV2W here? */ + +@@ -135,7 +141,7 @@ + #define CONFIG_HEADER_RC4_LOCL_H + /* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +-#undef RC4_INDEX ++#define RC4_INDEX + #endif + + #if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +@@ -149,14 +155,14 @@ + /* the following is tweaked from a config script, that is why it is a + * protected undef/define */ + #ifndef DES_PTR +-#undef DES_PTR ++#define DES_PTR + #endif + + /* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependancies at the expense of 2 more + * registers */ + #ifndef DES_RISC1 +-#undef DES_RISC1 ++#define DES_RISC1 + #endif + + #ifndef DES_RISC2 +@@ -170,7 +176,7 @@ + /* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very mucy CPU dependant */ + #ifndef DES_UNROLL +-#undef DES_UNROLL ++#define DES_UNROLL + #endif + + /* These default values were supplied by +diff -Naur openssl-1.0.0d/Makefile openssl-1.0.0d-tee-sdk/Makefile +--- openssl-1.0.0d/Makefile 2011-02-08 12:13:20.000000000 -0500 ++++ openssl-1.0.0d-tee-sdk/Makefile 2013-10-21 16:16:49.000000000 -0400 +@@ -11,11 +11,11 @@ + SHLIB_VERSION_HISTORY= + SHLIB_MAJOR=1 + SHLIB_MINOR=0.0 +-SHLIB_EXT= +-PLATFORM=dist +-OPTIONS= no-gmp no-jpake no-krb5 no-md2 no-rc5 no-rfc3779 no-shared no-store no-zlib no-zlib-dynamic static-engine +-CONFIGURE_ARGS=dist +-SHLIB_TARGET= ++SHLIB_EXT=.so.$(SHLIB_MAJOR).$(SHLIB_MINOR) ++PLATFORM=tsvc-elf ++OPTIONS=--prefix=/user/local/i586-tsvc/usr -DOPENSSL_NO_DGRAM -DOPENSSL_NO_SOCK -UWINDOWS -UWIN32 -U_WIN32 -DOPENSSL_SYS_LINUX no-asm no-dso no-gmp no-hw no-jpake no-krb5 no-md2 no-rc5 no-rfc3779 no-shared no-sse2 no-store no-threads no-zlib no-zlib-dynamic static-engine ++CONFIGURE_ARGS=tsvc-elf --prefix=/user/local/i586-tsvc/usr no-threads no-zlib no-shared no-sse2 no-dso no-hw no-asm -DOPENSSL_NO_DGRAM -DOPENSSL_NO_SOCK -UWINDOWS -UWIN32 -U_WIN32 -DOPENSSL_SYS_LINUX ++SHLIB_TARGET=linux-shared + + # HERE indicates where this Makefile lives. This can be used to indicate + # where sub-Makefiles are expected to be. Currently has very limited usage, +@@ -26,10 +26,10 @@ + # for, say, /usr/ and yet have everything installed to /tmp/somedir/usr/. + # Normally it is left empty. + INSTALL_PREFIX= +-INSTALLTOP=/usr/local/ssl ++INSTALLTOP=/user/local/i586-tsvc/usr + + # Do not edit this manually. Use Configure --openssldir=DIR do change this! +-OPENSSLDIR=/usr/local/ssl ++OPENSSLDIR=/user/local/i586-tsvc/usr/ssl + + # NO_IDEA - Define to build without the IDEA algorithm + # NO_RC4 - Define to build without the RC4 algorithm +@@ -59,15 +59,15 @@ + # equal 4. + # PKCS1_CHECK - pkcs1 tests. + +-CC= cc +-CFLAG= -O ++CC= i586-tsvc-cc ++CFLAG= -DOPENSSL_NO_DGRAM -DOPENSSL_NO_SOCK -UWINDOWS -UWIN32 -U_WIN32 -DOPENSSL_SYS_LINUX -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall + DEPFLAG= -DOPENSSL_NO_GMP -DOPENSSL_NO_JPAKE -DOPENSSL_NO_MD2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_STORE + PEX_LIBS= + EX_LIBS= + EXE_EXT= + ARFLAGS= +-AR= ar $(ARFLAGS) r +-RANLIB= /usr/bin/ranlib ++AR= i586-tsvc-ar $(ARFLAGS) r ++RANLIB= i586-tsvc-ranlib + NM= nm + PERL= /usr/bin/perl + TAR= tar +@@ -101,7 +101,7 @@ + RMD160_ASM_OBJ= + WP_ASM_OBJ= wp_block.o + CMLL_ENC= camellia.o cmll_misc.o cmll_cbc.o +-PERLASM_SCHEME= ++PERLASM_SCHEME= elf + + # KRB5 stuff + KRB5_INCLUDES= +@@ -111,7 +111,7 @@ + ZLIB_INCLUDE= + LIBZLIB= + +-DIRS= crypto ssl engines apps test tools ++DIRS= crypto ssl engines + ENGDIRS= ccgost + SHLIBDIRS= crypto ssl + +@@ -149,7 +149,7 @@ + SHARED_CRYPTO=libcrypto$(SHLIB_EXT) + SHARED_SSL=libssl$(SHLIB_EXT) + SHARED_LIBS= +-SHARED_LIBS_LINK_EXTS= ++SHARED_LIBS_LINK_EXTS=.so.$(SHLIB_MAJOR) .so + SHARED_LDFLAGS= + + GENERAL= Makefile +@@ -239,7 +239,7 @@ + @[ -n "$(THIS)" ] && $(CLEARENV) && $(MAKE) $(THIS) -e $(BUILDENV) + + sub_all: build_all +-build_all: build_libs build_apps build_tests build_tools ++build_all: build_libs + + build_libs: build_crypto build_ssl build_engines + +diff -Naur openssl-1.0.0d/Makefile.org openssl-1.0.0d-tee-sdk/Makefile.org +--- openssl-1.0.0d/Makefile.org 2010-01-27 11:06:58.000000000 -0500 ++++ openssl-1.0.0d-tee-sdk/Makefile.org 2013-10-21 16:16:49.000000000 -0400 +@@ -109,7 +109,7 @@ + ZLIB_INCLUDE= + LIBZLIB= + +-DIRS= crypto ssl engines apps test tools ++DIRS= crypto ssl engines + ENGDIRS= ccgost + SHLIBDIRS= crypto ssl + +@@ -237,7 +237,7 @@ + @[ -n "$(THIS)" ] && $(CLEARENV) && $(MAKE) $(THIS) -e $(BUILDENV) + + sub_all: build_all +-build_all: build_libs build_apps build_tests build_tools ++build_all: build_libs + + build_libs: build_crypto build_ssl build_engines + +diff -Naur openssl-1.0.0d/tools/c_rehash openssl-1.0.0d-tee-sdk/tools/c_rehash +--- openssl-1.0.0d/tools/c_rehash 2011-02-08 12:13:22.000000000 -0500 ++++ openssl-1.0.0d-tee-sdk/tools/c_rehash 2013-10-21 16:16:49.000000000 -0400 +@@ -6,8 +6,8 @@ + + my $openssl; + +-my $dir = "/usr/local/ssl"; +-my $prefix = "/usr/local/ssl"; ++my $dir = "/user/local/i586-tsvc/usr/ssl"; ++my $prefix = "/user/local/i586-tsvc/usr"; + + if(defined $ENV{OPENSSL}) { + $openssl = $ENV{OPENSSL}; diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/Makefile.in b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/Makefile.in new file mode 100644 index 0000000000..f8a2ec9879 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/Makefile.in @@ -0,0 +1,16 @@ +target_alias=@target_alias@ +INSTALL=@INSTALL@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@ + +UTILS=strip ranlib objdump nm ld as ar cc pkg-config + +all: + +install: + for UTIL in $(UTILS) ; do \ + $(INSTALL) -D $$UTIL $(bindir)/$(target_alias)-$$UTIL ; \ + done + ln -fs $(bindir)/$(target_alias)-cc $(bindir)/$(target_alias)-gcc + diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/ar.in b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/ar.in new file mode 100644 index 0000000000..81dafc923f --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/ar.in @@ -0,0 +1,4 @@ +#!/bin/sh +AR="@AR@" + +exec $AR "$@" diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/as.in b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/as.in new file mode 100644 index 0000000000..22e44f08fd --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/as.in @@ -0,0 +1,3 @@ +#!/bin/sh +AS="@AS@" +exec $AS "$@" diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/autogen.sh b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/autogen.sh new file mode 100755 index 0000000000..66887dab27 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/autogen.sh @@ -0,0 +1,5 @@ +#!/bin/sh +autoreconf --install +automake --add-missing --copy >/dev/null 2>&1 + +exit 0 \ No newline at end of file diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/build-aux/config.sub b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/build-aux/config.sub new file mode 100755 index 0000000000..32cd2be415 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/build-aux/config.sub @@ -0,0 +1,1696 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +# Free Software Foundation, Inc. + +timestamp='2012-03-23' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file 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., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tile*) + basic_machine=tile-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -tsvc*) + os=-tsvc + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/cc.in b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/cc.in new file mode 100644 index 0000000000..17c5e7f247 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/cc.in @@ -0,0 +1,24 @@ +#!/bin/sh +CC="@CC@" +CCINC="@CCINC@" +ARCH="@ARCH@" +OS="@OS@" +prefix="@prefix@" +CFLAGS="@CFLAGS@" +LDFLAGS="@LDFLAGS@" +LDLIBS="@LDLIBS@" + +for ARG in $@ ; do + if [ x"$ARG" = x"-nostdlib" ] || [ x"$ARG" = x"-nodefaultlibs" ] ; then + LDLIBS="" + fi +done + +for ARG in $@ ; do + if [ x"$ARG" = x"-c" ] || [ x"$ARG" = x"-S" ] || [ x"$ARG" = x"-E" ] ; then + LDLIBS="" + LDFLAGS="" + fi +done + +exec $CC $CFLAGS $LDFLAGS "$@" $LDLIBS diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/configure.ac b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/configure.ac new file mode 100644 index 0000000000..93610059f8 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/configure.ac @@ -0,0 +1,93 @@ +AC_INIT([tsvc-toolchain], [0.1]) +AC_CONFIG_AUX_DIR([build-aux]) +AC_CANONICAL_SYSTEM + +AS_IF([test -z ${target}], + target_cpu=i586; + target_os=tsvc; + target="${target_cpu}-${target_os}" + target_alias=$target) +AC_SUBST([target_cpu]) +AC_SUBST([target_os]) +AC_SUBST([target_alias]) + +AS_IF([test -z ${SYSROOT}], + SYSROOT='${prefix}'/${target_alias}) +AC_SUBST([SYSROOT]) + +#AC_SUBST([exec_prefix], [$prefix/$ARCH-$OS/bin]) # wrappers get installed here +#AC_SUBST([datadir]) +#AC_SUBST([libdir]) +#AC_SUBST([includedir]) + +# we want these to be absolute for substitution +# into the wrapper scripts + +AS_IF([test "$host" != "$build"], + [TOOLPREFIX="${host_alias}-"], + [TOOLPREFIX=""]) + +AC_PATH_PROG([AR], [${TOOLPREFIX}ar]) +AC_PATH_PROG([AS], [${TOOLPREFIX}as]) +AC_PATH_PROG([CC], [${TOOLPREFIX}cc]) +AC_PATH_PROG([LD], [${TOOLPREFIX}ld]) +AC_PATH_PROG([NM], [${TOOLPREFIX}nm]) +AC_PATH_PROG([OBJDUMP], [${TOOLPREFIX}objdump]) +AC_PATH_PROG([RANLIB], [${TOOLPREFIX}ranlib]) +AC_PATH_PROG([STRIP], [${TOOLPREFIX}strip]) +AC_PATH_PROG([PKG_CONFIG], [${TOOLPREFIX}pkg-config]) + +AC_SUBST([CCLIB], [`$CC -m32 --print-file-name=`]) + +AC_SUBST([LDFLAGS]) +LDFLAGS="" +LDFLAGS="$LDFLAGS -nostdlib" +LDFLAGS="$LDFLAGS -L"'$prefix'"/$target_alias/usr/local/lib -L"'$prefix'"/$target_alias/usr/lib -L"'$prefix'"/$target_alias/lib" +LDFLAGS="$LDFLAGS -L$CCLIB" + +AC_SUBST([LDLIBS]) +LDLIBS="-lgcc -lc -lnosys" + +AC_SUBST([CCINC], [`$CC --print-file-name=include`]) + +AC_SUBST([CFLAGS]) +CFLAGS="-march=$target_cpu" +CFLAGS="$CFLAGS -nostdinc" # drop default include directories +CFLAGS="$CFLAGS -isystem $CCINC -isystem $CCINC-fixed" # add back compiler-include directories +CFLAGS="$CFLAGS -I"'$prefix'"/$target_alias/usr/local/include -I"'$prefix'"/$target_alias/usr/include -I"'$prefix'"/$target_alias/include" +#CFLAGS="$CFLAGS --sysroot=$prefix" # would replace the above nastiness, but unfortunately ld is not built to support it on ubuntu +CFLAGS="$CFLAGS -fno-jump-tables" # sometimes conflicts with PAL memory protections. may no longer be needed +CFLAGS="$CFLAGS -fno-stack-protector" # stack protector results in unresolved symbols + +case $host_os in + *cygwin* ) CYGWIN=yes;; + * ) CYGWIN=no;; +esac +AS_IF([test "x${CYGWIN}" != "xno"], + # lie to newlib so it doesn't try including cygwin system headers + CFLAGS="$CFLAGS -U__CYGWIN__ -U__CYGWIN32__"; + # ugly hack to pick up __main, allowing cc to compile + # standalone executables, even if they won't run. this is + # helpful to fool autoconf when cross-compiling + LDLIBS="$LDLIBS /usr/lib/libcygwin.a", + ) + +# unfortunately there's no command-line option to the compiler to specify +# which linker to use, in which case we could just point it to our linker +# wrapper that has the appropriate linker flags. Since we can't do that, +# we need to also pass the linker flags to the compiler for when the +# compiler is used as a wrapper to the linker. +#CFLAGS="$CFLAGS $LDFLAGS" + +AC_CHECK_PROG([RM], [rm -f], [rm -f]) +AC_CHECK_PROG([CP], [cp], [cp]) +AC_CHECK_PROG([SED], [sed], [sed]) +AC_CHECK_PROG([CAT], [cat], [cat]) +AC_CHECK_PROG([INSTALL], [install], [install]) + +AC_PROG_INSTALL + +AC_CONFIG_FILES([ + ar as cc ld nm objdump ranlib strip pkg-config Makefile +]) +AC_OUTPUT diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/ld.in b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/ld.in new file mode 100644 index 0000000000..af99caeaee --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/ld.in @@ -0,0 +1,13 @@ +#!/bin/sh +LD="@LD@" +prefix="@prefix@" +LDFLAGS="@LDFLAGS@" +LDLIBS="@LDLIBS@" + +for ARG in $@ ; do + if [ x"$ARG" = x"-nostdlib" ] || [ x"$ARG" = x"-nodefaultlibs" ] ; then + LDLIBS="" + fi +done + +exec $LD $LDFLAGS "$@" $LDLIBS diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/nm.in b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/nm.in new file mode 100644 index 0000000000..f21d6ac84a --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/nm.in @@ -0,0 +1,3 @@ +#!/bin/sh +NM="@NM@" +exec $NM "$@" diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/objdump.in b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/objdump.in new file mode 100644 index 0000000000..8f96e1f84f --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/objdump.in @@ -0,0 +1,3 @@ +#!/bin/sh +OBJDUMP="@OBJDUMP@" +exec $OBJDUMP "$@" diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/pkg-config.in b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/pkg-config.in new file mode 100644 index 0000000000..204bee5cd8 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/pkg-config.in @@ -0,0 +1,10 @@ +#!/bin/sh +prefix=@prefix@ +SYSROOT=@SYSROOT@ +PKG_CONFIG=@PKG_CONFIG@ + +export PKG_CONFIG_PATH= +export PKG_CONFIG_LIBDIR=${SYSROOT}/lib/pkgconfig:${SYSROOT}/usr/local/lib/pkgconfig:${SYSROOT}/usr/local/share/pkgconfig:${SYSROOT}/usr/lib/pkgconfig:${SYSROOT}/usr/share/pkgconfig +export PKG_CONFIG_SYSROOT_DIR= + +exec ${PKG_CONFIG} "$@" diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/ranlib.in b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/ranlib.in new file mode 100644 index 0000000000..8f5ef17bc5 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/ranlib.in @@ -0,0 +1,3 @@ +#!/bin/sh +RANLIB="@RANLIB@" +exec $RANLIB "$@" diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/strip.in b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/strip.in new file mode 100644 index 0000000000..e4304101de --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/toolchain/strip.in @@ -0,0 +1,3 @@ +#!/bin/sh +STRIP="@STRIP@" +exec $STRIP "$@" diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/Makefile.am b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/Makefile.am new file mode 100644 index 0000000000..ab9c1e35d6 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/Makefile.am @@ -0,0 +1,5 @@ +SUBDIRS = src include dev + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = tee-sdk-app.pc tee-sdk-svc.pc +pkgdata_DATA = conf/pal-template.ld conf/pal.mk conf/onepal.mk conf/pkgconfig.mk diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/TrustZone_API_3.0_Specification.pdf b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/TrustZone_API_3.0_Specification.pdf new file mode 100644 index 0000000000..10e721d8e6 Binary files /dev/null and b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/TrustZone_API_3.0_Specification.pdf differ diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/conf/onepal.mk b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/conf/onepal.mk new file mode 100644 index 0000000000..40224ca8f4 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/conf/onepal.mk @@ -0,0 +1,32 @@ +######### generic rules for a program that uses one pal +# must define: PAL_NAME, PAL_OBJS, PROG_NAME, PROG_OBJS +# +# may also define PKGCONFIG_DEPS, PAL_PKGCONFIG_DEPS, CFLAGS, +# PAL_CFLAGS, etc. + +# grab pkgconfig_deps-related flags +CFLAGS+=$(call pkgconfig_cflags, $(PKGCONFIG_DEPS)) +LDLIBS+=$(call pkgconfig_ldlibs, $(PKGCONFIG_DEPS)) +LDFLAGS+=$(call pkgconfig_ldflags, $(PKGCONFIG_DEPS)) + +# PAL target +$(PAL_NAME).pal.o : $(PAL_OBJS) + +# to link against a pal, add depenedencies for the object and linker +# script, and add the linker script to the target's LDLIBS. +$(PROG_NAME) : $(PAL_NAME).pal.o $(PAL_NAME).pal.ld +$(PROG_NAME) : LDLIBS+=-T$(PAL_NAME).pal.ld + +# save objects to be used in recipe, below. +# need this to support multiple inclusion of this file, +# since PROG_OBJS may change, and variables in the recipe are +# evaluated at execution time, not when make reads them +$(PROG_NAME) : OBJS:=$(PROG_OBJS) # need this to support multiple inclusion + +# need to explicitly give recipe to prevent make's default recipe from +# adding the pal linker script and object dependencies to the cmd line. +# The pal's palname.pal.o must *NOT* appear explicitly on the linker cmd line, +# since the linker script already pulls it in. Multiple inclusion will result +# in link failure or subtle errors later. +$(PROG_NAME) : $(PROG_OBJS) + $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS) diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/conf/pal-template.ld b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/conf/pal-template.ld new file mode 100644 index 0000000000..7df46d437b --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/conf/pal-template.ld @@ -0,0 +1,34 @@ +SECTIONS +{ + /* define layout for PAL-related memory sections, + ensuring that they are each page aligned and padded. + */ + .SCODE ALIGN(0x1000): + { + __scode_start = .; + ___scode_start = .; /* accomodate name mangling on windows */ + PAL_NAME.pal.o(.text) + PAL_NAME.pal.o(.scode) /* backwards compat */ + PAL_NAME.pal.o(.SCODE) /* backwards compat */ + PAL_NAME.pal.o(.stext) /* backwards compat */ + PAL_NAME.pal.o(.STEXT) /* backwards compat */ + . = ALIGN(0x1000); + __scode_end = .; + ___scode_end = .; + } =0x90909090 /* fill padding space with no-ops */ + + .SDATA ALIGN(0x1000): + { + __sdata_start = .; + ___sdata_start = .; + PAL_NAME.pal.o(.sdata) /* backwards compat */ + PAL_NAME.pal.o(.SDATA) /* backwards compat */ + PAL_NAME.pal.o(.rodata*) + PAL_NAME.pal.o(.rdata) /* win32 read-only data */ + PAL_NAME.pal.o(.data) + PAL_NAME.pal.o(.bss) + . = ALIGN(0x1000); + __sdata_end = .; + ___sdata_end = .; + } =0x00000000 /* fill padding space with zeros */ +} INSERT AFTER .text; diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/conf/pal.mk b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/conf/pal.mk new file mode 100644 index 0000000000..ccd7b3ce38 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/conf/pal.mk @@ -0,0 +1,36 @@ +# generic pal-building rules. depends on pkgconfig.mk + +OBJCOPY ?= objcopy +NM ?= nm +PAL_CC ?= i586-tsvc-cc +PAL_LD ?= i586-tsvc-ld +PAL_PKG_CONFIG ?= i586-tsvc-pkg-config + +%.pal.o : PKG_CONFIG_PATH = $(PAL_PKG_CONFIG_PATH) +%.pal.o : CC=$(PAL_CC) + +# get flags and libraries specified by pkgconfig +PAL_CFLAGS+=$(call pkgconfig_cflags, $(PAL_PKGCONFIG_DEPS)) +PAL_LDFLAGS+=$(call pkgconfig_ldflags, $(PAL_PKGCONFIG_DEPS)) +PAL_LDLIBS+=$(call pkgconfig_ldlibs, $(PAL_PKGCONFIG_DEPS)) + +# use make's default recipes to build pal object files, but substitute +# in pal-specific flags +%.pal.o : LDLIBS = $(PAL_LDLIBS) +%.pal.o : CFLAGS = $(PAL_CFLAGS) +%.pal.o : LDFLAGS = $(PAL_LDFLAGS) +%.pal.o : PKG_CONFIG = $(PAL_PKG_CONFIG) + +# generate a pal-specific linker script +%.pal.ld : + sed 's/PAL_NAME/$*/g' $(TEESDK_DATA_DIR)/pal-template.ld > $@ + +# create the pal object file. all symbols except for the entry-point +# (which is assumed to match the %) are made private so as not to conflict +# with the regular program's symbols (e.g., so the pal and regular program +# can use different versions of libc) +# -r to create a relocatable output, -d to force allocation of 'common' symbols +%.pal.o: %.o + $(CC) -r -Wl,-d $(LDFLAGS) -o $@ $^ $(LDLIBS) + $(OBJCOPY) -G $(subst -,_,$*) -G _$(subst -,_,$*) $@ + if test `$(NM) -u $@ | wc -l` -ne 0 ; then echo "undefd symbols in $@:"; nm -u $@; rm $@; false; else true; fi diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/conf/pkgconfig.mk b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/conf/pkgconfig.mk new file mode 100644 index 0000000000..c5301b4951 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/conf/pkgconfig.mk @@ -0,0 +1,7 @@ +#### generic pkgconfig helpers +# to be used with $(call pkgconfig_*, $pkgconfig_dependencies) +PKG_CONFIG ?= pkg-config +pkgconfig_cflags = $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --cflags $(1)) +pkgconfig_ldlibs = $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --libs-only-l --static $(1)) +pkgconfig_ldflags =$(filter-out -l%, $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --libs --static $(1))) +#### diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/conf/svc.ld b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/conf/svc.ld new file mode 100644 index 0000000000..85aa95ac17 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/conf/svc.ld @@ -0,0 +1,36 @@ +SECTIONS +{ + /* define layout for PAL-related memory sections, + ensuring that they are each page aligned and padded. + */ + .SCODE ALIGN(0x1000): + { + __scode_start = .; + ___scode_start = .; /* accomodate name mangling on windows */ + *.o(.scode) + . = ALIGN(0x1000); + __scode_end = .; + ___scode_end = .; + } =0x90909090 /* fill padding space with no-ops */ + + .STEXT ALIGN(0x1000): + { + __stext_start = .; + ___stext_start = .; + *(.stext) + . = ALIGN(0x1000); + __stext_end = .; + ___stext_end = .; + } =0x90909090 /* fill padding space with no-ops */ + + .SDATA ALIGN(0x1000): + { + __sdata_start = .; + ___sdata_start = .; + *(.sdata) + . = ALIGN(0x1000); + __sdata_end = .; + ___sdata_end = .; + } =0x00000000 /* fill padding space with zeros */ +} +INSERT AFTER .text; diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/configure.ac b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/configure.ac new file mode 100644 index 0000000000..98c071119e --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/configure.ac @@ -0,0 +1,35 @@ +AC_INIT([tee-sdk], [0.1], [jnewsome@cmu.edu]) +AC_CONFIG_AUX_DIR([build-aux]) +AM_INIT_AUTOMAKE([foreign -Wall -Werror]) +AC_SUBST([CFLAGS], ['-g -O0 -m32']) +AC_PROG_CC +AC_CONFIG_HEADERS([include/config.h]) + +PKG_PROG_PKG_CONFIG +PKG_CHECK_MODULES([TRUSTVISOR], [trustvisor]) + + +# install in-place by default +#AC_PREFIX_DEFAULT([${top_srcdir}/_install]) +#svc_mk=$srcdir/../conf/svc.mk +#AC_SUBST([SVC_LINK_SCRIPT_SRC = $(srcdir)/conf/svc.ld +#AC_DEFUN([SVC_LINK_SCRIPT], [${pkgdatadir}/svc.ld]) +AC_SUBST([datadir]) +AC_SUBST([pkgdatadir], ['${datadir}/AC_PACKAGE_NAME']) +AC_SUBST([SVC_LINK_SCRIPT], ["${pkgdatadir}/svc.ld"]) + +# prevent gcc from compiling switch statements as jump tables. can +# probably get rid of this in the future by somehow ensuring that the +# jump table data is also included in the svc memory areas +#SVC_CFLAGS=-fno-jump-tables +# Not sure whether this is necessary. Carried over from an old makefile +#SVC_CFLAGS+=-fno-stack-protector +# use the designated linker script +#svc_ldflags=-T $(SVC_LINK_SCRIPT) + +AC_CHECK_FUNCS([_aligned_malloc posix_memalign]) + +AC_CHECK_HEADERS([sys/mman.h sys/resource.h windows.h]) +AC_CONFIG_FILES([Makefile src/Makefile include/Makefile dev/Makefile dev/tv/Makefile dev/tv/src/Makefile tee-sdk-app.pc tee-sdk-svc.pc dev/tv/tee-sdk-svc-tv.pc dev/tv/tee-sdk-app-tv.pc dev/tv/include/Makefile dev/null/Makefile dev/null/src/Makefile dev/null/tee-sdk-svc-null.pc]) +AC_PROG_RANLIB +AC_OUTPUT diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/create-deb.sh b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/create-deb.sh new file mode 100644 index 0000000000..9de0b2c9cd --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/create-deb.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +if [ -d .svn ] ; then +SVNREV=`svn info | grep Revision | cut -d ' ' -f 2` +else +SVNREV=`git log --max-count=1 | perl -ne 'if (m/@(.*) /) { print "$1\n"; } '` +fi + +echo "Detected SVN Revision: $SVNREV" + +debuild -us -uc -b + diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/Makefile.am b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/Makefile.am new file mode 100644 index 0000000000..7fb3d8cb25 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = tv null diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/null/Makefile.am b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/null/Makefile.am new file mode 100644 index 0000000000..5e995f9115 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/null/Makefile.am @@ -0,0 +1,4 @@ +SUBDIRS = src + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = tee-sdk-svc-null.pc diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/null/src/Makefile.am b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/null/src/Makefile.am new file mode 100644 index 0000000000..e39dd7c67a --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/null/src/Makefile.am @@ -0,0 +1,6 @@ +# make these libraries are suitable for services to compile against + +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(srcdir)/../include $(TRUSTVISOR_CFLAGS) + +pkglib_LIBRARIES = libsvc-null.a +libsvc_null_a_SOURCES = svcapi.c diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/null/src/svcapi.c b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/null/src/svcapi.c new file mode 100644 index 0000000000..06edd7f176 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/null/src/svcapi.c @@ -0,0 +1,218 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include + + +/* from emhf's processor.h */ +static inline uint64_t rdtsc64(void) +{ +#ifdef __AMD64__ + uint32_t eax, edx; + + __asm__ __volatile__ ("rdtsc" : "=a" (eax), "=d" (edx)); + return ((uint64_t)edx << 32) | eax; +#elif defined(__I386__) + uint64_t rv; + + __asm__ __volatile__ ("rdtsc" : "=A" (rv)); + return (rv); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +} + +int svc_time_elapsed_us(uint64_t *epoch_nonce, /* out */ + uint64_t *us) /* out */ +{ + static uint64_t our_epoch_nonce; + static uint32_t cycles_per_us; + static bool initd=false; + int rv=0; + + /* FIXME: check for constant_tsc. otherwise rdtsc is unreliable */ + + /* initialize epoch nonce */ + if(!initd) { + rv = svc_utpm_rand_block(&our_epoch_nonce, sizeof(our_epoch_nonce)); + if (rv) { + return rv; + } + + cycles_per_us = 2000; /* FIXME - get real cpu frequency */ + + initd=true; + } + + *epoch_nonce = our_epoch_nonce; + /* FIXME : technically ought to serialize with, e.g. cpuid */ + *us = rdtsc64() / cycles_per_us; + + return 0; +} + +int svc_utpm_seal(TPM_PCR_INFO *pcrInfo, + void *in, + size_t in_len, + void *out, + size_t *out_len) +{ + memcpy(out, pcrInfo, sizeof(*pcrInfo)); + memcpy(out+sizeof(*pcrInfo), in, in_len); + *out_len = in_len+sizeof(*pcrInfo); + return 0; +} + +int svc_utpm_unseal(void *in, + size_t in_len, + void *out, + size_t *out_len, + void *digestAtCreation) +{ + TPM_PCR_INFO *info_at_creation = (TPM_PCR_INFO*)in; + + memcpy(digestAtCreation, + &info_at_creation->digestAtCreation, + sizeof(TPM_COMPOSITE_HASH)); + + *out_len = in_len-sizeof(TPM_PCR_INFO); + memcpy(out, in+sizeof(TPM_PCR_INFO), *out_len); + + return 0; +} + +int svc_utpm_quote(TPM_NONCE *nonce, /* in */ + TPM_PCR_SELECTION *tpmsel, /* in */ + uint8_t *sig, + size_t *sigLen, + uint8_t *pcrComposite, + size_t *pcrCompositeLen) +{ + *sigLen=0; + return 0; +} + +int svc_utpm_pcr_extend(uint32_t idx, + uint8_t *meas) +{ + return 0; +} + +int svc_utpm_pcr_read(uint32_t idx, + uint8_t* val) +{ + memset(val, 0, 20); + return 0; +} + +int svc_utpm_id_getpub(uint8_t *N, + size_t *out_len) +{ + return 0; +} + +int svc_utpm_rand(void *out, /* out */ + size_t *out_len) /* in,out */ +{ + memset(out, 0, *out_len); + return 0; +} + +int svc_utpm_rand_block(void *out, /* out */ + size_t out_len) /* in */ +{ + memset(out, 0, out_len); + return 0; +} + +/** + * Semantics for "fake" NVRAM: Persist what is written for the life of + * a service invocation, but do not actually persist to disk. + * + * TODO: Wire it up to the logic currently residing in + * ~hyp/trustvisor/trunk/code/app/hc_utpm.c + */ + +#define FAKE_NVRAM_SIZE 32 +uint8_t g_fake_nvram[FAKE_NVRAM_SIZE]; + +int svc_tpmnvram_getsize(size_t *size) { /* out */ + if(NULL == size) { + return -1; + } + *size = FAKE_NVRAM_SIZE; + + return 0; +} + +int svc_tpmnvram_readall(uint8_t *out) { /* out */ + if(NULL == out) { + return -1; + } + + memcpy(out, g_fake_nvram, FAKE_NVRAM_SIZE); + + return 0; +} + +int svc_tpmnvram_writeall(uint8_t *in) { /* in */ + if(NULL == in) { + return -1; + } + + memcpy(g_fake_nvram, in, FAKE_NVRAM_SIZE); + + return 0; +} + +/* Local Variables: */ +/* mode:c */ +/* indent-tabs-mode:'t */ +/* tab-width:2 */ +/* End: */ diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/null/tee-sdk-svc-null.pc.in b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/null/tee-sdk-svc-null.pc.in new file mode 100644 index 0000000000..bae4db9cd4 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/null/tee-sdk-svc-null.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: tee-sdk-svc-null +Description: used for applications that talk to tee services +Requires: +Version: @PACKAGE_VERSION@ +Libs: -L${libdir}/tee-sdk -lsvc-null +Cflags: -I${includedir} \ No newline at end of file diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/Makefile.am b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/Makefile.am new file mode 100644 index 0000000000..68c5effdf9 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/Makefile.am @@ -0,0 +1,4 @@ +SUBDIRS = src include + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = tee-sdk-app-tv.pc tee-sdk-svc-tv.pc diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/Makefile.old b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/Makefile.old new file mode 100644 index 0000000000..ccb59f3f7a --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/Makefile.old @@ -0,0 +1,28 @@ +include svcmakefile.inc + +# test if we're on a vmx platform. +# FIXME this is brittle, and assumes that the target +# platform and the host platform are the same. +# best solution would be for compiled code to do a runtime check +# so that it will work on both vmx and non-vmx platforms +VMXTEST=$(shell egrep -q '^flags.*\bvmx\b' /proc/cpuinfo ; echo $$?) +ifeq (0, $(VMXTEST)) + IS_VMX=-DIS_VMX +else ifeq (1, $(VMXTEST)) + IS_VMX= +else + $(error "couldn't determine if platform is vmx") +endif + +INCLUDES=-I ./common/ -I ../ +CFLAGS=$(IS_VMX) $(SVC_CFLAGS) -g $(INCLUDES) + +OBJS=common/vmcalls.o + +all: libsvcapi.a + +libsvcapi.a: $(OBJS) + $(AR) rcs $@ $< + +clean: + $(RM) libsvcapi.a $(OBJS) diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/include/Makefile.am b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/include/Makefile.am new file mode 100644 index 0000000000..8a84d544f6 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/include/Makefile.am @@ -0,0 +1 @@ +pkginclude_HEADERS = tv.h diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/include/tv.h b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/include/tv.h new file mode 100644 index 0000000000..01baf12a57 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/include/tv.h @@ -0,0 +1,173 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef TZDEV_TRUSTVISOR_H +#define TZDEV_TRUSTVISOR_H + +#include "svcapi.h" +#include "tz.h" + +#include +#include + +#include + +/* FIXME: copied from paging.h in trustvisor. should use that directly */ +#define PAGE_SIZE 0x1000 +#define PAGE_SIZE_4K (1UL << 12) +#define PAGE_ALIGN_UP_4K(size) (((size) + PAGE_SIZE_4K - 1) & ~(PAGE_SIZE_4K - 1)) +#define PAGE_ALIGN_4K(size) ((size) & ~(PAGE_SIZE_4K - 1)) + +#define PAGE_ALIGNED_4K(size) (PAGE_ALIGN_4K(size) == size) + +typedef void (*pal_fn_t)(uint32_t uiCommand, struct tzi_encode_buffer_t *psInBuf, struct tzi_encode_buffer_t *psOutBuf, tz_return_t *puiRv); + +typedef struct { + struct tv_pal_sections *sPageInfo; + struct tv_pal_params *sParams; + pal_fn_t pEntry; +} tv_service_t; + +typedef struct { + bool userspace_only; +} tv_device_open_options_t; + +/* read (and optionally write) to the memory pages in the specified + * range. use this to make sure pages are present for trustvisor + * (e.g., for pointer parameters before calling a pal function) + */ +/* int scode_touch_range(void *ptr, size_t len, int do_write); */ + +/* convenience function for getting size of a section from end and start symbols */ +size_t tv_ptr_diff(void *end, void *start); + +/* initialize a tv_pal_sections struct, allocating page-aligned memory + * for the parameters and stack. + */ +void tv_pal_sections_init(struct tv_pal_sections *scode_info, + size_t param_sz, + size_t stack_sz); + +/* add a section to an scode_sections_info struct. + * The struct should have already been initialized. + */ +void tv_pal_sections_add(struct tv_pal_sections *scode_info, + int type, + void *start_addr, size_t len); + +/* Print tv_pal_sections_info to stdout */ +void tv_pal_sections_print(struct tv_pal_sections *scode_info); + +/* Register a PAL. + * pageinfo describes the memory areas to be used by the PAL. + * These memory areas must be page-aligned (e.g., 4K-aligned). + * These areas must not be swapped out (use tv_lock_pal_sections) + * params describes the parameters to the PAL function. + * entry is a pointer to the PAL function. + * + * Once a function is registered, any call to that function + * will take place in the secure environment. + * + * Returns 0 on success, nonzero on failure. + */ +int tv_pal_register(const struct tv_pal_sections *pageinfo, + const struct tv_pal_params *params, + const void *entry); + +/* Unregister a PAL. + * entry is a pointer to a function previously registered + * with tv_pal_register + * + * After unregistration, calls to the given function + * no longer take place in the secure environment. + * + * Returns 0 on success, nonzero on failure. + */ +int tv_pal_unregister(void *entry); + +/* share memory ranges with a PAL. + The memory areas must be page-aligned, and must not be swapped out. + (use tv_lock_range and\or tv_touch_range) +*/ +int tv_pal_share(const void *entry, void **start, size_t *len, size_t count); + +/* Test for presence of TrustVisor. + * + * Returns 0 on success, nonzero on failure. + */ +int tv_test(void); + +/** + * Convenience function to load the linked PAL using the TZ + * interfaces, and initialize the tzDevice, tzPalSession, and tzSvcId. + */ +tz_return_t tv_tz_init(tz_device_t* tzDevice, + tz_session_t* tzPalSession, + tz_uuid_t* tzSvcId, + pal_fn_t pal_entry, + size_t param_sz, + size_t stack_sz); + +/** + * Convenience function to gracefully unload the linked PAL using the + * TZ interfaces, and tear down the tzPalSession and tzDevice. + */ +tz_return_t tv_tz_teardown(tz_device_t* tzDevice, + tz_session_t* tzPalSession, + tz_uuid_t* tzSvcId); + + +/* utility functions for locking ranges into memory. useful to call + before and after registration, and before and after sharing + memory */ +int tv_lock_range(void *ptr, size_t len); +int tv_touch_range(void *ptr, size_t len, int do_write); +void tv_lock_pal_sections(const struct tv_pal_sections *scode_info); + +int tv_unlock_range(void *ptr, size_t len); +void tv_unlock_pal_sections(const struct tv_pal_sections *scode_info); + +#endif diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/include/tz_platform.h b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/include/tz_platform.h new file mode 100644 index 0000000000..b817a5fce1 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/include/tz_platform.h @@ -0,0 +1,60 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef TZ_PLATFORM_H +#define TZ_PLATFORM_H + +#include + +/* allocate and free an aligned buffer. + alignment must be a power of 2. + malloc returns NULL on failure. + it is safe to pass NULL to tz_aligned_free. +*/ +void* tz_aligned_malloc(size_t sz, size_t alignment); +void tz_aligned_free(void *p); + +#endif diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/Makefile.am b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/Makefile.am new file mode 100644 index 0000000000..c57fea4276 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/Makefile.am @@ -0,0 +1,9 @@ +# make these libraries are suitable for services to compile against + +AM_CFLAGS = $(SVC_CFLAGS) @TRUSTVISOR_CFLAGS@ + +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(srcdir)/../include + +pkglib_LIBRARIES = libtz-tv.a libsvc-tv.a +libtz_tv_a_SOURCES = app_vmcalls.c scode.c tv.c tz_aligned_malloc.c +libsvc_tv_a_SOURCES = svc_vmcalls.c svc.c diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/app_vmcalls.c b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/app_vmcalls.c new file mode 100644 index 0000000000..dc547b71cf --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/app_vmcalls.c @@ -0,0 +1,256 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include +#include + +#include + +#include "vmcalls.h" +#include "config.h" + +#if HAVE_SYS_MMAN_H +#include +#include +#include +#endif + +#if HAVE_WINDOWS_H +#include +#endif + +#if HAVE_WINDOWS_H +/* mlock always returns an error on cygwin, and get\setrlimit doesn't + support RLIMIT_MEMLOCK. Instead we use the native windows API + VirtualLock. Unfortunately this API only guarantees that the pages + are in physical memory while the process is in physical memory. + Windows may still swap out the whole process. +*/ +int tv_lock_range(void *ptr, size_t len) +{ + SIZE_T dwMin, dwMax; + HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_SET_QUOTA, + FALSE, + GetCurrentProcessId()); + ptr = (void*)PAGE_ALIGN_4K((uintptr_t)ptr); + len = PAGE_ALIGN_UP_4K(len); + + if (!GetProcessWorkingSetSize(hProcess, &dwMin, &dwMax)) { + printf("GetProcessWorkingSetSize failed (%ld)\n", + GetLastError()); + return -1; + } + + if (!SetProcessWorkingSetSize(hProcess, dwMin+len, dwMax+len)) { + printf("GetProcessWorkingSetSize failed (%ld)\n", + GetLastError()); + return -2; + } + + if (!VirtualLock(ptr, len)) { + printf("VirtualLock failed (%ld)\n", + GetLastError()); + return -3; + } + + return 0; +} +#elif HAVE_SYS_MMAN_H +int tv_lock_range(void *ptr, size_t len) +{ + ptr = (void*)PAGE_ALIGN_4K((uintptr_t)ptr); + len = PAGE_ALIGN_UP_4K(len); + + if(!mlock(ptr, len)) { + return 0; + } + + if(errno == ENOMEM) { + /* try increasing soft limit. + * this will only work if this process is privileged + * or if the soft limit is less than the hard limit + */ + struct rlimit memlock_limit; + + if(getrlimit(RLIMIT_MEMLOCK, &memlock_limit)) { + perror("getrlimit"); + return -1; + } + memlock_limit.rlim_cur += len; + if(setrlimit(RLIMIT_MEMLOCK, &memlock_limit)) { + if (!(memlock_limit.rlim_cur > memlock_limit.rlim_max + && errno == EINVAL)) { + perror("setrlimit"); + } + return -2; + } + + /* successfully increased limit. try locking again. */ + if(mlock(ptr, len)) { + perror("mlock"); + return -3; + } + + return 0; + } + + perror("mlock"); + return -4; +} +#else +int tv_lock_range(void *ptr, size_t len) +{ + return -1; +} +#endif + +#if HAS_WINDOWS_H +int tv_unlock_range(void *ptr, size_t len) +{ + return !VirtualUnlock(ptr, len); +} +#elif HAVE_SYS_MMAN_H +int tv_unlock_range(void *ptr, size_t len) +{ + return munlock(ptr, len); +} +#else +int tv_unlock_range(void *ptr, size_t len) +{ + return -1; +} +#endif + +int tv_touch_range(void *ptr, size_t len, int do_write) +{ + int i; + + for(i=0; inum_sections; i++) { + /* first try locking the pages into physical memory */ + if(tv_lock_range((void*)scode_info->sections[i].start_addr, + scode_info->sections[i].page_num*PAGE_SIZE)) { + printf("warning, couldn't lock scode section %d into physical memory\n", i); + printf("getting pages swapped in and hoping for the best...\n"); + } + + /* if tv_lock_range succeeded, + * pages *should* already be in physical memory with + * correct permissions. however, this doesn't seem to be + * the case on windows unless we still go ahead and touch + * them first. + */ + tv_touch_range((void*)scode_info->sections[i].start_addr, + scode_info->sections[i].page_num*PAGE_SIZE, + !(scode_info->sections[i].type == TV_PAL_SECTION_CODE + || scode_info->sections[i].type == TV_PAL_SECTION_SHARED_CODE)); + + } +} +void tv_unlock_pal_sections(const struct tv_pal_sections *scode_info) +{ + int i; + + for(i=0; i < scode_info->num_sections; i++) { + tv_unlock_range((void*)scode_info->sections[i].start_addr, + scode_info->sections[i].page_num*PAGE_SIZE); + } +} + +int tv_pal_register(const struct tv_pal_sections *pageinfo, + const struct tv_pal_params *params, + const void *entry) +{ + int ret; + + return vmcall(TV_HC_REG, + (uint32_t)pageinfo, + 0, + (uint32_t)params, + (uint32_t)entry); +} + +int tv_pal_unregister(void *entry) +{ + int ret; + return vmcall(TV_HC_UNREG, + (uint32_t)entry, + 0, 0, 0); +} + +int tv_pal_share(const void *entry, void **start, size_t *len, size_t count) +{ + int i; + + return vmcall(TV_HC_SHARE, + (uint32_t)entry, + (uint32_t)start, + (uint32_t)len, + (uint32_t)count); +} + +int tv_test(void) +{ + int ret; + return vmcall(TV_HC_TEST, + 0, 0, 0, 0); +} diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/scode.c b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/scode.c new file mode 100644 index 0000000000..bd0fb51ad9 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/scode.c @@ -0,0 +1,240 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include +#include "sections.h" + +#include + +#include + +#include +#include +#include + +#include + +#include + +size_t tv_ptr_diff(void *end, void *start) +{ + return (uintptr_t)end - (uintptr_t)start; +} + +void tv_pal_sections_add(struct tv_pal_sections *scode_info, + int type, + void *start_addr, size_t len) +{ + int sections = scode_info->num_sections; + + assert(sections < TV_MAX_SECTIONS); + + scode_info->sections[sections].type = type; + scode_info->sections[sections].start_addr = (unsigned int)start_addr; + assert((len % PAGE_SIZE) == 0); + scode_info->sections[sections].page_num = len / PAGE_SIZE; + scode_info->num_sections++; +} + +/* FIXME- allocates memory. how to make sure it gets freed? */ +void tv_pal_sections_init(struct tv_pal_sections *scode_info, + size_t param_sz, + size_t stack_sz) +{ + uint8_t *mem = NULL; + uint8_t *param_mem = NULL; + uint8_t *stack_mem = NULL; + + scode_info->num_sections = 0; + + /* add scode section */ + tv_pal_sections_add(scode_info, TV_PAL_SECTION_CODE, &__scode_start, + tv_ptr_diff(&__scode_end, &__scode_start)); + + /* add sdata section */ + if (&__sdata_end != &__sdata_start) { + tv_pal_sections_add(scode_info, TV_PAL_SECTION_DATA, &__sdata_start, + tv_ptr_diff(&__sdata_end, &__sdata_start)); + } + + /* allocate and add scratch memory areas */ + + /* put stack at the lower address, so that overflows won't go into the param + * memory space. We still need a stronger guarantee that nothing is mapped to + * the next lowest page, though (see Issue #67) + */ + param_sz = PAGE_ALIGN_UP_4K(param_sz); + stack_sz = PAGE_ALIGN_UP_4K(stack_sz); + assert(mem = tz_aligned_malloc(param_sz+stack_sz, PAGE_SIZE)); + stack_mem = mem; + param_mem = stack_mem+stack_sz; + + tv_pal_sections_add(scode_info, TV_PAL_SECTION_STACK, stack_mem, stack_sz); + tv_pal_sections_add(scode_info, TV_PAL_SECTION_PARAM, param_mem, param_sz); +} + +void tv_pal_sections_print(struct tv_pal_sections *scode_info) +{ + int i; + printf(".num_sections = %d\n", scode_info->num_sections); + for(i=0; inum_sections; i++) { + printf(".sections[%d].type = %d\n", i, scode_info->sections[i].type); + printf(".sections[%d].start_addr = 0x%08x\n", i, scode_info->sections[i].start_addr); + printf(".sections[%d].page_num = %d\n", i, scode_info->sections[i].page_num); + printf("\n"); + } +} + +tz_return_t tv_tz_init(tz_device_t *tzDevice, + tz_session_t *tzPalSession, + tz_uuid_t *tzSvcId, + pal_fn_t pal_entry, + size_t param_sz, + size_t stack_sz) +{ + struct tv_pal_sections scode_info; + tz_return_t rv = TZ_SUCCESS; + tv_service_t pal = + { + .sPageInfo = &scode_info, + .sParams = NULL, /* soon to be deprecated? */ + .pEntry = pal_entry, + }; + + rv = TZDeviceOpen(NULL, NULL, tzDevice); + if (rv != TZ_SUCCESS) + return rv; + + /* download pal 'service' */ + { + tz_session_t tzManagerSession; + + /* open session with device manager */ + rv = TZManagerOpen(tzDevice, NULL, &tzManagerSession); + if (rv != TZ_SUCCESS) + return rv; + + /* prepare pal descriptor */ + tv_pal_sections_init(&scode_info, + param_sz, stack_sz); + + /* download */ + rv = TZManagerDownloadService(&tzManagerSession, + &pal, + sizeof(pal), + tzSvcId); + if (rv != TZ_SUCCESS) { + TZManagerClose(&tzManagerSession); + return rv; + } + + /* close session */ + rv = TZManagerClose(&tzManagerSession); + if (rv != TZ_SUCCESS) + return rv; + } + + /* now open a service handle to the pal */ + { + tz_operation_t op; + tz_return_t serviceReturn; + rv = TZOperationPrepareOpen(tzDevice, + tzSvcId, + NULL, NULL, + tzPalSession, + &op); + if (rv != TZ_SUCCESS) { + TZDeviceClose(tzDevice); + return rv; + } + + rv = TZOperationPerform(&op, &serviceReturn); + if (rv != TZ_SUCCESS) { + TZOperationRelease(&op); + TZDeviceClose(tzDevice); + return rv; + } + + TZOperationRelease(&op); + } + + return rv; +} + +tz_return_t tv_tz_teardown(tz_device_t *tzDevice, tz_session_t *tzPalSession, tz_uuid_t *tzSvcId) +{ + tz_return_t rv = TZ_SUCCESS; + + /* close session */ + { + tz_operation_t op; + tz_return_t serviceReturn; + + rv = TZOperationPrepareClose(tzPalSession, &op) || rv; + rv = TZOperationPerform(&op, &serviceReturn) || rv; + + TZOperationRelease(&op); + } + + /* unload pal */ + { + tz_session_t tzManagerSession; + + /* open session with device manager */ + rv = TZManagerOpen(tzDevice, NULL, &tzManagerSession) || rv; + + /* unload */ + rv = TZManagerRemoveService(&tzManagerSession, tzSvcId) || rv; + + /* close session */ + rv = TZManagerClose(&tzManagerSession) || rv; + } + + /* close device */ + rv = TZDeviceClose(tzDevice) || rv; + + return rv; +} diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/svc.c b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/svc.c new file mode 100644 index 0000000000..01cb34cb1e --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/svc.c @@ -0,0 +1,113 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include +#include +#include + +/* from emhf's processor.h */ +static inline uint64_t rdtsc64(void) +{ +#ifdef __AMD64__ + uint32_t eax, edx; + + __asm__ __volatile__ ("rdtsc" : "=a" (eax), "=d" (edx)); + return ((uint64_t)edx << 32) | eax; +#elif defined(__I386__) + uint64_t rv; + + __asm__ __volatile__ ("rdtsc" : "=A" (rv)); + return (rv); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +} + +int svc_time_elapsed_us(uint64_t *epoch_nonce, /* out */ + uint64_t *us) /* out */ +{ + static uint64_t our_epoch_nonce; + static uint32_t cycles_per_us; + static bool initd=false; + int rv=0; + + /* FIXME: check for constant_tsc. otherwise rdtsc is unreliable */ + + /* initialize epoch nonce */ + if(!initd) { + rv = svc_utpm_rand_block(&our_epoch_nonce, sizeof(our_epoch_nonce)); + if (rv) { + return rv; + } + + cycles_per_us = 2000; /* FIXME - get real cpu frequency */ + + initd=true; + } + + *epoch_nonce = our_epoch_nonce; + /* FIXME : technically ought to serialize with, e.g. cpuid */ + *us = rdtsc64() / cycles_per_us; + + return 0; +} + +int svc_utpm_rand_block(void *out, /* out */ + size_t out_len) /* in */ +{ + size_t recvd=0; + int rv; + + while (recvd < out_len) { + size_t num=out_len-recvd; + rv = svc_utpm_rand(out+recvd, &num); + if(rv) { + return rv; + } + recvd += num; + } + return 0; +} diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/svc_vmcalls.c b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/svc_vmcalls.c new file mode 100644 index 0000000000..2f1fc0cd18 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/svc_vmcalls.c @@ -0,0 +1,167 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include "vmcalls.h" +#include +#include +#include + +#include +#include + +int svc_utpm_seal(TPM_PCR_INFO *pcrInfo, + void *in, + size_t in_len, + void *out, + size_t *out_len) +{ + unsigned int inbuf1[2]= {(unsigned int)in, (unsigned int)in_len}; + unsigned int outbuf1[2]= {(unsigned int)out, (unsigned int)out_len}; + + return vmcall(TV_HC_UTPM_SEAL, + (uint32_t)inbuf1, + (uint32_t)pcrInfo, + (uint32_t)outbuf1, + 0); +} + +int svc_utpm_unseal(void *in, + size_t in_len, + void *out, + size_t *out_len, + void *digestAtCreation) /* out */ +{ + unsigned int inbuf2[2]= {(unsigned int)in, (unsigned int)in_len}; + unsigned int outbuf2[2]= {(unsigned int)out, (unsigned int)out_len}; + + return vmcall(TV_HC_UTPM_UNSEAL, /* eax */ + (uint32_t)inbuf2, /* ecx */ + (uint32_t)outbuf2, /* edx */ + (uint32_t)digestAtCreation, /* esi */ + 0); /* edi */ +} + +int svc_utpm_quote(TPM_NONCE *nonce, + TPM_PCR_SELECTION *tpmsel, + uint8_t *sig, + size_t *sigLen, + uint8_t *pcrComposite, + size_t *pcrCompositeLen) + +{ + unsigned int sigbuf[2]= {(unsigned int)sig, (unsigned int)sigLen}; + unsigned int pcrCompBuf[2] = {(unsigned int)pcrComposite, (unsigned int)pcrCompositeLen}; + + return vmcall(TV_HC_UTPM_QUOTE, /* eax */ + (uint32_t)tpmsel, /* ecx */ + (uint32_t)sigbuf, /* edx */ + (uint32_t)nonce, /* esi */ + (uint32_t)pcrCompBuf); /* edi */ +} + +int svc_utpm_pcr_extend(uint32_t idx, /* in */ + uint8_t *meas) /* in */ +{ + return vmcall(TV_HC_UTPM_PCREXT, /* eax */ + (uint32_t)idx, /* ecx */ + (uint32_t)meas, /* edx */ + 0, + 0); +} + +int svc_utpm_id_getpub(uint8_t *N, + size_t *out_len) /* out */ +{ + return vmcall(TV_HC_UTPM_ID_GETPUB, + (uint32_t)N, + (uint32_t)out_len, + 0, + 0); +} + +int svc_utpm_pcr_read(uint32_t idx, /* in */ + uint8_t *val) /* out */ +{ + return vmcall(TV_HC_UTPM_PCRREAD, + (uint32_t)idx, + (uint32_t)val, + 0, + 0); +} + +int svc_utpm_rand(void *out, /* out */ + size_t *out_len) /* in,out */ +{ + return vmcall(TV_HC_UTPM_GENRAND, + (uint32_t)out, + (uint32_t)out_len, + 0, + 0); +} + +int svc_tpmnvram_getsize(size_t *size) { /* out */ + return vmcall(TV_HC_TPMNVRAM_GETSIZE, /* eax */ + (uint32_t)size, /* ecx */ + 0, + 0, + 0); +} + +int svc_tpmnvram_readall(uint8_t *out) { /* out */ + return vmcall(TV_HC_TPMNVRAM_READALL, /* eax */ + (uint32_t)out, /* ecx */ + 0, + 0, + 0); +} + +int svc_tpmnvram_writeall(uint8_t *in) { /* in */ + return vmcall(TV_HC_TPMNVRAM_WRITEALL, /* eax */ + (uint32_t)in, /* ecx */ + 0, + 0, + 0); +} diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/tv.c b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/tv.c new file mode 100644 index 0000000000..ea8609cc9e --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/tv.c @@ -0,0 +1,450 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * Author - Jim Newsome (jnewsome@no-fuss.com) + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include + +typedef struct tzi_session_ext_t { + pal_fn_t pFn; +} tzi_session_ext_t; + +typedef struct tzi_operation_open_ext_t { +} tzi_operation_open_ext_t; +typedef struct tzi_operation_invoke_ext_t { + uint32_t uiCommand; +} tzi_operation_invoke_ext_t; +typedef struct tzi_operation_close_ext_t { +} tzi_operation_close_ext_t; + +typedef struct tzi_device_ext_t { + bool userspace_only; +} tzi_device_ext_t; + +/* temporary hard-coded size of marshal buffer */ +#define MARSHAL_BUF_SIZE (1*PAGE_SIZE_4K) + +tz_return_t +TVOperationPrepareOpen(INOUT tz_device_t* psDevice, + IN tz_uuid_t const * pksService, + IN tz_login_t const * pksLogin, + IN tz_timelimit_t const * pksTimeLimit, + OUT tzi_encoded_t **ppsBufData, + OUT uint32_t *puiBufSize, + OUT tzi_session_ext_t** ppsSessionExt, + OUT tzi_operation_open_ext_t** ppsOperationExt) +{ + + /* XXX later we'll point to a page to be re-mapped instead of + copied */ + *puiBufSize = MARSHAL_BUF_SIZE; + *ppsBufData = tz_aligned_malloc( *puiBufSize, PAGE_SIZE_4K); + *ppsSessionExt = malloc(sizeof(tzi_session_ext_t)); + *ppsOperationExt = NULL; + if (*ppsBufData == NULL || *ppsSessionExt == NULL) { + tz_aligned_free( *ppsBufData); + free(*ppsSessionExt); + return TZ_ERROR_MEMORY; + } + + (*ppsSessionExt)->pFn = *((pal_fn_t*)pksService); + + return TZ_SUCCESS; +} + +static int share_referenced_mem(pal_fn_t fn, ll_t* psRefdSubranges, void* psOutBuf, void* psInBuf, bool userspace_only, + void ***addrs, size_t **lens, size_t *count) +{ + tzi_shared_memory_subrange_t *subrange; + int i; + int rv=0; + + *addrs = NULL; + *lens = NULL; + + *count=2; /* psOutBuf and psInBuf */ + LL_FOR_EACH(psRefdSubranges, subrange) { + (*count)++; + } + + *addrs = calloc(*count, sizeof(void*)); + *lens = calloc(*count, sizeof(size_t)); + + (*addrs)[0] = psOutBuf; + (*lens)[0] = MARSHAL_BUF_SIZE; + (*addrs)[1] = psInBuf; + (*lens)[1] = MARSHAL_BUF_SIZE; + + i=2; + LL_FOR_EACH(psRefdSubranges, subrange) { + (*addrs)[i] = subrange->psSharedMem->pBlock + subrange->uiOffset; + (*lens)[i] = subrange->uiLength; + if(!PAGE_ALIGNED_4K((uintptr_t)(*addrs)[i]) || !PAGE_ALIGNED_4K((*lens)[i])) { + printf("Error: TV back-end currently only supports 4K-aligned shared memory subranges\n"); + goto out; + } + i++; + } + + for(i=0; i<*count; i++) { + tv_lock_range((*addrs)[i], (*lens)[i]); + tv_touch_range((*addrs)[i], (*lens)[i], true); + } + + if(!userspace_only) + rv = tv_pal_share(fn, (*addrs), (*lens), *count); + + /* XXX we currently do not enforce the specified permissions- + the service (pal) gets full access */ + + out: + if(rv) { + free(*addrs); + *addrs=NULL; + free(*lens); + *lens=NULL; + } + return rv; +} + +static int unshare_referenced_mem(void **addrs, size_t *lens, size_t count) +{ + int i; + int rv=0; + + for(i=0; isImp.uiOpType) { + case TZI_OPERATION_OPEN: + return TZ_SUCCESS; + break; + case TZI_OPERATION_INVOKE: + { + tzi_operation_invoke_ext_t *psExt = (tzi_operation_invoke_ext_t*)psOperation->sImp.psExt; + pal_fn_t fn = psOperation->sImp.psSession->sImp.psExt->pFn; + uint32_t uiCommand = psExt->uiCommand; + tzi_encode_buffer_t *psInBuf = psOperation->sImp.psEncodeBuffer; + tzi_encode_buffer_t *psOutBuf = NULL; + void **shared_addrs=NULL; + size_t *shared_lens=NULL; + size_t shared_count=0; + + psOutBuf = tz_aligned_malloc( MARSHAL_BUF_SIZE, PAGE_SIZE_4K); + if(psOutBuf == NULL) { + return TZ_ERROR_MEMORY; + } + TZIEncodeBufInit(psOutBuf, MARSHAL_BUF_SIZE); + + TZIEncodeToDecode(psInBuf); + + if (share_referenced_mem(fn, + psOperation->sImp.psRefdSubranges, + psOutBuf, + psInBuf, + psOperation->sImp.psSession->sImp.psDevice->sImp.psExt->userspace_only, + &shared_addrs, + &shared_lens, + &shared_count)) { + return TZ_ERROR_GENERIC; + } + fn(uiCommand, psInBuf, psOutBuf, puiServiceReturn); + unshare_referenced_mem(shared_addrs, shared_lens, shared_count); + + TZIEncodeToDecode(psOutBuf); + + tz_aligned_free(psInBuf); + psOperation->sImp.psEncodeBuffer = psOutBuf; + + if (*puiServiceReturn != TZ_SUCCESS) { + printf("[tee-sdk] Failure in %s (*puiServiceReturn = 0x%08x) in %s:%d\n", + __FUNCTION__, *puiServiceReturn, __FILE__, __LINE__); + return TZ_ERROR_SERVICE; + } + return TZ_SUCCESS; + } + break; + case TZI_OPERATION_CLOSE: + return TZ_SUCCESS; + break; + default: + return TZ_ERROR_NOT_IMPLEMENTED; + } +} + +tz_return_t +TVOperationPrepareInvoke(INOUT tz_session_t* psSession, + uint32_t uiCommand, + IN tz_timelimit_t const * pksTimeLimit, + OUT tzi_encoded_t **ppsBufData, + OUT uint32_t *puiBufSize, + OUT tzi_operation_invoke_ext_t** ppsOperationExt) +{ + /* XXX later we'll point to a page to be re-mapped instead of + copied */ + *puiBufSize = MARSHAL_BUF_SIZE; + *ppsBufData = tz_aligned_malloc( *puiBufSize, PAGE_SIZE_4K); + *ppsOperationExt = malloc(sizeof(tzi_operation_invoke_ext_t)); + if (*ppsBufData == NULL || *ppsOperationExt == NULL) { + tz_aligned_free( *ppsBufData); + free(*ppsOperationExt); + return TZ_ERROR_MEMORY; + } + + (*ppsOperationExt)->uiCommand = uiCommand; + + return TZ_SUCCESS; +} + +tz_return_t +TVOperationPrepareClose(INOUT tz_session_t* psSession, + OUT tzi_operation_close_ext_t** ppsOperationExt) +{ + *ppsOperationExt = NULL; + return TZ_SUCCESS; +} + + +void +TVOperationRelease(INOUT tz_operation_t* psOperation) +{ + free(psOperation->sImp.psExt); + tz_aligned_free( psOperation->sImp.psEncodeBuffer); + return; +} + +tz_return_t +TVDeviceOpen(IN void const *pkDeviceName, + IN void const *pkInit, + OUT tz_device_t *psDevice, + OUT tzi_device_ext_t **psExt) +{ + const tv_device_open_options_t *options; + const tv_device_open_options_t default_options = + (tv_device_open_options_t) { + .userspace_only = false, + }; + if (pkInit) { + options = (const tv_device_open_options_t*)pkInit; + } else { + options = &default_options; + } + + *psExt = malloc(sizeof(tzi_device_ext_t)); + if (!*psExt) { + return TZ_ERROR_MEMORY; + } + + (*psExt)->userspace_only = options->userspace_only; + + assert(!strcmp(pkDeviceName, "trustvisor")); + + return TZ_SUCCESS; +} + +tz_return_t +TVDeviceClose(INOUT tz_device_t *psDevice) +{ + return TZ_SUCCESS; +} + +tz_return_t +TVManagerOpen(INOUT tz_device_t* psDevice, + IN tz_login_t const * pksLogin, + OUT tzi_session_ext_t** psSession) +{ + *psSession = NULL; + return TZ_SUCCESS; +} + +tz_return_t +TVManagerClose(INOUT tz_session_t* psSession) +{ + return TZ_SUCCESS; +} + +tz_return_t +TVManagerDownloadService(INOUT tz_session_t* psSession, + IN uint8_t const * kauiData, + uint32_t uiLength, + OUT tz_uuid_t* psService) +{ + const tv_service_t *svc = (tv_service_t*) kauiData; + int rv; + + struct tv_pal_params params = + { + .num_params = 4, + .params = + { + /* uiCommand */ + {.type = TV_PAL_PM_INTEGER, + .size = sizeof(uint32_t)/sizeof(int)}, + + /* psInBuf. (pass a pointer to a shared region) */ + {.type = TV_PAL_PM_INTEGER, + .size = sizeof(uint32_t)/sizeof(int)}, + + /* psOutBuf */ + {.type = TV_PAL_PM_INTEGER, + .size = sizeof(uint32_t)/sizeof(int)}, + + /* puiRv */ + {.type = TV_PAL_PM_POINTER, + .size = sizeof(uint32_t)/sizeof(int)} + } + }; + + if (!psSession->sImp.psDevice->sImp.psExt->userspace_only) { + tv_lock_pal_sections(svc->sPageInfo); + + rv = tv_pal_register(svc->sPageInfo, + ¶ms, + svc->pEntry); + + if (rv != 0) { + return TZ_ERROR_GENERIC; + } + } + + /* for now we just shove the function ptr into + * the uuid. once we're using proper uuid's we'll + * need to maintain a uuid -> function ptr mapping. + */ + *((pal_fn_t*)psService) = svc->pEntry; + + return TZ_SUCCESS; +} + +tz_return_t +TVManagerRemoveService(INOUT tz_session_t* psSession, + IN tz_uuid_t const * pksService) +{ + if (!psSession->sImp.psDevice->sImp.psExt->userspace_only) { + /* FIXME- need to make sure there's no open sessions */ + if(tv_pal_unregister(*((pal_fn_t*)(pksService))) != 0) + return TZ_ERROR_GENERIC; + } + + return TZ_SUCCESS; +} + +tz_return_t TVsharedMemoryAllocate(INOUT tz_session_t* psSession, + INOUT tz_shared_memory_t* psSharedMem) +{ + if ( !( psSharedMem->pBlock = tz_aligned_malloc( PAGE_ALIGN_UP_4K( psSharedMem->uiLength), + PAGE_SIZE_4K))) { + return TZ_ERROR_MEMORY; + } + return TZ_SUCCESS; +} + +tz_return_t TVsharedMemoryRegister(INOUT tz_session_t* psSession, + INOUT tz_shared_memory_t* psSharedMem) +{ + if (!PAGE_ALIGNED_4K((uintptr_t)psSharedMem->pBlock) + || !PAGE_ALIGNED_4K(psSharedMem->uiLength)) { + /* we only handle aligned regions right now */ + return TZ_ERROR_ILLEGAL_ARGUMENT; + } else { + return TZ_SUCCESS; + } +} + +void TVsharedMemoryRelease(INOUT tz_shared_memory_t* psSharedMem) +{ + if(psSharedMem->sImp.bAllocated) { + tz_aligned_free( psSharedMem->pBlock); + } + psSharedMem->pBlock=NULL; + return; +} + +static tzi_device_cb_block_t tv_cb_block = + { &TVDeviceOpen, + &TVDeviceClose, + &TVManagerOpen, + &TVManagerClose, + &TVManagerDownloadService, + &TVManagerRemoveService, + &TVOperationPrepareOpen, + &TVOperationPrepareInvoke, + &TVOperationPrepareClose, + &TVOperationPerform, + &TVOperationRelease, + &TVsharedMemoryAllocate, + &TVsharedMemoryRegister, + &TVsharedMemoryRelease, + }; + +void TVregister() +{ + TZIDeviceRegister("trustvisor", &tv_cb_block); +} diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/tz_aligned_malloc.c b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/tz_aligned_malloc.c new file mode 100644 index 0000000000..60f21126d8 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/tz_aligned_malloc.c @@ -0,0 +1,92 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include +#include + +#if defined HAVE__ALIGNED_MALLOC + +#define __MSVCRT_VERSION__ 0x0700 /* minimum API version for _aligned_malloc */ +#include + +void* tz_aligned_malloc(size_t sz, size_t alignment) +{ + if (sz==0) { + return NULL; + } + return _aligned_malloc(sz, alignment); +} + +void tz_aligned_free(void *p) +{ + if (p) { + _aligned_free(p); + } +} + +#elif defined HAVE_POSIX_MEMALIGN + +#include + +void* tz_aligned_malloc(size_t sz, size_t alignment) +{ + void *rv; + int err; + + err = posix_memalign(&rv, alignment, sz); + if (err) { + rv=NULL; + } + + return rv; +} + +void tz_aligned_free(void *p) +{ + free(p); +} + +#endif diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/vmcalls.h b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/vmcalls.h new file mode 100644 index 0000000000..439abbca6d --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/src/vmcalls.h @@ -0,0 +1,119 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef VMCALLS_H +#define VMCALLS_H + +#include +#include + +/* XXX ripped from emhf's processor.h. use it directly? */ + +#define CPU_VENDOR_INTEL 0xAB +#define CPU_VENDOR_AMD 0xCD +#define CPU_VENDOR_UNKNOWN 0x00 + +#define AMD_STRING_DWORD1 0x68747541 +#define AMD_STRING_DWORD2 0x69746E65 +#define AMD_STRING_DWORD3 0x444D4163 + +#define INTEL_STRING_DWORD1 0x756E6547 +#define INTEL_STRING_DWORD2 0x49656E69 +#define INTEL_STRING_DWORD3 0x6C65746E + +#define cpuid(op, eax, ebx, ecx, edx) \ +({ \ + __asm__ __volatile__("cpuid" \ + :"=a"(*(eax)), "=b"(*(ebx)), "=c"(*(ecx)), "=d"(*(edx)) \ + :"0"(op), "2" (0)); \ +}) + +static inline uint32_t get_cpu_vendor(void) { + uint32_t dummy; + uint32_t vendor_dword1, vendor_dword2, vendor_dword3; + + cpuid(0, &dummy, &vendor_dword1, &vendor_dword3, &vendor_dword2); + if(vendor_dword1 == AMD_STRING_DWORD1 && vendor_dword2 == AMD_STRING_DWORD2 + && vendor_dword3 == AMD_STRING_DWORD3) + return CPU_VENDOR_AMD; + else if(vendor_dword1 == INTEL_STRING_DWORD1 && vendor_dword2 == INTEL_STRING_DWORD2 + && vendor_dword3 == INTEL_STRING_DWORD3) + return CPU_VENDOR_INTEL; + else + return CPU_VENDOR_UNKNOWN; + + return 0; /* never reached */ +} +/* XXX end processor.h */ + +static inline int vmcall(uint32_t eax, uint32_t ecx, uint32_t edx, + uint32_t esi, uint32_t edi) +{ + /* FIXME - should use a static bool to cache result. + However, this is tricky since we need to store in different + locations depending if we're executing inside a pal or not. */ + switch(get_cpu_vendor()) { + case CPU_VENDOR_INTEL: + __asm__ __volatile__( + "vmcall\n\t" + :"=a"(eax) + : "a"(eax), "c"(ecx), "d"(edx), + "S"(esi), "D"(edi)); + break; + case CPU_VENDOR_AMD: + __asm__ __volatile__( + "vmmcall\n\t" + :"=a"(eax) + : "a"(eax), "c"(ecx), "d"(edx), + "S"(esi), "D"(edi)); + break; + default: + eax = -1; + } + return eax; +} + +#endif diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/tee-sdk-app-tv.pc.in b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/tee-sdk-app-tv.pc.in new file mode 100644 index 0000000000..71f4dc2411 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/tee-sdk-app-tv.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: tee-sdk-app-tv +Description: used for applications that talk to tee services +Requires: trustvisor +Version: @PACKAGE_VERSION@ +Libs: -L${libdir}/tee-sdk -ltz-tv +Cflags: -I${includedir} \ No newline at end of file diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/tee-sdk-svc-tv.pc.in b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/tee-sdk-svc-tv.pc.in new file mode 100644 index 0000000000..48c5fe9441 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/dev/tv/tee-sdk-svc-tv.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: tee-sdk-svc-tv +Description: used for applications that talk to tee services +Requires: +Version: @PACKAGE_VERSION@ +Libs: -L${libdir}/tee-sdk -lsvc-tv +Cflags: -I${includedir} \ No newline at end of file diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/Makefile.am b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/Makefile.am new file mode 100644 index 0000000000..aee41056d2 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/Makefile.am @@ -0,0 +1 @@ +pkginclude_HEADERS = tz.h tze.h tzmarshal.h svcapi.h sections.h diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/list.h b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/list.h new file mode 100644 index 0000000000..c30ba4e0cc --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/list.h @@ -0,0 +1,142 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef LIST_H +#define LIST_H + +/* loosely based on ch 7 of "C Interfaces and Implementations" by + David Hanson */ + +typedef struct ll_t { + void *first; + struct ll_t *rest; +} ll_t; + +__attribute__((unused)) +static void* LL_first(ll_t *list) +{ + return list->first; +} + +__attribute__((unused)) +static ll_t* LL_rest(ll_t *list) +{ + return list->rest; +} + +/* note- allocates memory. will return null if allocation fails */ +__attribute__((unused)) +static ll_t* LL_push(ll_t *list, void *first) +{ + ll_t *rv = malloc(sizeof(ll_t)); + if (rv != NULL) { + *rv = (ll_t) { + .first = first, + .rest = list + }; + } + + return rv; +} + +/* destructive push. rewrite the list ptr to pt to the new head */ +__attribute__((unused)) +static ll_t* LL_dpush(ll_t **list, void *first) +{ + *list = LL_push(*list, first); + return *list; +} + +__attribute__((unused)) +static ll_t* LL_pop(ll_t *list, void **x) +{ + ll_t *rest = NULL; + + if(list) { + rest = list->rest; + if (x) { + *x = list->first; + } + free(list); + } + + return rest; +} + +/* frees the list structure itself, not the items in it */ +__attribute__((unused)) +static void LL_free(ll_t *list) +{ + while (list != NULL) { + list = LL_pop(list, NULL); + } +} + +/* for loop. on each iteration x is set to the current head item, l is set to the current tail */ +#define LL_FOR_EACH(l, x) for((x) = ((l) == NULL) ? NULL : (l)->first ; (l) != NULL ; (l) = (l)->rest, (x) = (l) == NULL ? NULL : (l)->first) + +/* note that ptr is compared directly, not dereferenced. */ +static void LL_dremove(ll_t **list, void *x) +{ + ll_t *prev = NULL; + ll_t *curr = *list; + void *y; + + LL_FOR_EACH(curr, y) { + if (y == x) { + if (prev != NULL) { + prev->rest = curr->rest; + } else { + *list = curr->rest; + } + free(curr); + return; + } + prev = curr; + } +} + +#endif diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/missing.h b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/missing.h new file mode 100644 index 0000000000..42e0d0d053 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/missing.h @@ -0,0 +1,54 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef MISSING_H +#define MISSING_H + +#ifndef HAVE_POSIX_MEMALIGN +int posix_memalign(void **memptr, size_t alignment, size_t size); +#endif + +#endif diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/sections.h b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/sections.h new file mode 100644 index 0000000000..b2244a9ae9 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/sections.h @@ -0,0 +1,59 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef SECTIONS_H +#define SECTIONS_H + +/* The linker script ensures that these symbols point to beginnings + * and ends of the named sections. The _end symbols point to the address + * after the last byte of the section. e.g., the size of a section is + * __SECTIONNAME_end - __SECTIONNAME_start + */ +extern unsigned int __scode_start, __scode_end; +extern unsigned int __stext_start, __stext_end; +extern unsigned int __sdata_start, __sdata_end; + +#endif diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/svcapi.h b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/svcapi.h new file mode 100644 index 0000000000..beec609569 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/svcapi.h @@ -0,0 +1,195 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef SVCAPI_H +#define SVCAPI_H + +#include +#include + +#include + +/* typedef void (*svc_fn_t)(uint32_t uiCommand, */ +/* tzi_encode_buffer_t *psInBuf, */ +/* tzi_encode_buffer_t *psOutBuf, */ +/* tz_return_t *puiRv); */ + +/* return micro-seconds elapsed from the beginning of the current + * epoch. when calculating a time interval from t0 to t1, the caller + * must check that epoch_nonce is identical for both calls. Otherwise + * the two times are not comparable. This could occur, for example, + * after a reboot for trusted execution environments without a + * trustworthy absolute time source. + * + * epoch_nonce : a unique identifier for the current epoch + * us : microseconds elapsed since the current epoch + */ +int svc_time_elapsed_us(uint64_t *epoch_nonce, /* out */ + uint64_t *us); /* out */ + +/* Seal data, optionally controlled by PCR values. + * pcrInfo points to a TPM_PCR_INFO struct. + * in_len is the size of the data to be sealed, in bytes + * out is a pointer at which the sealed data will be stored + * out_len will be set to the length of the sealed data + * FIXME: this is currently output only. TV does not check + * that the destination is large enough. + * + * Returns 0 on success, nonzero on failure. + */ +int svc_utpm_seal(TPM_PCR_INFO *pcrInfo, + void *in, + size_t in_len, + void *out, + size_t *out_len); + +/* unseal data + * in is a pointer to the data to be unsealed. + * in_len is the size of the sealed data, in bytes + * out is a pointer at which the unsealed data will be stored + * out_len will be set to the length of the unsealed data + * FIXME: this is currently output only. TV does not check + * that the destination is large enough. + * + * Returns 0 on success, nonzero on failure. + */ +int svc_utpm_unseal(void *in, + size_t in_len, + void *out, + size_t *out_len, + void *digestAtCreation); + +/* generate a TPM quote (FIXME of...?) + * nonce points to a nonce to be used FIXME: size? + * tpmsel FIXME what is this? + * out the quote is written here + * out_len the length of out is written here. + * FIXME: output only? + * + * Returns 0 on success, nonzero on failure. + */ +int svc_utpm_quote(TPM_NONCE *nonce, /* in */ + TPM_PCR_SELECTION *tpmsel, /* in */ + uint8_t *sig, + size_t *sigLen, + uint8_t *pcrComposite, + size_t *pcrCompositeLen); + +/* Extend uTPM PCR 'idx' with new measurement 'meas'. + * 'meas' is assumed to be exactly 20 bytes. + * + * Returns 0 on success, nonzero on failure. + */ +int svc_utpm_pcr_extend(uint32_t idx, /* in */ + uint8_t *meas); /* in */ + +/* Read the value of uTPM PCR 'idx' + * 'val' is assumed to point to 20 bytes of + * available space. + * + * Returns 0 on success, nonzero on failure. + */ +int svc_utpm_pcr_read(uint32_t idx, /* in */ + uint8_t* val); /* out */ + + +/* Read the RSA public key modulus that corresponds to the TrustVisor + * uTPM identity keypair that is used to sign quotes. + * + * Returns 0 on success, nonzero on failure. + */ +int svc_utpm_id_getpub(uint8_t *N, /* out */ + size_t *out_len /* in, out*/ ); + +/* Request out_len secure-random bytes. The TEE will use some secure + * source of true entropy, either directly, or to seed a secure PRNG. + * The TEE may return fewer than the requested number of bytes if + * insufficient entropy is currently available. + * + * out : random bytes + * out_len : in: the number of requested bytes, + * out: the number of provided bytes + */ +int svc_utpm_rand(void *out, /* out */ + size_t *out_len); /* in,out */ + +/* Request out_len secure-random bytes. The TEE will use some secure + * source of true entropy, either directly, or to seed a secure PRNG. + * The TEE will block to get more entropy if necessary. + * + * out : random bytes + * out_len : the number of requested bytes, + */ +int svc_utpm_rand_block(void *out, /* out */ + size_t out_len); /* in */ + +/* Get the size of the TrustVisor-internal Hardware TPM NVRAM space + * dedicated to providing rollback resistance for a privileged NV + * Multiplexor PAL (NvMuxPal). + * + * size : the number of bytes that fit in the relevant NVRAM index. + */ +int svc_tpmnvram_getsize(size_t *size); /* out */ + +/* Get the bytes stored in the TrustVisor-internal Hardware TPM NVRAM + * space dedicated to providing rollback resistance for a privileged + * NV Multiplexor PAL (NvMuxPal). + * + * out : a buffer to hold the contents from NVRAM; had better be big + * enough. + */ +int svc_tpmnvram_readall(uint8_t *out); /* out */ + +/* Write the provided bytes into the TrustVisor-internal Hardware TPM NVRAM + * space dedicated to providing rollback resistance for a privileged + * NV Multiplexor PAL (NvMuxPal). + * + * in : a buffer holding the data to write into NVRAM; had better be + * big enough. + */ +int svc_tpmnvram_writeall(uint8_t *in); /* in */ + +#endif diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/tz.h b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/tz.h new file mode 100644 index 0000000000..a9c548ba5f --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/tz.h @@ -0,0 +1,570 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + + +/* + * Author - Jim Newsome (jnewsome@no-fuss.com) + */ + +#ifndef TZ_H +#define TZ_H + +#include +#include +#include +#include +#include + +/* implementation features. + * define iff the implementation implements the corresponding feature. + * [TZS] 5.5.1 + */ +#define TZ_BUILD_RUNTIME_SERVICE_CONTROL +#undef TZ_BUILD_ASYNCHRONOUS +#undef TZ_BUILD_MULTITHREADS + +/* 5.3.1 */ +typedef uint32_t tz_return_t; + +/* 5.3.2 */ +typedef uint32_t tz_state_t; + +/* 5.3.3 */ +typedef struct +{ + uint32_t uiTimeLow; + uint16_t uiTimeMid; + uint16_t uiTimeHiAndVersion; + uint8_t auiClockSeqAndNode[8]; +} tz_uuid_t; + +/* 5.3.4 */ +typedef struct +{ + uint32_t uiType; + void *pBuff; + uint32_t uiBuffLen; +} tz_login_t; + +/* 5.3.5 */ +typedef struct tz_property_t +{ + uint32_t uiNamespace; + uint32_t uiName; + void *pValue; + uint32_t uiLength; +} tz_property_t; + +/* 5.3.6 */ +typedef struct tz_property_name_t +{ + uint32_t uiNamespace; + uint32_t uiName; +} tz_property_name_t; + +/* 5.4.1 */ +typedef struct tz_timelimit_t +{ + /* Implementation-defined. */ +} tz_timelimit_t; + +typedef struct tzi_device_cb_block_t { + tz_return_t (*deviceOpen)(); + tz_return_t (*deviceClose)(); + tz_return_t (*managerOpen)(); + tz_return_t (*managerClose)(); + tz_return_t (*downloadService)(); + tz_return_t (*removeService)(); + tz_return_t (*operationPrepareOpen)(); + tz_return_t (*operationPrepareInvoke)(); + tz_return_t (*operationPrepareClose)(); + tz_return_t (*operationPerform)(); + void (*operationRelease)(); + tz_return_t (*sharedMemoryAllocate)(); + tz_return_t (*sharedMemoryRegister)(); + void (*sharedMemoryRelease)(); +} tzi_device_cb_block_t; + +typedef struct tzi_device_registry_entry_t { + const char* name; + tzi_device_cb_block_t* cbb; +} tzi_device_registry_entry_t; + +/* 5.4.2 */ +typedef struct tz_device_t +{ + tz_state_t uiState; + struct + { + /* Implementation-defined. */ + const tzi_device_cb_block_t *cbb; + struct tzi_device_ext_t* psExt; + uint32_t uiSessionCount; + } sImp; +} tz_device_t; + +/* 5.4.3 */ +typedef struct tz_session_t +{ + tz_state_t uiState; + struct + { + /* Implementation-defined. */ + tz_device_t* psDevice; + uint32_t uiOpenOps; + uint32_t uiOpenSharedMem; + bool bManagerSession; + struct tzi_session_ext_t* psExt; + } sImp; +} tz_session_t; + +typedef enum { + TZI_OPERATION_OPEN, + TZI_OPERATION_INVOKE, + TZI_OPERATION_CLOSE, +} tzi_operation_t; + +/* used to keep track of referenced memory ranges in a + tz_shared_memory_t */ +typedef struct tzi_shared_memory_subrange_t +{ + struct tz_shared_memory_t *psSharedMem; + uint32_t uiOffset; + uint32_t uiLength; + uint32_t uiFlags; + uint32_t uiEncodeOffset; +} tzi_shared_memory_subrange_t; + +/* 5.4.4 */ +typedef struct tz_operation_t +{ + tz_state_t uiState; + struct + { + /* Implementation-defined. */ + tz_session_t *psSession; + tzi_operation_t uiOpType; + struct tzi_encode_buffer_t *psEncodeBuffer; + struct tzi_operation_ext_t* psExt; + struct ll_t* psRefdSubranges; + } sImp; +} tz_operation_t; + +/* 5.4.5 */ +typedef struct tz_shared_memory_t +{ + tz_state_t uiState; + uint32_t uiLength; + uint32_t uiFlags; + void* pBlock; + struct + { + /* Implementation-defined. */ + tz_session_t *psSession; + struct ll_t* psRefdOperations; + bool bAllocated; /* true if initd through TZSharedMemoryAllocate */ + } sImp; +} tz_shared_memory_t; + + +/* [TZS] 5.5.2 */ +enum { + TZ_SUCCESS, /* The operation succeeded. */ + TZ_PENDING, /* The asynchronous operation is still pending. */ + TZ_ERROR_ACCESS_DENIED, /* Access has been denied, + or the item cannot be found. */ + TZ_ERROR_BUSY, /* The system is busy. */ + TZ_ERROR_CANCEL, /* The execution was cancelled. */ + TZ_ERROR_COMMUNICATION, /* There is a system communication error. */ + TZ_ERROR_DECODE_NO_DATA, /* The decoder ran out of data. */ + TZ_ERROR_DECODE_TYPE, /* The decoder hit a type error. */ + TZ_ERROR_ENCODE_FORMAT, /* The encoded data is of a bad format. + This generally applies to incorrectly specified + memory references. */ + TZ_ERROR_ENCODE_MEMORY, /* The encoder ran out of memory. */ + TZ_ERROR_GENERIC, /* An unspecified error has occurred. */ + TZ_ERROR_ILLEGAL_ARGUMENT, /* A bad parameter has been specified. */ + TZ_ERROR_ILLEGAL_STATE, /* A state machine has been violated. */ + TZ_ERROR_MEMORY, /* There is not enough memory to perform the operation. */ + TZ_ERROR_NOT_IMPLEMENTED, /* The functionality is not implemented. */ + TZ_ERROR_SECURITY, /* There is a security error. */ + TZ_ERROR_SERVICE, /* The service has returned an error in the service + return code variable. */ + TZ_ERROR_SHORT_BUFFER, /* The input buffer is not long enough. */ + TZ_ERROR_UNDEFINED, /* The implementation has reached an + UNDEFINED condition. */ +}; + +/* [TZS] 5.5.3 */ +enum { + TZ_STATE_UNDEFINED=0, /* Structures in the UNDEFINED state may have + any value for their state constant; it may + not exist as an explicit value. Clients + should never make use of this constant, + although an implementation may use it + internally for debugging purposes. */ + TZ_STATE_INVALID, /* The state is in a safe invalid state. */ + TZ_STATE_OPEN, /* The state is open. */ + TZ_STATE_CLOSING, /* The state is closing, but not yet closed. */ + TZ_STATE_ENCODE, /* The state an operation that is not running and + can accept data to be encoded. */ + TZ_STATE_PERFORMABLE, /* The state of an operation that is not + running, but which cannot accept data to be + encoded. This state applies only to close + operations. */ + TZ_STATE_RUNNING, /* The state of an operation that is executing + synchronously. */ + TZ_STATE_RUNNING_ASYNC, /* The state of an operation that is + executing asynchronously. */ + TZ_STATE_DECODE, /* The state of an operation that can have data + read using the decoder functions. */ +}; + +/* [TZS] 5.5.4 */ +/* FIXME: should these be an enum? or literal tz_property_t's, or...? */ +#if 0 +TZ_PROPERTY_SVC_UUID /* The UUID of the service, provided as an array + uint8_t values of length 16. The array is not + zero-terminated. */ +TZ_PROPERTY_SVC_NAME /* The human-readable name of the service, + provided as an array of uint8_t values of + variable length. The array is + zero-terminated. */ +TZ_PROPERTY_SVC_VENDOR /* The human-readable name of the service + vendor, provided as an array of uint8_t + values of variable length. The array is + zero- terminated. */ +#endif + +/* [TZS] 5.5.4.1 Property namespaces */ +enum { + TZ_NAMESPACE_SYSTEM, /* This namespace is used for all system + properties returned by the TZSystem + functions. */ + TZ_NAMESPACE_SERVICE, /* This namespace is used for general service + properties. */ + TZ_NAMESPACE_CLIENT, /* This namespace is reserved for client + properties and should not need to be used by + a client using this API. */ + TZ_NAMESPACE_CONFIG, /* This namespace is reserved for private + configuration properties which are not + exposed to the client. */ +}; + +/* [TZS] 5.5.5 System properties */ +#if 0 +/* TZ_PROPERTY_SYS_API_VERSION The version number of the API. This property’s value is a */ +/* single uint32_t. The top 16 bits of the value are the */ +/* major version, the bottom 16 bits are minor version. */ +/* The value for this version of the specification will be */ +/* 0x00030000. */ +/* TZ_PROPERTY_SYS_MEMORY_ALIGN The shared memory alignment constraints on memory */ +/* references required for efficient memory coherency with */ +/* hardware devices. This property’s value is a single */ +/* uint32_t. */ +/* Value is implementation-defined. */ +#endif + +/* 5.5.6 Login flags */ +#if 0 +/* TZ_LOGIN_PUBLIC No login is to be used. */ +/* TZ_LOGIN_CLIENT_DATA A buffer of client data is to be provided. */ +/* TZ_LOGIN_USER The user executing the application is provided. */ +/* TZ_LOGIN_GROUP The user group executing the application is provided. */ +/* TZ_LOGIN_NAME The name of the application is provided; may include path */ +/* information. */ +/* TZ_LOGIN_DIGEST The digest of the client application is provided. */ +/* TZ_LOGIN_ALL A utility constant indicating all available login types should be used. */ +#endif + +#define TZ_MEM_SERVICE_RO (1<<0) /* Service can only read from the memory block. */ +#define TZ_MEM_SERVICE_WO (1<<1) /* Service can only write from the memory block. */ +#define TZ_MEM_SERVICE_RW (TZ_MEM_SERVICE_RO | TZ_MEM_SERVICE_WO) /* Service can read and write from the memory block. */ + +/* 5.5.8 Decode data types */ +enum { + TZ_TYPE_NONE, /* There is no more data in the decode stream. */ + TZ_TYPE_UINT32, /* The next data type in the stream is a uint32_t. */ + TZ_TYPE_ARRAY, /* The next data type in the stream is an array. */ +}; + +/* no-op macros for documentation */ +#define IN +#define OUT +#define INOUT + +/* used by device back-ends to register themselves */ +tz_return_t TZIDeviceRegister(const char *name, tzi_device_cb_block_t* cbb); + +/* 6.1.1 TZDeviceOpen */ +tz_return_t +TZDeviceOpen(IN void const *pkDeviceName, + IN void const *pkInit, + OUT tz_device_t *psDevice); + +/* 6.1.2 TZDeviceClose */ +tz_return_t +TZDeviceClose(INOUT tz_device_t *psDevice); + +/* 6.1.3 TZDeviceGetTimeLimit */ +tz_return_t +TZDeviceGetTimeLimit(INOUT tz_device_t * psDevice, + uint32_t uiTimeout, + OUT tz_timelimit_t * psTimeLimit); + +/* 6.1.4 TZOperationPrepareOpen */ +tz_return_t +TZOperationPrepareOpen(INOUT tz_device_t* psDevice, + IN tz_uuid_t const * pksService, + IN tz_login_t const * pksLogin, + IN tz_timelimit_t const * pksTimeLimit, + OUT tz_session_t* psSession, + OUT tz_operation_t* psOperation); + +/* 6.1.5 TZOperationPrepareInvoke */ +tz_return_t +TZOperationPrepareInvoke(INOUT tz_session_t* psSession, + uint32_t uiCommand, + IN tz_timelimit_t const * pksTimeLimit, + OUT tz_operation_t * psOperation); + +/* 6.1.6 TZOperationPrepareClose */ +tz_return_t +TZOperationPrepareClose(INOUT tz_session_t* psSession, + OUT tz_operation_t* psOperation); + +/* 6.1.7 TZOperationPerform */ +tz_return_t +TZOperationPerform(INOUT tz_operation_t* psOperation, + OUT tz_return_t* puiServiceReturn); + +/* 6.1.8 TZOperationRelease */ +void +TZOperationRelease(INOUT tz_operation_t* psOperation); + +/* 6.1.9 TZOperationCancel */ +void +TZOperationCancel(INOUT tz_operation_t* psOperation); + +/* 6.1.10 TZSharedMemoryAllocate */ +tz_return_t +TZSharedMemoryAllocate(INOUT tz_session_t* psSession, + INOUT tz_shared_memory_t* psSharedMem); + +/* 6.1.11 TZSharedMemoryRegister */ +tz_return_t +TZSharedMemoryRegister(INOUT tz_session_t* psSession, + INOUT tz_shared_memory_t* psSharedMem); + +/* 6.1.12 TZSharedMemoryRelease */ +void +TZSharedMemoryRelease(INOUT tz_shared_memory_t* psSharedMem); + +/* 6.1.13 TZSystemGetPropertyList */ +tz_return_t +TZSystemGetPropertyList(INOUT tz_device_t* psDevice, + OUT tz_property_name_t* psList, + OUT uint32_t* puiLength); + +/* 6.1.14 TZSystemGetProperty */ +tz_return_t +TZSystemGetProperty(INOUT tz_device_t* psDevice, + INOUT tz_property_t* psProperty); + +/* 6.2.1 TZEncodeUint32 */ +void +TZEncodeUint32(INOUT tz_operation_t* psOperation, + uint32_t uiData); + +/* 6.2.2 TZEncodeArray */ +void TZEncodeArray(INOUT tz_operation_t* psOperation, + IN void const * pkArray, + uint32_t uiLength); + +/* 6.2.3 TZEncodeArraySpace */ +void * TZEncodeArraySpace(INOUT tz_operation_t* psOperation, + uint32_t uiLength); + +/* 6.2.4 TZEncodeMemoryReference */ +void +TZEncodeMemoryReference(INOUT tz_operation_t* psOperation, + INOUT tz_shared_memory_t* psSharedMem, + uint32_t uiOffset, + uint32_t uiLength, + uint32_t uiFlags); + +/* extension: encode multiple by format string */ + +/* expects see */ +#define TZI_EU32 PRIu32 /* (u32) TZEncodeUint32 */ +#define TZI_ESTR "s" /* (char*) TZEncodeArray */ +/* encodes as an array, up to and + including null terminator */ +#define TZI_EARR "p%"PRIu32 /* (void*, u32) TZEncodeArray */ +#define TZI_EARRSPC "-p%"PRIu32 /* (void**, u32) TZEncodeArraySpace */ + +/* Convenience functions for encoding multiple parameters. Use the + * format-specifier macros TZI_E* + */ +tz_return_t +TZIEncodeF(INOUT tz_operation_t *psOperation, const char* str, ...) + __attribute__ ((format (printf, 2, 3))); + +tz_return_t +vTZIEncodeF(INOUT tz_operation_t *psOperation, const char* str, va_list argp); + +/* expects see */ +#define TZI_DU32 PRIu32 /* (u32*) TZDecodeUint32 */ +#define TZI_DARRSPC "p%"PRIu32 /* (void**, u32*) TZDecodeArraySpace */ +#define TZI_DARRSPC_NOLEN "p%*"PRIu32 /* (void**) TZDecodeArraySpace */ +#define TZI_DARR "s%"PRIu32 /* (void*, u32*) TZDecodeArraySpace */ +/* checks second parameter for + buffer size, copies into + buffer spec'd by first + parameter, and sets second + parameter to size of decoded + buffer */ +#define TZI_DARR_NOLEN "s%*"PRIu32 /* (void*) TZI_DARR */ + +/* Convenience functions for decoding multiple paramters. Use the + * format-specifier macros TZI_D* + */ +tz_return_t +TZIDecodeF(INOUT tz_operation_t *psOperation, const char* str, ...) + __attribute__ ((format (scanf, 2, 3))); + +tz_return_t +vTZIDecodeF(INOUT tz_operation_t *psOperation, const char* str, va_list argp); + +/* 6.2.5 TZDecodeUint32 */ +uint32_t +TZDecodeUint32(INOUT tz_operation_t* psOperation); + + +/* 6.2.6 TZDecodeArraySpace */ +void * +TZDecodeArraySpace(INOUT tz_operation_t* psOperation, + OUT uint32_t* puiLength); + + +/* 6.2.7 TZDecodeGetType */ +uint32_t +TZDecodeGetType(INOUT tz_operation_t* psOperation); + +/* 6.2.8 TZDecodeGetError */ +tz_return_t +TZDecodeGetError(INOUT tz_operation_t * psOperation); + +/* 6.3.1 TZManagerOpen */ +tz_return_t +TZManagerOpen(INOUT tz_device_t* psDevice, + IN tz_login_t const * pksLogin, + OUT tz_session_t* psSession); + +/* 6.3.2 TZManagerClose */ +tz_return_t +TZManagerClose(INOUT tz_session_t* psSession); + +/* 6.3.3 TZManagerGetServiceList */ +tz_return_t +TZManagerGetServiceList(INOUT tz_session_t* psSession, + OUT tz_uuid_t* psList, + INOUT uint32_t* puiLength); + +/* 6.3.4 TZManagerGetServicePropertyList */ +tz_return_t +TZManagerGetServicePropertyList(INOUT tz_session_t* psSession, + IN tz_uuid_t const * pksService, + OUT tz_property_name_t * pasList, + INOUT uint32_t * puiLength); + +/* 6.3.5 TZManagerGetServiceProperty */ +tz_return_t +TZManagerGetServiceProperty(INOUT tz_session_t* psSession, + IN tz_uuid_t const* pksService, + INOUT tz_property_t* psProperty); + +/* 7.2.1 TZManagerDownloadService */ +/* note- kauiData is uint8_t* by standard. making it void* + * so that caller doesn't need to explicitly cast. + */ +tz_return_t +TZManagerDownloadService(INOUT tz_session_t* psSession, + IN void const * kauiData, + uint32_t uiLength, + OUT tz_uuid_t* psService); + +/* 7.2.2 TZManagerRemoveService */ +tz_return_t +TZManagerRemoveService(INOUT tz_session_t* psSession, + IN tz_uuid_t const * pksService); + +/******************************************************/ +/* implementation-specific. using prefix 'tv' for now */ +/******************************************************/ + +/* typedef struct etz_service_handle_t { */ +/* tz_uuid_t sId; */ +/* uint32_t activeSessions; */ +/* tz_return_t (*pCall)(struct etz_service_handle_t*, tz_session_t*); */ +/* tz_return_t (*pRemove)(struct etz_service_handle_t*); */ +/* } etz_service_handle_t; */ + +/* /\* service descriptor to be passed to */ +/* * TZManagerDownloadService. Think */ +/* * of this is an 'abstract interface'. */ +/* * Specific service descriptor types will */ +/* * include this as their first struct element. */ +/* *\/ */ +/* typedef struct etz_service_t { */ +/* tz_uuid_t sId; */ +/* tz_return_t (*pDownload)(const struct etz_service_t*, etz_service_handle_t**); */ +/* } etz_service_t; */ + + +/**********************************************************/ + +#endif diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/tze.h b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/tze.h new file mode 100644 index 0000000000..ec2196c787 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/tze.h @@ -0,0 +1,73 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef TZE_H +#define TZE_H + +#include "tz.h" + +typedef struct { + tz_device_t tzDevice; + tz_uuid_t tzSvcId; + tz_session_t tzSession; +} tze_dev_svc_sess_t; + +typedef struct { + const void *pkDeviceName; + const void *pkDeviceInit; + const tz_login_t *pksManagerLogin; + const tz_login_t * pksSvcLogin; + const tz_timelimit_t * pksSvcTimeLimit; +} tze_svc_load_and_open_options_t; + +tz_return_t TZESvcLoadAndOpen(tze_dev_svc_sess_t *sess, + const void *kauiSvcData, + uint32_t uiSvcDataLength, + const tze_svc_load_and_open_options_t *options); + +tz_return_t TZEClose(tze_dev_svc_sess_t *sess); + +#endif diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/tzmarshal.h b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/tzmarshal.h new file mode 100644 index 0000000000..2af9b40949 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/include/tzmarshal.h @@ -0,0 +1,143 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * Author - Jim Newsome (jnewsome@no-fuss.com) + */ + +#ifndef TZMARSHAL_H +#define TZMARSHAL_H + +#include + +#include "tz.h" + +typedef enum tzi_encoded_type_t { + TZI_ENCODED_UINT32, + TZI_ENCODED_ARRAY, + TZI_ENCODED_MEM, +} tzi_encoded_type_t; + +typedef struct tzi_encoded_t { + tzi_encoded_type_t uiType; + union { + struct { + uint32_t uiValue; + } sUint32; + struct { + uint32_t uiSize; + uint8_t aData[]; /* there must be nothing after this union for + this to work! */ + } sArray; + struct { + uint32_t uiSize; + void *pMem; + } sMem; + }; +} tzi_encoded_t; + +typedef struct tzi_encode_buffer_t { + tz_return_t uiRetVal; + uint32_t uiSize; + uint32_t uiOffset; + uint32_t uiSizeUsed; /* only valid when decoding */ + tzi_encoded_t pBuf[];/* CAUTION when adding members to this struct- + pBuf must be 8-byte aligned. */ +} tzi_encode_buffer_t; + +void +TZIEncodeUint32(INOUT tzi_encode_buffer_t* psBuffer, + uint32_t uiData); +uint32_t +TZIDecodeUint32(INOUT tzi_encode_buffer_t* psBuffer); + +void +TZIEncodeArray(INOUT tzi_encode_buffer_t* psBuffer, + IN void const * pkArray, + uint32_t uiLength); +void* +TZIEncodeArraySpace(INOUT tzi_encode_buffer_t* psBuffer, + uint32_t uiLength); + +uint32_t TZIEncodeMemoryReference(INOUT tzi_encode_buffer_t* psBuffer, + IN void* pMem, + uint32_t Length); + +void* +TZIDecodeMemoryReference(INOUT tzi_encode_buffer_t* psBuffer, + OUT uint32_t* puiLength); + +void * +TZIDecodeArraySpace(INOUT tzi_encode_buffer_t* psBuffer, + OUT uint32_t* puiLength); + +void +TZIEncodeToDecode(INOUT tzi_encode_buffer_t* psBuffer); + +void +TZIEncodeBufInit(INOUT tzi_encode_buffer_t* psBuffer, uint32_t uiLength); + +void +TZIEncodeBufReInit(INOUT tzi_encode_buffer_t* psBuffer); + +tz_return_t +TZIDecodeGetError(INOUT tzi_encode_buffer_t* psBuffer); + +tz_return_t +vTZIEncodeBufF(tzi_encode_buffer_t* psBuffer, const char* str, va_list argp); + +tz_return_t +TZIEncodeBufF(tzi_encode_buffer_t* psBuffer, const char* str, ...) + __attribute__ ((format (printf, 2, 3))); + +tz_return_t +vTZIDecodeBufF(tzi_encode_buffer_t* psBuffer, const char* str, va_list argp); + +tz_return_t +TZIDecodeBufF(tzi_encode_buffer_t* psBuffer, const char* str, ...) + __attribute__ ((format (scanf, 2, 3))); + +#endif diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/src/Makefile.am b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/src/Makefile.am new file mode 100644 index 0000000000..9969b0288e --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/src/Makefile.am @@ -0,0 +1,9 @@ +# make this library suitable for services to compile against +AM_CFLAGS = $(SVC_CFLAGS) + +AM_CPPFLAGS = -I$(top_srcdir)/include + +pkglib_LIBRARIES = libtz.a libsvc.a +libtz_a_SOURCES = marshal.c tz.c tze.c ../include/tzmarshal.h ../include/tz.h ../include/tze.h ../include/list.h + +libsvc_a_SOURCES = marshal.c ../include/tzmarshal.h ../include/tz.h ../include/list.h diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/src/marshal.c b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/src/marshal.c new file mode 100644 index 0000000000..83c8bc9eab --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/src/marshal.c @@ -0,0 +1,570 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * Author - Jim Newsome (jnewsome@no-fuss.com) + */ + +#include +#include + +#define BUFFER_HEAD(psB) ((tzi_encoded_t*)((uintptr_t)(psB)->pBuf + (psB)->uiOffset)) + +/* #DEFINE BUF_PUSH(psB, d) \ */ +/* do { \ */ +/* if ((psB)->UiRetVal == TZ_SUCCESS) { \ */ +/* if (((psB)->uiOffset + sizeof(d)) > (psB)->uiSize) \ */ +/* (psB)->uiRetVal = TZ_ERROR_ENCODE_MEMORY \ */ +/* else { \ */ +/* memcpy((psB)->pBuf, &(d), sizeof(d)); \ */ +/* (psB)->uiOffset += sizeof(d); \ */ +/* }} \ */ +/* } while(0) */ + +#define ALIGN_UP(uiX, uiAlign) ((((uiAlign) - (((uintptr_t)uiX) % (uiAlign))) % (uiAlign)) + ((uintptr_t)uiX)); + +/* use our own implementation of memcpy so that + it's available to PALs. + XXX better solution? +*/ +__attribute__ ((section (".stext"))) +static void *memcpy(void *dest, const void *src, size_t n) +{ + size_t i; + + /* move a uint32_t at a time */ + for(i=0; i < (n / sizeof(uint32_t)); i++) { + ((uint32_t*)dest)[i] = ((uint32_t*)src)[i]; + } + + /* now move a byte at a time */ + for(i=(n/sizeof(uint32_t)*sizeof(uint32_t)); ipBuf->uiType) + + sizeof(psBuffer->pBuf->sUint32); + + if (psBuffer->uiRetVal != TZ_SUCCESS) { + return; + } + + if ((psBuffer->uiOffset + sz) > psBuffer->uiSize) { + psBuffer->uiRetVal = TZ_ERROR_ENCODE_MEMORY; + return; + } + + BUFFER_HEAD(psBuffer)->uiType = TZI_ENCODED_UINT32; + BUFFER_HEAD(psBuffer)->sUint32.uiValue = uiData; + psBuffer->uiOffset += sz; +} + +__attribute__ ((section (".stext"))) +uint32_t +TZIDecodeUint32(INOUT tzi_encode_buffer_t* psBuffer) +{ + uint32_t rv; + uint32_t sz = + sizeof(psBuffer->pBuf->uiType) + + sizeof(psBuffer->pBuf->sUint32); + + if (psBuffer->uiRetVal != TZ_SUCCESS) { + return 0; + } + + if ((psBuffer->uiOffset + sz) > psBuffer->uiSizeUsed) { + psBuffer->uiRetVal = TZ_ERROR_DECODE_NO_DATA; + return 0; + } + + if (BUFFER_HEAD(psBuffer)->uiType != TZI_ENCODED_UINT32) { + psBuffer->uiRetVal = TZ_ERROR_DECODE_TYPE; + return 0; + } + + rv = BUFFER_HEAD(psBuffer)->sUint32.uiValue; + psBuffer->uiOffset += sz; + + return rv; +} + + +__attribute__ ((section (".stext"))) +static void* +_TZIEncodeArraySpace(INOUT tzi_encode_buffer_t* psBuffer, + uint32_t uiLength) +{ + uint32_t sz = + sizeof(psBuffer->pBuf->uiType) + + sizeof(psBuffer->pBuf->sArray) + + uiLength; + uint32_t paddingBefore; + uint32_t arrayUnalignedStartOffset; + uint32_t arrayStartOffset; + + if (psBuffer->uiRetVal != TZ_SUCCESS) { + return NULL; + } + + /* standard guarantees that arrays are stored + * at an 8-aligned address. + * device should guarantee that base address + * is 8-aligned. + */ + arrayUnalignedStartOffset = psBuffer->uiOffset + + sizeof(psBuffer->pBuf->uiType) + + sizeof(psBuffer->pBuf->sArray); + arrayStartOffset = ALIGN_UP(arrayUnalignedStartOffset, 8); + + paddingBefore = arrayStartOffset - arrayUnalignedStartOffset; + sz += paddingBefore; + if ((psBuffer->uiOffset + sz) > psBuffer->uiSize) { + psBuffer->uiRetVal = TZ_ERROR_ENCODE_MEMORY; + return NULL; + } + + BUFFER_HEAD(psBuffer)->uiType = TZI_ENCODED_ARRAY; + BUFFER_HEAD(psBuffer)->sArray.uiSize = uiLength; + + /* we 4-align afterwards */ + psBuffer->uiOffset += ALIGN_UP(sz, 4); + + return &((uint8_t*)(psBuffer->pBuf))[arrayStartOffset]; +} + +uint32_t +TZIEncodeMemoryReference(INOUT tzi_encode_buffer_t* psBuffer, + IN void* pMem, + uint32_t Length) +{ + uint32_t sz = + sizeof(psBuffer->pBuf->uiType) + + sizeof(psBuffer->pBuf->sMem); + uint32_t encodeOffset; + + if (psBuffer->uiRetVal != TZ_SUCCESS) { + return 0; + } + + if ((psBuffer->uiOffset + sz) > psBuffer->uiSize) { + psBuffer->uiRetVal = TZ_ERROR_ENCODE_MEMORY; + return 0; + } + + encodeOffset = psBuffer->uiOffset + ((uintptr_t)(&BUFFER_HEAD(psBuffer)->sMem.pMem) + - (uintptr_t)(BUFFER_HEAD(psBuffer))); + + BUFFER_HEAD(psBuffer)->uiType = TZI_ENCODED_MEM; + BUFFER_HEAD(psBuffer)->sMem.uiSize = Length; + BUFFER_HEAD(psBuffer)->sMem.pMem = pMem; + psBuffer->uiOffset += sz; + + return encodeOffset; +} + +__attribute__ ((section (".stext"))) +void* +TZIDecodeMemoryReference(INOUT tzi_encode_buffer_t* psBuffer, + OUT uint32_t* puiLength) +{ + void* rv; + uint32_t sz = + sizeof(psBuffer->pBuf->uiType) + + sizeof(psBuffer->pBuf->sMem); + + if (psBuffer->uiRetVal != TZ_SUCCESS) { + return NULL; + } + + if ((psBuffer->uiOffset + sz) > psBuffer->uiSizeUsed) { + psBuffer->uiRetVal = TZ_ERROR_DECODE_NO_DATA; + return NULL; + } + + if (BUFFER_HEAD(psBuffer)->uiType != TZI_ENCODED_MEM) { + psBuffer->uiRetVal = TZ_ERROR_DECODE_TYPE; + return NULL; + } + + rv = BUFFER_HEAD(psBuffer)->sMem.pMem; + *puiLength = BUFFER_HEAD(psBuffer)->sMem.uiSize; + psBuffer->uiOffset += sz; + + return rv; +} + + + +__attribute__ ((section (".stext"))) +void * +TZIDecodeArraySpace(INOUT tzi_encode_buffer_t* psBuffer, + OUT uint32_t* puiLength) +{ + uint32_t sz = + sizeof(psBuffer->pBuf->uiType) + + sizeof(psBuffer->pBuf->sArray); + uint32_t paddingBefore; + uint32_t arrayStartOffset; + uint32_t arrayUnalignedStartOffset; + + if (psBuffer->uiRetVal != TZ_SUCCESS) { + *puiLength = 0; + return NULL; + } + + /* first check that the header isn't off the end */ + if (psBuffer->uiOffset + sz > psBuffer->uiSizeUsed) { + psBuffer->uiRetVal = TZ_ERROR_DECODE_NO_DATA; + *puiLength = 0; + return NULL; + } + + /* type check */ + if (BUFFER_HEAD(psBuffer)->uiType != TZI_ENCODED_ARRAY) { + psBuffer->uiRetVal = TZ_ERROR_DECODE_TYPE; + *puiLength = 0; + return NULL; + } + + /* now make sure the whole array is here */ + *puiLength = BUFFER_HEAD(psBuffer)->sArray.uiSize; + arrayUnalignedStartOffset = psBuffer->uiOffset + + sizeof(psBuffer->pBuf->uiType) + + sizeof(psBuffer->pBuf->sArray); + arrayStartOffset = ALIGN_UP(arrayUnalignedStartOffset, 8); + paddingBefore = arrayStartOffset - arrayUnalignedStartOffset; + + sz += paddingBefore; + sz += *puiLength; + if (psBuffer->uiOffset + sz > psBuffer->uiSizeUsed) { + psBuffer->uiRetVal = TZ_ERROR_DECODE_NO_DATA; + *puiLength = 0; + return NULL; + } + + psBuffer->uiOffset += ALIGN_UP(sz, 4); + + return &((uint8_t*)(psBuffer->pBuf))[arrayStartOffset]; +} + +__attribute__ ((section (".stext"))) +void* +TZIEncodeArraySpace(INOUT tzi_encode_buffer_t* psBuffer, + uint32_t uiLength) +{ + void *m = _TZIEncodeArraySpace(psBuffer, uiLength); + + /* in case caller doesn't fill entire array, + * prevent existing data from leaking. + * XXX is this necessary? and if so, would it be + * bigger to do one big memset on the encode buffer? + */ + /* XXX revisit whether to do this + if (m != NULL) { + memset(m, 0, uiLength); + } + */ + return m; +} + +__attribute__ ((section (".stext"))) +void +TZIEncodeArray(INOUT tzi_encode_buffer_t* psBuffer, + IN void const * pkArray, + uint32_t uiLength) +{ + void *m = _TZIEncodeArraySpace(psBuffer, uiLength); + if (m != NULL) + memcpy(m, pkArray, uiLength); + +} + +__attribute__ ((section (".stext"))) +tz_return_t +TZIDecodeGetError(INOUT tzi_encode_buffer_t* psBuffer) +{ + return psBuffer->uiRetVal; +} + +__attribute__ ((section (".stext"))) +void +TZIEncodeToDecode(INOUT tzi_encode_buffer_t* psBuffer) +{ + if (psBuffer->uiRetVal != TZ_SUCCESS) + return; + psBuffer->uiSizeUsed = psBuffer->uiOffset; + psBuffer->uiOffset = 0; +} + +__attribute__ ((section (".stext"))) +void +TZIEncodeBufInit(INOUT tzi_encode_buffer_t* psBuffer, uint32_t uiLength) +{ + *psBuffer = (tzi_encode_buffer_t) { + .uiRetVal = TZ_SUCCESS, + .uiSize = uiLength - sizeof(tzi_encode_buffer_t), + .uiOffset = 0, + .uiSizeUsed = 0 + }; +} + +__attribute__ ((section (".stext"))) +void +TZIEncodeBufReInit(INOUT tzi_encode_buffer_t* psBuffer) +{ + psBuffer->uiRetVal = TZ_SUCCESS; + psBuffer->uiOffset = 0; + psBuffer->uiSizeUsed = 0; +} + +static int is_prefix(const char* prefix, const char* s) +{ + int i=0; + + while(1) { + if (prefix[i] == '\0') + return 1; + + if (prefix[i] != s[i]) + return 0; + + i++; + } +} + +static size_t strlen(const char *s) +{ + int i =0; + while(s[i] != '\0') + i++; + return i; +} + +tz_return_t +vTZIEncodeBufF(tzi_encode_buffer_t* psBuffer, const char* str, va_list argp) +{ + int i; + + while(1) { + if(str[0] == '\0') { + break; + } + if(str[0] != '%') { + str++; + continue; + } + str++; /* skip the '%' */ + + if(is_prefix(TZI_EU32, str)) { + str += strlen(TZI_EU32); + TZIEncodeUint32(psBuffer, va_arg(argp, uint32_t)); + } else if (is_prefix(TZI_ESTR, str)) { + char *s = va_arg(argp, char*); + str += strlen(TZI_ESTR); + TZIEncodeArray(psBuffer, s, strlen(s)+1); + } else if (is_prefix(TZI_EARR, str)) { + void *x = va_arg(argp, void*); + uint32_t sz = va_arg(argp, uint32_t); + str += strlen(TZI_EARR); + + TZIEncodeArray(psBuffer, x, sz); + } else if (is_prefix(TZI_EARRSPC, str)) { + void **x = va_arg(argp, void**); + uint32_t sz = va_arg(argp, uint32_t); + str += strlen(TZI_EARRSPC); + + *x = TZIEncodeArraySpace(psBuffer, sz); + } else { + return TZ_ERROR_ILLEGAL_ARGUMENT; + } + } + return TZIDecodeGetError(psBuffer); +} + +tz_return_t +TZIEncodeBufF(tzi_encode_buffer_t* psBuffer, const char* str, ...) +{ + tz_return_t rv; + va_list argp; + va_start(argp, str); + rv = vTZIEncodeBufF(psBuffer, str, argp); + va_end(argp); + return rv; +} + +static int is_prefix_ignore_splats(const char* prefix, const char* s) +{ + int i=0; + + while(1) { + /* ignore splats. */ + while(*s == '*') + s++; + + if (*prefix == '\0') + return 1; + + if (*prefix != *s) + return 0; + + prefix++; + s++; + } +} + +tz_return_t +vTZIDecodeBufF(tzi_encode_buffer_t* psBuffer, const char* str, va_list argp) +{ + int i; + + while(1) { + if(str[0] == '\0') { + break; + } + if(str[0] != '%') { + str++; + continue; + } + str++; /* skip the '%' */ + + /* we only decode array spaces and uint32's for now. we *do* + allow the '*' assignment-suppression character in the style of + scanf. unfortunately that makes this code rather ugly and + brittle, but hopefully makes client code a bit tidier. */ + + if(is_prefix_ignore_splats(TZI_DU32, str)) { + uint32_t i; + i = TZIDecodeUint32(psBuffer); + + if (str[0] == '*') { + str++; + } else { + uint32_t *pi = va_arg(argp, uint32_t*); + *pi = i; + } + str += strlen(PRIu32); + } else if (is_prefix_ignore_splats(TZI_DARRSPC, str)) { + void *x=NULL; + uint32_t sz; + + x = TZIDecodeArraySpace(psBuffer, &sz); + + if (str[0] == '*') { + str++; + } else { + void **px = va_arg(argp, void**); + *px = x; + } + str+=2; /* should now point after next '%' */ + + if (str[0] == '*') { + str++; + } else { + uint32_t *psz = va_arg(argp, uint32_t*); + *psz = sz; + } + str+=strlen(PRIu32); + } else if (is_prefix_ignore_splats(TZI_DARR, str)) { + void *dst=NULL; + void *src=NULL; + uint32_t dst_sz, src_sz; + uint32_t *pdst_sz = NULL; + + src = TZIDecodeArraySpace(psBuffer, &src_sz); + + if (str[0] == '*') { + str++; + } else { + dst = va_arg(argp, void*); + } + str+=2; /* should now point after next '%' */ + + if (str[0] == '*') { + str++; + } else { + pdst_sz = va_arg(argp, uint32_t*); + dst_sz = *pdst_sz; + *pdst_sz = src_sz; + } + str+=strlen(PRIu32); + + if (dst) { + if (!pdst_sz) { + /* illegal to request data copy without specifying destination + buffer size */ + return TZ_ERROR_ILLEGAL_ARGUMENT; + } + if (dst_sz < src_sz) { + return TZ_ERROR_SHORT_BUFFER; + } + memcpy(dst, src, src_sz); + } + } else { + return TZ_ERROR_ILLEGAL_ARGUMENT; + } + } + return TZIDecodeGetError(psBuffer); +} + +tz_return_t +TZIDecodeBufF(tzi_encode_buffer_t* psBuffer, const char* str, ...) +{ + tz_return_t rv; + va_list argp; + va_start(argp, str); + rv = vTZIDecodeBufF(psBuffer, str, argp); + va_end(argp); + return rv; +} diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/src/tz.c b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/src/tz.c new file mode 100644 index 0000000000..848c4f3f49 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/src/tz.c @@ -0,0 +1,843 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * Author - Jim Newsome (jnewsome@no-fuss.com) + */ + +#include +#include +#include + +#include +#include + +#define CBB_OF_DEVICE(d) ((d)->sImp.cbb) +#define CBB_OF_SESSION(s) (CBB_OF_DEVICE((s)->sImp.psDevice)) +#define CBB_OF_OPERATION(o) (CBB_OF_SESSION((o)->sImp.psSession)) +#define CBB_OF_SHAREDMEM(m) (CBB_OF_SESSION((m)->sImp.psSession)) + +#define TZI_DEVICE_REGISTRY_MAX 10 +static size_t tzi_device_registry_count = 0; +static tzi_device_registry_entry_t tzi_device_registry[TZI_DEVICE_REGISTRY_MAX]; + +tz_return_t TZIDeviceRegister(const char *name, tzi_device_cb_block_t* cbb) +{ + if (tzi_device_registry_count >= TZI_DEVICE_REGISTRY_MAX) { + return TZ_ERROR_GENERIC; + } + tzi_device_registry[tzi_device_registry_count++] = + (tzi_device_registry_entry_t) {.name = name, .cbb = cbb}; + + return TZ_SUCCESS; +} + +extern void TVregister(); + +tz_return_t +TZDeviceOpen(IN void const *pkDeviceName, + IN void const *pkInit, + OUT tz_device_t *psDevice) +{ + int i; + tz_return_t rv; + static bool initialized = false; + struct tzi_device_ext_t *psExt; + + /* temporary (?) hack. attempted to get device backends to register + themselves with constructor functions, but they don't get linked + in unless we reference symbols from them here. So we might as well + just register them from here. */ + if(!initialized) { + TVregister(); + initialized = true; + } + + /* default device. currently hard-coded. + * later consider taking an environment variable? + */ + if (pkDeviceName == NULL) { + pkDeviceName = "trustvisor"; + } + + /* linear search for requested device name */ + for(i=0; i < tzi_device_registry_count; i++) { + if (strcmp(pkDeviceName, tzi_device_registry[i].name) == 0) { + break; + } + } + if (i >= tzi_device_registry_count) { + return TZ_ERROR_ILLEGAL_ARGUMENT; + } + + rv = tzi_device_registry[i].cbb->deviceOpen(pkDeviceName, pkInit, psDevice, &psExt); + + if (rv == TZ_SUCCESS) { + *psDevice = (tz_device_t) { + .uiState = TZ_STATE_OPEN, + .sImp = { + .cbb = tzi_device_registry[i].cbb, + .uiSessionCount = 0, + .psExt = psExt, + }, + }; + } else { + *psDevice = (tz_device_t) { + .uiState = TZ_STATE_INVALID, + }; + } + + return rv; +} + +tz_return_t +TZDeviceClose(INOUT tz_device_t *psDevice) +{ + tz_return_t rv; + if (psDevice->uiState == TZ_STATE_INVALID) { + psDevice->uiState = TZ_STATE_UNDEFINED; + + return TZ_SUCCESS; + } else if (psDevice->uiState != TZ_STATE_OPEN) { + return TZ_ERROR_UNDEFINED; + } else if (psDevice->sImp.uiSessionCount > 0) { + return TZ_ERROR_ILLEGAL_STATE; + } + + rv = psDevice->sImp.cbb->deviceClose(psDevice); + if (rv == TZ_SUCCESS) { + psDevice->uiState = TZ_STATE_UNDEFINED; + } + return rv; +} + +tz_return_t +TZOperationPrepareOpen(INOUT tz_device_t* psDevice, + IN tz_uuid_t const * pksService, + IN tz_login_t const * pksLogin, + IN tz_timelimit_t const * pksTimeLimit, + OUT tz_session_t* psSession, + OUT tz_operation_t* psOperation) +{ + tz_return_t rv; + struct tzi_session_ext_t *session_ext; + struct tzi_operation_ext_t *operation_ext; + tzi_encode_buffer_t *psEncodeBuf; + uint32_t uiBufSize; + + if (psDevice == NULL + || psDevice->uiState == TZ_STATE_INVALID + || pksService == NULL + || psSession == NULL + || psOperation == NULL) { + return TZ_ERROR_UNDEFINED; + } + + rv = CBB_OF_DEVICE(psDevice)->operationPrepareOpen(psDevice, + pksService, + pksLogin, + pksTimeLimit, + &psEncodeBuf, + &uiBufSize, + &session_ext, + &operation_ext); + + if (rv == TZ_SUCCESS) { + *psSession = (tz_session_t) { + .uiState = TZ_STATE_INVALID, + .sImp = { + .psDevice = psDevice, + .uiOpenOps = 1, + .bManagerSession = false, + .psExt = session_ext, + } + }; + + assert(psEncodeBuf != NULL && uiBufSize >= sizeof(tzi_encode_buffer_t)); + *psEncodeBuf = (tzi_encode_buffer_t) { + .uiRetVal = TZ_SUCCESS, + .uiSize = uiBufSize - sizeof(tzi_encode_buffer_t), + .uiOffset = 0, + }; + + *psOperation = (tz_operation_t) { + .uiState = TZ_STATE_ENCODE, + .sImp = { + .psSession = psSession, + .uiOpType = TZI_OPERATION_OPEN, + .psEncodeBuffer = psEncodeBuf, + .psExt = operation_ext, + } + }; + + psDevice->sImp.uiSessionCount++; + } else { + *psSession = (tz_session_t) { + .uiState = TZ_STATE_UNDEFINED + }; + *psOperation = (tz_operation_t) { + .uiState = TZ_STATE_INVALID + }; + } + + return rv; +} + +tz_return_t +TZOperationPrepareInvoke(INOUT tz_session_t* psSession, + uint32_t uiCommand, + IN tz_timelimit_t const * pksTimeLimit, + OUT tz_operation_t * psOperation) +{ + tz_return_t rv; + struct tzi_operation_ext_t *psOperationExt; + tzi_encode_buffer_t *psEncodeBuf; + uint32_t uiBufSize; + + if (psSession == NULL + || psSession->uiState != TZ_STATE_OPEN + || psOperation == NULL) { + return TZ_ERROR_UNDEFINED; + } + + rv = CBB_OF_SESSION(psSession)->operationPrepareInvoke(psSession, + uiCommand, + pksTimeLimit, + &psEncodeBuf, + &uiBufSize, + &psOperationExt); + + if (rv == TZ_SUCCESS) { + psSession->sImp.uiOpenOps++; + + assert(psEncodeBuf != NULL && uiBufSize >= sizeof(tzi_encode_buffer_t)); + *psEncodeBuf = (tzi_encode_buffer_t) { + .uiRetVal = TZ_SUCCESS, + .uiSize = uiBufSize - sizeof(tzi_encode_buffer_t), + .uiOffset = 0, + }; + + *psOperation = (tz_operation_t) { + .uiState = TZ_STATE_ENCODE, + .sImp = { + .psSession = psSession, + .uiOpType = TZI_OPERATION_INVOKE, + .psEncodeBuffer = psEncodeBuf, + .psExt = psOperationExt, + } + }; + } else { + *psOperation = (tz_operation_t) { + .uiState = TZ_STATE_INVALID + }; + } + + return rv; +} + +tz_return_t +TZOperationPrepareClose(INOUT tz_session_t* psSession, + OUT tz_operation_t* psOperation) +{ + tz_return_t rv; + struct tzi_operation_ext_t *psOperationExt; + if (psSession == NULL + || psSession->uiState != TZ_STATE_OPEN + || psOperation == NULL) { + return TZ_ERROR_UNDEFINED; + } + + rv = CBB_OF_SESSION(psSession)->operationPrepareClose(psSession, &psOperationExt); + + if (rv == TZ_SUCCESS) { + psSession->sImp.uiOpenOps++; + psSession->uiState = TZ_STATE_CLOSING; + + *psOperation = (tz_operation_t) { + .uiState = TZ_STATE_PERFORMABLE, + .sImp = { + .psSession = psSession, + .uiOpType = TZI_OPERATION_CLOSE, + .psExt = psOperationExt, + } + }; + } else { + *psOperation = (tz_operation_t) { + .uiState = TZ_STATE_INVALID + }; + } + return rv; +} + +static void unreferenceSharedMemSubranges(INOUT tz_operation_t *psOperation) +{ + ll_t *refdSubranges=psOperation->sImp.psRefdSubranges; + tzi_shared_memory_subrange_t *subrange; + LL_FOR_EACH(refdSubranges, subrange) { + /* remove self from the shared memory's list of referencing + operations */ + LL_dremove(&subrange->psSharedMem->sImp.psRefdOperations, psOperation); + } + LL_free(psOperation->sImp.psRefdSubranges); + psOperation->sImp.psRefdSubranges = NULL; +} + +tz_return_t +TZOperationPerform(INOUT tz_operation_t* psOperation, + OUT tz_return_t* puiServiceReturn) +{ + tz_return_t rv; + if (psOperation == NULL + || !(psOperation->uiState == TZ_STATE_ENCODE + || psOperation->uiState == TZ_STATE_PERFORMABLE)/* TZ_STATE_PERFORMABLE may also be acceptable. 6.1.7 contradicts itself */ + || (psOperation->sImp.uiOpType == TZI_OPERATION_CLOSE + && (psOperation->sImp.psSession->sImp.uiOpenOps > 1 + || psOperation->sImp.psSession->sImp.uiOpenSharedMem > 0)) + || puiServiceReturn == NULL) { + return TZ_ERROR_UNDEFINED; + } + + if (psOperation->sImp.psEncodeBuffer != NULL + && psOperation->sImp.psEncodeBuffer->uiRetVal != TZ_SUCCESS) { + *puiServiceReturn = TZ_ERROR_GENERIC; + psOperation->uiState = TZ_STATE_INVALID; + return psOperation->sImp.psEncodeBuffer->uiRetVal; + } + + rv = CBB_OF_OPERATION(psOperation)->operationPerform(psOperation, puiServiceReturn); + + /* cf 6.2.4 */ + unreferenceSharedMemSubranges(psOperation); + + /* check for encoder errors caused by the service */ + if (psOperation->sImp.psEncodeBuffer != NULL + && psOperation->sImp.psEncodeBuffer->uiRetVal != TZ_SUCCESS) { + *puiServiceReturn = TZ_ERROR_GENERIC; + psOperation->uiState = TZ_STATE_INVALID; + rv = psOperation->sImp.psEncodeBuffer->uiRetVal; + } + + /* enforce spec post-conditions */ + if (rv == TZ_SUCCESS) { + *puiServiceReturn = TZ_SUCCESS; + } + switch (psOperation->sImp.uiOpType) { + case TZI_OPERATION_OPEN: + if (rv == TZ_SUCCESS) { + psOperation->sImp.psSession->uiState = TZ_STATE_OPEN; + psOperation->uiState = TZ_STATE_DECODE; + /* note that device session count was already incremented + in TZOperationPrepareOpen */ + } + break; + case TZI_OPERATION_INVOKE: + if (rv == TZ_SUCCESS) { + psOperation->uiState = TZ_STATE_DECODE; + } else if (rv == TZ_ERROR_SERVICE) { + psOperation->uiState = TZ_STATE_DECODE; + } else { + psOperation->uiState = TZ_STATE_INVALID; + } + break; + case TZI_OPERATION_CLOSE: + psOperation->uiState = TZ_STATE_INVALID; + + /* session is considered closed regardless of rv */ + psOperation->sImp.psSession->uiState = TZ_STATE_INVALID; + psOperation->sImp.psSession->sImp.psDevice->sImp.uiSessionCount--; + break; + default: + return TZ_ERROR_UNDEFINED; + } + return rv; +} + +void +TZOperationRelease(INOUT tz_operation_t* psOperation) +{ + if (psOperation == NULL + || !(psOperation->uiState == TZ_STATE_ENCODE + || psOperation->uiState == TZ_STATE_PERFORMABLE + || psOperation->uiState == TZ_STATE_DECODE + || psOperation->uiState == TZ_STATE_INVALID)) { + return; /* undefined behavior */ + } + + /* cf 6.2.4 */ + unreferenceSharedMemSubranges(psOperation); + + /* any cleanup should already be done when + * transition to TZ_STATE_INVALID occurred + * FIXME- revisit this + */ + if (psOperation->uiState == TZ_STATE_INVALID) { + return; /* no-op */ + } + + CBB_OF_OPERATION(psOperation)->operationRelease(psOperation); + + /* unwind un-issued operations */ + /* FIXME is the state TZ_STATE_ENCODE or TZ_STATE_PEFORMABLE + iff the operation is un-issued? + */ + if((psOperation->uiState == TZ_STATE_ENCODE + || psOperation->uiState == TZ_STATE_PERFORMABLE)) { + switch (psOperation->sImp.uiOpType) { + case TZI_OPERATION_OPEN: + psOperation->sImp.psSession->sImp.psDevice->sImp.uiSessionCount--; + break; + case TZI_OPERATION_INVOKE: + break; + case TZI_OPERATION_CLOSE: + psOperation->sImp.psSession->uiState = TZ_STATE_OPEN; + break; + } + } + /* FIXME will need to clean up marshalling, shared mem, etc. */ + + psOperation->sImp.psSession->sImp.uiOpenOps--; +} + +static bool bits_are_subset_of(uint32_t child, uint32_t parent) +{ + return ((child & ~parent) == 0); +} + +tz_return_t +TZSharedMemoryAllocate(INOUT tz_session_t* psSession, + INOUT tz_shared_memory_t* psSharedMem) +{ + tz_return_t rv; + + if (psSession == NULL + || psSession->uiState != TZ_STATE_OPEN + || psSharedMem == NULL + || !bits_are_subset_of(psSharedMem->uiFlags, TZ_MEM_SERVICE_RW) + || psSharedMem->uiLength == 0) { + return TZ_ERROR_UNDEFINED; + } + + rv = CBB_OF_SESSION(psSession)->sharedMemoryAllocate(psSession, + psSharedMem); + + if(rv == TZ_SUCCESS) { + assert((uint32_t)(psSharedMem->pBlock) % 8 == 0); /* TZ spec requirement */ + psSharedMem->uiState = TZ_STATE_OPEN; + psSharedMem->sImp.psSession = psSession; + psSession->sImp.uiOpenSharedMem++; + psSharedMem->sImp.bAllocated = true; + } else { + assert(psSharedMem->pBlock == NULL); + psSharedMem->uiState = TZ_STATE_INVALID; + psSharedMem->sImp.psSession = NULL; + } + + return rv; +} + +tz_return_t +TZSharedMemoryRegister(INOUT tz_session_t* psSession, + INOUT tz_shared_memory_t* psSharedMem) +{ + tz_return_t rv; + + if (psSession == NULL + || psSession->uiState != TZ_STATE_OPEN + || psSharedMem == NULL + || psSharedMem->pBlock == NULL + || !bits_are_subset_of(psSharedMem->uiFlags, TZ_MEM_SERVICE_RW) + || psSharedMem->uiFlags == 0) { + return TZ_ERROR_UNDEFINED; + } + + rv = CBB_OF_SESSION(psSession)->sharedMemoryRegister(psSession, + psSharedMem); + + if(rv == TZ_SUCCESS) { + psSharedMem->uiState = TZ_STATE_OPEN; + psSharedMem->sImp.bAllocated = false; + psSession->sImp.uiOpenSharedMem++; + } else { + psSharedMem->uiState = TZ_STATE_INVALID; + } + + return rv; +} + +void +TZSharedMemoryRelease(INOUT tz_shared_memory_t* psSharedMem) +{ + if (psSharedMem == NULL + || psSharedMem->sImp.psRefdOperations != NULL) { + /* FIXME undefined behavior. print a warning? */ + return; + } + + if (psSharedMem->uiState != TZ_STATE_INVALID) { + CBB_OF_SHAREDMEM(psSharedMem)->sharedMemoryRelease(psSharedMem); + psSharedMem->sImp.psSession->sImp.uiOpenSharedMem--; + } + + psSharedMem->uiState = TZ_STATE_UNDEFINED; + psSharedMem->pBlock = NULL; /* not required by spec, but good for debugging */ +} + + +void +TZEncodeUint32(INOUT tz_operation_t* psOperation, + uint32_t uiData) +{ + TZIEncodeUint32(psOperation->sImp.psEncodeBuffer, + uiData); +} +uint32_t +TZDecodeUint32(INOUT tz_operation_t* psOperation) +{ + return TZIDecodeUint32(psOperation->sImp.psEncodeBuffer); +} + + +void +TZEncodeArray(INOUT tz_operation_t* psOperation, + IN void const * pkArray, + uint32_t uiLength) +{ + TZIEncodeArray(psOperation->sImp.psEncodeBuffer, + pkArray, + uiLength); +} + +void* +TZEncodeArraySpace(INOUT tz_operation_t* psOperation, + uint32_t uiLength) +{ + return TZIEncodeArraySpace(psOperation->sImp.psEncodeBuffer, + uiLength); +} + +void * +TZDecodeArraySpace(INOUT tz_operation_t* psOperation, + OUT uint32_t* puiLength) +{ + return TZIDecodeArraySpace(psOperation->sImp.psEncodeBuffer, + puiLength); +} + +static bool ranges_overlap(uint32_t start1, uint32_t length1, + uint32_t start2, uint32_t length2) +{ + uint32_t end1 = start1+length1-1; + uint32_t end2 = start2+length2-1; + + /* break into 3 cases: start2 is before, in, or after first range */ + if (start2 < start1) { + /* before */ + return (end2 >= start1); + } else if (start2 >= start1 && start2 <= end1) { + /* in */ + return true; + } else { + /* after */ + return false; + } +} + +static bool range_already_referenced(IN tz_shared_memory_t *psSharedMem, + uint32_t uiOffset, + uint32_t uiLength) +{ + ll_t *ops_l = psSharedMem->sImp.psRefdOperations; + tz_operation_t *op = NULL; + LL_FOR_EACH(ops_l, op) { + ll_t *range_l = op->sImp.psRefdSubranges; + tzi_shared_memory_subrange_t *subrange = NULL; + LL_FOR_EACH(range_l, subrange) { + if (ranges_overlap(uiOffset, uiLength, + subrange->uiOffset, subrange->uiLength)) { + return true; + } + } + } + return false; +} + +void +TZEncodeMemoryReference(INOUT tz_operation_t* psOperation, + INOUT tz_shared_memory_t* psSharedMem, + uint32_t uiOffset, + uint32_t uiLength, + uint32_t uiFlags) +{ + uint32_t uiEncodeOffset; + tzi_shared_memory_subrange_t *psSubrange=NULL; + + if (psOperation == NULL + || psOperation->uiState != TZ_STATE_ENCODE + || psSharedMem == NULL + || psSharedMem->uiState != TZ_STATE_OPEN) { + return; /* FIXME print warning? */ + } + + /* check for encode_format errors, as per spec */ + if ((uiOffset+uiLength) > psSharedMem->uiLength + || !bits_are_subset_of(uiFlags, psSharedMem->uiFlags) + || range_already_referenced(psSharedMem, uiOffset, uiLength)) { + psOperation->sImp.psEncodeBuffer->uiRetVal = TZ_ERROR_ENCODE_FORMAT; + return; + } + + /* encoder just needs address and length. returns offset (into the + * encode-buffer) of the encoded address so that device back-end can + * rewrite it if necessary. (address space of trusted environment + * may not be unity-mapped with address space of caller) + */ + uiEncodeOffset = TZIEncodeMemoryReference(psOperation->sImp.psEncodeBuffer, + psSharedMem->pBlock+uiOffset, + uiLength); + + /* silently return if encoder is in an error state, + whether caused previously or just now */ + if (psOperation->sImp.psEncodeBuffer->uiRetVal != TZ_SUCCESS) { + return; + } + + /* malloc and init new subrange struct */ + psSubrange = malloc(sizeof(*psSubrange)); + if (psSubrange == NULL) { + /* using TZ_ERROR_MEMORY instead of TZ_ERROR_ENCODE_MEMORY, to + distinguish from case where encode buffer itself wasn't large + enough */ + psOperation->sImp.psEncodeBuffer->uiRetVal = TZ_ERROR_MEMORY; + return; + } + *psSubrange = (tzi_shared_memory_subrange_t) { + .psSharedMem = psSharedMem, + .uiOffset = uiOffset, + .uiLength = uiLength, + .uiFlags = uiFlags, + .uiEncodeOffset = uiEncodeOffset + }; + + /* add to operation's list of referenced subranges */ + if (LL_dpush(&psOperation->sImp.psRefdSubranges, psSubrange) == NULL) { + psOperation->sImp.psEncodeBuffer->uiRetVal = TZ_ERROR_MEMORY; + return; + } + + /* add this operation to psSharedMem's list of referencing + * operations, if not already there. */ + /* XXX horribly inefficient if we have a large number of + open operations referencing a psSharedMem */ + { + ll_t *l = psSharedMem->sImp.psRefdOperations; + tz_operation_t *op = NULL; + LL_FOR_EACH(l, op) { + if (op == psOperation) { + break; + } + } + if (l == NULL) { /* not found */ + if (LL_dpush(&psSharedMem->sImp.psRefdOperations, + psOperation) == NULL) { + psOperation->sImp.psEncodeBuffer->uiRetVal = TZ_ERROR_MEMORY; + return; + } + } + } +} + +tz_return_t +vTZIEncodeF(INOUT tz_operation_t *psOperation, const char* str, va_list argp) +{ + return vTZIEncodeBufF(psOperation->sImp.psEncodeBuffer, str, argp); +} + +tz_return_t +TZIEncodeF(INOUT tz_operation_t *psOperation, const char* str, ...) +{ + tz_return_t rv; + va_list argp; + va_start(argp, str); + rv = vTZIEncodeF(psOperation, str, argp); + va_end(argp); + return rv; +} + +tz_return_t +vTZIDecodeF(INOUT tz_operation_t *psOperation, const char* str, va_list argp) +{ + return vTZIDecodeBufF(psOperation->sImp.psEncodeBuffer, str, argp); +} + +tz_return_t +TZIDecodeF(INOUT tz_operation_t *psOperation, const char* str, ...) +{ + tz_return_t rv; + va_list argp; + va_start(argp, str); + rv = vTZIDecodeF(psOperation, str, argp); + va_end(argp); + return rv; +} + +tz_return_t +TZDecodeGetError(INOUT tz_operation_t * psOperation) +{ + return TZIDecodeGetError(psOperation->sImp.psEncodeBuffer); +} + +tz_return_t +TZManagerOpen(INOUT tz_device_t* psDevice, + IN tz_login_t const * pksLogin, + OUT tz_session_t* psSession) +{ + tz_return_t rv; + struct tzi_session_ext_t* psExt; + + if (psDevice == NULL + || psDevice->uiState != TZ_STATE_OPEN + || psSession == NULL) { + psSession->uiState = TZ_STATE_INVALID; + return TZ_ERROR_UNDEFINED; + } + + rv = CBB_OF_DEVICE(psDevice)->managerOpen(psDevice, pksLogin, &psExt); + + if (rv == TZ_SUCCESS) { + *psSession = (tz_session_t) { + .uiState = TZ_STATE_OPEN, + .sImp = { + .psDevice = psDevice, + .uiOpenOps = 0, + .bManagerSession = true, + .psExt = psExt, + } + }; + psDevice->sImp.uiSessionCount++; + } else { + *psSession = (tz_session_t) { + .uiState = TZ_STATE_INVALID, + }; + } + + return rv; +} + +tz_return_t +TZManagerClose(INOUT tz_session_t* psSession) +{ + tz_return_t rv; + + if (psSession == NULL) { + return TZ_ERROR_UNDEFINED; + } + if (!psSession->sImp.bManagerSession) { + /* session is not with Manager */ + return TZ_ERROR_UNDEFINED; + } + if (psSession->uiState == TZ_STATE_INVALID) { + /* according to TZ spec- silently succeed */ + return TZ_SUCCESS; + } + if (psSession->uiState != TZ_STATE_OPEN) { + return TZ_ERROR_UNDEFINED; + } + + /* FIXME- according to spec, need to cancel any operations pending + on service manager. Should we do it at this layer by keeping + track of open operations on a session and here calling + TZOperationCancel on each one? + */ + + rv = CBB_OF_SESSION(psSession)->managerClose(psSession); + + /* spec guarantees that session is closed when this function returns, + even if returning an error. Therefore unconditionally close: + */ + psSession->sImp.psDevice->sImp.uiSessionCount--; + psSession->uiState = TZ_STATE_UNDEFINED; + + return TZ_SUCCESS; +} + +tz_return_t +TZManagerDownloadService(INOUT tz_session_t* psSession, + IN void const * kauiData, + uint32_t uiLength, + OUT tz_uuid_t* psServiceId) +{ + + /* ensure basic parameter validity */ + { + if (psSession == NULL + || psSession->uiState == TZ_STATE_INVALID + || !psSession->sImp.bManagerSession + || kauiData == NULL) { + return TZ_ERROR_UNDEFINED; + } + } + + return CBB_OF_SESSION(psSession)->downloadService(psSession, + kauiData, uiLength, + psServiceId); +} + +tz_return_t +TZManagerRemoveService(INOUT tz_session_t* psSession, + IN tz_uuid_t const * pksService) +{ + /* ensure basic param validity */ + { + if (psSession == NULL + || psSession->uiState == TZ_STATE_INVALID + || !psSession->sImp.bManagerSession + || pksService == NULL) { + return TZ_ERROR_UNDEFINED; + } + } + + return CBB_OF_SESSION(psSession)->removeService(psSession, pksService); +} diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/src/tze.c b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/src/tze.c new file mode 100644 index 0000000000..37d0ec700d --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/src/tze.c @@ -0,0 +1,151 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include + +tz_return_t TZESvcLoadAndOpen(tze_dev_svc_sess_t *sess, + const void *kauiSvcData, + uint32_t uiSvcDataLength, + const tze_svc_load_and_open_options_t *options) +{ + tz_return_t rv; + const tze_svc_load_and_open_options_t default_options = + (tze_svc_load_and_open_options_t) { }; + if (!options) + options = &default_options; + + rv = TZDeviceOpen(options->pkDeviceName, options->pkDeviceInit, &sess->tzDevice); + if (rv != TZ_SUCCESS) + return rv; + + /* download service */ + { + tz_session_t tzManagerSession; + + /* open session with device manager */ + rv = TZManagerOpen(&sess->tzDevice, options->pksManagerLogin, &tzManagerSession); + if (rv != TZ_SUCCESS) + return rv; + + /* download */ + rv = TZManagerDownloadService(&tzManagerSession, + kauiSvcData, + uiSvcDataLength, + &sess->tzSvcId); + if (rv != TZ_SUCCESS) { + TZManagerClose(&tzManagerSession); + return rv; + } + + /* close session */ + rv = TZManagerClose(&tzManagerSession); + if (rv != TZ_SUCCESS) + return rv; + } + + /* now open a service handle to the svc */ + { + tz_operation_t op; + tz_return_t serviceReturn; + rv = TZOperationPrepareOpen(&sess->tzDevice, + &sess->tzSvcId, + options->pksSvcLogin, + options->pksSvcTimeLimit, + &sess->tzSession, + &op); + if (rv != TZ_SUCCESS) { + TZDeviceClose(&sess->tzDevice); + return rv; + } + + rv = TZOperationPerform(&op, &serviceReturn); + if (rv != TZ_SUCCESS) { + TZOperationRelease(&op); + TZDeviceClose(&sess->tzDevice); + return rv; + } + + TZOperationRelease(&op); + } + + return TZ_SUCCESS; +} + + +tz_return_t TZEClose(tze_dev_svc_sess_t *sess) +{ + tz_return_t rv = TZ_SUCCESS; + + /* close session */ + { + tz_operation_t op; + tz_return_t serviceReturn; + + rv = rv ?: TZOperationPrepareClose(&sess->tzSession, &op); + rv = rv ?: TZOperationPerform(&op, &serviceReturn); + + TZOperationRelease(&op); + } + + /* unload pal */ + { + tz_session_t tzManagerSession; + + /* open session with device manager */ + rv = rv ?: TZManagerOpen(&sess->tzDevice, NULL, &tzManagerSession); + + /* unload */ + rv = rv ?: TZManagerRemoveService(&tzManagerSession, &sess->tzSvcId); + + /* close session */ + rv = rv ?: TZManagerClose(&tzManagerSession); + } + + /* close device */ + rv = rv ?: TZDeviceClose(&sess->tzDevice); + + return rv; +} diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/tee-sdk-app.pc.in b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/tee-sdk-app.pc.in new file mode 100644 index 0000000000..97fc90c5f3 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/tee-sdk-app.pc.in @@ -0,0 +1,14 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +datarootdir=@datarootdir@ +datadir=@datadir@ +pkgdatadir=@pkgdatadir@ + +Name: tee-sdk-app +Description: used for applications that talk to tee services +Requires: +Version: @PACKAGE_VERSION@ +Libs: -L${libdir}/tee-sdk -ltz +Cflags: -I${includedir} \ No newline at end of file diff --git a/xmhf-64/hypapps/trustvisor/tee-sdk/tz/tee-sdk-svc.pc.in b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/tee-sdk-svc.pc.in new file mode 100644 index 0000000000..01dff59be9 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/tee-sdk/tz/tee-sdk-svc.pc.in @@ -0,0 +1,15 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +datarootdir=@datarootdir@ +datadir=@datadir@ +svc_link_script=@SVC_LINK_SCRIPT@ + +Name: @PACKAGE_NAME@-svc +Description: library for interacting with tz services +Requires: +Version: @PACKAGE_VERSION@ +Libs: -L${libdir}/tee-sdk -lsvc +Cflags: -I${includedir} + diff --git a/xmhf-64/hypapps/trustvisor/test/Makefile b/xmhf-64/hypapps/trustvisor/test/Makefile new file mode 100644 index 0000000000..b15df9a7a0 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/test/Makefile @@ -0,0 +1,65 @@ +# CMOCKDIR:=$(realpath ../../../../tools/cmock) +# UNITYDIR:=$(realpath ../../../../tools/cmock/vendor/unity) +# EMHFROOT:=$(CURDIR)/../../../../emhf/trunk/code + +CFLAGS := -I${UNITYDIR}/src -DUNITY_SUPPORT_64 -g +CFLAGS := $(filter-out -nostdinc,${CFLAGS}) +CFLAGS += -I$(EMHF_ROOT)/libemhfutil/include +CFLAGS += -I$(EMHF_ROOT)/emhfcore/include + +all: do_hpt do_drbg # do_pages do_pt + +# FIXME should create separately compiled objects here, instead of in src dir +#unity.o: ${UNITYDIR}/src/unity.c +#pt.o: ../app/pt.c + +pt: pt_runner.o pt.o ../app/objects/pt.o ${UNITYDIR}/src/unity.o + +hpt: hpt_runner.o hpt.o ${UNITYDIR}/src/unity.o + +drbg: test_drbg_runner.o test_drbg.o ../app/objects/dump.o ${UNITYDIR}/src/unity.o + $(CC) -o $@ $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) $(EMHF_ROOT)/libemhfutil/libemhfutil.a + +pages: test_pages_runner.o test_pages.o ../app/pages.o ../app/puttymem.o ../app/tlsf.o $(EMHF_ROOT)/x86/libcommon/mpsup.o ${UNITYDIR}/src/unity.o + $(CC) -o $@ $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) + +do_%: % + ./$< + +%_runner.c: %.c + ruby ${UNITYDIR}/auto/generate_test_runner.rb $< $@ + + + +#------------------------------------------------------------------------------- +# app top-level makefile for apps based on emhf +# author: Zongwei Zhou (zongweiz@andrew.cmu.edu) + +# app-specific configuration options +# + +# source files +# AS_SOURCES = +# C_SOURCES = appmain.c scode.c puttymem.c \ +# malloc.c pt.c tpm_sw.c aes.c \ +# rsa.c bignum.c sha1.c random.c linuxrelc.c + +# OBJECTS = $(patsubst %.S, $(APPOBJECTSDIR)/%.o, $(AS_SOURCES)) +# OBJECTS += $(patsubst %.c, $(APPOBJECTSDIR)/%.o, $(C_SOURCES)) + +# I_SOURCES = $(wildcard $(EMHF_INCLUDEDIR)/*.h) +# I_SOURCES += $(wildcard $(APP_INCLUDEDIR)/*.h) + +# # targets +# .PHONY: all +# all: $(OBJECTS) + +# $(APPBOJECTSDIR)/%.o: %.S $(I_SOURCES) Makefile ../Makefile +# $(CC) -c $(ASFLAGS) -o $@ $< +%.o: %.c $(I_SOURCES) Makefile ../Makefile + $(CC) -c $(CFLAGS) -o $@ $< + +.PHONY: clean +clean: + $(RM) *.o + $(RM) *_runner.c diff --git a/xmhf-64/hypapps/trustvisor/test/hpt.c b/xmhf-64/hypapps/trustvisor/test/hpt.c new file mode 100644 index 0000000000..835703e424 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/test/hpt.c @@ -0,0 +1,295 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include "unity.h" + +#define __PRINT_H_ /* avoid indirectly including our print.h, which conflicts with libc stdio.h */ + +#define dprintf(...) while(0) + +#include +#include +#include +#include + +#ifndef u32 +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +#endif + +#include + + +/* global CPU structs */ +/* VCPU g_vcpubuffers[0]; */ + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +#define maxu64 0xffffffffffffffffull + +void test_ZERO_HI64(void) +{ + TEST_ASSERT_EQUAL_HEX64(maxu64, ZERO_HI64(maxu64, 0)); + TEST_ASSERT_EQUAL_HEX64(0x7fffffffffffffffull, ZERO_HI64(maxu64, 1)); + TEST_ASSERT_EQUAL_HEX64(0x1ull, ZERO_HI64(maxu64, 63)); +} + +void test_ZERO_LO64(void) +{ + TEST_ASSERT_EQUAL_HEX64(maxu64, ZERO_LO64(maxu64, 0)); + TEST_ASSERT_EQUAL_HEX64(0xfffffffffffffffeull, ZERO_LO64(maxu64, 1)); + TEST_ASSERT_EQUAL_HEX64(0x8000000000000000ull, ZERO_LO64(maxu64, 63)); +} + +void test_MASKRANGE64(void) +{ + TEST_ASSERT_EQUAL_HEX64(0xffffffffffffffffull, MASKRANGE64(63, 0)); + TEST_ASSERT_EQUAL_HEX64(0x7fffffffffffffffull, MASKRANGE64(62, 0)); + TEST_ASSERT_EQUAL_HEX64(0x3ull, MASKRANGE64(1, 0)); + TEST_ASSERT_EQUAL_HEX64(0x1ull, MASKRANGE64(0, 0)); + + TEST_ASSERT_EQUAL_HEX64(0x700ull, MASKRANGE64(10, 8)); + TEST_ASSERT_EQUAL_HEX64(0x8000000000000000ull, MASKRANGE64(63, 63)); +} + +void test_BR64_GET_HL(void) +{ + TEST_ASSERT_EQUAL_HEX64(0x1, BR64_GET_HL(maxu64, 0, 0)); + TEST_ASSERT_EQUAL_HEX64(0x1, BR64_GET_HL(maxu64, 1, 1)); + TEST_ASSERT_EQUAL_HEX64(0x1, BR64_GET_HL(maxu64, 63, 63)); + + TEST_ASSERT_EQUAL_HEX64(0x3, BR64_GET_HL(maxu64, 1, 0)); + TEST_ASSERT_EQUAL_HEX64(0x3, BR64_GET_HL(maxu64, 63, 62)); + TEST_ASSERT_EQUAL_HEX64(0x3, BR64_GET_HL(maxu64, 32, 31)); + + TEST_ASSERT_EQUAL_HEX64(maxu64, BR64_GET_HL(maxu64, 63, 0)); +} + +void test_BR64_SET_HL(void) +{ + TEST_ASSERT_EQUAL_HEX64(0x1, BR64_SET_HL(0, 0, 0, 1)); + TEST_ASSERT_EQUAL_HEX64(0x0, BR64_SET_HL(0, 0, 0, 0)); + TEST_ASSERT_EQUAL_HEX64(0x8000000000000000ull, BR64_SET_HL(0, 63, 63, 1)); + + TEST_ASSERT_EQUAL_HEX64(0x700ull, BR64_SET_HL(0, 10, 8, 7)); +} + +void test_BR64_COPY_BITS_HL(void) +{ + TEST_ASSERT_EQUAL_HEX64(0, BR64_COPY_BITS_HL(0x0ull, 0x0ull, 0, 0, 0)); + TEST_ASSERT_EQUAL_HEX64(1, BR64_COPY_BITS_HL(0x0ull, 0x1ull, 0, 0, 0)); + TEST_ASSERT_EQUAL_HEX64(2, BR64_COPY_BITS_HL(0x0ull, 0x1ull, 0, 0, 1)); + + TEST_ASSERT_EQUAL_HEX64(0x1, BR64_COPY_BITS_HL(0x0ull, 0x7ull, 0, 0, 0)); + TEST_ASSERT_EQUAL_HEX64(0x700, BR64_COPY_BITS_HL(0x0ull, 0x7ull, 2, 0, 8)); +} + +void test_BR64_GET_BIT(void) +{ + TEST_ASSERT_EQUAL_HEX64(0x0, BR64_GET_BIT(0xfffffffffffffffeull, 0)); + TEST_ASSERT_EQUAL_HEX64(0x0, BR64_GET_BIT(0x7fffffffffffffffull, 63)); +} + +void test_BR64_SET_BIT(void) +{ + TEST_ASSERT_EQUAL_HEX64(0x7fffffffffffffffull, BR64_SET_BIT(0xffffffffffffffffull, 63, 0)); + TEST_ASSERT_EQUAL_HEX64(0xffffffffffffffffull, BR64_SET_BIT(0x7fffffffffffffffull, 63, 1)); +} + +void test_hpt_setprot(void) +{ + +} + +void test_hpt_getprot_intel(void) +{ + TEST_ASSERT_EQUAL_HEX64(0x0, hpt_pme_getprot(HPT_TYPE_EPT, 1, 0xfffffffffffffff8ull)); + + TEST_ASSERT_EQUAL_HEX64(HPT_PROTS_R, hpt_pme_getprot(HPT_TYPE_EPT, 1, 0xfffffffffffffff9ull)); + TEST_ASSERT_EQUAL_HEX64(HPT_PROTS_W, hpt_pme_getprot(HPT_TYPE_EPT, 1, 0xfffffffffffffffaull)); + TEST_ASSERT_EQUAL_HEX64(HPT_PROTS_X, hpt_pme_getprot(HPT_TYPE_EPT, 1, 0xfffffffffffffffcull)); + + TEST_ASSERT_EQUAL_HEX64(HPT_PROTS_RWX, hpt_pme_getprot(HPT_TYPE_EPT, 1, 0xffffffffffffffffull)); +} + +void test_hpt_getprot_amd(void) +{ + TEST_ASSERT_EQUAL_HEX64(0x0, hpt_pme_getprot(HPT_TYPE_LONG, 1, 0xfffffffffffffffcull)); + + TEST_ASSERT_EQUAL_HEX64(HPT_PROTS_R, hpt_pme_getprot(HPT_TYPE_LONG, 1, 0xfffffffffffffffdull)); + TEST_ASSERT_EQUAL_HEX64(HPT_PROTS_W, hpt_pme_getprot(HPT_TYPE_LONG, 1, 0xfffffffffffffffeull)); + TEST_ASSERT_EQUAL_HEX64(HPT_PROTS_X, hpt_pme_getprot(HPT_TYPE_LONG, 1, 0x7ffffffffffffffcull)); + + TEST_ASSERT_EQUAL_HEX64(HPT_PROTS_RWX, hpt_pme_getprot(HPT_TYPE_LONG, 1, 0x7fffffffffffffffull)); +} + +void test_hpt_setprot_amd(void) +{ + /* none to none */ + TEST_ASSERT_EQUAL_HEX64(0x8000000000000000ull, + hpt_pme_setprot(HPT_TYPE_LONG, 1, 0x0ull, HPT_PROTS_NONE)); + + /* none to one */ + TEST_ASSERT_EQUAL_HEX64(0x8000000000000001ull, + hpt_pme_setprot(HPT_TYPE_LONG, 1, 0x0ull, HPT_PROTS_R)); + TEST_ASSERT_EQUAL_HEX64(0x8000000000000003ull, + hpt_pme_setprot(HPT_TYPE_LONG, 1, 0x0ull, HPT_PROTS_RW)); + TEST_ASSERT_EQUAL_HEX64(0x0000000000000001ull, + hpt_pme_setprot(HPT_TYPE_LONG, 1, 0x0ull, HPT_PROTS_RX)); + + /* none to all */ + TEST_ASSERT_EQUAL_HEX64(0x0000000000000003ull, + hpt_pme_setprot(HPT_TYPE_LONG, 1, 0x0ull, HPT_PROTS_RWX)); + + /* none to none */ + TEST_ASSERT_EQUAL_HEX64(0xfffffffffffffffcull, + hpt_pme_setprot(HPT_TYPE_LONG, + 1, + 0xfffffffffffffffcull, + HPT_PROTS_NONE)); + + /* none to one */ + TEST_ASSERT_EQUAL_HEX64(0xfffffffffffffffdull, + hpt_pme_setprot(HPT_TYPE_LONG, + 1, + 0xfffffffffffffffcull, + HPT_PROTS_R)); + TEST_ASSERT_EQUAL_HEX64(0xffffffffffffffffull, + hpt_pme_setprot(HPT_TYPE_LONG, + 1, + 0xfffffffffffffffcull, + HPT_PROTS_RW)); + TEST_ASSERT_EQUAL_HEX64(0x7ffffffffffffffdull, + hpt_pme_setprot(HPT_TYPE_LONG, + 1, + 0xfffffffffffffffcull, + HPT_PROTS_RX)); + + /* none to all */ + TEST_ASSERT_EQUAL_HEX64(0x7fffffffffffffffull, + hpt_pme_setprot(HPT_TYPE_LONG, + 1, + 0xfffffffffffffffcull, + HPT_PROTS_RWX)); + + /* all to none */ + TEST_ASSERT_EQUAL_HEX64(0xfffffffffffffffcull, + hpt_pme_setprot(HPT_TYPE_LONG, + 1, + 0x7ffffffffffffffcull, + HPT_PROTS_NONE)); + +} + +void test_hpt_getunused(void) +{ + TEST_ASSERT_EQUAL_HEX64(0x7, hpt_pme_getunused(HPT_TYPE_EPT, 1, 0x0000000000000e00ull, 2, 0)); + TEST_ASSERT_EQUAL_HEX64(0x7, hpt_pme_getunused(HPT_TYPE_EPT, 1, 0xffffffffffffffffull, 2, 0)); + + TEST_ASSERT_EQUAL_HEX64(0x5, hpt_pme_getunused(HPT_TYPE_LONG, 1, 0x0000000000000a00ull, 2, 0)); + TEST_ASSERT_EQUAL_HEX64(0x5, hpt_pme_getunused(HPT_TYPE_LONG, 1, 0x0000000000000a00ull, 2, 0)); +} + +void test_pm_size(void) +{ + TEST_ASSERT_EQUAL_INT(4096, hpt_pm_size(HPT_TYPE_EPT, 1)); + TEST_ASSERT_EQUAL_INT(4096, hpt_pm_size(HPT_TYPE_EPT, 2)); + TEST_ASSERT_EQUAL_INT(4096, hpt_pm_size(HPT_TYPE_EPT, 3)); + TEST_ASSERT_EQUAL_INT(4096, hpt_pm_size(HPT_TYPE_EPT, 4)); +} + +void test_pme_get_address(void) +{ + TEST_ASSERT_EQUAL_HEX64(0x000ffffffffff000ull, hpt_pme_get_address(HPT_TYPE_EPT, 1, 0xffffffffffffffffull)); + TEST_ASSERT_EQUAL_HEX64(0x000ffffffffff000ull, hpt_pme_get_address(HPT_TYPE_EPT, 2, 0xffffffffffffffffull)); + TEST_ASSERT_EQUAL_HEX64(0x000ffffffffff000ull, hpt_pme_get_address(HPT_TYPE_EPT, 3, 0xffffffffffffffffull)); + TEST_ASSERT_EQUAL_HEX64(0x000ffffffffff000ull, hpt_pme_get_address(HPT_TYPE_EPT, 4, 0xffffffffffffffffull)); + + TEST_ASSERT_EQUAL_HEX64(0x000ffffffffff000ull, hpt_pme_get_address(HPT_TYPE_EPT, 4, 0x000ffffffffff000ull)); + TEST_ASSERT_EQUAL_HEX64(0x000ffff0fffff000ull, hpt_pme_get_address(HPT_TYPE_EPT, 4, 0x000ffff0fffff000ull)); +} + +void test_pme_set_address(void) +{ + TEST_ASSERT_EQUAL_HEX64(0x000ffffffffff000ull, hpt_pme_set_address(HPT_TYPE_EPT, 1, 0x0ull, 0x000ffffffffff000ull)); + TEST_ASSERT_EQUAL_HEX64(0x000ffffffffff000ull, hpt_pme_set_address(HPT_TYPE_EPT, 1, 0x0ull, 0xffffffffffffffffull)); +} + +void test_get_pm_idx(void) +{ + TEST_ASSERT_EQUAL_HEX64(0x1ff, hpt_get_pm_idx(HPT_TYPE_EPT, 1, 0x1ffull<<12)); + TEST_ASSERT_EQUAL_HEX64(0x1ff, hpt_get_pm_idx(HPT_TYPE_EPT, 2, 0x1ffull<<12<<9)); + TEST_ASSERT_EQUAL_HEX64(0x1ff, hpt_get_pm_idx(HPT_TYPE_EPT, 3, 0x1ffull<<12<<9<<9)); + TEST_ASSERT_EQUAL_HEX64(0x1ff, hpt_get_pm_idx(HPT_TYPE_EPT, 4, 0x1ffull<<12<<9<<9<<9)); +} + +void test_get_pme_by_va(void) +{ + u64 pm[512] = { [0x100] = 0xdeadbeeff00dd00dull, [0x1ff] = 0xffffffffffffffffull }; + TEST_ASSERT_EQUAL_HEX64(0xffffffffffffffffull, hpt_pm_get_pme_by_va(HPT_TYPE_EPT, 1, pm, 0x1ffull<<12)); + TEST_ASSERT_EQUAL_HEX64(0xdeadbeeff00dd00dull, hpt_pm_get_pme_by_va(HPT_TYPE_EPT, 2, pm, 0x100ull<<12<<9)); +} + +void test_set_pme_by_va(void) +{ + u64 pm[512]; + hpt_pm_set_pme_by_va(HPT_TYPE_EPT, 2, pm, 0x50ull<<12<<9, 0xdeadbeeff00dd00dull); + TEST_ASSERT_EQUAL_HEX64(pm[0x50], 0xdeadbeeff00dd00dull); +} + +void test_cr3_set_address(void) +{ + TEST_ASSERT_EQUAL_HEX64(0xffffffe0, + hpt_cr3_set_address(HPT_TYPE_PAE, 0, 0xffffffff)); +} diff --git a/xmhf-64/hypapps/trustvisor/test/nist_test_vectors.h b/xmhf-64/hypapps/trustvisor/test/nist_test_vectors.h new file mode 100644 index 0000000000..d59bb4c8c5 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/test/nist_test_vectors.h @@ -0,0 +1,255 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +EntropyInputLen256NonceLen128PersonalizationStringLen0AdditionalInputLen0_t count0 = { + "\x5a\x19\x4d\x5e\x2b\x31\x58\x14\x54\xde\xf6\x75\xfb\x79\x58\xfe\xc7\xdb\x87\x3e\x56\x89\xfc\x9d\x03\x21\x7c\x68\xd8\x03\x38\x20", + "\x1b\x54\xb8\xff\x06\x42\xbf\xf5\x21\xf1\x5c\x1c\x0b\x66\x5f\x3f", + "", + "", + "\xb8\x39\xfa\x3b\x11\xb7\x7a\xc8\x0f\x10\x1e\x14\xaf\xa7\xf8\x52\x11\x04\x8d\x74\x5d\x8e\xaa\xa4\xbd\xa9\xdc\xa2\xa5\x62\x59\xc1", + "\xb0\xee\x8d\xfa\x67\xec\xfd\x5c\x8d\xca\x69\xad\xc0\xb7\x5e\x8d", + "\x3f\x6d\xb5\x2d\xff\x53\xae\x68\xe9\x2a\xbc\xd8\x13\x1e\xf8\xbf", + "\xf9\xe6\x5e\x04\xd8\x56\xf3\xa9\xc4\x4a\x4c\xbd\xc1\xd0\x08\x46\xf5\x98\x3d\x77\x1c\x1b\x13\x7e\x4e\x0f\x9d\x8e\xf4\x09\xf9\x2e", + "", + "", + "\xa0\x54\x30\x3d\x8a\x7e\xa9\x88\x9d\x90\x3e\x07\x7c\x6f\x21\x8f" +}; + +EntropyInputLen256NonceLen128PersonalizationStringLen0AdditionalInputLen0_t count1 = { + "\x93\xb7\x05\x5d\x78\x88\xae\x23\x4b\xfb\x43\x1e\x37\x90\x69\xd0\x0a\xe8\x10\xfb\xd4\x8f\x2e\x06\xc2\x04\xbe\xae\x3b\x0b\xfa\xf0", + "\x90\xbc\x3b\x55\x5b\x9d\x6b\x6a\xeb\x17\x74\xa5\x83\xf9\x8c\xad", + "", + "", + "\x54\xd0\x91\x23\x2a\xb8\x09\x27\xe3\xeb\x8f\x71\x3d\x42\x04\xa2\x58\x8c\x99\x4b\x98\x30\xb2\xdb\x84\x20\xf7\x7f\xbd\x51\x18\x73", + "\x5d\xeb\xa5\xd0\xdd\x46\x12\x05\xab\x3f\xbf\x20\xf7\x59\x71\x3c", + "\xbb\xaa\x55\x39\x3c\xfe\x8f\x1c\xbe\x25\x7c\x7c\x1b\xd2\x07\xc9", + "\x91\xd1\xd0\xe8\x53\x52\x5e\xad\x0e\x7f\x79\xab\xb0\xf0\xbf\x68\x06\x45\x76\x33\x9c\x35\x85\xcf\xd6\xd9\xb5\x5d\x4f\x39\x27\x8d", + "", + "", + "\xaa\xf2\x7f\xc2\xbf\x64\xb0\x32\x0d\xd3\x56\x4b\xb9\xb0\x33\x77", +}; + +EntropyInputLen256NonceLen128PersonalizationStringLen0AdditionalInputLen0_t count2 = { + "\x58\x36\x4c\xee\xfa\xd3\x75\x81\xc5\x18\xb7\xd4\x2a\xc4\xf9\xaa\xe2\x2b\xef\xd8\x4c\xbc\x98\x6c\x08\xd1\xfb\x20\xd3\xbd\x24\x00", + "\x4a\x2a\x7d\xcb\xde\x58\xb8\xb3\xc3\xf4\x69\x7b\xeb\x67\xbb\xa2", + "", + "", + "\x7e\xe9\x98\x24\x0e\x9e\x8c\x32\x98\xd6\xb3\x5b\xae\xbe\x8b\x16\x2e\x9f\xc7\x72\x6c\xae\xd6\x45\xcd\xfd\xbf\x7a\x5e\x36\x95\x93", + "\x5d\x29\xc6\x61\x33\xef\x17\x5a\xdb\x55\xd2\xb4\xb2\xbd\x93\x8e", + "\xc0\xca\x20\x03\x43\xc7\x2b\x55\x52\x3c\xef\x09\x2e\xf4\xc4\xbd", + "\xa8\x99\xba\xfd\x47\x02\x78\xfa\xd8\xf0\xa5\x0f\x84\x90\xaf\x29\xf9\x38\x47\x1b\x40\x75\x65\x4f\xda\x57\x7d\xad\x20\xfa\x01\xca", + "", + "", + "\x20\xc5\x11\x7a\x8a\xca\x72\xee\x5a\xb9\x14\x68\xda\xf4\x4f\x29", +}; + +EntropyInputLen256NonceLen128PersonalizationStringLen0AdditionalInputLen0_t count3 = { + "\x2f\x04\x4b\x86\x51\xe1\xc9\xd9\x93\x17\x08\x4c\xc6\xc4\xfa\x1f\x50\x2d\xd6\x24\x66\xa5\x7d\x4b\x88\xbc\x0d\x70\x3c\xab\xc5\x62", + "\x91\x1f\xaa\xb1\x34\x7a\xe2\xb3\x09\x3a\x60\x7c\x8b\xc7\x7b\xfe", + "", + "", + "\x18\x8e\x99\x4d\x22\x4c\x3e\xd6\xce\x72\x29\xd2\xf1\xfe\x89\xa0\x66\xfb\x55\xc2\xd3\x11\xa8\x79\x4c\xb0\x9f\xc9\x1f\x9d\x1f\x77", + "\xb0\x68\xe8\x78\xb2\xaf\x5a\x17\xbf\x3a\x57\x9d\x3b\x86\xbc\xb3", + "\x4a\x0d\xc1\x4f\x06\xeb\xf8\x98\x0a\x66\x69\x11\x4e\x40\x6e\x6d", + "\x70\x82\x01\xac\x19\xcd\xb5\xcf\x91\x8f\xae\x29\xc0\x09\xfb\x1a\x2c\xf4\x2f\xd7\x14\xcc\x9a\x53\xca\x5a\xcb\x71\x54\x82\x45\x6a", + "", + "", + "\xaa\xe0\xc0\xac\x97\xf5\x3d\x22\x2b\x83\x57\x8a\x2b\x3d\xd0\x5d" +}; + +EntropyInputLen256NonceLen128PersonalizationStringLen0AdditionalInputLen0_t count4 = { + "\x77\xd0\xf0\xef\xbc\x7c\xa7\x94\xa5\x1d\xff\x96\xe8\x5b\x8e\x7d\xfd\x48\x75\xfb\xfb\x6e\x55\x93\xae\x17\x90\x8b\xfb\xdd\xc3\x13", + "\xf9\x59\xf1\xbc\x10\x0a\xe3\x00\x88\x01\x7f\xae\x51\x28\x9d\x8e", + "", + "", + "\x58\x6e\x52\xf2\xdf\x17\x68\x6c\x07\x23\x71\x44\xe4\xe7\x87\x64\x96\x10\x1d\x59\xb3\x4e\x46\x33\x71\xde\xb0\x60\xe1\xb0\x54\x0a", + "\x71\xca\x05\xee\x3e\x09\x2d\x68\x53\xa4\xe9\x99\x46\x91\xd3\xc2", + "\x36\xed\x09\x82\x3a\x74\x18\x69\xf7\x8a\x33\x77\x46\x36\xbd\x68", + "\xe0\x51\xcb\x7d\x65\x9c\x83\x81\x80\xd8\x34\xfd\xd9\x87\xae\x3c\x7f\x60\x5a\xaa\x1b\x3a\x93\x65\x75\x38\x4b\x00\x2a\x35\xdd\x98", + "", + "", + "\x5d\x80\xbc\x3f\xff\xa4\x2b\x89\xcc\xb3\x90\xe8\x44\x7e\x33\xe5" +}; + +EntropyInputLen256NonceLen128PersonalizationStringLen0AdditionalInputLen0_t count5 = { + "\x6b\xb1\x4d\xc3\x4f\x66\x97\x59\xf8\xfa\x54\x53\xc4\x89\x9e\xb5\xac\x4e\x33\xa6\x9e\x35\xe8\x9b\x19\xa4\x6d\xbd\x08\x88\x42\x9d", + "\x45\xa8\xbb\x33\x06\x27\x83\xee\xde\x09\xb0\x5a\x35\xbd\x44\xdd", + "", + "", + "\x4b\xf9\xaa\x62\xd0\x14\x03\x7b\x23\x2c\x6c\x77\x4d\x76\x0f\x11\xb6\x78\x25\x5b\x49\x49\x7d\xa3\xd7\x30\xf9\x4a\x51\xd1\xe8\xc9", + "\xb9\x8a\x33\xeb\x7c\x7d\xfe\x42\xea\x20\x39\xe1\xd3\x00\xd4\x64", + "\x76\xb0\x4f\x4a\xb4\xef\x30\xbf\x18\x94\x49\xbe\xb0\x4c\x1e\x80", + "\x13\x67\xf7\xf3\x19\x1e\x91\x1b\x3b\x35\x5b\x6e\x3b\x24\x26\xe2\x42\xef\x41\x40\xdd\xcc\x96\x76\x37\x11\x01\x20\x96\x62\xf2\x53", + "", + "", + "\x0d\xfa\x99\x55\xa1\x3a\x9c\x57\xa3\x54\x6a\x04\x10\x8b\x8e\x9e" +}; + +EntropyInputLen256NonceLen128PersonalizationStringLen0AdditionalInputLen0_t count6 = { + "\xb3\xd0\x1b\xcb\x1e\xc7\x47\xfd\xb7\xfe\xb5\xa7\xde\x92\x80\x7a\xfa\x43\x38\xab\xa1\xc8\x1c\xe1\xeb\x50\x95\x5e\x12\x5a\xf4\x6b", + "\x0a\xda\x12\x9f\x99\x48\x07\x3d\x62\x8c\x11\x27\x4c\xec\x3f\x69", + "", + "", + "\x8f\x05\x68\x1c\x0b\x4d\x6d\x7b\xdf\x16\x09\x74\xfb\xd6\xe9\xe9\x07\xab\x2b\xd9\x2b\x76\x58\xa2\xd3\xaf\xa1\xce\x8c\x06\x52\x13", + "\xa0\xcc\x87\x8f\x11\x9a\x82\x67\xd6\x13\x1c\xcf\xaf\x8b\x46\x63", + "\x33\x39\x31\xe1\x19\x7e\x46\x6f\x0c\x72\xd2\xe1\xa8\x6c\x32\x75", + "\x19\xae\xd8\x91\x36\x6e\xc0\xf7\x0b\x07\x90\x37\xa5\xae\xb3\x3f\x07\xf4\xc8\x94\xfd\xcd\xa3\xff\x41\xe2\x86\x7a\xce\x1a\xa0\x5c", + "", + "", + "\xf3\x47\x10\xc9\xeb\xf9\xd5\xaa\xa5\xf7\x97\xfd\x85\xa1\xc4\x13" +}; + +EntropyInputLen256NonceLen128PersonalizationStringLen0AdditionalInputLen0_t count7 = { + "\x98\x48\x2e\x58\xe4\x4b\x8e\x4a\x6b\x09\xfa\x02\xc0\x5f\xcc\x49\x1d\xa0\x3a\x47\x9a\x7f\xad\x13\xa8\x3b\x60\x80\xd3\x0b\x3b\x25", + "\x05\x2a\x5a\xd4\xcd\x38\xde\x90\xe5\xd3\xc2\xfc\x43\x0f\xa5\x1e", + "", + "", + "\xd4\x18\x18\x1a\x5b\xb1\x76\xd2\xd9\x21\x51\xfa\xf4\xbc\x94\xad\x4e\x26\x2a\xb9\x77\x9c\x0a\x81\x31\x3f\xd1\xb7\xfe\x38\x59\x92", + "\x15\xb9\x09\x2b\x2e\x98\xf2\xb2\x71\xd5\xea\x8c\x4c\x3b\xb6\x9a", + "\xff\x33\xbc\x0f\xd4\x35\xb2\x13\x19\xd1\x9d\xb7\xed\xde\xde\x51", + "\x5e\x01\xa4\x35\x68\xa9\xd6\xdd\x5c\xec\xf9\x9b\x0c\xe9\xfd\x59\x4d\x69\xef\xf8\xfa\x88\x15\x9b\x2d\xa2\x4c\x33\xba\x81\xa1\x4d", + "", + "", + "\x3f\x55\x14\x4e\xec\x26\x3a\xed\x50\xf9\xc9\xa6\x41\x53\x8e\x55" +}; + +EntropyInputLen256NonceLen128PersonalizationStringLen0AdditionalInputLen0_t count8 = { + "\x62\x38\xd4\x48\x01\x5e\x86\xaa\x16\xaf\x62\xcd\xc2\x87\xf1\xc1\x7b\x78\xa7\x98\x09\xfa\x00\xb8\xc6\x55\xe0\x67\x15\xcd\x2b\x93", + "\x00\x4c\xd2\xf2\x8f\x08\x3d\x1c\xee\x68\x97\x5d\x5c\xbb\xbe\x4f", + "", + "", + "\xb7\x83\xcb\x2c\x81\x4e\x76\x30\xc5\x99\xa1\x09\xf3\x81\xe3\xa9\x97\xe9\x38\xf1\x1f\x7e\xad\xc1\x2c\x17\x5b\x61\xe7\x79\x60\x54", + "\x97\xa0\xf1\x4d\x77\xc0\x36\xd5\x57\x33\x1b\x83\x28\x8e\xc0\xe6", + "\x98\x9f\x7c\x9a\x33\x7f\xdd\xa8\x26\x84\xdf\xfd\x24\x4f\x4f\x9a", + "\x5b\xf4\xdf\x96\x6e\x3e\xc1\xf1\x4b\x28\xcc\x1d\x08\x0f\x88\x2a\x72\x15\xe2\x58\x43\x0c\x91\xa4\xa0\xa2\xaa\x98\xd7\xcd\x80\x53", + "", + "", + "\xb1\x37\x11\x9d\xbb\xd9\xd7\x52\xa8\xdf\xce\xec\x05\xb8\x84\xb6" +}; + +EntropyInputLen256NonceLen128PersonalizationStringLen0AdditionalInputLen0_t count9 = { + "\x50\xd3\xc4\xec\xb1\xd6\xe9\x5a\xeb\xb8\x7e\x9e\x8a\x5c\x86\x9c\x11\xfb\x94\x5d\xfa\xd2\xe4\x5e\xe9\x0f\xb6\x19\x31\xfc\xed\xd4", + "\xf9\x85\xb3\xea\x2d\x8b\x15\xdb\x26\xa7\x18\x95\xa2\xff\x57\xcd", + "", + "", + "\x5f\xf5\x31\xbf\x12\xda\x7c\xaa\x99\xf9\x0c\x27\xb9\x4e\xea\x26\x69\xf4\x98\xa4\xe1\xae\x13\x64\xe6\x65\x8e\xf8\x75\xb4\x90\x06", + "\xa2\x9d\xf5\x0e\xa8\x45\x5b\x02\x68\x97\x4e\xd6\x00\x68\x04\x71", + "\xeb\x60\xf8\xa9\xa5\x6b\xe8\x0f\x4a\x3a\xd4\x75\xf9\xcb\xf4\x7b", + "\x7d\x60\x05\xaa\x5d\xf2\x4b\xb9\xef\xc1\x1b\xbb\x96\xbb\x21\x06\x5d\x44\xe2\x53\x2a\x1e\x17\x49\x3f\x97\x4a\x4b\xf8\xf8\xb5\x80", + "", + "", + "\xeb\x41\x96\x28\xfb\xc4\x41\xae\x6a\x03\xe2\x6a\xee\xcb\x34\xa6" +}; + +EntropyInputLen256NonceLen128PersonalizationStringLen0AdditionalInputLen0_t count10 = { + "\xd2\x7c\xbe\xac\x39\xa6\xc8\x99\x93\x81\x97\xf0\xe6\x1d\xc9\x0b\xe3\xa3\xa2\x0f\xa5\xc5\xe1\xf7\xa7\x6a\xdd\xe0\x05\x98\xe5\x95", + "\x10\x0f\x19\x69\x91\xb6\xe9\x6f\x8b\x96\xa3\x45\x6f\x6e\x2b\xaf", + "", + "", + "\x62\xc4\x59\xd5\x11\x81\xba\x31\xad\x16\xd4\xd2\xc3\xb4\xfb\x7a\x89\x4b\x19\xc4\x62\x21\x8a\xd3\x17\x7c\x2c\x12\xb0\xa8\x22\x33", + "\x40\x1b\xde\x26\x1b\x6e\xb2\x2e\x24\xda\xe4\xbe\x44\x50\xbf\xbc", + "\x3e\xa5\xb6\xe1\x33\xb8\xfe\x9c\x8d\xa9\xec\x61\xdd\x39\x56\x66", + "\x55\xc1\xe9\xfd\x10\x2d\x4b\x52\xe1\xae\x9f\xb0\x04\xbe\x89\x44\xba\xd8\x5c\x58\xe3\x41\xd1\xbe\xe0\x14\x05\x7d\xa9\x8e\xb3\xbc", + "", + "", + "\xe3\xe0\x9d\x0e\xd8\x27\xe4\xf2\x4a\x20\x55\x3f\xd1\x08\x7c\x9d" +}; + +EntropyInputLen256NonceLen128PersonalizationStringLen0AdditionalInputLen0_t count11 = { + "\x16\xf9\xf5\x35\x4d\x62\x4c\x5a\xb1\xf8\x2c\x75\x0e\x05\xf5\x1f\x2a\x2e\xec\xa7\xe5\xb7\x74\xfd\x96\x14\x8d\xdb\xa3\xb3\x8d\x34", + "\x88\xf5\x5d\x9b\xa8\xfe\xf7\x82\x84\x83\x29\x83\x21\x13\x3f\xec", + "", + "", + "\x84\x90\x76\x88\xfe\x5a\x28\x1e\x02\x2e\xac\x7e\x26\x01\xd2\x00\xb1\x6d\x92\x52\x3d\x56\x18\xfa\xe3\x54\x9f\x37\xea\x4f\x1b\x3a", + "\x2e\x20\x1b\xf3\x8d\x99\x62\xc3\x71\xfc\x4e\x5d\x69\x76\x6b\xb8", + "\xbc\x96\x87\x39\xf1\x61\xea\x4b\x21\xcc\x71\x14\xab\x6f\x68\x14", + "\xba\x7f\x14\x72\x56\x7c\x52\x08\x72\x52\x48\x0d\x30\x5a\xd1\xc6\x9e\x4a\xac\x84\x72\xa1\x54\xae\x03\x51\x1d\x0e\x8a\xac\x90\x5a", + "", + "", + "\x07\xcd\x82\x10\x12\xef\x03\xf1\x6d\x85\x10\xc2\x3b\x86\xba\xf3" +}; + +EntropyInputLen256NonceLen128PersonalizationStringLen0AdditionalInputLen0_t count12 = { + "\x70\xaf\xbc\x83\xbf\x9f\xf0\x95\x35\xd6\xf0\xdd\xc5\x12\x78\xad\x79\x09\xf1\x1e\x6f\x19\x8b\x59\x13\x2c\x9e\x26\x9d\xeb\x41\xba", + "\x12\x64\x79\xab\xd7\x0b\x25\xac\xd8\x91\xe1\xc4\xc9\x20\x44\xf9", + "", + "", + "\xf9\x86\x8b\xa0\xea\xdd\x24\xcb\x99\xbb\x86\x2b\x14\x2a\x1c\x2b\x2c\x4d\xf2\x26\xc4\x1a\x6f\xb2\xb8\xe6\x02\xd6\x31\x1a\x4d\xd1", + "\xf0\xb8\x9f\x17\xbd\xe2\xf5\x4e\xd9\x9b\xc9\x0f\x91\x55\x71\x87", + "\x42\x1e\x5b\x2e\xb2\x4b\x1a\xe1\x95\x68\xc4\x3e\x38\x33\x09\x53", + "\x90\x1c\x62\x34\x62\x83\xe2\x93\xb8\x71\x4f\xd3\x24\x1a\xe8\x70\xf9\x74\xff\x33\xc3\x5f\x9a\xff\x05\x14\x4b\xe0\x39\xd2\x4e\x50", + "", + "", + "\x0f\x90\xdf\x35\x07\x41\xd8\x85\x52\xa5\xb0\x3b\x64\x88\xe9\xfb" +}; + +EntropyInputLen256NonceLen128PersonalizationStringLen0AdditionalInputLen0_t count13 = { + "\x5e\x5a\x9e\x1e\x3c\xb8\x07\x38\xc2\x38\x46\x4e\xde\x1b\x6b\x6a\x32\x12\x61\xa3\xb0\x06\xa9\x8a\x79\x26\x5a\xd1\xf6\x35\x57\x3b", + "\xa4\x5f\x2f\xca\x55\x30\x89\xfe\x04\xe7\x83\x20\x59\xdc\x79\x76", + "", + "", + "\x0c\x76\xba\x02\xd4\x81\xdb\xef\x99\x1d\xf2\x1c\x92\x4b\x8f\x98\x02\xb9\x0a\x39\x73\x35\x49\xc3\xc7\xfa\x3a\xf4\xd4\x5f\x71\x12", + "\xc5\x95\xe1\x96\xa9\x6f\x74\xab\x53\x65\x4b\xf2\x68\x65\x35\x32", + "\x63\xb1\x19\x45\xb3\x24\x02\x0f\xc8\x03\x26\x39\xe9\x39\x27\x27", + "\xba\x48\xdc\xcf\x17\xb1\x2f\x68\x68\x47\x82\x52\xf5\x56\xb7\x7c\x3e\xc5\x7a\x3b\xf6\xbb\x65\x99\x42\x94\x53\xdb\x2d\x05\x03\x52", + "", + "", + "\x6e\xb8\x5a\xe2\x40\x6c\x43\x81\x4b\x68\x7f\x74\xf4\xe9\x42\xbc" +}; + +EntropyInputLen256NonceLen128PersonalizationStringLen0AdditionalInputLen0_t count14 = { + "\x31\xcf\xe6\x0e\x5e\xd1\x2f\xf3\x7d\x7f\x22\x70\x96\x3d\xef\x59\x87\x26\x32\x0c\x02\xb9\x10\xb5\xc6\xc7\x95\xe2\x20\x9b\x4b\x4a", + "\x52\xdb\xb4\x32\x41\x00\x24\x15\x96\x6e\xae\xc2\x61\x5a\xba\x27", + "", + "", + "\xb1\xca\xdb\x20\xa5\xf0\x24\x8a\x4e\x35\x18\xdb\x5f\xcb\x00\x5b\x51\x48\xe8\x23\x3a\xf7\x1e\x98\xed\xb5\x0a\xc3\x3c\x8b\x5c\x22", + "\xcb\xea\x05\x67\x4c\x8b\xcb\x1e\x00\x4c\x0f\xb1\x56\x58\x76\xb4", + "\x8f\x45\x25\x71\x14\x77\x33\x78\x3b\xe6\x1e\x68\x1a\x36\xd4\xdf", + "\x95\x86\x6c\x64\xcb\x09\x7a\xf1\xd6\x40\x4d\x1e\x61\x82\xed\xf9\x60\x0e\x18\x55\x34\x53\x75\xb2\x01\x80\x1d\x6f\x4c\x4e\x4b\x32", + "", + "", + "\x2a\x27\x0f\x5e\xf8\x15\x66\x5d\xdd\x07\x52\x7c\x48\x71\x9a\xb1" +}; diff --git a/xmhf-64/hypapps/trustvisor/test/pt.c b/xmhf-64/hypapps/trustvisor/test/pt.c new file mode 100644 index 0000000000..b2e191dc87 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/test/pt.c @@ -0,0 +1,317 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include "unity.h" + +#define __PRINT_H_ /* avoid indirectly including our print.h, which conflicts with libc stdio.h */ +#include + +/* run time parameter block. we'll mock this up as needed */ +RPB __rpb; +RPB *rpb = &__rpb; + +/* global CPU structs */ +VCPU g_vcpubuffers[0]; + +#define BR64_GET(x64, name) BR64_GET_HL(x64, name##_HI, name##_LO) +#define BR64_SET(x64, name, val) BR64_SET_HL(x64, name##_HI, name##_LO, val) + +/* do-nothing mock */ +void xmhf_hwpgtbl_flushall(VCPU *vcpu) +{ +} + +static u64 get_addr(u64 entry, u32 hi, u32 lo) +{ + return BR64_GET_HL(entry, hi, lo) << lo; +} +static u64 set_addr(u64 entry, u32 hi, u32 lo, u64 val) +{ + HALT_ON_ERRORCOND((BR64_GET_HL(val, hi, lo) << lo) == val); + return BR64_SET_HL(entry, hi, lo, val >> lo); +} + +typedef u64 ept_pml4e_t; +typedef u64 ept_pdpte_t; +typedef u64 ept_pde_t; +typedef u64 ept_pte_t; + +typedef u64 gpaddr_t; +typedef u64 hpaddr_t; + +#define EPT_PML4_SIZE 512 +#define EPT_PDPT_SIZE 512 +#define EPT_PD_SIZE 512 +#define EPT_PT_SIZE 512 + +/* max bits used in physical devices. processor-dependent. */ +#define M 47 + +/* PML4E bit fields */ +#define EPT_PML4E_IGN0_HI 63 +#define EPT_PML4E_IGN0_LO 52 +#define EPT_PML4E_RSVD0_HI 51 +#define EPT_PML4E_RSVD0_LO M +#define EPT_PML4E_PDPT_HI (M-1) +#define EPT_PML4E_PDPT_LO 12 +#define EPT_PML4E_IGN1_HI 11 +#define EPT_PML4E_IGN1_LO 8 +#define EPT_PML4E_RSVD2_HI 7 +#define EPT_PML4E_RSVD2_LO 3 +#define EPT_PML4E_X_HI 2 +#define EPT_PML4E_X_LO 2 +#define EPT_PML4E_W_HI 1 +#define EPT_PML4E_W_LO 1 +#define EPT_PML4E_R_HI 0 +#define EPT_PML4E_R_LO 0 +#define EPT_PML4E_NP_HI 2 /* not-present */ +#define EPT_PML4E_NP_LO 0 + + +/* PDPTE bit fields */ +#define EPT_PDPTE_IGN0_HI 63 +#define EPT_PDPTE_IGN0_LO 52 +#define EPT_PDPTE_RSVD0_HI 51 +#define EPT_PDPTE_RSVD0_LO M +/****** when ISPAGE==0 ********************/ + #define EPT_PDPTE_PD_HI (M-1) + #define EPT_PDPTE_PD_LO 12 +/******* when ISPAGE==1********************/ + #define EPT_PDPTE_PAGE_HI (M-1) + #define EPT_PDPTE_PAGE_LO 30 + #define EPT_PDPTE_RSVD1_HI 29 + #define EPT_PDPTE_RSVD1_LO 12 +/******************************************/ +#define EPT_PDPTE_IGN1_HI 11 +#define EPT_PDPTE_IGN1_LO 8 +#define EPT_PDPTE_ISPAGE_HI 7 +#define EPT_PDPTE_ISPAGE_LO 7 +/****** when ISPAGE==0 ********************/ + #define EPT_PDPTE_RSVD2_HI 6 + #define EPT_PDPTE_RSVD2_LO 3 +/****** when ISPAGE==1 ********************/ + #define EPT_PDPTE_IPAT_HI 6 + #define EPT_PDPTE_IPAT_LO 6 + #define EPT_PDPTE_EPTMT_HI 5 + #define EPT_PDPTE_EPTMT_LO 3 +/******************************************/ +#define EPT_PDPTE_X_HI 2 +#define EPT_PDPTE_X_LO 2 +#define EPT_PDPTE_W_HI 1 +#define EPT_PDPTE_W_LO 1 +#define EPT_PDPTE_R_HI 0 +#define EPT_PDPTE_R_LO 0 +#define EPT_PDPTE_NP_HI 2 /* not-present */ +#define EPT_PDPTE_NP_LO 0 +#define EPT_PDPTE_PROT_HI 2 +#define EPT_PDPTE_PROT_LO 0 + + +/* PDE bit fields */ +#define EPT_PDE_IGN0_HI 63 +#define EPT_PDE_IGN0_LO 52 +#define EPT_PDE_RSVD0_HI 51 +#define EPT_PDE_RSVD0_LO M +/****** when ISPAGE==0 ********************/ + #define EPT_PDE_PT_HI (M-1) + #define EPT_PDE_PT_LO 12 +/******* when ISPAGE==1********************/ + #define EPT_PDE_PAGE_HI (M-1) + #define EPT_PDE_PAGE_LO 21 + #define EPT_PDE_RSVD1_HI 20 + #define EPT_PDE_RSVD1_LO 12 +/******************************************/ +#define EPT_PDE_IGN1_HI 11 +#define EPT_PDE_IGN1_LO 8 +#define EPT_PDE_ISPAGE_HI 7 +#define EPT_PDE_ISPAGE_LO 7 +/****** when ISPAGE==0 ********************/ + #define EPT_PDE_RSVD2_HI 6 + #define EPT_PDE_RSVD2_LO 3 +/****** when ISPAGE==1 ********************/ + #define EPT_PDE_IPAT_HI 6 + #define EPT_PDE_IPAT_LO 6 + #define EPT_PDE_EPTMT_HI 5 + #define EPT_PDE_EPTMT_LO 3 +/******************************************/ +#define EPT_PDE_X_HI 2 +#define EPT_PDE_X_LO 2 +#define EPT_PDE_W_HI 1 +#define EPT_PDE_W_LO 1 +#define EPT_PDE_R_HI 0 +#define EPT_PDE_R_LO 0 +#define EPT_PDE_NP_HI 2 /* not-present */ +#define EPT_PDE_NP_LO 0 +#define EPT_PDE_PROT_HI 2 +#define EPT_PDE_PROT_LO 0 + +static hpaddr_t ept_pde_pt_get(ept_pde_t ept_pde) +{ + return get_addr(ept_pde, EPT_PDE_PT_HI, EPT_PDE_PT_LO); +} +static ept_pde_t ept_pde_pt_set(ept_pde_t ept_pde, hpaddr_t ept_pt) +{ + return set_addr(ept_pde, EPT_PDE_PT_HI, EPT_PDE_PT_LO, ept_pt); +} + +/* PTE bit fields */ +#define EPT_PTE_IGN0_HI 63 +#define EPT_PTE_IGN0_LO 52 +#define EPT_PTE_RSVD0_HI 51 +#define EPT_PTE_RSVD0_LO M +#define EPT_PTE_PAGE_HI (M-1) +#define EPT_PTE_PAGE_LO 12 +#define EPT_PTE_IGN1_HI 11 +#define EPT_PTE_IGN1_LO 7 +#define EPT_PTE_IPAT_HI 6 +#define EPT_PTE_IPAT_LO 6 +#define EPT_PTE_EPTMT_HI 5 +#define EPT_PTE_EPTMT_LO 3 +#define EPT_PTE_X_HI 2 +#define EPT_PTE_X_LO 2 +#define EPT_PTE_W_HI 1 +#define EPT_PTE_W_LO 1 +#define EPT_PTE_R_HI 0 +#define EPT_PTE_R_LO 0 +#define EPT_PTE_NP_HI 2 /* not-present */ +#define EPT_PTE_NP_LO 0 +#define EPT_PTE_PROT_HI 2 +#define EPT_PTE_PROT_LO 0 + +/* guest physical address */ + +#define EPT_GPA_PML4_I_HI 47 +#define EPT_GPA_PML4_I_LO 39 +#define EPT_GPA_PDPT_I_HI 38 +#define EPT_GPA_PDPT_I_LO 30 +#define EPT_GPA_PD_I_HI 29 +#define EPT_GPA_PD_I_LO 21 +#define EPT_GPA_PT_I_HI 20 +#define EPT_GPA_PT_I_LO 12 +#define EPT_GPA_OFFSET_HI 11 +#define EPT_GPA_OFFSET_LO 0 + +static u32 gpaddr_list; +static u32 gpaddr_count; +static u64 ept_pdpt[EPT_PDPT_SIZE]; + +static void ept_pdpte_init(ept_pdpte_t *ept_pdpte) +{ + *ept_pdpte = 0; +} + +static void ept_pdpt_init(ept_pdpte_t *ept_pdpt) +{ + int i; + for(i=0; i +#include +#include +#include + + +/* standard unity constructions */ +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +/** + [AES-256 use df] + [PredictionResistance = False] + [EntropyInputLen = 256] + [NonceLen = 128] + [PersonalizationStringLen = 0] + [AdditionalInputLen = 0] + */ + +typedef struct { + unsigned char EntropyInput[32]; + unsigned char Nonce[16]; + unsigned char PersonalizationString[1]; + unsigned char AdditionalInput[1]; + unsigned char INTERMEDIATE_Key[32]; + unsigned char INTERMEDIATE_V[16]; + unsigned char INTERMEDIATE_ReturnedBits[16]; + unsigned char EntropyInputReseed[32]; + unsigned char AdditionalInputReseed[1]; + unsigned char AdditionalInput2[1]; + unsigned char ReturnedBits[16]; +} EntropyInputLen256NonceLen128PersonalizationStringLen0AdditionalInputLen0_t; + +#include "nist_test_vectors.h" + +void do_buffer(NIST_CTR_DRBG* drbg, char* buffer, int length) +{ + nist_ctr_drbg_generate(drbg, buffer, length, NULL, 0); + + /* printf("%d: ", length); */ + /* nist_dump_hex(buffer, length); */ + /* printf("\n"); */ +} + +void do_initialize_instantiate_and_buffer(EntropyInputLen256NonceLen128PersonalizationStringLen0AdditionalInputLen0_t *s, + NIST_CTR_DRBG* drbg, char* buffer) { + + nist_ctr_initialize(); + + nist_ctr_drbg_instantiate(drbg, s->EntropyInput, sizeof(s->EntropyInput), s->Nonce, sizeof(s->Nonce), NULL, 0); + do_buffer(drbg, buffer, sizeof(s->INTERMEDIATE_ReturnedBits)); +} + +void do_reseed_and_buffer(EntropyInputLen256NonceLen128PersonalizationStringLen0AdditionalInputLen0_t *s, + NIST_CTR_DRBG* drbg, char* buffer) { + + nist_ctr_drbg_reseed(drbg, s->EntropyInputReseed, sizeof(s->EntropyInputReseed), NULL, 0); + + do_buffer(drbg, buffer, sizeof(s->ReturnedBits)); +} + + +void test_AES256_use_df_EntropyInputLen256_NonceLen128_PersonalizationStringLen0_AdditionalInputLen0(void) { + NIST_CTR_DRBG drbg; + char buffer[256]; + EntropyInputLen256NonceLen128PersonalizationStringLen0AdditionalInputLen0_t *s; + + s = &count0; + do_initialize_instantiate_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->INTERMEDIATE_ReturnedBits, buffer, sizeof(s->INTERMEDIATE_ReturnedBits)); + do_reseed_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->ReturnedBits, buffer, sizeof(s->ReturnedBits)); + + s = &count1; + do_initialize_instantiate_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->INTERMEDIATE_ReturnedBits, buffer, sizeof(s->INTERMEDIATE_ReturnedBits)); + do_reseed_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->ReturnedBits, buffer, sizeof(s->ReturnedBits)); + + s = &count2; + do_initialize_instantiate_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->INTERMEDIATE_ReturnedBits, buffer, sizeof(s->INTERMEDIATE_ReturnedBits)); + do_reseed_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->ReturnedBits, buffer, sizeof(s->ReturnedBits)); + + s = &count3; + do_initialize_instantiate_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->INTERMEDIATE_ReturnedBits, buffer, sizeof(s->INTERMEDIATE_ReturnedBits)); + do_reseed_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->ReturnedBits, buffer, sizeof(s->ReturnedBits)); + + s = &count4; + do_initialize_instantiate_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->INTERMEDIATE_ReturnedBits, buffer, sizeof(s->INTERMEDIATE_ReturnedBits)); + do_reseed_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->ReturnedBits, buffer, sizeof(s->ReturnedBits)); + + s = &count5; + do_initialize_instantiate_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->INTERMEDIATE_ReturnedBits, buffer, sizeof(s->INTERMEDIATE_ReturnedBits)); + do_reseed_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->ReturnedBits, buffer, sizeof(s->ReturnedBits)); + + s = &count6; + do_initialize_instantiate_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->INTERMEDIATE_ReturnedBits, buffer, sizeof(s->INTERMEDIATE_ReturnedBits)); + do_reseed_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->ReturnedBits, buffer, sizeof(s->ReturnedBits)); + + s = &count7; + do_initialize_instantiate_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->INTERMEDIATE_ReturnedBits, buffer, sizeof(s->INTERMEDIATE_ReturnedBits)); + do_reseed_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->ReturnedBits, buffer, sizeof(s->ReturnedBits)); + + s = &count8; + do_initialize_instantiate_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->INTERMEDIATE_ReturnedBits, buffer, sizeof(s->INTERMEDIATE_ReturnedBits)); + do_reseed_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->ReturnedBits, buffer, sizeof(s->ReturnedBits)); + + s = &count9; + do_initialize_instantiate_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->INTERMEDIATE_ReturnedBits, buffer, sizeof(s->INTERMEDIATE_ReturnedBits)); + do_reseed_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->ReturnedBits, buffer, sizeof(s->ReturnedBits)); + + s = &count10; + do_initialize_instantiate_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->INTERMEDIATE_ReturnedBits, buffer, sizeof(s->INTERMEDIATE_ReturnedBits)); + do_reseed_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->ReturnedBits, buffer, sizeof(s->ReturnedBits)); + + s = &count11; + do_initialize_instantiate_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->INTERMEDIATE_ReturnedBits, buffer, sizeof(s->INTERMEDIATE_ReturnedBits)); + do_reseed_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->ReturnedBits, buffer, sizeof(s->ReturnedBits)); + + s = &count12; + do_initialize_instantiate_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->INTERMEDIATE_ReturnedBits, buffer, sizeof(s->INTERMEDIATE_ReturnedBits)); + do_reseed_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->ReturnedBits, buffer, sizeof(s->ReturnedBits)); + + s = &count13; + do_initialize_instantiate_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->INTERMEDIATE_ReturnedBits, buffer, sizeof(s->INTERMEDIATE_ReturnedBits)); + do_reseed_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->ReturnedBits, buffer, sizeof(s->ReturnedBits)); + + s = &count14; + do_initialize_instantiate_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->INTERMEDIATE_ReturnedBits, buffer, sizeof(s->INTERMEDIATE_ReturnedBits)); + do_reseed_and_buffer(s, &drbg, buffer); + TEST_ASSERT_EQUAL_MEMORY(s->ReturnedBits, buffer, sizeof(s->ReturnedBits)); +} + +void test_uninstantiate_actually_zeros(void) { + NIST_CTR_DRBG drbg; + NIST_CTR_DRBG drbg0; + + /* First give us a reference struct set to 0 ourselves, to compare against. */ + memset(&drbg0, 0x00, sizeof(NIST_CTR_DRBG)); + + /* Second set the DRBG struct to have all bits set. */ + memset(&drbg, 0xff, sizeof(NIST_CTR_DRBG)); + + /* Third invoke the library's zeroize function */ + nist_zeroize(&drbg, sizeof(NIST_CTR_DRBG)); + + /* Fourth check that it worked */ + TEST_ASSERT_EQUAL_MEMORY(&drbg, &drbg0, sizeof(NIST_CTR_DRBG)); +} diff --git a/xmhf-64/hypapps/trustvisor/test/test_pages.c b/xmhf-64/hypapps/trustvisor/test/test_pages.c new file mode 100644 index 0000000000..a8304da3ba --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/test/test_pages.c @@ -0,0 +1,78 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include "unity.h" + +#define __PRINT_H_ /* avoid indirectly including our print.h, which conflicts with libc stdio.h */ +#include +#include +#include + +/* run time parameter block. we'll mock this up as needed */ +/* RPB __rpb; */ +/* RPB *rpb = &__rpb; */ + +/* /\* global CPU structs *\/ */ +/* VCPU g_vcpubuffers[0]; */ + +static pagelist_t pl; + +void setUp(void) +{ + mem_init(); + pagelist_init(&pl); +} + +void tearDown(void) +{ + pagelist_free_all(&pl); +} + +void test_foo(void) +{ + void *p = pagelist_getpage(&pl); + TEST_ASSERT(PAGE_ALIGNED_4K((uintptr_t)p)); +} diff --git a/xmhf-64/hypapps/trustvisor/trustvisor.pc.in b/xmhf-64/hypapps/trustvisor/trustvisor.pc.in new file mode 100644 index 0000000000..8291f428f6 --- /dev/null +++ b/xmhf-64/hypapps/trustvisor/trustvisor.pc.in @@ -0,0 +1,9 @@ +prefix=@prefix@ +includedir=@includedir@ + +Name: trustvisor +Description: trustvisor hypervisor +Requires: +Version: @PACKAGE_VERSION@ +Libs: +Cflags: -I${includedir} diff --git a/xmhf-64/tools/circleci/README b/xmhf-64/tools/circleci/README new file mode 100644 index 0000000000..2c59cdbb65 --- /dev/null +++ b/xmhf-64/tools/circleci/README @@ -0,0 +1,5 @@ +This folder contains configuration for Circle CI. The CI workflow builds XMHF +and tests it in QEMU. + +This folder is currently under development. + diff --git a/xmhf-64/tools/circleci/config.yml b/xmhf-64/tools/circleci/config.yml new file mode 100644 index 0000000000..de9f2dd0fe --- /dev/null +++ b/xmhf-64/tools/circleci/config.yml @@ -0,0 +1,85 @@ +version: 2.1 + +jobs: + test-xmhf: + machine: + # Need nested virtualization + # https://discuss.circleci.com/t/new-android-machine-image-now-/39467 + image: android:2022.03.1 + resource_class: medium + parameters: + subarch: + type: string + steps: + - checkout + - run: + name: "Apt-get" + command: " + sudo apt-get update && \ + sudo apt-get -y -q install \ + git crossbuild-essential-i386 \ + pbuilder texinfo ruby build-essential autoconf libtool \ + qemu-system-x86 sshpass + " + - run: + name: "Build" + command: "./.github/build.sh << parameters.subarch >> circleci" + - run: + name: "Versions" + command: | + lscpu + ssh -V + qemu-system-x86_64 -version + gcc -v + - store_artifacts: + path: xmhf/src/xmhf-core/xmhf-runtime/runtime.exe + - store_artifacts: + path: xmhf/src/xmhf-core/xmhf-bootloader/init_syms.exe + - store_artifacts: + path: xmhf/src/xmhf-core/xmhf-secureloader/sl_syms.exe + - store_artifacts: + path: init-x86-amd64.bin + - store_artifacts: + path: hypervisor-x86-amd64.bin.gz + - restore_cache: + keys: + - debian11x86x64-20220407-<< parameters.subarch >> + - run: + name: "Download Debian" + command: | + source .circleci/env.sh << parameters.subarch >> + .jenkins/download.sh cache ${qemu_image_back} + - save_cache: + key: debian11x86x64-20220407-<< parameters.subarch >> + paths: + - cache/ + - run: + name: "Test" + command: | + source .circleci/env.sh << parameters.subarch >> + rm -rf tmp qemu + mkdir tmp qemu + ln -s ${PWD}/cache/${qemu_image_back} qemu + qemu-img create -f qcow2 -b ${PWD}/qemu/${qemu_image_back} \ + -F qcow2 ${PWD}/qemu/${qemu_image} + sha512sum ${PWD}/qemu/${qemu_image_back} + python3 -u ./.jenkins/test3.py \ + --subarch ${SUBARCH} \ + --qemu-image ${PWD}/qemu/${qemu_image} \ + --qemu-image-back ${PWD}/qemu/${qemu_image_back} \ + --xmhf-bin ${PWD}/ \ + --sshpass jkl \ + --work-dir ${PWD}/tmp/ \ + --no-display \ + --verbose \ + --boot-dir ${PWD}/.jenkins/boot \ + --watch-serial \ + --smp 2 + +workflows: + test-xmhf-workflow: + jobs: + - test-xmhf: + matrix: + parameters: + subarch: ["i386", "amd64"] diff --git a/xmhf-64/tools/circleci/env.sh b/xmhf-64/tools/circleci/env.sh new file mode 100755 index 0000000000..43c01188a7 --- /dev/null +++ b/xmhf-64/tools/circleci/env.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -xe +if [ "$1" == "i386" ]; then + export SUBARCH="i386" + export SA_x86_x64="x86" + export SA_32_64="32" +else if [ "$1" == "amd64" ]; then + export SUBARCH="amd64" + export SA_x86_x64="x64" + export SA_32_64="64" +else + echo 'Error: unknown subarch'; exit 1 +fi; fi + +export qemu_image_back="debian11${SA_x86_x64}.qcow2" +export qemu_image="debian11${SA_x86_x64}-c.qcow2" + diff --git a/xmhf-64/tools/docgen/render-doc.sh b/xmhf-64/tools/docgen/render-doc.sh new file mode 100755 index 0000000000..ef654e27ba --- /dev/null +++ b/xmhf-64/tools/docgen/render-doc.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +EXPORT_PREFIX=doc + +# quick and dirty offline documentation generator. Note that to be +# compatible with the dynamically rendered documentation in the +# sourceforge repository viewer, we have to rewrite links to other +# markdown files to point to the generated html files instead. +# +# XXX probably ought to be more selective with the sed find/replace + +# generated html files are left in-place. The ideal solution is +# to view these directly, in case links in these refer to other +# resources in the repository. +for f in `find . -name '*.md'`; +do + DATE=`date` + cat $f | sed 's/.md/.md.html/g' | pandoc --template=tools/docgen/template/template.html -s -V DATE="`date`" -V SOURCE="$f" -o $f.html + + # copy to EXPORT_PREFIX + mkdir -p $EXPORT_PREFIX/`dirname $f` + cp $f.html $EXPORT_PREFIX/`dirname $f` + + # generate index.html from any README.md, + # and copy to EXPORT_PREFIX + if [ x`basename $f` = x"README.md" ]; + then + cp $f.html `dirname $f`/index.html + cp `dirname $f`/index.html $EXPORT_PREFIX/`dirname $f` + fi +done diff --git a/xmhf-64/tools/docgen/template/template.html b/xmhf-64/tools/docgen/template/template.html new file mode 100644 index 0000000000..65625c095b --- /dev/null +++ b/xmhf-64/tools/docgen/template/template.html @@ -0,0 +1,56 @@ + + + + + + +$for(author-meta)$ + +$endfor$ +$if(date-meta)$ + +$endif$ + $if(title-prefix)$$title-prefix$ - $endif$$if(pagetitle)$$pagetitle$$endif$ +$if(highlighting-css)$ + +$endif$ +$for(css)$ + +$endfor$ +$if(math)$ + $math$ +$endif$ +$for(header-includes)$ + $header-includes$ +$endfor$ + + +$for(include-before)$ +$include-before$ +$endfor$ +$if(title)$ +
+

$title$

+$for(author)$ +

$author$

+$endfor$ +$if(date)$ +

$date$

+$endif$ +
+$endif$ +$if(toc)$ +
+$toc$ +
+$endif$ +$body$ +$for(include-after)$ +$include-after$ +$endfor$ +
+Generated $DATE$ from xmhf's $SOURCE$ + + diff --git a/xmhf-64/tools/github/README b/xmhf-64/tools/github/README new file mode 100644 index 0000000000..fb90afe03d --- /dev/null +++ b/xmhf-64/tools/github/README @@ -0,0 +1,6 @@ +This folder contains configuration for GitHub actions. This CI workflow builds +XMHF in many configurations (x86 / x64, drt / no drt, dmap / no dmap, no +compiler optimize / optimize). + +This folder is currently under development. + diff --git a/xmhf-64/tools/github/build.sh b/xmhf-64/tools/github/build.sh new file mode 100755 index 0000000000..bca2c6bcc3 --- /dev/null +++ b/xmhf-64/tools/github/build.sh @@ -0,0 +1,187 @@ +#!/bin/bash +# Usage: build.sh subarch [arguments [...]] +# subarch: i386 or amd64 +# arguments: +# --drt: enable DRT (--disable-drt) +# --dmap: enable DMAP (--disable-dmap) +# --no-dbg: do not use QEMU debug workarounds (--enable-debug-qemu) +# --no-ucode: disable Intel microcode update (--enable-update-intel-ucode) +# --app APP: set hypapp, default is "hypapps/trustvisor" (--with-approot) +# --mem MEM: if amd64, set physical memory, default is 0x140000000 (5GiB) +# release: equivalent to --drt --dmap --no-dbg (For GitHub actions) +# debug: ignored (For GitHub actions) +# O0: ignored (For GitHub actions) +# O3: enable -O3 optimization, etc. (For GitHub actions) +# circleci: enable --enable-optimize-nested-virt workaround for Circle CI +# -n: print autogen.sh and configure options, do not run them + +set -e + +# Information about compiler's platform +LINUX_BASE="" # DEB or RPM +LINUX_BIT=$(getconf LONG_BIT) # 32 or 64 + +# Information about XMHF +APPROOT="hypapps/trustvisor" +SUBARCH="" +DRT="n" +DMAP="n" +QEMU="y" +UCODE="y" +AMD64MEM="0x140000000" +DRY_RUN="n" +CIRCLE_CI="n" +OPT="" + +# Determine LINUX_BASE (may not be 100% correct all the time) +if [ -f "/etc/debian_version" ]; then + # DEB-based Linux (e.g. Debian, Ubuntu) + LINUX_BASE="DEB" +else if [ -f "/etc/redhat-release" ]; then + # RPM-based Linux (e.g. Fedora) + LINUX_BASE="RPM" +else + echo 'Error: build.sh does not know about OS it is running on.'; exit 1 +fi; fi + +# Check LINUX_BIT +case "$LINUX_BIT" in + 32) + ;; + 64) + ;; + *) + echo 'Error: unknown result from `getconf LONG_BIT`'; exit 1 + ;; +esac + +# Determine SUBARCH +case "$1" in + i386) + SUBARCH="i386" + ;; + amd64) + SUBARCH="amd64" + ;; + *) + echo 'Error: subarch incorrect, should be i386 or amd64'; exit 1 + ;; +esac +shift + +# Process other arguments +while [ "$#" -gt 0 ]; do + case "$1" in + --drt) + DRT="y" + ;; + --dmap) + DMAP="y" + ;; + --no-dbg) + QEMU="n" + ;; + --no-ucode) + UCODE="n" + ;; + --app) + APPROOT="$2" + shift + ;; + --mem) + AMD64MEM="$2" + shift + ;; + release) + # For GitHub actions + DRT="y" + DMAP="y" + QEMU="n" + ;; + debug) + # For GitHub actions + ;; + O0) + # For GitHub actions + ;; + O3) + # For GitHub actions + OPT="O3" + ;; + circleci) + CIRCLE_CI="y" + ;; + -n) + DRY_RUN="y" + ;; + *) + echo "Error: unknown argument $1"; exit 1 + ;; + esac + shift +done + +# Build configure arguments +CONF=() +CONF+=("--with-approot=$APPROOT") +CONF+=("--enable-debug-symbols") + +if [ "$SUBARCH" == "i386" ]; then + # Building i386 XMHF + if [ "$LINUX_BASE" == "DEB" -a "$LINUX_BIT" == "64" ]; then + # Building on amd64 Debian + CONF+=("CC=i686-linux-gnu-gcc") + CONF+=("LD=i686-linux-gnu-ld") + fi +else if [ "$SUBARCH" == "amd64" ]; then + # Building amd64 XMHF + CONF+=("--with-target-subarch=amd64") + CONF+=("--with-amd64-max-phys-addr=$AMD64MEM") + if [ "$LINUX_BASE" == "DEB" -a "$LINUX_BIT" == "32" ]; then + # Building on i386 Debian + CONF+=("CC=x86_64-linux-gnu-gcc") + CONF+=("LD=x86_64-linux-gnu-ld") + fi +else + echo 'Error: unexpected $SUBARCH'; exit 1 +fi; fi + +if [ "$DRT" == "n" ]; then + CONF+=("--disable-drt") +fi + +if [ "$DMAP" == "n" ]; then + CONF+=("--disable-dmap") +fi + +if [ "$QEMU" == "y" ]; then + CONF+=("--enable-debug-qemu") +fi + +if [ "$UCODE" == "y" ]; then + CONF+=("--enable-update-intel-ucode") +fi + +if [ "$OPT" == "O3" ]; then + # -Wno-stringop-overflow is set due to a compile bug in GCC 10 / GCC 11 + # Reported in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105100 + CONF+=("--with-opt=-O3 -Wno-stringop-overflow") +fi + +if [ "$CIRCLE_CI" == "y" ]; then + CONF+=("--enable-optimize-nested-virt") +fi + +# Output configure arguments, if `-n` +if [ "$DRY_RUN" == "y" ]; then + set +x + echo $'\n'"./autogen.sh; ./configure ${CONF[@]@Q}"$'\n' + exit 0 +fi + +# Build +set -x +./autogen.sh +./configure "${CONF[@]}" +make -j "$(nproc)" + diff --git a/xmhf-64/tools/github/build_pal_demo.sh b/xmhf-64/tools/github/build_pal_demo.sh new file mode 100755 index 0000000000..9a29c5476f --- /dev/null +++ b/xmhf-64/tools/github/build_pal_demo.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +set -xe + +MAKE_ARGS="" + +if [ "$1" == "windows" ]; then + MAKE_ARGS="${MAKE_ARGS} WINDOWS=y" + if [ "$2" == "i386" ]; then + MAKE_ARGS="${MAKE_ARGS} CC=i686-w64-mingw32-gcc" + MAKE_ARGS="${MAKE_ARGS} LD=i686-w64-mingw32-ld" + else if [ "$2" == "amd64" ]; then + MAKE_ARGS="${MAKE_ARGS} CC=x86_64-w64-mingw32-gcc" + MAKE_ARGS="${MAKE_ARGS} LD=x86_64-w64-mingw32-ld" + else + echo '$2 incorrect, should be i386 or amd64'; exit 1 + fi; fi +else if [ "$1" == "linux" ]; then + if [ "$2" == "i386" ]; then + MAKE_ARGS="${MAKE_ARGS} CC=i686-linux-gnu-gcc" + MAKE_ARGS="${MAKE_ARGS} LD=i686-linux-gnu-ld" + else if [ "$2" == "amd64" ]; then + MAKE_ARGS="${MAKE_ARGS}" + else + echo '$2 incorrect, should be i386 or amd64'; exit 1 + fi; fi +else if [ "$1" == "all" ]; then + build_and_move () { + "$1" "$2" "$3" + for i in hypapps/trustvisor/pal_demo/{main,test,test_args}; do + mv "${i}$5" "${i}$4$5" + done + } + build_and_move "$0" linux i386 32 "" + build_and_move "$0" linux amd64 64 "" + build_and_move "$0" windows i386 32 ".exe" + build_and_move "$0" windows amd64 64 ".exe" + cd hypapps/trustvisor/pal_demo/ + rm -f pal_demo.zip + zip pal_demo.zip {main,test,test_args}{32,64}{,.exe} + exit +else + echo '$1 incorrect, should be windows or linux or all'; exit 1 +fi; fi; fi + +cd hypapps/trustvisor/pal_demo +make clean +make ${MAKE_ARGS} + diff --git a/xmhf-64/tools/github/workflows/build.yml b/xmhf-64/tools/github/workflows/build.yml new file mode 100644 index 0000000000..33d04ab3df --- /dev/null +++ b/xmhf-64/tools/github/workflows/build.yml @@ -0,0 +1,74 @@ +name: Build XMHF with TrustVisor + +on: ["push", "pull_request"] + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + target_arch: + - 'i386' + - 'amd64' + compile_mode: + - 'debug' + - 'release' + optimize_mode: + - 'O0' + - 'O3' + + steps: + - uses: actions/checkout@v2 + - name: apt-get + run: | + sudo apt-get update && \ + sudo apt-get install \ + openssh-server tmux vim git aptitude \ + pbuilder texinfo ruby build-essential autoconf libtool \ + crossbuild-essential-i386 gcc-mingw-w64 \ + -y + - name: Build + run: | + ./.github/build.sh \ + ${{ matrix.target_arch }} \ + ${{ matrix.compile_mode }} \ + ${{ matrix.optimize_mode }} + - name: Release + uses: actions/upload-artifact@v2 + with: + name: boot-${{ matrix.target_arch }}-${{ matrix.compile_mode }}-${{ matrix.optimize_mode }} + path: | + xmhf/src/xmhf-core/xmhf-secureloader/sl_syms.exe + xmhf/src/xmhf-core/xmhf-bootloader/init_syms.exe + xmhf/src/xmhf-core/xmhf-runtime/runtime.exe + hypervisor-x86-${{ matrix.target_arch }}.bin.gz + init-x86-${{ matrix.target_arch }}.bin + - name: Build pal_demo Linux + if: ${{ matrix.compile_mode == 'debug' && matrix.optimize_mode == 'O0' }} + run: | + ./.github/build_pal_demo.sh linux ${{ matrix.target_arch }} + - name: Release pal_demo Linux + if: ${{ matrix.compile_mode == 'debug' && matrix.optimize_mode == 'O0' }} + uses: actions/upload-artifact@v2 + with: + name: pal_demo-linux-${{ matrix.target_arch }} + path: | + hypapps/trustvisor/pal_demo/main + hypapps/trustvisor/pal_demo/test + hypapps/trustvisor/pal_demo/test_args + - name: Build pal_demo Windows + if: ${{ matrix.compile_mode == 'debug' && matrix.optimize_mode == 'O0' }} + run: | + ./.github/build_pal_demo.sh windows ${{ matrix.target_arch }} + - name: Release pal_demo Windows + if: ${{ matrix.compile_mode == 'debug' && matrix.optimize_mode == 'O0' }} + uses: actions/upload-artifact@v2 + with: + name: pal_demo-windows-${{ matrix.target_arch }} + path: | + hypapps/trustvisor/pal_demo/main.exe + hypapps/trustvisor/pal_demo/test.exe + hypapps/trustvisor/pal_demo/test_args.exe + diff --git a/xmhf-64/tools/jenkins/Jenkinsfile b/xmhf-64/tools/jenkins/Jenkinsfile new file mode 100644 index 0000000000..86bafe9f83 --- /dev/null +++ b/xmhf-64/tools/jenkins/Jenkinsfile @@ -0,0 +1,86 @@ +/* + * Files and directories in build environment + * * ./: PWD, contains XMHF64 source + * * ./.git: Git directory, not used directly by Jenkins + * * ./cache/: cache QEMU images + * * ./qemu/: QEMU work directory + * * ./tmp/: temporary directory for testing script + * * ./.github/build.sh: script to build XMHF in one line + * * ./.jenkins/Jenkinsfile: this file + * * ./.jenkins/test3.py: test script + * * ./.jenkins/boot: files to construct a minimal GRUB + * * ./.jenkins/download.sh: download QEMU images from Google Drive + */ + +parameters { + string(name: 'XMHF_BRANCH', defaultValue: 'xmhf64', description: '') +} + +void qemu_test(String subarch, String qemu_image, String qemu_image_back) { + PWD = sh(returnStdout: true, script: 'pwd').trim() + sh "./.jenkins/download.sh cache ${qemu_image_back}" + sh "rm -rf tmp qemu" + sh "mkdir tmp qemu" + sh "ln -s ${PWD}/cache/${qemu_image_back} qemu" + sh """ + qemu-img create -f qcow2 -b ${PWD}/qemu/${qemu_image_back} \ + -F qcow2 ${PWD}/qemu/${qemu_image} + """ + sh """ + python3 -u ./.jenkins/test3.py \ + --subarch ${subarch} \ + --qemu-image ${PWD}/qemu/${qemu_image} \ + --qemu-image-back ${PWD}/qemu/${qemu_image_back} \ + --xmhf-bin ${PWD}/ \ + --sshpass jkl \ + --work-dir ${PWD}/tmp/ \ + --no-display \ + --verbose \ + --boot-dir ${PWD}/.jenkins/boot \ + --watch-serial + """ +} + +pipeline { + agent any + + stages { + stage('Logistics') { + steps { + sh "git fetch origin ${params.XMHF_BRANCH}" + sh "git checkout ${params.XMHF_BRANCH}" + sh "git pull origin ${params.XMHF_BRANCH}" + script { + cmt = sh( + returnStdout: true, + script: 'git rev-parse HEAD | head -c 9').trim() + currentBuild.displayName += " ${params.XMHF_BRANCH}" + currentBuild.displayName += " ${cmt}" + } + } + } + stage('Build i386') { + steps { + sh "git clean -Xdf" + sh "./.github/build.sh i386" + } + } + stage('Test i386') { + steps { + qemu_test "i386", "debian11x86-j.qcow2", "debian11x86.qcow2" + } + } + stage('Build amd64') { + steps { + sh "git clean -Xdf" + sh "./.github/build.sh amd64" + } + } + stage('Test amd64') { + steps { + qemu_test "amd64", "debian11x64-j.qcow2", "debian11x64.qcow2" + } + } + } +} + diff --git a/xmhf-64/tools/jenkins/README b/xmhf-64/tools/jenkins/README new file mode 100644 index 0000000000..cbcf7c487f --- /dev/null +++ b/xmhf-64/tools/jenkins/README @@ -0,0 +1,9 @@ +This folder contains configuration for Jenkins. The CI workflow builds XMHF +and tests it in QEMU. + +This folder is currently under development. + +Note: the following binary files are removed temporarily: +* boot/a.img +* boot/grub/i386-pc/* + diff --git a/xmhf-64/tools/jenkins/boot/grub/grub.cfg b/xmhf-64/tools/jenkins/boot/grub/grub.cfg new file mode 100644 index 0000000000..144c664c9e --- /dev/null +++ b/xmhf-64/tools/jenkins/boot/grub/grub.cfg @@ -0,0 +1,229 @@ +# +# DO NOT EDIT THIS FILE +# +# It is automatically generated by grub-mkconfig using templates +# from /etc/grub.d and settings from /etc/default/grub +# + +### BEGIN /etc/grub.d/00_header ### +if [ -s $prefix/grubenv ]; then + set have_grubenv=true + load_env +fi +if [ "${next_entry}" ] ; then + set default="${next_entry}" + set next_entry= + save_env next_entry + set boot_once=true +else + set default="0" +fi + +if [ x"${feature_menuentry_id}" = xy ]; then + menuentry_id_option="--id" +else + menuentry_id_option="" +fi + +export menuentry_id_option + +if [ "${prev_saved_entry}" ]; then + set saved_entry="${prev_saved_entry}" + save_env saved_entry + set prev_saved_entry= + save_env prev_saved_entry + set boot_once=true +fi + +function savedefault { + if [ -z "${boot_once}" ]; then + saved_entry="${chosen}" + save_env saved_entry + fi +} +function load_video { + if [ x$feature_all_video_module = xy ]; then + insmod all_video + else + insmod efi_gop + insmod efi_uga + insmod ieee1275_fb + insmod vbe + insmod vga + insmod video_bochs + insmod video_cirrus + fi +} + +terminal_input console +terminal_output console +if [ "${recordfail}" = 1 ] ; then + set timeout=30 +else + if [ x$feature_timeout_style = xy ] ; then + set timeout_style=menu + set timeout=5 + # Fallback normal timeout code in case the timeout_style feature is + # unavailable. + else + set timeout=5 + fi +fi +### END /etc/grub.d/00_header ### + +### BEGIN /etc/grub.d/05_debian_theme ### +set menu_color_normal=cyan/blue +set menu_color_highlight=white/blue +### END /etc/grub.d/05_debian_theme ### + +#### BEGIN /etc/grub.d/10_linux ### +#function gfxmode { +# set gfxpayload="${1}" +#} +#set linux_gfx_mode=text +#export linux_gfx_mode +#menuentry 'Debian GNU/Linux' --class debian --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-b2d5dc8b-583b-4ce0-b43f-e23603eb6e67' { +# gfxmode $linux_gfx_mode +# insmod gzio +# if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi +# insmod part_msdos +# insmod ext2 +# set root='hd0,msdos1' +# if [ x$feature_platform_search_hint = xy ]; then +# search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 b2d5dc8b-583b-4ce0-b43f-e23603eb6e67 +# else +# search --no-floppy --fs-uuid --set=root b2d5dc8b-583b-4ce0-b43f-e23603eb6e67 +# fi +# echo 'Loading Linux 5.10.0-9-amd64 ...' +# linux /boot/vmlinuz-5.10.0-9-amd64 root=UUID=b2d5dc8b-583b-4ce0-b43f-e23603eb6e67 ro quiet +# echo 'Loading initial ramdisk ...' +# initrd /boot/initrd.img-5.10.0-9-amd64 +#} +#submenu 'Advanced options for Debian GNU/Linux' $menuentry_id_option 'gnulinux-advanced-b2d5dc8b-583b-4ce0-b43f-e23603eb6e67' { +# menuentry 'Debian GNU/Linux, with Linux 5.10.0-9-amd64' --class debian --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.10.0-9-amd64-advanced-b2d5dc8b-583b-4ce0-b43f-e23603eb6e67' { +# gfxmode $linux_gfx_mode +# insmod gzio +# if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi +# insmod part_msdos +# insmod ext2 +# set root='hd0,msdos1' +# if [ x$feature_platform_search_hint = xy ]; then +# search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 b2d5dc8b-583b-4ce0-b43f-e23603eb6e67 +# else +# search --no-floppy --fs-uuid --set=root b2d5dc8b-583b-4ce0-b43f-e23603eb6e67 +# fi +# echo 'Loading Linux 5.10.0-9-amd64 ...' +# linux /boot/vmlinuz-5.10.0-9-amd64 root=UUID=b2d5dc8b-583b-4ce0-b43f-e23603eb6e67 ro quiet +# echo 'Loading initial ramdisk ...' +# initrd /boot/initrd.img-5.10.0-9-amd64 +# } +# menuentry 'Debian GNU/Linux, with Linux 5.10.0-9-amd64 (recovery mode)' --class debian --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.10.0-9-amd64-recovery-b2d5dc8b-583b-4ce0-b43f-e23603eb6e67' { +# gfxmode $linux_gfx_mode +# insmod gzio +# if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi +# insmod part_msdos +# insmod ext2 +# set root='hd0,msdos1' +# if [ x$feature_platform_search_hint = xy ]; then +# search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 b2d5dc8b-583b-4ce0-b43f-e23603eb6e67 +# else +# search --no-floppy --fs-uuid --set=root b2d5dc8b-583b-4ce0-b43f-e23603eb6e67 +# fi +# echo 'Loading Linux 5.10.0-9-amd64 ...' +# linux /boot/vmlinuz-5.10.0-9-amd64 root=UUID=b2d5dc8b-583b-4ce0-b43f-e23603eb6e67 ro single +# echo 'Loading initial ramdisk ...' +# initrd /boot/initrd.img-5.10.0-9-amd64 +# } +# menuentry 'Debian GNU/Linux, with Linux 5.10.0-8-amd64' --class debian --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.10.0-8-amd64-advanced-b2d5dc8b-583b-4ce0-b43f-e23603eb6e67' { +# gfxmode $linux_gfx_mode +# insmod gzio +# if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi +# insmod part_msdos +# insmod ext2 +# set root='hd0,msdos1' +# if [ x$feature_platform_search_hint = xy ]; then +# search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 b2d5dc8b-583b-4ce0-b43f-e23603eb6e67 +# else +# search --no-floppy --fs-uuid --set=root b2d5dc8b-583b-4ce0-b43f-e23603eb6e67 +# fi +# echo 'Loading Linux 5.10.0-8-amd64 ...' +# linux /boot/vmlinuz-5.10.0-8-amd64 root=UUID=b2d5dc8b-583b-4ce0-b43f-e23603eb6e67 ro quiet +# echo 'Loading initial ramdisk ...' +# initrd /boot/initrd.img-5.10.0-8-amd64 +# } +# menuentry 'Debian GNU/Linux, with Linux 5.10.0-8-amd64 (recovery mode)' --class debian --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.10.0-8-amd64-recovery-b2d5dc8b-583b-4ce0-b43f-e23603eb6e67' { +# gfxmode $linux_gfx_mode +# insmod gzio +# if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi +# insmod part_msdos +# insmod ext2 +# set root='hd0,msdos1' +# if [ x$feature_platform_search_hint = xy ]; then +# search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 b2d5dc8b-583b-4ce0-b43f-e23603eb6e67 +# else +# search --no-floppy --fs-uuid --set=root b2d5dc8b-583b-4ce0-b43f-e23603eb6e67 +# fi +# echo 'Loading Linux 5.10.0-8-amd64 ...' +# linux /boot/vmlinuz-5.10.0-8-amd64 root=UUID=b2d5dc8b-583b-4ce0-b43f-e23603eb6e67 ro single +# echo 'Loading initial ramdisk ...' +# initrd /boot/initrd.img-5.10.0-8-amd64 +# } +#} +# +#### END /etc/grub.d/10_linux ### + +### BEGIN /etc/grub.d/20_linux_xen ### + +### END /etc/grub.d/20_linux_xen ### + +### BEGIN /etc/grub.d/30_os-prober ### +### END /etc/grub.d/30_os-prober ### + +### BEGIN /etc/grub.d/30_uefi-firmware ### +### END /etc/grub.d/30_uefi-firmware ### + +### BEGIN /etc/grub.d/40_custom ### +# This file provides an easy way to add custom menu entries. Simply type the +# menu entries you want to add after this comment. Be careful not to change +# the 'exec tail' line above. +### END /etc/grub.d/40_custom ### + +### BEGIN /etc/grub.d/41_custom ### +if [ -f ${config_directory}/custom.cfg ]; then + source ${config_directory}/custom.cfg +elif [ -z "${config_directory}" -a -f $prefix/custom.cfg ]; then + source $prefix/custom.cfg; +fi +### END /etc/grub.d/41_custom ### + +### BEGIN /etc/grub.d/42_xmhf_i386 ### +# This file provides an easy way to add custom menu entries. Simply type the +# menu entries you want to add after this comment. Be careful not to change +# the 'exec tail' line above. + +menuentry "XMHF-i386" { + set root='(hd0,msdos1)' # point to file system for / + set kernel='/boot/init-x86-i386.bin' + set boot_drive='0x81' # should point to where grub is installed + echo "Loading ${kernel}..." + multiboot ${kernel} serial=115200,8n1,0x3f8 boot_drive=${boot_drive} + module /boot/hypervisor-x86-i386.bin.gz + module --nounzip (hd1)+1 # should point to where grub is installed +} +### END /etc/grub.d/42_xmhf_i386 ### + +### BEGIN /etc/grub.d/43_xmhf_amd64 ### +# This file provides an easy way to add custom menu entries. Simply type the +# menu entries you want to add after this comment. Be careful not to change +# the 'exec tail' line above. + +menuentry "XMHF-amd64" { + set root='(hd0,msdos1)' # point to file system for / + set kernel='/boot/init-x86-amd64.bin' + set boot_drive='0x81' # should point to where grub is installed + echo "Loading ${kernel}..." + multiboot ${kernel} serial=115200,8n1,0x3f8 boot_drive=${boot_drive} + module /boot/hypervisor-x86-amd64.bin.gz + module --nounzip (hd1)+1 # should point to where grub is installed +} +### END /etc/grub.d/43_xmhf_amd64 ### diff --git a/xmhf-64/tools/jenkins/boot/grub/grubenv b/xmhf-64/tools/jenkins/boot/grub/grubenv new file mode 100644 index 0000000000..b2a7dff879 --- /dev/null +++ b/xmhf-64/tools/jenkins/boot/grub/grubenv @@ -0,0 +1,3 @@ +# GRUB Environment Block +next_entry= +########################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################### \ No newline at end of file diff --git a/xmhf-64/tools/jenkins/boot/grubenv-amd64 b/xmhf-64/tools/jenkins/boot/grubenv-amd64 new file mode 100644 index 0000000000..4a4eb091cb --- /dev/null +++ b/xmhf-64/tools/jenkins/boot/grubenv-amd64 @@ -0,0 +1,3 @@ +# GRUB Environment Block +next_entry=XMHF-amd64 +################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################# \ No newline at end of file diff --git a/xmhf-64/tools/jenkins/boot/grubenv-i386 b/xmhf-64/tools/jenkins/boot/grubenv-i386 new file mode 100644 index 0000000000..815f3942ac --- /dev/null +++ b/xmhf-64/tools/jenkins/boot/grubenv-i386 @@ -0,0 +1,3 @@ +# GRUB Environment Block +next_entry=XMHF-i386 +################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################## \ No newline at end of file diff --git a/xmhf-64/tools/jenkins/download.sh b/xmhf-64/tools/jenkins/download.sh new file mode 100755 index 0000000000..b2ba261d35 --- /dev/null +++ b/xmhf-64/tools/jenkins/download.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +set -xe +if [ $# -le 0 ]; then + echo "Error: no enough arguments"; exit 1 +fi + +DOWNLOAD_DIR="$1" +mkdir -p "$DOWNLOAD_DIR" +shift + +download () { + TARGET_FILE="$DOWNLOAD_DIR/$2" + if [ -f "$TARGET_FILE" ]; then + echo "$TARGET_FILE already exists" + else + if ! python3 -c 'import gdown'; then + python3 -m pip install gdown + fi + python3 -m gdown.cli "$1" -O "$TARGET_FILE" + fi +} + +while [ "$#" -gt 0 ]; do + case "$1" in + debian11x86.qcow2) + download "1T1Yw8cBa2zo1fWSZIkry0aOuz2pZS6Tl" "$1" + ;; + debian11x64.qcow2) + download "1WntdHCKNmuJ5I34xqriokMlSAC3KcqL-" "$1" + ;; + *) + echo "Error: unknown file $1"; exit 1 + ;; + esac + shift +done + diff --git a/xmhf-64/tools/jenkins/test2.py b/xmhf-64/tools/jenkins/test2.py new file mode 100644 index 0000000000..1ad52eb6f1 --- /dev/null +++ b/xmhf-64/tools/jenkins/test2.py @@ -0,0 +1,288 @@ +from subprocess import Popen, check_call +import argparse, subprocess, time, os, random, socket, threading + +SSH_CONNECTING = 0 +SSH_RUNNING = 1 +SSH_COMPLETED = 2 + +SSH_TIMEOUT = 2 +HALT_TIMEOUT = 10 + +println_lock = threading.Lock() + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument('--subarch', required=True) + parser.add_argument('--xmhf-bin', required=True) + parser.add_argument('--qemu-image', required=True) + parser.add_argument('--qemu-image-back', required=True) + parser.add_argument('--smp', type=int, default=2) + parser.add_argument('--work-dir', required=True) + parser.add_argument('--no-display', action='store_true') + parser.add_argument('--sshpass', help='Password for ssh') + parser.add_argument('--verbose', action='store_true') + parser.add_argument('--watch-serial', action='store_true') + parser.add_argument('--skip-install', action='store_true') + parser.add_argument('--no-test-xmhf', action='store_true', + help='Skip testing XMHF in QEMU for Circle CI set-up ' + '(deprecated)') + args = parser.parse_args() + return args + +def println(*args): + with println_lock: + print('{', *args, '}') + +def reset_qemu(args): + ''' + Remove changes relative to backing qcow2 file + ''' + assert os.path.exists(args.qemu_image) + assert os.path.exists(args.qemu_image_back) + check_call(['qemu-img', 'create', '-f', 'qcow2', '-b', args.qemu_image_back, + '-F', 'qcow2', args.qemu_image]) + +def get_port(): + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) + for i in range(10000): + num = random.randrange(1024, 65536) + try: + s.bind(('127.0.0.1', num)) + except OSError: + continue + s.close() + return num + else: + raise RuntimeError('Cannot get port') + +def spawn_qemu(args, serial_file, ssh_port): + qemu_args = [ + 'qemu-system-x86_64', '-m', '512M', + '--drive', 'media=disk,file=%s,index=2' % args.qemu_image, + '-device', 'e1000,netdev=net0', + '-netdev', 'user,id=net0,hostfwd=tcp::%d-:22' % ssh_port, + '-smp', str(args.smp), '-cpu', 'Haswell,vmx=yes', '--enable-kvm', + '-serial', 'file:%s' % serial_file, + ] + if args.no_display: + qemu_args.append('-display') + qemu_args.append('none') + popen_stderr = { 'stderr': -1 } + if args.verbose: + del popen_stderr['stderr'] + p = Popen(qemu_args, stdin=-1, stdout=-1, **popen_stderr) + return p + +class SSHOperations: + def __init__(self, args, ssh_port): + self.args = args + self.ssh_port = ssh_port + def get_ssh_cmd(self, exe='ssh', port_opt='-p'): + ssh_cmd = [] + if self.args.sshpass: + ssh_cmd += ['sshpass', '-p', self.args.sshpass] + ssh_cmd += [exe, port_opt, str(self.ssh_port), + '-o', 'ConnectTimeout=%d' % SSH_TIMEOUT, + '-o', 'StrictHostKeyChecking=no', + '-o', 'UserKnownHostsFile=/dev/null'] + return ssh_cmd + def send_ssh(self, bash_script, status): + ''' + bash_script: script to run, must print something, or will retry forever + status[0] = lock + status[1] = SSH_CONNECTING (0): test not started yet + status[1] = SSH_RUNNING (1): test started + status[1] = SSH_COMPLETED (2): test finished + status[2] = command return code + status[3] = stdout lines + status[4] = whether abort + ''' + ssh_cmd = self.get_ssh_cmd() + ssh_cmd += ['lxy@127.0.0.1', 'bash', '-c', bash_script] + state = None + if self.args.verbose: + println('send_ssh:', repr(bash_script)) + while True: + p = Popen(ssh_cmd, stdin=-1, stdout=-1, stderr=-1) + while True: + line = p.stdout.readline().decode() + if not line: + p.wait() + assert p.returncode is not None + # Connection failed + # Warning: will incorrectly retry is script has no output. + # This is necessary to distinguish between connection + # failure and command failure. + if status[1] == SSH_CONNECTING and p.returncode == 255: + break + # Command successfully completed + with status[0]: + status[1] = SSH_COMPLETED + status[2] = p.returncode + return + println('ssh: ', repr(line.rstrip())) + with status[0]: + status[1] = SSH_RUNNING + status[2] = time.time() + status[3].append(line.strip()) + # Check abort + if status[4]: + return + time.sleep(1) + if self.args.verbose: + println('send_ssh: retry SSH', repr(bash_script)) + def run_ssh(self, bash_script, connect_timeout, run_timeout, ss): + ''' + Run an ssh command with timeout control etc + ''' + assert not ss + for i in [threading.Lock(), SSH_CONNECTING, 0, [], 0]: + ss.append(i) + ts = threading.Thread(target=self.send_ssh, + args=(bash_script, ss), daemon=True) + ts.start() + + start_time = time.time() + run_time = None + while True: + state = [None] + with ss[0]: + state[1:] = ss[1:] + if self.args.verbose: + println('run_ssh: MET = %d;' % int(time.time() - start_time), + 'state =', state[:3], len(state[3])) + if state[1] == SSH_CONNECTING: + if time.time() - start_time > connect_timeout: + return 'connect_aborted' + elif state[1] == SSH_RUNNING: + if run_time is None: + run_time = time.time() + if time.time() - run_time > run_timeout: + return 'run_time_exceeded' + elif state[1] == SSH_COMPLETED: + # test completed + return None + else: + raise ValueError + time.sleep(1) + def ssh_operations(self): + ''' + Return None if successful, error message otherwise + ''' + if not self.args.skip_install: + ans = self.ssh_operations_install() + if ans is not None: + return ans + return self.ssh_operations_test() + def ssh_operations_install(self): + # 1. test booted + ss = [] + stat = self.run_ssh('date; echo 1. test boot; ', 120, 10, ss) + if stat or ss[2] != 0: + return 'Failed to boot 1: (%s, %d, %s)' % (stat, ss[2], ss[3]) + # 2. scp + scp_cmd = self.get_ssh_cmd('scp', '-P') + pf = lambda x: os.path.join(self.args.xmhf_bin, x % self.args.subarch) + scp_cmd += [ + pf('init-x86-%s.bin'), + pf('hypervisor-x86-%s.bin.gz'), + 'lxy@127.0.0.1:/tmp', + ] + println('scp') + check_call(scp_cmd) + println('scp done') + # 3. install + ss = [] + install_num = { 'i386': 86, 'amd64': 64 }[self.args.subarch] + stat = self.run_ssh( + 'date; echo 3. install; ./install%d.sh' % install_num, + 10, 20, ss) + if stat or ss[2] != 0: + return 'Failed to install: (%s, %d, %s)' % (stat, ss[2], ss[3]) + # 4. restart + ss = [] + stat = self.run_ssh( + 'date; echo 4. restart; touch /tmp/asdf; sudo init 6; ', + 10, 20, ss) + if stat: + return 'Failed to restart: (%s, %d, %s)' % (stat, ss[2], ss[3]) + # 5. make sure restart started + while True: + println('Checking restart') + ss = [] + stat = self.run_ssh('date; echo 5. restart start; ls /tmp/asdf', + 10, 10, ss) + if stat or ss[2] != 0: + println('Restart checked') + break + def ssh_operations_test(self): + # For Circle CI, cannot boot Debian on XMHF on KVM, so return success + if self.args.no_test_xmhf: + sleep_dur = 50 + for i in range(sleep_dur): + println('Sleep', i, '/', sleep_dur) + return None + # 6. test booted 2 + ss = [] + stat = self.run_ssh('date; echo 6. test boot 2; [ ! -f /tmp/asdf ]', + 150, 10, ss) + if stat or ss[2] != 0: + return 'Failed to boot 2: (%s, %d, %s)' % (stat, ss[2], ss[3]) + # 7. run test + wordsizes = { 'i386': [32], 'amd64': [32, 64] }[self.args.subarch] + for w in wordsizes: + ss = [] + cmd = 'date; echo 7. run test %d; ./test_args%d 7 7 7' % (w, w) + stat = self.run_ssh(cmd, 10, 45, ss) + if stat or ss[2] != 0 or 'Test pass' not in ss[3]: + return 'Test %d failed: (%s, %d, %s)' % (w, stat, ss[2], ss[3]) + # Success + return None + +def main(): + args = parse_args() + if not args.skip_install: + reset_qemu(args) + ssh_port = get_port() + println('Use ssh port', ssh_port) + serial_file = os.path.join(args.work_dir, 'serial') + p = spawn_qemu(args, serial_file, ssh_port) + + # Simple workaround to watch serial output + if args.watch_serial: + threading.Thread(target=os.system, args=('tail -F %s' % serial_file,), + daemon=True).start() + + result = 'Unknown' + try: + result = SSHOperations(args, ssh_port).ssh_operations() + if result is None: + # give the OS 10 seconds to shutdown; if wait() succeeds, calling + # wait() again will still succeed + try: + p.wait(timeout=HALT_TIMEOUT) + except subprocess.TimeoutExpired: + pass + finally: + p.kill() + p.wait() + + if result is None: + println('PASS: successful ssh_operations()') + else: + println('ERROR in ssh_operations()') + println(result) + return 1 + + # Test serial output + println('Test XMHF banner in serial') + check_call(['grep', 'eXtensible Modular Hypervisor', serial_file]) + println('Test E820 in serial') + check_call(['grep', 'e820', serial_file]) + + println('TEST PASSED') + return 0 + +if __name__ == '__main__': + exit(main()) + diff --git a/xmhf-64/tools/jenkins/test3.py b/xmhf-64/tools/jenkins/test3.py new file mode 100644 index 0000000000..d0a463676e --- /dev/null +++ b/xmhf-64/tools/jenkins/test3.py @@ -0,0 +1,285 @@ +from subprocess import Popen, check_call +import argparse, subprocess, time, os, random, socket, threading + +SSH_CONNECTING = 0 +SSH_RUNNING = 1 +SSH_COMPLETED = 2 + +SSH_TIMEOUT = 2 +HALT_TIMEOUT = 10 + +println_lock = threading.Lock() + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument('--subarch', required=True) + parser.add_argument('--xmhf-bin', required=True) + parser.add_argument('--qemu-image', required=True) + parser.add_argument('--qemu-image-back', required=True) + parser.add_argument('--smp', type=int, default=2) + parser.add_argument('--work-dir', required=True) + parser.add_argument('--no-display', action='store_true') + parser.add_argument('--sshpass', help='Password for ssh') + parser.add_argument('--verbose', action='store_true') + parser.add_argument('--watch-serial', action='store_true') + parser.add_argument('--skip-reset-qemu', action='store_true') + parser.add_argument('--boot-dir', required=True, + help='Contain /boot and MBR image to generate GRUB') + args = parser.parse_args() + return args + +def println(*args): + with println_lock: + print('{', *args, '}') + +def reset_qemu(args): + ''' + Remove changes relative to backing qcow2 file + ''' + assert os.path.exists(args.qemu_image) + assert os.path.exists(args.qemu_image_back) + check_call(['qemu-img', 'create', '-f', 'qcow2', '-b', args.qemu_image_back, + '-F', 'qcow2', args.qemu_image]) + +def get_port(): + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) + for i in range(10000): + num = random.randrange(1024, 65536) + try: + s.bind(('127.0.0.1', num)) + except OSError: + continue + s.close() + return num + else: + raise RuntimeError('Cannot get port') + +def generate_xmhf_image(args): + grub_dir = os.path.join(args.work_dir, 'grub') + check_call(['rm', '-rf', grub_dir]) + assert not os.path.exists(grub_dir) + os.mkdir(grub_dir) + + # As of writing test3.py, GRUB uses less than 4M, XMHF uses less than 1M. + ext4_size_mb = 7 + + # Construct ext4 + b_img = os.path.join(grub_dir, 'b.img') + check_call(['dd', 'if=/dev/zero', 'of=%s' % b_img, 'bs=1M', + 'seek=%d' % ext4_size_mb, 'count=0']) + check_call(['/sbin/mkfs.ext4', b_img]) + debugfs_cmds = [] + debugfs_cmds.append('mkdir boot') + debugfs_cmds.append('cd boot') + for i in ['init-x86-%s.bin', 'hypervisor-x86-%s.bin.gz']: + name = i % args.subarch + src_pathname = os.path.join(args.xmhf_bin, name) + debugfs_cmds.append('write %s %s' % (src_pathname, name)) + debugfs_cmds.append('mkdir grub') + debugfs_cmds.append('cd grub') + debugfs_cmds.append('write %s grub.cfg' % + os.path.join(args.boot_dir, 'grub/grub.cfg')) + envfile = 'grubenv-%s' % args.subarch + debugfs_cmds.append('write %s grubenv' % + os.path.join(args.boot_dir, envfile)) + debugfs_cmds.append('mkdir i386-pc') + debugfs_cmds.append('cd i386-pc') + mods_dir = os.path.join(os.path.join(args.boot_dir, 'grub/i386-pc/')) + for i in os.listdir(mods_dir): + debugfs_cmds.append('write %s %s' % (os.path.join(mods_dir, i), i)) + cmd_file = os.path.join(grub_dir, 'debugfs.cmd') + print(*debugfs_cmds, sep='\n') + print(*debugfs_cmds, sep='\n', file=open(cmd_file, 'w')) + popen_stdout = { 'stdout': -1 } + if args.verbose: + del popen_stdout['stdout'] + check_call(['/sbin/debugfs', '-w', b_img, '-f', cmd_file], **popen_stdout) + + # Concat to c.img + a_img = os.path.join(args.boot_dir, 'a.img') + c_img = os.path.join(grub_dir, 'c.img') + check_call(['dd', 'if=/dev/zero', 'of=%s' % c_img, 'bs=1M', + 'seek=%d' % (ext4_size_mb + 1), 'count=0']) + check_call(['dd', 'if=%s' % a_img, 'of=%s' % c_img, 'conv=sparse,notrunc', + 'bs=512', 'count=1M', 'iflag=count_bytes']) + check_call(['dd', 'if=%s' % b_img, 'of=%s' % c_img, 'conv=sparse,notrunc', + 'bs=512', 'seek=1M', 'oflag=seek_bytes']) + return c_img + +def spawn_qemu(args, xmhf_img, serial_file, ssh_port): + qemu_args = [ + 'qemu-system-x86_64', '-m', '512M', + '--drive', 'media=disk,file=%s,format=raw,index=1' % xmhf_img, + '--drive', 'media=disk,file=%s,format=qcow2,index=2' % args.qemu_image, + '-device', 'e1000,netdev=net0', + '-netdev', 'user,id=net0,hostfwd=tcp::%d-:22' % ssh_port, + '-smp', str(args.smp), '-cpu', 'Haswell,vmx=yes', '--enable-kvm', + '-serial', 'file:%s' % serial_file, + ] + if args.no_display: + qemu_args.append('-display') + qemu_args.append('none') + popen_stderr = { 'stderr': -1 } + if args.verbose: + del popen_stderr['stderr'] + p = Popen(qemu_args, stdin=-1, stdout=-1, **popen_stderr) + return p + +class SSHOperations: + def __init__(self, args, ssh_port): + self.args = args + self.ssh_port = ssh_port + def get_ssh_cmd(self, exe='ssh', port_opt='-p'): + ssh_cmd = [] + if self.args.sshpass: + ssh_cmd += ['sshpass', '-p', self.args.sshpass] + ssh_cmd += [exe, port_opt, str(self.ssh_port), + '-o', 'ConnectTimeout=%d' % SSH_TIMEOUT, + '-o', 'StrictHostKeyChecking=no', + '-o', 'UserKnownHostsFile=/dev/null'] + return ssh_cmd + def send_ssh(self, bash_script, status): + ''' + bash_script: script to run, must print something, or will retry forever + status[0] = lock + status[1] = SSH_CONNECTING (0): test not started yet + status[1] = SSH_RUNNING (1): test started + status[1] = SSH_COMPLETED (2): test finished + status[2] = command return code + status[3] = stdout lines + status[4] = whether abort + ''' + ssh_cmd = self.get_ssh_cmd() + ssh_cmd += ['lxy@127.0.0.1', 'bash', '-c', bash_script] + state = None + if self.args.verbose: + println('send_ssh:', repr(bash_script)) + while True: + p = Popen(ssh_cmd, stdin=-1, stdout=-1, stderr=-1) + while True: + line = p.stdout.readline().decode() + if not line: + p.wait() + assert p.returncode is not None + # Connection failed + # Warning: will incorrectly retry is script has no output. + # This is necessary to distinguish between connection + # failure and command failure. + if status[1] == SSH_CONNECTING and p.returncode == 255: + break + # Command successfully completed + with status[0]: + status[1] = SSH_COMPLETED + status[2] = p.returncode + return + println('ssh: ', repr(line.rstrip())) + with status[0]: + status[1] = SSH_RUNNING + status[2] = time.time() + status[3].append(line.strip()) + # Check abort + if status[4]: + return + time.sleep(1) + if self.args.verbose: + println('send_ssh: retry SSH', repr(bash_script)) + def run_ssh(self, bash_script, connect_timeout, run_timeout, ss): + ''' + Run an ssh command with timeout control etc + ''' + assert not ss + for i in [threading.Lock(), SSH_CONNECTING, 0, [], 0]: + ss.append(i) + ts = threading.Thread(target=self.send_ssh, + args=(bash_script, ss), daemon=True) + ts.start() + + start_time = time.time() + run_time = None + while True: + state = [None] + with ss[0]: + state[1:] = ss[1:] + if self.args.verbose: + println('run_ssh: MET = %d;' % int(time.time() - start_time), + 'state =', state[:3], len(state[3])) + if state[1] == SSH_CONNECTING: + if time.time() - start_time > connect_timeout: + return 'connect_aborted' + elif state[1] == SSH_RUNNING: + if run_time is None: + run_time = time.time() + if time.time() - run_time > run_timeout: + return 'run_time_exceeded' + elif state[1] == SSH_COMPLETED: + # test completed + return None + else: + raise ValueError + time.sleep(1) + def ssh_operations(self): + # 6. test booted 2 + ss = [] + stat = self.run_ssh('date; echo 6. test boot 2; [ ! -f /tmp/asdf ]', + 150, 10, ss) + if stat or ss[2] != 0: + return 'Failed to boot 2: (%s, %d, %s)' % (stat, ss[2], ss[3]) + # 7. run test + wordsizes = { 'i386': [32], 'amd64': [32, 64] }[self.args.subarch] + for w in wordsizes: + ss = [] + cmd = 'date; echo 7. run test %d; ./test_args%d 7 7 7' % (w, w) + stat = self.run_ssh(cmd, 10, 45, ss) + if stat or ss[2] != 0 or 'Test pass' not in ss[3]: + return 'Test %d failed: (%s, %d, %s)' % (w, stat, ss[2], ss[3]) + # Success + return None + +def main(): + args = parse_args() + if not args.skip_reset_qemu: + reset_qemu(args) + ssh_port = get_port() + println('Use ssh port', ssh_port) + serial_file = os.path.join(args.work_dir, 'serial') + xmhf_img = generate_xmhf_image(args) + p = spawn_qemu(args, xmhf_img, serial_file, ssh_port) + + # Simple workaround to watch serial output + if args.watch_serial: + threading.Thread(target=os.system, args=('tail -F %s' % serial_file,), + daemon=True).start() + + result = 'Unknown' + try: + result = SSHOperations(args, ssh_port).ssh_operations() + if result is None: + # give the OS 10 seconds to shutdown; if wait() succeeds, calling + # wait() again will still succeed + try: + p.wait(timeout=HALT_TIMEOUT) + except subprocess.TimeoutExpired: + pass + finally: + p.kill() + p.wait() + + if result is None: + println('PASS: successful ssh_operations()') + else: + println('ERROR in ssh_operations()') + println(result) + return 1 + + # Test serial output + println('Test XMHF banner in serial') + check_call(['grep', 'eXtensible Modular Hypervisor', serial_file]) + println('Test E820 in serial') + check_call(['grep', 'e820', serial_file]) + + println('TEST PASSED') + return 0 + +if __name__ == '__main__': + exit(main()) + diff --git a/xmhf-64/xmhf/README.md b/xmhf-64/xmhf/README.md new file mode 100644 index 0000000000..ab12034a15 --- /dev/null +++ b/xmhf-64/xmhf/README.md @@ -0,0 +1,47 @@ +Introduction +============ + +XMHF is an eXtensible and Modular Hypervisor Framework +that strives to be a +comprehensible and flexible platform for performing +hypervisor research and development. The framework allows others to +build custom (security-sensitive) hypervisor-based solutions +(called "hypapps"). + +XMHF is designed to achieve three goals – modular extensibility, +automated verification, and high performance. XMHF includes a +core that provides functionality common to many hypervisor-based security +architectures and supports extensions that augment the core with +additional security or functional properties while preserving the +fundamental hypervisor security property of memory integrity +(i.e., ensuring that the hypervisor’s memory is not modified by +software running at a lower privilege level). + +XMHF advocates a "rich" single-guest execution model where the +hypervisor framework supports only a single-guest and allows the +guest direct access to all performance-critical system devices and +device interrupts. + +XMHF currently runs on recent multicore x86 hardware +virtualized platforms with support for dynamic root of trust +and nested (2-dimensional) paging. The framework is capable of +running unmodified legacy multiprocessor capable OSes such as +Windows and Linux. + +XMHF64 supports running 64-bit OS and software in XMHF. + +Quick start to using XMHF +========================= + +* [XMHF Hardware Requirements](doc/hardware-requirements.md) +* [Guest Operating Systems supported by XMHF](doc/supported-OS.md) +* [Building XMHF](doc/building-xmhf.md) +* [Verifying XMHF](doc/verifying-xmhf.md) +* [Installing XMHF](doc/installing-xmhf.md) +* [Debugging XMHF](doc/debugging-xmhf.md) + +Quick start to using XMHF64 +========================= + +* [Setting up XMHF64](doc/setup-xmhf64.md) + diff --git a/xmhf-64/xmhf/src/libbaremetal/Makefile b/xmhf-64/xmhf/src/libbaremetal/Makefile new file mode 100644 index 0000000000..bb98a61c61 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/Makefile @@ -0,0 +1,33 @@ +# Makefile for libbaremetal +# author: amit vasudevan (amitvasudevan@acm.org) + +# Builds a bunch of sublibraries + +# get the "source" directory of this Makefile (useful for +# out-of-tree build) +srcdir := $(realpath $(dir $(lastword $(MAKEFILE_LIST)))) + +# grab all the sub-library directories +LIBDIRS = $(wildcard $(srcdir)/lib*) + + +.PHONY: all +all: subdirs + +.PHONY: subdirs +subdirs: $(LIBDIRS) + mkdir -p _objects + @for i in $(LIBDIRS); \ + do \ + (cd _objects && echo "Making all in $$i..." && $(MAKE) -f $$i/Makefile -w all) || exit 1; \ + done; + cd _objects && ar -rcs libbaremetal.a *.o + +.PHONY: clean +clean: + mkdir -p _objects + @for i in $(LIBDIRS) ;\ + do \ + (cd _objects && echo "making clean in $$i..." && $(MAKE) -f $$i/Makefile -w clean) || exit 1; \ + done; + rm -rf _objects diff --git a/xmhf-64/xmhf/src/libbaremetal/README.md b/xmhf-64/xmhf/src/libbaremetal/README.md new file mode 100644 index 0000000000..2987f7a1bf --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/README.md @@ -0,0 +1,36 @@ +libbaremetal +============ + +libbaremetal is composed of several sub-libraries which provide, +libc stubs (think `string.h`'s mem*(), str*()); utility +functions (e.g., HPT abstraction, command line parameter parsing); +TPM functions; and general cryptography routines (both asymmetric and +symmetric). The following are the included sub-libraries and their +functionality: + +* libxmhfc - minimalistic libc functions + +* libxmhfutil - various utility functions (e.g., HPT abstraction and command line parameter parsing) + +* libtpm - functions to interact with a (physical) TPM + +* libtv_utpm - hypervisor-agnostic core logic of the TrustVisor hypapp's Micro-TPM implementation + +* libxmhfcrypto - general cryptography routines + +Building +======== + +libbaremetal and sub-libraries are typically built using an out-of-tree +build process as follows: + + cd mybuilddir + make -f /Makefile + +libbaremetal can also be built in-tree if needed as follows: + + make + +this will result in the objects and sub-libraries being generated +in the `_objects` directory. + diff --git a/xmhf-64/xmhf/src/libbaremetal/libtpm/Makefile b/xmhf-64/xmhf/src/libbaremetal/libtpm/Makefile new file mode 100644 index 0000000000..a32384cdef --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libtpm/Makefile @@ -0,0 +1,31 @@ +srcdir := $(dir $(lastword $(MAKEFILE_LIST))) +vpath %.c $(srcdir) + +C_SOURCES:= $(wildcard $(srcdir)/*.c) +C_SOURCES:= $(patsubst $(srcdir)/%, %, $(C_SOURCES)) +OBJECTS = $(patsubst %.c, %.o, $(C_SOURCES)) + +I_SOURCES := $(wildcard $(srcdir)/include/*.h) + +CFLAGS += -I$(srcdir)/../libxmhfc/include -I$(srcdir)/../libxmhfcrypto/include -I$(srcdir)/../libxmhfutil/include -I$(srcdir)/include -nostdinc -fno-builtin -nostdlib -Wall + +THE_ARCHIVE = libtpm.a + +# targets +.PHONY: all +all: $(THE_ARCHIVE) + +$(THE_ARCHIVE): $(OBJECTS) + $(AR) -rcs $(THE_ARCHIVE) $(OBJECTS) + +#%.o: %.c $(C_SOURCES) $(I_SOURCES) Makefile ../Makefile +# $(CC) -c $(CFLAGS) -o $@ $< + +.PHONY: clean +clean: + $(RM) $(OBJECTS) $(THE_ARCHIVE) + +.PHONY: install-dev +install-dev: + # Nothing to do here + diff --git a/xmhf-64/xmhf/src/libbaremetal/libtpm/README.TXT b/xmhf-64/xmhf/src/libbaremetal/libtpm/README.TXT new file mode 100644 index 0000000000..8271f2023b --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libtpm/README.TXT @@ -0,0 +1,20 @@ +libtpm - generic TPM functionality +================================== + +libtpm contains generic TPM functionality (e.g., read/extend pcrs, +seal/unseal etc.). It is designed to be used with an environment +specific TPM driver that is in charge of setting up and +preparing the TPM for operations. The driver needs to +provide the following two function definitions for libtpm +to communicate with the physical TPM: + +uint32_t tpm_wait_cmd_ready(uint32_t locality); + + +uint32_t tpm_write_cmd_fifo(uint32_t locality, uint8_t *in, + uint32_t in_size, uint8_t *out, + uint32_t *out_size); + +for EMHF, these are defined in the emhf-tpm component; more +specifically in emhf-tpm/arch/x86/tpm-x86.c + diff --git a/xmhf-64/xmhf/src/libbaremetal/libtpm/include/tpm.h b/xmhf-64/xmhf/src/libbaremetal/libtpm/include/tpm.h new file mode 100644 index 0000000000..02d9eec204 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libtpm/include/tpm.h @@ -0,0 +1,733 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * tpm.h: TPM-related support functions + * + * Copyright (c) 2006-2009, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __TPM_H__ +#define __TPM_H__ + +#include +#include +#include + +//====================================================================== +//libtpm environment specific functions +//the following need to be defined within the target environment +//that uses libtpm +//e.g., EMHF-x86 + +#ifndef __ASSEMBLY__ + + +extern uint32_t tpm_wait_cmd_ready(uint32_t locality); + + +extern uint32_t tpm_write_cmd_fifo(uint32_t locality, uint8_t *in, + uint32_t in_size, uint8_t *out, + uint32_t *out_size); + +#endif //__ASSEMBLY__ +//====================================================================== + + +#define TPM_NR_LOCALITIES 5 + + +/* + * return code: + * The TPM has five types of return code. One indicates successful operation + * and four indicate failure. + * TPM_SUCCESS (00000000) indicates successful execution. + * The failure reports are: + * TPM defined fatal errors (00000001 to 000003FF) + * vendor defined fatal errors (00000400 to 000007FF) + * TPM defined non-fatal errors (00000800 to 00000BFF) + * vendor defined non-fatal errors (00000C00 to 00000FFF). + * Here only give definitions for a few commonly used return code. + */ +#define TPM_BASE 0x00000000 +#define TPM_NON_FATAL 0x00000800 +#define TPM_SUCCESS TPM_BASE +#define TPM_BADINDEX (TPM_BASE + 2) +#define TPM_BAD_PARAMETER (TPM_BASE + 3) +#define TPM_DEACTIVATED (TPM_BASE + 6) +#define TPM_DISABLED (TPM_BASE + 7) +#define TPM_FAIL (TPM_BASE + 9) +#define TPM_BAD_ORDINAL (TPM_BASE + 10) +#define TPM_NOSPACE (TPM_BASE + 17) +#define TPM_NOTRESETABLE (TPM_BASE + 50) +#define TPM_NOTLOCAL (TPM_BASE + 51) +#define TPM_BAD_LOCALITY (TPM_BASE + 61) +#define TPM_READ_ONLY (TPM_BASE + 62) +#define TPM_NOT_FULLWRITE (TPM_BASE + 70) +#define TPM_RETRY (TPM_BASE + TPM_NON_FATAL) + +#ifndef __ASSEMBLY__ + + +#define TPM_DIGEST_SIZE 20 +typedef struct __attribute__ ((packed)) { + uint8_t digest[TPM_DIGEST_SIZE]; +} tpm_digest_t; +typedef tpm_digest_t tpm_pcr_value_t; + +/* + * specified as minimum cmd buffer size should be supported by all 1.2 TPM + * device in the TCG_PCClientTPMSpecification_1-20_1-00_FINAL.pdf + */ +#define TPM_CMD_SIZE_MAX 768 +#define TPM_RSP_SIZE_MAX 768 + +#define TPM_NR_PCRS 24 + + +extern uint32_t tpm_get_version(uint8_t *major, uint8_t *minor); + +/* + * tpm_pcr_read fetchs the current value of given PCR vai given locality. + * locality : TPM locality (0 - 4) + * pcr : PCR index (0 - 23) + * out : PCR value buffer, out parameter, should not be NULL + * return : TPM_SUCCESS for success, error code defined as TPM_xxx + */ +extern uint32_t tpm_pcr_read(uint32_t locality, uint32_t pcr, + tpm_pcr_value_t *pcr_value); + +/* + * tpm_pcr_extend extends data octets into given PCR via given locality, + * and return the PCR value after extending if required. + * locality : TPM locality (0 - 4) + * pcr : PCR index (0 - 23) + * in : Hash value to be extended into PCR, should not be NULL + * out : Out buffer for PCR value after extending, may be NULL + * return : TPM_SUCCESS for success, error code defined as TPM_xxx + */ +extern uint32_t tpm_pcr_extend(uint32_t locality, uint32_t pcr, + const tpm_digest_t* in, tpm_pcr_value_t* out); + +/* PCRs lower than 16 are not resetable */ +#define TPM_PCR_RESETABLE_MIN 16 + +/* + * tpm_pcr_reset resets given PCR via given locality. + * locality : TPM locality (0 - 4) + * pcr : PCR index (16 - 23) + * return : TPM_SUCCESS for success, error code defined as TPM_xxx + */ +extern uint32_t tpm_pcr_reset(uint32_t locality, uint32_t pcr); + +#define TPM_NV_READ_VALUE_DATA_SIZE_MAX (TPM_RSP_SIZE_MAX - 14) + +typedef uint32_t tpm_nv_index_t; + +/* + * tpm_nv_read_value reads data from TPM NV ram in the given locality. + * locality : TPM locality (0 - 4) + * index : Predefined index for certain NV space + * offset : Start reading from offset given by this parameter. + * data : Out buffer for read data, should not be NULL + * data_size : As IN, give the size required to read, should not be NULL; + * : as OUT, return the size really read from TPM. + * : The largest nv data size can be read in a single call is + * : defined by TPM_NV_READ_VALUE_DATA_SIZE_MAX. + * return : TPM_SUCCESS for success, error code defined as TPM_xxx + */ +extern uint32_t tpm_nv_read_value(uint32_t locality, tpm_nv_index_t index, + uint32_t offset, uint8_t *data, + uint32_t *data_size); + +#define TPM_NV_WRITE_VALUE_DATA_SIZE_MAX (TPM_CMD_SIZE_MAX - 22) + +/* + * tpm_nv_write_value writes data into TPM NV ram in the given locality. + * locality : TPM locality (0 - 4) + * index : Predefined index for certain NV space + * offset : Start writing from offset given by this parameter. + * data : Data to be written to TPM NV, should not be NULL + * data_size : The size of data to be written. + * : The largest nv data size can be written in a single call + * : is defined by TPM_NV_WRITE_VALUE_DATA_SIZE_MAX. + * return : TPM_SUCCESS for success, error code defined as TPM_xxx + */ +extern uint32_t tpm_nv_write_value(uint32_t locality, tpm_nv_index_t index, + uint32_t offset, const uint8_t *data, + uint32_t data_size); + +typedef uint8_t tpm_locality_selection_t; +#define TPM_LOC_ZERO 0x01 +#define TPM_LOC_ONE 0x02 +#define TPM_LOC_TWO 0x04 +#define TPM_LOC_THREE 0x08 +#define TPM_LOC_FOUR 0x10 +#define TPM_LOC_RSVD 0xE0 + +/* + * tpm_seal seal given data (in_data[in_data_size]) to given pcrs + * (pcr_indcs_create[pcr_nr_create]). The sealed data can only be unsealed + * while the given pcrs (pcr_indcs_release[pcr_nr_release]) met given values + * (pcr_values_release[pcr_nr_release]), and under one of the given release + * locality (release_locsa). + * + * locality : TPM locality (0 - 4) + * release_locs : should be one or composition of TPM_LOC_ZERO to TPM_LOC_FOUR + * pcr_nr_create: the number of pcrs which will be used as creation pcrs + * pcr_indcs_create + * : an array of pcr indices, size is pcr_nr_create. + * pcr_nr_release + * : the number of pcrs which will be used as release pcrs + * pcr_indcs_release + * : an array of pcr indices, size is pcr_nr_release. + * pcr_values_release + * : an array of pointers to pcr value, size is pcr_nr_release. + * in_data_size : The size of data to be sealed. + * in_data : Data to be sealed, should not be NULL + * sealed_data_size + * : [in] the size of prepared output buffer (sealed_data) + * [out] the size of sealed data blob + * sealed_data : [out] the buffer to receive sealed data blob. The buffer + * size should be large enough. For example, the sealed blob + * for 20-byte data will need buffer larger than 322 bytes. + * return : TPM_SUCCESS for success, error code defined as TPM_xxx + * TPM_NOSPACE for insufficient output buffer + */ +extern uint32_t tpm_seal( + uint32_t locality, tpm_locality_selection_t release_locs, + uint32_t pcr_nr_create, const uint8_t pcr_indcs_create[], + uint32_t pcr_nr_release, const uint8_t pcr_indcs_release[], + const tpm_pcr_value_t *pcr_values_release[], + uint32_t in_data_size, const uint8_t *in_data, + uint32_t *sealed_data_size, uint8_t *sealed_data); + +/* + * tpm_unseal unseal given data (sealed_data[sealed_data_size]) and return the + * unsealed data in the given buffer (secret[*secret_size]). + * + * locality : TPM locality (0 - 4) + * sealed_data_size + * : the size of data to be unsealed. + * sealed_data : the data to be unsealed. + * secret_size : [in] the output buffer size. + * [out] the size of unsealed data + * secret : [out]unsealed data. + * return : TPM_SUCCESS for success, error code defined as TPM_xxx + */ +extern uint32_t tpm_unseal( + uint32_t locality, + uint32_t sealed_data_size, const uint8_t *sealed_data, + uint32_t *secret_size, uint8_t *secret); + +/* + * tpm_cmp_creation_pcrs compare the current values of specified PCRs with + * the values of the creation PCRs in the sealed data + * + * return : true if they match, false if they don't match + */ +extern bool tpm_cmp_creation_pcrs( + uint32_t pcr_nr_create, const uint8_t pcr_indcs_create[], + const tpm_pcr_value_t *pcr_values_create[], + uint32_t sealed_data_size, uint8_t *sealed_data); + +/* + * tpm_get_nvindex_size use TPM_GETCAPABILITY cmd to get the size of the NV + * index given as index. + * + * return : TPM_SUCCESS for success, error code defined as TPM_xxx + */ +extern uint32_t tpm_get_nvindex_size(uint32_t locality, + tpm_nv_index_t index, uint32_t *size); + +/* + * tpm_save_state save all volatile state info into non-volatile memory. + * + * return : TPM_SUCCESS for success, error code defined as TPM_xxx + */ +extern uint32_t tpm_save_state(uint32_t locality); + + +/* + * tpm_get_random return TPM-generated random data. + * + * return : TPM_SUCCESS for success, error code defined as TPM_xxx + */ +extern uint32_t tpm_get_random(uint32_t locality, uint8_t *random_data, + uint32_t *data_size); + + + + + +/* + * the following inline function reversely copy the bytes from 'in' to + * 'out', the byte number to copy is given in count. + */ +#define reverse_copy(out, in, count) \ + _reverse_copy((uint8_t *)(out), (const uint8_t *)(in), count) + +static inline void _reverse_copy(uint8_t *out, const uint8_t *in, uint32_t count) +{ + uint32_t i; + for ( i = 0; i < count; i++ ) + out[i] = in[count - i - 1]; +} + + +/* un-comment to enable detailed command tracing */ +#define noTPM_TRACE + +/* ~5 secs are required for Infineon that requires this, so leave some extra */ +#define MAX_SAVESTATE_RETRIES 60 + +#define TPM_TAG_RQU_COMMAND 0x00C1 +#define TPM_TAG_RQU_AUTH1_COMMAND 0x00C2 +#define TPM_TAG_RQU_AUTH2_COMMAND 0x00C3 +#define TPM_ORD_PCR_EXTEND 0x00000014 +#define TPM_ORD_PCR_READ 0x00000015 +#define TPM_ORD_PCR_RESET 0x000000C8 +#define TPM_ORD_NV_READ_VALUE 0x000000CF +#define TPM_ORD_NV_WRITE_VALUE 0x000000CD +#define TPM_ORD_GET_CAPABILITY 0x00000065 +#define TPM_ORD_SEAL 0x00000017 +#define TPM_ORD_UNSEAL 0x00000018 +#define TPM_ORD_OSAP 0x0000000B +#define TPM_ORD_OIAP 0x0000000A +#define TPM_ORD_SAVE_STATE 0x00000098 +#define TPM_ORD_GET_RANDOM 0x00000046 + +#define TPM_TAG_PCR_INFO_LONG 0x0006 +#define TPM_TAG_STORED_DATA12 0x0016 + +//TPM data structures + + + +#define CMD_HEAD_SIZE 10 +#define RSP_HEAD_SIZE 10 +#define CMD_SIZE_OFFSET 2 +#define CMD_ORD_OFFSET 6 +#define RSP_SIZE_OFFSET 2 +#define RSP_RST_OFFSET 6 + + +#define WRAPPER_IN_BUF (cmd_buf + CMD_HEAD_SIZE) +#define WRAPPER_OUT_BUF (rsp_buf + RSP_HEAD_SIZE) +#define WRAPPER_IN_MAX_SIZE (TPM_CMD_SIZE_MAX - CMD_HEAD_SIZE) +#define WRAPPER_OUT_MAX_SIZE (TPM_RSP_SIZE_MAX - RSP_HEAD_SIZE) + +typedef struct __attribute__ ((packed)) { + uint16_t size_of_select; + uint8_t pcr_select[3]; +} tpm_pcr_selection_t; + + +#define TPM_CAP_VERSION_VAL 0x1A + +typedef uint16_t tpm_structure_tag_t; + +typedef struct __attribute__ ((packed)) { + uint8_t major; + uint8_t minor; + uint8_t rev_major; + uint8_t rev_minor; +} tpm_version_t; + +typedef struct __attribute__ ((packed)) { + tpm_structure_tag_t tag; + tpm_version_t version; + uint16_t specLevel; + uint8_t errataRev; + uint8_t tpmVendorID[4]; + uint16_t vendorSpecificSize; + uint8_t vendorSpecific[]; +} tpm_cap_version_info_t; + + +#define HMAC_BLOCK_SIZE 64 +#define HMAC_OUTPUT_SIZE 20 + + +typedef uint16_t tpm_entity_type_t; +typedef uint32_t tpm_authhandle_t; +typedef struct __attribute__ ((packed)) { + uint8_t nonce[20]; +} tpm_nonce_t; + +#define TPM_ET_SRK 0x0004 +#define TPM_KH_SRK 0x40000000 + +typedef uint32_t tpm_key_handle_t; + +typedef tpm_digest_t tpm_composite_hash_t; +typedef struct __attribute__ ((packed)) { + tpm_structure_tag_t tag; + tpm_locality_selection_t locality_at_creation; + tpm_locality_selection_t locality_at_release; + tpm_pcr_selection_t creation_pcr_selection; + tpm_pcr_selection_t release_pcr_selection; + tpm_composite_hash_t digest_at_creation; + tpm_composite_hash_t digest_at_release; +} tpm_pcr_info_long_t; + +typedef uint8_t tpm_authdata_t[20]; +typedef tpm_authdata_t tpm_encauth_t; + +typedef struct __attribute__ ((packed)) { + tpm_structure_tag_t tag; + tpm_entity_type_t et; + uint32_t seal_info_size; +} tpm_stored_data12_header_t; + +typedef struct __attribute__ ((packed)) { + tpm_stored_data12_header_t header; + uint32_t enc_data_size; + uint8_t enc_data[]; +} tpm_stored_data12_short_t; + +typedef struct __attribute__ ((packed)) { + tpm_stored_data12_header_t header; + tpm_pcr_info_long_t seal_info; + uint32_t enc_data_size; + uint8_t enc_data[]; +} tpm_stored_data12_t; + +#define UNLOAD_INTEGER(buf, offset, var) {\ + reverse_copy(buf + offset, &(var), sizeof(var));\ + offset += sizeof(var);\ +} + +#define UNLOAD_BLOB(buf, offset, blob, size) {\ + memcpy(buf + offset, blob, size); \ + offset += size;\ +} + +#define UNLOAD_BLOB_TYPE(buf, offset, blob) \ + UNLOAD_BLOB(buf, offset, blob, sizeof(*(blob))) + +#define UNLOAD_PCR_SELECTION(buf, offset, sel) {\ + UNLOAD_INTEGER(buf, offset, (sel)->size_of_select);\ + UNLOAD_BLOB(buf, offset, (sel)->pcr_select, (sel)->size_of_select);\ +} + +#define UNLOAD_PCR_INFO_SHORT(buf, offset, info) {\ + UNLOAD_PCR_SELECTION(buf, offset, &(info)->pcr_selection);\ + UNLOAD_BLOB_TYPE(buf, offset, &(info)->locality_at_release);\ + UNLOAD_BLOB_TYPE(buf, offset, &(info)->digest_at_release);\ +} + +#define UNLOAD_NV_ATTRIBUTES(buf, offset, attr) {\ + UNLOAD_INTEGER(buf, offset, (attr)->tag);\ + UNLOAD_INTEGER(buf, offset, (attr)->attributes);\ +} + +/* Single-byte values do not require reverse_copy(endianness n/a) */ +#define UNLOAD_NV_DATA_PUBLIC(buf, offset, pub) {\ + UNLOAD_INTEGER(buf, offset, (pub)->tag);\ + UNLOAD_INTEGER(buf, offset, (pub)->nv_index);\ + UNLOAD_PCR_INFO_SHORT(buf, offset, &(pub)->pcr_info_read);\ + UNLOAD_PCR_INFO_SHORT(buf, offset, &(pub)->pcr_info_write);\ + UNLOAD_NV_ATTRIBUTES(buf, offset, &(pub)->permission);\ + *(buf + offset) = (pub)->b_read_st_clear; offset += 1;\ + *(buf + offset) = (pub)->b_write_st_clear; offset += 1;\ + *(buf + offset) = (pub)->b_write_define; offset += 1;\ + UNLOAD_INTEGER(buf, offset, (pub)->data_size);\ +} + +#define UNLOAD_PCR_INFO_LONG(buf, offset, info) {\ + UNLOAD_INTEGER(buf, offset, (info)->tag);\ + UNLOAD_BLOB_TYPE(buf, offset, &(info)->locality_at_creation);\ + UNLOAD_BLOB_TYPE(buf, offset, &(info)->locality_at_release);\ + UNLOAD_PCR_SELECTION(buf, offset, &(info)->creation_pcr_selection);\ + UNLOAD_PCR_SELECTION(buf, offset, &(info)->release_pcr_selection);\ + UNLOAD_BLOB_TYPE(buf, offset, &(info)->digest_at_creation);\ + UNLOAD_BLOB_TYPE(buf, offset, &(info)->digest_at_release);\ +} + +#define UNLOAD_STORED_DATA12(buf, offset, hdr) {\ + UNLOAD_INTEGER(buf, offset, ((const tpm_stored_data12_header_t *)(hdr))->tag);\ + UNLOAD_INTEGER(buf, offset, ((const tpm_stored_data12_header_t *)(hdr))->et);\ + UNLOAD_INTEGER(buf, offset,\ + ((const tpm_stored_data12_header_t *)(hdr))->seal_info_size);\ + if ( ((const tpm_stored_data12_header_t *)(hdr))->seal_info_size == 0 ) {\ + UNLOAD_INTEGER(buf, offset,\ + ((const tpm_stored_data12_short_t *)hdr)->enc_data_size);\ + UNLOAD_BLOB(buf, offset,\ + ((const tpm_stored_data12_short_t *)hdr)->enc_data,\ + ((const tpm_stored_data12_short_t *)hdr)->enc_data_size);\ + }\ + else {\ + UNLOAD_PCR_INFO_LONG(buf, offset,\ + &((const tpm_stored_data12_t *)hdr)->seal_info);\ + UNLOAD_INTEGER(buf, offset,\ + ((const tpm_stored_data12_t *)hdr)->enc_data_size);\ + UNLOAD_BLOB(buf, offset,\ + ((const tpm_stored_data12_t *)hdr)->enc_data,\ + ((const tpm_stored_data12_t *)hdr)->enc_data_size);\ + }\ +} + +#define LOAD_INTEGER(buf, offset, var) {\ + reverse_copy(&(var), buf + offset, sizeof(var));\ + offset += sizeof(var);\ +} + +#define LOAD_BLOB(buf, offset, blob, size) {\ + memcpy(blob, buf + offset, size);\ + offset += size;\ +} + +#define LOAD_BLOB_TYPE(buf, offset, blob) \ + LOAD_BLOB(buf, offset, blob, sizeof(*(blob))) + +#define LOAD_PCR_SELECTION(buf, offset, sel) {\ + LOAD_INTEGER(buf, offset, (sel)->size_of_select);\ + LOAD_BLOB(buf, offset, (sel)->pcr_select, (sel)->size_of_select);\ +} + +#define LOAD_PCR_INFO_SHORT(buf, offset, info) {\ + LOAD_PCR_SELECTION(buf, offset, &(info)->pcr_selection);\ + LOAD_BLOB_TYPE(buf, offset, &(info)->locality_at_release);\ + LOAD_BLOB_TYPE(buf, offset, &(info)->digest_at_release);\ +} + +#define LOAD_NV_ATTRIBUTES(buf, offset, attr) {\ + LOAD_INTEGER(buf, offset, (attr)->tag);\ + LOAD_INTEGER(buf, offset, (attr)->attributes);\ +} + +/* Single-byte values do not require reverse_copy(endianness n/a) */ +#define LOAD_NV_DATA_PUBLIC(buf, offset, pub) {\ + LOAD_INTEGER(buf, offset, (pub)->tag);\ + LOAD_INTEGER(buf, offset, (pub)->nv_index);\ + LOAD_PCR_INFO_SHORT(buf, offset, &(pub)->pcr_info_read);\ + LOAD_PCR_INFO_SHORT(buf, offset, &(pub)->pcr_info_write);\ + LOAD_NV_ATTRIBUTES(buf, offset, &(pub)->permission);\ + (pub)->b_read_st_clear = *(buf + offset); offset += 1;\ + (pub)->b_write_st_clear = *(buf + offset); offset += 1;\ + (pub)->b_write_define = *(buf + offset); offset += 1;\ + LOAD_INTEGER(buf, offset, (pub)->data_size);\ +} + +#define LOAD_PCR_INFO_LONG(buf, offset, info) {\ + LOAD_INTEGER(buf, offset, (info)->tag);\ + LOAD_BLOB_TYPE(buf, offset, &(info)->locality_at_creation);\ + LOAD_BLOB_TYPE(buf, offset, &(info)->locality_at_release);\ + LOAD_PCR_SELECTION(buf, offset, &(info)->creation_pcr_selection);\ + LOAD_PCR_SELECTION(buf, offset, &(info)->release_pcr_selection);\ + LOAD_BLOB_TYPE(buf, offset, &(info)->digest_at_creation);\ + LOAD_BLOB_TYPE(buf, offset, &(info)->digest_at_release);\ +} + +#define LOAD_STORED_DATA12(buf, offset, hdr) {\ + LOAD_INTEGER(buf, offset, ((tpm_stored_data12_header_t *)(hdr))->tag);\ + LOAD_INTEGER(buf, offset, ((tpm_stored_data12_header_t *)(hdr))->et);\ + LOAD_INTEGER(buf, offset, \ + ((tpm_stored_data12_header_t *)(hdr))->seal_info_size);\ + if ( ((tpm_stored_data12_header_t *)(hdr))->seal_info_size == 0 ) {\ + LOAD_INTEGER(buf, offset,\ + ((tpm_stored_data12_short_t *)hdr)->enc_data_size);\ + LOAD_BLOB(buf, offset,\ + ((tpm_stored_data12_short_t *)hdr)->enc_data,\ + ((tpm_stored_data12_short_t *)hdr)->enc_data_size);\ + }\ + else {\ + LOAD_PCR_INFO_LONG(buf, offset,\ + &((tpm_stored_data12_t *)hdr)->seal_info);\ + LOAD_INTEGER(buf, offset,\ + ((tpm_stored_data12_t *)hdr)->enc_data_size);\ + LOAD_BLOB(buf, offset,\ + ((tpm_stored_data12_t *)hdr)->enc_data,\ + ((tpm_stored_data12_t *)hdr)->enc_data_size);\ + }\ +} + + +#define XOR_BLOB_TYPE(data, pad) {\ + uint32_t i; \ + for ( i = 0; i < sizeof(*(data)); i++ ) \ + ((uint8_t *)data)[i] ^= ((uint8_t *)pad)[i % sizeof(*(pad))];\ +} + + +typedef uint32_t tpm_capability_area_t; + +#define TPM_CAP_NV_INDEX 0x00000011 + + +typedef struct __attribute__ ((packed)) { + tpm_pcr_selection_t pcr_selection; + tpm_locality_selection_t locality_at_release; + tpm_composite_hash_t digest_at_release; +} tpm_pcr_info_short_t; + +typedef struct __attribute__ ((packed)) { + tpm_structure_tag_t tag; + uint32_t attributes; +} tpm_nv_attributes_t; + +typedef struct __attribute__ ((packed)) { + tpm_structure_tag_t tag; + tpm_nv_index_t nv_index; + tpm_pcr_info_short_t pcr_info_read; + tpm_pcr_info_short_t pcr_info_write; + tpm_nv_attributes_t permission; + uint8_t b_read_st_clear; + uint8_t b_write_st_clear; + uint8_t b_write_define; + uint32_t data_size; +} tpm_nv_data_public_t; + + + +typedef struct __attribute__ ((packed)) { + tpm_structure_tag_t tag; + uint8_t disable; + uint8_t ownership; + uint8_t deactivated; + uint8_t read_pubek; + uint8_t disable_owner_clear; + uint8_t allow_maintenance; + uint8_t physical_presence_lifetime_lock; + uint8_t physical_presence_hw_enable; + uint8_t physical_presence_cmd_enable; + uint8_t cekp_used; + uint8_t tpm_post; + uint8_t tpm_post_lock; + uint8_t fips; + uint8_t operator; + uint8_t enable_revoke_ek; + uint8_t nv_locked; + uint8_t read_srk_pub; + uint8_t tpm_established; + uint8_t maintenance_done; + uint8_t disable_full_da_logic_info; +} tpm_permanent_flags_t; + +typedef struct __attribute__ ((packed)) { + tpm_structure_tag_t tag; + uint8_t deactivated; + uint8_t disable_force_clear; + uint8_t physical_presence; + uint8_t phycical_presence_lock; + uint8_t b_global_lock; +} tpm_stclear_flags_t; + +#define TPM_CAP_FLAG 0x00000004 +#define TPM_CAP_FLAG_PERMANENT 0x00000108 +#define TPM_CAP_FLAG_VOLATILE 0x00000109 + + +#define TPM_CAP_PROPERTY 0x00000005 +#define TPM_CAP_PROP_TIS_TIMEOUT 0x00000115 + + +/* + * tpm_get_nv_data_public uses TPM_GETCAPABILITY cmd to get the public + * data associated with the NV given index. + * + * return : TPM_SUCCESS for success, error code defined as TPM_xxx + */ +extern uint32_t tpm_get_nv_data_public(uint32_t locality, + tpm_nv_index_t index, + tpm_nv_data_public_t *pub); + +/* Functions newly required to be extern since they can be referenced + * from tpm_extra.c as well. */ +extern uint32_t _tpm_submit_cmd(uint32_t locality, uint16_t tag, uint32_t cmd, + uint32_t arg_size, uint32_t *out_size); + +extern uint32_t tpm_submit_cmd(uint32_t locality, uint32_t cmd, + uint32_t arg_size, uint32_t *out_size); +extern uint32_t tpm_get_capability( + uint32_t locality, tpm_capability_area_t cap_area, + uint32_t sub_cap_size, const uint8_t *sub_cap, + uint32_t *resp_size, uint8_t *resp); + +#endif // __ASSEMBLY__ + + +#endif /* __TPM_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libtpm/tpm.c b/xmhf-64/xmhf/src/libbaremetal/libtpm/tpm.c new file mode 100644 index 0000000000..2657abab55 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libtpm/tpm.c @@ -0,0 +1,469 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * tpm.c: TPM-related support functions + * + * Copyright (c) 2006-2010, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * Modified for XMHF by jonmccune@cmu.edu, 2011.01.18 + * + * "Extra" functions unnecessary in SL denoted as such. + */ + +/** + * Adapted for libtpm - generic TPM library + * by Amit Vasudevan amitvasudevan@acm.org + */ + +#include +#include +#include +#include +#include + + +/* + * The _tpm_submit_cmd function comes with 2 global buffers: cmd_buf & rsp_buf. + * Before calling, caller should fill cmd arguements into cmd_buf via + * WRAPPER_IN_BUF macro. After calling, caller should fetch result from + * rsp_buffer via WRAPPER_OUT_BUF macro. + * cmd_buf content: + * 0 1 2 3 4 5 6 7 8 9 10 ... + * ------------------------------------------------------------- + * | TAG | SIZE | ORDINAL | arguments ... + * ------------------------------------------------------------- + * rsp_buf content: + * 0 1 2 3 4 5 6 7 8 9 10 ... + * ------------------------------------------------------------- + * | TAG | SIZE | RETURN CODE | other data ... + * ------------------------------------------------------------- + * + * locality : TPM locality (0 - 4) + * tag : The TPM command tag + * cmd : The TPM command ordinal + * arg_size : Size of argument data. + * out_size : IN/OUT paramter. The IN is the expected size of out data; + * the OUT is the size of output data within out buffer. + * The out_size MUST NOT be NULL. + * return : TPM_SUCCESS for success, for other error code, refer to the .h + */ +/* static */ +uint8_t cmd_buf[TPM_CMD_SIZE_MAX]; +/* static */ +uint8_t rsp_buf[TPM_RSP_SIZE_MAX]; + +/* static */ +uint32_t _tpm_submit_cmd(uint32_t locality, uint16_t tag, uint32_t cmd, + uint32_t arg_size, uint32_t *out_size) +{ + uint32_t ret; + uint32_t cmd_size, rsp_size = 0; + + if ( out_size == NULL ) { + printf("TPM: invalid param for _tpm_submit_cmd()\n"); + return TPM_BAD_PARAMETER; + } + + /* + * real cmd size should add 10 more bytes: + * 2 bytes for tag + * 4 bytes for size + * 4 bytes for ordinal + */ + cmd_size = CMD_HEAD_SIZE + arg_size; + + if ( cmd_size > TPM_CMD_SIZE_MAX ) { + printf("TPM: cmd exceeds the max supported size.\n"); + return TPM_BAD_PARAMETER; + } + + /* copy tag, size & ordinal into buf in a reversed byte order */ + reverse_copy(cmd_buf, &tag, sizeof(tag)); + reverse_copy(cmd_buf + CMD_SIZE_OFFSET, &cmd_size, sizeof(cmd_size)); + reverse_copy(cmd_buf + CMD_ORD_OFFSET, &cmd, sizeof(cmd)); + + rsp_size = RSP_HEAD_SIZE + *out_size; + rsp_size = (rsp_size > TPM_RSP_SIZE_MAX) ? TPM_RSP_SIZE_MAX: rsp_size; + ret = tpm_write_cmd_fifo(locality, cmd_buf, cmd_size, rsp_buf, &rsp_size); + + /* + * should subtract 10 bytes from real response size: + * 2 bytes for tag + * 4 bytes for size + * 4 bytes for return code + */ + rsp_size -= (rsp_size > RSP_HEAD_SIZE) ? RSP_HEAD_SIZE : rsp_size; + + if ( ret != TPM_SUCCESS ) + return ret; + + if ( *out_size == 0 || rsp_size == 0 ) + *out_size = 0; + else + *out_size = (rsp_size < *out_size) ? rsp_size : *out_size; + + return ret; +} + +/* from emhf's processor.h */ +static inline uint64_t rdtsc64(void) +{ +#ifdef __AMD64__ + uint32_t eax, edx; + + __asm__ __volatile__ ("rdtsc" : "=a" (eax), "=d" (edx)); + return ((uint64_t)edx << 32) | eax; +#elif defined(__I386__) + uint64_t rv; + + __asm__ __volatile__ ("rdtsc" : "=A" (rv)); + return (rv); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +} + +/*static inline*/ +uint32_t tpm_submit_cmd(uint32_t locality, uint32_t cmd, + uint32_t arg_size, uint32_t *out_size) +{ + uint32_t rv; + uint64_t start, end; + + start = rdtsc64(); + rv = _tpm_submit_cmd(locality, TPM_TAG_RQU_COMMAND, cmd, + arg_size, out_size); + end = rdtsc64(); + printf("TPM: PERF: Command 0x%08x consumed %lld cycles\n", cmd, end-start); + return rv; +} + + +uint32_t tpm_pcr_read(uint32_t locality, uint32_t pcr, tpm_pcr_value_t *out) +{ + uint32_t ret, out_size = sizeof(*out); + + if ( out == NULL ) + return TPM_BAD_PARAMETER; + if ( pcr >= TPM_NR_PCRS ) + return TPM_BAD_PARAMETER; + + /* copy pcr into buf in reversed byte order */ + reverse_copy(WRAPPER_IN_BUF, &pcr, sizeof(pcr)); + + ret = tpm_submit_cmd(locality, TPM_ORD_PCR_READ, sizeof(pcr), &out_size); + +#ifdef TPM_TRACE + printf("TPM: Pcr %d Read return value = %08X\n", pcr, ret); +#endif + if ( ret != TPM_SUCCESS ) { + printf("TPM: Pcr %d Read return value = %08X\n", pcr, ret); + return ret; + } + + if ( out_size > sizeof(*out) ) + out_size = sizeof(*out); + memcpy((void *)out, WRAPPER_OUT_BUF, out_size); + +#ifdef TPM_TRACE + { + printf("TPM: "); + print_hex(NULL, out->digest, out_size); + } +#endif + + return ret; +} + +uint32_t tpm_pcr_extend(uint32_t locality, uint32_t pcr, + const tpm_digest_t* in, tpm_pcr_value_t* out) +{ + uint32_t ret, in_size = 0, out_size; + + if ( in == NULL ) + return TPM_BAD_PARAMETER; + if ( pcr >= TPM_NR_PCRS ) + return TPM_BAD_PARAMETER; + if ( out == NULL ) + out_size = 0; + else + out_size = sizeof(*out); + + /* copy pcr into buf in reversed byte order, then copy in data */ + reverse_copy(WRAPPER_IN_BUF, &pcr, sizeof(pcr)); + in_size += sizeof(pcr); + memcpy(WRAPPER_IN_BUF + in_size, (const void *)in, sizeof(*in)); + in_size += sizeof(*in); + + ret = tpm_submit_cmd(locality, TPM_ORD_PCR_EXTEND, in_size, &out_size); + +#ifdef TPM_TRACE + printf("TPM: Pcr %d extend, return value = %08X\n", pcr, ret); +#endif + if ( ret != TPM_SUCCESS ) { + printf("TPM: Pcr %d extend, return value = %08X\n", pcr, ret); + return ret; + } + + if ( out != NULL && out_size > 0 ) { + out_size = (out_size > sizeof(*out)) ? sizeof(*out) : out_size; + memcpy((void *)out, WRAPPER_OUT_BUF, out_size); + } + +#ifdef TPM_TRACE + { + printf("TPM: "); + print_hex(NULL, out->digest, out_size); + } +#endif + + return ret; +} + + + +/* get tpm module version */ +uint32_t tpm_get_version(uint8_t *major, uint8_t *minor) +{ + uint32_t ret, in_size = 0, out_size; + uint32_t cap_area = TPM_CAP_VERSION_VAL; + uint32_t sub_cap_size = 0; + uint32_t resp_size = 0; + tpm_cap_version_info_t *cap_version; + + if ( major == NULL || minor == NULL ) + return TPM_BAD_PARAMETER; + + reverse_copy(WRAPPER_IN_BUF, &cap_area, sizeof(cap_area)); + in_size += sizeof(cap_area); + reverse_copy(WRAPPER_IN_BUF+in_size, &sub_cap_size, sizeof(sub_cap_size)); + in_size += sizeof(sub_cap_size); + + out_size = sizeof(resp_size) + sizeof(tpm_cap_version_info_t); + ret = tpm_submit_cmd(0, TPM_ORD_GET_CAPABILITY, in_size, &out_size); + +#ifdef TPM_TRACE + printf("TPM: get version, return value = %08X\n", ret); +#endif + if ( ret != TPM_SUCCESS ) { + printf("TPM: get version, return value = %08X\n", ret); + return ret; + } + +#ifdef TPM_TRACE + { + printf("TPM: "); + print_hex(NULL, WRAPPER_OUT_BUF, out_size); + } +#endif + + reverse_copy(&resp_size, WRAPPER_OUT_BUF, sizeof(resp_size)); + cap_version = (tpm_cap_version_info_t *) + (WRAPPER_OUT_BUF + sizeof(resp_size)); + *major = cap_version->version.major; + *minor = cap_version->version.minor; + + return ret; +} + + + +/* static */ +uint32_t tpm_get_capability( + uint32_t locality, tpm_capability_area_t cap_area, + uint32_t sub_cap_size, const uint8_t *sub_cap, + uint32_t *resp_size, uint8_t *resp) +{ + uint32_t ret, offset, out_size; + + if ( sub_cap == NULL || resp_size == NULL || resp == NULL ) { + printf("TPM: tpm_get_capability() bad parameter\n"); + return TPM_BAD_PARAMETER; + } + + offset = 0; + UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, cap_area); + UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, sub_cap_size); + UNLOAD_BLOB(WRAPPER_IN_BUF, offset, sub_cap, sub_cap_size); + + out_size = sizeof(*resp_size) + *resp_size; + + ret = tpm_submit_cmd(locality, TPM_ORD_GET_CAPABILITY, offset, &out_size); + +#ifdef TPM_TRACE + printf("TPM: get capability, return value = %08X\n", ret); +#endif + if ( ret != TPM_SUCCESS ) { + printf("TPM: get capability, return value = %08X\n", ret); + return ret; + } + + offset = 0; + LOAD_INTEGER(WRAPPER_OUT_BUF, offset, *resp_size); + if ( out_size < sizeof(*resp_size) + *resp_size ) { + printf("TPM: capability response too small\n"); + return TPM_FAIL; + } + LOAD_BLOB(WRAPPER_OUT_BUF, offset, resp, *resp_size); + + return ret; +} + + +uint32_t tpm_get_random(uint32_t locality, uint8_t *random_data, + uint32_t *data_size) +{ + uint32_t ret, in_size = 0, out_size, requested_size; + static bool first_attempt; + uint32_t second_size; + + if ( random_data == NULL || data_size == NULL ) + return TPM_BAD_PARAMETER; + if ( *data_size == 0 ) + return TPM_BAD_PARAMETER; + + first_attempt = true; + requested_size = *data_size; + + /* copy the *data_size into buf in reversed byte order */ + reverse_copy(WRAPPER_IN_BUF + in_size, data_size, sizeof(*data_size)); + in_size += sizeof(*data_size); + + out_size = *data_size + sizeof(*data_size); + ret = tpm_submit_cmd(locality, TPM_ORD_GET_RANDOM, in_size, &out_size); + +#ifdef TPM_TRACE + printf("TPM: get random %u bytes, return value = %08X\n", *data_size, ret); +#endif + if ( ret != TPM_SUCCESS ) { + printf("TPM: get random %u bytes, return value = %08X\n", *data_size, + ret); + return ret; + } + +#ifdef TPM_TRACE + { + printf("TPM: "); + print_hex(NULL, WRAPPER_OUT_BUF, out_size); + } +#endif + + if ( out_size <= sizeof(*data_size) ) { + *data_size = 0; + return ret; + } + + out_size -= sizeof(*data_size); + reverse_copy(data_size, WRAPPER_OUT_BUF, sizeof(*data_size)); + if ( *data_size > 0 ) + memcpy(random_data, WRAPPER_OUT_BUF + sizeof(*data_size), *data_size); + + /* data might be used as key, so clear from buffer memory */ + memset(WRAPPER_OUT_BUF + sizeof(*data_size), 0, *data_size); + + /* if TPM doesn't return all requested random bytes, try one more time */ + if ( *data_size < requested_size ) { + printf("requested %x random bytes but only got %x\n", requested_size, + *data_size); + /* we're only going to try twice */ + if ( first_attempt ) { + first_attempt = false; + second_size = requested_size - *data_size; + printf("trying one more time to get remaining %x bytes\n", + second_size); + ret = tpm_get_random(locality, random_data + *data_size, + &second_size); + *data_size += second_size; + } + } + + return ret; +} + + + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libtpm/tpm_extra.c b/xmhf-64/xmhf/src/libbaremetal/libtpm/tpm_extra.c new file mode 100644 index 0000000000..d62d279caa --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libtpm/tpm_extra.c @@ -0,0 +1,1034 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * tpm.c: TPM-related support functions + * + * Copyright (c) 2006-2010, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * Modified for XMHF by jonmccune@cmu.edu, 2011.01.18 + * + * "Extra" functions unnecessary in SL denoted as such. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* These go with _tpm_submit_cmd in tpm.c */ +extern uint8_t cmd_buf[TPM_CMD_SIZE_MAX]; +extern uint8_t rsp_buf[TPM_RSP_SIZE_MAX]; + + +static int sha1_id = -1; + +/* compatibility wrapper */ +static void HMAC_SHA1( uint8_t* secret, size_t secret_len, + uint8_t* in, size_t in_len, + uint8_t* out) +{ + int rv; + unsigned long out_len; + + if (sha1_id < 0) { + sha1_id = register_hash( &sha1_desc); + } + + out_len = hash_descriptor[sha1_id].hashsize; + rv = hmac_memory( sha1_id, + secret, secret_len, + in, in_len, + out, &out_len); + if (rv) { + abort(); + } +} + +uint32_t tpm_pcr_reset(uint32_t locality, uint32_t pcr) +{ + uint32_t ret, in_size, out_size = 0; + uint16_t size_of_select; + tpm_pcr_selection_t pcr_sel = {0,{0,}}; + + if ( pcr >= TPM_NR_PCRS || pcr < TPM_PCR_RESETABLE_MIN ) + return TPM_BAD_PARAMETER; + + /* the pcr_sel.pcr_select[size_of_select - 1] should not be 0 */ + size_of_select = pcr / 8 + 1; + reverse_copy(&pcr_sel.size_of_select, &size_of_select, + sizeof(size_of_select)); + pcr_sel.pcr_select[pcr / 8] = 1 << (pcr % 8); + + in_size = sizeof(pcr_sel); + memcpy(WRAPPER_IN_BUF, (void *)&pcr_sel, in_size); + + ret = tpm_submit_cmd(locality, TPM_ORD_PCR_RESET, in_size, &out_size); + + printf("TPM: Pcr %d reset, return value = %08X\n", pcr, ret); + + return ret; +} + +uint32_t tpm_nv_read_value(uint32_t locality, tpm_nv_index_t index, + uint32_t offset, uint8_t *data, + uint32_t *data_size) +{ + uint32_t ret, in_size = 0, out_size; + + if ( data == NULL || data_size == NULL ) + return TPM_BAD_PARAMETER; + if ( *data_size == 0 ) + return TPM_BAD_PARAMETER; + if ( *data_size > TPM_NV_READ_VALUE_DATA_SIZE_MAX ) + *data_size = TPM_NV_READ_VALUE_DATA_SIZE_MAX; + + /* copy the index, offset and *data_size into buf in reversed byte order */ + reverse_copy(WRAPPER_IN_BUF, &index, sizeof(index)); + in_size += sizeof(index); + reverse_copy(WRAPPER_IN_BUF + in_size, &offset, sizeof(offset)); + in_size += sizeof(offset); + reverse_copy(WRAPPER_IN_BUF + in_size, data_size, sizeof(*data_size)); + in_size += sizeof(*data_size); + + out_size = *data_size + sizeof(*data_size); + ret = tpm_submit_cmd(locality, TPM_ORD_NV_READ_VALUE, in_size, &out_size); + +#ifdef TPM_TRACE + printf("TPM: read nv index %08x from offset %08x, return value = %08X\n", + index, offset, ret); +#endif + if ( ret != TPM_SUCCESS ) { + printf("TPM: read nv index %08x offset %08x, return value = %08X\n", + index, offset, ret); + return ret; + } + +#ifdef TPM_TRACE + { + printf("TPM: "); + print_hex(NULL, WRAPPER_OUT_BUF, out_size); + } +#endif + + if ( out_size <= sizeof(*data_size) ) { + *data_size = 0; + return ret; + } + + out_size -= sizeof(*data_size); + reverse_copy(data_size, WRAPPER_OUT_BUF, sizeof(*data_size)); + *data_size = (*data_size > out_size) ? out_size : *data_size; + if( *data_size > 0 ) + memcpy(data, WRAPPER_OUT_BUF + sizeof(*data_size), *data_size); + + return ret; +} + +uint32_t tpm_nv_write_value(uint32_t locality, tpm_nv_index_t index, + uint32_t offset, const uint8_t *data, + uint32_t data_size) +{ + uint32_t ret, in_size = 0, out_size = 0; + + if ( data == NULL ) + return TPM_BAD_PARAMETER; + if ( data_size == 0 || data_size > TPM_NV_WRITE_VALUE_DATA_SIZE_MAX ) + return TPM_BAD_PARAMETER; + + /* copy index, offset and *data_size into buf in reversed byte order */ + reverse_copy(WRAPPER_IN_BUF, &index, sizeof(index)); + in_size += sizeof(index); + reverse_copy(WRAPPER_IN_BUF + in_size, &offset, sizeof(offset)); + in_size += sizeof(offset); + reverse_copy(WRAPPER_IN_BUF + in_size, &data_size, sizeof(data_size)); + in_size += sizeof(data_size); + memcpy(WRAPPER_IN_BUF + in_size, data, data_size); + in_size += data_size; + + ret = tpm_submit_cmd(locality, TPM_ORD_NV_WRITE_VALUE, + in_size, &out_size); + +#ifdef TPM_TRACE + printf("TPM: write nv %08x, offset %08x, %08x bytes, return = %08X\n", + index, offset, data_size, ret); +#endif + if ( ret != TPM_SUCCESS ) + printf("TPM: write nv %08x, offset %08x, %08x bytes, return = %08X\n", + index, offset, data_size, ret); + + return ret; +} + + +static inline uint32_t tpm_submit_cmd_auth1(uint32_t locality, uint32_t cmd, + uint32_t arg_size, uint32_t *out_size) +{ + return _tpm_submit_cmd(locality, TPM_TAG_RQU_AUTH1_COMMAND, cmd, + arg_size, out_size); +} + +static inline uint32_t tpm_submit_cmd_auth2(uint32_t locality, uint32_t cmd, + uint32_t arg_size, uint32_t *out_size) +{ + return _tpm_submit_cmd(locality, TPM_TAG_RQU_AUTH2_COMMAND, cmd, + arg_size, out_size); +} + +static uint32_t tpm_oiap(uint32_t locality, tpm_authhandle_t *hauth, + tpm_nonce_t *nonce_even) +{ + uint32_t ret, offset, out_size; + + if ( hauth == NULL || nonce_even == NULL ) + return TPM_BAD_PARAMETER; + + offset = 0; + + out_size = sizeof(*hauth) + sizeof(*nonce_even); + + ret = tpm_submit_cmd(locality, TPM_ORD_OIAP, offset, &out_size); + +#ifdef TPM_TRACE + printf("TPM: start OIAP, return value = %08X\n", ret); +#endif + if ( ret != TPM_SUCCESS ) { + printf("TPM: start OIAP, return value = %08X\n", ret); + return ret; + } + +#ifdef TPM_TRACE + { + printf("TPM: "); + print_hex(NULL, WRAPPER_OUT_BUF, out_size); + } +#endif + + offset = 0; + LOAD_INTEGER(WRAPPER_OUT_BUF, offset, *hauth); + LOAD_BLOB_TYPE(WRAPPER_OUT_BUF, offset, nonce_even); + + return ret; +} + +static uint32_t tpm_osap(uint32_t locality, tpm_entity_type_t ent_type, + uint32_t ent_value, const tpm_nonce_t *odd_osap, + tpm_authhandle_t *hauth, tpm_nonce_t *nonce_even, + tpm_nonce_t *even_osap) +{ + uint32_t ret, offset, out_size; + + if ( odd_osap == NULL || hauth == NULL || + nonce_even == NULL || even_osap == NULL ) + return TPM_BAD_PARAMETER; + + offset = 0; + UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, ent_type); + UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, ent_value); + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, odd_osap); + + out_size = sizeof(*hauth) + sizeof(*nonce_even) + sizeof(*even_osap); + ret = tpm_submit_cmd(locality, TPM_ORD_OSAP, offset, &out_size); + +#ifdef TPM_TRACE + printf("TPM: start OSAP, return value = %08X\n", ret); +#endif + if ( ret != TPM_SUCCESS ) { + printf("TPM: start OSAP, return value = %08X\n", ret); + return ret; + } + +#ifdef TPM_TRACE + { + printf("TPM: "); + print_hex(NULL, WRAPPER_OUT_BUF, out_size); + } +#endif + + offset = 0; + LOAD_INTEGER(WRAPPER_OUT_BUF, offset, *hauth); + LOAD_BLOB_TYPE(WRAPPER_OUT_BUF, offset, nonce_even); + LOAD_BLOB_TYPE(WRAPPER_OUT_BUF, offset, even_osap); + + return ret; +} + +static uint32_t _tpm_seal(uint32_t locality, tpm_key_handle_t hkey, + const tpm_encauth_t *enc_auth, uint32_t pcr_info_size, + const tpm_pcr_info_long_t *pcr_info, uint32_t in_data_size, + const uint8_t *in_data, + tpm_authhandle_t hauth, const tpm_nonce_t *nonce_odd, + uint8_t *cont_session, const tpm_authdata_t *pub_auth, + uint32_t *sealed_data_size, uint8_t *sealed_data, + tpm_nonce_t *nonce_even, tpm_authdata_t *res_auth) +{ + uint32_t ret, offset, out_size; + + if ( enc_auth == NULL || pcr_info == NULL || in_data == NULL || + nonce_odd == NULL || cont_session == NULL || pub_auth == NULL || + sealed_data_size == NULL || sealed_data == NULL || + nonce_even == NULL || res_auth == NULL ) { + printf("TPM: _tpm_seal() bad parameter\n"); + return TPM_BAD_PARAMETER; + } + + offset = 0; + UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, hkey); + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, enc_auth); + UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, pcr_info_size); + UNLOAD_PCR_INFO_LONG(WRAPPER_IN_BUF, offset, pcr_info); + UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, in_data_size); + UNLOAD_BLOB(WRAPPER_IN_BUF, offset, in_data, in_data_size); + + UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, hauth); + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, nonce_odd); + UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, *cont_session); + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, pub_auth); + + out_size = WRAPPER_OUT_MAX_SIZE; + + ret = tpm_submit_cmd_auth1(locality, TPM_ORD_SEAL, offset, &out_size); + +#ifdef TPM_TRACE + printf("TPM: seal data, return value = %08X\n", ret); +#endif + if ( ret != TPM_SUCCESS ) { + printf("TPM: seal data, return value = %08X\n", ret); + return ret; + } + +#ifdef TPM_TRACE + { + printf("TPM: "); + print_hex(NULL, WRAPPER_OUT_BUF, out_size); + } +#endif + + if ( *sealed_data_size < + ( out_size - sizeof(*nonce_even) - sizeof(*cont_session) + - sizeof(*res_auth) ) ) { + printf("TPM: sealed blob is too small\n"); + return TPM_NOSPACE; + } + + offset = 0; + LOAD_STORED_DATA12(WRAPPER_OUT_BUF, offset, sealed_data); + *sealed_data_size = offset; + LOAD_BLOB_TYPE(WRAPPER_OUT_BUF, offset, nonce_even); + LOAD_INTEGER(WRAPPER_OUT_BUF, offset, *cont_session); + LOAD_BLOB_TYPE(WRAPPER_OUT_BUF, offset, res_auth); + + return ret; +} + +static uint32_t _tpm_unseal(uint32_t locality, tpm_key_handle_t hkey, + const uint8_t *in_data, + tpm_authhandle_t hauth, const tpm_nonce_t *nonce_odd, + uint8_t *cont_session, const tpm_authdata_t *auth, + tpm_authhandle_t hauth_d, const tpm_nonce_t *nonce_odd_d, + uint8_t *cont_session_d, const tpm_authdata_t *auth_d, + uint32_t *secret_size, uint8_t *secret, + tpm_nonce_t *nonce_even, tpm_authdata_t *res_auth, + tpm_nonce_t *nonce_even_d, tpm_authdata_t *res_auth_d) +{ + uint32_t ret, offset, out_size; + + if ( in_data == NULL || nonce_odd == NULL || cont_session == NULL || + auth == NULL || nonce_odd_d == NULL || cont_session_d == NULL || + auth_d == NULL || secret_size == NULL || secret == NULL || + nonce_even == NULL || res_auth == NULL || nonce_even_d == NULL || + res_auth_d == NULL ) { + printf("TPM: _tpm_unseal() bad parameter\n"); + return TPM_BAD_PARAMETER; + } + + offset = 0; + UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, hkey); + UNLOAD_STORED_DATA12(WRAPPER_IN_BUF, offset, in_data); + + UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, hauth); + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, nonce_odd); + UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, *cont_session); + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, auth); + + UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, hauth_d); + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, nonce_odd_d); + UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, *cont_session_d); + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, auth_d); + + out_size = WRAPPER_OUT_MAX_SIZE; + + ret = tpm_submit_cmd_auth2(locality, TPM_ORD_UNSEAL, offset, &out_size); + +#ifdef TPM_TRACE + printf("TPM: unseal data, return value = %08X\n", ret); +#endif + if ( ret != TPM_SUCCESS ) { + printf("TPM: unseal data, return value = %08X\n", ret); + return ret; + } + +#ifdef TPM_TRACE + { + printf("TPM: "); + print_hex(NULL, WRAPPER_OUT_BUF, out_size); + } +#endif + + if ( *secret_size < + ( out_size - sizeof(*secret_size) - sizeof(*nonce_even) + - sizeof(*cont_session) - sizeof(*res_auth) - sizeof(*nonce_even_d) + - sizeof(*cont_session_d) - sizeof(*res_auth_d) ) ) { + printf("TPM: unsealed data too small\n"); + return TPM_NOSPACE; + } + + offset = 0; + LOAD_INTEGER(WRAPPER_OUT_BUF, offset, *secret_size); + LOAD_BLOB(WRAPPER_OUT_BUF, offset, secret, *secret_size); + + LOAD_BLOB_TYPE(WRAPPER_OUT_BUF, offset, nonce_even); + LOAD_INTEGER(WRAPPER_OUT_BUF, offset, *cont_session); + LOAD_BLOB_TYPE(WRAPPER_OUT_BUF, offset, res_auth); + + LOAD_BLOB_TYPE(WRAPPER_OUT_BUF, offset, nonce_even_d); + LOAD_INTEGER(WRAPPER_OUT_BUF, offset, *cont_session_d); + LOAD_BLOB_TYPE(WRAPPER_OUT_BUF, offset, res_auth_d); + + return ret; +} + + +static const tpm_authdata_t srk_authdata = + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const tpm_authdata_t blob_authdata = + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +static uint32_t _tpm_wrap_seal(uint32_t locality, + const tpm_pcr_info_long_t *pcr_info, + uint32_t in_data_size, const uint8_t *in_data, + uint32_t *sealed_data_size, uint8_t *sealed_data) +{ + uint32_t ret; + tpm_nonce_t odd_osap, even_osap, nonce_even, nonce_odd; + tpm_authhandle_t hauth; + tpm_authdata_t shared_secret, pub_auth, res_auth; + tpm_encauth_t enc_auth; + uint8_t cont_session = false; + tpm_key_handle_t hkey = TPM_KH_SRK; + uint32_t pcr_info_size = sizeof(*pcr_info); + uint32_t offset; + uint32_t ordinal = TPM_ORD_SEAL; + tpm_digest_t digest; + + /* + * Skip generate nonce for odd_osap. Used to use the random value in stack, + * but since GCC 11 -Werror=maybe-uninitialized will cause compiler + * warning. TODO: generate a random number? + */ + memset(&odd_osap, 0, sizeof(odd_osap)); + + /* establish a osap session */ + ret = tpm_osap(locality, TPM_ET_SRK, TPM_KH_SRK, &odd_osap, &hauth, + &nonce_even, &even_osap); + if ( ret != TPM_SUCCESS ) + return ret; + + /* calculate the shared secret + shared-secret = HMAC(srk_auth, even_osap || odd_osap) */ + offset = 0; + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &even_osap); + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &odd_osap); + HMAC_SHA1((uint8_t *)&srk_authdata, sizeof(srk_authdata), + WRAPPER_IN_BUF, offset, + (uint8_t *)&shared_secret); + + /* generate ecrypted authdata for data + enc_auth = XOR(authdata, sha1(shared_secret || last_even_nonce)) */ + offset = 0; + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &shared_secret); + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &nonce_even); + sha1_buffer(WRAPPER_IN_BUF, offset, (uint8_t *)&digest); + memcpy(&enc_auth, &blob_authdata, sizeof(blob_authdata)); + XOR_BLOB_TYPE(&enc_auth, &digest); + + /* skip generate nonce for nonce_odd, just use the random value in stack */ + + /* calculate authdata */ + /* in_param_digest = sha1(1S ~ 6S) */ + offset = 0; + UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, ordinal); + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &enc_auth); + UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, pcr_info_size); + UNLOAD_PCR_INFO_LONG(WRAPPER_IN_BUF, offset, pcr_info); + UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, in_data_size); + UNLOAD_BLOB(WRAPPER_IN_BUF, offset, in_data, in_data_size); + sha1_buffer(WRAPPER_IN_BUF, offset, (uint8_t *)&digest); + + /* authdata = hmac(key, in_param_digest || auth_params) */ + offset = 0; + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &digest); + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &nonce_even); + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &nonce_odd); + UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, cont_session); + HMAC_SHA1((uint8_t *)&shared_secret, sizeof(shared_secret), + WRAPPER_IN_BUF, offset, + (uint8_t *)&pub_auth); + + /* call the simple seal function */ + ret = _tpm_seal(locality, hkey, (const tpm_encauth_t *)&enc_auth, + pcr_info_size, pcr_info, in_data_size, in_data, + hauth, &nonce_odd, &cont_session, + (const tpm_authdata_t *)&pub_auth, + sealed_data_size, sealed_data, + &nonce_even, &res_auth); + + /* skip check for res_auth */ + + return ret; +} + +static uint32_t _tpm_wrap_unseal(uint32_t locality, const uint8_t *in_data, + uint32_t *secret_size, uint8_t *secret) +{ + uint32_t ret; + tpm_nonce_t odd_osap, even_osap; + tpm_nonce_t nonce_even, nonce_odd, nonce_even_d, nonce_odd_d; + tpm_authhandle_t hauth, hauth_d; + tpm_authdata_t shared_secret; + tpm_authdata_t pub_auth, res_auth, pub_auth_d, res_auth_d; + uint8_t cont_session = false, cont_session_d = false; + tpm_key_handle_t hkey = TPM_KH_SRK; + uint32_t offset; + uint32_t ordinal = TPM_ORD_UNSEAL; + tpm_digest_t digest; + + /* + * Skip generate nonce for odd_osap. Used to use the random value in stack, + * but since GCC 11 -Werror=maybe-uninitialized will cause compiler + * warning. TODO: generate a random number? + */ + memset(&odd_osap, 0, sizeof(odd_osap)); + + /* establish a osap session */ + ret = tpm_osap(locality, TPM_ET_SRK, TPM_KH_SRK, &odd_osap, &hauth, + &nonce_even, &even_osap); + if ( ret != TPM_SUCCESS ) + return ret; + + /* calculate the shared secret + shared-secret = HMAC(auth, even_osap || odd_osap) */ + offset = 0; + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &even_osap); + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &odd_osap); + HMAC_SHA1((uint8_t *)&srk_authdata, sizeof(srk_authdata), + WRAPPER_IN_BUF, offset, + (uint8_t *)&shared_secret); + + /* establish a oiap session */ + ret = tpm_oiap(locality, &hauth_d, &nonce_even_d); + if ( ret != TPM_SUCCESS ) + return ret; + + /* skip generate nonce_odd & nonce_odd_d, just use the random values */ + + /* calculate authdata */ + /* in_param_digest = sha1(1S ~ 6S) */ + offset = 0; + UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, ordinal); + UNLOAD_STORED_DATA12(WRAPPER_IN_BUF, offset, in_data); + sha1_buffer(WRAPPER_IN_BUF, offset, (uint8_t *)&digest); + + /* authdata1 = hmac(key, in_param_digest || auth_params1) */ + offset = 0; + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &digest); + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &nonce_even); + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &nonce_odd); + UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, cont_session); + HMAC_SHA1((uint8_t *)&shared_secret, sizeof(shared_secret), + WRAPPER_IN_BUF, offset, + (uint8_t *)&pub_auth); + + /* authdata2 = hmac(key, in_param_digest || auth_params2) */ + offset = 0; + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &digest); + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &nonce_even_d); + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &nonce_odd_d); + UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, cont_session_d); + HMAC_SHA1((uint8_t *)&blob_authdata, sizeof(blob_authdata), + WRAPPER_IN_BUF, offset, + (uint8_t *)&pub_auth_d); + + /* call the simple seal function */ + ret = _tpm_unseal(locality, hkey, in_data, + hauth, &nonce_odd, &cont_session, + (const tpm_authdata_t *)&pub_auth, + hauth_d, &nonce_odd_d, &cont_session_d, + (const tpm_authdata_t *)&pub_auth_d, + secret_size, secret, + &nonce_even, &res_auth, &nonce_even_d, &res_auth_d); + + /* skip check for res_auth */ + + return ret; +} + +static bool init_pcr_info(uint32_t locality, + tpm_locality_selection_t release_locs, + uint32_t nr_create, const uint8_t indcs_create[], + uint32_t nr_release, const uint8_t indcs_release[], + const tpm_pcr_value_t *values_release[], + tpm_pcr_info_long_t *pcr_info) +{ + uint32_t offset; + uint32_t i, blob_size; + static tpm_locality_selection_t localities[TPM_NR_LOCALITIES] = { + TPM_LOC_ZERO, TPM_LOC_ONE, TPM_LOC_TWO, TPM_LOC_THREE, TPM_LOC_FOUR + }; + + + if ( (release_locs & TPM_LOC_RSVD) != 0 ) + return TPM_BAD_PARAMETER; + if ( pcr_info == NULL ) + return TPM_BAD_PARAMETER; + if ( locality >= TPM_NR_LOCALITIES ) + return TPM_BAD_PARAMETER; + if ( indcs_create == NULL ) + nr_create = 0; + if ( indcs_release == NULL || values_release == NULL ) + nr_release = 0; + for ( i = 0; i < nr_create; i++ ) + if ( indcs_create[i] >= TPM_NR_PCRS ) + return TPM_BAD_PARAMETER; + for ( i = 0; i < nr_release; i++ ) { + if ( indcs_release[i] >= TPM_NR_PCRS || values_release[i] == NULL ) + return TPM_BAD_PARAMETER; + } + + memset(pcr_info, 0, sizeof(*pcr_info)); + pcr_info->tag = TPM_TAG_PCR_INFO_LONG; + pcr_info->locality_at_creation = localities[locality]; + pcr_info->locality_at_release = release_locs; + pcr_info->creation_pcr_selection.size_of_select = 3; + for ( i = 0; i < nr_create; i++ ) + pcr_info->creation_pcr_selection.pcr_select[indcs_create[i]/8] |= + 1 << (indcs_create[i] % 8); + pcr_info->release_pcr_selection.size_of_select = 3; + for ( i = 0; i < nr_release; i++ ) + pcr_info->release_pcr_selection.pcr_select[indcs_release[i]/8] |= + 1 << (indcs_release[i] % 8); + + if ( nr_release > 0 ) { + offset = 0; + UNLOAD_PCR_SELECTION(WRAPPER_IN_BUF, offset, + &pcr_info->release_pcr_selection); + blob_size = sizeof(tpm_pcr_value_t) * nr_release; + UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, blob_size); + for ( i = 0; i < nr_release; i++ ) + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, values_release[i]); + sha1_buffer(WRAPPER_IN_BUF, offset, + (uint8_t *)&pcr_info->digest_at_release); + } + + return true; +} + +uint32_t tpm_seal(uint32_t locality, tpm_locality_selection_t release_locs, + uint32_t pcr_nr_create, const uint8_t pcr_indcs_create[], + uint32_t pcr_nr_release, const uint8_t pcr_indcs_release[], + const tpm_pcr_value_t *pcr_values_release[], + uint32_t in_data_size, const uint8_t *in_data, + uint32_t *sealed_data_size, uint8_t *sealed_data) +{ + uint32_t ret; + tpm_pcr_info_long_t pcr_info; + + if ( locality >= TPM_NR_LOCALITIES || + in_data_size == 0 || in_data == NULL || + sealed_data_size == NULL || sealed_data == NULL || + *sealed_data_size == 0 ) { + printf("TPM: tpm_seal() bad parameter\n"); + return TPM_BAD_PARAMETER; + } + + if ( !init_pcr_info(locality, release_locs, pcr_nr_create, + pcr_indcs_create, pcr_nr_release, pcr_indcs_release, + pcr_values_release, &pcr_info) ) { + printf("TPM: tpm_seal() bad parameter\n"); + return TPM_BAD_PARAMETER; + } + + ret = _tpm_wrap_seal(locality, &pcr_info, in_data_size, in_data, + sealed_data_size, sealed_data); + + return ret; +} + +static bool check_sealed_data(uint32_t size, const uint8_t *data) +{ + if ( size < sizeof(tpm_stored_data12_header_t) ) + return false; + if ( ((const tpm_stored_data12_header_t *)data)->tag != TPM_TAG_STORED_DATA12 ) + return false; + + if ( ((const tpm_stored_data12_header_t *)data)->seal_info_size == 0 ) { + const tpm_stored_data12_short_t *data12_s; + + if ( size < sizeof(*data12_s) ) + return false; + data12_s = (const tpm_stored_data12_short_t *)data; + if ( size != sizeof(*data12_s) + data12_s->enc_data_size ) + return false; + } + else { + const tpm_stored_data12_t *data12; + + if ( size < sizeof(*data12) ) + return false; + data12 = (const tpm_stored_data12_t *)data; + if ( size != sizeof(*data12) + data12->enc_data_size ) + return false; + } + + return true; +} + +uint32_t tpm_unseal(uint32_t locality, + uint32_t sealed_data_size, const uint8_t *sealed_data, + uint32_t *secret_size, uint8_t *secret) +{ + uint32_t ret; + + if ( sealed_data == NULL || + secret_size == NULL || secret == NULL ) { + printf("TPM: tpm_unseal() bad parameter\n"); + return TPM_BAD_PARAMETER; + } + + if ( !check_sealed_data(sealed_data_size, sealed_data) ) { + printf("TPM: tpm_unseal() blob invalid\n"); + return TPM_BAD_PARAMETER; + } + + ret = _tpm_wrap_unseal(locality, sealed_data, secret_size, secret); + + return ret; +} + +static void calc_pcr_composition(uint32_t nr, const uint8_t indcs[], + const tpm_pcr_value_t *values[], + tpm_composite_hash_t *composite) +{ + uint32_t i, offset, blob_size; + tpm_pcr_selection_t sel; + + if ( nr == 0 || indcs == NULL || values == NULL || composite == NULL) + return; + + sel.size_of_select = 3; + sel.pcr_select[0] = sel.pcr_select[1] = sel.pcr_select[2] = 0; + for ( i = 0; i < nr; i++ ) + sel.pcr_select[indcs[i]/8] |= 1 << (indcs[i] % 8); + + offset = 0; + UNLOAD_PCR_SELECTION(WRAPPER_IN_BUF, offset, &sel); + blob_size = sizeof(tpm_pcr_value_t) * nr; + UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, blob_size); + for ( i = 0; i < nr; i++ ) + UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, values[i]); + sha1_buffer(WRAPPER_IN_BUF, offset, (uint8_t *)composite); +} + +static tpm_composite_hash_t *get_cre_pcr_composite(uint8_t *data) +{ + if ( ((tpm_stored_data12_header_t *)data)->seal_info_size == 0 ) + return NULL; + else + return &((tpm_stored_data12_t *)data)->seal_info.digest_at_creation; +} + +bool tpm_cmp_creation_pcrs(uint32_t pcr_nr_create, + const uint8_t pcr_indcs_create[], + const tpm_pcr_value_t *pcr_values_create[], + uint32_t sealed_data_size, uint8_t *sealed_data) +{ + uint32_t i; + tpm_composite_hash_t composite = {{0,}}, *cre_composite; + + if ( pcr_indcs_create == NULL ) + pcr_nr_create = 0; + for ( i = 0; i < pcr_nr_create; i++ ) { + if ( pcr_indcs_create[i] >= TPM_NR_PCRS ) + return false; + } + if ( !check_sealed_data(sealed_data_size, sealed_data) ) { + printf("TPM: Bad blob.\n"); + return false; + } + + if ( pcr_nr_create > 0 ) + calc_pcr_composition(pcr_nr_create, pcr_indcs_create, + pcr_values_create, &composite); + + cre_composite = get_cre_pcr_composite(sealed_data); + if ( cre_composite == NULL ) + return false; + if ( memcmp((char*)&composite, (char*)cre_composite, sizeof(composite)) ) { + printf("TPM: Not equal to creation composition:\n"); + print_hex(NULL, (uint8_t *)&composite, sizeof(composite)); + print_hex(NULL, (uint8_t *)cre_composite, sizeof(composite)); + return false; + } + + return true; +} + + +uint32_t tpm_get_nvindex_size(uint32_t locality, + tpm_nv_index_t index, uint32_t *size) +{ + uint32_t ret, offset, resp_size; + uint8_t sub_cap[sizeof(index)]; + uint8_t resp[sizeof(tpm_nv_data_public_t)]; + tpm_nv_index_t idx; + + if ( size == NULL ) { + printf("TPM: tpm_get_nvindex_size() bad parameter\n"); + return TPM_BAD_PARAMETER; + } + + offset = 0; + UNLOAD_INTEGER(sub_cap, offset, index); + + resp_size = sizeof(resp); + ret = tpm_get_capability(locality, TPM_CAP_NV_INDEX, sizeof(sub_cap), + sub_cap, &resp_size, resp); + +#ifdef TPM_TRACE + printf("TPM: get nvindex size, return value = %08X\n", ret); +#endif + if ( ret != TPM_SUCCESS ) { + printf("TPM: fail to get public data of 0x%08X in TPM NV\n", index); + return ret; + } + +#ifdef TPM_TRACE + { + printf("TPM: "); + print_hex(NULL, resp, resp_size); + } +#endif + + /* check size */ + if ( resp_size == 0 ) { + printf("TPM: Index 0x%08X does not exist\n", index); + return TPM_BADINDEX; + } + + /* check index */ + offset = sizeof(tpm_structure_tag_t); + LOAD_INTEGER(resp, offset, idx); +#ifdef TPM_TRACE + printf("TPM: get index value = %08X\n", idx); +#endif + + if ( idx != index ) { + printf("TPM: Index 0x%08X is not the one expected 0x%08X\n", + idx, index); + return TPM_BADINDEX; + } + + if ( resp_size != sizeof(resp) ) { + printf("TPM: public data size of Index 0x%08X responsed incorrect\n", + index); + return TPM_FAIL; + } + + offset = resp_size - sizeof(uint32_t); + LOAD_INTEGER(resp, offset, *size); + + return ret; +} + +extern uint32_t tpm_get_nv_data_public(uint32_t locality, + tpm_nv_index_t index, + tpm_nv_data_public_t *pub) +{ + uint32_t ret, offset, resp_size; + uint8_t sub_cap[sizeof(index)]; + uint8_t resp[sizeof(tpm_nv_data_public_t)]; + tpm_nv_index_t idx; + + if ( pub == NULL ) { + printf("TPM: tpm_get_nvindex_size() bad parameter\n"); + return TPM_BAD_PARAMETER; + } + + offset = 0; + UNLOAD_INTEGER(sub_cap, offset, index); + + resp_size = sizeof(resp); + ret = tpm_get_capability(locality, TPM_CAP_NV_INDEX, sizeof(sub_cap), + sub_cap, &resp_size, resp); + +#ifdef TPM_TRACE + printf("TPM: get nv_data_public, return value = %08X\n", ret); +#endif + if ( ret != TPM_SUCCESS ) { + printf("TPM: fail to get public data of 0x%08X in TPM NV\n", index); + return ret; + } + +#ifdef TPM_TRACE + { + printf("TPM: "); + print_hex(NULL, resp, resp_size); + } +#endif + + /* check size */ + if ( resp_size == 0 ) { + printf("TPM: Index 0x%08X does not exist\n", index); + return TPM_BADINDEX; + } + + /* check index */ + offset = sizeof(tpm_structure_tag_t); + LOAD_INTEGER(resp, offset, idx); +#ifdef TPM_TRACE + printf("TPM: get index value = %08X\n", idx); +#endif + + if ( idx != index ) { + printf("TPM: Index 0x%08X is not the one expected 0x%08X\n", + idx, index); + return TPM_BADINDEX; + } + + if ( resp_size != sizeof(resp) ) { + printf("TPM: public data size of Index 0x%08X responsed incorrect\n", + index); + return TPM_FAIL; + } + + offset = 0; + LOAD_NV_DATA_PUBLIC(resp, offset, pub); + + /*print_hex(" NV pub: ", pub, resp_size);*/ + + return ret; +} + + +uint32_t tpm_save_state(uint32_t locality) +{ + uint32_t ret, offset, out_size; + uint32_t retries = 0; + + do { + offset = 0; + out_size = 0; + + ret = tpm_submit_cmd(locality, TPM_ORD_SAVE_STATE, offset, &out_size); + if ( retries == 0 ) + printf("TPM: save state, return value = %08X\n", ret); + else if ( retries == 1 ) + printf("retrying command: ."); + else + printf("."); + + if ( ret != TPM_RETRY ) + break; + + retries++; + //HALT_ON_ERRORCOND(false); // XXX need delay support + //delay(100); + //delay support; should probably end up using udelay (EMHF) or + //environment specific delay routine + printf("\nHalting, need delay support..."); + while(1); + } while ( retries < MAX_SAVESTATE_RETRIES ); + if ( retries >= MAX_SAVESTATE_RETRIES ) + printf("TIMEOUT!"); + if ( retries > 0 ) + printf("\n"); + + return ret; +} diff --git a/xmhf-64/xmhf/src/libbaremetal/libtv_utpm/Makefile b/xmhf-64/xmhf/src/libbaremetal/libtv_utpm/Makefile new file mode 100644 index 0000000000..345b97b57e --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libtv_utpm/Makefile @@ -0,0 +1,31 @@ +srcdir := $(dir $(lastword $(MAKEFILE_LIST))) +vpath %.c $(srcdir) + +C_SOURCES:= $(wildcard $(srcdir)/*.c) +C_SOURCES:= $(patsubst $(srcdir)/%, %, $(C_SOURCES)) +OBJECTS = $(patsubst %.c, %.o, $(C_SOURCES)) + +I_SOURCES := $(wildcard $(srcdir)/include/*.h) + +CFLAGS += -I$(srcdir)/../libemhfc/include -I$(srcdir)/../libemhfcrypto/include -I$(srcdir)/include -nostdinc -fno-builtin -nostdlib -Wall + +THE_ARCHIVE = libtv_utpm.a + +# targets +.PHONY: all +all: $(THE_ARCHIVE) + +$(THE_ARCHIVE): $(OBJECTS) + $(AR) -rcs $(THE_ARCHIVE) $(OBJECTS) + +#%.o: %.c $(C_SOURCES) $(I_SOURCES) Makefile ../Makefile +# $(CC) -c $(CFLAGS) -o $@ $< + +.PHONY: clean +clean: + $(RM) $(OBJECTS) $(THE_ARCHIVE) + +.PHONY: install-dev +install-dev: + # Nothing to do here + diff --git a/xmhf-64/xmhf/src/libbaremetal/libtv_utpm/README b/xmhf-64/xmhf/src/libbaremetal/libtv_utpm/README new file mode 100644 index 0000000000..4a40c0f470 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libtv_utpm/README @@ -0,0 +1,3 @@ +This directory contains the core implementation of the "MicroTPM" as proposed +for TrustVisor. It is intended to be independent of TrustVisor, and equally +amenable to testing entirely within userspace from a suitable test harness. diff --git a/xmhf-64/xmhf/src/libbaremetal/libtv_utpm/include/tv_utpm.h b/xmhf-64/xmhf/src/libbaremetal/libtv_utpm/include/tv_utpm.h new file mode 100644 index 0000000000..6b09a6e34f --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libtv_utpm/include/tv_utpm.h @@ -0,0 +1,298 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/** + * Common type and structure definitions across TrustVisor's internal + * Micro-TPM implementation, tee-sdk's svcapi, and any PAL writer who + * uses any of the relevant Micro-TPM operations. + */ + +#ifndef _TV_UTPM_H_ +#define _TV_UTPM_H_ + +/** + * FIXME: Once libemhfcrypto exists, it may be reasonable to depend on + * rsa.h in here. For now, it's not. + */ +//#include + +/* Intentionally not including basic types such as uintXX_t, since the + * headers that provide these may vary across hypervisor-internal + * environments and test userspace builds. Whatever code consumes + * this header is expected to have included the appropriate basic + * types already. */ + +/* FIXME: A lot of these values are also defined in the public header + * files for a TSS. We should consider leveraging those and changing + * the names here of the ones where we break compatibility. */ + +/* constant value for TPM chip */ +#define TPM_RSA_KEY_LEN 256 /* RSA key size is 2048 bit */ +#define TPM_HASH_SIZE 20 + +#define MAX_PCR_SEL_NUM 4 +#define MAX_PCR_SEL_SIZE (4+4*MAX_PCR_SEL_NUM) +#define MAX_PCR_DATA_SIZE (MAX_PCR_SEL_NUM*20) + +#define MAX_TPM_EXTEND_DATA_LEN 4096 +#define MAX_TPM_RAND_DATA_LEN 4096 + +#define TPM_QUOTE_SIZE ( 8 + MAX_PCR_SEL_SIZE + MAX_PCR_DATA_SIZE + TPM_NONCE_SIZE + TPM_RSA_KEY_LEN ) + +#define TPM_CONFOUNDER_SIZE 20 + +/* Return codes for uTPM operations. */ +#define UTPM_SUCCESS 0 +#define UTPM_ERR_BAD_PARAM 1 +#define UTPM_ERR_PCR_OUT_OF_RANGE 2 +#define UTPM_ERR_INSUFFICIENT_ENTROPY 3 +#define UTPM_ERR 4 + +/* MicroTPM related definitions */ +#define TPM_PCR_SIZE 20 +#define TPM_AES_KEY_LEN 128 /* key size is 128 bit */ +#define TPM_AES_KEY_LEN_BYTES (TPM_AES_KEY_LEN/8) +#define TPM_HMAC_KEY_LEN 20 + +/* max len of sealed data */ +#define MAX_SEALDATA_LEN 2048 +#define SEALDATA_HEADER_LEN 48 + +/* TODO: create an enum with meaningful errors that can be passed back + * to PAL authors. */ +typedef uint32_t TPM_RESULT; + +#define TPM_PCR_NUM 8 + +struct tdTPM_PCR_SELECTION { + uint16_t sizeOfSelect; /* The size in bytes of the pcrSelect structure */ + uint8_t pcrSelect[TPM_PCR_NUM/8]; /* This SHALL be a bit map that indicates if a PCR + is active or not */ +} __attribute__((packed)); + +typedef struct tdTPM_PCR_SELECTION TPM_PCR_SELECTION; + +#define TPM_MAX_QUOTE_LEN ( \ + sizeof(TPM_PCR_SELECTION) + sizeof(uint32_t) \ + + TPM_PCR_NUM*TPM_HASH_SIZE /* max size of TPM_PCR_COMPOSITE */ \ + + sizeof(uint32_t) /* sigSize */ \ + + TPM_RSA_KEY_LEN) /* sig */ + + +static inline void utpm_pcr_select_i(TPM_PCR_SELECTION *tpmsel, uint32_t i) { + /* TODO: fail loudly if any of these conditions do not hold */ + if(NULL == tpmsel) return; + if(i >= TPM_PCR_NUM) return; + /*if(i/8 >= tpmsel->sizeOfSelect) return; */ /* deprecated in favor of + * auto-growing, as in the + * next line. */ + + if(tpmsel->sizeOfSelect < i/8+1) { tpmsel->sizeOfSelect = i/8+1; } /* XXX not future-proof */ + /* Set the bit corresponding to PCR i */ + tpmsel->pcrSelect[i/8] |= (1 << (i%8)); +} + +static inline bool utpm_pcr_is_selected(TPM_PCR_SELECTION *tpmsel, uint32_t i) { + /* TODO: fail loudly if any of these conditions do not hold */ + if(NULL == tpmsel) return false; + if(i >= TPM_PCR_NUM) return false; + if(i/8 >= tpmsel->sizeOfSelect) return false; + + return (tpmsel->pcrSelect[i/8] & (1 << (i%8))); +} + +typedef struct tdTPM_DIGEST{ + uint8_t value[TPM_HASH_SIZE]; +} TPM_DIGEST; + +typedef TPM_DIGEST TPM_COMPOSITE_HASH; + +typedef struct tdTPM_PCR_INFO { + TPM_PCR_SELECTION pcrSelection; /* This SHALL be the selection of PCRs to which the + data or key is bound. */ + TPM_COMPOSITE_HASH digestAtRelease; /* This SHALL be the digest of the PCR indices and + PCR values to verify when revealing Sealed Data + or using a key that was wrapped to PCRs. NOTE: + This is passed in by the host, and used as + authorization to use the key */ + TPM_COMPOSITE_HASH digestAtCreation; /* This SHALL be the composite digest value of the + PCR values, at the time when the sealing is + performed. NOTE: This is generated at key + creation, but is just informative to the host, + not used for authorization */ +} TPM_PCR_INFO; + +/** + * Return the amount of space overhead (in bytes) expected when + * 'inlen' bytes of plaintext are sealed to the PCRs specified in + * 'tpmsel'. + * + * NOTE: This _must_ remain consistent with the logic in utpm_seal(). + * + * TODO: Refactor utpm_seal() to have a size-only operating mode + * (i.e., when certain input parameters are NULL). It will be + * reasonable to change this function into a wrapper to call + * utpm_seal() with NULL buffers once that refactoring is complete. + */ +#define ALIGN_UP(n, boundary) (((n)+((boundary)-1))&(~((boundary)-1))) +static inline unsigned int utpm_seal_output_size(unsigned int inlen, + bool usingPcrs) +{ + unsigned int pad, size = 0; + + /** + * 6 Contributors: + * 0. IV for symmetric encryption + * 1. TPM_PCR_SELECTION (two cases: 0 PCRs, 1+ PCRs) + * 2. input_len + * 3. input itself + * 4. pad out to symmetric encryption block size + * 5. SHA1-HMAC + */ + + /* 0 */ + size += TPM_AES_KEY_LEN_BYTES; + /* 1 */ + size += usingPcrs ? sizeof(TPM_PCR_INFO) : sizeof(uint16_t); + /* 2 */ + size += sizeof(uint32_t); + /* 3 */ + size += inlen; + /* 4 */ + pad = ALIGN_UP(size, TPM_AES_KEY_LEN_BYTES) - size; + size += pad; + /* 5 */ + size += TPM_HASH_SIZE; + + return size; +} + +#define TPM_NONCE_SIZE 20 +typedef struct tdTPM_NONCE{ + uint8_t nonce[TPM_NONCE_SIZE]; +} TPM_NONCE; + +/* structure for storage */ /* XXX inconsistent with hardware TPM */ +typedef struct tdTPM_SEALED_DATA{ + /*TPM_HMAC hmac;*/ /* NOT SURE HMAC */ + uint32_t dataSize; + uint8_t* data; /*data to be sealed*/ +} TPM_SEALED_DATA; + +typedef struct tdTPM_STRUCT_VER{ + uint8_t major; /* 0x01 */ + uint8_t minor; /* 0x01 */ + uint8_t revMajor; /* 0x00 */ + uint8_t revMinor; /* 0x00 */ +} TPM_STRUCT_VER; + +typedef struct tdTPM_QUOTE_INFO{ + TPM_STRUCT_VER version; /* must be 1.1.0.0 based on TPM part2 structure */ + uint8_t fixed[4]; /* this always be the string 'QUOT'*/ + TPM_COMPOSITE_HASH digestValue; + TPM_NONCE externalData; +} TPM_QUOTE_INFO; + +/** + * Everything below is specific to the internals of a MicroTPM + * implementation, and as such is _not_ required by your average PAL + * author or tee-sdk's svcapi. + * + * TODO: Refactor this file into something more sensible. + */ + +typedef struct tdTPM_STORED_DATA{ /* XXX inconsistent with hardware TPM */ + uint32_t sealInfoSize; + TPM_PCR_INFO sealInfo; /* structure of TPM_PCR_INFO */ + uint32_t encDataSize; + uint8_t* encData; /* encrypted TPM_SEALED_DATA structure containg the confidential part of data*/ +} TPM_STORED_DATA; + +typedef struct utpm_master_state { + TPM_DIGEST pcr_bank[TPM_PCR_NUM]; +} __attribute__ ((packed)) utpm_master_state_t; + +/* TPM functions */ +TPM_RESULT utpm_pcrread(TPM_DIGEST* pcr_value, + utpm_master_state_t *utpm, uint32_t pcr_num); +TPM_RESULT utpm_extend(TPM_DIGEST *measurement, utpm_master_state_t *utpm, uint32_t pcr_num); + +TPM_RESULT utpm_seal(utpm_master_state_t *utpm, + TPM_PCR_INFO *tpmPcrInfo, + uint8_t* input, uint32_t inlen, + uint8_t* output, uint32_t* outlen); +TPM_RESULT utpm_unseal(utpm_master_state_t *utpm, uint8_t* input, uint32_t inlen, uint8_t* output, uint32_t* outlen, TPM_COMPOSITE_HASH *digestAtCreation); + +TPM_RESULT utpm_quote(TPM_NONCE* externalnonce, TPM_PCR_SELECTION* tpmsel, /* hypercall inputs */ + uint8_t* output, uint32_t* outlen, /* hypercall outputs */ + uint8_t* pcrComp, uintptr_t* pcrCompLen, + utpm_master_state_t *utpm); /* TrustVisor inputs */ + +/** + * Keeping these around solely for the Apache SSL web server demo + */ +TPM_RESULT utpm_seal_deprecated(uint8_t* pcrAtRelease, uint8_t* input, uint32_t inlen, uint8_t* output, uint32_t* outlen); +TPM_RESULT utpm_unseal_deprecated(utpm_master_state_t *utpm, uint8_t* input, uint32_t inlen, uint8_t* output, uint32_t* outlen); +TPM_RESULT utpm_quote_deprecated(uint8_t* externalnonce, uint8_t* output, uint32_t* outlen, + utpm_master_state_t *utpm, uint8_t* tpmsel, uint32_t tpmsel_len); + + +TPM_RESULT utpm_rand(uint8_t* buffer, uint32_t *numbytes); + +/* return public key in PKCS #1 v2.1 (ASN.1 DER) */ +TPM_RESULT utpm_id_getpub(uint8_t *N, uint32_t *len); + +void utpm_init_instance(utpm_master_state_t *utpm); + +/** + * FIXME: Once libemhfcrypto exists, it may be reasonable to depend on + * rsa.h in here. For now, it's not. + */ +TPM_RESULT utpm_init_master_entropy(uint8_t *aeskey, + uint8_t *hmackey, + void /*rsa_context*/ *rsa); + +#endif /* _TV_UTPM_H_ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libtv_utpm/tv_utpm.pc b/xmhf-64/xmhf/src/libbaremetal/libtv_utpm/tv_utpm.pc new file mode 100644 index 0000000000..b0d1184dd9 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libtv_utpm/tv_utpm.pc @@ -0,0 +1,11 @@ +prefix=/usr/local +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +Name: tv_utpm +Description: Micro-TPM used with TrustVisor +Requires: trustvisor +Version: 0.1 +Libs: -L${libdir} -ltv_utpm +Cflags: -I${includedir}/trustvisor diff --git a/xmhf-64/xmhf/src/libbaremetal/libtv_utpm/utpm.c b/xmhf-64/xmhf/src/libbaremetal/libtv_utpm/utpm.c new file mode 100644 index 0000000000..ffff914842 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libtv_utpm/utpm.c @@ -0,0 +1,1041 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* utpm.c routines to handle all micro-TPM related functions + * Written for TrustVisor by Ning Qu + * Edited by Zongwei Zhou, Jonathan McCune for EMHF project + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +/* TODO: Fix this hack! */ +//#include +void *malloc(size_t); +void free(void *); + +//#include + +//XXX: FIXME, these are defined in TrustVisor hyperapp +//if we intend libtv_utpm to be generic we need to find a way to +//get rid of this dependency +extern int rand_bytes(uint8_t *out, unsigned int *len); +extern uint8_t rand_byte_or_die(void); + +/* TODO: Fix this hack! */ +#define LOG_PROFILE (1<<0) +#define LOG_TRACE (1<<1) +#define LOG_ERROR (1<<2) + +/* keys for software TPM seal, unseal and quote operations */ +/* SECURITY: these global variables are very sensitive! */ +/* FIXME: put all of these keys into a struct so that all long-term + * secrets are well-identified and therefore easy to wipe, etc. */ +uint8_t g_aeskey[TPM_AES_KEY_LEN_BYTES]; +uint8_t g_hmackey[TPM_HMAC_KEY_LEN]; +rsa_key g_rsa_key; + +/* compatibility wrapper */ +static void HMAC_SHA1( uint8_t* secret, size_t secret_len, + uint8_t* in, size_t in_len, + uint8_t* out) +{ + int rv; + int hash_id = find_hash("sha1"); + unsigned long out_len = hash_descriptor[hash_id].hashsize; + + rv = hmac_memory( hash_id, + secret, secret_len, + in, in_len, + out, &out_len); + if (rv) { + abort(); + } +} + +/** + * This function is expected to only be called once during the life of + * anything that uses this uTPM implementation. This function will + * need significant modification if we ever decide to support + * arbitrarily many signing keys for uTPM instances. + */ +TPM_RESULT utpm_init_master_entropy(uint8_t *aeskey, + uint8_t *hmackey, + void /*rsa_context*/ *rsa) { + if(!aeskey || !hmackey || !rsa) { + dprintf(LOG_ERROR, "[TV:UTPM] AHHHHHHHHH!!!!! MASSIVE SECURITY ERROR: " + "!aeskey || !hmackey || !rsa\n"); + return UTPM_ERR_INSUFFICIENT_ENTROPY; + + } + memcpy(g_aeskey, aeskey, TPM_AES_KEY_LEN_BYTES); + memcpy(g_hmackey, hmackey, TPM_HMAC_KEY_LEN); + /* Note: This is intentionally a shallow copy. The rsa_context + * likely contains data structures allocated on the heap. This + * strucure is never freed during the life of the system, and is a + * memory leak in principle, but irrelevant in practice since + * there is currently no reason to ever free it. + * + * TODO: zero & free this before any dynamic unloading of the + * hypervisor. + * + * NB: userspace testing of this uTPM may reveal the leak and lead + * to earlier implementation of some kind of free()ing behavior. + */ + memcpy(&g_rsa_key, rsa, sizeof(g_rsa_key)); + + /* register libtomcrypt algorithms */ + if (register_hash( &sha1_desc) < 0) { + abort(); + } + if (register_cipher( &aes_desc) < 0) { + abort(); + } + + /* ensure libtomcrypto's math descriptor is initialized */ + if (!ltc_mp.name) { + ltc_mp = ltm_desc; + } + + return UTPM_SUCCESS; +} + +void utpm_init_instance(utpm_master_state_t *utpm) { + if(NULL == utpm) return; + + memset(utpm->pcr_bank, 0, TPM_PCR_SIZE*TPM_PCR_NUM); + +} + +/* software tpm pcr read */ +TPM_RESULT utpm_pcrread(TPM_DIGEST* pcr_value /* output */, + utpm_master_state_t *utpm, uint32_t pcr_num) /* inputs */ +{ + if(!pcr_value || !utpm) { return UTPM_ERR_BAD_PARAM; } + if(pcr_num >= TPM_PCR_NUM) { return UTPM_ERR_PCR_OUT_OF_RANGE; } + + memcpy(pcr_value->value, utpm->pcr_bank[pcr_num].value, TPM_PCR_SIZE); + return UTPM_SUCCESS; +} + +/* software tpm pcr extend */ +TPM_RESULT utpm_extend(TPM_DIGEST *measurement, utpm_master_state_t *utpm, uint32_t pcr_num) +{ + unsigned long outlen; + int rv; + + if(!measurement || !utpm) { return UTPM_ERR_BAD_PARAM; } + if(pcr_num >= TPM_PCR_NUM) { return UTPM_ERR_PCR_OUT_OF_RANGE; } + + dprintf(LOG_TRACE, "utpm_extend: extending PCR %d\n", pcr_num); + + //print_hex("utpm_extend: PCR before: ", utpm->pcr_bank[pcr_num].value, TPM_HASH_SIZE); + //print_hex("utpm_extend: measurement: ", measurement->value, TPM_HASH_SIZE); + + /* pcr = H( pcr || measurement) */ + outlen = sizeof(utpm->pcr_bank[pcr_num].value); + /* + * TPM_HASH_SIZE must be casted as unsigned long, otherwise in amd64 it + * will be treated as int in the caller and unsigned long in the callee, + * causing problems in va_arg (e.g. the upper 32-bits become undefined). + */ + rv = hash_memory_multi( find_hash("sha1"), + utpm->pcr_bank[pcr_num].value, &outlen, + utpm->pcr_bank[pcr_num].value, + (unsigned long) TPM_HASH_SIZE, + measurement->value, + (unsigned long) TPM_HASH_SIZE, + NULL, NULL); + if (rv) { + abort(); + } + + //print_hex("utpm_extend: PCR after: ", utpm->pcr_bank[pcr_num].value, TPM_HASH_SIZE); + + return UTPM_SUCCESS; +} + +/* If no destination buffer is provided then just set the number of + * bytes that would be consumed.*/ +static uint32_t utpm_internal_memcpy_TPM_PCR_SELECTION( + TPM_PCR_SELECTION *pcrSelection, uint8_t *dest, uint32_t *bytes_consumed) +{ + if(!pcrSelection || !bytes_consumed) return 1; + + *bytes_consumed = sizeof(pcrSelection->sizeOfSelect) + pcrSelection->sizeOfSelect; + + if(dest) { + memcpy(dest, pcrSelection, *bytes_consumed); + } + + return 0; /* success */ +} + +/* If no destination buffer is provided then just set the number of + * bytes that would be consumed.*/ +static uint32_t utpm_internal_memcpy_TPM_PCR_INFO( + TPM_PCR_INFO *pcrInfo, /* in */ + uint8_t *dest, /* out */ + uint32_t *bytes_consumed) /* out */ +{ + uint32_t rv; + + if(!pcrInfo || !bytes_consumed) { return 1; } + + rv = utpm_internal_memcpy_TPM_PCR_SELECTION(&pcrInfo->pcrSelection, dest, bytes_consumed); + if(0 != rv) { return rv; } + + + if(pcrInfo->pcrSelection.sizeOfSelect > 0) { + /* If no destination buffer, then just return the required + * size in bytes_consumed. */ + if(NULL == dest) { + *bytes_consumed += 2*TPM_HASH_SIZE; + return 0; + } + /* If we're still here, copy two TPM_COMPOSITE_HASH values to dest. */ + else { + memcpy(dest + *bytes_consumed, pcrInfo->digestAtRelease.value, TPM_HASH_SIZE); + *bytes_consumed += TPM_HASH_SIZE; + + memcpy(dest + *bytes_consumed, pcrInfo->digestAtCreation.value, TPM_HASH_SIZE); + *bytes_consumed += TPM_HASH_SIZE; + } + } + return 0; +} + +/* FIXME: place this somewhere appropriate */ +static inline uint32_t ntohl(uint32_t in) { + uint8_t *s = (uint8_t *)∈ + return (uint32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]); +} + +/** + * Create the current TPM_PCR_COMPOSITE for uTPM PCR values + * specified by TPM_PCR_SELECTION. + * + * Caller must free *tpm_pcr_composite. + */ +static uint32_t utpm_internal_allocate_and_populate_current_TpmPcrComposite( + utpm_master_state_t *utpm, + TPM_PCR_SELECTION *tpmsel, + uint8_t **tpm_pcr_composite, + uintptr_t *space_needed_for_composite + ) +{ + uint32_t rv = 0; + uint32_t i; + uint32_t num_pcrs_to_include = 0; + uint8_t *p = NULL; + + if(!utpm || !tpmsel || !tpm_pcr_composite || !space_needed_for_composite) return 1; + + dprintf(LOG_TRACE, "[TV:UTPM] %s: tpmsel->sizeOfSelect %d\n", + __FUNCTION__, tpmsel->sizeOfSelect); + print_hex(" tpmsel->pcrSelect: ", tpmsel->pcrSelect, tpmsel->sizeOfSelect); + for(i=0; isizeOfSelect) + tpmsel->sizeOfSelect + /* TPM_PCR_COMPOSITE.select */ + sizeof(uint32_t) + /* TPM_PCR_COMPOSITE.valueSize */ + num_pcrs_to_include * TPM_HASH_SIZE; /* TPM_PCR_COMPOSITE.pcrValue[] */ + + dprintf(LOG_TRACE, " sizeof(tpmsel->sizeOfSelect) + tpmsel->sizeOfSelect = %ld\n", + sizeof(tpmsel->sizeOfSelect) + tpmsel->sizeOfSelect); + dprintf(LOG_TRACE, " sizeof(uint32_t) = %ld\n", + sizeof(uint32_t)); + dprintf(LOG_TRACE, " num_pcrs_to_include * TPM_HASH_SIZE = %ld\n", + num_pcrs_to_include * TPM_HASH_SIZE); + dprintf(LOG_TRACE, " ---------------------------------------------------------\n"); + dprintf(LOG_TRACE, " *space_needed_for_composite = %ld\n", + *space_needed_for_composite); + + if(NULL == (*tpm_pcr_composite = malloc(*space_needed_for_composite))) { + dprintf(LOG_ERROR, "[TV:UTPM] malloc(%ld) failed!\n", *space_needed_for_composite); + return 1; + } + + /** Populate TPM_COMPOSITE buffer **/ + p = *tpm_pcr_composite; + /* 1. TPM_PCR_COMPOSITE.select */ + memcpy(p, tpmsel, sizeof(tpmsel->sizeOfSelect) + tpmsel->sizeOfSelect); + p += sizeof(tpmsel->sizeOfSelect) + tpmsel->sizeOfSelect; + /* 2. TPM_PCR_COMPOSITE.valueSize (big endian # of bytes (not # of PCRs)) */ + *((uint32_t*)p) = ntohl(num_pcrs_to_include*TPM_HASH_SIZE); + p += sizeof(uint32_t); + /* 3. TPM_PCR_COMPOSITE.pcrValue[] */ + for(i=0; ipcr_bank[i].value, TPM_HASH_SIZE); + dprintf(LOG_TRACE, " PCR-%d: ", i); + print_hex(NULL, p, TPM_HASH_SIZE); + p += TPM_HASH_SIZE; + } + } + + /* TODO: Assert */ + if((uintptr_t)p-(uintptr_t)(*tpm_pcr_composite) != *space_needed_for_composite) { + dprintf(LOG_ERROR, "[TV:UTPM] ERROR! (uint32_t)p-(uint32_t)*tpm_pcr_composite " + "!= space_needed_for_composite\n"); + rv = 1; /* FIXME: Indicate internal error */ + goto out; + } + + print_hex(" TPM_PCR_COMPOSITE: ", *tpm_pcr_composite, *space_needed_for_composite); + out: + return rv; + +} + +/** + * TPM_PCR_COMPOSITE is created by reading the current value of the + * PCRs mentioned in TPM_PCR_SELECTION. + * + * It does not make sense to call this function if the + * TPM_PCR_SELECTION does not select anything. + */ +static TPM_RESULT utpm_internal_digest_current_TpmPcrComposite( + utpm_master_state_t *utpm, + TPM_PCR_SELECTION *pcrSelection, + TPM_COMPOSITE_HASH *digest) +{ + uintptr_t space_needed_for_composite = 0; + uint8_t *tpm_pcr_composite = NULL; + uint32_t rv = 0; + + if(!utpm || !pcrSelection || !digest) { return 1; } + + if(pcrSelection->sizeOfSelect < 1) { return 1; } + + rv = utpm_internal_allocate_and_populate_current_TpmPcrComposite( + utpm, + pcrSelection, + &tpm_pcr_composite, + &space_needed_for_composite); + + if(0 != rv) { return 1; } + + sha1_buffer(tpm_pcr_composite, space_needed_for_composite, digest->value); + + if(tpm_pcr_composite) { free(tpm_pcr_composite); tpm_pcr_composite = NULL; } + + return rv; +} + +TPM_RESULT utpm_seal(utpm_master_state_t *utpm, + TPM_PCR_INFO *tpmPcrInfo, + uint8_t* input, uint32_t inlen, + uint8_t* output, uint32_t* outlen) +{ + uint32_t rv = 0; + uint32_t outlen_beforepad; + uint8_t* p; + uint8_t *iv; + uint32_t bytes_consumed_by_pcrInfo; + symmetric_CBC cbc_ctx; + TPM_PCR_INFO tpmPcrInfo_internal; + uint8_t *plaintext = NULL; + uint32_t bytes_of_entropy = 0; + if(!utpm || !tpmPcrInfo || !input || !output || !outlen) { + dprintf(LOG_ERROR, "[TV] utpm_seal ERROR: !utpm || !tpmPcrInfo || !input || !output || !outlen\n"); + return 1; + } + + dprintf(LOG_TRACE, "[TV:utpm_seal] inlen %u, outlen (junk expected) %u, tpmPcrInfo %p\n", inlen, *outlen, tpmPcrInfo); + print_hex(" [TV:utpm_seal] tpmPcrInfo: ", (uint8_t*)tpmPcrInfo, sizeof(TPM_PCR_INFO)); + print_hex(" [TV:utpm_seal] input: ", input, inlen); + print_hex(" [TV:utpm_seal] g_hmackey: ", g_hmackey, TPM_HASH_SIZE); /* XXX SECURITY */ + print_hex(" [TV:utpm_seal] g_aeskey: ", g_aeskey, TPM_AES_KEY_LEN_BYTES); /* XXX SECURITY */ + + /** + * Part 1: Populate digestAtCreation (only for tpmPcrInfo that selects 1+ PCRs). + */ + if(0 != tpmPcrInfo->pcrSelection.sizeOfSelect) { + /* The caller does not provide the DigestAtCreation component of + * the tpmPcrInfo input parameter, so we must populate this + * component of the TPM_PCR_INFO structure ourselves, + * internally. */ + /* 1. make our own TPM_PCR_INFO and copy caller-specified values */ + rv = utpm_internal_memcpy_TPM_PCR_INFO(tpmPcrInfo, + NULL, + &bytes_consumed_by_pcrInfo); + if(0 != rv) { return 1; } + if(bytes_consumed_by_pcrInfo != sizeof(TPM_PCR_INFO)) { + dprintf(LOG_ERROR, "[TV:UTPM] bytes_consumed_by_pcrInfo (%d) != sizeof(TPM_PCR_INFO) (%d)\n", + bytes_consumed_by_pcrInfo, sizeof(TPM_PCR_INFO)); + return 1; + } + rv = utpm_internal_memcpy_TPM_PCR_INFO(tpmPcrInfo, + (uint8_t*)&tpmPcrInfo_internal, + &bytes_consumed_by_pcrInfo); + if(0 != rv) { return 1; } + + /* 2. overwrite digestAtCreation based on current PCR contents */ + rv = utpm_internal_digest_current_TpmPcrComposite( + utpm, + &tpmPcrInfo_internal.pcrSelection, + &tpmPcrInfo_internal.digestAtCreation); + if(0 != rv) { return 1; } + } else { + tpmPcrInfo_internal.pcrSelection.sizeOfSelect = 0; + } + + /** + * Part 2: Do the actual encryption + */ + + plaintext = malloc(inlen + 100); /* XXX figure out actual required size */ + // It's probably TPM_AES_KEY_LEN_BYTES + TPM_HASH_SIZE + sizeof(TPM_PCR_INFO) + if(NULL == plaintext) { + dprintf(LOG_ERROR, "ERROR: malloc FAILED\n"); + return 1; + } + + p = iv = plaintext; + + /* 0. get IV */ + bytes_of_entropy = TPM_AES_KEY_LEN_BYTES; + rand_bytes(iv, &bytes_of_entropy); + if(TPM_AES_KEY_LEN_BYTES != bytes_of_entropy) { + dprintf(LOG_ERROR, "ERROR: rand_bytes FAILED\n"); + return UTPM_ERR_INSUFFICIENT_ENTROPY; + } + memcpy(output, iv, TPM_AES_KEY_LEN_BYTES); /* Copy IV directly to output */ + p += TPM_AES_KEY_LEN_BYTES; /* IV */ + + print_hex(" iv: ", iv, TPM_AES_KEY_LEN_BYTES); + + /* output = IV || AES-CBC(TPM_PCR_INFO (or 0x0000 if none selected) || input_len || input || PADDING) || HMAC( entire ciphertext including IV ) */ + /* 1a. TPM_PCR_SELECTION with 0 PCRs selected */ + if(0 == tpmPcrInfo_internal.pcrSelection.sizeOfSelect) { /* no PCRs selected */ + memcpy(p, &tpmPcrInfo_internal.pcrSelection.sizeOfSelect, + sizeof(tpmPcrInfo_internal.pcrSelection.sizeOfSelect)); + print_hex(" tpmPcrInfo_internal.pcrSelection.sizeOfSelect: ", p, + sizeof(tpmPcrInfo_internal.pcrSelection.sizeOfSelect)); + p += sizeof(tpmPcrInfo_internal.pcrSelection.sizeOfSelect); + } + /* 1b. TPM_PCR_SELECTION with 1 or more PCRs selected */ + else { + rv = utpm_internal_memcpy_TPM_PCR_INFO(&tpmPcrInfo_internal, p, &bytes_consumed_by_pcrInfo); + if(0 != rv) { return 1; } + print_hex(" tpmPcrInfo_internal: ", + (uint8_t*)&tpmPcrInfo_internal, + bytes_consumed_by_pcrInfo); + p += bytes_consumed_by_pcrInfo; + } + /* 2. input_len */ + *((uint32_t *)p) = inlen; + print_hex(" inlen: ", p, sizeof(uint32_t)); + p += sizeof(uint32_t); + /* 3. actual input data */ + memcpy(p, input, inlen); + print_hex(" input: ", p, inlen); + p += inlen; + + /* 4. add padding */ + outlen_beforepad = (uintptr_t)p - (uintptr_t)plaintext; + if ((outlen_beforepad & 0xF) != 0) { + *outlen = (outlen_beforepad + TPM_AES_KEY_LEN_BYTES) & (~0xF); + } else { + *outlen = outlen_beforepad; + } + memset(p, 0, *outlen-outlen_beforepad); + + print_hex("padding: ", p, *outlen - outlen_beforepad); + p += *outlen - outlen_beforepad; + + /* encrypt (1-4) data using g_aeskey in AES-CBC mode */ + if ( cbc_start( find_cipher( "aes"), iv, g_aeskey, TPM_AES_KEY_LEN_BYTES, 0, &cbc_ctx)) { + abort(); + } + + print_hex(" plaintext (including IV) just prior to AES encrypt: ", plaintext, *outlen); + if (cbc_encrypt( plaintext + TPM_AES_KEY_LEN_BYTES, /* skip IV */ + output + TPM_AES_KEY_LEN_BYTES, /* don't clobber IV */ + *outlen - TPM_AES_KEY_LEN_BYTES, + &cbc_ctx)) { + abort(); + } + if (cbc_done( &cbc_ctx)) { + abort(); + } + + print_hex(" freshly encrypted ciphertext: ", output, *outlen); + + /* 5. compute and append hmac */ + HMAC_SHA1(g_hmackey, TPM_HASH_SIZE, output, *outlen, output + *outlen); + print_hex("hmac: ", output + *outlen, TPM_HASH_SIZE); + *outlen += TPM_HASH_SIZE; /* hmac */ + + dprintf(LOG_TRACE, "*outlen = %d\n", *outlen); + print_hex("ciphertext from utpm_seal: ", output, *outlen); + + /* Sanity checking output size */ + if(*outlen != utpm_seal_output_size(inlen, false)) { + dprintf(LOG_ERROR, "\n\nERROR!!! *outlen(%d) != utpm_seal_output_size(%d)\n\n", *outlen, + utpm_seal_output_size(inlen, false)); + } + + /* SECURITY: zero memory before freeing? */ + if(plaintext) { free(plaintext); plaintext = NULL; iv = NULL; } + + return rv; +} + + +TPM_RESULT utpm_unseal(utpm_master_state_t *utpm, + uint8_t* input, uint32_t inlen, + uint8_t* output, uint32_t* outlen, + TPM_COMPOSITE_HASH *digestAtCreation) /* out */ +{ + uint8_t hmacCalculated[TPM_HASH_SIZE]; + uint32_t rv; + symmetric_CBC cbc_ctx; + + if(!utpm || !input || !output || !outlen || !digestAtCreation) { return 1; } + + /** + * Recall from utpm_seal(): + * output = IV || AES-CBC(TPM_PCR_INFO || input_len || input || PADDING) || HMAC( entire ciphertext including IV ) + */ + + /** + * Step 1: Verify HMAC. This ensures the sealed ciphertext has + * not been modified and that it was sealed on this particular + * instance of TrustVisor. + */ + + /* Ciphertext (input) length should be a multiple of the AES block size + HMAC size */ + if(0 != (inlen - TPM_HASH_SIZE) % TPM_AES_KEY_LEN_BYTES) { + dprintf(LOG_ERROR, "Unseal Input **Length FAILURE**: 0 != (inlen - TPM_HASH_SIZE) %% TPM_AES_KEY_LEN_BYTES\n"); + dprintf(LOG_ERROR, "inlen %d, TPM_HASH_SIZE %d, TPM_AES_KEY_LEN_BYTES %d\n", + inlen, TPM_HASH_SIZE, TPM_AES_KEY_LEN_BYTES); + return 1; + } + + /* HMAC should be the last TPM_HASH_SIZE bytes of the + * input. Calculate its expected value based on the first (inlen - + * TPM_HASH_SIZE) bytes of the input and compare against provided + * value. */ + HMAC_SHA1(g_hmackey, TPM_HASH_SIZE, input, inlen - TPM_HASH_SIZE, hmacCalculated); + if(memcmp(hmacCalculated, input + inlen - TPM_HASH_SIZE, TPM_HASH_SIZE)) { + dprintf(LOG_ERROR, "Unseal HMAC **INTEGRITY FAILURE**: memcmp(hmacCalculated, input + inlen - TPM_HASH_SIZE, TPM_HASH_SIZE)\n"); + print_hex(" hmacCalculated: ", hmacCalculated, TPM_HASH_SIZE); + print_hex(" input + inlen - TPM_HASH_SIZE:" , input + inlen - TPM_HASH_SIZE, TPM_HASH_SIZE); + return 1; + } + + /** + * Step 2. Decrypt data. I cannot think of a reason why this + * could ever fail if the above HMAC check was successful. + */ + + *outlen = inlen + - TPM_AES_KEY_LEN_BYTES /* iv */ + - TPM_HASH_SIZE; /* hmac */ + + if (cbc_start( find_cipher("aes"), + input, /* iv is at beginning of input */ + g_aeskey, TPM_AES_KEY_LEN_BYTES, + 0, + &cbc_ctx)) { + abort(); + } + if (cbc_decrypt( input+TPM_AES_KEY_LEN_BYTES, /* offset to ciphertext just beyond iv */ + output, + *outlen, + &cbc_ctx)) { + abort(); + } + if (cbc_done( &cbc_ctx)) { + abort(); + } + + print_hex(" Unsealed plaintext: ", output, *outlen); + + /** + * Step 3. Verify that PCR values match. + */ + + /* 1. Determine which PCRs were included */ + /* 2. Create the TPM_PCR_COMPOSITE for those PCRs with their current values */ + /* 3. Compare the COMPOSITE_HASH with the one in the ciphertext. */ + + /* plaintext contains [ TPM_PCR_INFO | plaintextLen | plaintext ] */ + { /* Separate logic for PCR checking since eventually it will + * likely be library functionality (TODO). */ + uint8_t *p = output; + TPM_PCR_INFO unsealedPcrInfo; + uint32_t bytes_consumed_by_pcrInfo; + uintptr_t space_needed_for_composite = 0; + uint8_t *currentPcrComposite = NULL; + TPM_COMPOSITE_HASH digestRightNow; + + /* 1. TPM_PCR_INFO */ + rv = utpm_internal_memcpy_TPM_PCR_INFO((TPM_PCR_INFO*)p, (uint8_t*)&unsealedPcrInfo, &bytes_consumed_by_pcrInfo); + if(0 != rv) return rv; + p += bytes_consumed_by_pcrInfo; + print_hex(" unsealedPcrInfo: ", (uint8_t*)&unsealedPcrInfo, bytes_consumed_by_pcrInfo); + + /* 1a. Handle the simple case where no PCRs are involved */ + if(bytes_consumed_by_pcrInfo <= sizeof(unsealedPcrInfo.pcrSelection.sizeOfSelect)) { + dprintf(LOG_TRACE, " No PCRs selected. No checking required.\n"); + memset(digestAtCreation->value, 0, TPM_HASH_SIZE); + } + /* 1b. Verify that required PCR values match */ + else { + print_hex(" unsealedPcrInfo.digestAtRelease: ", (uint8_t*)&unsealedPcrInfo.digestAtRelease, TPM_HASH_SIZE); + + /* 2. Create current PCR Composite digest, for use in compairing against digestAtRelease */ + rv = utpm_internal_allocate_and_populate_current_TpmPcrComposite( + utpm, + &unsealedPcrInfo.pcrSelection, + ¤tPcrComposite, + &space_needed_for_composite); + if(rv != 0) { + dprintf(LOG_ERROR, "utpm_internal_allocate_and_populate_current_TpmPcrComposite FAILED\n"); + return 1; + } + print_hex(" current PcrComposite: ", currentPcrComposite, space_needed_for_composite); + + /* 3. Composite hash */ + sha1_buffer(currentPcrComposite, space_needed_for_composite, digestRightNow.value); + print_hex(" digestRightNow: ", digestRightNow.value, TPM_HASH_SIZE); + + if(0 != memcmp(digestRightNow.value, unsealedPcrInfo.digestAtRelease.value, TPM_HASH_SIZE)) { + dprintf(LOG_ERROR, "0 != memcmp(digestRightNow.value, unsealedPcrInfo.digestAtRelease.value, TPM_HASH_SIZE)\n"); + rv = 1; + goto out; + } + + dprintf(LOG_TRACE, "[TV:UTPM_UNSEAL] digestAtRelase MATCH; Unseal ALLOWED!\n"); + + memcpy(digestAtCreation->value, unsealedPcrInfo.digestAtCreation.value, TPM_HASH_SIZE); + } + /* 4. Reshuffle output buffer and strip padding so that only + * the user's plaintext is returned. Buffer's contents: [ + * plaintextLen | plainText | padding ] */ + + *outlen = *((uint32_t*)p); + p += sizeof(uint32_t); + memcpy(output, p, *outlen); + + out: + if(currentPcrComposite) { free(currentPcrComposite); currentPcrComposite = NULL; } + } /* END Separate logic for PCR checking. */ + + return rv; +} + + +TPM_RESULT utpm_seal_deprecated(uint8_t* pcrAtRelease, uint8_t* input, uint32_t inlen, uint8_t* output, uint32_t* outlen) +{ + s32 len; + uint32_t outlen_beforepad; + uint8_t* pdata; + uint8_t iv[16]; + uint8_t confounder[TPM_CONFOUNDER_SIZE]; + uint8_t hashdata[TPM_HASH_SIZE]; + symmetric_CBC cbc_ctx; + uint32_t confounder_size; + + /* IV can be 0 because we have confounder */ + memset(iv, 0, 16); + + /* get a random confounder */ + confounder_size = TPM_CONFOUNDER_SIZE; + rand_bytes(confounder, &confounder_size); + if(TPM_CONFOUNDER_SIZE != confounder_size) { + printf("[TV] Unseal ERROR: insufficient entropy!\n"); + return UTPM_ERR_INSUFFICIENT_ENTROPY; + } + + /* output = + * AES-CBC(confounder || HMAC( entire message w/ zero HMAC field) || pcr || input_len || input || PADDING) + * */ + memcpy(output, confounder, TPM_CONFOUNDER_SIZE); + memset(output+TPM_CONFOUNDER_SIZE, 0, TPM_HASH_SIZE); + memcpy(output+TPM_CONFOUNDER_SIZE+TPM_HASH_SIZE, pcrAtRelease, TPM_PCR_SIZE); + pdata = output + TPM_CONFOUNDER_SIZE + TPM_HASH_SIZE + TPM_PCR_SIZE; + *((uint32_t *)pdata) = inlen; + memcpy(pdata + 4, input, inlen); + + /* add padding */ + outlen_beforepad = TPM_CONFOUNDER_SIZE + TPM_PCR_SIZE + TPM_HASH_SIZE + 4 + inlen ; + if ((outlen_beforepad&0xF) != 0) { + *outlen = (outlen_beforepad+16)&(~0xF); + } else { + *outlen = outlen_beforepad; + } + len = (s32)(*outlen); + memset(output+outlen_beforepad, 0, len-outlen_beforepad); + + /* get HMAC of the entire message w/ zero HMAC field */ + HMAC_SHA1(g_hmackey, 20, output, len, hashdata); + memcpy(output+TPM_CONFOUNDER_SIZE, hashdata, TPM_HASH_SIZE); + + /* encrypt data using sealAesKey by AES-CBC mode */ + if (cbc_start( find_cipher( "aes"), iv, g_aeskey, TPM_AES_KEY_LEN_BYTES, 0, &cbc_ctx)) { + abort(); + } + if (cbc_encrypt( output, + output, + len, + &cbc_ctx)) { + abort(); + } + if (cbc_done( &cbc_ctx)) { + abort(); + } + + return 0; +} + +TPM_RESULT utpm_unseal_deprecated(utpm_master_state_t *utpm, uint8_t* input, uint32_t inlen, uint8_t* output, uint32_t* outlen) +{ + uint32_t len; + uint8_t hashdata[TPM_HASH_SIZE]; + uint8_t oldhmac[TPM_HASH_SIZE]; + uint8_t iv[16]; + symmetric_CBC cbc_ctx; + int i; + + memset(iv, 0, 16); + + /* decrypt data */ + if (cbc_start( find_cipher( "aes"), iv, g_aeskey, TPM_AES_KEY_LEN_BYTES, 0, &cbc_ctx)) { + abort(); + } + if (cbc_decrypt( input, + output, + inlen, + &cbc_ctx)) { + abort(); + } + if (cbc_done( &cbc_ctx)) { + abort(); + } + + /* compare the current pcr (default pcr 0) with pcrHashAtRelease */ + /* XXX TODO: this code implicitly uses PCR 0, and assumes that it + * is the first thing inside the pcr_bank. This is a Bad Thing. + * Need to mature pcr_bank into an actual structure, teach + * seal/unseal about identifying which PCRs to seal to, etc. */ + if(memcmp(output+TPM_CONFOUNDER_SIZE+TPM_HASH_SIZE, utpm->pcr_bank[0].value, TPM_PCR_SIZE)) + { + printf("[TV] Unseal ERROR: wrong pcr value!\n"); + printf("[TV] sealed pcr:"); + for(i=0;ipcr_bank[0].value[i]); + } + printf("\n"); + return 1; + } + + /* copy hmac */ + memcpy(oldhmac, output+TPM_CONFOUNDER_SIZE, TPM_HASH_SIZE); + + /* zero HMAC field, and recalculate hmac of the message */ + memset(output+TPM_CONFOUNDER_SIZE, 0, TPM_HASH_SIZE); + HMAC_SHA1(g_hmackey, 20, output, inlen, hashdata); + + /* compare the hmac */ + if (memcmp(hashdata, oldhmac, TPM_HASH_SIZE)) + { + printf("[TV] Unseal ERROR: HMAC check fail\n"); + return 1; + } + + len = *((uint32_t*)(output + TPM_CONFOUNDER_SIZE +TPM_PCR_SIZE + TPM_HASH_SIZE)); + memcpy(output, output + TPM_CONFOUNDER_SIZE + TPM_PCR_SIZE + TPM_HASH_SIZE + 4, len); + *outlen = len; + + return 0; +} + +/* Desired hypercall response-length semantics: Hypercall response + * length parameter is both an input and output parameter (i.e., + * pointer to a uint32_t). Caller presets it to the size of its + * response buffer. Hypercall resets it to the size of the true + * response if the hypercall succeeds (i.e., buffer is big enough), or + * to the required size if the hypercall fails because the response + * buffer is too small. */ +TPM_RESULT utpm_quote(TPM_NONCE* externalnonce, TPM_PCR_SELECTION* tpmsel, /* hypercall inputs */ + uint8_t* output, uint32_t* outlen, /* hypercall outputs */ + uint8_t* pcrComp, uintptr_t* pcrCompLen, + utpm_master_state_t *utpm) /* TrustVisor inputs */ +{ + TPM_RESULT rv = 0; /* success */ + uintptr_t space_needed_for_composite = 0; + uint8_t *tpm_pcr_composite = NULL; + TPM_QUOTE_INFO quote_info; + + printf("[TV:UTPM] utpm_quote invoked\n"); + + if(!externalnonce || !tpmsel || !output || !outlen || !pcrComp || !pcrCompLen || !utpm) { + printf("[TV:UTPM] ERROR: NULL function parameter!\n"); + rv = 1; /* FIXME: Indicate invalid input parameter */ + goto out; + } + + print_hex(" externalnonce: ", externalnonce->nonce, TPM_HASH_SIZE); + + rv = utpm_internal_allocate_and_populate_current_TpmPcrComposite( + utpm, + tpmsel, + &tpm_pcr_composite, + &space_needed_for_composite); + if(0 != rv) { goto out; } + + print_hex(" TPM_PCR_COMPOSITE: ", tpm_pcr_composite, space_needed_for_composite); + + /* Copy PCR Composite and len to the appropriate output buffer, + * checking for enough space */ + if(space_needed_for_composite > *pcrCompLen) { + dprintf(LOG_ERROR, "ERROR: space_needed_for_composite (%ld) > *pcrCompLen (%ld)\n", + space_needed_for_composite, *pcrCompLen); + *pcrCompLen = space_needed_for_composite; + rv = 1; /* FIXME: Indicate insufficient pcrComp buffer size */ + goto out; + } + /* FIXME: find a way to eliminate this extra copy; likely entails + * changes to: + * utpm_internal_allocate_and_populate_current_TpmPcrComposite */ + memcpy(pcrComp, tpm_pcr_composite, *pcrCompLen); + + /** + * Populate 4-element TPM_QUOTE_INFO structure which will be hashed and signed + */ + + /* 1) 1.1.0.0 for consistency w/ TPM 1.2 spec */ + *((uint32_t*)"e_info.version) = 0x00000101; + /* 2) 'QUOT' */ + *((uint32_t*)quote_info.fixed) = 0x544f5551; + /* 3) SHA-1 hash of TPM_PCR_COMPOSITE */ + sha1_buffer(tpm_pcr_composite, space_needed_for_composite, quote_info.digestValue.value); + print_hex(" COMPOSITE_HASH: ", quote_info.digestValue.value, TPM_HASH_SIZE); + /* 4) external nonce */ + memcpy(quote_info.externalData.nonce, externalnonce->nonce, TPM_HASH_SIZE); + + print_hex(" quote_info: ", (uint8_t*)"e_info, sizeof(TPM_QUOTE_INFO)); + + /** + * Compute the signature and format the output buffer + */ + + if(TPM_RSA_KEY_LEN > *outlen) { + dprintf(LOG_ERROR, "ERROR: TPM_RSA_KEY_LEN (%d) > *outlen (%d)\n", + TPM_RSA_KEY_LEN, *outlen); + *outlen = TPM_RSA_KEY_LEN; + rv = 1; /* FIXME: Indicate insufficient output buffer size */ + goto out; + } + + *outlen = TPM_RSA_KEY_LEN; + dprintf(LOG_TRACE, "required output size = *outlen = %d\n", *outlen); + + { + unsigned long outlen_long = *outlen; + uint8_t md[SHA_DIGEST_LENGTH]; + + sha1_buffer( (uint8_t*)"e_info, sizeof(TPM_QUOTE_INFO), md); + + if( (rv = rsa_sign_hash_ex( md, sizeof(md), + output, &outlen_long, + LTC_LTC_PKCS_1_V1_5, + NULL, 0, /* no prng for v1.5 padding */ + find_hash("sha1"), + 0, /* no salt for v1.5 padding */ + &g_rsa_key))) { + printf("[TV:UTPM] ERROR: tpm_pkcs1_sign FAILED\n"); + goto out; + } + if (outlen_long != *outlen) { + abort(); + } + } + + dprintf(LOG_TRACE, "[TV:UTPM] Success!\n"); + + out: + if(tpm_pcr_composite) { free(tpm_pcr_composite); tpm_pcr_composite = NULL; } + + return 0; +} + +/* + * todo: get TPM_QUOTE_INFO, then sign it + * input: externalnonce, get from external server to avoid replay attack + * output: quote result and data length + */ +TPM_RESULT utpm_quote_deprecated(uint8_t* externalnonce, uint8_t* output, uint32_t* outlen, + utpm_master_state_t *utpm, uint8_t* tpmsel, uint32_t tpmsel_len) +{ + int ret; + uint32_t i, idx; + uint8_t* pdata; + uint32_t datalen; + + /* construct TPM_QUOTE_INFO in output */ + ((uint32_t *)output)[0] = 0x00000101; /* version information */ + ((uint32_t *)output)[1] = 0x544f5551; /* 'QUOTE' */ + + /* add TPM PCR information */ + memcpy(output+8, tpmsel, tpmsel_len); + datalen = 8 + tpmsel_len; + pdata = output+datalen; + for( i=0 ; i<*((uint32_t *)tpmsel) ; i++ ) { + idx=*(((uint32_t *)tpmsel)+i+1); + memcpy(pdata+i*TPM_PCR_SIZE, utpm->pcr_bank[idx].value, TPM_PCR_SIZE); + datalen += TPM_PCR_SIZE; + } + + /* add nonce */ + memcpy(output + datalen, externalnonce, TPM_NONCE_SIZE); + datalen += TPM_NONCE_SIZE; + + /* sign the quoteInfo and add the signature to output + * get the outlen + */ + { + unsigned long outlen_long = TPM_RSA_KEY_LEN; + if( (ret = rsa_sign_hash_ex( output, datalen, + output+datalen, &outlen_long, + LTC_LTC_PKCS_1_V1_5, + NULL, 0, /* no prng for v1.5 padding */ + find_hash("sha1"), + 0, /* no salt for v1.5 padding */ + &g_rsa_key))) { + printf("[TV] Quote ERROR: rsa sign fail\n"); + return 1; + } + } + + *outlen = TPM_RSA_KEY_LEN + datalen; + + return 0; +} + +TPM_RESULT utpm_id_getpub(uint8_t *N, uint32_t *len) { + unsigned long len_long; + int tcrv; + uint8_t buf[1]; + bool len_check; + + if(!len) { return UTPM_ERR_BAD_PARAM; } + + if (!N) { + /* treat as an inquiry into how many bytes are needed */ + len_check = true; + *len = 0; + N = buf; + } else { + len_check = false; + } + + len_long = *len; + tcrv = rsa_export( N, &len_long, PK_PUBLIC, &g_rsa_key); + *len = len_long; + + if ( tcrv != 0 && !(len_check)) { + dprintf( LOG_ERROR, "rsa_export failed with %d\n", tcrv); + return UTPM_ERR; + } + + return UTPM_SUCCESS; +} + + +/* get random bytes from software TPM */ +/* XXX TODO: Make this look like an actual TPM command (return value + * should simply be a status code) */ +TPM_RESULT utpm_rand(uint8_t* buffer, uint32_t *numbytes) +{ + int rv; + + rv = rand_bytes(buffer, numbytes); + if(0 != rv) { + printf("[TV] ERROR: utpm_rand: insufficient entropy\n"); + return UTPM_ERR_INSUFFICIENT_ENTROPY; + } + + return UTPM_SUCCESS; +} diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/Makefile b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/Makefile new file mode 100644 index 0000000000..34fdedc361 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/Makefile @@ -0,0 +1,30 @@ +srcdir := $(dir $(lastword $(MAKEFILE_LIST))) +vpath %.c $(srcdir) + +C_SOURCES:= $(wildcard $(srcdir)/*.c) +C_SOURCES:= $(patsubst $(srcdir)/%, %, $(C_SOURCES)) +OBJECTS = $(patsubst %.c, %.o, $(C_SOURCES)) + +I_SOURCES := $(wildcard $(srcdir)/include/*.h) + +CFLAGS += -I$(srcdir)/include -nostdinc -fno-builtin -nostdlib -Wall + +THE_ARCHIVE = libemhfc.a + +# targets +.PHONY: all +all: $(THE_ARCHIVE) + +$(THE_ARCHIVE): $(OBJECTS) + $(AR) -rcs $(THE_ARCHIVE) $(OBJECTS) + +#%.o: %.c $(C_SOURCES) $(I_SOURCES) Makefile ../Makefile +# $(CC) -c $(CFLAGS) -o $@ $< + +.PHONY: clean +clean: + $(RM) $(OBJECTS) $(THE_ARCHIVE) + +.PHONY: install-dev +install-dev: + # Nothing to do here diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/README b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/README new file mode 100644 index 0000000000..e56e7af3c6 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/README @@ -0,0 +1,12 @@ +This directory contains an extremely stripped down libc. +Primarily, it contains the mem*() and str*() functions +that are part of string.h. + +The intention is to provide basic libc computational support +for hypervisor internals, extremely minimized PALs, and +other environments where TCB / code size is a priority, and +using 'newlib' constitues too much TCB / code size. + +A lot of headers were taken from FreeBSD 9. Logic from FreeBSD to +support a multitude of different architectures was removed. Hence +files include/sys/i386_*. These were originally machine/* in FreeBSD. diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/abort.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/abort.c new file mode 100644 index 0000000000..4a753e2fc3 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/abort.c @@ -0,0 +1,55 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include + +#include + +__attribute__((__noreturn__)) void abort(void) +{ + emhfc_abort(); + while(1); +} diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/bcd.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/bcd.c new file mode 100644 index 0000000000..b8d602b23b --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/bcd.c @@ -0,0 +1,38 @@ +/* + * Some data-tables that are often used. + * Cannot be copyrighted. + */ + +/* #include */ +/* __FBSDID("$FreeBSD: src/sys/libkern/bcd.c,v 1.7.22.1.6.1 2010/12/21 17:09:25 kensmith Exp $"); */ + +#include + +u_char const bcd2bin_data[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 0, 0, 0, 0, 0, 0, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 0, 0, 0, 0, 0, 0, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 0, 0, 0, 0, 0, 0, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 0, 0, 0, 0, 0, 0, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, 0, 0, 0, 0, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 0, 0, 0, 0, 0, 0, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 +}; + +u_char const bin2bcd_data[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99 +}; + +/* This is actually used with radix [2..36] */ +char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz"; diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/emhfc_abort.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/emhfc_abort.c new file mode 100644 index 0000000000..5bf6b315a7 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/emhfc_abort.c @@ -0,0 +1,52 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include + +void emhfc_abort(void) +{ + while(1); +} diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/emhfc_log_error.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/emhfc_log_error.c new file mode 100644 index 0000000000..d84d91de0d --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/emhfc_log_error.c @@ -0,0 +1,52 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include + +void emhfc_log_error(const char *format, ...) +{ + (void)format; +} diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/assert.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/assert.h new file mode 100644 index 0000000000..c1defa2877 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/assert.h @@ -0,0 +1,69 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef __ASSERT_H__ +#define __ASSERT_H__ + +#ifndef __XMHF_VERIFICATION__ + + #include + #include /* defines abort */ + + #ifdef NDEBUG + # define assert(x) ((void)0) + #else + # define assert(x) \ + do { \ + if(!(x)) { \ + emhfc_log_error("%s:%d: assert failed: %s", __FILE__, __LINE__, #x); \ + abort(); \ + } \ + } while(0) + #endif + +#endif + +#endif /* __ASSERT_H__ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/ctype.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/ctype.h new file mode 100644 index 0000000000..237fbf6d02 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/ctype.h @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 1982, 1988, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: stable/8/sys/sys/ctype.h 199583 2009-11-20 15:27:52Z jhb $ + */ + +/** + * Modified for XMHF. + */ + +#ifndef _SYS_CTYPE_H_ +#define _SYS_CTYPE_H_ + +#define isspace(c) ((c) == ' ' || ((c) >= '\t' && (c) <= '\r')) +#define isascii(c) (((c) & ~0x7f) == 0) +#define isupper(c) ((c) >= 'A' && (c) <= 'Z') +#define islower(c) ((c) >= 'a' && (c) <= 'z') +#define isalpha(c) (isupper(c) || islower(c)) +#define isdigit(c) ((c) >= '0' && (c) <= '9') +#define isxdigit(c) (isdigit(c) \ + || ((c) >= 'A' && (c) <= 'F') \ + || ((c) >= 'a' && (c) <= 'f')) +#define isprint(c) ((c) >= ' ' && (c) <= '~') + +#define toupper(c) ((c) - 0x20 * (((c) >= 'a') && ((c) <= 'z'))) +#define tolower(c) ((c) + 0x20 * (((c) >= 'A') && ((c) <= 'Z'))) + +#endif /* !_SYS_CTYPE_H_ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/emhfc_callbacks.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/emhfc_callbacks.h new file mode 100644 index 0000000000..8b8c69991f --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/emhfc_callbacks.h @@ -0,0 +1,63 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef __EMHFC_CALLBACKS__ +#define __EMHFC_CALLBACKS__ + +/* These are functions that are intended to be overriden by the emhfc + user */ + +void emhfc_log_error(const char *format, ...); +void emhfc_abort(void); + +void emhfc_putchar(int ch, void *arg); +extern void *emhfc_putchar_arg; + +void emhfc_putchar_linelock(void *arg); +void emhfc_putchar_lineunlock(void *arg); +extern void *emhfc_putchar_linelock_arg; + +#endif diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/endian.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/endian.h new file mode 100644 index 0000000000..c295bea518 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/endian.h @@ -0,0 +1,209 @@ +/*- + * Copyright (c) 2002 Thomas Moestl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: stable/8/sys/sys/endian.h 199583 2009-11-20 15:27:52Z jhb $ + */ + +/** + * Modified for XMHF. + */ + +#ifndef _SYS_ENDIAN_H_ +#define _SYS_ENDIAN_H_ + +#ifdef __AMD64__ +#include +#elif defined(__I386__) +#include +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +#include + +#ifndef _UINT16_T_DECLARED +typedef __uint16_t uint16_t; +#define _UINT16_T_DECLARED +#endif + +#ifndef _UINT32_T_DECLARED +typedef __uint32_t uint32_t; +#define _UINT32_T_DECLARED +#endif + +#ifndef _UINT64_T_DECLARED +typedef __uint64_t uint64_t; +#define _UINT64_T_DECLARED +#endif + +/* + * General byte order swapping functions. + */ +#define bswap16(x) __bswap16(x) +#define bswap32(x) __bswap32(x) +#define bswap64(x) __bswap64(x) + +/* + * Host to big endian, host to little endian, big endian to host, and little + * endian to host byte order functions as detailed in byteorder(9). + */ +#if _BYTE_ORDER == _LITTLE_ENDIAN +#define htobe16(x) bswap16((x)) +#define htobe32(x) bswap32((x)) +#define htobe64(x) bswap64((x)) +#define htole16(x) ((uint16_t)(x)) +#define htole32(x) ((uint32_t)(x)) +#define htole64(x) ((uint64_t)(x)) + +#define be16toh(x) bswap16((x)) +#define be32toh(x) bswap32((x)) +#define be64toh(x) bswap64((x)) +#define le16toh(x) ((uint16_t)(x)) +#define le32toh(x) ((uint32_t)(x)) +#define le64toh(x) ((uint64_t)(x)) +#else /* _BYTE_ORDER != _LITTLE_ENDIAN */ +#define htobe16(x) ((uint16_t)(x)) +#define htobe32(x) ((uint32_t)(x)) +#define htobe64(x) ((uint64_t)(x)) +#define htole16(x) bswap16((x)) +#define htole32(x) bswap32((x)) +#define htole64(x) bswap64((x)) + +#define be16toh(x) ((uint16_t)(x)) +#define be32toh(x) ((uint32_t)(x)) +#define be64toh(x) ((uint64_t)(x)) +#define le16toh(x) bswap16((x)) +#define le32toh(x) bswap32((x)) +#define le64toh(x) bswap64((x)) +#endif /* _BYTE_ORDER == _LITTLE_ENDIAN */ + +/* Alignment-agnostic encode/decode bytestream to/from little/big endian. */ + +static __inline uint16_t +be16dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return ((p[0] << 8) | p[1]); +} + +static __inline uint32_t +be32dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); +} + +static __inline uint64_t +be64dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return (((uint64_t)be32dec(p) << 32) | be32dec(p + 4)); +} + +static __inline uint16_t +le16dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return ((p[1] << 8) | p[0]); +} + +static __inline uint32_t +le32dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); +} + +static __inline uint64_t +le64dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return (((uint64_t)le32dec(p + 4) << 32) | le32dec(p)); +} + +static __inline void +be16enc(void *pp, uint16_t u) +{ + unsigned char *p = (unsigned char *)pp; + + p[0] = (u >> 8) & 0xff; + p[1] = u & 0xff; +} + +static __inline void +be32enc(void *pp, uint32_t u) +{ + unsigned char *p = (unsigned char *)pp; + + p[0] = (u >> 24) & 0xff; + p[1] = (u >> 16) & 0xff; + p[2] = (u >> 8) & 0xff; + p[3] = u & 0xff; +} + +static __inline void +be64enc(void *pp, uint64_t u) +{ + unsigned char *p = (unsigned char *)pp; + + be32enc(p, u >> 32); + be32enc(p + 4, u & 0xffffffff); +} + +static __inline void +le16enc(void *pp, uint16_t u) +{ + unsigned char *p = (unsigned char *)pp; + + p[0] = u & 0xff; + p[1] = (u >> 8) & 0xff; +} + +static __inline void +le32enc(void *pp, uint32_t u) +{ + unsigned char *p = (unsigned char *)pp; + + p[0] = u & 0xff; + p[1] = (u >> 8) & 0xff; + p[2] = (u >> 16) & 0xff; + p[3] = (u >> 24) & 0xff; +} + +static __inline void +le64enc(void *pp, uint64_t u) +{ + unsigned char *p = (unsigned char *)pp; + + le32enc(p, u & 0xffffffff); + le32enc(p + 4, u >> 32); +} + +#endif /* _SYS_ENDIAN_H_ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/limits.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/limits.h new file mode 100644 index 0000000000..114373270b --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/limits.h @@ -0,0 +1,109 @@ +/*- + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: stable/8/sys/sys/limits.h 219757 2011-03-18 22:35:48Z jilles $ + */ + +/** + * Modified for XMHF. + */ + +#ifndef _SYS_LIMITS_H_ +#define _SYS_LIMITS_H_ + +#ifdef __AMD64__ +#include +#elif defined(__I386__) +#include +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + +#define CHAR_BIT __CHAR_BIT /* number of bits in a char */ + +#define SCHAR_MAX __SCHAR_MAX /* max value for a signed char */ +#define SCHAR_MIN __SCHAR_MIN /* min value for a signed char */ + +#define UCHAR_MAX __UCHAR_MAX /* max value for an unsigned char */ + +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MAX UCHAR_MAX /* max value for a char */ +#define CHAR_MIN 0 /* min value for a char */ +#else +#define CHAR_MAX SCHAR_MAX +#define CHAR_MIN SCHAR_MIN +#endif + +#define USHRT_MAX __USHRT_MAX /* max value for an unsigned short */ +#define SHRT_MAX __SHRT_MAX /* max value for a short */ +#define SHRT_MIN __SHRT_MIN /* min value for a short */ + +#define UINT_MAX __UINT_MAX /* max value for an unsigned int */ +#define INT_MAX __INT_MAX /* max value for an int */ +#define INT_MIN __INT_MIN /* min value for an int */ + +#define ULONG_MAX __ULONG_MAX /* max for an unsigned long */ +#define LONG_MAX __LONG_MAX /* max for a long */ +#define LONG_MIN __LONG_MIN /* min for a long */ + +#ifdef __LONG_LONG_SUPPORTED +#define ULLONG_MAX __ULLONG_MAX /* max for an unsigned long long */ +#define LLONG_MAX __LLONG_MAX /* max for a long long */ +#define LLONG_MIN __LLONG_MIN /* min for a long long */ +#endif + +#if __POSIX_VISIBLE || __XSI_VISIBLE +#define SSIZE_MAX __SSIZE_MAX /* max value for an ssize_t */ +#endif + +#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE +#define SIZE_T_MAX __SIZE_T_MAX /* max value for a size_t */ + +#define OFF_MAX __OFF_MAX /* max value for an off_t */ +#define OFF_MIN __OFF_MIN /* min value for an off_t */ +#endif + +#if __BSD_VISIBLE +#define GID_MAX UINT_MAX /* max value for a gid_t */ +#define UID_MAX UINT_MAX /* max value for a uid_t */ + +#define UQUAD_MAX (__UQUAD_MAX) /* max value for a uquad_t */ +#define QUAD_MAX (__QUAD_MAX) /* max value for a quad_t */ +#define QUAD_MIN (__QUAD_MIN) /* min value for a quad_t */ +#endif + +#if __XSI_VISIBLE || __POSIX_VISIBLE >= 200809 +#define LONG_BIT __LONG_BIT +#define WORD_BIT __WORD_BIT +#endif + +#if __POSIX_VISIBLE +#define MQ_PRIO_MAX 64 +#endif + +#endif /* !_SYS_LIMITS_H_ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/stdarg.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/stdarg.h new file mode 100644 index 0000000000..6e5ef53843 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/stdarg.h @@ -0,0 +1,77 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +//stdarg.h - variable length arguments +//author: amit vasudevan (amitvasudevan@acm.org) +//based on guidelines in +//http://pubs.opengroup.org/onlinepubs/007904875/basedefs/stdarg.h.html + +#ifndef __STDARG_H__ +#define __STDARG_H__ + +#ifndef __ASSEMBLY__ + +#ifdef __AMD64__ + +#include + +#elif defined(__I386__) + +typedef void *va_list; + +#define va_start(list, name) (void) (list = (void *)((char *)&name + \ + ((sizeof (name) + (sizeof (int) - 1)) & ~(sizeof (int) - 1)))) +#define va_arg(list, mode) ((mode *)(list = (char *)list + sizeof (mode)))[-1] + +#define va_end(list) (void)0 + +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + +#endif //#ifndef __ASSEMBLY__ + +#endif /* __STDARG_H__ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/stdarg64.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/stdarg64.h new file mode 100644 index 0000000000..bd9d90177d --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/stdarg64.h @@ -0,0 +1,42 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2002 David E. O'Brien. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef __STDARG64_H__ +#define __STDARG64_H__ + +typedef __builtin_va_list va_list; + +#define va_start(ap, last) __builtin_va_start((ap), (last)) +#define va_arg(ap, type) __builtin_va_arg((ap), type) +#define va_end(ap) __builtin_va_end(ap) + +#endif /* ! __STDARG64_H__ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/stdbool.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/stdbool.h new file mode 100644 index 0000000000..6d93bb5216 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/stdbool.h @@ -0,0 +1,58 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* Implemented based on + * http://pubs.opengroup.org/onlinepubs/007904875/basedefs/stdbool.h.html */ +#ifndef __STDBOOL_H__ +#define __STDBOOL_H__ + +typedef int boolean_t; +typedef boolean_t bool; +#define true 1 +#define false 0 +#define __bool_true_false_are_defined + +#endif /* __STDBOOL_H__ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/stddef.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/stddef.h new file mode 100644 index 0000000000..f1da7f86af --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/stddef.h @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 2002 Maxime Henrion + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: stable/8/sys/sys/stddef.h 199583 2009-11-20 15:27:52Z jhb $ + */ +/** + * Modified for XMHF. + */ + +#ifndef _SYS_STDDEF_H_ +#define _SYS_STDDEF_H_ + +#include +#ifdef __AMD64__ +#include +#elif defined(__I386__) +#include +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + +typedef __ptrdiff_t ptrdiff_t; + +/* extracted from cdefs.h */ +#include +#define offsetof(type, field) __offsetof(type, field) + +#endif /* !_SYS_STDDEF_H_ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/stdint.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/stdint.h new file mode 100644 index 0000000000..e4e295f74d --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/stdint.h @@ -0,0 +1,116 @@ +/*- + * Copyright (c) 2001 Mike Barcroft + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: stable/8/sys/sys/stdint.h 199583 2009-11-20 15:27:52Z jhb $ + */ + +/** + * Modified for XMHF. + */ + +#ifndef _SYS_STDINT_H_ +#define _SYS_STDINT_H_ + +#ifdef __AMD64__ +#include +#include +#elif defined(__I386__) +#include +#include +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +#include + +#ifndef _INT8_T_DECLARED +typedef __int8_t int8_t; +#define _INT8_T_DECLARED +#endif + +#ifndef _INT16_T_DECLARED +typedef __int16_t int16_t; +#define _INT16_T_DECLARED +#endif + +#ifndef _INT32_T_DECLARED +typedef __int32_t int32_t; +#define _INT32_T_DECLARED +#endif + +#ifndef _INT64_T_DECLARED +typedef __int64_t int64_t; +#define _INT64_T_DECLARED +#endif + +#ifndef _UINT8_T_DECLARED +typedef __uint8_t uint8_t; +#define _UINT8_T_DECLARED +#endif + +#ifndef _UINT16_T_DECLARED +typedef __uint16_t uint16_t; +#define _UINT16_T_DECLARED +#endif + +#ifndef _UINT32_T_DECLARED +typedef __uint32_t uint32_t; +#define _UINT32_T_DECLARED +#endif + +#ifndef _UINT64_T_DECLARED +typedef __uint64_t uint64_t; +#define _UINT64_T_DECLARED +#endif + +typedef __int_least8_t int_least8_t; +typedef __int_least16_t int_least16_t; +typedef __int_least32_t int_least32_t; +typedef __int_least64_t int_least64_t; + +typedef __uint_least8_t uint_least8_t; +typedef __uint_least16_t uint_least16_t; +typedef __uint_least32_t uint_least32_t; +typedef __uint_least64_t uint_least64_t; + +typedef __int_fast8_t int_fast8_t; +typedef __int_fast16_t int_fast16_t; +typedef __int_fast32_t int_fast32_t; +typedef __int_fast64_t int_fast64_t; + +typedef __uint_fast8_t uint_fast8_t; +typedef __uint_fast16_t uint_fast16_t; +typedef __uint_fast32_t uint_fast32_t; +typedef __uint_fast64_t uint_fast64_t; + +typedef __intmax_t intmax_t; +typedef __uintmax_t uintmax_t; + +#ifndef _INTPTR_T_DECLARED +typedef __intptr_t intptr_t; +typedef __uintptr_t uintptr_t; +#define _INTPTR_T_DECLARED +#endif + +#endif /* !_SYS_STDINT_H_ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/stdio.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/stdio.h new file mode 100644 index 0000000000..f892760986 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/stdio.h @@ -0,0 +1,126 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef STDIO_H +#define STDIO_H + +#include +#include + +typedef size_t fpos_t; + +typedef struct { + int fd; +} FILE; + +#define stderr NULL +#define stdout NULL +#define stdin NULL + +void clearerr(FILE *); +char *ctermid(char *); +char *cuserid(char *); /* (LEGACY) */ +int fclose(FILE *); +FILE *fdopen(int, const char *); +int feof(FILE *); +int ferror(FILE *); +int fflush(FILE *); +int fgetc(FILE *); +int fgetpos(FILE *, fpos_t *); +char *fgets(char *, int, FILE *); +int fileno(FILE *); +void flockfile(FILE *); +FILE *fopen(const char *, const char *); +int fprintf(FILE *, const char *, ...); +int fputc(int, FILE *); +int fputs(const char *, FILE *); +size_t fread(void *, size_t, size_t, FILE *); +FILE *freopen(const char *, const char *, FILE *); +int fscanf(FILE *, const char *, ...); +int fseek(FILE *, long int, int); +int fseeko(FILE *, off_t, int); +int fsetpos(FILE *, const fpos_t *); +long int ftell(FILE *); +off_t ftello(FILE *); +int ftrylockfile(FILE *); +void funlockfile(FILE *); +size_t fwrite(const void *, size_t, size_t, FILE *); +int getc(FILE *); +int getchar(void); +int getc_unlocked(FILE *); +int getchar_unlocked(void); +int getopt(int, char * const[], const char); /* (LEGACY) */ +char *gets(char *); +int getw(FILE *); +int pclose(FILE *); +void perror(const char *); +FILE *popen(const char *, const char *); +int printf(const char *, ...); +int putc(int, FILE *); +int putchar(int); +int putc_unlocked(int, FILE *); +int putchar_unlocked(int); +int puts(const char *); +int putw(int, FILE *); +int remove(const char *); +int rename(const char *, const char *); +void rewind(FILE *); +int scanf(const char *, ...); +void setbuf(FILE *, char *); +int setvbuf(FILE *, char *, int, size_t); +int snprintf(char *, size_t, const char *, ...); +int sprintf(char *, const char *, ...); +int sscanf(const char *, const char *, ...); +char *tempnam(const char *, const char *); +FILE *tmpfile(void); +char *tmpnam(char *); +int ungetc(int, FILE *); +int vfprintf(FILE *, const char *, va_list); +int vprintf(const char *, va_list); +int vsnprintf(char *, size_t, const char *, va_list); +int vsprintf(char *, const char *, va_list); + +#endif diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/stdlib.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/stdlib.h new file mode 100644 index 0000000000..495d0d2a2d --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/stdlib.h @@ -0,0 +1,52 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef __STDLIB_H__ +#define __STDLIB_H__ + +__attribute__((__noreturn__)) void abort(void); + +#endif diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/string.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/string.h new file mode 100644 index 0000000000..be9156ff3f --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/string.h @@ -0,0 +1,72 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/** + * libc string functions for use in a stand-alone environment + */ +#ifndef __EMHF_STRING_H__ +#define __EMHF_STRING_H__ + +#include +#include +#include +#include + +#ifndef __ASSEMBLY__ +void *memmove(void *dst_void, const void *src_void, size_t length); +char *strchr(const char *s, int c); +size_t strnlen(const char * s, size_t count); +void *memcpy(void * to, const void * from, size_t n); +void *memset (void *str, int c, size_t len); +int strncmp(const char *s1, const char *s2, size_t n); +int strcmp(const char * cs,const char * ct); +char *strncpy(char * dst, const char * src, size_t n); +size_t strlen(const char * s); +unsigned long strtoul(const char *cp,const char **endp, unsigned int base); +int memcmp(const void *b1, const void *b2, size_t len); +#endif /* __ASSEMBLY__ */ + +#endif /* __EMHF_STRING_H__ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/_null.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/_null.h new file mode 100644 index 0000000000..5a49cc227a --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/_null.h @@ -0,0 +1,49 @@ +/*- + * Copyright (c) 2003 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: stable/8/sys/sys/_null.h 199583 2009-11-20 15:27:52Z jhb $ + */ + +/** + * Modified for XMHF. + */ + +#ifndef NULL + +#if !defined(__cplusplus) +#define NULL ((void *)0) +#else +#if defined(__GNUG__) && defined(__GNUC__) && __GNUC__ >= 4 +#define NULL __null +#else +#if defined(__LP64__) +#define NULL (0L) +#else +#define NULL 0 +#endif /* __LP64__ */ +#endif /* __GNUG__ */ +#endif /* !__cplusplus */ + +#endif diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/amd64_endian.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/amd64_endian.h new file mode 100644 index 0000000000..e33c52c756 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/amd64_endian.h @@ -0,0 +1,162 @@ +/*- + * Copyright (c) 1987, 1991 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)endian.h 7.8 (Berkeley) 4/3/91 + * $FreeBSD$ + */ + +/** + * Modified for XMHF. + */ + +#ifndef _MACHINE_ENDIAN_H_ +#define _MACHINE_ENDIAN_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Define the order of 32-bit words in 64-bit words. + */ +#define _QUAD_HIGHWORD 1 +#define _QUAD_LOWWORD 0 + +/* + * Definitions for byte order, according to byte significance from low + * address to high. + */ +#define _LITTLE_ENDIAN 1234 /* LSB first: i386, vax */ +#define _BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */ +#define _PDP_ENDIAN 3412 /* LSB first in word, MSW first in long */ + +#define _BYTE_ORDER _LITTLE_ENDIAN + +/* + * Deprecated variants that don't have enough underscores to be useful in more + * strict namespaces. + */ +#if __BSD_VISIBLE +#define LITTLE_ENDIAN _LITTLE_ENDIAN +#define BIG_ENDIAN _BIG_ENDIAN +#define PDP_ENDIAN _PDP_ENDIAN +#define BYTE_ORDER _BYTE_ORDER +#endif + +#if defined(__GNUCLIKE_ASM) && defined(__GNUCLIKE_BUILTIN_CONSTANT_P) + +#define __byte_swap_int_var(x) \ +__extension__ ({ register __uint32_t __X = (x); \ + __asm ("bswap %0" : "+r" (__X)); \ + __X; }) + +#ifdef __OPTIMIZE__ + +#define __byte_swap_int_const(x) \ + ((((x) & 0xff000000) >> 24) | \ + (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | \ + (((x) & 0x000000ff) << 24)) +#define __byte_swap_int(x) (__builtin_constant_p(x) ? \ + __byte_swap_int_const(x) : __byte_swap_int_var(x)) + +#else /* __OPTIMIZE__ */ + +#define __byte_swap_int(x) __byte_swap_int_var(x) + +#endif /* __OPTIMIZE__ */ + +#define __byte_swap_long_var(x) \ +__extension__ ({ register __uint64_t __X = (x); \ + __asm ("bswap %0" : "+r" (__X)); \ + __X; }) + +#ifdef __OPTIMIZE__ + +#define __byte_swap_long_const(x) \ + (((x >> 56) | \ + ((x >> 40) & 0xff00) | \ + ((x >> 24) & 0xff0000) | \ + ((x >> 8) & 0xff000000) | \ + ((x << 8) & (0xfful << 32)) | \ + ((x << 24) & (0xfful << 40)) | \ + ((x << 40) & (0xfful << 48)) | \ + ((x << 56)))) + +#define __byte_swap_long(x) (__builtin_constant_p(x) ? \ + __byte_swap_long_const(x) : __byte_swap_long_var(x)) + +#else /* __OPTIMIZE__ */ + +#define __byte_swap_long(x) __byte_swap_long_var(x) + +#endif /* __OPTIMIZE__ */ + +static __inline __uint64_t +__bswap64(__uint64_t _x) +{ + + return (__byte_swap_long(_x)); +} + +static __inline __uint32_t +__bswap32(__uint32_t _x) +{ + + return (__byte_swap_int(_x)); +} + +static __inline __uint16_t +__bswap16(__uint16_t _x) +{ + return (_x << 8 | _x >> 8); +} + +#define __htonl(x) __bswap32(x) +#define __htons(x) __bswap16(x) +#define __ntohl(x) __bswap32(x) +#define __ntohs(x) __bswap16(x) + +#else /* !(__GNUCLIKE_ASM && __GNUCLIKE_BUILTIN_CONSTANT_P) */ + +/* + * No optimizations are available for this compiler. Fall back to + * non-optimized functions by defining the constant usually used to prevent + * redefinition. + */ +#define _BYTEORDER_FUNC_DEFINED + +#endif /* __GNUCLIKE_ASM && __GNUCLIKE_BUILTIN_CONSTANT_P */ + +#ifdef __cplusplus +} +#endif + +#endif /* !_MACHINE_ENDIAN_H_ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/amd64_inttypes.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/amd64_inttypes.h new file mode 100644 index 0000000000..fb0417b8fb --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/amd64_inttypes.h @@ -0,0 +1,217 @@ +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Klaus Klein. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * From: $NetBSD: int_fmtio.h,v 1.2 2001/04/26 16:25:21 kleink Exp $ + * $FreeBSD: stable/8/sys/amd64/include/_inttypes.h 213956 2010-10-17 12:11:42Z marius $ + */ + +/** + * Modified for XMHF. + */ + +#ifndef _MACHINE_INTTYPES_H_ +#define _MACHINE_INTTYPES_H_ + +/* + * Macros for format specifiers. + */ + +/* fprintf(3) macros for signed integers. */ + +#define PRId8 "d" /* int8_t */ +#define PRId16 "d" /* int16_t */ +#define PRId32 "d" /* int32_t */ +#define PRId64 "ld" /* int64_t */ +#define PRIdLEAST8 "d" /* int_least8_t */ +#define PRIdLEAST16 "d" /* int_least16_t */ +#define PRIdLEAST32 "d" /* int_least32_t */ +#define PRIdLEAST64 "ld" /* int_least64_t */ +#define PRIdFAST8 "d" /* int_fast8_t */ +#define PRIdFAST16 "d" /* int_fast16_t */ +#define PRIdFAST32 "d" /* int_fast32_t */ +#define PRIdFAST64 "ld" /* int_fast64_t */ +#define PRIdMAX "jd" /* intmax_t */ +#define PRIdPTR "ld" /* intptr_t */ + +#define PRIi8 "i" /* int8_t */ +#define PRIi16 "i" /* int16_t */ +#define PRIi32 "i" /* int32_t */ +#define PRIi64 "li" /* int64_t */ +#define PRIiLEAST8 "i" /* int_least8_t */ +#define PRIiLEAST16 "i" /* int_least16_t */ +#define PRIiLEAST32 "i" /* int_least32_t */ +#define PRIiLEAST64 "li" /* int_least64_t */ +#define PRIiFAST8 "i" /* int_fast8_t */ +#define PRIiFAST16 "i" /* int_fast16_t */ +#define PRIiFAST32 "i" /* int_fast32_t */ +#define PRIiFAST64 "li" /* int_fast64_t */ +#define PRIiMAX "ji" /* intmax_t */ +#define PRIiPTR "li" /* intptr_t */ + +/* fprintf(3) macros for unsigned integers. */ + +#define PRIo8 "o" /* uint8_t */ +#define PRIo16 "o" /* uint16_t */ +#define PRIo32 "o" /* uint32_t */ +#define PRIo64 "lo" /* uint64_t */ +#define PRIoLEAST8 "o" /* uint_least8_t */ +#define PRIoLEAST16 "o" /* uint_least16_t */ +#define PRIoLEAST32 "o" /* uint_least32_t */ +#define PRIoLEAST64 "lo" /* uint_least64_t */ +#define PRIoFAST8 "o" /* uint_fast8_t */ +#define PRIoFAST16 "o" /* uint_fast16_t */ +#define PRIoFAST32 "o" /* uint_fast32_t */ +#define PRIoFAST64 "lo" /* uint_fast64_t */ +#define PRIoMAX "jo" /* uintmax_t */ +#define PRIoPTR "lo" /* uintptr_t */ + +#define PRIu8 "u" /* uint8_t */ +#define PRIu16 "u" /* uint16_t */ +#define PRIu32 "u" /* uint32_t */ +#define PRIu64 "lu" /* uint64_t */ +#define PRIuLEAST8 "u" /* uint_least8_t */ +#define PRIuLEAST16 "u" /* uint_least16_t */ +#define PRIuLEAST32 "u" /* uint_least32_t */ +#define PRIuLEAST64 "lu" /* uint_least64_t */ +#define PRIuFAST8 "u" /* uint_fast8_t */ +#define PRIuFAST16 "u" /* uint_fast16_t */ +#define PRIuFAST32 "u" /* uint_fast32_t */ +#define PRIuFAST64 "lu" /* uint_fast64_t */ +#define PRIuMAX "ju" /* uintmax_t */ +#define PRIuPTR "lu" /* uintptr_t */ + +#define PRIx8 "x" /* uint8_t */ +#define PRIx16 "x" /* uint16_t */ +#define PRIx32 "x" /* uint32_t */ +#define PRIx64 "lx" /* uint64_t */ +#define PRIxLEAST8 "x" /* uint_least8_t */ +#define PRIxLEAST16 "x" /* uint_least16_t */ +#define PRIxLEAST32 "x" /* uint_least32_t */ +#define PRIxLEAST64 "lx" /* uint_least64_t */ +#define PRIxFAST8 "x" /* uint_fast8_t */ +#define PRIxFAST16 "x" /* uint_fast16_t */ +#define PRIxFAST32 "x" /* uint_fast32_t */ +#define PRIxFAST64 "lx" /* uint_fast64_t */ +#define PRIxMAX "jx" /* uintmax_t */ +#define PRIxPTR "lx" /* uintptr_t */ + +#define PRIX8 "X" /* uint8_t */ +#define PRIX16 "X" /* uint16_t */ +#define PRIX32 "X" /* uint32_t */ +#define PRIX64 "lX" /* uint64_t */ +#define PRIXLEAST8 "X" /* uint_least8_t */ +#define PRIXLEAST16 "X" /* uint_least16_t */ +#define PRIXLEAST32 "X" /* uint_least32_t */ +#define PRIXLEAST64 "lX" /* uint_least64_t */ +#define PRIXFAST8 "X" /* uint_fast8_t */ +#define PRIXFAST16 "X" /* uint_fast16_t */ +#define PRIXFAST32 "X" /* uint_fast32_t */ +#define PRIXFAST64 "lX" /* uint_fast64_t */ +#define PRIXMAX "jX" /* uintmax_t */ +#define PRIXPTR "lX" /* uintptr_t */ + +/* fscanf(3) macros for signed integers. */ + +#define SCNd8 "hhd" /* int8_t */ +#define SCNd16 "hd" /* int16_t */ +#define SCNd32 "d" /* int32_t */ +#define SCNd64 "ld" /* int64_t */ +#define SCNdLEAST8 "hhd" /* int_least8_t */ +#define SCNdLEAST16 "hd" /* int_least16_t */ +#define SCNdLEAST32 "d" /* int_least32_t */ +#define SCNdLEAST64 "ld" /* int_least64_t */ +#define SCNdFAST8 "d" /* int_fast8_t */ +#define SCNdFAST16 "d" /* int_fast16_t */ +#define SCNdFAST32 "d" /* int_fast32_t */ +#define SCNdFAST64 "ld" /* int_fast64_t */ +#define SCNdMAX "jd" /* intmax_t */ +#define SCNdPTR "ld" /* intptr_t */ + +#define SCNi8 "hhi" /* int8_t */ +#define SCNi16 "hi" /* int16_t */ +#define SCNi32 "i" /* int32_t */ +#define SCNi64 "li" /* int64_t */ +#define SCNiLEAST8 "hhi" /* int_least8_t */ +#define SCNiLEAST16 "hi" /* int_least16_t */ +#define SCNiLEAST32 "i" /* int_least32_t */ +#define SCNiLEAST64 "li" /* int_least64_t */ +#define SCNiFAST8 "i" /* int_fast8_t */ +#define SCNiFAST16 "i" /* int_fast16_t */ +#define SCNiFAST32 "i" /* int_fast32_t */ +#define SCNiFAST64 "li" /* int_fast64_t */ +#define SCNiMAX "ji" /* intmax_t */ +#define SCNiPTR "li" /* intptr_t */ + +/* fscanf(3) macros for unsigned integers. */ + +#define SCNo8 "hho" /* uint8_t */ +#define SCNo16 "ho" /* uint16_t */ +#define SCNo32 "o" /* uint32_t */ +#define SCNo64 "lo" /* uint64_t */ +#define SCNoLEAST8 "hho" /* uint_least8_t */ +#define SCNoLEAST16 "ho" /* uint_least16_t */ +#define SCNoLEAST32 "o" /* uint_least32_t */ +#define SCNoLEAST64 "lo" /* uint_least64_t */ +#define SCNoFAST8 "o" /* uint_fast8_t */ +#define SCNoFAST16 "o" /* uint_fast16_t */ +#define SCNoFAST32 "o" /* uint_fast32_t */ +#define SCNoFAST64 "lo" /* uint_fast64_t */ +#define SCNoMAX "jo" /* uintmax_t */ +#define SCNoPTR "lo" /* uintptr_t */ + +#define SCNu8 "hhu" /* uint8_t */ +#define SCNu16 "hu" /* uint16_t */ +#define SCNu32 "u" /* uint32_t */ +#define SCNu64 "lu" /* uint64_t */ +#define SCNuLEAST8 "hhu" /* uint_least8_t */ +#define SCNuLEAST16 "hu" /* uint_least16_t */ +#define SCNuLEAST32 "u" /* uint_least32_t */ +#define SCNuLEAST64 "lu" /* uint_least64_t */ +#define SCNuFAST8 "u" /* uint_fast8_t */ +#define SCNuFAST16 "u" /* uint_fast16_t */ +#define SCNuFAST32 "u" /* uint_fast32_t */ +#define SCNuFAST64 "lu" /* uint_fast64_t */ +#define SCNuMAX "ju" /* uintmax_t */ +#define SCNuPTR "lu" /* uintptr_t */ + +#define SCNx8 "hhx" /* uint8_t */ +#define SCNx16 "hx" /* uint16_t */ +#define SCNx32 "x" /* uint32_t */ +#define SCNx64 "lx" /* uint64_t */ +#define SCNxLEAST8 "hhx" /* uint_least8_t */ +#define SCNxLEAST16 "hx" /* uint_least16_t */ +#define SCNxLEAST32 "x" /* uint_least32_t */ +#define SCNxLEAST64 "lx" /* uint_least64_t */ +#define SCNxFAST8 "x" /* uint_fast8_t */ +#define SCNxFAST16 "x" /* uint_fast16_t */ +#define SCNxFAST32 "x" /* uint_fast32_t */ +#define SCNxFAST64 "lx" /* uint_fast64_t */ +#define SCNxMAX "jx" /* uintmax_t */ +#define SCNxPTR "lx" /* uintptr_t */ + +#endif /* !_MACHINE_INTTYPES_H_ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/amd64_limits.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/amd64_limits.h new file mode 100644 index 0000000000..a826173674 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/amd64_limits.h @@ -0,0 +1,96 @@ +/*- + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)limits.h 8.3 (Berkeley) 1/4/94 + * $FreeBSD$ + */ + +/** + * Modified for XMHF. + */ + +#ifndef _MACHINE__LIMITS_H_ +#define _MACHINE__LIMITS_H_ + +/* + * According to ANSI (section 2.2.4.2), the values below must be usable by + * #if preprocessing directives. Additionally, the expression must have the + * same type as would an expression that is an object of the corresponding + * type converted according to the integral promotions. The subtraction for + * INT_MIN, etc., is so the value is not unsigned; e.g., 0x80000000 is an + * unsigned int for 32-bit two's complement ANSI compilers (section 3.1.3.2). + * These numbers are for the default configuration of gcc. They work for + * some other compilers as well, but this should not be depended on. + */ + +#define __CHAR_BIT 8 /* number of bits in a char */ + +#define __SCHAR_MAX 0x7f /* max value for a signed char */ +#define __SCHAR_MIN (-0x7f - 1) /* min value for a signed char */ + +#define __UCHAR_MAX 0xffU /* max value for an unsigned char */ + +#define __USHRT_MAX 0xffffU /* max value for an unsigned short */ +#define __SHRT_MAX 0x7fff /* max value for a short */ +#define __SHRT_MIN (-0x7fff - 1) /* min value for a short */ + +#define __UINT_MAX 0xffffffffU /* max value for an unsigned int */ +#define __INT_MAX 0x7fffffff /* max value for an int */ +#define __INT_MIN (-0x7fffffff - 1) /* min value for an int */ + +#define __ULONG_MAX 0xffffffffffffffffUL /* max for an unsigned long */ +#define __LONG_MAX 0x7fffffffffffffffL /* max for a long */ +#define __LONG_MIN (-0x7fffffffffffffffL - 1) /* min for a long */ + + /* max value for an unsigned long long */ +#define __ULLONG_MAX 0xffffffffffffffffULL +#define __LLONG_MAX 0x7fffffffffffffffLL /* max value for a long long */ +#define __LLONG_MIN (-0x7fffffffffffffffLL - 1) /* min for a long long */ + +#define __SSIZE_MAX __LONG_MAX /* max value for a ssize_t */ + +#define __SIZE_T_MAX __ULONG_MAX /* max value for a size_t */ + +#define __OFF_MAX __LONG_MAX /* max value for an off_t */ +#define __OFF_MIN __LONG_MIN /* min value for an off_t */ + +/* Quads and longs are the same on the amd64. Ensure they stay in sync. */ +#define __UQUAD_MAX __ULONG_MAX /* max value for a uquad_t */ +#define __QUAD_MAX __LONG_MAX /* max value for a quad_t */ +#define __QUAD_MIN __LONG_MIN /* min value for a quad_t */ + +#define __LONG_BIT 64 +#define __WORD_BIT 32 + +/* + * Minimum signal stack size. The current signal frame + * for i386 is 408 bytes large. + */ +#define __MINSIGSTKSZ (512 * 4) + +#endif /* !_MACHINE__LIMITS_H_ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/amd64_stdint.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/amd64_stdint.h new file mode 100644 index 0000000000..1ca94dae1b --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/amd64_stdint.h @@ -0,0 +1,175 @@ +/*- + * Copyright (c) 2001, 2002 Mike Barcroft + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Klaus Klein. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/** + * Modified for XMHF. + */ + +#ifndef _MACHINE__STDINT_H_ +#define _MACHINE__STDINT_H_ + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) + +#define INT8_C(c) (c) +#define INT16_C(c) (c) +#define INT32_C(c) (c) +#define INT64_C(c) (c ## L) + +#define UINT8_C(c) (c) +#define UINT16_C(c) (c) +#define UINT32_C(c) (c ## U) +#define UINT64_C(c) (c ## UL) + +#define INTMAX_C(c) (c ## L) +#define UINTMAX_C(c) (c ## UL) + +#endif /* !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) */ + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) + +/* + * ISO/IEC 9899:1999 + * 7.18.2.1 Limits of exact-width integer types + */ +/* Minimum values of exact-width signed integer types. */ +#define INT8_MIN (-0x7f-1) +#define INT16_MIN (-0x7fff-1) +#define INT32_MIN (-0x7fffffff-1) +#define INT64_MIN (-0x7fffffffffffffffL-1) + +/* Maximum values of exact-width signed integer types. */ +#define INT8_MAX 0x7f +#define INT16_MAX 0x7fff +#define INT32_MAX 0x7fffffff +#define INT64_MAX 0x7fffffffffffffffL + +/* Maximum values of exact-width unsigned integer types. */ +#define UINT8_MAX 0xff +#define UINT16_MAX 0xffff +#define UINT32_MAX 0xffffffffU +#define UINT64_MAX 0xffffffffffffffffUL + +/* + * ISO/IEC 9899:1999 + * 7.18.2.2 Limits of minimum-width integer types + */ +/* Minimum values of minimum-width signed integer types. */ +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST64_MIN INT64_MIN + +/* Maximum values of minimum-width signed integer types. */ +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MAX INT64_MAX + +/* Maximum values of minimum-width unsigned integer types. */ +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +/* + * ISO/IEC 9899:1999 + * 7.18.2.3 Limits of fastest minimum-width integer types + */ +/* Minimum values of fastest minimum-width signed integer types. */ +#define INT_FAST8_MIN INT32_MIN +#define INT_FAST16_MIN INT32_MIN +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST64_MIN INT64_MIN + +/* Maximum values of fastest minimum-width signed integer types. */ +#define INT_FAST8_MAX INT32_MAX +#define INT_FAST16_MAX INT32_MAX +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MAX INT64_MAX + +/* Maximum values of fastest minimum-width unsigned integer types. */ +#define UINT_FAST8_MAX UINT32_MAX +#define UINT_FAST16_MAX UINT32_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +/* + * ISO/IEC 9899:1999 + * 7.18.2.4 Limits of integer types capable of holding object pointers + */ +#define INTPTR_MIN INT64_MIN +#define INTPTR_MAX INT64_MAX +#define UINTPTR_MAX UINT64_MAX + +/* + * ISO/IEC 9899:1999 + * 7.18.2.5 Limits of greatest-width integer types + */ +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +/* + * ISO/IEC 9899:1999 + * 7.18.3 Limits of other integer types + */ +/* Limits of ptrdiff_t. */ +#define PTRDIFF_MIN INT64_MIN +#define PTRDIFF_MAX INT64_MAX + +/* Limits of sig_atomic_t. */ +#define SIG_ATOMIC_MIN INT32_MIN +#define SIG_ATOMIC_MAX INT32_MAX + +/* Limit of size_t. */ +#define SIZE_MAX UINT64_MAX + +#ifndef WCHAR_MIN /* Also possibly defined in */ +/* Limits of wchar_t. */ +#define WCHAR_MIN INT32_MIN +#define WCHAR_MAX INT32_MAX +#endif + +/* Limits of wint_t. */ +#define WINT_MIN INT32_MIN +#define WINT_MAX INT32_MAX + +#endif /* !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) */ + +#endif /* !_MACHINE__STDINT_H_ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/amd64_types.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/amd64_types.h new file mode 100644 index 0000000000..5a4b1266ac --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/amd64_types.h @@ -0,0 +1,105 @@ +/*- + * Copyright (c) 2002 Mike Barcroft + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * From: @(#)ansi.h 8.2 (Berkeley) 1/4/94 + * From: @(#)types.h 8.3 (Berkeley) 1/5/94 + * $FreeBSD$ + */ + +/** + * Modified for XMHF to remove cdefs.h requirement. + */ + +#ifndef _MACHINE__TYPES_H_ +#define _MACHINE__TYPES_H_ + +/* number of bits per byte */ +#define NBBY 8 + +#define __NO_STRICT_ALIGNMENT + +/* + * Basic types upon which most other types are built. + */ +typedef __signed char __int8_t; +typedef unsigned char __uint8_t; +typedef short __int16_t; +typedef unsigned short __uint16_t; +typedef int __int32_t; +typedef unsigned int __uint32_t; +typedef long __int64_t; +typedef unsigned long __uint64_t; + +/* + * Standard type definitions. + */ +typedef __int32_t __clock_t; /* clock()... */ +typedef unsigned int __cpumask_t; +typedef __int64_t __critical_t; +typedef double __double_t; +typedef float __float_t; +typedef __int64_t __intfptr_t; +typedef __int64_t __intmax_t; +typedef __int64_t __intptr_t; +typedef __int32_t __int_fast8_t; +typedef __int32_t __int_fast16_t; +typedef __int32_t __int_fast32_t; +typedef __int64_t __int_fast64_t; +typedef __int8_t __int_least8_t; +typedef __int16_t __int_least16_t; +typedef __int32_t __int_least32_t; +typedef __int64_t __int_least64_t; +typedef __int64_t __ptrdiff_t; /* ptr1 - ptr2 */ +typedef __int64_t __register_t; +typedef __int64_t __segsz_t; /* segment size (in pages) */ +typedef __uint64_t __size_t; /* sizeof() */ +typedef __int64_t __ssize_t; /* byte count or error */ +typedef __int64_t __time_t; /* time()... */ +typedef __uint64_t __uintfptr_t; +typedef __uint64_t __uintmax_t; +typedef __uint64_t __uintptr_t; +typedef __uint32_t __uint_fast8_t; +typedef __uint32_t __uint_fast16_t; +typedef __uint32_t __uint_fast32_t; +typedef __uint64_t __uint_fast64_t; +typedef __uint8_t __uint_least8_t; +typedef __uint16_t __uint_least16_t; +typedef __uint32_t __uint_least32_t; +typedef __uint64_t __uint_least64_t; +typedef __uint64_t __u_register_t; + +typedef __uint64_t off_t; + +/* varargs stuff removed */ + +#endif /* !_MACHINE__TYPES_H_ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/cdefs.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/cdefs.h new file mode 100644 index 0000000000..7329265ff7 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/cdefs.h @@ -0,0 +1,586 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Berkeley Software Design, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)cdefs.h 8.8 (Berkeley) 1/9/95 + * $FreeBSD: src/sys/sys/cdefs.h,v 1.102.2.2.2.1 2010/12/21 17:09:25 kensmith Exp $ + */ + +/** + * Modified for XMHF. + */ + +#ifndef _SYS_CDEFS_H_ +#define _SYS_CDEFS_H_ + +#if defined(__cplusplus) +#define __BEGIN_DECLS extern "C" { +#define __END_DECLS } +#else +#define __BEGIN_DECLS +#define __END_DECLS +#endif + +/* + * This code has been put in place to help reduce the addition of + * compiler specific defines in FreeBSD code. It helps to aid in + * having a compiler-agnostic source tree. + */ + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) + +#if __GNUC__ >= 3 || defined(__INTEL_COMPILER) +#define __GNUCLIKE_ASM 3 +#define __GNUCLIKE_MATH_BUILTIN_CONSTANTS +#else +#define __GNUCLIKE_ASM 2 +#endif +#define __GNUCLIKE___TYPEOF 1 +#define __GNUCLIKE___OFFSETOF 1 +#define __GNUCLIKE___SECTION 1 + +#define __GNUCLIKE_ATTRIBUTE_MODE_DI 1 + +#ifndef __INTEL_COMPILER +# define __GNUCLIKE_CTOR_SECTION_HANDLING 1 +#endif + +#define __GNUCLIKE_BUILTIN_CONSTANT_P 1 +# if defined(__INTEL_COMPILER) && defined(__cplusplus) \ + && __INTEL_COMPILER < 800 +# undef __GNUCLIKE_BUILTIN_CONSTANT_P +# endif + +#if (__GNUC_MINOR__ > 95 || __GNUC__ >= 3) && !defined(__INTEL_COMPILER) +# define __GNUCLIKE_BUILTIN_VARARGS 1 +# define __GNUCLIKE_BUILTIN_STDARG 1 +# define __GNUCLIKE_BUILTIN_VAALIST 1 +#endif + +#if defined(__GNUC__) +# define __GNUC_VA_LIST_COMPATIBILITY 1 +#endif + +#ifndef __INTEL_COMPILER +# define __GNUCLIKE_BUILTIN_NEXT_ARG 1 +# define __GNUCLIKE_MATH_BUILTIN_RELOPS +#endif + +#define __GNUCLIKE_BUILTIN_MEMCPY 1 + +/* XXX: if __GNUC__ >= 2: not tested everywhere originally, where replaced */ +#define __CC_SUPPORTS_INLINE 1 +#define __CC_SUPPORTS___INLINE 1 +#define __CC_SUPPORTS___INLINE__ 1 + +#define __CC_SUPPORTS___FUNC__ 1 +#define __CC_SUPPORTS_WARNING 1 + +#define __CC_SUPPORTS_VARADIC_XXX 1 /* see varargs.h */ + +#define __CC_SUPPORTS_DYNAMIC_ARRAY_INIT 1 + +#endif /* __GNUC__ || __INTEL_COMPILER */ + +/* + * Macro to test if we're using a specific version of gcc or later. + */ +#if defined(__GNUC__) && !defined(__INTEL_COMPILER) +#define __GNUC_PREREQ__(ma, mi) \ + (__GNUC__ > (ma) || __GNUC__ == (ma) && __GNUC_MINOR__ >= (mi)) +#else +#define __GNUC_PREREQ__(ma, mi) 0 +#endif + +/* + * The __CONCAT macro is used to concatenate parts of symbol names, e.g. + * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo. + * The __CONCAT macro is a bit tricky to use if it must work in non-ANSI + * mode -- there must be no spaces between its arguments, and for nested + * __CONCAT's, all the __CONCAT's must be at the left. __CONCAT can also + * concatenate double-quoted strings produced by the __STRING macro, but + * this only works with ANSI C. + * + * __XSTRING is like __STRING, but it expands any macros in its argument + * first. It is only available with ANSI C. + */ +#if defined(__STDC__) || defined(__cplusplus) +#define __P(protos) protos /* full-blown ANSI C */ +#define __CONCAT1(x,y) x ## y +#define __CONCAT(x,y) __CONCAT1(x,y) +#define __STRING(x) #x /* stringify without expanding x */ +#define __XSTRING(x) __STRING(x) /* expand x, then stringify */ + +#define __const const /* define reserved names to standard */ +#define __signed signed +#define __volatile volatile +#if defined(__cplusplus) +#define __inline inline /* convert to C++ keyword */ +#else +#if !(defined(__CC_SUPPORTS___INLINE)) +#define __inline /* delete GCC keyword */ +#endif /* ! __CC_SUPPORTS___INLINE */ +#endif /* !__cplusplus */ + +#else /* !(__STDC__ || __cplusplus) */ +#define __P(protos) () /* traditional C preprocessor */ +#define __CONCAT(x,y) x/**/y +#define __STRING(x) "x" + +#if !defined(__CC_SUPPORTS___INLINE) +#define __const /* delete pseudo-ANSI C keywords */ +#define __inline +#define __signed +#define __volatile +/* + * In non-ANSI C environments, new programs will want ANSI-only C keywords + * deleted from the program and old programs will want them left alone. + * When using a compiler other than gcc, programs using the ANSI C keywords + * const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS. + * When using "gcc -traditional", we assume that this is the intent; if + * __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone. + */ +#ifndef NO_ANSI_KEYWORDS +#define const /* delete ANSI C keywords */ +#define inline +#define signed +#define volatile +#endif /* !NO_ANSI_KEYWORDS */ +#endif /* !__CC_SUPPORTS___INLINE */ +#endif /* !(__STDC__ || __cplusplus) */ + +/* + * Compiler-dependent macros to help declare dead (non-returning) and + * pure (no side effects) functions, and unused variables. They are + * null except for versions of gcc that are known to support the features + * properly (old versions of gcc-2 supported the dead and pure features + * in a different (wrong) way). If we do not provide an implementation + * for a given compiler, let the compile fail if it is told to use + * a feature that we cannot live without. + */ +#ifdef lint +#define __dead2 +#define __pure2 +#define __unused +#define __packed +#define __aligned(x) +#define __section(x) +#else +#if !__GNUC_PREREQ__(2, 5) && !defined(__INTEL_COMPILER) +#define __dead2 +#define __pure2 +#define __unused +#endif +#if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 7 && !defined(__INTEL_COMPILER) +#define __dead2 __attribute__((__noreturn__)) +#define __pure2 __attribute__((__const__)) +#define __unused +/* XXX Find out what to do for __packed, __aligned and __section */ +#endif +#if __GNUC_PREREQ__(2, 7) +#define __dead2 __attribute__((__noreturn__)) +#define __pure2 __attribute__((__const__)) +#define __unused __attribute__((__unused__)) +#define __used __attribute__((__used__)) +#define __packed __attribute__((__packed__)) +#define __aligned(x) __attribute__((__aligned__(x))) +#define __section(x) __attribute__((__section__(x))) +#endif +#if defined(__INTEL_COMPILER) +#define __dead2 __attribute__((__noreturn__)) +#define __pure2 __attribute__((__const__)) +#define __unused __attribute__((__unused__)) +#define __used __attribute__((__used__)) +#define __packed __attribute__((__packed__)) +#define __aligned(x) __attribute__((__aligned__(x))) +#define __section(x) __attribute__((__section__(x))) +#endif +#endif + +#if __GNUC_PREREQ__(2, 96) +#define __malloc_like __attribute__((__malloc__)) +#define __pure __attribute__((__pure__)) +#else +#define __malloc_like +#define __pure +#endif + +#if __GNUC_PREREQ__(3, 1) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 800) +#define __always_inline __attribute__((__always_inline__)) +#else +#define __always_inline +#endif + +#if __GNUC_PREREQ__(4, 2) /* actually 4.1.3 */ +#define __gnu89_inline __attribute__((__gnu_inline__)) __inline +#else +#define __gnu89_inline +#endif + +#if __GNUC_PREREQ__(3, 1) +#define __noinline __attribute__ ((__noinline__)) +#else +#define __noinline +#endif + +#if __GNUC_PREREQ__(3, 3) +#define __nonnull(x) __attribute__((__nonnull__(x))) +#else +#define __nonnull(x) +#endif + +/* XXX: should use `#if __STDC_VERSION__ < 199901'. */ +#if !__GNUC_PREREQ__(2, 7) && !defined(__INTEL_COMPILER) +#define __func__ NULL +#endif + +#if (defined(__INTEL_COMPILER) || (defined(__GNUC__) && __GNUC__ >= 2)) && !defined(__STRICT_ANSI__) || __STDC_VERSION__ >= 199901 +#define __LONG_LONG_SUPPORTED +#endif + +/* + * GCC 2.95 provides `__restrict' as an extension to C90 to support the + * C99-specific `restrict' type qualifier. We happen to use `__restrict' as + * a way to define the `restrict' type qualifier without disturbing older + * software that is unaware of C99 keywords. + */ +#if !(__GNUC__ == 2 && __GNUC_MINOR__ == 95) +#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901 || defined(lint) +#define __restrict +#else +#define __restrict restrict +#endif +#endif + +/* + * GNU C version 2.96 adds explicit branch prediction so that + * the CPU back-end can hint the processor and also so that + * code blocks can be reordered such that the predicted path + * sees a more linear flow, thus improving cache behavior, etc. + * + * The following two macros provide us with a way to utilize this + * compiler feature. Use __predict_true() if you expect the expression + * to evaluate to true, and __predict_false() if you expect the + * expression to evaluate to false. + * + * A few notes about usage: + * + * * Generally, __predict_false() error condition checks (unless + * you have some _strong_ reason to do otherwise, in which case + * document it), and/or __predict_true() `no-error' condition + * checks, assuming you want to optimize for the no-error case. + * + * * Other than that, if you don't know the likelihood of a test + * succeeding from empirical or other `hard' evidence, don't + * make predictions. + * + * * These are meant to be used in places that are run `a lot'. + * It is wasteful to make predictions in code that is run + * seldomly (e.g. at subsystem initialization time) as the + * basic block reordering that this affects can often generate + * larger code. + */ +#if __GNUC_PREREQ__(2, 96) +#define __predict_true(exp) __builtin_expect((exp), 1) +#define __predict_false(exp) __builtin_expect((exp), 0) +#else +#define __predict_true(exp) (exp) +#define __predict_false(exp) (exp) +#endif + +#if __GNUC_PREREQ__(4, 2) +#define __hidden __attribute__((__visibility__("hidden"))) +#define __exported __attribute__((__visibility__("default"))) +#else +#define __hidden +#define __exported +#endif + +/* + * We define this here since , , and + * require it. + */ +#if __GNUC_PREREQ__(4, 1) +#define __offsetof(type, field) __builtin_offsetof(type, field) +#else +#ifndef __cplusplus +#define __offsetof(type, field) ((size_t)(&((type *)0)->field)) +#else +#define __offsetof(type, field) \ + (__offsetof__ (reinterpret_cast \ + (&reinterpret_cast \ + (static_cast (0)->field)))) +#endif +#endif +#define __rangeof(type, start, end) \ + (__offsetof(type, end) - __offsetof(type, start)) + +/* + * Compiler-dependent macros to declare that functions take printf-like + * or scanf-like arguments. They are null except for versions of gcc + * that are known to support the features properly (old versions of gcc-2 + * didn't permit keeping the keywords out of the application namespace). + */ +#if !__GNUC_PREREQ__(2, 7) && !defined(__INTEL_COMPILER) +#define __printflike(fmtarg, firstvararg) +#define __scanflike(fmtarg, firstvararg) +#define __format_arg(fmtarg) +#else +#define __printflike(fmtarg, firstvararg) \ + __attribute__((__format__ (__printf__, fmtarg, firstvararg))) +#define __scanflike(fmtarg, firstvararg) \ + __attribute__((__format__ (__scanf__, fmtarg, firstvararg))) +#define __format_arg(fmtarg) __attribute__((__format_arg__ (fmtarg))) +#endif + +/* Compiler-dependent macros that rely on FreeBSD-specific extensions. */ +#if __FreeBSD_cc_version >= 300001 && defined(__GNUC__) && !defined(__INTEL_COMPILER) +#define __printf0like(fmtarg, firstvararg) \ + __attribute__((__format__ (__printf0__, fmtarg, firstvararg))) +#else +#define __printf0like(fmtarg, firstvararg) +#endif + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) +#ifndef __INTEL_COMPILER +#define __strong_reference(sym,aliassym) \ + extern __typeof (sym) aliassym __attribute__ ((__alias__ (#sym))) +#endif +#ifdef __STDC__ +#define __weak_reference(sym,alias) \ + __asm__(".weak " #alias); \ + __asm__(".equ " #alias ", " #sym) +#define __warn_references(sym,msg) \ + __asm__(".section .gnu.warning." #sym); \ + __asm__(".asciz \"" msg "\""); \ + __asm__(".previous") +#define __sym_compat(sym,impl,verid) \ + __asm__(".symver " #impl ", " #sym "@" #verid) +#define __sym_default(sym,impl,verid) \ + __asm__(".symver " #impl ", " #sym "@@" #verid) +#else +#define __weak_reference(sym,alias) \ + __asm__(".weak alias"); \ + __asm__(".equ alias, sym") +#define __warn_references(sym,msg) \ + __asm__(".section .gnu.warning.sym"); \ + __asm__(".asciz \"msg\""); \ + __asm__(".previous") +#define __sym_compat(sym,impl,verid) \ + __asm__(".symver impl, sym@verid") +#define __sym_default(impl,sym,verid) \ + __asm__(".symver impl, sym@@verid") +#endif /* __STDC__ */ +#endif /* __GNUC__ || __INTEL_COMPILER */ + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) +#define __IDSTRING(name,string) __asm__(".ident\t\"" string "\"") +#else +/* + * The following definition might not work well if used in header files, + * but it should be better than nothing. If you want a "do nothing" + * version, then it should generate some harmless declaration, such as: + * #define __IDSTRING(name,string) struct __hack + */ +#define __IDSTRING(name,string) static const char name[] __unused = string +#endif + +/* + * Embed the rcs id of a source file in the resulting library. Note that in + * more recent ELF binutils, we use .ident allowing the ID to be stripped. + * Usage: + * __FBSDID("$FreeBSD: src/sys/sys/cdefs.h,v 1.102.2.2.2.1 2010/12/21 17:09:25 kensmith Exp $"); + */ +#ifndef __FBSDID +#if !defined(lint) && !defined(STRIP_FBSDID) +#define __FBSDID(s) __IDSTRING(__CONCAT(__rcsid_,__LINE__),s) +#else +#define __FBSDID(s) struct __hack +#endif +#endif + +#ifndef __RCSID +#ifndef NO__RCSID +#define __RCSID(s) __IDSTRING(__CONCAT(__rcsid_,__LINE__),s) +#else +#define __RCSID(s) struct __hack +#endif +#endif + +#ifndef __RCSID_SOURCE +#ifndef NO__RCSID_SOURCE +#define __RCSID_SOURCE(s) __IDSTRING(__CONCAT(__rcsid_source_,__LINE__),s) +#else +#define __RCSID_SOURCE(s) struct __hack +#endif +#endif + +#ifndef __SCCSID +#ifndef NO__SCCSID +#define __SCCSID(s) __IDSTRING(__CONCAT(__sccsid_,__LINE__),s) +#else +#define __SCCSID(s) struct __hack +#endif +#endif + +#ifndef __COPYRIGHT +#ifndef NO__COPYRIGHT +#define __COPYRIGHT(s) __IDSTRING(__CONCAT(__copyright_,__LINE__),s) +#else +#define __COPYRIGHT(s) struct __hack +#endif +#endif + +#ifndef __DECONST +#define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var)) +#endif + +#ifndef __DEVOLATILE +#define __DEVOLATILE(type, var) ((type)(uintptr_t)(volatile void *)(var)) +#endif + +#ifndef __DEQUALIFY +#define __DEQUALIFY(type, var) ((type)(uintptr_t)(const volatile void *)(var)) +#endif + +/* + * The following definitions are an extension of the behavior originally + * implemented in , but with a different level of granularity. + * POSIX.1 requires that the macros we test be defined before any standard + * header file is included. + * + * Here's a quick run-down of the versions: + * defined(_POSIX_SOURCE) 1003.1-1988 + * _POSIX_C_SOURCE == 1 1003.1-1990 + * _POSIX_C_SOURCE == 2 1003.2-1992 C Language Binding Option + * _POSIX_C_SOURCE == 199309 1003.1b-1993 + * _POSIX_C_SOURCE == 199506 1003.1c-1995, 1003.1i-1995, + * and the omnibus ISO/IEC 9945-1: 1996 + * _POSIX_C_SOURCE == 200112 1003.1-2001 + * _POSIX_C_SOURCE == 200809 1003.1-2008 + * + * In addition, the X/Open Portability Guide, which is now the Single UNIX + * Specification, defines a feature-test macro which indicates the version of + * that specification, and which subsumes _POSIX_C_SOURCE. + * + * Our macros begin with two underscores to avoid namespace screwage. + */ + +/* Deal with IEEE Std. 1003.1-1990, in which _POSIX_C_SOURCE == 1. */ +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 1 +#undef _POSIX_C_SOURCE /* Probably illegal, but beyond caring now. */ +#define _POSIX_C_SOURCE 199009 +#endif + +/* Deal with IEEE Std. 1003.2-1992, in which _POSIX_C_SOURCE == 2. */ +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 2 +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 199209 +#endif + +/* Deal with various X/Open Portability Guides and Single UNIX Spec. */ +#ifdef _XOPEN_SOURCE +#if _XOPEN_SOURCE - 0 >= 700 +#define __XSI_VISIBLE 700 +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200809 +#elif _XOPEN_SOURCE - 0 >= 600 +#define __XSI_VISIBLE 600 +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200112 +#elif _XOPEN_SOURCE - 0 >= 500 +#define __XSI_VISIBLE 500 +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 199506 +#endif +#endif + +/* + * Deal with all versions of POSIX. The ordering relative to the tests above is + * important. + */ +#if defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE) +#define _POSIX_C_SOURCE 198808 +#endif +#ifdef _POSIX_C_SOURCE +#if _POSIX_C_SOURCE >= 200809 +#define __POSIX_VISIBLE 200809 +#define __ISO_C_VISIBLE 1999 +#elif _POSIX_C_SOURCE >= 200112 +#define __POSIX_VISIBLE 200112 +#define __ISO_C_VISIBLE 1999 +#elif _POSIX_C_SOURCE >= 199506 +#define __POSIX_VISIBLE 199506 +#define __ISO_C_VISIBLE 1990 +#elif _POSIX_C_SOURCE >= 199309 +#define __POSIX_VISIBLE 199309 +#define __ISO_C_VISIBLE 1990 +#elif _POSIX_C_SOURCE >= 199209 +#define __POSIX_VISIBLE 199209 +#define __ISO_C_VISIBLE 1990 +#elif _POSIX_C_SOURCE >= 199009 +#define __POSIX_VISIBLE 199009 +#define __ISO_C_VISIBLE 1990 +#else +#define __POSIX_VISIBLE 198808 +#define __ISO_C_VISIBLE 0 +#endif /* _POSIX_C_SOURCE */ +#else +/* + * Deal with _ANSI_SOURCE: + * If it is defined, and no other compilation environment is explicitly + * requested, then define our internal feature-test macros to zero. This + * makes no difference to the preprocessor (undefined symbols in preprocessing + * expressions are defined to have value zero), but makes it more convenient for + * a test program to print out the values. + * + * If a program mistakenly defines _ANSI_SOURCE and some other macro such as + * _POSIX_C_SOURCE, we will assume that it wants the broader compilation + * environment (and in fact we will never get here). + */ +#if defined(_ANSI_SOURCE) /* Hide almost everything. */ +#define __POSIX_VISIBLE 0 +#define __XSI_VISIBLE 0 +#define __BSD_VISIBLE 0 +#define __ISO_C_VISIBLE 1990 +#elif defined(_C99_SOURCE) /* Localism to specify strict C99 env. */ +#define __POSIX_VISIBLE 0 +#define __XSI_VISIBLE 0 +#define __BSD_VISIBLE 0 +#define __ISO_C_VISIBLE 1999 +#else /* Default environment: show everything. */ +#define __POSIX_VISIBLE 200809 +#define __XSI_VISIBLE 700 +#define __BSD_VISIBLE 1 +#define __ISO_C_VISIBLE 1999 +#endif +#endif + +#endif /* !_SYS_CDEFS_H_ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/i386_endian.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/i386_endian.h new file mode 100644 index 0000000000..4282027bc8 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/i386_endian.h @@ -0,0 +1,139 @@ +/*- + * Copyright (c) 1987, 1991 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)endian.h 7.8 (Berkeley) 4/3/91 + * $FreeBSD: stable/8/sys/i386/include/endian.h 199583 2009-11-20 15:27:52Z jhb $ + */ + +/** + * Modified for XMHF. + */ + +#ifndef _MACHINE_ENDIAN_H_ +#define _MACHINE_ENDIAN_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Define the order of 32-bit words in 64-bit words. + */ +#define _QUAD_HIGHWORD 1 +#define _QUAD_LOWWORD 0 + +/* + * Definitions for byte order, according to byte significance from low + * address to high. + */ +#define _LITTLE_ENDIAN 1234 /* LSB first: i386, vax */ +#define _BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */ +#define _PDP_ENDIAN 3412 /* LSB first in word, MSW first in long */ + +#define _BYTE_ORDER _LITTLE_ENDIAN + +/* + * Deprecated variants that don't have enough underscores to be useful in more + * strict namespaces. + */ +#if __BSD_VISIBLE +#define LITTLE_ENDIAN _LITTLE_ENDIAN +#define BIG_ENDIAN _BIG_ENDIAN +#define PDP_ENDIAN _PDP_ENDIAN +#define BYTE_ORDER _BYTE_ORDER +#endif + +#if defined(__GNUCLIKE_ASM) && defined(__GNUCLIKE_BUILTIN_CONSTANT_P) + +#define __byte_swap_int_var(x) \ +__extension__ ({ register __uint32_t __X = (x); \ + __asm ("bswap %0" : "+r" (__X)); \ + __X; }) + +#ifdef __OPTIMIZE__ + +#define __byte_swap_int_const(x) \ + ((((x) & 0xff000000) >> 24) | \ + (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | \ + (((x) & 0x000000ff) << 24)) +#define __byte_swap_int(x) (__builtin_constant_p(x) ? \ + __byte_swap_int_const(x) : __byte_swap_int_var(x)) + +#else /* __OPTIMIZE__ */ + +#define __byte_swap_int(x) __byte_swap_int_var(x) + +#endif /* __OPTIMIZE__ */ + +static __inline __uint64_t +__bswap64(__uint64_t _x) +{ + + return ((_x >> 56) | ((_x >> 40) & 0xff00) | ((_x >> 24) & 0xff0000) | + ((_x >> 8) & 0xff000000) | ((_x << 8) & ((__uint64_t)0xff << 32)) | + ((_x << 24) & ((__uint64_t)0xff << 40)) | + ((_x << 40) & ((__uint64_t)0xff << 48)) | ((_x << 56))); +} + +static __inline __uint32_t +__bswap32(__uint32_t _x) +{ + + return (__byte_swap_int(_x)); +} + +static __inline __uint16_t +__bswap16(__uint16_t _x) +{ + return (_x << 8 | _x >> 8); +} + +#define __htonl(x) __bswap32(x) +#define __htons(x) __bswap16(x) +#define __ntohl(x) __bswap32(x) +#define __ntohs(x) __bswap16(x) + +#else /* !(__GNUCLIKE_ASM && __GNUCLIKE_BUILTIN_CONSTANT_P) */ + +/* + * No optimizations are available for this compiler. Fall back to + * non-optimized functions by defining the constant usually used to prevent + * redefinition. + */ +#define _BYTEORDER_FUNC_DEFINED + +#endif /* __GNUCLIKE_ASM && __GNUCLIKE_BUILTIN_CONSTANT_P */ + +#ifdef __cplusplus +} +#endif + +#endif /* !_MACHINE_ENDIAN_H_ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/i386_inttypes.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/i386_inttypes.h new file mode 100644 index 0000000000..813f5847a5 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/i386_inttypes.h @@ -0,0 +1,217 @@ +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Klaus Klein. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * From: $NetBSD: int_fmtio.h,v 1.2 2001/04/26 16:25:21 kleink Exp $ + * $FreeBSD: stable/8/sys/i386/include/_inttypes.h 213956 2010-10-17 12:11:42Z marius $ + */ + +/** + * Modified for XMHF. + */ + +#ifndef _MACHINE_INTTYPES_H_ +#define _MACHINE_INTTYPES_H_ + +/* + * Macros for format specifiers. + */ + +/* fprintf(3) macros for signed integers. */ + +#define PRId8 "d" /* int8_t */ +#define PRId16 "d" /* int16_t */ +#define PRId32 "d" /* int32_t */ +#define PRId64 "lld" /* int64_t */ +#define PRIdLEAST8 "d" /* int_least8_t */ +#define PRIdLEAST16 "d" /* int_least16_t */ +#define PRIdLEAST32 "d" /* int_least32_t */ +#define PRIdLEAST64 "lld" /* int_least64_t */ +#define PRIdFAST8 "d" /* int_fast8_t */ +#define PRIdFAST16 "d" /* int_fast16_t */ +#define PRIdFAST32 "d" /* int_fast32_t */ +#define PRIdFAST64 "lld" /* int_fast64_t */ +#define PRIdMAX "jd" /* intmax_t */ +#define PRIdPTR "d" /* intptr_t */ + +#define PRIi8 "i" /* int8_t */ +#define PRIi16 "i" /* int16_t */ +#define PRIi32 "i" /* int32_t */ +#define PRIi64 "lli" /* int64_t */ +#define PRIiLEAST8 "i" /* int_least8_t */ +#define PRIiLEAST16 "i" /* int_least16_t */ +#define PRIiLEAST32 "i" /* int_least32_t */ +#define PRIiLEAST64 "lli" /* int_least64_t */ +#define PRIiFAST8 "i" /* int_fast8_t */ +#define PRIiFAST16 "i" /* int_fast16_t */ +#define PRIiFAST32 "i" /* int_fast32_t */ +#define PRIiFAST64 "lli" /* int_fast64_t */ +#define PRIiMAX "ji" /* intmax_t */ +#define PRIiPTR "i" /* intptr_t */ + +/* fprintf(3) macros for unsigned integers. */ + +#define PRIo8 "o" /* uint8_t */ +#define PRIo16 "o" /* uint16_t */ +#define PRIo32 "o" /* uint32_t */ +#define PRIo64 "llo" /* uint64_t */ +#define PRIoLEAST8 "o" /* uint_least8_t */ +#define PRIoLEAST16 "o" /* uint_least16_t */ +#define PRIoLEAST32 "o" /* uint_least32_t */ +#define PRIoLEAST64 "llo" /* uint_least64_t */ +#define PRIoFAST8 "o" /* uint_fast8_t */ +#define PRIoFAST16 "o" /* uint_fast16_t */ +#define PRIoFAST32 "o" /* uint_fast32_t */ +#define PRIoFAST64 "llo" /* uint_fast64_t */ +#define PRIoMAX "jo" /* uintmax_t */ +#define PRIoPTR "o" /* uintptr_t */ + +#define PRIu8 "u" /* uint8_t */ +#define PRIu16 "u" /* uint16_t */ +#define PRIu32 "u" /* uint32_t */ +#define PRIu64 "llu" /* uint64_t */ +#define PRIuLEAST8 "u" /* uint_least8_t */ +#define PRIuLEAST16 "u" /* uint_least16_t */ +#define PRIuLEAST32 "u" /* uint_least32_t */ +#define PRIuLEAST64 "llu" /* uint_least64_t */ +#define PRIuFAST8 "u" /* uint_fast8_t */ +#define PRIuFAST16 "u" /* uint_fast16_t */ +#define PRIuFAST32 "u" /* uint_fast32_t */ +#define PRIuFAST64 "llu" /* uint_fast64_t */ +#define PRIuMAX "ju" /* uintmax_t */ +#define PRIuPTR "u" /* uintptr_t */ + +#define PRIx8 "x" /* uint8_t */ +#define PRIx16 "x" /* uint16_t */ +#define PRIx32 "x" /* uint32_t */ +#define PRIx64 "llx" /* uint64_t */ +#define PRIxLEAST8 "x" /* uint_least8_t */ +#define PRIxLEAST16 "x" /* uint_least16_t */ +#define PRIxLEAST32 "x" /* uint_least32_t */ +#define PRIxLEAST64 "llx" /* uint_least64_t */ +#define PRIxFAST8 "x" /* uint_fast8_t */ +#define PRIxFAST16 "x" /* uint_fast16_t */ +#define PRIxFAST32 "x" /* uint_fast32_t */ +#define PRIxFAST64 "llx" /* uint_fast64_t */ +#define PRIxMAX "jx" /* uintmax_t */ +#define PRIxPTR "x" /* uintptr_t */ + +#define PRIX8 "X" /* uint8_t */ +#define PRIX16 "X" /* uint16_t */ +#define PRIX32 "X" /* uint32_t */ +#define PRIX64 "llX" /* uint64_t */ +#define PRIXLEAST8 "X" /* uint_least8_t */ +#define PRIXLEAST16 "X" /* uint_least16_t */ +#define PRIXLEAST32 "X" /* uint_least32_t */ +#define PRIXLEAST64 "llX" /* uint_least64_t */ +#define PRIXFAST8 "X" /* uint_fast8_t */ +#define PRIXFAST16 "X" /* uint_fast16_t */ +#define PRIXFAST32 "X" /* uint_fast32_t */ +#define PRIXFAST64 "llX" /* uint_fast64_t */ +#define PRIXMAX "jX" /* uintmax_t */ +#define PRIXPTR "X" /* uintptr_t */ + +/* fscanf(3) macros for signed integers. */ + +#define SCNd8 "hhd" /* int8_t */ +#define SCNd16 "hd" /* int16_t */ +#define SCNd32 "d" /* int32_t */ +#define SCNd64 "lld" /* int64_t */ +#define SCNdLEAST8 "hhd" /* int_least8_t */ +#define SCNdLEAST16 "hd" /* int_least16_t */ +#define SCNdLEAST32 "d" /* int_least32_t */ +#define SCNdLEAST64 "lld" /* int_least64_t */ +#define SCNdFAST8 "d" /* int_fast8_t */ +#define SCNdFAST16 "d" /* int_fast16_t */ +#define SCNdFAST32 "d" /* int_fast32_t */ +#define SCNdFAST64 "lld" /* int_fast64_t */ +#define SCNdMAX "jd" /* intmax_t */ +#define SCNdPTR "d" /* intptr_t */ + +#define SCNi8 "hhi" /* int8_t */ +#define SCNi16 "hi" /* int16_t */ +#define SCNi32 "i" /* int32_t */ +#define SCNi64 "lli" /* int64_t */ +#define SCNiLEAST8 "hhi" /* int_least8_t */ +#define SCNiLEAST16 "hi" /* int_least16_t */ +#define SCNiLEAST32 "i" /* int_least32_t */ +#define SCNiLEAST64 "lli" /* int_least64_t */ +#define SCNiFAST8 "i" /* int_fast8_t */ +#define SCNiFAST16 "i" /* int_fast16_t */ +#define SCNiFAST32 "i" /* int_fast32_t */ +#define SCNiFAST64 "lli" /* int_fast64_t */ +#define SCNiMAX "ji" /* intmax_t */ +#define SCNiPTR "i" /* intptr_t */ + +/* fscanf(3) macros for unsigned integers. */ + +#define SCNo8 "hho" /* uint8_t */ +#define SCNo16 "ho" /* uint16_t */ +#define SCNo32 "o" /* uint32_t */ +#define SCNo64 "llo" /* uint64_t */ +#define SCNoLEAST8 "hho" /* uint_least8_t */ +#define SCNoLEAST16 "ho" /* uint_least16_t */ +#define SCNoLEAST32 "o" /* uint_least32_t */ +#define SCNoLEAST64 "llo" /* uint_least64_t */ +#define SCNoFAST8 "o" /* uint_fast8_t */ +#define SCNoFAST16 "o" /* uint_fast16_t */ +#define SCNoFAST32 "o" /* uint_fast32_t */ +#define SCNoFAST64 "llo" /* uint_fast64_t */ +#define SCNoMAX "jo" /* uintmax_t */ +#define SCNoPTR "o" /* uintptr_t */ + +#define SCNu8 "hhu" /* uint8_t */ +#define SCNu16 "hu" /* uint16_t */ +#define SCNu32 "u" /* uint32_t */ +#define SCNu64 "llu" /* uint64_t */ +#define SCNuLEAST8 "hhu" /* uint_least8_t */ +#define SCNuLEAST16 "hu" /* uint_least16_t */ +#define SCNuLEAST32 "u" /* uint_least32_t */ +#define SCNuLEAST64 "llu" /* uint_least64_t */ +#define SCNuFAST8 "u" /* uint_fast8_t */ +#define SCNuFAST16 "u" /* uint_fast16_t */ +#define SCNuFAST32 "u" /* uint_fast32_t */ +#define SCNuFAST64 "llu" /* uint_fast64_t */ +#define SCNuMAX "ju" /* uintmax_t */ +#define SCNuPTR "u" /* uintptr_t */ + +#define SCNx8 "hhx" /* uint8_t */ +#define SCNx16 "hx" /* uint16_t */ +#define SCNx32 "x" /* uint32_t */ +#define SCNx64 "llx" /* uint64_t */ +#define SCNxLEAST8 "hhx" /* uint_least8_t */ +#define SCNxLEAST16 "hx" /* uint_least16_t */ +#define SCNxLEAST32 "x" /* uint_least32_t */ +#define SCNxLEAST64 "llx" /* uint_least64_t */ +#define SCNxFAST8 "x" /* uint_fast8_t */ +#define SCNxFAST16 "x" /* uint_fast16_t */ +#define SCNxFAST32 "x" /* uint_fast32_t */ +#define SCNxFAST64 "llx" /* uint_fast64_t */ +#define SCNxMAX "jx" /* uintmax_t */ +#define SCNxPTR "x" /* uintptr_t */ + +#endif /* !_MACHINE_INTTYPES_H_ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/i386_limits.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/i386_limits.h new file mode 100644 index 0000000000..d827bda99d --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/i386_limits.h @@ -0,0 +1,107 @@ +/*- + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)limits.h 8.3 (Berkeley) 1/4/94 + * $FreeBSD: stable/8/sys/i386/include/_limits.h 199583 2009-11-20 15:27:52Z jhb $ + */ + +/** + * Modified for XMHF. + */ + +#ifndef _MACHINE__LIMITS_H_ +#define _MACHINE__LIMITS_H_ + +/* + * According to ANSI (section 2.2.4.2), the values below must be usable by + * #if preprocessing directives. Additionally, the expression must have the + * same type as would an expression that is an object of the corresponding + * type converted according to the integral promotions. The subtraction for + * INT_MIN, etc., is so the value is not unsigned; e.g., 0x80000000 is an + * unsigned int for 32-bit two's complement ANSI compilers (section 3.1.3.2). + * These numbers are for the default configuration of gcc. They work for + * some other compilers as well, but this should not be depended on. + */ + +#define __CHAR_BIT 8 /* number of bits in a char */ + +#define __SCHAR_MAX 0x7f /* max value for a signed char */ +#define __SCHAR_MIN (-0x7f - 1) /* min value for a signed char */ + +#define __UCHAR_MAX 0xff /* max value for an unsigned char */ + +#define __USHRT_MAX 0xffff /* max value for an unsigned short */ +#define __SHRT_MAX 0x7fff /* max value for a short */ +#define __SHRT_MIN (-0x7fff - 1) /* min value for a short */ + +#define __UINT_MAX 0xffffffffU /* max value for an unsigned int */ +#define __INT_MAX 0x7fffffff /* max value for an int */ +#define __INT_MIN (-0x7fffffff - 1) /* min value for an int */ + +/* Bad hack for gcc configured to give 64-bit longs. */ +#ifdef _LARGE_LONG +#define __ULONG_MAX 0xffffffffffffffffUL +#define __LONG_MAX 0x7fffffffffffffffL +#define __LONG_MIN (-0x7fffffffffffffffL - 1) +#else +#define __ULONG_MAX 0xffffffffUL /* max value for an unsigned long */ +#define __LONG_MAX 0x7fffffffL /* max value for a long */ +#define __LONG_MIN (-0x7fffffffL - 1) /* min value for a long */ +#endif + + /* max value for an unsigned long long */ +#define __ULLONG_MAX 0xffffffffffffffffULL +#define __LLONG_MAX 0x7fffffffffffffffLL /* max value for a long long */ +#define __LLONG_MIN (-0x7fffffffffffffffLL - 1) /* min for a long long */ + +#define __SSIZE_MAX __INT_MAX /* max value for a ssize_t */ + +#define __SIZE_T_MAX __UINT_MAX /* max value for a size_t */ + +#define __OFF_MAX __LLONG_MAX /* max value for an off_t */ +#define __OFF_MIN __LLONG_MIN /* min value for an off_t */ + +/* Quads and long longs are the same size. Ensure they stay in sync. */ +#define __UQUAD_MAX __ULLONG_MAX /* max value for a uquad_t */ +#define __QUAD_MAX __LLONG_MAX /* max value for a quad_t */ +#define __QUAD_MIN __LLONG_MIN /* min value for a quad_t */ + +#ifdef _LARGE_LONG +#define __LONG_BIT 64 +#else +#define __LONG_BIT 32 +#endif +#define __WORD_BIT 32 + +/* + * Minimum signal stack size. The current signal frame + * for i386 is 408 bytes large. + */ +#define __MINSIGSTKSZ (512 * 4) + +#endif /* !_MACHINE__LIMITS_H_ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/i386_stdint.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/i386_stdint.h new file mode 100644 index 0000000000..eaf31d11d0 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/i386_stdint.h @@ -0,0 +1,175 @@ +/*- + * Copyright (c) 2001, 2002 Mike Barcroft + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Klaus Klein. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: stable/8/sys/i386/include/_stdint.h 199583 2009-11-20 15:27:52Z jhb $ + */ + +/** + * Modified for XMHF. + */ + +#ifndef _MACHINE__STDINT_H_ +#define _MACHINE__STDINT_H_ + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) + +#define INT8_C(c) (c) +#define INT16_C(c) (c) +#define INT32_C(c) (c) +#define INT64_C(c) (c ## LL) + +#define UINT8_C(c) (c) +#define UINT16_C(c) (c) +#define UINT32_C(c) (c ## U) +#define UINT64_C(c) (c ## ULL) + +#define INTMAX_C(c) (c ## LL) +#define UINTMAX_C(c) (c ## ULL) + +#endif /* !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) */ + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) + +/* + * ISO/IEC 9899:1999 + * 7.18.2.1 Limits of exact-width integer types + */ +/* Minimum values of exact-width signed integer types. */ +#define INT8_MIN (-0x7f-1) +#define INT16_MIN (-0x7fff-1) +#define INT32_MIN (-0x7fffffff-1) +#define INT64_MIN (-0x7fffffffffffffffLL-1) + +/* Maximum values of exact-width signed integer types. */ +#define INT8_MAX 0x7f +#define INT16_MAX 0x7fff +#define INT32_MAX 0x7fffffff +#define INT64_MAX 0x7fffffffffffffffLL + +/* Maximum values of exact-width unsigned integer types. */ +#define UINT8_MAX 0xff +#define UINT16_MAX 0xffff +#define UINT32_MAX 0xffffffffU +#define UINT64_MAX 0xffffffffffffffffULL + +/* + * ISO/IEC 9899:1999 + * 7.18.2.2 Limits of minimum-width integer types + */ +/* Minimum values of minimum-width signed integer types. */ +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST64_MIN INT64_MIN + +/* Maximum values of minimum-width signed integer types. */ +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MAX INT64_MAX + +/* Maximum values of minimum-width unsigned integer types. */ +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +/* + * ISO/IEC 9899:1999 + * 7.18.2.3 Limits of fastest minimum-width integer types + */ +/* Minimum values of fastest minimum-width signed integer types. */ +#define INT_FAST8_MIN INT32_MIN +#define INT_FAST16_MIN INT32_MIN +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST64_MIN INT64_MIN + +/* Maximum values of fastest minimum-width signed integer types. */ +#define INT_FAST8_MAX INT32_MAX +#define INT_FAST16_MAX INT32_MAX +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MAX INT64_MAX + +/* Maximum values of fastest minimum-width unsigned integer types. */ +#define UINT_FAST8_MAX UINT32_MAX +#define UINT_FAST16_MAX UINT32_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +/* + * ISO/IEC 9899:1999 + * 7.18.2.4 Limits of integer types capable of holding object pointers + */ +#define INTPTR_MIN INT32_MIN +#define INTPTR_MAX INT32_MAX +#define UINTPTR_MAX UINT32_MAX + +/* + * ISO/IEC 9899:1999 + * 7.18.2.5 Limits of greatest-width integer types + */ +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +/* + * ISO/IEC 9899:1999 + * 7.18.3 Limits of other integer types + */ +/* Limits of ptrdiff_t. */ +#define PTRDIFF_MIN INT32_MIN +#define PTRDIFF_MAX INT32_MAX + +/* Limits of sig_atomic_t. */ +#define SIG_ATOMIC_MIN INT32_MIN +#define SIG_ATOMIC_MAX INT32_MAX + +/* Limit of size_t. */ +#define SIZE_MAX UINT32_MAX + +#ifndef WCHAR_MIN /* Also possibly defined in */ +/* Limits of wchar_t. */ +#define WCHAR_MIN INT32_MIN +#define WCHAR_MAX INT32_MAX +#endif + +/* Limits of wint_t. */ +#define WINT_MIN INT32_MIN +#define WINT_MAX INT32_MAX + +#endif /* !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) */ + +#endif /* !_MACHINE__STDINT_H_ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/i386_types.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/i386_types.h new file mode 100644 index 0000000000..9fa4f258e0 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/i386_types.h @@ -0,0 +1,108 @@ +/*- + * Copyright (c) 2002 Mike Barcroft + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * From: @(#)ansi.h 8.2 (Berkeley) 1/4/94 + * From: @(#)types.h 8.3 (Berkeley) 1/5/94 + * $FreeBSD: stable/8/sys/i386/include/_types.h 199583 2009-11-20 15:27:52Z jhb $ + */ + +/** + * Modified for XMHF to remove cdefs.h requirement. + */ + +#ifndef _MACHINE__TYPES_H_ +#define _MACHINE__TYPES_H_ + +#define __NO_STRICT_ALIGNMENT + +/* number of bits per byte */ +#define NBBY 8 + +/* + * Basic types upon which most other types are built. + */ +typedef __signed char __int8_t; +typedef unsigned char __uint8_t; +typedef short __int16_t; +typedef unsigned short __uint16_t; +typedef int __int32_t; +typedef unsigned int __uint32_t; + +/* LONGLONG */ +typedef long long __int64_t; +/* LONGLONG */ +typedef unsigned long long __uint64_t; + +/* + * Standard type definitions. + */ +typedef unsigned long __clock_t; /* clock()... */ +typedef unsigned int __cpumask_t; +typedef __int32_t __critical_t; +typedef long double __double_t; +typedef long double __float_t; +typedef __int32_t __intfptr_t; +typedef __int64_t __intmax_t; +typedef __int32_t __intptr_t; +typedef __int32_t __int_fast8_t; +typedef __int32_t __int_fast16_t; +typedef __int32_t __int_fast32_t; +typedef __int64_t __int_fast64_t; +typedef __int8_t __int_least8_t; +typedef __int16_t __int_least16_t; +typedef __int32_t __int_least32_t; +typedef __int64_t __int_least64_t; +typedef __int32_t __ptrdiff_t; /* ptr1 - ptr2 */ +typedef __int32_t __register_t; +typedef __int32_t __segsz_t; /* segment size (in pages) */ +typedef __uint32_t __size_t; /* sizeof() */ +typedef __int32_t __ssize_t; /* byte count or error */ +typedef __int32_t __time_t; /* time()... */ +typedef __uint32_t __uintfptr_t; +typedef __uint64_t __uintmax_t; +typedef __uint32_t __uintptr_t; +typedef __uint32_t __uint_fast8_t; +typedef __uint32_t __uint_fast16_t; +typedef __uint32_t __uint_fast32_t; +typedef __uint64_t __uint_fast64_t; +typedef __uint8_t __uint_least8_t; +typedef __uint16_t __uint_least16_t; +typedef __uint32_t __uint_least32_t; +typedef __uint64_t __uint_least64_t; +typedef __uint32_t __u_register_t; + +typedef __uint32_t off_t; + +/* varargs stuff removed */ + +#endif /* !_MACHINE__TYPES_H_ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/libkern.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/libkern.h new file mode 100644 index 0000000000..6df407f2fc --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/libkern.h @@ -0,0 +1,193 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)libkern.h 8.1 (Berkeley) 6/10/93 + * $FreeBSD: src/sys/sys/libkern.h,v 1.60.2.1.6.1 2010/12/21 17:09:25 kensmith Exp $ + */ + +/** + * Modified for XMHF. + */ + +#ifndef _SYS_LIBKERN_H_ +#define _SYS_LIBKERN_H_ + +#include +#include +#ifdef _KERNEL +#include +#endif + +#ifndef LIBKERN_INLINE +#define LIBKERN_INLINE static __inline +#define LIBKERN_BODY +#endif + +/* BCD conversions. */ +extern u_char const bcd2bin_data[]; +extern u_char const bin2bcd_data[]; +extern char const hex2ascii_data[]; + +#define bcd2bin(bcd) (bcd2bin_data[bcd]) +#define bin2bcd(bin) (bin2bcd_data[bin]) +#define hex2ascii(hex) (hex2ascii_data[hex]) + +static __inline int imax(int a, int b) { return (a > b ? a : b); } +static __inline int imin(int a, int b) { return (a < b ? a : b); } +static __inline long lmax(long a, long b) { return (a > b ? a : b); } +static __inline long lmin(long a, long b) { return (a < b ? a : b); } +static __inline u_int max(u_int a, u_int b) { return (a > b ? a : b); } +static __inline u_int min(u_int a, u_int b) { return (a < b ? a : b); } +static __inline quad_t qmax(quad_t a, quad_t b) { return (a > b ? a : b); } +static __inline quad_t qmin(quad_t a, quad_t b) { return (a < b ? a : b); } +static __inline u_long ulmax(u_long a, u_long b) { return (a > b ? a : b); } +static __inline u_long ulmin(u_long a, u_long b) { return (a < b ? a : b); } +/* static __inline off_t omax(off_t a, off_t b) { return (a > b ? a : b); } */ +/* static __inline off_t omin(off_t a, off_t b) { return (a < b ? a : b); } */ + +static __inline int abs(int a) { return (a < 0 ? -a : a); } +static __inline long labs(long a) { return (a < 0 ? -a : a); } +static __inline quad_t qabs(quad_t a) { return (a < 0 ? -a : a); } + +/* Prototypes for non-quad routines. */ +struct malloc_type; +uint32_t arc4random(void); +void arc4rand(void *ptr, u_int len, int reseed); +int bcmp(const void *, const void *, size_t); +void *bsearch(const void *, const void *, size_t, + size_t, int (*)(const void *, const void *)); +#ifndef HAVE_INLINE_FFS +int ffs(int); +#endif +#ifndef HAVE_INLINE_FFSL +int ffsl(long); +#endif +#ifndef HAVE_INLINE_FLS +int fls(int); +#endif +#ifndef HAVE_INLINE_FLSL +int flsl(long); +#endif +int fnmatch(const char *, const char *, int); +/* void gets(char *, size_t, int); */ +int locc(int, char *, u_int); +int memcmp(const void *b1, const void *b2, size_t len); +void qsort(void *base, size_t nmemb, size_t size, + int (*compar)(const void *, const void *)); +void qsort_r(void *base, size_t nmemb, size_t size, void *thunk, + int (*compar)(void *, const void *, const void *)); +u_long random(void); +char *index(const char *, int); +char *rindex(const char *, int); +int scanc(u_int, const u_char *, const u_char *, int); +int skpc(int, int, char *); +void srandom(u_long); +int strcasecmp(const char *, const char *); +char *strcat(char * __restrict, const char * __restrict); +int strcmp(const char *, const char *); +char *strcpy(char * __restrict, const char * __restrict); +size_t strcspn(const char * __restrict, const char * __restrict) __pure; +char *strdup(const char *__restrict, struct malloc_type *); +size_t strlcat(char *, const char *, size_t); +size_t strlcpy(char *, const char *, size_t); +size_t strlen(const char *); +int strncasecmp(const char *, const char *, size_t); +int strncmp(const char *, const char *, size_t); +char *strncpy(char * __restrict, const char * __restrict, size_t); +char *strsep(char **, const char *delim); +size_t strspn(const char *, const char *); +char *strstr(const char *, const char *); +int strvalid(const char *, size_t); + +extern uint32_t crc32_tab[]; + +static __inline uint32_t +crc32_raw(const void *buf, size_t size, uint32_t crc) +{ + const uint8_t *p = (const uint8_t *)buf; + + while (size--) + crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8); + return (crc); +} + +static __inline uint32_t +crc32(const void *buf, size_t size) +{ + uint32_t crc; + + crc = crc32_raw(buf, size, ~0U); + return (crc ^ ~0U); +} + +uint32_t +calculate_crc32c(uint32_t crc32c, const unsigned char *buffer, + unsigned int length); + + +/* LIBKERN_INLINE void *memset(void *, int, size_t); */ +/* #ifdef LIBKERN_BODY */ +/* LIBKERN_INLINE void * */ +/* memset(void *b, int c, size_t len) */ +/* { */ +/* char *bb; */ + +/* if (c == 0) */ +/* bzero(b, len); */ +/* else */ +/* for (bb = (char *)b; len--; ) */ +/* *bb++ = c; */ +/* return (b); */ +/* } */ +/* #endif */ + +static __inline char * +strchr(const char *p, int ch) +{ + return (index(p, ch)); +} + +static __inline char * +strrchr(const char *p, int ch) +{ + return (rindex(p, ch)); +} + +/* fnmatch() return values. */ +#define FNM_NOMATCH 1 /* Match failed. */ + +/* fnmatch() flags. */ +#define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */ +#define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */ +#define FNM_PERIOD 0x04 /* Period must be matched by period. */ +#define FNM_LEADING_DIR 0x08 /* Ignore / after Imatch. */ +#define FNM_CASEFOLD 0x10 /* Case insensitive search. */ +#define FNM_IGNORECASE FNM_CASEFOLD +#define FNM_FILE_NAME FNM_PATHNAME + +#endif /* !_SYS_LIBKERN_H_ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/limits.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/limits.h new file mode 100644 index 0000000000..bcc335bfa9 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/limits.h @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)limits.h 8.3 (Berkeley) 1/4/94 + * $FreeBSD: stable/8/sys/i386/include/limits.h 199583 2009-11-20 15:27:52Z jhb $ + */ + +/** + * Modified for XMHF. + */ + +#ifndef _MACHINE_LIMITS_H_ +#define _MACHINE_LIMITS_H_ + +#ifdef __AMD64__ +#include +#elif defined(__I386__) +#include +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + +#endif /* !_MACHINE_LIMITS_H_ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/types.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/types.h new file mode 100644 index 0000000000..f38a1513ab --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/include/sys/types.h @@ -0,0 +1,150 @@ +/*- + * Copyright (c) 1982, 1986, 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)types.h 8.6 (Berkeley) 2/19/95 + * $FreeBSD: stable/8/sys/sys/types.h 199583 2009-11-20 15:27:52Z jhb $ + */ + +/** + * Modified for XMHF. + */ + +#ifndef _SYS_TYPES_H_ +#define _SYS_TYPES_H_ + +/* Machine type dependent parameters. */ +#ifdef __AMD64__ +#include +#include +#elif defined(__I386__) +#include +#include +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned int u_int; +typedef unsigned long u_long; +typedef unsigned short ushort; /* Sys V compatibility */ +typedef unsigned int uint; /* Sys V compatibility */ + +/* + * XXX POSIX sized integrals that should appear only in . + */ +#ifndef _INT8_T_DECLARED +typedef __int8_t int8_t; +#define _INT8_T_DECLARED +#endif + +#ifndef _INT16_T_DECLARED +typedef __int16_t int16_t; +#define _INT16_T_DECLARED +#endif + +#ifndef _INT32_T_DECLARED +typedef __int32_t int32_t; +#define _INT32_T_DECLARED +#endif + +#ifndef _INT64_T_DECLARED +typedef __int64_t int64_t; +#define _INT64_T_DECLARED +#endif + +#ifndef _UINT8_T_DECLARED +typedef __uint8_t uint8_t; +#define _UINT8_T_DECLARED +#endif + +#ifndef _UINT16_T_DECLARED +typedef __uint16_t uint16_t; +#define _UINT16_T_DECLARED +#endif + +#ifndef _UINT32_T_DECLARED +typedef __uint32_t uint32_t; +#define _UINT32_T_DECLARED +#endif + +#ifndef _UINT64_T_DECLARED +typedef __uint64_t uint64_t; +#define _UINT64_T_DECLARED +#endif + +#ifndef _INTPTR_T_DECLARED +typedef __intptr_t intptr_t; +typedef __uintptr_t uintptr_t; +#define _INTPTR_T_DECLARED +#endif + +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +#ifndef _ULONG_T_DECLARED +typedef size_t ulong_t; +#define _ULONG_T_DECLARED +#endif + +#ifndef _SSIZE_T_DECLARED +typedef __ssize_t ssize_t; +#define _SSIZE_T_DECLARED +#endif + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; + +typedef int64_t s64; +typedef int32_t s32; +typedef int16_t s16; +typedef int8_t s8; + +typedef __uint8_t u_int8_t; /* unsigned integrals (deprecated) */ +typedef __uint16_t u_int16_t; +typedef __uint32_t u_int32_t; +typedef __uint64_t u_int64_t; + +typedef __uint64_t u_quad_t; /* quads (deprecated) */ +typedef __int64_t quad_t; +typedef quad_t * qaddr_t; + +typedef char * caddr_t; /* core address */ +typedef __const char * c_caddr_t; /* core address, pointer to const */ +typedef __volatile char *v_caddr_t; /* core address, pointer to volatile */ + +#endif /* !_SYS_TYPES_H_ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/libemhfc.pc b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/libemhfc.pc new file mode 100644 index 0000000000..acb428a74a --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/libemhfc.pc @@ -0,0 +1,11 @@ +prefix=/usr/local +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +Name: libemhfc +Description: Extremely barebones libc replacement +Requires: +Version: 0.1 +Libs: -L${libdir} -lemhfc +Cflags: diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/qsort.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/qsort.c new file mode 100644 index 0000000000..7122459573 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/qsort.c @@ -0,0 +1,193 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* #include */ +/* __FBSDID("$FreeBSD: src/sys/libkern/qsort.c,v 1.15.30.1.6.1 2010/12/21 17:09:25 kensmith Exp $"); */ + +/** + * Modified for XMHF. + */ + +/* #include */ +/* #include */ + +#include +#include + +#ifdef I_AM_QSORT_R +typedef int cmp_t(void *, const void *, const void *); +#else +typedef int cmp_t(const void *, const void *); +#endif +static __inline char *med3(char *, char *, char *, cmp_t *, void *); +static __inline void swapfunc(char *, char *, int, int); + +#define min(a, b) (a) < (b) ? (a) : (b) + +/* + * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". + */ +#define swapcode(TYPE, parmi, parmj, n) { \ + long i = (n) / sizeof (TYPE); \ + register TYPE *pi = (TYPE *) (parmi); \ + register TYPE *pj = (TYPE *) (parmj); \ + do { \ + register TYPE t = *pi; \ + *pi++ = *pj; \ + *pj++ = t; \ + } while (--i > 0); \ +} + +#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ + es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; + +static __inline void +swapfunc(char *a, char *b, int n, int swaptype) +{ + if(swaptype <= 1) + swapcode(long, a, b, n) + else + swapcode(char, a, b, n) +} + +#define swap(a, b) \ + if (swaptype == 0) { \ + long t = *(long *)(a); \ + *(long *)(a) = *(long *)(b); \ + *(long *)(b) = t; \ + } else \ + swapfunc(a, b, es, swaptype) + +#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) + +#ifdef I_AM_QSORT_R +#define CMP(t, x, y) (cmp((t), (x), (y))) +#else +#define CMP(t, x, y) (cmp((x), (y))) +#endif + +static __inline char * +med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk +#ifndef I_AM_QSORT_R +__unused +#endif +) +{ + return CMP(thunk, a, b) < 0 ? + (CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a )) + :(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c )); +} + +#ifdef I_AM_QSORT_R +void +qsort_r(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp) +#else +#define thunk NULL +void +qsort(void *a, size_t n, size_t es, cmp_t *cmp) +#endif +{ + char *pa, *pb, *pc, *pd, *pl, *pm, *pn; + int d, r, swaptype, swap_cnt; + +loop: SWAPINIT(a, es); + swap_cnt = 0; + if (n < 7) { + for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) + for (pl = pm; pl > (char *)a && CMP(thunk, pl - es, pl) > 0; + pl -= es) + swap(pl, pl - es); + return; + } + pm = (char *)a + (n / 2) * es; + if (n > 7) { + pl = a; + pn = (char *)a + (n - 1) * es; + if (n > 40) { + d = (n / 8) * es; + pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk); + pm = med3(pm - d, pm, pm + d, cmp, thunk); + pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk); + } + pm = med3(pl, pm, pn, cmp, thunk); + } + swap(a, pm); + pa = pb = (char *)a + es; + + pc = pd = (char *)a + (n - 1) * es; + for (;;) { + while (pb <= pc && (r = CMP(thunk, pb, a)) <= 0) { + if (r == 0) { + swap_cnt = 1; + swap(pa, pb); + pa += es; + } + pb += es; + } + while (pb <= pc && (r = CMP(thunk, pc, a)) >= 0) { + if (r == 0) { + swap_cnt = 1; + swap(pc, pd); + pd -= es; + } + pc -= es; + } + if (pb > pc) + break; + swap(pb, pc); + swap_cnt = 1; + pb += es; + pc -= es; + } + if (swap_cnt == 0) { /* Switch to insertion sort */ + for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) + for (pl = pm; pl > (char *)a && CMP(thunk, pl - es, pl) > 0; + pl -= es) + swap(pl, pl - es); + return; + } + + pn = (char *)a + n * es; + r = min(pa - (char *)a, pb - pa); + vecswap(a, pb - r, r); + r = min(pd - pc, pn - pd - (ssize_t)es); + vecswap(pb, pn - r, r); + if ((r = pb - pa) > (ssize_t)es) +#ifdef I_AM_QSORT_R + qsort_r(a, r / es, es, thunk, cmp); +#else + qsort(a, r / es, es, cmp); +#endif + if ((r = pd - pc) > (ssize_t)es) { + /* Iterate rather than recurse to save stack space */ + a = pn - r; + n = r / es; + goto loop; + } +} diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/strchr.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/strchr.c new file mode 100644 index 0000000000..167080ee25 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/strchr.c @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* + * From: FreeBSD sys/libkern/strchr.c + */ +/** + * Modified for XMHF. + */ + +#include +#include + +char * +strchr(const char *p, int ch) +{ + union { + const char *cp; + char *p; + } u; + + u.cp = p; + for (;; ++u.p) { + if (*u.p == ch) + return(u.p); + if (*u.p == '\0') + return(NULL); + } + /* NOTREACHED */ +} diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/strcmp.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/strcmp.c new file mode 100644 index 0000000000..c4bad329bf --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/strcmp.c @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* + * From: FreeBSD sys/libkern/strcmp.c + */ +/** + * Modified for XMHF. + */ + +#include +#include +/* + * Compare strings. + */ +int strcmp(s1, s2) + register const char *s1, *s2; +{ + while (*s1 == *s2++) + if (*s1++ == 0) + return (0); + return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1)); +} diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/string.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/string.c new file mode 100644 index 0000000000..0a6381066e --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/string.c @@ -0,0 +1,109 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include +#include + +void *memmove(void *dst_void, const void *src_void, size_t length){ + char *dst = dst_void; + const char *src = src_void; + + if (src < dst && dst < src + length){ + // Have to copy backwards + src += length; + dst += length; + while (length--){ + *--dst = *--src; + } + }else{ + while (length--){ + *dst++ = *src++; + } + } + + return dst_void; +} + + +size_t strnlen(const char * s, size_t count){ + const char *sc; + + for (sc = s; count-- && *sc != '\0'; ++sc); + return (size_t)(sc - s); +} + +void *memcpy(void * to, const void * from, size_t n) +{ + size_t i; + for(i=0; i 0) + *st++ = (u8)c; + return str; +} + +#ifndef HAVE_MEMCMP +int +memcmp(const void *s1, const void *s2, size_t n) +{ + if (n != 0) { + const unsigned char *p1 = s1, *p2 = s2; + + do { + if (*p1++ != *p2++) + return (*--p1 - *--p2); + } while (--n != 0); + } + return (0); +} +#endif /* HAVE_MEMCMP */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/strlen.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/strlen.c new file mode 100644 index 0000000000..520a3c03d3 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/strlen.c @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* + * From: FreeBSD sys/libkern/strlen.c + */ +/** + * Modified for XMHF. + */ + +#include +#include + +size_t strlen(str) + const char *str; +{ + register const char *s; + + for (s = str; *s; ++s); + return(s - str); +} diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/strncmp.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/strncmp.c new file mode 100644 index 0000000000..7753cbb737 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/strncmp.c @@ -0,0 +1,95 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* $OpenBSD: strncmp.c,v 1.9 2004/11/28 07:23:41 mickey Exp $ */ + +/* + * Copyright (c) 1989 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* + * From: OpenBSD sys/libkern/strcmp.c + */ + +#include +#include +int +strncmp(const char *s1, const char *s2, size_t n) +{ + if (n == 0) + return (0); + do { + if (*s1 != *s2++) + return (*(const unsigned char *)s1 - *(const unsigned char *)--s2); + if (*s1++ == 0) + break; + } while (--n != 0); + return (0); +} diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/strncpy.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/strncpy.c new file mode 100644 index 0000000000..0b60a3cc29 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/strncpy.c @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* + * From: FreeBSD sys/libkern/strncpy.c + */ +/** + * Modified for XMHF. + */ + +#include +#include +/* + * Copy src to dst, truncating or null-padding to always copy n bytes. + * Return dst. + */ +char *strncpy(char * dst, const char * src, size_t n) +{ + if (n != 0) { + register char *d = dst; + register const char *s = src; + + do { + if ((*d++ = *s++) == 0) { + /* NUL pad the remaining n-1 bytes */ + while (--n != 0) + *d++ = 0; + break; + } + } while (--n != 0); + } + return (dst); +} diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/strtoul.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/strtoul.c new file mode 100644 index 0000000000..f26ef7c60e --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/strtoul.c @@ -0,0 +1,108 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * From: @(#)strtoul.c 8.1 (Berkeley) 6/4/93 + */ + +/* $FreeBSD: src/sys/libkern/strtoul.c,v 1.6.32.1 2010/02/10 00:26:20 kensmith Exp $ */ + +/** + * Modified for XMHF. + */ + +#include +#include +#include + +#ifndef ULONG_MAX +#define ULONG_MAX 0xFFFFFFFFUL +#endif + +/* + * Convert a string to an unsigned long integer. + * + * Ignores `locale' stuff. Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +unsigned long strtoul(const char *nptr, const char **endptr, unsigned int base) +{ + const char *s = nptr; + unsigned long acc; + unsigned char c; + unsigned long cutoff; + int neg = 0, any, cutlim; + + /* + * See strtol for comments as to the logic used. + */ + do { + c = *s++; + } while (isspace(c)); + if (c == '-') { + neg = 1; + c = *s++; + } else if (c == '+') + c = *s++; + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; + cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; + for (acc = 0, any = 0;; c = *s++) { + if (isdigit(c)) + c -= '0'; + else if (isalpha(c)) + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = ULONG_MAX; + } else if (neg) + acc = -acc; + if (endptr != 0) + *((const char **)endptr) = any ? s - 1 : nptr; + return (acc); +} diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfc/subr_prf.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/subr_prf.c new file mode 100644 index 0000000000..5860af2d87 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfc/subr_prf.c @@ -0,0 +1,1067 @@ +/*- + * Copyright (c) 1986, 1988, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94 + */ + +/* #include */ +/* __FBSDID("$FreeBSD: src/sys/kern/subr_prf.c,v 1.138.2.2.2.1 2010/12/21 17:09:25 kensmith Exp $"); */ + +/** + * Modified for XMHF. + */ + +/* #include "opt_ddb.h" */ +/* #include "opt_printf.h" */ + +/* #include */ +/* #include */ +/* #include */ +/* #include */ +/* #include */ +/* #include */ +/* #include */ +/* #include */ +/* #include */ +/* #include */ +/* #include */ +/* #include */ +/* #include */ +/* #include */ +/* #include */ +/* #include */ +/* #include */ +/* #include */ + +/* #ifdef DDB */ +/* #include */ +/* #endif */ +#include +#include +#include +#include + +#include + +/* + * Note that stdarg.h and the ANSI style va_start macro is used for both + * ANSI and traditional C compilers. + */ +/* #include */ +#include + +#define TOCONS 0x01 +#define TOTTY 0x02 +#define TOLOG 0x04 + +/* Max number conversion buffer length: a u_quad_t in base 2, plus NUL byte. */ +#define MAXNBUF (sizeof(intmax_t) * NBBY + 1) + +/* struct putchar_arg { */ +/* int flags; */ +/* int pri; */ +/* struct tty *tty; */ +/* char *p_bufr; */ +/* size_t n_bufr; */ +/* char *p_next; */ +/* size_t remain; */ +/* }; */ + +#include "emhfc_callbacks.h" + +struct snprintf_arg { + char *str; + size_t remain; +}; + +extern int log_open; + +/* static void msglogchar(int c, int pri); */ +/* static void putchar(int ch, void *arg); */ +static char *ksprintn(char *nbuf, uintmax_t num, int base, int *len, int upper); +static void snprintf_func(int ch, void *arg); +static int +kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap); + +/* static int msgbufmapped; /\* Set when safe to use msgbuf *\/ */ +/* int msgbuftrigger; */ + +/* static int log_console_output = 1; */ +/* TUNABLE_INT("kern.log_console_output", &log_console_output); */ +/* SYSCTL_INT(_kern, OID_AUTO, log_console_output, CTLFLAG_RW, */ +/* &log_console_output, 0, "Duplicate console output to the syslog."); */ + +/* static int always_console_output = 0; */ +/* TUNABLE_INT("kern.always_console_output", &always_console_output); */ +/* SYSCTL_INT(_kern, OID_AUTO, always_console_output, CTLFLAG_RW, */ +/* &always_console_output, 0, "Always output to console despite TIOCCONS."); */ + +/* + * Warn that a system table is full. + */ +/* void */ +/* tablefull(const char *tab) */ +/* { */ + +/* log(LOG_ERR, "%s: table is full\n", tab); */ +/* } */ + +/* + * Uprintf prints to the controlling terminal for the current process. + */ +/* int */ +/* uprintf(const char *fmt, ...) */ +/* { */ +/* va_list ap; */ +/* struct putchar_arg pca; */ +/* struct proc *p; */ +/* struct thread *td; */ +/* int retval; */ + +/* td = curthread; */ +/* if (TD_IS_IDLETHREAD(td)) */ +/* return (0); */ + +/* sx_slock(&proctree_lock); */ +/* p = td->td_proc; */ +/* PROC_LOCK(p); */ +/* if ((p->p_flag & P_CONTROLT) == 0) { */ +/* PROC_UNLOCK(p); */ +/* retval = 0; */ +/* goto out; */ +/* } */ +/* SESS_LOCK(p->p_session); */ +/* pca.tty = p->p_session->s_ttyp; */ +/* SESS_UNLOCK(p->p_session); */ +/* PROC_UNLOCK(p); */ +/* if (pca.tty == NULL) { */ +/* retval = 0; */ +/* goto out; */ +/* } */ +/* pca.flags = TOTTY; */ +/* va_start(ap, fmt); */ +/* tty_lock(pca.tty); */ +/* retval = kvprintf(fmt, putchar, &pca, 10, ap); */ +/* tty_unlock(pca.tty); */ +/* va_end(ap); */ +/* out: */ +/* sx_sunlock(&proctree_lock); */ +/* return (retval); */ +/* } */ + +/* + * tprintf prints on the controlling terminal associated with the given + * session, possibly to the log as well. + */ +/* void */ +/* tprintf(struct proc *p, int pri, const char *fmt, ...) */ +/* { */ +/* struct tty *tp = NULL; */ +/* int flags = 0; */ +/* va_list ap; */ +/* struct putchar_arg pca; */ +/* struct session *sess = NULL; */ + +/* sx_slock(&proctree_lock); */ +/* if (pri != -1) */ +/* flags |= TOLOG; */ +/* if (p != NULL) { */ +/* PROC_LOCK(p); */ +/* if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) { */ +/* sess = p->p_session; */ +/* sess_hold(sess); */ +/* PROC_UNLOCK(p); */ +/* tp = sess->s_ttyp; */ +/* if (tp != NULL && tty_checkoutq(tp)) */ +/* flags |= TOTTY; */ +/* else */ +/* tp = NULL; */ +/* } else */ +/* PROC_UNLOCK(p); */ +/* } */ +/* pca.pri = pri; */ +/* pca.tty = tp; */ +/* pca.flags = flags; */ +/* va_start(ap, fmt); */ +/* if (pca.tty != NULL) */ +/* tty_lock(pca.tty); */ +/* kvprintf(fmt, putchar, &pca, 10, ap); */ +/* if (pca.tty != NULL) */ +/* tty_unlock(pca.tty); */ +/* va_end(ap); */ +/* if (sess != NULL) */ +/* sess_release(sess); */ +/* msgbuftrigger = 1; */ +/* sx_sunlock(&proctree_lock); */ +/* } */ + +/* + * Ttyprintf displays a message on a tty; it should be used only by + * the tty driver, or anything that knows the underlying tty will not + * be revoke(2)'d away. Other callers should use tprintf. + */ +/* int */ +/* ttyprintf(struct tty *tp, const char *fmt, ...) */ +/* { */ +/* va_list ap; */ +/* struct putchar_arg pca; */ +/* int retval; */ + +/* va_start(ap, fmt); */ +/* pca.tty = tp; */ +/* pca.flags = TOTTY; */ +/* retval = kvprintf(fmt, putchar, &pca, 10, ap); */ +/* va_end(ap); */ +/* return (retval); */ +/* } */ + +/* + * Log writes to the log buffer, and guarantees not to sleep (so can be + * called by interrupt routines). If there is no process reading the + * log yet, it writes to the console also. + */ +/* void */ +/* log(int level, const char *fmt, ...) */ +/* { */ +/* va_list ap; */ +/* struct putchar_arg pca; */ + +/* pca.tty = NULL; */ +/* pca.pri = level; */ +/* pca.flags = log_open ? TOLOG : TOCONS; */ +/* pca.p_bufr = NULL; */ + +/* va_start(ap, fmt); */ +/* kvprintf(fmt, putchar, &pca, 10, ap); */ +/* va_end(ap); */ + +/* msgbuftrigger = 1; */ +/* } */ + +/* #define CONSCHUNK 128 */ + +/* void */ +/* log_console(struct uio *uio) */ +/* { */ +/* int c, i, error, nl; */ +/* char *consbuffer; */ +/* int pri; */ + +/* if (!log_console_output) */ +/* return; */ + +/* pri = LOG_INFO | LOG_CONSOLE; */ +/* uio = cloneuio(uio); */ +/* consbuffer = malloc(CONSCHUNK, M_TEMP, M_WAITOK); */ + +/* nl = 0; */ +/* while (uio->uio_resid > 0) { */ +/* c = imin(uio->uio_resid, CONSCHUNK); */ +/* error = uiomove(consbuffer, c, uio); */ +/* if (error != 0) */ +/* break; */ +/* for (i = 0; i < c; i++) { */ +/* msglogchar(consbuffer[i], pri); */ +/* if (consbuffer[i] == '\n') */ +/* nl = 1; */ +/* else */ +/* nl = 0; */ +/* } */ +/* } */ +/* if (!nl) */ +/* msglogchar('\n', pri); */ +/* msgbuftrigger = 1; */ +/* free(uio, M_IOV); */ +/* free(consbuffer, M_TEMP); */ +/* return; */ +/* } */ + +int +printf(const char *fmt, ...) +{ + va_list ap; + int retval; + + va_start(ap, fmt); + retval = vprintf(fmt, ap); + va_end(ap); + + return (retval); +} + +int +vprintf(const char *fmt, va_list ap) +{ + /* struct putchar_arg pca; */ + int retval; +/* #ifdef PRINTF_BUFR_SIZE */ +/* char bufr[PRINTF_BUFR_SIZE]; */ +/* #endif */ + +/* pca.tty = NULL; */ +/* pca.flags = TOCONS | TOLOG; */ +/* pca.pri = -1; */ +/* #ifdef PRINTF_BUFR_SIZE */ +/* pca.p_bufr = bufr; */ +/* pca.p_next = pca.p_bufr; */ +/* pca.n_bufr = sizeof(bufr); */ +/* pca.remain = sizeof(bufr); */ +/* *pca.p_next = '\0'; */ +/* #else */ +/* /\* Don't buffer console output. *\/ */ +/* pca.p_bufr = NULL; */ +/* #endif */ + + emhfc_putchar_linelock(emhfc_putchar_linelock_arg); + retval = kvprintf(fmt, emhfc_putchar, emhfc_putchar_arg, 10, ap); + emhfc_putchar_lineunlock(emhfc_putchar_linelock_arg); + +/* #ifdef PRINTF_BUFR_SIZE */ +/* /\* Write any buffered console output: *\/ */ +/* if (*pca.p_bufr != '\0') */ +/* cnputs(pca.p_bufr); */ +/* #endif */ + + /* if (!panicstr) */ + /* msgbuftrigger = 1; */ + + return (retval); +} + +/* static void */ +/* putcons(int c, struct putchar_arg *ap) */ +/* { */ +/* /\* Check if no console output buffer was provided. *\/ */ +/* if (ap->p_bufr == NULL) */ +/* /\* Output direct to the console. *\/ */ +/* cnputc(c); */ +/* else { */ +/* /\* Buffer the character: *\/ */ +/* if (c == '\n') { */ +/* *ap->p_next++ = '\r'; */ +/* ap->remain--; */ +/* } */ +/* *ap->p_next++ = c; */ +/* ap->remain--; */ + +/* /\* Always leave the buffer zero terminated. *\/ */ +/* *ap->p_next = '\0'; */ + +/* /\* Check if the buffer needs to be flushed. *\/ */ +/* if (ap->remain < 3 || c == '\n') { */ +/* cnputs(ap->p_bufr); */ +/* ap->p_next = ap->p_bufr; */ +/* ap->remain = ap->n_bufr; */ +/* *ap->p_next = '\0'; */ +/* } */ +/* } */ +/* } */ + +/* + * Print a character on console or users terminal. If destination is + * the console then the last bunch of characters are saved in msgbuf for + * inspection later. + */ +/* static void */ +/* putchar(int c, void *arg) */ +/* { */ +/* struct putchar_arg *ap = (struct putchar_arg*) arg; */ +/* struct tty *tp = ap->tty; */ +/* int flags = ap->flags; */ + +/* /\* Don't use the tty code after a panic or while in ddb. *\/ */ +/* if (kdb_active) { */ +/* if (c != '\0') */ +/* cnputc(c); */ +/* } else if (panicstr || ((flags & TOCONS) && constty == NULL)) { */ +/* if (c != '\0') */ +/* putcons(c, ap); */ +/* } else { */ +/* if ((flags & TOTTY) && tp != NULL) */ +/* tty_putchar(tp, c); */ +/* if (flags & TOCONS) { */ +/* if (constty != NULL) */ +/* msgbuf_addchar(&consmsgbuf, c); */ +/* if (always_console_output && c != '\0') */ +/* putcons(c, ap); */ +/* } */ +/* } */ +/* if ((flags & TOLOG)) */ +/* msglogchar(c, ap->pri); */ +/* } */ + +/* + * Scaled down version of sprintf(3). + */ +int +sprintf(char *buf, const char *cfmt, ...) +{ + int retval; + va_list ap; + + va_start(ap, cfmt); + retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap); + buf[retval] = '\0'; + va_end(ap); + return (retval); +} + +/* + * Scaled down version of vsprintf(3). + */ +int +vsprintf(char *buf, const char *cfmt, va_list ap) +{ + int retval; + + retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap); + buf[retval] = '\0'; + return (retval); +} + +/* + * Scaled down version of snprintf(3). + */ +int +snprintf(char *str, size_t size, const char *format, ...) +{ + int retval; + va_list ap; + + va_start(ap, format); + retval = vsnprintf(str, size, format, ap); + va_end(ap); + return(retval); +} + +/* + * Scaled down version of vsnprintf(3). + */ +int +vsnprintf(char *str, size_t size, const char *format, va_list ap) +{ + struct snprintf_arg info; + int retval; + + info.str = str; + info.remain = size; + retval = kvprintf(format, snprintf_func, &info, 10, ap); + if (info.remain >= 1) + *info.str++ = '\0'; + return (retval); +} + +/* + * Kernel version which takes radix argument vsnprintf(3). + */ +int +vsnrprintf(char *str, size_t size, int radix, const char *format, va_list ap) +{ + struct snprintf_arg info; + int retval; + + info.str = str; + info.remain = size; + retval = kvprintf(format, snprintf_func, &info, radix, ap); + if (info.remain >= 1) + *info.str++ = '\0'; + return (retval); +} + +static void +snprintf_func(int ch, void *arg) +{ + struct snprintf_arg *const info = arg; + + if (info->remain >= 2) { + *info->str++ = ch; + info->remain--; + } +} + +/* + * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse + * order; return an optional length and a pointer to the last character + * written in the buffer (i.e., the first character of the string). + * The buffer pointed to by `nbuf' must have length >= MAXNBUF. + */ +static char * +ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper) +{ + char *p, c; + + p = nbuf; + *p = '\0'; + do { + c = hex2ascii(num % base); + *++p = upper ? toupper(c) : c; + } while (num /= base); + if (lenp) + *lenp = p - nbuf; + return (p); +} + +/* + * Scaled down version of printf(3). + * + * Two additional formats: + * + * The format %b is supported to decode error registers. + * Its usage is: + * + * printf("reg=%b\n", regval, "*"); + * + * where is the output base expressed as a control character, e.g. + * \10 gives octal; \20 gives hex. Each arg is a sequence of characters, + * the first of which gives the bit number to be inspected (origin 1), and + * the next characters (up to a control character, i.e. a character <= 32), + * give the name of the register. Thus: + * + * kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); + * + * would produce output: + * + * reg=3 + * + * XXX: %D -- Hexdump, takes pointer and separator string: + * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX + * ("%*D", len, ptr, " " -> XX XX XX XX ... + */ +static int +kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap) +{ +#define PCHAR(c) {int cc=(c); if (func) (*func)(cc,arg); else *d++ = cc; retval++; } + char nbuf[MAXNBUF]; + char *d; + const char *p, *percent, *q; + u_char *up; + int ch, n; + uintmax_t num; + int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot; + int cflag, hflag, jflag, tflag, zflag; + int dwidth, upper; + char padc; + int stop = 0, retval = 0; + + num = 0; + if (!func) + d = (char *) arg; + else + d = NULL; + + if (fmt == NULL) + fmt = "(fmt null)\n"; + + if (radix < 2 || radix > 36) + radix = 10; + + for (;;) { + padc = ' '; + width = 0; + while ((ch = (u_char)*fmt++) != '%' || stop) { + if (ch == '\0') + return (retval); + PCHAR(ch); + } + percent = fmt - 1; + qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0; + sign = 0; dot = 0; dwidth = 0; upper = 0; + cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0; +reswitch: switch (ch = (u_char)*fmt++) { + case '.': + dot = 1; + goto reswitch; + case '#': + sharpflag = 1; + goto reswitch; + case '+': + sign = 1; + goto reswitch; + case '-': + ladjust = 1; + goto reswitch; + case '%': + PCHAR(ch); + break; + case '*': + if (!dot) { + width = va_arg(ap, int); + if (width < 0) { + ladjust = !ladjust; + width = -width; + } + } else { + dwidth = va_arg(ap, int); + } + goto reswitch; + case '0': + if (!dot) { + padc = '0'; + goto reswitch; + } + /* fallthrough */ + case '1': + /* fallthrough */ + case '2': + /* fallthrough */ + case '3': + /* fallthrough */ + case '4': + /* fallthrough */ + case '5': + /* fallthrough */ + case '6': + /* fallthrough */ + case '7': + /* fallthrough */ + case '8': + /* fallthrough */ + case '9': + for (n = 0;; ++fmt) { + n = n * 10 + ch - '0'; + ch = *fmt; + if (ch < '0' || ch > '9') + break; + } + if (dot) + dwidth = n; + else + width = n; + goto reswitch; + case 'b': + num = (u_int)va_arg(ap, int); + p = va_arg(ap, char *); + for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;) + PCHAR(*q--); + + if (num == 0) + break; + + for (tmp = 0; *p;) { + n = *p++; + if (num & (1 << (n - 1))) { + PCHAR(tmp ? ',' : '<'); + for (; (n = *p) > ' '; ++p) + PCHAR(n); + tmp = 1; + } else + for (; *p > ' '; ++p) + continue; + } + if (tmp) + PCHAR('>'); + break; + case 'c': + PCHAR(va_arg(ap, int)); + break; + case 'D': + up = va_arg(ap, u_char *); + p = va_arg(ap, char *); + if (!width) + width = 16; + while(width--) { + PCHAR(hex2ascii(*up >> 4)); + PCHAR(hex2ascii(*up & 0x0f)); + up++; + if (width) + for (q=p;*q;q++) + PCHAR(*q); + } + break; + case 'd': + case 'i': + base = 10; + sign = 1; + goto handle_sign; + case 'h': + if (hflag) { + hflag = 0; + cflag = 1; + } else + hflag = 1; + goto reswitch; + case 'j': + jflag = 1; + goto reswitch; + case 'l': + if (lflag) { + lflag = 0; + qflag = 1; + } else + lflag = 1; + goto reswitch; + case 'n': + if (jflag) + *(va_arg(ap, intmax_t *)) = retval; + else if (qflag) + *(va_arg(ap, quad_t *)) = retval; + else if (lflag) + *(va_arg(ap, long *)) = retval; + else if (zflag) + *(va_arg(ap, size_t *)) = retval; + else if (hflag) + *(va_arg(ap, short *)) = retval; + else if (cflag) + *(va_arg(ap, char *)) = retval; + else + *(va_arg(ap, int *)) = retval; + break; + case 'o': + base = 8; + goto handle_nosign; + case 'p': + base = 16; + sharpflag = (width == 0); + sign = 0; + num = (uintptr_t)va_arg(ap, void *); + goto number; + case 'q': + qflag = 1; + goto reswitch; + case 'r': + base = radix; + if (sign) + goto handle_sign; + goto handle_nosign; + case 's': + p = va_arg(ap, char *); + if (p == NULL) + p = "(null)"; + if (!dot) + n = strlen (p); + else + for (n = 0; n < dwidth && p[n]; n++) + continue; + + width -= n; + + if (!ladjust && width > 0) + while (width--) + PCHAR(padc); + while (n--) + PCHAR(*p++); + if (ladjust && width > 0) + while (width--) + PCHAR(padc); + break; + case 't': + tflag = 1; + goto reswitch; + case 'u': + base = 10; + goto handle_nosign; + case 'X': + upper = 1; + /* fallthrough */ + case 'x': + base = 16; + goto handle_nosign; + case 'y': + base = 16; + sign = 1; + goto handle_sign; + case 'z': + zflag = 1; + goto reswitch; +handle_nosign: + sign = 0; + if (jflag) + num = va_arg(ap, uintmax_t); + else if (qflag) + num = va_arg(ap, u_quad_t); + else if (tflag) + num = va_arg(ap, ptrdiff_t); + else if (lflag) + num = va_arg(ap, u_long); + else if (zflag) + num = va_arg(ap, size_t); + else if (hflag) + num = (u_short)va_arg(ap, int); + else if (cflag) + num = (u_char)va_arg(ap, int); + else + num = va_arg(ap, u_int); + goto number; +handle_sign: + if (jflag) + num = va_arg(ap, intmax_t); + else if (qflag) + num = va_arg(ap, quad_t); + else if (tflag) + num = va_arg(ap, ptrdiff_t); + else if (lflag) + num = va_arg(ap, long); + else if (zflag) + num = va_arg(ap, ssize_t); + else if (hflag) + num = (short)va_arg(ap, int); + else if (cflag) + num = (char)va_arg(ap, int); + else + num = va_arg(ap, int); +number: + if (sign && (intmax_t)num < 0) { + neg = 1; + num = -(intmax_t)num; + } + p = ksprintn(nbuf, num, base, &n, upper); + tmp = 0; + if (sharpflag && num != 0) { + if (base == 8) + tmp++; + else if (base == 16) + tmp += 2; + } + if (neg) + tmp++; + + if (!ladjust && padc == '0') + dwidth = width - tmp; + width -= tmp + imax(dwidth, n); + dwidth -= n; + if (!ladjust) + while (width-- > 0) + PCHAR(' '); + if (neg) + PCHAR('-'); + if (sharpflag && num != 0) { + if (base == 8) { + PCHAR('0'); + } else if (base == 16) { + PCHAR('0'); + PCHAR('x'); + } + } + while (dwidth-- > 0) + PCHAR('0'); + + while (*p) + PCHAR(*p--); + + if (ladjust) + while (width-- > 0) + PCHAR(' '); + + break; + default: + while (percent < fmt) + PCHAR(*percent++); + /* + * Since we ignore an formatting argument it is no + * longer safe to obey the remaining formatting + * arguments as the arguments will no longer match + * the format specs. + */ + stop = 1; + break; + } + } +#undef PCHAR +} + +/* + * Put character in log buffer with a particular priority. + */ +/* static void */ +/* msglogchar(int c, int pri) */ +/* { */ +/* static int lastpri = -1; */ +/* static int dangling; */ +/* char nbuf[MAXNBUF]; */ +/* char *p; */ + +/* if (!msgbufmapped) */ +/* return; */ +/* if (c == '\0' || c == '\r') */ +/* return; */ +/* if (pri != -1 && pri != lastpri) { */ +/* if (dangling) { */ +/* msgbuf_addchar(msgbufp, '\n'); */ +/* dangling = 0; */ +/* } */ +/* msgbuf_addchar(msgbufp, '<'); */ +/* for (p = ksprintn(nbuf, (uintmax_t)pri, 10, NULL, 0); *p;) */ +/* msgbuf_addchar(msgbufp, *p--); */ +/* msgbuf_addchar(msgbufp, '>'); */ +/* lastpri = pri; */ +/* } */ +/* msgbuf_addchar(msgbufp, c); */ +/* if (c == '\n') { */ +/* dangling = 0; */ +/* lastpri = -1; */ +/* } else { */ +/* dangling = 1; */ +/* } */ +/* } */ + +/* void */ +/* msgbufinit(void *ptr, int size) */ +/* { */ +/* char *cp; */ +/* static struct msgbuf *oldp = NULL; */ + +/* size -= sizeof(*msgbufp); */ +/* cp = (char *)ptr; */ +/* msgbufp = (struct msgbuf *)(cp + size); */ +/* msgbuf_reinit(msgbufp, cp, size); */ +/* if (msgbufmapped && oldp != msgbufp) */ +/* msgbuf_copy(oldp, msgbufp); */ +/* msgbufmapped = 1; */ +/* oldp = msgbufp; */ +/* } */ + +/* static int unprivileged_read_msgbuf = 1; */ +/* SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_read_msgbuf, */ +/* CTLFLAG_RW, &unprivileged_read_msgbuf, 0, */ +/* "Unprivileged processes may read the kernel message buffer"); */ + +/* /\* Sysctls for accessing/clearing the msgbuf *\/ */ +/* static int */ +/* sysctl_kern_msgbuf(SYSCTL_HANDLER_ARGS) */ +/* { */ +/* char buf[128]; */ +/* u_int seq; */ +/* int error, len; */ + +/* if (!unprivileged_read_msgbuf) { */ +/* error = priv_check(req->td, PRIV_MSGBUF); */ +/* if (error) */ +/* return (error); */ +/* } */ + +/* /\* Read the whole buffer, one chunk at a time. *\/ */ +/* msgbuf_peekbytes(msgbufp, NULL, 0, &seq); */ +/* while ((len = msgbuf_peekbytes(msgbufp, buf, sizeof(buf), &seq)) > 0) { */ +/* error = sysctl_handle_opaque(oidp, buf, len, req); */ +/* if (error) */ +/* return (error); */ +/* } */ +/* return (0); */ +/* } */ + +/* SYSCTL_PROC(_kern, OID_AUTO, msgbuf, CTLTYPE_STRING | CTLFLAG_RD, */ +/* NULL, 0, sysctl_kern_msgbuf, "A", "Contents of kernel message buffer"); */ + +/* static int msgbuf_clearflag; */ + +/* static int */ +/* sysctl_kern_msgbuf_clear(SYSCTL_HANDLER_ARGS) */ +/* { */ +/* int error; */ +/* error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req); */ +/* if (!error && req->newptr) { */ +/* msgbuf_clear(msgbufp); */ +/* msgbuf_clearflag = 0; */ +/* } */ +/* return (error); */ +/* } */ + +/* SYSCTL_PROC(_kern, OID_AUTO, msgbuf_clear, */ +/* CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE, &msgbuf_clearflag, 0, */ +/* sysctl_kern_msgbuf_clear, "I", "Clear kernel message buffer"); */ + +/* #ifdef DDB */ + +/* DB_SHOW_COMMAND(msgbuf, db_show_msgbuf) */ +/* { */ +/* int i, j; */ + +/* if (!msgbufmapped) { */ +/* db_printf("msgbuf not mapped yet\n"); */ +/* return; */ +/* } */ +/* db_printf("msgbufp = %p\n", msgbufp); */ +/* db_printf("magic = %x, size = %d, r= %u, w = %u, ptr = %p, cksum= %u\n", */ +/* msgbufp->msg_magic, msgbufp->msg_size, msgbufp->msg_rseq, */ +/* msgbufp->msg_wseq, msgbufp->msg_ptr, msgbufp->msg_cksum); */ +/* for (i = 0; i < msgbufp->msg_size && !db_pager_quit; i++) { */ +/* j = MSGBUF_SEQ_TO_POS(msgbufp, i + msgbufp->msg_rseq); */ +/* db_printf("%c", msgbufp->msg_ptr[j]); */ +/* } */ +/* db_printf("\n"); */ +/* } */ + +/* #endif /\* DDB *\/ */ + +/* void */ +/* hexdump(const void *ptr, int length, const char *hdr, int flags) */ +/* { */ +/* int i, j, k; */ +/* int cols; */ +/* const unsigned char *cp; */ +/* char delim; */ + +/* if ((flags & HD_DELIM_MASK) != 0) */ +/* delim = (flags & HD_DELIM_MASK) >> 8; */ +/* else */ +/* delim = ' '; */ + +/* if ((flags & HD_COLUMN_MASK) != 0) */ +/* cols = flags & HD_COLUMN_MASK; */ +/* else */ +/* cols = 16; */ + +/* cp = ptr; */ +/* for (i = 0; i < length; i+= cols) { */ +/* if (hdr != NULL) */ +/* printf("%s", hdr); */ + +/* if ((flags & HD_OMIT_COUNT) == 0) */ +/* printf("%04x ", i); */ + +/* if ((flags & HD_OMIT_HEX) == 0) { */ +/* for (j = 0; j < cols; j++) { */ +/* k = i + j; */ +/* if (k < length) */ +/* printf("%c%02x", delim, cp[k]); */ +/* else */ +/* printf(" "); */ +/* } */ +/* } */ + +/* if ((flags & HD_OMIT_CHARS) == 0) { */ +/* printf(" |"); */ +/* for (j = 0; j < cols; j++) { */ +/* k = i + j; */ +/* if (k >= length) */ +/* printf(" "); */ +/* else if (cp[k] >= ' ' && cp[k] <= '~') */ +/* printf("%c", cp[k]); */ +/* else */ +/* printf("."); */ +/* } */ +/* printf("|"); */ +/* } */ +/* printf("\n"); */ +/* } */ +/* } */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/Makefile b/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/Makefile new file mode 100644 index 0000000000..b718229cbe --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/Makefile @@ -0,0 +1,32 @@ +srcdir := $(dir $(lastword $(MAKEFILE_LIST))) +vpath %.c $(srcdir) + +C_SOURCES:= $(wildcard $(srcdir)/*.c) +C_SOURCES:= $(patsubst $(srcdir)/%, %, $(C_SOURCES)) +OBJECTS = $(patsubst %.c, %.o, $(C_SOURCES)) + +I_SOURCES := $(wildcard $(srcdir)/include/*.h) + +CFLAGS += -I$(srcdir)/../libemhfc/include -I$(srcdir)/include -nostdinc -fno-builtin -nostdlib -Wall + +THE_ARCHIVE = libemhfcrypto.a + +# targets +.PHONY: all +all: $(THE_ARCHIVE) + +$(THE_ARCHIVE): $(OBJECTS) + $(AR) -rcs $(THE_ARCHIVE) $(OBJECTS) + +#%.o: %.c $(C_SOURCES) $(I_SOURCES) Makefile ../Makefile +# $(CC) -c $(CFLAGS) -o $@ $< + +.PHONY: clean +clean: + $(RM) $(OBJECTS) $(THE_ARCHIVE) + +.PHONY: install-dev +install-dev: + # Nothing to do here + + diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/hashandprint.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/hashandprint.c new file mode 100644 index 0000000000..d46273f293 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/hashandprint.c @@ -0,0 +1,81 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include +#include + +#include + +void hashandprint(const char* prefix, const u8 *bytes, size_t len) { + u8 digest[SHA_DIGEST_LENGTH]; + +#ifdef __AMD64__ + printf("hashandprint: processing 0x%016x bytes at addr %016x\n", len, (u64)bytes); +#elif defined(__I386__) + printf("hashandprint: processing 0x%08x bytes at addr 0x%08x\n", len, (u32)bytes); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + + EU_VERIFYN( sha1_buffer(bytes, len, digest)); + + printf("%s: %*D\n", prefix, SHA_DIGEST_LENGTH, digest, " "); + /* print_hex( prefix, digest, SHA_DIGEST_LENGTH); */ + + /* Simulate PCR 17 value on AMD processor */ + /* if(len == 0x10000) { */ + /* u8 zeros[SHA_DIGEST_LENGTH]; */ + /* u8 pcr17[SHA_DIGEST_LENGTH]; */ + /* memset(zeros, 0, SHA_DIGEST_LENGTH); */ + + /* SHA1_Init(&ctx); */ + /* SHA1_Update(&ctx, zeros, SHA_DIGEST_LENGTH); */ + /* SHA1_Update(&ctx, digest, SHA_DIGEST_LENGTH); */ + /* SHA1_Final(pcr17, &ctx); */ + + /* print_hex("[AMD] Expected PCR-17: ", pcr17, SHA_DIGEST_LENGTH); */ + /* } */ +} diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/include/aes.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/include/aes.h new file mode 100644 index 0000000000..bfc1dfa9c3 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/include/aes.h @@ -0,0 +1,145 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/** + * \file aes.h + * Edited by Zongwei Zhou for EMHF project + */ +#ifndef XYSSL_AES_H +#define XYSSL_AES_H + +#define XYSSL_AES_ROM_TABLES + +#define AES_ENCRYPT 1 +#define AES_DECRYPT 0 + +/** + * \brief AES context structure + */ +typedef struct +{ + int nr; /*!< number of rounds */ + unsigned long *rk; /*!< AES round keys */ + unsigned long buf[68]; /*!< unaligned data */ +} +aes_context; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief AES key schedule (encryption) + * + * \param ctx AES context to be initialized + * \param key encryption key + * \param keysize must be 128, 192 or 256 + */ +void aes_setkey_enc( aes_context *ctx, unsigned char *key, int keysize ); + +/** + * \brief AES key schedule (decryption) + * + * \param ctx AES context to be initialized + * \param key decryption key + * \param keysize must be 128, 192 or 256 + */ +void aes_setkey_dec( aes_context *ctx, unsigned char *key, int keysize ); + +/** + * \brief AES-ECB block encryption/decryption + * + * \param ctx AES context + * \param mode AES_ENCRYPT or AES_DECRYPT + * \param input 16-byte input block + * \param output 16-byte output block + */ +void aes_crypt_ecb( aes_context *ctx, + int mode, + unsigned char input[16], + unsigned char output[16] ); + +/** + * \brief AES-CBC buffer encryption/decryption + * + * \param ctx AES context + * \param mode AES_ENCRYPT or AES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + */ +void aes_crypt_cbc( aes_context *ctx, + int mode, + int length, + unsigned char iv[16], + unsigned char *input, + unsigned char *output ); + +/** + * \brief AES-CFB buffer encryption/decryption + * + * \param ctx AES context + * \param mode AES_ENCRYPT or AES_DECRYPT + * \param length length of the input data + * \param iv_off offset in IV (updated after use) + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + */ +void aes_crypt_cfb( aes_context *ctx, + int mode, + int length, + int *iv_off, + unsigned char iv[16], + unsigned char *input, + unsigned char *output ); + +#ifdef __cplusplus +} +#endif + +#endif /* aes.h */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/include/bignum.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/include/bignum.h new file mode 100644 index 0000000000..abcf519fa6 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/include/bignum.h @@ -0,0 +1,446 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/** + * \file bignum.h + */ +#ifndef XYSSL_BIGNUM_H +#define XYSSL_BIGNUM_H + +//#include + +#define XYSSL_ERR_MPI_FILE_IO_ERROR -0x0002 +#define XYSSL_ERR_MPI_BAD_INPUT_DATA -0x0004 +#define XYSSL_ERR_MPI_INVALID_CHARACTER -0x0006 +#define XYSSL_ERR_MPI_BUFFER_TOO_SMALL -0x0008 +#define XYSSL_ERR_MPI_NEGATIVE_VALUE -0x000A +#define XYSSL_ERR_MPI_DIVISION_BY_ZERO -0x000C +#define XYSSL_ERR_MPI_NOT_ACCEPTABLE -0x000E + +#define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup + +/* + * Define the base integer type, architecture-wise + */ +#if defined(XYSSL_HAVE_INT8) +typedef unsigned char t_int; +typedef unsigned short t_dbl; +#else +#if defined(XYSSL_HAVE_INT16) +typedef unsigned short t_int; +typedef unsigned long t_dbl; +#else + typedef unsigned long t_int; + #if defined(_MSC_VER) && defined(_M_IX86) + typedef unsigned __int64 t_dbl; + #else + #if defined(__amd64__) || defined(__x86_64__) || \ + defined(__ppc64__) || defined(__powerpc64__) || \ + defined(__ia64__) || defined(__alpha__) + typedef unsigned int t_dbl __attribute__((mode(TI))); + #else + typedef unsigned long long t_dbl; + #endif + #endif +#endif +#endif + +/** + * \brief MPI structure + */ +typedef struct +{ + int s; /*!< integer sign */ + int n; /*!< total # of limbs */ + t_int *p; /*!< pointer to limbs */ +} +mpi; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Initialize one or more mpi + */ +void mpi_init( mpi *X); + +/** + * \brief Unallocate one or more mpi + */ +void mpi_free( mpi *X); + +/** + * \brief Enlarge to the specified number of limbs + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_grow( mpi *X, int nblimbs ); + +/** + * \brief Copy the contents of Y into X + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_copy( mpi *X, mpi *Y ); + +/** + * \brief Swap the contents of X and Y + */ +void mpi_swap( mpi *X, mpi *Y ); + +/** + * \brief Set value from integer + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_lset( mpi *X, int z ); + +/** + * \brief Return the number of least significant bits + */ +int mpi_lsb( mpi *X ); + +/** + * \brief Return the number of most significant bits + */ +int mpi_msb( mpi *X ); + +/** + * \brief Return the total size in bytes + */ +int mpi_size( mpi *X ); + +/** + * \brief Import from an ASCII string + * + * \param X destination mpi + * \param radix input numeric base + * \param s null-terminated string buffer + * + * \return 0 if successful, or an XYSSL_ERR_MPI_XXX error code + */ +int mpi_read_string( mpi *X, int radix, char *s ); + +/** + * \brief Export into an ASCII string + * + * \param X source mpi + * \param radix output numeric base + * \param s string buffer + * \param slen string buffer size + * + * \return 0 if successful, or an XYSSL_ERR_MPI_XXX error code + * + * \note Call this function with *slen = 0 to obtain the + * minimum required buffer size in *slen. + */ +//int mpi_write_string( mpi *X, int radix, char *s, int *slen ); + +/** + * \brief Read X from an opened file + * + * \param X destination mpi + * \param radix input numeric base + * \param fin input file handle + * + * \return 0 if successful, or an XYSSL_ERR_MPI_XXX error code + */ +//int mpi_read_file( mpi *X, int radix, FILE *fin ); + +/** + * \brief Write X into an opened file, or stdout + * + * \param p prefix, can be NULL + * \param X source mpi + * \param radix output numeric base + * \param fout output file handle + * + * \return 0 if successful, or an XYSSL_ERR_MPI_XXX error code + * + * \note Set fout == NULL to print X on the console. + */ +//int mpi_write_file( char *p, mpi *X, int radix, FILE *fout ); + +/** + * \brief Import X from unsigned binary data, big endian + * + * \param X destination mpi + * \param buf input buffer + * \param buflen input buffer size + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_read_binary( mpi *X, unsigned char *buf, int buflen ); + +/** + * \brief Export X into unsigned binary data, big endian + * + * \param X source mpi + * \param buf output buffer + * \param buflen output buffer size + * + * \return 0 if successful, + * XYSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough + * + * \note Call this function with *buflen = 0 to obtain the + * minimum required buffer size in *buflen. + */ +int mpi_write_binary( mpi *X, unsigned char *buf, int buflen ); + +/** + * \brief Left-shift: X <<= count + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_shift_l( mpi *X, int count ); + +/** + * \brief Right-shift: X >>= count + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_shift_r( mpi *X, int count ); + +/** + * \brief Compare unsigned values + * + * \return 1 if |X| is greater than |Y|, + * -1 if |X| is lesser than |Y| or + * 0 if |X| is equal to |Y| + */ +int mpi_cmp_abs( mpi *X, mpi *Y ); + +/** + * \brief Compare signed values + * + * \return 1 if X is greater than Y, + * -1 if X is lesser than Y or + * 0 if X is equal to Y + */ +int mpi_cmp_mpi( mpi *X, mpi *Y ); + +/** + * \brief Compare signed values + * + * \return 1 if X is greater than z, + * -1 if X is lesser than z or + * 0 if X is equal to z + */ +int mpi_cmp_int( mpi *X, int z ); + +/** + * \brief Unsigned addition: X = |A| + |B| + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_add_abs( mpi *X, mpi *A, mpi *B ); + +/** + * \brief Unsigned substraction: X = |A| - |B| + * + * \return 0 if successful, + * XYSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A + */ +int mpi_sub_abs( mpi *X, mpi *A, mpi *B ); + +/** + * \brief Signed addition: X = A + B + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_add_mpi( mpi *X, mpi *A, mpi *B ); + +/** + * \brief Signed substraction: X = A - B + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_sub_mpi( mpi *X, mpi *A, mpi *B ); + +/** + * \brief Signed addition: X = A + b + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_add_int( mpi *X, mpi *A, int b ); + +/** + * \brief Signed substraction: X = A - b + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_sub_int( mpi *X, mpi *A, int b ); + +/** + * \brief Baseline multiplication: X = A * B + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_mul_mpi( mpi *X, mpi *A, mpi *B ); + +/** + * \brief Baseline multiplication: X = A * b + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_mul_int( mpi *X, mpi *A, t_int b ); + +/** + * \brief Division by mpi: A = Q * B + R + * + * \return 0 if successful, + * 1 if memory allocation failed, + * XYSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0 + * + * \note Either Q or R can be NULL. + */ +int mpi_div_mpi( mpi *Q, mpi *R, mpi *A, mpi *B ); + +/** + * \brief Division by int: A = Q * b + R + * + * \return 0 if successful, + * 1 if memory allocation failed, + * XYSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0 + * + * \note Either Q or R can be NULL. + */ +int mpi_div_int( mpi *Q, mpi *R, mpi *A, int b ); + +/** + * \brief Modulo: R = A mod B + * + * \return 0 if successful, + * 1 if memory allocation failed, + * XYSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0 + */ +int mpi_mod_mpi( mpi *R, mpi *A, mpi *B ); + +/** + * \brief Modulo: r = A mod b + * + * \return 0 if successful, + * 1 if memory allocation failed, + * XYSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0 + */ +int mpi_mod_int( t_int *r, mpi *A, int b ); + +/** + * \brief Sliding-window exponentiation: X = A^E mod N + * + * \return 0 if successful, + * 1 if memory allocation failed, + * XYSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even + * + * \note _RR is used to avoid re-computing R*R mod N across + * multiple calls, which speeds up things a bit. It can + * be set to NULL if the extra performance is unneeded. + */ +int mpi_exp_mod( mpi *X, mpi *A, mpi *E, mpi *N, mpi *_RR ); + +/** + * \brief Greatest common divisor: G = gcd(A, B) + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_gcd( mpi *G, mpi *A, mpi *B ); + +/** + * \brief Modular inverse: X = A^-1 mod N + * + * \return 0 if successful, + * 1 if memory allocation failed, + * XYSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil + * XYSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N + */ +int mpi_inv_mod( mpi *X, mpi *A, mpi *N ); + +#if 0 +/** + * \brief Miller-Rabin primality test + * + * \return 0 if successful (probably prime), + * 1 if memory allocation failed, + * XYSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime + */ +int mpi_is_prime( mpi *X); +#endif + +/** + * \brief Prime number generation + * + * \param X destination mpi + * \param nbits required size of X in bits + * \param dh_flag if 1, then (X-1)/2 will be prime too + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \return 0 if successful (probably prime), + * 1 if memory allocation failed, + * XYSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3 + */ +int mpi_gen_prime( mpi *X, int nbits, int dh_flag); + +#ifdef __cplusplus +} +#endif + +#endif /* bignum.h */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/include/bn_mul.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/include/bn_mul.h new file mode 100644 index 0000000000..c8ffe53ec8 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/include/bn_mul.h @@ -0,0 +1,728 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/** + * \file bn_mul.h + */ +/* + * Multiply source vector [s] with b, add result + * to destination vector [d] and set carry c. + * + * Currently supports: + * + * . IA-32 (386+) . AMD64 / EM64T + * . IA-32 (SSE2) . Motorola 68000 + * . PowerPC, 32-bit . MicroBlaze + * . PowerPC, 64-bit . TriCore + * . SPARC v8 . ARM v3+ + * . Alpha . MIPS32 + * . C, longlong . C, generic + */ +#ifndef XYSSL_BN_MUL_H +#define XYSSL_BN_MUL_H + +//#include "rsaconfig.h" + +//#if defined(XYSSL_HAVE_ASM) + +#if defined(__GNUC__) +#if defined(__i386__) + +#define MULADDC_INIT \ + asm( "movl %%ebx, %0 " : "=m" (t)); \ + asm( "movl %0, %%esi " :: "m" (s)); \ + asm( "movl %0, %%edi " :: "m" (d)); \ + asm( "movl %0, %%ecx " :: "m" (c)); \ + asm( "movl %0, %%ebx " :: "m" (b)); + +#define MULADDC_CORE \ + asm( "lodsl " ); \ + asm( "mull %ebx " ); \ + asm( "addl %ecx, %eax " ); \ + asm( "adcl $0, %edx " ); \ + asm( "addl (%edi), %eax " ); \ + asm( "adcl $0, %edx " ); \ + asm( "movl %edx, %ecx " ); \ + asm( "stosl " ); + +#define MULADDC_STOP \ + asm( "movl %0, %%ebx " :: "m" (t)); \ + asm( "movl %%ecx, %0 " : "=m" (c)); \ + asm( "movl %%edi, %0 " : "=m" (d)); \ + asm( "movl %%esi, %0 " : "=m" (s) :: \ + "eax", "ecx", "edx", "esi", "edi" ); + +#if defined(XYSSL_HAVE_SSE2) + +#define MULADDC_HUIT \ + asm( "movd %ecx, %mm1 " ); \ + asm( "movd %ebx, %mm0 " ); \ + asm( "movd (%edi), %mm3 " ); \ + asm( "paddq %mm3, %mm1 " ); \ + asm( "movd (%esi), %mm2 " ); \ + asm( "pmuludq %mm0, %mm2 " ); \ + asm( "movd 4(%esi), %mm4 " ); \ + asm( "pmuludq %mm0, %mm4 " ); \ + asm( "movd 8(%esi), %mm6 " ); \ + asm( "pmuludq %mm0, %mm6 " ); \ + asm( "movd 12(%esi), %mm7 " ); \ + asm( "pmuludq %mm0, %mm7 " ); \ + asm( "paddq %mm2, %mm1 " ); \ + asm( "movd 4(%edi), %mm3 " ); \ + asm( "paddq %mm4, %mm3 " ); \ + asm( "movd 8(%edi), %mm5 " ); \ + asm( "paddq %mm6, %mm5 " ); \ + asm( "movd 12(%edi), %mm4 " ); \ + asm( "paddq %mm4, %mm7 " ); \ + asm( "movd %mm1, (%edi) " ); \ + asm( "movd 16(%esi), %mm2 " ); \ + asm( "pmuludq %mm0, %mm2 " ); \ + asm( "psrlq $32, %mm1 " ); \ + asm( "movd 20(%esi), %mm4 " ); \ + asm( "pmuludq %mm0, %mm4 " ); \ + asm( "paddq %mm3, %mm1 " ); \ + asm( "movd 24(%esi), %mm6 " ); \ + asm( "pmuludq %mm0, %mm6 " ); \ + asm( "movd %mm1, 4(%edi) " ); \ + asm( "psrlq $32, %mm1 " ); \ + asm( "movd 28(%esi), %mm3 " ); \ + asm( "pmuludq %mm0, %mm3 " ); \ + asm( "paddq %mm5, %mm1 " ); \ + asm( "movd 16(%edi), %mm5 " ); \ + asm( "paddq %mm5, %mm2 " ); \ + asm( "movd %mm1, 8(%edi) " ); \ + asm( "psrlq $32, %mm1 " ); \ + asm( "paddq %mm7, %mm1 " ); \ + asm( "movd 20(%edi), %mm5 " ); \ + asm( "paddq %mm5, %mm4 " ); \ + asm( "movd %mm1, 12(%edi) " ); \ + asm( "psrlq $32, %mm1 " ); \ + asm( "paddq %mm2, %mm1 " ); \ + asm( "movd 24(%edi), %mm5 " ); \ + asm( "paddq %mm5, %mm6 " ); \ + asm( "movd %mm1, 16(%edi) " ); \ + asm( "psrlq $32, %mm1 " ); \ + asm( "paddq %mm4, %mm1 " ); \ + asm( "movd 28(%edi), %mm5 " ); \ + asm( "paddq %mm5, %mm3 " ); \ + asm( "movd %mm1, 20(%edi) " ); \ + asm( "psrlq $32, %mm1 " ); \ + asm( "paddq %mm6, %mm1 " ); \ + asm( "movd %mm1, 24(%edi) " ); \ + asm( "psrlq $32, %mm1 " ); \ + asm( "paddq %mm3, %mm1 " ); \ + asm( "movd %mm1, 28(%edi) " ); \ + asm( "addl $32, %edi " ); \ + asm( "addl $32, %esi " ); \ + asm( "psrlq $32, %mm1 " ); \ + asm( "movd %mm1, %ecx " ); + +#endif /* SSE2 */ +#endif /* i386 */ + +#if defined(__amd64__) || defined (__x86_64__) + +#define MULADDC_INIT \ + asm( "movq %0, %%rsi " :: "m" (s)); \ + asm( "movq %0, %%rdi " :: "m" (d)); \ + asm( "movq %0, %%rcx " :: "m" (c)); \ + asm( "movq %0, %%rbx " :: "m" (b)); \ + asm( "xorq %r8, %r8 " ); + +#define MULADDC_CORE \ + asm( "movq (%rsi),%rax " ); \ + asm( "mulq %rbx " ); \ + asm( "addq $8, %rsi " ); \ + asm( "addq %rcx, %rax " ); \ + asm( "movq %r8, %rcx " ); \ + asm( "adcq $0, %rdx " ); \ + asm( "nop " ); \ + asm( "addq %rax, (%rdi) " ); \ + asm( "adcq %rdx, %rcx " ); \ + asm( "addq $8, %rdi " ); + +#define MULADDC_STOP \ + asm( "movq %%rcx, %0 " : "=m" (c)); \ + asm( "movq %%rdi, %0 " : "=m" (d)); \ + asm( "movq %%rsi, %0 " : "=m" (s) :: \ + "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" ); + +#endif /* AMD64 */ + +#if defined(__mc68020__) || defined(__mcpu32__) + +#define MULADDC_INIT \ + asm( "movl %0, %%a2 " :: "m" (s)); \ + asm( "movl %0, %%a3 " :: "m" (d)); \ + asm( "movl %0, %%d3 " :: "m" (c)); \ + asm( "movl %0, %%d2 " :: "m" (b)); \ + asm( "moveq #0, %d0 " ); + +#define MULADDC_CORE \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d4:%d1 " ); \ + asm( "addl %d3, %d1 " ); \ + asm( "addxl %d0, %d4 " ); \ + asm( "moveq #0, %d3 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "addxl %d4, %d3 " ); + +#define MULADDC_STOP \ + asm( "movl %%d3, %0 " : "=m" (c)); \ + asm( "movl %%a3, %0 " : "=m" (d)); \ + asm( "movl %%a2, %0 " : "=m" (s) :: \ + "d0", "d1", "d2", "d3", "d4", "a2", "a3" ); + +#define MULADDC_HUIT \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d4:%d1 " ); \ + asm( "addxl %d3, %d1 " ); \ + asm( "addxl %d0, %d4 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d3:%d1 " ); \ + asm( "addxl %d4, %d1 " ); \ + asm( "addxl %d0, %d3 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d4:%d1 " ); \ + asm( "addxl %d3, %d1 " ); \ + asm( "addxl %d0, %d4 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d3:%d1 " ); \ + asm( "addxl %d4, %d1 " ); \ + asm( "addxl %d0, %d3 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d4:%d1 " ); \ + asm( "addxl %d3, %d1 " ); \ + asm( "addxl %d0, %d4 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d3:%d1 " ); \ + asm( "addxl %d4, %d1 " ); \ + asm( "addxl %d0, %d3 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d4:%d1 " ); \ + asm( "addxl %d3, %d1 " ); \ + asm( "addxl %d0, %d4 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d3:%d1 " ); \ + asm( "addxl %d4, %d1 " ); \ + asm( "addxl %d0, %d3 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "addxl %d0, %d3 " ); + +#endif /* MC68000 */ + +#if defined(__powerpc__) || defined(__ppc__) +#if defined(__powerpc64__) || defined(__ppc64__) + +#if defined(__MACH__) && defined(__APPLE__) + +#define MULADDC_INIT \ + asm( "ld r3, %0 " :: "m" (s)); \ + asm( "ld r4, %0 " :: "m" (d)); \ + asm( "ld r5, %0 " :: "m" (c)); \ + asm( "ld r6, %0 " :: "m" (b)); \ + asm( "addi r3, r3, -8 " ); \ + asm( "addi r4, r4, -8 " ); \ + asm( "addic r5, r5, 0 " ); + +#define MULADDC_CORE \ + asm( "ldu r7, 8(r3) " ); \ + asm( "mulld r8, r7, r6 " ); \ + asm( "mulhdu r9, r7, r6 " ); \ + asm( "adde r8, r8, r5 " ); \ + asm( "ld r7, 8(r4) " ); \ + asm( "addze r5, r9 " ); \ + asm( "addc r8, r8, r7 " ); \ + asm( "stdu r8, 8(r4) " ); + +#define MULADDC_STOP \ + asm( "addze r5, r5 " ); \ + asm( "addi r4, r4, 8 " ); \ + asm( "addi r3, r3, 8 " ); \ + asm( "std r5, %0 " : "=m" (c)); \ + asm( "std r4, %0 " : "=m" (d)); \ + asm( "std r3, %0 " : "=m" (s) :: \ + "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); + +#else + +#define MULADDC_INIT \ + asm( "ld %%r3, %0 " :: "m" (s)); \ + asm( "ld %%r4, %0 " :: "m" (d)); \ + asm( "ld %%r5, %0 " :: "m" (c)); \ + asm( "ld %%r6, %0 " :: "m" (b)); \ + asm( "addi %r3, %r3, -8 " ); \ + asm( "addi %r4, %r4, -8 " ); \ + asm( "addic %r5, %r5, 0 " ); + +#define MULADDC_CORE \ + asm( "ldu %r7, 8(%r3) " ); \ + asm( "mulld %r8, %r7, %r6 " ); \ + asm( "mulhdu %r9, %r7, %r6 " ); \ + asm( "adde %r8, %r8, %r5 " ); \ + asm( "ld %r7, 8(%r4) " ); \ + asm( "addze %r5, %r9 " ); \ + asm( "addc %r8, %r8, %r7 " ); \ + asm( "stdu %r8, 8(%r4) " ); + +#define MULADDC_STOP \ + asm( "addze %r5, %r5 " ); \ + asm( "addi %r4, %r4, 8 " ); \ + asm( "addi %r3, %r3, 8 " ); \ + asm( "std %%r5, %0 " : "=m" (c)); \ + asm( "std %%r4, %0 " : "=m" (d)); \ + asm( "std %%r3, %0 " : "=m" (s) :: \ + "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); + +#endif + +#else /* PPC32 */ + +#if defined(__MACH__) && defined(__APPLE__) + +#define MULADDC_INIT \ + asm( "lwz r3, %0 " :: "m" (s)); \ + asm( "lwz r4, %0 " :: "m" (d)); \ + asm( "lwz r5, %0 " :: "m" (c)); \ + asm( "lwz r6, %0 " :: "m" (b)); \ + asm( "addi r3, r3, -4 " ); \ + asm( "addi r4, r4, -4 " ); \ + asm( "addic r5, r5, 0 " ); + +#define MULADDC_CORE \ + asm( "lwzu r7, 4(r3) " ); \ + asm( "mullw r8, r7, r6 " ); \ + asm( "mulhwu r9, r7, r6 " ); \ + asm( "adde r8, r8, r5 " ); \ + asm( "lwz r7, 4(r4) " ); \ + asm( "addze r5, r9 " ); \ + asm( "addc r8, r8, r7 " ); \ + asm( "stwu r8, 4(r4) " ); + +#define MULADDC_STOP \ + asm( "addze r5, r5 " ); \ + asm( "addi r4, r4, 4 " ); \ + asm( "addi r3, r3, 4 " ); \ + asm( "stw r5, %0 " : "=m" (c)); \ + asm( "stw r4, %0 " : "=m" (d)); \ + asm( "stw r3, %0 " : "=m" (s) :: \ + "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); + +#else + +#define MULADDC_INIT \ + asm( "lwz %%r3, %0 " :: "m" (s)); \ + asm( "lwz %%r4, %0 " :: "m" (d)); \ + asm( "lwz %%r5, %0 " :: "m" (c)); \ + asm( "lwz %%r6, %0 " :: "m" (b)); \ + asm( "addi %r3, %r3, -4 " ); \ + asm( "addi %r4, %r4, -4 " ); \ + asm( "addic %r5, %r5, 0 " ); + +#define MULADDC_CORE \ + asm( "lwzu %r7, 4(%r3) " ); \ + asm( "mullw %r8, %r7, %r6 " ); \ + asm( "mulhwu %r9, %r7, %r6 " ); \ + asm( "adde %r8, %r8, %r5 " ); \ + asm( "lwz %r7, 4(%r4) " ); \ + asm( "addze %r5, %r9 " ); \ + asm( "addc %r8, %r8, %r7 " ); \ + asm( "stwu %r8, 4(%r4) " ); + +#define MULADDC_STOP \ + asm( "addze %r5, %r5 " ); \ + asm( "addi %r4, %r4, 4 " ); \ + asm( "addi %r3, %r3, 4 " ); \ + asm( "stw %%r5, %0 " : "=m" (c)); \ + asm( "stw %%r4, %0 " : "=m" (d)); \ + asm( "stw %%r3, %0 " : "=m" (s) :: \ + "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); + +#endif + +#endif /* PPC32 */ +#endif /* PPC64 */ + +#if defined(__sparc__) + +#define MULADDC_INIT \ + asm( "ld %0, %%o0 " :: "m" (s)); \ + asm( "ld %0, %%o1 " :: "m" (d)); \ + asm( "ld %0, %%o2 " :: "m" (c)); \ + asm( "ld %0, %%o3 " :: "m" (b)); + +#define MULADDC_CORE \ + asm( "ld [%o0], %o4 " ); \ + asm( "inc 4, %o0 " ); \ + asm( "ld [%o1], %o5 " ); \ + asm( "umul %o3, %o4, %o4 " ); \ + asm( "addcc %o4, %o2, %o4 " ); \ + asm( "rd %y, %g1 " ); \ + asm( "addx %g1, 0, %g1 " ); \ + asm( "addcc %o4, %o5, %o4 " ); \ + asm( "st %o4, [%o1] " ); \ + asm( "addx %g1, 0, %o2 " ); \ + asm( "inc 4, %o1 " ); + +#define MULADDC_STOP \ + asm( "st %%o2, %0 " : "=m" (c)); \ + asm( "st %%o1, %0 " : "=m" (d)); \ + asm( "st %%o0, %0 " : "=m" (s) :: \ + "g1", "o0", "o1", "o2", "o3", "o4", "o5" ); + +#endif /* SPARCv8 */ + +#if defined(__microblaze__) || defined(microblaze) + +#define MULADDC_INIT \ + asm( "lwi r3, %0 " :: "m" (s)); \ + asm( "lwi r4, %0 " :: "m" (d)); \ + asm( "lwi r5, %0 " :: "m" (c)); \ + asm( "lwi r6, %0 " :: "m" (b)); \ + asm( "andi r7, r6, 0xffff" ); \ + asm( "bsrli r6, r6, 16 " ); + +#define MULADDC_CORE \ + asm( "lhui r8, r3, 0 " ); \ + asm( "addi r3, r3, 2 " ); \ + asm( "lhui r9, r3, 0 " ); \ + asm( "addi r3, r3, 2 " ); \ + asm( "mul r10, r9, r6 " ); \ + asm( "mul r11, r8, r7 " ); \ + asm( "mul r12, r9, r7 " ); \ + asm( "mul r13, r8, r6 " ); \ + asm( "bsrli r8, r10, 16 " ); \ + asm( "bsrli r9, r11, 16 " ); \ + asm( "add r13, r13, r8 " ); \ + asm( "add r13, r13, r9 " ); \ + asm( "bslli r10, r10, 16 " ); \ + asm( "bslli r11, r11, 16 " ); \ + asm( "add r12, r12, r10 " ); \ + asm( "addc r13, r13, r0 " ); \ + asm( "add r12, r12, r11 " ); \ + asm( "addc r13, r13, r0 " ); \ + asm( "lwi r10, r4, 0 " ); \ + asm( "add r12, r12, r10 " ); \ + asm( "addc r13, r13, r0 " ); \ + asm( "add r12, r12, r5 " ); \ + asm( "addc r5, r13, r0 " ); \ + asm( "swi r12, r4, 0 " ); \ + asm( "addi r4, r4, 4 " ); + +#define MULADDC_STOP \ + asm( "swi r5, %0 " : "=m" (c)); \ + asm( "swi r4, %0 " : "=m" (d)); \ + asm( "swi r3, %0 " : "=m" (s) :: \ + "r3", "r4" , "r5" , "r6" , "r7" , "r8" , \ + "r9", "r10", "r11", "r12", "r13" ); + +#endif /* MicroBlaze */ + +#if defined(__tricore__) + +#define MULADDC_INIT \ + asm( "ld.a %%a2, %0 " :: "m" (s)); \ + asm( "ld.a %%a3, %0 " :: "m" (d)); \ + asm( "ld.w %%d4, %0 " :: "m" (c)); \ + asm( "ld.w %%d1, %0 " :: "m" (b)); \ + asm( "xor %d5, %d5 " ); + +#define MULADDC_CORE \ + asm( "ld.w %d0, [%a2+] " ); \ + asm( "madd.u %e2, %e4, %d0, %d1 " ); \ + asm( "ld.w %d0, [%a3] " ); \ + asm( "addx %d2, %d2, %d0 " ); \ + asm( "addc %d3, %d3, 0 " ); \ + asm( "mov %d4, %d3 " ); \ + asm( "st.w [%a3+], %d2 " ); + +#define MULADDC_STOP \ + asm( "st.w %0, %%d4 " : "=m" (c)); \ + asm( "st.a %0, %%a3 " : "=m" (d)); \ + asm( "st.a %0, %%a2 " : "=m" (s) :: \ + "d0", "d1", "e2", "d4", "a2", "a3" ); + +#endif /* TriCore */ + +#if defined(__arm__) + +#define MULADDC_INIT \ + asm( "ldr r0, %0 " :: "m" (s)); \ + asm( "ldr r1, %0 " :: "m" (d)); \ + asm( "ldr r2, %0 " :: "m" (c)); \ + asm( "ldr r3, %0 " :: "m" (b)); + +#define MULADDC_CORE \ + asm( "ldr r4, [r0], #4 " ); \ + asm( "mov r5, #0 " ); \ + asm( "ldr r6, [r1] " ); \ + asm( "umlal r2, r5, r3, r4 " ); \ + asm( "adds r7, r6, r2 " ); \ + asm( "adc r2, r5, #0 " ); \ + asm( "str r7, [r1], #4 " ); + +#define MULADDC_STOP \ + asm( "str r2, %0 " : "=m" (c)); \ + asm( "str r1, %0 " : "=m" (d)); \ + asm( "str r0, %0 " : "=m" (s) :: \ + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" ); + +#endif /* ARMv3 */ + +#if defined(__alpha__) + +#define MULADDC_INIT \ + asm( "ldq $1, %0 " :: "m" (s)); \ + asm( "ldq $2, %0 " :: "m" (d)); \ + asm( "ldq $3, %0 " :: "m" (c)); \ + asm( "ldq $4, %0 " :: "m" (b)); + +#define MULADDC_CORE \ + asm( "ldq $6, 0($1) " ); \ + asm( "addq $1, 8, $1 " ); \ + asm( "mulq $6, $4, $7 " ); \ + asm( "umulh $6, $4, $6 " ); \ + asm( "addq $7, $3, $7 " ); \ + asm( "cmpult $7, $3, $3 " ); \ + asm( "ldq $5, 0($2) " ); \ + asm( "addq $7, $5, $7 " ); \ + asm( "cmpult $7, $5, $5 " ); \ + asm( "stq $7, 0($2) " ); \ + asm( "addq $2, 8, $2 " ); \ + asm( "addq $6, $3, $3 " ); \ + asm( "addq $5, $3, $3 " ); + +#define MULADDC_STOP \ + asm( "stq $3, %0 " : "=m" (c)); \ + asm( "stq $2, %0 " : "=m" (d)); \ + asm( "stq $1, %0 " : "=m" (s) :: \ + "$1", "$2", "$3", "$4", "$5", "$6", "$7" ); + +#endif /* Alpha */ + +#if defined(__mips__) + +#define MULADDC_INIT \ + asm( "lw $10, %0 " :: "m" (s)); \ + asm( "lw $11, %0 " :: "m" (d)); \ + asm( "lw $12, %0 " :: "m" (c)); \ + asm( "lw $13, %0 " :: "m" (b)); + +#define MULADDC_CORE \ + asm( "lw $14, 0($10) " ); \ + asm( "multu $13, $14 " ); \ + asm( "addi $10, $10, 4 " ); \ + asm( "mflo $14 " ); \ + asm( "mfhi $9 " ); \ + asm( "addu $14, $12, $14 " ); \ + asm( "lw $15, 0($11) " ); \ + asm( "sltu $12, $14, $12 " ); \ + asm( "addu $15, $14, $15 " ); \ + asm( "sltu $14, $15, $14 " ); \ + asm( "addu $12, $12, $9 " ); \ + asm( "sw $15, 0($11) " ); \ + asm( "addu $12, $12, $14 " ); \ + asm( "addi $11, $11, 4 " ); + +#define MULADDC_STOP \ + asm( "sw $12, %0 " : "=m" (c)); \ + asm( "sw $11, %0 " : "=m" (d)); \ + asm( "sw $10, %0 " : "=m" (s) :: \ + "$9", "$10", "$11", "$12", "$13", "$14", "$15" ); + +#endif /* MIPS */ +#endif /* GNUC */ + +#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) + +#define MULADDC_INIT \ + __asm mov esi, s \ + __asm mov edi, d \ + __asm mov ecx, c \ + __asm mov ebx, b + +#define MULADDC_CORE \ + __asm lodsd \ + __asm mul ebx \ + __asm add eax, ecx \ + __asm adc edx, 0 \ + __asm add eax, [edi] \ + __asm adc edx, 0 \ + __asm mov ecx, edx \ + __asm stosd + +#define MULADDC_STOP \ + __asm mov c, ecx \ + __asm mov d, edi \ + __asm mov s, esi \ + +#if defined(XYSSL_HAVE_SSE2) + +#define EMIT __asm _emit + +#define MULADDC_HUIT \ + EMIT 0x0F EMIT 0x6E EMIT 0xC9 \ + EMIT 0x0F EMIT 0x6E EMIT 0xC3 \ + EMIT 0x0F EMIT 0x6E EMIT 0x1F \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ + EMIT 0x0F EMIT 0x6E EMIT 0x16 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \ + EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \ + EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \ + EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \ + EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCA \ + EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xDC \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xEE \ + EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \ + EMIT 0x0F EMIT 0xD4 EMIT 0xFC \ + EMIT 0x0F EMIT 0x7E EMIT 0x0F \ + EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ + EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \ + EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCD \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCF \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCA \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCC \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \ + EMIT 0x0F EMIT 0xD4 EMIT 0xDD \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCE \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \ + EMIT 0x83 EMIT 0xC7 EMIT 0x20 \ + EMIT 0x83 EMIT 0xC6 EMIT 0x20 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0x7E EMIT 0xC9 + +#endif /* SSE2 */ +#endif /* MSVC */ + +//#endif /* XYSSL_HAVE_ASM */ + +#if !defined(MULADDC_CORE) +#if defined(XYSSL_HAVE_LONGLONG) + +#define MULADDC_INIT \ +{ \ + t_dbl r; \ + t_int r0, r1; + +#define MULADDC_CORE \ + r = *(s++) * (t_dbl) b; \ + r0 = r; \ + r1 = r >> biL; \ + r0 += c; r1 += (r0 < c); \ + r0 += *d; r1 += (r0 < *d); \ + c = r1; *(d++) = r0; + +#define MULADDC_STOP \ +} + +#else +#define MULADDC_INIT \ +{ \ + t_int s0, s1, b0, b1; \ + t_int r0, r1, rx, ry; \ + b0 = ( b << biH ) >> biH; \ + b1 = ( b >> biH ); + +#define MULADDC_CORE \ + s0 = ( *s << biH ) >> biH; \ + s1 = ( *s >> biH ); s++; \ + rx = s0 * b1; r0 = s0 * b0; \ + ry = s1 * b0; r1 = s1 * b1; \ + r1 += ( rx >> biH ); \ + r1 += ( ry >> biH ); \ + rx <<= biH; ry <<= biH; \ + r0 += rx; r1 += (r0 < rx); \ + r0 += ry; r1 += (r0 < ry); \ + r0 += c; r1 += (r0 < c); \ + r0 += *d; r1 += (r0 < *d); \ + c = r1; *(d++) = r0; + +#define MULADDC_STOP \ +} + +#endif /* C (generic) */ +#endif /* C (longlong) */ + +#endif /* bn_mul.h */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/include/hmac.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/include/hmac.h new file mode 100644 index 0000000000..4bcdda6752 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/include/hmac.h @@ -0,0 +1,41 @@ +/* $OpenBSD: hmac.h,v 1.2 2008/09/06 22:23:20 djm Exp $ */ + +/*- + * Copyright (c) 2008 Damien Bergamini + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/** + * Modified for XMHF. + */ + +#ifndef _HMAC_H_ +#define _HMAC_H_ + +#ifndef __ASSEMBLY__ + +typedef struct _HMAC_SHA1_CTX { + SHA_CTX ctx; + uint8_t key[SHA_DIGEST_LENGTH]; + unsigned int key_len; +} HMAC_SHA1_CTX; + +void HMAC_SHA1_Init(HMAC_SHA1_CTX *, const uint8_t *, unsigned int); +void HMAC_SHA1_Update(HMAC_SHA1_CTX *, const uint8_t *, unsigned int); +void HMAC_SHA1_Final(uint8_t [SHA_DIGEST_LENGTH], HMAC_SHA1_CTX *); +void HMAC_SHA1(const uint8_t *key, uint32_t keylen, + const uint8_t *msg, uint32_t len, + uint8_t md[SHA_DIGEST_LENGTH]); +#endif //__ASSEMBLY__ + +#endif /* _HMAC_H_ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/include/rsa.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/include/rsa.h new file mode 100644 index 0000000000..4e0e5fa2fe --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/include/rsa.h @@ -0,0 +1,326 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/** + * \file rsa.h + */ +#ifndef XYSSL_RSA_H +#define XYSSL_RSA_H + +#include "bignum.h" + +#define XYSSL_ERR_RSA_BAD_INPUT_DATA -0x0400 +#define XYSSL_ERR_RSA_INVALID_PADDING -0x0410 +#define XYSSL_ERR_RSA_KEY_GEN_FAILED -0x0420 +#define XYSSL_ERR_RSA_KEY_CHECK_FAILED -0x0430 +#define XYSSL_ERR_RSA_PUBLIC_FAILED -0x0440 +#define XYSSL_ERR_RSA_PRIVATE_FAILED -0x0450 +#define XYSSL_ERR_RSA_VERIFY_FAILED -0x0460 + +/* + * PKCS#1 constants + */ +#define RSA_RAW 0 +#define RSA_MD2 2 +#define RSA_MD4 3 +#define RSA_MD5 4 +#define RSA_SHA1 5 +#define RSA_SHA256 6 + +#define RSA_PUBLIC 0 +#define RSA_PRIVATE 1 + +#define RSA_PKCS_V15 0 +#define RSA_PKCS_V21 1 + +#define RSA_SIGN 1 +#define RSA_CRYPT 2 + +/* + * DigestInfo ::= SEQUENCE { + * digestAlgorithm DigestAlgorithmIdentifier, + * digest Digest } + * + * DigestAlgorithmIdentifier ::= AlgorithmIdentifier + * + * Digest ::= OCTET STRING + */ +#define ASN1_HASH_MDX \ + "\x30\x20\x30\x0C\x06\x08\x2A\x86\x48" \ + "\x86\xF7\x0D\x02\x00\x05\x00\x04\x10" + +#define ASN1_HASH_SHA1 \ + "\x30\x21\x30\x09\x06\x05\x2B\x0E\x03" \ + "\x02\x1A\x05\x00\x04\x14" + +/** + * \brief RSA context structure + */ +typedef struct +{ + int ver; /*!< always 0 */ + int len; /*!< size(N) in chars */ + + mpi N; /*!< public modulus */ + mpi E; /*!< public exponent */ + + mpi D; /*!< private exponent */ + mpi P; /*!< 1st prime factor */ + mpi Q; /*!< 2nd prime factor */ + mpi DP; /*!< D % (P - 1) */ + mpi DQ; /*!< D % (Q - 1) */ + mpi QP; /*!< 1 / (Q % P) */ + + mpi RN; /*!< cached R^2 mod N */ + mpi RP; /*!< cached R^2 mod P */ + mpi RQ; /*!< cached R^2 mod Q */ + + int padding; /*!< 1.5 or OAEP/PSS */ + int hash_id; /*!< hash identifier */ +} +rsa_context; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Initialize an RSA context + * + * \param ctx RSA context to be initialized + * \param padding RSA_PKCS_V15 or RSA_PKCS_V21 + * \param hash_id RSA_PKCS_V21 hash identifier + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \note The hash_id parameter is actually ignored + * when using RSA_PKCS_V15 padding. + * + * \note Currently (xyssl-0.8), RSA_PKCS_V21 padding + * is not supported. + */ +void rsa_init( rsa_context *ctx, + int padding, + int hash_id); + +/** + * \brief Generate an RSA keypair + * + * \param ctx RSA context that will hold the key + * \param nbits size of the public key in bits + * \param exponent public exponent (e.g., 65537) + * + * \note rsa_init() must be called beforehand to setup + * the RSA context (especially f_rng and p_rng). + * + * \return 0 if successful, or an XYSSL_ERR_RSA_XXX error code + */ +int rsa_gen_key( rsa_context *ctx, int nbits, int exponent ); + +/** + * \brief Check a public RSA key + * + * \param ctx RSA context to be checked + * + * \return 0 if successful, or an XYSSL_ERR_RSA_XXX error code + */ +int rsa_check_pubkey( rsa_context *ctx ); + +/** + * \brief Check a private RSA key + * + * \param ctx RSA context to be checked + * + * \return 0 if successful, or an XYSSL_ERR_RSA_XXX error code + */ +int rsa_check_privkey( rsa_context *ctx ); + +/** + * \brief Do an RSA public key operation + * + * \param ctx RSA context + * \param input input buffer + * \param output output buffer + * + * \return 0 if successful, or an XYSSL_ERR_RSA_XXX error code + * + * \note This function does NOT take care of message + * padding. Also, be sure to set input[0] = 0. + * + * \note The input and output buffers must be large + * enough (eg. 128 bytes if RSA-1024 is used). + */ +int rsa_public( rsa_context *ctx, + unsigned char *input, + unsigned char *output ); + +/** + * \brief Do an RSA private key operation + * + * \param ctx RSA context + * \param input input buffer + * \param output output buffer + * + * \return 0 if successful, or an XYSSL_ERR_RSA_XXX error code + * + * \note The input and output buffers must be large + * enough (eg. 128 bytes if RSA-1024 is used). + */ +int rsa_private( rsa_context *ctx, + unsigned char *input, + unsigned char *output ); + +#if 0 +/** + * \brief Add the message padding, then do an RSA operation + * + * \param ctx RSA context + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param ilen contains the the plaintext length + * \param input buffer holding the data to be encrypted + * \param output buffer that will hold the ciphertext + * + * \return 0 if successful, or an XYSSL_ERR_RSA_XXX error code + * + * \note The output buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + */ +int rsa_pkcs1_encrypt( rsa_context *ctx, + int mode, int ilen, + unsigned char *input, + unsigned char *output ); + +#endif + +/** + * \brief Do an RSA operation, then remove the message padding + * + * \param ctx RSA context + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param input buffer holding the encrypted data + * \param output buffer that will hold the plaintext + * \param olen will contain the plaintext length + * + * \return 0 if successful, or an XYSSL_ERR_RSA_XXX error code + * + * \note The output buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + */ +int rsa_pkcs1_decrypt( rsa_context *ctx, + int mode, int *olen, + unsigned char *input, + unsigned char *output ); + +/** + * \brief Do a private RSA to sign a message digest + * + * \param ctx RSA context + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param hash_id RSA_RAW, RSA_MD{2,4,5} or RSA_SHA{1,256} + * \param hashlen message digest length (for RSA_RAW only) + * \param hash buffer holding the message digest + * \param sig buffer that will hold the ciphertext + * + * \return 0 if the signing operation was successful, + * or an XYSSL_ERR_RSA_XXX error code + * + * \note The "sig" buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + */ +int rsa_pkcs1_sign( rsa_context *ctx, + int mode, + int hash_id, + int hashlen, + unsigned char *hash, + unsigned char *sig ); + +/** + * \brief Do a public RSA and check the message digest + * + * \param ctx points to an RSA public key + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param hash_id RSA_RAW, RSA_MD{2,4,5} or RSA_SHA{1,256} + * \param hashlen message digest length (for RSA_RAW only) + * \param hash buffer holding the message digest + * \param sig buffer holding the ciphertext + * + * \return 0 if the verify operation was successful, + * or an XYSSL_ERR_RSA_XXX error code + * + * \note The "sig" buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + */ +int rsa_pkcs1_verify( rsa_context *ctx, + int mode, + int hash_id, + int hashlen, + unsigned char *hash, + unsigned char *sig ); + +/** + * \brief Free the components of an RSA key + */ +void rsa_free( rsa_context *ctx ); + + +/** + * add by yanlin at March 7 + * \todo sign the pcr in tpm_quote + * \input see rsa_pkcs1_sign + * \note the key is constant and defined in rsa.c file + */ + +int tpm_pkcs1_sign(rsa_context *ctx, + int datalen, + unsigned char *data_addr, + unsigned char *sig ); + + +#ifdef __cplusplus +} +#endif + +#endif /* rsa.h */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/include/sha1.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/include/sha1.h new file mode 100644 index 0000000000..eae0433069 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/include/sha1.h @@ -0,0 +1,59 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef __SHA1_H__ +#define __SHA1_H__ + +#define SHA1_RESULTLEN (160/8) +#define SHA_DIGEST_LENGTH SHA1_RESULTLEN + +int sha1_buffer(const unsigned char *buffer, size_t len, + unsigned char md[SHA_DIGEST_LENGTH]); + +// utility function to perform a SHA-1 hash and print result +void hashandprint(const char* prefix, const u8 *bytes, size_t len); + +#endif /* __SHA1_H__ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/sha1_buffer.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/sha1_buffer.c new file mode 100644 index 0000000000..d15c91b058 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfcrypto/sha1_buffer.c @@ -0,0 +1,64 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include +#include + +#include + +int sha1_buffer(const unsigned char *buffer, size_t len, + unsigned char md[SHA_DIGEST_LENGTH]) +{ + int rv=0; + hash_state hs; + + EU_CHKN( rv = sha1_init( &hs)); + EU_CHKN( rv = sha1_process( &hs, buffer, len)); + EU_CHKN( rv = sha1_done( &hs, md)); + + out: + return rv; +} diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/Makefile b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/Makefile new file mode 100644 index 0000000000..4972bfb87a --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/Makefile @@ -0,0 +1,31 @@ +srcdir := $(dir $(lastword $(MAKEFILE_LIST))) +vpath %.c $(srcdir) + +C_SOURCES:= $(wildcard $(srcdir)/*.c) +C_SOURCES:= $(patsubst $(srcdir)/%, %, $(C_SOURCES)) +OBJECTS = $(patsubst %.c, %.o, $(C_SOURCES)) + +I_SOURCES := $(wildcard $(srcdir)/include/*.h) + +CFLAGS += -I$(srcdir)/../libemhfc/include -I$(srcdir)/include -nostdinc -fno-builtin -nostdlib -Wall + +THE_ARCHIVE = libemhfutil.a + +# targets +.PHONY: all +all: $(THE_ARCHIVE) + +$(THE_ARCHIVE): $(OBJECTS) + $(AR) -rcs $(THE_ARCHIVE) $(OBJECTS) + +#%.o: %.c $(C_SOURCES) $(I_SOURCES) Makefile ../Makefile +# $(CC) -c $(CFLAGS) -o $@ $< + +.PHONY: clean +clean: + $(RM) $(OBJECTS) $(THE_ARCHIVE) + +.PHONY: install-dev +install-dev: + # Nothing to do here + diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/cmdline.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/cmdline.c new file mode 100644 index 0000000000..8e0676c622 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/cmdline.c @@ -0,0 +1,173 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * cmdline.c: command line parsing fns + * + * Copyright (c) 2006-2010, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/** + * Modified for XMHF. + */ + +#include +#include + +const char* cmdline_get_option_val(const cmdline_option_t *options, + char vals[][MAX_VALUE_LEN], + const char *opt_name) +{ + int i; + for ( i = 0; options[i].name != NULL; i++ ) { + if ( strcmp(options[i].name, opt_name) == 0 ) + return vals[i]; + } + printf("requested unknown option: %s\n", opt_name); + return NULL; +} + +void cmdline_parse(const char *cmdline, const cmdline_option_t *options, + char vals[][MAX_VALUE_LEN]) +{ + const char *p = cmdline; + int i; + + /* copy default values to vals[] */ + for ( i = 0; options[i].name != NULL; i++ ) { + strncpy(vals[i], options[i].def_val, MAX_VALUE_LEN-1); + vals[i][MAX_VALUE_LEN-1] = '\0'; + } + + if ( p == NULL ) + return; + + /* parse options */ + while ( true ) + { + /* skip whitespace */ + while ( isspace(*p) ) + p++; + if ( *p == '\0' ) + break; + + { + /* find end of current option */ + const char *opt_start = p; + const char *opt_end = strchr(opt_start, ' '); + if ( opt_end == NULL ) + opt_end = opt_start + strlen(opt_start); + p = opt_end; + + { + /* find value part; if no value found, use default and continue */ + const char *val_start = strchr(opt_start, '='); + if ( val_start == NULL || val_start > opt_end ) + continue; + val_start++; + + { + unsigned int opt_name_size = val_start - opt_start - 1; + unsigned int copy_size = opt_end - val_start; + if ( copy_size > MAX_VALUE_LEN - 1 ) + copy_size = MAX_VALUE_LEN - 1; + if ( opt_name_size == 0 || copy_size == 0 ) + continue; + + /* value found, so copy it */ + for ( i = 0; options[i].name != NULL; i++ ) { + if ( strncmp(options[i].name, opt_start, opt_name_size ) == 0 ) { + strncpy(vals[i], val_start, copy_size); + vals[i][copy_size] = '\0'; /* add '\0' to the end of string */ + break; + } + } + } + } + } + } +} + + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/hpt.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/hpt.c new file mode 100644 index 0000000000..e1eae7d8ea --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/hpt.c @@ -0,0 +1,799 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include +#include "hpt_internal.h" + +/* page map sizes, in bytes. note that zero index is invalid. */ +const u16 hpt_pm_sizes[HPT_TYPE_NUM][HPT_MAX_LEVEL+1] = + { + [HPT_TYPE_NORM] = {0, HPT_PM_SIZE, HPT_PM_SIZE, 0, 0}, + [HPT_TYPE_PAE] = {0, HPT_PM_SIZE, HPT_PM_SIZE, 4*sizeof(hpt_pme_t), 0}, + [HPT_TYPE_LONG] = {0, HPT_PM_SIZE, HPT_PM_SIZE, HPT_PM_SIZE, HPT_PM_SIZE }, + [HPT_TYPE_EPT] = {0, HPT_PM_SIZE, HPT_PM_SIZE, HPT_PM_SIZE, HPT_PM_SIZE }, + }; + +/* page map alignments, in bytes. note that zero index is invalid. */ +const u16 hpt_pm_alignments[HPT_TYPE_NUM][HPT_MAX_LEVEL+1] = + { + [HPT_TYPE_NORM] = { 0, HPT_PM_SIZE, HPT_PM_SIZE, 0, 0}, + [HPT_TYPE_PAE] = { 0, HPT_PM_SIZE, HPT_PM_SIZE, 32, 0}, + [HPT_TYPE_LONG] = { 0, HPT_PM_SIZE, HPT_PM_SIZE, HPT_PM_SIZE, 1 }, + [HPT_TYPE_EPT] = { 0, HPT_PM_SIZE, HPT_PM_SIZE, HPT_PM_SIZE, HPT_PM_SIZE }, + }; + +/* high bit of va used to index into the page map of the given level. + * we treat level '0' specially here, so that the low bit of the index + * can consistently be found by looking up the entry for 'level-1'. + */ +const u8 hpt_va_idx_hi[HPT_TYPE_NUM][HPT_MAX_LEVEL+1] = + { + [HPT_TYPE_NORM] = { 11, 21, 31, 0, 0}, + [HPT_TYPE_PAE] = { 11, 20, 29, 31, 0}, + [HPT_TYPE_LONG] = { 11, 20, 29, 38, 47}, + [HPT_TYPE_EPT] = { 11, 20, 29, 38, 47}, + }; + +/* Number of levels in the paging. */ +const u8 hpt_type_max_lvl[HPT_TYPE_NUM] = + { + [HPT_TYPE_NORM] = 2, + [HPT_TYPE_PAE] = 3, + [HPT_TYPE_LONG] = 4, + [HPT_TYPE_EPT] = 4, + }; + +/* Get page map size */ +size_t hpt_pm_size(hpt_type_t t, int lvl) +{ + size_t rv; + assert(lvl <= HPT_MAX_LEVEL); + rv = hpt_pm_sizes[t][lvl]; + assert(rv != 0); + return rv; +} + +/* Change address bits in cr3 */ +u64 hpt_cr3_set_address(hpt_type_t t, u64 cr3, hpt_pa_t a) +{ + if (t==HPT_TYPE_NORM) { + cr3 = BR64_COPY_BITS_HL(cr3, a, HPT_CR3_PML2_NORM_HI, HPT_CR3_PML2_NORM_LO, 0); + cr3 = BR64_COPY_BITS_HL(cr3, 0, HPT_CR3_MBZ11_NORM_HI, HPT_CR3_MBZ11_NORM_LO, 0); + cr3 = BR64_COPY_BITS_HL(cr3, 0, HPT_CR3_MBZ2_HI, HPT_CR3_MBZ2_LO, 0); + } else if (t==HPT_TYPE_PAE) { + cr3 = BR64_COPY_BITS_HL(cr3, a, HPT_CR3_PML3_PAE_HI, HPT_CR3_PML3_PAE_LO, 0); + cr3 = BR64_COPY_BITS_HL(cr3, 0, HPT_CR3_MBZ2_HI, HPT_CR3_MBZ2_LO, 0); + } else if (t==HPT_TYPE_LONG) { + cr3 = BR64_COPY_BITS_HL(cr3, a, HPT_CR3_PML4_LONG_HI, HPT_CR3_PML4_LONG_LO, 0); + } else if (t==HPT_TYPE_EPT) { + assert(0); /* N\A. set EPTP ptr */ + } else { + assert(0); + } + return cr3; +} + +/* Get address bits in cr3 */ +hpt_pa_t hpt_cr3_get_address(hpt_type_t t, u64 cr3) +{ + if (t==HPT_TYPE_NORM) { + return BR64_COPY_BITS_HL(0, cr3, HPT_CR3_PML2_NORM_HI, HPT_CR3_PML2_NORM_LO, 0); + } else if (t==HPT_TYPE_PAE) { + return BR64_COPY_BITS_HL(0, cr3, HPT_CR3_PML3_PAE_HI, HPT_CR3_PML3_PAE_LO, 0); + } else if (t==HPT_TYPE_LONG) { + return BR64_COPY_BITS_HL(0, cr3, HPT_CR3_PML4_LONG_HI, HPT_CR3_PML4_LONG_LO, 0); + } else if (t==HPT_TYPE_EPT) { + assert(0); /* N\A. set EPTP ptr */ + } else { + assert(0); + } + assert(0); return (hpt_pa_t)0; /* unreachable; appeases compiler */ +} + +/* Change address bits in eptp */ +u64 hpt_eptp_set_address(hpt_type_t t, u64 eptp, hpt_pa_t a) +{ + assert(t == HPT_TYPE_EPT); + return BR64_COPY_BITS_HL(eptp, a, HPT_EPTP_PML4_HI, HPT_EPTP_PML4_LO, 0); +} + +/* Get address bits in eptp */ +hpt_pa_t hpt_eptp_get_address(hpt_type_t t, u64 eptp) +{ + assert(t == HPT_TYPE_EPT); + return BR64_COPY_BITS_HL(0, eptp, HPT_EPTP_PML4_HI, HPT_EPTP_PML4_LO, 0); +} + +/* + * Check whether perms is valid for paging type t and level lvl. + * (e.g. HPT_TYPE_NORM does not support executable bit, so there is no RW). + * This function assumes lvl is valid for the given type t. + */ +bool hpt_prot_is_valid(hpt_type_t t, int lvl, hpt_prot_t perms) +{ + /* consider making this a table lookup. however, if perms is passed + a compile-time constant, the compiler should constant fold this + whole function to the corresponding constant output. */ + return + (t == HPT_TYPE_NORM) + ? (perms == HPT_PROTS_NONE + || perms == HPT_PROTS_RX + || perms == HPT_PROTS_RWX) + : (t == HPT_TYPE_PAE) + ? ((perms == HPT_PROTS_NONE + || perms == HPT_PROTS_RWX + || (((lvl != HPT_LVL_PDPT3) && + (perms == HPT_PROTS_R)) + || (perms == HPT_PROTS_RX) + || (perms == HPT_PROTS_RW)))) + : (t == HPT_TYPE_LONG) + ? (perms == HPT_PROTS_NONE + || perms == HPT_PROTS_R + || perms == HPT_PROTS_RX + || perms == HPT_PROTS_RW + || perms == HPT_PROTS_RWX) + : (t == HPT_TYPE_EPT) + ? (true) + : (false); +} + +/* Check whether level lvl is valid for paging type t. */ +bool hpt_lvl_is_valid(hpt_type_t t, int lvl) +{ + return lvl <= hpt_type_max_lvl[t]; +} + +/* Check whether paging type t is valid. */ +bool hpt_type_is_valid(hpt_type_t t) +{ + return t < HPT_TYPE_NUM; +} + +/* Get root page table level for paging type t. */ +int hpt_root_lvl(hpt_type_t t) +{ + assert(hpt_type_is_valid(t)); + return hpt_type_max_lvl[t]; +} + +/* + * Change the user / supervisor bit (U/S) in entry. + * EPT does not have U/S bit, so must be accessible. + */ +hpt_pme_t hpt_pme_setuser(hpt_type_t t, int lvl, hpt_pme_t entry, bool user_accessible) +{ + if (t == HPT_TYPE_NORM) { + return BR64_SET_BIT(entry, HPT_NORM_US_L21_MP_BIT, user_accessible); + } else if (t == HPT_TYPE_PAE) { + if (lvl == 3) { + assert(user_accessible); + return entry; + } else { + return BR64_SET_BIT(entry, HPT_PAE_US_L21_MP_BIT, user_accessible); + } + } else if (t == HPT_TYPE_LONG) { + return BR64_SET_BIT(entry, HPT_LONG_US_L4321_MP_BIT, user_accessible); + } else if (t == HPT_TYPE_EPT) { + assert(user_accessible); + return entry; + } + assert(0); return 0; /* unreachable; appeases compiler */ +} + +/* Get the user / supervisor bit (U/S) in entry. */ +bool hpt_pme_getuser(hpt_type_t t, int lvl, hpt_pme_t entry) +{ + if (t == HPT_TYPE_NORM) { + return BR64_GET_BIT(entry, HPT_NORM_US_L21_MP_BIT); + } else if (t == HPT_TYPE_PAE) { + if (lvl == 3) { + return true; + } else { + return BR64_GET_BIT(entry, HPT_PAE_US_L21_MP_BIT); + } + } else if (t == HPT_TYPE_LONG) { + return BR64_GET_BIT(entry, HPT_LONG_US_L4321_MP_BIT); + } else if (t == HPT_TYPE_EPT) { + return true; + } + assert(0); return false; /* unreachable; appeases compiler */ +} + +/* Change the protection bits (R, W, X) in entry. */ +hpt_pme_t hpt_pme_setprot(hpt_type_t t, int lvl, hpt_pme_t entry, hpt_prot_t perms) +{ + hpt_pme_t rv=entry; + assert(hpt_lvl_is_valid(t, lvl)); + assert(hpt_prot_is_valid(t, lvl, perms)); + + if (t == HPT_TYPE_NORM) { + rv = BR64_SET_BIT(rv, HPT_NORM_P_L21_MP_BIT, perms & HPT_PROT_READ_MASK); + rv = BR64_SET_BIT(rv, HPT_NORM_RW_L21_MP_BIT, perms & HPT_PROT_WRITE_MASK); + } else if (t == HPT_TYPE_PAE) { + rv = BR64_SET_BIT(rv, HPT_PAE_P_L321_MP_BIT, perms & HPT_PROT_READ_MASK); + if (lvl == 2 || lvl == 1) { + rv = BR64_SET_BIT(rv, HPT_PAE_RW_L21_MP_BIT, perms & HPT_PROT_WRITE_MASK); + rv = BR64_SET_BIT(rv, HPT_PAE_NX_L21_MP_BIT, !(perms & HPT_PROT_EXEC_MASK)); + } + } else if (t == HPT_TYPE_LONG) { + rv = BR64_SET_BIT(rv, HPT_LONG_P_L4321_MP_BIT, perms & HPT_PROT_READ_MASK); + rv = BR64_SET_BIT(rv, HPT_LONG_RW_L4321_MP_BIT, perms & HPT_PROT_WRITE_MASK); + rv = BR64_SET_BIT(rv, HPT_LONG_NX_L4321_MP_BIT, !(perms & HPT_PROT_EXEC_MASK)); + } else if (t == HPT_TYPE_EPT) { + rv = BR64_SET_BR(rv, HPT_EPT_PROT_L4321_MP, perms); + } else { + assert(0); + } + + return rv; +} + +/* Get the protection bits (R, W, X) in entry. */ +hpt_prot_t hpt_pme_getprot(hpt_type_t t, int lvl, hpt_pme_t entry) +{ + hpt_prot_t rv=HPT_PROTS_NONE; + bool r,w,x; + assert(hpt_lvl_is_valid(t, lvl)); + + if (t == HPT_TYPE_NORM) { + r= entry & MASKBIT64(HPT_NORM_P_L21_MP_BIT); + w= entry & MASKBIT64(HPT_NORM_RW_L21_MP_BIT); + x= r; + } else if (t == HPT_TYPE_PAE) { + r= entry & MASKBIT64(HPT_PAE_P_L321_MP_BIT); + if (lvl == 2 || lvl == 1) { + w= entry & MASKBIT64(HPT_PAE_RW_L21_MP_BIT); + x= !(entry & MASKBIT64(HPT_PAE_NX_L21_MP_BIT));; + } else { + w=r; + x=r; + } + } else if (t == HPT_TYPE_LONG) { + r=entry & MASKBIT64(HPT_LONG_P_L4321_MP_BIT); + w=entry & MASKBIT64(HPT_LONG_RW_L4321_MP_BIT); + x=!(entry & MASKBIT64(HPT_LONG_NX_L4321_MP_BIT)); + } else if (t == HPT_TYPE_EPT) { + r=entry & MASKBIT64(HPT_EPT_R_L4321_MP_BIT); + w=entry & MASKBIT64(HPT_EPT_W_L4321_MP_BIT); + x=entry & MASKBIT64(HPT_EPT_X_L4321_MP_BIT); + } else { + assert(0); + } + rv = HPT_PROTS_NONE; + rv = rv | (r ? HPT_PROT_READ_MASK : 0); + rv = rv | (w ? HPT_PROT_WRITE_MASK : 0); + rv = rv | (x ? HPT_PROT_EXEC_MASK : 0); + + return rv; +} + +/* Change the bits not used by hardware in entry. */ +hpt_pme_t hpt_pme_setunused(hpt_type_t t, int lvl, hpt_pme_t entry, int hi, int lo, hpt_pme_t val) +{ + hpt_pme_t rv=entry; + assert(hi>lo); + HPT_UNUSED_ARGUMENT(lvl); + + /* bits 9, 10, and 11 are unused in all levels of all current page + types. For convenience and simplicity we map those to\from bits 2-0. + + If we need more unused bits, for some page table types and levels other + bits are available. + */ + + if(t == HPT_TYPE_NORM + || t == HPT_TYPE_PAE + || t == HPT_TYPE_LONG + || t == HPT_TYPE_EPT) { + assert(hi <= 2); /* we can remove this limitation for some table + types and levels if necessary. */ + rv = BR64_COPY_BITS_HL(rv, val, MIN(2,hi), MAX(0,lo), (9-0)); + } else { + assert(0); + } + return rv; +} + +/* Get the bits not used by hardware in entry. */ +hpt_pme_t hpt_pme_getunused(hpt_type_t t, int lvl, hpt_pme_t entry, int hi, int lo) +{ + hpt_pme_t rv = 0ull; + assert(hi>lo); + HPT_UNUSED_ARGUMENT(lvl); + + if(t == HPT_TYPE_NORM + || t == HPT_TYPE_PAE + || t == HPT_TYPE_LONG + || t == HPT_TYPE_EPT) { + assert(hi <= 2); /* we can remove this limitation for some table + types and levels if necessary. */ + rv = BR64_COPY_BITS_HL(rv, entry, MIN(2,hi), MAX(0,lo), (9-0)); + rv = BR64_GET_HL(entry, MIN(2,hi)+9, MAX(0,lo)+9); + } else { + assert(0); + } + return rv; +} + +/* Get the present bit in entry. */ +bool hpt_pme_is_present(hpt_type_t t, int lvl, hpt_pme_t entry) +{ + /* a valid entry is present iff read access is enabled. */ + return hpt_pme_getprot(t, lvl, entry) & HPT_PROT_READ_MASK; +} + +/* + * Check whether entry points to a page (otherwise, point to a page table). + * For example, in 32-bit paging, when PDE.PS = 1, it points to a 4MB page + * (this function returns true). When PDE.PS = 0, it points to a page table + * (this function returns false). + */ +bool hpt_pme_is_page(hpt_type_t t, int lvl, hpt_pme_t entry) +{ + if (t== HPT_TYPE_NORM) { + assert(lvl<=2); + return lvl == 1 || (lvl==2 && BR64_GET_BIT(entry, HPT_NORM_PS_L2_MP_BIT)); + } else if (t == HPT_TYPE_PAE) { + assert(lvl<=3); + return lvl == 1 || (lvl==2 && BR64_GET_BIT(entry, HPT_PAE_PS_L2_MP_BIT)); + } else if (t == HPT_TYPE_LONG) { + assert(lvl<=4); + return lvl == 1 || ((lvl==2 || lvl==3) && BR64_GET_BIT(entry, HPT_LONG_PS_L32_MP_BIT)); + } else if (t == HPT_TYPE_EPT) { + assert(lvl<=4); + return lvl == 1 || ((lvl==2 || lvl==3) && BR64_GET_BIT(entry, HPT_EPT_PS_L32_MP_BIT)); + } else { + assert(0); + return false; + } +} + +/* Get the physical address (of page / page table) pointed by entry. */ +hpt_pa_t hpt_pme_get_address(hpt_type_t t, int lvl, hpt_pme_t entry) +{ + if (t == HPT_TYPE_NORM) { + assert(lvl<=2); + if(lvl==2) { + if (hpt_pme_is_page(t,lvl,entry)) { + /* 4 MB page */ + hpt_pa_t rv = 0; + rv = BR64_COPY_BITS_HL(rv, entry, + 39, 32, + 32-HPT_NORM_ADDR3932_L2_P_LO); + rv = BR64_COPY_BITS_HL(rv, entry, + 31, 22, + 22-HPT_NORM_ADDR3122_L2_P_LO); + return rv; + } else { + return BR64_COPY_BITS_HL(0, entry, + HPT_NORM_ADDR_L2_M_HI, + HPT_NORM_ADDR_L2_M_LO, 0); + } + } else { + return BR64_COPY_BITS_HL(0, entry, + HPT_NORM_ADDR_L1_P_HI, + HPT_NORM_ADDR_L1_P_LO, 0); + } + } else if (t == HPT_TYPE_PAE) { + assert(lvl<=3); + if (hpt_pme_is_page(t, lvl, entry)) { + if (lvl == 1) { + return BR64_COPY_BITS_HL(0, entry, + HPT_PAE_ADDR_L1_P_HI, + HPT_PAE_ADDR_L1_P_LO, 0); + } else { + assert(lvl==2); + return BR64_COPY_BITS_HL(0, entry, + HPT_PAE_ADDR_L2_P_HI, + HPT_PAE_ADDR_L2_P_LO, 0); + } + } else { + return BR64_COPY_BITS_HL(0, entry, + HPT_PAE_ADDR_L321_M_HI, + HPT_PAE_ADDR_L321_M_LO, 0); + } + } else if (t == HPT_TYPE_LONG) { + assert(lvl<=4); + if (hpt_pme_is_page(t, lvl, entry)) { + if(lvl==1) { + return BR64_COPY_BITS_HL(0, entry, + HPT_LONG_ADDR_L1_P_HI, + HPT_LONG_ADDR_L1_P_LO, 0); + } else { + return BR64_COPY_BITS_HL(0, entry, + HPT_LONG_ADDR_L32_P_HI, + HPT_LONG_ADDR_L32_P_LO, 0); + } + } else { + return BR64_COPY_BITS_HL(0, entry, + HPT_LONG_ADDR_L4321_M_HI, + HPT_LONG_ADDR_L4321_M_LO, 0); + } + } else if (t == HPT_TYPE_EPT) { + assert(lvl<=4); + return BR64_COPY_BITS_HL(0, entry, + HPT_EPT_ADDR_L4321_MP_HI, + HPT_EPT_ADDR_L4321_MP_LO, 0); + } else { + assert(0); + return 0; + } +} + +/* Set the physical address (of page / page table) pointed by entry. */ +hpt_pme_t hpt_pme_set_address(hpt_type_t t, int lvl, hpt_pme_t entry, hpt_pa_t addr) +{ + if (t == HPT_TYPE_NORM) { + assert(lvl<=2); + if(lvl==2) { + if (hpt_pme_is_page(t,lvl,entry)) { + hpt_pme_t rv = entry; + /* 4 MB page */ + rv = BR64_COPY_BITS_HL(entry, addr, + HPT_NORM_ADDR3932_L2_P_HI, + HPT_NORM_ADDR3932_L2_P_LO, + HPT_NORM_ADDR3932_L2_P_LO-32); + rv = BR64_COPY_BITS_HL(entry, addr, + HPT_NORM_ADDR3122_L2_P_HI, + HPT_NORM_ADDR3122_L2_P_LO, + HPT_NORM_ADDR3122_L2_P_LO-22); + return rv; + } else { + return BR64_COPY_BITS_HL(entry, addr, + HPT_NORM_ADDR_L2_M_HI, + HPT_NORM_ADDR_L2_M_LO, 0); + } + } else { + return BR64_COPY_BITS_HL(entry, addr, + HPT_NORM_ADDR_L1_P_HI, + HPT_NORM_ADDR_L1_P_LO, 0); + } + } else if (t == HPT_TYPE_PAE) { + assert(lvl<=3); + if (hpt_pme_is_page(t, lvl, entry)) { + if (lvl == 1) { + return BR64_COPY_BITS_HL(entry, addr, + HPT_PAE_ADDR_L1_P_HI, + HPT_PAE_ADDR_L1_P_LO, 0); + } else { + assert(lvl==2); + return BR64_COPY_BITS_HL(entry, addr, + HPT_PAE_ADDR_L2_P_HI, + HPT_PAE_ADDR_L2_P_LO, 0); + } + } else { + return BR64_COPY_BITS_HL(entry, addr, + HPT_PAE_ADDR_L321_M_HI, + HPT_PAE_ADDR_L321_M_LO, 0); + } + } else if (t == HPT_TYPE_LONG) { + assert(lvl<=4); + if (hpt_pme_is_page(t, lvl, entry)) { + if(lvl==1) { + return BR64_COPY_BITS_HL(entry, addr, + HPT_LONG_ADDR_L1_P_HI, + HPT_LONG_ADDR_L1_P_LO, 0); + } else { + return BR64_COPY_BITS_HL(entry, addr, + HPT_LONG_ADDR_L32_P_HI, + HPT_LONG_ADDR_L32_P_LO, 0); + } + } else { + return BR64_COPY_BITS_HL(entry, addr, + HPT_LONG_ADDR_L4321_M_HI, + HPT_LONG_ADDR_L4321_M_LO, 0); + } + } else if (t == HPT_TYPE_EPT) { + assert(lvl<=4); + return BR64_COPY_BITS_HL(entry, addr, + HPT_EPT_ADDR_L4321_MP_HI, + HPT_EPT_ADDR_L4321_MP_LO, 0); + } else { + assert(0); + return 0; + } +} + +/* Set the PAT (page attribute table) bit in entry. */ +/* "internal". use hpt_pme_set_pmt instead */ +static hpt_pme_t hpt_pme_set_pat(hpt_type_t t, int lvl, hpt_pme_t pme, bool pat) +{ + hpt_pme_t rv; + if (t == HPT_TYPE_NORM) { + rv = pme; + if (hpt_pme_is_page(t, lvl, pme) && lvl==1) { + rv = BR64_SET_BIT(rv, HPT_NORM_PAT_L1_P_BIT, pat); + } else if (hpt_pme_is_page(t, lvl, pme) && lvl==2) { + rv = BR64_SET_BIT(rv, HPT_NORM_PAT_L2_P_BIT, pat); + } else { + assert(!pat); + } + } else if (t== HPT_TYPE_PAE) { + rv = pme; + if (hpt_pme_is_page(t, lvl, pme) && lvl==1) { + rv = BR64_SET_BIT(rv, HPT_PAE_PAT_L1_P_BIT, pat); + } else if (hpt_pme_is_page(t, lvl, pme) && lvl==2) { + rv = BR64_SET_BIT(rv, HPT_PAE_PAT_L2_P_BIT, pat); + } else { + assert(!pat); + } + } else if (t==HPT_TYPE_LONG) { + rv = pme; + if (hpt_pme_is_page(t, lvl, pme) && lvl==1) { + rv = BR64_SET_BIT(rv, HPT_LONG_PAT_L1_P_BIT, pat); + } else if (hpt_pme_is_page(t, lvl, pme) && (lvl==2||lvl==3)) { + rv = BR64_SET_BIT(rv, HPT_LONG_PAT_L32_P_BIT, pat); + } else { + assert(!pat); + } + } else { + assert(0); + } + return rv; +} + +/* Get the PAT (page attribute table) bit in entry. */ +/* "internal". use hpt_pme_get_pmt instead */ +static bool hpt_pme_get_pat(hpt_type_t t, int lvl, hpt_pme_t pme) __attribute__((unused)); +static bool hpt_pme_get_pat(hpt_type_t t, int lvl, hpt_pme_t pme) +{ + if (t == HPT_TYPE_NORM) { + if (hpt_pme_is_page(t, lvl, pme) && lvl==1) { + return BR64_GET_BIT(pme, HPT_NORM_PAT_L1_P_BIT); + } else if (hpt_pme_is_page(t, lvl, pme) && lvl==2) { + return BR64_GET_BIT(pme, HPT_NORM_PAT_L2_P_BIT); + } else { + return false; + } + } else if (t== HPT_TYPE_PAE) { + if (hpt_pme_is_page(t, lvl, pme) && lvl==1) { + return BR64_GET_BIT(pme, HPT_PAE_PAT_L1_P_BIT); + } else if (hpt_pme_is_page(t, lvl, pme) && lvl==2) { + return BR64_GET_BIT(pme, HPT_PAE_PAT_L2_P_BIT); + } else { + return false; + } + } else if (t==HPT_TYPE_LONG) { + if (hpt_pme_is_page(t, lvl, pme) && lvl==1) { + return BR64_GET_BIT(pme, HPT_LONG_PAT_L1_P_BIT); + } else if (hpt_pme_is_page(t, lvl, pme) && (lvl==2||lvl==3)) { + return BR64_GET_BIT(pme, HPT_LONG_PAT_L32_P_BIT); + } else { + return false; + } + } else { + assert(0); + } + return pme; +} + +/* Get the PCD (page-level cache disable) bit in entry. */ +/* "internal". use hpt_pme_get_pmt instead */ +static bool hpt_pme_get_pcd(hpt_type_t t, int __attribute__((unused)) lvl, hpt_pme_t pme) +{ + if (t == HPT_TYPE_NORM) { + return BR64_GET_BIT(pme, HPT_NORM_PCD_L21_MP_BIT); + } else if (t== HPT_TYPE_PAE) { + return BR64_GET_BIT(pme, HPT_PAE_PCD_L321_MP_BIT); + } else if (t==HPT_TYPE_LONG) { + return BR64_GET_BIT(pme, HPT_LONG_PCD_L4321_MP_BIT); + } else { + assert(0); + } + assert(0); return false; /* unreachable; appeases compiler */ +} + +/* Set the PCD (page-level cache disable) bit in entry. */ +/* "internal". use hpt_pme_set_pmt instead */ +static hpt_pme_t hpt_pme_set_pcd(hpt_type_t t, int __attribute__((unused)) lvl, hpt_pme_t pme, bool pcd) +{ + if (t == HPT_TYPE_NORM) { + return BR64_SET_BIT(pme, HPT_NORM_PCD_L21_MP_BIT, pcd); + } else if (t== HPT_TYPE_PAE) { + return BR64_SET_BIT(pme, HPT_PAE_PCD_L321_MP_BIT, pcd); + } else if (t==HPT_TYPE_LONG) { + return BR64_SET_BIT(pme, HPT_LONG_PCD_L4321_MP_BIT, pcd); + } else { + assert(0); + } + assert(0); return (hpt_pme_t)0; /* unreachable; appeases compiler */ +} + +/* Get the PWT (page-level write-through) bit in entry. */ +/* "internal". use hpt_pme_get_pmt instead */ +static bool hpt_pme_get_pwt(hpt_type_t t, int __attribute__((unused)) lvl, hpt_pme_t pme) +{ + if (t == HPT_TYPE_NORM) { + return BR64_GET_BIT(pme, HPT_NORM_PWT_L21_MP_BIT); + } else if (t== HPT_TYPE_PAE) { + return BR64_GET_BIT(pme, HPT_PAE_PWT_L321_MP_BIT); + } else if (t==HPT_TYPE_LONG) { + return BR64_GET_BIT(pme, HPT_LONG_PWT_L4321_MP_BIT); + } else { + assert(0); + } + assert(0); return false; /* unreachable; appeases compiler */ +} + +/* Set the PWT (page-level write-through) bit in entry. */ +/* "internal". use hpt_pme_set_pmt instead */ +static hpt_pme_t hpt_pme_set_pwt(hpt_type_t t, int __attribute__((unused)) lvl, hpt_pme_t pme, bool pwt) +{ + if (t == HPT_TYPE_NORM) { + return BR64_SET_BIT(pme, HPT_NORM_PWT_L21_MP_BIT, pwt); + } else if (t== HPT_TYPE_PAE) { + return BR64_SET_BIT(pme, HPT_PAE_PWT_L321_MP_BIT, pwt); + } else if (t==HPT_TYPE_LONG) { + return BR64_SET_BIT(pme, HPT_LONG_PWT_L4321_MP_BIT, pwt); + } else { + assert(0); + } + assert(0); return (hpt_pme_t)0; /* unreachable; appeases compiler */ +} + +/* Get the memory type (e.g. uncached, write back) of entry. */ +/* Assumes PAT register has default values */ +hpt_pmt_t hpt_pme_get_pmt(hpt_type_t t, int lvl, hpt_pme_t pme) +{ + hpt_pmt_t rv; + if (t == HPT_TYPE_EPT) { + assert(lvl <= 3 && hpt_pme_is_page(t, lvl, pme)); + rv = BR64_GET_HL(pme, HPT_EPT_MT_L321_P_HI, HPT_EPT_MT_L321_P_LO); + } else if (t == HPT_TYPE_PAE || t == HPT_TYPE_LONG || t == HPT_TYPE_NORM) { + bool pcd, pwt; + pcd = hpt_pme_get_pcd(t, lvl, pme); + pwt = hpt_pme_get_pwt(t, lvl, pme); + if (!pcd && !pwt) { + return HPT_PMT_WB; + } else if (!pcd && pwt) { + return HPT_PMT_WT; + } else if (pcd && !pwt) { + return HPT_PMT_WC; /* really UC- unless overriden by mtrr */ + } else if (pcd && pwt) { + return HPT_PMT_UC; + } else { + assert(0); /* Not implemented? */ + } + } else { + assert(0); + } + return rv; +} + +/* Set the memory type (e.g. uncached, write back) of entry. */ +/* Always clears PAT bit when applicable. */ +hpt_pmt_t hpt_pme_set_pmt(hpt_type_t t, int lvl, hpt_pme_t pme, hpt_pmt_t pmt) +{ + hpt_pme_t rv; + if (t == HPT_TYPE_EPT) { + assert(lvl <= 3 && hpt_pme_is_page(t, lvl, pme)); + rv = BR64_SET_HL(pme, HPT_EPT_MT_L321_P_HI, HPT_EPT_MT_L321_P_LO, pmt); + } else if (t == HPT_TYPE_NORM || t == HPT_TYPE_PAE || t == HPT_TYPE_LONG) { + bool pat, pcd, pwt; + pat=0; + if (pmt == HPT_PMT_UC) { + pcd=1; + pwt=1; + } else if (pmt == HPT_PMT_WC) { + pcd=1; + pwt=0; /* this is actually 'UC-'. can be overriden to WC by setting MTRR */ + } else if (pmt == HPT_PMT_WT) { + pcd=0; + pwt=1; + } else if (pmt == HPT_PMT_WP) { + assert(0); /* can only get this by manipulating PAT register */ + } else if (pmt == HPT_PMT_WB) { + pcd=0; + pwt=0; + } else { + assert(0); + } + rv = pme; + rv = hpt_pme_set_pat(t, lvl, rv, pat); + rv = hpt_pme_set_pcd(t, lvl, rv, pcd); + rv = hpt_pme_set_pwt(t, lvl, rv, pwt); + } else { + assert(0); + } + return rv; +} + +/* + * Get index in a page table for virtual address va. + * For example, when resolving the first level of 32-bit paging, this function + * returns the 31-22 bits of VA (i.e. index to PDE). + */ +unsigned int hpt_get_pm_idx(hpt_type_t t, int lvl, hpt_va_t va) +{ + unsigned int lo; + unsigned int hi; + assert(hpt_type_is_valid(t)); + assert(hpt_lvl_is_valid(t, lvl)); + + hi = hpt_va_idx_hi[t][lvl]; + lo = hpt_va_idx_hi[t][lvl-1]+1; + + return BR64_GET_HL(va, hi, lo); +} + +/* Get a page table entry in a page table (pm) using its index (idx). */ +hpt_pme_t hpt_pm_get_pme_by_idx(hpt_type_t t, int lvl, hpt_pm_t pm, int idx) +{ + HPT_UNUSED_ARGUMENT(lvl); + if(t == HPT_TYPE_EPT || t == HPT_TYPE_PAE || t == HPT_TYPE_LONG) { + return ((u64*)pm)[idx]; + } else if (t == HPT_TYPE_NORM) { + return ((u32*)pm)[idx]; + } else { + assert(0); + return 0; + } +} + +/* Set a page table entry (pme) in a page table (pm) using its index (idx). */ +void hpt_pm_set_pme_by_idx(hpt_type_t t, int lvl, hpt_pm_t pm, int idx, hpt_pme_t pme) +{ + HPT_UNUSED_ARGUMENT(lvl); + if(t == HPT_TYPE_EPT || t == HPT_TYPE_PAE || t == HPT_TYPE_LONG) { + ((u64*)pm)[idx] = pme; + } else if (t == HPT_TYPE_NORM) { + ((u32*)pm)[idx] = pme; + } else { + assert(0); + } +} + +/* Get page table entry in page table (pm) using virtual address (va). */ +hpt_pme_t hpt_pm_get_pme_by_va(hpt_type_t t, int lvl, hpt_pm_t pm, hpt_va_t va) +{ + return hpt_pm_get_pme_by_idx(t, lvl, pm, hpt_get_pm_idx(t, lvl, va)); +} + +/* Set page table entry (pme) in page table (pm) using virtual address (va). */ +void hpt_pm_set_pme_by_va(hpt_type_t t, int lvl, hpt_pm_t pm, hpt_va_t va, hpt_pme_t pme) +{ + hpt_pm_set_pme_by_idx(t, lvl, pm, hpt_get_pm_idx(t, lvl, va), pme); +} diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/hpt_internal.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/hpt_internal.c new file mode 100644 index 0000000000..657d92ba0f --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/hpt_internal.c @@ -0,0 +1,613 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include +#include "hpt_internal.h" + +hpt_pme_t hpt_pme_setuser(hpt_type_t t, int lvl, hpt_pme_t entry, bool user_accessible) +{ + if (t == HPT_TYPE_NORM) { + return BR64_SET_BIT(entry, HPT_NORM_US_L21_MP_BIT, user_accessible); + } else if (t == HPT_TYPE_PAE) { + if (lvl == 3) { + assert(user_accessible); + return entry; + } else { + return BR64_SET_BIT(entry, HPT_PAE_US_L21_MP_BIT, user_accessible); + } + } else if (t == HPT_TYPE_LONG) { + return BR64_SET_BIT(entry, HPT_LONG_US_L4321_MP_BIT, user_accessible); + } else if (t == HPT_TYPE_EPT) { + assert(user_accessible); + return entry; + } + assert(0); return 0; /* unreachable; appeases compiler */ +} + +bool hpt_pme_getuser(hpt_type_t t, int lvl, hpt_pme_t entry) +{ + if (t == HPT_TYPE_NORM) { + return BR64_GET_BIT(entry, HPT_NORM_US_L21_MP_BIT); + } else if (t == HPT_TYPE_PAE) { + if (lvl == 3) { + return true; + } else { + return BR64_GET_BIT(entry, HPT_PAE_US_L21_MP_BIT); + } + } else if (t == HPT_TYPE_LONG) { + return BR64_GET_BIT(entry, HPT_LONG_US_L4321_MP_BIT); + } else if (t == HPT_TYPE_EPT) { + return true; + } + assert(0); return false; /* unreachable; appeases compiler */ +} + +hpt_pme_t hpt_pme_setprot(hpt_type_t t, int lvl, hpt_pme_t entry, hpt_prot_t perms) +{ + hpt_pme_t rv=entry; + assert(hpt_lvl_is_valid(t, lvl)); + assert(hpt_prot_is_valid(t, lvl, perms)); + + if (t == HPT_TYPE_NORM) { + rv = BR64_SET_BIT(rv, HPT_NORM_P_L21_MP_BIT, perms & HPT_PROT_READ_MASK); + rv = BR64_SET_BIT(rv, HPT_NORM_RW_L21_MP_BIT, perms & HPT_PROT_WRITE_MASK); + } else if (t == HPT_TYPE_PAE) { + rv = BR64_SET_BIT(rv, HPT_PAE_P_L321_MP_BIT, perms & HPT_PROT_READ_MASK); + if (lvl == 2 || lvl == 1) { + rv = BR64_SET_BIT(rv, HPT_PAE_RW_L21_MP_BIT, perms & HPT_PROT_WRITE_MASK); + rv = BR64_SET_BIT(rv, HPT_PAE_NX_L21_MP_BIT, !(perms & HPT_PROT_EXEC_MASK)); + } + } else if (t == HPT_TYPE_LONG) { + rv = BR64_SET_BIT(rv, HPT_LONG_P_L4321_MP_BIT, perms & HPT_PROT_READ_MASK); + rv = BR64_SET_BIT(rv, HPT_LONG_RW_L4321_MP_BIT, perms & HPT_PROT_WRITE_MASK); + rv = BR64_SET_BIT(rv, HPT_LONG_NX_L4321_MP_BIT, !(perms & HPT_PROT_EXEC_MASK)); + } else if (t == HPT_TYPE_EPT) { + rv = BR64_SET_BR(rv, HPT_EPT_PROT_L4321_MP, perms); + } else { + assert(0); + } + + return rv; +} + +hpt_prot_t hpt_pme_getprot(hpt_type_t t, int lvl, hpt_pme_t entry) +{ + hpt_prot_t rv=HPT_PROTS_NONE; + bool r,w,x; + assert(hpt_lvl_is_valid(t, lvl)); + + if (t == HPT_TYPE_NORM) { + r= entry & MASKBIT64(HPT_NORM_P_L21_MP_BIT); + w= entry & MASKBIT64(HPT_NORM_RW_L21_MP_BIT); + x= r; + } else if (t == HPT_TYPE_PAE) { + r= entry & MASKBIT64(HPT_PAE_P_L321_MP_BIT); + if (lvl == 2 || lvl == 1) { + w= entry & MASKBIT64(HPT_PAE_RW_L21_MP_BIT); + x= !(entry & MASKBIT64(HPT_PAE_NX_L21_MP_BIT));; + } else { + w=r; + x=r; + } + } else if (t == HPT_TYPE_LONG) { + r=entry & MASKBIT64(HPT_LONG_P_L4321_MP_BIT); + w=entry & MASKBIT64(HPT_LONG_RW_L4321_MP_BIT); + x=!(entry & MASKBIT64(HPT_LONG_NX_L4321_MP_BIT)); + } else if (t == HPT_TYPE_EPT) { + r=entry & MASKBIT64(HPT_EPT_R_L4321_MP_BIT); + w=entry & MASKBIT64(HPT_EPT_W_L4321_MP_BIT); + x=entry & MASKBIT64(HPT_EPT_X_L4321_MP_BIT); + } else { + assert(0); + } + rv = HPT_PROTS_NONE; + rv = rv | (r ? HPT_PROT_READ_MASK : 0); + rv = rv | (w ? HPT_PROT_WRITE_MASK : 0); + rv = rv | (x ? HPT_PROT_EXEC_MASK : 0); + + return rv; +} + +hpt_pme_t hpt_pme_setunused(hpt_type_t t, int lvl, hpt_pme_t entry, int hi, int lo, hpt_pme_t val) +{ + hpt_pme_t rv=entry; + assert(hi>lo); + HPT_UNUSED_ARGUMENT(lvl); + + /* bits 9, 10, and 11 are unused in all levels of all current page + types. For convenience and simplicity we map those to\from bits 2-0. + + If we need more unused bits, for some page table types and levels other + bits are available. + */ + + if(t == HPT_TYPE_NORM + || t == HPT_TYPE_PAE + || t == HPT_TYPE_LONG + || t == HPT_TYPE_EPT) { + assert(hi <= 2); /* we can remove this limitation for some table + types and levels if necessary. */ + rv = BR64_COPY_BITS_HL(rv, val, MIN(2,hi), MAX(0,lo), (9-0)); + } else { + assert(0); + } + return rv; +} + +hpt_pme_t hpt_pme_getunused(hpt_type_t t, int lvl, hpt_pme_t entry, int hi, int lo) +{ + hpt_pme_t rv = 0ull; + assert(hi>lo); + HPT_UNUSED_ARGUMENT(lvl); + + if(t == HPT_TYPE_NORM + || t == HPT_TYPE_PAE + || t == HPT_TYPE_LONG + || t == HPT_TYPE_EPT) { + assert(hi <= 2); /* we can remove this limitation for some table + types and levels if necessary. */ + rv = BR64_COPY_BITS_HL(rv, entry, MIN(2,hi), MAX(0,lo), (9-0)); + rv = BR64_GET_HL(entry, MIN(2,hi)+9, MAX(0,lo)+9); + } else { + assert(0); + } + return rv; +} + +bool hpt_pme_is_present(hpt_type_t t, int lvl, hpt_pme_t entry) +{ + /* a valid entry is present iff read access is enabled. */ + return hpt_pme_getprot(t, lvl, entry) & HPT_PROT_READ_MASK; +} + +bool hpt_pme_is_page(hpt_type_t t, int lvl, hpt_pme_t entry) +{ + if (t== HPT_TYPE_NORM) { + assert(lvl<=2); + return lvl == 1 || (lvl==2 && BR64_GET_BIT(entry, HPT_NORM_PS_L2_MP_BIT)); + } else if (t == HPT_TYPE_PAE) { + assert(lvl<=3); + return lvl == 1 || (lvl==2 && BR64_GET_BIT(entry, HPT_PAE_PS_L2_MP_BIT)); + } else if (t == HPT_TYPE_LONG) { + assert(lvl<=3); + return lvl == 1 || ((lvl==2 || lvl==3) && BR64_GET_BIT(entry, HPT_LONG_PS_L32_MP_BIT)); + } else if (t == HPT_TYPE_EPT) { + assert(lvl<=4); + return lvl == 1 || ((lvl==2 || lvl==3) && BR64_GET_BIT(entry, HPT_EPT_PS_L32_MP_BIT)); + } else { + assert(0); + return false; + } +} + +hpt_pa_t hpt_pme_get_address(hpt_type_t t, int lvl, hpt_pme_t entry) +{ + if (t == HPT_TYPE_NORM) { + assert(lvl<=2); + if(lvl==2) { + if (hpt_pme_is_page(t,lvl,entry)) { + /* 4 MB page */ + hpt_pa_t rv = 0; + rv = BR64_COPY_BITS_HL(rv, entry, + 39, 32, + 32-HPT_NORM_ADDR3932_L2_P_LO); + rv = BR64_COPY_BITS_HL(rv, entry, + 31, 22, + 22-HPT_NORM_ADDR3122_L2_P_LO); + return rv; + } else { + return BR64_COPY_BITS_HL(0, entry, + HPT_NORM_ADDR_L2_M_HI, + HPT_NORM_ADDR_L2_M_LO, 0); + } + } else { + return BR64_COPY_BITS_HL(0, entry, + HPT_NORM_ADDR_L1_P_HI, + HPT_NORM_ADDR_L1_P_LO, 0); + } + } else if (t == HPT_TYPE_PAE) { + assert(lvl<=3); + if (hpt_pme_is_page(t, lvl, entry)) { + if (lvl == 1) { + return BR64_COPY_BITS_HL(0, entry, + HPT_PAE_ADDR_L1_P_HI, + HPT_PAE_ADDR_L1_P_LO, 0); + } else { + assert(lvl==2); + return BR64_COPY_BITS_HL(0, entry, + HPT_PAE_ADDR_L2_P_HI, + HPT_PAE_ADDR_L2_P_LO, 0); + } + } else { + return BR64_COPY_BITS_HL(0, entry, + HPT_PAE_ADDR_L321_M_HI, + HPT_PAE_ADDR_L321_M_LO, 0); + } + } else if (t == HPT_TYPE_LONG) { + assert(lvl<=4); + if (hpt_pme_is_page(t, lvl, entry)) { + if(lvl==1) { + return BR64_COPY_BITS_HL(0, entry, + HPT_LONG_ADDR_L1_P_HI, + HPT_LONG_ADDR_L1_P_LO, 0); + } else { + return BR64_COPY_BITS_HL(0, entry, + HPT_LONG_ADDR_L32_P_HI, + HPT_LONG_ADDR_L32_P_LO, 0); + } + } else { + return BR64_COPY_BITS_HL(0, entry, + HPT_LONG_ADDR_L4321_M_HI, + HPT_LONG_ADDR_L4321_M_LO, 0); + } + } else if (t == HPT_TYPE_EPT) { + assert(lvl<=4); + return BR64_COPY_BITS_HL(0, entry, + HPT_EPT_ADDR_L4321_MP_HI, + HPT_EPT_ADDR_L4321_MP_LO, 0); + } else { + assert(0); + return 0; + } +} + +hpt_pme_t hpt_pme_set_address(hpt_type_t t, int lvl, hpt_pme_t entry, hpt_pa_t addr) +{ + if (t == HPT_TYPE_NORM) { + assert(lvl<=2); + if(lvl==2) { + if (hpt_pme_is_page(t,lvl,entry)) { + hpt_pme_t rv = entry; + /* 4 MB page */ + rv = BR64_COPY_BITS_HL(entry, addr, + HPT_NORM_ADDR3932_L2_P_HI, + HPT_NORM_ADDR3932_L2_P_LO, + HPT_NORM_ADDR3932_L2_P_LO-32); + rv = BR64_COPY_BITS_HL(entry, addr, + HPT_NORM_ADDR3122_L2_P_HI, + HPT_NORM_ADDR3122_L2_P_LO, + HPT_NORM_ADDR3122_L2_P_LO-22); + return rv; + } else { + return BR64_COPY_BITS_HL(entry, addr, + HPT_NORM_ADDR_L2_M_HI, + HPT_NORM_ADDR_L2_M_LO, 0); + } + } else { + return BR64_COPY_BITS_HL(entry, addr, + HPT_NORM_ADDR_L1_P_HI, + HPT_NORM_ADDR_L1_P_LO, 0); + } + } else if (t == HPT_TYPE_PAE) { + assert(lvl<=3); + if (hpt_pme_is_page(t, lvl, entry)) { + if (lvl == 1) { + return BR64_COPY_BITS_HL(entry, addr, + HPT_PAE_ADDR_L1_P_HI, + HPT_PAE_ADDR_L1_P_LO, 0); + } else { + assert(lvl==2); + return BR64_COPY_BITS_HL(entry, addr, + HPT_PAE_ADDR_L2_P_HI, + HPT_PAE_ADDR_L2_P_LO, 0); + } + } else { + return BR64_COPY_BITS_HL(entry, addr, + HPT_PAE_ADDR_L321_M_HI, + HPT_PAE_ADDR_L321_M_LO, 0); + } + } else if (t == HPT_TYPE_LONG) { + assert(lvl<=4); + if (hpt_pme_is_page(t, lvl, entry)) { + if(lvl==1) { + return BR64_COPY_BITS_HL(entry, addr, + HPT_LONG_ADDR_L1_P_HI, + HPT_LONG_ADDR_L1_P_LO, 0); + } else { + return BR64_COPY_BITS_HL(entry, addr, + HPT_LONG_ADDR_L32_P_HI, + HPT_LONG_ADDR_L32_P_LO, 0); + } + } else { + return BR64_COPY_BITS_HL(entry, addr, + HPT_LONG_ADDR_L4321_M_HI, + HPT_LONG_ADDR_L4321_M_LO, 0); + } + } else if (t == HPT_TYPE_EPT) { + assert(lvl<=4); + return BR64_COPY_BITS_HL(entry, addr, + HPT_EPT_ADDR_L4321_MP_HI, + HPT_EPT_ADDR_L4321_MP_LO, 0); + } else { + assert(0); + return 0; + } +} + +/* "internal". use hpt_pme_set_pmt instead */ +static hpt_pme_t hpt_pme_set_pat(hpt_type_t t, int lvl, hpt_pme_t pme, bool pat) +{ + hpt_pme_t rv; + if (t == HPT_TYPE_NORM) { + rv = pme; + if (hpt_pme_is_page(t, lvl, pme) && lvl==1) { + rv = BR64_SET_BIT(rv, HPT_NORM_PAT_L1_P_BIT, pat); + } else if (hpt_pme_is_page(t, lvl, pme) && lvl==2) { + rv = BR64_SET_BIT(rv, HPT_NORM_PAT_L2_P_BIT, pat); + } else { + assert(!pat); + } + } else if (t== HPT_TYPE_PAE) { + rv = pme; + if (hpt_pme_is_page(t, lvl, pme) && lvl==1) { + rv = BR64_SET_BIT(rv, HPT_PAE_PAT_L1_P_BIT, pat); + } else if (hpt_pme_is_page(t, lvl, pme) && lvl==2) { + rv = BR64_SET_BIT(rv, HPT_PAE_PAT_L2_P_BIT, pat); + } else { + assert(!pat); + } + } else if (t==HPT_TYPE_LONG) { + rv = pme; + if (hpt_pme_is_page(t, lvl, pme) && lvl==1) { + rv = BR64_SET_BIT(rv, HPT_LONG_PAT_L1_P_BIT, pat); + } else if (hpt_pme_is_page(t, lvl, pme) && (lvl==2||lvl==3)) { + rv = BR64_SET_BIT(rv, HPT_LONG_PAT_L32_P_BIT, pat); + } else { + assert(!pat); + } + } else { + assert(0); + } + return rv; +} + +/* "internal". use hpt_pme_get_pmt instead */ +static bool hpt_pme_get_pat(hpt_type_t t, int lvl, hpt_pme_t pme) __attribute__((unused)); + +static bool hpt_pme_get_pat(hpt_type_t t, int lvl, hpt_pme_t pme) +{ + if (t == HPT_TYPE_NORM) { + if (hpt_pme_is_page(t, lvl, pme) && lvl==1) { + return BR64_GET_BIT(pme, HPT_NORM_PAT_L1_P_BIT); + } else if (hpt_pme_is_page(t, lvl, pme) && lvl==2) { + return BR64_GET_BIT(pme, HPT_NORM_PAT_L2_P_BIT); + } else { + return false; + } + } else if (t== HPT_TYPE_PAE) { + if (hpt_pme_is_page(t, lvl, pme) && lvl==1) { + return BR64_GET_BIT(pme, HPT_PAE_PAT_L1_P_BIT); + } else if (hpt_pme_is_page(t, lvl, pme) && lvl==2) { + return BR64_GET_BIT(pme, HPT_PAE_PAT_L2_P_BIT); + } else { + return false; + } + } else if (t==HPT_TYPE_LONG) { + if (hpt_pme_is_page(t, lvl, pme) && lvl==1) { + return BR64_GET_BIT(pme, HPT_LONG_PAT_L1_P_BIT); + } else if (hpt_pme_is_page(t, lvl, pme) && (lvl==2||lvl==3)) { + return BR64_GET_BIT(pme, HPT_LONG_PAT_L32_P_BIT); + } else { + return false; + } + } else { + assert(0); + } + return pme; +} + +/* "internal". use hpt_pme_get_pmt instead */ +static bool hpt_pme_get_pcd(hpt_type_t t, int __attribute__((unused)) lvl, hpt_pme_t pme) +{ + if (t == HPT_TYPE_NORM) { + return BR64_GET_BIT(pme, HPT_NORM_PCD_L21_MP_BIT); + } else if (t== HPT_TYPE_PAE) { + return BR64_GET_BIT(pme, HPT_PAE_PCD_L321_MP_BIT); + } else if (t==HPT_TYPE_LONG) { + return BR64_GET_BIT(pme, HPT_LONG_PCD_L4321_MP_BIT); + } else { + assert(0); + } + assert(0); return false; /* unreachable; appeases compiler */ +} + +/* "internal". use hpt_pme_set_pmt instead */ +static hpt_pme_t hpt_pme_set_pcd(hpt_type_t t, int __attribute__((unused)) lvl, hpt_pme_t pme, bool pcd) +{ + if (t == HPT_TYPE_NORM) { + return BR64_SET_BIT(pme, HPT_NORM_PCD_L21_MP_BIT, pcd); + } else if (t== HPT_TYPE_PAE) { + return BR64_SET_BIT(pme, HPT_PAE_PCD_L321_MP_BIT, pcd); + } else if (t==HPT_TYPE_LONG) { + return BR64_SET_BIT(pme, HPT_LONG_PCD_L4321_MP_BIT, pcd); + } else { + assert(0); + } + assert(0); return (hpt_pme_t)0; /* unreachable; appeases compiler */ +} + +/* "internal". use hpt_pme_get_pmt instead */ +static bool hpt_pme_get_pwt(hpt_type_t t, int __attribute__((unused)) lvl, hpt_pme_t pme) +{ + if (t == HPT_TYPE_NORM) { + return BR64_GET_BIT(pme, HPT_NORM_PWT_L21_MP_BIT); + } else if (t== HPT_TYPE_PAE) { + return BR64_GET_BIT(pme, HPT_PAE_PWT_L321_MP_BIT); + } else if (t==HPT_TYPE_LONG) { + return BR64_GET_BIT(pme, HPT_LONG_PWT_L4321_MP_BIT); + } else { + assert(0); + } + assert(0); return false; /* unreachable; appeases compiler */ +} + +/* "internal". use hpt_pme_set_pmt instead */ +static hpt_pme_t hpt_pme_set_pwt(hpt_type_t t, int __attribute__((unused)) lvl, hpt_pme_t pme, bool pwt) +{ + if (t == HPT_TYPE_NORM) { + return BR64_SET_BIT(pme, HPT_NORM_PWT_L21_MP_BIT, pwt); + } else if (t== HPT_TYPE_PAE) { + return BR64_SET_BIT(pme, HPT_PAE_PWT_L321_MP_BIT, pwt); + } else if (t==HPT_TYPE_LONG) { + return BR64_SET_BIT(pme, HPT_LONG_PWT_L4321_MP_BIT, pwt); + } else { + assert(0); + } + assert(0); return (hpt_pme_t)0; /* unreachable; appeases compiler */ +} + +/* Assumes PAT register has default values */ +hpt_pmt_t hpt_pme_get_pmt(hpt_type_t t, int lvl, hpt_pme_t pme) +{ + hpt_pmt_t rv; + if (t == HPT_TYPE_EPT) { + assert(lvl <= 3 && hpt_pme_is_page(t, lvl, pme)); + rv = BR64_GET_HL(pme, HPT_EPT_MT_L321_P_HI, HPT_EPT_MT_L321_P_LO); + } else if (t == HPT_TYPE_PAE || t == HPT_TYPE_LONG || t == HPT_TYPE_NORM) { + bool pcd, pwt; + pcd = hpt_pme_get_pcd(t, lvl, pme); + pwt = hpt_pme_get_pwt(t, lvl, pme); + if (!pcd && !pwt) { + return HPT_PMT_WB; + } else if (!pcd && pwt) { + return HPT_PMT_WT; + } else if (pcd && !pwt) { + return HPT_PMT_WC; /* really UC- unless overriden by mtrr */ + } else if (pcd && pwt) { + return HPT_PMT_UC; + } else { + assert(0); /* Not implemented? */ + } + } else { + assert(0); + } + return rv; +} + +/* Always clears PAT bit when applicable. */ +hpt_pmt_t hpt_pme_set_pmt(hpt_type_t t, int lvl, hpt_pme_t pme, hpt_pmt_t pmt) +{ + hpt_pme_t rv; + if (t == HPT_TYPE_EPT) { + assert(lvl <= 3 && hpt_pme_is_page(t, lvl, pme)); + rv = BR64_SET_HL(pme, HPT_EPT_MT_L321_P_HI, HPT_EPT_MT_L321_P_LO, pmt); + } else if (t == HPT_TYPE_NORM || t == HPT_TYPE_PAE || t == HPT_TYPE_LONG) { + bool pat, pcd, pwt; + pat=0; + if (pmt == HPT_PMT_UC) { + pcd=1; + pwt=1; + } else if (pmt == HPT_PMT_WC) { + pcd=1; + pwt=0; /* this is actually 'UC-'. can be overriden to WC by setting MTRR */ + } else if (pmt == HPT_PMT_WT) { + pcd=0; + pwt=1; + } else if (pmt == HPT_PMT_WP) { + assert(0); /* can only get this by manipulating PAT register */ + } else if (pmt == HPT_PMT_WB) { + pcd=0; + pwt=0; + } else { + assert(0); + } + rv = pme; + rv = hpt_pme_set_pat(t, lvl, rv, pat); + rv = hpt_pme_set_pcd(t, lvl, rv, pcd); + rv = hpt_pme_set_pwt(t, lvl, rv, pwt); + } else { + assert(0); + } + return rv; +} + +unsigned int hpt_get_pm_idx(hpt_type_t t, int lvl, hpt_va_t va) +{ + unsigned int lo; + unsigned int hi; + assert(hpt_type_is_valid(t)); + assert(hpt_lvl_is_valid(t, lvl)); + + hi = hpt_va_idx_hi[t][lvl]; + lo = hpt_va_idx_hi[t][lvl-1]+1; + + return BR64_GET_HL(va, hi, lo); +} + +hpt_pme_t hpt_pm_get_pme_by_idx(hpt_type_t t, int lvl, hpt_pm_t pm, int idx) +{ + HPT_UNUSED_ARGUMENT(lvl); + if(t == HPT_TYPE_EPT || t == HPT_TYPE_PAE || t == HPT_TYPE_LONG) { + return ((u64*)pm)[idx]; + } else if (t == HPT_TYPE_NORM) { + return ((u32*)pm)[idx]; + } else { + assert(0); + return 0; + } +} + +void hpt_pm_set_pme_by_idx(hpt_type_t t, int lvl, hpt_pm_t pm, int idx, hpt_pme_t pme) +{ + HPT_UNUSED_ARGUMENT(lvl); + if(t == HPT_TYPE_EPT || t == HPT_TYPE_PAE || t == HPT_TYPE_LONG) { + ((u64*)pm)[idx] = pme; + } else if (t == HPT_TYPE_NORM) { + ((u32*)pm)[idx] = pme; + } else { + assert(0); + } +} + +hpt_pme_t hpt_pm_get_pme_by_va(hpt_type_t t, int lvl, hpt_pm_t pm, hpt_va_t va) +{ + return hpt_pm_get_pme_by_idx(t, lvl, pm, hpt_get_pm_idx(t, lvl, va)); +} + +void hpt_pm_set_pme_by_va(hpt_type_t t, int lvl, hpt_pm_t pm, hpt_va_t va, hpt_pme_t pme) +{ + hpt_pm_set_pme_by_idx(t, lvl, pm, hpt_get_pm_idx(t, lvl, va), pme); +} diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/hpt_internal.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/hpt_internal.h new file mode 100644 index 0000000000..9963b706c8 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/hpt_internal.h @@ -0,0 +1,81 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef HPT_INTERNAL_H +#define HPT_INTERNAL_H + +hpt_pme_t hpt_pme_setuser(hpt_type_t t, int lvl, hpt_pme_t entry, bool user_accessible); +bool hpt_pme_getuser(hpt_type_t t, int lvl, hpt_pme_t entry); + +hpt_pme_t hpt_pme_setprot(hpt_type_t t, int lvl, hpt_pme_t entry, hpt_prot_t perms); +hpt_prot_t hpt_pme_getprot(hpt_type_t t, int lvl, hpt_pme_t entry); + +hpt_pme_t hpt_pme_setunused(hpt_type_t t, int lvl, hpt_pme_t entry, int hi, int lo, hpt_pme_t val); +hpt_pme_t hpt_pme_getunused(hpt_type_t t, int lvl, hpt_pme_t entry, int hi, int lo); + +bool hpt_pme_is_present(hpt_type_t t, int lvl, hpt_pme_t entry); + +bool hpt_pme_is_page(hpt_type_t t, int lvl, hpt_pme_t entry); + +hpt_pa_t hpt_pme_get_address(hpt_type_t t, int lvl, hpt_pme_t entry); + +hpt_pme_t hpt_pme_set_address(hpt_type_t t, int lvl, hpt_pme_t entry, hpt_pa_t addr); + +/* Assumes PAT register has default values */ +hpt_pmt_t hpt_pme_get_pmt(hpt_type_t t, int lvl, hpt_pme_t pme); + +/* Always clears PAT bit when applicable. */ +hpt_pmt_t hpt_pme_set_pmt(hpt_type_t t, int lvl, hpt_pme_t pme, hpt_pmt_t pmt); + +unsigned int hpt_get_pm_idx(hpt_type_t t, int lvl, hpt_va_t va); + +hpt_pme_t hpt_pm_get_pme_by_idx(hpt_type_t t, int lvl, hpt_pm_t pm, int idx); +void hpt_pm_set_pme_by_idx(hpt_type_t t, int lvl, hpt_pm_t pm, int idx, hpt_pme_t pme); + +hpt_pme_t hpt_pm_get_pme_by_va(hpt_type_t t, int lvl, hpt_pm_t pm, hpt_va_t va); +void hpt_pm_set_pme_by_va(hpt_type_t t, int lvl, hpt_pm_t pm, hpt_va_t va, hpt_pme_t pme); + +#endif diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/hpt_log.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/hpt_log.h new file mode 100644 index 0000000000..326fad3241 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/hpt_log.h @@ -0,0 +1,55 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef HPT_LOG_H +#define HPT_LOG_H + +#define EU_LOG_LVL EU_WARN +#define EU_LOG_PREFIX "HPT" +#include +#include + +#endif diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/hpto.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/hpto.c new file mode 100644 index 0000000000..27a7a873d5 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/hpto.c @@ -0,0 +1,179 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include +#include "hpt_internal.h" + +/* Get the physical address (of page / page table) */ +hpt_pa_t hpt_pmeo_get_address(const hpt_pmeo_t *pmeo) +{ + return hpt_pme_get_address(pmeo->t, pmeo->lvl, pmeo->pme); +} + +/* Set the physical address (of page / page table) */ +void hpt_pmeo_set_address(hpt_pmeo_t *pmeo, hpt_pa_t addr) +{ + pmeo->pme = hpt_pme_set_address(pmeo->t, pmeo->lvl, pmeo->pme, addr); +} + +/* Get the present bit */ +bool hpt_pmeo_is_present(const hpt_pmeo_t *pmeo) +{ + return hpt_pme_is_present(pmeo->t, pmeo->lvl, pmeo->pme); +} + +/* + * Check whether entry points to a page (otherwise, point to a page table). + * For example, in 32-bit paging, when PDE.PS = 1, it points to a 4MB page + * (this function returns true). When PDE.PS = 0, it points to a page table + * (this function returns false). + */ +bool hpt_pmeo_is_page(const hpt_pmeo_t *pmeo) +{ + return hpt_pme_is_page(pmeo->t, pmeo->lvl, pmeo->pme); +} + +/* Change the protection bits (R, W, X) */ +void hpt_pmeo_setprot(hpt_pmeo_t *pmeo, hpt_prot_t perms) +{ + pmeo->pme = hpt_pme_setprot(pmeo->t, pmeo->lvl, pmeo->pme, perms); +} + +/* Get the protection bits (R, W, X) */ +hpt_prot_t hpt_pmeo_getprot(const hpt_pmeo_t *pmeo) +{ + return hpt_pme_getprot(pmeo->t, pmeo->lvl, pmeo->pme); +} + +/* Set the memory type (e.g. uncached, write back) */ +void hpt_pmeo_setcache(hpt_pmeo_t *pmeo, hpt_pmt_t pmt) +{ + pmeo->pme = hpt_pme_set_pmt(pmeo->t, pmeo->lvl, pmeo->pme, pmt); +} + +/* Get the user / supervisor bit (U/S) */ +bool hpt_pmeo_getuser(const hpt_pmeo_t *pmeo) +{ + return hpt_pme_getuser(pmeo->t, pmeo->lvl, pmeo->pme); +} + +/* Change the user / supervisor bit (U/S) */ +void hpt_pmeo_setuser(hpt_pmeo_t *pmeo, bool user) +{ + pmeo->pme = hpt_pme_setuser(pmeo->t, pmeo->lvl, pmeo->pme, user); +} + +/* Get page table entry in page table (pm) using virtual address (va) */ +void hpt_pm_get_pmeo_by_va(hpt_pmeo_t *pmeo, const hpt_pmo_t *pmo, hpt_va_t va) +{ + pmeo->t = pmo->t; + pmeo->lvl = pmo->lvl; + pmeo->pme = hpt_pm_get_pme_by_va(pmo->t, pmo->lvl, pmo->pm, va); +} + +/* Set page table entry (pme) in page table (pm) using virtual address (va) */ +void hpt_pmo_set_pme_by_va(hpt_pmo_t *pmo, const hpt_pmeo_t *pmeo, hpt_va_t va) +{ + hpt_pm_set_pme_by_va(pmo->t, pmo->lvl, pmo->pm, va, pmeo->pme); +} + +/* + * Get the physical address of virtual address (va), pmeo is the last level of + * page table entry. + * For example, in 32-bit paging with 4K pages, pmeo is the page table entry, + * va=0x12345678, then pa=0xabcde678. + */ +hpt_pa_t hpt_pmeo_va_to_pa(hpt_pmeo_t* pmeo, hpt_va_t va) +{ + hpt_pa_t base; + hpt_pa_t offset; + int offset_hi; + + assert(hpt_pme_is_page(pmeo->t, pmeo->lvl, pmeo->pme)); + base = hpt_pmeo_get_address(pmeo); + + offset_hi = hpt_va_idx_hi[pmeo->t][pmeo->lvl-1]; + offset = va & MASKRANGE64(offset_hi, 0); + return base + offset; +} + +/* + * Get the log2 of size region controlled by the page map entry. + * For example, in 32-bit paging, PDE's size is log(4M) = 22, PTE's size is + * log(4K) = 12. + */ +size_t hpt_pmeo_page_size_log_2(const hpt_pmeo_t *pmeo) +{ + int offset_hi; + offset_hi = hpt_va_idx_hi[pmeo->t][pmeo->lvl-1]; + return offset_hi+1; +} + +/* + * Get the size region controlled by the page map entry. + * For example, in 32-bit paging, PDE's size 4M, PTE's size is 4K. + */ +size_t hpt_pmeo_page_size(const hpt_pmeo_t *pmeo) +{ + return 1 << hpt_pmeo_page_size_log_2(pmeo); +} + +/* + * Get the number of bytes from va to page boundary. + * For example, in 32-bit paging with 4K pages, when va=0x12345678, this + * function returns 0x1000 - 0x678 = 0x988. + */ +size_t hpt_remaining_on_page(const hpt_pmeo_t *pmeo, hpt_va_t va) +{ + size_t offset_on_page; + size_t page_size; + size_t page_size_log_2; + + page_size_log_2 = hpt_pmeo_page_size_log_2(pmeo); + page_size = 1 << page_size_log_2; + offset_on_page = va & MASKRANGE64(page_size_log_2-1, 0); + return page_size - offset_on_page; +} diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/hptw.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/hptw.c new file mode 100644 index 0000000000..9f46923e98 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/hptw.c @@ -0,0 +1,558 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include +#include +#include /* for memset */ + +#include "hpt_log.h" + +/* + * Get the root page map object (pmo) for context (ctx) + * For example, in 32-bit paging it gives the PDE pointed to by CR3 + */ +static int hptw_get_root( hptw_ctx_t *ctx, hpt_pmo_t *pmo) +{ + int lvl = hpt_type_max_lvl[ ctx->t]; + size_t pm_sz = hpt_pm_size( ctx->t, lvl); + size_t avail; + hpt_pm_t pm; + int err = 1; + + pm = ctx->pa2ptr( ctx, + ctx->root_pa, + pm_sz, + HPT_PROTS_RW, + HPTW_CPL0, + &avail); + EU_CHK( pm); + EU_CHK( avail == pm_sz); + + *pmo = (hpt_pmo_t) { + .t = ctx->t, + .pm = pm, + .lvl = lvl, + }; + + err = 0; + out: + return err; +} + +/* + * Insert page map entry object (pmeo) to context (ctx) at virtual address (va). + * For example, in 32-bit paging, if pmeo is a page table entry (PTE), this + * function will walk the page directory to find the page table, then change + * the page table entry. + */ +int hptw_insert_pmeo(hptw_ctx_t *ctx, + const hpt_pmeo_t *pmeo, + hpt_va_t va) +{ + hpt_pmo_t pmo; + int err = 1; + + hptw_get_pmo( &pmo, ctx, pmeo->lvl, va); + EU_CHK( pmo.pm); + EU_CHK( pmo.lvl == pmeo->lvl); + + hpt_pmo_set_pme_by_va( &pmo, pmeo, va); + + err = 0; + out: + return err; +} + +/* + * Get the page map object (pmo) at level (end_lvl) to context (ctx) at virtual + * address (va), allocate empty page tables if needed. + */ +int hptw_get_pmo_alloc(hpt_pmo_t *pmo, + hptw_ctx_t *ctx, + int end_lvl, + hpt_va_t va) +{ + int err = 1; + + EU_CHKN( hptw_get_root( ctx, pmo)); + + while(pmo->lvl > end_lvl) { + hpt_pmeo_t pmeo; + hpt_pm_get_pmeo_by_va(&pmeo, pmo, va); + EU_CHK( !hpt_pmeo_is_page(&pmeo)); + + if (!hpt_pmeo_is_present(&pmeo)) { + hpt_pm_t pm; + hpt_pmo_t new_pmo; + + EU_CHK( pm = ctx->gzp(ctx, + HPT_PM_SIZE, /*FIXME*/ + hpt_pm_size(pmo->t, pmo->lvl-1))); + new_pmo = (hpt_pmo_t) { + .pm = pm, + .lvl = pmo->lvl-1, + .t = pmo->t, + }; + hpt_pmeo_set_address(&pmeo, ctx->ptr2pa(ctx, new_pmo.pm)); + hpt_pmeo_setprot( &pmeo, HPT_PROTS_RWX); + hpt_pmeo_setuser( &pmeo, true); + + hpt_pmo_set_pme_by_va(pmo, &pmeo, va); + } + { + bool walked_next_lvl; + walked_next_lvl = hptw_next_lvl(ctx, pmo, va); + assert(walked_next_lvl); + } + } + + err = 0; + out: + return err; +} + +/* + * Insert page map entry object (pmeo) to context (ctx) at virtual address (va), + * allocate empty page tables if needed. + */ +int hptw_insert_pmeo_alloc(hptw_ctx_t *ctx, + const hpt_pmeo_t *pmeo, + hpt_va_t va) +{ + hpt_pmo_t pmo; + int err=1; + + EU_CHKN( hptw_get_pmo_alloc( &pmo, ctx, pmeo->lvl, va)); + EU_CHK( pmo.pm); + EU_CHK( pmo.lvl == pmeo->lvl); + + hpt_pmo_set_pme_by_va(&pmo, pmeo, va); + + err=0; + out: + return err; +} + +/* + * Get the page map object (pmo) at level (end_lvl) to context (ctx) at virtual + * address (va). + */ +void hptw_get_pmo( hpt_pmo_t *pmo, + hptw_ctx_t *ctx, + int end_lvl, + hpt_va_t va) +{ + int err=1; + EU_CHKN( hptw_get_root( ctx, pmo)); + while (pmo->lvl > end_lvl + && hptw_next_lvl(ctx, pmo, va)); + err=0; + out: + EU_VERIFYN( err); /* XXX */ +} + +/* + * Get the page map entry object (pmeo) at level (end_lvl) to context (ctx) at + * virtual address (va). + */ +void hptw_get_pmeo(hpt_pmeo_t *pmeo, + hptw_ctx_t *ctx, + int end_lvl, + hpt_va_t va) +{ + hpt_pmo_t end_pmo; + hptw_get_pmo(&end_pmo, ctx, end_lvl, va); + hpt_pm_get_pmeo_by_va(pmeo, &end_pmo, va); +} + +/* + * In context (ctx) when walking page table for virtual address (va), descent + * the page map object (pmo) one level down. + * For example, in 32-bit paging, if pmo points to a page directory when + * calling this function, it will point to a page table after calling. + */ +bool hptw_next_lvl(hptw_ctx_t *ctx, hpt_pmo_t *pmo, hpt_va_t va) +{ + hpt_pmeo_t pmeo; + hpt_pm_get_pmeo_by_va(&pmeo, pmo, va); + + assert(pmo->pm); + + if (!hpt_pmeo_is_present(&pmeo) + || hpt_pmeo_is_page(&pmeo)) { + eu_trace("at leaf. is-present:%d is-page:%d", + hpt_pmeo_is_present(&pmeo), hpt_pmeo_is_page(&pmeo)); + return false; + } else { + size_t avail; + size_t pm_sz = hpt_pm_size(pmo->t, pmo->lvl-1); + pmo->pm = ctx->pa2ptr(ctx, hpt_pmeo_get_address(&pmeo), + pm_sz, HPT_PROTS_R, HPTW_CPL0, &avail); + eu_trace("next-lvl:%d pm-sz:%d pmo->pm:%p avail:%d", + pmo->lvl-1, pm_sz, pmo->pm, avail); + if(!pmo->pm) { + /* didn't descend, and this is an error. we ran into trouble + accessing the page tables themselves, which should only + happen if the entity that set up the page tables, whether the + guest OS or the hypervisor, is buggy or malicious */ + pmo->t = HPT_TYPE_INVALID; + pmo->lvl = 0; + return false; + } + assert(avail == pm_sz); /* this could in principle be false if, + e.g., a host page table has a smaller + page size than the size of the given + page map. we don't handle this + case. will never happen with current + x86 page types */ + pmo->lvl--; + return true; + } +} + +/* + * Returns the effective protections for the given address, which is + * the lowest permissions for the page walk. Also sets + * *user_accessible if not NULL and if the virtual address is set + * user-accessible. + * According to hardware, this is usually the logical AND for the permission + * bits in all levels of page map entries during the page table walk. + */ +hpt_prot_t hptw_get_effective_prots(hptw_ctx_t *ctx, + hpt_va_t va, + bool *user_accessible) +{ + hpt_prot_t prots_rv = HPT_PROTS_RWX; + bool user_accessible_rv = true; + hpt_pmo_t pmo; + int err = 1; + + EU_CHKN( hptw_get_root( ctx, &pmo)); + + do { + hpt_pmeo_t pmeo; + hpt_pm_get_pmeo_by_va(&pmeo, &pmo, va); + prots_rv &= hpt_pmeo_getprot(&pmeo); + user_accessible_rv = user_accessible_rv && hpt_pmeo_getuser(&pmeo); + } while (hptw_next_lvl(ctx, &pmo, va)); + + /* XXX should more clearly indicate an error */ + EU_CHK( pmo.t != HPT_TYPE_INVALID); + + if(user_accessible != NULL) { + *user_accessible = user_accessible_rv; + } + + err=0; + out: + if (err) { + prots_rv = HPT_PROTS_NONE; + } + return prots_rv; +} + +/* Set protection bits (prot) for a virtual address (va) in context (ctx) */ +void hptw_set_prot(hptw_ctx_t *ctx, + hpt_va_t va, + hpt_prot_t prot) +{ + hpt_pmo_t pmo; + hpt_pmeo_t pmeo; + + hptw_get_pmo (&pmo, ctx, 1, va); + assert (pmo.pm); + assert (pmo.lvl == 1); + + hpt_pm_get_pmeo_by_va (&pmeo, &pmo, va); + hpt_pmeo_setprot (&pmeo, prot); + hpt_pmo_set_pme_by_va (&pmo, &pmeo, va); +} + +/* + * Translate virtual address (va) in context (ctx) to physical address + * (i.e. walk the page table in software). + */ +hpt_pa_t hptw_va_to_pa(hptw_ctx_t *ctx, + hpt_va_t va) +{ + hpt_pmeo_t pmeo; + hptw_get_pmeo(&pmeo, ctx, 1, va); + return hpt_pmeo_va_to_pa(&pmeo, va); +} + +// translate guest paddr to system paddr (spa) +uintptr_t hptw_gpa_to_spa(hptw_ctx_t *ctx, + hpt_pa_t gpa) +{ + hpt_pa_t result = 0; + + result = hptw_va_to_pa(ctx, (hpt_va_t) gpa); + return (uintptr_t)result; +} + +/* + * Access virtual address (va) in context (ctx) in software. + * return value is the physical address that can be accessed by the caller. + * requested_sz is the size caller wants to access. + * avail_sz is the size available in the same page. + * If avail_sz < requested_sz, the caller needs to call this function again. + */ +void* hptw_access_va(hptw_ctx_t *ctx, + hpt_va_t va, + size_t requested_sz, + size_t *avail_sz) +{ + hpt_pmeo_t pmeo; + hpt_pa_t pa; + + hptw_get_pmeo(&pmeo, ctx, 1, va); + + pa = hpt_pmeo_va_to_pa(&pmeo, va); + *avail_sz = MIN(requested_sz, hpt_remaining_on_page(&pmeo, pa)); + + return ctx->pa2ptr(ctx, pa, + *avail_sz, HPT_PROTS_R, HPTW_CPL0, avail_sz); +} + +/* + * Access virtual address (va) in context (ctx) in software. Return NULL when + * error (e.g. invalid permission). + * access_type and cpl are used to check permissions when accessing va. + * return value is the physical address that can be accessed by the caller. + * requested_sz is the size caller wants to access. + * avail_sz is the size available in the same page. + * If avail_sz < requested_sz, the caller needs to call this function again. + */ +void* hptw_checked_access_va(hptw_ctx_t *ctx, + hpt_prot_t access_type, + hptw_cpl_t cpl, + hpt_va_t va, + size_t requested_sz, + size_t *avail_sz) +{ + hpt_pmeo_t pmeo; + hpt_pa_t pa; + hpt_pmo_t pmo; + void *rv=NULL; + *avail_sz=0; + + EU_CHKN( hptw_get_root( ctx, &pmo)); + + eu_trace("va:0x%llx access_type %lld cpl:%d", + va, access_type, cpl); + + do { + eu_trace("pmo t:%d pm:%p lvl:%d", + pmo.t, pmo.pm, pmo.lvl); + hpt_pm_get_pmeo_by_va( &pmeo, &pmo, va); + EU_CHK(((access_type & hpt_pmeo_getprot(&pmeo)) == access_type) + && (cpl == HPTW_CPL0 || hpt_pmeo_getuser(&pmeo)), + eu_err_e("req-priv:%lld req-cpl:%d priv:%lld user-accessible:%d", + access_type, cpl, hpt_pmeo_getprot(&pmeo), hpt_pmeo_getuser(&pmeo))); + } while (hptw_next_lvl(ctx, &pmo, va)); + + EU_CHK( pmo.t != HPT_TYPE_INVALID); + + EU_CHK( hpt_pmeo_is_present(&pmeo)); + + /* exiting loop means hptw_next_lvl failed, which means either the + * current pmeo is a page, or the current pmeo is not present. + * however, we should have already returned if not present, so pmeo + * must be a page */ + EU_VERIFY(hpt_pmeo_is_page(&pmeo)); + + pa = hpt_pmeo_va_to_pa(&pmeo, va); + *avail_sz = MIN(requested_sz, hpt_remaining_on_page(&pmeo, pa)); + eu_trace("got pa:%llx sz:%d", pa, *avail_sz); + rv = ctx->pa2ptr(ctx, pa, + *avail_sz, access_type, cpl, avail_sz); + + out: + return rv; +} + +/* + * Memory copy from virtual address (src_va_base) to physical address (dst), + * assuming privilege level at (cpl) when reading from source. + * Return 0 if successful, 1 if failed. + */ +int hptw_checked_copy_from_va(hptw_ctx_t *ctx, + hptw_cpl_t cpl, + void *dst, + hpt_va_t src_va_base, + size_t len) +{ + size_t copied=0; + + while(copied < len) { + hpt_va_t src_va = src_va_base + copied; + size_t to_copy; + void *src; + + src = hptw_checked_access_va(ctx, HPT_PROTS_R, cpl, src_va, len-copied, &to_copy); + if(!src) { + return 1; + } + memcpy(dst+copied, src, to_copy); + copied += to_copy; + } + return 0; +} + +/* + * Memory copy from physical address (src) to virtual address (dst_va_base), + * assuming privilege level at (cpl) when writing to destination. + * Return 0 if successful, 1 if failed. + */ +int hptw_checked_copy_to_va(hptw_ctx_t *ctx, + hptw_cpl_t cpl, + hpt_va_t dst_va_base, + void *src, + size_t len) +{ + size_t copied=0; + + while(copied < len) { + hpt_va_t dst_va = dst_va_base + copied; + size_t to_copy; + void *dst; + + dst = hptw_checked_access_va(ctx, HPT_PROTS_W, cpl, dst_va, len-copied, &to_copy); + if (!dst) { + return 1; + } + memcpy(dst, src+copied, to_copy); + copied += to_copy; + } + return 0; +} + +/* + * Memory copy from virtual address (src_va_base) to virtual address + * (dst_va_base), assuming privilege level at (cpl) when reading / writing. + * Return 0 if successful, 1 if failed. + */ +int hptw_checked_copy_va_to_va(hptw_ctx_t *dst_ctx, + hptw_cpl_t dst_cpl, + hpt_va_t dst_va_base, + hptw_ctx_t *src_ctx, + hptw_cpl_t src_cpl, + hpt_va_t src_va_base, + size_t len) +{ + size_t copied=0; + int rv=1; + + while(copied < len) { + hpt_va_t dst_va = dst_va_base + copied; + hpt_va_t src_va = src_va_base + copied; + size_t to_copy; + void *src, *dst; + + eu_trace("dst_va:0x%llx src_va:0x%llx", dst_va, src_va); + + EU_CHK( dst = hptw_checked_access_va(dst_ctx, + HPT_PROTS_W, + dst_cpl, + dst_va, + len-copied, + &to_copy)); + EU_CHK( src = hptw_checked_access_va(src_ctx, + HPT_PROTS_R, + src_cpl, + src_va, + to_copy, + &to_copy)); + eu_trace("dst-ptr:%p src-ptr:%p to-copy:%d", + dst, src, to_copy); + + memcpy(dst, src, to_copy); + copied += to_copy; + } + + eu_trace("hptw_checked_copy_va_to_va: returning"); + rv=0; + out: + return rv; +} + +/* + * Set memory for virtual address (dst_va_base), assuming privilege level at + * (cpl) when reading / writing. + * Return 0 if successful, 1 if failed. + */ +int hptw_checked_memset_va(hptw_ctx_t *ctx, + hptw_cpl_t cpl, + hpt_va_t dst_va_base, + int c, + size_t len) +{ + size_t set=0; + int rv=1; + eu_trace("hptw_checked_memset_va entering"); + + while(set < len) { + hpt_va_t dst_va = dst_va_base + set; + size_t to_set; + void *dst; + + eu_trace("calling hptw_checked_access_va"); + EU_CHK(dst = hptw_checked_access_va(ctx, + HPT_PROTS_W, + cpl, + dst_va, + len-set, + &to_set)); + eu_trace("got pointer %p, size %d", dst, to_set); + memset(dst, c, to_set); + set += to_set; + } + eu_trace("hptw_checked_memset_va returning"); + + rv=0; + out: + return rv; +} diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/bitfield.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/bitfield.h new file mode 100644 index 0000000000..37c06e23ed --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/bitfield.h @@ -0,0 +1,171 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* bitfield.h - bitfield utility functions + * + * author - Jim Newsome (jnewsome@no-fuss.com) + * + * Some utility functions for manipulating bits within 32 bit and 64 + * bit unsigned ints. These functions tend to be a bit more verbose + * than doing the low-level operations directly, but they also help to + * make the semantic meaning clearer, and to avoid subtle bugs that + * tend to crop up. + * + * All of these functions are intended to be side-effect-free. In + * particular, they return a new value rather than manipulating data + * in place. + */ +#ifndef BITFIELD_H +#define BITFIELD_H + +#include +#include +#include + +static inline u64 ZERO_HI64(u64 x, int bits) +{ + return ((x) << (bits) >> (bits)); +} +static inline u64 ZERO_LO64(u64 x, int bits) +{ + return ((x) >> (bits) << (bits)); +} +static inline u32 ZERO_HI32(u32 x, int bits) +{ + return ((x) << (bits) >> (bits)); +} +static inline u32 ZERO_LO32(u32 x, int bits) +{ + return ((x) >> (bits) << (bits)); +} + +static inline u64 MASKRANGE64(int hi, int lo) +{ + return ZERO_LO64(ZERO_HI64(0xffffffffffffffffull, + 64-(hi)-1), + (lo)); +} + +static inline u32 MASKRANGE32(int hi, int lo) +{ + return ZERO_LO32(ZERO_HI32(0xfffffffful, + 32-(hi)-1), + (lo)); +} + +static inline u64 MASKBIT64(int bit) +{ + return 1ull<> (lo); +} +static inline u64 BR32_GET_HL(u32 x32, int hi, int lo) +{ + return ZERO_HI64(x32, 31-(hi)) >> (lo); +} + +static inline u64 BR64_SET_HL(u64 x64, int hi, int lo, u64 val) +{ + assert(ZERO_HI64(val, 63-(hi-lo)) == val); + return ((x64 & ~MASKRANGE64((hi), (lo))) | ((val) << (lo))); +} +static inline u32 BR32_SET_HL(u32 x32, int hi, int lo, u32 val) +{ + assert(ZERO_HI64(val, 31-(hi-lo)) == val); + return ((x32 & ~MASKRANGE32((hi), (lo))) | ((val) << (lo))); +} + +#define BR64_GET_BR(x64, name) BR64_GET_HL(x64, name##_HI, name##_LO) +#define BR64_SET_BR(x64, name, val) BR64_SET_HL(x64, name##_HI, name##_LO, val) + +static inline unsigned int BR64_GET_BIT(u64 x64, int pos) +{ + return ((x64 & MASKRANGE64(pos, pos)) >> pos); +} +static inline u64 BR64_SET_BIT(u64 x64, int pos, bool val) +{ + u64 bit = val ? 1ull : 0ull; + return ((x64 & ~(0x1ull<> pos); +} +static inline u32 BR32_SET_BIT(u32 x32, int pos, bool val) +{ + u32 bit = val ? 1ul : 0ul; + return ((x32 & ~(0x1ul< +#include + +/* normally use eu_log, but give option for client to override */ +#ifndef EU_CHK_LOG +#define EU_CHK_LOG( pri, fmt, args...) EU_LOG( pri, fmt, ## args) +#endif + +/* EU_CHK(cond) - if condition is false, will log an error, including + * the stringified condition, and goto label 'out'. Use above variants + * if a different logging priority is desired. + * + * Optionally, include additional expressions that will be evaluated + * iff the condition doesn't hold. This can be used, e.g., to set a + * return value or error flag. examples: + * + * EU_CHK((buf = malloc(20))); + * + * EU_CHK(buf = malloc(20), + * rv = ENOMEM); + * + * In either case, allocation failure will print a useful log message + * including the location of the check and the stringified condition + * that failed ("buf = malloc(20)"), and goto label 'out'. In the + * second case, failure will also cause the variable rv to be assigned + * ENOMEM. + * + * EU_CHKN is as-above, but inverts the condition, and prints the value of the condition + * on failure. useful for checking (and printing) error codes. example: + * + * EU_CHKN(fn_that_may_fail(arg1, arg2, arg3)); + * + * if fn_that_may_fail returns non-zero, the check will fail and the + * return value will be logged. + * + */ + +/* Adding the unlikely compiler hint can remove some compiler warnings */ +#define _euchk_unlikely(x) __builtin_expect(!!(x), 0) + +#define EU_CHKN_PRI(cond, priority, args...) \ + do { \ + int _eu_chk_cond = (int)(cond); \ + if (_euchk_unlikely(_eu_chk_cond)) { \ + EU_CHK_LOG(priority, "EU_CHKN( %s) failed with: %d", #cond, _eu_chk_cond); \ + (void)0, ## args; \ + goto out; \ + } \ + } while(0) + +#define EU_CHK_PRI(cond, priority, args...) \ + do { \ + if (_euchk_unlikely(!(cond))) { \ + EU_CHK_LOG(priority, "EU_CHK( %s) failed", #cond); \ + (void)0, ## args; \ + goto out; \ + } \ + } while(0) + +#define EU_CHK_T(cond, args...) EU_CHK_PRI(cond, EU_TRACE, ## args) +#define EU_CHK_W(cond, args...) EU_CHK_PRI(cond, EU_WARN, ## args) +#define EU_CHK_E(cond, args...) EU_CHK_PRI(cond, EU_ERR, ## args) + +#define EU_CHKN_T(cond, args...) EU_CHKN_PRI(cond, EU_TRACE, ## args) +#define EU_CHKN_W(cond, args...) EU_CHKN_PRI(cond, EU_WARN, ## args) +#define EU_CHKN_E(cond, args...) EU_CHKN_PRI(cond, EU_ERR, ## args) + +#define EU_CHK(cond, args...) EU_CHK_E(cond, ## args) +#define EU_CHKN(cond, args...) EU_CHKN_E(cond, ## args) + +/* use like assert, but where arg will always be expanded and the + check never disabled */ +#define EU_VERIFY(cond, args...) \ + do { \ + if (_euchk_unlikely(!(cond))) { \ + EU_CHK_LOG( EU_ERR, "EU_VERIFY( %s) failed", #cond); \ + (void)0, ## args; \ + abort(); \ + } \ + } while(0) + +/* verify-not. logs value in case of failure as with EU_CHKN. */ +#define EU_VERIFYN(cond, args...) \ + do { \ + int _eu_chk_cond = (int)(cond); \ + if (_euchk_unlikely(_eu_chk_cond)) { \ + EU_CHK_LOG( EU_ERR, "EU_VERIFYN( %s) failed with %d", #cond, _eu_chk_cond); \ + (void)0, ## args; \ + abort(); \ + } \ + } while(0) + +#endif diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/eulog.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/eulog.h new file mode 100644 index 0000000000..cdff631e3e --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/eulog.h @@ -0,0 +1,125 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef EULOG_H +#define EULOG_H + +#define EU_TRACE 0 +#define EU_PERF 1 +#define EU_WARN 2 +#define EU_ERR 3 + +#ifndef EU_LOG_PREFIX +#define EU_LOG_PREFIX "" +#endif + +#ifndef EU_LOG_LVL +#define EU_LOG_LVL EU_TRACE +#endif + +#ifndef EU_LOG_PRINTLN +#define EU_LOG_PRINTLN( prefix, fmt, args...) printf( "%-50s " fmt "\n", prefix, ## args) +#endif + +#include +#include + +#ifndef EU_PREFIX_MAX_LEN +#define EU_PREFIX_MAX_LEN 256 +#endif + +#define EU_LOG(pri, fmt, args...) \ + do { \ + char _eulogbuf[EU_PREFIX_MAX_LEN]; \ + if (EU_LOG_LVL <= pri) { \ + snprintf(_eulogbuf, EU_PREFIX_MAX_LEN, "%s[%d]:%s:%s:%d:", EU_LOG_PREFIX, pri, __FILE__, __FUNCTION__, __LINE__); \ + _eulogbuf[EU_PREFIX_MAX_LEN-1] = '\0'; \ + EU_LOG_PRINTLN( _eulogbuf, fmt, ## args); \ + } \ + } while(0) + +#define eu_trace(fmt, args...) EU_LOG(EU_TRACE, fmt, ## args) +#define eu_perf(fmt, args...) EU_LOG(EU_PERF, fmt, ## args) +#define eu_warn(fmt, args...) EU_LOG(EU_WARN, fmt, ## args) +#define eu_err(fmt, args...) EU_LOG(EU_ERR, fmt, ## args) + +#define eu_pulse() EU_LOG(EU_TRACE, "pulse") + +/* below are versions that can be used where an expression is + expected. this is useful as extra parameters to eu_chk + functions. Unfortunately we end up using multiple print statements, + which may not be printed atomically. +*/ +static int eu_logfn(const char* fmt, const char* prefix, int pri, const char *file, const char *fn, int line, ...) __attribute__ ((unused)); +static int eu_logfn(const char* fmt, const char* prefix, int pri, const char *file, const char *fn, int line, ...) +{ + va_list va; + char loc_string[128]; + /* int written; */ + + snprintf(loc_string, 128, "%s[%d]:%s:%s:%d:", prefix, pri, file, fn, line); + printf("%-50s ", loc_string); + + va_start(va, line); + vprintf(fmt, va); + va_end(va); + + printf("\n"); + return 0; +} + +#define EU_LOGE(pri, fmt, args...) \ + ((void)((EU_LOG_LVL <= pri) && \ + eu_logfn(fmt, EU_LOG_PREFIX, pri, __FILE__, __FUNCTION__, __LINE__, ## args))) + +#define eu_trace_e(fmt, args...) EU_LOGE(EU_TRACE, fmt, ## args) +#define eu_perf_e(fmt, args...) EU_LOGE(EU_PERF, fmt, ## args) +#define eu_warn_e(fmt, args...) EU_LOGE(EU_WARN, fmt, ## args) +#define eu_err_e(fmt, args...) EU_LOGE(EU_ERR, fmt, ## args) + +#define eu_pulse_e() EU_LOGE(EU_TRACE, "pulse" + +#endif diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/hpt.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/hpt.h new file mode 100644 index 0000000000..848556b5e3 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/hpt.h @@ -0,0 +1,193 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* hpt.h - hypervisor page table abstraction + * + * author - Jim Newsome (jnewsome@no-fuss.com) + * + * note: the HPT abstraction requires certain target interfaces to + * be defined by a "provider". EMHF specific target interface + * definitions live in hpt_emhf.h + */ + +#ifndef HPT_H +#define HPT_H + +#include +#include +#include + +typedef enum { + HPT_TYPE_NORM=0, /* x86 'normal'\legacy */ + HPT_TYPE_PAE=1, /* Physical address extension */ + HPT_TYPE_LONG=2, /* AMD Long Mode */ + HPT_TYPE_EPT=3, /* Intel Extended Page Tables */ + + HPT_TYPE_INVALID=4, /* same number as below intentionally; saves memory in static arrays */ + HPT_TYPE_NUM=4 /* dummy entry. must be last */ +} hpt_type_t; + +#define HPT_MAX_LEVEL 4 + +#define HPT_LVL_PT1 1 +#define HPT_LVL_PD2 2 +#define HPT_LVL_PDP3 3 +#define HPT_LVL_PDPT3 3 +#define HPT_LVL_PML4 4 + +typedef u64 hpt_pme_t; /* page map entry (any level) */ +typedef hpt_pme_t* hpt_pm_t; /* page map (any level) */ + +/* NOTE- do not dereference directly. + Some page table types use 32-bit entries instead + of 64-bit. */ + +typedef u64 hpt_prot_t; /* pme protection flags type */ +typedef u64 hpt_va_t; /* virtual address type */ +typedef u64 hpt_pa_t; /* physical address type */ + +/* Page map object (e.g. pointer to page table with metadata) */ +typedef struct { + hpt_pm_t pm; + hpt_type_t t; + int lvl; +} hpt_pmo_t; + +/* Page map entry object (e.g. page table entry with metadata) */ +typedef struct { + hpt_pme_t pme; + hpt_type_t t; + int lvl; +} hpt_pmeo_t; + +#define HPT_UNUSED_ARGUMENT(x) (void)x + +/* Common page size */ +#define HPT_PM_SIZE 4096 + +/* page map sizes, in bytes. note that zero index is invalid. */ +extern const u16 hpt_pm_sizes[HPT_TYPE_NUM][HPT_MAX_LEVEL+1]; + +/* page map sizes, in bytes. note that zero index is invalid. */ +extern const u16 hpt_pm_alignments[HPT_TYPE_NUM][HPT_MAX_LEVEL+1]; + +/* high bit of va used to index into the page map of the given level. + * we treat level '0' specially here, so that the low bit of the index + * can consistently be found by looking up the entry for 'level-1'. + */ +extern const u8 hpt_va_idx_hi[HPT_TYPE_NUM][HPT_MAX_LEVEL+1]; + +/* Number of levels in the paging. */ +extern const u8 hpt_type_max_lvl[HPT_TYPE_NUM]; + +size_t hpt_pm_size(hpt_type_t t, int lvl); + +#include /* XXX - remove this once fn bodies are moved + into hpt.c */ + +/* Abstract protection flags. */ +#define HPT_PROT_READ_BIT 0 +#define HPT_PROT_WRITE_BIT 1 +#define HPT_PROT_EXEC_BIT 2 +#define HPT_PROT_READ_MASK (1ull< (x)) ? (y) : (x)) +#endif +#ifndef MIN +#define MIN(x, y) (((y) < (x)) ? (y) : (x)) +#endif + +/* Page memory types */ +typedef enum { + HPT_PMT_UC=0, HPT_PMT_WC=1, HPT_PMT_WT=4, HPT_PMT_WP=5, HPT_PMT_WB=6 +} hpt_pmt_t; + +/* assumes lvl is valid for the given type */ +bool hpt_prot_is_valid(hpt_type_t t, int lvl, hpt_prot_t perms); + +bool hpt_lvl_is_valid(hpt_type_t t, int lvl); +bool hpt_type_is_valid(hpt_type_t t); +int hpt_root_lvl(hpt_type_t t); + +hpt_pa_t hpt_pmeo_get_address(const hpt_pmeo_t *pmeo); +void hpt_pmeo_set_address(hpt_pmeo_t *pmeo, hpt_pa_t addr); +bool hpt_pmeo_is_present(const hpt_pmeo_t *pmeo); +bool hpt_pmeo_is_page(const hpt_pmeo_t *pmeo); +void hpt_pmeo_setprot(hpt_pmeo_t *pmeo, hpt_prot_t perms); +hpt_prot_t hpt_pmeo_getprot(const hpt_pmeo_t *pmeo); + +// Set Cachable +void hpt_pmeo_setcache(hpt_pmeo_t *pmeo, hpt_pmt_t pmt); + +bool hpt_pmeo_getuser(const hpt_pmeo_t *pmeo); +void hpt_pmeo_setuser(hpt_pmeo_t *pmeo, bool user); +void hpt_pm_get_pmeo_by_va(hpt_pmeo_t *pmeo, const hpt_pmo_t *pmo, hpt_va_t va); +void hpt_pmo_set_pme_by_va(hpt_pmo_t *pmo, const hpt_pmeo_t *pmeo, hpt_va_t va); +hpt_pa_t hpt_pmeo_va_to_pa(hpt_pmeo_t* pmeo, hpt_va_t va); +size_t hpt_pmeo_page_size_log_2(const hpt_pmeo_t *pmeo); +size_t hpt_pmeo_page_size(const hpt_pmeo_t *pmeo); +size_t hpt_remaining_on_page(const hpt_pmeo_t *pmeo, hpt_va_t va); + +#endif diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/hpt_consts.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/hpt_consts.h new file mode 100644 index 0000000000..5e773ba317 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/hpt_consts.h @@ -0,0 +1,199 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef HPT_CONSTS_H +#define HPT_CONSTS_H + +/* HPT___L_[M][P]_[LO|HI|BIT] */ +/* P if the mapping is valid for entries mapping a page. + * M if the mapping is valid for entries mapping another map (table) + * when there's no ambiguity, the same macro may include level 1 and 'M', + * even though a level 1 entry is always a page. e.g., '...L21_MP...' + * for a name that is valid for l2 maps, l2 pages, and l1 pages. + * + * Including in the name of each macro which levels and types it is + * valid for is intended to help write error-free code below. e.g., it + * is clear when using an 'L32_M' macro that one must first ensure that + * the PTE being dealt with maps a map\table and is of level 3 or 2. + * + */ +#define HPT_NORM_ADDR_L2_M_HI 31 +#define HPT_NORM_ADDR_L2_M_LO 12 +#define HPT_NORM_ADDR3122_L2_P_HI 31 +#define HPT_NORM_ADDR3122_L2_P_LO 22 +#define HPT_NORM_MBZ21_L2_P_BIT 21 +#define HPT_NORM_ADDR3932_L2_P_HI 20 +#define HPT_NORM_ADDR3932_L2_P_LO 13 +#define HPT_NORM_PAT_L2_P_BIT 12 /* page attribute table */ +#define HPT_NORM_ADDR_L1_P_HI 31 +#define HPT_NORM_ADDR_L1_P_LO 12 +#define HPT_NORM_AVL11_L21_MP_HI 11 /* available */ +#define HPT_NORM_AVL11_L21_MP_LO 9 +#define HPT_NORM_G_L21_P_BIT 8 /* global */ +#define HPT_NORM_IGN8_L2_M_BIT 8 +#define HPT_NORM_PS_L2_MP_BIT 7 /* page size */ +#define HPT_NORM_PAT_L1_P_BIT 7 /* page attribute table */ +#define HPT_NORM_D_L21_P_BIT 6 /* dirty (valid for lowest lvl only) */ +#define HPT_NORM_IGN6_L2_M_BIT 6 +#define HPT_NORM_A_L21_MP_BIT 5 /* accessed */ +#define HPT_NORM_PCD_L21_MP_BIT 4 /* page cache disable */ +#define HPT_NORM_PWT_L21_MP_BIT 3 /* page write through */ +#define HPT_NORM_US_L21_MP_BIT 2 /* 0:supervisor 1:user */ +#define HPT_NORM_RW_L21_MP_BIT 1 /* 0:read-only 1:read\write */ +#define HPT_NORM_P_L21_MP_BIT 0 /* present */ + +#define HPT_PAE_MBZ63_L3_MP_BIT 63 +#define HPT_PAE_NX_L21_MP_BIT 63 +#define HPT_PAE_MBZ62_L321_MP_HI 62 +#define HPT_PAE_MBZ62_L321_MP_LO 52 +#define HPT_PAE_ADDR_L321_M_HI 51 /* address bits */ +#define HPT_PAE_ADDR_L321_M_LO 12 +#define HPT_PAE_ADDR_L2_P_HI 51 +#define HPT_PAE_ADDR_L2_P_LO 13 +#define HPT_PAE_PAT_L2_P_BIT 12 +#define HPT_PAE_ADDR_L1_P_HI 51 /* address bits */ +#define HPT_PAE_ADDR_L1_P_LO 12 +#define HPT_PAE_AVL11_L321_MP_HI 11 /* available */ +#define HPT_PAE_AVL11_L321_MP_LO 9 +#define HPT_PAE_MBZ8_L3_MP_HI 8 +#define HPT_PAE_MBZ8_L3_MP_LO 5 +#define HPT_PAE_G_L21_P_BIT 8 /* global */ +#define HPT_PAE_IGN8_L2_M_BIT 8 +#define HPT_PAE_PS_L2_MP_BIT 7 /* page size */ +#define HPT_PAE_PAT_L1_P_BIT 7 /* page attribute table */ +#define HPT_PAE_D_L21_P_BIT 6 /* dirty */ +#define HPT_PAE_IGN6_L2_M_BIT 6 +#define HPT_PAE_A_L21_P_BIT 5 /* accessed */ +#define HPT_PAE_PCD_L321_MP_BIT 4 /* page cache disable */ +#define HPT_PAE_PWT_L321_MP_BIT 3 /* page write through */ +#define HPT_PAE_MBZ2_L3_M_HI 2 +#define HPT_PAE_MBZ2_L3_M_LO 1 +#define HPT_PAE_US_L21_MP_BIT 2 /* 0:supervisor 1:user */ +#define HPT_PAE_RW_L21_MP_BIT 1 /* 0:read-only 1:read\write */ +#define HPT_PAE_P_L321_MP_BIT 0 /* present */ + +#define HPT_LONG_NX_L4321_MP_BIT 63 +#define HPT_LONG_AVL62_L4321_MP_HI 62 +#define HPT_LONG_AVL52_L4321_MP_LO 52 +#define HPT_LONG_ADDR_L4321_M_HI 51 /* address bits */ +#define HPT_LONG_ADDR_L4321_M_LO 12 +#define HPT_LONG_ADDR_L32_P_HI 51 +#define HPT_LONG_ADDR_L32_P_LO 13 +#define HPT_LONG_ADDR_L1_P_HI 51 +#define HPT_LONG_ADDR_L1_P_LO 12 +#define HPT_LONG_PAT_L32_P_BIT 12 +#define HPT_LONG_AVL11_L4321_MP_HI 11 /* available */ +#define HPT_LONG_AVL11_L4321_MP_LO 9 +#define HPT_LONG_MBZ8_L4_MP_BIT 8 +#define HPT_LONG_MBZ7_L4_MP_BIT 7 +#define HPT_LONG_G_L21_P_BIT 8 /* global */ +#define HPT_LONG_PS_L32_MP_BIT 7 /* page size */ +#define HPT_LONG_PAT_L1_P_BIT 7 /* page attribute table */ +#define HPT_LONG_IGN6_L4_M_BIT 6 +#define HPT_LONG_D_L321_P_BIT 6 /* dirty */ +#define HPT_LONG_A_L4321_MP_BIT 5 /* accessed */ +#define HPT_LONG_PCD_L4321_MP_BIT 4 /* page cache disable */ +#define HPT_LONG_PWT_L4321_MP_BIT 3 /* page write through */ +#define HPT_LONG_US_L4321_MP_BIT 2 /* 0:supervisor 1:user */ +#define HPT_LONG_RW_L4321_MP_BIT 1 /* 0:read-only 1:read\write */ +#define HPT_LONG_P_L4321_MP_BIT 0 /* present */ + +#define HPT_EPT_MAXPHYADDR 52 /* FIXME, should find this dynamically + using cpuid, cf Intel manual 3A + 4.1.4. using the max value of 52, + which could cause trouble if the + reserved bitfield above MAXPHYADDR + gets used for anything. */ +#define HPT_EPT_AVL63_L4321_MP_HI 63 +#define HPT_EPT_AVL52_L4321_MP_LO 52 +#define HPT_EPT_ADDR_L4321_MP_HI (HPT_EPT_MAXPHYADDR-1) +#define HPT_EPT_ADDR_L4321_MP_LO 12 +#define HPT_EPT_AVL11_L4321_MP_HI 11 +#define HPT_EPT_AVL11_L4321_MP_LO 8 +#define HPT_EPT_MBZ7_L4_M_BIT 7 +#define HPT_EPT_PS_L32_MP_BIT 7 +#define HPT_EPT_AVL7_L1_P_BIT 7 +#define HPT_EPT_IPAT_L321_P_BIT 6 +#define HPT_EPT_MBZ6_L432_M_HI 6 +#define HPT_EPT_MBZ6_L432_M_LO 3 +#define HPT_EPT_MT_L321_P_HI 5 +#define HPT_EPT_MT_L321_P_LO 3 +#define HPT_EPT_X_L4321_MP_BIT 2 +#define HPT_EPT_W_L4321_MP_BIT 1 +#define HPT_EPT_R_L4321_MP_BIT 0 +#define HPT_EPT_PROT_L4321_MP_HI 2 +#define HPT_EPT_PROT_L4321_MP_LO 0 + +#define HPT_CR3_PML4_LONG_HI 51 +#define HPT_CR3_PML4_LONG_LO 12 +#define HPT_CR3_PML2_LONG_MBZ11_HI 11 +#define HPT_CR3_PML2_LONG_MBZ11_LO 5 +#define HPT_CR3_PML3_PAE_HI 31 +#define HPT_CR3_PML3_PAE_LO 5 +#define HPT_CR3_PML2_NORM_HI 31 +#define HPT_CR3_PML2_NORM_LO 12 +#define HPT_CR3_MBZ11_NORM_HI 11 +#define HPT_CR3_MBZ11_NORM_LO 5 +#define HPT_CR3_PCD_BIT 4 +#define HPT_CR3_PWT_BIT 3 +#define HPT_CR3_MBZ2_HI 2 +#define HPT_CR3_MBZ2_LO 0 + +#define HPT_EPTP_MBZ63_H 63 +#define HPT_EPTP_MBZ63_L HPT_EPT_MAXPHYADDR +#define HPT_EPTP_PML4_HI (HPT_EPT_MAXPHYADDR-1) +#define HPT_EPTP_PML4_LO 12 +#define HPT_EPTP_MBZ11_HI 11 +#define HPT_EPTP_MBZ11_LO 6 +#define HPT_EPTP_PWLM1_HI 5 +#define HPT_EPTP_PWLM1_LO 3 +#define HPT_EPTP_PSMT_HI 2 +#define HPT_EPTP_PSMT_LO 0 + +#define HPT_CR4_PAE_BIT 5 +#define HPT_CR4_PSE_BIT 4 + +#endif diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/hpt_emhf.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/hpt_emhf.h new file mode 100644 index 0000000000..01413233f3 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/hpt_emhf.h @@ -0,0 +1,200 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* hpt_emhf.h - HPT abstraction target interface for EMHF + * author - amit vasudevan (amitvasudevan@acm.org) + */ + +#ifndef _HPT_EMHF_H +#define _HPT_EMHF_H + +#include + +#ifndef __ASSEMBLY__ + +static inline hpt_pme_t* hpt_emhf_get_pml1es(VCPU *vcpu){ + return (hpt_pme_t *)xmhf_memprot_get_lvl1_pagemap_address(vcpu); + +} + +static inline hpt_pme_t* hpt_emhf_get_pml2es(VCPU *vcpu){ + return (hpt_pme_t *)xmhf_memprot_get_lvl2_pagemap_address(vcpu); +} + +static inline hpt_pme_t* hpt_emhf_get_pml3es(VCPU *vcpu){ + return (hpt_pme_t *)xmhf_memprot_get_lvl3_pagemap_address(vcpu); +} + +static inline hpt_pme_t* hpt_emhf_get_pml4(VCPU *vcpu){ + return (hpt_pme_t *)xmhf_memprot_get_lvl4_pagemap_address(vcpu); +} + +static inline hpt_type_t hpt_emhf_get_hpt_type(VCPU *vcpu) +{ + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + return HPT_TYPE_EPT; + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + return HPT_TYPE_PAE; + } + + HALT_ON_ERRORCOND(0); + return HPT_TYPE_INVALID; +} + +static inline hpt_pm_t hpt_emhf_get_default_root_pm(VCPU *vcpu) +{ + return (hpt_pm_t)xmhf_memprot_get_default_root_pagemap_address(vcpu); +} + +static inline hpt_pa_t hpt_emhf_get_root_pm_pa(VCPU *vcpu) +{ + hpt_type_t t = hpt_emhf_get_hpt_type(vcpu); + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + return hpt_eptp_get_address(t, + xmhf_memprot_arch_x86vmx_get_EPTP(vcpu)); + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + return hpt_cr3_get_address(t, + xmhf_memprot_arch_x86svm_get_h_cr3(vcpu)); + } else { + HALT_ON_ERRORCOND(0); + return 0; + } +} + +static inline void hpt_emhf_set_root_pm_pa(VCPU *vcpu, hpt_pa_t root_pa) +{ + hpt_type_t t = hpt_emhf_get_hpt_type(vcpu); + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + xmhf_memprot_arch_x86vmx_set_EPTP( vcpu, hpt_eptp_set_address(t, + xmhf_memprot_arch_x86vmx_get_EPTP(vcpu), + root_pa)); + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + xmhf_memprot_arch_x86svm_set_h_cr3( vcpu, hpt_cr3_set_address(t, + xmhf_memprot_arch_x86svm_get_h_cr3(vcpu), + root_pa)); + } else { + HALT_ON_ERRORCOND(0); + } +} + +static inline hpt_pm_t hpt_emhf_get_root_pm(VCPU *vcpu) +{ + return spa2hva( hpt_emhf_get_root_pm_pa( vcpu)); +} + +static inline void hpt_emhf_set_root_pm(VCPU *vcpu, hpt_pm_t root) +{ + hpt_emhf_set_root_pm_pa( vcpu, hva2spa(root)); +} + +static inline hpt_type_t hpt_emhf_get_guest_hpt_type(VCPU *vcpu) { + u64 cr4 = VCPU_gcr4(vcpu); + if (!(cr4 & CR4_PAE)) { + return HPT_TYPE_NORM; + } else if (!(VCPU_glm(vcpu))) { + return HPT_TYPE_PAE; + } else if (!(cr4 & CR4_LA57)) { + return HPT_TYPE_LONG; + } else { + /* 5-level paging not supported yet */ + HALT_ON_ERRORCOND(0); + return HPT_TYPE_INVALID; + } +} + +static inline hpt_pa_t hpt_emhf_get_guest_root_pm_pa(VCPU *vcpu) +{ + hpt_type_t t = hpt_emhf_get_guest_hpt_type(vcpu); + return hpt_cr3_get_address(t, + VCPU_gcr3(vcpu)); +} + +static inline void hpt_emhf_set_guest_root_pm_pa( VCPU *vcpu, hpt_pa_t root_pa) +{ + hpt_type_t t = hpt_emhf_get_guest_hpt_type(vcpu); + VCPU_gcr3_set(vcpu, + hpt_cr3_set_address(t, + VCPU_gcr3(vcpu), + root_pa)); +} + +/* XXX use with extreme caution. guest could have set its cr3 to point + to a gpa to which it shouldn't have access */ +static inline hpt_pm_t hpt_emhf_get_guest_root_pm(VCPU *vcpu) +{ + return gpa2hva( hpt_emhf_get_guest_root_pm_pa( vcpu)); +} + +static inline void hpt_emhf_set_guest_root_pm( VCPU *vcpu, hpt_pm_t root) +{ + hpt_emhf_set_guest_root_pm_pa( vcpu, hva2gpa( root)); +} + +static inline void hpt_emhf_get_root_pmo(VCPU *vcpu, hpt_pmo_t *root) +{ + hpt_type_t t = hpt_emhf_get_hpt_type(vcpu); + *root = (hpt_pmo_t) { + .pm = hpt_emhf_get_root_pm(vcpu), + .t = t, + .lvl = hpt_root_lvl(t), + }; +} + +static inline void hpt_emhf_get_guest_root_pmo(VCPU *vcpu, hpt_pmo_t *root) +{ + hpt_type_t t = hpt_emhf_get_guest_hpt_type(vcpu); + *root = (hpt_pmo_t) { + .pm = hpt_emhf_get_guest_root_pm(vcpu), + .t = t, + .lvl = hpt_root_lvl(t), + }; +} + + +#endif //__ASSEMBLY__ + + +#endif //_HPT_EMHF_H diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/hptw.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/hptw.h new file mode 100644 index 0000000000..e4ab62d5d1 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/hptw.h @@ -0,0 +1,162 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef HPTW_H +#define HPTW_H + +#include + +typedef enum { + HPTW_CPL0=0, + HPTW_CPL1=1, + HPTW_CPL2=2, + HPTW_CPL3=3, +} hptw_cpl_t; + +/* Translate a referencable pointer to a physical address */ +typedef hpt_pa_t (*hpt_ptr2pa_t)(void *self, void *ptr); +/* Translate a physical address to a referenceable pointer */ +typedef void* (*hpt_pa2ptr_t)(void *self, hpt_pa_t pa, size_t sz, hpt_prot_t access_type, hptw_cpl_t cpl, size_t *avail_sz); +/* Allocate a physical page full of 0s */ +typedef void* (*hpt_get_zeroed_page_t)(void *self, size_t alignment, size_t sz); + +/* Context to perform page table operations */ +typedef struct { + /* Function to allocate new page */ + hpt_get_zeroed_page_t gzp; + /* Function to translate physical address to pointer */ + hpt_pa2ptr_t pa2ptr; + /* Function to translate pointer to physical address */ + hpt_ptr2pa_t ptr2pa; + + /* Physical address of paging root (e.g. CR3, eptp) */ + hpt_pa_t root_pa; + /* Paging type */ + hpt_type_t t; +} hptw_ctx_t; + +int hptw_insert_pmeo( hptw_ctx_t *ctx, + const hpt_pmeo_t *pmeo, + hpt_va_t va); + +int hptw_get_pmo_alloc( hpt_pmo_t *pmo, + hptw_ctx_t *ctx, + int end_lvl, + hpt_va_t va); + +int hptw_insert_pmeo_alloc( hptw_ctx_t *ctx, + const hpt_pmeo_t *pmeo, + hpt_va_t va); + +void hptw_get_pmo( hpt_pmo_t *pmo, + hptw_ctx_t *ctx, + int end_lvl, + hpt_va_t va); + +void hptw_get_pmeo( hpt_pmeo_t *pmeo, + hptw_ctx_t *ctx, + int end_lvl, + hpt_va_t va); + +/* tries to descend one level in the page table tree. returns true + * if successful. in case of an exception, such as pa2ptr callback + * failing, pmo is set to type HPT_INVALID. + */ +bool hptw_next_lvl( hptw_ctx_t *ctx, hpt_pmo_t *pmo, hpt_va_t va); + +hpt_prot_t hptw_get_effective_prots( hptw_ctx_t *ctx, + hpt_va_t va, + bool *user_accessible); + +void hptw_set_prot( hptw_ctx_t *ctx, + hpt_va_t va, + hpt_prot_t prot); + +hpt_pa_t hptw_va_to_pa( hptw_ctx_t *ctx, + hpt_va_t va); + +void* hptw_checked_access_va( hptw_ctx_t *ctx, + hpt_prot_t access_type, + hptw_cpl_t cpl, + hpt_va_t va, + size_t requested_sz, + size_t *avail_sz); + +int hptw_checked_copy_from_va( hptw_ctx_t *ctx, + hptw_cpl_t cpl, + void *dst, + hpt_va_t src_va_base, + size_t len); + +int hptw_checked_copy_to_va( hptw_ctx_t *ctx, + hptw_cpl_t cpl, + hpt_va_t dst_va_base, + void *src, + size_t len); + +int hptw_copy_to_va(hptw_ctx_t *ctx, + hpt_va_t dst_va_base, + void *src, + size_t len); + +// translate guest paddr to system paddr (spa) +extern uintptr_t hptw_gpa_to_spa(hptw_ctx_t *ctx, + hpt_pa_t gpa); + +int hptw_checked_copy_va_to_va( hptw_ctx_t *dst_ctx, + hptw_cpl_t dst_cpl, + hpt_va_t dst_va_base, + hptw_ctx_t *src_ctx, + hptw_cpl_t src_cpl, + hpt_va_t src_va_base, + size_t len); + +int hptw_checked_memset_va( hptw_ctx_t *ctx, + hptw_cpl_t cpl, + hpt_va_t dst_va_base, + int c, + size_t len); +#endif diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/nist_aes_rijndael.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/nist_aes_rijndael.h new file mode 100644 index 0000000000..18f0457f21 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/nist_aes_rijndael.h @@ -0,0 +1,103 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * Copyright (c) 2007 Henric Jungheim + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Interface adapter for Rijndael implmentation (for use by NIST SP 800-90 CTR_DRBG) + */ + +#ifndef NIST_AES_RIJNDAEL_H +#define NIST_AES_RIJNDAEL_H + +#ifndef __RIJNDAEL_H +#include "rijndael.h" +#endif + +#define NIST_AES_MAXKEYBITS 256 +#define NIST_AES_MAXKEYBYTES (NIST_AES_MAXKEYBITS / 8) +#define NIST_AES_MAXKEYINTS (NIST_AES_MAXKEYBYTES / sizeof(int)) + +#define NIST_AES_BLOCKSIZEBITS 128 +#define NIST_AES_BLOCKSIZEBYTES (NIST_AES_BLOCKSIZEBITS / 8) +#define NIST_AES_BLOCKSIZEINTS (NIST_AES_BLOCKSIZEBYTES / sizeof(int)) + +typedef struct { + int Nr; /* key-length-dependent number of rounds */ + unsigned int ek[4*(AES_MAXROUNDS + 1)]; /* encrypt key schedule */ +} NIST_AES_ENCRYPT_CTX; + +static __inline void +NIST_AES_ECB_Encrypt(const NIST_AES_ENCRYPT_CTX* ctx, const void* src, void* dst) +{ + rijndaelEncrypt(ctx->ek, ctx->Nr, (const unsigned char *)src, (unsigned char *)dst); +} + +static __inline int +NIST_AES_Schedule_Encryption(NIST_AES_ENCRYPT_CTX* ctx, const void* key, int bits) +{ + ctx->Nr = rijndaelKeySetupEnc(ctx->ek, (const unsigned char *)key, bits); + if (!ctx->Nr) + return 1; + + return 0; +} + +#endif /* NIST_AES_RIJNDAEL_H */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/nist_config.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/nist_config.h new file mode 100644 index 0000000000..50d95ee623 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/nist_config.h @@ -0,0 +1,90 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * Copyright (c) 2007 Henric Jungheim + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * NIST SP 800-90 Configuration (Random Number Generator) + */ + +#ifndef NIST_CONFIG_H +#define NIST_CONFIG_H + +#define NIST_IS_LITTLE_ENDIAN 0 + +#define NIST_ZEROIZE 1 + +#if 0 +/* Use the VIA padlock hardware as the AES implementation */ +#ifndef NIST_AES_PADLOCK_H_ +#include "nist_aes_padlock.h" +#endif +#else +#ifndef NIST_AES_RIJNDAEL_H_ +#include "nist_aes_rijndael.h" +#endif +#endif + +/* Use AES-256 as the block cipher */ +#ifndef NIST_CTR_DRBG_AES256_H +#include "nist_ctr_drbg_aes256.h" +#endif + +#endif /* NIST_CONFIG_H */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/nist_ctr_drbg.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/nist_ctr_drbg.h new file mode 100644 index 0000000000..9e78ae2822 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/nist_ctr_drbg.h @@ -0,0 +1,165 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * Copyright (c) 2007 Henric Jungheim + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * NIST SP 800-90 CTR_DRBG (Random Number Generator) + */ + +#ifndef NIST_CTR_DRBG_H +#define NIST_CTR_DRBG_H + +#ifndef NIST_CONFIG_H +#include "nist_config.h" +#endif + +#define NIST_BLOCK_SEEDLEN (NIST_BLOCK_KEYLEN + NIST_BLOCK_OUTLEN) +#define NIST_BLOCK_SEEDLEN_BYTES (NIST_BLOCK_SEEDLEN / 8) +#define NIST_BLOCK_SEEDLEN_INTS (NIST_BLOCK_SEEDLEN_BYTES / sizeof(int)) + +#ifndef NIST_KEY_ALIGNMENT +#define NIST_KEY_ALIGNMENT +#endif + +typedef struct { + unsigned int reseed_counter; + NIST_Key ctx; + unsigned int V[NIST_BLOCK_OUTLEN_INTS]; +} NIST_KEY_ALIGNMENT NIST_CTR_DRBG; + + +int +nist_ctr_initialize(void); + +int +nist_ctr_drbg_generate(NIST_CTR_DRBG* drbg, + void* output_string, int output_string_length, + const void* additional_input, int additional_input_length); + +int +nist_ctr_drbg_reseed(NIST_CTR_DRBG* drbg, + const void* entropy_input, int entropy_input_length, + const void* additional_input, int additional_input_length); + +int +nist_ctr_drbg_instantiate(NIST_CTR_DRBG* drbg, + const void* entropy_input, int entropy_input_length, + const void* nonce, int nonce_length, + const void* personalization_string, int personalization_string_length); + +int +nist_ctr_drbg_destroy(NIST_CTR_DRBG* ); + +void +nist_dump_simple_hex(const void* data, int length); + +void +nist_dump_hex(const void* data, int length); + +void +nist_dump_named_hex(const char* name, const void* data, int length); + +void +nist_dump_ctr_drbg(const NIST_CTR_DRBG* drbg); + +void +nist_dump_block_ctx(const NIST_Key* ctx); + + +#ifdef NIST_ZEROIZE +#define nist_zeroize(p, s) memset(p, 0, s) +#else +#define nist_zeroize(p, s) do { } while(0) +#error "INSECURE WITHOUT ZEROIZE" +#endif + +/* + * The test vectors will indicate failure if the + * byte ordering is set incorrectly. + * Pretending to be little endian will improve performance + * slightly but should not have an impact on + * security (a byte-swapped nonce is still a nonce). + */ + +#ifndef NIST_HTONL +#if defined(NIST_IS_LITTLE_ENDIAN) +#define NIST_HTONL(x) nist_htonl(x) +static __inline unsigned int nist_htonl(unsigned int x) +{ + return + ((((x) & 0xff000000) >> 24) | + (((x) & 0x00ff0000) >> 8) | + (((x) & 0x0000ff00) << 8) | + (((x) & 0x000000ff) << 24)); +} +#elif defined(NIST_IS_BIG_ENDIAN) +#define NIST_HTONL(x) (x) +#else +#error "Define NIST_HTONL or define NIST_IS_{BIG|LITTLE}_ENDIAN." +#endif +#endif /* NIST_HTONL */ + +#ifndef NIST_NTOHL +/* BE->H and H->BE are usually the same. */ +#define NIST_NTOHL(x) NIST_HTONL(x) +#endif /* NIST_NTOHL */ + +#endif /* NIST_CTR_DRBG_H */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/nist_ctr_drbg_aes256.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/nist_ctr_drbg_aes256.h new file mode 100644 index 0000000000..b258e7d48a --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/nist_ctr_drbg_aes256.h @@ -0,0 +1,94 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * Copyright (c) 2007 Henric Jungheim + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * NIST SP 800-90 CTR_DRBG (Random Number Generator) + */ + +#ifndef NIST_CTR_DRBG_AES256_H +#define NIST_CTR_DRBG_AES256_H + +/* Choose AES-256 as the underlying block cipher */ +#define NIST_BLOCK_KEYLEN (256) +#define NIST_BLOCK_KEYLEN_BYTES (NIST_BLOCK_KEYLEN / 8) +#define NIST_BLOCK_KEYLEN_INTS (NIST_BLOCK_KEYLEN_BYTES / sizeof(int)) + +#define NIST_BLOCK_OUTLEN (NIST_AES_BLOCKSIZEBITS) +#define NIST_BLOCK_OUTLEN_BYTES (NIST_BLOCK_OUTLEN / 8) +#define NIST_BLOCK_OUTLEN_INTS (NIST_BLOCK_OUTLEN_BYTES / sizeof(int)) + +typedef NIST_AES_ENCRYPT_CTX NIST_Key; + +#define Block_Encrypt(ctx, src, dst) NIST_AES_ECB_Encrypt(ctx, src, dst) +#define Block_Schedule_Encryption(ctx, key) NIST_AES_Schedule_Encryption(ctx, key, NIST_BLOCK_KEYLEN) + +/* + * NIST SP 800-90 March 2007 + * 10.2 DRBG Mechanism Based on Block Ciphers + * + * Table 3 specifies the reseed interval as + * <= 2^48. We are only using a 32-bit counter, + * so we set the reseed interval a bit lower. + */ +#define NIST_CTR_DRBG_RESEED_INTERVAL (100000) + +#endif /* NIST_CTR_DRBG_AES256_H */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/perf.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/perf.h new file mode 100644 index 0000000000..54a561b90c --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/perf.h @@ -0,0 +1,178 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* perf.h - profiling utility functions + * + * author - Jim Newsome (jnewsome@no-fuss.com) + * + * Some utility functions for profiling. They are designed to be + * smp-safe - each running timer is cpu-specific. + * + * Call perf_ctr_init before using a perf_ctr_t. + * Call perf_ctr_timer_start before + * perf_ctr_timer_record or perf_ctr_timer_discard. + * After calling perf_ctr_timer_start, be sure to call + * perf_ctr_timer_record or perf_ctr_timer_discard before calling it again + */ + +#ifndef PERF_H +#define PERF_H + +#ifndef __ASSEMBLY__ + + +#ifdef __PROFILING__ + +typedef struct perf_counter { + /* per-cpu */ + u64 start_time[MAX_VCPU_ENTRIES]; + + /* protects all below */ + u32 lock; + + u64 total_time; + u64 count; +} perf_ctr_t; + +/* call exactly once for a perf_ctr_t */ +static inline void perf_ctr_init(perf_ctr_t *p) +{ + u32 i; + + for(i=0; istart_time[i] = 0; + } + p->lock = 1; + p->total_time = 0; + p->count = 0; +} + +/* ASSUMES no currently running timers in p. */ +static inline void perf_ctr_reset(perf_ctr_t *p) +{ + u32 i; + spin_lock(&(p->lock)); + for(i=0; istart_time[i] == 0); + } + p->total_time = 0; + p->count = 0; + spin_unlock(&(p->lock)); +} + +/* p must be initialized, and the specified timer not running */ +static inline void perf_ctr_timer_start(perf_ctr_t *p, u32 cpuid) +{ + HALT_ON_ERRORCOND(cpuid < MAX_VCPU_ENTRIES); + HALT_ON_ERRORCOND(p->start_time[cpuid] == 0); + + p->start_time[cpuid] = rdtsc64(); +} + +/* specified timer must be running */ +static inline void perf_ctr_timer_record(perf_ctr_t *p, u32 cpuid) +{ + HALT_ON_ERRORCOND(cpuid < MAX_VCPU_ENTRIES); + HALT_ON_ERRORCOND(p->start_time[cpuid] != 0); + + spin_lock(&(p->lock)); + p->total_time += rdtsc64() - p->start_time[cpuid]; + p->count++; + p->start_time[cpuid] = 0; + spin_unlock(&(p->lock)); +} + +/* specified timer must be running */ +static inline void perf_ctr_timer_discard(perf_ctr_t *p, u32 cpuid) +{ + HALT_ON_ERRORCOND(cpuid < MAX_VCPU_ENTRIES); + HALT_ON_ERRORCOND(p->start_time[cpuid] != 0); + + p->start_time[cpuid] = 0; +} + +static inline u64 perf_ctr_get_total_time(perf_ctr_t *p) +{ + u64 rv; + spin_lock(&(p->lock)); + rv = p->total_time; + spin_unlock(&(p->lock)); + return rv; +} + +static inline u64 perf_ctr_get_count(perf_ctr_t *p) +{ + u64 rv; + spin_lock(&(p->lock)); + rv = p->count; + spin_unlock(&(p->lock)); + return rv; +} + +#else /* __PROFILING__ */ + +typedef struct perf_counter { + u32 placeholder; +} perf_ctr_t; + +/* call exactly once for a perf_ctr_t */ +#define perf_ctr_init(...) do { } while (0) +#define perf_ctr_reset(...) do { } while (0) +#define perf_ctr_timer_start(...) do { } while (0) +#define perf_ctr_timer_record(...) do { } while (0) +#define perf_ctr_timer_discard(...) do { } while (0) +#define perf_ctr_get_total_time(...) 0ull +#define perf_ctr_get_count(...) 0ull + + + +#endif /* __PROFILING__ */ + + +#endif //__ASSEMBLY__ + + +#endif diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/print_hex.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/print_hex.h new file mode 100644 index 0000000000..5f04c40c09 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/print_hex.h @@ -0,0 +1,63 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* print_hex.h - hex printing function + author(s): Amit Vasudevan (amitvasudevan@acm.org) + Jim Newsome +*/ + +#ifndef PRINT_HEX_H +#define PRINT_HEX_H + +#ifndef __ASSEMBLY__ + +void dprintf(u32 log_type, const char *fmt, ...); +void print_hex(const char *prefix, const void *prtptr, size_t size); + +#endif //__ASSEMBLY__ + + +#endif //PRINT_HEX_H diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/rijndael.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/rijndael.h new file mode 100644 index 0000000000..384a0c6147 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/rijndael.h @@ -0,0 +1,104 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* $OpenBSD: rijndael.h,v 1.12 2007/05/27 05:43:17 tedu Exp $ */ + +/** + * rijndael-alg-fst.h + * + * @version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen + * @author Antoon Bosselaers + * @author Paulo Barreto + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __RIJNDAEL_H +#define __RIJNDAEL_H + +#define AES_MAXKEYBITS (256) +#define AES_MAXKEYBYTES (AES_MAXKEYBITS/8) +/* for 256-bit keys, fewer for less */ +#define AES_MAXROUNDS 14 + +/* typedef unsigned char u8; */ +/* typedef unsigned short u16; */ +/* typedef unsigned int u32; */ + +/* The structure for key information */ +typedef struct { + int enc_only; /* context contains only encrypt schedule */ + int Nr; /* key-length-dependent number of rounds */ + uint32_t ek[4*(AES_MAXROUNDS + 1)]; /* encrypt key schedule */ + uint32_t dk[4*(AES_MAXROUNDS + 1)]; /* decrypt key schedule */ +} rijndael_ctx; + +/*int rijndael_set_key(rijndael_ctx *, const u_char *, int); +int rijndael_set_key_enc_only(rijndael_ctx *, const u_char *, int); +void rijndael_decrypt(const rijndael_ctx *, const u_char *src, u_char *dst); +void rijndael_encrypt(const rijndael_ctx *, const u_char *src, u_char *dst); +*/ +int rijndaelKeySetupEnc(unsigned int [], const unsigned char [], int); +int rijndaelKeySetupDec(unsigned int [], const unsigned char [], int); +void rijndaelEncrypt(const unsigned int [], int, const unsigned char [16], + unsigned char [16]); + +#endif /* __RIJNDAEL_H */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/sha2.h b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/sha2.h new file mode 100644 index 0000000000..afa21a99fe --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/include/sha2.h @@ -0,0 +1,192 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* $FreeBSD: releng/8.2/sys/crypto/sha2/sha2.h 92756 2002-03-20 05:14:42Z alfred $ */ +/* $KAME: sha2.h,v 1.3 2001/03/12 08:27:48 itojun Exp $ */ + +/* + * sha2.h + * + * Version 1.0.0beta1 + * + * Written by Aaron D. Gifford + * + * Copyright 2000 Aaron D. Gifford. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#ifndef __SHA2_H__ +#define __SHA2_H__ + +#ifndef __ASSEMBLY__ + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*** SHA-256/384/512 Various Length Definitions ***********************/ +#define SHA256_BLOCK_LENGTH 64 +#define SHA256_DIGEST_LENGTH 32 +#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) +#define SHA384_BLOCK_LENGTH 128 +#define SHA384_DIGEST_LENGTH 48 +#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) +#define SHA512_BLOCK_LENGTH 128 +#define SHA512_DIGEST_LENGTH 64 +#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) + + +/*** SHA-256/384/512 Context Structures *******************************/ +/* NOTE: If your architecture does not define either u_intXX_t types or + * uintXX_t (from inttypes.h), you may need to define things by hand + * for your system: + */ +#if 0 +typedef unsigned char u_int8_t; /* 1-byte (8-bits) */ +typedef unsigned int u_int32_t; /* 4-bytes (32-bits) */ +typedef unsigned long long u_int64_t; /* 8-bytes (64-bits) */ +#endif +/* + * Most BSD systems already define u_intXX_t types, as does Linux. + * Some systems, however, like Compaq's Tru64 Unix instead can use + * uintXX_t types defined by very recent ANSI C standards and included + * in the file: + * + * #include + * + * If you choose to use then please define: + * + * #define SHA2_USE_INTTYPES_H + * + * Or on the command line during compile: + * + * cc -DSHA2_USE_INTTYPES_H ... + */ +#if 1 /*def SHA2_USE_INTTYPES_H*/ + +typedef struct _SHA256_CTX { + uint32_t state[8]; + uint64_t bitcount; + uint8_t buffer[SHA256_BLOCK_LENGTH]; +} SHA256_CTX; +typedef struct _SHA512_CTX { + uint64_t state[8]; + uint64_t bitcount[2]; + uint8_t buffer[SHA512_BLOCK_LENGTH]; +} SHA512_CTX; + +#else /* SHA2_USE_INTTYPES_H */ + +typedef struct _SHA256_CTX { + u_int32_t state[8]; + u_int64_t bitcount; + u_int8_t buffer[SHA256_BLOCK_LENGTH]; +} SHA256_CTX; +typedef struct _SHA512_CTX { + u_int64_t state[8]; + u_int64_t bitcount[2]; + u_int8_t buffer[SHA512_BLOCK_LENGTH]; +} SHA512_CTX; + +#endif /* SHA2_USE_INTTYPES_H */ + +typedef SHA512_CTX SHA384_CTX; + + +/*** SHA-256/384/512 Function Prototypes ******************************/ + +void SHA256_Init(SHA256_CTX *); +void SHA256_Update(SHA256_CTX*, const u_int8_t*, size_t); +void SHA256_Final(u_int8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); +char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); +char* SHA256_Data(const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); + +void SHA384_Init(SHA384_CTX*); +void SHA384_Update(SHA384_CTX*, const u_int8_t*, size_t); +void SHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); +char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); +char* SHA384_Data(const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); + +void SHA512_Init(SHA512_CTX*); +void SHA512_Update(SHA512_CTX*, const u_int8_t*, size_t); +void SHA512_Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); +char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); +char* SHA512_Data(const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __ASSEMBLY__ + + +#endif /* __SHA2_H__ */ diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/nist_ctr_drbg.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/nist_ctr_drbg.c new file mode 100644 index 0000000000..7ef174e1e6 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/nist_ctr_drbg.c @@ -0,0 +1,655 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * Copyright (c) 2007 Henric Jungheim + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * NIST SP 800-90 CTR_DRBG (Random Number Generator) + */ + +#include +#include +#include + +/* #include */ +/* #include */ +/* #include */ +/* #include */ + +#ifndef assert +/** + * AHH! FIXME: TODO: Come up with systematic assert() handling. XXX + */ +#define assert(x) { if(!(x)) { __asm__ __volatile__ ("hlt\r\n"); } } +#endif + +/* + * NIST SP 800-90 March 2007 + * 10.4.2 Derivation Function Using a Block Cipher Algorithm + * Global Constants + */ +static NIST_Key nist_cipher_df_ctx; +static unsigned char nist_cipher_df_encrypted_iv[NIST_BLOCK_SEEDLEN / NIST_BLOCK_OUTLEN][NIST_BLOCK_OUTLEN_BYTES]; + +/* + * NIST SP 800-90 March 2007 + * 10.2.1.3.2 The Process Steps for Instantiation When a Derivation + * Function is Used + * Global Constants + */ +static NIST_Key nist_cipher_zero_ctx; + +/* + * NIST SP 800-90 March 2007 + * 10.2.1.5.2 The Process Steps for Generating Pseudorandom Bits When a + * Derivation Function is Used for the DRBG Implementation + * Global Constants + */ +static const unsigned int nist_ctr_drgb_generate_null_input[NIST_BLOCK_SEEDLEN_INTS] = { 0 }; + + +/* + * Utility + */ +/* + * nist_increment_block + * Increment the output block as a big-endian number. + */ +static void +nist_increment_block(unsigned int* V) +{ + int i; + unsigned int x; + + for (i = NIST_BLOCK_OUTLEN_INTS - 1; i >= 0; --i) { + x = NIST_NTOHL(V[i]) + 1; + V[i] = NIST_HTONL(x); + if (x) /* There was only a carry if we are zero */ + return; + } +} + +/* + * NIST SP 800-90 March 2007 + * 10.4.3 BCC Function + */ +static void +nist_ctr_drbg_bcc_update(const NIST_Key* ctx, const unsigned int* data, int n, unsigned int *chaining_value) +{ + int i; + unsigned j; + unsigned int input_block[NIST_BLOCK_OUTLEN_INTS]; + + /* [4] for i = 1 to n */ + for (i = 0; i < n; ++i) { + + /* [4.1] input_block = chaining_value XOR block_i */ + for (j = 0; j < NIST_BLOCK_OUTLEN_INTS; ++j) + input_block[j] = chaining_value[j] ^ *data++; + + /* [4.2] chaining_value = Block_Encrypt(Key, input_block) */ + Block_Encrypt(ctx, &input_block[0], &chaining_value[0]); + } + + /* [5] output_block = chaining_value */ + /* chaining_value already is output_block, so no copy is required */ +} + +static void +nist_ctr_drbg_bcc(NIST_Key* ctx, const unsigned int* data, int n, unsigned int *output_block) +{ + unsigned int* chaining_value = output_block; + + /* [1] chaining_value = 0^outlen */ + memset(&chaining_value[0], 0, NIST_BLOCK_OUTLEN_BYTES); + + nist_ctr_drbg_bcc_update(ctx, data, n, output_block); +} + +/* + * NIST SP 800-90 March 2007 + * 10.4.2 Derivation Function Using a Block Cipher Algorithm + */ + +typedef struct { + int index; + unsigned char S[NIST_BLOCK_OUTLEN_BYTES]; +} NIST_CTR_DRBG_DF_BCC_CTX; + +static __inline int +check_int_alignment(const void* p) +{ + /* + * It would be great if "intptr_t" could be found in + * some standard place. + */ + unsigned int ip = (unsigned int)((const char *)p - (const char *)0); + + if (ip & (sizeof(int) - 1)) + return 0; + + return 1; +} + +static void +nist_ctr_drbg_df_bcc_init(NIST_CTR_DRBG_DF_BCC_CTX* ctx, int L, int N) +{ + unsigned int* S = (unsigned int *)ctx->S; + + /* [4] S = L || N || input_string || 0x80 */ + S[0] = NIST_HTONL(L); + S[1] = NIST_HTONL(N); + ctx->index = 2 * sizeof(S[0]); +} + +static void +nist_ctr_drbg_df_bcc_update(NIST_CTR_DRBG_DF_BCC_CTX* ctx, const char* input_string, int input_string_length, unsigned int* temp) +{ + int i, len; + int index = ctx->index; + unsigned char* S = ctx->S; + + if (index) { + assert(index < NIST_BLOCK_OUTLEN_BYTES); + len = NIST_BLOCK_OUTLEN_BYTES - index; + if (input_string_length < len) + len = input_string_length; + + memcpy(&S[index], input_string, len); + + index += len; + input_string += len; + input_string_length -= len; + + if (index < NIST_BLOCK_OUTLEN_BYTES) { + ctx->index = index; + + return; + } + + /* We have a full block in S, so let's process it */ + /* [9.2] BCC */ + nist_ctr_drbg_bcc_update(&nist_cipher_df_ctx, (unsigned int *)&S[0], 1, temp); + index = 0; + } + + /* ctx->S is empty, so let's handle as many input blocks as we can */ + len = input_string_length / NIST_BLOCK_OUTLEN_BYTES; + if (len > 0) { + if (check_int_alignment(input_string)) { + /* [9.2] BCC */ + nist_ctr_drbg_bcc_update(&nist_cipher_df_ctx, (const unsigned int *)input_string, len, temp); + + input_string += len * NIST_BLOCK_OUTLEN_BYTES; + input_string_length -= len * NIST_BLOCK_OUTLEN_BYTES; + } else { + for (i = 0; i < len; ++i) { + memcpy(&S[0], input_string, NIST_BLOCK_OUTLEN_BYTES); + + /* [9.2] BCC */ + nist_ctr_drbg_bcc_update(&nist_cipher_df_ctx, (unsigned int *)&S[0], 1, temp); + + input_string += NIST_BLOCK_OUTLEN_BYTES; + input_string_length -= NIST_BLOCK_OUTLEN_BYTES; + } + } + } + + assert(input_string_length < NIST_BLOCK_OUTLEN_BYTES); + + if (input_string_length) { + memcpy(&S[0], input_string, input_string_length); + index = input_string_length; + } + + ctx->index = index; +} + +static void +nist_ctr_drbg_df_bcc_final(NIST_CTR_DRBG_DF_BCC_CTX* ctx, unsigned int* temp) +{ + int index; + unsigned char* S = ctx->S; + static const char endmark[] = { 0x80 }; + + nist_ctr_drbg_df_bcc_update(ctx, endmark, sizeof(endmark), temp); + + index = ctx->index; + if (index) { + memset(&S[index], 0, NIST_BLOCK_OUTLEN_BYTES - index); + + /* [9.2] BCC */ + nist_ctr_drbg_bcc_update(&nist_cipher_df_ctx, (unsigned int *)&S[0], 1, temp); + } +} + +static int +nist_ctr_drbg_block_cipher_df(const char* input_string[], unsigned int L[], + int input_string_count, unsigned char* output_string, unsigned int N) +{ + int j, k, blocks, sum_L; + unsigned int *temp; + unsigned int *X; + NIST_Key ctx; + NIST_CTR_DRBG_DF_BCC_CTX df_bcc_ctx; + unsigned int buffer[NIST_BLOCK_SEEDLEN_INTS]; + /* + * NIST SP 800-90 March 2007 10.4.2 states that 512 bits is + * the maximum length for the approved block cipher algorithms. + */ + unsigned int output_buffer[512 / 8 / sizeof(unsigned int)]; + + if (N > sizeof(output_buffer) || N < 1) + return 0; + + sum_L = 0; + for (j = 0; j < input_string_count; ++j) + sum_L += L[j]; + + /* [6] temp = Null string */ + temp = buffer; + + /* [9] while len(temp) < keylen + outlen, do */ + for (j = 0; j < NIST_BLOCK_SEEDLEN / NIST_BLOCK_OUTLEN; ++j) { + /* [9.2] temp = temp || BCC(K, (IV || S)) */ + + /* Since we have precomputed BCC(K, IV), we start with that... */ + memcpy(&temp[0], &nist_cipher_df_encrypted_iv[j][0], NIST_BLOCK_OUTLEN_BYTES); + + nist_ctr_drbg_df_bcc_init(&df_bcc_ctx, sum_L, N); + + /* Compute the rest of BCC(K, (IV || S)) */ + for (k = 0; k < input_string_count; ++k) + nist_ctr_drbg_df_bcc_update(&df_bcc_ctx, input_string[k], L[k], temp); + + nist_ctr_drbg_df_bcc_final(&df_bcc_ctx, temp); + + temp += NIST_BLOCK_OUTLEN_INTS; + } + + nist_zeroize(&df_bcc_ctx, sizeof(df_bcc_ctx)); + + /* [6] temp = Null string */ + temp = buffer; + + /* [10] K = Leftmost keylen bits of temp */ + Block_Schedule_Encryption(&ctx, &temp[0]); + + /* [11] X = next outlen bits of temp */ + X = &temp[NIST_BLOCK_KEYLEN_INTS]; + + /* [12] temp = Null string */ + temp = output_buffer; + + /* [13] While len(temp) < number_of_bits_to_return, do */ + blocks = (int)(N / NIST_BLOCK_OUTLEN_BYTES); + if (N & (NIST_BLOCK_OUTLEN_BYTES - 1)) + ++blocks; + for (j = 0; j < blocks; ++j) { + /* [13.1] X = Block_Encrypt(K, X) */ + Block_Encrypt(&ctx, X, temp); + X = temp; + temp += NIST_BLOCK_OUTLEN_INTS; + } + + /* [14] requested_bits = Leftmost number_of_bits_to_return of temp */ + memcpy(output_string, output_buffer, N); + + nist_zeroize(&ctx, sizeof(ctx)); + + return 0; +} + + +static int +nist_ctr_drbg_block_cipher_df_initialize(void) +{ + unsigned int i; + int err; + unsigned char K[NIST_BLOCK_KEYLEN_BYTES]; + unsigned int IV[NIST_BLOCK_OUTLEN_INTS]; + + /* [8] K = Leftmost keylen bits of 0x00010203 ... 1D1E1F */ + for (i = 0; i < sizeof(K); ++i) + K[i] = (unsigned char)i; + + err = Block_Schedule_Encryption(&nist_cipher_df_ctx, K); + if (err) + return err; + + /* + * Precompute the partial BCC result from encrypting the IVs: + * nist_cipher_df_encrypted_iv[i] = BCC(K, IV(i)) + */ + + /* [7] i = 0 */ + /* [9.1] IV = i || 0^(outlen - len(i)) */ + memset(&IV[0], 0, sizeof(IV)); + + /* [9.3] i = i + 1 */ + for (i = 0; i < NIST_BLOCK_SEEDLEN / NIST_BLOCK_OUTLEN; ++i) { + + /* [9.1] IV = i || 0^(outlen - len(i)) */ + IV[0] = NIST_HTONL(i); + + /* [9.2] temp = temp || BCC(K, (IV || S)) (the IV part, at least) */ + nist_ctr_drbg_bcc(&nist_cipher_df_ctx, &IV[0], 1, (unsigned int *)&nist_cipher_df_encrypted_iv[i][0]); + } + + return 0; +} + +/* + * NIST SP 800-90 March 2007 + * 10.2.1.2 The Update Function + */ +static void +nist_ctr_drbg_update(NIST_CTR_DRBG* drbg, const unsigned int* provided_data) +{ + unsigned int i; + unsigned int temp[NIST_BLOCK_SEEDLEN_INTS]; + unsigned int* output_block; + + /* 2. while (len(temp) < seedlen) do */ + for (output_block = temp; output_block < &temp[NIST_BLOCK_SEEDLEN_INTS]; + output_block += NIST_BLOCK_OUTLEN_INTS) { + + /* 2.1 V = (V + 1) mod 2^outlen */ + nist_increment_block(&drbg->V[0]); + + /* 2.2 output_block = Block_Encrypt(K, V) */ + Block_Encrypt(&drbg->ctx, drbg->V, output_block); + } + + /* 3 temp is already of size seedlen (NIST_BLOCK_SEEDLEN_INTS) */ + + /* 4 (part 1) temp = temp XOR provided_data */ + for (i = 0; i < NIST_BLOCK_KEYLEN_INTS; ++i) + temp[i] ^= *provided_data++; + + /* 5 Key = leftmost keylen bits of temp */ + Block_Schedule_Encryption(&drbg->ctx, &temp[0]); + + /* 4 (part 2) combined with 6 V = rightmost outlen bits of temp */ + for (i = 0; i < NIST_BLOCK_OUTLEN_INTS; ++i) + drbg->V[i] = temp[NIST_BLOCK_KEYLEN_INTS + i] ^ *provided_data++; +} + +/* + * NIST SP 800-90 March 2007 + * 10.2.1.3.2 The Process Steps for Instantiation When a Derivation + * Function is Used + */ +int +nist_ctr_drbg_instantiate(NIST_CTR_DRBG* drbg, + const void* entropy_input, int entropy_input_length, + const void* nonce, int nonce_length, + const void* personalization_string, int personalization_string_length) +{ + int err, count; + unsigned int seed_material[NIST_BLOCK_SEEDLEN_INTS]; + unsigned int length[3]; + const char *input_string[3]; + + /* [1] seed_material = entropy_input || nonce || personalization_string */ + + input_string[0] = entropy_input; + length[0] = entropy_input_length; + + input_string[1] = nonce; + length[1] = nonce_length; + + count = 2; + if (personalization_string) { + input_string[count] = personalization_string; + length[count] = personalization_string_length; + ++count; + } + /* [2] seed_material = Block_Cipher_df(seed_material, seedlen) */ + err = nist_ctr_drbg_block_cipher_df(input_string, length, count, + (unsigned char *)seed_material, sizeof(seed_material)); + if (err) + return err; + + /* [3] Key = 0^keylen */ + memcpy(&drbg->ctx, &nist_cipher_zero_ctx, sizeof(drbg->ctx)); + + /* [4] V = 0^outlen */ + memset(&drbg->V, 0, sizeof(drbg->V)); + + /* [5] (Key, V) = Update(seed_material, Key, V) */ + nist_ctr_drbg_update(drbg, seed_material); + + /* [6] reseed_counter = 1 */ + drbg->reseed_counter = 1; + + return 0; +} + +static int +nist_ctr_drbg_instantiate_initialize(void) +{ + int err; + unsigned char K[NIST_BLOCK_KEYLEN_BYTES]; + + memset(&K[0], 0, sizeof(K)); + + err = Block_Schedule_Encryption(&nist_cipher_zero_ctx, &K[0]); + + return err; +} + +/* + * NIST SP 800-90 March 2007 + * 10.2.1.4.2 The Process Steps for Reseeding When a Derivation + * Function is Used + */ +int +nist_ctr_drbg_reseed(NIST_CTR_DRBG* drbg, + const void* entropy_input, int entropy_input_length, + const void* additional_input, int additional_input_length) +{ + int err, count; + const char *input_string[2]; + unsigned int length[2]; + unsigned int seed_material[NIST_BLOCK_SEEDLEN_INTS]; + + /* [1] seed_material = entropy_input || additional_input */ + input_string[0] = entropy_input; + length[0] = entropy_input_length; + count = 1; + + if (additional_input) { + input_string[count] = additional_input; + length[count] = additional_input_length; + + ++count; + } + /* [2] seed_material = Block_Cipher_df(seed_material, seedlen) */ + err = nist_ctr_drbg_block_cipher_df(input_string, length, count, + (unsigned char *)seed_material, sizeof(seed_material)); + if (err) + return err; + + /* [3] (Key, V) = Update(seed_material, Key, V) */ + nist_ctr_drbg_update(drbg, seed_material); + + /* [4] reseed_counter = 1 */ + drbg->reseed_counter = 1; + + return 0; +} + +/* + * NIST SP 800-90 March 2007 + * 10.2.1.5.2 The Process Steps for Generating Pseudorandom Bits When a + * Derivation Function is Used for the DRBG Implementation + */ +static void +nist_ctr_drbg_generate_block(NIST_CTR_DRBG* drbg, unsigned int* output_block) +{ + /* [4.1] V = (V + 1) mod 2^outlen */ + nist_increment_block(&drbg->V[0]); + + /* [4.2] output_block = Block_Encrypt(Key, V) */ + Block_Encrypt(&drbg->ctx, &drbg->V[0], output_block); +} + +int +nist_ctr_drbg_generate(NIST_CTR_DRBG* drbg, + void* output_string, int output_string_length, + const void* additional_input, int additional_input_length) +{ + int i, len, err; + int blocks = output_string_length / NIST_BLOCK_OUTLEN_BYTES; + unsigned char* p; + unsigned int* temp; + const char *input_string[1]; + unsigned int length[1]; + unsigned int buffer[NIST_BLOCK_OUTLEN_BYTES]; + unsigned int additional_input_buffer[NIST_BLOCK_SEEDLEN_INTS]; + + if (output_string_length < 1) + return 1; + + /* [1] If reseed_counter > reseed_interval ... */ + if (drbg->reseed_counter >= NIST_CTR_DRBG_RESEED_INTERVAL) + return 1; + + /* [2] If (addional_input != Null), then */ + if (additional_input) { + input_string[0] = additional_input; + length[0] = additional_input_length; + /* [2.1] additional_input = Block_Cipher_df(additional_input, seedlen) */ + err = nist_ctr_drbg_block_cipher_df(input_string, length, 1, + (unsigned char *)additional_input_buffer, sizeof(additional_input_buffer)); + if (err) + return err; + + /* [2.2] (Key, V) = Update(additional_input, Key, V) */ + nist_ctr_drbg_update(drbg, additional_input_buffer); + } + + if (blocks && check_int_alignment(output_string)) { + /* [3] temp = Null */ + temp = (unsigned int *)output_string; + for (i = 0; i < blocks; ++i) { + nist_ctr_drbg_generate_block(drbg, temp); + + temp += NIST_BLOCK_OUTLEN_INTS; + output_string_length -= NIST_BLOCK_OUTLEN_BYTES; + } + + output_string = (unsigned char *)temp; + } + + /* [3] temp = Null */ + temp = buffer; + + len = NIST_BLOCK_OUTLEN_BYTES; + + /* [4] While (len(temp) < requested_number_of_bits) do: */ + p = output_string; + while (output_string_length > 0) { + nist_ctr_drbg_generate_block(drbg, temp); + + if (output_string_length < NIST_BLOCK_OUTLEN_BYTES) + len = output_string_length; + + memcpy(p, temp, len); + + p += len; + output_string_length -= len; + } + + /* [6] (Key, V) = Update(additional_input, Key, V) */ + nist_ctr_drbg_update(drbg, additional_input ? + &additional_input_buffer[0] : + &nist_ctr_drgb_generate_null_input[0]); + + /* [7] reseed_counter = reseed_counter + 1 */ + ++drbg->reseed_counter; + + return 0; +} + +int +nist_ctr_initialize() +{ + int err; + + err = nist_ctr_drbg_instantiate_initialize(); + if (err) + return err; + err = nist_ctr_drbg_block_cipher_df_initialize(); + if (err) + return err; + + return 0; +} + +int +nist_ctr_drbg_destroy(NIST_CTR_DRBG* drbg) +{ + nist_zeroize(drbg, sizeof(*drbg)); + drbg->reseed_counter = ~0U; + + return 1; +} diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/print_hex.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/print_hex.c new file mode 100644 index 0000000000..723da9af71 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/print_hex.c @@ -0,0 +1,78 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* print_hex.c - hex printing function + author(s): Amit Vasudevan (amitvasudevan@acm.org) + Jim Newsome +*/ + +#include +#include +#include + +void dprintf(u32 log_type, const char *fmt, ...) +{ + va_list args; + (void)log_type; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); +} + + +/* + * if 'prefix' != NULL, print it before each line of hex string + */ +void print_hex(const char *prefix, const void *prtptr, size_t size) +{ + size_t i; + for ( i = 0; i < size; i++ ) { + if ( i % 16 == 0 && prefix != NULL ) + printf("\n%s", prefix); + printf("%02x ", *(const uint8_t *)prtptr++); + } + printf("\n"); +} diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/rijndael.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/rijndael.c new file mode 100644 index 0000000000..9ecd296ba6 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/rijndael.c @@ -0,0 +1,1315 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* $OpenBSD: rijndael.c,v 1.18 2005/05/25 05:47:53 markus Exp $ */ + +/** + * rijndael-alg-fst.c + * + * @version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen + * @author Antoon Bosselaers + * @author Paulo Barreto + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include +//#include + +#include +#include + +#include + +#undef FULL_UNROLL + +/* +Te0[x] = S [x].[02, 01, 01, 03]; +Te1[x] = S [x].[03, 02, 01, 01]; +Te2[x] = S [x].[01, 03, 02, 01]; +Te3[x] = S [x].[01, 01, 03, 02]; +Te4[x] = S [x].[01, 01, 01, 01]; + +Td0[x] = Si[x].[0e, 09, 0d, 0b]; +Td1[x] = Si[x].[0b, 0e, 09, 0d]; +Td2[x] = Si[x].[0d, 0b, 0e, 09]; +Td3[x] = Si[x].[09, 0d, 0b, 0e]; +Td4[x] = Si[x].[01, 01, 01, 01]; +*/ + +static const u32 Te0[256] = { + 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, + 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, + 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, + 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, + 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, + 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, + 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, + 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, + 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, + 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, + 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, + 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, + 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, + 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, + 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, + 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, + 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, + 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, + 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, + 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, + 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, + 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, + 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, + 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, + 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, + 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, + 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, + 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, + 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, + 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, + 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, + 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, + 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, + 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, + 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, + 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, + 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, + 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, + 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, + 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, + 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, + 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, + 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, + 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, + 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, + 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, + 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, + 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, + 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, + 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, + 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, + 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, + 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, + 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, + 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, + 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, + 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, + 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, + 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, + 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, + 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, + 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, + 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, + 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, +}; +static const u32 Te1[256] = { + 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, + 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, + 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, + 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, + 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, + 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, + 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, + 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, + 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, + 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, + 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, + 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, + 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, + 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, + 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, + 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, + 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, + 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, + 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, + 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, + 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, + 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, + 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, + 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, + 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, + 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, + 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, + 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, + 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, + 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, + 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, + 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, + 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, + 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, + 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, + 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, + 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, + 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, + 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, + 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, + 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, + 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, + 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, + 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, + 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, + 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, + 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, + 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, + 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, + 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, + 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, + 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, + 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, + 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, + 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, + 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, + 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, + 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, + 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, + 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, + 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, + 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, + 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, + 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, +}; +static const u32 Te2[256] = { + 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, + 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, + 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, + 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, + 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, + 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, + 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, + 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, + 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, + 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, + 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, + 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, + 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, + 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, + 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, + 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, + 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, + 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, + 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, + 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, + 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, + 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, + 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, + 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, + 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, + 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, + 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, + 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, + 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, + 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, + 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, + 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, + 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, + 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, + 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, + 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, + 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, + 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, + 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, + 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, + 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, + 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, + 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, + 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, + 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, + 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, + 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, + 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, + 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, + 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, + 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, + 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, + 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, + 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, + 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, + 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, + 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, + 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, + 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, + 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, + 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, + 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, + 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, + 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, +}; +static const u32 Te3[256] = { + 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, + 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, + 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, + 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, + 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, + 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, + 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, + 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, + 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, + 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, + 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, + 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, + 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, + 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, + 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, + 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, + 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, + 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, + 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, + 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, + 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, + 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, + 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, + 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, + 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, + 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, + 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, + 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, + 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, + 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, + 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, + 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, + 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, + 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, + 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, + 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, + 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, + 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, + 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, + 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, + 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, + 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, + 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, + 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, + 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, + 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, + 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, + 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, + 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, + 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, + 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, + 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, + 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, + 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, + 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, + 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, + 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, + 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, + 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, + 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, + 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, + 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, + 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, + 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, +}; +static const u32 Te4[256] = { + 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, + 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, + 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, + 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U, + 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, + 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, + 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, + 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U, + 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, + 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, + 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, + 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U, + 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, + 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU, + 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, + 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, + 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, + 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U, + 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, + 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, + 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, + 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, + 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, + 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU, + 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, + 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, + 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, + 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U, + 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, + 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, + 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, + 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, + 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, + 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U, + 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, + 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, + 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, + 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U, + 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, + 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, + 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, + 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU, + 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, + 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U, + 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, + 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, + 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, + 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U, + 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, + 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, + 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, + 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, + 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, + 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU, + 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, + 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, + 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, + 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U, + 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, + 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, + 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, + 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, + 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, + 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, +}; +static const u32 Td0[256] = { + 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, + 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, + 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, + 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, + 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, + 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, + 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, + 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, + 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, + 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, + 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, + 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, + 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, + 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, + 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, + 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, + 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, + 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, + 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, + 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, + 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, + 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, + 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, + 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, + 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, + 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, + 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, + 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, + 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, + 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, + 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, + 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, + 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, + 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, + 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, + 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, + 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, + 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, + 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, + 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, + 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, + 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, + 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, + 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, + 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, + 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, + 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, + 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, + 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, + 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, + 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, + 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, + 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, + 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, + 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, + 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, + 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, + 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, + 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, + 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, + 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, + 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, + 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, + 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, +}; +static const u32 Td1[256] = { + 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, + 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, + 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, + 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, + 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, + 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, + 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, + 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, + 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, + 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, + 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, + 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, + 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, + 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, + 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, + 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, + 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, + 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, + 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, + 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, + 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, + 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, + 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, + 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, + 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, + 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, + 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, + 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, + 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, + 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, + 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, + 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, + 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, + 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, + 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, + 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, + 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, + 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, + 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, + 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, + 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, + 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, + 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, + 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, + 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, + 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, + 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, + 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, + 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, + 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, + 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, + 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, + 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, + 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, + 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, + 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, + 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, + 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, + 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, + 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, + 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, + 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, + 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, + 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, +}; +static const u32 Td2[256] = { + 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, + 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, + 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, + 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, + 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, + 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, + 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, + 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, + 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, + 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, + 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, + 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, + 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, + 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, + 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, + 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, + 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, + 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, + 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, + 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, + 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, + 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, + 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, + 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, + 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, + 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, + 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, + 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, + 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, + 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, + 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, + 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, + 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, + 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, + 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, + 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, + 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, + 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, + 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, + 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, + 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, + 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, + 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, + 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, + 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, + 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, + 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, + 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, + 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, + 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, + 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, + 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, + 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, + 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, + 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, + 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, + 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, + 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, + 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, + 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, + 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, + 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, + 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, + 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, +}; +static const u32 Td3[256] = { + 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, + 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, + 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, + 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, + 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, + 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, + 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, + 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, + 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, + 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, + 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, + 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, + 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, + 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, + 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, + 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, + 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, + 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, + 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, + 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, + 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, + 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, + 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, + 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, + 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, + 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, + 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, + 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, + 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, + 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, + 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, + 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, + 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, + 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, + 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, + 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, + 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, + 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, + 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, + 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, + 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, + 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, + 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, + 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, + 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, + 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, + 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, + 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, + 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, + 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, + 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, + 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, + 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, + 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, + 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, + 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, + 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, + 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, + 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, + 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, + 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, + 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, + 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, + 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, +}; +static const u32 Td4[256] = { + 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, + 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U, + 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU, + 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU, + 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U, + 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U, + 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U, + 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU, + 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U, + 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU, + 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU, + 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU, + 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U, + 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U, + 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U, + 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U, + 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U, + 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U, + 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU, + 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U, + 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U, + 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU, + 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U, + 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U, + 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U, + 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU, + 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U, + 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U, + 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU, + 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U, + 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U, + 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU, + 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U, + 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU, + 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU, + 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U, + 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U, + 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U, + 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U, + 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU, + 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U, + 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U, + 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU, + 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU, + 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU, + 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U, + 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU, + 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U, + 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U, + 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U, + 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U, + 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU, + 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U, + 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU, + 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU, + 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU, + 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU, + 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U, + 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU, + 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U, + 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU, + 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U, + 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, + 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU, +}; +static const u32 rcon[] = { + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; + +#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) +#define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } + +/** + * Expand the cipher key into the encryption key schedule. + * + * @return the number of rounds for the given cipher key size. + */ +int +rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) +{ + int i = 0; + u32 temp; + + rk[0] = GETU32(cipherKey ); + rk[1] = GETU32(cipherKey + 4); + rk[2] = GETU32(cipherKey + 8); + rk[3] = GETU32(cipherKey + 12); + if (keyBits == 128) { + for (;;) { + temp = rk[3]; + rk[4] = rk[0] ^ + (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te4[(temp ) & 0xff] & 0x0000ff00) ^ + (Te4[(temp >> 24) ] & 0x000000ff) ^ + rcon[i]; + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + if (++i == 10) { + return 10; + } + rk += 4; + } + } + rk[4] = GETU32(cipherKey + 16); + rk[5] = GETU32(cipherKey + 20); + if (keyBits == 192) { + for (;;) { + temp = rk[ 5]; + rk[ 6] = rk[ 0] ^ + (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te4[(temp ) & 0xff] & 0x0000ff00) ^ + (Te4[(temp >> 24) ] & 0x000000ff) ^ + rcon[i]; + rk[ 7] = rk[ 1] ^ rk[ 6]; + rk[ 8] = rk[ 2] ^ rk[ 7]; + rk[ 9] = rk[ 3] ^ rk[ 8]; + if (++i == 8) { + return 12; + } + rk[10] = rk[ 4] ^ rk[ 9]; + rk[11] = rk[ 5] ^ rk[10]; + rk += 6; + } + } + rk[6] = GETU32(cipherKey + 24); + rk[7] = GETU32(cipherKey + 28); + if (keyBits == 256) { + for (;;) { + temp = rk[ 7]; + rk[ 8] = rk[ 0] ^ + (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te4[(temp ) & 0xff] & 0x0000ff00) ^ + (Te4[(temp >> 24) ] & 0x000000ff) ^ + rcon[i]; + rk[ 9] = rk[ 1] ^ rk[ 8]; + rk[10] = rk[ 2] ^ rk[ 9]; + rk[11] = rk[ 3] ^ rk[10]; + if (++i == 7) { + return 14; + } + temp = rk[11]; + rk[12] = rk[ 4] ^ + (Te4[(temp >> 24) ] & 0xff000000) ^ + (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(temp ) & 0xff] & 0x000000ff); + rk[13] = rk[ 5] ^ rk[12]; + rk[14] = rk[ 6] ^ rk[13]; + rk[15] = rk[ 7] ^ rk[14]; + rk += 8; + } + } + return 0; +} + +/** + * Expand the cipher key into the decryption key schedule. + * + * @return the number of rounds for the given cipher key size. + */ +int +rijndaelKeySetupDec(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) +{ + int Nr, i, j; + u32 temp; + + /* expand the cipher key: */ + Nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits); + + /* invert the order of the round keys: */ + for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) { + temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; + temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; + temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; + temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; + } + /* apply the inverse MixColumn transform to all round keys but the first and the last: */ + for (i = 1; i < Nr; i++) { + rk += 4; + rk[0] = + Td0[Te4[(rk[0] >> 24) ] & 0xff] ^ + Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^ + Td3[Te4[(rk[0] ) & 0xff] & 0xff]; + rk[1] = + Td0[Te4[(rk[1] >> 24) ] & 0xff] ^ + Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^ + Td3[Te4[(rk[1] ) & 0xff] & 0xff]; + rk[2] = + Td0[Te4[(rk[2] >> 24) ] & 0xff] ^ + Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^ + Td3[Te4[(rk[2] ) & 0xff] & 0xff]; + rk[3] = + Td0[Te4[(rk[3] >> 24) ] & 0xff] ^ + Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^ + Td3[Te4[(rk[3] ) & 0xff] & 0xff]; + } + return Nr; +} + +void +rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], + u8 ct[16]) +{ + u32 s0, s1, s2, s3, t0, t1, t2, t3; +#ifndef FULL_UNROLL + int r; +#endif /* ?FULL_UNROLL */ + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(pt ) ^ rk[0]; + s1 = GETU32(pt + 4) ^ rk[1]; + s2 = GETU32(pt + 8) ^ rk[2]; + s3 = GETU32(pt + 12) ^ rk[3]; +#ifdef FULL_UNROLL + /* round 1: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7]; + /* round 2: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11]; + /* round 3: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15]; + /* round 4: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19]; + /* round 5: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23]; + /* round 6: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27]; + /* round 7: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31]; + /* round 8: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35]; + /* round 9: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39]; + if (Nr > 10) { + /* round 10: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43]; + /* round 11: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47]; + if (Nr > 12) { + /* round 12: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51]; + /* round 13: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55]; + } + } + rk += Nr << 2; +#else /* !FULL_UNROLL */ + /* + * Nr - 1 full rounds: + */ + r = Nr >> 1; + for (;;) { + t0 = + Te0[(s0 >> 24) ] ^ + Te1[(s1 >> 16) & 0xff] ^ + Te2[(s2 >> 8) & 0xff] ^ + Te3[(s3 ) & 0xff] ^ + rk[4]; + t1 = + Te0[(s1 >> 24) ] ^ + Te1[(s2 >> 16) & 0xff] ^ + Te2[(s3 >> 8) & 0xff] ^ + Te3[(s0 ) & 0xff] ^ + rk[5]; + t2 = + Te0[(s2 >> 24) ] ^ + Te1[(s3 >> 16) & 0xff] ^ + Te2[(s0 >> 8) & 0xff] ^ + Te3[(s1 ) & 0xff] ^ + rk[6]; + t3 = + Te0[(s3 >> 24) ] ^ + Te1[(s0 >> 16) & 0xff] ^ + Te2[(s1 >> 8) & 0xff] ^ + Te3[(s2 ) & 0xff] ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + s0 = + Te0[(t0 >> 24) ] ^ + Te1[(t1 >> 16) & 0xff] ^ + Te2[(t2 >> 8) & 0xff] ^ + Te3[(t3 ) & 0xff] ^ + rk[0]; + s1 = + Te0[(t1 >> 24) ] ^ + Te1[(t2 >> 16) & 0xff] ^ + Te2[(t3 >> 8) & 0xff] ^ + Te3[(t0 ) & 0xff] ^ + rk[1]; + s2 = + Te0[(t2 >> 24) ] ^ + Te1[(t3 >> 16) & 0xff] ^ + Te2[(t0 >> 8) & 0xff] ^ + Te3[(t1 ) & 0xff] ^ + rk[2]; + s3 = + Te0[(t3 >> 24) ] ^ + Te1[(t0 >> 16) & 0xff] ^ + Te2[(t1 >> 8) & 0xff] ^ + Te3[(t2 ) & 0xff] ^ + rk[3]; + } +#endif /* ?FULL_UNROLL */ + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = + (Te4[(t0 >> 24) ] & 0xff000000) ^ + (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(t3 ) & 0xff] & 0x000000ff) ^ + rk[0]; + PUTU32(ct , s0); + s1 = + (Te4[(t1 >> 24) ] & 0xff000000) ^ + (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(t0 ) & 0xff] & 0x000000ff) ^ + rk[1]; + PUTU32(ct + 4, s1); + s2 = + (Te4[(t2 >> 24) ] & 0xff000000) ^ + (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(t1 ) & 0xff] & 0x000000ff) ^ + rk[2]; + PUTU32(ct + 8, s2); + s3 = + (Te4[(t3 >> 24) ] & 0xff000000) ^ + (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(t2 ) & 0xff] & 0x000000ff) ^ + rk[3]; + PUTU32(ct + 12, s3); +} + +static void +rijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16], + u8 pt[16]) +{ + u32 s0, s1, s2, s3, t0, t1, t2, t3; +#ifndef FULL_UNROLL + int r; +#endif /* ?FULL_UNROLL */ + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(ct ) ^ rk[0]; + s1 = GETU32(ct + 4) ^ rk[1]; + s2 = GETU32(ct + 8) ^ rk[2]; + s3 = GETU32(ct + 12) ^ rk[3]; +#ifdef FULL_UNROLL + /* round 1: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7]; + /* round 2: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11]; + /* round 3: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15]; + /* round 4: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19]; + /* round 5: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23]; + /* round 6: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27]; + /* round 7: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31]; + /* round 8: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35]; + /* round 9: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39]; + if (Nr > 10) { + /* round 10: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43]; + /* round 11: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47]; + if (Nr > 12) { + /* round 12: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51]; + /* round 13: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55]; + } + } + rk += Nr << 2; +#else /* !FULL_UNROLL */ + /* + * Nr - 1 full rounds: + */ + r = Nr >> 1; + for (;;) { + t0 = + Td0[(s0 >> 24) ] ^ + Td1[(s3 >> 16) & 0xff] ^ + Td2[(s2 >> 8) & 0xff] ^ + Td3[(s1 ) & 0xff] ^ + rk[4]; + t1 = + Td0[(s1 >> 24) ] ^ + Td1[(s0 >> 16) & 0xff] ^ + Td2[(s3 >> 8) & 0xff] ^ + Td3[(s2 ) & 0xff] ^ + rk[5]; + t2 = + Td0[(s2 >> 24) ] ^ + Td1[(s1 >> 16) & 0xff] ^ + Td2[(s0 >> 8) & 0xff] ^ + Td3[(s3 ) & 0xff] ^ + rk[6]; + t3 = + Td0[(s3 >> 24) ] ^ + Td1[(s2 >> 16) & 0xff] ^ + Td2[(s1 >> 8) & 0xff] ^ + Td3[(s0 ) & 0xff] ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + s0 = + Td0[(t0 >> 24) ] ^ + Td1[(t3 >> 16) & 0xff] ^ + Td2[(t2 >> 8) & 0xff] ^ + Td3[(t1 ) & 0xff] ^ + rk[0]; + s1 = + Td0[(t1 >> 24) ] ^ + Td1[(t0 >> 16) & 0xff] ^ + Td2[(t3 >> 8) & 0xff] ^ + Td3[(t2 ) & 0xff] ^ + rk[1]; + s2 = + Td0[(t2 >> 24) ] ^ + Td1[(t1 >> 16) & 0xff] ^ + Td2[(t0 >> 8) & 0xff] ^ + Td3[(t3 ) & 0xff] ^ + rk[2]; + s3 = + Td0[(t3 >> 24) ] ^ + Td1[(t2 >> 16) & 0xff] ^ + Td2[(t1 >> 8) & 0xff] ^ + Td3[(t0 ) & 0xff] ^ + rk[3]; + } +#endif /* ?FULL_UNROLL */ + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = + (Td4[(t0 >> 24) ] & 0xff000000) ^ + (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t1 ) & 0xff] & 0x000000ff) ^ + rk[0]; + PUTU32(pt , s0); + s1 = + (Td4[(t1 >> 24) ] & 0xff000000) ^ + (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t2 ) & 0xff] & 0x000000ff) ^ + rk[1]; + PUTU32(pt + 4, s1); + s2 = + (Td4[(t2 >> 24) ] & 0xff000000) ^ + (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t3 ) & 0xff] & 0x000000ff) ^ + rk[2]; + PUTU32(pt + 8, s2); + s3 = + (Td4[(t3 >> 24) ] & 0xff000000) ^ + (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t0 ) & 0xff] & 0x000000ff) ^ + rk[3]; + PUTU32(pt + 12, s3); +} + +/* setup key context for encryption only */ +int +rijndael_set_key_enc_only(rijndael_ctx *ctx, const u_char *key, int bits) +{ + int rounds; + + rounds = rijndaelKeySetupEnc(ctx->ek, key, bits); + if (rounds == 0) + return -1; + + ctx->Nr = rounds; + ctx->enc_only = 1; + + return 0; +} + +/* setup key context for both encryption and decryption */ +int +rijndael_set_key(rijndael_ctx *ctx, const u_char *key, int bits) +{ + int rounds; + + rounds = rijndaelKeySetupEnc(ctx->ek, key, bits); + if (rounds == 0) + return -1; + if (rijndaelKeySetupDec(ctx->dk, key, bits) != rounds) + return -1; + + ctx->Nr = rounds; + ctx->enc_only = 0; + + return 0; +} + +void +rijndael_decrypt(const rijndael_ctx *ctx, const u_char *src, u_char *dst) +{ + rijndaelDecrypt(ctx->dk, ctx->Nr, src, dst); +} + +void +rijndael_encrypt(const rijndael_ctx *ctx, const u_char *src, u_char *dst) +{ + rijndaelEncrypt(ctx->ek, ctx->Nr, src, dst); +} diff --git a/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/sha2.c b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/sha2.c new file mode 100644 index 0000000000..ba8628f227 --- /dev/null +++ b/xmhf-64/xmhf/src/libbaremetal/libxmhfutil/sha2.c @@ -0,0 +1,1101 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* $KAME: sha2.c,v 1.8 2001/11/08 01:07:52 itojun Exp $ */ + +/* + * sha2.c + * + * Version 1.0.0beta1 + * + * Written by Aaron D. Gifford + * + * Copyright 2000 Aaron D. Gifford. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +/* + * HALT_ON_ERRORCOND NOTE: + * Some sanity checking code is included using assert(). On my FreeBSD + * system, this additional code can be removed by compiling with NDEBUG + * defined. Check your own systems manpage on assert() to see how to + * compile WITHOUT the sanity checking code on your system. + * + * UNROLLED TRANSFORM LOOP NOTE: + * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform + * loop version for the hash transform rounds (defined using macros + * later in this file). Either define on the command line, for example: + * + * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c + * + * or define below: + * + * #define SHA2_UNROLL_TRANSFORM + * + */ + +/*** SHA-256/384/512 Machine Architecture Definitions *****************/ +/* + * BYTE_ORDER NOTE: + * + * Please make sure that your system defines BYTE_ORDER. If your + * architecture is little-endian, make sure it also defines + * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are + * equivilent. + * + * If your system does not define the above, then you can do so by + * hand like this: + * + * #define LITTLE_ENDIAN 1234 + * #define BIG_ENDIAN 4321 + * + * And for little-endian machines, add: + * + * #define BYTE_ORDER LITTLE_ENDIAN + * + * Or for big-endian machines: + * + * #define BYTE_ORDER BIG_ENDIAN + * + * The FreeBSD machine this was written on defines BYTE_ORDER + * appropriately by including (which in turn includes + * where the appropriate definitions are actually + * made). + */ + +/* Inspired by the macros in sha1.[ch] */ +#undef LITTLE_ENDIAN +#undef BIG_ENDIAN +#define LITTLE_ENDIAN 1234 +#define BIG_ENDIAN 4321 + +#undef BYTE_ORDER +#if (!(__x86_64__ || __i386__ || _M_IX86 || _M_X64 || __ARMEL__ || __MIPSEL__)) +#define BYTE_ORDER BIG_ENDIAN +#else +#define BYTE_ORDER LITTLE_ENDIAN +#endif + +#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) +#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN +#endif + +#define bzero(buf, len) memset(buf, 0, len) +#define bcopy(src, dst, len) memcpy(dst, src, len) + +/* + * Define the followingsha2_* types to types of the correct length on + * the native archtecture. Most BSD systems and Linux define u_intXX_t + * types. Machines with very recent ANSI C headers, can use the + * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H + * during compile or in the sha.h header file. + * + * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t + * will need to define these three typedefs below (and the appropriate + * ones in sha.h too) by hand according to their system architecture. + * + * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t + * types and pointing out recent ANSI C support for uintXX_t in inttypes.h. + */ +#if 1 /*def SHA2_USE_INTTYPES_H*/ + +typedef uint8_t sha2_byte; /* Exactly 1 byte */ +typedef uint32_t sha2_word32; /* Exactly 4 bytes */ +typedef uint64_t sha2_word64; /* Exactly 8 bytes */ + +#else /* SHA2_USE_INTTYPES_H */ + +typedef u_int8_t sha2_byte; /* Exactly 1 byte */ +typedef u_int32_t sha2_word32; /* Exactly 4 bytes */ +typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ + +#endif /* SHA2_USE_INTTYPES_H */ + + +/*** SHA-256/384/512 Various Length Definitions ***********************/ +/* NOTE: Most of these are in sha2.h */ +#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) +#define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16) +#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) + + +/*** ENDIAN REVERSAL MACROS *******************************************/ +#if BYTE_ORDER == LITTLE_ENDIAN +#define REVERSE32(w,x) { \ + sha2_word32 tmp = (w); \ + tmp = (tmp >> 16) | (tmp << 16); \ + (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ +} +#define REVERSE64(w,x) { \ + sha2_word64 tmp = (w); \ + tmp = (tmp >> 32) | (tmp << 32); \ + tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ + ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ + (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ + ((tmp & 0x0000ffff0000ffffULL) << 16); \ +} +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +/* + * Macro for incrementally adding the unsigned 64-bit integer n to the + * unsigned 128-bit integer (represented using a two-element array of + * 64-bit words): + */ +#define ADDINC128(w,n) { \ + (w)[0] += (sha2_word64)(n); \ + if ((w)[0] < (n)) { \ + (w)[1]++; \ + } \ +} + +/*** THE SIX LOGICAL FUNCTIONS ****************************************/ +/* + * Bit shifting and rotation (used by the six SHA-XYZ logical functions: + * + * NOTE: The naming of R and S appears backwards here (R is a SHIFT and + * S is a ROTATION) because the SHA-256/384/512 description document + * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this + * same "backwards" definition. + */ +/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ +#define R(b,x) ((x) >> (b)) +/* 32-bit Rotate-right (used in SHA-256): */ +#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) +/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ +#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) + +/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ +#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +/* Four of six logical functions used in SHA-256: */ +#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) +#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) +#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) +#define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) + +/* Four of six logical functions used in SHA-384 and SHA-512: */ +#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) +#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) +#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x))) +#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x))) + +/*** INTERNAL FUNCTION PROTOTYPES *************************************/ +/* NOTE: These should not be accessed directly from outside this + * library -- they are intended for private internal visibility/use + * only. + */ +void SHA512_Last(SHA512_CTX*); +void SHA256_Transform(SHA256_CTX*, const sha2_word32*); +void SHA512_Transform(SHA512_CTX*, const sha2_word64*); + + +/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ +/* Hash constant words K for SHA-256: */ +static const sha2_word32 K256[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, + 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, + 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, + 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, + 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + +/* Initial hash value H for SHA-256: */ +static const sha2_word32 sha256_initial_hash_value[8] = { + 0x6a09e667UL, + 0xbb67ae85UL, + 0x3c6ef372UL, + 0xa54ff53aUL, + 0x510e527fUL, + 0x9b05688cUL, + 0x1f83d9abUL, + 0x5be0cd19UL +}; + +/* Hash constant words K for SHA-384 and SHA-512: */ +static const sha2_word64 K512[80] = { + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, + 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, + 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, + 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, + 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, + 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, + 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, + 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, + 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, + 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, + 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, + 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, + 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, + 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, + 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, + 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, + 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, + 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, + 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, + 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, + 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, + 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, + 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, + 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, + 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, + 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, + 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, + 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, + 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, + 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, + 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, + 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, + 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, + 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, + 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, + 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, + 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL +}; + +/* Initial hash value H for SHA-384 */ +static const sha2_word64 sha384_initial_hash_value[8] = { + 0xcbbb9d5dc1059ed8ULL, + 0x629a292a367cd507ULL, + 0x9159015a3070dd17ULL, + 0x152fecd8f70e5939ULL, + 0x67332667ffc00b31ULL, + 0x8eb44a8768581511ULL, + 0xdb0c2e0d64f98fa7ULL, + 0x47b5481dbefa4fa4ULL +}; + +/* Initial hash value H for SHA-512 */ +static const sha2_word64 sha512_initial_hash_value[8] = { + 0x6a09e667f3bcc908ULL, + 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, + 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, + 0x5be0cd19137e2179ULL +}; + +/* + * Constant used by SHA256/384/512_End() functions for converting the + * digest to a readable hexadecimal character string: + */ +static const char *sha2_hex_digits = "0123456789abcdef"; + + +/*** SHA-256: *********************************************************/ +void SHA256_Init(SHA256_CTX* context) { + if (context == (SHA256_CTX*)0) { + return; + } + bcopy(sha256_initial_hash_value, context->state, SHA256_DIGEST_LENGTH); + bzero(context->buffer, SHA256_BLOCK_LENGTH); + context->bitcount = 0; +} + +#ifdef SHA2_UNROLL_TRANSFORM + +/* Unrolled SHA-256 round macros: */ + +#if BYTE_ORDER == LITTLE_ENDIAN + +#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ + REVERSE32(*data++, W256[j]); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + K256[j] + W256[j]; \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + + +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + K256[j] + (W256[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND256(a,b,c,d,e,f,g,h) \ + s0 = W256[(j+1)&0x0f]; \ + s0 = sigma0_256(s0); \ + s1 = W256[(j+14)&0x0f]; \ + s1 = sigma1_256(s1); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + +void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { + sha2_word32 a, b, c, d, e, f, g, h, s0, s1; + sha2_word32 T1, *W256; + int j; + + W256 = (sha2_word32*)context->buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { + /* Rounds 0 to 15 (unrolled): */ + ROUND256_0_TO_15(a,b,c,d,e,f,g,h); + ROUND256_0_TO_15(h,a,b,c,d,e,f,g); + ROUND256_0_TO_15(g,h,a,b,c,d,e,f); + ROUND256_0_TO_15(f,g,h,a,b,c,d,e); + ROUND256_0_TO_15(e,f,g,h,a,b,c,d); + ROUND256_0_TO_15(d,e,f,g,h,a,b,c); + ROUND256_0_TO_15(c,d,e,f,g,h,a,b); + ROUND256_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds to 64: */ + do { + ROUND256(a,b,c,d,e,f,g,h); + ROUND256(h,a,b,c,d,e,f,g); + ROUND256(g,h,a,b,c,d,e,f); + ROUND256(f,g,h,a,b,c,d,e); + ROUND256(e,f,g,h,a,b,c,d); + ROUND256(d,e,f,g,h,a,b,c); + ROUND256(c,d,e,f,g,h,a,b); + ROUND256(b,c,d,e,f,g,h,a); + } while (j < 64); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; +} + +#else /* SHA2_UNROLL_TRANSFORM */ + +void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { + sha2_word32 a, b, c, d, e, f, g, h, s0, s1; + sha2_word32 T1, T2, *W256; + int j; + + W256 = (sha2_word32*)context->buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { +#if BYTE_ORDER == LITTLE_ENDIAN + /* Copy data while converting to host byte order */ + REVERSE32(*data++,W256[j]); + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + /* Apply the SHA-256 compression function to update a..h with copy */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W256[(j+1)&0x0f]; + s0 = sigma0_256(s0); + s1 = W256[(j+14)&0x0f]; + s1 = sigma1_256(s1); + + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 64); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; +} + +#endif /* SHA2_UNROLL_TRANSFORM */ + +void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { + unsigned int freespace, usedspace; + + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); + + usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA256_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + bcopy(data, &context->buffer[usedspace], freespace); + context->bitcount += freespace << 3; + len -= freespace; + data += freespace; + SHA256_Transform(context, (sha2_word32*)context->buffer); + } else { + /* The buffer is not yet full */ + bcopy(data, &context->buffer[usedspace], len); + context->bitcount += len << 3; + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA256_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + SHA256_Transform(context, (const sha2_word32*)data); + context->bitcount += SHA256_BLOCK_LENGTH << 3; + len -= SHA256_BLOCK_LENGTH; + data += SHA256_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + bcopy(data, context->buffer, len); + context->bitcount += len << 3; + } + /* Clean up: */ + usedspace = freespace = 0; +} + +void SHA256_Final(sha2_byte digest[SHA256_DIGEST_LENGTH], SHA256_CTX* context) { + sha2_word32 *d = (sha2_word32*)digest; + unsigned int usedspace; + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert FROM host byte order */ + REVERSE64(context->bitcount,context->bitcount); +#endif + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->buffer[usedspace++] = 0x80; + + if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { + /* Set-up for the last transform: */ + bzero(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace); + } else { + if (usedspace < SHA256_BLOCK_LENGTH) { + bzero(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace); + } + /* Do second-to-last transform: */ + SHA256_Transform(context, (sha2_word32*)context->buffer); + + /* And set-up for the last transform: */ + bzero(context->buffer, SHA256_SHORT_BLOCK_LENGTH); + } + } else { + /* Set-up for the last transform: */ + bzero(context->buffer, SHA256_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *context->buffer = 0x80; + } + /* Set the bit count: */ + *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount; + + /* Final transform: */ + SHA256_Transform(context, (sha2_word32*)context->buffer); + +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 8; j++) { + REVERSE32(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } +#else + bcopy(context->state, d, SHA256_DIGEST_LENGTH); +#endif + } + + /* Clean up state data: */ + bzero(context, sizeof(*context)); + usedspace = 0; +} + +char *SHA256_End(SHA256_CTX* context, char buffer[SHA256_DIGEST_STRING_LENGTH]) { + sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0); + + if (buffer != (char*)0) { + SHA256_Final(digest, context); + + for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + bzero(context, sizeof(*context)); + } + bzero(digest, SHA256_DIGEST_LENGTH); + return buffer; +} + +char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) { + SHA256_CTX context; + + SHA256_Init(&context); + SHA256_Update(&context, data, len); + return SHA256_End(&context, digest); +} + + +/*** SHA-512: *********************************************************/ +void SHA512_Init(SHA512_CTX* context) { + if (context == (SHA512_CTX*)0) { + return; + } + bcopy(sha512_initial_hash_value, context->state, SHA512_DIGEST_LENGTH); + bzero(context->buffer, SHA512_BLOCK_LENGTH); + context->bitcount[0] = context->bitcount[1] = 0; +} + +#ifdef SHA2_UNROLL_TRANSFORM + +/* Unrolled SHA-512 round macros: */ +#if BYTE_ORDER == LITTLE_ENDIAN + +#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ + REVERSE64(*data++, W512[j]); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ + K512[j] + W512[j]; \ + (d) += T1, \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ + j++ + + +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ + K512[j] + (W512[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ + +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND512(a,b,c,d,e,f,g,h) \ + s0 = W512[(j+1)&0x0f]; \ + s0 = sigma0_512(s0); \ + s1 = W512[(j+14)&0x0f]; \ + s1 = sigma1_512(s1); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ + +void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { + sha2_word64 a, b, c, d, e, f, g, h, s0, s1; + sha2_word64 T1, *W512 = (sha2_word64*)context->buffer; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { + ROUND512_0_TO_15(a,b,c,d,e,f,g,h); + ROUND512_0_TO_15(h,a,b,c,d,e,f,g); + ROUND512_0_TO_15(g,h,a,b,c,d,e,f); + ROUND512_0_TO_15(f,g,h,a,b,c,d,e); + ROUND512_0_TO_15(e,f,g,h,a,b,c,d); + ROUND512_0_TO_15(d,e,f,g,h,a,b,c); + ROUND512_0_TO_15(c,d,e,f,g,h,a,b); + ROUND512_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds up to 79: */ + do { + ROUND512(a,b,c,d,e,f,g,h); + ROUND512(h,a,b,c,d,e,f,g); + ROUND512(g,h,a,b,c,d,e,f); + ROUND512(f,g,h,a,b,c,d,e); + ROUND512(e,f,g,h,a,b,c,d); + ROUND512(d,e,f,g,h,a,b,c); + ROUND512(c,d,e,f,g,h,a,b); + ROUND512(b,c,d,e,f,g,h,a); + } while (j < 80); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; +} + +#else /* SHA2_UNROLL_TRANSFORM */ + +void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { + sha2_word64 a, b, c, d, e, f, g, h, s0, s1; + sha2_word64 T1 = 0, T2 = 0, *W512 = (sha2_word64*)context->buffer; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert TO host byte order */ + REVERSE64(*data++, W512[j]); + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + /* Apply the SHA-512 compression function to update a..h with copy */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W512[(j+1)&0x0f]; + s0 = sigma0_512(s0); + s1 = W512[(j+14)&0x0f]; + s1 = sigma1_512(s1); + + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 80); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; +} + +#endif /* SHA2_UNROLL_TRANSFORM */ + +void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { + unsigned int freespace, usedspace; + + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); + + usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA512_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + bcopy(data, &context->buffer[usedspace], freespace); + ADDINC128(context->bitcount, freespace << 3); + len -= freespace; + data += freespace; + SHA512_Transform(context, (sha2_word64*)context->buffer); + } else { + /* The buffer is not yet full */ + bcopy(data, &context->buffer[usedspace], len); + ADDINC128(context->bitcount, len << 3); + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA512_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + SHA512_Transform(context, (const sha2_word64*)data); + ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); + len -= SHA512_BLOCK_LENGTH; + data += SHA512_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + bcopy(data, context->buffer, len); + ADDINC128(context->bitcount, len << 3); + } + /* Clean up: */ + usedspace = freespace = 0; +} + +void SHA512_Last(SHA512_CTX* context) { + unsigned int usedspace; + + usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert FROM host byte order */ + REVERSE64(context->bitcount[0],context->bitcount[0]); + REVERSE64(context->bitcount[1],context->bitcount[1]); +#endif + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->buffer[usedspace++] = 0x80; + + if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { + /* Set-up for the last transform: */ + bzero(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace); + } else { + if (usedspace < SHA512_BLOCK_LENGTH) { + bzero(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace); + } + /* Do second-to-last transform: */ + SHA512_Transform(context, (sha2_word64*)context->buffer); + + /* And set-up for the last transform: */ + bzero(context->buffer, SHA512_BLOCK_LENGTH - 2); + } + } else { + /* Prepare for final transform: */ + bzero(context->buffer, SHA512_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *context->buffer = 0x80; + } + /* Store the length of input data (in bits): */ + *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1]; + *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0]; + + /* Final transform: */ + SHA512_Transform(context, (sha2_word64*)context->buffer); +} + +void SHA512_Final(sha2_byte digest[SHA512_DIGEST_LENGTH], SHA512_CTX* context) { + sha2_word64 *d = (sha2_word64*)digest; + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + SHA512_Last(context); + + /* Save the hash data for output: */ +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 8; j++) { + REVERSE64(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } +#else + bcopy(context->state, d, SHA512_DIGEST_LENGTH); +#endif + } + + /* Zero out state data */ + bzero(context, sizeof(*context)); +} + +char *SHA512_End(SHA512_CTX* context, char buffer[SHA512_DIGEST_STRING_LENGTH]) { + sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0); + + if (buffer != (char*)0) { + SHA512_Final(digest, context); + + for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + bzero(context, sizeof(*context)); + } + bzero(digest, SHA512_DIGEST_LENGTH); + return buffer; +} + +char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { + SHA512_CTX context; + + SHA512_Init(&context); + SHA512_Update(&context, data, len); + return SHA512_End(&context, digest); +} + + +/*** SHA-384: *********************************************************/ +void SHA384_Init(SHA384_CTX* context) { + if (context == (SHA384_CTX*)0) { + return; + } + bcopy(sha384_initial_hash_value, context->state, SHA512_DIGEST_LENGTH); + bzero(context->buffer, SHA384_BLOCK_LENGTH); + context->bitcount[0] = context->bitcount[1] = 0; +} + +void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) { + SHA512_Update((SHA512_CTX*)context, data, len); +} + +void SHA384_Final(sha2_byte digest[SHA384_DIGEST_LENGTH], SHA384_CTX* context) { + sha2_word64 *d = (sha2_word64*)digest; + + /* Sanity check: */ + assert(context != (SHA384_CTX*)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + SHA512_Last((SHA512_CTX*)context); + + /* Save the hash data for output: */ +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 6; j++) { + REVERSE64(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } +#else + bcopy(context->state, d, SHA384_DIGEST_LENGTH); +#endif + } + + /* Zero out state data */ + bzero(context, sizeof(*context)); +} + +char *SHA384_End(SHA384_CTX* context, char buffer[SHA384_DIGEST_STRING_LENGTH]) { + sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA384_CTX*)0); + + if (buffer != (char*)0) { + SHA384_Final(digest, context); + + for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + bzero(context, sizeof(*context)); + } + bzero(digest, SHA384_DIGEST_LENGTH); + return buffer; +} + +char* SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) { + SHA384_CTX context; + + SHA384_Init(&context); + SHA384_Update(&context, data, len); + return SHA384_End(&context, digest); +} diff --git a/xmhf-64/xmhf/src/xmhf-core/Doxyfile b/xmhf-64/xmhf/src/xmhf-core/Doxyfile new file mode 100644 index 0000000000..4c97da4f93 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/Doxyfile @@ -0,0 +1,1661 @@ +# Doxyfile 1.7.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = emhfcore + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 1 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = /share/amit-git/hyp-emhf/trunk/docs/emhfcore + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = /share/amit-git/hyp-emhf/trunk/code/emhfcore + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.vhd \ + *.vhdl + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the stylesheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvances is that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = NO + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans.ttf + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = YES + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/xmhf-64/xmhf/src/xmhf-core/Makefile b/xmhf-64/xmhf/src/xmhf-core/Makefile new file mode 100644 index 0000000000..8d5e462827 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/Makefile @@ -0,0 +1,80 @@ +# top-level makefile for XMHF x86 platform +# author: amit vasudevan (amitvasudevan@acm.org) + +# e.g. init-x86-i386.bin or init-x86-amd64.bin +INIT_BIN := init-$(TARGET_HWPLATFORM)-$(TARGET_SUBARCH).bin + +# e.g. hypervisor-x86-i386.bin.gz or hypervisor-x86-amd64.bin.gz +HYPERVISOR_BIN_GZ := hypervisor-$(TARGET_HWPLATFORM)-$(TARGET_SUBARCH).bin.gz + +#-----build rules +.PHONY: all +all: runtime secureloader bootloader $(HYPERVISOR_BIN_GZ) + +.PHONY: runtime +runtime: + cd xmhf-runtime && $(MAKE) -w all + +.PHONY: secureloader +secureloader: runtime + # Double-dollar-sign required to cause make to provide literal dollar sign to perl + # Objective: Create an escaped ASCII string containing the SHA-1 hash of the + # runtime and pass it to the SL's makefile + cd xmhf-secureloader && $(MAKE) -w all \ + RUNTIME_INTEGRITY_HASH=\""$(shell ( perl -nae '$$F[0] =~ s/(..)/\\\\x$$1/g; print $$F[0];' ./xmhf-runtime/runtime.sha1 ))"\" + +.PHONY: bootloader +bootloader: secureloader runtime + cd xmhf-bootloader && $(MAKE) -w all \ + RUNTIME_INTEGRITY_HASH=\""$(shell ( perl -nae '$$F[0] =~ s/(..)/\\\\x$$1/g; print $$F[0];' ./xmhf-runtime/runtime.sha1 ))"\" \ + SLBELOW64K_INTEGRITY_HASH=\""$(shell ( perl -nae '$$F[0] =~ s/(..)/\\\\x$$1/g; print $$F[0];' ./xmhf-secureloader/sl-below.sha1 ))"\" \ + SLABOVE64K_INTEGRITY_HASH=\""$(shell ( perl -nae '$$F[0] =~ s/(..)/\\\\x$$1/g; print $$F[0];' ./xmhf-secureloader/sl-above.sha1 ))"\" + +# $(HYPERVISOR_BIN_GZ) needs xmhf-bootloader/$(INIT_BIN), +# xmhf-secureloader/sl.bin, and xmhf-runtime/runtime.bin. However, to make the +# Makefile prerequisits correct we need to list all these files' prerequisits +# here (e.g. xmhf-runtime/xmhf-baseplatform/bplt-data.c). So we instead make +# $(HYPERVISOR_BIN_GZ) a phony target and always make it. +.PHONY: $(HYPERVISOR_BIN_GZ) +$(HYPERVISOR_BIN_GZ): runtime secureloader bootloader + # concatenate sl image and runtime image + $(CAT) ./xmhf-secureloader/sl.bin ./xmhf-runtime/runtime.bin > ./hypervisor.tmp.img + gzip -c ./hypervisor.tmp.img > $(HYPERVISOR_BIN_GZ) + $(RM) -rf ./hypervisor.tmp.img + # install loader and runtime images to INSTALLDIR + $(CP) ./xmhf-bootloader/$(INIT_BIN) $(HYPOUTDIR)/$(INIT_BIN) + $(CP) $(HYPERVISOR_BIN_GZ) $(HYPOUTDIR)/$(HYPERVISOR_BIN_GZ) + + +# cleanup rules +#.PHONY: clean init-late-clean +.PHONY: clean +clean: + cd xmhf-runtime && $(MAKE) -w clean + + cd xmhf-secureloader && $(MAKE) -w clean + + cd xmhf-bootloader && $(MAKE) -w clean + + rm -rf $(APPOBJECTSDIR) + + rm -rf ./$(HYPERVISOR_BIN_GZ) + $(RM) -rf $(HYPOUTDIR)/$(INIT_BIN) + $(RM) -rf $(HYPOUTDIR)/$(HYPERVISOR_BIN_GZ) + + +.PHONY: install-dev +install-dev: + # Nothing to do here + +.PHONY: verify +verify: + cd verification/ && $(MAKE) -w verify + +.PHONY: verifyinit +verifyinit: + cd verification/ && $(MAKE) -w verifyinit + +.PHONY: verifyall +verifyall: + cd verification/ && $(MAKE) -w verifyall diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_acpi.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_acpi.h new file mode 100644 index 0000000000..9562793a65 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_acpi.h @@ -0,0 +1,214 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// Advanced Configuration and Power-management Interface (ACPI) definitions +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __ACPI_H__ +#define __ACPI_H__ + +#define ACPI_RSDP_SIGNATURE (0x2052545020445352ULL) //"RSD PTR " +#define ACPI_FADT_SIGNATURE (0x50434146) //"FACP" +#define ACPI_MADT_SIGNATURE (0x43495041) //"APIC" + +#define ACPI_GAS_ASID_SYSMEMORY 0x0 +#define ACPI_GAS_ASID_SYSIO 0x1 +#define ACPI_GAS_ASID_PCI 0x2 +#define ACPI_GAS_ASID_EC 0x3 +#define ACPI_GAS_ASID_SMBUS 0x4 +#define ACPI_GAS_ASID_FFHW 0x7F + +#define ACPI_GAS_ACCESS_UNDEF 0x0 +#define ACPI_GAS_ACCESS_BYTE 0x1 +#define ACPI_GAS_ACCESS_WORD 0x2 +#define ACPI_GAS_ACCESS_DWORD 0x3 +#define ACPI_GAS_ACCESS_QWORD 0x4 + +#ifndef __ASSEMBLY__ + +//ACPI GAS, Generic Address Structure +typedef struct { + u8 address_space_id; + u8 register_bit_width; + u8 register_bit_offset; + u8 access_size; + u64 address; +} __attribute__ ((packed)) ACPI_GAS; + + +//ACPI RSDP structure +typedef struct { + u64 signature; + u8 checksum; + u8 oemid[6]; + u8 revision; + u32 rsdtaddress; + u32 length; + u64 xsdtaddress; + u8 xchecksum; + u8 rsvd0[3]; +} __attribute__ ((packed)) ACPI_RSDP; + +//ACPI XSDT structure +typedef struct { + u32 signature; + u32 length; + u8 revision; + u8 checksum; + u8 oemid[6]; + u64 oemtableid; + u32 oemrevision; + u32 creatorid; + u32 creatorrevision; +} __attribute__ ((packed)) ACPI_XSDT; + + +//ACPI RSDT structure +typedef struct { + u32 signature; + u32 length; + u8 revision; + u8 checksum; + u8 oemid[6]; + u64 oemtableid; + u32 oemrevision; + u32 creatorid; + u32 creatorrevision; +} __attribute__ ((packed)) ACPI_RSDT; + + +//ACPI MADT structure +typedef struct { + u32 signature; + u32 length; + u8 revision; + u8 checksum; + u8 oemid[6]; + u64 oemtableid; + u32 oemrevision; + u32 creatorid; + u32 creatorrevision; + u32 lapicaddress; + u32 mapicflags; +} __attribute__ ((packed)) ACPI_MADT; + +//ACPI MADT APIC structure +typedef struct { + u8 type; + u8 length; + u8 procid; + u8 lapicid; + u32 flags; +} __attribute__ ((packed)) ACPI_MADT_APIC; + +//FADT structure +typedef struct{ + u32 signature; + u32 length; + u8 revision; + u8 checksum; + u8 oemid[6]; + u64 oemtableid; + u32 oemrevision; + u32 creatorid; + u32 creatorrevision; + u32 firmware_ctrl; + u32 dsdt; + u8 rsvd0; + u8 preferred_pm_profile; + u16 sci_int; + u32 smi_cmd; + u8 acpi_enable; + u8 acpi_disable; + u8 s4bios_req; + u8 pstate_cnt; + u32 pm1a_evt_blk; + u32 pm1b_evt_blk; + u32 pm1a_cnt_blk; + u32 pm1b_cnt_blk; + u32 pm2_cnt_blk; + u32 pm_tmr_blk; + u32 gpe0_blk; + u32 gpe1_blk; + u8 pm1_evt_len; + u8 pm1_cnt_len; + u8 pm2_cnt_len; + u8 pm_tmr_len; + u8 gpe0_blk_len; + u8 gpe1_blk_len; + u8 gpe1_base; + u8 cst_cnt; + u16 p_lvl2_lat; + u16 p_lvl3_lat; + u16 flushsize; + u16 flushstride; + u8 duty_offset; + u8 duty_width; + u8 day_alrm; + u8 mon_alrm; + u8 century; + u16 iapc_boot_arch; + u8 rsvd1; + u32 flags; + u8 reset_reg[12]; + u8 reset_value; + u8 rsvd2[3]; + u64 x_firmware_ctrl; + u64 x_dsdt; + u8 x_pm1a_evt_blk[12]; + u8 x_pm1b_evt_blk[12]; + u8 x_pm1a_cnt_blk[12]; + u8 x_pm1b_cnt_blk[12]; + u8 x_pm2_cnt_blk[12]; + u8 x_pm_tmr_blk[12]; + u8 x_gpe0_blk[12]; + u8 x_gpe1_blk[12]; +}__attribute__ ((packed)) ACPI_FADT; + + +#endif //__ASSEMBLY__ + +#endif //__ACPI_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_apic.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_apic.h new file mode 100644 index 0000000000..3426d58a6b --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_apic.h @@ -0,0 +1,63 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// apic.h - APIC defines +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __APIC_H__ +#define __APIC_H__ + +#define LAPIC_ICR_LOW (0x300) +#define LAPIC_ICR_HIGH (0x310) +#define LAPIC_ID (0x20) + +//LAPIC emulation defines +#define LAPIC_OP_RSVD (3) +#define LAPIC_OP_READ (2) +#define LAPIC_OP_WRITE (1) + + +#endif // __APIC_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_cmdline.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_cmdline.h new file mode 100644 index 0000000000..d5108d70b8 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_cmdline.h @@ -0,0 +1,112 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * cmdline.h: support functions for command line parsing + * + * Copyright (c) 2006-2010, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __CMDLINE_H__ +#define __CMDLINE_H__ + +#define CMDLINE_SIZE 512 + +#ifndef __ASSEMBLY__ + +extern char g_cmdline[CMDLINE_SIZE]; + +extern void tboot_parse_cmdline(void); +extern void get_tboot_loglvl(void); +extern void get_tboot_log_targets(void); +extern bool get_tboot_serial(void); +extern u8 get_tboot_boot_drive(void); +extern void get_tboot_baud(void); +extern void get_tboot_fmt(void); + +#endif // __ASSEMBLY__ + +#endif /* __CMDLINE_H__ */ + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_com.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_com.h new file mode 100644 index 0000000000..06b2475e66 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_com.h @@ -0,0 +1,321 @@ +/*- + * Copyright (c) 1991 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)ns16550.h 7.1 (Berkeley) 5/9/91 + * $FreeBSD: src/sys/dev/ic/ns16550.h,v 1.20 2010/01/11 04:13:06 imp Exp $ + */ +/* + * Portions copyright (c) 2010, Intel Corporation + */ +/** + * Modified for XMHF. + */ + + +/* + * NS8250... UART registers. + */ +#ifndef __COM_H__ +#define __COM_H__ + +/* 8250 registers #[0-6]. */ + +#define com_data 0 /* data register (R/W) */ +#define REG_DATA com_data + +#define com_ier 1 /* interrupt enable register (W) */ +#define REG_IER com_ier +#define IER_ERXRDY 0x1 +#define IER_ETXRDY 0x2 +#define IER_ERLS 0x4 +#define IER_EMSC 0x8 + +#define IER_BITS "\20\1ERXRDY\2ETXRDY\3ERLS\4EMSC" + +#define com_iir 2 /* interrupt identification register (R) */ +#define REG_IIR com_iir +#define IIR_IMASK 0xf +#define IIR_RXTOUT 0xc +#define IIR_BUSY 0x7 +#define IIR_RLS 0x6 +#define IIR_RXRDY 0x4 +#define IIR_TXRDY 0x2 +#define IIR_NOPEND 0x1 +#define IIR_MLSC 0x0 +#define IIR_FIFO_MASK 0xc0 /* set if FIFOs are enabled */ + +#define IIR_BITS "\20\1NOPEND\2TXRDY\3RXRDY" + +#define com_lcr 3 /* line control register (R/W) */ +#define com_cfcr com_lcr /* character format control register (R/W) */ +#define REG_LCR com_lcr +#define LCR_DLAB 0x80 +#define CFCR_DLAB LCR_DLAB +#define LCR_EFR_ENABLE 0xbf /* magic to enable EFR on 16650 up */ +#define CFCR_EFR_ENABLE LCR_EFR_ENABLE +#define LCR_SBREAK 0x40 +#define CFCR_SBREAK LCR_SBREAK +#define LCR_PZERO 0x30 +#define CFCR_PZERO LCR_PZERO +#define LCR_PONE 0x20 +#define CFCR_PONE LCR_PONE +#define LCR_PEVEN 0x10 +#define CFCR_PEVEN LCR_PEVEN +#define LCR_PODD 0x00 +#define CFCR_PODD LCR_PODD +#define LCR_PENAB 0x08 +#define CFCR_PENAB LCR_PENAB +#define LCR_STOPB 0x04 +#define CFCR_STOPB LCR_STOPB +#define LCR_8BITS 0x03 +#define CFCR_8BITS LCR_8BITS +#define LCR_7BITS 0x02 +#define CFCR_7BITS LCR_7BITS +#define LCR_6BITS 0x01 +#define CFCR_6BITS LCR_6BITS +#define LCR_5BITS 0x00 +#define CFCR_5BITS LCR_5BITS + +#define LCR_ODD_PARITY (LCR_PENAB | LCR_PODD) +#define LCR_EVEN_PARITY (LCR_PENAB | LCR_PEVEN) +#define LCR_MARK_PARITY (LCR_PENAB | LCR_PONE) +#define LCR_SPACE_PARITY (LCR_PENAB | LCR_PZERO) + +#define com_mcr 4 /* modem control register (R/W) */ +#define REG_MCR com_mcr +#define MCR_PRESCALE 0x80 /* only available on 16650 up */ +#define MCR_LOOPBACK 0x10 +#define MCR_IE 0x08 +#define MCR_IENABLE MCR_IE +#define MCR_DRS 0x04 +#define MCR_RTS 0x02 +#define MCR_DTR 0x01 + +#define MCR_BITS "\20\1DTR\2RTS\3DRS\4IE\5LOOPBACK\10PRESCALE" + +#define com_lsr 5 /* line status register (R/W) */ +#define REG_LSR com_lsr +#define LSR_RCV_FIFO 0x80 +#define LSR_TEMT 0x40 +#define LSR_TSRE LSR_TEMT +#define LSR_THRE 0x20 +#define LSR_TXRDY LSR_THRE +#define LSR_BI 0x10 +#define LSR_FE 0x08 +#define LSR_PE 0x04 +#define LSR_OE 0x02 +#define LSR_RXRDY 0x01 +#define LSR_RCV_MASK 0x1f + +#define LSR_BITS "\20\1RXRDY\2OE\3PE\4FE\5BI\6THRE\7TEMT\10RCV_FIFO" + +#define com_msr 6 /* modem status register (R/W) */ +#define REG_MSR com_msr +#define MSR_DCD 0x80 +#define MSR_RI 0x40 +#define MSR_DSR 0x20 +#define MSR_CTS 0x10 +#define MSR_DDCD 0x08 +#define MSR_TERI 0x04 +#define MSR_DDSR 0x02 +#define MSR_DCTS 0x01 + +#define MSR_BITS "\20\1DCTS\2DDSR\3TERI\4DDCD\5CTS\6DSR\7RI\10DCD" + +/* 8250 multiplexed registers #[0-1]. Access enabled by LCR[7]. */ +#define com_dll 0 /* divisor latch low (R/W) */ +#define com_dlbl com_dll +#define com_dlm 1 /* divisor latch high (R/W) */ +#define com_dlbh com_dlm +#define REG_DLL com_dll +#define REG_DLH com_dlm + +/* 16450 register #7. Not multiplexed. */ +#define com_scr 7 /* scratch register (R/W) */ + +/* 16550 register #2. Not multiplexed. */ +#define com_fcr 2 /* FIFO control register (W) */ +#define com_fifo com_fcr +#define REG_FCR com_fcr +#define FCR_ENABLE 0x01 +#define FIFO_ENABLE FCR_ENABLE +#define FCR_RCV_RST 0x02 +#define FIFO_RCV_RST FCR_RCV_RST +#define FCR_XMT_RST 0x04 +#define FIFO_XMT_RST FCR_XMT_RST +#define FCR_DMA 0x08 +#define FIFO_DMA_MODE FCR_DMA +#define FCR_RX_LOW 0x00 +#define FIFO_RX_LOW FCR_RX_LOW +#define FCR_RX_MEDL 0x40 +#define FIFO_RX_MEDL FCR_RX_MEDL +#define FCR_RX_MEDH 0x80 +#define FIFO_RX_MEDH FCR_RX_MEDH +#define FCR_RX_HIGH 0xc0 +#define FIFO_RX_HIGH FCR_RX_HIGH + +#define FCR_BITS "\20\1ENABLE\2RCV_RST\3XMT_RST\4DMA" + +/* 16650 registers #2,[4-7]. Access enabled by LCR_EFR_ENABLE. */ + +#define com_efr 2 /* enhanced features register (R/W) */ +#define REG_EFR com_efr +#define EFR_CTS 0x80 +#define EFR_AUTOCTS EFR_CTS +#define EFR_RTS 0x40 +#define EFR_AUTORTS EFR_RTS +#define EFR_EFE 0x10 /* enhanced functions enable */ + +#define com_xon1 4 /* XON 1 character (R/W) */ +#define com_xon2 5 /* XON 2 character (R/W) */ +#define com_xoff1 6 /* XOFF 1 character (R/W) */ +#define com_xoff2 7 /* XOFF 2 character (R/W) */ + +#define com_usr 39 /* Octeon 16750/16550 Uart Status Reg */ +#define REG_USR com_usr +#define USR_TXFIFO_NOTFULL 2 /* Uart TX FIFO Not full */ + +/* 16950 register #1. Access enabled by ACR[7]. Also requires !LCR[7]. */ +#define com_asr 1 /* additional status register (R[0-7]/W[0-1]) */ + +/* 16950 register #3. R/W access enabled by ACR[7]. */ +#define com_rfl 3 /* receiver fifo level (R) */ + +/* + * 16950 register #4. Access enabled by ACR[7]. Also requires + * !LCR_EFR_ENABLE. + */ +#define com_tfl 4 /* transmitter fifo level (R) */ + +/* + * 16950 register #5. Accessible if !LCR_EFR_ENABLE. Read access also + * requires ACR[6]. + */ +#define com_icr 5 /* index control register (R/W) */ + +/* + * 16950 register #7. It is the same as com_scr except it has a different + * abbreviation in the manufacturer's data sheet and it also serves as an + * index into the Indexed Control register set. + */ +#define com_spr com_scr /* scratch pad (and index) register (R/W) */ +#define REG_SPR com_scr + +/* + * 16950 indexed control registers #[0-0x13]. Access is via index in SPR, + * data in ICR (if ICR is accessible). + */ + +#define com_acr 0 /* additional control register (R/W) */ +#define ACR_ASE 0x80 /* ASR/RFL/TFL enable */ +#define ACR_ICRE 0x40 /* ICR enable */ +#define ACR_TLE 0x20 /* TTL/RTL enable */ + +#define com_cpr 1 /* clock prescaler register (R/W) */ +#define com_tcr 2 /* times clock register (R/W) */ +#define com_ttl 4 /* transmitter trigger level (R/W) */ +#define com_rtl 5 /* receiver trigger level (R/W) */ +/* ... */ + +/* Hardware extension mode register for RSB-2000/3000. */ +#define com_emr com_msr +#define EMR_EXBUFF 0x04 +#define EMR_CTSFLW 0x08 +#define EMR_DSRFLW 0x10 +#define EMR_RTSFLW 0x20 +#define EMR_DTRFLW 0x40 +#define EMR_EFMODE 0x80 + +/* com port */ +#define COM1_ADDR 0x3f8 +#define COM2_ADDR 0x2f8 +#define COM3_ADDR 0x3e8 +#define COM4_ADDR 0x2e8 + +/* These parity settings can be ORed directly into the LCR. */ +#define PARITY_NONE (0<<3) +#define PARITY_ODD (1<<3) +#define PARITY_EVEN (3<<3) +#define PARITY_MARK (5<<3) +#define PARITY_SPACE (7<<3) + +#ifndef __ASSEMBLY__ + + +#define GET_LCR_DATABIT(x) ({ \ + typeof(x) val = 0; \ + val = (((x) == 5) ? LCR_5BITS : (val)); \ + val = (((x) == 6) ? LCR_6BITS : (val)); \ + val = (((x) == 7) ? LCR_7BITS : (val)); \ + val = (((x) == 8) ? LCR_8BITS : (val)); \ + val; }) + +#define GET_LCR_STOPBIT(x) ({ \ + typeof(x) val = 0; \ + val = (((x) > 1) ? LCR_STOPB : val); \ + val; }) + +#define GET_LCR_PARITY(x) ({ \ + typeof(x) val = 0; \ + val = (((x) == 'n') ? (!LCR_PENAB) : val); \ + val = (((x) == 'o') ? LCR_ODD_PARITY : val); \ + val = (((x) == 'e') ? LCR_EVEN_PARITY : val); \ + val = (((x) == 'm') ? LCR_MARK_PARITY : val); \ + val = (((x) == 's') ? LCR_SPACE_PARITY : val); \ + val; }) + +#define GET_LCR_VALUE(data, stop, parity) \ + (GET_LCR_DATABIT(data) | GET_LCR_STOPBIT(stop) | GET_LCR_PARITY(parity)) + + +typedef struct { + u32 baud; + u8 data_bits; + u8 parity; + u8 stop_bits; + u8 fifo; + u32 clock_hz; + u32 port; +} __attribute__((packed)) uart_config_t; + + +#endif // __ASSEMBLY__ + + +#endif /* __COM_H__ */ + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_configx86.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_configx86.h new file mode 100644 index 0000000000..408e07f748 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_configx86.h @@ -0,0 +1,119 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF x86 arch. specific configurable definitions +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __EMHF_CONFIGX86_H__ +#define __EMHF_CONFIGX86_H__ + +//====================================================================== +//EMHF arch. specific configurable constant definitions + +//SL + runtime base addresses +//SL currently sits at absolute address 256MB (0x10000000). runtime is +//at an offset of 2M from this SL base address +#define __TARGET_BASE_SL 0x10000000 +#define __TARGET_BASE (__TARGET_BASE_SL + PAGE_SIZE_2M) + +//"sl" parameter block magic value +#define SL_PARAMETER_BLOCK_MAGIC 0xDEADBEEF + +//"runtime" parameter block magic value +#define RUNTIME_PARAMETER_BLOCK_MAGIC 0xF00DDEAD + +// For i386, 16K stack for each core during runtime. For amd64, 64K stack. +#ifdef __AMD64__ +#define RUNTIME_STACK_SIZE (65536) +#elif defined(__I386__) +#define RUNTIME_STACK_SIZE (16384) +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + +//8K stack for each core in "init" +#define INIT_STACK_SIZE (8192) + +//maximum system memory map entries (e.g., E820) currently supported +#define MAX_E820_ENTRIES (64) + +//preferred TPM locality to use for access inside hypervisor +//needs to be 2 or 1 (4 is hw-only, 3 is sinit-only on Intel) +#define EMHF_TPM_LOCALITY_PREF 2 + +//where the guest OS boot record is loaded +#define __GUESTOSBOOTMODULE_BASE 0x7c00 +#define __GUESTOSBOOTMODULESUP1_BASE 0x7C00 + +//code segment of memory address where APs startup initially +//address 0x1000:0x0000 or 0x10000 physical +#define AP_BOOTSTRAP_CODE_SEG 0x1000 + +//TXT SENTER MLE specific constants +#define TEMPORARY_HARDCODED_MLE_SIZE 0x10000 +#define TEMPORARY_MAX_MLE_HEADER_SIZE 0x80 +#define TEMPORARY_HARDCODED_MLE_ENTRYPOINT TEMPORARY_MAX_MLE_HEADER_SIZE + +//VMX Unrestricted Guest (UG) E820 hook support +//we currently use the BIOS data area (BDA) unused region +//at 0x0040:0x00AC +#define VMX_UG_E820HOOK_CS (0x0040) +#define VMX_UG_E820HOOK_IP (0x00AC) + +// SHA-1 hash of runtime should be defined during build process. +// However, if it's not, don't fail. Just proceed with all zeros. +// XXX TODO Disable proceeding with insecure hash value. +#define BAD_INTEGRITY_HASH "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + +#ifndef ___RUNTIME_INTEGRITY_HASH___ +#define ___RUNTIME_INTEGRITY_HASH___ BAD_INTEGRITY_HASH +#endif // ___RUNTIME_INTEGRITY_HASH___ + +//====================================================================== + + + +#endif //__EMHF_CONFIGX86_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_div64.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_div64.h new file mode 100644 index 0000000000..ec2bb9a3b8 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_div64.h @@ -0,0 +1,80 @@ +/*- +* Copyright (c) 1990 The Regents of the University of California. +* All rights reserved. +* +* This code is derived from software contributed to Berkeley by +* William Jolitz and Don Ahn. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* 3. All advertising materials mentioning features or use of this software +* must display the following acknowledgement: +* This product includes software developed by the University of +* California, Berkeley and its contributors. +* 4. Neither the name of the University nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +* +* from: @(#)clock.c 7.2 (Berkeley) 5/12/91 +*/ + +/** + * Modified for XMHF. + */ + +// div64.h - 64-bit division macros + +#ifndef __DIV64_H__ +#define __DIV64_H__ + +#ifndef __ASSEMBLY__ + + +// do_div() +// modifies the 64-bit dividend _in_place_ +// returns the 32-bit remainder + +// TODO: not implemented for amd64 + +#ifdef __AMD64__ +#define do_div(n,base) ({ \ + switch(0) { case 0: case 0: not_implemented_for_amd64 }; \ +}) +#elif defined(__I386__) +#define do_div(n,base) ({ \ + unsigned long __upper, __low, __high, __mod, __base; \ + __base = (base); \ + __asm("":"=a" (__low), "=d" (__high):"A" (n)); \ + __upper = __high; \ + if (__high) { \ + __upper = __high % (__base); \ + __high = __high / (__base); \ + } \ + __asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (__base), "0" (__low), "1" (__upper)); \ + __asm("":"=A" (n):"a" (__low),"d" (__high)); \ + __mod; \ +}) +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + +#endif /* __ASSEMBLY__ */ +#endif /* __DIV64_H__ */ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_error.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_error.h new file mode 100644 index 0000000000..aa214c21a6 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_error.h @@ -0,0 +1,107 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +//error.h - error handling +//author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __ERROR_H_ +#define __ERROR_H_ + + +#ifndef __ASSEMBLY__ + +/* HALT() contains an infinite loop to indicate that it never exits */ +#define HALT() do { __asm__ __volatile__ ("hlt\r\n"); } while (1) + +#define HALT_ON_ERRORCOND(_p) \ + do { \ + if ( !(_p) ) { \ + printf("\nFatal: Halting! Condition '%s' failed, line %d, file %s\n", #_p , __LINE__, __FILE__); \ + HALT(); \ + } \ + } while (0) +//#define WARNING(_p) { if ( !(_p) ) { printf("\nWarning Assertion '%s' failed, line %d, file %s\n", #_p , __LINE__, __FILE__);} } + +/* awesome trick from http://www.jaggersoft.com/pubs/CVu11_3.html */ +#define COMPILE_TIME_ASSERT(pred) \ + switch(0){case 0:case pred:;} + +/* Overflow functions from tboot-20101005/tboot/include/misc.h */ + +/* + * These three "plus overflow" functions take a "x" value + * and add the "y" value to it and if the two values are + * greater than the size of the variable type, they will + * overflow the type and end up with a smaller value and + * return TRUE - that they did overflow. i.e. + * x + y <= variable type maximum. + */ +static inline bool plus_overflow_u64(uint64_t x, uint64_t y) +{ + return ((((uint64_t)(~0)) - x) < y); +} + +static inline bool plus_overflow_u32(uint32_t x, uint32_t y) +{ + return ((((uint32_t)(~0)) - x) < y); +} + +/* + * This checks to see if two numbers multiplied together are larger + * than the type that they are. Returns TRUE if OVERFLOWING. + * If the first parameter "x" is greater than zero and + * if that is true, that the largest possible value 0xFFFFFFFF / "x" + * is less than the second parameter "y". If "y" is zero then + * it will also fail because no unsigned number is less than zero. + */ +static inline bool multiply_overflow_u32(uint32_t x, uint32_t y) +{ + return (x > 0) ? ((((uint32_t)(~0))/x) < y) : false; +} + +#endif /*__ASSEMBLY__*/ + +#endif /* _ERROR_H */ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_io.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_io.h new file mode 100644 index 0000000000..b0955d1899 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_io.h @@ -0,0 +1,135 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +//io.h - legacy I/O read and write support +// author: amit vasudevan (amitvasudevan@acm.org) +#ifndef __IO_H_ +#define __IO_H_ + +#ifndef __ASSEMBLY__ + +#ifndef __XMHF_VERIFICATION__ + + static inline void outl(u32 val, u32 port){ + __asm__ __volatile__("out %0, %w1" + : /* no outputs */ + :"a"(val), "Nd"((u16)port)); + } + + static inline void outw (u32 value, u32 port){ + __asm__ __volatile__ ("outw %w0,%w1": :"a" ((u16)value), "Nd" ((u16)port)); + } + + static inline void outb (u32 value, u32 port){ + __asm__ __volatile__ ("outb %b0,%w1": :"a" ((u8)value), "Nd" ((u16)port)); + } + + static inline u32 inl(u32 port){ + u32 val; + + __asm__ __volatile__("in %w1, %0" + :"=a"(val) + :"Nd"((u16)port)); + return val; + } + + static inline unsigned short inw (u32 port){ + unsigned short _v; + + __asm__ __volatile__ ("inw %w1,%0":"=a" (_v):"Nd" ((u16)port)); + return _v; + } + + static inline unsigned char inb (u32 port){ + unsigned char _v; + + __asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" ((u16)port)); + return _v; + } + +#else //__XMHF_VERIFICATION__ + + static inline void outl(u32 val, u32 port){ + (void)val; + (void)port; + } + + static inline void outw (u32 value, u32 port){ + (void)value; + (void)port; + } + + static inline void outb (u32 value, u32 port){ + (void)value; + (void)port; + } + + static inline u32 inl(u32 port){ + u32 val; + val = nondet_u32(); + return val; + } + + static inline unsigned short inw (u32 port){ + unsigned short _v; + _v = nondet_u16(); + return _v; + } + + static inline unsigned char inb (u32 port){ + unsigned char _v; + + _v = (u8)nondet_u16(); + return _v; + } + +#endif //__XMHF_VERIFICATION__ + +void udelay(u32 usecs); + +#endif /* __ASSEMBLY__ */ + +#endif /* __IO_H_ */ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_msr.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_msr.h new file mode 100644 index 0000000000..5e7fbe84ce --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_msr.h @@ -0,0 +1,258 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// msr.h - CPU MSR declarations +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __MSR_H__ +#define __MSR_H__ + +#define MSR_EFER 0xc0000080 // prevent write to efer.sce +#define MSR_K6_STAR 0xc0000081 +#define VM_CR_MSR 0xc0010114 +#define VM_HSAVE_PA 0xc0010117 //this is critical +#define IGNNE 0xc0010115 //can be used to freeze/restart +#define SMM_CTL 0xc0010116 //SMRAM control + +#define MSR_IA32_PAT 0x277 //Page Attribute Table MSR + +#define MSR_AMD64_PATCH_LEVEL 0x0000008b //AMD-specific microcode patch level MSR +#define MSR_AMD64_PATCH_CLEAR 0xc0010021 //AMD-specific microcode patch clear + +#define MSR_APIC_BASE 0x0000001B + +#define IA32_X2APIC_ICR 0x830 +#define IA32_X2APIC_APICID 0x802 + +// EFER bits +#define EFER_SCE 0 /* SYSCALL/SYSRET */ +#define EFER_LME 8 /* Long Mode enable */ +#define EFER_LMA 10 /* Long Mode Active (read-only) */ +#define EFER_NXE 11 /* no execute */ +#define EFER_SVME 12 /* SVM extensions enable */ + +// VM CR MSR bits +#define VM_CR_DPD 0 +#define VM_CR_R_INIT 1 +#define VM_CR_DIS_A20M 2 +#define VM_CR_SVME_DISABLE 4 + +// VMX capabilities MSR +#define IA32_VMX_BASIC_MSR 0x480 +#define IA32_VMX_PINBASED_CTLS_MSR 0x481 +#define IA32_VMX_PROCBASED_CTLS_MSR 0x482 +#define IA32_VMX_EXIT_CTLS_MSR 0x483 +#define IA32_VMX_ENTRY_CTLS_MSR 0x484 +#define IA32_VMX_MISC_MSR 0x485 +#define IA32_VMX_CR0_FIXED0_MSR 0x486 +#define IA32_VMX_CR0_FIXED1_MSR 0x487 +#define IA32_VMX_CR4_FIXED0_MSR 0x488 +#define IA32_VMX_CR4_FIXED1_MSR 0x489 +#define IA32_VMX_VMCS_ENUM_MSR 0x48A +#define IA32_VMX_PROCBASED_CTLS2_MSR 0x48B + +//sysenter/sysexit MSRs +#define IA32_SYSENTER_CS_MSR 0x174 +#define IA32_SYSENTER_EIP_MSR 0x176 +#define IA32_SYSENTER_ESP_MSR 0x175 + +//only for 64-bit LM +#define IA32_MSR_FS_BASE 0xC0000100 +#define IA32_MSR_GS_BASE 0xC0000101 + +#define MSR_EFCR 0x0000003A // index for Extended Feature Control + +//#define MSR_IA32_FEATURE_CONTROL 0x03a tboot version trumped by our own +#define IA32_FEATURE_CONTROL_MSR_LOCK 0x1 +#define IA32_FEATURE_CONTROL_MSR_ENABLE_VMX_IN_SMX 0x2 +#define IA32_FEATURE_CONTROL_MSR_SENTER_PARAM_CTL 0x7f00 +#define IA32_FEATURE_CONTROL_MSR_ENABLE_SENTER 0x8000 + +//MTRRs +#define IA32_MTRRCAP 0x000000fe +#define IA32_MTRR_DEF_TYPE 0x000002ff + +//fixed range MTRRs +#define IA32_MTRR_FIX64K_00000 0x00000250 //64-bits, 8 ranges (8bits/range) from 00000-7FFFF +#define IA32_MTRR_FIX16K_80000 0x00000258 //64-bits, 8 ranges (8bits/range) from 80000-9FFFF +#define IA32_MTRR_FIX16K_A0000 0x00000259 //64-bits, 8 ranges (8bits/range) from A0000-BFFFF +#define IA32_MTRR_FIX4K_C0000 0x00000268 //64-bits, 8 ranges (8bits/range) from C0000-C7FFF +#define IA32_MTRR_FIX4K_C8000 0x00000269 //64-bits, 8 ranges (8bits/range) from C8000-CFFFF +#define IA32_MTRR_FIX4K_D0000 0x0000026a //64-bits, 8 ranges (8bits/range) from D0000-D7FFF +#define IA32_MTRR_FIX4K_D8000 0x0000026b //64-bits, 8 ranges (8bits/range) from D8000-DFFFF +#define IA32_MTRR_FIX4K_E0000 0x0000026c //64-bits, 8 ranges (8bits/range) from E0000-E7FFF +#define IA32_MTRR_FIX4K_E8000 0x0000026d //64-bits, 8 ranges (8bits/range) from E8000-EFFFF +#define IA32_MTRR_FIX4K_F0000 0x0000026e //64-bits, 8 ranges (8bits/range) from F0000-F7FFF +#define IA32_MTRR_FIX4K_F8000 0x0000026f //64-bits, 8 ranges (8bits/range) from F8000-FFFFF + +//variable range MTRRs +#define IA32_MTRR_PHYSBASE0 0x00000200 +#define IA32_MTRR_PHYSMASK0 0x00000201 +#define IA32_MTRR_PHYSBASE1 0x00000202 +#define IA32_MTRR_PHYSMASK1 0x00000203 +#define IA32_MTRR_PHYSBASE2 0x00000204 +#define IA32_MTRR_PHYSMASK2 0x00000205 +#define IA32_MTRR_PHYSBASE3 0x00000206 +#define IA32_MTRR_PHYSMASK3 0x00000207 +#define IA32_MTRR_PHYSBASE4 0x00000208 +#define IA32_MTRR_PHYSMASK4 0x00000209 +#define IA32_MTRR_PHYSBASE5 0x0000020a +#define IA32_MTRR_PHYSMASK5 0x0000020b +#define IA32_MTRR_PHYSBASE6 0x0000020c +#define IA32_MTRR_PHYSMASK6 0x0000020d +#define IA32_MTRR_PHYSBASE7 0x0000020e +#define IA32_MTRR_PHYSMASK7 0x0000020f +#define IA32_MTRR_PHYSBASE8 0x00000210 +#define IA32_MTRR_PHYSMASK8 0x00000211 +#define IA32_MTRR_PHYSBASE9 0x00000212 +#define IA32_MTRR_PHYSMASK9 0x00000213 + +#define MTRR_TYPE_UC 0x0 +#define MTRR_TYPE_WC 0x1 +#define MTRR_TYPE_WT 0x4 +#define MTRR_TYPE_WP 0x5 +#define MTRR_TYPE_WB 0x6 +#define MTRR_TYPE_RESV 0x7 + +/* + * from: @(#)specialreg.h 7.1 (Berkeley) 5/9/91 + * $FreeBSD: src/sys/i386/include/specialreg.h,v 1.53.2.1.2.2 2009/11/06 17:09:04 attilio Exp $ + */ + +#define MSR_APICBASE 0x01b +#define MSR_IA32_FEATURE_CONTROL 0x03a +#define MSR_IA32_SMM_MONITOR_CTL 0x09b +#define MSR_MTRRcap 0x0fe +#define MSR_MCG_CAP 0x179 +#define MSR_MCG_STATUS 0x17a +#define MSR_IA32_MISC_ENABLE 0x1a0 +#define MSR_MTRRdefType 0x2ff +#define MSR_MC0_STATUS 0x401 +#define MSR_IA32_VMX_BASIC_MSR 0x480 +#define MSR_IA32_VMX_PINBASED_CTLS_MSR 0x481 +#define MSR_IA32_VMX_PROCBASED_CTLS_MSR 0x482 +#define MSR_IA32_VMX_EXIT_CTLS_MSR 0x483 +#define MSR_IA32_VMX_ENTRY_CTLS_MSR 0x484 + +/* + * Constants related to MSR's. + */ +#define APICBASE_BSP 0x00000100 +#define MSR_IA32_APICBASE_ENABLE (1<<11) + +#define MSR_IA32_SMM_MONITOR_CTL_VALID 1 +#define MSR_IA32_SMM_MONITOR_CTL_MSEG_BASE(x) (x>>12) + +/* MSRs & bits used for VMX enabling */ +#define IA32_FEATURE_CONTROL_MSR_LOCK 0x1 +#define IA32_FEATURE_CONTROL_MSR_ENABLE_VMX_IN_SMX 0x2 +#define IA32_FEATURE_CONTROL_MSR_SENTER_PARAM_CTL 0x7f00 +#define IA32_FEATURE_CONTROL_MSR_ENABLE_SENTER 0x8000 + +// Intel Microcode related +#define IA32_PLATFORM_ID 0x17 +#define IA32_BIOS_UPDT_TRIG 0x79 +#define IA32_BIOS_SIGN_ID 0x8b + +/* AMD64 MSR's */ +#define MSR_EFER 0xc0000080 /* extended features */ + +/* EFER bits */ +#define _EFER_LME 8 /* Long mode enable */ + +#define MTRR_TYPE_UNCACHABLE 0 +#define MTRR_TYPE_WRTHROUGH 4 +#define MTRR_TYPE_WRBACK 6 + + +#ifndef __ASSEMBLY__ +static inline void rdmsr(u32 msr, u32 *eax, u32 *edx) __attribute__((always_inline)); +static inline void wrmsr(u32 msr, u32 eax, u32 edx) __attribute__((always_inline)); + +static inline void rdmsr(u32 msr, u32 *eax, u32 *edx){ + __asm__("rdmsr" + :"=a"(*eax), "=d"(*edx) + :"c"(msr)); +} + +static inline void wrmsr(u32 msr, u32 eax, u32 edx){ + __asm__("wrmsr" + : /* no outputs */ + :"c"(msr), "a"(eax), "d"(edx)); +} + + +static inline u64 rdmsr64(uint32_t msr) +{ +#ifdef __AMD64__ + u32 eax, edx; + __asm__ __volatile__ ("rdmsr" : "=a" (eax), "=d" (edx) : "c" (msr)); + return ((u64)edx << 32) | eax; +#elif defined(__I386__) + u64 rv; + __asm__ __volatile__ ("rdmsr" : "=A" (rv) : "c" (msr)); + return (rv); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +} + +static inline void wrmsr64(uint32_t msr, uint64_t newval) +{ +#ifdef __AMD64__ + __asm__ __volatile__ ("wrmsr" : : "a" (newval & ((1UL << 32) - 1)), + "d" (newval >> 32), "c" (msr)); +#elif defined(__I386__) + __asm__ __volatile__ ("wrmsr" : : "A" (newval), "c" (msr)); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +} + +#endif /* __ASSEMBLY__ */ + + +#endif/* __MSR_H__ */ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_multiboot.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_multiboot.h new file mode 100644 index 0000000000..4c45d5c68c --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_multiboot.h @@ -0,0 +1,107 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// multiboot.h - declarations for the multiboot spec +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __MULTIBOOT_H_ +#define __MULTIBOOT_H_ + +#define MULTIBOOT_HEADER_MAGIC 0x1badb002 +#define MEM_INFO 0x01 +#define MULTIBOOT_HEADER_FLAGS ((1<> PAGE_SHIFT_4K) + +// non-PAE mode specific definitions +#define NPAE_PTRS_PER_PDT 1024 +#define NPAE_PTRS_PER_PT 1024 +#define NPAE_PAGETABLE_SHIFT 12 +#define NPAE_PAGEDIR_SHIFT 22 +#define NPAE_PAGE_DIR_MASK 0xffc00000 +#define NPAE_PAGE_TABLE_MASK 0x003ff000 + +// PAE mode specific definitions +#define PAE_PTRS_PER_PDPT 4 +#define PAE_PTRS_PER_PDT 512 +#define PAE_PTRS_PER_PT 512 +#define PAE_PT_SHIFT 12 +#define PAE_PDT_SHIFT 21 +#define PAE_PDPT_SHIFT 30 +#define PAE_PT_MASK 0x001ff000 +#define PAE_PDT_MASK 0x3fe00000 +#define PAE_PDPT_MASK 0xc0000000 +#define PAE_ENTRY_SIZE 8 + +// 4-level paging specific definitions +#define P4L_NPLM4T \ + (PA_PAGE_ALIGN_UP_NOCHK_256T(MAX_PHYS_ADDR) >> PAGE_SHIFT_256T) +#define P4L_NPDPT \ + (PA_PAGE_ALIGN_UP_NOCHK_512G(MAX_PHYS_ADDR) >> PAGE_SHIFT_512G) +#define P4L_NPDT \ + (PA_PAGE_ALIGN_UP_NOCHK_1G(MAX_PHYS_ADDR) >> PAGE_SHIFT_1G) +#define P4L_NPT \ + (PA_PAGE_ALIGN_UP_NOCHK_2M(MAX_PHYS_ADDR) >> PAGE_SHIFT_2M) + +// various paging flags +#define _PAGE_BIT_PRESENT 0 +#define _PAGE_BIT_RW 1 +#define _PAGE_BIT_USER 2 +#define _PAGE_BIT_PWT 3 +#define _PAGE_BIT_PCD 4 +#define _PAGE_BIT_ACCESSED 5 +#define _PAGE_BIT_DIRTY 6 +#define _PAGE_BIT_PSE 7 +#define _PAGE_BIT_GLOBAL 8 +#define _PAGE_BIT_UNUSED1 9 +#define _PAGE_BIT_UNUSED2 10 +#define _PAGE_BIT_UNUSED3 11 +#define _PAGE_BIT_NX 63 + +#define _PAGE_PRESENT 0x001 +#define _PAGE_RW 0x002 +#define _PAGE_USER 0x004 +#define _PAGE_PWT 0x008 +#define _PAGE_PCD 0x010 +#define _PAGE_ACCESSED 0x020 +#define _PAGE_DIRTY 0x040 +#define _PAGE_PSE 0x080 +#define _PAGE_GLOBAL 0x100 +#define _PAGE_UNUSED1 0x200 +#define _PAGE_UNUSED2 0x400 +#define _PAGE_UNUSED3 0x800 + +#ifndef __ASSEMBLY__ +#define _PAGE_NX (1ULL<<_PAGE_BIT_NX) +#else +#define _PAGE_NX (1 << _PAGE_BIT_NX) +#endif + +#define PAGE_FAULT_BITS (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_NX) + +#ifndef __ASSEMBLY__ + +typedef u64 pml4te_t; +typedef u64 pdpte_t; +typedef u64 pdte_t; +typedef u64 pte_t; + +typedef pml4te_t *pml4t_t; +typedef pdpte_t *pdpt_t; +typedef pdte_t *pdt_t; +typedef pte_t *pt_t; + +typedef u32 *npdt_t; +typedef u32 *npt_t; + +#ifdef __AMD64__ + +/* 4-level paging macros */ + +/* make a PML4 entry from individual fields */ +#define p4l_make_plm4e(paddr, flags) \ + ((u64)(paddr) & (~(((u64)PAGE_SIZE_4K - 1) | _PAGE_NX))) | (u64)(flags) + +/* make a page directory pointer entry from individual fields */ +#define p4l_make_pdpe(paddr, flags) \ + ((u64)(paddr) & (~(((u64)PAGE_SIZE_4K - 1) | _PAGE_NX))) | (u64)(flags) + +/* make a page directory entry for a 2MB page from individual fields */ +#define p4l_make_pde_big(paddr, flags) \ + ((u64)(paddr) & (~(((u64)PAGE_SIZE_2M - 1) | _PAGE_NX))) | (u64)(flags) + +/* make a page directory entry for a 4KB page from individual fields */ +#define p4l_make_pde(paddr, flags) \ + ((u64)(paddr) & (~(((u64)PAGE_SIZE_4K - 1) | _PAGE_NX))) | (u64)(flags) + +/* make a page table entry from individual fields */ +#define p4l_make_pte(paddr, flags) \ + ((u64)(paddr) & (~(((u64)PAGE_SIZE_4K - 1) | _PAGE_NX))) | (u64)(flags) + +/* get address field from 64-bit cr3 (page directory pointer) */ +#define p4l_get_addr_from_32bit_cr3(entry) \ + ((u64)(entry) & (~((1UL << 12) - 1))) + +/* get flags field from 64-bit cr3 (page directory pointer) */ +#define p4l_get_flags_from_32bit_cr3(entry) \ + ((u64)(entry) & ((1UL << 12) - 1)) + +/* get address field of a PML4E (page directory pointer entry) */ +#define p4l_get_addr_from_pml4e(entry) \ + ((u64)(entry) & (~(((u64)PAGE_SIZE_4K - 1) | _PAGE_NX))) + +/* get flags field of a PML4E (page directory pointer entry) */ +#define p4l_get_flags_from_pml4e(entry) \ + ((u64)(entry) & (((u64)PAGE_SIZE_4K - 1) | _PAGE_NX)) + +/* get address field of a pdpe (page directory pointer entry) */ +#define p4l_get_addr_from_pdpe(entry) \ + ((u64)(entry) & (~(((u64)PAGE_SIZE_4K - 1) | _PAGE_NX))) + +/* get flags field of a pdpe (page directory pointer entry) */ +#define p4l_get_flags_from_pdpe(entry) \ + ((u64)(entry) & (((u64)PAGE_SIZE_4K - 1) | _PAGE_NX)) + +/* get address field of a 2MB pdte (page directory entry) */ +#define p4l_get_addr_from_pde_big(entry) \ + ((u64)(entry) & (~(((u64)PAGE_SIZE_2M - 1) | _PAGE_NX))) + +/* get flags field of a 2MB pdte (page directory entry) */ +#define p4l_get_flags_from_pde_big(entry) \ + ((u64)(entry) & (((u64)PAGE_SIZE_2M - 1) | _PAGE_NX)) + +/* get address field of a 4K pdte (page directory entry) */ +#define p4l_get_addr_from_pde(entry) \ + ((u64)(entry) & (~(((u64)PAGE_SIZE_4K - 1) | _PAGE_NX))) + +/* get flags field of a 4K pdte (page directory entry) */ +#define p4l_get_flags_from_pde(entry) \ + ((u64)(entry) & (((u64)PAGE_SIZE_4K - 1) | _PAGE_NX)) + +/* get address field of a pte (page table entry) */ +#define p4l_get_addr_from_pte(entry) \ + ((u64)(entry) & (~(((u64)PAGE_SIZE_4K - 1) | _PAGE_NX))) + +/* get flags field of a pte (page table entry) */ +#define p4l_get_flags_from_pte(entry) \ + ((u64)(entry) & (((u64)PAGE_SIZE_4K - 1) | _PAGE_NX)) + +#elif !defined(__I386__) + #error "Unsupported Arch" +#endif /* !defined(__I386__) */ + +/* 32-bit macros */ + +/* make a page directory pointer entry from individual fields */ +#define pae_make_pdpe(paddr, flags) \ + ((u64)(paddr) & (~(((u64)PAGE_SIZE_4K - 1) | _PAGE_NX))) | (u64)(flags) + +/* make a page directory entry for a 2MB page from individual fields */ +#define pae_make_pde_big(paddr, flags) \ + ((u64)(paddr) & (~(((u64)PAGE_SIZE_2M - 1) | _PAGE_NX))) | (u64)(flags) + +/* make a page directory entry for a 4KB page from individual fields */ +#define pae_make_pde(paddr, flags) \ + ((u64)(paddr) & (~(((u64)PAGE_SIZE_4K - 1) | _PAGE_NX))) | (u64)(flags) + +/* make a page table entry from individual fields */ +#define pae_make_pte(paddr, flags) \ + ((u64)(paddr) & (~(((u64)PAGE_SIZE_4K - 1) | _PAGE_NX))) | (u64)(flags) + +/* get address field from 32-bit cr3 (page directory pointer) in PAE mode */ +#define pae_get_addr_from_32bit_cr3(entry) \ + ((u32)(entry) & (~((1UL << 5) - 1))) + +/* get flags field from 32-bit cr3 (page directory pointer) in PAE mode */ +#define pae_get_flags_from_32bit_cr3(entry) \ + ((u32)(entry) & ((1UL << 5) - 1)) + +/* get address field of a pdpe (page directory pointer entry) */ +#define pae_get_addr_from_pdpe(entry) \ + ((u64)(entry) & (~(((u64)PAGE_SIZE_4K - 1) | _PAGE_NX))) + +/* get flags field of a pdpe (page directory pointer entry) */ +#define pae_get_flags_from_pdpe(entry) \ + ((u64)(entry) & (((u64)PAGE_SIZE_4K - 1) | _PAGE_NX)) + +/* get address field of a 2MB pdte (page directory entry) */ +#define pae_get_addr_from_pde_big(entry) \ + ((u64)(entry) & (~(((u64)PAGE_SIZE_2M - 1) | _PAGE_NX))) + +/* get flags field of a 2MB pdte (page directory entry) */ +#define pae_get_flags_from_pde_big(entry) \ + ((u64)(entry) & (((u64)PAGE_SIZE_2M - 1) | _PAGE_NX)) + +/* get address field of a 4K pdte (page directory entry) */ +#define pae_get_addr_from_pde(entry) \ + ((u64)(entry) & (~(((u64)PAGE_SIZE_4K - 1) | _PAGE_NX))) + +/* get flags field of a 4K pdte (page directory entry) */ +#define pae_get_flags_from_pde(entry) \ + ((u64)(entry) & (((u64)PAGE_SIZE_4K - 1) | _PAGE_NX)) + +/* get address field of a pte (page table entry) */ +#define pae_get_addr_from_pte(entry) \ + ((u64)(entry) & (~(((u64)PAGE_SIZE_4K - 1) | _PAGE_NX))) + +/* get flags field of a pte (page table entry) */ +#define pae_get_flags_from_pte(entry) \ + ((u64)(entry) & (((u64)PAGE_SIZE_4K - 1) | _PAGE_NX)) + +/* make a page directory entry for a 4MB page from individual fields */ +#define npae_make_pde_big(paddr, flags) \ + ((u32)(paddr) & (~(((u32)PAGE_SIZE_4M - 1)))) | (u32)(flags) + +/* make a page directory entry for a 4KB page from individual fields */ +#define npae_make_pde(paddr, flags) \ + ((u32)(paddr) & (~(((u32)PAGE_SIZE_4K - 1)))) | (u32)(flags) + +/* get address field from NON-PAE cr3 (page directory pointer) */ +#define npae_get_addr_from_32bit_cr3(entry) \ + ((u32)(entry) & (~((u32)PAGE_SIZE_4K - 1))) + +/* get address field of a 4K non-PAE pdte (page directory entry) */ +#define npae_get_addr_from_pde(entry) \ + ((u32)(entry) & (~((u32)PAGE_SIZE_4K - 1))) + +/* get flags field of a 4K non-PAE pdte (page directory entry) */ +#define npae_get_flags_from_pde(entry) \ + ((u32)(entry) & ((u32)PAGE_SIZE_4K - 1)) + +/* get address field of a 4M (non-PAE) pdte (page directory entry) */ +#define npae_get_addr_from_pde_big(entry) \ + ((u32)(entry) & (~((u32)PAGE_SIZE_4M - 1))) + +/* get flags field of a 4M (non-PAE) pdte (page directory entry) */ +#define npae_get_flags_from_pde_big(entry) \ + ((u32)(entry) & ((u32)PAGE_SIZE_4M - 1)) + +/* get flags field of a pte (page table entry) */ +#define npae_get_flags_from_pte(entry) \ + ((u32)(entry) & (((u32)PAGE_SIZE_4K - 1))) + +/* get address field of a 4K (non-PAE) pte (page table entry) */ +#define npae_get_addr_from_pte(entry) \ + ((u32)(entry) & (~((u32)PAGE_SIZE_4K - 1))) + +/* get page offset field of a vaddr in a 4K page (PAE mode) */ +#define pae_get_offset_4K_page(entry) \ + ((u32)(entry) & ((u32)PAGE_SIZE_4K - 1)) + +/* get page offset field of a vaddr in a 2M page */ +#define pae_get_offset_big(entry) \ + ((u32)(entry) & ((u32)PAGE_SIZE_2M - 1)) + +/* get offset field of a vaddr in a 4K page (non-PAE mode) */ +#define npae_get_offset_4K_page(vaddr) \ + ((u32)(vaddr) & ((u32)PAGE_SIZE_4K - 1)) + +/* get offset field of a vaddr in a 4M page */ +#define npae_get_offset_big(vaddr) \ + ((u32)(vaddr) & ((u32)PAGE_SIZE_4M - 1)) + +/* get index field of a paddr in a pdp level */ +#define pae_get_pdpt_index(paddr)\ + (((paddr) & PAE_PDPT_MASK) >> PAE_PDPT_SHIFT) + +/* get index field of a paddr in a pd level */ +#define pae_get_pdt_index(paddr)\ + (((paddr) & PAE_PDT_MASK) >> PAE_PDT_SHIFT) + +/* get index field of a paddr in a pt level */ +#define pae_get_pt_index(paddr)\ + (((paddr) & PAE_PT_MASK) >> PAE_PT_SHIFT) + +/* get index field of a paddr in a pd level */ +#define npae_get_pdt_index(paddr)\ + (((paddr) & NPAE_PAGE_DIR_MASK) >> NPAE_PAGEDIR_SHIFT) + +/* get index field of a paddr in a pt level */ +#define npae_get_pt_index(paddr)\ + (((paddr) & NPAE_PAGE_TABLE_MASK) >> NPAE_PAGETABLE_SHIFT) + +#define set_exec(entry) (((u64)entry) &= (~((u64)_PAGE_NX))) +#define set_nonexec(entry) (((u64)entry) |= ((u64)_PAGE_NX)) +#define set_readonly(entry) (((u64)entry) &= (~((u64)_PAGE_RW))) +#define set_readwrite(entry) (((u64)entry) |= ((u64)_PAGE_RW)) +#define set_present(entry) (((u64)entry) |= ((u64)_PAGE_PRESENT)) +#define set_not_present(entry) (((u64)entry) &= (~((u64)_PAGE_PRESENT))) + +#define SAME_PAGE_PAE(addr1, addr2) \ + (((addr1) >> PAE_PT_SHIFT) == ((addr2) >> PAE_PT_SHIFT)) + +#define SAME_PAGE_NPAE(addr1, addr2) \ + (((addr1) >> NPAE_PAGETABLE_SHIFT) == ((addr2) >> NPAE_PAGETABLE_SHIFT)) + + +#define CACHE_WBINV() __asm__ __volatile__("wbinvd\n" :::"memory") +#define TLB_INVLPG(x) __asm__ __volatile__("invlpg (%0)\n": /* no output */ : "r" (x): "memory") + + +#endif /* __ASSEMBLY__ */ + +#endif /* __PAGING_H__ */ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_pci.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_pci.h new file mode 100644 index 0000000000..f8571f801b --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_pci.h @@ -0,0 +1,112 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +//pci.h - peripheral component interconnect (PCI) spec. +// implementation declarations +//author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __PCI_H__ +#define __PCI_H__ + +//PCI type-1 access ports +#define PCI_CONFIG_ADDR_PORT (0x0cf8) +#define PCI_CONFIG_DATA_PORT (0x0cfc) + +//PCI configuration header indices (as per PCI local bus spec. v3.0) +#define PCI_CONF_HDR_IDX_VENDOR_ID 0x0 +#define PCI_CONF_HDR_IDX_DEVICE_ID 0x02 +#define PCI_CONF_HDR_IDX_COMMAND 0x04 +#define PCI_CONF_HDR_IDX_STATUS 0x06 +#define PCI_CONF_HDR_IDX_REVISION_ID 0x08 +#define PCI_CONF_HDR_IDX_CLASS_CODE 0x09 +#define PCI_CONF_HDR_IDX_HEADER_TYPE 0x0E +#define PCI_CONF_HDR_IDX_CAPABILITIES_POINTER 0x34 + +//PCI "command" register +#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */ +#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */ +#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */ +#define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */ +#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */ +#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */ +#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */ +#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */ +#define PCI_COMMAND_SERR 0x100 /* Enable SERR */ +#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */ +#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */ + +//maximum PCI bus, device and function numbers +#define PCI_BUS_MAX 256 +#define PCI_DEVICE_MAX 32 +#define PCI_FUNCTION_MAX 8 + +//AMD PCI configuration space constants +#define PCI_VENDOR_ID_AMD 0x1022 //Vendor ID for AMD + +#define PCI_DEVICE_ID_AMD_HT_CONFIGURATION 0x1200 //Device ID for AMD Hypertransport Configuration +#define PCI_DEVICE_ID_AMD_ADDRESSMAP 0x1201 //Device ID for AMD Address Map +#define PCI_DEVICE_ID_AMD_DRAMCONTROL 0x1202 //Device ID for AMD DRAM Controller +#define PCI_DEVICE_ID_AMD_MISCCONTROL 0x1203 //Device ID for AMD Miscellaneous Control +#define PCI_DEVICE_ID_AMD_LINKCONTROL 0x1204 //Device ID for AMD Link Control + +#define PCI_CAPABILITIES_POINTER_ID_DEV 0x0F //PCI capability ID for SVM DEV + + +#ifndef __ASSEMBLY__ + +//macro to encode a device and function into a 8-bit value +#define PCI_DEVICE_FN(device, function) ((((device) & 0x1f) << 3) | ((function) & 0x07)) + +//macro to encode a bus, device, function and index into a 32-bit +//PCI type-1 address +#define PCI_TYPE1_ADDRESS(bus, device, function, index) \ + (0x80000000 | ((index & 0xF00) << 16) | (bus << 16) \ + | (PCI_DEVICE_FN(device, function) << 8) | (index & 0xFC)) + + + +#endif /* __ASSEMBLY__ */ +#endif /* __PCI_H__ */ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_processor.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_processor.h new file mode 100644 index 0000000000..f77502bf42 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_processor.h @@ -0,0 +1,458 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +//processor.h - CPU declarations +//author: amit vasudevan (amitvasudevan@acm.org) +#ifndef __PROCESSOR_H +#define __PROCESSOR_H + +#define CPU_VENDOR_INTEL 0xAB +#define CPU_VENDOR_AMD 0xCD + +#define AMD_STRING_DWORD1 0x68747541 +#define AMD_STRING_DWORD2 0x69746E65 +#define AMD_STRING_DWORD3 0x444D4163 + +#define INTEL_STRING_DWORD1 0x756E6547 +#define INTEL_STRING_DWORD2 0x49656E69 +#define INTEL_STRING_DWORD3 0x6C65746E + +#define EFLAGS_CF 0x00000001 /* Carry Flag */ +#define EFLAGS_PF 0x00000004 /* Parity Flag */ +#define EFLAGS_AF 0x00000010 /* Auxillary carry Flag */ +#define EFLAGS_ZF 0x00000040 /* Zero Flag */ +#define EFLAGS_SF 0x00000080 /* Sign Flag */ +#define EFLAGS_TF 0x00000100 /* Trap Flag */ +#define EFLAGS_IF 0x00000200 /* Interrupt Flag */ +#define EFLAGS_DF 0x00000400 /* Direction Flag */ +#define EFLAGS_OF 0x00000800 /* Overflow Flag */ +#define EFLAGS_IOPL 0x00003000 /* IOPL mask */ +#define EFLAGS_NT 0x00004000 /* Nested Task */ +#define EFLAGS_RF 0x00010000 /* Resume Flag */ +#define EFLAGS_VM 0x00020000 /* Virtual Mode */ +#define EFLAGS_AC 0x00040000 /* Alignment Check */ +#define EFLAGS_VIF 0x00080000 /* Virtual Interrupt Flag */ +#define EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */ +#define EFLAGS_ID 0x00200000 /* CPUID detection flag */ + +#define CR0_PE 0x00000001 /* Enable Protected Mode (RW) */ +#define CR0_MP 0x00000002 /* Monitor Coprocessor (RW) */ +#define CR0_EM 0x00000004 /* Require FPU Emulation (RO) */ +#define CR0_TS 0x00000008 /* Task Switched (RW) */ +#define CR0_ET 0x00000010 /* Extension type (RO) */ +#define CR0_NE 0x00000020 /* Numeric Error Reporting (RW) */ +#define CR0_WP 0x00010000 /* Supervisor Write Protect (RW) */ +#define CR0_AM 0x00040000 /* Alignment Checking (RW) */ +#define CR0_NW 0x20000000 /* Not Write-Through (RW) */ +#define CR0_CD 0x40000000 /* Cache Disable (RW) */ +#define CR0_PG 0x80000000 /* Paging (RW) */ + +#define CR4_VME 0x0001 /* enable vm86 extensions */ +#define CR4_PVI 0x0002 /* virtual interrupts flag enable */ +#define CR4_TSD 0x0004 /* disable time stamp at ipl 3 */ +#define CR4_DE 0x0008 /* enable debugging extensions */ +#define CR4_PSE 0x0010 /* enable page size extensions */ +#define CR4_PAE 0x0020 /* enable physical address extensions */ +#define CR4_MCE 0x0040 /* Machine check enable */ +#define CR4_PGE 0x0080 /* enable global pages */ +#define CR4_PCE 0x0100 /* enable performance counters at ipl 3 */ +#define CR4_OSFXSR 0x0200 /* enable fast FPU save and restore */ +#define CR4_OSXMMEXCPT 0x0400 /* enable unmasked SSE exceptions */ +#define CR4_LA57 0x1000 /* enable 5-level paging */ +#define CR4_VMXE 0x2000 /* enable VMX */ +#define CR4_SMXE 0x4000 /* enable SMX */ +#define CR4_OSXSAVE (1UL << 18) // XSAVE and Processor Extended States Enable bit + +//CPUID related +#define EDX_PAE 6 +#define EDX_NX 20 +#define ECX_SVM 2 +#define EDX_NP 0 + +#define SVM_CPUID_FEATURE (1 << 2) + +#define CPUID_X86_FEATURE_VMX (1<<5) +#define CPUID_X86_FEATURE_SMX (1<<6) + +//CPU exception numbers +//(intel SDM vol 3a 6-27) +#define CPU_EXCEPTION_DE 0 //divide error exception +#define CPU_EXCEPTION_DB 1 //debug exception +#define CPU_EXCEPTION_NMI 2 //non-maskable interrupt +#define CPU_EXCEPTION_BP 3 //breakpoint exception +#define CPU_EXCEPTION_OF 4 //overflow exception +#define CPU_EXCEPTION_BR 5 //bound-range exceeded +#define CPU_EXCEPTION_UD 6 //invalid opcode +#define CPU_EXCEPTION_NM 7 //device not available +#define CPU_EXCEPTION_DF 8 //double fault exception (code) +#define CPU_EXCEPTION_RESV9 9 //reserved +#define CPU_EXCEPTION_TS 10 //invalid TSS (code) +#define CPU_EXCEPTION_NP 11 //segment not present (code) +#define CPU_EXCEPTION_SS 12 //stack fault (code) +#define CPU_EXCEPTION_GP 13 //general protection (code) +#define CPU_EXCEPTION_PF 14 //page fault (code) +#define CPU_EXCEPTION_RESV15 15 //reserved +#define CPU_EXCEPTION_MF 16 //floating-point exception +#define CPU_EXCEPTION_AC 17 //alignment check (code) +#define CPU_EXCEPTION_MC 18 //machine check +#define CPU_EXCEPTION_XM 19 //SIMD floating point exception + + +//extended control registers +#define XCR_XFEATURE_ENABLED_MASK 0x00000000 + + +#ifndef __ASSEMBLY__ + +// Return the low 32 bits +#define LOW32(v) ((u32)v) + +// Return the high 32 bits +#define HIGH32(v) ((u32)(v >> 32)) + +// i386: follow the order enforced by PUSHAD/POPAD +// amd64: manually follow this order in assembly code +struct regs +{ +#ifdef __AMD64__ + union { u64 rdi; u32 edi; } __attribute__ ((packed)); + union { u64 rsi; u32 esi; } __attribute__ ((packed)); + union { u64 rbp; u32 ebp; } __attribute__ ((packed)); + union { u64 rsp; u32 esp; } __attribute__ ((packed)); + union { u64 rbx; u32 ebx; } __attribute__ ((packed)); + union { u64 rdx; u32 edx; } __attribute__ ((packed)); + union { u64 rcx; u32 ecx; } __attribute__ ((packed)); + union { u64 rax; u32 eax; } __attribute__ ((packed)); + u64 r8; + u64 r9; + u64 r10; + u64 r11; + u64 r12; + u64 r13; + u64 r14; + u64 r15; +#elif defined(__I386__) + u32 edi; + u32 esi; + u32 ebp; + u32 esp; + u32 ebx; + u32 edx; + u32 ecx; + u32 eax; +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +} __attribute__ ((packed)); + + +typedef struct { + u16 isrLow16; + u16 isrSelector; + u8 count; + u8 type; + u16 isrHigh16; +#ifdef __AMD64__ + u32 isrHigh32; + u32 reserved_zero; +#elif !defined(__I386__) + #error "Unsupported Arch" +#endif /* !defined(__I386__) */ +} __attribute__ ((packed)) idtentry_t; + +typedef struct { + u16 limit0_15; + u16 baseAddr0_15; + u8 baseAddr16_23; + u8 attributes1; + u8 limit16_19attributes2; + u8 baseAddr24_31; +#ifdef __AMD64__ + u32 baseAddr32_63; + u32 reserved_zero; +#elif !defined(__I386__) + #error "Unsupported Arch" +#endif /* !defined(__I386__) */ +} __attribute__ ((packed)) TSSENTRY; + + +#ifdef __AMD64__ +#define get_eflags(x) __asm__ __volatile__("pushfq ; popq %0 ":"=g" (x): /* no input */ :"memory") +#define set_eflags(x) __asm__ __volatile__("pushq %0 ; popfq": /* no output */ :"g" (x):"memory", "cc") +#elif defined(__I386__) +#define get_eflags(x) __asm__ __volatile__("pushfl ; popl %0 ":"=g" (x): /* no input */ :"memory") +#define set_eflags(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory", "cc") +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + +#define cpuid(op, eax, ebx, ecx, edx) \ +({ \ + __asm__ __volatile__("cpuid" \ + :"=a"(*(eax)), "=b"(*(ebx)), "=c"(*(ecx)), "=d"(*(edx)) \ + :"0"(op), "2" (0)); \ +}) + + +#define rdtsc(eax, edx) \ +({ \ + __asm__ __volatile__ ("rdtsc" \ + :"=a"(*(eax)), "=d"(*(edx)) \ + :); \ +}) + +static inline uint64_t rdtsc64(void) +{ +#ifdef __AMD64__ + u32 eax, edx; + __asm__ __volatile__ ("rdtsc" : "=a" (eax), "=d" (edx)); + return ((u64)edx << 32) | eax; +#elif defined(__I386__) + uint64_t rv; + __asm__ __volatile__ ("rdtsc" : "=A" (rv)); + return (rv); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +} + + +/* Calls to read and write control registers */ +static inline unsigned long read_cr0(void){ + unsigned long __cr0; + __asm__("mov %%cr0,%0\n\t" :"=r" (__cr0)); + return __cr0; +} + +static inline void write_cr0(unsigned long val){ + __asm__("mov %0,%%cr0": :"r" ((unsigned long)val)); +} + +static inline unsigned long read_cr3(void){ + unsigned long __cr3; + __asm__("mov %%cr3,%0\n\t" :"=r" (__cr3)); + return __cr3; +} + +static inline unsigned long read_esp(void){ + unsigned long __esp; + __asm__("mov %%esp,%0\n\t" :"=r" (__esp)); + return __esp; +} + +static inline unsigned long read_ebp(void){ + unsigned long __ebp; + __asm__("mov %%ebp,%0\n\t" :"=r" (__ebp)); + return __ebp; +} + +static inline void write_cr3(unsigned long val){ + __asm__("mov %0,%%cr3\n\t" + "jmp 1f\n\t" + "1:" + : + :"r" ((unsigned long)val)); +} + +static inline unsigned long read_cr2(void){ + unsigned long __cr2; + __asm__("mov %%cr2,%0\n\t" :"=r" (__cr2)); + return __cr2; +} + +static inline unsigned long read_cr4(void){ + unsigned long __cr4; + __asm__("mov %%cr4,%0\n\t" :"=r" (__cr4)); + return __cr4; +} + +static inline void write_cr4(unsigned long val){ + __asm__("mov %0,%%cr4": :"r" ((unsigned long)val)); +} + +static inline void skinit(unsigned long eax) { + __asm__("mov %0, %%eax": :"r" (eax)); + __asm__("skinit":); +} + + +//segment register access +static inline u32 read_segreg_cs(void){ + u32 __cs; + __asm__("mov %%cs, %0 \r\n" :"=r" (__cs)); + return __cs; +} + +static inline u32 read_segreg_ds(void){ + u32 __ds; + __asm__("mov %%ds, %0 \r\n" :"=r" (__ds)); + return __ds; +} + +static inline u32 read_segreg_es(void){ + u32 __es; + __asm__("mov %%es, %0 \r\n" :"=r" (__es)); + return __es; +} + +static inline u32 read_segreg_fs(void){ + u32 __fs; + __asm__("mov %%fs, %0 \r\n" :"=r" (__fs)); + return __fs; +} + +static inline u32 read_segreg_gs(void){ + u32 __gs; + __asm__("mov %%gs, %0 \r\n" :"=r" (__gs)); + return __gs; +} + +static inline u32 read_segreg_ss(void){ + u32 __ss; + __asm__("mov %%ss, %0 \r\n" :"=r" (__ss)); + return __ss; +} + +static inline u16 read_tr_sel(void){ + u16 __trsel; + __asm__("str %0 \r\n" :"=r" (__trsel)); + return __trsel; +} + +static inline void wbinvd(void) +{ + __asm__ __volatile__ ("wbinvd"); +} + +static inline uint32_t bsrl(uint32_t mask) +{ + uint32_t result; + + __asm__ __volatile__ ("bsrl %1,%0" : "=r" (result) : "rm" (mask) : "cc"); + return (result); +} + +static inline int fls(int mask) +{ + return (mask == 0 ? mask : (int)bsrl((u32)mask) + 1); +} + +static inline void disable_intr(void) +{ + __asm__ __volatile__ ("cli" : : : "memory"); +} + +static inline void enable_intr(void) +{ + __asm__ __volatile__ ("sti"); +} + +//get extended control register (xcr) +static inline u64 xgetbv(u32 xcr_reg){ + u32 eax, edx; + + asm volatile(".byte 0x0f,0x01,0xd0" + : "=a" (eax), "=d" (edx) + : "c" (xcr_reg)); + + return ((u64)edx << 32) + (u64)eax; +} + +//set extended control register (xcr) +static inline void xsetbv(u32 xcr_reg, u64 value){ + u32 eax = (u32)value; + u32 edx = value >> 32; + + asm volatile(".byte 0x0f,0x01,0xd1" + : + : "a" (eax), "d" (edx), "c" (xcr_reg)); +} + +#ifndef __XMHF_VERIFICATION__ + + static inline u32 get_cpu_vendor_or_die(void) { + u32 dummy; + u32 vendor_dword1, vendor_dword2, vendor_dword3; + + cpuid(0, &dummy, &vendor_dword1, &vendor_dword3, &vendor_dword2); + if(vendor_dword1 == AMD_STRING_DWORD1 && vendor_dword2 == AMD_STRING_DWORD2 + && vendor_dword3 == AMD_STRING_DWORD3) + return CPU_VENDOR_AMD; + else if(vendor_dword1 == INTEL_STRING_DWORD1 && vendor_dword2 == INTEL_STRING_DWORD2 + && vendor_dword3 == INTEL_STRING_DWORD3) + return CPU_VENDOR_INTEL; + else + HALT(); + + return 0; // never reached + } + + + void spin_lock(volatile u32 *); + void spin_unlock(volatile u32 *); + +#else //__XMHF_VERIFICATION__ + + static inline u32 get_cpu_vendor_or_die(void) { + extern u32 xmhf_verify_cpu_vendor; + return xmhf_verify_cpu_vendor; + } + + inline void spin_lock(volatile u32 *lock){ + (void)lock; + } + + inline void spin_unlock(volatile u32 *lock){ + (void)lock; + } + +#endif //__XMHF_VERIFICATION__ + + + +#endif //__ASSEMBLY__ + +#endif /* __PROCESSOR_H */ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_svm.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_svm.h new file mode 100644 index 0000000000..105a9bae39 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_svm.h @@ -0,0 +1,232 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +//AMD SVM definitions +//author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __SVM_H__ +#define __SVM_H__ + +#define SKINIT_SLB_SIZE 0x10000 + +#define SIZEOF_MSRPM_BITMAP (2*4096) + +#ifndef __ASSEMBLY__ + +//AMD SVM Exception Intercepts +//each exception (0-31) is a bit, if set to 1 then the +//exception is intercepted +#define EXCEPTION_INTERCEPT_DB (1UL << 1) + +//SVM Class-1 and Class-2 Intercepts +//Appendix B-1, AMD SDM + +//Class-1 +#define SVM_CLASS1_INTERCEPT_NMI (1UL << 1) +#define SVM_CLASS1_INTERCEPT_IOIO_PROT (1UL << 27) +#define SVM_CLASS1_INTERCEPT_MSR_PROT (1UL << 28) + +//Class-2 +#define SVM_CLASS2_INTERCEPT_VMRUN (1UL << 0) +#define SVM_CLASS2_INTERCEPT_VMMCALL (1UL << 1) +#define SVM_CLASS2_INTERCEPT_VMLOAD (1UL << 2) +#define SVM_CLASS2_INTERCEPT_VMSAVE (1UL << 3) +#define SVM_CLASS2_INTERCEPT_STGI (1UL << 4) +#define SVM_CLASS2_INTERCEPT_CLGI (1UL << 5) +#define SVM_CLASS2_INTERCEPT_SKINIT (1UL << 6) +#define SVM_CLASS2_INTERCEPT_ICEBP (1UL << 8) + + +//SVM VMEXIT Codes +//Appendix C AMD SDM +#define SVM_VMEXIT_EXCEPTION_DB 65 +#define SVM_VMEXIT_EXCEPTION_NMI 66 +#define SVM_VMEXIT_NMI 97 +#define SVM_VMEXIT_INIT 99 +#define SVM_VMEXIT_IOIO 123 +#define SVM_VMEXIT_MSR 124 +#define SVM_VMEXIT_SHUTDOWN 127 +#define SVM_VMEXIT_VMMCALL 129 +#define SVM_VMEXIT_NPF 1024 +#define SVM_VMEXIT_INVALID -1 + +//SVM VMCB TLB Control +//Appendix B-1 AMD SDM +#define VMCB_TLB_CONTROL_NOTHING 0 +#define VMCB_TLB_CONTROL_FLUSHALL 1 +#define VMCB_TLB_CONTROL_THISGUEST 3 +#define VMCB_TLB_CONTROL_THISGUESTNONGLOBAL 7 + +//SVM Nested Page Fault Error Codes +//Sec. 15.25.6 AMD SDM +#define VMCB_NPT_ERRORCODE_P (1UL << 0) +#define VMCB_NPT_ERRORCODE_RW (1UL << 1) +#define VMCB_NPT_ERRORCODE_US (1UL << 2) +#define VMCB_NPT_ERRORCODE_RSV (1UL << 3) +#define VMCB_NPT_ERRORCODE_ID (1UL << 4) +#define VMCB_NPT_ERRORCODE_TABLEWALK (((u64)1)<<33) +#define VMCB_NPT_ERRORCODE_FINALWALK (((u64)1)<<32) + +//SVM (Segment) Descriptor State Structure +//Appendix B-1 AMD SDM +struct svmdesc { + u16 selector; + u16 attrib; + u32 limit; + u64 base; +} __attribute__ ((packed)); + + +//SVM Event Injection Structure and Event Types +//Sec. 15.20 AMD SDM +struct svmeventinj { + u64 vector: 8; + u64 type: 3; + u64 ev: 1; + u64 reserved: 19; + u64 v: 1; + u64 errorcode: 32; +} __attribute__ ((packed)); + +#define EVENTINJ_TYPE_INTR 0 +#define EVENTINJ_TYPE_NMI 2 +#define EVENTINJ_TYPE_EXCEPTION 3 +#define EVENTINJ_TYPE_SWINT 4 + +//SVM I/O Intercept Information Structure +//Sec. 15.10.2, AMD SDM +union svmioiointerceptinfo { + u64 rawbits; + struct { + u64 type: 1; + u64 rsv0: 1; + u64 str: 1; + u64 rep: 1; + u64 sz8: 1; + u64 sz16: 1; + u64 sz32: 1; + u64 a16: 1; + u64 a32: 1; + u64 a64: 1; + u64 seg: 3; + u64 rsv1: 3; + u64 port: 16; + } __attribute__ ((packed)) fields; +} __attribute__ ((packed)); + +//SVM Virtual Machine Control Block Structure +//Appendix B-1, AMD SDM +struct _svm_vmcbfields { + u8 __currently_unused0[8]; + u32 exception_intercepts_bitmask; //byte offset 0x08 + u32 class1_intercepts_bitmask; //byte offset 0x0C + u32 class2_intercepts_bitmask; //byte offset 0x10 + u8 __reserved0[44]; + u64 iopm_base_pa; //byte offset 0x40 + u64 msrpm_base_pa; //byte offset 0x48 + u8 __currently_unused1[8]; + u32 guest_asid; //byte offset 0x58 + u8 tlb_control; //byte offset 0x5C + u8 __reserved1[3]; + u8 __currently_unused2[16]; + u64 exitcode; //byte offset 0x70 + u64 exitinfo1; //byte offset 0x78 + u64 exitinfo2; //byte offset 0x80 + struct svmeventinj exitintinfo; //byte offset 0x88 + u64 np_enable; //byte offset 0x90 + u8 __reserved2[16]; + struct svmeventinj eventinj; //byte offset 0xA8 + u64 n_cr3; //byte offset 0xB0 + u8 __reserved3[840]; + struct svmdesc es; //byte offset 0x400 + struct svmdesc cs; + struct svmdesc ss; + struct svmdesc ds; + struct svmdesc fs; + struct svmdesc gs; + struct svmdesc gdtr; + struct svmdesc ldtr; + struct svmdesc idtr; + struct svmdesc tr; + u8 __reserved4[43]; + u8 cpl; + u8 __reserved5[4]; + u64 efer; + u8 __reserved6[112]; + u64 cr4; + u64 cr3; + u64 cr0; + u64 dr7; + u64 dr6; + u64 rflags; + u64 rip; + u8 __reserved7[88]; + u64 rsp; + u8 __reserved8[24]; + u64 rax; + u8 __currently_unused3[64]; + u64 cr2; + u8 __currently_unused4[32]; + u64 g_pat; + u8 __reserved9[2448]; +} __attribute__ ((packed)); + +//macros for saving and storing additional VMCB state information +static inline void vmsave(u32 vmcb){ + __asm__("vmsave" + : // no output + :"a"(vmcb)); +} + +static inline void vmload(u32 vmcb){ + __asm__("vmload" + : // no output + :"a"(vmcb)); +} + +#endif /* __ASSEMBLY__ */ + +#endif /* __SVM_H__ */ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_svm_eap.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_svm_eap.h new file mode 100644 index 0000000000..0275babdbc --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_svm_eap.h @@ -0,0 +1,196 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +//svm_eap.h - SVM External Access Protection declarations/definitions +//author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __SVM_EAP_H__ +#define __SVM_EAP_H__ + +//DEV is part of the Miscellaneous Configuration HT Device that is +//guaranteed to be on bus 0, device 0x18 and function 3 (2.11 & 3.6, AMD BKDG) +//XXX: what is not clear from the doc. is whether there could be multiple DEV +//devices like on Intel platforms (VT-d DMAR). +#define DEV_PCI_BUS 0x0 +#define DEV_PCI_DEVICE 0x18 +#define DEV_PCI_FUNCTION 0x3 + + +//DEV function codes (15.24.5, AMD Dev. vol-2) +#define DEV_BASE_LO 0 +#define DEV_BASE_HI 1 +#define DEV_MAP 2 +#define DEV_CAP 3 +#define DEV_CR 4 +#define DEV_ERR_STATUS 5 +#define DEV_ERR_ADDR_LO 6 +#define DEV_ERR_ADDR_HI 7 + + +#ifndef __ASSEMBLY__ + +//SVM EAP container structure +struct _svm_eap { + u32 dev_hdr_reg; //DEV header register (32-bit) + u32 dev_fnidx_reg; //DEV function/index register (32-bit) + u32 dev_data_reg; //DEV data register (32-bit) + hva_t dev_bitmap_vaddr; //DEV bitmap virtual address +}; + + +//DEV DEV_BASE_LO structure (p. 329, AMD BKDG) +typedef union dev_base_lo { + u32 bytes; + struct{ + u32 valid:1; //1= DEV enabled, 0= DEV disabled + u32 protect:1; //0= allow out-of-range addresses, 1= disallow out-of-range addresses + u32 size:5; //size of memory region that DEV covers (4GB*(2^size)) + u32 resv:5; //reserved + u32 base_addr:20; //bits 12-31 of physical address of DEV table + }fields; +} __attribute__ ((packed)) dev_base_lo_t; + +//DEV DEV_BASE_HI structure (p. 330, AMD BKDG) +typedef union dev_base_hi { + u32 bytes; + struct{ + u32 base_addr:16; //bits 32-47 of physical address of DEV table + u32 resv:16; //reserved + }fields; +} __attribute__ ((packed)) dev_base_hi_t; + +//DEV DEV_MAP structure (p. 330, AMD BKDG) +typedef union dev_map{ + u32 bytes; + struct{ + u32 unit0:5; //I/O link unit 0 ID + u32 valid0:1; //1= enable DEV for unit 0 and dom 0 + u32 unit1:5; //I/O link unit 1 ID + u32 valid1:1; //1= enable DEV for unit 1 and dom 1 + u32 busno:8; //HT bus number + u32 dom0:6; //protection domain number assigned to unit 0 + u32 dom1:6; //protection domain number assigned to unit 1 + }fields; +} __attribute__ ((packed)) dev_map_t; + +//DEV DEV_CAP structure (p. 330, AMD BKDG) +typedef union dev_cap{ + u32 bytes; + struct{ + u32 rev:8; //DEV register set revision number (00h for current) + u32 n_doms:8; //number of protection domains implemented + u32 n_maps:8; //number of map registers implemented + u32 resv:8; //reserved + }fields; +} __attribute__ ((packed)) dev_cap_t; + +//DEV DEV_CR structure (p. 331, AMD BKDG) +typedef union dev_cr { + u32 bytes; + struct{ + u32 deven:1; //1=enable DEV + u32 resv0:1; //reserved + u32 iodis:1; //1=disable upstream i/o cycles, set to 1 after SKINIT + u32 mceen:1; //1=enable logging and reporting of DEV violations through MCE + u32 devinv:1; //1=invalidate DEV table walk cache. bit cleared by h/w when complete + u32 sldev:1; //1=memory region associated with SKINIT is internally protected, 0=use DEV table instead + u32 walkprobe:1;//1=disable probing of CPU caches during DEV table walks + u32 resv1:25; //bits 7-31 reserved + }fields; +} __attribute__ ((packed)) dev_cr_t; + + +//DEV DEV_ERR_STATUS structure (p 331 & 332, AMD BKDG) +typedef union dev_err_status { + u32 bytes; + struct{ + u32 accesstype:2; //error code access type +#define DEV_ERR_STATUS_ACCESSTYPE_GENERIC 0 +#define DEV_ERR_STATUS_ACCESSTYPE_READ 1 +#define DEV_ERR_STATUS_ACCESSTYPE_WRITE 2 +#define DEV_ERR_STATUS_ACCESSTYPE_READMODIFYWRITE 3 + u32 source:3; //error code source +#define DEV_ERR_STATUS_SOURCE_GENERIC 0 +#define DEV_ERR_STATUS_SOURCE_CPU 1 +#define DEV_ERR_STATUS_SOURCE_DEVICE 2 + u32 dest:3; //error code destination +#define DEV_ERR_STATUS_DEST_GENERIC 0 +#define DEV_ERR_STATUS_DEST_DRAM 1 +#define DEV_ERR_STATUS_DEST_MMIO 2 +#define DEV_ERR_STATUS_DEST_IO 4 +#define DEV_ERR_STATUS_DEST_CONFIGURATION 5 + u32 resv0:8; //reserved + u32 mserror:8; //model-specific error + u32 resv1:5; //reserved + u32 addrvalid:1; //error address valid + u32 overflow:1; //error overflow, 1=DEV violation was detected + u32 valid:1; //error valid, 1=DEV violation has been logged + }fields; +} __attribute__ ((packed)) dev_err_status_t; + + +//DEV DEV_ERROR_ADDR_LO structure (p. 332, AMD BKDG) +typedef union dev_err_addr_lo { + u32 bytes; + struct{ + u32 resv0:2; //reserved + u32 addr:30; //bits 2:31 of error address + }fields; +} __attribute__((packed)) dev_err_addr_lo_t; + +//DEV DEV_ERROR_ADDR_HI structure (p. 332, AMD BKDG) +typedef union dev_err_addr_hi { + u32 bytes; + struct{ + u32 addr:16; //bits 32-47 of error address + u32 resv:16; //reserved + }fields; +} __attribute__((packed)) dev_err_addr_hi_t; + + +#endif //__ASSEMBLY__ + +#endif //__SVM_EAP_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt.h new file mode 100644 index 0000000000..96d6222b1b --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt.h @@ -0,0 +1,69 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* txt.h - Unified header file for Intel TXT requirements */ +//author: jonmccune@cmu.edu + +#ifndef __UNI_TXT_ +#define __UNI_TXT_ + +#ifndef __ASSEMBLY__ + +#include "_txt_config_regs.h" +#include "_txt_hash.h" + +/* XXX TODO order is important for these; fix it */ +#include "_txt_mle.h" +#include "_txt_smx.h" +#ifdef __DRT__ +#include "_txt_acmod.h" +#include "_txt_mtrrs.h" +#include "_txt_heap.h" +#endif /* __DRT__ */ + +#endif //__ASSEMBLY__ + +#endif /* __UNI_TXT_ */ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt_acmod.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt_acmod.h new file mode 100644 index 0000000000..a99d85a6f2 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt_acmod.h @@ -0,0 +1,190 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * acmod.c: support functions for use of Intel(r) TXT Authenticated + * Code (AC) Modules + * + * Copyright (c) 2003-2010, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * Modified for XMHF by jonmccune@cmu.edu, 2011.01.04 + * + * XXX TODO: [Almost?] All of this is only needed in init; pull out of + * common include directory to reduce SL/Runtime TCB. + */ + +#ifndef __TXT_ACMOD_H__ +#define __TXT_ACMOD_H__ + +/* + * authenticated code (AC) module header (ver 0.0) + */ + +typedef union { + uint16_t _raw; + struct { + uint16_t reserved : 14; + uint16_t pre_production : 1; + uint16_t debug_signed : 1; + } __attribute__((packed)); +} acm_flags_t; + +typedef struct { + uint32_t module_type; + uint32_t header_len; + uint32_t header_ver; /* currently 0.0 */ + uint16_t chipset_id; + acm_flags_t flags; + uint32_t module_vendor; + uint32_t date; + uint32_t size; + uint32_t reserved1; + uint32_t code_control; + uint32_t error_entry_point; + uint32_t gdt_limit; + uint32_t gdt_base; + uint32_t seg_sel; + uint32_t entry_point; + uint8_t reserved2[64]; + uint32_t key_size; + uint32_t scratch_size; + uint8_t rsa2048_pubkey[256]; + uint32_t pub_exp; + uint8_t rsa2048_sig[256]; + uint32_t scratch[143]; + uint8_t user_area[]; +} __attribute__((packed)) acm_hdr_t; + +/* value of module_type field */ +#define ACM_TYPE_CHIPSET 0x02 + +/* value of module_vendor field */ +#define ACM_VENDOR_INTEL 0x8086 + +typedef struct { + uuid_t uuid; + uint8_t chipset_acm_type; + uint8_t version; /* currently 3 */ + uint16_t length; + uint32_t chipset_id_list; + uint32_t os_sinit_data_ver; + uint32_t min_mle_hdr_ver; + txt_caps_t capabilities; + uint8_t acm_ver; + uint8_t reserved[3]; +} __attribute__((packed)) acm_info_table_t; + +/* ACM UUID value */ +#define ACM_UUID_V3 {0x7fc03aaa, 0x46a7, 0x18db, 0xac2e, \ + {0x69, 0x8f, 0x8d, 0x41, 0x7f, 0x5a}} + +/* chipset_acm_type field values */ +#define ACM_CHIPSET_TYPE_BIOS 0x00 +#define ACM_CHIPSET_TYPE_SINIT 0x01 + +typedef struct { + uint32_t flags; + uint16_t vendor_id; + uint16_t device_id; + uint16_t revision_id; + uint16_t reserved; + uint32_t extended_id; +} __attribute__((packed)) acm_chipset_id_t; + +typedef struct { + uint32_t count; + acm_chipset_id_t chipset_ids[]; +} __attribute__((packed)) acm_chipset_id_list_t; + +extern void print_uuid(const uuid_t *uuid); +extern void print_txt_caps(const char *prefix, txt_caps_t caps); +extern bool is_sinit_acmod(void *acmod_base, size_t acmod_size, bool quiet); +extern bool does_acmod_match_chipset(acm_hdr_t* hdr); +extern acm_hdr_t *copy_sinit(acm_hdr_t *sinit); +extern bool verify_acmod(acm_hdr_t *acm_hdr); +extern uint32_t get_supported_os_sinit_data_ver(acm_hdr_t* hdr); +extern uint32_t get_sinit_capabilities(acm_hdr_t* hdr); +#endif /* __TXT_ACMOD_H__ */ + +/* + * Local variables: + * mode: C + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt_config_regs.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt_config_regs.h new file mode 100644 index 0000000000..f560155664 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt_config_regs.h @@ -0,0 +1,365 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * config_regs.h: Intel(r) TXT configuration register -related definitions + * + * Copyright (c) 2003-2010, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * Modified for XMHF by jonmccune@cmu.edu, 2011.01.04 + */ + +#ifndef __TXT_CONFIG_REGS_H__ +#define __TXT_CONFIG_REGS_H__ + +/* + * TXT configuration registers (offsets from TXT_{PUB, PRIV}_CONFIG_REGS_BASE) + */ + +#define TXT_PUB_CONFIG_REGS_BASE 0xfed30000 +#define TXT_PRIV_CONFIG_REGS_BASE 0xfed20000 + +/* # pages for each config regs space - used by fixmap */ +#define NR_TXT_CONFIG_PAGES ((TXT_PUB_CONFIG_REGS_BASE - \ + TXT_PRIV_CONFIG_REGS_BASE) >> \ + PAGE_SHIFT) + +/* offsets to config regs (from either public or private _BASE) */ +#define TXTCR_STS 0x0000 +#define TXTCR_ESTS 0x0008 +#define TXTCR_ERRORCODE 0x0030 +#define TXTCR_CMD_RESET 0x0038 +#define TXTCR_CMD_CLOSE_PRIVATE 0x0048 +#define TXTCR_VER_FSBIF 0x0100 +#define TXTCR_DIDVID 0x0110 +#define TXTCR_VER_EMIF 0x0200 +#define TXTCR_CMD_UNLOCK_MEM_CONFIG 0x0218 +#define TXTCR_SINIT_BASE 0x0270 +#define TXTCR_SINIT_SIZE 0x0278 +#define TXTCR_MLE_JOIN 0x0290 +#define TXTCR_HEAP_BASE 0x0300 +#define TXTCR_HEAP_SIZE 0x0308 +#define TXTCR_MSEG_BASE 0x0310 +#define TXTCR_MSEG_SIZE 0x0318 +#define TXTCR_DPR 0x0330 +#define TXTCR_CMD_OPEN_LOCALITY1 0x0380 +#define TXTCR_CMD_CLOSE_LOCALITY1 0x0388 +#define TXTCR_CMD_OPEN_LOCALITY2 0x0390 +#define TXTCR_CMD_CLOSE_LOCALITY2 0x0398 +#define TXTCR_CMD_SECRETS 0x08e0 +#define TXTCR_CMD_NO_SECRETS 0x08e8 +#define TXTCR_E2STS 0x08f0 + +/* + * format of ERRORCODE register + */ +typedef union { + uint64_t _raw; + struct { + uint64_t type : 30; /* external-specific error code */ + uint64_t external : 1; /* 0=from proc, 1=from external SW */ + uint64_t valid : 1; /* 1=valid */ + }; +} txt_errorcode_t; + +/* + * format of ESTS register + */ +typedef union { + uint64_t _raw; + struct { + uint64_t txt_reset_sts : 1; + uint64_t reserved1 : 5; + uint64_t txt_wake_error_sts : 1; + uint64_t reserved2 : 1; + }; +} txt_ests_t; + +/* + * format of E2STS register + */ +typedef union { + uint64_t _raw; + struct { + uint64_t slp_entry_error_sts : 1; + uint64_t secrets_sts : 1; + uint64_t block_mem_sts : 1; + uint64_t reset_sts : 1; + }; +} txt_e2sts_t; + +/* + * format of STS register + */ +typedef union { + uint64_t _raw; + struct { + uint64_t senter_done_sts : 1; + uint64_t sexit_done_sts : 1; + uint64_t reserved1 : 2; + uint64_t mem_unlock_sts : 1; + uint64_t reserved2 : 1; + uint64_t mem_config_lock_sts : 1; + uint64_t private_open_sts : 1; + uint64_t reserved3 : 3; + uint64_t mem_config_ok_sts : 1; + }; +} txt_sts_t; + +/* + * format of DIDVID register + */ +typedef union { + uint64_t _raw; + struct { + uint16_t vendor_id; + uint16_t device_id; + uint16_t revision_id; + uint16_t reserved; + }; +} txt_didvid_t; + +/* + * format of VER.FSBIF and VER.EMIF registers + */ +typedef union { + uint64_t _raw; + struct { + uint64_t reserved : 31; + uint64_t prod_fused : 1; + }; +} txt_ver_fsbif_emif_t; + +/* + * format of DPR register + */ +typedef union { + uint64_t _raw; + struct { + uint64_t lock : 1; + uint64_t reserved1 : 3; + uint64_t size : 8; + uint64_t reserved2 : 8; + uint64_t top : 12; + uint64_t reserved3 : 32; + }; +} txt_dpr_t; + +/* + * RLP JOIN structure for GETSEC[WAKEUP] and MLE_JOIN register + */ +typedef struct { + uint32_t gdt_limit; + uint32_t gdt_base; + uint32_t seg_sel; /* cs (ds, es, ss are seg_sel+8) */ + uint32_t entry_point; /* phys addr */ +} mle_join_t; + +/* + * format of MSEG header + */ +typedef struct { + uint32_t revision_id; + uint32_t smm_mon_feat; + uint32_t gdtr_limit; + uint32_t gdtr_base_offset; + uint32_t cs_sel; + uint32_t eip_offset; + uint32_t esp_offset; + uint32_t cr3_offset; +} mseg_hdr_t; + +/* + * fns to read/write TXT config regs + * + * In i386, always use %FS segment-override + * In amd64, use (VA + 256MiB) % 4GiB = PA to access physical memory + */ + +#ifdef __AMD64__ +extern u32 xmhf_baseplatform_arch_flat_va_offset; +#elif !defined(__I386__) + #error "Unsupported Arch" +#endif /* !defined(__I386__) */ + +static inline uint64_t read_config_reg(uint32_t config_regs_base, uint32_t reg) +{ + u32 addr = config_regs_base + reg; +#ifdef __AMD64__ + u32 physical_addr = (u32)addr - (u32)xmhf_baseplatform_arch_flat_va_offset; + u64 ret = *(u64 *)(u64)physical_addr; +#elif defined(__I386__) + u64 ret; + __asm__ __volatile__("movl %%fs:(%%ebx), %%eax\r\n" + "movl %%fs:4(%%ebx), %%edx\r\n" + : "=A"(ret) + : "b"(addr) + ); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + return ret; +} + +static inline void write_config_reg(uint32_t config_regs_base, uint32_t reg, + uint64_t val) +{ + u32 addr = config_regs_base + reg; +#ifdef __AMD64__ + u32 physical_addr = (u32)addr - (u32)xmhf_baseplatform_arch_flat_va_offset; + *(u64 *)(u64)physical_addr = val; +#elif defined(__I386__) + __asm__ __volatile__("movl %%eax, %%fs:(%%ebx)\r\n" + "movl %%edx, %%fs:4(%%ebx)\r\n" + : + : "A"(val), "b"(addr) + ); + +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +} + +static inline uint64_t read_pub_config_reg(uint32_t reg) +{ + return read_config_reg(TXT_PUB_CONFIG_REGS_BASE, reg); +} + +static inline void write_pub_config_reg(uint32_t reg, uint64_t val) +{ + write_config_reg(TXT_PUB_CONFIG_REGS_BASE, reg, val); +} + +static inline uint64_t read_priv_config_reg(uint32_t reg) +{ + return read_config_reg(TXT_PRIV_CONFIG_REGS_BASE, reg); +} + +static inline void write_priv_config_reg(uint32_t reg, uint64_t val) +{ + write_config_reg(TXT_PRIV_CONFIG_REGS_BASE, reg, val); +} + + +/*********************************************************** + These next two taken from tboot-20101005/tboot/include/txt/ + **********************************************************/ + +/* + * for SW errors (ERRORCODE.external = 1) + */ +typedef union { + uint32_t _raw; + struct { + uint32_t err1 : 15; /* specific to src */ + uint32_t src : 1; /* 0=ACM, 1=other */ + uint32_t err2 : 14; /* specific to src */ + }; +} txt_errorcode_sw_t; + +/* + * ACM errors (txt_errorcode_sw_t.src=0), format of err field + */ +typedef union { + uint32_t _raw; + struct { + uint32_t acm_type : 4; /* 0000=BIOS ACM, 0001=SINIT, */ + /* 0010-1111=reserved */ + uint32_t progress : 6; + uint32_t error : 4; + uint32_t reserved : 1; + uint32_t src : 1; /* above value */ + uint32_t error2 : 14; /* sub-error */ + }; +} acmod_error_t; + + + + + + +#endif /* __TXT_CONFIG_REGS_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt_hash.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt_hash.h new file mode 100644 index 0000000000..25b9f1b7c5 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt_hash.h @@ -0,0 +1,143 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * hash.h: definition of and support fns for tb_hash_t type + * + * Copyright (c) 2006-2007, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * Modified for XMHF by jonmccune@cmu.edu, 2011.01.04 + */ + +#ifndef __HASH_H__ +#define __HASH_H__ + +#define TB_HALG_SHA1 0 + +#ifndef SHA1_LENGTH +#define SHA1_LENGTH 20 +#endif +#ifndef SHA256_LENGTH +#define SHA256_LENGTH 32 +#endif + +typedef union { + uint8_t sha1[SHA1_LENGTH]; + uint8_t sha256[SHA256_LENGTH]; +} tb_hash_t; + + +/* static inline const char *hash_alg_to_string(uint8_t hash_alg) */ +/* { */ +/* if ( hash_alg == TB_HALG_SHA1 ) */ +/* return "TB_HALG_SHA1"; */ +/* else { */ +/* static char buf[32]; */ +/* snprintf(buf, sizeof(buf), "unsupported (%u)", hash_alg); */ +/* return buf; */ +/* } */ +/* } */ + + +static inline unsigned int get_hash_size(uint8_t hash_alg) +{ + return (hash_alg == TB_HALG_SHA1) ? SHA1_LENGTH : 0; +} + +extern bool are_hashes_equal(const tb_hash_t *hash1, const tb_hash_t *hash2, + uint8_t hash_alg); +extern bool hash_buffer(const unsigned char* buf, size_t size, tb_hash_t *hash, + uint8_t hash_alg); +extern bool extend_hash(tb_hash_t *hash1, const tb_hash_t *hash2, + uint8_t hash_alg); +extern void print_hash(const tb_hash_t *hash, uint8_t hash_alg); +extern void copy_hash(tb_hash_t *dest_hash, const tb_hash_t *src_hash, + uint8_t hash_alg); + + +#endif /* __HASH_H__ */ + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt_heap.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt_heap.h new file mode 100644 index 0000000000..5beee4a8ac --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt_heap.h @@ -0,0 +1,296 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * heap.h: Intel(r) TXT heap definitions + * + * Copyright (c) 2003-2008, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * Modified for XMHF by jonmccune@cmu.edu, 2011.01.04 + */ + +#ifndef __TXT_HEAP_H__ +#define __TXT_HEAP_H__ + +/* + * data-passing structures contained in TXT heap: + * - BIOS + * - OS/loader to MLE + * - OS/loader to SINIT + * - SINIT to MLE + */ + +/* + * BIOS structure + */ +typedef struct { + uint32_t version; /* WB = 2, current = 3 */ + uint32_t bios_sinit_size; + uint64_t lcp_pd_base; + uint64_t lcp_pd_size; + uint32_t num_logical_procs; + /* versions >= 3 */ + uint64_t flags; +} __attribute__((packed)) bios_data_t; + +/* + * OS/loader to MLE structure + * - private to tboot (so can be any format we need) + */ +#define MAX_LCP_PO_DATA_SIZE 64*1024 /* 64k */ + +/* This struct is manually aligned */ +typedef struct { + uint32_t version; /* currently 2 */ + uint32_t _; /* alignment padding for amd64 */ + mtrr_state_t saved_mtrr_state; /* saved prior to changes for SINIT */ + uint32_t mbi; /* needs to be restored to ebx */ + /* type was multiboot_info_t* */ + uint32_t saved_misc_enable_msr; /* saved prior to SENTER */ + /* PO policy data */ + uint8_t lcp_po_data[MAX_LCP_PO_DATA_SIZE]; +} __attribute__((packed)) os_mle_data_t; + +/* + * OS/loader to SINIT structure + */ +typedef struct { + uint32_t version; /* currently 4, 5 */ + uint32_t reserved; + uint64_t mle_ptab; + uint64_t mle_size; + uint64_t mle_hdr_base; + uint64_t vtd_pmr_lo_base; + uint64_t vtd_pmr_lo_size; + uint64_t vtd_pmr_hi_base; + uint64_t vtd_pmr_hi_size; + uint64_t lcp_po_base; + uint64_t lcp_po_size; + txt_caps_t capabilities; + /* versions >= 5 */ + uint64_t efi_rsdt_ptr; +} __attribute__((packed)) os_sinit_data_t; + +/* + * SINIT to MLE structure + */ +#define MDR_MEMTYPE_GOOD 0x00 +#define MDR_MEMTYPE_SMM_OVERLAY 0x01 +#define MDR_MEMTYPE_SMM_NONOVERLAY 0x02 +#define MDR_MEMTYPE_PCIE_CONFIG_SPACE 0x03 +#define MDR_MEMTYPE_PROTECTED 0x04 + +typedef struct __attribute__ ((packed)) { + uint64_t base; + uint64_t length; + uint8_t mem_type; + uint8_t reserved[7]; +} __attribute__((packed)) sinit_mdr_t; + +#define SHA1_SIZE 20 +typedef uint8_t sha1_hash_t[SHA1_SIZE]; + +typedef struct { + uint32_t version; /* currently 6-8 */ + sha1_hash_t bios_acm_id; + uint32_t edx_senter_flags; + uint64_t mseg_valid; + sha1_hash_t sinit_hash; + sha1_hash_t mle_hash; + sha1_hash_t stm_hash; + sha1_hash_t lcp_policy_hash; + uint32_t lcp_policy_control; + uint32_t rlp_wakeup_addr; + uint32_t reserved; + uint32_t num_mdrs; + uint32_t mdrs_off; + uint32_t num_vtd_dmars; + uint32_t vtd_dmars_off; + /* versions >= 8 */ + uint32_t proc_scrtm_status; +} __attribute__((packed)) sinit_mle_data_t; + + +/* + * TXT heap data format and field accessor fns + */ + +/* + * offset length field + * ------ ------ ----- + * 0 8 bios_data_size + * 8 bios_data_size - 8 bios_data + * + * bios_data_size 8 os_mle_data_size + * bios_data_size + os_mle_data_size - 8 os_mle_data + * 8 + * + * bios_data_size + 8 os_sinit_data_size + * os_mle_data_size + * bios_data_size + os_sinit_data_size - 8 os_sinit_data + * os_mle_data_size + + * 8 + * + * bios_data_size + 8 sinit_mle_data_size + * os_mle_data_size + + * os_sinit_data_size + * bios_data_size + sinit_mle_data_size - 8 sinit_mle_data + * os_mle_data_size + + * os_sinit_data_size + + * 8 + */ + +typedef void txt_heap_t; + +/* this is a common use with annoying casting, so make it an inline */ +static inline txt_heap_t *get_txt_heap(void) +{ + return (txt_heap_t *)(unsigned long)read_pub_config_reg(TXTCR_HEAP_BASE); +} + +static inline uint64_t get_bios_data_size(txt_heap_t *heap) +{ + return *(uint64_t *)heap; + //return xmhf_arch_baseplatform_flat_readu64((u32)heap); +} + +static inline bios_data_t *get_bios_data_start(txt_heap_t *heap) +{ + return (bios_data_t *)((char*)heap + sizeof(uint64_t)); +} + +static inline uint64_t get_os_mle_data_size(txt_heap_t *heap) +{ + return *(uint64_t *)(heap + get_bios_data_size(heap)); + //return xmhf_arch_baseplatform_flat_readu64((u32)(heap + get_bios_data_size(heap))); +} + +static inline os_mle_data_t *get_os_mle_data_start(txt_heap_t *heap) +{ + return (os_mle_data_t *)(heap + get_bios_data_size(heap) + + sizeof(uint64_t)); +} + +static inline uint64_t get_os_sinit_data_size(txt_heap_t *heap) +{ + return *(uint64_t *)(heap + get_bios_data_size(heap) + + get_os_mle_data_size(heap)); + //return xmhf_arch_baseplatform_flat_readu64((u32)(heap + get_bios_data_size(heap) + + // get_os_mle_data_size(heap))); + +} + +static inline os_sinit_data_t *get_os_sinit_data_start(txt_heap_t *heap) +{ + return (os_sinit_data_t *)(heap + get_bios_data_size(heap) + + get_os_mle_data_size(heap) + + sizeof(uint64_t)); +} + +static inline uint64_t get_sinit_mle_data_size(txt_heap_t *heap) +{ + return *(uint64_t *)(heap + get_bios_data_size(heap) + + get_os_mle_data_size(heap) + + get_os_sinit_data_size(heap)); + //return xmhf_arch_baseplatform_flat_readu64((u32)(heap + get_bios_data_size(heap) + + // get_os_mle_data_size(heap) + + // get_os_sinit_data_size(heap))); +} + +static inline sinit_mle_data_t *get_sinit_mle_data_start(txt_heap_t *heap) +{ + return (sinit_mle_data_t *)(heap + get_bios_data_size(heap) + + get_os_mle_data_size(heap) + + get_os_sinit_data_size(heap) + + sizeof(uint64_t)); +} + +extern bool verify_txt_heap(txt_heap_t *txt_heap, bool bios_data_only); +extern bool verify_bios_data(txt_heap_t *txt_heap); +extern void print_os_sinit_data(os_sinit_data_t *os_sinit_data); + +#endif /* __TXT_HEAP_H__ */ + + +/* + * Local variables: + * mode: C + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt_mle.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt_mle.h new file mode 100644 index 0000000000..558e0f7d54 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt_mle.h @@ -0,0 +1,188 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * mle.h: Intel(r) TXT MLE header definition + * + * Copyright (c) 2003-2008, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * Modified for XMHF by jonmccune@cmu.edu, 2011.01.04 + */ + +#ifndef __MLE_H__ +#define __MLE_H__ + +/* + * SINIT/MLE capabilities + */ +typedef union { + uint32_t _raw; + struct { + uint32_t rlp_wake_getsec : 1; + uint32_t rlp_wake_monitor : 1; + uint32_t ecx_pgtbl : 1; + uint32_t reserved : 29; + }; +} txt_caps_t; + + +/* taken from tboot-20101005/include/uuid.h */ +typedef struct __packed { + uint32_t data1; + uint16_t data2; + uint16_t data3; + uint16_t data4; + uint8_t data5[6]; +} uuid_t; + +/* static inline bool are_uuids_equal(const uuid_t *uuid1, const uuid_t *uuid2) */ +/* { */ +/* return (memcmp(uuid1, uuid2, sizeof(*uuid1)) == 0); */ +/* } */ + +/* + * MLE header structure + * describes an MLE for SINIT and OS/loader SW + */ +typedef struct { + uuid_t uuid; + uint32_t length; + uint32_t version; + uint32_t entry_point; + uint32_t first_valid_page; + uint32_t mle_start_off; + uint32_t mle_end_off; + txt_caps_t capabilities; + uint32_t cmdline_start_off; + uint32_t cmdline_end_off; +} mle_hdr_t; + +#define MLE_HDR_UUID {0x9082ac5a, 0x476f, 0x74a7, 0x5c0f, \ + {0x55, 0xa2, 0xcb, 0x51, 0xb6, 0x42}} + +/* + * values supported by current version of tboot + */ +#define MLE_HDR_VER 0x00020001 /* 2.1 */ +#define MLE_HDR_CAPS 0x00000007 /* rlp_wake_{getsec, monitor} = 1, + ecx_pgtbl = 1 */ + +/* from tboot-20101005/include/tb_error.h */ +typedef enum { + TB_ERR_NONE = 0, /* succeed */ + TB_ERR_FIXED = 1, /* previous error has been fixed */ + + TB_ERR_GENERIC, /* non-fatal generic error */ + + TB_ERR_TPM_NOT_READY, /* tpm not ready */ + TB_ERR_SMX_NOT_SUPPORTED, /* smx not supported */ + TB_ERR_VMX_NOT_SUPPORTED, /* vmx not supported */ + TB_ERR_TXT_NOT_SUPPORTED, /* txt not supported */ + + TB_ERR_MODULE_VERIFICATION_FAILED, /* module failed to verify against + policy */ + TB_ERR_MODULES_NOT_IN_POLICY, /* modules in mbi but not in + policy */ + TB_ERR_POLICY_INVALID, /* policy is invalid */ + TB_ERR_POLICY_NOT_PRESENT, /* no policy in TPM NV */ + + TB_ERR_SINIT_NOT_PRESENT, /* SINIT ACM not provided */ + TB_ERR_ACMOD_VERIFY_FAILED, /* verifying AC module failed */ + + TB_ERR_POST_LAUNCH_VERIFICATION, /* verification of post-launch + failed */ + TB_ERR_S3_INTEGRITY, /* creation or verification of + S3 integrity measurements + failed */ + + TB_ERR_FATAL, /* generic fatal error */ + TB_ERR_MAX +} tb_error_t; + + +#endif /* __MLE_H__ */ + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt_mtrrs.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt_mtrrs.h new file mode 100644 index 0000000000..69aef965f6 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt_mtrrs.h @@ -0,0 +1,207 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * mtrrs.c: Intel(r) TXT MTRR-related definitions + * + * Copyright (c) 2003-2010, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * Modified for XMHF by jonmccune@cmu.edu, 2011.01.04 + */ + +#ifndef __TXT_MTRRS_H__ +#define __TXT_MTRRS_H__ + +/* XXX TODO eliminate this dependency. txt_heap.h is also dependent + * on the current file. tboot code has the ugly structure. we should + * do better. */ +#include "_txt_acmod.h" + +enum fix_mtrr_t { + MTRR_FIX64K_00000 = 0x250, + MTRR_FIX16K_80000 = 0x258, + MTRR_FIX16K_A0000 = 0x259, + MTRR_FIX4K_C0000 = 0x268, + MTRR_FIX4K_C8000 = 0x269, + MTRR_FIX4K_D0000 = 0x26A, + MTRR_FIX4K_D8000 = 0x26B, + MTRR_FIX4K_E0000 = 0x26C, + MTRR_FIX4K_E8000 = 0x26D, + MTRR_FIX4K_F0000 = 0x26E, + MTRR_FIX4K_F8000 = 0x26F +}; + +typedef union { + uint64_t raw; + uint8_t type[8]; +} mtrr_fix_types_t; + +enum var_mtrr_t { + MTRR_PHYS_BASE0_MSR = 0x200, + MTRR_PHYS_MASK0_MSR = 0x201, + MTRR_PHYS_BASE1_MSR = 0x202, + MTRR_PHYS_MASK1_MSR = 0x203, + MTRR_PHYS_BASE2_MSR = 0x204, + MTRR_PHYS_MASK2_MSR = 0x205, + MTRR_PHYS_BASE3_MSR = 0x206, + MTRR_PHYS_MASK3_MSR = 0x207, + MTRR_PHYS_BASE4_MSR = 0x208, + MTRR_PHYS_MASK4_MSR = 0x209, + MTRR_PHYS_BASE5_MSR = 0x20A, + MTRR_PHYS_MASK5_MSR = 0x20B, + MTRR_PHYS_BASE6_MSR = 0x20C, + MTRR_PHYS_MASK6_MSR = 0x20D, + MTRR_PHYS_BASE7_MSR = 0x20E, + MTRR_PHYS_MASK7_MSR = 0x20F +}; + +typedef union { + uint64_t raw; + struct { + uint64_t vcnt : 8; /* num variable MTRR pairs */ + uint64_t fix : 1; /* fixed range MTRRs are supported */ + uint64_t reserved1 : 1; + uint64_t wc : 1; /* write-combining mem type supported */ + uint64_t reserved2 : 53; + } __attribute__((packed)); +} mtrr_cap_t; + +typedef union { + uint64_t raw; + struct { + uint64_t type : 8; + uint64_t reserved1 : 2; + uint64_t fe : 1; /* fixed MTRR enable */ + uint64_t e : 1; /* (all) MTRR enable */ + uint64_t reserved2 : 52; + } __attribute__((packed)); +} mtrr_def_type_t; + +typedef union { + uint64_t raw; + struct { + uint64_t type : 8; + uint64_t reserved1 : 4; + /* TBD: the end of base really depends on MAXPHYADDR, but since */ + /* the MTRRs are set for SINIT and it must be <4GB, can use 24b */ + uint64_t base : 24; + uint64_t reserved2 : 28; + } __attribute__((packed)); +} mtrr_physbase_t; + +typedef union { + uint64_t raw; + struct { + uint64_t reserved1 : 11; + uint64_t v : 1; /* valid */ + /* TBD: the end of mask really depends on MAXPHYADDR, but since */ + /* the MTRRs are set for SINIT and it must be <4GB, can use 24b */ + uint64_t mask : 24; + uint64_t reserved2 : 28; + } __attribute__((packed)); +} mtrr_physmask_t; + +/* current procs only have 8, so this should hold us for a while */ +#define MAX_VARIABLE_MTRRS 16 + +typedef struct { + mtrr_def_type_t mtrr_def_type; + uint64_t num_var_mtrrs; + mtrr_physbase_t mtrr_physbases[MAX_VARIABLE_MTRRS]; + mtrr_physmask_t mtrr_physmasks[MAX_VARIABLE_MTRRS]; +} __attribute__((packed)) mtrr_state_t; + +extern bool set_mtrrs_for_acmod(acm_hdr_t *hdr); +extern void print_mtrrs(const mtrr_state_t *saved_state); +extern void save_mtrrs(mtrr_state_t *saved_state); +extern void set_all_mtrrs(bool enable); +extern bool set_mem_type(void *base, uint32_t size, uint32_t mem_type); +extern void restore_mtrrs(mtrr_state_t *saved_state); +extern bool validate_mtrrs(const mtrr_state_t *saved_state); + +#endif /*__TXT_MTRRS_H__ */ + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt_smx.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt_smx.h new file mode 100644 index 0000000000..f3237c1141 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_txt_smx.h @@ -0,0 +1,220 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * smx.h: Intel(r) TXT SMX architecture-related definitions + * + * Copyright (c) 2003-2008, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * Modified for XMHF by jonmccune@cmu.edu, 2011.01.04 + */ + + +#ifndef __TXT_SMX_H__ +#define __TXT_SMX_H__ + +/* + * GETSEC[] instructions + */ + +/* GETSEC instruction opcode */ +#define IA32_GETSEC_OPCODE ".byte 0x0f,0x37" + +/* GETSEC leaf function codes */ +#define IA32_GETSEC_CAPABILITIES 0 +#define IA32_GETSEC_SENTER 4 +#define IA32_GETSEC_SEXIT 5 +#define IA32_GETSEC_PARAMETERS 6 +#define IA32_GETSEC_SMCTRL 7 +#define IA32_GETSEC_WAKEUP 8 + +/* + * GETSEC[] leaf functions + */ + +typedef union { + uint32_t _raw; + struct { + uint32_t chipset_present : 1; + uint32_t undefined1 : 1; + uint32_t enteraccs : 1; + uint32_t exitac : 1; + uint32_t senter : 1; + uint32_t sexit : 1; + uint32_t parameters : 1; + uint32_t smctrl : 1; + uint32_t wakeup : 1; + uint32_t undefined9 : 22; + uint32_t extended_leafs : 1; + }; +} capabilities_t; + +static inline uint32_t __getsec_capabilities(uint32_t index) +{ + uint32_t cap; + __asm__ __volatile__ (IA32_GETSEC_OPCODE "\n" + : "=a"(cap) + : "a"(IA32_GETSEC_CAPABILITIES), "b"(index)); + return cap; +} + +/* helper fn. for getsec_capabilities */ +/* this is arbitrary and can be increased when needed */ +#define MAX_SUPPORTED_ACM_VERSIONS 16 + +typedef struct { + struct { + uint32_t mask; + uint32_t version; + } acm_versions[MAX_SUPPORTED_ACM_VERSIONS]; + int n_versions; + uint32_t acm_max_size; + uint32_t acm_mem_types; + uint32_t senter_controls; + bool proc_based_scrtm; + bool preserve_mce; +} getsec_parameters_t; + +///extern bool get_parameters(getsec_parameters_t *params); + + +static inline void __getsec_senter(uint32_t sinit_base, uint32_t sinit_size) +{ + __asm__ __volatile__ (IA32_GETSEC_OPCODE "\n" + : + : "a"(IA32_GETSEC_SENTER), + "b"(sinit_base), + "c"(sinit_size), + "d"(0x0)); +} + +static inline void __getsec_sexit(void) +{ + __asm__ __volatile__ (IA32_GETSEC_OPCODE "\n" + : : "a"(IA32_GETSEC_SEXIT)); +} + +static inline void __getsec_wakeup(void) +{ + __asm__ __volatile__ (IA32_GETSEC_OPCODE "\n" + : : "a"(IA32_GETSEC_WAKEUP)); +} + +static inline void __getsec_smctrl(void) +{ + __asm__ __volatile__ (IA32_GETSEC_OPCODE "\n" + : : "a"(IA32_GETSEC_SMCTRL), "b"(0x0)); +} + +static inline void __getsec_parameters(uint32_t index, int* param_type, + uint32_t* peax, uint32_t* pebx, + uint32_t* pecx) +{ + uint32_t eax=0, ebx=0, ecx=0; + __asm__ __volatile__ (IA32_GETSEC_OPCODE "\n" + : "=a"(eax), "=b"(ebx), "=c"(ecx) + : "a"(IA32_GETSEC_PARAMETERS), "b"(index)); + + if ( param_type != NULL ) *param_type = eax & 0x1f; + if ( peax != NULL ) *peax = eax; + if ( pebx != NULL ) *pebx = ebx; + if ( pecx != NULL ) *pecx = ecx; +} + +static inline bool txt_is_launched(void) +{ + txt_sts_t sts; + + sts._raw = read_pub_config_reg(TXTCR_STS); + + return sts.senter_done_sts; +} + +bool txt_prepare_cpu(void); +tb_error_t txt_launch_environment(void *sinit_ptr, size_t sinit_size, + void *phys_mle_start, size_t mle_size); +#endif /* __TXT_SMX_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_vmx.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_vmx.h new file mode 100644 index 0000000000..010bb39009 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_vmx.h @@ -0,0 +1,825 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +//vmx.h - Intel VMX definitions +//author: amit vasudevan (amitvasudevan@acm.org) + +#define VMXON_SIZE (4096) +#define VMCS_SIZE (8192) + +//VM Exit Interruption-information format +#define INTR_INFO_VECTOR_MASK (0x000000ff) // 7:0 +#define INTR_INFO_INTR_TYPE_MASK (0x00000700) // 10:8 +#define INTR_INFO_DELIVER_CODE_MASK (0x00000800) // 11 +#define INTR_INFO_VALID_MASK (0x80000000) // 31 + +#define VECTORING_INFO_VECTOR_MASK INTR_INFO_VECTOR_MASK +#define VECTORING_INFO_TYPE_MASK INTR_INFO_INTR_TYPE_MASK +#define VECTORING_INFO_DELIVER_CODE_MASK INTR_INFO_DELIVER_CODE_MASK +#define VECTORING_INFO_VALID_MASK INTR_INFO_VALID_MASK + +#define INTR_TYPE_HW_INTERRUPT (0UL << 8) // hardware/external interrupt +#define INTR_TYPE_NMI (2UL << 8) // NMI +#define INTR_TYPE_HW_EXCEPTION (3UL << 8) // processor exception +#define INTR_TYPE_SW_INTERRUPT (4UL << 8) // software interrupt +#define INTR_TYPE_SW_EXCEPTION (6UL << 8) // software exception (INTO, INT3) + +// +#define VMX_EVENT_CANCEL (0) +#define VMX_EVENT_INJECT (1) + +// +#define DF_VECTOR 8 +#define INT1_VECTOR 0x1 +#define NMI_VECTOR 0x2 +#define INT3_VECTOR 0x3 +#define GP_VECTOR 13 +#define PF_VECTOR 14 + +#define INTERCEPT_EXCEPTIONS_00 (0x00) +#define INTERCEPT_EXCEPTIONS_01 (0x01) +#define INTERCEPT_EXCEPTIONS_02 (0x02) +#define INTERCEPT_EXCEPTIONS_03 (0x03) +#define INTERCEPT_EXCEPTIONS_04 (0x04) +#define INTERCEPT_EXCEPTIONS_05 (0x05) +#define INTERCEPT_EXCEPTIONS_06 (0x06) +#define INTERCEPT_EXCEPTIONS_07 (0x07) +#define INTERCEPT_EXCEPTIONS_08 (0x08) +#define INTERCEPT_EXCEPTIONS_09 (0x09) +#define INTERCEPT_EXCEPTIONS_0A (0x0A) +#define INTERCEPT_EXCEPTIONS_0B (0x0B) +#define INTERCEPT_EXCEPTIONS_0C (0x0C) +#define INTERCEPT_EXCEPTIONS_0D (0x0D) +#define INTERCEPT_EXCEPTIONS_0E (0x0E) +#define INTERCEPT_EXCEPTIONS_0F (0x0F) +#define INTERCEPT_EXCEPTIONS_10 (0x10) +#define INTERCEPT_EXCEPTIONS_11 (0x11) +#define INTERCEPT_EXCEPTIONS_12 (0x12) +#define INTERCEPT_EXCEPTIONS_13 (0x13) +#define INTERCEPT_EXCEPTIONS_14 (0x14) +#define INTERCEPT_EXCEPTIONS_15 (0x15) +#define INTERCEPT_EXCEPTIONS_16 (0x16) +#define INTERCEPT_EXCEPTIONS_17 (0x17) +#define INTERCEPT_EXCEPTIONS_18 (0x18) +#define INTERCEPT_EXCEPTIONS_19 (0x19) +#define INTERCEPT_EXCEPTIONS_1A (0x1A) +#define INTERCEPT_EXCEPTIONS_1B (0x1B) +#define INTERCEPT_EXCEPTIONS_1C (0x1C) +#define INTERCEPT_EXCEPTIONS_1D (0x1D) +#define INTERCEPT_EXCEPTIONS_1E (0x1E) +#define INTERCEPT_EXCEPTIONS_1F (0x1F) +#define INTERCEPT_EXCEPTIONS_20 (0x20) + + +#define INTERCEPT_INVLPG 0x21 +#define INTERCEPT_CR3_READ 0x22 +#define INTERCEPT_CR3_WRITE 0x23 +#define INTERCEPT_CR0_SEL_WRITE 0x24 +#define INTERCEPT_CR4_WRITE 0x25 +#define INTERCEPT_MSR 0x26 +#define INTERCEPT_IOIO 0x27 +#define INTERCEPT_VMMCALL 0x28 +#define INTERCEPT_EXCEPTIONS 0x29 + +#define VMX_VMEXIT_EXCEPTION 0 +#define VMX_VMEXIT_INVLPG 14 +#define VMX_VMEXIT_NMI_WINDOW 8 +#define VMX_VMEXIT_MONITOR_TRAP 37 + +#define VMX_VMEXIT_CRX_ACCESS 0x1C + +#define VMX_CRX_ACCESS_FROM 0x1 +#define VMX_CRX_ACCESS_TO 0x0 + +#define VMX_VMEXIT_CR3_READ 28 +#define VMX_VMEXIT_CR3_WRITE 28 +#define VMX_VMEXIT_CR0_SEL_WRITE 28 +#define VMX_VMEXIT_CR4_WRITE 28 +#define VMX_VMEXIT_CRX_READWRITE 28 +#define VMX_VMEXIT_MSR_READ 31 +#define VMX_VMEXIT_MSR_WRITE 32 +#define VMX_VMEXIT_IOIO 30 +#define VMX_VMEXIT_VMCALL 18 +#define VMX_VMEXIT_HLT 12 +#define VMX_VMEXIT_INVLPG 14 +#define VMX_VMEXIT_RDMSR 0x1f +#define VMX_VMEXIT_WRMSR 0x20 +#define VMX_VMEXIT_CPUID 0x0a +#define VMX_VMEXIT_INIT 0x3 +#define VMX_VMEXIT_EPT_VIOLATION 0x30 +#define VMX_VMEXIT_TASKSWITCH 0x9 +#define VMX_VMEXIT_WBINVD 54 +#define VMX_VMEXIT_XSETBV 55 + +#define VMX_VMEXIT_EPT_VIOLATON 48 +#define VMX_VMEXIT_EPT_MISCONFIGURATION 49 + +//VMEXIT_IOIO defines +#define IO_SIZE_BYTE 0x0 +#define IO_SIZE_WORD 0x1 +#define IO_SIZE_DWORD 0x3 + +#define IO_TYPE_IN 0x1 +#define IO_TYPE_OUT 0x0 + +#define IO_INSN_STRING 0x1 +#define IO_INSN_NORMAL 0x0 +#define IO_INSN_REP 0x1 +#define IO_INSN_OPCODE_IMM 0x1 + + +#ifndef __ASSEMBLY__ + + +typedef struct { + u32 writable; + u32 encoding; + u32 addressofvariable; +} __attribute__ ((packed)) VMCSENCODINGS; + + +typedef struct { + u32 type: 4; + u32 desctype: 1; //0=system, 1=code or data + u32 dpl: 2; + u32 p: 1; + u32 res1: 4; + u32 avl: 1; + u32 csmode: 1; + u32 s: 1; //0=16-bit segment, 1=32-bit segment + u32 g: 1; + u32 usable: 1; //0=usable, 1=unusable + u32 res2: 15; +} __attribute__ ((packed)) segment_desc_accessrights; + + +/* cf. IA32_SDM_Vol3B table 24-7 */ +enum EPTViolationCode +{ + EPT_ERRORCODE_READ = 1 << 0, + EPT_ERRORCODE_WRITE = 1 << 1, + EPT_ERRORCODE_EXEC = 1 << 2, + EPT_ERRORCODE_READABLE = 1 << 3, + EPT_ERRORCODE_WRITABLE = 1 << 4, + EPT_ERRORCODE_EXECABLE = 1 << 5, + EPT_ERRORCODE_RESERVED = 1 << 6, + EPT_ERRORCODE_VADDR_VALID = 1 << 7, + EPT_ERRORCODE_TABLEWALK= 1 << 8, +}; +#define EPT_ERRORCODE_PRESENT ((EPT_ERRORCODE_READABLE)+(EPT_ERRORCODE_WRITABLE)+(EPT_ERRORCODE_EXECABLE)) + +#define EPT_PROT_READ (1UL << 0) +#define EPT_PROT_WRITE (1UL << 1) +#define EPT_PROT_EXEC (1UL << 2) + +#define EPT_PML4_SIZE 512 +#define EPT_PDPT_SIZE 512 +#define EPT_PD_SIZE 512 +#define EPT_PT_SIZE 512 + +/* max bits used in physical devices. processor-dependent. */ +#define M 47 + +/* PML4E bit fields */ +#define EPT_PML4E_IGN0_HI 63 +#define EPT_PML4E_IGN0_LO 52 +#define EPT_PML4E_RSVD0_HI 51 +#define EPT_PML4E_RSVD0_LO M +#define EPT_PML4E_PDPT_HI (M-1) +#define EPT_PML4E_PDPT_LO 12 +#define EPT_PML4E_IGN1_HI 11 +#define EPT_PML4E_IGN1_LO 8 +#define EPT_PML4E_RSVD2_HI 7 +#define EPT_PML4E_RSVD2_LO 3 +#define EPT_PML4E_X_HI 2 +#define EPT_PML4E_X_LO 2 +#define EPT_PML4E_W_HI 1 +#define EPT_PML4E_W_LO 1 +#define EPT_PML4E_R_HI 0 +#define EPT_PML4E_R_LO 0 +#define EPT_PML4E_NP_HI 2 /* not-present */ +#define EPT_PML4E_NP_LO 0 + + +/* PDPTE bit fields */ +#define EPT_PDPTE_IGN0_HI 63 +#define EPT_PDPTE_IGN0_LO 52 +#define EPT_PDPTE_RSVD0_HI 51 +#define EPT_PDPTE_RSVD0_LO M +/****** when ISPAGE==0 ********************/ + #define EPT_PDPTE_PD_HI (M-1) + #define EPT_PDPTE_PD_LO 12 +/******* when ISPAGE==1********************/ + #define EPT_PDPTE_PAGE_HI (M-1) + #define EPT_PDPTE_PAGE_LO 30 + #define EPT_PDPTE_RSVD1_HI 29 + #define EPT_PDPTE_RSVD1_LO 12 +/******************************************/ +#define EPT_PDPTE_IGN1_HI 11 +#define EPT_PDPTE_IGN1_LO 8 +#define EPT_PDPTE_ISPAGE_HI 7 +#define EPT_PDPTE_ISPAGE_LO 7 +/****** when ISPAGE==0 ********************/ + #define EPT_PDPTE_RSVD2_HI 6 + #define EPT_PDPTE_RSVD2_LO 3 +/****** when ISPAGE==1 ********************/ + #define EPT_PDPTE_IPAT_HI 6 + #define EPT_PDPTE_IPAT_LO 6 + #define EPT_PDPTE_EPTMT_HI 5 + #define EPT_PDPTE_EPTMT_LO 3 +/******************************************/ +#define EPT_PDPTE_X_HI 2 +#define EPT_PDPTE_X_LO 2 +#define EPT_PDPTE_W_HI 1 +#define EPT_PDPTE_W_LO 1 +#define EPT_PDPTE_R_HI 0 +#define EPT_PDPTE_R_LO 0 +#define EPT_PDPTE_NP_HI 2 /* not-present */ +#define EPT_PDPTE_NP_LO 0 +#define EPT_PDPTE_PROT_HI 2 +#define EPT_PDPTE_PROT_LO 0 + +/* PDE bit fields */ +#define EPT_PDE_IGN0_HI 63 +#define EPT_PDE_IGN0_LO 52 +#define EPT_PDE_RSVD0_HI 51 +#define EPT_PDE_RSVD0_LO M +/****** when ISPAGE==0 ********************/ + #define EPT_PDE_PT_HI (M-1) + #define EPT_PDE_PT_LO 12 +/******* when ISPAGE==1********************/ + #define EPT_PDE_PAGE_HI (M-1) + #define EPT_PDE_PAGE_LO 21 + #define EPT_PDE_RSVD1_HI 20 + #define EPT_PDE_RSVD1_LO 12 +/******************************************/ +#define EPT_PDE_IGN1_HI 11 +#define EPT_PDE_IGN1_LO 8 +#define EPT_PDE_ISPAGE_HI 7 +#define EPT_PDE_ISPAGE_LO 7 +/****** when ISPAGE==0 ********************/ + #define EPT_PDE_RSVD2_HI 6 + #define EPT_PDE_RSVD2_LO 3 +/****** when ISPAGE==1 ********************/ + #define EPT_PDE_IPAT_HI 6 + #define EPT_PDE_IPAT_LO 6 + #define EPT_PDE_EPTMT_HI 5 + #define EPT_PDE_EPTMT_LO 3 +/******************************************/ +#define EPT_PDE_X_HI 2 +#define EPT_PDE_X_LO 2 +#define EPT_PDE_W_HI 1 +#define EPT_PDE_W_LO 1 +#define EPT_PDE_R_HI 0 +#define EPT_PDE_R_LO 0 +#define EPT_PDE_NP_HI 2 /* not-present */ +#define EPT_PDE_NP_LO 0 +#define EPT_PDE_PROT_HI 2 +#define EPT_PDE_PROT_LO 0 + +/* PTE bit fields */ +#define EPT_PTE_IGN0_HI 63 +#define EPT_PTE_IGN0_LO 52 +#define EPT_PTE_RSVD0_HI 51 +#define EPT_PTE_RSVD0_LO M +#define EPT_PTE_PAGE_HI (M-1) +#define EPT_PTE_PAGE_LO 12 +#define EPT_PTE_IGN1_HI 11 +#define EPT_PTE_IGN1_LO 7 +#define EPT_PTE_IPAT_HI 6 +#define EPT_PTE_IPAT_LO 6 +#define EPT_PTE_EPTMT_HI 5 +#define EPT_PTE_EPTMT_LO 3 +#define EPT_PTE_X_HI 2 +#define EPT_PTE_X_LO 2 +#define EPT_PTE_W_HI 1 +#define EPT_PTE_W_LO 1 +#define EPT_PTE_R_HI 0 +#define EPT_PTE_R_LO 0 +#define EPT_PTE_NP_HI 2 /* not-present */ +#define EPT_PTE_NP_LO 0 +#define EPT_PTE_PROT_HI 2 +#define EPT_PTE_PROT_LO 0 + +/* guest physical address */ +#define EPT_GPA_PML4_I_HI 47 +#define EPT_GPA_PML4_I_LO 39 +#define EPT_GPA_PDPT_I_HI 38 +#define EPT_GPA_PDPT_I_LO 30 +#define EPT_GPA_PD_I_HI 29 +#define EPT_GPA_PD_I_LO 21 +#define EPT_GPA_PT_I_HI 20 +#define EPT_GPA_PT_I_LO 12 +#define EPT_GPA_OFFSET_HI 11 +#define EPT_GPA_OFFSET_LO 0 + +enum { + TASK_SWITCH_CALL = 0, + TASK_SWITCH_IRET = 1, + TASK_SWITCH_JMP = 2, + TASK_SWITCH_GATE = 3, +}; + + +typedef struct { + u16 sel; + u64 base; + u32 limit; + union{ + segment_desc_accessrights ar; + u32 aru32; + }; +} __attribute__ ((packed)) segment_desc; + + +typedef struct msr_entry { + u32 index; + u32 reserved; + u64 data; +} __attribute__((packed)) msr_entry_t; + + +typedef struct { + u32 id; + u32 vmxonSize; + u32 physicalAddressWidth; + u32 vmcsMemoryType; + u32 ioCapability; + u64 cr0fixed0; + u64 cr0fixed1; + u64 cr4fixed0; + u64 cr4fixed1; + u64 pinbasedctls; + u64 procbasedctls; + u64 procbasedctls2; +u64 exitctls; +u64 entryctls; +}__attribute__ ((packed)) VMXINFO; + + +//VMX VMCS fields +struct _vmx_vmcsfields { +#if defined(__NESTED_PAGING__) + //16-bit control fields + unsigned int control_vpid; +#endif + // Natural 32-bit Control fields + unsigned int control_VMX_pin_based; + unsigned int control_VMX_cpu_based; +//#if defined(__NESTED_PAGING__) + unsigned int control_VMX_seccpu_based; +//#endif + unsigned int control_exception_bitmap; + unsigned int control_pagefault_errorcode_mask; + unsigned int control_pagefault_errorcode_match; + unsigned int control_CR3_target_count; + unsigned int control_VM_exit_controls; + unsigned int control_VM_exit_MSR_store_count; + unsigned int control_VM_exit_MSR_load_count; + unsigned int control_VM_entry_controls; + unsigned int control_VM_entry_MSR_load_count; + unsigned int control_VM_entry_interruption_information; + unsigned int control_VM_entry_exception_errorcode; + unsigned int control_VM_entry_instruction_length; + unsigned int control_Task_PRivilege_Threshold; + // Natural 64-bit Control fields + unsigned long long control_CR0_mask; + unsigned long long control_CR4_mask; + unsigned long long control_CR0_shadow; + unsigned long long control_CR4_shadow; +#ifndef __DEBUG_QEMU__ + unsigned long long control_CR3_target0; + unsigned long long control_CR3_target1; + unsigned long long control_CR3_target2; + unsigned long long control_CR3_target3; +#endif /* !__DEBUG_QEMU__ */ + // Full 64-bit Control fields + union { + unsigned long long control_IO_BitmapA_address; + struct { + unsigned int control_IO_BitmapA_address_full; + unsigned int control_IO_BitmapA_address_high; + }; + }; + union { + unsigned long long control_IO_BitmapB_address; + struct { + unsigned int control_IO_BitmapB_address_full; + unsigned int control_IO_BitmapB_address_high; + }; + }; + union { + unsigned long long control_MSR_Bitmaps_address; + struct { + unsigned int control_MSR_Bitmaps_address_full; + unsigned int control_MSR_Bitmaps_address_high; + }; + }; + union { + unsigned long long control_VM_exit_MSR_store_address; + struct { + unsigned int control_VM_exit_MSR_store_address_full; + unsigned int control_VM_exit_MSR_store_address_high; + }; + }; + union { + unsigned long long control_VM_exit_MSR_load_address; + struct { + unsigned int control_VM_exit_MSR_load_address_full; + unsigned int control_VM_exit_MSR_load_address_high; + }; + }; + union { + unsigned long long control_VM_entry_MSR_load_address; + struct { + unsigned int control_VM_entry_MSR_load_address_full; + unsigned int control_VM_entry_MSR_load_address_high; + }; + }; +#ifndef __DEBUG_QEMU__ + union { + unsigned long long control_Executive_VMCS_pointer; + struct { + unsigned int control_Executive_VMCS_pointer_full; + unsigned int control_Executive_VMCS_pointer_high; + }; + }; +#endif /* !__DEBUG_QEMU__ */ + union { + unsigned long long control_TSC_offset; + struct { + unsigned int control_TSC_offset_full; + unsigned int control_TSC_offset_high; + }; + }; + union { + unsigned long long control_virtual_APIC_page_address; + struct { + unsigned int control_virtual_APIC_page_address_full; + unsigned int control_virtual_APIC_page_address_high; + }; + }; +#if defined(__NESTED_PAGING__) + union { + unsigned long long control_EPT_pointer; + struct { + unsigned int control_EPT_pointer_full; + unsigned int control_EPT_pointer_high; + }; + }; +#endif + // Natural 64-bit Host-State fields + unsigned long long host_CR0; + unsigned long long host_CR3; + unsigned long long host_CR4; + unsigned long long host_FS_base; + unsigned long long host_GS_base; + unsigned long long host_TR_base; + unsigned long long host_GDTR_base; + unsigned long long host_IDTR_base; + unsigned long long host_SYSENTER_ESP; + unsigned long long host_SYSENTER_EIP; + unsigned long long host_RSP; + unsigned long long host_RIP; + // Natural 32-bit Host-State fields + unsigned int host_SYSENTER_CS; + // Natural 16-bit Host-State fields + unsigned int host_ES_selector; + unsigned int host_CS_selector; + unsigned int host_SS_selector; + unsigned int host_DS_selector; + unsigned int host_FS_selector; + unsigned int host_GS_selector; + unsigned int host_TR_selector; + // Natural 64-bit Guest-State fields + unsigned long long guest_CR0; + unsigned long long guest_CR3; + unsigned long long guest_CR4; + unsigned long long guest_ES_base; + unsigned long long guest_CS_base; + unsigned long long guest_SS_base; + unsigned long long guest_DS_base; + unsigned long long guest_FS_base; + unsigned long long guest_GS_base; + unsigned long long guest_LDTR_base; + unsigned long long guest_TR_base; + unsigned long long guest_GDTR_base; + unsigned long long guest_IDTR_base; + unsigned long long guest_DR7; + unsigned long long guest_RSP; + unsigned long long guest_RIP; + unsigned long long guest_RFLAGS; + unsigned long long guest_pending_debug_x; + unsigned long long guest_SYSENTER_ESP; + unsigned long long guest_SYSENTER_EIP; + // Natural 32-bit Guest-State fields + unsigned int guest_ES_limit; + unsigned int guest_CS_limit; + unsigned int guest_SS_limit; + unsigned int guest_DS_limit; + unsigned int guest_FS_limit; + unsigned int guest_GS_limit; + unsigned int guest_LDTR_limit; + unsigned int guest_TR_limit; + unsigned int guest_GDTR_limit; + unsigned int guest_IDTR_limit; + unsigned int guest_ES_access_rights; + unsigned int guest_CS_access_rights; + unsigned int guest_SS_access_rights; + unsigned int guest_DS_access_rights; + unsigned int guest_FS_access_rights; + unsigned int guest_GS_access_rights; + unsigned int guest_LDTR_access_rights; + unsigned int guest_TR_access_rights; + unsigned int guest_interruptibility; + unsigned int guest_activity_state; +#ifndef __DEBUG_QEMU__ + unsigned int guest_SMBASE; +#endif /* !__DEBUG_QEMU__ */ + unsigned int guest_SYSENTER_CS; + // Natural 16-bit Guest-State fields + unsigned int guest_ES_selector; + unsigned int guest_CS_selector; + unsigned int guest_SS_selector; + unsigned int guest_DS_selector; + unsigned int guest_FS_selector; + unsigned int guest_GS_selector; + unsigned int guest_LDTR_selector; + unsigned int guest_TR_selector; + // Full 64-bit Guest-State fields + union { + unsigned long long guest_VMCS_link_pointer; + struct { + unsigned int guest_VMCS_link_pointer_full; + unsigned int guest_VMCS_link_pointer_high; + }; + }; + union { + unsigned long long guest_IA32_DEBUGCTL; + struct { + unsigned int guest_IA32_DEBUGCTL_full; + unsigned int guest_IA32_DEBUGCTL_high; + }; + }; +#if defined(__NESTED_PAGING__) + union { + unsigned long long guest_paddr; + struct { + unsigned int guest_paddr_full; + unsigned int guest_paddr_high; + }; + }; + union { + unsigned long long guest_PDPTE0; + struct { + unsigned int guest_PDPTE0_full; + unsigned int guest_PDPTE0_high; + }; + }; + union { + unsigned long long guest_PDPTE1; + struct { + unsigned int guest_PDPTE1_full; + unsigned int guest_PDPTE1_high; + }; + }; + union { + unsigned long long guest_PDPTE2; + struct { + unsigned int guest_PDPTE2_full; + unsigned int guest_PDPTE2_high; + }; + }; + union { + unsigned long long guest_PDPTE3; + struct { + unsigned int guest_PDPTE3_full; + unsigned int guest_PDPTE3_high; + }; + }; +#endif + //Read-Only Fields + unsigned int info_vminstr_error; + unsigned int info_vmexit_reason; + unsigned int info_vmexit_interrupt_information; + unsigned int info_vmexit_interrupt_error_code; + unsigned int info_IDT_vectoring_information; + unsigned int info_IDT_vectoring_error_code; + unsigned int info_vmexit_instruction_length; + unsigned int info_vmx_instruction_information; + unsigned long long info_exit_qualification; +#ifndef __DEBUG_QEMU__ + unsigned long long info_IO_RCX; + unsigned long long info_IO_RSI; + unsigned long long info_IO_RDI; + unsigned long long info_IO_RIP; +#endif /* !__DEBUG_QEMU__ */ + unsigned long long info_guest_linear_address; +} __attribute__((packed)); + + +struct _vmx_vmcsrofields_encodings { + unsigned int encoding; + unsigned int fieldoffset; + unsigned int membersize; +} __attribute__((packed)); + +struct _vmx_vmcsrwfields_encodings { + unsigned int encoding; + unsigned int fieldoffset; + unsigned int membersize; +} __attribute__((packed)); + +/* VM-Entry Interruption-Information Field */ +struct _vmx_event_injection { + u32 vector: 8; + u32 type: 3; + u32 errorcode: 1; + u32 reserved: 19; + u32 valid: 1; +} __attribute__ ((packed)); + +//VMX functions +static inline void __vmx_vmxon(u64 vmxonRegion){ + __asm__("vmxon %0\n\t" + : //no outputs + : "m"(vmxonRegion) + : "cc"); +} + +static inline u32 __vmx_vmwrite(unsigned long encoding, unsigned long value){ + u32 status; + __asm__("vmwrite %2, %1 \r\n" + "jbe 1f \r\n" + "movl $1, %0 \r\n" + "jmp 2f \r\n" + "1: movl $0, %0 \r\n" + "2: \r\n" + : "=g"(status) + : "r"(encoding), "g"(value) + : "cc" + ); + return status; +} + +static inline u32 __vmx_vmread(unsigned long encoding, unsigned long *value){ + u32 status; + __asm__ __volatile__("vmread %2, %0 \r\n" + "jbe 1f \r\n" + "movl $1, %1 \r\n" + "jmp 2f \r\n" + "1: movl $0, %1 \r\n" + "2: \r\n" + : "=g"(*value), "=g"(status) + : "r"(encoding) + : "cc"); + return status; +} + +static inline u32 __vmx_vmclear(u64 vmcs){ + u32 status; + __asm__("vmclear %1 \r\n" + "jbe 1f \r\n" + "movl $1, %%eax \r\n" + "jmp 2f \r\n" + "1: movl $0, %%eax \r\n" + "2: movl %%eax, %0 \r\n" + : "=m" (status) + : "m"(vmcs) + : "%eax", "cc" + ); + return status; +} + +static inline u32 __vmx_vmptrld(u64 vmcs){ + u32 status; + __asm__("vmptrld %1 \r\n" + "jbe 1f \r\n" + "movl $1, %%eax \r\n" + "jmp 2f \r\n" + "1: movl $0, %%eax \r\n" + "2: movl %%eax, %0 \r\n" + : "=m" (status) + : "m"(vmcs) + : "%eax", "cc" + ); + return status; +} + +// VMX instruction INVVPID +// Invalidate Translations Based on VPID +// INVVPID r32, m128 +//returns 1 on success, 0 on failure + +#define VMX_INVVPID_INDIVIDUALADDRESS 0 +#define VMX_INVVPID_SINGLECONTEXT 1 +#define VMX_INVVPID_ALLCONTEXTS 2 +#define VMX_INVVPID_SINGLECONTEXTGLOBAL 3 + +static inline u32 __vmx_invvpid(int invalidation_type, u16 vpid, u32 linearaddress){ + //return status (1 or 0) + u32 status; + + //invvpid descriptor + struct { + u64 vpid : 16; + u64 reserved : 48; + u64 linearaddress; + } invvpiddescriptor = { vpid, 0, linearaddress }; + + //issue invvpid instruction + //note: GCC does not seem to support this instruction directly + //so we encode it as hex + __asm__(".byte 0x66, 0x0f, 0x38, 0x81, 0x08 \r\n" + "movl $1, %%eax \r\n" + "ja 1f \r\n" + "movl $0, %%eax \r\n" + "1: movl %%eax, %0 \r\n" + : "=m" (status) + : "a"(&invvpiddescriptor), "c"(invalidation_type) + : "cc", "memory"); + + return status; +} + + +// VMX instruction INVEPT +// Invalidate Translations Derived from EPT +// INVEPT r32, m128 +//returns 1 on success, 0 on failure + +#define VMX_INVEPT_SINGLECONTEXT 1 +#define VMX_INVEPT_GLOBAL 2 + +static inline u32 __vmx_invept(int invalidation_type, u64 eptp){ + //return status (1 or 0) + u32 status; + + //invvpid descriptor + struct { + u64 eptp; + u64 reserved; + } inveptdescriptor = { eptp, 0}; + + //issue invept instruction + //note: GCC does not seem to support this instruction directly + //so we encode it as hex + __asm__(".byte 0x66, 0x0f, 0x38, 0x80, 0x08 \r\n" + "movl $1, %%eax \r\n" + "ja 1f \r\n" + "movl $0, %%eax \r\n" + "1: movl %%eax, %0 \r\n" + : "=m" (status) + : "a"(&inveptdescriptor), "c"(invalidation_type) + : "cc", "memory"); + + return status; +} + + + + +#endif diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_vmx_eap.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_vmx_eap.h new file mode 100644 index 0000000000..6bd25e845b --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/_vmx_eap.h @@ -0,0 +1,313 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +//vmx_eap.h - VMX VT-d (External Access Protection) declarations/definitions +//author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __VMX_EAP_H__ +#define __VMX_EAP_H__ + +#define VTD_DMAR_SIGNATURE (0x52414D44) //"DMAR" +#define VTD_MAX_DRHD 8 //maximum number of DMAR h/w units + +//VT-d register offsets (sec. 10.4, Intel_VT_for_Direct_IO) +#define VTD_VER_REG_OFF 0x000 //arch. version (32-bit) +#define VTD_CAP_REG_OFF 0x008 //h/w capabilities (64-bit) +#define VTD_ECAP_REG_OFF 0x010 //h/w extended capabilities (64-bit) +#define VTD_GCMD_REG_OFF 0x018 //global command (32-bit) +#define VTD_GSTS_REG_OFF 0x01C //global status (32-bit) +#define VTD_RTADDR_REG_OFF 0x020 //root-entry table address (64-bit) +#define VTD_CCMD_REG_OFF 0x028 //manage context-entry cache (64-bit) +#define VTD_FSTS_REG_OFF 0x034 //report fault/error status (32-bit) +#define VTD_FECTL_REG_OFF 0x038 //interrupt control (32-bit) +#define VTD_PMEN_REG_OFF 0x064 //enable DMA protected memory regions (32-bits) +#define VTD_IVA_REG_OFF 0x0DEAD //invalidate address register (64-bits) + //note: the offset of this register is computed + //at runtime for a specified DMAR device +#define VTD_IOTLB_REG_OFF 0x0BEEF //IOTLB invalidate register (64-bits) + //note: the offset is VTD_IVA_REG_OFF + 8 and + //computed at runtime for a specified DMAR device + + +//VT-d register access types (custom definitions) +#define VTD_REG_READ 0xaa //read VTD register +#define VTD_REG_WRITE 0xbb //write VTD register + +//Vt-d register access widths (custom definitions) +#define VTD_REG_32BITS 0x32ff +#define VTD_REG_64BITS 0x64ff + +//Vt-d page-table bits +#define VTD_READ 0x1 +#define VTD_WRITE 0x2 +#define VTD_SUPERPAGE (0x1UL << 7) + + +#ifndef __ASSEMBLY__ + +//Vt-d DMAR structure +typedef struct{ + u32 signature; + u32 length; + u8 revision; + u8 checksum; + u8 oemid[6]; + u64 oemtableid; + u32 oemrevision; + u32 creatorid; + u32 creatorrevision; + u8 hostaddresswidth; + u8 flags; + u8 rsvdz[10]; +}__attribute__ ((packed)) VTD_DMAR; + +//VT-d DRHD structure +typedef struct{ + u16 type; + u16 length; + u8 flags; + u8 rsvdz0; + u16 pcisegment; + u64 regbaseaddr; +}__attribute__ ((packed)) VTD_DRHD; + + +//------------------------------------------------------------------------------ +//VT-d register structure definitions + +//VTD_VER_REG (sec. 10.4.1) +typedef union { + u32 value; + struct + { + u32 min : 4; //minor version no. + u32 max : 4; //major version no. + u32 rsvdz : 24; //reserved + } bits; +} __attribute__ ((packed)) VTD_VER_REG; + +//VTD_CAP_REG (sec. 10.4.2) +typedef union { + u64 value; + struct + { + u32 nd : 3; //no. of domains + u32 afl : 1; //advanced fault logging + u32 rwbf : 1; //required write-buffer flushing + u32 plmr : 1; //protected low-memory region + u32 phmr : 1; //protected high-memory region + u32 cm : 1; //caching mode + u32 sagaw: 5; //supported adjuested guest address widths + u32 rsvdz0: 3; //reserved + u32 mgaw : 6; //maximum guest address width + u32 zlr: 1; //zero length read + u32 isoch: 1; //isochrony + u32 fro : 10; //fault-recording register offset + u32 sps : 4; //super-page support + u32 rsvdz1: 1; //reserved + u32 psi: 1; //page selective invalidation + u32 nfr: 8; //no. of fault-recording registers + u32 mamv: 6; //max. address mask value + u32 dwd: 1; //DMA write draining + u32 drd: 1; //DMA read draining + u32 rsvdz2: 8; //reserved + } bits; +} __attribute__ ((packed)) VTD_CAP_REG; + +//VTD_ECAP_REG (sec. 10.4.3) +typedef union { + u64 value; + struct + { + u32 c:1; //coherency + u32 qi:1; //queued invalidation support + u32 di:1; //device IOTLB support + u32 ir:1; //interrupt remapping support + u32 eim:1; //extended interrupt mode + u32 ch:1; //caching hints + u32 pt:1; //pass through + u32 sc:1; //snoop control + u32 iro:10; //IOTLB register offset + u32 rsvdz0: 2; //reserved + u32 mhmv: 4; //maximum handle mask value + u64 rsvdz1: 40; //reserved + } bits; +} __attribute__ ((packed)) VTD_ECAP_REG; + +//VTD_GCMD_REG (sec. 10.4.4) +typedef union { + u32 value; + struct + { + u32 rsvdz0: 23; //reserved + u32 cfi: 1; //compatibility format interrupt + u32 sirtp: 1; //set interrupt remap table pointer + u32 ire:1; //interrupt remapping enable + u32 qie:1; //queued invalidation enable + u32 wbf:1; //write buffer flush + u32 eafl:1; //enable advanced fault logging + u32 sfl:1; //set fault log + u32 srtp:1; //set root table pointer + u32 te:1; //translation enable + } bits; +} __attribute__ ((packed)) VTD_GCMD_REG; + +//VTD_GSTS_REG (sec. 10.4.5) +typedef union { + u32 value; + struct + { + u32 rsvdz0: 23; //reserved + u32 cfis:1; //compatibility interrupt format status + u32 irtps:1; //interrupt remapping table pointer status + u32 ires:1; //interrupt remapping enable status + u32 qies:1; //queued invalidation enable status + u32 wbfs:1; //write buffer flush status + u32 afls:1; //advanced fault logging status + u32 fls:1; //fault log status + u32 rtps:1; //root table pointer status + u32 tes:1; //translation enable status + } bits; +} __attribute__ ((packed)) VTD_GSTS_REG; + +//VTD_RTADDR_REG (sec. 10.4.6) +typedef union { + u64 value; + struct + { + u32 rsvdz0: 12; //reserved + u64 rta: 52; //root table address + } bits; +} __attribute__ ((packed)) VTD_RTADDR_REG; + +//VTD_CCMD_REG (sec. 10.4.7) +typedef union { + u64 value; + struct + { + u32 did:16; //domain id + u32 sid:16; //source id + u32 fm:2; //function mask + u32 rsvdz0: 25; //reserved + u32 caig:2; //context invalidation actual granularity + u32 cirg:2; //context invalidation request granularity + u32 icc:1; //invalidate context-cache + } bits; +} __attribute__ ((packed)) VTD_CCMD_REG; + +//VTD_IOTLB_REG (sec. 10.4.8.1) +typedef union { + u64 value; + struct + { + u32 rsvdz0: 32; //reserved + u32 did:16; //domain-id + u32 dw: 1; //drain writes + u32 dr:1; //drain reads + u32 rsvdz1: 7; //reserved + u32 iaig: 3; //IOTLB actual invalidation granularity + u32 iirg: 3; //IOTLB request invalidation granularity + u32 ivt: 1; //invalidate IOTLB + } bits; +} __attribute__ ((packed)) VTD_IOTLB_REG; + +//VTD_IVA_REG (sec. 10.4.8.2) +typedef union { + u64 value; + struct + { + u32 am: 6; //address mask + u32 ih:1; //invalidation hint + u32 rsvdz0: 5; //reserved + u64 addr:52; //address + } bits; +} __attribute__ ((packed)) VTD_IVA_REG; + + +//VTD_FSTS_REG (sec. 10.4.9) +typedef union { + u32 value; + struct + { + u32 pfo:1; //fault overflow + u32 ppf:1; //primary pending fault + u32 afo:1; //advanced fault overflow + u32 apf:1; //advanced pending fault + u32 iqe:1; //invalidation queue error + u32 ice:1; //invalidation completion error + u32 ite:1; //invalidation time-out error + u32 rsvdz0: 1; //reserved + u32 fri:8; //fault record index + u32 rsvdz1: 16; //reserved + } bits; +} __attribute__ ((packed)) VTD_FSTS_REG; + +//VTD_FECTL_REG (sec. 10.4.10) +typedef union { + u32 value; + struct + { + u32 rsvdp0:30; //reserved + u32 ip:1; //interrupt pending + u32 im:1; //interrupt mask + } bits; +} __attribute__ ((packed)) VTD_FECTL_REG; + +//VTD_PMEN_REG (sec. 10.4.16) +typedef union { + u32 value; + struct + { + u32 prs:1; //protected region status + u32 rsvdp:30; //reserved + u32 epm:1; //enable protected memory + } bits; +} __attribute__ ((packed)) VTD_PMEN_REG; + + +#endif //__ASSEMBLY__ + +#endif //__VMX_EAP_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/xmhf-baseplatform-arch-x86.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/xmhf-baseplatform-arch-x86.h new file mode 100644 index 0000000000..e4de8b3da6 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/xmhf-baseplatform-arch-x86.h @@ -0,0 +1,832 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF base platform component +// x86 arch. specific declarations +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __EMHF_BASEPLATFORM_ARCH_X86_H__ +#define __EMHF_BASEPLATFORM_ARCH_X86_H__ + +#include "_configx86.h" //EMHF arch. specific configurable definitions +#include "_multiboot.h" //boot manager (multiboot) +#include "_cmdline.h" //GRUB command line handling functions +#include "_error.h" //error handling and assertions +#include "_processor.h" //CPU +#include "_msr.h" //model specific registers +#include "_paging.h" //MMU +#include "_io.h" //legacy I/O +#include "_apic.h" //APIC +#include "_svm.h" //SVM extensions +#include "_vmx.h" //VMX extensions +#include "_txt.h" //Trusted eXecution Technology (SENTER support) +#include "_pci.h" //PCI bus glue +#include "_acpi.h" //ACPI glue +#include "_svm_eap.h" //SVM DMA protection +#include "_vmx_eap.h" //VMX DMA protection + + +//SMP configuration table signatures on x86 platforms +#define MPFP_SIGNATURE (0x5F504D5FUL) //"_MP_" +#define MPCONFTABLE_SIGNATURE (0x504D4350UL) //"PCMP" + + +#ifndef __ASSEMBLY__ + +typedef struct { + u32 signature; + u32 paddrpointer; + u8 length; + u8 spec_rev; + u8 checksum; + u8 mpfeatureinfo1; + u8 mpfeatureinfo2; + u8 mpfeatureinfo3; + u8 mpfeatureinfo4; + u8 mpfeatureinfo5; +} __attribute__ ((packed)) MPFP; + +typedef struct{ + u32 signature; + u16 length; + u8 spec_rev; + u8 checksum; + u8 oemid[8]; + u8 productid[12]; + u32 oemtableptr; + u16 oemtablesize; + u16 entrycount; + u32 lapicaddr; + u16 exttablelength; + u16 exttablechecksum; +} __attribute__ ((packed)) MPCONFTABLE; + +typedef struct { + u8 entrytype; + u8 lapicid; + u8 lapicver; + u8 cpuflags; + u32 cpusig; + u32 featureflags; + u32 res0; + u32 res1; +} __attribute__ ((packed)) MPENTRYCPU; + +//MTRR memory type structure +struct _memorytype { + u64 startaddr; + u64 endaddr; + u32 type; + u32 invalid; + u32 reserved[6]; +} __attribute__((packed)); +#endif //__ASSEMBLY__ + +//---platform +#define NUM_FIXED_MTRRS 11 +#define MAX_VARIABLE_MTRR_PAIRS 10 + + +//---platform + +#ifndef __ASSEMBLY__ +//---platform +//structure which holds values of guest MTRRs (64-bit) +struct _guestvarmtrrmsrpair { + u64 base; /* IA32_MTRR_PHYSBASEi */ + u64 mask; /* IA32_MTRR_PHYSMASKi */ +}; + +struct _guestmtrrmsrs { + u64 def_type; /* IA32_MTRR_DEF_TYPE */ + u64 fix_mtrrs[NUM_FIXED_MTRRS]; /* IA32_MTRR_FIX*, see fixed_mtrr_prop */ + u32 var_count; /* Number of valid var_mtrrs's */ + struct _guestvarmtrrmsrpair var_mtrrs[MAX_VARIABLE_MTRR_PAIRS]; +}; +#endif //__ASSEMBLY__ + +//---platform +//VMX MSR indices for the vcpu structure +#define INDEX_IA32_VMX_BASIC_MSR 0x0 +#define INDEX_IA32_VMX_PINBASED_CTLS_MSR 0x1 +#define INDEX_IA32_VMX_PROCBASED_CTLS_MSR 0x2 +#define INDEX_IA32_VMX_EXIT_CTLS_MSR 0x3 +#define INDEX_IA32_VMX_ENTRY_CTLS_MSR 0x4 +#define INDEX_IA32_VMX_MISC_MSR 0x5 +#define INDEX_IA32_VMX_CR0_FIXED0_MSR 0x6 +#define INDEX_IA32_VMX_CR0_FIXED1_MSR 0x7 +#define INDEX_IA32_VMX_CR4_FIXED0_MSR 0x8 +#define INDEX_IA32_VMX_CR4_FIXED1_MSR 0x9 +#define INDEX_IA32_VMX_VMCS_ENUM_MSR 0xA +#define INDEX_IA32_VMX_PROCBASED_CTLS2_MSR 0xB + +//---platform +#define IA32_VMX_MSRCOUNT 12 + +#ifndef __ASSEMBLY__ +//the vcpu structure which holds the current state of a core +typedef struct _vcpu { + //common fields +#ifdef __AMD64__ + hva_t rsp; //used to establish stack for the CPU +#elif defined(__I386__) + hva_t esp; //used to establish stack for the CPU +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + hva_t sipi_page_vaddr; //SIPI page of the CPU used for SIPI handling + u32 id; //LAPIC id of the core + u32 idx; //this vcpu's index in the g_vcpubuffers array + u32 sipivector; //SIPI vector + volatile u32 sipireceived; //SIPI received indicator, 1 if yes + //u32 nmiinhvm; //this is 1 if there was a NMI when in HVM, else 0 + u32 cpu_vendor; //Intel or AMD + u32 isbsp; //1 if this core is BSP else 0 + u32 quiesced; //1 if this core is currently quiesced + + //SVM specific fields + hva_t hsave_vaddr_ptr; //VM_HSAVE area of the CPU + //u32 vmcb_vaddr_ptr; //VMCB of the CPU + struct _svm_vmcbfields *vmcb_vaddr_ptr; + //u32 npt_vaddr_ptr; //NPT base of the CPU + hva_t npt_vaddr_ptr; //NPT base of the CPU + hva_t npt_vaddr_pdts; + u32 npt_asid; //NPT ASID for this core + hva_t npt_vaddr_pts; //NPT page-tables for protection manipulation + hva_t svm_vaddr_iobitmap; //virtual address of the I/O Bitmap area + + //VMX specific fields + u64 vmx_msrs[IA32_VMX_MSRCOUNT]; //VMX msr values + u64 vmx_msr_efer; + u64 vmx_msr_efcr; + hva_t vmx_vmxonregion_vaddr; //virtual address of the vmxon region + hva_t vmx_vmcs_vaddr; //virtual address of the VMCS region + + hva_t vmx_vaddr_iobitmap; //virtual address of the I/O Bitmap area + hva_t vmx_vaddr_msr_area_host; //virtual address of the host MSR area + hva_t vmx_vaddr_msr_area_guest; //virtual address of the guest MSR area + hva_t vmx_vaddr_msrbitmaps; //virtual address of the MSR bitmap area + + hva_t vmx_vaddr_ept_pml4_table; //virtual address of EPT PML4 table + hva_t vmx_vaddr_ept_pdp_table; //virtual address of EPT PDP table + hva_t vmx_vaddr_ept_pd_tables; //virtual address of base of EPT PD tables + hva_t vmx_vaddr_ept_p_tables; //virtual address of base of EPT P tables + + + u32 vmx_ept_defaulttype; //default EPT memory type + u32 vmx_ept_mtrr_enable; + u32 vmx_ept_fixmtrr_enable; + u64 vmx_ept_paddrmask; //mask from bit 12 to MAXPHYADDR + //guest MTRR shadow MSRs + struct _guestmtrrmsrs vmx_guestmtrrmsrs; + + u32 vmx_guest_inject_nmi; //asynchronously inject NMI to guest + + //guest state fields + u32 vmx_guest_currentstate; //current operating mode of guest + u32 vmx_guest_nextstate; //next operating mode of guest + u32 vmx_guest_unrestricted; //this is 1 if the CPU VMX implementation supports unrestricted guest execution + struct _vmx_vmcsfields vmcs; //the VMCS fields + +} VCPU; + +#define SIZE_STRUCT_VCPU (sizeof(struct _vcpu)) +#define CPU_VENDOR (g_vcpubuffers[0].cpu_vendor) +#endif //__ASSEMBLY__ + + +//---------------------------------------------------------------------- +//ARCH. BACKENDS +//---------------------------------------------------------------------- +#ifndef __ASSEMBLY__ +//get CPU vendor +u32 xmhf_baseplatform_arch_getcpuvendor(void); + +//initialize CPU state +void xmhf_baseplatform_arch_cpuinitialize(void); + +//initialize SMP +void xmhf_baseplatform_arch_smpinitialize(void); + +//initialize basic platform elements +void xmhf_baseplatform_arch_initialize(void); + +//read 8-bits from absolute physical address +u8 xmhf_baseplatform_arch_flat_readu8(u32 addr); + +//read 32-bits from absolute physical address +u32 xmhf_baseplatform_arch_flat_readu32(u32 addr); + +//read 64-bits from absolute physical address +u64 xmhf_baseplatform_arch_flat_readu64(u32 addr); + +//write 32-bits to absolute physical address +void xmhf_baseplatform_arch_flat_writeu32(u32 addr, u32 val); + +//write 64-bits to absolute physical address +void xmhf_baseplatform_arch_flat_writeu64(u32 addr, u64 val); + +//memory copy from absolute physical address (src) to +//data segment relative address (dest) +void xmhf_baseplatform_arch_flat_copy(u8 *dest, u8 *src, u32 size); + +//reboot platform +void xmhf_baseplatform_arch_reboot(VCPU *vcpu); + +//returns true if CPU has support for XSAVE/XRSTOR +bool xmhf_baseplatform_arch_x86_cpuhasxsavefeature(void); + +#endif //__ASSEMBLY__ + +//---------------------------------------------------------------------- +//x86 ARCH. INTERFACES +//---------------------------------------------------------------------- +#ifdef __AMD64__ +#define __CS 0x0008 //runtime code segment selector +#define __DS 0x0018 //runtime data segment selector +#define __CS32 0x0010 //runtime 32-bit code segment selector +#define __TRSEL 0x0020 //runtime TSS (task) selector +#elif defined(__I386__) +#define __CS 0x0008 //runtime code segment selector +#define __DS 0x0010 //runtime data segment selector +#define __TRSEL 0x0018 //runtime TSS (task) selector +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + + +#ifndef __ASSEMBLY__ + +//x86 GDT descriptor type +typedef struct { + u16 size; + uintptr_t base; +} __attribute__((packed)) arch_x86_gdtdesc_t; + + +//runtime TSS +extern u8 g_runtime_TSS[PAGE_SIZE_4K] __attribute__(( section(".data") )); + +//this is the start of the real-mode AP bootstrap code (bplt-x86-smptrampoline.S) +extern u32 _ap_bootstrap_start[]; + +//this is the end of the real-mode AP bootstrap code (bplt-x86-smptrampoline.S) +extern u32 _ap_bootstrap_end[]; + +//the CR3 value to be loaded by the AP boot-strap code is placed in this +//variable by the runtime before waking up the APs (bplt-x86-smptrampoline.S) +extern u32 _ap_cr3_value; + +//the CR4 value to be loaded by the AP boot-strap code is placed in this +//variable by the runtime before waking up the APs (bplt-x86-smptrampoline.S) +extern u32 _ap_cr4_value; + + + +//return 1 if the calling CPU is the BSP +u32 xmhf_baseplatform_arch_x86_isbsp(void); + +//wake up APs using the LAPIC by sending the INIT-SIPI-SIPI IPI sequence +void xmhf_baseplatform_arch_x86_wakeupAPs(void); + +//generic x86 platform reboot +void xmhf_baseplatform_arch_x86_reboot(void); + +//get the physical address of the root system description pointer (rsdp) +uintptr_t xmhf_baseplatform_arch_x86_acpi_getRSDP(ACPI_RSDP *rsdp); + +//PCI subsystem initialization +void xmhf_baseplatform_arch_x86_pci_initialize(void); + +//does a PCI type-1 write of PCI config space for a given bus, device, +//function and index +void xmhf_baseplatform_arch_x86_pci_type1_write(u32 bus, u32 device, u32 function, u32 index, u32 len, + u32 value); + +//does a PCI type-1 read of PCI config space for a given bus, device, +//function and index +void xmhf_baseplatform_arch_x86_pci_type1_read(u32 bus, u32 device, u32 function, u32 index, u32 len, + u32 *value); + +//microsecond delay +void xmhf_baseplatform_arch_x86_udelay(u32 usecs); + + +static inline u64 VCPU_gdtr_base(VCPU *vcpu) +{ + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + return ((struct _vmx_vmcsfields*)&(vcpu->vmcs))->guest_GDTR_base; + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + return ((struct _svm_vmcbfields*)vcpu->vmcb_vaddr_ptr)->gdtr.base; + } else { + HALT_ON_ERRORCOND(false); + return 0; + } +} + +static inline size_t VCPU_gdtr_limit(VCPU *vcpu) +{ + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + return ((struct _vmx_vmcsfields*)&(vcpu->vmcs))->guest_GDTR_limit; + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + return ((struct _svm_vmcbfields*)vcpu->vmcb_vaddr_ptr)->gdtr.limit; + } else { + HALT_ON_ERRORCOND(false); + return 0; + } +} + +static inline u64 VCPU_grflags(VCPU *vcpu) +{ + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + return ((struct _vmx_vmcsfields*)&(vcpu->vmcs))->guest_RFLAGS; + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + return ((struct _svm_vmcbfields*)vcpu->vmcb_vaddr_ptr)->rflags; + } else { + HALT_ON_ERRORCOND(false); + return 0; + } +} + +static inline void VCPU_grflags_set(VCPU *vcpu, u64 val) +{ + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + ((struct _vmx_vmcsfields*)&(vcpu->vmcs))->guest_RFLAGS = val; + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + ((struct _svm_vmcbfields*)vcpu->vmcb_vaddr_ptr)->rflags = val; + } else { + HALT_ON_ERRORCOND(false); + } +} + +static inline u64 VCPU_grip(VCPU *vcpu) +{ + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + return ((struct _vmx_vmcsfields*)&(vcpu->vmcs))->guest_RIP; + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + return ((struct _svm_vmcbfields*)vcpu->vmcb_vaddr_ptr)->rip; + } else { + HALT_ON_ERRORCOND(false); + return 0; + } +} + +static inline void VCPU_grip_set(VCPU *vcpu, u64 val) +{ + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + ((struct _vmx_vmcsfields*)&(vcpu->vmcs))->guest_RIP = val; + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + ((struct _svm_vmcbfields*)vcpu->vmcb_vaddr_ptr)->rip = val; + } else { + HALT_ON_ERRORCOND(false); + } +} + +static inline u64 VCPU_grsp(VCPU *vcpu) +{ + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + return ((struct _vmx_vmcsfields*)&(vcpu->vmcs))->guest_RSP; + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + return ((struct _svm_vmcbfields*)vcpu->vmcb_vaddr_ptr)->rsp; + } else { + HALT_ON_ERRORCOND(false); + return 0; + } +} + +static inline void VCPU_grsp_set(VCPU *vcpu, u64 val) +{ + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + ((struct _vmx_vmcsfields*)&(vcpu->vmcs))->guest_RSP = val; + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + ((struct _svm_vmcbfields*)vcpu->vmcb_vaddr_ptr)->rsp = val; + } else { + HALT_ON_ERRORCOND(false); + } +} + +static inline u64 VCPU_gcr0(VCPU *vcpu) +{ + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + return vcpu->vmcs.guest_CR0; + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + return ((struct _svm_vmcbfields*)vcpu->vmcb_vaddr_ptr)->cr0; + } else { + HALT_ON_ERRORCOND(false); + return 0; + } +} + +static inline void VCPU_gcr0_set(VCPU *vcpu, u64 cr0) +{ + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + vcpu->vmcs.guest_CR0 = cr0; + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + ((struct _svm_vmcbfields*)vcpu->vmcb_vaddr_ptr)->cr0 = cr0; + } else { + HALT_ON_ERRORCOND(false); + } +} + +static inline u64 VCPU_gcr3(VCPU *vcpu) +{ + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + return vcpu->vmcs.guest_CR3; + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + return ((struct _svm_vmcbfields*)vcpu->vmcb_vaddr_ptr)->cr3; + } else { + HALT_ON_ERRORCOND(false); + return 0; + } +} + +static inline void VCPU_gcr3_set(VCPU *vcpu, u64 cr3) +{ + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + vcpu->vmcs.guest_CR3 = cr3; + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + ((struct _svm_vmcbfields*)vcpu->vmcb_vaddr_ptr)->cr3 = cr3; + } else { + HALT_ON_ERRORCOND(false); + } +} + +static inline u64 VCPU_gcr4(VCPU *vcpu) +{ + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + return vcpu->vmcs.guest_CR4; + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + return ((struct _svm_vmcbfields*)vcpu->vmcb_vaddr_ptr)->cr4; + } else { + HALT_ON_ERRORCOND(false); + return 0; + } +} + +static inline void VCPU_gcr4_set(VCPU *vcpu, u64 cr4) +{ + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + vcpu->vmcs.guest_CR4 = cr4; + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + ((struct _svm_vmcbfields*)vcpu->vmcb_vaddr_ptr)->cr4 = cr4; + } else { + HALT_ON_ERRORCOND(false); + } +} + +/* Return whether guest blocks NMI (return 1 or 0) */ +static inline int VCPU_gnmiblock(VCPU *vcpu) +{ + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + return (vcpu->vmcs.guest_interruptibility >> 3) & 1U; + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + /* Not implemented */ + HALT_ON_ERRORCOND(false); + return 0; + } else { + HALT_ON_ERRORCOND(false); + return 0; + } +} + +/* Set whether guest blocks NMI, block is treated as boolean value */ +static inline void VCPU_gnmiblock_set(VCPU *vcpu, int block) +{ + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + if (block) { + vcpu->vmcs.guest_interruptibility |= (1U << 3); + } else { + vcpu->vmcs.guest_interruptibility &= ~(1U << 3); + } + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + /* Not implemented */ + HALT_ON_ERRORCOND(false); + } else { + HALT_ON_ERRORCOND(false); + } +} + +/* Return whether guest OS is in long mode (return 1 or 0) */ +static inline u32 VCPU_glm(VCPU *vcpu) { + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + return (vcpu->vmcs.control_VM_entry_controls >> 9) & 1U; + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + /* Not implemented */ + HALT_ON_ERRORCOND(false); + return 0; + } else { + HALT_ON_ERRORCOND(false); + return 0; + } +} + +/* + * Return whether guest application is in 64-bit mode (return 1 or 0). + * If guest OS is in long mode, return 1 if guest application in 64-bit mode. + * If guest OS in legacy mode (e.g. protected mode), will always return 0; + */ +static inline u32 VCPU_g64(VCPU *vcpu) { + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + return (vcpu->vmcs.guest_CS_access_rights >> 13) & 1U; + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + /* Not implemented */ + HALT_ON_ERRORCOND(false); + return 0; + } else { + HALT_ON_ERRORCOND(false); + return 0; + } +} + +/* + * Update vcpu->vmcs.guest_PDPTE{0..3} for PAE guests. This is needed + * after guest CR3 is changed. + */ +static inline void VCPU_gpdpte_set(VCPU *vcpu, u64 pdptes[4]) { + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + vcpu->vmcs.guest_PDPTE0 = pdptes[0]; + vcpu->vmcs.guest_PDPTE1 = pdptes[1]; + vcpu->vmcs.guest_PDPTE2 = pdptes[2]; + vcpu->vmcs.guest_PDPTE3 = pdptes[3]; + } else if (vcpu->cpu_vendor == CPU_VENDOR_AMD) { + /* Not implemented */ + HALT_ON_ERRORCOND(false); + } else { + HALT_ON_ERRORCOND(false); + } +} + +/* + * Selector for VCPU_reg_get and VCPU_reg_set + */ +enum CPU_Reg_Sel +{ + CPU_REG_AX, + CPU_REG_BX, + CPU_REG_CX, + CPU_REG_DX, + CPU_REG_SI, + CPU_REG_DI, + CPU_REG_SP, + CPU_REG_BP, + +#ifdef __AMD64__ + CPU_REG_R8, + CPU_REG_R9, + CPU_REG_R10, + CPU_REG_R11, + CPU_REG_R12, + CPU_REG_R13, + CPU_REG_R14, + CPU_REG_R15, +#elif !defined(__I386__) + #error "Unsupported Arch" +#endif /* !defined(__I386__) */ + + CPU_REG_FLAGS, + CPU_REG_IP +}; + +/* + * Get a guest register + */ +static inline ulong_t VCPU_reg_get(VCPU *vcpu, struct regs* r, + enum CPU_Reg_Sel sel) +{ + switch (sel) + { +#ifdef __AMD64__ + case CPU_REG_AX: return r->rax; + case CPU_REG_BX: return r->rbx; + case CPU_REG_CX: return r->rcx; + case CPU_REG_DX: return r->rdx; + case CPU_REG_SI: return r->rsi; + case CPU_REG_DI: return r->rdi; + case CPU_REG_BP: return r->rbp; + + case CPU_REG_R8: return r->r8; + case CPU_REG_R9: return r->r9; + case CPU_REG_R10: return r->r10; + case CPU_REG_R11: return r->r11; + case CPU_REG_R12: return r->r12; + case CPU_REG_R13: return r->r13; + case CPU_REG_R14: return r->r14; + case CPU_REG_R15: return r->r15; +#elif defined(__I386__) + case CPU_REG_AX: return r->eax; + case CPU_REG_BX: return r->ebx; + case CPU_REG_CX: return r->ecx; + case CPU_REG_DX: return r->edx; + case CPU_REG_SI: return r->esi; + case CPU_REG_DI: return r->edi; + case CPU_REG_BP: return r->ebp; +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + + case CPU_REG_SP: return VCPU_grsp(vcpu); + case CPU_REG_FLAGS: return VCPU_grflags(vcpu); + case CPU_REG_IP: return VCPU_grip(vcpu); + + default: + printf("VCPU_reg_get: Invalid guest CPU register is given (sel:%u)!\n", sel); + HALT(); + return 0; // should never hit + } +} + +/* + * Set a guest register + */ +static inline void VCPU_reg_set(VCPU *vcpu, struct regs* r, + enum CPU_Reg_Sel sel, ulong_t val) +{ + switch (sel) + { +#ifdef __AMD64__ + case CPU_REG_AX: r->rax = val; break; + case CPU_REG_BX: r->rbx = val; break; + case CPU_REG_CX: r->rcx = val; break; + case CPU_REG_DX: r->rdx = val; break; + case CPU_REG_SI: r->rsi = val; break; + case CPU_REG_DI: r->rdi = val; break; + case CPU_REG_BP: r->rbp = val; break; + + case CPU_REG_R8: r->r8 = val; break; + case CPU_REG_R9: r->r9 = val; break; + case CPU_REG_R10: r->r10 = val; break; + case CPU_REG_R11: r->r11 = val; break; + case CPU_REG_R12: r->r12 = val; break; + case CPU_REG_R13: r->r13 = val; break; + case CPU_REG_R14: r->r14 = val; break; + case CPU_REG_R15: r->r15 = val; break; +#elif defined(__I386__) + case CPU_REG_AX: r->eax = val; break; + case CPU_REG_BX: r->ebx = val; break; + case CPU_REG_CX: r->ecx = val; break; + case CPU_REG_DX: r->edx = val; break; + case CPU_REG_SI: r->esi = val; break; + case CPU_REG_DI: r->edi = val; break; + case CPU_REG_BP: r->ebp = val; break; +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + + case CPU_REG_SP: + VCPU_grsp_set(vcpu, val); + break; + case CPU_REG_FLAGS: + VCPU_grflags_set(vcpu, val); + break; + case CPU_REG_IP: + VCPU_grip_set(vcpu, val); + break; + + default: + printf("VCPU_reg_set: Invalid guest CPU register is given (sel:%u)!\n", sel); + HALT(); + } +} + +//---------------------------------------------------------------------- +//x86vmx SUBARCH. INTERFACES +//---------------------------------------------------------------------- + +//this is the MLE Join stucture to bring up the APs (bplt-x86-smptrampoline.S) +extern u32 _mle_join_start[]; + + +//VMX VMCS read-only field encodings +extern struct _vmx_vmcsrofields_encodings g_vmx_vmcsrofields_encodings[] __attribute__(( section(".data") )); + +//count of VMX VMCS read-only fields +extern unsigned int g_vmx_vmcsrofields_encodings_count __attribute__(( section(".data") )); + +//VMX VMCS read-write field encodings +extern struct _vmx_vmcsrwfields_encodings g_vmx_vmcsrwfields_encodings[] __attribute__(( section(".data") )); + +//count of VMX VMCS read-write fields +extern unsigned int g_vmx_vmcsrwfields_encodings_count __attribute__(( section(".data") )); + +//VMX VMXON buffers +extern u8 g_vmx_vmxon_buffers[] __attribute__(( section(".bss.palign_data") )); + +//VMX VMCS buffers +extern u8 g_vmx_vmcs_buffers[] __attribute__(( section(".bss.palign_data") )); + +//VMX IO bitmap buffers +extern u8 g_vmx_iobitmap_buffer[] __attribute__(( section(".bss.palign_data") )); + +//VMX guest and host MSR save area buffers +extern u8 g_vmx_msr_area_host_buffers[] __attribute__(( section(".bss.palign_data") )); +extern u8 g_vmx_msr_area_guest_buffers[] __attribute__(( section(".bss.palign_data") )); + +//VMX MSR bitmap buffers +extern u8 g_vmx_msrbitmap_buffers[] __attribute__(( section(".bss.palign_data") )); + + +//initialize CPU state +void xmhf_baseplatform_arch_x86vmx_cpuinitialize(void); + +//wake up application processors (cores) in the system +void xmhf_baseplatform_arch_x86vmx_wakeupAPs(void); + +//allocate and setup VCPU structure for all the CPUs +void xmhf_baseplatform_arch_x86vmx_allocandsetupvcpus(u32 cpu_vendor); + +// routine takes vcpu vmcsfields and stores it in the CPU VMCS +void xmhf_baseplatform_arch_x86vmx_putVMCS(VCPU *vcpu); + +// routine takes CPU VMCS and stores it in vcpu vmcsfields +void xmhf_baseplatform_arch_x86vmx_getVMCS(VCPU *vcpu); + +//--debug: dumpVMCS dumps VMCS contents +void xmhf_baseplatform_arch_x86vmx_dumpVMCS(VCPU *vcpu); + +//--debug: dump_vcpu dumps vcpu contents (more verbose than dumpVMCS) +void xmhf_baseplatform_arch_x86vmx_dump_vcpu(VCPU *vcpu); + +//VMX specific platform reboot +void xmhf_baseplatform_arch_x86vmx_reboot(VCPU *vcpu); + +//---------------------------------------------------------------------- +//x86svm SUBARCH. INTERFACES +//---------------------------------------------------------------------- + +#ifdef __NESTED_PAGING__ +#define ASID_GUEST_KERNEL 2 +#endif + +//SVM VM_HSAVE buffers +extern u8 g_svm_hsave_buffers[]__attribute__(( section(".bss.palign_data") )); + +//SVM VMCB buffers +extern u8 g_svm_vmcb_buffers[]__attribute__(( section(".bss.palign_data") )); + +//SVM IO bitmap buffer +extern u8 g_svm_iobitmap_buffer[]__attribute__(( section(".bss.palign_data") )); + +//SVM MSR bitmap buffer +extern u8 g_svm_msrpm[]__attribute__(( section(".bss.palign_data") )); + + +//wake up application processors (cores) in the system +void xmhf_baseplatform_arch_x86svm_wakeupAPs(void); + +//allocate and setup VCPU structure for all the CPUs +void xmhf_baseplatform_arch_x86svm_allocandsetupvcpus(u32 cpu_vendor); + +//SVM specific platform reboot +void xmhf_baseplatform_arch_x86svm_reboot(VCPU *vcpu); + + + + + + +#endif //__ASSEMBLY__ + +#endif //__EMHF_BASEPLATFORM_ARCH_X86_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/xmhf-debug-arch-x86.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/xmhf-debug-arch-x86.h new file mode 100644 index 0000000000..2b4c348248 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/xmhf-debug-arch-x86.h @@ -0,0 +1,84 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF debug component +// x86 arch. specific declarations +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __EMHF_DEBUG_ARCH_X86_H__ +#define __EMHF_DEBUG_ARCH_X86_H__ + +#include "_com.h" //serial UART as debugging backend +#include "_div64.h" //arch. specific do_div definition + +#ifndef __ASSEMBLY__ + +//---------------------------------------------------------------------- +//ARCH. BACKENDS +//---------------------------------------------------------------------- +void xmhf_debug_arch_init(char *params); +void xmhf_debug_arch_putstr(const char *str); +void xmhf_debug_arch_putc(char c); + +//---------------------------------------------------------------------- +//x86 ARCH. INTERFACES +//---------------------------------------------------------------------- +extern uart_config_t g_uart_config; + +//#ifdef __DEBUG_SERIAL__ +void dbg_x86_uart_init(char *params); +void dbg_x86_uart_putc(char ch); +void dbg_x86_uart_putstr(const char *str); + +//#ifdef __DEBUG_VGA__ +void dbg_x86_vgamem_init(char *params); +void dbg_x86_vgamem_putc(int c); +void dbg_x86_vgamem_putstr(const char *str); + + +#endif // __ASSEMBLY__ + +#endif //__EMHF_DEBUG_ARCH_X86_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/xmhf-smpguest-arch-x86.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/xmhf-smpguest-arch-x86.h new file mode 100644 index 0000000000..d32e64f687 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/xmhf-smpguest-arch-x86.h @@ -0,0 +1,214 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF smpguest component +// x86 arch. specific declarations +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __EMHF_SMPGUEST_ARCH_X86_H__ +#define __EMHF_SMPGUEST_ARCH_X86_H__ + + + +#ifndef __ASSEMBLY__ + + +//---------------------------------------------------------------------- +//ARCH. BACKENDS +//---------------------------------------------------------------------- + +//initialize SMP guest logic +void xmhf_smpguest_arch_initialize(VCPU *vcpu); + +//quiesce interface to switch all guest cores into hypervisor mode +void xmhf_smpguest_arch_quiesce(VCPU *vcpu); + +//endquiesce interface to resume all guest cores after a quiesce +void xmhf_smpguest_arch_endquiesce(VCPU *vcpu); + +//walk guest page tables; returns pointer to corresponding guest physical address +//note: returns 0xFFFFFFFF if there is no mapping +u8 * xmhf_smpguest_arch_walk_pagetables(VCPU *vcpu, u32 vaddr); + + + +//---------------------------------------------------------------------- +//x86 ARCH. INTERFACES +//---------------------------------------------------------------------- + +//perform required setup after a guest awakens a new CPU +void xmhf_smpguest_arch_x86_postCPUwakeup(VCPU *vcpu); + +//handle LAPIC access #DB (single-step) exception event +void xmhf_smpguest_arch_x86_eventhandler_dbexception(VCPU *vcpu, + struct regs *r); + +//handle LAPIC access #NPF (nested page fault) event +void xmhf_smpguest_arch_x86_eventhandler_hwpgtblviolation(VCPU *vcpu, u32 gpa, u32 errorcode); + +//quiescing handler for #NMI (non-maskable interrupt) exception event +void xmhf_smpguest_arch_x86_eventhandler_nmiexception(VCPU *vcpu, struct regs *r, u32 from_guest); + + +//---------------------------------------------------------------------- +//x86vmx SUBARCH. INTERFACES +//---------------------------------------------------------------------- + +void xmhf_smpguest_arch_x86vmx_initialize(VCPU *vcpu, u32 unmaplapic); +void xmhf_smpguest_arch_x86vmx_eventhandler_dbexception(VCPU *vcpu, + struct regs *r); +int xmhf_smpguest_arch_x86vmx_eventhandler_x2apic_icrwrite(VCPU *vcpu, + struct regs *r); +void xmhf_smpguest_arch_x86vmx_eventhandler_nmiexception(VCPU *vcpu, struct regs *r, u32 from_guest); +u32 xmhf_smpguest_arch_x86vmx_eventhandler_hwpgtblviolation(VCPU *vcpu, u32 paddr, u32 errorcode); +void xmhf_smpguest_arch_x86vmx_unblock_nmi(void); +void xmhf_smpguest_arch_x86vmx_quiesce(VCPU *vcpu); +void xmhf_smpguest_arch_x86vmx_endquiesce(VCPU *vcpu); + + +//perform required setup after a guest awakens a new CPU +void xmhf_smpguest_arch_x86vmx_postCPUwakeup(VCPU *vcpu); +//walk guest page tables; returns pointer to corresponding guest physical address +//note: returns 0xFFFFFFFF if there is no mapping +u8 * xmhf_smpguest_arch_x86vmx_walk_pagetables(VCPU *vcpu, u32 vaddr); + +//the BSP LAPIC base address +extern u32 g_vmx_lapic_base __attribute__(( section(".data") )); + +//4k buffer which is the virtual LAPIC page that guest reads and writes from/to +//during INIT-SIPI-SIPI emulation +extern u8 g_vmx_virtual_LAPIC_base[] __attribute__(( section(".bss.palign_data") )); + +//the quiesce counter, all CPUs except for the one requesting the +//quiesce will increment this when they get their quiesce signal +extern u32 volatile g_vmx_quiesce_counter __attribute__(( section(".data") )); + +//SMP lock to access the above variable +extern u32 volatile g_vmx_lock_quiesce_counter __attribute__(( section(".data") )); + +//resume counter to rally all CPUs after resumption from quiesce +extern u32 volatile g_vmx_quiesce_resume_counter __attribute__(( section(".data") )); + +//SMP lock to access the above variable +extern u32 volatile g_vmx_lock_quiesce_resume_counter __attribute__(( section(".data") )); + +//the "quiesce" variable, if 1, then we have a quiesce in process +extern u32 volatile g_vmx_quiesce __attribute__(( section(".data") )); + +//SMP lock to access the above variable +extern u32 volatile g_vmx_lock_quiesce __attribute__(( section(".data") )); + +//resume signal, becomes 1 to signal resume after quiescing +extern u32 volatile g_vmx_quiesce_resume_signal __attribute__(( section(".data") )); + +//SMP lock to access the above variable +extern u32 volatile g_vmx_lock_quiesce_resume_signal __attribute__(( section(".data") )); + +//Flush all EPT TLB on all cores +//smpguest x86vmx +extern u32 volatile g_vmx_flush_all_tlb_signal __attribute__(( section(".data") )); + + +//---------------------------------------------------------------------- +//x86svm SUBARCH. INTERFACES +//---------------------------------------------------------------------- + +void xmhf_smpguest_arch_x86svm_initialize(VCPU *vcpu); +void xmhf_smpguest_arch_x86svm_eventhandler_dbexception(VCPU *vcpu, + struct regs *r); +void xmhf_smpguest_arch_x86svm_eventhandler_nmiexception(VCPU *vcpu, struct regs *r); +u32 xmhf_smpguest_arch_x86svm_eventhandler_hwpgtblviolation(VCPU *vcpu, u32 paddr, u32 errorcode); +void xmhf_smpguest_arch_x86svm_quiesce(VCPU *vcpu); +void xmhf_smpguest_arch_x86svm_endquiesce(VCPU *vcpu); + + +//perform required setup after a guest awakens a new CPU +void xmhf_smpguest_arch_x86svm_postCPUwakeup(VCPU *vcpu); +//walk guest page tables; returns pointer to corresponding guest physical address +//note: returns 0xFFFFFFFF if there is no mapping +u8 * xmhf_smpguest_arch_x86svm_walk_pagetables(VCPU *vcpu, u32 vaddr); + +//the BSP LAPIC base address +extern u32 g_svm_lapic_base __attribute__(( section(".data") )); + +//the quiesce counter, all CPUs except for the one requesting the +//quiesce will increment this when they get their quiesce signal +extern u32 g_svm_quiesce_counter __attribute__(( section(".data") )); + +//SMP lock to access the above variable +extern u32 g_svm_lock_quiesce_counter __attribute__(( section(".data") )); + +//resume counter to rally all CPUs after resumption from quiesce +extern u32 g_svm_quiesce_resume_counter __attribute__(( section(".data") )); + +//SMP lock to access the above variable +extern u32 g_svm_lock_quiesce_resume_counter __attribute__(( section(".data") )); + +//the "quiesce" variable, if 1, then we have a quiesce in process +extern u32 g_svm_quiesce __attribute__(( section(".data") )); + +//SMP lock to access the above variable +extern u32 g_svm_lock_quiesce __attribute__(( section(".data") )); + +//resume signal, becomes 1 to signal resume after quiescing +extern u32 g_svm_quiesce_resume_signal __attribute__(( section(".data") )); + +//SMP lock to access the above variable +extern u32 g_svm_lock_quiesce_resume_signal __attribute__(( section(".data") )); + +//4k buffer which is the virtual LAPIC page that guest reads and writes from/to +//during INIT-SIPI-SIPI emulation +extern u8 g_svm_virtual_LAPIC_base[] __attribute__(( section(".bss.palign_data") )); + +//SVM SIPI page buffers used for guest INIT-SIPI-SIPI emulation +extern u8 g_svm_sipi_page_buffers[]__attribute__(( section(".bss.palign_data") )); + + + + +#endif //__ASSEMBLY__ + +#endif // __EMHF_SMPGUEST_ARCH_X86_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/xmhf-tpm-arch-x86.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/xmhf-tpm-arch-x86.h new file mode 100644 index 0000000000..2780057df5 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/x86/xmhf-tpm-arch-x86.h @@ -0,0 +1,265 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF TPM component +// x86 arch. specific declarations +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __XMHF_TPM_ARCH_X86_H__ +#define __XMHF_TPM_ARCH_X86_H__ + + + +#ifndef __ASSEMBLY__ + + +//---------------------------------------------------------------------- +//ARCH. BACKENDS +//---------------------------------------------------------------------- +//open TPM locality +int xmhf_tpm_arch_open_locality(int locality); + +//check if TPM is ready for use +bool xmhf_tpm_arch_is_tpm_ready(uint32_t locality); + +//deactivate all TPM localities +void xmhf_tpm_arch_deactivate_all_localities(void); + +//prepare TPM for use +bool xmhf_tpm_arch_prepare_tpm(void); + + + +//---------------------------------------------------------------------- +//x86 ARCH. INTERFACES +//---------------------------------------------------------------------- +#define TPM_LOCALITY_BASE 0xfed40000 +#define NR_TPM_LOCALITY_PAGES ((TPM_LOCALITY_1 - TPM_LOCALITY_0) >> \ + PAGE_SHIFT) + +#define TPM_LOCALITY_0 TPM_LOCALITY_BASE +#define TPM_LOCALITY_1 (TPM_LOCALITY_BASE | 0x1000) +#define TPM_LOCALITY_2 (TPM_LOCALITY_BASE | 0x2000) +/* these localities (3+4) are mostly not usable by Xen */ +#define TPM_LOCALITY_3 (TPM_LOCALITY_BASE | 0x3000) +#define TPM_LOCALITY_4 (TPM_LOCALITY_BASE | 0x4000) + +#define TPM_LOCALITY_BASE_N(n) (TPM_LOCALITY_BASE | ((n) << 12)) + + + +#define TPM_VALIDATE_LOCALITY_TIME_OUT 0x100 + +/* + * TPM registers and data structures + * + * register values are offsets from each locality base + * see {read,write}_tpm_reg() for data struct format + */ + +/* TPM_ACCESS_x */ +#define TPM_REG_ACCESS 0x00 +typedef union { + u8 _raw[1]; /* 1-byte reg */ + struct __attribute__ ((packed)) { + u8 tpm_establishment : 1; /* RO, 0=T/OS has been established + before */ + u8 request_use : 1; /* RW, 1=locality is requesting TPM use */ + u8 pending_request : 1; /* RO, 1=other locality is requesting + TPM usage */ + u8 seize : 1; /* WO, 1=seize locality */ + u8 been_seized : 1; /* RW, 1=locality seized while active */ + u8 active_locality : 1; /* RW, 1=locality is active */ + u8 reserved : 1; + u8 tpm_reg_valid_sts : 1; /* RO, 1=other bits are valid */ + }; +} tpm_reg_access_t; + +/* TPM_STS_x */ +#define TPM_REG_STS 0x18 +typedef union { + u8 _raw[3]; /* 3-byte reg */ + struct __attribute__ ((packed)) { + u8 reserved1 : 1; + u8 response_retry : 1; /* WO, 1=re-send response */ + u8 reserved2 : 1; + u8 expect : 1; /* RO, 1=more data for command expected */ + u8 data_avail : 1; /* RO, 0=no more data for response */ + u8 tpm_go : 1; /* WO, 1=execute sent command */ + u8 command_ready : 1; /* RW, 1=TPM ready to receive new cmd */ + u8 sts_valid : 1; /* RO, 1=data_avail and expect bits are + valid */ + u16 burst_count : 16; /* RO, # read/writes bytes before wait */ + }; +} tpm_reg_sts_t; + +/* TPM_DATA_FIFO_x */ +#define TPM_REG_DATA_FIFO 0x24 +typedef union { + uint8_t _raw[1]; /* 1-byte reg */ +} tpm_reg_data_fifo_t; + +/* + * assumes that all reg types follow above format: + * - packed + * - member named '_raw' which is array whose size is that of data to read + */ +#define read_tpm_reg(locality, reg, pdata) \ + _read_tpm_reg(locality, reg, (pdata)->_raw, sizeof(*(pdata))) + +#define write_tpm_reg(locality, reg, pdata) \ + _write_tpm_reg(locality, reg, (pdata)->_raw, sizeof(*(pdata))) + + +/********************************************************************* + * Moved in from tboot's tpm.c; I think it belongs in a .h file. Also + * facilitates split into tpm.c and tpm_extra.c. + *********************************************************************/ + +/* TODO: Give these a more appropriate home */ +/* #define readb(va) (*(volatile uint8_t *) (va)) */ +/* #define writeb(va, d) (*(volatile uint8_t *) (va) = (d)) */ + +#ifndef __XMHF_VERIFICATION__ + +#ifdef __AMD64__ + /* + * NOTE: in 64-bit mode, use (VA + 256MiB) % 4GiB = PA to access physical + * memory. + */ + extern u32 xmhf_baseplatform_arch_flat_va_offset; +#elif !defined(__I386__) + #error "Unsupported Arch" +#endif /* !defined(__I386__) */ + + static inline void writeb(u32 addr, u8 val) { +#ifdef __AMD64__ + u32 phys_addr = (u32)addr - (u32)xmhf_baseplatform_arch_flat_va_offset; + *(u8 *)(u64)phys_addr = val; +#elif defined(__I386__) + __asm__ __volatile__("movb %%al, %%fs:(%%ebx)\r\n" + : + : "b"(addr), "a"((u32)val) + ); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + } + + static inline u8 readb(u32 addr) { +#ifdef __AMD64__ + u32 phys_addr = (u32)addr - (u32)xmhf_baseplatform_arch_flat_va_offset; + return *(u8 *)(u64)phys_addr; +#elif defined(__I386__) + u32 ret; + __asm__ __volatile("xor %%eax, %%eax\r\n" + "movb %%fs:(%%ebx), %%al\r\n" + : "=a"(ret) + : "b"(addr) + ); + return (u8)ret; +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + } + +#else //__XMHF_VERIFICATION__ + + static inline void writeb(u32 addr, u8 val) { + + } + + static inline u8 readb(u32 addr) { + return 0; + } + +#endif //__XMHF_VERIFICATION__ + +//TPM timeouts +#define TIMEOUT_UNIT (0x100000 / 330) /* ~1ms, 1 tpm r/w need > 330ns */ +#define TIMEOUT_A 750 /* 750ms */ +#define TIMEOUT_B 2000 /* 2s */ +#define TIMEOUT_C 750 /* 750ms */ +#define TIMEOUT_D 750 /* 750ms */ + +typedef struct __attribute__ ((packed)) { + uint32_t timeout_a; + uint32_t timeout_b; + uint32_t timeout_c; + uint32_t timeout_d; +} tpm_timeout_t; + + +#define TPM_ACTIVE_LOCALITY_TIME_OUT \ + (TIMEOUT_UNIT * g_timeout.timeout_a) /* according to spec */ +#define TPM_CMD_READY_TIME_OUT \ + (TIMEOUT_UNIT * g_timeout.timeout_b) /* according to spec */ +#define TPM_CMD_WRITE_TIME_OUT \ + (TIMEOUT_UNIT * g_timeout.timeout_d) /* let it long enough */ +#define TPM_DATA_AVAIL_TIME_OUT \ + (TIMEOUT_UNIT * g_timeout.timeout_c) /* let it long enough */ +#define TPM_RSP_READ_TIME_OUT \ + (TIMEOUT_UNIT * g_timeout.timeout_d) /* let it long enough */ + + +//---------------------------------------------------------------------- +//x86vmx SUBARCH. INTERFACES +//---------------------------------------------------------------------- +//open TPM locality +int xmhf_tpm_arch_x86vmx_open_locality(int locality); + + +//---------------------------------------------------------------------- +//x86vmx SUBARCH. INTERFACES +//---------------------------------------------------------------------- +//open TPM locality +int xmhf_tpm_arch_x86svm_open_locality(int locality); + + + +#endif //__ASSEMBLY__ + +#endif //__XMHF_TPM_ARCH_X86_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/xmhf-baseplatform-arch.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/xmhf-baseplatform-arch.h new file mode 100644 index 0000000000..94b475b08b --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/xmhf-baseplatform-arch.h @@ -0,0 +1,61 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF base platform component +// arch. specific declarations +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __EMHF_BASEPLATFORM_ARCH_H__ +#define __EMHF_BASEPLATFORM_ARCH_H__ + + +//XXX: this file needs to include the appropriate arch. specific +//header using either preprocessor directives, could be a +//symlink or use configure +#include + + +#endif //__EMHF_BASEPLATFORM_ARCH_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/xmhf-debug-arch.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/xmhf-debug-arch.h new file mode 100644 index 0000000000..1b9911f7b5 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/xmhf-debug-arch.h @@ -0,0 +1,64 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF debug component +// arch. specific declarations +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __EMHF_DEBUG_ARCH_H__ +#define __EMHF_DEBUG_ARCH_H__ + + +#ifndef __ASSEMBLY__ + +//XXX: this file needs to include the appropriate arch. specific +//header using either preprocessor directives, could be a +//symlink or use configure +#include + +#endif //__ASSEMBLY__ + +#endif //__EMHF_DEBUG_ARCH_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/xmhf-smpguest-arch.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/xmhf-smpguest-arch.h new file mode 100644 index 0000000000..e0c6ca4f5b --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/xmhf-smpguest-arch.h @@ -0,0 +1,64 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF smpguest component +// arch. specific declarations +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __EMHF_SMPGUEST_ARCH_H__ +#define __EMHF_SMPGUEST_ARCH_H__ + + +#ifndef __ASSEMBLY__ + +//XXX: this file needs to include the appropriate arch. specific +//header using either preprocessor directives, could be a +//symlink or use configure +#include + +#endif //__ASSEMBLY__ + +#endif //__EMHF_SMPGUEST_ARCH_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/arch/xmhf-tpm-arch.h b/xmhf-64/xmhf/src/xmhf-core/include/arch/xmhf-tpm-arch.h new file mode 100644 index 0000000000..4937a648f4 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/arch/xmhf-tpm-arch.h @@ -0,0 +1,60 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF TPM component +// arch. specific declarations +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __EMHF_TPM_ARCH_H__ +#define __EMHF_TPM_ARCH_H__ + + +//XXX: this file needs to include the appropriate arch. specific +//header using either preprocessor directives, could be a +//symlink or use configure +#include + +#endif //__EMHF_TPM_ARCH_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/stl/xmhfc-bitmap.h b/xmhf-64/xmhf/src/xmhf-core/include/stl/xmhfc-bitmap.h new file mode 100644 index 0000000000..d72f94c508 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/stl/xmhfc-bitmap.h @@ -0,0 +1,36 @@ +// Bitmap with optimized space and time complexity. The xmhfstl_bitmap allocates/revoke +// space on demand (PAGE granularity), but adds a little performance overhead +// in the critical path + +#ifndef XMHFSTL_BITMAP +#define XMHFSTL_BITMAP + +#define BITS_PER_BYTE_SHIFT 3 +#define BITS_PER_BYTE (1 << BITS_PER_BYTE_SHIFT) +#define BITS_TO_BYTES(x) ((x) >> BITS_PER_BYTE_SHIFT) +#define BYTES_TO_BITS(x) ((x) << BITS_PER_BYTE_SHIFT) + +#ifndef __ASSEMBLY__ + +// A xmhfstl_bitmap is allocated in separate memory pages. So we track the use of each +// xmhfstl_bitmap page to allocate/revoke memory on demand +typedef struct{ + uint32_t max_bits; + char** mem_table; // Contains page aligned addresses for holding xmhfstl_bitmap content + uint16_t* bits_stat; // num of set bit in the corresponding xmhfstl_bitmap page +}XMHF_STL_BITMAP; + +extern XMHF_STL_BITMAP* xmhfstl_bitmap_create(uint32_t num_bits); +extern void xmhfstl_bitmap_destroy(XMHF_STL_BITMAP* bitmap); + +extern bool xmhfstl_bitmap_set_bit(XMHF_STL_BITMAP* bitmap, const uint32_t bit_idx); +extern bool xmhfstl_bitmap_clear_bit(XMHF_STL_BITMAP* bitmap, const uint32_t bit_idx); + +extern bool xmhfstl_bitmap_is_bit_set(XMHF_STL_BITMAP* bitmap, const uint32_t bit_idx); +extern bool xmhfstl_bitmap_is_bit_clear(XMHF_STL_BITMAP* bitmap, const uint32_t bit_idx); + + + +#endif // __ASSEMBLY__ + +#endif // XMHFSTL_BITMAP diff --git a/xmhf-64/xmhf/src/xmhf-core/include/stl/xmhfc-dlist.h b/xmhf-64/xmhf/src/xmhf-core/include/stl/xmhfc-dlist.h new file mode 100644 index 0000000000..844791a56e --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/stl/xmhfc-dlist.h @@ -0,0 +1,52 @@ +// copy from http://c.learncodethehardway.org/book/ex32.html + +#ifndef XMHF_STL_DOUBLE_LLIST +#define XMHF_STL_DOUBLE_LLIST + +#ifndef __ASSEMBLY__ + +struct XMHFListNode; + +typedef struct XMHFListNode { + struct XMHFListNode *next; + struct XMHFListNode *prev; + void *value; +} XMHFListNode; + +typedef struct XMHFList { + int count; + XMHFListNode *first; + XMHFListNode *last; +} XMHFList; + +extern XMHFList* xmhfstl_list_create(void); +extern void xmhfstl_list_destroy(XMHFList *list); +extern void xmhfstl_list_clear(XMHFList *list); +extern void xmhfstl_list_clear_destroy(XMHFList *list); + +#define XMHFList_count(A) ((A)->count) +#define XMHFList_first(A) ((A)->first != NULL ? (A)->first->value : NULL) +#define XMHFList_last(A) ((A)->last != NULL ? (A)->last->value : NULL) +#define xmhfstl_list_enqueue(l, v) xmhfstl_list_push(l, v) +#define is_list_empty(l) (l->count == 0) + +extern XMHFListNode* xmhfstl_list_push(XMHFList *list, void *value); +extern void* xmhfstl_list_pop(XMHFList *list); +extern void* xmhfstl_list_dequeue(XMHFList *list); + +extern XMHFListNode* xmhfstl_list_last(XMHFList *list); +extern XMHFListNode* xmhfstl_list_first(XMHFList *list); + + +extern void xmhfstl_list_unshift(XMHFList *list, void *value); +extern void *xmhfstl_list_shift(XMHFList *list); + +extern void *xmhfstl_list_remove(XMHFList *list, XMHFListNode *node); +extern void xmhfstl_list_debug(XMHFList *list); + +#define XMHFLIST_FOREACH(L, S, M, V) XMHFListNode *_node = NULL;\ + XMHFListNode *V = NULL;\ + for(V = _node = L->S; _node != NULL; V = _node = _node->M) + +#endif // __ASSEMBLY__ +#endif // XMHF_STL_DOUBLE_LLIST diff --git a/xmhf-64/xmhf/src/xmhf-core/include/tomcrypt_custom.h b/xmhf-64/xmhf/src/xmhf-core/include/tomcrypt_custom.h new file mode 100644 index 0000000000..7dfa59ebf4 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/tomcrypt_custom.h @@ -0,0 +1,458 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#ifndef TOMCRYPT_CUSTOM_H_ +#define TOMCRYPT_CUSTOM_H_ + +#define LTC_NO_WCHAR +#define LTC_NO_FILE +#define LTC_NO_ROLC /* optimized rotate-left macros that don't always compile correctly */ +#define ARGTYPE 1 /* have argchk macros use assert instead of custom check with fprintf */ + +/* macros for various libc functions you can change for embedded targets */ +#ifndef XMALLOC + #ifdef malloc + #define LTC_NO_PROTOTYPES + #endif +#define XMALLOC malloc +#endif +#ifndef XREALLOC + #ifdef realloc + #define LTC_NO_PROTOTYPES + #endif +#define XREALLOC realloc +#endif +#ifndef XCALLOC + #ifdef calloc + #define LTC_NO_PROTOTYPES + #endif +#define XCALLOC calloc +#endif +#ifndef XFREE + #ifdef free + #define LTC_NO_PROTOTYPES + #endif +#define XFREE free +#endif + +#ifndef XMEMSET + #ifdef memset + #define LTC_NO_PROTOTYPES + #endif +#define XMEMSET memset +#endif +#ifndef XMEMCPY + #ifdef memcpy + #define LTC_NO_PROTOTYPES + #endif +#define XMEMCPY memcpy +#endif +#ifndef XMEMCMP + #ifdef memcmp + #define LTC_NO_PROTOTYPES + #endif +#define XMEMCMP memcmp +#endif +#ifndef XSTRCMP + #ifdef strcmp + #define LTC_NO_PROTOTYPES + #endif +#define XSTRCMP strcmp +#endif + +#ifndef XCLOCK +#define XCLOCK clock +#endif +#ifndef XCLOCKS_PER_SEC +#define XCLOCKS_PER_SEC CLOCKS_PER_SEC +#endif + +#ifndef XQSORT + #ifdef qsort + #define LTC_NO_PROTOTYPES + #endif +#define XQSORT qsort +#endif + +/* Easy button? */ +#ifdef LTC_EASY + #define LTC_NO_CIPHERS + #define LTC_RIJNDAEL + #define LTC_BLOWFISH + #define LTC_DES + #define LTC_CAST5 + + #define LTC_NO_MODES + #define LTC_ECB_MODE + #define LTC_CBC_MODE + #define LTC_CTR_MODE + + #define LTC_NO_HASHES + #define LTC_SHA1 + #define LTC_SHA512 + #define LTC_SHA384 + #define LTC_SHA256 + #define LTC_SHA224 + + #define LTC_NO_MACS + #define LTC_HMAC + #define LTC_OMAC + #define LTC_CCM_MODE + + #define LTC_NO_PRNGS + #define LTC_SPRNG + #define LTC_YARROW + #define LTC_DEVRANDOM + #define TRY_URANDOM_FIRST + + #define LTC_NO_PK + #define LTC_MRSA + #define LTC_MECC +#endif + +/* Use small code where possible */ +/* #define LTC_SMALL_CODE */ + +/* Enable self-test test vector checking */ +#ifndef LTC_NO_TEST + #define LTC_TEST +#endif + +/* clean the stack of functions which put private information on stack */ +/* #define LTC_CLEAN_STACK */ + +/* disable all file related functions */ +/* #define LTC_NO_FILE */ + +/* disable all forms of ASM */ +/* #define LTC_NO_ASM */ + +/* disable FAST mode */ +/* #define LTC_NO_FAST */ + +/* disable BSWAP on x86 */ +/* #define LTC_NO_BSWAP */ + +/* ---> Symmetric Block Ciphers <--- */ +#ifndef LTC_NO_CIPHERS + +/* #define LTC_BLOWFISH */ +/* #define LTC_RC2 */ +/* #define LTC_RC5 */ +/* #define LTC_RC6 */ +/* #define LTC_SAFERP */ +#define LTC_RIJNDAEL +/* #define LTC_XTEA */ +/* _TABLES tells it to use tables during setup, _SMALL means to use the smaller scheduled key format + * (saves 4KB of ram), _ALL_TABLES enables all tables during setup */ +/* #define LTC_TWOFISH */ +/* #ifndef LTC_NO_TABLES */ +/* #define LTC_TWOFISH_TABLES */ +/* /\* #define LTC_TWOFISH_ALL_TABLES *\/ */ +/* #else */ +/* #define LTC_TWOFISH_SMALL */ +/* #endif */ +/* #define LTC_TWOFISH_SMALL */ +/* LTC_DES includes EDE triple-LTC_DES */ +/* #define LTC_DES */ +/* #define LTC_CAST5 */ +/* #define LTC_NOEKEON */ +/* #define LTC_SKIPJACK */ +/* #define LTC_SAFER */ +/* #define LTC_KHAZAD */ +/* #define LTC_ANUBIS */ +/* #define LTC_ANUBIS_TWEAK */ +/* #define LTC_KSEED */ +/* #define LTC_KASUMI */ + +#endif /* LTC_NO_CIPHERS */ + + +/* ---> Block Cipher Modes of Operation <--- */ +#ifndef LTC_NO_MODES + +/* #define LTC_CFB_MODE */ +/* #define LTC_OFB_MODE */ +/* #define LTC_ECB_MODE */ +#define LTC_CBC_MODE +/* #define LTC_CTR_MODE */ + +/* F8 chaining mode */ +/* #define LTC_F8_MODE */ + +/* LRW mode */ +/* #define LTC_LRW_MODE */ +/* #ifndef LTC_NO_TABLES */ +/* /\* like GCM mode this will enable 16 8x128 tables [64KB] that make */ +/* * seeking very fast. */ +/* *\/ */ +/* #define LRW_TABLES */ +/* #endif */ + +/* XTS mode */ +/* #define LTC_XTS_MODE */ + +#endif /* LTC_NO_MODES */ + +/* ---> One-Way Hash Functions <--- */ +#ifndef LTC_NO_HASHES + +/* #define LTC_CHC_HASH */ +/* #define LTC_WHIRLPOOL */ +/* #define LTC_SHA512 */ +/* #define LTC_SHA384 */ +/* #define LTC_SHA256 */ +/* #define LTC_SHA224 */ +/* #define LTC_TIGER */ +#define LTC_SHA1 +/* #define LTC_MD5 */ +/* #define LTC_MD4 */ +/* #define LTC_MD2 */ +/* #define LTC_RIPEMD128 */ +/* #define LTC_RIPEMD160 */ +/* #define LTC_RIPEMD256 */ +/* #define LTC_RIPEMD320 */ + +#endif /* LTC_NO_HASHES */ + +/* ---> MAC functions <--- */ +#ifndef LTC_NO_MACS + +#define LTC_HMAC +/* #define LTC_OMAC */ +/* #define LTC_PMAC */ +/* #define LTC_XCBC */ +/* #define LTC_F9_MODE */ +/* #define LTC_PELICAN */ + +#if defined(LTC_PELICAN) && !defined(LTC_RIJNDAEL) + #error Pelican-MAC requires LTC_RIJNDAEL +#endif + +/* ---> Encrypt + Authenticate Modes <--- */ + +/* #define LTC_EAX_MODE */ +#if defined(LTC_EAX_MODE) && !(defined(LTC_CTR_MODE) && defined(LTC_OMAC)) + #error LTC_EAX_MODE requires CTR and LTC_OMAC mode +#endif + +/* #define LTC_OCB_MODE */ +/* #define LTC_CCM_MODE */ +/* #define LTC_GCM_MODE */ + +/* Use 64KiB tables */ +#ifndef LTC_NO_TABLES + #define LTC_GCM_TABLES +#endif + +/* USE SSE2? requires GCC works on x86_32 and x86_64*/ +#ifdef LTC_GCM_TABLES +/* #define LTC_GCM_TABLES_SSE2 */ +#endif + +#endif /* LTC_NO_MACS */ + +/* Various tidbits of modern neatoness */ +/* #define LTC_BASE64 */ + +/* --> Pseudo Random Number Generators <--- */ +#ifndef LTC_NO_PRNGS + +/* Yarrow */ +/* #define LTC_YARROW */ +/* which descriptor of AES to use? */ +/* 0 = rijndael_enc 1 = aes_enc, 2 = rijndael [full], 3 = aes [full] */ +/* #define LTC_YARROW_AES 0 */ + +#if defined(LTC_YARROW) && !defined(LTC_CTR_MODE) + #error LTC_YARROW requires LTC_CTR_MODE chaining mode to be defined! +#endif + +/* a PRNG that simply reads from an available system source */ +/* #define LTC_SPRNG */ + +/* The LTC_RC4 stream cipher */ +/* #define LTC_RC4 */ + +/* Fortuna PRNG */ +/* #define LTC_FORTUNA */ +/* reseed every N calls to the read function */ +#define LTC_FORTUNA_WD 10 +/* number of pools (4..32) can save a bit of ram by lowering the count */ +#define LTC_FORTUNA_POOLS 32 + +/* Greg's LTC_SOBER128 PRNG ;-0 */ +/* #define LTC_SOBER128 */ + +/* the *nix style /dev/random device */ +/* #define LTC_DEVRANDOM */ +/* try /dev/urandom before trying /dev/random */ +/* #define TRY_URANDOM_FIRST */ + +#endif /* LTC_NO_PRNGS */ + +/* ---> math provider? <--- */ +#ifndef LTC_NO_MATH + +/* LibTomMath */ +#define LTM_LTC_DESC +#define LTM_DESC + +/* TomsFastMath */ +/* #define TFM_LTC_DESC */ + +#endif /* LTC_NO_MATH */ + +/* ---> Public Key Crypto <--- */ +#ifndef LTC_NO_PK + +/* Include RSA support */ +#define LTC_MRSA + +/* Include Katja (a Rabin variant like RSA) */ +/* #define MKAT */ + +/* Digital Signature Algorithm */ +/* #define LTC_MDSA */ + +/* ECC */ +/* #define LTC_MECC */ + +/* use Shamir's trick for point mul (speeds up signature verification) */ +#define LTC_ECC_SHAMIR + +#if defined(TFM_LTC_DESC) && defined(LTC_MECC) + #define LTC_MECC_ACCEL +#endif + +/* do we want fixed point ECC */ +/* #define LTC_MECC_FP */ + +/* Timing Resistant? */ +/* #define LTC_ECC_TIMING_RESISTANT */ + +#endif /* LTC_NO_PK */ + +/* LTC_PKCS #1 (RSA) and #5 (Password Handling) stuff */ +#ifndef LTC_NO_PKCS + +#define LTC_PKCS_1 +/* #define LTC_PKCS_5 */ + +/* Include ASN.1 DER (required by DSA/RSA) */ +#define LTC_DER + +#endif /* LTC_NO_PKCS */ + +/* cleanup */ + +#ifdef LTC_MECC +/* Supported ECC Key Sizes */ +#ifndef LTC_NO_CURVES + #define ECC112 + #define ECC128 + #define ECC160 + #define ECC192 + #define ECC224 + #define ECC256 + #define ECC384 + #define ECC521 +#endif +#endif + +#if defined(LTC_MECC) || defined(LTC_MRSA) || defined(LTC_MDSA) || defined(MKATJA) + /* Include the MPI functionality? (required by the PK algorithms) */ + #define MPI +#endif + +#ifdef LTC_MRSA + #define LTC_PKCS_1 +#endif + +#if defined(LTC_DER) && !defined(MPI) + #error ASN.1 DER requires MPI functionality +#endif + +#if (defined(LTC_MDSA) || defined(LTC_MRSA) || defined(LTC_MECC) || defined(MKATJA)) && !defined(LTC_DER) + #error PK requires ASN.1 DER functionality, make sure LTC_DER is enabled +#endif + +/* THREAD management */ +#ifdef LTC_PTHREAD + +#include + +#define LTC_MUTEX_GLOBAL(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER; +#define LTC_MUTEX_PROTO(x) extern pthread_mutex_t x; +#define LTC_MUTEX_TYPE(x) pthread_mutex_t x; +#define LTC_MUTEX_INIT(x) pthread_mutex_init(x, NULL); +#define LTC_MUTEX_LOCK(x) pthread_mutex_lock(x); +#define LTC_MUTEX_UNLOCK(x) pthread_mutex_unlock(x); + +#else + +/* default no functions */ +#define LTC_MUTEX_GLOBAL(x) +#define LTC_MUTEX_PROTO(x) +#define LTC_MUTEX_TYPE(x) +#define LTC_MUTEX_INIT(x) +#define LTC_MUTEX_LOCK(x) +#define LTC_MUTEX_UNLOCK(x) + +#endif + +/* Debuggers */ + +/* define this if you use Valgrind, note: it CHANGES the way SOBER-128 and LTC_RC4 work (see the code) */ +/* #define LTC_VALGRIND */ + +#endif + + + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_custom.h,v $ */ +/* $Revision: 1.73 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/tommath_superclass.h b/xmhf-64/xmhf/src/xmhf-core/include/tommath_superclass.h new file mode 100644 index 0000000000..8760be420c --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/tommath_superclass.h @@ -0,0 +1,131 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* super class file for PK algos */ + +/* default ... include all MPI */ +/* #define LTM_ALL */ + +/* RSA only (does not support DH/DSA/ECC) */ +#define SC_RSA_1 + +#define LTM_NO_FILE +#define BN_MP_NEG_C +#define BN_MP_GET_INT_C +#define BN_MP_READ_RADIX_C +#define BN_MP_TORADIX_C +#define BN_MP_WRITE_RADIX_C +#define BN_MP_MONTGOMERY_REDUCE_C +#define BN_MP_TO_UNSIGNED_BIN_N_C + +/* For reference.... On an Athlon64 optimizing for speed... + + LTM's mpi.o with all functions [striped] is 142KiB in size. + +*/ + +/* Works for RSA only, mpi.o is 68KiB */ +#ifdef SC_RSA_1 + #define BN_MP_SHRINK_C + #define BN_MP_LCM_C + #define BN_MP_PRIME_RANDOM_EX_C + #define BN_MP_INVMOD_C + #define BN_MP_GCD_C + #define BN_MP_MOD_C + #define BN_MP_MULMOD_C + #define BN_MP_ADDMOD_C + #define BN_MP_EXPTMOD_C + #define BN_MP_SET_INT_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_CLEAR_MULTI_C + #define BN_MP_UNSIGNED_BIN_SIZE_C + #define BN_MP_TO_UNSIGNED_BIN_C + #define BN_MP_MOD_D_C + #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C + #define BN_REVERSE_C + #define BN_PRIME_TAB_C + + /* other modifiers */ + #define BN_MP_DIV_SMALL /* Slower division, not critical */ + + /* here we are on the last pass so we turn things off. The functions classes are still there + * but we remove them specifically from the build. This also invokes tweaks in functions + * like removing support for even moduli, etc... + */ +#ifdef LTM_LAST + #undef BN_MP_TOOM_MUL_C + #undef BN_MP_TOOM_SQR_C + #undef BN_MP_KARATSUBA_MUL_C + #undef BN_MP_KARATSUBA_SQR_C + #undef BN_MP_REDUCE_C + #undef BN_MP_REDUCE_SETUP_C + #undef BN_MP_DR_IS_MODULUS_C + #undef BN_MP_DR_SETUP_C + #undef BN_MP_DR_REDUCE_C + #undef BN_MP_REDUCE_IS_2K_C + #undef BN_MP_REDUCE_2K_SETUP_C + #undef BN_MP_REDUCE_2K_C + #undef BN_S_MP_EXPTMOD_C + #undef BN_MP_DIV_3_C + #undef BN_S_MP_MUL_HIGH_DIGS_C + #undef BN_FAST_S_MP_MUL_HIGH_DIGS_C + #undef BN_FAST_MP_INVMOD_C + + /* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold + * which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines] + * which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without + * trouble. + */ + #undef BN_S_MP_MUL_DIGS_C + #undef BN_S_MP_SQR_C + /* #undef BN_MP_MONTGOMERY_REDUCE_C */ +#endif + +#endif + +/* $Source$ */ +/* $Revision: 0.36 $ */ +/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/xmhf-app.h b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-app.h new file mode 100644 index 0000000000..20b870e05a --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-app.h @@ -0,0 +1,97 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF app. callback declarations +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __EMHF_APP_H__ +#define __EMHF_APP_H__ + +#ifndef __ASSEMBLY__ + +//---------------------------------------------------------------------- +// EMHF application related declarations +//---------------------------------------------------------------------- + +//generic catch-all app return codes +#define APP_SUCCESS (0x1) +#define APP_ERROR (0x0) + +//emhf app constant definitions +#define APP_IOINTERCEPT_CHAIN 0xA0 +#define APP_IOINTERCEPT_SKIP 0xA1 +#define APP_INIT_SUCCESS 0x0 +#define APP_INIT_FAIL 0xFF + + +//application parameter block +//for now it holds the bootsector and optional module info loaded by GRUB +//eventually this will be generic enough for both boot-time and dynamic loading +//capabilities +typedef struct { + hva_t bootsector_ptr; + hva_t bootsector_size; + hva_t optionalmodule_ptr; + hva_t optionalmodule_size; + hva_t runtimephysmembase; + u8 boot_drive; + char cmdline[1024]; +} APP_PARAM_BLOCK; + + +//EMHF application callbacks +extern u32 xmhf_app_main(VCPU *vcpu, APP_PARAM_BLOCK *apb); +extern u32 xmhf_app_handleintercept_portaccess(VCPU *vcpu, struct regs *r, u32 portnum, u32 access_type, u32 access_size); +extern u32 xmhf_app_handleintercept_hwpgtblviolation(VCPU *vcpu, + struct regs *r, + gpa_t gpa, gva_t gva, u64 violationcode); +extern void xmhf_app_handleshutdown(VCPU *vcpu, struct regs *r); +extern u32 xmhf_app_handlehypercall(VCPU *vcpu, struct regs *r); //returns APP_SUCCESS if handled, else APP_ERROR +extern u32 xmhf_app_handlemtrr(VCPU *vcpu, u32 msr, u64 val); //returns APP_SUCCESS if allow MTRR change + +#endif //__ASSEMBLY__ + +#endif // __EMHF_APP_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/xmhf-baseplatform.h b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-baseplatform.h new file mode 100644 index 0000000000..c233af87eb --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-baseplatform.h @@ -0,0 +1,205 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// XMHF base platform component +// declarations +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __XMHF_BASEPLATFORM_H__ +#define __XMHF_BASEPLATFORM_H__ + +//bring in arch. specific declarations +#include + + +#ifndef __ASSEMBLY__ + +//---------------------------------------------------------------------- +//the master-id table, which is used by the AP bootstrap code +//to locate its own vcpu structure +//NOTE: The size of this structure _MUST_ be _EXACTLY_EQUAL_ to 8 bytes +//as it is made use of in low-level assembly language stubs +typedef struct _midtab { + union { + u32 cpu_lapic_id; // CPU LAPIC id (unique) + hva_t _cpu_lapic_id_64; // Keep struct aligned in amd64; don't use this + }; + hva_t vcpu_vaddr_ptr; // virt. addr. pointer to vcpu struct for this CPU +} __attribute__((packed)) MIDTAB; + +#define SIZE_STRUCT_MIDTAB (sizeof(struct _midtab)) + +//---platform +typedef struct _grube820 { + u32 baseaddr_low; + u32 baseaddr_high; + u32 length_low; + u32 length_high; + u32 type; +} __attribute__((packed)) GRUBE820; + +#define SIZE_STRUCT_GRUBE820 (sizeof(struct _grube820)) + +//---platform +typedef struct _pcpu { + u32 lapic_id; + u32 lapic_ver; + u32 lapic_base; + u32 isbsp; +} __attribute__((packed)) PCPU; + +#define SIZE_STRUCT_PCPU (sizeof(struct _pcpu)) + +//---------------------------------------------------------------------- +//exported DATA +//---------------------------------------------------------------------- +//system e820 map + extern GRUBE820 g_e820map[] __attribute__(( section(".data") )); + +//SMP CPU map; lapic id, base, ver and bsp indication for each available core +extern PCPU g_cpumap[] __attribute__(( section(".data") )); + +//runtime stacks for individual cores +extern u8 g_cpustacks[] __attribute__(( section(".bss.stack") )); + +//VCPU structure for each "guest OS" core +extern VCPU g_vcpubuffers[] __attribute__(( section(".data") )); + +//master id table, contains core lapic id to VCPU mapping information +extern MIDTAB g_midtable[] __attribute__(( section(".data") )); + +//number of entries in the master id table, in essence the number of +//physical cores in the system +extern u32 g_midtable_numentries __attribute__(( section(".data") )); + +//variable that is incremented by 1 by all cores that boot up, this should +//be finally equal to g_midtable_numentries at runtime which signifies +//that all physical cores have been booted up and initialized by the runtime +extern volatile u32 g_cpus_active __attribute__(( section(".data") )); + +//SMP lock for the above variable +extern volatile u32 g_lock_cpus_active __attribute__(( section(".data") )); + +//variable that is set to 1 by the BSP after rallying all the other cores. +//this is used by the application cores to enter the "wait-for-SIPI" state +extern volatile u32 g_ap_go_signal __attribute__(( section(".data") )); + +//SMP lock for the above variable +extern volatile u32 g_lock_ap_go_signal __attribute__(( section(".data") )); + +//---------------------------------------------------------------------- +//exported FUNCTIONS +//---------------------------------------------------------------------- + +//get CPU vendor +u32 xmhf_baseplatform_getcpuvendor(void); + +//initialize CPU state +void xmhf_baseplatform_cpuinitialize(void); + +//initialize SMP +void xmhf_baseplatform_smpinitialize(void); + +//initialize basic platform elements +void xmhf_baseplatform_initialize(void); + +//reboot platform +void xmhf_baseplatform_reboot(VCPU *vcpu); + +// Traverse the E820 map and return the base and limit of used system physical address (i.e., used by main memory and MMIO). +// [NOTE] must be u64 even on 32-bit machines, because it could be 4G, and hence overflow u32. +// Return: and may not be 4K-aligned. +// [TODO][Issue 85] Move this function to a better place +extern bool xmhf_baseplatform_x86_e820_paddr_range(spa_t* machine_base_spa, spa_t* machine_limit_spa); + +#ifndef __XMHF_VERIFICATION__ + + //hypervisor runtime virtual address to secure loader address + //note: secure loader runs in a DS relative addressing mode and + //rest of hypervisor runtime is at secure loader base address + 2MB + static inline void * hva2sla(void *hva){ + return (void*)((hva_t)hva - rpb->XtVmmRuntimePhysBase + PAGE_SIZE_2M); + } + + //secure loader address to system physical address + //note: secure loader runs in a DS relative addressing mode + //(relative to secure loader base address) + static inline spa_t sla2spa(void *sla){ + return (spa_t) ((sla_t)sla + (rpb->XtVmmRuntimePhysBase - PAGE_SIZE_2M)); + } + + // XMHF runtime virtual-address to system-physical-address and vice-versa + // Note: since we are unity mapped, runtime VA = system PA + static inline spa_t hva2spa(void *hva){ + hva_t hva_ui = (hva_t)hva; + return hva_ui; + } + + static inline void * spa2hva(spa_t spa){ + return (void *)(hva_t)spa; + } + + static inline spa_t gpa2spa(gpa_t gpa) { return gpa; } + static inline gpa_t spa2gpa(spa_t spa) { return spa; } + static inline void* gpa2hva(gpa_t gpa) { return spa2hva(gpa2spa(gpa)); } + static inline gpa_t hva2gpa(void* hva) { return spa2gpa(hva2spa(hva)); } + +#else //__XMHF_VERIFICATION__ + + #define hva2spa(x) (u32)(x) + static inline void * spa2hva(spa_t spa) { (void *)(hva_t)(spa); } + static inline spa_t gpa2spa(gpa_t gpa) { return gpa; } + static inline gpa_t spa2gpa(spa_t spa) { return spa; } + static inline void* gpa2hva(gpa_t gpa) { return spa2hva(gpa2spa(gpa)); } + static inline gpa_t hva2gpa(void* hva) { return spa2gpa(hva2spa(hva)); } + +#endif //__XMHF_VERIFICATION__ + +#endif //__ASSEMBLY__ + + + +#endif //__XMHF_BASEPLATFORM_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/xmhf-config.h b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-config.h new file mode 100644 index 0000000000..107f9f8739 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-config.h @@ -0,0 +1,77 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF x86 arch. specific configurable definitions +// author: amit vasudevan (amitvasudevan@acm.org) +// author: Eric Li +// author: Miao Yu + +// This file must be modified first to support hardware configuration + +#ifndef __XMHF_CONFIG_H__ +#define __XMHF_CONFIG_H__ + +// maximum supported physical address, currently 16GB +// Note: This value must be larger than 4GB +#ifdef __I386__ + // Note: 32-bit XMHF (non-PAE) always assumes the maximum physical memory size == 4GB. + #define MAX_PHYS_ADDR ADDR_4GB +#elif defined(__AMD64__) + #define MAX_PHYS_ADDR (AMD64_MAX_PHYS_ADDR) +#else + #error "Unsupported Arch" +#endif // __I386__ + + +// max. cores/vcpus we support currently +#define MAX_MIDTAB_ENTRIES (8) +#define MAX_PCPU_ENTRIES (MAX_MIDTAB_ENTRIES) +#define MAX_VCPU_ENTRIES (MAX_PCPU_ENTRIES) + +#ifndef __ASSEMBLY__ + +#endif // __ASSEMBLY__ +#endif // __XMHF_CONFIG_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/xmhf-debug.h b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-debug.h new file mode 100644 index 0000000000..52a4131f2f --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-debug.h @@ -0,0 +1,156 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF secure loader component declarations +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __EMHF_DEBUG_H__ +#define __EMHF_DEBUG_H__ + +//bring in arch. specific declarations +#include + +#ifndef __ASSEMBLY__ + +//---------------------------------------------------------------------- +//exported DATA +extern uint8_t g_log_targets; +extern uint8_t g_log_level; +//extern unsigned char g_dbg_ctype[]; + +//---------------------------------------------------------------------- +//definitions +#define print_string putstr + +#define LOG_LEVEL_NONE 0x00 +#define LOG_LEVEL_ALL 0xFF + +#define LOG_TARGET_NONE 0x00 +#define LOG_TARGET_VGA 0x01 +#define LOG_TARGET_SERIAL 0x02 +#define LOG_TARGET_MEMORY 0x04 + +#define LOG_PROFILE (1<<0) +#define LOG_TRACE (1<<1) +#define LOG_ERROR (1<<2) + +#define ENABLED_LOG_TYPES (LOG_PROFILE|LOG_TRACE|LOG_ERROR) + +#define _U 0x01 /* upper */ +#define _L 0x02 /* lower */ +#define _D 0x04 /* digit */ +#define _C 0x08 /* cntrl */ +#define _P 0x10 /* punct */ +#define _S 0x20 /* white space (space/lf/tab) */ +#define _X 0x40 /* hex digit */ +#define _SP 0x80 /* hard space (0x20) */ + + +/*#define __ismask(x) (g_dbg_ctype[(int)(unsigned char)(x)]) + +#define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0) +#define isalpha(c) ((__ismask(c)&(_U|_L)) != 0) +#define iscntrl(c) ((__ismask(c)&(_C)) != 0) +#define isdigit(c) ((__ismask(c)&(_D)) != 0) +#define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0) +#define islower(c) ((__ismask(c)&(_L)) != 0) +#define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0) +#define ispunct(c) ((__ismask(c)&(_P)) != 0) +#define isspace(c) ((__ismask(c)&(_S)) != 0) +#define isupper(c) ((__ismask(c)&(_U)) != 0) +#define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0) + +#define isascii(c) (((unsigned char)(c))<=0x7f) +#define toascii(c) (((unsigned char)(c))&0x7f) + +static inline unsigned char __tolower(unsigned char c) +{ + int ctemp; + if (isupper(c)) + ctemp -= 'A'-'a'; + return (unsigned char)ctemp; +} + +static inline unsigned char __toupper(unsigned char c) +{ + int ctemp; + if (islower(c)) + ctemp -= 'a'-'A'; + return (unsigned char)ctemp; +} + +#define tolower(c) __tolower(c) +#define toupper(c) __toupper(c) +*/ + + +//---------------------------------------------------------------------- +//exported FUNCTIONS +void xmhf_debug_init(char *params); + +#include +#if defined (__DEBUG_SERIAL__) || defined (__DEBUG_VGA__) + /* void printf(const char *format, ...) */ + /* __attribute__ ((format (printf, 1, 2))); */ + void dprintf(u32 log_type, const char *format, ...) + __attribute__ ((format (printf, 2, 3))); + void dvprintf(u32 log_type, const char *fmt, va_list args); + void print_hex(const char *prefix, const void *prtptr, size_t size); + +#else + /* #define printf(format, args...) while(0) */ + #define dprintf(format, args...) while(0) + #define dvprintf(log_type, fmt, args) while(0) + #define print_hex(prefix, prtptr, size) while(0) +#endif + + + + + +#endif //__ASSEMBLY__ + +#endif //__EMHF_DEBUG_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/xmhf-dmaprot.h b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-dmaprot.h new file mode 100644 index 0000000000..27025ff52b --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-dmaprot.h @@ -0,0 +1,237 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF DMA protection component declarations +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __EMHF_DMAPROT_H__ +#define __EMHF_DMAPROT_H__ + + +#ifndef __ASSEMBLY__ + +/// @brief maximum number of RSDT entries we support +#define ACPI_MAX_RSDT_ENTRIES (256) + +/// @brief The invalid handler of the IOMMU PageTable +#define IOMMU_PT_INVALID 0xFFFFFFFF + +/// @brief The IOMMU PT ID of the untrusted OS +#define UNTRUSTED_OS_IOMMU_PT_ID 1 + +/// @brief The handler type of the IOMMU PageTable +typedef uint32_t iommu_pt_t; + +/// @brief The descriptor to locate a Device +// [TODO] We only support PCI/PCIe devices at current. +typedef union +{ + struct { + unsigned short func:3, + dev:5, + bus:8; + char __resvs[sizeof(unsigned long) - sizeof(unsigned short)]; + } __attribute__ ((packed)); + unsigned long raw; +} DEVICEDESC; + +//---------------------------------------------------------------------- +//exported DATA +//---------------------------------------------------------------------- + + +//---------------------------------------------------------------------- +//exported FUNCTIONS +//---------------------------------------------------------------------- + +typedef enum +{ + /// @brief Invalid type of IOMMU PT. + IOMMU_PT_TYPE_INVALID = 0, + + /// @brief Support DMA accesses to secure domain's memory only. + /// [NOTE] This type of IOMMU PT allows DMA destinations to be paddrs of the secure domain. + IOMMU_PT_TYPE_S_EXCLUSIVE = 1, + + /// @brief Support DMA accesses to both secure domain's memory and non-secure domain's memory. + /// [NOTE] This type of IOMMU PT requires that DMA destinations must be spaddrs instead of paddrs of + /// secure/non-secure domains. + IOMMU_PT_TYPE_S_NS_SHARED = 2 +} IOMMU_PT_TYPE; + +/// @brief Initialize the IOMMU (DMA Protection to the main memory) subsystem +extern void xmhf_iommu_init(void); + +/// @brief Finalize the IOMMU subsystem +extern void xmhf_iommu_fini(void); + +extern uint32_t iommu_is_pt_s_exclusive(iommu_pt_t pt_handle, bool* out_result); +extern uint32_t iommu_is_pt_s_ns_shared(iommu_pt_t pt_handle, bool* out_result); + +/// @brief Create a new IOMMU Page Table +extern iommu_pt_t xmhf_iommu_pt_create(IOMMU_PT_TYPE type); + +/// @brief Destroy an IOMMU Page Table +extern bool xmhf_iommu_pt_destroy(iommu_pt_t pt_handle); + +// Mapping flags +#define DMA_ALLOW_ACCESS 1 +#define DMA_DENY_ACCESS 2 + +/// @brief Map with in the IOMMU PT +extern bool xmhf_iommu_pt_map(iommu_pt_t pt_handle, gpa_t gpa, spa_t spa, uint32_t flags); + +/// @brief Load the IOMMU PT for a specific device +extern bool xmhf_iommu_bind_device(iommu_pt_t pt_handle, DEVICEDESC* device); + +/// @brief Bind the untrusted OS's default IOMMU PT to the specific device +extern bool xmhf_iommu_unbind_device(DEVICEDESC* device); + +/// @brief Map with in all IOMMU_PT_TYPE_S_NS_SHARED IOMMU PTs. +/// [NOTE] This function is needed when moving memory between S and NS domains. Otherwise, a shared IOMMU PT created +/// by a SecProcess ealier may map isolated memory given to other SecProcesses later. This violates memory separation +/// between SecProcesses. +/// [TODO][Issue 60] SecBase needs to prove: All IOMMU_PT_TYPE_S_NS_SHARED IOMMU PTs map NS domain's memory and given +/// S domain's memory, but not any other S domain's memory. +extern bool xmhf_iommu_all_shared_pts_map(gpa_t gpa, uint32_t flags); + +//return size (in bytes) of the memory buffer required for +//DMA protection for a given physical memory limit +u32 xmhf_dmaprot_getbuffersize(u64 physical_memory_limit); + + +//"early" DMA protection initialization to setup minimal +//structures to protect a range of physical memory +//return 1 on success 0 on failure +u32 xmhf_dmaprot_earlyinitialize(u64 protectedbuffer_paddr, + u32 protectedbuffer_vaddr, u32 protectedbuffer_size, + u64 memregionbase_paddr, u32 memregion_size); + +//"normal" DMA protection initialization to setup required +//structures for DMA protection +//return 1 on success 0 on failure +u32 xmhf_dmaprot_initialize(u64 protectedbuffer_paddr, + u32 protectedbuffer_vaddr, u32 protectedbuffer_size); + +//DMA protect a given region of memory, start_paddr is +//assumed to be page aligned physical memory address +void xmhf_dmaprot_protect(spa_t start_paddr, size_t size); + +extern void xmhf_dmaprot_unprotect(spa_t start_paddr, size_t size); + +extern void xmhf_dmaprot_invalidate_cache(void); + +//---------------------------------------------------------------------- +//ARCH. BACKENDS +//---------------------------------------------------------------------- +u32 xmhf_dmaprot_arch_getbuffersize(u64 physical_memory_limit); +u32 xmhf_dmaprot_arch_earlyinitialize(u64 protectedbuffer_paddr, + u32 protectedbuffer_vaddr, u32 protectedbuffer_size, + u64 memregionbase_paddr, u32 memregion_size); +u32 xmhf_dmaprot_arch_initialize(u64 protectedbuffer_paddr, + u32 protectedbuffer_vaddr, u32 protectedbuffer_size); +void xmhf_dmaprot_arch_protect(spa_t start_paddr, size_t size); + +extern void xmhf_dmaprot_arch_unprotect(spa_t start_paddr, size_t size); + +extern void xmhf_dmaprot_arch_invalidate_cache(void); + + +//---------------------------------------------------------------------- +//x86_vmx SUBARCH. INTERFACES +//---------------------------------------------------------------------- +// Capabilities of Intel VT-d HW +struct dmap_vmx_cap +{ + u32 nd:3; + u32 sagaw:5; + u32 _reserved1:24; +} __attribute__ ((packed)); + +//---------------------------------------------------------------------- +//vmx SUBARCH. INTERFACES +//---------------------------------------------------------------------- +u32 xmhf_dmaprot_arch_x86_vmx_earlyinitialize(sla_t protectedbuffer_paddr, + sla_t protectedbuffer_vaddr, size_t protectedbuffer_size, + sla_t memregionbase_paddr, u32 memregion_size); +u32 xmhf_dmaprot_arch_x86_vmx_initialize(spa_t protectedbuffer_paddr, + hva_t protectedbuffer_vaddr, size_t protectedbuffer_size); +void xmhf_dmaprot_arch_x86_vmx_protect(spa_t start_paddr, size_t size); +extern void xmhf_dmaprot_arch_x86_vmx_unprotect(spa_t start_paddr, size_t size); +extern void xmhf_dmaprot_arch_x86_vmx_invalidate_cache(void); + +//---------------------------------------------------------------------- +//svm SUBARCH. INTERFACES +//---------------------------------------------------------------------- +u32 xmhf_dmaprot_arch_x86_svm_earlyinitialize(u64 protectedbuffer_paddr, + u32 protectedbuffer_vaddr, u32 protectedbuffer_size, + u64 memregionbase_paddr, u32 memregion_size); +u32 xmhf_dmaprot_arch_x86_svm_initialize(u64 protectedbuffer_paddr, + u32 protectedbuffer_vaddr, u32 protectedbuffer_size); +void xmhf_dmaprot_arch_x86_svm_protect(u32 start_paddr, u32 size); +extern void xmhf_dmaprot_arch_x86_svm_invalidate_cache(void); + +//VMX VT-d page table buffers; we support a 3 level page-table walk, +//4kb pdpt, 4kb pdt and 4kb pt and each entry in pdpt, pdt and pt is 64-bits +//extern u8 g_vmx_vtd_pdp_table[] __attribute__(( section(".bss.palign_data") )); +//extern u8 g_vmx_vtd_pd_tables[] __attribute__(( section(".bss.palign_data") )); +//extern u8 g_vmx_vtd_p_tables[] __attribute__(( section(".bss.palign_data") )); + +//VMX VT-d Root Entry Table (RET) +//the RET is 4kb, each root entry (RE) is 128-bits +//this gives us 256 entries in the RET, each corresponding to a PCI bus num. (0-255) +extern u8 g_vmx_vtd_ret[] __attribute__(( section(".bss.palign_data") )); + +//VMX VT-d Context Entry Table (CET) +//each RE points to a context entry table (CET) of 4kb, each context entry (CE) +//is 128-bits which gives us 256 entries in the CET, accounting for 32 devices +//with 8 functions each as per the PCI spec. +extern u8 g_vmx_vtd_cet[] __attribute__(( section(".bss.palign_data") )); + + +#endif //__ASSEMBLY__ + +#endif //__EMHF_DMAPROT_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/xmhf-memprot.h b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-memprot.h new file mode 100644 index 0000000000..2e850eacdc --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-memprot.h @@ -0,0 +1,211 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF memory protection component +// declarations +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __EMHF_MEMPROT_H__ +#define __EMHF_MEMPROT_H__ + + +#ifndef __ASSEMBLY__ + +// memory protection types +#define MEMP_PROT_NOTPRESENT (1) // page not present +#define MEMP_PROT_PRESENT (2) // page present +#define MEMP_PROT_READONLY (4) // page read-only +#define MEMP_PROT_READWRITE (8) // page read-write +#define MEMP_PROT_EXECUTE (16) // page execute +#define MEMP_PROT_NOEXECUTE (32) // page no-execute +#define MEMP_PROT_MAXVALUE (MEMP_PROT_NOTPRESENT+MEMP_PROT_PRESENT+MEMP_PROT_READONLY+MEMP_PROT_READWRITE+MEMP_PROT_NOEXECUTE+MEMP_PROT_EXECUTE) + +//---------------------------------------------------------------------- +//exported DATA +//---------------------------------------------------------------------- + + +//---------------------------------------------------------------------- +//exported FUNCTIONS +//---------------------------------------------------------------------- + +//initialize memory protection for a core +void xmhf_memprot_initialize(VCPU *vcpu); + +// get level-1 page map address +u64 * xmhf_memprot_get_lvl1_pagemap_address(VCPU *vcpu); + +//get level-2 page map address +u64 * xmhf_memprot_get_lvl2_pagemap_address(VCPU *vcpu); + +//get level-3 page map address +u64 * xmhf_memprot_get_lvl3_pagemap_address(VCPU *vcpu); + +//get level-4 page map address +u64 * xmhf_memprot_get_lvl4_pagemap_address(VCPU *vcpu); + +//get default root page map address +u64 * xmhf_memprot_get_default_root_pagemap_address(VCPU *vcpu); + +//flush hardware page table mappings (TLB) +void xmhf_memprot_flushmappings(VCPU *vcpu); + +//flush the TLB of all nested page tables in the current core +void xmhf_memprot_flushmappings_localtlb(VCPU *vcpu); + +//set protection for a given physical memory address +void xmhf_memprot_setprot(VCPU *vcpu, u64 gpa, u32 prottype); + +//get protection for a given physical memory address +u32 xmhf_memprot_getprot(VCPU *vcpu, u64 gpa); + +// Is the given system paddr belong to mHV (XMHF + hypapp)? +bool xmhf_is_mhv_memory(spa_t spa); + +// On 32bit machine, we always return 0 - 4G as the machine physical address range, no matter how many memory is installed +// On 64-bit machine, the function queries the E820 map for the used memory region. +bool xmhf_get_machine_paddr_range(spa_t* machine_base_spa, spa_t* machine_limit_spa); + + +//---------------------------------------------------------------------- +//ARCH. BACKENDS +//---------------------------------------------------------------------- + +//initialize memory protection for a core +void xmhf_memprot_arch_initialize(VCPU *vcpu); + +// get level-1 page map address +u64 * xmhf_memprot_arch_get_lvl1_pagemap_address(VCPU *vcpu); + +//get level-2 page map address +u64 * xmhf_memprot_arch_get_lvl2_pagemap_address(VCPU *vcpu); + +//get level-3 page map address +u64 * xmhf_memprot_arch_get_lvl3_pagemap_address(VCPU *vcpu); + +//get level-4 page map address +u64 * xmhf_memprot_arch_get_lvl4_pagemap_address(VCPU *vcpu); + +//get default root page map address +u64 * xmhf_memprot_arch_get_default_root_pagemap_address(VCPU *vcpu); + +//handle RDMSR on MTRRs +u32 xmhf_memprot_arch_x86vmx_mtrr_read(VCPU *vcpu, u32 msr, u64 *val); + +//handle WRMSR on MTRRs +u32 xmhf_memprot_arch_x86vmx_mtrr_write(VCPU *vcpu, u32 msr, u64 val); + +//flush hardware page table mappings (TLB) +void xmhf_memprot_arch_flushmappings(VCPU *vcpu); + +//flush the TLB of all nested page tables in the current core +void xmhf_memprot_arch_flushmappings_localtlb(VCPU *vcpu); + +//set protection for a given physical memory address +void xmhf_memprot_arch_setprot(VCPU *vcpu, u64 gpa, u32 prottype); + +//get protection for a given physical memory address +u32 xmhf_memprot_arch_getprot(VCPU *vcpu, u64 gpa); + +// On 32bit machine, we always return 0 - 4G as the machine physical address range, no matter how many memory is installed +// On 64-bit machine, the function queries the E820 map for the used memory region. +bool xmhf_arch_get_machine_paddr_range(spa_t* machine_base_spa, spa_t* machine_limit_spa); + + +//---------------------------------------------------------------------- +//x86 ARCH. INTERFACES +//---------------------------------------------------------------------- + + +//---------------------------------------------------------------------- +//x86vmx SUBARCH. INTERFACES +//---------------------------------------------------------------------- + +void xmhf_memprot_arch_x86vmx_initialize(VCPU *vcpu); //initialize memory protection for a core +void xmhf_memprot_arch_x86vmx_flushmappings(VCPU *vcpu); //flush hardware page table mappings (TLB) +void xmhf_memprot_arch_x86vmx_flushmappings_localtlb(VCPU *vcpu); +void xmhf_memprot_arch_x86vmx_setprot(VCPU *vcpu, u64 gpa, u32 prottype); //set protection for a given physical memory address +u32 xmhf_memprot_arch_x86vmx_getprot(VCPU *vcpu, u64 gpa); //get protection for a given physical memory address +u64 xmhf_memprot_arch_x86vmx_get_EPTP(VCPU *vcpu); // get or set EPTP (only valid on Intel) +void xmhf_memprot_arch_x86vmx_set_EPTP(VCPU *vcpu, u64 eptp); + +//VMX EPT PML4 table buffers +extern u8 g_vmx_ept_pml4_table_buffers[] __attribute__(( section(".bss.palign_data") )); + +//VMX EPT PDP table buffers +extern u8 g_vmx_ept_pdp_table_buffers[] __attribute__(( section(".bss.palign_data") )); + +//VMX EPT PD table buffers +extern u8 g_vmx_ept_pd_table_buffers[] __attribute__(( section(".bss.palign_data") )); + +//VMX EPT P table buffers +extern u8 g_vmx_ept_p_table_buffers[] __attribute__(( section(".bss.palign_data") )); + + +//---------------------------------------------------------------------- +//x86svm SUBARCH. INTERFACES +//---------------------------------------------------------------------- + +void xmhf_memprot_arch_x86svm_initialize(VCPU *vcpu); //initialize memory protection for a core +void xmhf_memprot_arch_x86svm_flushmappings(VCPU *vcpu); //flush hardware page table mappings (TLB) +void xmhf_memprot_arch_x86svm_setprot(VCPU *vcpu, u64 gpa, u32 prottype); //set protection for a given physical memory address +u32 xmhf_memprot_arch_x86svm_getprot(VCPU *vcpu, u64 gpa); //get protection for a given physical memory address +u64 xmhf_memprot_arch_x86svm_get_h_cr3(VCPU *vcpu); // get or set host cr3 (only valid on AMD) +void xmhf_memprot_arch_x86svm_set_h_cr3(VCPU *vcpu, u64 hcr3); + +//SVM NPT PDPT buffers +extern u8 g_svm_npt_pdpt_buffers[] __attribute__(( section(".bss.palign_data") )); + +//SVM NPT PDT buffers +extern u8 g_svm_npt_pdts_buffers[]__attribute__(( section(".bss.palign_data") )); + +//SVM NPT PT buffers +extern u8 g_svm_npt_pts_buffers[]__attribute__(( section(".bss.palign_data") )); + + +#endif //__ASSEMBLY__ + +#endif //__EMHF_MEMPROT_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/xmhf-mm.h b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-mm.h new file mode 100644 index 0000000000..e3ab7b1dad --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-mm.h @@ -0,0 +1,42 @@ +// author: Miao Yu +#ifndef __XMHF_MM_H__ +#define __XMHF_MM_H__ + +#define XMHF_HEAP_SIZE (64*(1<<20)) +#ifndef __ASSEMBLY__ + +//! This struct records the information of memory allocation +//! This struct is stored in the caller provided memory allocation record list. +struct xmhf_mm_alloc_info +{ + void* hva; + uint32_t alignment; + size_t size; +}; + +void xmhf_mm_init(void); +void xmhf_mm_fini(void); +void* xmhf_mm_alloc_page(uint32_t num_pages); +void* xmhf_mm_malloc(size_t size); +void* xmhf_mm_malloc_align(uint32_t alignment, size_t size); +void xmhf_mm_free(void* ptr); + +//! Allocate an aligned memory from the heap of XMHF. Also it records the allocation in the +extern void* xmhf_mm_alloc_align_with_record(XMHFList* mm_alloc_infolist, uint32_t alignment, size_t size); + +//! Allocate a piece of memory from the heap of XMHF. Also it records the allocation in the +extern void* xmhf_mm_malloc_with_record(XMHFList* mm_alloc_infolist, size_t size); + +//! Allocate a memory page from the heap of XMHF. Also it records the allocation in the +extern void* xmhf_mm_alloc_page_with_record(XMHFList* mm_alloc_infolist, uint32_t num_pages); + +//! Free the memory allocated from the heap of XMHF. And also remove the record in the +extern void xmhf_mm_free_from_record(XMHFList* mm_alloc_infolist, void* ptr); + +//! @brief Free all the recorded memory +extern void xmhf_mm_free_all_records(XMHFList* mm_alloc_infolist); + + +#endif // __ASSEMBLY__ + +#endif // __XMHF_MM_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/xmhf-parteventhub.h b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-parteventhub.h new file mode 100644 index 0000000000..ecf6d6b39e --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-parteventhub.h @@ -0,0 +1,102 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF partition event-hub component declarations +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __EMHF_PARTEVENTHUB_H__ +#define __EMHF_PARTEVENTHUB_H__ + +#ifndef __ASSEMBLY__ + +//XXX: FIX this +//extern u8 * _svm_lib_guestpgtbl_walk(VCPU *vcpu, u32 vaddr); + +//XXX: FIX this +//extern u8 * _vmx_lib_guestpgtbl_walk(VCPU *vcpu, u32 vaddr); +extern void _vmx_putVMCS(VCPU *vcpu); +extern void _vmx_getVMCS(VCPU *vcpu); +extern void _vmx_dumpVMCS(VCPU *vcpu); + +extern u32 rdmsr_safe(struct regs *r); + +//---------------------------------------------------------------------- +//exported DATA +//---------------------------------------------------------------------- + + +//---------------------------------------------------------------------- +//exported FUNCTIONS +//---------------------------------------------------------------------- + + +//---------------------------------------------------------------------- +//ARCH. BACKENDS +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +//x86 ARCH. INTERFACES +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +//x86vmx SUBARCH. INTERFACES +//---------------------------------------------------------------------- +void xmhf_parteventhub_arch_x86vmx_entry(void); +u32 xmhf_parteventhub_arch_x86vmx_intercept_handler(VCPU *vcpu, struct regs *r); +#ifdef __UPDATE_INTEL_UCODE__ +void handle_intel_ucode_update(VCPU *vcpu, u64 update_data); +#endif /* __UPDATE_INTEL_UCODE__ */ + +//---------------------------------------------------------------------- +//x86svm SUBARCH. INTERFACES +//---------------------------------------------------------------------- +void xmhf_parteventhub_arch_x86svm_entry(void); +u32 xmhf_parteventhub_arch_x86svm_intercept_handler(VCPU *vcpu, struct regs *r); + + +#endif //__ASSEMBLY__ + +#endif //__EMHF_PARTEVENTHUB_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/xmhf-partition.h b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-partition.h new file mode 100644 index 0000000000..70a4dced5f --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-partition.h @@ -0,0 +1,147 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF partition component +// declarations +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __EMHF_PARTITION_H__ +#define __EMHF_PARTITION_H__ + +//partition legacy I/O protection types +#define PART_LEGACYIO_NOACCESS (1) //no access +#define PART_LEGACYIO_READWRITE (2) //read and write access + +//partition legacy I/O port sizes +#define PART_LEGACYIO_PORTSIZE_BYTE (1) //8-bit port +#define PART_LEGACYIO_PORTSIZE_WORD (2) //16-bit port +#define PART_LEGACYIO_PORTSIZE_DWORD (4) //32-bit port + + +#ifndef __ASSEMBLY__ + +//---------------------------------------------------------------------- +//exported DATA +//---------------------------------------------------------------------- + + +//---------------------------------------------------------------------- +//exported FUNCTIONS +//---------------------------------------------------------------------- + +//initialize partition monitor for a given CPU +void xmhf_partition_initializemonitor(VCPU *vcpu); + +//setup guest OS state for the partition +void xmhf_partition_setupguestOSstate(VCPU *vcpu); + +//start executing the partition and guest OS +void xmhf_partition_start(VCPU *vcpu); + +//set legacy I/O protection for the partition +void xmhf_partition_legacyIO_setprot(VCPU *vcpu, u32 port, u32 size, u32 prottype); + + +//---------------------------------------------------------------------- +//ARCH. BACKENDS +//---------------------------------------------------------------------- +//initialize partition monitor for a given CPU +void xmhf_partition_arch_initializemonitor(VCPU *vcpu); + +//setup guest OS state for the partition +void xmhf_partition_arch_setupguestOSstate(VCPU *vcpu); + +//start executing the partition and guest OS +void xmhf_partition_arch_start(VCPU *vcpu); + +//set legacy I/O protection for the partition +void xmhf_partition_arch_legacyIO_setprot(VCPU *vcpu, u32 port, u32 size, u32 prottype); + +//---------------------------------------------------------------------- +//x86 ARCH. INTERFACES +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +//x86vmx SUBARCH. INTERFACES +//---------------------------------------------------------------------- +//initialize partition monitor for a given CPU +void xmhf_partition_arch_x86vmx_initializemonitor(VCPU *vcpu); + +//setup guest OS state for the partition +void xmhf_partition_arch_x86vmx_setupguestOSstate(VCPU *vcpu); + +//start executing the partition and guest OS +void xmhf_partition_arch_x86vmx_start(VCPU *vcpu); + +//low-level HVM start routine (part-x86vmx-sup.S) +/* 32-bit EDX in i386, 64-bit RDX in amd64 */ +u32 __vmx_start_hvm(uint32_t rdx); + +//set legacy I/O protection for the partition +void xmhf_partition_arch_x86vmx_legacyIO_setprot(VCPU *vcpu, u32 port, u32 size, u32 prottype); + +//---------------------------------------------------------------------- +//x86svm SUBARCH. INTERFACES +//---------------------------------------------------------------------- +//initialize partition monitor for a given CPU +void xmhf_partition_arch_x86svm_initializemonitor(VCPU *vcpu); + +//setup guest OS state for the partition +void xmhf_partition_arch_x86svm_setupguestOSstate(VCPU *vcpu); + +//start executing the partition and guest OS +void xmhf_partition_arch_x86svm_start(VCPU *vcpu); + +//low-level HVM start routine (part-x86svm-sup.S) +void __svm_start_hvm(VCPU *vcpu, u32 vmcb_paddr); + +//set legacy I/O protection for the partition +void xmhf_partition_arch_x86svm_legacyIO_setprot(VCPU *vcpu, u32 port, u32 size, u32 prottype); + + +#endif //__ASSEMBLY__ + +#endif //__EMHF_PARTITION_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/xmhf-runtime.h b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-runtime.h new file mode 100644 index 0000000000..acc7329898 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-runtime.h @@ -0,0 +1,119 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF runtime component declarations +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __EMHF_RUNTIME_H__ +#define __EMHF_RUNTIME_H__ + +#define DMAPROT_PHY_ADDR_SPACE_SIZE (PA_PAGE_ALIGN_UP_NOCHK_1G(MAX_PHYS_ADDR)) +#define DMAPROT_VMX_P4L_NPDT (DMAPROT_PHY_ADDR_SPACE_SIZE >> PAGE_SHIFT_1G) + +// 4-level PML4 page tables + 4KB root entry table + 4K context entry table per PCI bus +#define SIZE_G_RNTM_DMAPROT_BUFFER (PAGE_SIZE_4K + PAGE_SIZE_4K + (PAGE_SIZE_4K * DMAPROT_VMX_P4L_NPDT) \ + + (PAGE_SIZE_4K * DMAPROT_VMX_P4L_NPDT * PAE_PTRS_PER_PDT) + PAGE_SIZE_4K + \ + (PAGE_SIZE_4K * PCI_BUS_MAX)) + +#ifndef __ASSEMBLY__ + +//---------------------------------------------------------------------- +//exported DATA +//---------------------------------------------------------------------- + +//runtime parameter block data area +//extern u8 arch_rpb[]; +extern RPB arch_rpb; + +//runtime parameter block pointer +extern RPB *rpb __attribute__(( section(".data") )); + +//runtime DMA protection buffer +extern u8 g_rntm_dmaprot_buffer[] __attribute__(( section(".bss.palign_data") )); + +//variable that is incremented by 1 by all cores that cycle through appmain +//successfully, this should be finally equal to g_midtable_numentries at +//runtime which signifies that EMHF appmain executed successfully on all +//cores +extern volatile u32 g_appmain_success_counter __attribute__(( section(".data") )); + +//SMP lock for the above variable +extern volatile u32 g_lock_appmain_success_counter __attribute__(( section(".data") )); + +//---------------------------------------------------------------------- +//exported FUNCTIONS +//---------------------------------------------------------------------- + +//entry point of EMHF runtime; this is where we get control from the SL +void xmhf_runtime_entry(void); + +//EMHF runtime main function; gets control in the context of each core +void xmhf_runtime_main(VCPU *vcpu, u32 isEarlyInit); + +//---------------------------------------------------------------------- +//ARCH. BACKENDS +//---------------------------------------------------------------------- + + +//---------------------------------------------------------------------- +//x86 ARCH. INTERFACES +//---------------------------------------------------------------------- + + + +//---------------------------------------------------------------------- +//x86vmx SUBARCH. INTERFACES +//---------------------------------------------------------------------- + + +//---------------------------------------------------------------------- +//x86svm SUBARCH. INTERFACES +//---------------------------------------------------------------------- + + +#endif //__ASSEMBLY__ + +#endif //__EMHF_RUNTIME_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/xmhf-sl.h b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-sl.h new file mode 100644 index 0000000000..0fbc6e24fc --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-sl.h @@ -0,0 +1,109 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF secure loader component declarations +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __EMHF_SL_H__ +#define __EMHF_SL_H__ + + +#ifndef __ASSEMBLY__ + +//---------------------------------------------------------------------- +//exported DATA +//---------------------------------------------------------------------- +extern u32 sl_baseaddr; + + +//---------------------------------------------------------------------- +//exported FUNCTIONS +//---------------------------------------------------------------------- + + +//---------------------------------------------------------------------- +//ARCH. BACKENDS +//---------------------------------------------------------------------- +void* xmhf_sl_arch_hva2sla(uintptr_t x); +u64 xmhf_sl_arch_sla2spa(void* x); +bool xmhf_sl_arch_integrity_check(u8* runtime_base_addr, size_t runtime_len); +void xmhf_sl_arch_sanitize_post_launch(void); +void xmhf_sl_arch_early_dmaprot_init(u32 runtime_size); +void xmhf_sl_arch_xfer_control_to_runtime(RPB * rpb); + + +//---------------------------------------------------------------------- +//x86 ARCH. INTERFACES +//---------------------------------------------------------------------- +#ifdef __AMD64__ +u64 xmhf_sl_arch_x86_setup_runtime_paging(RPB *rpb, spa_t runtime_spa, hva_t runtime_sva, hva_t totalsize); +void xmhf_setup_sl_paging(u32 baseaddr); +void xmhf_sl_arch_x86_invoke_runtime_entrypoint(u64 gdtbase, u64 idtbase, + u64 entrypoint, u64 stacktop, u64 cr3, u64 sla_off); +#elif defined(__I386__) +u32 xmhf_sl_arch_x86_setup_runtime_paging(RPB * rpb, u32 runtime_spa, u32 runtime_sva, u32 totalsize); +void xmhf_sl_arch_x86_invoke_runtime_entrypoint(u32 gdtbase, u32 idtbase, + u32 entrypoint, u32 stacktop, u32 cr3)__attribute__((cdecl)); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + +//---------------------------------------------------------------------- +//x86vmx SUBARCH. INTERFACES +//---------------------------------------------------------------------- + + +//---------------------------------------------------------------------- +//x86svm SUBARCH. INTERFACES +//---------------------------------------------------------------------- +extern u32 g_sl_protected_dmabuffer[]; //protected DMA-protection buffer + //for early DMA protection + //(only used for x86svm) + + +#endif //__ASSEMBLY__ + +#endif //__EMHF_SL_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/xmhf-smpguest.h b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-smpguest.h new file mode 100644 index 0000000000..17ed1a1449 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-smpguest.h @@ -0,0 +1,86 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF SMP guest component +// declarations +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __EMHF_SMPGUEST_H__ +#define __EMHF_SMPGUEST_H__ + +//bring in arch. specific declarations +#include + + +#ifndef __ASSEMBLY__ + +//---------------------------------------------------------------------- +//exported DATA +//---------------------------------------------------------------------- + + +//---------------------------------------------------------------------- +//exported FUNCTIONS +//---------------------------------------------------------------------- + +//initialize SMP guest logic +void xmhf_smpguest_initialize(VCPU *vcpu); + +//quiesce interface to switch all guest cores into hypervisor mode +//void xmhf_smpguest_quiesce(VCPU *vcpu); + +//endquiesce interface to resume all guest cores after a quiesce +//void xmhf_smpguest_endquiesce(VCPU *vcpu); + +//walk guest page tables; returns pointer to corresponding guest physical address +//note: returns 0xFFFFFFFF if there is no mapping +u8 * xmhf_smpguest_walk_pagetables(VCPU *vcpu, u32 vaddr); + + + +#endif //__ASSEMBLY__ + +#endif //__EMHF_SMPGUEST_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/xmhf-tpm.h b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-tpm.h new file mode 100644 index 0000000000..555d3bbf83 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-tpm.h @@ -0,0 +1,86 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF TPM component declarations +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __EMHF_TPM_H__ +#define __EMHF_TPM_H__ + + +//bring in arch. specific declarations +#include + + +#ifndef __ASSEMBLY__ + + +//---------------------------------------------------------------------- +//exported DATA +//---------------------------------------------------------------------- + + +//---------------------------------------------------------------------- +//exported FUNCTIONS +//---------------------------------------------------------------------- + +//open TPM locality +int xmhf_tpm_open_locality(int locality); + +//check if TPM is ready for use +bool xmhf_tpm_is_tpm_ready(uint32_t locality); + +//deactivate all TPM localities +void xmhf_tpm_deactivate_all_localities(void); + +//prepare TPM for use +bool xmhf_tpm_prepare_tpm(void); + + + +#endif //__ASSEMBLY__ + +#endif //__EMHF_TPM_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/xmhf-types.h b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-types.h new file mode 100644 index 0000000000..d50f06bdcc --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-types.h @@ -0,0 +1,172 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +//types.h - base types +#ifndef __EMHF_TYPES_H_ +#define __EMHF_TYPES_H_ + + +#ifndef __ASSEMBLY__ + +#define GB(x) (((size_t)(x)) << 30) +#define MB(x) (((size_t)(x)) << 20) +#define KB(x) (((size_t)(x)) << 10) + +// TODO: bootloader for 64 bit XMHF will have incorrect size +// Ideally, should change __AMD64__ to __XMHF_AMD64__ +#ifdef __I386__ + typedef u32 hva_t; // hypervisor virtual address + typedef u64 spa_t; // system physical address. [NOTE] spa_t could have a value larger than 4G; e.g., PC installs + // 8GB physical memory but installing 32-bit software stack. + typedef u64 spfn_t; // pfn of system physical address + typedef u32 gva_t; // guest virtual address + typedef u64 gpa_t; // guest physical address. can be 64-bit with PAE + typedef u32 sla_t; // secure loader address +#elif defined(__AMD64__) + typedef u64 hva_t; // hypervisor virtual address + typedef u64 spa_t; // system physical address + typedef u64 spfn_t; // pfn of system physical address + typedef u64 gva_t; // guest virtual address + typedef u64 gpa_t; // guest physical address + typedef u64 sla_t; // secure loader address +#else + #error "Unsupported Arch" +#endif /* __I386__ */ + + +#define INVALID_ADDR 0 +#define INVALID_VADDR (INVALID_ADDR) +#define INVALID_SPADDR (INVALID_ADDR) +#define INVALID_GPADDR (INVALID_ADDR) +#define INVALID_GVADDR (INVALID_ADDR) + +#define UINT32sToUINT64(high, low) (u64)((((u64)(high)) << 32) | (low)) +#ifdef __I386__ + #define UINT32sToSPADDR(high, low) (spa_t)(UINT32sToUINT64(high, low)) + #define UINT32sToSIZE(high, low) (size_t)(low) +#elif defined(__AMD64__) + #define UINT32sToSPADDR(high, low) (spa_t)(UINT32sToUINT64(high, low)) + #define UINT32sToSIZE(high, low) (size_t)(UINT32sToUINT64(high, low)) +#else + #error "Unsupported Arch" +#endif /* __I386__ */ + +#define ADDR_TO_PFN(addr) (addr >> PAGE_SHIFT_4K) + +//"golden" digest values injected using CFLAGS during build process +//NOTE: NO WAY TO SELF-CHECK slbelow64K; JUST A SANITY-CHECK +typedef struct _integrity_measurement_values { + u8 sha_slbelow64K[20]; // TODO: play nice with SHA_DIGEST_LENGTH in sha1.h + u8 sha_slabove64K[20]; + u8 sha_runtime[20]; +} INTEGRITY_MEASUREMENT_VALUES; + + +//"runtime" parameter block structure; arch_rpb (in startup component) +//is the default definition +typedef struct { + u32 magic; + hva_t XtVmmEntryPoint; +#ifdef __XMHF_AMD64__ + hva_t XtVmmPml4Base; +#endif /* __XMHF_AMD64__ */ + hva_t XtVmmPdptBase; + hva_t XtVmmPdtsBase; + hva_t XtGuestOSBootModuleBase; + hva_t XtGuestOSBootModuleSize; + hva_t runtime_appmodule_base; + hva_t runtime_appmodule_size; + u8 XtGuestOSBootDrive; /* drive used to boot (can be passed to INT 13h) */ + hva_t XtVmmStackBase; + hva_t XtVmmStackSize; + hva_t XtVmmGdt; + hva_t XtVmmIdt; + hva_t XtVmmIdtFunctionPointers; + u32 XtVmmIdtEntries; + sla_t XtVmmRuntimePhysBase; + hva_t XtVmmRuntimeVirtBase; + hva_t XtVmmRuntimeSize; + hva_t XtVmmE820Buffer; + u32 XtVmmE820NumEntries; + hva_t XtVmmMPCpuinfoBuffer; + u32 XtVmmMPCpuinfoNumEntries; + hva_t XtVmmTSSBase; + uart_config_t RtmUartConfig; /* runtime options parsed in init and passed forward */ + char cmdline[1024]; /* runtime options parsed in init and passed forward */ + u32 isEarlyInit; //1 for an "early init" else 0 (late-init) +} RPB, *PRPB; + + +//"sl" parameter block structure +typedef struct _sl_parameter_block { + u32 magic; // magic identifier + u32 errorHandler; // error handler (currently unused) + u32 isEarlyInit; // "early" or "late" init + u32 numE820Entries; // number of E820 entries + u8 memmapbuffer[1280]; // max. 64 entries of 20 bytes each describing the system memory map + u32 numCPUEntries; // number of cores + u8 cpuinfobuffer[128]; // max. 8 entries of 16 bytes each describing each physical core in the system + u32 runtime_size; // size of the runtime image + u32 runtime_osbootmodule_base; // guest OS bootmodule base + u32 runtime_osbootmodule_size; // guest OS bootmodule size + u32 runtime_appmodule_base; // XMHF hypapp optional module base + u32 runtime_appmodule_size; // XMHF hypapp optional module size + u64 rdtsc_before_drtm; // Performance measurements related to DRTM + u64 rdtsc_after_drtm; + u8 runtime_osbootdrive; // Boot drive number (usually 0x80) + + /* runtime options parsed in init and passed forward */ + uart_config_t uart_config; + char cmdline[1024]; /* runtime options parsed in init and passed forward */ +} SL_PARAMETER_BLOCK; + + + + + +#endif /*ifndef __ASSEMBLY__*/ + +#endif /* __EMHF_TYPES_H_ */ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/xmhf-var.h b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-var.h new file mode 100644 index 0000000000..e28cd9baeb --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-var.h @@ -0,0 +1,12 @@ +#ifndef __EMHF_VAR_H_ +#define __EMHF_VAR_H_ + +#ifndef __ASSEMBLY__ + +// Secure foreach +// we should use it as much as possible for every for statement +#define FOREACH_S(var_name, m1, m2, initial, step) for(var_name = (initial); (var_name < (m1)) && (var_name < (m2)); var_name += (step)) + + +#endif // __ASSEMBLY__ +#endif // VKDDK_VAR_H diff --git a/xmhf-64/xmhf/src/xmhf-core/include/xmhf-verification.h b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-verification.h new file mode 100644 index 0000000000..5ba2f24822 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-verification.h @@ -0,0 +1,69 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +//---------------------------------------------------------------------- +//xmhf-verification.h +//XMHF verification primitives header file +//author: amit vasudevan (amitvasudevan@acm.org) +//---------------------------------------------------------------------- + +#ifndef __XMHF_VERIFICATION_H__ +#define __XMHF_VERIFICATION_H__ + +#ifndef __ASSEMBLY__ + +#ifdef __XMHF_VERIFICATION__ + //CBMC SATABS internal functions for non-deterministic values + u32 nondet_u32(); + u64 nondet_u64(); + int nondet_int(); + u32* nondet_u32_ptr(); + u16 nondet_u16(); +#endif + +#endif //__ASSEMBLY__ + +#endif //__XMHF_VERIFICATION_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/xmhf-xcphandler.h b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-xcphandler.h new file mode 100644 index 0000000000..6056a6c60d --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/xmhf-xcphandler.h @@ -0,0 +1,101 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF exception handler component +// declarations +// author: amit vasudevan (amitvasudevan@acm.org) + +#ifndef __EMHF_XCPHANDLER_H__ +#define __EMHF_XCPHANDLER_H__ + +#define EMHF_XCPHANDLER_MAXEXCEPTIONS 32 +#define EMHF_XCPHANDLER_IDTSIZE (EMHF_XCPHANDLER_MAXEXCEPTIONS * 8) + +#ifndef __ASSEMBLY__ + +//---------------------------------------------------------------------- +//exported DATA + +//array of exception handler stubs +extern u8 xmhf_xcphandler_exceptionstubs[]; + +//IDT descriptor +extern u8 xmhf_xcphandler_idt[]; + +//start of interrupt descriptor table +extern u8 xmhf_xcphandler_idt_start[]; + +//---------------------------------------------------------------------- +//exported FUNCTIONS + +//initialize EMHF core exception handlers +void xmhf_xcphandler_initialize(void); + +//get IDT start address +u8 * xmhf_xcphandler_get_idt_start(void); + +//EMHF exception handler hub +void xmhf_xcphandler_hub(uintptr_t vector, struct regs *r); + + +//---------------------------------------------------------------------- +// generic arch. interfaces + +//initialize EMHF core exception handlers +void xmhf_xcphandler_arch_initialize(void); + +//get IDT start address +u8 * xmhf_xcphandler_arch_get_idt_start(void); + +//EMHF exception handler hub +void xmhf_xcphandler_arch_hub(uintptr_t vector, struct regs *r); + + + + +#endif //__ASSEMBLY__ + +#endif //__EMHF_XCPHANDLER_H__ diff --git a/xmhf-64/xmhf/src/xmhf-core/include/xmhf.h b/xmhf-64/xmhf/src/xmhf-core/include/xmhf.h new file mode 100644 index 0000000000..ad1f150ed3 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/include/xmhf.h @@ -0,0 +1,123 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +//xmhf.h - main XMHF core header file +// this orchestrates the inclusion of other core component specific +// headers +//author: amit vasudevan (amitvasudevan@acm.org) +// +#ifndef __XMHF_H_ +#define __XMHF_H_ + + +//pull in required C99 compatible C-library interfaces +//libXMHFc +#ifndef __ASSEMBLY__ + + #include + #include + #include + #include + #include + #include + #include + #ifndef __XMHF_VERIFICATION__ + #include + #endif +#endif /* __ASSEMBLY__ */ + +//pull in required crypto (SHA-1) +//libXMHFcrypto +#ifndef __ASSEMBLY__ + #include + #include +#endif /* __ASSEMBLY__ */ + + +//pull in required TPM library +//libtpm +#ifndef __ASSEMBLY__ + #include +#endif /* __ASSEMBLY__ */ + +#include //XMHF debug component +#include //XMHF specific base types +#include + +#ifdef __XMHF_VERIFICATION__ + //include verification related primitives + #include +#endif //__XMHF_VERIFICATION__ + +//forward declaration of runtime parameter block +#ifndef __ASSEMBLY__ +extern RPB *rpb; +#endif //__ASSEMBLY__ + +// STL for XMHF +#include +#include + +//---------------------------------------------------------------------- +// component headers +#include // Global configurations of XMHF +#include //XMHF base platform component +#include //XMHF memory management component +#include //XMHF memory protection component +#ifdef __DMAP__ +#include //XMHF DMA protection component +#endif /* __DMAP__ */ +#include //XMHF partition component +#include //XMHF SMP guest component +#include //XMHF partition event-hub component +#include //XMHF exception handler component +#include //XMHF Trusted Platform Module component +#include //XMHF secure loader component +#include //XMHF runtime component +#include //XMHF Application callback declarations + + +#endif /* __XMHF_H_ */ diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/Makefile b/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/Makefile new file mode 100644 index 0000000000..787267585c --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/Makefile @@ -0,0 +1,88 @@ +# makefile for "init" +# author: amit vasudevan (amitvasudevan@acm.org) + +CFLAGS := $(BCFLAGS) +ASFLAGS := $(BASFLAGS) +CCLIB := $(BCCLIB) + +# source files +AS_SOURCES = header.S initsup.S +C_SOURCES = init.c smp.c cmdline.c +ifeq ($(DRT), y) +C_SOURCES += txt.c txt_acmod.c txt_heap.c txt_hash.c +endif + +OBJECTS = $(patsubst %.S, %.o, $(AS_SOURCES)) +OBJECTS += $(patsubst %.c, %.o, $(C_SOURCES)) + +OBJECTS_PRECOMPILED = ../xmhf-runtime/xmhf-debug/lib.a + +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-tpm/tpm-interface.o +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-tpm/arch/x86/tpm-x86.o +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-tpm/arch/x86/svm/tpm-x86svm.o +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-tpm/arch/x86/vmx/tpm-x86vmx.o + +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-pci.o +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-acpi.o +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-i386-smplock.o +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-addressing.o +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-cpu.o + +ifeq ($(DRT), y) +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx-mtrrs.o +endif + +# FIXME: This is overly general; init/ doesn't need all of these +CFLAGS += $(ADDL_INCLUDES_BOOTLOADER) + +# separate from OBJECTS_PRECOMPILED becasue needs to come after libs on link line +OBJECTS_PRECOMPILED_LIBBACKENDS = ../xmhf-runtime/xmhf-xmhfcbackend/xmhfc-putchar.o + +I_SOURCES = $(wildcard $(INCLUDEDIR)/*.h) + + +# Bootloader is always i386. If runtime is amd64, bootloader need to switch to +# i386 version of precompiled object files. +ifeq ($(TARGET_SUBARCH), amd64) +OBJECTS_PRECOMPILED := $(patsubst %.o, %.i386.o, $(OBJECTS_PRECOMPILED)) +OBJECTS_PRECOMPILED := $(patsubst %.a, %.i386.a, $(OBJECTS_PRECOMPILED)) +OBJECTS_PRECOMPILED_LIBBACKENDS := $(patsubst %.o, %.i386.o, $(OBJECTS_PRECOMPILED_LIBBACKENDS)) +endif + + +# NOTE: THIS IS THE init MODULE. IT IS COMPLETELY UNTRUSTED. THESE +# VALUES ARE HERE SIMPLY TO AID IN DEVELOPMENT AND DEBUGGING, TO STOP +# EARLY IN THE EVENT OF MISTAKES. DO NOT RELY ON THEM! + +# RUNTIME_INTEGRITY_HASH should be set by parent Makefile +ifdef RUNTIME_INTEGRITY_HASH +CFLAGS += -D___RUNTIME_INTEGRITY_HASH___=\"$(RUNTIME_INTEGRITY_HASH)\" +endif +# SLABOVE64K_INTEGRITY_HASH should be set by parent Makefile +ifdef SLABOVE64K_INTEGRITY_HASH +CFLAGS += -D___SLABOVE64K_INTEGRITY_HASH___=\"$(SLABOVE64K_INTEGRITY_HASH)\" +endif +# SLBELOW64K_INTEGRITY_HASH should be set by parent Makefile +ifdef SLBELOW64K_INTEGRITY_HASH +CFLAGS += -D___SLBELOW64K_INTEGRITY_HASH___=\"$(SLBELOW64K_INTEGRITY_HASH)\" +endif + + +# targets +.PHONY: all +all: init-$(TARGET_HWPLATFORM)-$(TARGET_SUBARCH).bin + +# FIXME: ADDL_LIBS is overly general; init/ doesn't need all of them +init-$(TARGET_HWPLATFORM)-$(TARGET_SUBARCH).bin: $(OBJECTS) $(OBJECTS_PRECOMPILED) init.lds.S + $(LD) -T init.lds.S -o init.exe $(OBJECTS) $(OBJECTS_PRECOMPILED) $(ADDL_LIBS_BOOTLOADER) $(OBJECTS_PRECOMPILED_LIBBACKENDS) -L$(CCLIB) -lgcc + $(CP) init.exe init_syms.exe + $(STRIP) -s init.exe + $(OBJCOPY) --output-format=binary init.exe init-$(TARGET_HWPLATFORM)-$(TARGET_SUBARCH).bin + +.PHONY: clean +clean: + $(RM) -rf *.o + $(RM) -rf *.exe + $(RM) -rf *.bin + $(RM) -rf *.gz + diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/cmdline.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/cmdline.c new file mode 100644 index 0000000000..4fa90513ac --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/cmdline.c @@ -0,0 +1,464 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * cmdline.c: command line parsing fns + * + * Copyright (c) 2006-2010, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/** + * Modified for XMHF. + */ + +#include +#include + +/* + * copy of original command line + * part of tboot measurement (hence in .text section) + * FIXME - is this getting measured? + */ +char g_cmdline[CMDLINE_SIZE] = { 0 }; + +/* + * the option names and default values must be separate from the actual + * params entered + * this allows the names and default values to be part of the MLE measurement + * param_values[] need to be in .bss section so that will get cleared on launch + */ + +/* global option array for command line */ +static const cmdline_option_t g_tboot_cmdline_options[] = { + { "loglvl", "all" }, /* all|none */ + { "logging", "serial,vga" }, /* vga,serial,memory|none */ + { "serial", "115200,8n1,0x3f8" }, + { "boot_drive", "0x80" }, + /* serial=[/][,[,[,[,[,]]]]] */ + + /* { "vga_delay", "0" }, /\* # secs *\/ */ + /* { "no_usb", "true" }, /\* true|false *\/ */ + { NULL, NULL } +}; + +/* static const cmdline_option_t g_linux_cmdline_options[] = { */ +/* { "vga", "" }, */ +/* { "mem", "" }, */ +/* { NULL, NULL } */ +/* }; */ +/* static char g_linux_param_values[ARRAY_SIZE(g_linux_cmdline_options)][MAX_VALUE_LEN]; */ +static char g_tboot_param_values[ARRAY_SIZE(g_tboot_cmdline_options)][MAX_VALUE_LEN]; + + +void tboot_parse_cmdline(void) +{ + cmdline_parse(g_cmdline, g_tboot_cmdline_options, g_tboot_param_values); +} + +/* void linux_parse_cmdline(char *cmdline) */ +/* { */ +/* cmdline_parse(cmdline, g_linux_cmdline_options, g_linux_param_values); */ +/* } */ + +void get_tboot_loglvl(void) +{ + const char *loglvl = cmdline_get_option_val(g_tboot_cmdline_options, + g_tboot_param_values, "loglvl"); + if ( loglvl == NULL ) + return; + + if ( strcmp(loglvl, "none") == 0 ) + g_log_level = LOG_LEVEL_NONE; /* print nothing */ +} + +void get_tboot_log_targets(void) +{ + const char *targets = cmdline_get_option_val(g_tboot_cmdline_options, + g_tboot_param_values, "logging"); + + /* nothing set, leave defaults */ + if ( targets == NULL || *targets == '\0' ) + return; + + /* determine if no targets set explicitly */ + if ( strcmp(targets, "none") == 0 ) { + g_log_targets = LOG_TARGET_NONE; /* print nothing */ + return; + } + + /* else init to nothing and parse the possible targets */ + g_log_targets = LOG_TARGET_NONE; + + while ( *targets != '\0' ) { + if ( strncmp(targets, "memory", 6) == 0 ) { + g_log_targets |= LOG_TARGET_MEMORY; + targets += 6; + } + else if ( strncmp(targets, "serial", 6) == 0 ) { + g_log_targets |= LOG_TARGET_SERIAL; + targets += 6; + } + else if ( strncmp(targets, "vga", 3) == 0 ) { + g_log_targets |= LOG_TARGET_VGA; + targets += 3; + } + else + break; /* unrecognized, end loop */ + + if ( *targets == ',' ) + targets++; + else + break; /* unrecognized, end loop */ + } +} + +/* static bool parse_pci_bdf(const char **bdf, uint32_t *bus, uint32_t *slot, */ +/* uint32_t *func) */ +/* { */ +/* *bus = strtoul(*bdf, bdf, 16); */ +/* if ( **bdf != ':' ) */ +/* return false; */ +/* (*bdf)++; */ +/* *slot = strtoul(*bdf, bdf, 16); */ +/* if ( **bdf != '.' ) */ +/* return false; */ +/* (*bdf)++; */ +/* *func = strtoul(*bdf, bdf, 16); */ + +/* return true; */ +/* } */ + +/* bool g_psbdf_enabled = false; */ +/* static bool parse_com_psbdf(const char **bdf) */ +/* { */ +/* g_psbdf_enabled = parse_pci_bdf(bdf, */ +/* &g_com_port.comc_psbdf.bus, */ +/* &g_com_port.comc_psbdf.slot, */ +/* &g_com_port.comc_psbdf.func); */ + +/* return g_psbdf_enabled; */ +/* } */ + +/* bool g_pbbdf_enabled = false; */ +/* static bool parse_com_pbbdf(const char **bdf) */ +/* { */ +/* g_pbbdf_enabled = parse_pci_bdf(bdf, */ +/* &g_com_port.comc_pbbdf.bus, */ +/* &g_com_port.comc_pbbdf.slot, */ +/* &g_com_port.comc_pbbdf.func); */ + +/* return g_pbbdf_enabled; */ +/* } */ + +#if defined (__DEBUG_SERIAL__) + +static bool parse_com_fmt(const char **fmt) +{ + /* fmt: <5|6|7|8><0|1> */ + /* default 8n1 */ + /* uint8_t data_bits = 8; */ + /* uint8_t parity = 'n'; */ + /* uint8_t stop_bits = 1; */ + + /* must specify all values */ + if ( strlen(*fmt) < 3 ) + return false; + + /* data bits */ + if ( **fmt >= '5' && **fmt <= '8' ) + g_uart_config.data_bits = **fmt - '0'; + else + return false; + (*fmt)++; + + /* parity */ + if ( **fmt == 'n' || **fmt == 'o' || **fmt == 'e' || **fmt == 'm' || + **fmt == 's' ) + g_uart_config.parity = + (**fmt == 'n') + ? PARITY_NONE + : (**fmt == 'o') + ? PARITY_ODD + : (**fmt == 'e') + ? PARITY_EVEN + : (**fmt == 'm') + ? PARITY_MARK + : PARITY_SPACE; + else + return false; + (*fmt)++; + + /* stop bits */ + if ( **fmt == '0' || **fmt == '1' ) + g_uart_config.stop_bits = **fmt - '0'; + else + return false; + (*fmt)++; + + return true; +} + +static bool parse_serial_param(const char *com) +{ + /* parse baud */ + g_uart_config.baud = strtoul(com, &com, 10); + if ( (g_uart_config.baud < 1200) || + (g_uart_config.baud > 115200) ) + return false; + + /* parse clock hz */ + if ( *com == '/' ) { + ++com; + g_uart_config.clock_hz = strtoul(com, &com, 0) << 4; + if ( g_uart_config.clock_hz == 0 ) + return false; + } + + /* parse data_bits/parity/stop_bits */ + if ( *com != ',' ) + goto exit; + ++com; + while ( isspace(*com) ) + com++; + if ( !parse_com_fmt(&com) ) + return false; + + /* parse IO base */ + if ( *com != ',' ) + goto exit; + ++com; + g_uart_config.port = strtoul(com, &com, 0); + if ( g_uart_config.port == 0 ) + return false; + + /* we don't handle additional params */ + if ( *com == ',' ) { + return false; + } + + /* parse irq */ + /* if ( *com != ',' ) */ + /* goto exit; */ + /* ++com; */ + /* g_com_port.comc_irq = strtoul(com, &com, 10); */ + /* if ( g_com_port.comc_irq == 0 ) */ + /* return false; */ + + /* /\* parse PCI serial controller bdf *\/ */ + /* if ( *com != ',' ) */ + /* goto exit; */ + /* ++com; */ + /* if ( !parse_com_psbdf(&com) ) */ + /* return false; */ + + /* /\* parse PCI bridge bdf *\/ */ + /* if ( *com != ',' ) */ + /* goto exit; */ + /* ++com; */ + /* if ( !parse_com_pbbdf(&com) ) */ + /* return false; */ + + exit: + return true; +} + +bool get_tboot_serial(void) +{ + const char *serial = cmdline_get_option_val(g_tboot_cmdline_options, + g_tboot_param_values, "serial"); + if ( serial == NULL || *serial == '\0' ) + return false; + + return parse_serial_param(serial); +} + +#endif + +u8 get_tboot_boot_drive() +{ + const char *boot_drive = cmdline_get_option_val(g_tboot_cmdline_options, + g_tboot_param_values, + "boot_drive"); + if (boot_drive == NULL) { + return 0x80u; + } + return (u8)strtoul(boot_drive, NULL, 0); +} + +/* void get_tboot_vga_delay(void) */ +/* { */ +/* const char *vga_delay = cmdline_get_option_val(g_tboot_cmdline_options, */ +/* g_tboot_param_values, "vga_delay"); */ +/* if ( vga_delay == NULL ) */ +/* return; */ + +/* g_vga_delay = strtoul(vga_delay, NULL, 0); */ +/* } */ + +/* void get_tboot_no_usb(void) */ +/* { */ +/* const char *no_usb = cmdline_get_option_val(g_tboot_cmdline_options, */ +/* g_tboot_param_values, "no_usb"); */ +/* if ( no_usb == NULL ) */ +/* return; */ + +/* g_no_usb = ( strcmp(no_usb, "true") == 0 ); */ +/* } */ + + +/* + * linux kernel command line parsing + */ + +/* bool get_linux_vga(int *vid_mode) */ +/* { */ +/* const char *vga = cmdline_get_option_val(g_linux_cmdline_options, */ +/* g_linux_param_values, "vga"); */ +/* if ( vga == NULL || vid_mode == NULL ) */ +/* return false; */ + +/* if ( strcmp(vga, "normal") == 0 ) */ +/* *vid_mode = 0xFFFF; */ +/* else if ( strcmp(vga, "ext") == 0 ) */ +/* *vid_mode = 0xFFFE; */ +/* else if ( strcmp(vga, "ask") == 0 ) */ +/* *vid_mode = 0xFFFD; */ +/* else */ +/* *vid_mode = strtoul(vga, NULL, 0); */ + +/* return true; */ +/* } */ + +/* bool get_linux_mem(uint64_t *max_mem) */ +/* { */ +/* char *last = NULL; */ +/* const char *mem = cmdline_get_option_val(g_linux_cmdline_options, */ +/* g_linux_param_values, "mem"); */ +/* if ( mem == NULL || max_mem == NULL ) */ +/* return false; */ + +/* *max_mem = strtoul(mem, &last, 0); */ +/* if ( *max_mem == 0 ) */ +/* return false; */ + +/* if ( last == NULL ) */ +/* return true; */ + +/* switch ( *last ) { */ +/* case 'G': */ +/* case 'g': */ +/* *max_mem = *max_mem << 30; */ +/* return true; */ +/* case 'M': */ +/* case 'm': */ +/* *max_mem = *max_mem << 20; */ +/* return true; */ +/* case 'K': */ +/* case 'k': */ +/* *max_mem = *max_mem << 10; */ +/* return true; */ +/* default: */ +/* return false; */ +/* } */ + +/* return true; */ +/* } */ + +/* const char *skip_filename(const char *cmdline) */ +/* { */ +/* if ( cmdline == NULL || *cmdline == '\0' ) */ +/* return cmdline; */ + +/* /\* strip leading spaces, file name, then any spaces until the next */ +/* non-space char (e.g. " /foo/bar baz" -> "baz"; "/foo/bar" -> "")*\/ */ +/* while ( *cmdline != '\0' && isspace(*cmdline) ) */ +/* cmdline++; */ +/* while ( *cmdline != '\0' && !isspace(*cmdline) ) */ +/* cmdline++; */ +/* while ( *cmdline != '\0' && isspace(*cmdline) ) */ +/* cmdline++; */ +/* return cmdline; */ +/* } */ + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/header.S b/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/header.S new file mode 100644 index 0000000000..65aadeead4 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/header.S @@ -0,0 +1,87 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include + + .section .multiboot_header + + .align 4 + .global multiboot_header +multiboot_header: + .long 0x1BADB002 + .long 0x10003 + .long -(0x1BAEB005) + .long multiboot_header + .long multiboot_header + .long 0 + .long 0 + .long init_start + .long 0 + .long 0 + .long 0 + .long 0 + + .extern cstartup + .section .text + .global init_start +init_start: + + movl $(init_stack + INIT_STACK_SIZE), %esp + + pushl $0 + popf + + pushl %ebx + //pushl %eax + call cstartup + +halt: + hlt + jmp halt + + .section .stack +init_stack: + .fill INIT_STACK_SIZE, 1, 0 diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/init.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/init.c new file mode 100644 index 0000000000..f1c0fe634d --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/init.c @@ -0,0 +1,1090 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +//init.c - EMHF early initialization blob functionality +//author: amit vasudevan (amitvasudevan@acm.org) + +//---includes------------------------------------------------------------------- +#include + + +//---forward prototypes--------------------------------------------------------- +u32 smp_getinfo(PCPU *pcpus, u32 *num_pcpus); +void cstartup(multiboot_info_t *mbi); +MPFP * MP_GetFPStructure(void); +u32 _MPFPComputeChecksum(u32 spaddr, u32 size); +u32 isbsp(void); + +//---globals-------------------------------------------------------------------- +PCPU pcpus[MAX_PCPU_ENTRIES]; +u32 pcpus_numentries=0; +u32 cpu_vendor; //CPU_VENDOR_INTEL or CPU_VENDOR_AMD +u32 hypervisor_image_baseaddress; //2M aligned highest physical memory address +//where the hypervisor binary is relocated to +GRUBE820 grube820list[MAX_E820_ENTRIES]; +u32 grube820list_numentries=0; //actual number of e820 entries returned +//by grub + +//master-id table which holds LAPIC ID to VCPU mapping for each physical core +MIDTAB midtable[MAX_MIDTAB_ENTRIES] __attribute__(( section(".data") )); + +//number of physical cores in the system +u32 midtable_numentries=0; + +//VCPU buffers for all cores +VCPU vcpubuffers[MAX_VCPU_ENTRIES] __attribute__(( section(".data") )); + +//initial stacks for all cores +u8 cpustacks[RUNTIME_STACK_SIZE * MAX_PCPU_ENTRIES] __attribute__(( section(".stack") )); + +SL_PARAMETER_BLOCK *slpb = NULL; + +#ifdef __DRT__ +/* TODO: refactor to eliminate a lot of these globals, or at least use + * static where appropriate */ +static u8 *g_sinit_module_ptr = NULL; +static u32 g_sinit_module_size = 0; +#endif /* __DRT__ */ + +extern void init_core_lowlevel_setup(void); + +/* Don't break the build if the Makefile fails to define these. */ +#ifndef ___RUNTIME_INTEGRITY_HASH___ +#define ___RUNTIME_INTEGRITY_HASH___ BAD_INTEGRITY_HASH +#endif /* ___RUNTIME_INTEGRITY_HASH___ */ +#ifndef ___SLABOVE64K_INTEGRITY_HASH___ +#define ___SLABOVE64K_INTEGRITY_HASH___ BAD_INTEGRITY_HASH +#endif /* ___SLABOVE64K_INTEGRITY_HASH___ */ +#ifndef ___SLBELOW64K_INTEGRITY_HASH___ +#define ___SLBELOW64K_INTEGRITY_HASH___ BAD_INTEGRITY_HASH +#endif /* ___SLBELOW64K_INTEGRITY_HASH___ */ + +// we should get all of these from the build process, but don't forget +// that here in 'init' these values are UNTRUSTED +INTEGRITY_MEASUREMENT_VALUES g_init_gold /* __attribute__(( section("") )) */ = { + .sha_runtime = ___RUNTIME_INTEGRITY_HASH___, + .sha_slabove64K = ___SLABOVE64K_INTEGRITY_HASH___, + .sha_slbelow64K = ___SLBELOW64K_INTEGRITY_HASH___ +}; + +//size of SL + runtime in bytes +size_t sl_rt_size; + + +//---MP config table handling--------------------------------------------------- +void dealwithMP(void){ + if(!smp_getinfo(pcpus, &pcpus_numentries)){ + printf("\nFatal error with SMP detection. Halting!"); + HALT(); + } +} + + +//---microsecond delay---------------------------------------------------------- +void udelay(u32 usecs){ + u8 val; + u32 latchregval; + + //enable 8254 ch-2 counter + val = inb(0x61); + val &= 0x0d; //turn PC speaker off + val |= 0x01; //turn on ch-2 + outb(val, 0x61); + + //program ch-2 as one-shot + outb(0xB0, 0x43); + + //compute appropriate latch register value depending on usecs + latchregval = ((u64)1193182 * usecs) / 1000000; + + HALT_ON_ERRORCOND(latchregval < (1 << 16)); + + //write latch register to ch-2 + val = (u8)latchregval; + outb(val, 0x42); + val = (u8)((u32)latchregval >> (u32)8); + outb(val , 0x42); + + //wait for countdown + while(!(inb(0x61) & 0x20)); + + //disable ch-2 counter + val = inb(0x61); + val &= 0x0c; + outb(val, 0x61); +} + + +//---INIT IPI routine----------------------------------------------------------- +void send_init_ipi_to_all_APs(void) { + u32 eax, edx; + volatile u32 *icr; + u32 timeout = 0x01000000; + + //read LAPIC base address from MSR + rdmsr(MSR_APIC_BASE, &eax, &edx); + HALT_ON_ERRORCOND( edx == 0 ); //APIC is below 4G + printf("\nLAPIC base and status=0x%08x", eax); + + icr = (u32 *) (((u32)eax & 0xFFFFF000UL) + 0x300); + + //send INIT + printf("\nSending INIT IPI to all APs..."); + *icr = 0x000c4500UL; + udelay(10000); + //wait for command completion + { + u32 val; + do{ + val = *icr; + }while(--timeout > 0 && (val & 0x1000) ); + } + if(timeout == 0) { + printf("\nERROR: send_init_ipi_to_all_APs() TIMEOUT!\n"); + } + printf("\nDone.\n"); +} + + + +//---E820 parsing and handling-------------------------------------------------- +//runtimesize is assumed to be 2M aligned +u32 dealwithE820(multiboot_info_t *mbi, u32 runtimesize __attribute__((unused))){ + //check if GRUB has a valid E820 map + if(!(mbi->flags & MBI_MEMMAP)){ + printf("\n%s: no E820 map provided. HALT!", __FUNCTION__); + HALT(); + } + + //zero out grub e820 list + memset((void *)&grube820list, 0, sizeof(GRUBE820)*MAX_E820_ENTRIES); + + //grab e820 list into grube820list + { + // TODO: grube820list_numentries < MAX_E820_ENTRIES not checked. + // Possible buffer overflow? + memory_map_t *mmap; + for ( mmap = (memory_map_t *) mbi->mmap_addr; + (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length; + mmap = (memory_map_t *) ((unsigned long) mmap + + mmap->size + sizeof (mmap->size))){ + grube820list[grube820list_numentries].baseaddr_low = mmap->base_addr_low; + grube820list[grube820list_numentries].baseaddr_high = mmap->base_addr_high; + grube820list[grube820list_numentries].length_low = mmap->length_low; + grube820list[grube820list_numentries].length_high = mmap->length_high; + grube820list[grube820list_numentries].type = mmap->type; + grube820list_numentries++; + } + } + + //debug: print grube820list + { + u32 i; + printf("\noriginal system E820 map follows:\n"); + for(i=0; i < grube820list_numentries; i++){ + printf("\n0x%08x%08x, size=0x%08x%08x (%u)", + grube820list[i].baseaddr_high, grube820list[i].baseaddr_low, + grube820list[i].length_high, grube820list[i].length_low, + grube820list[i].type); + } + + } + + //traverse e820 list forward to find an entry with type=0x1 (free) + //with free amount of memory for runtime + { + u32 foundentry=0; + u32 slruntimephysicalbase=__TARGET_BASE_SL; //SL + runtime base + u32 i; + + //for(i= (int)(grube820list_numentries-1); i >=0; i--){ + for(i= 0; i < grube820list_numentries; i++){ + u32 baseaddr, size; + baseaddr = grube820list[i].baseaddr_low; + size = grube820list[i].length_low; + + if(grube820list[i].type == 0x1){ //free memory? + if(grube820list[i].baseaddr_high) //greater than 4GB? then skip + continue; + + if(grube820list[i].length_high){ + printf("\n%s: E820 parsing error (64-bit length for < 4GB). HALT!"); + HALT(); + } + + //check if this E820 range can accomodate SL + runtime + if( slruntimephysicalbase >= baseaddr && (slruntimephysicalbase + runtimesize) < (baseaddr + size) ){ + foundentry=1; + break; + } + } + } + + if(!foundentry){ + printf("\n%s: unable to find E820 memory for SL+runtime. HALT!"); + HALT(); + } + + //entry number we need to split is indexed by i + printf("\nproceeding to revise E820..."); + + { + + //temporary E820 table with index + GRUBE820 te820[MAX_E820_ENTRIES]; + u32 j=0; + + //copy all entries from original E820 table until index i + for(j=0; j < i; j++) + memcpy((void *)&te820[j], (void *)&grube820list[j], sizeof(GRUBE820)); + + //we need a maximum of 2 extra entries for the final table, make a sanity check + HALT_ON_ERRORCOND( (grube820list_numentries+2) < MAX_E820_ENTRIES ); + + //split entry i into required number of entries depending on the memory range alignments + if( (slruntimephysicalbase == grube820list[i].baseaddr_low) && ((slruntimephysicalbase+runtimesize) == (grube820list[i].baseaddr_low+grube820list[i].length_low)) ){ + //exact match, no split + te820[j].baseaddr_high=0; te820[j].length_high=0; te820[j].baseaddr_low=grube820list[i].baseaddr_low; te820[j].length_low=grube820list[i].length_low; te820[j].type=grube820list[i].type; + j++; + i++; + }else if ( (slruntimephysicalbase == grube820list[i].baseaddr_low) && (runtimesize < grube820list[i].length_low) ){ + //left aligned, split into 2 + te820[j].baseaddr_high=0; te820[j].length_high=0; te820[j].baseaddr_low=grube820list[i].baseaddr_low; te820[j].length_low=runtimesize; te820[j].type=0x2; + j++; + te820[j].baseaddr_high=0; te820[j].length_high=0; te820[j].baseaddr_low=grube820list[i].baseaddr_low+runtimesize; te820[j].length_low=grube820list[i].length_low-runtimesize; te820[j].type=1; + j++; + i++; + }else if ( ((slruntimephysicalbase+runtimesize) == (grube820list[i].baseaddr_low+grube820list[i].length_low)) && slruntimephysicalbase > grube820list[i].baseaddr_low ){ + //right aligned, split into 2 + te820[j].baseaddr_high=0; te820[j].length_high=0; te820[j].baseaddr_low=grube820list[i].baseaddr_low; te820[j].length_low=slruntimephysicalbase-grube820list[i].baseaddr_low; te820[j].type=0x1; + j++; + te820[j].baseaddr_high=0; te820[j].length_high=0; te820[j].baseaddr_low= slruntimephysicalbase; te820[j].length_low=runtimesize; te820[j].type=0x1; + j++; + i++; + }else{ + //range in the middle, split into 3 + te820[j].baseaddr_high=0; te820[j].length_high=0; te820[j].baseaddr_low=grube820list[i].baseaddr_low; te820[j].length_low=slruntimephysicalbase-grube820list[i].baseaddr_low; te820[j].type=0x1; + j++; + te820[j].baseaddr_high=0; te820[j].length_high=0; te820[j].baseaddr_low=slruntimephysicalbase; te820[j].length_low=runtimesize; te820[j].type=0x2; + j++; + te820[j].baseaddr_high=0; te820[j].length_high=0; te820[j].baseaddr_low=slruntimephysicalbase+runtimesize; te820[j].length_low=grube820list[i].length_low-runtimesize-(slruntimephysicalbase-grube820list[i].baseaddr_low); te820[j].type=1; + j++; + i++; + } + + //copy entries i through end of original E820 list into temporary E820 list starting at index j + while(i < grube820list_numentries){ + memcpy((void *)&te820[j], (void *)&grube820list[i], sizeof(GRUBE820)); + i++; + j++; + } + + //copy temporary E820 list into global E20 list and setup final E820 entry count + grube820list_numentries = j; + memcpy((void *)&grube820list, (void *)&te820, (grube820list_numentries * sizeof(GRUBE820)) ); + } + + printf("\nE820 revision complete."); + + //debug: print grube820list + { + u32 i; + printf("\nrevised system E820 map follows:\n"); + for(i=0; i < grube820list_numentries; i++){ + printf("\n0x%08x%08x, size=0x%08x%08x (%u)", + grube820list[i].baseaddr_high, grube820list[i].baseaddr_low, + grube820list[i].length_high, grube820list[i].length_low, + grube820list[i].type); + } + } + + + return slruntimephysicalbase; + } + +} + +#ifdef __DRT__ +/* Run tests to determine if platform supports TXT. Note that this + * enables SMX on the platform, but is safe to run more than once. */ +/* Based primarily on tboot-20101005's txt/verify.c */ +bool txt_supports_txt(void) { + + u32 cpuid_ext_feat_info, dummy; + u64 feat_ctrl_msr; + capabilities_t cap; + + cpuid(1, &dummy, &dummy, &cpuid_ext_feat_info, &dummy); + feat_ctrl_msr = rdmsr64(MSR_EFCR); + + /* Check for VMX support */ + if ( !(cpuid_ext_feat_info & CPUID_X86_FEATURE_VMX) ) { + printf("ERR: CPU does not support VMX\n"); + return false; + } + printf("CPU is VMX-capable\n"); + /* and that VMX is enabled in the feature control MSR */ + if ( !(feat_ctrl_msr & IA32_FEATURE_CONTROL_MSR_ENABLE_VMX_IN_SMX) ) { + printf("ERR: VMXON disabled by feature control MSR (%llx)\n", + feat_ctrl_msr); + return false; + } + + + /* Check that processor supports SMX instructions */ + if ( !(cpuid_ext_feat_info & CPUID_X86_FEATURE_SMX) ) { + printf("ERR: CPU does not support SMX\n"); + return false; + } + printf("CPU is SMX-capable\n"); + + /* and that SENTER (w/ full params) is enabled */ + if ( !(feat_ctrl_msr & (IA32_FEATURE_CONTROL_MSR_ENABLE_SENTER | + IA32_FEATURE_CONTROL_MSR_SENTER_PARAM_CTL)) ) { + printf("ERR: SENTER disabled by feature control MSR (%llx)\n", + feat_ctrl_msr); + return false; + } + printf("SENTER should work.\n"); + + /* testing for chipset support requires enabling SMX on the processor */ + write_cr4(read_cr4() | CR4_SMXE); + printf("SMX enabled in CR4\n"); + + /* Verify that an TXT-capable chipset is present and check that + * all needed SMX capabilities are supported. */ + + cap = (capabilities_t)__getsec_capabilities(0); + if(!cap.chipset_present) { + printf("ERR: TXT-capable chipset not present\n"); + return false; + } + if (!(cap.senter && cap.sexit && cap.parameters && cap.smctrl && + cap.wakeup)) { + printf("ERR: insufficient SMX capabilities (0x%08x)\n", cap._raw); + return false; + } + printf("TXT chipset and all needed capabilities (0x%08x) present\n", cap._raw); + + return true; +} + +/* Inspired by tboot-20101005/tboot/txt/verify.c */ +tb_error_t txt_verify_platform(void) +{ + txt_heap_t *txt_heap; + txt_ests_t ests; + + printf("txt_verify_platform\n"); + + /* check TXT supported */ + if(!txt_supports_txt()) { + printf("FATAL ERROR: TXT not supported\n"); + HALT(); + } + + /* check is TXT_RESET.STS is set, since if it is SENTER will fail */ + ests = (txt_ests_t)read_pub_config_reg(TXTCR_ESTS); + if ( ests.txt_reset_sts ) { + printf("TXT_RESET.STS is set and SENTER is disabled (%llx)\n", + ests._raw); + return TB_ERR_SMX_NOT_SUPPORTED; + } + + /* verify BIOS to OS data */ + txt_heap = get_txt_heap(); + if ( !verify_bios_data(txt_heap) ) + return TB_ERR_FATAL; + + return TB_ERR_NONE; +} + + +/* Read values in TXT status registers */ +/* Some tboot-20101005 code from tboot/txt/errors.c */ +void txt_status_regs(void) { + txt_errorcode_t err; + txt_ests_t ests; + txt_e2sts_t e2sts; + txt_errorcode_sw_t sw_err; + acmod_error_t acmod_err; + + err = (txt_errorcode_t)read_pub_config_reg(TXTCR_ERRORCODE); + printf("TXT.ERRORCODE=%llx\n", err._raw); + + /* AC module error (don't know how to parse other errors) */ + if ( err.valid ) { + if ( err.external == 0 ) /* processor error */ + printf("\t processor error %x\n", (uint32_t)err.type); + else { /* external SW error */ + sw_err._raw = err.type; + if ( sw_err.src == 1 ) /* unknown SW error */ + printf("unknown SW error %x:%x\n", sw_err.err1, sw_err.err2); + else { /* ACM error */ + acmod_err._raw = sw_err._raw; + printf("AC module error : acm_type=%x, progress=%02x, " + "error=%x\n", acmod_err.acm_type, acmod_err.progress, + acmod_err.error); + /* error = 0x0a, progress = 0x0d => error2 is a TPM error */ + if ( acmod_err.error == 0x0a && acmod_err.progress == 0x0d ) + printf("TPM error code = %x\n", acmod_err.error2); + } + } + } + + /* + * display LT.ESTS error + */ + ests = (txt_ests_t)read_pub_config_reg(TXTCR_ESTS); + printf("LT.ESTS=%llx\n", ests._raw); + + /* + * display LT.E2STS error + * - only valid if LT.WAKE-ERROR.STS set in LT.STS reg + */ + if ( ests.txt_wake_error_sts ) { + e2sts = (txt_e2sts_t)read_pub_config_reg(TXTCR_E2STS); + printf("LT.E2STS=%llx\n", e2sts._raw); + } +} + +/* Transfer control to the SL using GETSEC[SENTER] */ +/*///XXX TODO not fully functional yet. Expected flow: +txt_prepare_cpu(); +txt_verify_platform(); +// Legacy USB? + // disable legacy USB #SMIs + get_tboot_no_usb(); + disable_smis(); +prepare_tpm(); +txt_launch_environment(mbi);*/ + +bool txt_do_senter(void *phys_mle_start, size_t mle_size) { + tb_error_t err; + + txt_status_regs(); + + if((err = txt_verify_platform()) != TB_ERR_NONE) { + printf("ERROR: txt_verify_platform returned 0x%08x\n", (u32)err); + return false; + } + if(!txt_prepare_cpu()) { + printf("ERROR: txt_prepare_cpu failed.\n"); + return false; + } + + ///XXX TODO get addresses of SL, populate a mle_hdr_t + txt_launch_environment(g_sinit_module_ptr, g_sinit_module_size, + phys_mle_start, mle_size); + + return false; /* unreachable if launch is successful, thus should return failure */ +} + +/** + * Check each module to see if it is an SINIT module. If it is, set + * the globals g_sinit_module_ptr and g_sinit_module_size to point to + * it. + * + * Returns true if an SINIT module was found, false otherwise. + */ +static bool txt_parse_sinit(module_t *mod_array, unsigned int mods_count) { + int i; + unsigned int bytes; + + /* I can't think of a legitimate reason why this would ever be + * this large. */ + if(mods_count > 10) { + return false; + } + + for(i=(int)mods_count-1; i >= 0; i--) { + bytes = mod_array[i].mod_end - mod_array[i].mod_start; + printf("\nChecking whether MBI module %i is SINIT...\n", i); + if(is_sinit_acmod((void*)mod_array[i].mod_start, bytes, false)) { + g_sinit_module_ptr = (u8*)mod_array[i].mod_start; + g_sinit_module_size = bytes; + printf("YES! SINIT found @ %p, %d bytes\n", + g_sinit_module_ptr, g_sinit_module_size); + return true; + } else { + printf("no.\n"); + } + } + + return false; +} + +//---svm_verify_platform------------------------------------------------------- +//do some basic checks on SVM platform to ensure DRTM should work as expected +static bool svm_verify_platform(void) __attribute__((unused)); +static bool svm_verify_platform(void) +{ + uint32_t eax, edx, ebx, ecx; + uint64_t efer; + + cpuid(0x80000001, &eax, &ebx, &ecx, &edx); + + if ((ecx & SVM_CPUID_FEATURE) == 0) { + printf("ERR: CPU does not support AMD SVM\n"); + return false; + } + + /* Check whether SVM feature is disabled in BIOS */ + rdmsr(VM_CR_MSR, &eax, &edx); + if (eax & VM_CR_SVME_DISABLE) { + printf("ERR: AMD SVM Extension is disabled in BIOS\n"); + return false; + } + + /* Turn on SVM */ + efer = rdmsr64(MSR_EFER); + wrmsr64(MSR_EFER, efer | (1< this is implicit in even getting this far */ + /* since our bootstrap code loads a GDT, etc. */ + + /* must be in protected mode */ + cr0 = read_cr0(); + if (!(cr0 & CR0_PE)) { + printf("ERR: not in protected mode\n"); + return false; + } + + /* make sure the APIC is enabled */ + apicbase = rdmsr64(MSR_APIC_BASE); + if (!(apicbase & MSR_IA32_APICBASE_ENABLE)) { + printf("APIC disabled\n"); + return false; + } + + /* verify all machine check status registers are clear */ + + /* no machine check in progress (IA32_MCG_STATUS.MCIP=1) */ + mcg_stat = rdmsr64(MSR_MCG_STATUS); + if (mcg_stat & 0x04) { + printf("machine check in progress\n"); + return false; + } + + /* all machine check regs are clear */ + mcg_cap = rdmsr64(MSR_MCG_CAP); + bound = (u32)mcg_cap & 0x000000ff; + for (i = 0; i < bound; i++) { + mcg_stat = rdmsr64(MSR_MC0_STATUS + 4*i); + if (mcg_stat & (1ULL << 63)) { + printf("MCG[%d] = %llx ERROR\n", i, mcg_stat); + return false; + } + } + + printf("no machine check errors\n"); + + /* clear microcode on all the APs handled in mp_cstartup() */ + /* put all APs in INIT handled in do_drtm() */ + + /* all is well with the processor state */ + printf("CPU is ready for SKINIT\n"); + + return true; +} +#endif /* __DRT__ */ + +//---do_drtm-------------------------------------------------------------------- +//this establishes a dynamic root of trust +//inputs: +//cpu_vendor = intel or amd +//slbase= physical memory address of start of sl +void do_drtm(VCPU __attribute__((unused))*vcpu, u32 slbase, size_t mle_size __attribute__((unused))){ +#ifdef __MP_VERSION__ + HALT_ON_ERRORCOND(vcpu->id == 0); + //send INIT IPI to all APs + send_init_ipi_to_all_APs(); + printf("\nINIT(early): sent INIT IPI to APs"); +#endif + +#if defined (__DRT__) + + if(vcpu->cpu_vendor == CPU_VENDOR_AMD){ + if(!svm_verify_platform()) { + printf("\nINIT(early): ERROR: svm_verify_platform FAILED!\n"); + HALT(); + } + if(!svm_prepare_cpu()) { + printf("\nINIT(early): ERROR: svm_prepare_cpu FAILED!\n"); + HALT(); + } + //issue SKINIT + //our secure loader is the first 64K of the hypervisor image + printf("\nINIT(early): transferring control to SL via SKINIT..."); + #ifndef PERF_CRIT + if(NULL != slpb) { + slpb->rdtsc_before_drtm = rdtsc64(); + } + #endif + skinit((u32)slbase); + } else { + printf("\n****** INIT(early): Begin TXT Stuff ******\n"); + txt_do_senter((void*)(slbase+3*PAGE_SIZE_4K), TEMPORARY_HARDCODED_MLE_SIZE); + printf("\nINIT(early): error(fatal), should never come here!"); + HALT(); + } + +#else //!__DRT__ + //don't use SKINIT or SENTER + { + u32 sl_entry_point; + u16 *sl_entry_point_offset = (u16 *)slbase; + typedef void(*FCALL)(void); + FCALL invokesl; + + printf("\n****** NO DRTM startup ******\n"); + printf("\nslbase=0x%08x, sl_entry_point_offset=0x%08x", (u32)slbase, *sl_entry_point_offset); + sl_entry_point = (u32)slbase + (u32) (*sl_entry_point_offset); + invokesl = (FCALL)(u32)sl_entry_point; + printf("\nSL entry point to transfer control to: 0x%08x", invokesl); + invokesl(); + printf("\nINIT(early): error(fatal), should never come here!"); + HALT(); + } +#endif + +} + + +void setupvcpus(u32 cpu_vendor, MIDTAB *midtable, u32 midtable_numentries){ + u32 i; + VCPU *vcpu; + + printf("\n%s: cpustacks range 0x%08x-0x%08x in 0x%08x chunks", + __FUNCTION__, (u32)cpustacks, (u32)cpustacks + (RUNTIME_STACK_SIZE * MAX_VCPU_ENTRIES), + RUNTIME_STACK_SIZE); + printf("\n%s: vcpubuffers range 0x%08x-0x%08x in 0x%08x chunks", + __FUNCTION__, (u32)vcpubuffers, (u32)vcpubuffers + (SIZE_STRUCT_VCPU * MAX_VCPU_ENTRIES), + SIZE_STRUCT_VCPU); + + for(i=0; i < midtable_numentries; i++){ + vcpu = (VCPU *)((u32)vcpubuffers + (u32)(i * SIZE_STRUCT_VCPU)); + memset((void *)vcpu, 0, sizeof(VCPU)); + + vcpu->cpu_vendor = cpu_vendor; + + vcpu->esp = ((u32)cpustacks + (i * RUNTIME_STACK_SIZE)) + RUNTIME_STACK_SIZE; + vcpu->id = midtable[i].cpu_lapic_id; + + midtable[i].vcpu_vaddr_ptr = (u32)vcpu; + printf("\nCPU #%u: vcpu_vaddr_ptr=0x%08x, esp=0x%08x", i, midtable[i].vcpu_vaddr_ptr, + vcpu->esp); + } +} + + +//---wakeupAPs------------------------------------------------------------------ +void wakeupAPs(void){ + u32 eax, edx; + volatile u32 *icr; + + //read LAPIC base address from MSR + rdmsr(MSR_APIC_BASE, &eax, &edx); + HALT_ON_ERRORCOND( edx == 0 ); //APIC is below 4G + //printf("\nLAPIC base and status=0x%08x", eax); + + icr = (u32 *) (((u32)eax & 0xFFFFF000UL) + 0x300); + + { + extern u32 _ap_bootstrap_start[], _ap_bootstrap_end[]; + memcpy((void *)0x10000, (void *)_ap_bootstrap_start, (u32)_ap_bootstrap_end - (u32)_ap_bootstrap_start + 1); + } + + //our test code is at 1000:0000, we need to send 10 as vector + //send INIT + printf("\nSending INIT IPI to all APs..."); + *icr = 0x000c4500UL; + udelay(10000); + //wait for command completion + { + u32 val; + do{ + val = *icr; + }while( (val & 0x1000) ); + } + printf("Done."); + + //send SIPI (twice as per the MP protocol) + { + int i; + for(i=0; i < 2; i++){ + printf("\nSending SIPI-%u...", i); + *icr = 0x000c4610UL; + udelay(200); + //wait for command completion + { + u32 val; + do{ + val = *icr; + }while( (val & 0x1000) ); + } + printf("Done."); + } + } + + printf("\nAPs should be awake!"); +} + +/* The TPM must be ready for the AMD CPU to send it commands at + * Locality 4 when executing SKINIT. Ideally all that is necessary is + * to xmhf_tpm_deactivate_all_localities(), but some TPM's are still not + * sufficiently "awake" after that. Thus, make sure it successfully + * responds to a command at some locality, *then* + * xmhf_tpm_deactivate_all_localities(). + */ +bool svm_prepare_tpm(void) { + uint32_t locality = EMHF_TPM_LOCALITY_PREF; /* target.h */ + bool ret = true; + + printf("\nINIT:TPM: prepare_tpm starting."); + //dump_locality_access_regs(); + xmhf_tpm_deactivate_all_localities(); + //dump_locality_access_regs(); + + if(TPM_SUCCESS == tpm_wait_cmd_ready(locality)) { + printf("INIT:TPM: successfully opened in Locality %d.\n", locality); + } else { + printf("INIT:TPM: ERROR: Locality %d could not be opened.\n", locality); + ret = false; + } + xmhf_tpm_deactivate_all_localities(); + //dump_locality_access_regs(); + printf("\nINIT:TPM: prepare_tpm done."); + + return ret; +} + +//---init main---------------------------------------------------------------- +void cstartup(multiboot_info_t *mbi){ + module_t *mod_array; + u32 mods_count; + + /* parse command line */ + memset(g_cmdline, '\0', sizeof(g_cmdline)); + strncpy(g_cmdline, (char*)mbi->cmdline, sizeof(g_cmdline)-1); + g_cmdline[sizeof(g_cmdline)-1] = '\0'; /* in case strncpy truncated */ + tboot_parse_cmdline(); + +#if defined (__DEBUG_SERIAL__) + /* parse serial port params */ + { + uart_config_t uart_config_backup = g_uart_config; + if(!get_tboot_serial()) { + /* TODO: What's going on here? Redundant? */ + g_uart_config = uart_config_backup; + } + } + + //initialize debugging early on + xmhf_debug_init((char *)&g_uart_config); +#endif + + mod_array = (module_t*)mbi->mods_addr; + mods_count = mbi->mods_count; + + //welcome banner + printf("\neXtensible Modular Hypervisor Framework (XMHF) %s", ___XMHF_BUILD_VERSION___); + printf("\nBuild revision: %s", ___XMHF_BUILD_REVISION___); +#ifdef __XMHF_AMD64__ + printf("\nSubarch: amd64\n"); +#else /* !__XMHF_AMD64__ */ + printf("\nSubarch: i386\n"); +#endif /* __XMHF_AMD64__ */ + + printf("\nINIT(early): initializing, total modules=%u", mods_count); + + //check CPU type (Intel vs AMD) + cpu_vendor = get_cpu_vendor_or_die(); // HALT()'s if unrecognized + + if(CPU_VENDOR_INTEL == cpu_vendor) { + printf("\nINIT(early): detected an Intel CPU"); + +#ifdef __DRT__ + /* Intel systems require an SINIT module */ + if(!txt_parse_sinit(mod_array, mods_count)) { + printf("\nINIT(early): FATAL ERROR: Intel CPU without SINIT module!\n"); + HALT(); + } +#endif /* __DRT__ */ + } else if(CPU_VENDOR_AMD == cpu_vendor) { + printf("\nINIT(early): detected an AMD CPU"); + } else { + printf("\nINIT(early): Dazed and confused: Unknown CPU vendor %d\n", cpu_vendor); + } + + //deal with MP and get CPU table + dealwithMP(); + + //find highest 2MB aligned physical memory address that the hypervisor + //binary must be moved to + sl_rt_size = mod_array[0].mod_end - mod_array[0].mod_start; + hypervisor_image_baseaddress = dealwithE820(mbi, PAGE_ALIGN_UP_2M((sl_rt_size))); + + //relocate the hypervisor binary to the above calculated address + memcpy((void*)hypervisor_image_baseaddress, (void*)mod_array[0].mod_start, sl_rt_size); + + HALT_ON_ERRORCOND(sl_rt_size > 0x200000); /* 2M */ + + /* runtime */ + print_hex(" INIT(early): *UNTRUSTED* gold runtime: ", + g_init_gold.sha_runtime, SHA_DIGEST_LENGTH); + hashandprint(" INIT(early): *UNTRUSTED* comp runtime: ", + (u8*)hypervisor_image_baseaddress+0x200000, sl_rt_size-0x200000); + /* SL low 64K */ + print_hex(" INIT(early): *UNTRUSTED* gold SL low 64K: ", + g_init_gold.sha_slbelow64K, SHA_DIGEST_LENGTH); + hashandprint(" INIT(early): *UNTRUSTED* comp SL low 64K: ", + (u8*)hypervisor_image_baseaddress, 0x10000); + /* SL above 64K */ + print_hex(" INIT(early): *UNTRUSTED* gold SL above 64K: ", + g_init_gold.sha_slabove64K, SHA_DIGEST_LENGTH); + hashandprint(" INIT(early): *UNTRUSTED* comp SL above 64K): ", + (u8*)hypervisor_image_baseaddress+0x10000, 0x200000-0x10000); + + + //print out stats + printf("\nINIT(early): relocated hypervisor binary image to 0x%08x", hypervisor_image_baseaddress); + printf("\nINIT(early): 2M aligned size = 0x%08lx", PAGE_ALIGN_UP_2M((mod_array[0].mod_end - mod_array[0].mod_start))); + printf("\nINIT(early): un-aligned size = 0x%08x", mod_array[0].mod_end - mod_array[0].mod_start); + + //fill in "sl" parameter block + { + //"sl" parameter block is at hypervisor_image_baseaddress + 0x10000 + slpb = (SL_PARAMETER_BLOCK *)((u32)hypervisor_image_baseaddress + 0x10000); + HALT_ON_ERRORCOND(slpb->magic == SL_PARAMETER_BLOCK_MAGIC); + slpb->errorHandler = 0; + slpb->isEarlyInit = 1; //this is an "early" init + slpb->numE820Entries = grube820list_numentries; + //memcpy((void *)&slpb->e820map, (void *)&grube820list, (sizeof(GRUBE820) * grube820list_numentries)); + memcpy((void *)&slpb->memmapbuffer, (void *)&grube820list, (sizeof(GRUBE820) * grube820list_numentries)); + slpb->numCPUEntries = pcpus_numentries; + //memcpy((void *)&slpb->pcpus, (void *)&pcpus, (sizeof(PCPU) * pcpus_numentries)); + memcpy((void *)&slpb->cpuinfobuffer, (void *)&pcpus, (sizeof(PCPU) * pcpus_numentries)); + slpb->runtime_size = (mod_array[0].mod_end - mod_array[0].mod_start) - PAGE_SIZE_2M; + slpb->runtime_osbootmodule_base = mod_array[1].mod_start; + slpb->runtime_osbootmodule_size = (mod_array[1].mod_end - mod_array[1].mod_start); + slpb->runtime_osbootdrive = get_tboot_boot_drive(); + + //check if we have an optional app module and if so populate relevant SLPB + //fields + { + u32 i, start, bytes; + slpb->runtime_appmodule_base= 0; + slpb->runtime_appmodule_size= 0; + + //we search from module index 2 upto and including mods_count-1 + //and grab the first non-SINIT module in the list + for(i=2; i < mods_count; i++) { + start = mod_array[i].mod_start; + bytes = mod_array[i].mod_end - start; +#ifdef __DRT__ + if (is_sinit_acmod((void*) start, bytes, false)) { + continue; + } +#endif /* __DRT__ */ + /* Found app module */ + slpb->runtime_appmodule_base = start; + slpb->runtime_appmodule_size = bytes; + printf("\nINIT(early): found app module, base=0x%08x, size=0x%08x", + slpb->runtime_appmodule_base, slpb->runtime_appmodule_size); + break; + } + } + +#if defined (__DEBUG_SERIAL__) + slpb->uart_config = g_uart_config; +#endif + strncpy(slpb->cmdline, (const char *)mbi->cmdline, sizeof(slpb->cmdline)); + } + + //switch to MP mode + //setup Master-ID Table (MIDTABLE) + { + int i; + for(i=0; i < (int)pcpus_numentries; i++){ + midtable[midtable_numentries].cpu_lapic_id = pcpus[i].lapic_id; + midtable[midtable_numentries].vcpu_vaddr_ptr = 0; + midtable_numentries++; + } + } + + //setup vcpus + setupvcpus(cpu_vendor, midtable, midtable_numentries); + + //wakeup all APs + if(midtable_numentries > 1) + wakeupAPs(); + + //fall through and enter mp_cstartup via init_core_lowlevel_setup + init_core_lowlevel_setup(); + + printf("\nINIT(early): error(fatal), should never come here!"); + HALT(); +} + +//---isbsp---------------------------------------------------------------------- +//returns 1 if the calling CPU is the BSP, else 0 +u32 isbsp(void){ + u32 eax, edx; + //read LAPIC base address from MSR + rdmsr(MSR_APIC_BASE, &eax, &edx); + HALT_ON_ERRORCOND( edx == 0 ); //APIC is below 4G + + if(eax & 0x100) + return 1; + else + return 0; +} + + +//---CPUs must all have their microcode cleared for SKINIT to be successful----- +void svm_clear_microcode(VCPU *vcpu){ + u32 ucode_rev; + u32 dummy=0; + + // Current microcode patch level available via MSR read + rdmsr(MSR_AMD64_PATCH_LEVEL, &ucode_rev, &dummy); + printf("\nCPU(0x%02x): existing microcode version 0x%08x", vcpu->id, ucode_rev); + + if(ucode_rev != 0) { + wrmsr(MSR_AMD64_PATCH_CLEAR, dummy, dummy); + printf("\nCPU(0x%02x): microcode CLEARED", vcpu->id); + } +} + + +u32 cpus_active=0; //number of CPUs that are awake, should be equal to +//midtable_numentries -1 if all went well with the +//MP startup protocol +u32 lock_cpus_active=1; //spinlock to access the above + + +//------------------------------------------------------------------------------ +//all cores enter here +void mp_cstartup (VCPU *vcpu){ + //sanity, we should be an Intel or AMD core + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_INTEL || + vcpu->cpu_vendor == CPU_VENDOR_AMD); + + if(isbsp()){ + //clear microcode if AMD CPU + if(vcpu->cpu_vendor == CPU_VENDOR_AMD){ + printf("\nBSP(0x%02x): Clearing microcode...", vcpu->id); + svm_clear_microcode(vcpu); + printf("\nBSP(0x%02x): Microcode clear.", vcpu->id); + + if(!svm_prepare_tpm()) { + printf("\nBSP(0x%02x): ERROR: svm_prepare_tpm FAILED.", vcpu->id); + // XXX TODO HALT(); + } + } + + printf("\nBSP(0x%02x): Rallying APs...", vcpu->id); + + //increment a CPU to account for the BSP + spin_lock(&lock_cpus_active); + cpus_active++; + spin_unlock(&lock_cpus_active); + + //wait for cpus_active to become midtable_numentries -1 to indicate + //that all APs have been successfully started + while(cpus_active < midtable_numentries); + + + //put all APs in INIT state + + printf("\nBSP(0x%02x): APs ready, doing DRTM...", vcpu->id); + do_drtm(vcpu, hypervisor_image_baseaddress, sl_rt_size); // this function will not return + + printf("\nBSP(0x%02x): FATAL, should never be here!", vcpu->id); + HALT(); + + }else{ + //clear microcode if AMD CPU + if(vcpu->cpu_vendor == CPU_VENDOR_AMD){ + printf("\nAP(0x%02x): Clearing microcode...", vcpu->id); + svm_clear_microcode(vcpu); + printf("\nAP(0x%02x): Microcode clear.", vcpu->id); + } + + //update the AP startup counter + spin_lock(&lock_cpus_active); + cpus_active++; + spin_unlock(&lock_cpus_active); + + printf("\nAP(0x%02x): Waiting for DRTM establishment...", vcpu->id); + + HALT(); + } + + +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/init.lds.S b/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/init.lds.S new file mode 100644 index 0000000000..3328fa5a32 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/init.lds.S @@ -0,0 +1,115 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/*OUTPUT_FORMAT("pe-i386")*/ +OUTPUT_ARCH(i386) + +ENTRY(init_start) + +MEMORY +{ + all (rwxai) : ORIGIN = 0x1E00000, LENGTH = 100M /* length is arbitrary */ + debug (rwxai) : ORIGIN = 0, LENGTH = 1024M + unaccounted (rwxai) : ORIGIN = 0, LENGTH = 0 /* see section .unaccounted at end */ +} + +SECTIONS +{ + . = 0x1E00000; + .multiboot_header : { + *(.multiboot_header) + . = ALIGN(4096); + } = 0x9090 + + .text : { + *(.text) + *(.text.unlikely) + . = ALIGN(4096); + } =0x9090 + + .data : { + *(.data) + *(.rodata) + *(.rodata.str1.*) + *(.eh_frame) + *(.bss) + . = ALIGN(4096); + } =0x9090 + + .stack : { + *(.stack) + . = ALIGN(4096); + } =0x9090 + + /DISCARD/ : { + *(.comment) + *(.note.gnu.property) + *(.gnu.build.attributes) + } + + /* debug sections */ + .debug_abbrev : { *(.debug_abbrev) } >debug + .debug_aranges : { *(.debug_aranges) } >debug + .debug_info : { *(.debug_info) } >debug + .debug_line : { *(.debug_line) } >debug + .debug_line_str : { *(.debug_line_str) } >debug + .debug_loc : { *(.debug_loc) } >debug + .debug_loclists : { *(.debug_loclists) } >debug + .debug_ranges : { *(.debug_ranges) } >debug + .debug_rnglists : { *(.debug_rnglists) } >debug + .debug_str : { *(.debug_str) } >debug + + /* this is to cause the link to fail if there is + * anything we didn't explicitly place. + * when this does cause link to fail, temporarily comment + * this part out to see what sections end up in the output + * which are not handled above, and handle them. + */ + .unaccounted : { + *(*) + } >unaccounted + +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/initsup.S b/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/initsup.S new file mode 100644 index 0000000000..f2ba0712a4 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/initsup.S @@ -0,0 +1,163 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// init low-level support routines +// author: amit vasudevan (amitvasudevan@acm.org) + +#include + +.extern midtable_numentries +.extern mp_cstartup +.extern midtable + +//---AP boot-strap code--------------------------------------------------------- +.section .text + .code16 + .global _ap_bootstrap_start + _ap_bootstrap_start: + jmp ap_bootstrap_bypassdata + _ap_gdtdesc: + .word _ap_gdt_end - _ap_gdt_start - 1 + .long _ap_gdt_start - _ap_bootstrap_start + 0x10000 + .align 16 + _ap_gdt_start: + .quad 0x0000000000000000 + .quad 0x00cf9a000000ffff + .quad 0x00cf92000000ffff + _ap_gdt_end: + .word 0 + ap_bootstrap_bypassdata: + movw $0x1000, %ax + movw %ax, %ds + movw %ax, %es + movw $0xFFFF, %sp + movw $0x4000, %ax + movw %ax, %ss + + movw $0x0002, %si + + lgdt (%si) + + movl %cr0, %eax + orl $0x1, %eax + movl %eax, %cr0 + + jmpl $0x08, $(_ap_clear_pipe - _ap_bootstrap_start + (AP_BOOTSTRAP_CODE_SEG << 4)) + .code32 + _ap_clear_pipe: + movw $0x10, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %ss + movw %ax, %fs + movw %ax, %gs + + movl $init_core_lowlevel_setup, %eax + jmpl *%eax + hlt + + .global _ap_bootstrap_end + _ap_bootstrap_end: + nop + nop + nop + nop + +//---init_core_lowlevel_setup--------------------------------------------------- +.section .text + .global init_core_lowlevel_setup + init_core_lowlevel_setup: + + //load our gdt + lgdt init_gdt + + //get hold of local APIC id + mov $(MSR_APIC_BASE), %ecx + rdmsr + andl $0xFFFFF000, %eax + addl $0x20, %eax + movl (%eax), %eax + shr $24, %eax + + movl midtable_numentries, %edx + + //get vcpu virtual address of this CPU/core + movl $(midtable), %ebx + xorl %ecx, %ecx +getvcpuloop: + movl 0x0(%ebx, %ecx, 8), %ebp //ebp contains the lapic id + cmpl %eax, %ebp + jz gotvcpu + incl %ecx + cmpl %edx, %ecx + jb getvcpuloop + //we should never get here, if so just halt + hlt +gotvcpu: + movl 0x4(%ebx, %ecx, 8), %esi //esi contains vcpu pointer + movl 0x0(%esi), %esp //load stack for this CPU + pushl %esi + call mp_cstartup + //we should never get here, if so just halt + hlt + + + +//------------------------------------------------------------------------------ +.section .data + + //the GDT + init_gdt: + .word init_gdt_end - init_gdt_start - 1 + .long init_gdt_start + + .align 16 + init_gdt_start: + .quad 0x0000000000000000 + .quad 0x00cf9a000000ffff + .quad 0x00cf92000000ffff + .quad 0x0000000000000000 + init_gdt_end: diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/smp.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/smp.c new file mode 100644 index 0000000000..0c50569997 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/smp.c @@ -0,0 +1,367 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +//------------------------------------------------------------------------------ +//smp.c +//this module scans for multi-core/CPUs within the system and +//returns the number of cores/CPUs as well as their LAPIC id, +//version, base and BSP indications +//author: amit vasudevan (amitvasudevan@acm.org) +#include + +//forward prototypes +static int mp_checksum(unsigned char *mp, int len); +static u32 mp_scan_config(u32 base, u32 length, MPFP **mpfp); +static u32 mp_getebda(void); +ACPI_RSDP * ACPIGetRSDP(void); + +//exposed interface to the outside world +//inputs: array of type PCPU and pointer to u32 which will +//receive the number of cores/CPUs in the system +//returns: 1 on succes, 0 on any failure +u32 smp_getinfo(PCPU *pcpus, u32 *num_pcpus){ + MPFP *mpfp; + MPCONFTABLE *mpctable; + + ACPI_RSDP *rsdp; + +#if 0 + ACPI_XSDT *xsdt; + u32 n_xsdt_entries; + u64 *xsdtentrylist; +#else + ACPI_RSDT *rsdt; + u32 n_rsdt_entries; + u32 *rsdtentrylist; +#endif + + ACPI_MADT *madt; + u8 madt_found=0; + u32 i; + + //we scan ACPI MADT and then the MP configuration table if one is + //present, in that order! + + //if we get here it means that we did not find a MP table, so + //we need to look at ACPI MADT. Logical cores on some machines + //(e.g HP8540p laptop with Core i5) are reported only using ACPI MADT + //and there is no MP structures on such systems! + printf("\nFinding SMP info. via ACPI..."); + rsdp=(ACPI_RSDP *)ACPIGetRSDP(); + if(!rsdp){ + printf("\nSystem is not ACPI Compliant, falling through..."); + goto fallthrough; + } + + printf("\nACPI RSDP at 0x%08x", (u32)rsdp); + +#if 0 + xsdt=(ACPI_XSDT *)(u32)rsdp->xsdtaddress; + n_xsdt_entries=(u32)((xsdt->length-sizeof(ACPI_XSDT))/8); + + printf("\nACPI XSDT at 0x%08x", xsdt); + printf("\n len=0x%08x, headerlen=0x%08x, numentries=%u", + xsdt->length, sizeof(ACPI_XSDT), n_xsdt_entries); + + xsdtentrylist=(u64 *) ( (u32)xsdt + sizeof(ACPI_XSDT) ); + + for(i=0; i< n_xsdt_entries; i++){ + madt=(ACPI_MADT *)( (u32)xsdtentrylist[i]); + if(madt->signature == ACPI_MADT_SIGNATURE){ + madt_found=1; + break; + } + } +#else + rsdt=(ACPI_RSDT *)(u32)rsdp->rsdtaddress; + n_rsdt_entries=(u32)((rsdt->length-sizeof(ACPI_RSDT))/4); + + printf("\nACPI RSDT at 0x%08x", (u32)rsdt); + printf("\n len=0x%08x, headerlen=0x%08x, numentries=%u", + rsdt->length, sizeof(ACPI_RSDT), n_rsdt_entries); + + rsdtentrylist=(u32 *) ( (u32)rsdt + sizeof(ACPI_RSDT) ); + + for(i=0; i< n_rsdt_entries; i++){ + madt=(ACPI_MADT *)( (u32)rsdtentrylist[i]); + if(madt->signature == ACPI_MADT_SIGNATURE){ + madt_found=1; + break; + } + } + +#endif + + + if(!madt_found){ + printf("\nACPI MADT not found, falling through..."); + goto fallthrough; + } + + printf("\nACPI MADT at 0x%08x", (u32)madt); + printf("\n len=0x%08x, record-length=%u bytes", madt->length, + madt->length - sizeof(ACPI_MADT)); + + //scan through MADT APIC records to find processors + *num_pcpus=0; + { + u32 madtrecordlength = madt->length - sizeof(ACPI_MADT); + u32 madtcurrentrecordoffset=0; + u32 i=0; + u32 foundcores=0; + + do{ + ACPI_MADT_APIC *apicrecord = (ACPI_MADT_APIC *)((u32)madt + sizeof(ACPI_MADT) + madtcurrentrecordoffset); + printf("\nrec type=0x%02x, length=%u bytes, flags=0x%08x, id=0x%02x", apicrecord->type, + apicrecord->length, apicrecord->flags, apicrecord->lapicid); + + if(apicrecord->type == 0x0 && (apicrecord->flags & 0x1)){ //processor record + + foundcores=1; + HALT_ON_ERRORCOND( *num_pcpus < MAX_PCPU_ENTRIES); + i = *num_pcpus; + pcpus[i].lapic_id = apicrecord->lapicid; + pcpus[i].lapic_ver = 0; + pcpus[i].lapic_base = madt->lapicaddress; + if(i == 0) + pcpus[i].isbsp = 1; //ACPI spec says that first processor entry MUST be BSP + else + pcpus[i].isbsp = 0; + + *num_pcpus = *num_pcpus + 1; + } + madtcurrentrecordoffset += apicrecord->length; + }while(madtcurrentrecordoffset < madtrecordlength); + + if(foundcores) + return 1; + } + + +fallthrough: + //ok, ACPI detection failed proceed with MP table scan + //we simply grab all the info from there as per + //the intel MP spec. + //look at 1K at start of conventional mem. + //look at 1K at top of conventional mem + //look at 1K starting at EBDA and + //look at 64K starting at 0xF0000 + + if( mp_scan_config(0x0, 0x400, &mpfp) || + mp_scan_config(639 * 0x400, 0x400, &mpfp) || + mp_scan_config(mp_getebda(), 0x400, &mpfp) || + mp_scan_config(0xF0000, 0x10000, &mpfp) ){ + + printf("\nMP table found at: 0x%08x", (u32)mpfp); + printf("\nMP spec rev=0x%02x", mpfp->spec_rev); + printf("\nMP feature info1=0x%02x", mpfp->mpfeatureinfo1); + printf("\nMP feature info2=0x%02x", mpfp->mpfeatureinfo2); + printf("\nMP Configuration table at 0x%08x", mpfp->paddrpointer); + + HALT_ON_ERRORCOND( mpfp->paddrpointer != 0 ); + mpctable = (MPCONFTABLE *)mpfp->paddrpointer; + HALT_ON_ERRORCOND(mpctable->signature == MPCONFTABLE_SIGNATURE); + + {//debug + int i; + printf("\nOEM ID: "); + for(i=0; i < 8; i++) + printf("%c", mpctable->oemid[i]); + printf("\nProduct ID: "); + for(i=0; i < 12; i++) + printf("%c", mpctable->productid[i]); + } + + printf("\nEntry count=%u", mpctable->entrycount); + printf("\nLAPIC base=0x%08x", mpctable->lapicaddr); + + //now step through CPU entries in the MP-table to determine + //how many CPUs we have + *num_pcpus=0; + + { + int i; + u32 addrofnextentry= (u32)mpctable + sizeof(MPCONFTABLE); + + for(i=0; i < mpctable->entrycount; i++){ + MPENTRYCPU *cpu = (MPENTRYCPU *)addrofnextentry; + if(cpu->entrytype != 0) + break; + + if(cpu->cpuflags & 0x1){ + HALT_ON_ERRORCOND( *num_pcpus < MAX_PCPU_ENTRIES); + printf("\nCPU (0x%08x) #%u: lapic id=0x%02x, ver=0x%02x, cpusig=0x%08x", + (u32)cpu, i, cpu->lapicid, cpu->lapicver, cpu->cpusig); + pcpus[i].lapic_id = cpu->lapicid; + pcpus[i].lapic_ver = cpu->lapicver; + pcpus[i].lapic_base = mpctable->lapicaddr; + pcpus[i].isbsp = cpu->cpuflags & 0x2; + *num_pcpus = *num_pcpus + 1; + } + + addrofnextentry += sizeof(MPENTRYCPU); + } + } + + + return 1; + } + + + return 1; + +} + + +static int mp_checksum(unsigned char *mp, int len){ + int sum = 0; + + while (len--) + sum += *mp++; + + return sum & 0xFF; +} + + +//returns 1 if MP table found and populates mpfp with MP table pointer +//returns 0 if no MP table and makes mpfp=NULL +static u32 mp_scan_config(u32 base, u32 length, MPFP **mpfp){ + u32 *bp = (u32 *)base; + MPFP *mpf; + + printf("\n%s: Finding MP table from 0x%08x for %u bytes", + __FUNCTION__, (u32)bp, length); + + while (length > 0) { + mpf = (MPFP *)bp; + if ((*bp == MPFP_SIGNATURE) && + (mpf->length == 1) && + !mp_checksum((unsigned char *)bp, 16) && + ((mpf->spec_rev == 1) + || (mpf->spec_rev == 4))) { + + printf("\n%s: found SMP MP-table at 0x%08x", + __FUNCTION__, (u32)mpf); + + *mpfp = mpf; + return 1; + } + bp += 4; + length -= 16; + } + + *mpfp=0; + return 0; +} + + +u32 mp_getebda(void){ + u16 ebdaseg; + u32 ebdaphys; + //get EBDA segment from 040E:0000h in BIOS data area + ebdaseg= * ((u16 *)0x0000040E); + //convert it to its 32-bit physical address + ebdaphys=(u32)(ebdaseg * 16); + return ebdaphys; +} + +//------------------------------------------------------------------------------ +u32 _ACPIGetRSDPComputeChecksum(u32 spaddr, u32 size){ + char *p; + char checksum=0; + u32 i; + + p=(char *)spaddr; + + for(i=0; i< size; i++) + checksum+= (char)(*(p+i)); + + return (u32)checksum; +} + +//get the physical address of the root system description pointer (rsdp) +//return 0 if not found +ACPI_RSDP * ACPIGetRSDP(void){ + u16 ebdaseg; + u32 ebdaphys; + u32 i, found=0; + ACPI_RSDP *rsdp; + + //get EBDA segment from 040E:0000h in BIOS data area + ebdaseg= * ((u16 *)0x0000040E); + //convert it to its 32-bit physical address + ebdaphys=(u32)(ebdaseg * 16); + //search first 1KB of ebda for rsdp signature (8 bytes long) + for(i=0; i < (1024-8); i+=16){ + rsdp=(ACPI_RSDP *)(ebdaphys+i); + if(rsdp->signature == ACPI_RSDP_SIGNATURE){ + if(!_ACPIGetRSDPComputeChecksum((u32)rsdp, 20)){ + found=1; + break; + } + } + } + + if(found) + return rsdp; + + //search within BIOS areas 0xE0000 to 0xFFFFF + for(i=0xE0000; i < (0xFFFFF-8); i+=16){ + rsdp=(ACPI_RSDP *)i; + if(rsdp->signature == ACPI_RSDP_SIGNATURE){ + if(!_ACPIGetRSDPComputeChecksum((u32)rsdp, 20)){ + found=1; + break; + } + } + } + + if(found) + return rsdp; + + return (ACPI_RSDP *)NULL; +} +//------------------------------------------------------------------------------ diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/txt.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/txt.c new file mode 100644 index 0000000000..913165d687 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/txt.c @@ -0,0 +1,593 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * txt.c: Intel(r) TXT support functions, including initiating measured + * launch, post-launch, AP wakeup, etc. + * + * Copyright (c) 2003-2010, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * Modified for XMHF by jonmccune@cmu.edu, 2011.01.05 + */ + +/* + * NOTE: (TODO?) Stripped a lot of LCP, sleep, and MP code out of + * tboot's version of this file. Likely some of these are features + * that we would like to have. Look there instead of reinventing the + * wheel when the time comes. + */ + +#include + +extern SL_PARAMETER_BLOCK *slpb; /* Ugh; ugly global from init.c */ + +bool get_parameters(getsec_parameters_t *params); + +/* + * this is the structure whose addr we'll put in TXT heap + * it needs to be within the MLE pages, so force it to the .text section + */ +static mle_hdr_t g_mle_hdr = { + uuid : MLE_HDR_UUID, + length : sizeof(mle_hdr_t), + version : MLE_HDR_VER, + entry_point : TEMPORARY_HARDCODED_MLE_ENTRYPOINT, // XXX TODO remove magic number + first_valid_page : 0, + ///XXX I thnk these should be phys addres + mle_start_off : 0, /* In MLE address space as accessed via MLE page tables */ + mle_end_off : TEMPORARY_HARDCODED_MLE_SIZE, // XXX TODO remove magic number + capabilities : { MLE_HDR_CAPS }, + cmdline_start_off : 0, + cmdline_end_off : 0, +}; + +///XXX +static void print_file_info(void) +{ + printf("file addresses:\n"); + printf("\t &g_mle_hdr=%p\n", &g_mle_hdr); +} + +static void print_mle_hdr(const mle_hdr_t *mle_hdr) +{ + printf("MLE header:\n"); + printf("\t uuid="); print_uuid(&mle_hdr->uuid); printf("\n"); + printf("\t length=%x\n", mle_hdr->length); + printf("\t version=%08x\n", mle_hdr->version); + printf("\t entry_point=%08x\n", mle_hdr->entry_point); + printf("\t first_valid_page=%08x\n", mle_hdr->first_valid_page); + printf("\t mle_start_off=%x\n", mle_hdr->mle_start_off); + printf("\t mle_end_off=%x\n", mle_hdr->mle_end_off); + print_txt_caps("\t ", mle_hdr->capabilities); +} + +#define MAKE_PDTE(addr) (PAGE_ALIGN_4K((u32)addr) | 0x01) + +/* we assume/know that our image is <2MB and thus fits w/in a single */ +/* PT (512*4KB = 2MB) and thus fixed to 1 pg dir ptr and 1 pgdir and */ +/* 1 ptable = 3 pages and just 1 loop loop for ptable MLE page table */ +/* can only contain 4k pages */ +static void *build_mle_pagetable(uint32_t mle_start, uint32_t mle_size) +{ + void *ptab_base; + uint32_t ptab_size, mle_off; + void *pg_dir_ptr_tab, *pg_dir, *pg_tab; + uint64_t *pte; + + printf("MLE start=%x, end=%x, size=%x\n", mle_start, mle_start+mle_size, + mle_size); + if ( mle_size > 512*PAGE_SIZE_4K ) { + printf("MLE size too big for single page table\n"); + return NULL; + } + + /* should start on page boundary */ + if ( PAGE_ALIGN_4K(mle_start) != mle_start ) { + printf("MLE start is not page-aligned\n"); + return NULL; + } + + /* place ptab_base below MLE */ + ptab_size = 3 * PAGE_SIZE_4K; /* pgdir ptr + pgdir + ptab = 3 */ + ptab_base = (void *)(mle_start - ptab_size); + + /* NB: This memset will clobber the AMD-specific SL header. That + * is okay, as we are launching on an Intel TXT system. */ + memset(ptab_base, 0, ptab_size); + printf("ptab_size=%x, ptab_base=%p\n", ptab_size, ptab_base); + + pg_dir_ptr_tab = ptab_base; + pg_dir = pg_dir_ptr_tab + PAGE_SIZE_4K; + pg_tab = pg_dir + PAGE_SIZE_4K; + + /* only use first entry in page dir ptr table */ + *(uint64_t *)pg_dir_ptr_tab = MAKE_PDTE(pg_dir); + + printf("*(uint64_t *)pg_dir_ptr_tab = 0x%16llx\n", + *(uint64_t *)pg_dir_ptr_tab); + + /* only use first entry in page dir */ + *(uint64_t *)pg_dir = MAKE_PDTE(pg_tab); + printf("*(uint64_t *)pg_dir = 0x%16llx\n", + *(uint64_t *)pg_dir); + + + pte = pg_tab; + mle_off = 0; + do { + *pte = MAKE_PDTE(mle_start + mle_off); + printf("pte = 0x%08x\n*pte = 0x%15llx\n", + (u32)pte, *pte); + + pte++; + mle_off += PAGE_SIZE_4K; + } while ( mle_off < mle_size ); + + return ptab_base; +} + +/* + * will go through all modules to find an SINIT that matches the platform + * (size can be NULL) + */ +static bool check_sinit_module(void *base, size_t size) +{ + txt_didvid_t didvid; + txt_ver_fsbif_emif_t ver; + + if ( base == NULL ) + return false; + + /* display chipset fuse and device and vendor id info */ + didvid._raw = read_pub_config_reg(TXTCR_DIDVID); + printf("chipset ids: vendor: 0x%x, device: 0x%x, revision: 0x%x\n", + didvid.vendor_id, didvid.device_id, didvid.revision_id); + ver._raw = read_pub_config_reg(TXTCR_VER_FSBIF); + if ( (ver._raw & 0xffffffff) == 0xffffffff || + (ver._raw & 0xffffffff) == 0x00 ) /* need to use VER.EMIF */ + ver._raw = read_pub_config_reg(TXTCR_VER_EMIF); + printf("chipset production fused: %x\n", ver.prod_fused ); + + if ( is_sinit_acmod(base, size, false) && + does_acmod_match_chipset((acm_hdr_t *)base) ) { + printf("SINIT matches platform\n"); + return true; + } + /* no SINIT found for this platform */ + printf("no SINIT AC module found\n"); + return false; +} + + +/* + * sets up TXT heap + */ +static txt_heap_t *init_txt_heap(void *ptab_base, acm_hdr_t *sinit, + void *phys_mle_start, size_t mle_size) +{ + txt_heap_t *txt_heap; + uint64_t *size; + os_mle_data_t *os_mle_data; + os_sinit_data_t *os_sinit_data; + /* uint64_t min_lo_ram, max_lo_ram, min_hi_ram, max_hi_ram; */ + txt_caps_t sinit_caps; + txt_caps_t caps_mask; + + txt_heap = get_txt_heap(); + + /* + * BIOS data already setup by BIOS + */ + if ( !verify_txt_heap(txt_heap, true) ) + return NULL; + + /* + * OS/loader to MLE data + */ + os_mle_data = get_os_mle_data_start(txt_heap); + size = (uint64_t *)((uint32_t)os_mle_data - sizeof(uint64_t)); + *size = sizeof(*os_mle_data) + sizeof(uint64_t); + memset(os_mle_data, 0, sizeof(*os_mle_data)); + os_mle_data->version = 0x02; + os_mle_data->mbi = (uint32_t)NULL; + os_mle_data->saved_misc_enable_msr = rdmsr64(MSR_IA32_MISC_ENABLE); + + /* + * OS/loader to SINIT data + */ + os_sinit_data = get_os_sinit_data_start(txt_heap); + size = (uint64_t *)((uint32_t)os_sinit_data - sizeof(uint64_t)); + *size = sizeof(*os_sinit_data) + sizeof(uint64_t); + memset(os_sinit_data, 0, sizeof(*os_sinit_data)); + os_sinit_data->version = 5; // XXX too magical + /* this is phys addr */ + os_sinit_data->mle_ptab = (uint64_t)(unsigned long)ptab_base; + os_sinit_data->mle_size = g_mle_hdr.mle_end_off - g_mle_hdr.mle_start_off; + /* Copy populated MLE header into SL */ + HALT_ON_ERRORCOND(sizeof(mle_hdr_t) < TEMPORARY_MAX_MLE_HEADER_SIZE); + memcpy(phys_mle_start, &g_mle_hdr, sizeof(mle_hdr_t)); + printf("Copied mle_hdr (0x%08x, 0x%x bytes) into SL (0x%08x)\n", + (u32)&g_mle_hdr, sizeof(mle_hdr_t), (u32)phys_mle_start); + /* this is linear addr (offset from MLE base) of mle header, in MLE page tables */ + os_sinit_data->mle_hdr_base = 0; + //- (uint64_t)(unsigned long)&_mle_start; + /* VT-d PMRs */ + /* Must protect MLE, o/w get: TXT.ERRORCODE=c0002871 + AC module error : acm_type=1, progress=07, error=a + "page is not covered by DPR nor PMR regions" */ + { + extern u32 sl_rt_size; //XXX: Ugly hack to bring in SL + runtime size; ideally this should be passed in as another parameter + (void)mle_size; + os_sinit_data->vtd_pmr_lo_base = (u64)__TARGET_BASE_SL; + os_sinit_data->vtd_pmr_lo_size = (u64)PAGE_ALIGN_UP_2M(sl_rt_size); + } + + /* hi range is >4GB; unused for us */ + os_sinit_data->vtd_pmr_hi_base = 0; + os_sinit_data->vtd_pmr_hi_size = 0; + + /* LCP owner policy data -- DELETED */ + + /* capabilities : choose monitor wake mechanism first */ + ///XXX I don't really understand this + sinit_caps._raw = get_sinit_capabilities(sinit); + caps_mask._raw = 0; + caps_mask.rlp_wake_getsec = caps_mask.rlp_wake_monitor = 1; + os_sinit_data->capabilities._raw = MLE_HDR_CAPS & ~caps_mask._raw; + if ( sinit_caps.rlp_wake_monitor ) + os_sinit_data->capabilities.rlp_wake_monitor = 1; + else if ( sinit_caps.rlp_wake_getsec ) + os_sinit_data->capabilities.rlp_wake_getsec = 1; + else { /* should have been detected in verify_acmod() */ + printf("SINIT capabilities are icompatible (0x%x)\n", sinit_caps._raw); + return NULL; + } + /* capabilities : require MLE pagetable in ECX on launch */ + /* TODO: when SINIT ready + * os_sinit_data->capabilities.ecx_pgtbl = 1; + */ + os_sinit_data->capabilities.ecx_pgtbl = 0; + /* TODO: when tboot supports EFI then set efi_rsdt_ptr */ + + print_os_sinit_data(os_sinit_data); + + /* + * SINIT to MLE data will be setup by SINIT + */ + + return txt_heap; +} + +void delay(u64 cycles) +{ + uint64_t start = rdtsc64(); + + while ( rdtsc64()-start < cycles ) ; +} + + +tb_error_t txt_launch_environment(void *sinit_ptr, size_t sinit_size, + void *phys_mle_start, size_t mle_size) +{ + acm_hdr_t *sinit; + void *mle_ptab_base; + os_mle_data_t *os_mle_data; + txt_heap_t *txt_heap; + + if(NULL == sinit_ptr) return TB_ERR_SINIT_NOT_PRESENT; + else sinit = (acm_hdr_t*)sinit_ptr; + + if(!check_sinit_module((void *)sinit, sinit_size)) { + printf("check_sinit_module failed\n"); + return TB_ERR_SINIT_NOT_PRESENT; + } + /* if it is newer than BIOS-provided version, then copy it to */ + /* BIOS reserved region */ + sinit = copy_sinit(sinit); + if ( sinit == NULL ) + return TB_ERR_SINIT_NOT_PRESENT; + /* do some checks on it */ + if ( !verify_acmod(sinit) ) + return TB_ERR_ACMOD_VERIFY_FAILED; + + /* print some debug info */ + print_file_info(); + print_mle_hdr(&g_mle_hdr); + + /* create MLE page table */ + mle_ptab_base = build_mle_pagetable((u32)phys_mle_start, mle_size); + if ( mle_ptab_base == NULL ) + return TB_ERR_FATAL; + + /* initialize TXT heap */ + txt_heap = init_txt_heap(mle_ptab_base, sinit, + phys_mle_start, mle_size); + if ( txt_heap == NULL ) + return TB_ERR_FATAL; + + /* save MTRRs before we alter them for SINIT launch */ + os_mle_data = get_os_mle_data_start(txt_heap); + save_mtrrs(&(os_mle_data->saved_mtrr_state)); + + /* set MTRRs properly for AC module (SINIT) */ + if ( !set_mtrrs_for_acmod(sinit) ) + return TB_ERR_FATAL; + + printf("executing GETSEC[SENTER]...\n"); + /* pause before executing GETSEC[SENTER] */ + delay(0x80000000); + +#ifndef PERF_CRIT + if(NULL != slpb) { + slpb->rdtsc_before_drtm = rdtsc64(); + } +#endif + + __getsec_senter((uint32_t)sinit, (sinit->size)*4); + printf("ERROR--we should not get here!\n"); + return TB_ERR_FATAL; +} + + +bool txt_prepare_cpu(void) +{ + unsigned long eflags, cr0; + uint64_t mcg_cap, mcg_stat; + getsec_parameters_t params; + unsigned int i; + + /* must be running at CPL 0 => this is implicit in even getting this far */ + /* since our bootstrap code loads a GDT, etc. */ + cr0 = read_cr0(); + + /* must be in protected mode */ + if ( !(cr0 & CR0_PE) ) { + printf("ERR: not in protected mode\n"); + return false; + } + + /* cache must be enabled (CR0.CD = CR0.NW = 0) */ + if ( cr0 & CR0_CD ) { + printf("CR0.CD set; clearing it.\n"); + cr0 &= ~CR0_CD; + } + if ( cr0 & CR0_NW ) { + printf("CR0.NW set; clearing it.\n"); + cr0 &= ~CR0_NW; + } + + /* native FPU error reporting must be enabled for proper */ + /* interaction behavior */ + if ( !(cr0 & CR0_NE) ) { + printf("CR0.NE not set; setting it.\n"); + cr0 |= CR0_NE; + } + + write_cr0(cr0); + + /* cannot be in virtual-8086 mode (EFLAGS.VM=1) */ + get_eflags(eflags); + if ( eflags & EFLAGS_VM ) { + printf("EFLAGS.VM set; clearing it.\n"); + set_eflags(eflags | ~EFLAGS_VM); + } + + printf("CR0 and EFLAGS OK\n"); + + /* + * verify that we're not already in a protected environment + */ + if ( txt_is_launched() ) { + printf("already in protected environment\n"); + return false; + } + + /* + * verify all machine check status registers are clear (unless + * support preserving them) + */ + + /* no machine check in progress (IA32_MCG_STATUS.MCIP=1) */ + mcg_stat = rdmsr64(MSR_MCG_STATUS); + if ( mcg_stat & 0x04 ) { + printf("machine check in progress\n"); + return false; + } + + if ( !get_parameters(¶ms) ) { + printf("get_parameters() failed\n"); + return false; + } + + /* check if all machine check regs are clear */ + mcg_cap = rdmsr64(MSR_MCG_CAP); + for ( i = 0; i < (mcg_cap & 0xff); i++ ) { + mcg_stat = rdmsr64(MSR_MC0_STATUS + 4*i); + if ( mcg_stat & (1ULL << 63) ) { + printf("MCG[%u] = %llx ERROR\n", i, mcg_stat); + if ( !params.preserve_mce ) + return false; + } + } + + if ( params.preserve_mce ) + printf("supports preserving machine check errors\n"); + else + printf("no machine check errors\n"); + + if ( params.proc_based_scrtm ) + printf("CPU support processor-based S-CRTM\n"); + + /* all is well with the processor state */ + printf("CPU is ready for SENTER\n"); + + return true; +} + + + +#define ACM_MEM_TYPE_UC 0x0100 +#define ACM_MEM_TYPE_WC 0x0200 +#define ACM_MEM_TYPE_WT 0x1000 +#define ACM_MEM_TYPE_WP 0x2000 +#define ACM_MEM_TYPE_WB 0x4000 + +#define DEF_ACM_MAX_SIZE 0x8000 +#define DEF_ACM_VER_MASK 0xffffffff +#define DEF_ACM_VER_SUPPORTED 0x00 +#define DEF_ACM_MEM_TYPES ACM_MEM_TYPE_UC +#define DEF_SENTER_CTRLS 0x00 + +bool get_parameters(getsec_parameters_t *params) +{ + unsigned long cr4; + uint32_t index, eax, ebx, ecx; + int param_type; + + /* sanity check because GETSEC[PARAMETERS] will fail if not set */ + cr4 = read_cr4(); + if ( !(cr4 & CR4_SMXE) ) { + printf("SMXE not enabled, can't read parameters\n"); + return false; + } + + memset(params, 0, sizeof(*params)); + params->acm_max_size = DEF_ACM_MAX_SIZE; + params->acm_mem_types = DEF_ACM_MEM_TYPES; + params->senter_controls = DEF_SENTER_CTRLS; + params->proc_based_scrtm = false; + params->preserve_mce = false; + + index = 0; + do { + __getsec_parameters(index++, ¶m_type, &eax, &ebx, &ecx); + /* the code generated for a 'switch' statement doesn't work in this */ + /* environment, so use if/else blocks instead */ + + /* NULL - all reserved */ + if ( param_type == 0 ) + ; + /* supported ACM versions */ + else if ( param_type == 1 ) { + if ( params->n_versions == MAX_SUPPORTED_ACM_VERSIONS ) + printf("number of supported ACM version exceeds " + "MAX_SUPPORTED_ACM_VERSIONS\n"); + else { + params->acm_versions[params->n_versions].mask = ebx; + params->acm_versions[params->n_versions].version = ecx; + params->n_versions++; + } + } + /* max size AC execution area */ + else if ( param_type == 2 ) + params->acm_max_size = eax & 0xffffffe0; + /* supported non-AC mem types */ + else if ( param_type == 3 ) + params->acm_mem_types = eax & 0xffffffe0; + /* SENTER controls */ + else if ( param_type == 4 ) + params->senter_controls = (eax & 0x00007fff) >> 8; + /* TXT extensions support */ + else if ( param_type == 5 ) { + params->proc_based_scrtm = (eax & 0x00000020) ? true : false; + params->preserve_mce = (eax & 0x00000040) ? true : false; + } + else { + printf("unknown GETSEC[PARAMETERS] type: %d\n", param_type); + param_type = 0; /* set so that we break out of the loop */ + } + } while ( param_type != 0 ); + + if ( params->n_versions == 0 ) { + params->acm_versions[0].mask = DEF_ACM_VER_MASK; + params->acm_versions[0].version = DEF_ACM_VER_SUPPORTED; + params->n_versions = 1; + } + + return true; +} + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/txt_acmod.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/txt_acmod.c new file mode 100644 index 0000000000..919a46e125 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/txt_acmod.c @@ -0,0 +1,666 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * acmod.c: support functions for use of Intel(r) TXT Authenticated + * Code (AC) Modules + * + * Copyright (c) 2003-2010, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * Modified for XMHF by jonmccune@cmu.edu, 2011.01.04 + */ + +#include + +static acm_info_table_t *get_acmod_info_table(acm_hdr_t* hdr) +{ + uint32_t user_area_off; + + /* overflow? */ + if ( plus_overflow_u32(hdr->header_len, hdr->scratch_size) ) { + printf("ACM header length plus scratch size overflows\n"); + return NULL; + } + + if ( multiply_overflow_u32((hdr->header_len + hdr->scratch_size), 4) ) { + printf("ACM header length and scratch size in bytes overflows\n"); + return NULL; + } + + /* this fn assumes that the ACM has already passed at least the initial */ + /* is_acmod() checks */ + + user_area_off = (hdr->header_len + hdr->scratch_size) * 4; + + /* overflow? */ + if ( plus_overflow_u32(user_area_off, sizeof(acm_info_table_t)) ) { + printf("user_area_off plus acm_info_table_t size overflows\n"); + return NULL; + } + + /* check that table is within module */ + if ( user_area_off + sizeof(acm_info_table_t) > hdr->size*4 ) { + printf("ACM info table size too large: %x\n", + user_area_off + (uint32_t)sizeof(acm_info_table_t)); + return NULL; + } + + /* overflow? */ + if ( plus_overflow_u32((uint32_t)(uintptr_t)hdr, user_area_off) ) { + printf("hdr plus user_area_off overflows\n"); + return NULL; + } + + return (acm_info_table_t *)((unsigned long)hdr + user_area_off); +} + +static acm_chipset_id_list_t *get_acmod_chipset_list(acm_hdr_t* hdr) +{ + acm_info_table_t* info_table; + uint32_t size, id_list_off; + acm_chipset_id_list_t *chipset_id_list; + + /* this fn assumes that the ACM has already passed the is_acmod() checks */ + + info_table = get_acmod_info_table(hdr); + if ( info_table == NULL ) + return NULL; + id_list_off = info_table->chipset_id_list; + + size = hdr->size * 4; + + /* overflow? */ + if ( plus_overflow_u32(id_list_off, sizeof(acm_chipset_id_t)) ) { + printf("id_list_off plus acm_chipset_id_t size overflows\n"); + return NULL; + } + + /* check that chipset id table is w/in ACM */ + if ( id_list_off + sizeof(acm_chipset_id_t) > size ) { + printf("ACM chipset id list is too big: chipset_id_list=%x\n", + id_list_off); + return NULL; + } + + /* overflow? */ + if ( plus_overflow_u32((uint32_t)(uintptr_t)hdr, id_list_off) ) { + printf("hdr plus id_list_off overflows\n"); + return NULL; + } + + chipset_id_list = (acm_chipset_id_list_t *) + ((unsigned long)hdr + id_list_off); + + /* overflow? */ + if ( multiply_overflow_u32(chipset_id_list->count, + sizeof(acm_chipset_id_t)) ) { + printf("size of acm_chipset_id_list overflows\n"); + return NULL; + } + if ( plus_overflow_u32(id_list_off + sizeof(acm_chipset_id_t), + chipset_id_list->count * sizeof(acm_chipset_id_t)) ) { + printf("size of all entries overflows\n"); + return NULL; + } + + /* check that all entries are w/in ACM */ + if ( id_list_off + sizeof(acm_chipset_id_t) + + chipset_id_list->count * sizeof(acm_chipset_id_t) > size ) { + printf("ACM chipset id entries are too big:" + " chipset_id_list->count=%x\n", chipset_id_list->count); + return NULL; + } + + return chipset_id_list; +} + +void print_txt_caps(const char *prefix, txt_caps_t caps) +{ + printf("%scapabilities: 0x%08x\n", prefix, caps._raw); + printf("%s rlp_wake_getsec: %d\n", prefix, caps.rlp_wake_getsec); + printf("%s rlp_wake_monitor: %d\n", prefix, caps.rlp_wake_monitor); + printf("%s ecx_pgtbl: %d\n", prefix, caps.ecx_pgtbl); +} + +/* UUID helpers from tboot-20101005/include/uuid.h */ +void print_uuid(const uuid_t *uuid) +{ + printf("{0x%08x, 0x%04x, 0x%04x, 0x%04x,\n" + "\t\t{0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x}}", + uuid->data1, (uint32_t)uuid->data2, (uint32_t)uuid->data3, + (uint32_t)uuid->data4, (uint32_t)uuid->data5[0], + (uint32_t)uuid->data5[1], (uint32_t)uuid->data5[2], + (uint32_t)uuid->data5[3], (uint32_t)uuid->data5[4], + (uint32_t)uuid->data5[5]); +} + +static inline bool are_uuids_equal(const uuid_t *uuid1, const uuid_t *uuid2) +{ + return (memcmp((const char *)uuid1, (const char *)uuid2, sizeof(*uuid1)) == 0); +} + +static void print_acm_hdr(acm_hdr_t *hdr, const char *mod_name) +{ + acm_info_table_t *info_table; + acm_chipset_id_list_t *chipset_id_list; + unsigned int i; + + printf("AC module header dump for %s:\n", + (mod_name == NULL) ? "?" : mod_name); + + /* header */ + printf("\t type: 0x%x ", hdr->module_type); + if ( hdr->module_type == ACM_TYPE_CHIPSET ) + printf("(ACM_TYPE_CHIPSET)\n"); + else + printf("(unknown)\n"); + printf("\t length: 0x%x (%u)\n", hdr->header_len, hdr->header_len); + printf("\t version: %u\n", hdr->header_ver); + printf("\t chipset_id: 0x%x\n", (uint32_t)hdr->chipset_id); + printf("\t flags: 0x%x\n", (uint32_t)hdr->flags._raw); + printf("\t\t pre_production: %d\n", (int)hdr->flags.pre_production); + printf("\t\t debug_signed: %d\n", (int)hdr->flags.debug_signed); + printf("\t vendor: 0x%x\n", hdr->module_vendor); + printf("\t date: 0x%08x\n", hdr->date); + printf("\t size*4: 0x%x (%u)\n", hdr->size*4, hdr->size*4); + printf("\t code_control: 0x%x\n", hdr->code_control); + printf("\t error_entry_point: 0x%x\n", hdr->error_entry_point); + printf("\t gdt_limit 0x%x, gdt_base 0x%x\n", hdr->gdt_limit, + hdr->gdt_base); + printf("\t entry point (seg_sel:entry_point): 0x%08x:%08x\n", hdr->seg_sel, + hdr->entry_point); + printf("\t scratch_size: 0x%x (%u)", hdr->scratch_size, + hdr->scratch_size); + + /* GDT */ + print_hex("\t\t SINIT GDT: ", (void *)((u32)hdr+hdr->gdt_base), hdr->gdt_limit); + /* info table */ + printf("\t info_table:\n"); + info_table = get_acmod_info_table(hdr); + if ( info_table == NULL ) { + printf("\t\t \n"); + return; + } + printf("\t\t uuid: "); print_uuid(&info_table->uuid); printf("\n"); + if ( are_uuids_equal(&(info_table->uuid), &((uuid_t)ACM_UUID_V3)) ) + printf("\t\t ACM_UUID_V3\n"); + else + printf("\t\t unknown\n"); + printf("\t\t chipset_acm_type: 0x%x ", + (uint32_t)info_table->chipset_acm_type); + if ( info_table->chipset_acm_type == ACM_CHIPSET_TYPE_SINIT ) + printf("(SINIT)\n"); + else if ( info_table->chipset_acm_type == ACM_CHIPSET_TYPE_BIOS ) + printf("(BIOS)\n"); + else + printf("(unknown)\n"); + printf("\t\t version: %u\n", (uint32_t)info_table->version); + printf("\t\t length: 0x%x (%u)\n", (uint32_t)info_table->length, + (uint32_t)info_table->length); + printf("\t\t chipset_id_list: 0x%x\n", info_table->chipset_id_list); + printf("\t\t os_sinit_data_ver: 0x%x\n", info_table->os_sinit_data_ver); + printf("\t\t min_mle_hdr_ver: 0x%08x\n", info_table->min_mle_hdr_ver); + print_txt_caps("\t\t ", info_table->capabilities); + printf("\t\t acm_ver: %u\n", (uint32_t)info_table->acm_ver); + + /* chipset list */ + printf("\t chipset list:\n"); + chipset_id_list = get_acmod_chipset_list(hdr); + if ( chipset_id_list == NULL ) { + printf("\t\t \n"); + return; + } + printf("\t\t count: %u\n", chipset_id_list->count); + for ( i = 0; i < chipset_id_list->count; i++ ) { + acm_chipset_id_t *chipset_id; + printf("\t\t entry %u:\n", i); + chipset_id = &(chipset_id_list->chipset_ids[i]); + printf("\t\t flags: 0x%x\n", chipset_id->flags); + printf("\t\t vendor_id: 0x%x\n", (uint32_t)chipset_id->vendor_id); + printf("\t\t device_id: 0x%x\n", (uint32_t)chipset_id->device_id); + printf("\t\t revision_id: 0x%x\n", + (uint32_t)chipset_id->revision_id); + printf("\t\t extended_id: 0x%x\n", chipset_id->extended_id); + } +} + +uint32_t get_supported_os_sinit_data_ver(acm_hdr_t* hdr) +{ + /* assumes that it passed is_sinit_acmod() */ + + acm_info_table_t *info_table = get_acmod_info_table(hdr); + if ( info_table == NULL ) + return 0; + + return info_table->os_sinit_data_ver; +} + +// return type changed from txt_caps_t due to -Waggregate-return +uint32_t get_sinit_capabilities(acm_hdr_t* hdr) +{ + /* assumes that it passed is_sinit_acmod() */ + + acm_info_table_t *info_table = get_acmod_info_table(hdr); + if ( info_table == NULL || info_table->version < 3 ) + return 0; + + return info_table->capabilities._raw; +} + +static bool is_acmod(void *acmod_base, size_t acmod_size, uint8_t *type, + bool quiet) +{ + acm_hdr_t *acm_hdr; + acm_info_table_t *info_table; + + acm_hdr = (acm_hdr_t *)acmod_base; + + /* first check size */ + if ( acmod_size < sizeof(acm_hdr_t) ) { + if ( !quiet ) + printf("\t ACM size is too small: acmod_size=%x," + " sizeof(acm_hdr)=%x\n", (uint32_t)acmod_size, + (uint32_t)sizeof(acm_hdr) ); + return false; + } + + /* then check overflow */ + if ( multiply_overflow_u32(acm_hdr->size, 4) ) { + if ( !quiet ) + printf("\t ACM header size in bytes overflows\n"); + return false; + } + + /* then check size equivalency */ + if ( acmod_size != acm_hdr->size * 4 ) { + if ( !quiet ) + printf("\t ACM size is too small: acmod_size=%x," + " acm_hdr->size*4=%x\n", (uint32_t)acmod_size, + acm_hdr->size*4); + return false; + } + + /* then check type and vendor */ + if ( (acm_hdr->module_type != ACM_TYPE_CHIPSET) || + (acm_hdr->module_vendor != ACM_VENDOR_INTEL) ) { + if ( !quiet ) + printf("\t ACM type/vendor mismatch: module_type=%x," + " module_vendor=%x\n", acm_hdr->module_type, + acm_hdr->module_vendor); + return false; + } + + info_table = get_acmod_info_table(acm_hdr); + if ( info_table == NULL ) + return false; + + /* check if ACM UUID is present */ + if ( !are_uuids_equal(&(info_table->uuid), &((uuid_t)ACM_UUID_V3)) ) { + if ( !quiet ) { + printf("\t unknown UUID: "); print_uuid(&info_table->uuid); + printf("\n"); + } + return false; + } + + if ( type != NULL ) + *type = info_table->chipset_acm_type; + + if ( info_table->version < 3 ) { + if ( !quiet ) + printf("\t ACM info_table version unsupported (%u)\n", + (uint32_t)info_table->version); + return false; + } + /* there is forward compatibility, so this is just a warning */ + else if ( info_table->version > 3 ) { + if ( !quiet ) + printf("\t ACM info_table version mismatch (%u)\n", + (uint32_t)info_table->version); + } + + return true; +} + +bool is_sinit_acmod(void *acmod_base, size_t acmod_size, bool quiet) +{ + uint8_t type; + + if ( !is_acmod(acmod_base, acmod_size, &type, quiet) ) + return false; + + if ( type != ACM_CHIPSET_TYPE_SINIT ) { + printf("ACM is not an SINIT ACM (%x)\n", type); + return false; + } + + return true; +} + +bool does_acmod_match_chipset(acm_hdr_t* hdr) +{ + /* this fn assumes that the ACM has already passed the is_acmod() checks */ + acm_chipset_id_list_t *chipset_id_list; + txt_didvid_t didvid; + unsigned int i; + /* + * check if fusing is same + */ + txt_ver_fsbif_emif_t ver; + ver._raw = read_pub_config_reg(TXTCR_VER_FSBIF); + if ( (ver._raw & 0xffffffff) == 0xffffffff || + (ver._raw & 0xffffffff) == 0x00 ) /* need to use VER.EMIF */ + ver._raw = read_pub_config_reg(TXTCR_VER_EMIF); + if ( ver.prod_fused != !hdr->flags.debug_signed ) { + printf("\t production/debug mismatch between chipset and ACM\n"); + return false; + } + + /* + * check if vendor/device/revision IDs match + */ + chipset_id_list = get_acmod_chipset_list(hdr); + if ( chipset_id_list == NULL ) + return false; + + /* get chipset device and vendor id info */ + didvid._raw = read_pub_config_reg(TXTCR_DIDVID); + + printf("\t %x ACM chipset id entries:\n", chipset_id_list->count); + for ( i = 0; i < chipset_id_list->count; i++ ) { + acm_chipset_id_t *chipset_id = &(chipset_id_list->chipset_ids[i]); + printf("\t vendor: 0x%x, device: 0x%x, flags: 0x%x, " + "revision: 0x%x, extended: 0x%x\n", + (uint32_t)chipset_id->vendor_id, + (uint32_t)chipset_id->device_id, chipset_id->flags, + (uint32_t)chipset_id->revision_id, chipset_id->extended_id); + + if ( (didvid.vendor_id == chipset_id->vendor_id ) && + (didvid.device_id == chipset_id->device_id ) && + ( ( ( (chipset_id->flags & 0x1) == 0) && + (didvid.revision_id == chipset_id->revision_id) ) || + ( ( (chipset_id->flags & 0x1) == 1) && + ((didvid.revision_id & chipset_id->revision_id) != 0 ) ) ) ) + return true; + } + + printf("\t ACM does not match chipset\n"); + + return false; +} + +acm_hdr_t *copy_sinit(acm_hdr_t *sinit) +{ + void *sinit_region_base; + uint32_t sinit_region_size; + txt_heap_t *txt_heap; + bios_data_t *bios_data; + + /* get BIOS-reserved region from LT.SINIT.BASE config reg */ + sinit_region_base = + (void*)(unsigned long)read_pub_config_reg(TXTCR_SINIT_BASE); + sinit_region_size = (uint32_t)read_pub_config_reg(TXTCR_SINIT_SIZE); + + /* + * check if BIOS already loaded an SINIT module there + */ + txt_heap = get_txt_heap(); + bios_data = get_bios_data_start(txt_heap); + /* BIOS has loaded an SINIT module, so verify that it is valid */ + if ( bios_data->bios_sinit_size != 0 ) { + printf("BIOS has already loaded an SINIT module\n"); + /* is it a valid SINIT module? */ + if ( is_sinit_acmod(sinit_region_base, bios_data->bios_sinit_size, false) && + does_acmod_match_chipset((acm_hdr_t *)sinit_region_base) ) { + /* no other SINIT was provided so must use one BIOS provided */ + if ( sinit == NULL ) + return (acm_hdr_t *)sinit_region_base; + + /* is it newer than the one we've been provided? */ + if ( ((acm_hdr_t *)sinit_region_base)->date >= sinit->date ) { + printf("BIOS-provided SINIT is newer, so using it\n"); + return (acm_hdr_t *)sinit_region_base; /* yes */ + } + else + printf("BIOS-provided SINIT is older: date=%x\n", + ((acm_hdr_t *)sinit_region_base)->date); + } + } + /* our SINIT is newer than BIOS's (or BIOS did not have one) */ + + /* BIOS SINIT not present or not valid and none provided */ + if ( sinit == NULL ) + return NULL; + + /* overflow? */ + if ( multiply_overflow_u32(sinit->size, 4) ) { + printf("sinit size in bytes overflows\n"); + return NULL; + } + + /* make sure our SINIT fits in the reserved region */ + if ( (sinit->size * 4) > sinit_region_size ) { + printf("BIOS-reserved SINIT size (%x) is too small for loaded " + "SINIT (%x)\n", sinit_region_size, sinit->size*4); + return NULL; + } + + /* copy it there */ + memcpy(sinit_region_base, sinit, sinit->size*4); + + printf("copied SINIT (size=%x) to %p\n", sinit->size*4, + sinit_region_base); + + return (acm_hdr_t *)sinit_region_base; +} + + +/* + * Do some AC module sanity checks because any violations will cause + * an TXT.RESET. Instead detect these, print a desriptive message, + * and skip SENTER/ENTERACCS + */ +bool verify_acmod(acm_hdr_t *acm_hdr) +{ +/* getsec_parameters_t params; */ + uint32_t size; + acm_info_table_t *info_table; + txt_caps_t caps_mask = { 0 }; + + /* assumes this already passed is_acmod() test */ + + size = acm_hdr->size * 4; /* hdr size is in dwords, we want bytes */ + + /* + * AC mod must start on 4k page boundary + */ + + if ( (unsigned long)acm_hdr & 0xfff ) { + printf("AC mod base not 4K aligned (%p)\n", acm_hdr); + return false; + } + printf("AC mod base alignment OK\n"); + + /* AC mod size must: + * - be multiple of 64 + * - greater than ??? + * - less than max supported size for this processor + */ + + if ( (size == 0) || ((size % 64) != 0) ) { + printf("AC mod size %x bogus\n", size); + return false; + } + + /// XXX TODO bring in txt.c stuff +/* if ( !get_parameters(¶ms) ) { */ +/* printf("get_parameters() failed\n"); */ +/* return false; */ +/* } */ + +/* if ( size > params.acm_max_size ) { */ +/* printf("AC mod size too large: %x (max=%x)\n", size, */ +/* params.acm_max_size); */ +/* return false; */ +/* } */ + + printf("AC mod size OK\n"); + + /* + * perform checks on AC mod structure + */ + + /* print it for debugging */ + print_acm_hdr(acm_hdr, "SINIT"); + + /* entry point is offset from base addr so make sure it is within module */ + if ( acm_hdr->entry_point >= size ) { + printf("AC mod entry (%08x) >= AC mod size (%08x)\n", + acm_hdr->entry_point, size); + return false; + } + + /* overflow? */ + if ( plus_overflow_u32(acm_hdr->seg_sel, 8) ) { + printf("seg_sel plus 8 overflows\n"); + return false; + } + + if ( !acm_hdr->seg_sel || /* invalid selector */ + (acm_hdr->seg_sel & 0x07) || /* LDT, PL!=0 */ + (acm_hdr->seg_sel + 8 > acm_hdr->gdt_limit) ) { + printf("AC mod selector [%04x] bogus\n", acm_hdr->seg_sel); + return false; + } + + /* + * check for compatibility with this MLE + */ + + info_table = get_acmod_info_table(acm_hdr); + if ( info_table == NULL ) + return false; + + /* check MLE header versions */ + if ( info_table->min_mle_hdr_ver > MLE_HDR_VER ) { + printf("AC mod requires a newer MLE (0x%08x)\n", + info_table->min_mle_hdr_ver); + return false; + } + + /* check capabilities */ + /* we need to match one of rlp_wake_{getsec, monitor} */ + caps_mask.rlp_wake_getsec = caps_mask.rlp_wake_monitor = 1; + + if ( ( ( MLE_HDR_CAPS & caps_mask._raw ) & + ( info_table->capabilities._raw & caps_mask._raw) ) == 0 ) { + printf("SINIT and MLE not support compatible RLP wake mechanisms\n"); + return false; + } + /* we also expect ecx_pgtbl to be set */ + if ( !info_table->capabilities.ecx_pgtbl ) { + printf("SINIT does not support launch with MLE pagetable in ECX\n"); + /* TODO when SINIT ready + * return false; + */ + } + + /* check for version of OS to SINIT data */ + /* we don't support old versions */ + if ( info_table->os_sinit_data_ver < 4 ) { + printf("SINIT's os_sinit_data version unsupported (%u)\n", + info_table->os_sinit_data_ver); + return false; + } + /* only warn if SINIT supports more recent version than us */ + else if ( info_table->os_sinit_data_ver > 5 ) { + printf("SINIT's os_sinit_data version unsupported (%u)\n", + info_table->os_sinit_data_ver); + } + + return true; +} + + +/* + * Local variables: + * mode: C + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/txt_hash.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/txt_hash.c new file mode 100644 index 0000000000..2802968b84 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/txt_hash.c @@ -0,0 +1,200 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * hash.c: support functions for tb_hash_t type + * + * Copyright (c) 2006-2010, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * Modified for XMHF by jonmccune@cmu.edu, 2011.01.04 + */ + +#include + +/* + * are_hashes_equal + * + * compare whether two hash values are equal. + * + */ +bool are_hashes_equal(const tb_hash_t *hash1, const tb_hash_t *hash2, + uint8_t hash_alg) +{ + if ( ( hash1 == NULL ) || ( hash2 == NULL ) ) { + printf("Error: hash pointer is zero.\n"); + return false; + } + + if ( hash_alg == TB_HALG_SHA1 ) + return (memcmp((const char*)hash1, (const char*)hash2, SHA1_LENGTH) == 0); + else { + printf("unsupported hash alg (%u)\n", hash_alg); + return false; + } +} + +/* + * hash_buffer + * + * hash the buffer according to the algorithm + * + */ +bool hash_buffer(const unsigned char* buf, size_t size, tb_hash_t *hash, + uint8_t hash_alg) +{ + if ( hash == NULL ) { + printf("Error: There is no space for output hash.\n"); + return false; + } + + if ( hash_alg == TB_HALG_SHA1 ) { + sha1_buffer(buf, size, hash->sha1); + return true; + } + else { + printf("unsupported hash alg (%u)\n", hash_alg); + return false; + } +} + +/* + * extend_hash + * + * perform "extend" of two hashes (i.e. hash1 = SHA(hash1 || hash2) + * + */ +bool extend_hash(tb_hash_t *hash1, const tb_hash_t *hash2, uint8_t hash_alg) +{ + uint8_t buf[2*get_hash_size(hash_alg)]; + + if ( hash1 == NULL || hash2 == NULL ) { + printf("Error: There is no space for output hash.\n"); + return false; + } + + if ( hash_alg == TB_HALG_SHA1 ) { + memcpy(buf, &(hash1->sha1), sizeof(hash1->sha1)); + memcpy(buf + sizeof(hash1->sha1), &(hash2->sha1), sizeof(hash1->sha1)); + sha1_buffer(buf, 2*sizeof(hash1->sha1), hash1->sha1); + return true; + } + else { + printf("unsupported hash alg (%u)\n", hash_alg); + return false; + } +} + +void print_hash(const tb_hash_t *hash, uint8_t hash_alg) +{ + if ( hash == NULL ) { + printf("NULL"); + return; + } + + if ( hash_alg == TB_HALG_SHA1 ) + print_hex(NULL, (const uint8_t *)hash->sha1, sizeof(hash->sha1)); + else { + printf("unsupported hash alg (%u)\n", hash_alg); + return; + } +} + +void copy_hash(tb_hash_t *dest_hash, const tb_hash_t *src_hash, + uint8_t hash_alg) +{ + if ( dest_hash == NULL || dest_hash == NULL ) { + printf("hashes are NULL\n"); + return; + } + + if ( hash_alg == TB_HALG_SHA1 ) + memcpy(dest_hash, src_hash, SHA1_LENGTH); + else + printf("unsupported hash alg (%u)\n", hash_alg); +} + + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/txt_heap.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/txt_heap.c new file mode 100644 index 0000000000..8510e352f0 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-bootloader/txt_heap.c @@ -0,0 +1,421 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * heap.c: fns for verifying and printing the Intel(r) TXT heap data structs + * + * Copyright (c) 2003-2010, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * Modified for XMHF by jonmccune@cmu.edu, 2011.01.04 + */ + +#include + +static inline void print_heap_hash(sha1_hash_t hash) +{ + print_hash((const tb_hash_t *)hash, TB_HALG_SHA1); +} + +static void print_bios_data(bios_data_t *bios_data) +{ + printf("bios_data (@%p, %llx):\n", bios_data, + *((uint64_t *)bios_data - 1)); + printf("\t version: %u\n", bios_data->version); + printf("\t bios_sinit_size: 0x%x (%u)\n", bios_data->bios_sinit_size, + bios_data->bios_sinit_size); + printf("\t lcp_pd_base: 0x%llx\n", bios_data->lcp_pd_base); + printf("\t lcp_pd_size: 0x%llx (%llu)\n", bios_data->lcp_pd_size, + bios_data->lcp_pd_size); + printf("\t num_logical_procs: %u\n", bios_data->num_logical_procs); + if ( bios_data->version >= 3 ) + printf("\t flags: 0x%08llx\n", bios_data->flags); +} + +bool verify_bios_data(txt_heap_t *txt_heap) +{ + uint64_t size, heap_size; + bios_data_t *bios_data; + + /* check size */ + heap_size = read_priv_config_reg(TXTCR_HEAP_SIZE); + size = get_bios_data_size(txt_heap); + if ( size == 0 ) { + printf("BIOS data size is 0\n"); + return false; + } + if ( size > heap_size ) { + printf("BIOS data size is larger than heap size " + "(%llx, heap size=%llx)\n", size, heap_size); + return false; + } + + bios_data = get_bios_data_start(txt_heap); + + /* check version */ + if ( bios_data->version < 2 ) { + printf("unsupported BIOS data version (%u)\n", bios_data->version); + return false; + } + /* we assume backwards compatibility but print a warning */ + if ( bios_data->version > 3 ) + printf("unsupported BIOS data version (%u)\n", bios_data->version); + + /* all TXT-capable CPUs support at least 2 cores */ + if ( bios_data->num_logical_procs < 2 ) { + printf("BIOS data has incorrect num_logical_procs (%u)\n", + bios_data->num_logical_procs); + return false; + } +#define NR_CPUS 8 // XXX arbitrary value; use something sane + else if ( bios_data->num_logical_procs > NR_CPUS ) { + printf("BIOS data specifies too many CPUs (%u)\n", + bios_data->num_logical_procs); + return false; + } + + print_bios_data(bios_data); + + return true; +} + +static void print_os_mle_data(os_mle_data_t *os_mle_data) +{ + printf("os_mle_data (@%p, %llx):\n", os_mle_data, + *((uint64_t *)os_mle_data - 1)); + printf("\t version: %u\n", os_mle_data->version); + /* TBD: perhaps eventually print saved_mtrr_state field */ + printf("\t mbi: %p\n", (multiboot_info_t *)os_mle_data->mbi); +} + +static bool verify_os_mle_data(txt_heap_t *txt_heap) +{ + uint64_t size, heap_size; + os_mle_data_t *os_mle_data; + + /* check size */ + heap_size = read_priv_config_reg(TXTCR_HEAP_SIZE); + size = get_os_mle_data_size(txt_heap); + if ( size == 0 ) { + printf("OS to MLE data size is 0\n"); + return false; + } + if ( size > heap_size ) { + printf("OS to MLE data size is larger than heap size " + "(%llx, heap size=%llx)\n", size, heap_size); + return false; + } + if ( size != (sizeof(os_mle_data_t) + sizeof(size)) ) { + printf("OS to MLE data size (%llx) is not equal to " + "os_mle_data_t size (%x)\n", size, sizeof(os_mle_data_t)); + return false; + } + + os_mle_data = get_os_mle_data_start(txt_heap); + + /* check version */ + /* since this data is from our pre-launch to post-launch code only, it */ + /* should always be this */ + if ( os_mle_data->version != 2 ) { + printf("unsupported OS to MLE data version (%u)\n", + os_mle_data->version); + return false; + } + + /* field checks */ + if ( (multiboot_info_t *)os_mle_data->mbi == NULL ) { + printf("OS to MLE data mbi field is NULL\n"); + return false; + } + + print_os_mle_data(os_mle_data); + + return true; +} + +void print_os_sinit_data(os_sinit_data_t *os_sinit_data) +{ + printf("os_sinit_data (@%p, %llx):\n", os_sinit_data, + *((uint64_t *)os_sinit_data - 1)); + printf("\t version: %u\n", os_sinit_data->version); + printf("\t mle_ptab: 0x%llx\n", os_sinit_data->mle_ptab); + printf("\t mle_size: 0x%llx (%llu)\n", os_sinit_data->mle_size, + os_sinit_data->mle_size); + printf("\t mle_hdr_base: 0x%llx\n", os_sinit_data->mle_hdr_base); + printf("\t vtd_pmr_lo_base: 0x%llx\n", os_sinit_data->vtd_pmr_lo_base); + printf("\t vtd_pmr_lo_size: 0x%llx\n", os_sinit_data->vtd_pmr_lo_size); + printf("\t vtd_pmr_hi_base: 0x%llx\n", os_sinit_data->vtd_pmr_hi_base); + printf("\t vtd_pmr_hi_size: 0x%llx\n", os_sinit_data->vtd_pmr_hi_size); + printf("\t lcp_po_base: 0x%llx\n", os_sinit_data->lcp_po_base); + printf("\t lcp_po_size: 0x%llx (%llu)\n", os_sinit_data->lcp_po_size, + os_sinit_data->lcp_po_size); + print_txt_caps("\t ", os_sinit_data->capabilities); + if ( os_sinit_data->version >= 5 ) + printf("\t efi_rsdt_ptr: 0x%llx\n", os_sinit_data->efi_rsdt_ptr); +} + +static bool verify_os_sinit_data(txt_heap_t *txt_heap) +{ + uint64_t size, heap_size; + os_sinit_data_t *os_sinit_data; + + /* check size */ + heap_size = read_priv_config_reg(TXTCR_HEAP_SIZE); + size = get_os_sinit_data_size(txt_heap); + if ( size == 0 ) { + printf("OS to SINIT data size is 0\n"); + return false; + } + if ( size > heap_size ) { + printf("OS to SINIT data size is larger than heap size " + "(%llx, heap size=%llx)\n", size, heap_size); + return false; + } + + os_sinit_data = get_os_sinit_data_start(txt_heap); + + /* check version (but since we create this, it should always be OK) */ + if ( os_sinit_data->version < 4 || os_sinit_data->version > 5 ) { + printf("unsupported OS to SINIT data version (%u)\n", + os_sinit_data->version); + return false; + } + + if ( (os_sinit_data->version == 4 && + size != offsetof(os_sinit_data_t, efi_rsdt_ptr) + sizeof(uint64_t)) + || (os_sinit_data->version == 5 && + size != sizeof(os_sinit_data_t) + sizeof(uint64_t)) ) { + printf("OS to SINIT data size (%llx) does not match for version (%x)\n", + size, sizeof(os_sinit_data_t)); + return false; + } + + print_os_sinit_data(os_sinit_data); + + return true; +} + +static void print_sinit_mdrs(sinit_mdr_t mdrs[], uint32_t num_mdrs) +{ + static const char *mem_types[] = {"GOOD", "SMRAM OVERLAY", + "SMRAM NON-OVERLAY", + "PCIE EXTENDED CONFIG", "PROTECTED"}; + unsigned int i; + + printf("\t sinit_mdrs:\n"); + for ( i = 0; i < num_mdrs; i++ ) { + printf("\t\t %016llx - %016llx ", mdrs[i].base, + mdrs[i].base + mdrs[i].length); + if ( mdrs[i].mem_type < sizeof(mem_types)/sizeof(mem_types[0]) ) + printf("(%s)\n", mem_types[mdrs[i].mem_type]); + else + printf("(%d)\n", (int)mdrs[i].mem_type); + } +} + +static void print_sinit_mle_data(sinit_mle_data_t *sinit_mle_data) +{ + printf("sinit_mle_data (@%p, %llx):\n", sinit_mle_data, + *((uint64_t *)sinit_mle_data - 1)); + printf("\t version: %u\n", sinit_mle_data->version); + printf("\t bios_acm_id: \n\t"); + print_heap_hash(sinit_mle_data->bios_acm_id); + printf("\t edx_senter_flags: 0x%08x\n", + sinit_mle_data->edx_senter_flags); + printf("\t mseg_valid: 0x%llx\n", sinit_mle_data->mseg_valid); + printf("\t sinit_hash:\n\t"); print_heap_hash(sinit_mle_data->sinit_hash); + printf("\t mle_hash:\n\t"); print_heap_hash(sinit_mle_data->mle_hash); + printf("\t stm_hash:\n\t"); print_heap_hash(sinit_mle_data->stm_hash); + printf("\t lcp_policy_hash:\n\t"); + print_heap_hash(sinit_mle_data->lcp_policy_hash); + printf("\t lcp_policy_control: 0x%08x\n", + sinit_mle_data->lcp_policy_control); + printf("\t rlp_wakeup_addr: 0x%x\n", sinit_mle_data->rlp_wakeup_addr); + printf("\t num_mdrs: %u\n", sinit_mle_data->num_mdrs); + printf("\t mdrs_off: 0x%x\n", sinit_mle_data->mdrs_off); + printf("\t num_vtd_dmars: %u\n", sinit_mle_data->num_vtd_dmars); + printf("\t vtd_dmars_off: 0x%x\n", sinit_mle_data->vtd_dmars_off); + print_sinit_mdrs((sinit_mdr_t *) + (((void *)sinit_mle_data - sizeof(uint64_t)) + + sinit_mle_data->mdrs_off), sinit_mle_data->num_mdrs); + if ( sinit_mle_data->version >= 8 ) + printf("\t proc_scrtm_status: 0x%08x\n", + sinit_mle_data->proc_scrtm_status); +} + +static bool verify_sinit_mle_data(txt_heap_t *txt_heap) +{ + uint64_t size, heap_size; + sinit_mle_data_t *sinit_mle_data; + + /* check size */ + heap_size = read_priv_config_reg(TXTCR_HEAP_SIZE); + size = get_sinit_mle_data_size(txt_heap); + if ( size == 0 ) { + printf("SINIT to MLE data size is 0\n"); + return false; + } + if ( size > heap_size ) { + printf("SINIT to MLE data size is larger than heap size\n" + "(%llx, heap size=%llx)\n", size, heap_size); + return false; + } + + sinit_mle_data = get_sinit_mle_data_start(txt_heap); + + /* check version */ + sinit_mle_data = get_sinit_mle_data_start(txt_heap); + if ( sinit_mle_data->version < 6 ) { + printf("unsupported SINIT to MLE data version (%u)\n", + sinit_mle_data->version); + return false; + } + else if ( sinit_mle_data->version > 8 ) { + printf("unsupported SINIT to MLE data version (%u)\n", + sinit_mle_data->version); + } + + /* this data is generated by SINIT and so is implicitly trustworthy, */ + /* so we don't need to validate it's fields */ + + print_sinit_mle_data(sinit_mle_data); + + return true; +} + +bool verify_txt_heap(txt_heap_t *txt_heap, bool bios_data_only) +{ + uint64_t size1, size2, size3, size4; + + /* verify BIOS to OS data */ + if ( !verify_bios_data(txt_heap) ) + return false; + + if ( bios_data_only ) + return true; + + /* check that total size is within the heap */ + size1 = get_bios_data_size(txt_heap); + size2 = get_os_mle_data_size(txt_heap); + size3 = get_os_sinit_data_size(txt_heap); + size4 = get_sinit_mle_data_size(txt_heap); + + /* overflow? */ + if ( plus_overflow_u64(size1, size2) ) { + printf("TXT heap data size overflows\n"); + return false; + } + if ( plus_overflow_u64(size3, size4) ) { + printf("TXT heap data size overflows\n"); + return false; + } + if ( plus_overflow_u64(size1 + size2, size3 + size4) ) { + printf("TXT heap data size overflows\n"); + return false; + } + + if ( (size1 + size2 + size3 + size4) > + read_priv_config_reg(TXTCR_HEAP_SIZE) ) { + printf("TXT heap data sizes (%llx, %llx, %llx, %llx) are larger than\n" + "heap total size (%llx)\n", size1, size2, size3, size4, + read_priv_config_reg(TXTCR_HEAP_SIZE)); + return false; + } + + /* verify OS to MLE data */ + if ( !verify_os_mle_data(txt_heap) ) + return false; + + /* verify OS to SINIT data */ + if ( !verify_os_sinit_data(txt_heap) ) + return false; + + /* verify SINIT to MLE data */ + if ( !verify_sinit_mle_data(txt_heap) ) + return false; + + return true; +} + + +/* + * Local variables: + * mode: C + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/Makefile b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/Makefile new file mode 100644 index 0000000000..02e8987f1a --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/Makefile @@ -0,0 +1,186 @@ +# makefile for "runtime" +# author: amit vasudevan (amitvasudevan@acm.org) + +# tie components used by the runtime +# WARNING: if both Serial & VGA are enabled, you actually get neither. +# TODO: Fix it. +# OBJECTS_PRECOMPILED = ./xmhf-debug/lib.a + +# OBJECTS_PRECOMPILED += ./xmhf-tpm/tpm-interface.o +OBJECTS_PRECOMPILED = ./xmhf-tpm/tpm-interface.o +OBJECTS_PRECOMPILED += ./xmhf-tpm/arch/x86/tpm-x86.o +OBJECTS_PRECOMPILED += ./xmhf-tpm/arch/x86/svm/tpm-x86svm.o +OBJECTS_PRECOMPILED += ./xmhf-tpm/arch/x86/vmx/tpm-x86vmx.o + +OBJECTS_PRECOMPILED += ./xmhf-mm/xmhf-tlsf.o +OBJECTS_PRECOMPILED += ./xmhf-mm/xmhf-mm.o + +OBJECTS_PRECOMPILED += ./xmhf-memprot/memp-interface.o +OBJECTS_PRECOMPILED += ./xmhf-memprot/arch/x86/memp-x86.o +OBJECTS_PRECOMPILED += ./xmhf-memprot/arch/x86/vmx/memp-x86vmx.o +OBJECTS_PRECOMPILED += ./xmhf-memprot/arch/x86/vmx/memp-x86vmx-data.o +OBJECTS_PRECOMPILED += ./xmhf-memprot/arch/x86/svm/memp-x86svm.o +OBJECTS_PRECOMPILED += ./xmhf-memprot/arch/x86/svm/memp-x86svm-data.o + +OBJECTS_PRECOMPILED += ./xmhf-eventhub/arch/x86/svm/peh-x86-$(TARGET_SUBARCH)svm-entry.o +OBJECTS_PRECOMPILED += ./xmhf-eventhub/arch/x86/svm/peh-x86svm-main.o +OBJECTS_PRECOMPILED += ./xmhf-eventhub/arch/x86/vmx/peh-x86-$(TARGET_SUBARCH)vmx-entry.o +OBJECTS_PRECOMPILED += ./xmhf-eventhub/arch/x86/vmx/peh-x86vmx-main.o +OBJECTS_PRECOMPILED += ./xmhf-eventhub/arch/x86/vmx/peh-x86-safemsr.o +ifeq ($(UPDATE_INTEL_UCODE), y) +OBJECTS_PRECOMPILED += ./xmhf-eventhub/arch/x86/vmx/peh-x86vmx-ucode.o +OBJECTS_PRECOMPILED += ./xmhf-eventhub/arch/x86/vmx/peh-x86vmx-ucode-data.o +endif + +OBJECTS_PRECOMPILED += ./xmhf-smpguest/smpg-interface.o +OBJECTS_PRECOMPILED += ./xmhf-smpguest/arch/x86/smpg-x86.o +OBJECTS_PRECOMPILED += ./xmhf-smpguest/arch/x86/svm/smpg-x86svm.o +OBJECTS_PRECOMPILED += ./xmhf-smpguest/arch/x86/svm/smpg-x86svm-data.o +OBJECTS_PRECOMPILED += ./xmhf-smpguest/arch/x86/vmx/smpg-x86vmx.o +OBJECTS_PRECOMPILED += ./xmhf-smpguest/arch/x86/vmx/smpg-x86vmx-data.o + +ifeq ($(DMAP), y) +OBJECTS_PRECOMPILED += ./xmhf-dmaprot/dmap-interface-runtime.o +OBJECTS_PRECOMPILED += ./xmhf-dmaprot/iommu-pt.o +OBJECTS_PRECOMPILED += ./xmhf-dmaprot/arch/x86/dmap-x86-runtime.o +OBJECTS_PRECOMPILED += ./xmhf-dmaprot/arch/x86/svm/dmap-svm.o +OBJECTS_PRECOMPILED += ./xmhf-dmaprot/arch/x86/vmx/dmap-vmx-internal.o +OBJECTS_PRECOMPILED += ./xmhf-dmaprot/arch/x86/vmx/dmap-vmx-runtime.o +OBJECTS_PRECOMPILED += ./xmhf-dmaprot/arch/x86/vmx/dmap-vmx-utils.o +OBJECTS_PRECOMPILED += ./xmhf-dmaprot/arch/x86/vmx/dmap-vmx-data.o +endif + +OBJECTS_PRECOMPILED += ./xmhf-xcphandler/xcph-interface.o +OBJECTS_PRECOMPILED += ./xmhf-xcphandler/arch/x86/xcph-x86.o +OBJECTS_PRECOMPILED += ./xmhf-xcphandler/arch/x86/xcph-stubs-$(TARGET_SUBARCH).o + +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/bplt-interface.o +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/bplt-interface-runtime.o +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/bplt-interface-smp.o +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/bplt-data.o +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/arch/x86/bplt-x86.o +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/arch/x86/bplt-x86-data.o +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/arch/x86/bplt-x86-pci.o +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/arch/x86/bplt-x86-acpi.o +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/arch/x86/bplt-x86-pit.o +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/arch/x86/bplt-x86-smp.o +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/arch/x86/bplt-x86-$(TARGET_SUBARCH)-smptrampoline.o +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/arch/x86/bplt-x86-$(TARGET_SUBARCH)-smplock.o +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/arch/x86/bplt-x86-addressing.o +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/arch/x86/bplt-x86-reboot.o +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/arch/x86/bplt-x86-cpu.o + + +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx.o +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx-data.o +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx-smp.o +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx-vmcs.o +ifeq ($(DRT), y) +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx-mtrrs.o +endif +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx-reboot.o + + +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/arch/x86/svm/bplt-x86svm.o +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/arch/x86/svm/bplt-x86svm-data.o +OBJECTS_PRECOMPILED += ./xmhf-baseplatform/arch/x86/svm/bplt-x86svm-smp.o + + +OBJECTS_PRECOMPILED += ./xmhf-partition/part-interface.o +OBJECTS_PRECOMPILED += ./xmhf-partition/arch/x86/part-x86.o +OBJECTS_PRECOMPILED += ./xmhf-partition/arch/x86/svm/part-x86svm.o +OBJECTS_PRECOMPILED += ./xmhf-partition/arch/x86/svm/part-x86-$(TARGET_SUBARCH)svm-sup.o +OBJECTS_PRECOMPILED += ./xmhf-partition/arch/x86/vmx/part-x86vmx.o +OBJECTS_PRECOMPILED += ./xmhf-partition/arch/x86/vmx/part-x86-$(TARGET_SUBARCH)vmx-sup.o + +OBJECTS_PRECOMPILED += ./xmhf-startup/runtime.o +OBJECTS_PRECOMPILED += ./xmhf-startup/rntm-data.o +OBJECTS_PRECOMPILED += ./xmhf-startup/arch/x86/rntm-x86-data.o + +OBJECTS_PRECOMPILED += ./xmhf-debug/lib.a + + +# separate from OBJECTS_PRECOMPILED because needs to come after libs on link line +OBJECTS_PRECOMPILED_LIBBACKENDS = ./xmhf-xmhfcbackend/xmhfc-putchar.o +OBJECTS_PRECOMPILED_LIBBACKENDS += ./xmhf-xmhfcbackend/stl/xmhfc-bitmap.o +OBJECTS_PRECOMPILED_LIBBACKENDS += ./xmhf-xmhfcbackend/stl/xmhfc-dlist.o + +#XMHF memory protection component +RUNTIME_COMPONENTS = xmhf-memprot +#XMHF Memory management component +RUNTIME_COMPONENTS += xmhf-mm +#XMHF partition event-hub component +RUNTIME_COMPONENTS += xmhf-eventhub +#XMHF SMP guest component +RUNTIME_COMPONENTS += xmhf-smpguest +ifeq ($(DMAP), y) +#XMHF DMA protection component +RUNTIME_COMPONENTS += xmhf-dmaprot +endif +#XMHF exception handler component +RUNTIME_COMPONENTS += xmhf-xcphandler +#XMHF base platform component +RUNTIME_COMPONENTS += xmhf-baseplatform +#XMHF partition component +RUNTIME_COMPONENTS += xmhf-partition +#XMHF TPM component +RUNTIME_COMPONENTS += xmhf-tpm +#XMHF debug component +RUNTIME_COMPONENTS += xmhf-debug +#XMHF libxmhfc environment callbacks +RUNTIME_COMPONENTS += xmhf-xmhfcbackend +#XMHF startup component +RUNTIME_COMPONENTS += xmhf-startup + +# targets +.PHONY: runtimecomponents $(RUNTIME_COMPONENTS) +runtimecomponents: $(RUNTIME_COMPONENTS) + +$(RUNTIME_COMPONENTS): %: + cd $@ && $(MAKE) -w all + + +.PHONY: all +all: runtimecomponents runtime.bin + +# Add Makefile dependency to allow parallelize make +$(OBJECTS_PRECOMPILED): %: runtimecomponents +$(OBJECTS_PRECOMPILED_LIBBACKENDS): %: runtimecomponents + +runtime.bin: runtimecomponents $(APP_ARCHIVE) runtime.lds + $(LD) -T runtime.lds -o runtime.exe $(OBJECTS_PRECOMPILED) $(APP_ARCHIVE) $(ADDL_LIBS) $(OBJECTS_PRECOMPILED_LIBBACKENDS) -L$(CCLIB) -lgcc + # .palign_data and .stack are NOBITS in the ELF file (similar to .bss), but + # we need them in runtime.bin. So use the --set-section-flags option to + # force objcopy to zero them and add to runtime.bin. + $(OBJCOPY) \ + --set-section-flags .palign_data=alloc,load,contents \ + --set-section-flags .stack=alloc,load,contents \ + --output-format=binary runtime.exe runtime.bin + # Optional: use sparse file for runtime.bin to reduce fs space usage + -fallocate -d runtime.bin + # Compute sha-1 hash + sha1sum runtime.bin > runtime.sha1 + +runtime.lds: runtime.lds.S + gcc -E -x c $(ASFLAGS) $< | grep -v '^#' > $@ + +.PHONY: clean +clean: + $(RM) -rf *.exe + $(RM) -rf *.bin + $(RM) -rf *.gz + $(RM) -rf *.lds + $(RM) -rf *.sha1 + + cd xmhf-mm && $(MAKE) -w clean + cd xmhf-memprot && $(MAKE) -w clean + cd xmhf-eventhub && $(MAKE) -w clean + cd xmhf-dmaprot && $(MAKE) -w clean + cd xmhf-smpguest && $(MAKE) -w clean + cd xmhf-xcphandler && $(MAKE) -w clean + cd xmhf-baseplatform && $(MAKE) -w clean + cd xmhf-partition && $(MAKE) -w clean + cd xmhf-tpm && $(MAKE) -w clean + cd xmhf-debug && $(MAKE) -w clean + cd xmhf-xmhfcbackend && $(MAKE) -w clean + cd xmhf-startup && $(MAKE) -w clean diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/runtime.lds.S b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/runtime.lds.S new file mode 100644 index 0000000000..d33864f798 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/runtime.lds.S @@ -0,0 +1,141 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include + +/* gcc -m32 will define i386, but we do not want it */ +#ifdef i386 +#undef i386 +#endif /* i386 */ + +#ifdef __I386__ +OUTPUT_ARCH(i386) +#elif defined(__AMD64__) +OUTPUT_ARCH(i386:x86-64) +#else /* !defined(__I386__) && !defined(__AMD64__) */ +#error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + +ENTRY(xmhf_runtime_entry) + +MEMORY +{ + all (rwxai) : ORIGIN = __TARGET_BASE, LENGTH = 768M /* length is arbitrary */ + debug (rwxai) : ORIGIN = 0, LENGTH = 1024M + unaccounted (rwxai) : ORIGIN = 0, LENGTH = 0 /* see section .unaccounted at end */ +} + +SECTIONS +{ + . = __TARGET_BASE; + + .text : { + *(.s_rpb) + *(.text) + *(.text.unlikely) + . = ALIGN(4096); + } =0x9090 + + .data : { + *(.data) + *(.rodata) + *(.rodata.str1.*) + *(.comment) + *(.eh_frame) /* exception-metadata. might be able to discard */ + *(.bss) + . = ALIGN(4); + _begin_xcph_table = .; + *(.xcph_table) + _end_xcph_table = .; + . = ALIGN(4096); + } =0x9090 + + /* + * This section is marked as NOBITS in runtime.exe. Need to use + * --set-section-flags in objcopy to include this section to runtime.bin + */ + .palign_data : { + *(.bss.palign_data) + . = ALIGN(4096); + } =0x9090 + + /* + * This section is marked as NOBITS in runtime.exe. Need to use + * --set-section-flags in objcopy to include this section to runtime.bin + */ + .stack : { + *(.bss.stack) + . = ALIGN(4096); + } =0x9090 + + /* debug sections */ + .debug_abbrev : { *(.debug_abbrev) } >debug + .debug_aranges : { *(.debug_aranges) } >debug + .debug_info : { *(.debug_info) } >debug + .debug_line : { *(.debug_line) } >debug + .debug_line_str : { *(.debug_line_str) } >debug + .debug_loc : { *(.debug_loc) } >debug + .debug_loclists : { *(.debug_loclists) } >debug + .debug_ranges : { *(.debug_ranges) } >debug + .debug_rnglists : { *(.debug_rnglists) } >debug + .debug_str : { *(.debug_str) } >debug + + /DISCARD/ : { + *(.note.gnu.property) + *(.gnu.build.attributes) + } + + /* this is to cause the link to fail if there is + * anything we didn't explicitly place. + * when this does cause link to fail, temporarily comment + * this part out to see what sections end up in the output + * which are not handled above, and handle them. + */ + .unaccounted : { + *(*) + } >unaccounted + +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/runtime.mk b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/runtime.mk new file mode 100644 index 0000000000..80efa7fe09 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/runtime.mk @@ -0,0 +1,69 @@ +# Common makefile rules for components under xmhf-runtime +# author: Eric Li (xiaoyili@andrew.cmu.edu) +# +# Currently there are two subarch configurations: +# * Boot loader is i386, secure loader and runtime are also i386 +# * Boot loader is i386, secure loader and runtime are amd64 +# +# In the first case, object files need to be only compiled once. In the second +# case, objects needed by the boot loader need to be copied in both i386 and +# amd64. So each component needs to declare whether a source is needed by the +# bootloader. +# +# These variables should have been already defined when including this file +# * C_SOURCES: .c files needed by secure loader / runtime +# * AS_SOURCES: .S files needed by secure loader / runtime +# * C_SOURCES_BL: .c files needed by boot loader when runtime is amd64 +# * AS_SOURCES_BL: .S files needed by boot loader when runtime is amd64 +# * EXTRA_CLEAN: files to be cleaned other than OBJECTS and OBJECTS_BL +# +# This file will define these variables +# * OBJECTS: .o files needed by secure loader / runtime +# * OBJECTS_BL: .o files needed by boot loader when runtime is amd64 +# +# This file will define these targets +# * all: the default target, contains OBJECTS and OBJECTS_BL +# * *.o: built for secure loader / runtime +# * *.i386.o: built for boot loader when runtime is amd64 +# * clean: remove object files and EXTRA_CLEAN + +_AS_OBJECTS = $(patsubst %.S, %.o, $(AS_SOURCES)) +_C_OBJECTS = $(patsubst %.c, %.o, $(C_SOURCES)) +OBJECTS = $(_AS_OBJECTS) $(_C_OBJECTS) +OBJECTS_BL = + +.PHONY: all +all: $(OBJECTS) + +# Generate .d files +DEPFLAGS = -MMD + +M_SOURCES = Makefile ../Makefile ../../Makefile + +$(_AS_OBJECTS): %.o: %.S $(M_SOURCES) + $(CC) -c $(ASFLAGS) $(DEPFLAGS) -o $@ $< +$(_C_OBJECTS): %.o: %.c $(M_SOURCES) + $(CC) -c $(CFLAGS) $(DEPFLAGS) -o $@ $< + +# If runtime is amd64, compile i386 version of object files for bootloader +ifeq ($(TARGET_SUBARCH), amd64) +_AS_OBJECTS_BL = $(patsubst %.S, %.i386.o, $(AS_SOURCES_BL)) +_C_OBJECTS_BL = $(patsubst %.c, %.i386.o, $(C_SOURCES_BL)) +OBJECTS_BL = $(_AS_OBJECTS_BL) $(_C_OBJECTS_BL) + +all: $(OBJECTS_BL) + +$(_AS_OBJECTS_BL): %.i386.o: %.S $(M_SOURCES) + $(CC32) -c $(BASFLAGS) $(DEPFLAGS) -o $@ $< +$(_C_OBJECTS_BL): %.i386.o: %.c $(M_SOURCES) + $(CC32) -c $(BCFLAGS) $(DEPFLAGS) -o $@ $< +endif + +_DEP_FILES = $(patsubst %.o, %.d, $(OBJECTS) $(OBJECTS_BL)) + +-include $(_DEP_FILES) + +.PHONY: clean +clean: + $(RM) -rf $(OBJECTS) $(OBJECTS_BL) $(_DEP_FILES) $(EXTRA_CLEAN) + diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/Makefile b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/Makefile new file mode 100644 index 0000000000..0ba7517523 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/Makefile @@ -0,0 +1,48 @@ +# makefile for xmhf-baseplatform (EMHF base platform component) +# author: amit vasudevan (amitvasudevan@acm.org) + +# source files +AS_SOURCES = ./arch/x86/bplt-x86-$(TARGET_SUBARCH)-smptrampoline.S +AS_SOURCES += ./arch/x86/bplt-x86-$(TARGET_SUBARCH)-smplock.S + +C_SOURCES = bplt-interface.c +C_SOURCES += bplt-interface-runtime.c +C_SOURCES += bplt-interface-smp.c +C_SOURCES += bplt-data.c + +C_SOURCES += ./arch/x86/bplt-x86.c +C_SOURCES += ./arch/x86/bplt-x86-data.c +C_SOURCES += ./arch/x86/bplt-x86-pci.c +C_SOURCES += ./arch/x86/bplt-x86-acpi.c +C_SOURCES += ./arch/x86/bplt-x86-pit.c +C_SOURCES += ./arch/x86/bplt-x86-smp.c +C_SOURCES += ./arch/x86/bplt-x86-addressing.c +C_SOURCES += ./arch/x86/bplt-x86-reboot.c +C_SOURCES += ./arch/x86/bplt-x86-cpu.c + +C_SOURCES += ./arch/x86/vmx/bplt-x86vmx.c +C_SOURCES += ./arch/x86/vmx/bplt-x86vmx-data.c +C_SOURCES += ./arch/x86/vmx/bplt-x86vmx-vmcs.c +C_SOURCES += ./arch/x86/vmx/bplt-x86vmx-smp.c +ifeq ($(DRT), y) +C_SOURCES += ./arch/x86/vmx/bplt-x86vmx-mtrrs.c +endif +C_SOURCES += ./arch/x86/vmx/bplt-x86vmx-reboot.c + +C_SOURCES += ./arch/x86/svm/bplt-x86svm.c +C_SOURCES += ./arch/x86/svm/bplt-x86svm-data.c +C_SOURCES += ./arch/x86/svm/bplt-x86svm-smp.c + +AS_SOURCES_BL = ./arch/x86/bplt-x86-i386-smplock.S + +C_SOURCES_BL = ./arch/x86/bplt-x86-pci.c +C_SOURCES_BL += ./arch/x86/bplt-x86-acpi.c +C_SOURCES_BL += ./arch/x86/bplt-x86-addressing.c +C_SOURCES_BL += ./arch/x86/bplt-x86-cpu.c +ifeq ($(DRT), y) +C_SOURCES_BL += ./arch/x86/vmx/bplt-x86vmx-mtrrs.c +endif + +# targets +include ../runtime.mk + diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-acpi.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-acpi.c new file mode 100644 index 0000000000..49c11efac0 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-acpi.c @@ -0,0 +1,121 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// acpi.c +// advanced configuration and power-management interface subsystem +// glue code +// author: amit vasudevan (amitvasudevan@acm.org) + +#include + + + +//------------------------------------------------------------------------------ +//compute checksum of ACPI table +static u32 _acpi_computetablechecksum(uintptr_t spaddr, uintptr_t size){ + char *p; + char checksum=0; + u32 i; + + p=(char *)spaddr; + + for(i=0; i< size; i++) + checksum+= (char)(*(p+i)); + + return (u32)checksum; +} + + +//------------------------------------------------------------------------------ +//get the physical address of the root system description pointer (rsdp) +//return 0 in case of error (ACPI RSDP not found) else the absolute physical +//memory address of the RSDP +uintptr_t xmhf_baseplatform_arch_x86_acpi_getRSDP(ACPI_RSDP *rsdp){ + u16 ebdaseg; + uintptr_t ebdaphys; + uintptr_t i; + u32 found=0; + + //get EBDA segment from 040E:0000h in BIOS data area + xmhf_baseplatform_arch_flat_copy((u8 *)&ebdaseg, (u8 *)0x0000040E, sizeof(u16)); + + //convert it to its 32-bit physical address + ebdaphys=(uintptr_t)(ebdaseg * 16); + + //search first 1KB of ebda for rsdp signature (8 bytes long) + for(i=0; i < (1024-8); i+=16){ + xmhf_baseplatform_arch_flat_copy((u8 *)rsdp, (u8 *)(ebdaphys+i), sizeof(ACPI_RSDP)); + if(rsdp->signature == ACPI_RSDP_SIGNATURE){ + if(!_acpi_computetablechecksum((uintptr_t)rsdp, 20)){ + found=1; + break; + } + } + } + + //found RSDP? + if(found) + return (ebdaphys+i); + + //nope, search within BIOS areas 0xE0000 to 0xFFFFF + for(i=0xE0000; i < (0xFFFFF-8); i+=16){ + xmhf_baseplatform_arch_flat_copy((u8 *)rsdp, (u8 *)i, sizeof(ACPI_RSDP)); + if(rsdp->signature == ACPI_RSDP_SIGNATURE){ + if(!_acpi_computetablechecksum((uintptr_t)rsdp, 20)){ + found=1; + break; + } + } + } + + //found RSDP? + if(found) + return i; + + //no RSDP, system is not ACPI compliant! + return 0; +} +//------------------------------------------------------------------------------ diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-addressing.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-addressing.c new file mode 100644 index 0000000000..34d6d455da --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-addressing.c @@ -0,0 +1,165 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF base platform component +// addressing interface backends +// authors: amit vasudevan (amitvasudevan@acm.org) and +// jonathan m. mccune + +#include + +//functions to read/write memory using flat selector so that they +//can be used from both within the SL and runtime + +#ifdef __AMD64__ +u32 xmhf_baseplatform_arch_flat_va_offset = 0; + +// find a virtual address from physical address +// in secure loader, ((-(fs << 21)) % 4GiB) for VA is 0 for GA +static void *xmhf_baseplatform_arch_flat_pa2va(u32 addr) { + u32 physical_addr = (u32)addr - (u32)xmhf_baseplatform_arch_flat_va_offset; + return (void*)(u64)physical_addr; +} +#elif !defined(__I386__) + #error "Unsupported Arch" +#endif /* !defined(__I386__) */ + +//read 8-bits from absolute physical address +u8 xmhf_baseplatform_arch_flat_readu8(u32 addr){ +#ifdef __AMD64__ + return *(u8*)(xmhf_baseplatform_arch_flat_pa2va(addr)); +#elif defined(__I386__) + u32 ret; + __asm__ __volatile("xor %%eax, %%eax\r\n" + "movl %%fs:(%%ebx), %%eax\r\n" + : "=a"(ret) + : "b"(addr) + ); + return (u8)ret; +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +} + +//read 32-bits from absolute physical address +u32 xmhf_baseplatform_arch_flat_readu32(u32 addr){ +#ifdef __AMD64__ + return *(u32*)(xmhf_baseplatform_arch_flat_pa2va(addr)); +#elif defined(__I386__) + u32 ret; + __asm__ __volatile("xor %%eax, %%eax\r\n" + "movl %%fs:(%%ebx), %%eax\r\n" + : "=a"(ret) + : "b"(addr) + ); + return ret; +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +} + +//read 64-bits from absolute physical address +u64 xmhf_baseplatform_arch_flat_readu64(u32 addr){ +#ifdef __AMD64__ + return *(u64*)(xmhf_baseplatform_arch_flat_pa2va(addr)); +#elif defined(__I386__) + u32 highpart, lowpart; + __asm__ __volatile("xor %%eax, %%eax\r\n" + "xor %%edx, %%edx\r\n" + "movl %%fs:(%%ebx), %%eax\r\n" + "movl %%fs:0x4(%%ebx), %%edx\r\n" + : "=a"(lowpart), "=d"(highpart) + : "b"(addr) + ); + return ((u64)highpart << 32) | (u64)lowpart; +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +} + +//write 32-bits to absolute physical address +void xmhf_baseplatform_arch_flat_writeu32(u32 addr, u32 val) { +#ifdef __AMD64__ + *(u32*)(xmhf_baseplatform_arch_flat_pa2va(addr)) = val; +#elif defined(__I386__) + __asm__ __volatile__("movl %%eax, %%fs:(%%ebx)\r\n" + : + : "b"(addr), "a"((u32)val) + ); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +} + +//write 64-bits to absolute physical address +void xmhf_baseplatform_arch_flat_writeu64(u32 addr, u64 val) { +#ifdef __AMD64__ + *(u64*)(xmhf_baseplatform_arch_flat_pa2va(addr)) = val; +#elif defined(__I386__) + u32 highpart, lowpart; + lowpart = (u32)val; + highpart = (u32)((u64)val >> 32); + + __asm__ __volatile__("movl %%eax, %%fs:(%%ebx)\r\n" + "movl %%edx, %%fs:0x4(%%ebx)\r\n" + : + : "b"(addr), "a"(lowpart), "d"(highpart) + ); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +} + +//memory copy from absolute physical address (src) to +//data segment relative address (dest) +void xmhf_baseplatform_arch_flat_copy(u8 *dest, u8 *src, u32 size){ + u32 i; + u8 val; + for(i=0; i < size; i++){ + val = xmhf_baseplatform_arch_flat_readu8((uintptr_t)src + i); + dest[i] = val; + } +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-amd64-smplock.S b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-amd64-smplock.S new file mode 100644 index 0000000000..26b3e9c97c --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-amd64-smplock.S @@ -0,0 +1,69 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// multi-processor support routines +// author: amit vasudevan (amitvasudevan@acm.org) + +//---spinlock/unlock------------------------------------------------------------ +.section .text + +/* the lock size is 32-bits (u32, same as x86) */ + + .global spin_lock + spin_lock: + btl $0, (%rdi) + jnc spin_lock + + lock + btrl $0, (%rdi) + jnc spin_lock + + ret + + .global spin_unlock + spin_unlock: + btsl $0, (%rdi) + ret diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-amd64-smptrampoline.S b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-amd64-smptrampoline.S new file mode 100644 index 0000000000..685e598198 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-amd64-smptrampoline.S @@ -0,0 +1,235 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF base platform component; x86 backend + * SMP initialization low-level trampoline + */ + +#include + + .extern g_midtable + .extern g_midtable_numentries + .extern x_gdt + .extern xmhf_baseplatform_arch_x86_smpinitialize_commonstart + .extern xmhf_xcphandler_idt + +/*------------------------------------------------------------------------------ +CODE +------------------------------------------------------------------------------*/ + +.section .text + + /*--AP boot-strap code-------------------------------------------------------*/ + .code16 + .global _ap_bootstrap_start + _ap_bootstrap_start: + jmp ap_bootstrap_bypassdata + _ap_gdtdesc: + .word _ap_gdt_end - _ap_gdt_start - 1 + .long _ap_gdt_start - _ap_bootstrap_start + 0x10000 + .global _ap_cr3_value + _ap_cr3_value: + .long 0 + .global _ap_cr4_value + _ap_cr4_value: + .long 0 + .align 16 + _ap_gdt_start: + .quad 0x0000000000000000 // 0x00: NULL selector + .quad 0x00af9a000000ffff // 0x08: 64-bit CODE selector + .quad 0x00cf9a000000ffff // 0x10: 32-bit CODE selector + .quad 0x00cf92000000ffff // 0x18: 32-bit DATA selector + .quad 0x0000000000000000 // 0x20: TSS low (unused) + .quad 0x0000000000000000 // 0x28: TSS high (unused) + _ap_gdt_end: + .word 0 + .align 16 + .global _mle_join_start + _mle_join_start: + .long _ap_gdt_end - _ap_gdt_start - 1 // gdt_limit + .long _ap_gdt_start - _ap_bootstrap_start + 0x10000// gdt_base + .long __CS32 // CS, also DS - 8 + .long _ap_clear_pipe - _ap_bootstrap_start + 0x10000 // entry point + _mle_join_end: + .align 16 + ap_bootstrap_bypassdata: + movw $0x1000, %ax + movw %ax, %ds + movw %ax, %es + movw $0xFFFF, %sp + movw $0x4000, %ax + movw %ax, %ss + + movw $0x0002, %si + + lgdt (%si) + + movl %cr0, %eax + orl $(CR0_PE), %eax + movl %eax, %cr0 + + jmpl $__CS32, $(_ap_clear_pipe - _ap_bootstrap_start + (AP_BOOTSTRAP_CODE_SEG << 4)) + .code32 + _ap_clear_pipe: + movw $__DS, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %ss + movw %ax, %fs + movw %ax, %gs + + /* Set CR3 and CR4 (copy from BSP's value) */ + movl $(_ap_cr3_value - _ap_bootstrap_start + (AP_BOOTSTRAP_CODE_SEG << 4)), %esi + movl (%esi), %ebx + movl %ebx, %cr3 + movl $(_ap_cr4_value - _ap_bootstrap_start + (AP_BOOTSTRAP_CODE_SEG << 4)), %esi + movl (%esi), %ebx + movl %ebx, %cr4 + + /* Set EFER MSR LME */ + movl $(MSR_EFER), %ecx + rdmsr + btsl $(EFER_LME), %eax + wrmsr + + /* + * Setup stack in 32-bits in order to perform lret. For convenience use + * the same address as 64-bits stack. + * TODO: this is duplicate code; consider removing + */ + + /*get hold of local APIC id*/ + mov $(MSR_APIC_BASE), %ecx + rdmsr + andl $0xFFFFF000, %eax + addl $0x20, %eax + movl (%eax), %eax + shr $24, %eax + + movl g_midtable_numentries, %edx + /*movl g_runtime, %edx*/ + + /*get vcpu virtual address of this CPU/core*/ + /*movl $(__midtable), %ebx*/ + movl $(g_midtable), %ebx + xorl %ecx, %ecx +getvcpuloop32: + leal 0x0(%ebx, %ecx, 8), %esp + movl 0x0(%esp, %ecx, 8), %ebp // ebp contains the lapic id + cmpl %eax, %ebp + jz gotvcpu32 + incl %ecx + cmpl %edx, %ecx + jb getvcpuloop32 + /*we should never get here, if so just halt*/ + hlt +gotvcpu32: + movl 0x8(%esp, %ecx, 8), %esi // esi contains vcpu pointer + movl 0x0(%esi), %esp // load stack for this CPU + + /* setup jump to 64-bit mode */ + pushl $(__CS) /* 2nd entry in GDT (64-bit CODE) */ + leal _ap_pmode_entry_with_paging, %eax + pushl %eax + + /* set CR0 */ + movl %cr0, %eax + orl $(CR0_PG), %eax + andl $(~(CR0_NW | CR0_CD)), %eax + movl %eax, %cr0 + + /* jump to 64-bit mode */ + lret + + .global _ap_bootstrap_end + _ap_bootstrap_end: + nop + nop + nop + nop + + .code64 + + /*---AP common low-level entry point with paging enabled----------------------*/ + .global _ap_pmode_entry_with_paging + _ap_pmode_entry_with_paging: + /*load our gdt and idt*/ + lgdt x_gdt + lidt xmhf_xcphandler_idt + + /*get hold of local APIC id*/ + mov $(MSR_APIC_BASE), %ecx + rdmsr + andl $0xFFFFF000, %eax + addl $0x20, %eax + movl (%eax), %eax + shr $24, %eax + + movq g_midtable_numentries, %rdx + /*movl g_runtime, %edx*/ + + /*get vcpu virtual address of this CPU/core*/ + /*movl $(__midtable), %ebx*/ + movq $(g_midtable), %rbx + xorq %rcx, %rcx +getvcpuloop: + leaq 0x0(%rbx, %rcx, 8), %rsp + movl 0x0(%rsp, %rcx, 8), %ebp // ebp contains the lapic id + cmpl %eax, %ebp + jz gotvcpu + incq %rcx + cmpq %rdx, %rcx + jb getvcpuloop + /*we should never get here, if so just halt*/ + hlt +gotvcpu: + movq 0x8(%rsp, %rcx, 8), %rsi // esi contains vcpu pointer + movq 0x0(%rsi), %rsp // load stack for this CPU + movq %rsi, %rdi // first argument for function call + call xmhf_baseplatform_arch_x86_smpinitialize_commonstart + /*we should never get here, if so just halt*/ + hlt diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-cpu.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-cpu.c new file mode 100644 index 0000000000..bcc5f36078 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-cpu.c @@ -0,0 +1,69 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * XMHF base platform component interface, x86 common backend + * general CPU functions + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//returns true if CPU has support for XSAVE/XRSTOR +bool xmhf_baseplatform_arch_x86_cpuhasxsavefeature(void){ + u32 eax, ebx, ecx, edx; + + //bit 26 of ECX is 1 in CPUID function 0x00000001 if + //XSAVE/XRSTOR feature is available + + cpuid(0x00000001, &eax, &ebx, &ecx, &edx); + + if((ecx & (1UL << 26))) + return true; + else + return false; + +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-data.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-data.c new file mode 100644 index 0000000000..4714b61343 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-data.c @@ -0,0 +1,57 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF base platform component + * x86 arch. specific data definitions + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + + +//runtime TSS +u8 g_runtime_TSS[PAGE_SIZE_4K] __attribute__(( section(".data") )); diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-i386-smplock.S b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-i386-smplock.S new file mode 100644 index 0000000000..e7eba4c0f9 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-i386-smplock.S @@ -0,0 +1,72 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// multi-processor support routines +// author: amit vasudevan (amitvasudevan@acm.org) + +//---spinlock/unlock------------------------------------------------------------ +.section .text + + .global spin_lock + spin_lock: + pushl %esi + movl 0x8(%esp), %esi + spin: btl $0, (%esi) //mutex is available? + jnc spin //wait till it is + + lock //lock the bus (exclusive access) + btrl $0, (%esi) //and try to grab the mutex + jnc spin //spin until successful --> spinlock :p + popl %esi + ret + + .global spin_unlock + spin_unlock: + pushl %esi + movl 0x8(%esp), %esi + btsl $0, (%esi) //release the spinlock + popl %esi + ret diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-i386-smptrampoline.S b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-i386-smptrampoline.S new file mode 100644 index 0000000000..1c8307c306 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-i386-smptrampoline.S @@ -0,0 +1,185 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF base platform component; x86 backend + * SMP initialization low-level trampoline + */ + +#include + + .extern g_midtable + .extern g_midtable_numentries + .extern x_gdt + .extern xmhf_baseplatform_arch_x86_smpinitialize_commonstart + .extern xmhf_xcphandler_idt + +/*------------------------------------------------------------------------------ +CODE +------------------------------------------------------------------------------*/ + +.section .text + + /*--AP boot-strap code-------------------------------------------------------*/ + .code16 + .global _ap_bootstrap_start + _ap_bootstrap_start: + jmp ap_bootstrap_bypassdata + _ap_gdtdesc: + .word _ap_gdt_end - _ap_gdt_start - 1 + .long _ap_gdt_start - _ap_bootstrap_start + 0x10000 + .global _ap_cr3_value + _ap_cr3_value: + .long 0 + .global _ap_cr4_value + _ap_cr4_value: + .long 0 + .align 16 + _ap_gdt_start: + .quad 0x0000000000000000 + .quad 0x00cf9a000000ffff + .quad 0x00cf92000000ffff + _ap_gdt_end: + .word 0 + .align 16 + .global _mle_join_start + _mle_join_start: + .long _ap_gdt_end - _ap_gdt_start - 1 // gdt_limit + .long _ap_gdt_start - _ap_bootstrap_start + 0x10000// gdt_base + .long 0x00000008 // CS + .long _ap_clear_pipe - _ap_bootstrap_start + 0x10000 // entry point + _mle_join_end: + .align 16 + ap_bootstrap_bypassdata: + movw $0x1000, %ax + movw %ax, %ds + movw %ax, %es + movw $0xFFFF, %sp + movw $0x4000, %ax + movw %ax, %ss + + movw $0x0002, %si + + lgdt (%si) + + movl %cr0, %eax + orl $0x1, %eax + movl %eax, %cr0 + + jmpl $0x08, $(_ap_clear_pipe - _ap_bootstrap_start + (AP_BOOTSTRAP_CODE_SEG << 4)) + .code32 + _ap_clear_pipe: + movw $0x10, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %ss + movw %ax, %fs + movw %ax, %gs + + + movl $(_ap_cr3_value - _ap_bootstrap_start + (AP_BOOTSTRAP_CODE_SEG << 4)), %esi + movl (%esi), %ebx + movl %ebx, %cr3 + movl $(_ap_cr4_value - _ap_bootstrap_start + (AP_BOOTSTRAP_CODE_SEG << 4)), %esi + movl (%esi), %ebx + movl %ebx, %cr4 + + movl %cr0, %eax + orl $0x80000000, %eax + movl %eax, %cr0 + + movl $_ap_pmode_entry_with_paging, %eax + jmpl *%eax + hlt + + .global _ap_bootstrap_end + _ap_bootstrap_end: + nop + nop + nop + nop + + /*---AP common low-level entry point with paging enabled----------------------*/ + .global _ap_pmode_entry_with_paging + _ap_pmode_entry_with_paging: + /*load our gdt and idt*/ + lgdt x_gdt + lidt xmhf_xcphandler_idt + + + + /*get hold of local APIC id*/ + mov $(MSR_APIC_BASE), %ecx + rdmsr + andl $0xFFFFF000, %eax + addl $0x20, %eax + movl (%eax), %eax + shr $24, %eax + + movl g_midtable_numentries, %edx + /*movl g_runtime, %edx*/ + + + /*get vcpu virtual address of this CPU/core*/ + /*movl $(__midtable), %ebx*/ + movl $(g_midtable), %ebx + xorl %ecx, %ecx +getvcpuloop: + movl 0x0(%ebx, %ecx, 8), %ebp //ebp contains the lapic id + cmpl %eax, %ebp + jz gotvcpu + incl %ecx + cmpl %edx, %ecx + jb getvcpuloop + /*we should never get here, if so just halt*/ + hlt +gotvcpu: + movl 0x4(%ebx, %ecx, 8), %esi //esi contains vcpu pointer + movl 0x0(%esi), %esp //load stack for this CPU + pushl %esi + call xmhf_baseplatform_arch_x86_smpinitialize_commonstart + /*we should never get here, if so just halt*/ + hlt diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-pci.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-pci.c new file mode 100644 index 0000000000..bcac78c74e --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-pci.c @@ -0,0 +1,275 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// pci.c - peripheral component interconnect (PCI) interface implementation +// author: amit vasudevan (amitvasudevan@acm.org) + +#include + +/* + note on the two different types of PCI config space access methods + (unfortunately only a fraction of this is in the PCI specs... + maybe that is why the specs. are not public :p) + + type-1 accesses: + + this method uses two standard PCI I/O ports to initiate a + configuration cycle. The type of cycle is determined by the + host-bridge device based on the devices primary bus number. + if the configuration bus number matches the primary bus number then a + type 0 configuration cycle occurs. otherwise a type 1 cycle is generated. + this is all transparent to the user. more on type 0 and type 1 cycles + later... + + the two ports used for type-1 accesses are the + PCI_CONFIG_ADDR_PORT (0xCF8) and PCI_CONFIG_DATA_PORT (0xCFC). + + CF8h, 32-bit, r/w + bits 0-7 PCI conf. space index to read/write at CFCh + 8-15 device and function + 16-23 bus + 24-27 extended 4-bits of PCI conf. space index for PCIe conf. space accesses + 31 set to enable the PCI bus configuration space + + CFCh, 32-bit, r/w + bits 0-31 the PCI conf. space index specified in CF8h + can be accessed here for reads and writes. + + + type-2 accesses: + + this method uses three standard PCI I/O ports to initiate a + configuration cycle. + + the three ports used for type-2 accesses are the + PCI_CONFIG_ADDR_PORT (0xCF8), PCI_CONFIG_FORWARD_PORT (0xCFA), and + PCI_CONFIG_BASE_PORT (0xC000). + + CF8h, 8-bit, r/w + bits 0 reserved and set to 0 + 1-3 3-bit function + 4-7 reserved all set to 1s + + CFAh, 8-bit, r/w + bits 0-7 8-bit bus + + the function and bus are sent out to PCI_CONFIG_ADDR_PORT and + PCI_CONFIG_FORWARD_PORT respectively as above, this is followed + by a read or write to the i/o port that is constructed as follows: + + 32-bit i/o port to read/write required PCI conf. space index (reg) for device (dev) + = (PCI_CONFIG_BASE_PORT | (dev << 8) | reg) + + Note that type-1 accesses can address 256bytes (regular PCI) or + 4096bytes (PCIe) of PCI conf. space. However, type-2 is limited to only + 256bytes. + + The mechanism supported (type-1 or type-2) depends on the PCI chipset + implementation. All systems manufactured after 2001 seem to support + type-1 (ref: Linux Kernel), so we detect if it supports type-1 and go + with that, else halt! + + Some info on PCI configuration cycles (thankfully + this is in the PCI spec. :p) + + Type 0 PCI Configuration cycles do not contain a bus number and these + are interpreted by all devices as being for PCI configuration addresses on + this PCI bus. Bits 31:11 of the Type 0 configuraration cycles are treated as + the device select field. + + Type 1 PCI Configuration cycles contain a PCI bus number and this type of + configuration cycle is ignored by all PCI devices except the PCI-PCI bridges. + All of the PCI-PCI Bridges seeing Type 1 configuration cycles may choose to + pass them to the PCI buses downstream of themselves. Whether the PCI-PCI + Bridge ignores the Type 1 configuration cycle or passes it onto the downstream + PCI bus depends on how the PCI-PCI Bridge has been configured. Every + PCI-PCI bridge has a primary bus interface number and a secondary bus + interface number. The primary bus interface being the one nearest the CPU + and the secondary bus interface being the one furthest away. + Each PCI-PCI Bridge also has a subordinate bus number and this is the + maximum bus number of all the PCI buses that are bridged beyond the + secondary bus interface. Or to put it another way, the subordinate bus + number is the highest numbered PCI bus downstream of the PCI-PCI bridge. + + When the PCI-PCI bridge sees a Type 1 PCI configuration cycle it does one of + the following things: + + *Ignore it if the bus number specified is not in between the bridge's + secondary bus number and subordinate bus number (inclusive), + + *Convert it to a Type 0 configuration command if the bus number specified + matches the secondary bus number of the bridge, + + *Pass it onto the secondary bus interface unchanged if the bus number + specified is greater than the secondary bus number and less than or equal + to the subordinate bus number + + geronimo... +*/ + +//============================================================================== +//static (local) functions +//============================================================================== + +/*//enumerates the PCI bus on the system +static void _pci_enumeratebus(void){ + u32 b, d, f; + + //bus numbers range from 0-255, device from 0-31 and function from 0-7 + for(b=0; b < PCI_BUS_MAX; b++){ + for(d=0; d < PCI_DEVICE_MAX; d++){ + for(f=0; f < PCI_FUNCTION_MAX; f++){ + u32 vendor_id, device_id; + //read device and vendor ids, if no device then both will be 0xFFFF + xmhf_baseplatform_arch_x86_pci_type1_read(b, d, f, PCI_CONF_HDR_IDX_VENDOR_ID, sizeof(u16), &vendor_id); + xmhf_baseplatform_arch_x86_pci_type1_read(b, d, f, PCI_CONF_HDR_IDX_DEVICE_ID, sizeof(u16), &device_id); + if(vendor_id == 0xFFFF && device_id == 0xFFFF) + break; + + printf("\n %02x:%02x.%1x -> vendor_id=%04x, device_id=%04x", b, d, f, vendor_id, device_id); + } + } + } + + +}*/ + + +//does a PCI type-1 read of PCI config space for a given bus, device, +//function and index +//len = 1(byte), 2(word) and 4(dword) +//value is a pointer to a 32-bit dword which contains the value read +void xmhf_baseplatform_arch_x86_pci_type1_read(u32 bus, u32 device, u32 function, u32 index, u32 len, + u32 *value){ + + //sanity checks + HALT_ON_ERRORCOND( bus <= 255 ); + HALT_ON_ERRORCOND( PCI_DEVICE_FN(device,function) <= 255 ); + HALT_ON_ERRORCOND( index <= 4095 ); + + //encode and send the 32-bit type-1 address to PCI address port + outl(PCI_TYPE1_ADDRESS(bus, device, function, index), PCI_CONFIG_ADDR_PORT); + + //read a byte, word or dword depending on len + switch (len) { + case 1: //byte + *value = inb(PCI_CONFIG_DATA_PORT + (index & 3)); + break; + case 2: //word + *value = inw(PCI_CONFIG_DATA_PORT + (index & 2)); + break; + case 4: //dword + *value = inl(PCI_CONFIG_DATA_PORT); + break; + } + + return; +} + +//does a PCI type-1 write of PCI config space for a given bus, device, +//function and index +//len = 1(byte), 2(word) and 4(dword) +//value contains the value to be written + +void xmhf_baseplatform_arch_x86_pci_type1_write(u32 bus, u32 device, u32 function, u32 index, u32 len, + u32 value){ + + //sanity checks + HALT_ON_ERRORCOND( bus <= 255 ); + HALT_ON_ERRORCOND( PCI_DEVICE_FN(device,function) <= 255 ); + HALT_ON_ERRORCOND( index <= 4095 ); + + //encode and send the 32-bit type-1 address to PCI address port + outl(PCI_TYPE1_ADDRESS(bus, device, function, index), PCI_CONFIG_ADDR_PORT); + + //write a byte, word or dword depending on len + switch (len) { + case 1: //byte + outb((u8)value, PCI_CONFIG_DATA_PORT + (index & 3)); + break; + + case 2: //word + outw((u16)value, PCI_CONFIG_DATA_PORT + (index & 2)); + break; + + case 4: //dword + outl((u32)value, PCI_CONFIG_DATA_PORT); + break; + } + + return; +} + +//PCI subsystem initialization +//check that PCI chipset supports type-1 accesses +//true for most systems after 2001 +void xmhf_baseplatform_arch_x86_pci_initialize(void){ + u32 tmp; + + //save value at PCI_CONFIG_ADDR_PORT + tmp = inl(PCI_CONFIG_ADDR_PORT); + + //select command register on bus 0, device 0 and function 0 + outl(0x80000000, PCI_CONFIG_ADDR_PORT); + + //reading PCI_CONFIG_ADDR_PORT should return with bit 31 set + //if system supports type-1 access + if (inl(PCI_CONFIG_ADDR_PORT) != 0x80000000) { + printf("\n%s: system does not support type-1 access. HALT!", __FUNCTION__); + HALT(); + } + + //restore previous value at PCI_CONFIG_ADDR_PORT + outl(tmp, PCI_CONFIG_ADDR_PORT); + + //say we are good to go and enumerate the PCI bus + printf("\n%s: PCI type-1 access supported.", __FUNCTION__); + printf("\n%s: PCI bus enumeration follows:", __FUNCTION__); + //_pci_enumeratebus(); + printf("\n%s: Done with PCI bus enumeration.", __FUNCTION__); + + return; +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-pit.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-pit.c new file mode 100644 index 0000000000..8636a84391 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-pit.c @@ -0,0 +1,92 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// delay.c +// implements micro/milli second delay based on 8254 Programmable +// interval timer. +// author: amit vasudevan (amitvasudevan@acm.org) +// note: due to 8254 PIT usage, the routines in this module should not +// be called when a guest OS has been booted up on the physical PIT without +// saving/restoring the PIT registers + +#include + +//---microsecond delay---------------------------------------------------------- +void xmhf_baseplatform_arch_x86_udelay(u32 usecs){ + u8 val; + u32 latchregval; + + //enable 8254 ch-2 counter + val = inb(0x61); + val &= 0x0d; //turn PC speaker off + val |= 0x01; //turn on ch-2 + outb(val, 0x61); + + //program ch-2 as one-shot + outb(0xB0, 0x43); + + //compute appropriate latch register value depending on usecs + latchregval = ((u64)1193182 * usecs) / 1000000; + + HALT_ON_ERRORCOND(latchregval < (1 << 16)); + + //write latch register to ch-2 + val = (u8)latchregval; + outb(val, 0x42); + val = (u8)((u32)latchregval >> (u32)8); + outb(val , 0x42); + + #ifndef __XMHF_VERIFICATION__ + //TODO: plug in a 8254 programmable interval timer h/w model + //wait for countdown + while(!(inb(0x61) & 0x20)); + #endif //__XMHF_VERIFICATION__ + + //disable ch-2 counter + val = inb(0x61); + val &= 0x0c; + outb(val, 0x61); +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-reboot.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-reboot.c new file mode 100644 index 0000000000..1eb76d47c0 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-reboot.c @@ -0,0 +1,85 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF base platform component interface, x86 common backend + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + + +//generic x86 platform reboot +void xmhf_baseplatform_arch_x86_reboot(void){ + unsigned char flush = 0x02; + +#ifndef __XMHF_VERIFICATION__ + + while ((flush & 0x02) != 0) + flush = inb(0x64); + outb(0xFE, 0x64); + + //never get here + printf("\n%s: should never get here. halt!", __FUNCTION__); + HALT(); + +#else //__XMHF_VERIFICATION__ + //TODO: plug in a 8042 controller/reset h/w model + +#endif //__XMHF_VERIFICATION__ + +} + + +//reboot platform +void xmhf_baseplatform_arch_reboot(VCPU *vcpu){ + HALT_ON_ERRORCOND (vcpu->cpu_vendor == CPU_VENDOR_AMD || vcpu->cpu_vendor == CPU_VENDOR_INTEL); + + if(vcpu->cpu_vendor == CPU_VENDOR_AMD) + xmhf_baseplatform_arch_x86svm_reboot(vcpu); + else //CPU_VENDOR_INTEL + xmhf_baseplatform_arch_x86vmx_reboot(vcpu); +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-smp.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-smp.c new file mode 100644 index 0000000000..9633bd5047 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-smp.c @@ -0,0 +1,234 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF base platform component interface, x86 backend + * implements SMP functionality + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//return 1 if the calling CPU is the BSP +u32 xmhf_baseplatform_arch_x86_isbsp(void){ + u32 eax, edx; + //read LAPIC base address from MSR + rdmsr(MSR_APIC_BASE, &eax, &edx); + HALT_ON_ERRORCOND( edx == 0 ); //APIC is below 4G + + if(eax & 0x100) + return 1; + else + return 0; +} + +//wake up APs using the LAPIC by sending the INIT-SIPI-SIPI IPI sequence +void xmhf_baseplatform_arch_x86_wakeupAPs(void){ + u32 eax, edx; + volatile u32 *icr; + + //read LAPIC base address from MSR + rdmsr(MSR_APIC_BASE, &eax, &edx); + HALT_ON_ERRORCOND( edx == 0 ); //APIC is below 4G + + //construct the command register address (offset 0x300) + icr = (u32 *) (((u32)eax & 0xFFFFF000UL) + 0x300); + + //our AP boot-strap code is at physical memory location 0x10000. + //so use 0x10 as the vector (0x10000/0x1000 = 0x10) + + //send INIT + #ifndef __XMHF_VERIFICATION__ + //TODO: plug in LAPIC h/w model + *icr = 0x000c4500UL; + #endif + + xmhf_baseplatform_arch_x86_udelay(10000); + + //wait for command completion + #ifndef __XMHF_VERIFICATION__ + //TODO: plug in LAPIC h/w model + { + u32 val; + do{ + val = *icr; + }while( (val & 0x1000) ); + } + #endif + + //send SIPI (twice as per the MP protocol) + { + int i; + for(i=0; i < 2; i++){ + #ifndef __XMHF_VERIFICATION__ + //TODO: plug in LAPIC h/w model + *icr = 0x000c4610UL; + #endif + xmhf_baseplatform_arch_x86_udelay(200); + //wait for command completion + #ifndef __XMHF_VERIFICATION__ + //TODO: plug in LAPIC h/w model + { + u32 val; + do{ + val = *icr; + }while( (val & 0x1000) ); + } + #endif + } + } + +} + + +//initialize SMP +void xmhf_baseplatform_arch_smpinitialize(void){ + u32 cpu_vendor; + + //grab CPU vendor + cpu_vendor = xmhf_baseplatform_arch_getcpuvendor(); + HALT_ON_ERRORCOND(cpu_vendor == CPU_VENDOR_AMD || cpu_vendor == CPU_VENDOR_INTEL); + + + //setup Master-ID Table (MIDTABLE) + { + int i; + #ifndef __XMHF_VERIFICATION__ + for(i=0; i < (int)rpb->XtVmmMPCpuinfoNumEntries; i++){ + #else + for(i=0; i < 1; i++){ + #endif + g_midtable[g_midtable_numentries].cpu_lapic_id = g_cpumap[i].lapic_id; + g_midtable[g_midtable_numentries].vcpu_vaddr_ptr = 0; + g_midtable_numentries++; + } + } + + + //allocate and setup VCPU structure on each CPU + if(cpu_vendor == CPU_VENDOR_AMD) + xmhf_baseplatform_arch_x86svm_allocandsetupvcpus(cpu_vendor); + else //CPU_VENDOR_INTEL + xmhf_baseplatform_arch_x86vmx_allocandsetupvcpus(cpu_vendor); + + //wake up APS + if(g_midtable_numentries > 1){ + if(cpu_vendor == CPU_VENDOR_AMD) + xmhf_baseplatform_arch_x86svm_wakeupAPs(); + else //CPU_VENDOR_INTEL + xmhf_baseplatform_arch_x86vmx_wakeupAPs(); + } + + + //fall through to common code + { + void _ap_pmode_entry_with_paging(void); + printf("\nRelinquishing BSP thread and moving to common..."); + // Do some low-level init and then call allcpus_common_start() below + _ap_pmode_entry_with_paging(); + printf("\nBSP must never get here. HALT!"); + HALT(); + } +} + + +//common function which is entered by all CPUs upon SMP initialization +//note: this is specific to the x86 architecture backend +void xmhf_baseplatform_arch_x86_smpinitialize_commonstart(VCPU *vcpu){ + //step:1 rally all APs up, make sure all of them started, this is + //a task for the BSP + if(xmhf_baseplatform_arch_x86_isbsp()){ + vcpu->isbsp = 1; //this core is a BSP + + printf("\nBSP rallying APs..."); +#ifdef __AMD64__ + printf("\nBSP(0x%02x): My RSP is 0x%016lx", vcpu->id, vcpu->rsp); +#elif defined(__I386__) + printf("\nBSP(0x%02x): My ESP is 0x%08x", vcpu->id, vcpu->esp); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + + //increment a CPU to account for the BSP + spin_lock(&g_lock_cpus_active); + g_cpus_active++; + spin_unlock(&g_lock_cpus_active); + + //wait for g_cpus_active to become g_midtable_numentries -1 to indicate + //that all APs have been successfully started + while(g_cpus_active < g_midtable_numentries); + + printf("\nAPs all awake...Setting them free..."); + spin_lock(&g_lock_ap_go_signal); + g_ap_go_signal=1; + spin_unlock(&g_lock_ap_go_signal); + + + }else{ + //we are an AP, so we need to simply update the AP startup counter + //and wait until we are told to proceed + //increment active CPUs + vcpu->isbsp=0; //this core is a AP + + spin_lock(&g_lock_cpus_active); + g_cpus_active++; + spin_unlock(&g_lock_cpus_active); + + while(!g_ap_go_signal); //Just wait for the BSP to tell us all is well. + +#ifdef __AMD64__ + printf("\nAP(0x%02x): My RSP is 0x%016lx, proceeding...", vcpu->id, vcpu->rsp); +#elif defined(__I386__) + printf("\nAP(0x%02x): My ESP is 0x%08x, proceeding...", vcpu->id, vcpu->esp); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + } + + //invoke EMHF runtime component main function for this CPU + //TODO: don't reference rpb->isEarlyInit directly + xmhf_runtime_main(vcpu, rpb->isEarlyInit); +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86.c new file mode 100644 index 0000000000..cde03f6c35 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86.c @@ -0,0 +1,118 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF base platform component interface, x86 common backend + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//get CPU vendor +u32 xmhf_baseplatform_arch_getcpuvendor(void){ + u32 vendor_dword1, vendor_dword2, vendor_dword3; + u32 cpu_vendor; + asm( "xor %%eax, %%eax \n" + "cpuid \n" + "mov %%ebx, %0 \n" + "mov %%edx, %1 \n" + "mov %%ecx, %2 \n" + : "=m"(vendor_dword1), "=m"(vendor_dword2), "=m"(vendor_dword3) + : //no inputs + : "eax", "ebx", "ecx", "edx" ); + + if(vendor_dword1 == AMD_STRING_DWORD1 && vendor_dword2 == AMD_STRING_DWORD2 + && vendor_dword3 == AMD_STRING_DWORD3) + cpu_vendor = CPU_VENDOR_AMD; + else if(vendor_dword1 == INTEL_STRING_DWORD1 && vendor_dword2 == INTEL_STRING_DWORD2 + && vendor_dword3 == INTEL_STRING_DWORD3) + cpu_vendor = CPU_VENDOR_INTEL; + else{ + printf("\n%s: unrecognized x86 CPU (0x%08x:0x%08x:0x%08x). HALT!", + __FUNCTION__, vendor_dword1, vendor_dword2, vendor_dword3); + HALT(); + } + + return cpu_vendor; +} + + +//initialize basic platform elements +void xmhf_baseplatform_arch_initialize(void){ + //initialize PCI subsystem + xmhf_baseplatform_arch_x86_pci_initialize(); + + //check ACPI subsystem + { + ACPI_RSDP rsdp; + #ifndef __XMHF_VERIFICATION__ + //TODO: plug in a BIOS data area map/model + if(!xmhf_baseplatform_arch_x86_acpi_getRSDP(&rsdp)){ + printf("\n%s: ACPI RSDP not found, Halting!", __FUNCTION__); + HALT(); + } + #endif //__XMHF_VERIFICATION__ + } + +} + + +//initialize CPU state +void xmhf_baseplatform_arch_cpuinitialize(void){ + u32 cpu_vendor = xmhf_baseplatform_arch_getcpuvendor(); + + //set OSXSAVE bit in CR4 to enable us to pass-thru XSETBV intercepts + //when the CPU supports XSAVE feature + if(xmhf_baseplatform_arch_x86_cpuhasxsavefeature()){ + u32 t_cr4; + t_cr4 = read_cr4(); + t_cr4 |= CR4_OSXSAVE; + write_cr4(t_cr4); + } + + if(cpu_vendor == CPU_VENDOR_INTEL) + xmhf_baseplatform_arch_x86vmx_cpuinitialize(); +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/svm/bplt-x86svm-data.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/svm/bplt-x86svm-data.c new file mode 100644 index 0000000000..7b51b7f1cf --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/svm/bplt-x86svm-data.c @@ -0,0 +1,64 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF base platform component interface, x86 svm backend data + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//SVM VM_HSAVE buffers +u8 g_svm_hsave_buffers[2 * PAGE_SIZE_4K * MAX_VCPU_ENTRIES]__attribute__(( section(".bss.palign_data") )); + +//SVM VMCB buffers +u8 g_svm_vmcb_buffers[2 * PAGE_SIZE_4K * MAX_VCPU_ENTRIES]__attribute__(( section(".bss.palign_data") )); + +//SVM IO bitmap buffer +u8 g_svm_iobitmap_buffer[3 * PAGE_SIZE_4K]__attribute__(( section(".bss.palign_data") )); + +//SVM MSR bitmap buffer +u8 g_svm_msrpm[SIZEOF_MSRPM_BITMAP]__attribute__(( section(".bss.palign_data") )); diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/svm/bplt-x86svm-smp.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/svm/bplt-x86svm-smp.c new file mode 100644 index 0000000000..3c0f179095 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/svm/bplt-x86svm-smp.c @@ -0,0 +1,157 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF base platform component interface, x86 svm backend + * smp related functions + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//allocate and setup VCPU structure for all the CPUs +void xmhf_baseplatform_arch_x86svm_allocandsetupvcpus(u32 cpu_vendor){ + u32 i; + u32 npt_current_asid=ASID_GUEST_KERNEL; + VCPU *vcpu; + + printf("\n%s: g_cpustacks range 0x%08x-0x%08x in 0x%08x chunks", + __FUNCTION__, (hva_t)g_cpustacks, (hva_t)g_cpustacks + (RUNTIME_STACK_SIZE * MAX_VCPU_ENTRIES), + RUNTIME_STACK_SIZE); + printf("\n%s: g_vcpubuffers range 0x%08x-0x%08x in 0x%08x chunks", + __FUNCTION__, (hva_t)g_vcpubuffers, (hva_t)g_vcpubuffers + (SIZE_STRUCT_VCPU * MAX_VCPU_ENTRIES), + SIZE_STRUCT_VCPU); + printf("\n%s: g_svm_hsave_buffers range 0x%08x-0x%08x in 0x%08x chunks", + __FUNCTION__, (hva_t)g_svm_hsave_buffers, (hva_t)g_svm_hsave_buffers + (8192 * MAX_VCPU_ENTRIES), + 8192); + printf("\n%s: g_svm_vmcb_buffers range 0x%08x-0x%08x in 0x%08x chunks", + __FUNCTION__, (hva_t)g_svm_vmcb_buffers, (hva_t)g_svm_vmcb_buffers + (8192 * MAX_VCPU_ENTRIES), + 8192); + printf("\n%s: g_svm_npt_pdpt_buffers range 0x%08x-0x%08x in 0x%08x chunks", + __FUNCTION__, (hva_t)g_svm_npt_pdpt_buffers, (hva_t)g_svm_npt_pdpt_buffers + (4096 * MAX_VCPU_ENTRIES), + 4096); + printf("\n%s: g_svm_npt_pdts_buffers range 0x%08x-0x%08x in 0x%08x chunks", + __FUNCTION__, (hva_t)g_svm_npt_pdts_buffers, (hva_t)g_svm_npt_pdts_buffers + (16384 * MAX_VCPU_ENTRIES), + 16384); + printf("\n%s: g_svm_npt_pts_buffers range 0x%08x-0x%08x in 0x%08x chunks", + __FUNCTION__, (hva_t)g_svm_npt_pts_buffers, (hva_t)g_svm_npt_pts_buffers + ((2048*4096) * MAX_VCPU_ENTRIES), + (2048*4096)); + + for(i=0; i < g_midtable_numentries; i++){ + vcpu = (VCPU *)((hva_t)g_vcpubuffers + (hva_t)(i * SIZE_STRUCT_VCPU)); + #ifndef __XMHF_VERIFICATION__ + memset((void *)vcpu, 0, sizeof(VCPU)); + #endif + + vcpu->cpu_vendor = cpu_vendor; + +#ifdef __AMD64__ + vcpu->rsp = ((hva_t)g_cpustacks + (i * RUNTIME_STACK_SIZE)) + RUNTIME_STACK_SIZE; +#elif defined(__I386__) + vcpu->esp = ((hva_t)g_cpustacks + (i * RUNTIME_STACK_SIZE)) + RUNTIME_STACK_SIZE; +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + vcpu->hsave_vaddr_ptr = ((hva_t)g_svm_hsave_buffers + (i * 8192)); + vcpu->vmcb_vaddr_ptr = (struct _svm_vmcbfields *)((hva_t)g_svm_vmcb_buffers + (i * 8192)); + + //allocate SVM IO bitmap region and clear it + vcpu->svm_vaddr_iobitmap = (hva_t)g_svm_iobitmap_buffer; + #ifndef __XMHF_VERIFICATION__ + memset( (void *)vcpu->svm_vaddr_iobitmap, 0, (3*PAGE_SIZE_4K)); + #endif + + { + u32 npt_pdpt_base, npt_pdts_base, npt_pts_base; + npt_pdpt_base = ((hva_t)g_svm_npt_pdpt_buffers + (i * 4096)); + npt_pdts_base = ((hva_t)g_svm_npt_pdts_buffers + (i * 16384)); + npt_pts_base = ((hva_t)g_svm_npt_pts_buffers + (i * (2048*4096))); + vcpu->npt_vaddr_ptr = npt_pdpt_base; + vcpu->npt_vaddr_pdts = npt_pdts_base; + vcpu->npt_vaddr_pts = npt_pts_base; + vcpu->npt_asid = npt_current_asid; + npt_current_asid++; + } + + vcpu->id = g_midtable[i].cpu_lapic_id; + vcpu->idx = i; + vcpu->sipivector = 0; + vcpu->sipireceived = 0; + + g_midtable[i].vcpu_vaddr_ptr = (hva_t)vcpu; +#ifdef __AMD64__ + printf("\nCPU #%u: vcpu_vaddr_ptr=0x%08x, rsp=0x%16lx", i, g_midtable[i].vcpu_vaddr_ptr, + vcpu->rsp); +#elif defined(__I386__) + printf("\nCPU #%u: vcpu_vaddr_ptr=0x%08x, esp=0x%08x", i, g_midtable[i].vcpu_vaddr_ptr, + vcpu->esp); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + printf("\n hsave_vaddr_ptr=0x%08x, vmcb_vaddr_ptr=0x%08x", vcpu->hsave_vaddr_ptr, + vcpu->vmcb_vaddr_ptr); + } +} + +//wake up application processors (cores) in the system +void xmhf_baseplatform_arch_x86svm_wakeupAPs(void){ + //step-1: setup AP boot-strap code at in the desired physical memory location + //note that we need an address < 1MB since the APs are woken up in real-mode + //we choose 0x10000 physical or 0x1000:0x0000 logical + { + _ap_cr3_value = read_cr3(); + _ap_cr4_value = read_cr4(); + #ifndef __XMHF_VERIFICATION__ + memcpy((void *)0x10000, (void *)_ap_bootstrap_start, (uintptr_t)_ap_bootstrap_end - (uintptr_t)_ap_bootstrap_start + 1); + #endif + } + + //step-2: wake up the APs sending the INIT-SIPI-SIPI sequence as per the + //MP protocol. Use the APIC for IPI purposes. + printf("\nBSP: Using APIC to awaken APs..."); + xmhf_baseplatform_arch_x86_wakeupAPs(); + printf("\nBSP: APs should be awake."); +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/svm/bplt-x86svm.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/svm/bplt-x86svm.c new file mode 100644 index 0000000000..eba351622d --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/svm/bplt-x86svm.c @@ -0,0 +1,69 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF base platform component interface, x86 svm backend + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//SVM specific platform reboot +void xmhf_baseplatform_arch_x86svm_reboot(VCPU *vcpu){ + u32 eax, edx; + + (void)vcpu; + + //disable SVM extensions + rdmsr((u32)MSR_EFER, &eax, &edx); + eax &= ~(1<id); + + + //fall back on generic x86 reboot + xmhf_baseplatform_arch_x86_reboot(); +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx-data.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx-data.c new file mode 100644 index 0000000000..b3e5461c2b --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx-data.c @@ -0,0 +1,314 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF base platform component interface, x86 vmx backend data + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +#define DECLARE_FIELD(encoding, member) \ + { \ + encoding, \ + offsetof(struct _vmx_vmcsfields, member), \ + sizeof((struct _vmx_vmcsfields){}.member) \ + }, + +//VMX VMCS read-only field encodings +struct _vmx_vmcsrofields_encodings g_vmx_vmcsrofields_encodings[] __attribute__(( section(".data") )) = { + DECLARE_FIELD(0x4400, info_vminstr_error) + DECLARE_FIELD(0x4402, info_vmexit_reason) + DECLARE_FIELD(0x4404, info_vmexit_interrupt_information) + DECLARE_FIELD(0x4406, info_vmexit_interrupt_error_code) + DECLARE_FIELD(0x4408, info_IDT_vectoring_information) + DECLARE_FIELD(0x440A, info_IDT_vectoring_error_code) + DECLARE_FIELD(0x440C, info_vmexit_instruction_length) + DECLARE_FIELD(0x440E, info_vmx_instruction_information) + DECLARE_FIELD(0x6400, info_exit_qualification) +#ifndef __DEBUG_QEMU__ + DECLARE_FIELD(0x6402, info_IO_RCX) + DECLARE_FIELD(0x6404, info_IO_RSI) + DECLARE_FIELD(0x6406, info_IO_RDI) + DECLARE_FIELD(0x6408, info_IO_RIP) +#endif /* !__DEBUG_QEMU__ */ +#if defined(__NESTED_PAGING__) +#ifdef __AMD64__ + DECLARE_FIELD(0x2400, guest_paddr) +#elif defined(__I386__) + DECLARE_FIELD(0x2400, guest_paddr_full) + DECLARE_FIELD(0x2401, guest_paddr_high) +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +#endif + DECLARE_FIELD(0x640A, info_guest_linear_address) +}; + +//count of VMX VMCS read-only fields +unsigned int g_vmx_vmcsrofields_encodings_count __attribute__(( section(".data") )) = sizeof( g_vmx_vmcsrofields_encodings ) / sizeof( struct _vmx_vmcsrofields_encodings ); + +//VMX VMCS read-write field encodings +struct _vmx_vmcsrwfields_encodings g_vmx_vmcsrwfields_encodings[] __attribute__(( section(".data") )) = { + // Control fields + #if defined(__NESTED_PAGING__) + //16-bit control field + DECLARE_FIELD(0x0000, control_vpid) + #endif + // Natural 32-bit Control fields + DECLARE_FIELD(0x4000, control_VMX_pin_based) + DECLARE_FIELD(0x4002, control_VMX_cpu_based) + DECLARE_FIELD(0x401E, control_VMX_seccpu_based) + DECLARE_FIELD(0x4004, control_exception_bitmap) + DECLARE_FIELD(0x4006, control_pagefault_errorcode_mask) + DECLARE_FIELD(0x4008, control_pagefault_errorcode_match) + DECLARE_FIELD(0x400A, control_CR3_target_count) + DECLARE_FIELD(0x400C, control_VM_exit_controls) + DECLARE_FIELD(0x400E, control_VM_exit_MSR_store_count) + DECLARE_FIELD(0x4010, control_VM_exit_MSR_load_count) + DECLARE_FIELD(0x4012, control_VM_entry_controls) + DECLARE_FIELD(0x4014, control_VM_entry_MSR_load_count) + DECLARE_FIELD(0x4016, control_VM_entry_interruption_information) + DECLARE_FIELD(0x4018, control_VM_entry_exception_errorcode) + DECLARE_FIELD(0x401A, control_VM_entry_instruction_length) + DECLARE_FIELD(0x401C, control_Task_PRivilege_Threshold) + // Natural 64-bit Control fields + DECLARE_FIELD(0x6000, control_CR0_mask) + DECLARE_FIELD(0x6002, control_CR4_mask) + DECLARE_FIELD(0x6004, control_CR0_shadow) + DECLARE_FIELD(0x6006, control_CR4_shadow) +#ifndef __DEBUG_QEMU__ + DECLARE_FIELD(0x6008, control_CR3_target0) + DECLARE_FIELD(0x600A, control_CR3_target1) + DECLARE_FIELD(0x600C, control_CR3_target2) + DECLARE_FIELD(0x600E, control_CR3_target3) +#endif /* !__DEBUG_QEMU__ */ + // Full 64-bit Control fields +#ifdef __AMD64__ + DECLARE_FIELD(0x2000, control_IO_BitmapA_address) + DECLARE_FIELD(0x2002, control_IO_BitmapB_address) + DECLARE_FIELD(0x2004, control_MSR_Bitmaps_address) + DECLARE_FIELD(0x2006, control_VM_exit_MSR_store_address) + DECLARE_FIELD(0x2008, control_VM_exit_MSR_load_address) + DECLARE_FIELD(0x200A, control_VM_entry_MSR_load_address) +#elif defined(__I386__) + DECLARE_FIELD(0x2000, control_IO_BitmapA_address_full) + DECLARE_FIELD(0x2001, control_IO_BitmapA_address_high) + DECLARE_FIELD(0x2002, control_IO_BitmapB_address_full) + DECLARE_FIELD(0x2003, control_IO_BitmapB_address_high) + DECLARE_FIELD(0x2004, control_MSR_Bitmaps_address_full) + DECLARE_FIELD(0x2005, control_MSR_Bitmaps_address_high) + DECLARE_FIELD(0x2006, control_VM_exit_MSR_store_address_full) + DECLARE_FIELD(0x2007, control_VM_exit_MSR_store_address_high) + DECLARE_FIELD(0x2008, control_VM_exit_MSR_load_address_full) + DECLARE_FIELD(0x2009, control_VM_exit_MSR_load_address_high) + DECLARE_FIELD(0x200A, control_VM_entry_MSR_load_address_full) + DECLARE_FIELD(0x200B, control_VM_entry_MSR_load_address_high) +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +#ifndef __DEBUG_QEMU__ +#ifdef __AMD64__ + DECLARE_FIELD(0x200C, control_Executive_VMCS_pointer) +#elif defined(__I386__) + DECLARE_FIELD(0x200C, control_Executive_VMCS_pointer_full) + DECLARE_FIELD(0x200D, control_Executive_VMCS_pointer_high) +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +#endif /* !__DEBUG_QEMU__ */ +#ifdef __AMD64__ + DECLARE_FIELD(0x2010, control_TSC_offset) + //DECLARE_FIELD(0x2012, control_virtual_APIC_page_address) +#elif defined(__I386__) + DECLARE_FIELD(0x2010, control_TSC_offset_full) + DECLARE_FIELD(0x2011, control_TSC_offset_high) + //DECLARE_FIELD(0x2012, control_virtual_APIC_page_address_full) + //DECLARE_FIELD(0x2013, control_virtual_APIC_page_address_high) +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + #if defined(__NESTED_PAGING__) +#ifdef __AMD64__ + DECLARE_FIELD(0x201A, control_EPT_pointer) +#elif defined(__I386__) + DECLARE_FIELD(0x201A, control_EPT_pointer_full) + DECLARE_FIELD(0x201B, control_EPT_pointer_high) +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + #endif + // Host-State fields + // Natural 64-bit Host-State fields + DECLARE_FIELD(0x6C00, host_CR0) + DECLARE_FIELD(0x6C02, host_CR3) + DECLARE_FIELD(0x6C04, host_CR4) + DECLARE_FIELD(0x6C06, host_FS_base) + DECLARE_FIELD(0x6C08, host_GS_base) + DECLARE_FIELD(0x6C0A, host_TR_base) + DECLARE_FIELD(0x6C0C, host_GDTR_base) + DECLARE_FIELD(0x6C0E, host_IDTR_base) + DECLARE_FIELD(0x6C10, host_SYSENTER_ESP) + DECLARE_FIELD(0x6C12, host_SYSENTER_EIP) + DECLARE_FIELD(0x6C14, host_RSP) + DECLARE_FIELD(0x6C16, host_RIP) + // Natural 32-bit Host-State fields + DECLARE_FIELD(0x4C00, host_SYSENTER_CS) + // Natural 16-bit Host-State fields + DECLARE_FIELD(0x0C00, host_ES_selector) + DECLARE_FIELD(0x0C02, host_CS_selector) + DECLARE_FIELD(0x0C04, host_SS_selector) + DECLARE_FIELD(0x0C06, host_DS_selector) + DECLARE_FIELD(0x0C08, host_FS_selector) + DECLARE_FIELD(0x0C0A, host_GS_selector) + DECLARE_FIELD(0x0C0C, host_TR_selector) + // Guest-State fields + // Natural 64-bit Guest-State fields + DECLARE_FIELD(0x6800, guest_CR0) + DECLARE_FIELD(0x6802, guest_CR3) + DECLARE_FIELD(0x6804, guest_CR4) + DECLARE_FIELD(0x6806, guest_ES_base) + DECLARE_FIELD(0x6808, guest_CS_base) + DECLARE_FIELD(0x680A, guest_SS_base) + DECLARE_FIELD(0x680C, guest_DS_base) + DECLARE_FIELD(0x680E, guest_FS_base) + DECLARE_FIELD(0x6810, guest_GS_base) + DECLARE_FIELD(0x6812, guest_LDTR_base) + DECLARE_FIELD(0x6814, guest_TR_base) + DECLARE_FIELD(0x6816, guest_GDTR_base) + DECLARE_FIELD(0x6818, guest_IDTR_base) + DECLARE_FIELD(0x681A, guest_DR7) + DECLARE_FIELD(0x681C, guest_RSP) + DECLARE_FIELD(0x681E, guest_RIP) + DECLARE_FIELD(0x6820, guest_RFLAGS) + DECLARE_FIELD(0x6822, guest_pending_debug_x) + DECLARE_FIELD(0x6824, guest_SYSENTER_ESP) + DECLARE_FIELD(0x6826, guest_SYSENTER_EIP) + #if defined(__NESTED_PAGING__) +#ifdef __AMD64__ + DECLARE_FIELD(0x280A, guest_PDPTE0) + DECLARE_FIELD(0x280C, guest_PDPTE1) + DECLARE_FIELD(0x280E, guest_PDPTE2) + DECLARE_FIELD(0x2810, guest_PDPTE3) +#elif defined(__I386__) + DECLARE_FIELD(0x280A, guest_PDPTE0_full) + DECLARE_FIELD(0x280B, guest_PDPTE0_high) + DECLARE_FIELD(0x280C, guest_PDPTE1_full) + DECLARE_FIELD(0x280D, guest_PDPTE1_high) + DECLARE_FIELD(0x280E, guest_PDPTE2_full) + DECLARE_FIELD(0x280F, guest_PDPTE2_high) + DECLARE_FIELD(0x2810, guest_PDPTE3_full) + DECLARE_FIELD(0x2811, guest_PDPTE3_high) +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + #endif + // Natural 32-bit Guest-State fields + DECLARE_FIELD(0x4800, guest_ES_limit) + DECLARE_FIELD(0x4802, guest_CS_limit) + DECLARE_FIELD(0x4804, guest_SS_limit) + DECLARE_FIELD(0x4806, guest_DS_limit) + DECLARE_FIELD(0x4808, guest_FS_limit) + DECLARE_FIELD(0x480A, guest_GS_limit) + DECLARE_FIELD(0x480C, guest_LDTR_limit) + DECLARE_FIELD(0x480E, guest_TR_limit) + DECLARE_FIELD(0x4810, guest_GDTR_limit) + DECLARE_FIELD(0x4812, guest_IDTR_limit) + DECLARE_FIELD(0x4814, guest_ES_access_rights) + DECLARE_FIELD(0x4816, guest_CS_access_rights) + DECLARE_FIELD(0x4818, guest_SS_access_rights) + DECLARE_FIELD(0x481A, guest_DS_access_rights) + DECLARE_FIELD(0x481C, guest_FS_access_rights) + DECLARE_FIELD(0x481E, guest_GS_access_rights) + DECLARE_FIELD(0x4820, guest_LDTR_access_rights) + DECLARE_FIELD(0x4822, guest_TR_access_rights) + DECLARE_FIELD(0x4824, guest_interruptibility) + DECLARE_FIELD(0x4826, guest_activity_state) +#ifndef __DEBUG_QEMU__ + DECLARE_FIELD(0x4828, guest_SMBASE) +#endif /* !__DEBUG_QEMU__ */ + DECLARE_FIELD(0x482A, guest_SYSENTER_CS) + // Natural 16-bit Guest-State fields + DECLARE_FIELD(0x0800, guest_ES_selector) + DECLARE_FIELD(0x0802, guest_CS_selector) + DECLARE_FIELD(0x0804, guest_SS_selector) + DECLARE_FIELD(0x0806, guest_DS_selector) + DECLARE_FIELD(0x0808, guest_FS_selector) + DECLARE_FIELD(0x080A, guest_GS_selector) + DECLARE_FIELD(0x080C, guest_LDTR_selector) + DECLARE_FIELD(0x080E, guest_TR_selector) + // Full 64-bit Guest-State fields +#ifdef __AMD64__ + DECLARE_FIELD(0x2800, guest_VMCS_link_pointer) + DECLARE_FIELD(0x2802, guest_IA32_DEBUGCTL) +#elif defined(__I386__) + DECLARE_FIELD(0x2800, guest_VMCS_link_pointer_full) + DECLARE_FIELD(0x2801, guest_VMCS_link_pointer_high) + DECLARE_FIELD(0x2802, guest_IA32_DEBUGCTL_full) + DECLARE_FIELD(0x2803, guest_IA32_DEBUGCTL_high) +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +}; + +//count of VMX VMCS read-write fields +unsigned int g_vmx_vmcsrwfields_encodings_count __attribute__(( section(".data") )) = sizeof( g_vmx_vmcsrwfields_encodings ) / sizeof( struct _vmx_vmcsrwfields_encodings ); + +//VMX VMXON buffers +u8 g_vmx_vmxon_buffers[PAGE_SIZE_4K * MAX_VCPU_ENTRIES] __attribute__(( section(".bss.palign_data") )); + +//VMX VMCS buffers +u8 g_vmx_vmcs_buffers[PAGE_SIZE_4K * MAX_VCPU_ENTRIES] __attribute__(( section(".bss.palign_data") )); + +//VMX IO bitmap buffer (one buffer for the entire platform) +u8 g_vmx_iobitmap_buffer[2 * PAGE_SIZE_4K] __attribute__(( section(".bss.palign_data") )); + +//VMX guest and host MSR save area buffers +u8 g_vmx_msr_area_host_buffers[2 * PAGE_SIZE_4K * MAX_VCPU_ENTRIES] __attribute__(( section(".bss.palign_data") )); +u8 g_vmx_msr_area_guest_buffers[2 * PAGE_SIZE_4K * MAX_VCPU_ENTRIES] __attribute__(( section(".bss.palign_data") )); + +//VMX MSR bitmap buffers +u8 g_vmx_msrbitmap_buffers[PAGE_SIZE_4K * MAX_VCPU_ENTRIES] __attribute__(( section(".bss.palign_data") )); diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx-mtrrs.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx-mtrrs.c new file mode 100644 index 0000000000..436864fdbc --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx-mtrrs.c @@ -0,0 +1,608 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * mtrrs.c: support functions for manipulating MTRRs + * + * Copyright (c) 2003-2010, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * Modified for XMHF by jonmccune@cmu.edu, 2011.01.05 + */ + +#include + +#define MTRR_TYPE_MIXED -1 +#define MMIO_APIC_BASE 0xFEE00000 +#define NR_MMIO_APIC_PAGES 1 +#define NR_MMIO_IOAPIC_PAGES 1 +#define NR_MMIO_PCICFG_PAGES 1 + +/* saved MTRR state or NULL if orig. MTRRs have not been changed */ +//static __data mtrr_state_t *g_saved_mtrrs = NULL; +static mtrr_state_t *g_saved_mtrrs = NULL; + +/* + * this must be done for each processor so that all have the same + * memory types + */ +bool set_mtrrs_for_acmod(acm_hdr_t *hdr) +{ + unsigned long eflags; + unsigned long cr0, cr4; + + /* + * need to do some things before we start changing MTRRs + * + * since this will modify some of the MTRRs, they should be saved first + * so that they can be restored once the AC mod is done + */ + + /* disable interrupts */ + get_eflags(eflags); + disable_intr(); + + /* save CR0 then disable cache (CRO.CD=1, CR0.NW=0) */ + cr0 = read_cr0(); + write_cr0((cr0 & ~CR0_NW) | CR0_CD); + + /* flush caches */ + wbinvd(); + + /* save CR4 and disable global pages (CR4.PGE=0) */ + cr4 = read_cr4(); + write_cr4(cr4 & ~CR4_PGE); + + /* disable MTRRs */ + set_all_mtrrs(false); + + /* + * now set MTRRs for AC mod and rest of memory + */ + if ( !set_mem_type(hdr, hdr->size*4, MTRR_TYPE_WRBACK) ) + return false; + + /* + * now undo some of earlier changes and enable our new settings + */ + + /* flush caches */ + wbinvd(); + + /* enable MTRRs */ + set_all_mtrrs(true); + + /* restore CR0 (cacheing) */ + write_cr0(cr0); + + /* restore CR4 (global pages) */ + write_cr4(cr4); + + /* enable interrupts */ + set_eflags(eflags); + + + return true; +} + +void print_mtrrs(const mtrr_state_t *saved_state) +{ + u64 i; + + printf("mtrr_def_type: e = %d, fe = %d, type = %x\n", + saved_state->mtrr_def_type.e, saved_state->mtrr_def_type.fe, + saved_state->mtrr_def_type.type ); + printf("mtrrs:\n"); + printf("\t\tbase\tmask\ttype\tv\n"); + for ( i = 0; i < saved_state->num_var_mtrrs; i++ ) { + printf("\t\t%6.6x\t%6.6x\t%2.2x\t%d\n", + saved_state->mtrr_physbases[i].base, + saved_state->mtrr_physmasks[i].mask, + saved_state->mtrr_physbases[i].type, + saved_state->mtrr_physmasks[i].v ); + } +} + +void save_mtrrs(mtrr_state_t *saved_state) +{ + mtrr_cap_t mtrr_cap; + u64 ndx; + + /* IA32_MTRR_DEF_TYPE MSR */ + saved_state->mtrr_def_type.raw = rdmsr64(MSR_MTRRdefType); + + /* number variable MTTRRs */ + mtrr_cap.raw = rdmsr64(MSR_MTRRcap); + if ( mtrr_cap.vcnt > MAX_VARIABLE_MTRRS ) { + /* print warning but continue saving what we can */ + /* (set_mem_type() won't exceed the array, so we're safe doing this) */ + printf("actual # var MTRRs (%d) > MAX_VARIABLE_MTRRS (%d)\n", + mtrr_cap.vcnt, MAX_VARIABLE_MTRRS); + saved_state->num_var_mtrrs = MAX_VARIABLE_MTRRS; + } + else + saved_state->num_var_mtrrs = mtrr_cap.vcnt; + + /* physmask's and physbase's */ + for ( ndx = 0; ndx < saved_state->num_var_mtrrs; ndx++ ) { + saved_state->mtrr_physmasks[ndx].raw = + rdmsr64(MTRR_PHYS_MASK0_MSR + ndx*2); + saved_state->mtrr_physbases[ndx].raw = + rdmsr64(MTRR_PHYS_BASE0_MSR + ndx*2); + } + + print_mtrrs(saved_state); + + g_saved_mtrrs = saved_state; +} + +#if 0 /* functions unused as of 2011-07-19 */ +/* base should be 4k-bytes aligned, no invalid overlap combination */ +static int get_page_type(const mtrr_state_t *saved_state, uint32_t base) +{ + int type = -1; + bool wt = false; + u64 i; + + /* omit whether the fix mtrrs are enabled, just check var mtrrs */ + + base >>= PAGE_SHIFT_4K; + for ( i = 0; i < saved_state->num_var_mtrrs; i++ ) { + const mtrr_physbase_t *base_i = &saved_state->mtrr_physbases[i]; + const mtrr_physmask_t *mask_i = &saved_state->mtrr_physmasks[i]; + + if ( mask_i->v == 0 ) + continue; + if ( (base & mask_i->mask) != (uint32_t)(base_i->base & mask_i->mask) ) + continue; + + type = base_i->type; + if ( type == MTRR_TYPE_UNCACHABLE ) + return MTRR_TYPE_UNCACHABLE; + if ( type == MTRR_TYPE_WRTHROUGH ) + wt = true; + } + if ( wt ) + return MTRR_TYPE_WRTHROUGH; + if ( type != -1 ) + return type; + + return saved_state->mtrr_def_type.type; +} + +static int get_region_type(const mtrr_state_t *saved_state, + uint32_t base, uint32_t pages) +{ + int type; + uint32_t end; + + if ( pages == 0 ) + return MTRR_TYPE_MIXED; + + /* wrap the 4G address space */ + if ( ((uint32_t)(~0) - base) < (pages << PAGE_SHIFT_4K) ) + return MTRR_TYPE_MIXED; + + if ( saved_state->mtrr_def_type.e == 0 ) + return MTRR_TYPE_UNCACHABLE; + + /* align to 4k page boundary */ + base = PAGE_ALIGN_4K(base); //base &= PAGE_MASK; + end = base + (pages << PAGE_SHIFT_4K); + + type = get_page_type(saved_state, base); + base += PAGE_SIZE_4K; + for ( ; base < end; base += PAGE_SIZE_4K ) + if ( type != get_page_type(saved_state, base) ) + return MTRR_TYPE_MIXED; + + return type; +} +#endif + +/* static bool validate_mmio_regions(const mtrr_state_t *saved_state) */ +/* { */ +/* acpi_table_mcfg_t *acpi_table_mcfg; */ +/* acpi_table_ioapic_t *acpi_table_ioapic; */ + +/* /\* mmio space for TXT private config space should be UC *\/ */ +/* if ( get_region_type(saved_state, TXT_PRIV_CONFIG_REGS_BASE, */ +/* NR_TXT_CONFIG_PAGES) */ +/* != MTRR_TYPE_UNCACHABLE ) { */ +/* printf("MMIO space for TXT private config space should be UC\n"); */ +/* return false; */ +/* } */ + +/* /\* mmio space for TXT public config space should be UC *\/ */ +/* if ( get_region_type(saved_state, TXT_PUB_CONFIG_REGS_BASE, */ +/* NR_TXT_CONFIG_PAGES) */ +/* != MTRR_TYPE_UNCACHABLE ) { */ +/* printf("MMIO space for TXT public config space should be UC\n"); */ +/* return false; */ +/* } */ + +/* /\* mmio space for TPM should be UC *\/ */ +/* if ( get_region_type(saved_state, TPM_LOCALITY_BASE, */ +/* NR_TPM_LOCALITY_PAGES * TPM_NR_LOCALITIES) */ +/* != MTRR_TYPE_UNCACHABLE ) { */ +/* printf("MMIO space for TPM should be UC\n"); */ +/* return false; */ +/* } */ + +/* /\* mmio space for APIC should be UC *\/ */ +/* if ( get_region_type(saved_state, MMIO_APIC_BASE, NR_MMIO_APIC_PAGES) */ +/* != MTRR_TYPE_UNCACHABLE ) { */ +/* printf("MMIO space for APIC should be UC\n"); */ +/* return false; */ +/* } */ + +/* /\* TBD: is this check useful if we aren't DMA protecting ACPI? *\/ */ +/* /\* mmio space for IOAPIC should be UC *\/ */ +/* acpi_table_ioapic = (acpi_table_ioapic_t *)get_acpi_ioapic_table(); */ +/* if ( acpi_table_ioapic == NULL) { */ +/* printf("acpi_table_ioapic == NULL\n"); */ +/* return false; */ +/* } */ +/* printf("acpi_table_ioapic @ %p, .address = %x\n", */ +/* acpi_table_ioapic, acpi_table_ioapic->address); */ +/* if ( get_region_type(saved_state, acpi_table_ioapic->address, */ +/* NR_MMIO_IOAPIC_PAGES) */ +/* != MTRR_TYPE_UNCACHABLE ) { */ +/* printf("MMIO space(%x) for IOAPIC should be UC\n", */ +/* acpi_table_ioapic->address); */ +/* return false; */ +/* } */ + +/* /\* TBD: is this check useful if we aren't DMA protecting ACPI? *\/ */ +/* /\* mmio space for PCI config space should be UC *\/ */ +/* acpi_table_mcfg = (acpi_table_mcfg_t *)get_acpi_mcfg_table(); */ +/* if ( acpi_table_mcfg == NULL) { */ +/* printf("acpi_table_mcfg == NULL\n"); */ +/* return false; */ +/* } */ +/* printf("acpi_table_mcfg @ %p, .base_address = %x\n", */ +/* acpi_table_mcfg, acpi_table_mcfg->base_address); */ +/* if ( get_region_type(saved_state, acpi_table_mcfg->base_address, */ +/* NR_MMIO_PCICFG_PAGES) */ +/* != MTRR_TYPE_UNCACHABLE ) { */ +/* printf("MMIO space(%x) for PCI config space should be UC\n", */ +/* acpi_table_mcfg->base_address); */ +/* return false; */ +/* } */ + +/* return true; */ +/* } */ + +bool validate_mtrrs(const mtrr_state_t *saved_state) +{ + mtrr_cap_t mtrr_cap; + u64 ndx; + + /* check is meaningless if MTRRs were disabled */ + if ( saved_state->mtrr_def_type.e == 0 ) + return true; + + /* number variable MTRRs */ + mtrr_cap.raw = rdmsr64(MSR_MTRRcap); + if ( mtrr_cap.vcnt < saved_state->num_var_mtrrs ) { + printf("actual # var MTRRs (%d) < saved # (%d)\n", + mtrr_cap.vcnt, saved_state->num_var_mtrrs); + return false; + } + + /* variable MTRRs describing non-contiguous memory regions */ + /* TBD: assert(MAXPHYADDR == 36); */ + for ( ndx = 0; ndx < saved_state->num_var_mtrrs; ndx++ ) { + uint64_t tb; + + if ( saved_state->mtrr_physmasks[ndx].v == 0 ) + continue; + + for ( tb = 0x1; tb != 0x1000000; tb = tb << 1 ) { + if ( (tb & saved_state->mtrr_physmasks[ndx].mask) != 0 ) + break; + } + for ( ; tb != 0x1000000; tb = tb << 1 ) { + if ( (tb & saved_state->mtrr_physmasks[ndx].mask) == 0 ) + break; + } + if ( tb != 0x1000000 ) { + printf("var MTRRs with non-contiguous regions: " + "base=%06x, mask=%06x\n", + (unsigned int) saved_state->mtrr_physbases[ndx].base, + (unsigned int) saved_state->mtrr_physmasks[ndx].mask); + print_mtrrs(saved_state); + return false; + } + } + + /* overlaping regions with invalid memory type combinations */ + for ( ndx = 0; ndx < saved_state->num_var_mtrrs; ndx++ ) { + u64 i; + const mtrr_physbase_t *base_ndx = &saved_state->mtrr_physbases[ndx]; + const mtrr_physmask_t *mask_ndx = &saved_state->mtrr_physmasks[ndx]; + + if ( mask_ndx->v == 0 ) + continue; + + for ( i = ndx + 1; i < saved_state->num_var_mtrrs; i++ ) { + u64 j; + const mtrr_physbase_t *base_i = &saved_state->mtrr_physbases[i]; + const mtrr_physmask_t *mask_i = &saved_state->mtrr_physmasks[i]; + + if ( mask_i->v == 0 ) + continue; + + if ( (base_ndx->base & mask_ndx->mask & mask_i->mask) + != (base_i->base & mask_i->mask) + && (base_i->base & mask_i->mask & mask_ndx->mask) + != (base_ndx->base & mask_ndx->mask) ) + continue; + + if ( base_ndx->type == base_i->type ) + continue; + if ( base_ndx->type == MTRR_TYPE_UNCACHABLE + || base_i->type == MTRR_TYPE_UNCACHABLE ) + continue; + if ( base_ndx->type == MTRR_TYPE_WRTHROUGH + && base_i->type == MTRR_TYPE_WRBACK ) + continue; + if ( base_ndx->type == MTRR_TYPE_WRBACK + && base_i->type == MTRR_TYPE_WRTHROUGH ) + continue; + + /* 2 overlapped regions have invalid mem type combination, */ + /* need to check whether there is a third region which has type */ + /* of UNCACHABLE and contains at least one of these two regions. */ + /* If there is, then the combination of these 3 region is valid */ + for ( j = 0; j < saved_state->num_var_mtrrs; j++ ) { + const mtrr_physbase_t *base_j + = &saved_state->mtrr_physbases[j]; + const mtrr_physmask_t *mask_j + = &saved_state->mtrr_physmasks[j]; + + if ( mask_j->v == 0 ) + continue; + + if ( base_j->type != MTRR_TYPE_UNCACHABLE ) + continue; + + if ( (base_ndx->base & mask_ndx->mask & mask_j->mask) + == (base_j->base & mask_j->mask) + && (mask_j->mask & ~mask_ndx->mask) == 0 ) + break; + + if ( (base_i->base & mask_i->mask & mask_j->mask) + == (base_j->base & mask_j->mask) + && (mask_j->mask & ~mask_i->mask) == 0 ) + break; + } + if ( j < saved_state->num_var_mtrrs ) + continue; + + printf("var MTRRs overlaping regions, invalid type combinations\n"); + print_mtrrs(saved_state); + return false; + } + } + +/* if ( !validate_mmio_regions(saved_state) ) { */ +/* printf("Some mmio region should be UC type\n"); */ +/* print_mtrrs(saved_state); */ +/* return false; */ +/* } */ + + //print_mtrrs(saved_state); + return true; +} + +void restore_mtrrs(mtrr_state_t *saved_state) +{ + u64 ndx; + + if(NULL == saved_state) { + printf("\nFATAL ERROR: restore_mtrrs(): called with NULL\n"); + HALT(); + } + + //print_mtrrs(saved_state); + + /* called by apply_policy() so use saved ptr */ + if ( saved_state == NULL ) + saved_state = g_saved_mtrrs; + /* haven't saved them yet, so return */ + if ( saved_state == NULL ) + return; + + /* disable all MTRRs first */ + set_all_mtrrs(false); + + /* physmask's and physbase's */ + for ( ndx = 0; ndx < saved_state->num_var_mtrrs; ndx++ ) { + wrmsr64(MTRR_PHYS_MASK0_MSR + ndx*2, + saved_state->mtrr_physmasks[ndx].raw); + wrmsr64(MTRR_PHYS_BASE0_MSR + ndx*2, + saved_state->mtrr_physbases[ndx].raw); + } + + /* IA32_MTRR_DEF_TYPE MSR */ + wrmsr64(MSR_MTRRdefType, saved_state->mtrr_def_type.raw); +} + +/* + * set the memory type for specified range (base to base+size) + * to mem_type and everything else to UC + */ +bool set_mem_type(void *base, uint32_t size, uint32_t mem_type) +{ + int num_pages; + int ndx; + mtrr_def_type_t mtrr_def_type; + mtrr_cap_t mtrr_cap; + mtrr_physmask_t mtrr_physmask; + mtrr_physbase_t mtrr_physbase; + + /* + * disable all fixed MTRRs + * set default type to UC + */ + mtrr_def_type.raw = rdmsr64(MSR_MTRRdefType); + mtrr_def_type.fe = 0; + mtrr_def_type.type = MTRR_TYPE_UNCACHABLE; + wrmsr64(MSR_MTRRdefType, mtrr_def_type.raw); + + /* + * initially disable all variable MTRRs (we'll enable the ones we use) + */ + mtrr_cap.raw = rdmsr64(MSR_MTRRcap); + for ( ndx = 0; ndx < mtrr_cap.vcnt; ndx++ ) { + mtrr_physmask.raw = rdmsr64(MTRR_PHYS_MASK0_MSR + ndx*2); + mtrr_physmask.v = 0; + wrmsr64(MTRR_PHYS_MASK0_MSR + ndx*2, mtrr_physmask.raw); + } + + /* + * map all AC module pages as mem_type + */ + + num_pages = (size + PAGE_SIZE_4K - 1) >> PAGE_SHIFT_4K; + ndx = 0; + + printf("setting MTRRs for acmod: base=%p, size=%x, num_pages=%d\n", + base, size, num_pages); + + while ( num_pages > 0 ) { + uint32_t pages_in_range; + + /* set the base of the current MTRR */ + mtrr_physbase.raw = rdmsr64(MTRR_PHYS_BASE0_MSR + ndx*2); + mtrr_physbase.base = (unsigned long)base >> PAGE_SHIFT_4K; + mtrr_physbase.type = mem_type; + /* set explicitly in case base field is >24b (MAXPHYADDR >36) */ + mtrr_physbase.reserved2 = 0; + wrmsr64(MTRR_PHYS_BASE0_MSR + ndx*2, mtrr_physbase.raw); + + /* + * calculate MTRR mask + * MTRRs can map pages in power of 2 + * may need to use multiple MTRRS to map all of region + */ + pages_in_range = 1 << (fls(num_pages) - 1); + + mtrr_physmask.raw = rdmsr64(MTRR_PHYS_MASK0_MSR + ndx*2); + mtrr_physmask.mask = ~(pages_in_range - 1); + mtrr_physmask.v = 1; + /* set explicitly in case mask field is >24b (MAXPHYADDR >36) */ + mtrr_physmask.reserved2 = 0; + wrmsr64(MTRR_PHYS_MASK0_MSR + ndx*2, mtrr_physmask.raw); + + /* prepare for the next loop depending on number of pages + * We figure out from the above how many pages could be used in this + * mtrr. Then we decrement the count, increment the base, + * increment the mtrr we are dealing with, and if num_pages is + * still not zero, we do it again. + */ + base += (pages_in_range * PAGE_SIZE_4K); + num_pages -= pages_in_range; + ndx++; + if ( ndx == mtrr_cap.vcnt ) { + printf("exceeded number of var MTRRs when mapping range\n"); + return false; + } + } + + return true; +} + +/* enable/disable all MTRRs */ +void set_all_mtrrs(bool enable) +{ + mtrr_def_type_t mtrr_def_type; + + mtrr_def_type.raw = rdmsr64(MSR_MTRRdefType); + mtrr_def_type.e = enable ? 1 : 0; + wrmsr64(MSR_MTRRdefType, mtrr_def_type.raw); +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx-reboot.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx-reboot.c new file mode 100644 index 0000000000..d62e85bca2 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx-reboot.c @@ -0,0 +1,65 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF base platform component interface, x86 vmx backend + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + + +//VMX specific platform reboot +void xmhf_baseplatform_arch_x86vmx_reboot(VCPU *vcpu){ + (void)vcpu; + + //shut VMX off, else CPU ignores INIT signal! + __asm__ __volatile__("vmxoff \r\n"); + write_cr4(read_cr4() & ~(CR4_VMXE)); + + //fall back on generic x86 reboot + xmhf_baseplatform_arch_x86_reboot(); +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx-smp.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx-smp.c new file mode 100644 index 0000000000..dd784b1a4a --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx-smp.c @@ -0,0 +1,225 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF base platform component interface, x86 vmx backend + * smp related functions + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//allocate and setup VCPU structure for all the CPUs +void xmhf_baseplatform_arch_x86vmx_allocandsetupvcpus(u32 cpu_vendor){ + u32 i; + VCPU *vcpu; + + for(i=0; i < g_midtable_numentries; i++){ + //allocate VCPU structure + vcpu = (VCPU *)((hva_t)g_vcpubuffers + (hva_t)(i * SIZE_STRUCT_VCPU)); + + #ifndef __XMHF_VERIFICATION__ + memset((void *)vcpu, 0, sizeof(VCPU)); + #endif + + vcpu->cpu_vendor = cpu_vendor; + + //allocate runtime stack +#ifdef __AMD64__ + vcpu->rsp = ((hva_t)g_cpustacks + (i * RUNTIME_STACK_SIZE)) + RUNTIME_STACK_SIZE; +#elif defined(__I386__) + vcpu->esp = ((hva_t)g_cpustacks + (i * RUNTIME_STACK_SIZE)) + RUNTIME_STACK_SIZE; +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + + //allocate VMXON memory region + vcpu->vmx_vmxonregion_vaddr = ((hva_t)g_vmx_vmxon_buffers + (i * PAGE_SIZE_4K)) ; + #ifndef __XMHF_VERIFICATION__ + memset((void *)vcpu->vmx_vmxonregion_vaddr, 0, PAGE_SIZE_4K); + #endif + + //allocate VMCS memory region + vcpu->vmx_vmcs_vaddr = ((hva_t)g_vmx_vmcs_buffers + (i * PAGE_SIZE_4K)) ; + #ifndef __XMHF_VERIFICATION__ + memset((void *)vcpu->vmx_vmcs_vaddr, 0, PAGE_SIZE_4K); + #endif + + //allocate VMX IO bitmap region + vcpu->vmx_vaddr_iobitmap = (hva_t)g_vmx_iobitmap_buffer; + #ifndef __XMHF_VERIFICATION__ + memset( (void *)vcpu->vmx_vaddr_iobitmap, 0, (2*PAGE_SIZE_4K)); + #endif + + //allocate VMX guest and host MSR save areas + vcpu->vmx_vaddr_msr_area_host = ((hva_t)g_vmx_msr_area_host_buffers + (i * (2*PAGE_SIZE_4K))) ; + #ifndef __XMHF_VERIFICATION__ + memset( (void *)vcpu->vmx_vaddr_msr_area_host, 0, (2*PAGE_SIZE_4K)); + #endif + vcpu->vmx_vaddr_msr_area_guest = ((hva_t)g_vmx_msr_area_guest_buffers + (i * (2*PAGE_SIZE_4K))) ; + #ifndef __XMHF_VERIFICATION__ + memset( (void *)vcpu->vmx_vaddr_msr_area_guest, 0, (2*PAGE_SIZE_4K)); + #endif + + //allocate VMX MSR bitmap region + vcpu->vmx_vaddr_msrbitmaps = ((hva_t)g_vmx_msrbitmap_buffers + (i * PAGE_SIZE_4K)) ; + #ifndef __XMHF_VERIFICATION__ + memset( (void *)vcpu->vmx_vaddr_msrbitmaps, 0, PAGE_SIZE_4K); + #endif + + //allocate EPT paging structures + #ifdef __NESTED_PAGING__ + { + vcpu->vmx_vaddr_ept_pml4_table = ((hva_t)g_vmx_ept_pml4_table_buffers + (i * P4L_NPLM4T * PAGE_SIZE_4K)); + vcpu->vmx_vaddr_ept_pdp_table = ((hva_t)g_vmx_ept_pdp_table_buffers + (i * P4L_NPDPT * PAGE_SIZE_4K)); + vcpu->vmx_vaddr_ept_pd_tables = ((hva_t)g_vmx_ept_pd_table_buffers + (i * P4L_NPDT * PAGE_SIZE_4K)); + vcpu->vmx_vaddr_ept_p_tables = ((hva_t)g_vmx_ept_p_table_buffers + (i * P4L_NPT * PAGE_SIZE_4K)); + } + #endif + + //other VCPU data such as LAPIC id, SIPI vector and receive indication + vcpu->id = g_midtable[i].cpu_lapic_id; + vcpu->idx = i; + vcpu->sipivector = 0; + vcpu->sipireceived = 0; + + //map LAPIC to VCPU in midtable + g_midtable[i].vcpu_vaddr_ptr = (hva_t)vcpu; + } +} + +//wake up application processors (cores) in the system +void xmhf_baseplatform_arch_x86vmx_wakeupAPs(void){ + //step-1: setup AP boot-strap code at in the desired physical memory location + //note that we need an address < 1MB since the APs are woken up in real-mode + //we choose 0x10000 physical or 0x1000:0x0000 logical + { + _ap_cr3_value = read_cr3(); + _ap_cr4_value = read_cr4(); + #ifndef __XMHF_VERIFICATION__ + memcpy((void *)0x10000, (void *)_ap_bootstrap_start, (uintptr_t)_ap_bootstrap_end - (uintptr_t)_ap_bootstrap_start + 1); + #endif + } + +#if defined (__DRT__) + //step-2: wake up the APs sending the INIT-SIPI-SIPI sequence as per the + //MP protocol. Use the APIC for IPI purposes. + if(!txt_is_launched()) { // XXX TODO: Do actual GETSEC[WAKEUP] in here? + printf("\nBSP: Using APIC to awaken APs..."); + xmhf_baseplatform_arch_x86_wakeupAPs(); + printf("\nBSP: APs should be awake."); + }else{ + //we ran SENTER, so do a GETSEC[WAKEUP] + txt_heap_t *txt_heap; + os_mle_data_t *os_mle_data; + mle_join_t *mle_join; + sinit_mle_data_t *sinit_mle_data; + os_sinit_data_t *os_sinit_data; + + // sl.c unity-maps 0xfed00000 for 2M so these should work fine + #ifndef __XMHF_VERIFICATION__ + txt_heap = get_txt_heap(); + //printf("\ntxt_heap = 0x%08lx", (uintptr_t)txt_heap); + os_mle_data = get_os_mle_data_start(txt_heap); + (void)os_mle_data; + //printf("\nos_mle_data = 0x%08lx", (uintptr_t)os_mle_data); + sinit_mle_data = get_sinit_mle_data_start(txt_heap); + //printf("\nsinit_mle_data = 0x%08lx", (uintptr_t)sinit_mle_data); + os_sinit_data = get_os_sinit_data_start(txt_heap); + //printf("\nos_sinit_data = 0x%08lx", (uintptr_t)os_sinit_data); + #endif + + // Start APs. Choose wakeup mechanism based on + // capabilities used. MLE Dev Guide says MLEs should + // support both types of Wakeup mechanism. + + // We are jumping straight into the 32-bit portion of the + // unity-mapped trampoline that starts at 64K + // physical. Without SENTER, or with AMD, APs start in + // 16-bit mode. We get to skip that. + printf("\nBSP: _mle_join_start = 0x%08lx, _ap_bootstrap_start = 0x%08lx", + (uintptr_t)_mle_join_start, (uintptr_t)_ap_bootstrap_start); + + // enable SMIs on BSP before waking APs (which will enable them on APs) + // because some SMM may take immediate SMI and hang if AP gets in first + //printf("Enabling SMIs on BSP\n"); + //__getsec_smctrl(); + + // MLE Join structure constructed in runtimesup.S. Debug print. + #ifndef __XMHF_VERIFICATION__ + mle_join = (mle_join_t*)((uintptr_t)_mle_join_start - (uintptr_t)_ap_bootstrap_start + 0x10000); // XXX magic number + #endif + //printf("\nBSP: mle_join.gdt_limit = 0x%08x", mle_join->gdt_limit); + //printf("\nBSP: mle_join.gdt_base = 0x%08x", mle_join->gdt_base); + //printf("\nBSP: mle_join.seg_sel = 0x%08x", mle_join->seg_sel); + //printf("\nBSP: mle_join.entry_point = 0x%08x", mle_join->entry_point); + + #ifndef __XMHF_VERIFICATION__ + write_priv_config_reg(TXTCR_MLE_JOIN, (uint64_t)(unsigned long)mle_join); + + if (os_sinit_data->capabilities.rlp_wake_monitor) { + printf("\nBSP: joining RLPs to MLE with MONITOR wakeup"); + printf("\nBSP: rlp_wakeup_addr = 0x%08x", sinit_mle_data->rlp_wakeup_addr); + *((uint32_t *)(unsigned long)(sinit_mle_data->rlp_wakeup_addr)) = 0x01; + }else { + printf("\nBSP: joining RLPs to MLE with GETSEC[WAKEUP]"); + __getsec_wakeup(); + printf("\nBSP: GETSEC[WAKEUP] completed"); + } + #endif + + + } + +#else //!__DRT__ + printf("\nBSP: Using APIC to awaken APs..."); + xmhf_baseplatform_arch_x86_wakeupAPs(); + printf("\nBSP: APs should be awake."); + +#endif + + +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx-vmcs.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx-vmcs.c new file mode 100644 index 0000000000..015de1c2b1 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx-vmcs.c @@ -0,0 +1,387 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF base platform component interface, x86 vmx backend + * VMCS to memory interface + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//---putVMCS-------------------------------------------------------------------- +// routine takes vcpu vmcsfields and stores it in the CPU VMCS +void xmhf_baseplatform_arch_x86vmx_putVMCS(VCPU *vcpu){ + unsigned int i; + for(i=0; i < g_vmx_vmcsrwfields_encodings_count; i++){ + unsigned long *field = (unsigned long *)((hva_t)&vcpu->vmcs + (u32)g_vmx_vmcsrwfields_encodings[i].fieldoffset); + unsigned long fieldvalue = *field; + //printf("\nvmwrite: enc=0x%08x, value=0x%08x", vmcsrwfields_encodings[i].encoding, fieldvalue); + if(!__vmx_vmwrite(g_vmx_vmcsrwfields_encodings[i].encoding, fieldvalue)){ + printf("\nCPU(0x%02x): VMWRITE failed. HALT!", vcpu->id); + HALT(); + } + } + /* + * Logic to handle asynchronous access to vcpu->vmcs.control_VMX_cpu_based. + * See xmhf_smpguest_arch_x86vmx_eventhandler_nmiexception(). + */ + if (vcpu->vmx_guest_inject_nmi) { + unsigned long __control_VMX_cpu_based; + HALT_ON_ERRORCOND(__vmx_vmread(0x4002, &__control_VMX_cpu_based)); + __control_VMX_cpu_based |= (1U << 22); + HALT_ON_ERRORCOND(__vmx_vmwrite(0x4002, __control_VMX_cpu_based)); + } +} + +void xmhf_baseplatform_arch_x86vmx_read_field(u32 encoding, void *addr, + u32 size) { + unsigned long value; + HALT_ON_ERRORCOND(__vmx_vmread(encoding, &value)); +#ifdef __AMD64__ + /* Read 64-bit fields using 1 VMREAD instruction (different from x86) */ + switch ((encoding >> 13) & 0x3) { + case 0: /* 16-bit */ + /* fallthrough */ + case 2: /* 32-bit */ + HALT_ON_ERRORCOND(size == 4); + *(u32 *)addr = (u32)value; + break; + case 1: /* 64-bit */ + /* Disallow high access */ + HALT_ON_ERRORCOND((encoding & 0x1) == 0x0); + /* fallthrough */ + case 3: /* natural width */ + HALT_ON_ERRORCOND(size == 8); + *(u64 *)addr = value; + break; + default: + HALT(); + } +#elif defined(__I386__) + (void)size; + *(u32 *)addr = (u32)value; +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +} + +//---getVMCS-------------------------------------------------------------------- +// routine takes CPU VMCS and stores it in vcpu vmcsfields +void xmhf_baseplatform_arch_x86vmx_getVMCS(VCPU *vcpu){ + unsigned int i; + /* + * Logic to handle asynchronous access to vcpu->vmcs.control_VMX_cpu_based. + * See xmhf_smpguest_arch_x86vmx_eventhandler_nmiexception(). + */ + vcpu->vmx_guest_inject_nmi = 0; + for(i=0; i < g_vmx_vmcsrwfields_encodings_count; i++){ + u32 encoding = g_vmx_vmcsrwfields_encodings[i].encoding; + u32 offset = g_vmx_vmcsrwfields_encodings[i].fieldoffset; + void *field = (void *)((hva_t)&vcpu->vmcs + offset); + u32 size = g_vmx_vmcsrwfields_encodings[i].membersize; + xmhf_baseplatform_arch_x86vmx_read_field(encoding, field, size); + } + for(i=0; i < g_vmx_vmcsrofields_encodings_count; i++){ + u32 encoding = g_vmx_vmcsrofields_encodings[i].encoding; + u32 offset = g_vmx_vmcsrofields_encodings[i].fieldoffset; + void *field = (void *)((hva_t)&vcpu->vmcs + offset); + u32 size = g_vmx_vmcsrofields_encodings[i].membersize; + xmhf_baseplatform_arch_x86vmx_read_field(encoding, field, size); + } +} + +//--debug: dumpVMCS dumps VMCS contents----------------------------------------- +void xmhf_baseplatform_arch_x86vmx_dumpVMCS(VCPU *vcpu){ + printf("\nGuest State follows:"); + printf("\nguest_CS_selector=0x%04x", (unsigned short)vcpu->vmcs.guest_CS_selector); + printf("\nguest_DS_selector=0x%04x", (unsigned short)vcpu->vmcs.guest_DS_selector); + printf("\nguest_ES_selector=0x%04x", (unsigned short)vcpu->vmcs.guest_ES_selector); + printf("\nguest_FS_selector=0x%04x", (unsigned short)vcpu->vmcs.guest_FS_selector); + printf("\nguest_GS_selector=0x%04x", (unsigned short)vcpu->vmcs.guest_GS_selector); + printf("\nguest_SS_selector=0x%04x", (unsigned short)vcpu->vmcs.guest_SS_selector); + printf("\nguest_TR_selector=0x%04x", (unsigned short)vcpu->vmcs.guest_TR_selector); + printf("\nguest_LDTR_selector=0x%04x", (unsigned short)vcpu->vmcs.guest_LDTR_selector); + printf("\nguest_CS_access_rights=0x%08lx", + (unsigned long)vcpu->vmcs.guest_CS_access_rights); + printf("\nguest_DS_access_rights=0x%08lx", + (unsigned long)vcpu->vmcs.guest_DS_access_rights); + printf("\nguest_ES_access_rights=0x%08lx", + (unsigned long)vcpu->vmcs.guest_ES_access_rights); + printf("\nguest_FS_access_rights=0x%08lx", + (unsigned long)vcpu->vmcs.guest_FS_access_rights); + printf("\nguest_GS_access_rights=0x%08lx", + (unsigned long)vcpu->vmcs.guest_GS_access_rights); + printf("\nguest_SS_access_rights=0x%08lx", + (unsigned long)vcpu->vmcs.guest_SS_access_rights); + printf("\nguest_TR_access_rights=0x%08lx", + (unsigned long)vcpu->vmcs.guest_TR_access_rights); + printf("\nguest_LDTR_access_rights=0x%08lx", + (unsigned long)vcpu->vmcs.guest_LDTR_access_rights); + + printf("\nguest_CS_base/limit=0x%08lx/0x%04x", + (unsigned long)vcpu->vmcs.guest_CS_base, (unsigned short)vcpu->vmcs.guest_CS_limit); + printf("\nguest_DS_base/limit=0x%08lx/0x%04x", + (unsigned long)vcpu->vmcs.guest_DS_base, (unsigned short)vcpu->vmcs.guest_DS_limit); + printf("\nguest_ES_base/limit=0x%08lx/0x%04x", + (unsigned long)vcpu->vmcs.guest_ES_base, (unsigned short)vcpu->vmcs.guest_ES_limit); + printf("\nguest_FS_base/limit=0x%08lx/0x%04x", + (unsigned long)vcpu->vmcs.guest_FS_base, (unsigned short)vcpu->vmcs.guest_FS_limit); + printf("\nguest_GS_base/limit=0x%08lx/0x%04x", + (unsigned long)vcpu->vmcs.guest_GS_base, (unsigned short)vcpu->vmcs.guest_GS_limit); + printf("\nguest_SS_base/limit=0x%08lx/0x%04x", + (unsigned long)vcpu->vmcs.guest_SS_base, (unsigned short)vcpu->vmcs.guest_SS_limit); + printf("\nguest_GDTR_base/limit=0x%08lx/0x%04x", + (unsigned long)vcpu->vmcs.guest_GDTR_base, (unsigned short)vcpu->vmcs.guest_GDTR_limit); + printf("\nguest_IDTR_base/limit=0x%08lx/0x%04x", + (unsigned long)vcpu->vmcs.guest_IDTR_base, (unsigned short)vcpu->vmcs.guest_IDTR_limit); + printf("\nguest_TR_base/limit=0x%08lx/0x%04x", + (unsigned long)vcpu->vmcs.guest_TR_base, (unsigned short)vcpu->vmcs.guest_TR_limit); + printf("\nguest_LDTR_base/limit=0x%08lx/0x%04x", + (unsigned long)vcpu->vmcs.guest_LDTR_base, (unsigned short)vcpu->vmcs.guest_LDTR_limit); + + printf("\nguest_CR0=0x%08lx, guest_CR4=0x%08lx, guest_CR3=0x%08lx", + (unsigned long)vcpu->vmcs.guest_CR0, (unsigned long)vcpu->vmcs.guest_CR4, + (unsigned long)vcpu->vmcs.guest_CR3); + printf("\nguest_RSP=0x%08lx", (unsigned long)vcpu->vmcs.guest_RSP); + printf("\nguest_RIP=0x%08lx", (unsigned long)vcpu->vmcs.guest_RIP); + printf("\nguest_RFLAGS=0x%08lx", (unsigned long)vcpu->vmcs.guest_RFLAGS); +} + +void xmhf_baseplatform_arch_x86vmx_dump_vcpu(VCPU *vcpu){ + +#define DUMP_VCPU_PRINT_INT16(x) \ + printf("\nCPU(0x%02x): " #x "=0x%08x", vcpu->id, (x)); +#define DUMP_VCPU_PRINT_INT32(x) \ + printf("\nCPU(0x%02x): " #x "=0x%08x", vcpu->id, (x)); +#define DUMP_VCPU_PRINT_INT64(x) \ + printf("\nCPU(0x%02x): " #x "=0x%016lx", vcpu->id, (x)); +#define DUMP_VCPU_PRINT_INT64_INDEX(x, i) \ + printf("\nCPU(0x%02x): " #x "[%x]=0x%016lx", vcpu->id, (i), (x)[i]); + +#ifdef __AMD64__ + DUMP_VCPU_PRINT_INT64(vcpu->rsp); +#elif defined(__I386__) + DUMP_VCPU_PRINT_INT64(vcpu->esp); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + DUMP_VCPU_PRINT_INT64(vcpu->sipi_page_vaddr); + DUMP_VCPU_PRINT_INT32(vcpu->id); + DUMP_VCPU_PRINT_INT32(vcpu->idx); + DUMP_VCPU_PRINT_INT32(vcpu->sipivector); + DUMP_VCPU_PRINT_INT32(vcpu->sipireceived); + DUMP_VCPU_PRINT_INT32(vcpu->cpu_vendor); + DUMP_VCPU_PRINT_INT32(vcpu->isbsp); + DUMP_VCPU_PRINT_INT32(vcpu->quiesced); + DUMP_VCPU_PRINT_INT64(vcpu->hsave_vaddr_ptr); + DUMP_VCPU_PRINT_INT64(vcpu->vmcb_vaddr_ptr); + DUMP_VCPU_PRINT_INT64(vcpu->npt_vaddr_ptr); + DUMP_VCPU_PRINT_INT64(vcpu->npt_vaddr_pdts); + DUMP_VCPU_PRINT_INT64(vcpu->npt_asid); + DUMP_VCPU_PRINT_INT64(vcpu->npt_vaddr_pts); + DUMP_VCPU_PRINT_INT64(vcpu->svm_vaddr_iobitmap); + for (u32 i = 0; i < IA32_VMX_MSRCOUNT; i++) { + DUMP_VCPU_PRINT_INT64_INDEX(vcpu->vmx_msrs, i); + } + DUMP_VCPU_PRINT_INT64(vcpu->vmx_msr_efer); + DUMP_VCPU_PRINT_INT64(vcpu->vmx_msr_efcr); + DUMP_VCPU_PRINT_INT64(vcpu->vmx_vmxonregion_vaddr); + DUMP_VCPU_PRINT_INT64(vcpu->vmx_vmcs_vaddr); + DUMP_VCPU_PRINT_INT64(vcpu->vmx_vaddr_iobitmap); + DUMP_VCPU_PRINT_INT64(vcpu->vmx_vaddr_msr_area_host); + DUMP_VCPU_PRINT_INT64(vcpu->vmx_vaddr_msr_area_guest); + DUMP_VCPU_PRINT_INT64(vcpu->vmx_vaddr_msrbitmaps); + DUMP_VCPU_PRINT_INT64(vcpu->vmx_vaddr_ept_pml4_table); + DUMP_VCPU_PRINT_INT64(vcpu->vmx_vaddr_ept_pdp_table); + DUMP_VCPU_PRINT_INT64(vcpu->vmx_vaddr_ept_pd_tables); + DUMP_VCPU_PRINT_INT64(vcpu->vmx_vaddr_ept_p_tables); + // Skip: vmx_ept_memorytypes + // Skip: vmx_guestmtrrmsrs + DUMP_VCPU_PRINT_INT32(vcpu->vmx_guest_currentstate); + DUMP_VCPU_PRINT_INT32(vcpu->vmx_guest_nextstate); + DUMP_VCPU_PRINT_INT32(vcpu->vmx_guest_unrestricted); + DUMP_VCPU_PRINT_INT16(vcpu->vmcs.control_vpid); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.control_VMX_pin_based); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.control_VMX_cpu_based); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.control_VMX_seccpu_based); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.control_exception_bitmap); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.control_pagefault_errorcode_mask); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.control_pagefault_errorcode_match); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.control_CR3_target_count); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.control_VM_exit_controls); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.control_VM_exit_MSR_store_count); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.control_VM_exit_MSR_load_count); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.control_VM_entry_controls); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.control_VM_entry_MSR_load_count); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.control_VM_entry_interruption_information); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.control_VM_entry_exception_errorcode); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.control_VM_entry_instruction_length); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.control_Task_PRivilege_Threshold); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.control_CR0_mask); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.control_CR4_mask); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.control_CR0_shadow); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.control_CR4_shadow); +#ifndef __DEBUG_QEMU__ + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.control_CR3_target0); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.control_CR3_target1); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.control_CR3_target2); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.control_CR3_target3); +#endif /* !__DEBUG_QEMU__ */ + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.control_IO_BitmapA_address); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.control_IO_BitmapB_address); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.control_MSR_Bitmaps_address); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.control_VM_exit_MSR_store_address); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.control_VM_exit_MSR_load_address); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.control_VM_entry_MSR_load_address); +#ifndef __DEBUG_QEMU__ + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.control_Executive_VMCS_pointer); +#endif /* !__DEBUG_QEMU__ */ + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.control_TSC_offset); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.control_virtual_APIC_page_address); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.control_EPT_pointer); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.host_CR0); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.host_CR3); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.host_CR4); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.host_FS_base); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.host_GS_base); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.host_TR_base); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.host_GDTR_base); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.host_IDTR_base); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.host_SYSENTER_ESP); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.host_SYSENTER_EIP); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.host_RSP); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.host_RIP); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.host_SYSENTER_CS); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.host_ES_selector); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.host_CS_selector); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.host_SS_selector); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.host_DS_selector); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.host_FS_selector); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.host_GS_selector); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.host_TR_selector); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_CR0); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_CR3); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_CR4); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_ES_base); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_CS_base); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_SS_base); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_DS_base); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_FS_base); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_GS_base); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_LDTR_base); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_TR_base); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_GDTR_base); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_IDTR_base); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_DR7); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_RSP); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_RIP); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_RFLAGS); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_pending_debug_x); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_SYSENTER_ESP); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_SYSENTER_EIP); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_ES_limit); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_CS_limit); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_SS_limit); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_DS_limit); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_FS_limit); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_GS_limit); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_LDTR_limit); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_TR_limit); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_GDTR_limit); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_IDTR_limit); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_ES_access_rights); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_CS_access_rights); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_SS_access_rights); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_DS_access_rights); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_FS_access_rights); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_GS_access_rights); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_LDTR_access_rights); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_TR_access_rights); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_interruptibility); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_activity_state); +#ifndef __DEBUG_QEMU__ + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_SMBASE); +#endif /* !__DEBUG_QEMU__ */ + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_SYSENTER_CS); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_ES_selector); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_CS_selector); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_SS_selector); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_DS_selector); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_FS_selector); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_GS_selector); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_LDTR_selector); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.guest_TR_selector); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_VMCS_link_pointer); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_IA32_DEBUGCTL); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_paddr); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_PDPTE0); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_PDPTE1); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_PDPTE2); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.guest_PDPTE3); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.info_vminstr_error); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.info_vmexit_reason); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.info_vmexit_interrupt_information); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.info_vmexit_interrupt_error_code); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.info_IDT_vectoring_information); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.info_IDT_vectoring_error_code); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.info_vmexit_instruction_length); + DUMP_VCPU_PRINT_INT32(vcpu->vmcs.info_vmx_instruction_information); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.info_exit_qualification); +#ifndef __DEBUG_QEMU__ + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.info_IO_RCX); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.info_IO_RSI); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.info_IO_RDI); + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.info_IO_RIP); +#endif /* !__DEBUG_QEMU__ */ + DUMP_VCPU_PRINT_INT64(vcpu->vmcs.info_guest_linear_address); + +#undef DUMP_VCPU_PRINT_INT16 +#undef DUMP_VCPU_PRINT_INT32 +#undef DUMP_VCPU_PRINT_INT64 +#undef DUMP_VCPU_PRINT_INT64_INDEX + +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx.c new file mode 100644 index 0000000000..8f27739fe5 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx.c @@ -0,0 +1,86 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF base platform component interface, x86 vmx backend + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//initialize CPU state +void xmhf_baseplatform_arch_x86vmx_cpuinitialize(void){ + u32 bcr0; +#ifdef __DRT__ + txt_heap_t *txt_heap; + os_mle_data_t *os_mle_data; +#endif /* __DRT__ */ + + //set bit 5 (EM) of CR0 to be VMX compatible in case of Intel cores + bcr0 = read_cr0(); + bcr0 |= 0x20; + write_cr0(bcr0); + +#if defined (__DRT__) + // restore pre-SENTER MTRRs that were overwritten for SINIT launch + // NOTE: XXX TODO; BSP MTRRs ALREADY RESTORED IN SL; IS IT + // DANGEROUS TO DO THIS TWICE? + // sl.c unity-maps 0xfed00000 for 2M so these should work fine + #ifndef __XMHF_VERIFICATION__ + txt_heap = get_txt_heap(); + printf("\ntxt_heap = 0x%08lx", (uintptr_t)txt_heap); + os_mle_data = get_os_mle_data_start(txt_heap); + printf("\nos_mle_data = 0x%08lx", (uintptr_t)os_mle_data); + + if(!validate_mtrrs(&(os_mle_data->saved_mtrr_state))) { + printf("\nSECURITY FAILURE: validate_mtrrs() failed.\n"); + HALT(); + } + restore_mtrrs(&(os_mle_data->saved_mtrr_state)); + #endif +#endif //__DRT__ + +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/bplt-data.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/bplt-data.c new file mode 100644 index 0000000000..b4c992b512 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/bplt-data.c @@ -0,0 +1,87 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF base platform component + * arch. independent data definitions + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//system e820 map +GRUBE820 g_e820map[MAX_E820_ENTRIES] __attribute__(( section(".data") )); + +//SMP CPU map; lapic id, base, ver and bsp indication for each available core +PCPU g_cpumap[MAX_PCPU_ENTRIES] __attribute__(( section(".data") )); + +//runtime stacks for individual cores +u8 g_cpustacks[RUNTIME_STACK_SIZE * MAX_PCPU_ENTRIES] __attribute__(( section(".bss.stack") )); + +//VCPU structure for each "guest OS" core +VCPU g_vcpubuffers[MAX_VCPU_ENTRIES] __attribute__(( section(".data") )); + +//master id table, contains core lapic id to VCPU mapping information +MIDTAB g_midtable[MAX_MIDTAB_ENTRIES] __attribute__(( section(".data") )); + +//number of entries in the master id table, in essence the number of +//physical cores in the system +u32 g_midtable_numentries __attribute__(( section(".data") )) = 0; + +//variable that is incremented by 1 by all cores that boot up, this should +//be finally equal to g_midtable_numentries at runtime which signifies +//that all physical cores have been booted up and initialized by the runtime +volatile u32 g_cpus_active __attribute__(( section(".data") )) = 0; + +//SMP lock for the above variable +volatile u32 g_lock_cpus_active __attribute__(( section(".data") )) = 1; + +//variable that is set to 1 by the BSP after rallying all the other cores. +//this is used by the application cores to enter the "wait-for-SIPI" state +volatile u32 g_ap_go_signal __attribute__(( section(".data") )) = 0; + +//SMP lock for the above variable +volatile u32 g_lock_ap_go_signal __attribute__(( section(".data") )) = 1; diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/bplt-interface-runtime.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/bplt-interface-runtime.c new file mode 100644 index 0000000000..b271aacf52 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/bplt-interface-runtime.c @@ -0,0 +1,105 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF base platform component interface + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +extern RPB *rpb; +// extern GRUBE820 g_e820map[]; + +// Traverse the E820 map and return the base and limit of used system physical address (i.e., used by main memory and MMIO). +// [NOTE] must be u64 even on 32-bit machines, because it could be 4G, and hence overflow u32. +// Return: and may not be 4K-aligned. +// [TODO][Issue 85] Move this function to a better place +bool xmhf_baseplatform_x86_e820_paddr_range(spa_t* machine_base_spa, spa_t* machine_limit_spa) +{ + u32 i = 0; + spa_t base_spa = INVALID_SPADDR; + spa_t limit_spa = INVALID_SPADDR; + + // Sanity checks + if(!machine_base_spa || !machine_limit_spa) + return false; + + if(!rpb) + return false; + + if(!rpb->XtVmmE820NumEntries) + return false; + + // Traverse E820 entries to find the base and limit of the system phsical address. + // Note: E820 entries are unsorted, and sometimes overlapping with each other. + // Note: We ignore the type of E820 entries. + // see https://wiki.osdev.org/Detecting_Memory_(x86)#BIOS_Function:_INT_0x15.2C_EAX_.3D_0xE820 + base_spa = UINT32sToSPADDR(g_e820map[0].baseaddr_high, g_e820map[0].baseaddr_low); + FOREACH_S(i, rpb->XtVmmE820NumEntries, MAX_E820_ENTRIES, 0, 1) + { + spa_t cur_base_spa = UINT32sToSPADDR(g_e820map[i].baseaddr_high, g_e820map[i].baseaddr_low); + u64 cur_size = UINT32sToUINT64(g_e820map[i].length_high, g_e820map[i].length_low); // E820 map may have entry size > 4GB + spa_t cur_limit_spa = cur_base_spa + cur_size; + + if(cur_base_spa <= base_spa) + { + // Found a lower base + base_spa = cur_base_spa; + } + + if(cur_limit_spa >= limit_spa) + { + // Found an upper limit + limit_spa = cur_limit_spa; + } + } + + *machine_base_spa = base_spa; + *machine_limit_spa = limit_spa; + + return true; +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/bplt-interface-smp.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/bplt-interface-smp.c new file mode 100644 index 0000000000..aadfd385e4 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/bplt-interface-smp.c @@ -0,0 +1,62 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF base platform component interface (SMP exports) + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//initialize SMP +void xmhf_baseplatform_smpinitialize(void){ + xmhf_baseplatform_arch_smpinitialize(); +} + +//reboot platform +void xmhf_baseplatform_reboot(VCPU *vcpu){ + xmhf_baseplatform_arch_reboot(vcpu); +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/bplt-interface.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/bplt-interface.c new file mode 100644 index 0000000000..216819a1a0 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-baseplatform/bplt-interface.c @@ -0,0 +1,67 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF base platform component interface + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//get CPU vendor +u32 xmhf_baseplatform_getcpuvendor(void){ + return xmhf_baseplatform_arch_getcpuvendor(); +} + +//initialize basic platform elements +void xmhf_baseplatform_initialize(void){ + xmhf_baseplatform_arch_initialize(); +} + +//initialize CPU state +void xmhf_baseplatform_cpuinitialize(void){ + xmhf_baseplatform_arch_cpuinitialize(); +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-debug/Makefile b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-debug/Makefile new file mode 100644 index 0000000000..5a00e87375 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-debug/Makefile @@ -0,0 +1,38 @@ +# makefile for EMHF debug component +# author: amit vasudevan (amitvasudevan@acm.org) + +# source files +AS_SOURCES = +AS_SOURCES_BL = + +C_SOURCES = dbg-interface.c +C_SOURCES += ./arch/x86/emhf_debug_arch.c + +ifeq ($(DEBUG_SERIAL), y) +C_SOURCES += ./arch/x86/dbg-x86-uart.c +endif + +ifeq ($(DEBUG_VGA), y) +C_SOURCES += ./arch/x86/dbg-x86-vgamem.c +endif + +C_SOURCES_BL = $(C_SOURCES) + +EXTRA_CLEAN = lib.a lib.i386.a + +# targets +include ../runtime.mk + +all: lib.a + +lib.a: $(OBJECTS) + $(AR) rvs $@ $^ + +# If runtime is amd64, compile i386 version of this library for bootloader +ifeq ($(TARGET_SUBARCH), amd64) +all: lib.i386.a + +lib.i386.a: $(OBJECTS_BL) + $(AR) rvs $@ $^ +endif + diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-debug/arch/x86/dbg-x86-uart.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-debug/arch/x86/dbg-x86-uart.c new file mode 100644 index 0000000000..d3073fde33 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-debug/arch/x86/dbg-x86-uart.c @@ -0,0 +1,130 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * low-level UART comms. + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +// frequency of UART clock source +#define UART_CLOCKFREQ 1843200 + +// default config parameters for serial port +uart_config_t g_uart_config = {115200, + 8, + PARITY_NONE, + 1, + 0, + UART_CLOCKFREQ, + DEBUG_PORT}; + +//low-level UART character output +static void dbg_x86_uart_putc_bare(char ch){ + //wait for xmit hold register to be empty + while ( ! (inb(g_uart_config.port+0x5) & 0x20) ); + + //write the character + outb((u8)ch, g_uart_config.port); + + return; +} + + +// write character to serial port, translating '\n' to '\r\n' +void dbg_x86_uart_putc(char ch){ + if (ch == '\n') { + dbg_x86_uart_putc_bare('\r'); + } + dbg_x86_uart_putc_bare(ch); +} + + +// write string to serial port +void dbg_x86_uart_putstr(const char *s){ + while (*s) + dbg_x86_uart_putc(*s++); +} + + +//initialize UART comms. +void dbg_x86_uart_init(char *params){ + + //override default UART parameters with the one passed via the + //command line + memcpy((void *)&g_uart_config, params, sizeof(uart_config_t)); + + // FIXME: work-around for issue #143 + g_uart_config.fifo = 0; + + // disable UART interrupts + outb((u8)0, g_uart_config.port+0x1); //clear interrupt enable register + + //compute divisor latch data from baud-rate and set baud-rate + { + u16 divisor_latch_data = g_uart_config.clock_hz / (g_uart_config.baud * 16); + + outb(0x80, g_uart_config.port+0x3); //enable divisor latch access by + //writing to line control register + + outb((u8)divisor_latch_data, g_uart_config.port); //write low 8-bits of divisor latch data + outb((u8)(divisor_latch_data >> 8), g_uart_config.port+0x1); //write high 8-bits of divisor latch data + + } + + //set data bits, stop bits and parity info. by writing to + //line control register + outb((u8)((g_uart_config.data_bits - 5) | + ((g_uart_config.stop_bits - 1) << 2) | + g_uart_config.parity), g_uart_config.port+0x3); + + //signal ready by setting DTR and RTS high in + //modem control register + outb((u8)0x3, g_uart_config.port+0x4); + + return; +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-debug/arch/x86/dbg-x86-vgamem.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-debug/arch/x86/dbg-x86-vgamem.c new file mode 100644 index 0000000000..96658a8a8e --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-debug/arch/x86/dbg-x86-vgamem.c @@ -0,0 +1,92 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include + +#define COLS 80 +#define ROWS 25 +#define ATTR 7 + +static char *vidmem=(char *)0xB8000; +static unsigned int vid_x, vid_y; + +static void vgamem_newln(void){ + vid_x = 0; + vid_y++; + + if (vid_y >= ROWS){ + vid_y = ROWS-1; + memmove((char*)vidmem,(char*)vidmem + 2*COLS, (ROWS-1)*2*COLS); + memset((char*)vidmem + (ROWS-1)*2*COLS, 0, 2*COLS); + } +} + +void dbg_x86_vgamem_putc(int c) +{ + if ( c == '\n' ) + vgamem_newln(); + else + { + vidmem[(vid_x + vid_y * COLS) * 2] = c & 0xFF; + vidmem[(vid_x + vid_y * COLS) * 2 + 1] = ATTR; + if ( ++vid_x >= COLS ) vgamem_newln(); + } +} + +void dbg_x86_vgamem_putstr(const char *str) +{ + int c; + + while ( (c = *str++) != '\0' ) + dbg_x86_vgamem_putc(c); +} + + +void dbg_x86_vgamem_init(char *params){ + (void)params; //we don't use params for the VGA backend currently + memset((char *)vidmem, 0, COLS * ROWS * 2); + vid_x = vid_y = 0; +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-debug/arch/x86/emhf_debug_arch.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-debug/arch/x86/emhf_debug_arch.c new file mode 100644 index 0000000000..097de7586b --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-debug/arch/x86/emhf_debug_arch.c @@ -0,0 +1,83 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include + +void xmhf_debug_arch_init(char *params) +{ + (void)params; +#ifdef __DEBUG_SERIAL__ + dbg_x86_uart_init(params); +#endif + +#ifdef __DEBUG_VGA__ + dbg_x86_vgamem_init(NULL); +#endif +} + +void xmhf_debug_arch_putc(char c) +{ + (void)c; +#ifdef __DEBUG_SERIAL__ + dbg_x86_uart_putc(c); +#endif + +#ifdef __DEBUG_VGA__ + dbg_x86_vgamem_putc(c); +#endif +} + +void xmhf_debug_arch_putstr(const char *str) +{ + (void)str; +#ifdef __DEBUG_SERIAL__ + dbg_x86_uart_putstr(str); +#endif + +#ifdef __DEBUG_VGA__ + dbg_x86_vgamem_putstr(str); +#endif +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-debug/dbg-interface.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-debug/dbg-interface.c new file mode 100644 index 0000000000..3761bf26aa --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-debug/dbg-interface.c @@ -0,0 +1,72 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF debug component interface +// Author(s): Amit Vasudevan (amitvasudevan@acm.org) +// James Newsome + +#include + +uint8_t g_log_targets=LOG_TARGET_NONE; +uint8_t g_log_level=LOG_LEVEL_NONE; + +static volatile u32 printf_lock=1; + +#if defined (__DEBUG_SERIAL__) || defined (__DEBUG_VGA__) + +void dvprintf(u32 log_type, const char *fmt, va_list args) +{ + if (log_type & ENABLED_LOG_TYPES) { + vprintf(fmt, args); + } +} + + +#endif + +void xmhf_debug_init(char *params){ + xmhf_debug_arch_init(params); +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/Makefile b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/Makefile new file mode 100644 index 0000000000..a8b9d65bb0 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/Makefile @@ -0,0 +1,20 @@ +# makefile for xmhf-memprot (EMHF memory protection component) +# author: amit vasudevan (amitvasudevan@acm.org) + +# source files +AS_SOURCES = +C_SOURCES = dmap-interface-earlyinit.c +C_SOURCES += dmap-interface-runtime.c +C_SOURCES += iommu-pt.c +C_SOURCES += ./arch/x86/dmap-x86-earlyinit.c +C_SOURCES += ./arch/x86/dmap-x86-runtime.c +C_SOURCES += ./arch/x86/svm/dmap-svm.c +C_SOURCES += ./arch/x86/vmx/dmap-vmx-earlyinit.c +C_SOURCES += ./arch/x86/vmx/dmap-vmx-internal.c +C_SOURCES += ./arch/x86/vmx/dmap-vmx-runtime.c +C_SOURCES += ./arch/x86/vmx/dmap-vmx-utils.c +C_SOURCES += ./arch/x86/vmx/dmap-vmx-data.c + +# targets +include ../runtime.mk + diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/dmap-x86-earlyinit.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/dmap-x86-earlyinit.c new file mode 100644 index 0000000000..d72b1bbcf7 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/dmap-x86-earlyinit.c @@ -0,0 +1,66 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF DMA protection component implementation +// x86 backends +// author: amit vasudevan (amitvasudevan@acm.org) + +#include + +//"early" DMA protection initialization to setup minimal +//structures to protect a range of physical memory +//return 1 on success 0 on failure +u32 xmhf_dmaprot_arch_earlyinitialize(u64 protectedbuffer_paddr, u32 protectedbuffer_vaddr, u32 protectedbuffer_size, u64 memregionbase_paddr, u32 memregion_size){ + u32 cpu_vendor = get_cpu_vendor_or_die(); //determine CPU vendor + + + if(cpu_vendor == CPU_VENDOR_AMD){ + return xmhf_dmaprot_arch_x86_svm_earlyinitialize(protectedbuffer_paddr, protectedbuffer_vaddr, protectedbuffer_size, memregionbase_paddr, memregion_size); + } + else{ //CPU_VENDOR_INTEL + return xmhf_dmaprot_arch_x86_vmx_earlyinitialize(protectedbuffer_paddr, protectedbuffer_vaddr, protectedbuffer_size, memregionbase_paddr, memregion_size); + } +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/dmap-x86-runtime.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/dmap-x86-runtime.c new file mode 100644 index 0000000000..7778605d28 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/dmap-x86-runtime.c @@ -0,0 +1,116 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF DMA protection component implementation +// x86 backends +// author: amit vasudevan (amitvasudevan@acm.org) + +#include + +//return size (in bytes) of the memory buffer required for +//DMA protection for a given physical memory limit +u32 xmhf_dmaprot_arch_getbuffersize(u64 physical_memory_limit){ + u32 cpu_vendor = get_cpu_vendor_or_die(); //determine CPU vendor + HALT_ON_ERRORCOND( physical_memory_limit <= PA_PAGE_SIZE_512G ); //we only support 512GB physical memory currently + HALT_ON_ERRORCOND( physical_memory_limit <= DMAPROT_PHY_ADDR_SPACE_SIZE ); //we only support physical memory currently + + if(cpu_vendor == CPU_VENDOR_AMD){ + return ((physical_memory_limit / PAGE_SIZE_4K) / 8); //each page takes up 1-bit with AMD DEV + }else{ //CPU_VENDOR_INTEL + return (SIZE_G_RNTM_DMAPROT_BUFFER); //4-level PML4 page tables + 4KB root entry table + 4K context entry table per PCI bus + } +} + +//"normal" DMA protection initialization to setup required +//structures for DMA protection +//return 1 on success 0 on failure +u32 xmhf_dmaprot_arch_initialize(u64 protectedbuffer_paddr, + u32 protectedbuffer_vaddr, u32 protectedbuffer_size){ + u32 cpu_vendor = get_cpu_vendor_or_die(); //determine CPU vendor + + if(cpu_vendor == CPU_VENDOR_AMD){ + return xmhf_dmaprot_arch_x86_svm_initialize(protectedbuffer_paddr, protectedbuffer_vaddr, protectedbuffer_size); + }else{ //CPU_VENDOR_INTEL + return xmhf_dmaprot_arch_x86_vmx_initialize(protectedbuffer_paddr, protectedbuffer_vaddr, protectedbuffer_size); + // return 1; //we use Vtd PMRs to protect the SL + runtime during SL launch + } +} + +//DMA protect a given region of memory, start_paddr is +//assumed to be page aligned physical memory address +void xmhf_dmaprot_arch_protect(spa_t start_paddr, size_t size){ + u32 cpu_vendor = get_cpu_vendor_or_die(); //determine CPU vendor + + if(cpu_vendor == CPU_VENDOR_AMD){ + return xmhf_dmaprot_arch_x86_svm_protect(start_paddr, size); + }else{ //CPU_VENDOR_INTEL + return xmhf_dmaprot_arch_x86_vmx_protect(start_paddr, size); + // return; //we use Vtd PMRs to protect the SL + runtime during SL launch + } +} + +//DMA unprotect a given region of memory, start_paddr is +//assumed to be page aligned physical memory address +void xmhf_dmaprot_arch_unprotect(spa_t start_paddr, size_t size){ + u32 cpu_vendor = get_cpu_vendor_or_die(); //determine CPU vendor + + if(cpu_vendor == CPU_VENDOR_AMD){ + return; + }else{ //CPU_VENDOR_INTEL + return xmhf_dmaprot_arch_x86_vmx_unprotect(start_paddr, size); + } +} + +void xmhf_dmaprot_arch_invalidate_cache(void) +{ + u32 cpu_vendor = get_cpu_vendor_or_die(); //determine CPU vendor + + if(cpu_vendor == CPU_VENDOR_AMD){ + return xmhf_dmaprot_arch_x86_svm_invalidate_cache(); + }else{ //CPU_VENDOR_INTEL + return xmhf_dmaprot_arch_x86_vmx_invalidate_cache(); + } +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/svm/dmap-svm.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/svm/dmap-svm.c new file mode 100644 index 0000000000..775d16912b --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/svm/dmap-svm.c @@ -0,0 +1,467 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF DMA protection component implementation for x86 SVM +// author: amit vasudevan (amitvasudevan@acm.org) + +#include + +// static variables +// SVM EAP container structure, contains the DEV registers and the DEV bitmap +static struct _svm_eap _svm_eap __attribute__((section(".data"))); + +// forward declarations for some static (local) functions +static void svm_eap_dev_write(u32 function, u32 index, u32 value); +static u32 svm_eap_dev_read(u32 function, u32 index); + +// initialize SVM EAP a.k.a DEV +// returns 1 if all went well, else 0 +// inputs: physical and virtual addresses of the DEV bitmap area +static u32 svm_eap_initialize(u32 dev_bitmap_paddr, u32 dev_bitmap_vaddr) +{ + + u32 mc_capabilities_pointer; + u32 mc_caplist_nextptr; + u32 mc_caplist_id; + u32 found_dev = 0; + dev_cap_t dev_cap; + dev_map_t dev_map; + dev_base_lo_t dev_base_lo; + dev_base_hi_t dev_base_hi; + dev_cr_t dev_cr; + u32 i; + + // clear the SVM EAP container structure members including the DEV + // bitmap + // memset((void *)(u32)&_svm_eap, 0, sizeof(struct _svm_eap)); + _svm_eap.dev_hdr_reg = 0; // DEV header register (32-bit) + _svm_eap.dev_fnidx_reg = 0; // DEV function/index register (32-bit) + _svm_eap.dev_data_reg = 0; // DEV data register (32-bit) + _svm_eap.dev_bitmap_vaddr = 0; // DEV bitmap virtual address + + // ensure dev_bitmap_paddr is PAGE_ALIGNED + HALT_ON_ERRORCOND((dev_bitmap_paddr & 0xFFF) == 0); + + // we first need to detect the DEV capability block + // the DEV capability block is in the PCI configuration space + //(15.24.4, AMD Dev. Vol2) + // more precisely it is a part of the Miscellaneous Control + // HyperTransport Configuration space. (3.6, AMD BKDG) + // HyperTransport device configuration space is + // accessed by using bus 0, devices 24 to 31, where device 24 corresponds + // to node 0 and device 31 corresponds to node 7. (2.11, AMD BKDG 10h family) + // note: node 0 corresponds to 0th physical CPU package. So, if we have + // four logical cores on the same physical die, the HT device is on + // bus 0 as device 24 for all the cores. well at least to my knowledge... + // Miscellaneous Control is function 3 (3.6, AMD BKDG) + + // step-1: we read capabilities pointer (PCI_CONF_HDR_IDX_CAPABILITIES_POINTER) + // in b:d.f 0:24.3. If its 0, then DEV support is not available + xmhf_baseplatform_arch_x86_pci_type1_read(DEV_PCI_BUS, DEV_PCI_DEVICE, DEV_PCI_FUNCTION, PCI_CONF_HDR_IDX_CAPABILITIES_POINTER, sizeof(u32), &mc_capabilities_pointer); + if (mc_capabilities_pointer == 0) + return 0; // DEV support unavailable + + HALT_ON_ERRORCOND((u8)(mc_capabilities_pointer) == 0xF0); // p. 286, AMD BKDG + + // traverse the capabilities list as per the PCI spec. + mc_caplist_nextptr = (u32)(u8)mc_capabilities_pointer; + + do + { + // get the ID of this capability block + xmhf_baseplatform_arch_x86_pci_type1_read(DEV_PCI_BUS, DEV_PCI_DEVICE, DEV_PCI_FUNCTION, mc_caplist_nextptr, sizeof(u8), &mc_caplist_id); + +// check if this is a DEV capability ID block +#ifdef __XMHF_VERIFICATION__ + found_dev = 1; + break; +#else + if ((u8)mc_caplist_id == PCI_CAPABILITIES_POINTER_ID_DEV) + { + found_dev = 1; + break; + } +#endif + + // get the index of the next capability block + xmhf_baseplatform_arch_x86_pci_type1_read(DEV_PCI_BUS, DEV_PCI_DEVICE, DEV_PCI_FUNCTION, mc_caplist_nextptr, sizeof(u8), &mc_caplist_nextptr); + } while (mc_caplist_nextptr != 0); + + // did we find a DEV capability block above? if no simply return + if (!found_dev) + return 0; + + // okay, we found a DEV capability block at index mc_caplist_nextptr + printf("\n%s: found DEV capability block at index %04x", __FUNCTION__, mc_caplist_nextptr); + + // now obtain the PCI configuration space indices for DEV header, fn/idx + // and data registers and store them in the SVM EAP container structure + _svm_eap.dev_hdr_reg = mc_caplist_nextptr; + _svm_eap.dev_fnidx_reg = mc_caplist_nextptr + sizeof(u32); + _svm_eap.dev_data_reg = mc_caplist_nextptr + (2 * sizeof(u32)); + + // print it out for now... + printf("\n%s: dev_hdr_reg at %02x:%02x.%1x(%04x)", __FUNCTION__, DEV_PCI_BUS, DEV_PCI_DEVICE, DEV_PCI_FUNCTION, _svm_eap.dev_hdr_reg); + printf("\n%s: dev_fnidx_reg at %02x:%02x.%1x(%04x)", __FUNCTION__, DEV_PCI_BUS, DEV_PCI_DEVICE, DEV_PCI_FUNCTION, _svm_eap.dev_fnidx_reg); + printf("\n%s: dev_data_reg at %02x:%02x.%1x(%04x)", __FUNCTION__, DEV_PCI_BUS, DEV_PCI_DEVICE, DEV_PCI_FUNCTION, _svm_eap.dev_data_reg); + + // setup DEV + +// 0. populate the DEV bitmap physical address in the EAP structure +#ifndef __XMHF_VERIFICATION__ + _svm_eap.dev_bitmap_vaddr = dev_bitmap_vaddr; +#endif + printf("\n DEV: bitmap at v:p addr %08x:%08x", _svm_eap.dev_bitmap_vaddr, + dev_bitmap_paddr); + + // 1. read the DEV revision, and the number of maps and domains supported + dev_cap.bytes = svm_eap_dev_read(DEV_CAP, 0); + + printf("\n DEV:rev=%u, n_doms=%u, n_maps=%u", dev_cap.fields.rev, dev_cap.fields.n_doms, dev_cap.fields.n_maps); + + // 2. disable all the DEV maps. AMD manuals do not mention anything about + // the reset state of the map registers + dev_map.fields.valid0 = 0; + dev_map.fields.valid1 = 0; +#ifndef __XMHF_VERIFICATION__ + for (i = 0; i < dev_cap.fields.n_maps; i++) + svm_eap_dev_write(DEV_MAP, i, dev_map.bytes); +#else + svm_eap_dev_write(DEV_MAP, 0, dev_map.bytes); +#endif + printf("\n DEV: cleared map registers."); + + // 3. set the DEV_BASE_HI and DEV_BASE_LO registers of domain 0 + dev_base_hi.bytes = 0; // our DEV bitmap is within 4GB physical + svm_eap_dev_write(DEV_BASE_HI, 0, dev_base_hi.bytes); + dev_base_lo.fields.valid = 1; // valid + dev_base_lo.fields.protect = 0; + dev_base_lo.fields.size = 0; // 4GB + dev_base_lo.fields.resv = 0; + dev_base_lo.fields.base_addr = (u32)dev_bitmap_paddr >> 12; + svm_eap_dev_write(DEV_BASE_LO, 0, dev_base_lo.bytes); + printf("\n DEV: set DEV_BASE_LO and DEV_BASE_HI."); + + // 4. invalidate the DEV_BASE_HIGH and DEV_BASE_LOW registers of all other + // domains. + dev_base_lo.fields.valid = 0; + dev_base_lo.fields.base_addr = 0; +#ifndef __XMHF_VERIFICATION__ + for (i = 1; i < dev_cap.fields.n_doms; i++) + { + svm_eap_dev_write(DEV_BASE_HI, i, dev_base_hi.bytes); + svm_eap_dev_write(DEV_BASE_LO, i, dev_base_lo.bytes); + } +#else + for (i = 1; i < 2; i++) + { + svm_eap_dev_write(DEV_BASE_HI, i, dev_base_hi.bytes); + svm_eap_dev_write(DEV_BASE_LO, i, dev_base_lo.bytes); + } +#endif + printf("\n DEV: invalidated other domains."); + + // 5. enable DEV protections + dev_cr.fields.deven = 1; + dev_cr.fields.iodis = 1; + dev_cr.fields.mceen = 0; + dev_cr.fields.devinv = 0; + dev_cr.fields.sldev = 1; + dev_cr.fields.walkprobe = 0; + dev_cr.fields.resv0 = 0; + dev_cr.fields.resv1 = 0; +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + assert(dev_cr.fields.deven == 1); +#endif + svm_eap_dev_write(DEV_CR, 0, dev_cr.bytes); + printf("\n DEV: enabled protections."); + + return 1; +} + +//------------------------------------------------------------------------------ +// early initialization of SVM EAP a.k.a DEV +// returns 1 if all went well, else 0 +// inputs: physical and virtual addresses of a buffer that is +// already DMA protected, starting address and size (in bytes) +// of the physical memory region to be DMA protected +// Note: this function exists since we need to bootstrap DEV +// protections early on. We cannot afford to have the entire DEV bitmap +//(128K) within the SL, so we use a DMA-protected buffer +//(capable of DMA protecting a contiguous physical memory range) +// that lies within the initially DMA-protected SL region to protect +// the runtime physical memory. +// The runtime then re-initializes DEV once it gets control +static u32 svm_eap_early_initialize(uintptr_t protected_buffer_paddr, + uintptr_t protected_buffer_vaddr, uintptr_t memregion_paddr_start, + uintptr_t memregion_size) +{ + u32 dev_bitmap_paddr = 0; + + printf("\n%s: protected buffer, paddr=%08x, vaddr=%08x", __FUNCTION__, + protected_buffer_paddr, protected_buffer_vaddr); + + // sanity check: the protected buffer MUST be page aligned + HALT_ON_ERRORCOND(!(protected_buffer_paddr & 0x00000FFF) && + !(protected_buffer_vaddr & 0x00000FFF)); + + // compute DEV bitmap base address depending on the physical base address + // of the protected buffer and the physical base address of the memory + // region + // Note: we assume the protected buffer size to be 8K on AMD + // sanity check: memregion size cannot be greater than 128MB + HALT_ON_ERRORCOND(memregion_size < (8192 * 8 * PAGE_SIZE_4K)); + + { + u32 memregion_paligned_paddr_start; + u32 memregion_pfn = 0; + u32 devbitmap_bytes_before = 0; + u32 offset = 0; // this is the offset of the memory page corresponding to SL physical base + // within the 8K protected DEV buffer + + // compute page-aligned base address of memory region + memregion_paligned_paddr_start = PAGE_ALIGN_4K(memregion_paddr_start); + + // compute pfn of memregion + memregion_pfn = memregion_paligned_paddr_start / PAGE_SIZE_4K; + + // thus, there are memregion_pfn pages that need to be accounted for + // until we hit our protected buffer in the DEV bitmap + // each page is 1 bit in the bitmap, so compute number of bytes of + // DEV bitmap we need before our protected buffer + devbitmap_bytes_before = memregion_pfn / 8; // 8-bits in a byte + + // the physical base address of the DEV bitmap will be our protected + // buffer physical base minus devbitmap_bytes_before + // Note: we dont care about other parts of the DEV bitmap except for + // our protected buffer which is assumed to be protected... + dev_bitmap_paddr = protected_buffer_paddr - devbitmap_bytes_before; + printf("\nSL:%s dev_bitmap_paddr=%08x", __FUNCTION__, dev_bitmap_paddr); + + // DEV bitmap base MUST be page aligned, however dev_bitmap_paddr + // can violate this, so make sure we page align it and account for the + //"offset" within the 8K protected DEV buffer + if (dev_bitmap_paddr & 0x00000FFFUL) + { + offset = PAGE_SIZE_4K - (dev_bitmap_paddr & 0x00000FFFUL); // offset is always less than 4K + dev_bitmap_paddr += offset; // page-align dev_bitmap_paddr + printf("\nSL:%s dev_bitmap_paddr page-aligned to %08x", __FUNCTION__, dev_bitmap_paddr); + } + + // sanity check: dev_bitmap_paddr MUST be page aligned + HALT_ON_ERRORCOND(!(dev_bitmap_paddr & 0x00000FFF)); + + // now make sure the protected buffer (4K in our case) is set to all 1's + // effectively preventing DMA reads and writes from memregion_paligned_paddr_start + // to memregion_paligned_paddr_start + 128M + memset((void *)(protected_buffer_vaddr + (u32)offset), 0xFF, PAGE_SIZE_4K); + } + + return dev_bitmap_paddr; +} + +// DEV "read" function +// inputs: function (DEV function), index (DEV functions DEV_BASE_LO, +// DEV_BASE_HI and DEV_MAP have multiple instances, the index selects +// the appropriate instance in such cases; 0 for all other functions), +static u32 svm_eap_dev_read(u32 function, u32 index) +{ + u32 value; + + // sanity check on DEV registers + HALT_ON_ERRORCOND(_svm_eap.dev_hdr_reg != 0 && _svm_eap.dev_fnidx_reg != 0 && _svm_eap.dev_data_reg != 0); + + // step-1: write function and index to dev_fnidx_reg + // format of dev_fnidx_reg is in AMD Dev. Vol2 (p. 407) + xmhf_baseplatform_arch_x86_pci_type1_write(DEV_PCI_BUS, DEV_PCI_DEVICE, DEV_PCI_FUNCTION, + _svm_eap.dev_fnidx_reg, sizeof(u32), (u32)(((function & 0xff) << 8) + (index & 0xff))); + + // step-2: read 32-bit value from dev_data_reg + xmhf_baseplatform_arch_x86_pci_type1_read(DEV_PCI_BUS, DEV_PCI_DEVICE, DEV_PCI_FUNCTION, + _svm_eap.dev_data_reg, sizeof(u32), &value); + + return value; +} + +// DEV "write" function +// inputs: function (DEV function), index (DEV functions DEV_BASE_LO, +// DEV_BASE_HI and DEV_MAP have multiple instances, the index selects +// the appropriate instance in such cases; 0 for all other functions), +// and value (value to be written to the DEV function) +static void svm_eap_dev_write(u32 function, u32 index, u32 value) +{ + + // sanity check on DEV registers + HALT_ON_ERRORCOND(_svm_eap.dev_hdr_reg != 0 && _svm_eap.dev_fnidx_reg != 0 && _svm_eap.dev_data_reg != 0); + + // step-1: write function and index to dev_fnidx_reg + // format of dev_fnidx_reg is in AMD Dev. Vol2 (p. 407) + xmhf_baseplatform_arch_x86_pci_type1_write(DEV_PCI_BUS, DEV_PCI_DEVICE, DEV_PCI_FUNCTION, + _svm_eap.dev_fnidx_reg, sizeof(u32), (u32)(((function & 0xff) << 8) + (index & 0xff))); + + // step-2: write 32-bit value to dev_data_reg + xmhf_baseplatform_arch_x86_pci_type1_write(DEV_PCI_BUS, DEV_PCI_DEVICE, DEV_PCI_FUNCTION, + _svm_eap.dev_data_reg, sizeof(u32), value); +} + +//------------------------------------------------------------------------------ +// SVM DEV function implementation + +// helper functions to set and clear page protections in the DEV bitmap +// passed as a bit vector to these functions +static void svm_eap_dev_set_page_protection(u32 pfn, u8 *bit_vector) +{ + u32 byte_offset, bit_offset; + + // sanity check + HALT_ON_ERRORCOND(bit_vector != NULL); + + byte_offset = pfn / 8; + bit_offset = pfn & 7; + bit_vector[byte_offset] |= (1 << bit_offset); + + return; +} + +// invalidate DEV cache +static void svm_eap_dev_invalidate_cache(void) +{ + dev_cr_t dev_cr; + + dev_cr.bytes = svm_eap_dev_read(DEV_CR, 0); // read current DEV_CR value + dev_cr.fields.devinv = 1; // clear DEV cache + dev_cr.fields.deven = 1; // ensure DEV is enabled + svm_eap_dev_write(DEV_CR, 0, dev_cr.bytes); // write modified DEV_CR to invalidate caches + +#ifndef __XMHF_VERIFICATION__ + // wait until DEV h/w completes invalidation, seems like this may + // not be fast enough for us to skip the wait! + do + { + dev_cr.bytes = svm_eap_dev_read(DEV_CR, 0); // read DEV_CR value + } while (dev_cr.fields.devinv == 1); // h/w clears the devinv bit when done +#else + dev_cr.bytes = svm_eap_dev_read(DEV_CR, 0); // read DEV_CR value +#endif + + return; +} + +//////////////////////////////////////////////////////////////////////// +// GLOBALS + +//"early" DMA protection initialization to setup minimal +// structures to protect a range of physical memory +// return 1 on success 0 on failure +u32 xmhf_dmaprot_arch_x86_svm_earlyinitialize(u64 protectedbuffer_paddr, + u32 protectedbuffer_vaddr, u32 protectedbuffer_size, + u64 memregionbase_paddr, u32 memregion_size) +{ + + u32 dev_bitmap_paddr; + u32 status; + + // sanity check: protected DEV buffer MUST be page-aligned + HALT_ON_ERRORCOND(!(protectedbuffer_paddr & 0x00000FFF)); + HALT_ON_ERRORCOND(!(protectedbuffer_vaddr & 0x00000FFF)); + HALT_ON_ERRORCOND(protectedbuffer_size >= (PAGE_SIZE_4K * 2)); + + printf("\nSL: initializing SVM DMA protection..."); + +#ifndef __XMHF_VERIFICATION__ + dev_bitmap_paddr = svm_eap_early_initialize(protectedbuffer_paddr, protectedbuffer_vaddr, + memregionbase_paddr, memregion_size); +#else + dev_bitmap_paddr = 0xB8100000; +#endif + + // setup DEV + status = svm_eap_initialize(dev_bitmap_paddr, dev_bitmap_paddr); + + return status; +} + +//"normal" DMA protection initialization to setup required +// structures for DMA protection +// return 1 on success 0 on failure +u32 xmhf_dmaprot_arch_x86_svm_initialize(u64 protectedbuffer_paddr, + u32 protectedbuffer_vaddr, u32 protectedbuffer_size) +{ + + u32 status; + + HALT_ON_ERRORCOND(protectedbuffer_size >= 131072); // we need 128K + + status = svm_eap_initialize(protectedbuffer_paddr, protectedbuffer_vaddr); + + return status; +} + +// DMA protect a given region of memory, start_paddr is +// assumed to be page aligned physical memory address +void xmhf_dmaprot_arch_x86_svm_protect(u32 start_paddr, u32 size) +{ + u32 paligned_paddr_start, paligned_paddr_end, i; + + // compute page-aligned physical start and end addresses + paligned_paddr_start = PAGE_ALIGN_4K((uintptr_t)start_paddr); + paligned_paddr_end = PAGE_ALIGN_4K(((uintptr_t)start_paddr + size)); + +#ifndef __XMHF_VERIFICATION__ + // protect pages from paligned_paddr_start through paligned_paddr_end inclusive + for (i = paligned_paddr_start; i <= paligned_paddr_end; i += PAGE_SIZE_4K) + { + svm_eap_dev_set_page_protection(i >> PAGE_SHIFT_4K, (u8 *)_svm_eap.dev_bitmap_vaddr); + } +#endif + + svm_eap_dev_invalidate_cache(); // flush DEV cache +} + +void xmhf_dmaprot_arch_x86_svm_invalidate_cache(void) +{ + svm_eap_dev_invalidate_cache(); // flush DEV cache +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/vmx/dmap-vmx-data.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/vmx/dmap-vmx-data.c new file mode 100644 index 0000000000..caae906b7d --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/vmx/dmap-vmx-data.c @@ -0,0 +1,72 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/** + * dmap-x86vmx-data.c + * EMHF DMA protection component implementation for x86 VMX + * data definitions + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//VMX VT-d page table buffers; we support a 3-level and 4-level page-table walk , +//4kb pml4 4kb pdpt, 4kb pdt and 4kb pt and each entry in pdpt, pdt and pt is 64-bits +u8 g_vmx_vtd_pml4_table[PAGE_SIZE_4K] __attribute__(( section(".bss.palign_data") )); +u8 g_vmx_vtd_pdp_table[PAGE_SIZE_4K] __attribute__(( section(".bss.palign_data") )); +u8 g_vmx_vtd_pd_tables[PAGE_SIZE_4K * DMAPROT_VMX_P4L_NPDT] __attribute__(( section(".bss.palign_data") )); +u8 g_vmx_vtd_p_tables[PAGE_SIZE_4K * DMAPROT_VMX_P4L_NPDT * PAE_PTRS_PER_PDT] __attribute__(( section(".bss.palign_data") )); + +//VMX VT-d Root Entry Table (RET) +//the RET is 4kb, each root entry (RE) is 128-bits +//this gives us 256 entries in the RET, each corresponding to a PCI bus num. (0-255) +u8 g_vmx_vtd_ret[PAGE_SIZE_4K] __attribute__(( section(".bss.palign_data") )); + +//VMX VT-d Context Entry Table (CET) +//each RE points to a context entry table (CET) of 4kb, each context entry (CE) +//is 128-bits which gives us 256 entries in the CET, accounting for 32 devices +//with 8 functions each as per the PCI spec. +u8 g_vmx_vtd_cet[PAGE_SIZE_4K * PCI_BUS_MAX] __attribute__(( section(".bss.palign_data") )); diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/vmx/dmap-vmx-earlyinit.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/vmx/dmap-vmx-earlyinit.c new file mode 100644 index 0000000000..dfa03bc942 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/vmx/dmap-vmx-earlyinit.c @@ -0,0 +1,230 @@ +// XMHF must separate earlyinit from runtime, because secure loader links different files from the runtime. + +#include +#include "dmap-vmx-internal.h" + +//============================================================================== +// local (static) variables and function definitions +//============================================================================== + +// DMA Remapping Hardware Unit Definitions +static VTD_DRHD vtd_drhd[VTD_MAX_DRHD]; +static u32 vtd_num_drhd = 0; // total number of DMAR h/w units + +//------------------------------------------------------------------------------ +// set VT-d RET and CET tables for VT-d bootstrapping +// we have 1 root entry table (RET) of 4kb, each root entry (RE) is 128-bits +// which gives us 256 entries in the RET, each corresponding to a PCI bus num. +//(0-255) +// each RE points to a context entry table (CET) of 4kb, each context entry (CE) +// is 128-bits which gives us 256 entries in the CET, accounting for 32 devices +// with 8 functions each as per the PCI spec. +// each CE points to a PDPT type paging structure. +// we ensure that every entry in the RET is 0 which means that the DRHD will +// not allow any DMA requests for PCI bus 0-255 (Sec 3.3.2, IVTD Spec. v1.2) +// we zero out the CET just for sanity +static void _vtd_setupRETCET_bootstrap(uintptr_t vtd_ret_paddr, uintptr_t vtd_ret_vaddr, uintptr_t vtd_cet_paddr, uintptr_t vtd_cet_vaddr) +{ + // sanity check that RET and CET are page-aligned + HALT_ON_ERRORCOND(!(vtd_ret_paddr & 0x00000FFFUL) && !(vtd_cet_paddr & 0x00000FFFUL)); + + // zero out CET, we dont require it for bootstrapping + memset((void *)vtd_cet_vaddr, 0, PAGE_SIZE_4K); + + // zero out RET, effectively preventing DMA reads and writes in the system + memset((void *)vtd_ret_vaddr, 0, PAGE_SIZE_4K); +} + +// initialize VMX EAP a.k.a VT-d +// returns 1 if all went well, else 0 +// if input parameter bootstrap is 1 then we perform minimal translation +// structure initialization, else we do the full DMA translation structure +// initialization at a page-granularity +static u32 vmx_eap_initialize_early( + spa_t vtd_pml4t_paddr, hva_t vtd_pml4t_vaddr, + spa_t vtd_pdpt_paddr, hva_t vtd_pdpt_vaddr, + spa_t vtd_pdts_paddr, hva_t vtd_pdts_vaddr, + spa_t vtd_pts_paddr, hva_t vtd_pts_vaddr, + spa_t vtd_ret_paddr, hva_t vtd_ret_vaddr, + spa_t vtd_cet_paddr, hva_t vtd_cet_vaddr) +{ + ACPI_RSDP rsdp; + ACPI_RSDT rsdt; + u32 num_rsdtentries; + uintptr_t rsdtentries[ACPI_MAX_RSDT_ENTRIES]; + uintptr_t status; + bool status2 = false; + VTD_DMAR dmar; + u32 i, dmarfound; + spa_t dmaraddrphys, remappingstructuresaddrphys; + spa_t rsdt_xsdt_spaddr = INVALID_SPADDR; + hva_t rsdt_xsdt_vaddr = INVALID_VADDR; + + (void)vtd_pml4t_paddr;(void)vtd_pml4t_vaddr;(void)vtd_pdpt_paddr;(void)vtd_pdpt_vaddr; + (void)vtd_pdts_paddr;(void)vtd_pdts_vaddr;(void)vtd_pts_paddr;(void)vtd_pts_vaddr; + +#ifndef __XMHF_VERIFICATION__ + // zero out rsdp and rsdt structures + memset(&rsdp, 0, sizeof(ACPI_RSDP)); + memset(&rsdt, 0, sizeof(ACPI_RSDT)); + memset(&g_vtd_cap, 0, sizeof(struct dmap_vmx_cap)); + + // get ACPI RSDP + // [TODO] Unify the name of and , and then remove the following #ifdef + status = xmhf_baseplatform_arch_x86_acpi_getRSDP(&rsdp); + HALT_ON_ERRORCOND(status != 0); // we need a valid RSDP to proceed + printf("\n%s: RSDP at %08x", __FUNCTION__, status); + + // [Superymk] Use RSDT if it is ACPI v1, or use XSDT addr if it is ACPI v2 + if (rsdp.revision == 0) // ACPI v1 + { + printf("\n%s: ACPI v1", __FUNCTION__); + rsdt_xsdt_spaddr = rsdp.rsdtaddress; + } + else if (rsdp.revision == 0x2) // ACPI v2 + { + printf("\n%s: ACPI v2", __FUNCTION__); + rsdt_xsdt_spaddr = (spa_t)rsdp.xsdtaddress; + } + else // Unrecognized ACPI version + { + printf("\n%s: ACPI unsupported version!", __FUNCTION__); + return 0; + } + + // grab ACPI RSDT + // Note: in i386, should be in lower 4GB. So the conversion to vaddr is fine. + rsdt_xsdt_vaddr = (hva_t)rsdt_xsdt_spaddr; + + xmhf_baseplatform_arch_flat_copy((u8 *)&rsdt, (u8 *)rsdt_xsdt_vaddr, sizeof(ACPI_RSDT)); + printf("\n%s: RSDT at %08x, len=%u bytes, hdrlen=%u bytes", + __FUNCTION__, rsdt_xsdt_vaddr, rsdt.length, sizeof(ACPI_RSDT)); + + // get the RSDT entry list + num_rsdtentries = (rsdt.length - sizeof(ACPI_RSDT)) / sizeof(u32); + HALT_ON_ERRORCOND(num_rsdtentries < ACPI_MAX_RSDT_ENTRIES); + xmhf_baseplatform_arch_flat_copy((u8 *)&rsdtentries, (u8 *)(rsdt_xsdt_vaddr + sizeof(ACPI_RSDT)), + sizeof(rsdtentries[0]) * num_rsdtentries); + printf("\n%s: RSDT entry list at %08x, len=%u", __FUNCTION__, + (rsdt_xsdt_vaddr + sizeof(ACPI_RSDT)), num_rsdtentries); + + // find the VT-d DMAR table in the list (if any) + for (i = 0; i < num_rsdtentries; i++) + { + xmhf_baseplatform_arch_flat_copy((u8 *)&dmar, (u8 *)rsdtentries[i], sizeof(VTD_DMAR)); + if (dmar.signature == VTD_DMAR_SIGNATURE) + { + dmarfound = 1; + break; + } + } + + // if no DMAR table, bail out + if (!dmarfound) + return 0; + + dmaraddrphys = rsdtentries[i]; // DMAR table physical memory address; + printf("\n%s: DMAR at %08x", __FUNCTION__, dmaraddrphys); + + i = 0; + remappingstructuresaddrphys = dmaraddrphys + sizeof(VTD_DMAR); + printf("\n%s: remapping structures at %08x", __FUNCTION__, remappingstructuresaddrphys); + + while (i < (dmar.length - sizeof(VTD_DMAR))) + { + u16 type, length; + hva_t remappingstructures_vaddr = (hva_t)remappingstructuresaddrphys; + + xmhf_baseplatform_arch_flat_copy((u8 *)&type, (u8 *)(remappingstructures_vaddr + i), sizeof(u16)); + xmhf_baseplatform_arch_flat_copy((u8 *)&length, (u8 *)(remappingstructures_vaddr + i + sizeof(u16)), sizeof(u16)); + + switch (type) + { + case 0: // DRHD + printf("\nDRHD at %08x, len=%u bytes", (u32)(remappingstructures_vaddr + i), length); + HALT_ON_ERRORCOND(vtd_num_drhd < VTD_MAX_DRHD); + xmhf_baseplatform_arch_flat_copy((u8 *)&vtd_drhd[vtd_num_drhd], (u8 *)(remappingstructures_vaddr + i), length); + vtd_num_drhd++; + i += (u32)length; + break; + + default: // unknown type, we skip this + i += (u32)length; + break; + } + } + + printf("\n%s: total DRHDs detected= %u units", __FUNCTION__, vtd_num_drhd); + + // be a little verbose about what we found + printf("\n%s: DMAR Devices:", __FUNCTION__); + for (i = 0; i < vtd_num_drhd; i++) + { + VTD_CAP_REG cap; + VTD_ECAP_REG ecap; + printf("\n Device %u on PCI seg %04x; base=0x%016llx", i, + vtd_drhd[i].pcisegment, vtd_drhd[i].regbaseaddr); + _vtd_reg(&vtd_drhd[i], VTD_REG_READ, VTD_CAP_REG_OFF, (void *)&cap.value); + printf("\n cap=0x%016llx", (u64)cap.value); + _vtd_reg(&vtd_drhd[i], VTD_REG_READ, VTD_ECAP_REG_OFF, (void *)&ecap.value); + printf("\n ecap=0x%016llx", (u64)ecap.value); + } + + // Verify VT-d capabilities + status2 = _vtd_verify_cap(vtd_drhd, vtd_num_drhd, &g_vtd_cap); + if (!status2) + { + printf("\n%s: verify VT-d units' capabilities error! Halting!", __FUNCTION__); + HALT(); + } + + // initialize VT-d RET and CET using empty RET and CET, so no DMA is allowed + _vtd_setupRETCET_bootstrap(vtd_ret_paddr, vtd_ret_vaddr, vtd_cet_paddr, vtd_cet_vaddr); + printf("\n%s: setup VT-d RET (%08x) and CET (%08x) for bootstrap.", __FUNCTION__, vtd_ret_paddr, vtd_cet_paddr); + +#endif //__XMHF_VERIFICATION__ + +#ifndef __XMHF_VERIFICATION__ + // initialize all DRHD units + for (i = 0; i < vtd_num_drhd; i++) + { + printf("\n%s: initializing DRHD unit %u...", __FUNCTION__, i); + _vtd_drhd_initialize(&vtd_drhd[i], vtd_ret_paddr); + } +#else + printf("\n%s: initializing DRHD unit %u...", __FUNCTION__, i); + _vtd_drhd_initialize(&vtd_drhd[0], vtd_ret_paddr); +#endif + + // success + printf("\n%s: success, leaving...", __FUNCTION__); + + return 1; +} + +//////////////////////////////////////////////////////////////////////// +// GLOBALS + +//"early" DMA protection initialization to setup minimal +// structures to protect a range of physical memory +// return 1 on success 0 on failure +u32 xmhf_dmaprot_arch_x86_vmx_earlyinitialize(sla_t protectedbuffer_paddr, sla_t protectedbuffer_vaddr, size_t protectedbuffer_size, sla_t __attribute__((unused)) memregionbase_paddr, u32 __attribute__((unused)) memregion) +{ + u32 vmx_eap_vtd_ret_paddr, vmx_eap_vtd_ret_vaddr, vmx_eap_vtd_cet_paddr, vmx_eap_vtd_cet_vaddr; + + //(void)memregionbase_paddr; + //(void)memregion_size; + + printf("\nSL: Bootstrapping VMX DMA protection..."); + + // we use 2 pages for Vt-d bootstrapping + HALT_ON_ERRORCOND(protectedbuffer_size >= (2 * PAGE_SIZE_4K)); + + vmx_eap_vtd_ret_paddr = protectedbuffer_paddr; + vmx_eap_vtd_ret_vaddr = protectedbuffer_vaddr; + vmx_eap_vtd_cet_paddr = protectedbuffer_paddr + PAGE_SIZE_4K; + vmx_eap_vtd_cet_vaddr = protectedbuffer_vaddr + PAGE_SIZE_4K; + + return vmx_eap_initialize_early(0, 0, 0, 0, 0, 0, 0, 0, + vmx_eap_vtd_ret_paddr, vmx_eap_vtd_ret_vaddr, vmx_eap_vtd_cet_paddr, vmx_eap_vtd_cet_vaddr); +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/vmx/dmap-vmx-internal.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/vmx/dmap-vmx-internal.c new file mode 100644 index 0000000000..bd29bd14c7 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/vmx/dmap-vmx-internal.c @@ -0,0 +1,500 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF DMA protection component implementation for x86 VMX +// author: amit vasudevan (amitvasudevan@acm.org) + +#include +#include "dmap-vmx-internal.h" + +struct dmap_vmx_cap g_vtd_cap; + +//------------------------------------------------------------------------------ +// vt-d register access function +void _vtd_reg(VTD_DRHD *dmardevice, u32 access, u32 reg, void *value) +{ + u32 regtype = VTD_REG_32BITS, regaddr = 0; + + // obtain register type and base address + switch (reg) + { + // 32-bit registers + case VTD_VER_REG_OFF: + case VTD_GCMD_REG_OFF: + case VTD_GSTS_REG_OFF: + case VTD_FSTS_REG_OFF: + case VTD_FECTL_REG_OFF: + case VTD_PMEN_REG_OFF: + regtype = VTD_REG_32BITS; + regaddr = dmardevice->regbaseaddr + reg; + break; + + // 64-bit registers + case VTD_CAP_REG_OFF: + case VTD_ECAP_REG_OFF: + case VTD_RTADDR_REG_OFF: + case VTD_CCMD_REG_OFF: + regtype = VTD_REG_64BITS; + regaddr = dmardevice->regbaseaddr + reg; + break; + + case VTD_IOTLB_REG_OFF: + { + VTD_ECAP_REG t_vtd_ecap_reg; + regtype = VTD_REG_64BITS; +#ifndef __XMHF_VERIFICATION__ + _vtd_reg(dmardevice, VTD_REG_READ, VTD_ECAP_REG_OFF, (void *)&t_vtd_ecap_reg.value); +#endif + regaddr = dmardevice->regbaseaddr + (t_vtd_ecap_reg.bits.iro * 16) + 0x8; + break; + } + + case VTD_IVA_REG_OFF: + { + VTD_ECAP_REG t_vtd_ecap_reg; + regtype = VTD_REG_64BITS; +#ifndef __XMHF_VERIFICATION__ + _vtd_reg(dmardevice, VTD_REG_READ, VTD_ECAP_REG_OFF, (void *)&t_vtd_ecap_reg.value); +#endif + regaddr = dmardevice->regbaseaddr + (t_vtd_ecap_reg.bits.iro * 16); + break; + } + + default: + printf("\n%s: Halt, Unsupported register=%08x", __FUNCTION__, reg); + HALT(); + break; + } + + // perform the actual read or write request + switch (regtype) + { + case VTD_REG_32BITS: + { // 32-bit r/w + if (access == VTD_REG_READ) + *((u32 *)value) = xmhf_baseplatform_arch_flat_readu32(regaddr); + else + xmhf_baseplatform_arch_flat_writeu32(regaddr, *((u32 *)value)); + + break; + } + + case VTD_REG_64BITS: + { // 64-bit r/w + if (access == VTD_REG_READ) + *((u64 *)value) = xmhf_baseplatform_arch_flat_readu64(regaddr); + else + xmhf_baseplatform_arch_flat_writeu64(regaddr, *((u64 *)value)); + + break; + } + + default: + printf("\n%s: Halt, Unsupported access width=%08x", __FUNCTION__, regtype); + HALT(); + } + + return; +} + +// Return true if verification of VT-d capabilities succeed. +// Success means: +// (0) must be valid +// (1) Same AGAW, MGAW, and ND across VT-d units +// (2) supported MGAW to ensure our host address width is supported (32-bits) +// (3) AGAW must support 39-bits or 48-bits +// (4) Number of domains must not be unsupported +bool _vtd_verify_cap(VTD_DRHD* vtd_drhd, u32 vtd_num_drhd, struct dmap_vmx_cap *out_cap) +{ +#define INVALID_SAGAW_VAL 0xFFFFFFFF +#define INVALID_MGAW_VAL 0xFFFFFFFF +#define INVALID_NUM_DOMAINS 0xFFFFFFFF + + VTD_CAP_REG cap; + u32 i = 0; + u32 last_sagaw = INVALID_SAGAW_VAL; + u32 last_mgaw = INVALID_MGAW_VAL; + u32 last_nd = INVALID_NUM_DOMAINS; + + // Sanity checks + if (!out_cap) + return false; + + if(!vtd_drhd) + return false; + + if(!vtd_num_drhd || vtd_num_drhd >= VTD_MAX_DRHD) // Support maximum of VTD_MAX_DRHD VT-d units + return false; + + for (i = 0; i < vtd_num_drhd; i++) + { + VTD_DRHD *drhd = &vtd_drhd[i]; + printf("\n%s: verifying DRHD unit %u...", __FUNCTION__, i); + + // read CAP register + _vtd_reg(drhd, VTD_REG_READ, VTD_CAP_REG_OFF, (void *)&cap.value); + + // Check: Same AGAW, MGAW and ND across VT-d units + if (cap.bits.sagaw != last_sagaw) + { + if (last_sagaw == INVALID_SAGAW_VAL) + { + // This must the first VT-d unit + last_sagaw = cap.bits.sagaw; + } + else + { + // The current VT-d unit has different capabilities with some other units + printf("\n [VT-d] Check error! Different SAGAW capability found on VT-d unix %u. last sagaw:0x%08X, current sagaw:0x%08X", + i, last_sagaw, cap.bits.sagaw); + return false; + } + } + + if (cap.bits.mgaw != last_mgaw) + { + if (last_mgaw == INVALID_MGAW_VAL) + { + // This must the first VT-d unit + last_mgaw = cap.bits.mgaw; + } + else + { + // The current VT-d unit has different capabilities with some other units + printf("\n [VT-d] Check error! Different MGAW capability found on VT-d unix %u. last mgaw:0x%08X, current mgaw:0x%08X", + i, last_mgaw, cap.bits.mgaw); + return false; + } + } + + if (cap.bits.nd != last_nd) + { + if (last_nd == INVALID_NUM_DOMAINS) + { + // This must the first VT-d unit + last_nd = cap.bits.nd; + } + else + { + // The current VT-d unit has different capabilities with some other units + printf("\n [VT-d] Check error! Different ND capability found on VT-d unix %u. last nd:0x%08X, current nd:0x%08X", + i, last_nd, cap.bits.nd); + return false; + } + } + + // Check: supported MGAW to ensure our host address width is supported (32-bits) + if (cap.bits.mgaw < 31) + { + printf("\n [VT-d] Check error! GAW < 31 (%u) unsupported.", cap.bits.mgaw); + return false; + } + + // Check: AGAW must support 39-bits or 48-bits + if (!(cap.bits.sagaw & 0x2 || cap.bits.sagaw & 0x4)) + { + printf("\n [VT-d] Check error! AGAW does not support 3-level or 4-level page-table. See sagaw capabilities:0x%08X. Halting!", cap.bits.sagaw); + return false; + } + else + { + out_cap->sagaw = cap.bits.sagaw; + } + + // Check: Number of domains must not be unsupported + if (cap.bits.nd == 0x7) + { + printf("\n [VT-d] Check error! ND == 0x7 unsupported on VT-d unix %u.", i); + return false; + } + else + { + out_cap->nd = cap.bits.nd; + } + } + + printf("\nVerify all Vt-d units success"); + + return true; +} + +//------------------------------------------------------------------------------ +// initialize a DRHD unit +// note that the VT-d documentation does not describe the precise sequence of +// steps that need to be followed to initialize a DRHD unit!. we use our +// common sense instead...:p +void _vtd_drhd_initialize(VTD_DRHD *drhd, u32 vtd_ret_paddr) +{ + VTD_GCMD_REG gcmd; + VTD_GSTS_REG gsts; + VTD_FECTL_REG fectl; + VTD_CAP_REG cap; + VTD_RTADDR_REG rtaddr; + VTD_CCMD_REG ccmd; + VTD_IOTLB_REG iotlb; + + // sanity check + HALT_ON_ERRORCOND(drhd != NULL); + + // check VT-d snoop control capabilities + { + VTD_ECAP_REG ecap; + // read ECAP register + _vtd_reg(drhd, VTD_REG_READ, VTD_ECAP_REG_OFF, (void *)&ecap.value); + + if (ecap.bits.sc) + printf("\n VT-d hardware Snoop Control (SC) capabilities present"); + else + printf("\n VT-d hardware Snoop Control (SC) unavailable"); + + if (ecap.bits.c) + printf("\n VT-d hardware access to remapping structures COHERENT"); + else + printf("\n VT-d hardware access to remapping structures NON-COHERENT"); + } + + // 3. setup fault logging + printf("\n Setting Fault-reporting to NON-INTERRUPT mode..."); + { + // read FECTL + fectl.value = 0; + _vtd_reg(drhd, VTD_REG_READ, VTD_FECTL_REG_OFF, (void *)&fectl.value); + + // set interrupt mask bit and write + fectl.bits.im = 1; + _vtd_reg(drhd, VTD_REG_WRITE, VTD_FECTL_REG_OFF, (void *)&fectl.value); + + // check to see if the im bit actually stuck + _vtd_reg(drhd, VTD_REG_READ, VTD_FECTL_REG_OFF, (void *)&fectl.value); + + if (!fectl.bits.im) + { + printf("\n Failed to set fault-reporting. Halting!"); + HALT(); + } + } + printf("Done."); + + // 4. setup RET (root-entry) + printf("\n Setting up RET..."); + { + // setup RTADDR with base of RET + rtaddr.value = (u64)vtd_ret_paddr; + _vtd_reg(drhd, VTD_REG_WRITE, VTD_RTADDR_REG_OFF, (void *)&rtaddr.value); + + // read RTADDR and verify the base address + rtaddr.value = 0; + _vtd_reg(drhd, VTD_REG_READ, VTD_RTADDR_REG_OFF, (void *)&rtaddr.value); + if (rtaddr.value != (u64)vtd_ret_paddr) + { + printf("\n Failed to set RTADDR. Halting!"); + HALT(); + } + + // latch RET address by using GCMD.SRTP + gcmd.value = 0; + gcmd.bits.srtp = 1; + _vtd_reg(drhd, VTD_REG_WRITE, VTD_GCMD_REG_OFF, (void *)&gcmd.value); + + // ensure the RET address was latched by the h/w + _vtd_reg(drhd, VTD_REG_READ, VTD_GSTS_REG_OFF, (void *)&gsts.value); + + if (!gsts.bits.rtps) + { + printf("\n Failed to latch RTADDR. Halting!"); + HALT(); + } + } + printf("Done."); + + // 5. invalidate CET cache + printf("\n Invalidating CET cache..."); + { + // wait for context cache invalidation request to send +#ifndef __XMHF_VERIFICATION__ + do + { + _vtd_reg(drhd, VTD_REG_READ, VTD_CCMD_REG_OFF, (void *)&ccmd.value); + } while (ccmd.bits.icc); +#endif + + // initialize CCMD to perform a global invalidation + ccmd.value = 0; + ccmd.bits.cirg = 1; // global invalidation + ccmd.bits.icc = 1; // invalidate context cache + + // perform the invalidation + _vtd_reg(drhd, VTD_REG_WRITE, VTD_CCMD_REG_OFF, (void *)&ccmd.value); + + // wait for context cache invalidation completion status +#ifndef __XMHF_VERIFICATION__ + do + { + _vtd_reg(drhd, VTD_REG_READ, VTD_CCMD_REG_OFF, (void *)&ccmd.value); + } while (ccmd.bits.icc); +#endif + + // if all went well CCMD CAIG = CCMD CIRG (i.e., actual = requested invalidation granularity) + if (ccmd.bits.caig != 0x1) + { + printf("\n Invalidatation of CET failed. Halting! (%u)", ccmd.bits.caig); + HALT(); + } + } + printf("Done."); + + // 6. invalidate IOTLB + printf("\n Invalidating IOTLB..."); + { + // initialize IOTLB to perform a global invalidation + iotlb.value = 0; + iotlb.bits.iirg = 1; // global invalidation + iotlb.bits.ivt = 1; // invalidate + + // perform the invalidation + _vtd_reg(drhd, VTD_REG_WRITE, VTD_IOTLB_REG_OFF, (void *)&iotlb.value); + +#ifndef __XMHF_VERIFICATION__ + // wait for the invalidation to complete + do + { + _vtd_reg(drhd, VTD_REG_READ, VTD_IOTLB_REG_OFF, (void *)&iotlb.value); + } while (iotlb.bits.ivt); +#endif + + // if all went well IOTLB IAIG = IOTLB IIRG (i.e., actual = requested invalidation granularity) + if (iotlb.bits.iaig != 0x1) + { + printf("\n Invalidation of IOTLB failed. Halting! (%u)", iotlb.bits.iaig); + HALT(); + } + } + printf("Done."); + + // 7. disable options we dont support + printf("\n Disabling unsupported options..."); + { + // disable advanced fault logging (AFL) + gcmd.value = 0; + gcmd.bits.eafl = 0; + _vtd_reg(drhd, VTD_REG_WRITE, VTD_GCMD_REG_OFF, (void *)&gcmd.value); + _vtd_reg(drhd, VTD_REG_WRITE, VTD_GSTS_REG_OFF, (void *)&gsts.value); + if (gsts.bits.afls) + { + printf("\n Could not disable AFL. Halting!"); + HALT(); + } + + // disabled queued invalidation (QI) + gcmd.value = 0; + gcmd.bits.qie = 0; + _vtd_reg(drhd, VTD_REG_WRITE, VTD_GCMD_REG_OFF, (void *)&gcmd.value); + _vtd_reg(drhd, VTD_REG_WRITE, VTD_GSTS_REG_OFF, (void *)&gsts.value); + if (gsts.bits.qies) + { + printf("\n Could not disable QI. Halting!"); + HALT(); + } + + // disable interrupt remapping (IR) + gcmd.value = 0; + gcmd.bits.ire = 0; + _vtd_reg(drhd, VTD_REG_WRITE, VTD_GCMD_REG_OFF, (void *)&gcmd.value); + _vtd_reg(drhd, VTD_REG_WRITE, VTD_GSTS_REG_OFF, (void *)&gsts.value); + if (gsts.bits.ires) + { + printf("\n Could not disable IR. Halting!"); + HALT(); + } + } + printf("Done."); + + // 8. enable device + printf("\n Enabling device..."); + { + // enable translation + gcmd.value = 0; + gcmd.bits.te = 1; +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + assert(gcmd.bits.te == 1); +#endif + + _vtd_reg(drhd, VTD_REG_WRITE, VTD_GCMD_REG_OFF, (void *)&gcmd.value); + + // wait for translation enabled status to go green... + _vtd_reg(drhd, VTD_REG_READ, VTD_GSTS_REG_OFF, (void *)&gsts.value); +#ifndef __XMHF_VERIFICATION__ + while (!gsts.bits.tes) + { + _vtd_reg(drhd, VTD_REG_READ, VTD_GSTS_REG_OFF, (void *)&gsts.value); + } +#endif + } + printf("Done."); + + // 9. disable protected memory regions (PMR) if available + printf("\n Checking and disabling PMR..."); + { + VTD_PMEN_REG pmen; + _vtd_reg(drhd, VTD_REG_READ, VTD_CAP_REG_OFF, (void *)&cap.value); + + // PMR caps present, so disable it as we dont support that + if (cap.bits.plmr || cap.bits.phmr) + { + _vtd_reg(drhd, VTD_REG_READ, VTD_PMEN_REG_OFF, (void *)&pmen.value); + pmen.bits.epm = 0; // disable PMR + _vtd_reg(drhd, VTD_REG_WRITE, VTD_PMEN_REG_OFF, (void *)&pmen.value); +#ifndef __XMHF_VERIFICATION__ + // wait for PMR disabled... + do + { + _vtd_reg(drhd, VTD_REG_READ, VTD_PMEN_REG_OFF, (void *)&pmen.value); + } while (pmen.bits.prs); +#endif + } + } + printf("Done."); +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/vmx/dmap-vmx-internal.h b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/vmx/dmap-vmx-internal.h new file mode 100644 index 0000000000..721b63c256 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/vmx/dmap-vmx-internal.h @@ -0,0 +1,21 @@ +#include + +extern struct dmap_vmx_cap g_vtd_cap; + +//vt-d register access function +extern void _vtd_reg(VTD_DRHD *dmardevice, u32 access, u32 reg, void *value); + +// Return true if verification of VT-d capabilities succeed. +// Success means: +// (0) must be valid +// (1) Same AGAW, MGAW, and ND across VT-d units +// (2) supported MGAW to ensure our host address width is supported (32-bits) +// (3) AGAW must support 39-bits or 48-bits +// (4) Number of domains must not be unsupported +extern bool _vtd_verify_cap(VTD_DRHD* vtd_drhd, u32 vtd_num_drhd, struct dmap_vmx_cap* out_cap); + +//initialize a DRHD unit +//note that the VT-d documentation does not describe the precise sequence of +//steps that need to be followed to initialize a DRHD unit!. we use our +//common sense instead...:p +extern void _vtd_drhd_initialize(VTD_DRHD *drhd, u32 vtd_ret_paddr); diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/vmx/dmap-vmx-runtime.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/vmx/dmap-vmx-runtime.c new file mode 100644 index 0000000000..4430109ce8 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/vmx/dmap-vmx-runtime.c @@ -0,0 +1,640 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF DMA protection component implementation for x86 VMX +// author: amit vasudevan (amitvasudevan@acm.org) + +#include +#include "dmap-vmx-internal.h" + +void *vtd_cet = NULL; // cet holds all its structures in the memory linearly + +//============================================================================== +// local (static) variables and function definitions +//============================================================================== + +// DMA Remapping Hardware Unit Definitions +static VTD_DRHD vtd_drhd[VTD_MAX_DRHD]; +static u32 vtd_num_drhd = 0; // total number of DMAR h/w units + +// VT-d 3-level/4-level DMA protection page table data structure addresses +static spa_t l_vtd_pml4t_paddr = 0; +static hva_t l_vtd_pml4t_vaddr = 0; +static spa_t l_vtd_pdpt_paddr = 0; +static hva_t l_vtd_pdpt_vaddr = 0; +static spa_t l_vtd_pdts_paddr = 0; +static hva_t l_vtd_pdts_vaddr = 0; +static spa_t l_vtd_pts_paddr = 0; +static hva_t l_vtd_pts_vaddr = 0; + +//------------------------------------------------------------------------------ +// setup VT-d DMA protection page tables +static bool _vtd_setuppagetables(struct dmap_vmx_cap *vtd_cap, + spa_t vtd_pml4t_paddr, hva_t vtd_pml4t_vaddr, + spa_t vtd_pdpt_paddr, hva_t vtd_pdpt_vaddr, + spa_t vtd_pdts_paddr, hva_t vtd_pdts_vaddr, + spa_t vtd_pts_paddr, hva_t vtd_pts_vaddr, + spa_t machine_low_spa, spa_t machine_high_spa) +{ + spa_t pml4tphysaddr, pdptphysaddr, pdtphysaddr, ptphysaddr; + u32 i, j, k; + pml4t_t pml4t; + pdpt_t pdpt; + pdt_t pdt; + pt_t pt; + uintptr_t physaddr = 0; + spa_t m_low_spa = PA_PAGE_ALIGN_1G(machine_low_spa); + spa_t m_high_spa = PA_PAGE_ALIGN_UP_1G(machine_high_spa); + u32 num_1G_entries = (m_high_spa - (u64)m_low_spa) >> PAGE_SHIFT_1G; + + // Sanity checks + if (!vtd_cap) + return false; + + pml4tphysaddr = vtd_pml4t_paddr; + pdptphysaddr = vtd_pdpt_paddr; + pdtphysaddr = vtd_pdts_paddr; + ptphysaddr = vtd_pts_paddr; + + // ensure PDPT, PDTs and PTs are all page-aligned + HALT_ON_ERRORCOND(!(pml4tphysaddr & 0x00000FFFUL) && !(pdptphysaddr & 0x00000FFFUL) && !(pdtphysaddr & 0x00000FFFUL) && !((ptphysaddr & 0x00000FFFUL))); + + // initialize our local variables + l_vtd_pml4t_paddr = vtd_pml4t_paddr; + l_vtd_pml4t_vaddr = vtd_pml4t_vaddr; + l_vtd_pdpt_paddr = vtd_pdpt_paddr; + l_vtd_pdpt_vaddr = vtd_pdpt_vaddr; + l_vtd_pdts_paddr = vtd_pdts_paddr; + l_vtd_pdts_vaddr = vtd_pdts_vaddr; + l_vtd_pts_paddr = vtd_pts_paddr; + l_vtd_pts_vaddr = vtd_pts_vaddr; + + // setup pml4t + // The VT-d page table created here is a partial one. If 4-level PT is used, then there is only one PML4 entry instead + // of 512 entries. This is sufficient because the lower 3-level PT covers 0 - 512GB physical memory space + pml4t = (pml4t_t)vtd_pml4t_vaddr; + pml4t[0] = (u64)(pdptphysaddr + (0 * PAGE_SIZE_4K)); + pml4t[0] |= ((u64)VTD_READ | (u64)VTD_WRITE); + + // setup pdpt, pdt and pt + // initially set the entire spaddr space [m_low_spa, m_high_spa) as DMA read/write capable + pdpt = (pdpt_t)vtd_pdpt_vaddr; + + for (i = 0; i < num_1G_entries; i++) // DMAPROT_VMX_P4L_NPDT + { + pdpt[i] = (u64)(pdtphysaddr + (i * PAGE_SIZE_4K)); + pdpt[i] |= ((u64)VTD_READ | (u64)VTD_WRITE); + + pdt = (pdt_t)(vtd_pdts_vaddr + (i * PAGE_SIZE_4K)); + for (j = 0; j < PAE_PTRS_PER_PDT; j++) + { + pdt[j] = (u64)(ptphysaddr + (i * PAGE_SIZE_4K * PAE_PTRS_PER_PDT) + (j * PAGE_SIZE_4K)); + pdt[j] |= ((u64)VTD_READ | (u64)VTD_WRITE); + + pt = (pt_t)(vtd_pts_vaddr + (i * PAGE_SIZE_4K * PAE_PTRS_PER_PDT) + (j * PAGE_SIZE_4K)); + for (k = 0; k < PAE_PTRS_PER_PT; k++) + { + pt[k] = (u64)physaddr; + pt[k] |= ((u64)VTD_READ | (u64)VTD_WRITE); + physaddr += PAGE_SIZE_4K; + } + } + } + + return true; +} + +//------------------------------------------------------------------------------ +// set VT-d RET and CET tables +// we have 1 root entry table (RET) of 4kb, each root entry (RE) is 128-bits +// which gives us 256 entries in the RET, each corresponding to a PCI bus num. +//(0-255) +// each RE points to a context entry table (CET) of 4kb, each context entry (CE) +// is 128-bits which gives us 256 entries in the CET, accounting for 32 devices +// with 8 functions each as per the PCI spec. +// each CE points to a PDPT type paging structure. +// in our implementation, every CE will point to a single PDPT type paging +// structure for the whole system +static bool _vtd_setupRETCET(struct dmap_vmx_cap *vtd_cap, + uintptr_t vtd_pml4t_paddr, uintptr_t vtd_pdpt_paddr, + uintptr_t vtd_ret_paddr, uintptr_t vtd_ret_vaddr, + uintptr_t vtd_cet_paddr, uintptr_t vtd_cet_vaddr) +{ + uintptr_t retphysaddr, cetphysaddr; + u32 i, j; + u64 *value; + + // Sanity checks + if (!vtd_cap) + return false; + + retphysaddr = vtd_ret_paddr; + (void)retphysaddr; + cetphysaddr = vtd_cet_paddr; + + // sanity check that pdpt base address is page-aligned + HALT_ON_ERRORCOND(!(vtd_pdpt_paddr & 0x00000FFFUL)); + + // initialize RET + for (i = 0; i < PCI_BUS_MAX; i++) + { + value = (u64 *)(vtd_ret_vaddr + (i * 16)); + *(value + 1) = (u64)0x0ULL; + *value = (u64)(cetphysaddr + (i * PAGE_SIZE_4K)); + + // sanity check that CET is page aligned + HALT_ON_ERRORCOND(!(*value & 0x0000000000000FFFULL)); + + // set it to present + *value |= 0x1ULL; + } + + // initialize CET + for (i = 0; i < PCI_BUS_MAX; i++) + { + for (j = 0; j < PCI_BUS_MAX; j++) + { + value = (u64 *)(vtd_cet_vaddr + (i * PAGE_SIZE_4K) + (j * 16)); + + if (vtd_cap->sagaw & 0x4) + { + // Preferred to use 4-level PT + *(value + 1) = (u64)0x0000000000000102ULL; // domain:1, aw=48 bits, 4 level pt + *value = vtd_pml4t_paddr; + } + else if (vtd_cap->sagaw & 0x2) + { + // If no 4-level PT, then try 3-level PT + *(value + 1) = (u64)0x0000000000000101ULL; // domain:1, aw=39 bits, 3 level pt + *value = vtd_pdpt_paddr; + } + else + { + // Unsupported IOMMU + return false; + } + + *value |= 0x1ULL; // present, enable fault recording/processing, multilevel pt translation + } + } + + return true; +} + +// initialize VMX EAP a.k.a VT-d +// returns 1 if all went well, else 0 +// if input parameter bootstrap is 1 then we perform minimal translation +// structure initialization, else we do the full DMA translation structure +// initialization at a page-granularity +static u32 vmx_eap_initialize( + spa_t vtd_pml4t_paddr, hva_t vtd_pml4t_vaddr, + spa_t vtd_pdpt_paddr, hva_t vtd_pdpt_vaddr, + spa_t vtd_pdts_paddr, hva_t vtd_pdts_vaddr, + spa_t vtd_pts_paddr, hva_t vtd_pts_vaddr, + spa_t vtd_ret_paddr, hva_t vtd_ret_vaddr, + spa_t vtd_cet_paddr, hva_t vtd_cet_vaddr) +{ + ACPI_RSDP rsdp; + ACPI_RSDT rsdt; + u32 num_rsdtentries; + uintptr_t rsdtentries[ACPI_MAX_RSDT_ENTRIES]; + uintptr_t status; + bool status2 = false; + VTD_DMAR dmar; + u32 i, dmarfound; + spa_t dmaraddrphys, remappingstructuresaddrphys; + spa_t rsdt_xsdt_spaddr = INVALID_SPADDR; + hva_t rsdt_xsdt_vaddr = INVALID_VADDR; + +#ifndef __XMHF_VERIFICATION__ + // zero out rsdp and rsdt structures + memset(&rsdp, 0, sizeof(ACPI_RSDP)); + memset(&rsdt, 0, sizeof(ACPI_RSDT)); + memset(&g_vtd_cap, 0, sizeof(struct dmap_vmx_cap)); + + // get ACPI RSDP + // [TODO] Unify the name of and , and then remove the following #ifdef + status = xmhf_baseplatform_arch_x86_acpi_getRSDP(&rsdp); + HALT_ON_ERRORCOND(status != 0); // we need a valid RSDP to proceed + printf("\n%s: RSDP at %08x", __FUNCTION__, status); + + // [Superymk] Use RSDT if it is ACPI v1, or use XSDT addr if it is ACPI v2 + if (rsdp.revision == 0) // ACPI v1 + { + printf("\n%s: ACPI v1", __FUNCTION__); + rsdt_xsdt_spaddr = rsdp.rsdtaddress; + } + else if (rsdp.revision == 0x2) // ACPI v2 + { + printf("\n%s: ACPI v2", __FUNCTION__); + rsdt_xsdt_spaddr = (spa_t)rsdp.xsdtaddress; + } + else // Unrecognized ACPI version + { + printf("\n%s: ACPI unsupported version!", __FUNCTION__); + return 0; + } + + // grab ACPI RSDT + // Note: in i386, should be in lower 4GB. So the conversion to vaddr is fine. + rsdt_xsdt_vaddr = (hva_t)rsdt_xsdt_spaddr; + + xmhf_baseplatform_arch_flat_copy((u8 *)&rsdt, (u8 *)rsdt_xsdt_vaddr, sizeof(ACPI_RSDT)); + printf("\n%s: RSDT at %08x, len=%u bytes, hdrlen=%u bytes", + __FUNCTION__, rsdt_xsdt_vaddr, rsdt.length, sizeof(ACPI_RSDT)); + + // get the RSDT entry list + num_rsdtentries = (rsdt.length - sizeof(ACPI_RSDT)) / sizeof(u32); + HALT_ON_ERRORCOND(num_rsdtentries < ACPI_MAX_RSDT_ENTRIES); + xmhf_baseplatform_arch_flat_copy((u8 *)&rsdtentries, (u8 *)(rsdt_xsdt_vaddr + sizeof(ACPI_RSDT)), + sizeof(rsdtentries[0]) * num_rsdtentries); + printf("\n%s: RSDT entry list at %08x, len=%u", __FUNCTION__, + (rsdt_xsdt_vaddr + sizeof(ACPI_RSDT)), num_rsdtentries); + + // find the VT-d DMAR table in the list (if any) + for (i = 0; i < num_rsdtentries; i++) + { + xmhf_baseplatform_arch_flat_copy((u8 *)&dmar, (u8 *)rsdtentries[i], sizeof(VTD_DMAR)); + if (dmar.signature == VTD_DMAR_SIGNATURE) + { + dmarfound = 1; + break; + } + } + + // if no DMAR table, bail out + if (!dmarfound) + return 0; + + dmaraddrphys = rsdtentries[i]; // DMAR table physical memory address; + printf("\n%s: DMAR at %08x", __FUNCTION__, dmaraddrphys); + + i = 0; + remappingstructuresaddrphys = dmaraddrphys + sizeof(VTD_DMAR); + printf("\n%s: remapping structures at %08x", __FUNCTION__, remappingstructuresaddrphys); + + while (i < (dmar.length - sizeof(VTD_DMAR))) + { + u16 type, length; + hva_t remappingstructures_vaddr = (hva_t)remappingstructuresaddrphys; + + xmhf_baseplatform_arch_flat_copy((u8 *)&type, (u8 *)(remappingstructures_vaddr + i), sizeof(u16)); + xmhf_baseplatform_arch_flat_copy((u8 *)&length, (u8 *)(remappingstructures_vaddr + i + sizeof(u16)), sizeof(u16)); + + switch (type) + { + case 0: // DRHD + printf("\nDRHD at %08x, len=%u bytes", (u32)(remappingstructures_vaddr + i), length); + HALT_ON_ERRORCOND(vtd_num_drhd < VTD_MAX_DRHD); + xmhf_baseplatform_arch_flat_copy((u8 *)&vtd_drhd[vtd_num_drhd], (u8 *)(remappingstructures_vaddr + i), length); + vtd_num_drhd++; + i += (u32)length; + break; + + default: // unknown type, we skip this + i += (u32)length; + break; + } + } + + printf("\n%s: total DRHDs detected= %u units", __FUNCTION__, vtd_num_drhd); + + // be a little verbose about what we found + printf("\n%s: DMAR Devices:", __FUNCTION__); + for (i = 0; i < vtd_num_drhd; i++) + { + VTD_CAP_REG cap; + VTD_ECAP_REG ecap; + printf("\n Device %u on PCI seg %04x; base=0x%016llx", i, + vtd_drhd[i].pcisegment, vtd_drhd[i].regbaseaddr); + _vtd_reg(&vtd_drhd[i], VTD_REG_READ, VTD_CAP_REG_OFF, (void *)&cap.value); + printf("\n cap=0x%016llx", (u64)cap.value); + _vtd_reg(&vtd_drhd[i], VTD_REG_READ, VTD_ECAP_REG_OFF, (void *)&ecap.value); + printf("\n ecap=0x%016llx", (u64)ecap.value); + } + + // Verify VT-d capabilities + status2 = _vtd_verify_cap(vtd_drhd, vtd_num_drhd, &g_vtd_cap); + if (!status2) + { + printf("\n%s: verify VT-d units' capabilities error! Halting!", __FUNCTION__); + HALT(); + } + + // initialize VT-d page tables (not done if we are bootstrapping) + { + spa_t machine_low_spa = INVALID_SPADDR; + spa_t machine_high_spa = INVALID_SPADDR; + u64 phy_space_size = 0; + + // Get the base and limit used system physical address from the E820 map + status2 = xmhf_get_machine_paddr_range(&machine_low_spa, &machine_high_spa); + if (!status2) + { + printf("\n%s: Get system physical address range error! Halting!", __FUNCTION__); + HALT(); + } + + // Check: The base and limit of the physical address space must <= DMAPROT_PHY_ADDR_SPACE_SIZE + phy_space_size = machine_high_spa - machine_low_spa; + if(phy_space_size > DMAPROT_PHY_ADDR_SPACE_SIZE) + { + printf("\n%s: Too large system physical address! Found space size:%llX. Halting!", __FUNCTION__, phy_space_size); + HALT(); + } + + status2 = _vtd_setuppagetables(&g_vtd_cap, vtd_pml4t_paddr, vtd_pml4t_vaddr, vtd_pdpt_paddr, vtd_pdpt_vaddr, + vtd_pdts_paddr, vtd_pdts_vaddr, vtd_pts_paddr, vtd_pts_vaddr, machine_low_spa, machine_high_spa); + if (!status2) + { + printf("\n%s: setup VT-d page tables (pdpt=%08x, pdts=%08x, pts=%08x) error! Halting!", __FUNCTION__, vtd_pdpt_paddr, vtd_pdts_paddr, vtd_pts_paddr); + HALT(); + } + + printf("\n%s: setup VT-d page tables (pdpt=%08x, pdts=%08x, pts=%08x).", __FUNCTION__, vtd_pdpt_paddr, vtd_pdts_paddr, vtd_pts_paddr); + } + + // initialize VT-d RET and CET + { + status2 = _vtd_setupRETCET(&g_vtd_cap, vtd_pml4t_paddr, vtd_pdpt_paddr, vtd_ret_paddr, vtd_ret_vaddr, vtd_cet_paddr, vtd_cet_vaddr); + if (!status2) + { + printf("\n%s: setup VT-d RET (%08x) and CET (%08x) error! Halting!", __FUNCTION__, vtd_ret_paddr, vtd_cet_paddr); + HALT(); + } + + printf("\n%s: setup VT-d RET (%08x) and CET (%08x).", __FUNCTION__, vtd_ret_paddr, vtd_cet_paddr); + } + +#endif //__XMHF_VERIFICATION__ + +#ifndef __XMHF_VERIFICATION__ + // initialize all DRHD units + for (i = 0; i < vtd_num_drhd; i++) + { + printf("\n%s: initializing DRHD unit %u...", __FUNCTION__, i); + _vtd_drhd_initialize(&vtd_drhd[i], vtd_ret_paddr); + } +#else + printf("\n%s: initializing DRHD unit %u...", __FUNCTION__, i); + _vtd_drhd_initialize(&vtd_drhd[0], vtd_ret_paddr); +#endif + + // zap VT-d presence in ACPI table... + // TODO: we need to be a little elegant here. eventually need to setup + // EPT/NPTs such that the DMAR pages are unmapped for the guest + xmhf_baseplatform_arch_flat_writeu32(dmaraddrphys, 0UL); + + // success + printf("\n%s: success, leaving...", __FUNCTION__); + + return 1; +} + +//------------------------------------------------------------------------------ +// vt-d invalidate cachess note: we do global invalidation currently +static void _vtd_invalidatecaches(void) +{ + u32 i; + VTD_CCMD_REG ccmd; + VTD_IOTLB_REG iotlb; + +#ifdef __XMHF_VERIFICATION__ + for (i = 0; i < 1; i++) + { +#else + for (i = 0; i < vtd_num_drhd; i++) + { +#endif + // 1. invalidate CET cache + +#ifndef __XMHF_VERIFICATION__ + // wait for context cache invalidation request to send + do + { + _vtd_reg(&vtd_drhd[i], VTD_REG_READ, VTD_CCMD_REG_OFF, (void *)&ccmd.value); + } while (ccmd.bits.icc); +#else + _vtd_reg(&vtd_drhd[0], VTD_REG_READ, VTD_CCMD_REG_OFF, (void *)&ccmd.value); +#endif + + // initialize CCMD to perform a global invalidation + ccmd.value = 0; + ccmd.bits.cirg = 1; // global invalidation + ccmd.bits.icc = 1; // invalidate context cache + + // perform the invalidation + _vtd_reg(&vtd_drhd[i], VTD_REG_WRITE, VTD_CCMD_REG_OFF, (void *)&ccmd.value); + +#ifndef __XMHF_VERIFICATION__ + // wait for context cache invalidation completion status + do + { + _vtd_reg(&vtd_drhd[i], VTD_REG_READ, VTD_CCMD_REG_OFF, (void *)&ccmd.value); + } while (ccmd.bits.icc); +#else + _vtd_reg(&vtd_drhd[0], VTD_REG_READ, VTD_CCMD_REG_OFF, (void *)&ccmd.value); +#endif + + // if all went well CCMD CAIG = CCMD CIRG (i.e., actual = requested invalidation granularity) + if (ccmd.bits.caig != 0x1) + { + printf("\n Invalidatation of CET failed. Halting! (%u)", ccmd.bits.caig); + HALT(); + } + + // 2. invalidate IOTLB + // initialize IOTLB to perform a global invalidation + iotlb.value = 0; + iotlb.bits.iirg = 1; // global invalidation + iotlb.bits.ivt = 1; // invalidate + + // perform the invalidation + _vtd_reg(&vtd_drhd[i], VTD_REG_WRITE, VTD_IOTLB_REG_OFF, (void *)&iotlb.value); + +#ifndef __XMHF_VERIFICATION__ + // wait for the invalidation to complete + do + { + _vtd_reg(&vtd_drhd[i], VTD_REG_READ, VTD_IOTLB_REG_OFF, (void *)&iotlb.value); + } while (iotlb.bits.ivt); +#else + _vtd_reg(&vtd_drhd[0], VTD_REG_READ, VTD_IOTLB_REG_OFF, (void *)&iotlb.value); +#endif + + // if all went well IOTLB IAIG = IOTLB IIRG (i.e., actual = requested invalidation granularity) + if (iotlb.bits.iaig != 0x1) + { + printf("\n Invalidation of IOTLB failed. Halting! (%u)", iotlb.bits.iaig); + HALT(); + } + } +} + +//////////////////////////////////////////////////////////////////////// +// GLOBALS + +#define PAE_get_pdptindex(x) ((x) >> 30) +#define PAE_get_pdtindex(x) (((x) << 2) >> 23) +#define PAE_get_ptindex(x) (((x) << 11) >> 23) +#define PAE_get_pdtaddress(x) ((u32)((u64)(x) & (u64)0x3FFFFFFFFFFFF000ULL)) +#define PAE_get_ptaddress(x) ((u32)((u64)(x) & (u64)0x3FFFFFFFFFFFF000ULL)) + +//"normal" DMA protection initialization to setup required +// structures for DMA protection +// return 1 on success 0 on failure +u32 xmhf_dmaprot_arch_x86_vmx_initialize(spa_t protectedbuffer_paddr, + hva_t protectedbuffer_vaddr, size_t protectedbuffer_size) +{ + // Vt-d bootstrap has minimal DMA translation setup and protects entire + // system memory. Relax this by instantiating a complete DMA translation + // structure at a page granularity and protecting only the SL and Runtime + uintptr_t vmx_eap_vtd_pml4t_paddr, vmx_eap_vtd_pml4t_vaddr; + uintptr_t vmx_eap_vtd_pdpt_paddr, vmx_eap_vtd_pdpt_vaddr; + uintptr_t vmx_eap_vtd_pdts_paddr, vmx_eap_vtd_pdts_vaddr; + uintptr_t vmx_eap_vtd_pts_paddr, vmx_eap_vtd_pts_vaddr; + uintptr_t vmx_eap_vtd_ret_paddr, vmx_eap_vtd_ret_vaddr; + uintptr_t vmx_eap_vtd_cet_paddr, vmx_eap_vtd_cet_vaddr; + + HALT_ON_ERRORCOND(protectedbuffer_size >= SIZE_G_RNTM_DMAPROT_BUFFER); + + // The VT-d page table created here is a partial one. If 4-level PT is used, then there is only one PML4 entry instead + // of 512 entries. This is sufficient because the lower 3-level PT covers 0 - 512GB physical memory space + vmx_eap_vtd_pml4t_paddr = protectedbuffer_paddr; + vmx_eap_vtd_pml4t_vaddr = protectedbuffer_vaddr; + vmx_eap_vtd_pdpt_paddr = protectedbuffer_paddr + PAGE_SIZE_4K; + vmx_eap_vtd_pdpt_vaddr = protectedbuffer_vaddr + PAGE_SIZE_4K; + vmx_eap_vtd_pdts_paddr = vmx_eap_vtd_pdpt_paddr + PAGE_SIZE_4K; + vmx_eap_vtd_pdts_vaddr = vmx_eap_vtd_pdpt_vaddr + PAGE_SIZE_4K; + vmx_eap_vtd_pts_paddr = vmx_eap_vtd_pdts_paddr + (PAGE_SIZE_4K * DMAPROT_VMX_P4L_NPDT); + vmx_eap_vtd_pts_vaddr = vmx_eap_vtd_pdts_vaddr + (PAGE_SIZE_4K * DMAPROT_VMX_P4L_NPDT); + vmx_eap_vtd_ret_paddr = vmx_eap_vtd_pts_paddr + (PAGE_SIZE_4K * DMAPROT_VMX_P4L_NPDT * PAE_PTRS_PER_PDT); + vmx_eap_vtd_ret_vaddr = vmx_eap_vtd_pts_vaddr + (PAGE_SIZE_4K * DMAPROT_VMX_P4L_NPDT * PAE_PTRS_PER_PDT); + vmx_eap_vtd_cet_paddr = vmx_eap_vtd_ret_paddr + PAGE_SIZE_4K; + vmx_eap_vtd_cet_vaddr = vmx_eap_vtd_ret_vaddr + PAGE_SIZE_4K; + + // [Superymk] [TODO] ugly hack... + vtd_cet = (void *)vmx_eap_vtd_cet_vaddr; + return vmx_eap_initialize(vmx_eap_vtd_pml4t_paddr, vmx_eap_vtd_pml4t_vaddr, vmx_eap_vtd_pdpt_paddr, vmx_eap_vtd_pdpt_vaddr, vmx_eap_vtd_pdts_paddr, vmx_eap_vtd_pdts_vaddr, + vmx_eap_vtd_pts_paddr, vmx_eap_vtd_pts_vaddr, vmx_eap_vtd_ret_paddr, vmx_eap_vtd_ret_vaddr, vmx_eap_vtd_cet_paddr, vmx_eap_vtd_cet_vaddr); +} + +// DMA protect a given region of memory +void xmhf_dmaprot_arch_x86_vmx_protect(spa_t start_paddr, size_t size) +{ + pt_t pt; + spa_t cur_spaddr, end_paddr; + u32 pdptindex, pdtindex, ptindex; + + // compute page aligned end + end_paddr = PA_PAGE_ALIGN_UP_4K(start_paddr + size); + start_paddr = PA_PAGE_ALIGN_4K(start_paddr); + + // sanity check + HALT_ON_ERRORCOND((l_vtd_pdpt_paddr != 0) && (l_vtd_pdpt_vaddr != 0)); + HALT_ON_ERRORCOND((l_vtd_pdts_paddr != 0) && (l_vtd_pdts_vaddr != 0)); + HALT_ON_ERRORCOND((l_vtd_pts_paddr != 0) && (l_vtd_pts_vaddr != 0)); + +#ifndef __XMHF_VERIFICATION__ + for (cur_spaddr = start_paddr; cur_spaddr <= end_paddr; cur_spaddr += PAGE_SIZE_4K) + { + // compute pdpt, pdt and pt indices + pdptindex = PAE_get_pdptindex(cur_spaddr); + pdtindex = PAE_get_pdtindex(cur_spaddr); + ptindex = PAE_get_ptindex(cur_spaddr); + + // get the page-table for this physical page + pt = (pt_t)(l_vtd_pts_vaddr + (pdptindex * PAGE_SIZE_4K * PAE_PTRS_PER_PDT) + (pdtindex * PAGE_SIZE_4K)); + + // protect the physical page + // pt[ptindex] &= 0xFFFFFFFFFFFFFFFCULL; + pt[ptindex] &= ~((u64)VTD_READ | (u64)VTD_WRITE); + } +#endif + + // flush the caches + _vtd_invalidatecaches(); +} + +// DMA unprotect a given region of memory +void xmhf_dmaprot_arch_x86_vmx_unprotect(spa_t start_paddr, size_t size) +{ + pt_t pt; + spa_t cur_spaddr, end_paddr; + u32 pdptindex, pdtindex, ptindex; + + // compute page aligned end + end_paddr = PA_PAGE_ALIGN_UP_4K(start_paddr + size); + start_paddr = PA_PAGE_ALIGN_4K(start_paddr); + + // sanity check + HALT_ON_ERRORCOND((l_vtd_pdpt_paddr != 0) && (l_vtd_pdpt_vaddr != 0)); + HALT_ON_ERRORCOND((l_vtd_pdts_paddr != 0) && (l_vtd_pdts_vaddr != 0)); + HALT_ON_ERRORCOND((l_vtd_pts_paddr != 0) && (l_vtd_pts_vaddr != 0)); + +#ifndef __XMHF_VERIFICATION__ + for (cur_spaddr = start_paddr; cur_spaddr <= end_paddr; cur_spaddr += PAGE_SIZE_4K) + { + // compute pdpt, pdt and pt indices + pdptindex = PAE_get_pdptindex(cur_spaddr); + pdtindex = PAE_get_pdtindex(cur_spaddr); + ptindex = PAE_get_ptindex(cur_spaddr); + + // get the page-table for this physical page + pt = (pt_t)(l_vtd_pts_vaddr + (pdptindex * PAGE_SIZE_4K * PAE_PTRS_PER_PDT) + (pdtindex * PAGE_SIZE_4K)); + + // protect the physical page + // pt[ptindex] &= 0xFFFFFFFFFFFFFFFCULL; + pt[ptindex] |= ((u64)VTD_READ | (u64)VTD_WRITE); + } +#endif +} + +// flush the caches +void xmhf_dmaprot_arch_x86_vmx_invalidate_cache(void) +{ + _vtd_invalidatecaches(); +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/vmx/dmap-vmx-utils.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/vmx/dmap-vmx-utils.c new file mode 100644 index 0000000000..254ead4d84 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/arch/x86/vmx/dmap-vmx-utils.c @@ -0,0 +1,219 @@ +// author: Miao Yu + +#include +#include "../../../iommu-pt.h" + +extern void* vtd_cet; // cet holds all its structures in the memory linearly +extern struct dmap_vmx_cap g_vtd_cap; + +#define NUM_PT_ENTRIES 512 // The number of page table entries in each level + +#define PAE_get_pml4tindex(x) ((x) >> 39) & (NUM_PT_ENTRIES - 1) +#define PAE_get_pdptindex(x) ((x) >> 30) & (NUM_PT_ENTRIES - 1) +#define PAE_get_pdtindex(x) ( (x) >> 21) & (NUM_PT_ENTRIES - 1) +#define PAE_get_ptindex(x) ( (x) >> 12 ) & (NUM_PT_ENTRIES - 1) + + +//! Invalidate the IOMMU PageTable corresponding to +void iommu_vmx_invalidate_pt(IOMMU_PT_INFO* pt_info) +{ + (void)pt_info; + // [TODO] We should invalidate this page table only later + xmhf_dmaprot_invalidate_cache(); +} + + +/*static bool _iommu_destroy_1GB_pts(IOMMU_PT_INFO* pt_info, uint64_t pt_1GB_pte) +{ + +} + +static void _iommu_map_1GB_page(IOMMU_PT_INFO* pt_info, void* upper_level_pts, gpa_t gpa, spa_t spa, uint32_t flags) +{ + uint32_t pt_1GB_index = 0; + uint64_t old_1GB_pte = 0; + + pt_1GB_index = PAE_get_pdptindex(gpa); + old_1GB_pte = ((uint64_t*)upper_level_pts)[pt_1GB_index]; + + if(old_1GB_pte) + { + // We have set a PTE at this slot before, so we need to free the old + // page structures first. + + // Step 1. + + } + + // Now we can safely assign the new PTE. + ((uint64_t*)upper_level_pts)[pt_1GB_index] = (spa & PAGE_MASK_1G) | (uint64_t)flags + | (uint64_t)VTD_SUPERPAGE | (uint64_t) VTD_PRESENT; + + return true; +} + +bool iommu_vmx_map(IOMMU_PT_INFO* pt_info, gpa_t start_gpa, spa_t start_spa, uint32_t num_pages, uint32_t flags) +{ + uint32_t remained_pages = num_pages; + + // Step 1. Allocate root page table if not exist + if(!pt_info->pt_root) + { + pt_info->pt_root = xmhf_mm_alloc_page_with_record(pt_info->used_mem, 1); + if(!pt_info->pt_root) + return false; + } + + // Step 2. Try mapping 1GB page frame + + + return true; +} + +bool iommu_vmx_map_batch(IOMMU_PT_INFO* pt_info, gpa_t start_gpa, spa_t* spas, uint32_t num_pages, uint32_t flags) +{ + + // Step 1. Allocate root page table if not exist + if(!pt_info->pt_root) + { + pt_info->pt_root = xmhf_mm_alloc_page_with_record(pt_info->used_mem, 1); + if(!pt_info->pt_root) + return false; + } + + return true; +}*/ + +static void* __vtd_get_l1pt(IOMMU_PT_INFO* pt_info) +{ + // Step 1. Allocate root page table if not exist + if(!pt_info->pt_root) + { + pt_info->pt_root = xmhf_mm_alloc_page_with_record(pt_info->used_mem, 1); + if(!pt_info->pt_root) + printf("[VTD-ERROR] No memory to allocate IOMMU top-level page struct!\n"); + } + return pt_info->pt_root; +} + +static void* __vtd_get_nextlvl_pt(IOMMU_PT_INFO* pt_info, void* pt_base, uint32_t pt_idx) +{ + uint64_t* p_pte = &((uint64_t*)pt_base)[pt_idx]; + void* nextlvl_pt = NULL; + + if(!*p_pte) + { + nextlvl_pt = xmhf_mm_alloc_page_with_record(pt_info->used_mem, 1); + if(!nextlvl_pt) + { + printf("[VTD-ERROR] No memory to allocate next level IOMMU page struct!\n"); + return NULL; + } + + *p_pte = (hva2spa(nextlvl_pt) & PAGE_MASK_4K) | ((uint64_t)VTD_READ | (uint64_t)VTD_WRITE); + } + + return spa2hva(*p_pte & PAGE_MASK_4K); + +} + +bool iommu_vmx_map(IOMMU_PT_INFO* pt_info, gpa_t gpa, spa_t spa, uint32_t flags) +{ + void *pml4 = NULL, *pdp = NULL, *pd = NULL, *pt = NULL; + uint32_t pml4_idx, pdp_idx, pd_idx, pt_idx = 0; + + pml4_idx = PAE_get_pml4tindex(gpa); + pdp_idx = PAE_get_pdptindex(gpa); + pd_idx = PAE_get_pdtindex(gpa); + pt_idx = PAE_get_ptindex(gpa); + + if(g_vtd_cap.sagaw & 0x4) + { + // Preferred to use 4-level PT + // Step 1. Get PML4 + pml4 = __vtd_get_l1pt(pt_info); + if(!pml4) + return false; + + // Step 2. Get PDP + pdp = __vtd_get_nextlvl_pt(pt_info, pml4, pml4_idx); + if(!pdp) + return false; + } + else if(g_vtd_cap.sagaw & 0x2) + { + // Step 1. Get PDP + pdp = __vtd_get_l1pt(pt_info); + if(!pdp) + return false; + } + else + { + // Unsupported IOMMU + return false; + } + + // Step 3. Get PD + pd = __vtd_get_nextlvl_pt(pt_info, pdp, pdp_idx); + if(!pd) + return false; + + // Step 4. Get PT + pt = __vtd_get_nextlvl_pt(pt_info, pd, pd_idx); + if(!pt) + return false; + + // Step 5. Map spa + if(flags == DMA_ALLOW_ACCESS) + { + ((uint64_t*)pt)[pt_idx] = (spa & PAGE_MASK_4K) | ((uint64_t)VTD_READ | (uint64_t)VTD_WRITE); + } + else if (flags == DMA_DENY_ACCESS) + { + ((uint64_t*)pt)[pt_idx] = (spa & PAGE_MASK_4K) & (uint64_t)0xfffffffe; // remove the present bit + } + + + return true; +} + +static bool __x86vmx_bind_cet(DEVICEDESC* device, iommu_pt_t pt_id, spa_t iommu_pt_root) +{ + uint64_t *value; + + // Update the CET + value = (uint64_t *)((hva_t)vtd_cet + (device->bus * PAGE_SIZE_4K) + + (device->dev * PCI_FUNCTION_MAX + device->func) * 16); + + if(g_vtd_cap.sagaw & 0x4) + { + // Preferred to use 4-level PT + *(value + 1) = (uint64_t)0x0000000000000002ULL | (((uint64_t)pt_id & 0xFFFF) << 8); //domain:, aw=48 bits, 4 level pt + } + else if(g_vtd_cap.sagaw & 0x2) + { + // If no 4-level PT, then try 3-level PT + *(value + 1) = (uint64_t)0x0000000000000001ULL | (((uint64_t)pt_id & 0xFFFF) << 8); //domain:, aw=39 bits, 3 level pt + } + else + { + // Unsupported IOMMU + return false; + } + + *value = iommu_pt_root; + *value |= 0x1ULL; //present, enable fault recording/processing, multilevel pt translation + + return true; +} + +bool iommu_vmx_bind_device(IOMMU_PT_INFO* pt_info, DEVICEDESC* device) +{ + return __x86vmx_bind_cet(device, pt_info->iommu_pt_id, hva2spa(pt_info->pt_root));; +} + +//! Bind the untrusted OS's default IOMMU PT to a device +bool iommu_vmx_unbind_device(DEVICEDESC* device) +{ + return __x86vmx_bind_cet(device, UNTRUSTED_OS_IOMMU_PT_ID, hva2spa(g_rntm_dmaprot_buffer));; +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/dmap-interface-earlyinit.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/dmap-interface-earlyinit.c new file mode 100644 index 0000000000..c2b4395a5e --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/dmap-interface-earlyinit.c @@ -0,0 +1,57 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF DMA protection component implementation +// author: amit vasudevan (amitvasudevan@acm.org) + +#include + +//"early" DMA protection initialization to setup minimal +//structures to protect a range of physical memory +//return 1 on success 0 on failure +u32 xmhf_dmaprot_earlyinitialize(u64 protectedbuffer_paddr, u32 protectedbuffer_vaddr, u32 protectedbuffer_size, u64 memregionbase_paddr, u32 memregion_size){ + return xmhf_dmaprot_arch_earlyinitialize(protectedbuffer_paddr, protectedbuffer_vaddr, protectedbuffer_size, memregionbase_paddr, memregion_size); +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/dmap-interface-runtime.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/dmap-interface-runtime.c new file mode 100644 index 0000000000..67298efe5a --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/dmap-interface-runtime.c @@ -0,0 +1,80 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF DMA protection component implementation +// author: amit vasudevan (amitvasudevan@acm.org) + +#include + +//return size (in bytes) of the memory buffer required for +//DMA protection for a given physical memory limit +u32 xmhf_dmaprot_getbuffersize(u64 physical_memory_limit){ + return xmhf_dmaprot_arch_getbuffersize(physical_memory_limit); +} + +//"normal" DMA protection initialization to setup required +//structures for DMA protection +//return 1 on success 0 on failure +u32 xmhf_dmaprot_initialize(u64 protectedbuffer_paddr, u32 protectedbuffer_vaddr, u32 protectedbuffer_size){ + return xmhf_dmaprot_arch_initialize(protectedbuffer_paddr, protectedbuffer_vaddr, protectedbuffer_size); +} + +//DMA protect a given region of memory, start_paddr is +//assumed to be page aligned physical memory address +void xmhf_dmaprot_protect(spa_t start_paddr, size_t size){ + return xmhf_dmaprot_arch_protect(start_paddr, size); +} + +//DMA unprotect a given region of memory, start_paddr is +//assumed to be page aligned physical memory address +void xmhf_dmaprot_unprotect(spa_t start_paddr, size_t size){ + return xmhf_dmaprot_arch_unprotect(start_paddr, size); +} + +void xmhf_dmaprot_invalidate_cache(void) +{ + xmhf_dmaprot_arch_invalidate_cache(); +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/iommu-pt.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/iommu-pt.c new file mode 100644 index 0000000000..b111dda4f3 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/iommu-pt.c @@ -0,0 +1,322 @@ +#include "iommu-pt.h" + +static IOMMU_PT_INFO** iommu_pts = NULL; // The list holding all the IOMMU_PTs, it is +// indexed with the pt handle +static uint32_t max_num_pts = 16; // [TODO] Use a better way to decide the + +static void _pt_manager_init(void) +{ + if (iommu_pts) + return; + + iommu_pts = xmhf_mm_malloc(max_num_pts * sizeof(IOMMU_PT_INFO*)); +} + +static void _pt_manager_fini(void) +{ + if (!iommu_pts) + return; + + xmhf_mm_free(iommu_pts); +} + +#define MIN_SECOS_IOMMU_PT_ID 2 // Domain ID 0 is reserved for mHV, and 1 is reserved for the rich OS +static iommu_pt_t _pt_manager_register_pt(IOMMU_PT_INFO* pt_info) +{ + uint32_t i = 0; + + for (i = MIN_SECOS_IOMMU_PT_ID; i < max_num_pts; i++) + { + if (!iommu_pts[i]) + break; + } + + if (i == max_num_pts) + { + // no free slots + return IOMMU_PT_INVALID; + } + + iommu_pts[i] = pt_info; + return (iommu_pt_t)i; +} + +static IOMMU_PT_INFO* _pt_manager_unregister_pt(iommu_pt_t pt_handle) +{ + IOMMU_PT_INFO* result = NULL; + + if (pt_handle == IOMMU_PT_INVALID) + return NULL; + + // the handle should not be larger than + if ((uint32_t)pt_handle >= max_num_pts) + return NULL; + + result = iommu_pts[pt_handle]; + iommu_pts[pt_handle] = NULL; + + return result; +} + +static IOMMU_PT_INFO* _pt_manager_get_pt(iommu_pt_t pt_handle) +{ + if (pt_handle == IOMMU_PT_INVALID) + return NULL; + + // the handle should not be larger than + if ((uint32_t)pt_handle >= max_num_pts) + return NULL; + + return iommu_pts[pt_handle]; +} + +static bool _iommu_pt_create_root(IOMMU_PT_INFO* pt_info) +{ + bool status = true; + + // Sanity checks + if(!pt_info) + return false; + + // Force allocation of the IOMMU PT root page structure. + // [NOTE] Because IOMMU PT page structures are allocated on-demand, we can allocate the root page structure by + // creating a dummy mapping. + status = iommu_vmx_map(pt_info, 0, 0, DMA_DENY_ACCESS); + return status; +} + +/// @brief Initialize the IOMMU (DMA Protection to the main memory) subsystem +void xmhf_iommu_init(void) +{ + // Step 1. Init the PT manager + _pt_manager_init(); +} + +/// @brief Finalize the IOMMU subsystem +void xmhf_iommu_fini(void) +{ + _pt_manager_fini(); +} + +uint32_t iommu_is_pt_s_exclusive(iommu_pt_t pt_handle, bool* out_result) +{ + IOMMU_PT_INFO* pt_info = NULL; + + if(pt_handle == IOMMU_PT_INVALID) + return 1; + if(!out_result) + return 1; + + pt_info = _pt_manager_get_pt(pt_handle); + if (!pt_info) + return 1; + + if(pt_info->type == IOMMU_PT_TYPE_S_EXCLUSIVE) + *out_result = true; + else + *out_result = false; + + return 0; +} + +uint32_t iommu_is_pt_s_ns_shared(iommu_pt_t pt_handle, bool* out_result) +{ + IOMMU_PT_INFO* pt_info = NULL; + + if(pt_handle == IOMMU_PT_INVALID) + return 1; + if(!out_result) + return 1; + + pt_info = _pt_manager_get_pt(pt_handle); + if (!pt_info) + return 1; + + if(pt_info->type == IOMMU_PT_TYPE_S_NS_SHARED) + *out_result = true; + else + *out_result = false; + + return 0; +} + +/// @brief Create a new IOMMU Page Table +iommu_pt_t xmhf_iommu_pt_create(IOMMU_PT_TYPE type) +{ + bool status = true; + IOMMU_PT_INFO* pt_info = NULL; + iommu_pt_t pt_handle = IOMMU_PT_INVALID; + + // Step 1. Initialize + pt_info = (IOMMU_PT_INFO*)xmhf_mm_malloc(sizeof(IOMMU_PT_INFO)); + pt_info->used_mem = xmhfstl_list_create(); + + // Step 2. Register the new PT in the system, and returns its handle + pt_handle = _pt_manager_register_pt(pt_info); + if (pt_handle == IOMMU_PT_INVALID) + { + // The IOMMU cannot load more PTs, so we should destroy the allocated + // structures. + if (pt_info->used_mem) + xmhfstl_list_clear_destroy(pt_info->used_mem); + xmhf_mm_free(pt_info); + } + pt_info->iommu_pt_id = pt_handle; + pt_info->type = type; + + // Allocate the IOMMU PT root page structure, so we can bind the IOMMU PT to the device after creating the PT. + status = _iommu_pt_create_root(pt_info); + if(!status) + { + xmhf_iommu_pt_destroy(pt_handle); + return IOMMU_PT_INVALID; + } + + return pt_handle; +} + +/// @brief Destroy an IOMMU Page Table +bool xmhf_iommu_pt_destroy(iommu_pt_t pt_handle) +{ + IOMMU_PT_INFO* pt_info = NULL; + + if(pt_handle == IOMMU_PT_INVALID) + return true; + + // Step 1. Search the corresponding + pt_info = _pt_manager_unregister_pt(pt_handle); + if (!pt_info) + return false; + + // Step 2. Destroy the + if (pt_info->used_mem) + { + xmhf_mm_free_all_records(pt_info->used_mem); + pt_info->used_mem = NULL; + } + + pt_info->iommu_pt_id = IOMMU_PT_INVALID; + pt_info->type = IOMMU_PT_TYPE_INVALID; + xmhf_mm_free(pt_info); + + return true; +} + +/*bool xmhf_iommu_pt_map(iommu_pt_t pt_handle, gpa_t start_gpa, spa_t start_spa, uint32_t num_pages, uint32_t flags) +{ + IOMMU_PT_INFO* pt_info = NULL; + bool status = false; + + pt_info = _pt_manager_get_pt(pt_handle); + if (!pt_info) + return false; + + status = iommu_vmx_map(pt_info, start_gpa, start_gpa, num_pages, flags); + + iommu_vmx_invalidate_pt(pt_info); + return status; +} + +bool xmhf_iommu_pt_map_batch(iommu_pt_t pt_handle, gpa_t start_gpa, spa_t* spas, uint32_t num_pages, uint32_t flags) +{ + IOMMU_PT_INFO* pt_info = NULL; + bool status = false; + + pt_info = _pt_manager_get_pt(pt_handle); + if (!pt_info) + return false; + + status = iommu_vmx_map_batch(pt_info, start_gpa, spas, num_pages, flags); + + iommu_vmx_invalidate_pt(pt_info); + return status; +}*/ + + + +/// @brief Map with in the IOMMU PT +bool xmhf_iommu_pt_map(iommu_pt_t pt_handle, gpa_t gpa, spa_t spa, uint32_t flags) +{ + IOMMU_PT_INFO* pt_info = NULL; + bool status = false; + + pt_info = _pt_manager_get_pt(pt_handle); + if (!pt_info) + return false; + + // Check: The function must not map mhv's memory, even if specify deny accesses. + if(xmhf_is_mhv_memory(spa)) + return false; + + // printf(" pt_handle:%u, gpa:%#X, spa:%#X, flags:%u\n", + // pt_handle, gpa, spa, flags); + status = iommu_vmx_map(pt_info, gpa, spa, flags); + return status; +} + +/// @brief Load the IOMMU PT for a specific device +bool xmhf_iommu_bind_device(iommu_pt_t pt_handle, DEVICEDESC* device) +{ + IOMMU_PT_INFO* pt_info = NULL; + bool status = false; + + pt_info = _pt_manager_get_pt(pt_handle); + if (!pt_info) + return false; + + status = iommu_vmx_bind_device(pt_info, device); + + // Flush the IOMMU PT to the main memory + wbinvd(); + + xmhf_dmaprot_invalidate_cache(); + return status; +} + +/// @brief Bind the untrusted OS's default IOMMU PT to the specific device +bool xmhf_iommu_unbind_device(DEVICEDESC* device) +{ + bool status = false; + + status = iommu_vmx_unbind_device(device); + + // Flush the IOMMU PT to the main memory + wbinvd(); + + xmhf_dmaprot_invalidate_cache(); + return status; +} + +// [TODO-Important] Do we need this function? +/// @brief Map with in all IOMMU_PT_TYPE_S_NS_SHARED IOMMU PTs. +/// [NOTE] This function is needed when moving memory between S and NS domains. Otherwise, a shared IOMMU PT created +/// by a SecProcess ealier may map isolated memory given to other SecProcesses later. This violates memory separation +/// between SecProcesses. +/// [TODO][Issue 60] SecBase needs to prove: All IOMMU_PT_TYPE_S_NS_SHARED IOMMU PTs map NS domain's memory and given +/// S domain's memory, but not any other S domain's memory. +bool xmhf_iommu_all_shared_pts_map(gpa_t gpa, uint32_t flags) +{ + uint32_t i = 0; + + for (i = MIN_SECOS_IOMMU_PT_ID; i < max_num_pts; i++) + { + bool status = false; + IOMMU_PT_INFO* pt_info = iommu_pts[i]; + + if (!pt_info) + continue; + + if(pt_info->type == IOMMU_PT_TYPE_S_NS_SHARED) + { + status = xmhf_iommu_pt_map(pt_info->iommu_pt_id, gpa, (spa_t)gpa, flags); + if(!status) + { + printf("Update mappings of all shared IOMMU PTs error: pt_handle:%u, gpa:%#X, flags:%u\n", + pt_info->iommu_pt_id, gpa, flags); + return false; + } + } + } + + return true; +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/iommu-pt.h b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/iommu-pt.h new file mode 100644 index 0000000000..9b04382293 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-dmaprot/iommu-pt.h @@ -0,0 +1,39 @@ +// author: Miao Yu [Superymk] +#ifndef XMHF_DMAP +#define XMHF_DMAP + +#include + +#ifndef __ASSEMBLY__ + +/// IOMMU PageTable information structure +typedef struct +{ + iommu_pt_t iommu_pt_id; + IOMMU_PT_TYPE type; + + /// @brief Record the allocated memory (pages) + XMHFList* used_mem; + + /// @brief the root hva address of the iommu pt + void* pt_root; +} IOMMU_PT_INFO; + + + + +/********* SUBARCH Specific functions *********/ +/// Invalidate the IOMMU PageTable corresponding to +extern void iommu_vmx_invalidate_pt(IOMMU_PT_INFO* pt_info); + +/// +extern bool iommu_vmx_map(IOMMU_PT_INFO* pt_info, gpa_t gpa, spa_t spa, uint32_t flags); + +/// Bind an IOMMU PT to a device +extern bool iommu_vmx_bind_device(IOMMU_PT_INFO* pt_info, DEVICEDESC* device); + +/// Bind the untrusted OS's default IOMMU PT to a device +extern bool iommu_vmx_unbind_device(DEVICEDESC* device); +#endif // __ASSEMBLY__ + +#endif // XMHF_DMAP diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/Makefile b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/Makefile new file mode 100644 index 0000000000..8ce529ced8 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/Makefile @@ -0,0 +1,18 @@ +# makefile for xmhf-parteventhub (EMHF partition event-hub component) +# author: amit vasudevan (amitvasudevan@acm.org) + +# source files +AS_SOURCES = ./arch/x86/svm/peh-x86-$(TARGET_SUBARCH)svm-entry.S +AS_SOURCES += ./arch/x86/vmx/peh-x86-$(TARGET_SUBARCH)vmx-entry.S + +C_SOURCES = ./arch/x86/svm/peh-x86svm-main.c +C_SOURCES += ./arch/x86/vmx/peh-x86vmx-main.c +C_SOURCES += ./arch/x86/vmx/peh-x86-safemsr.c +ifeq ($(UPDATE_INTEL_UCODE), y) +C_SOURCES += ./arch/x86/vmx/peh-x86vmx-ucode.c +C_SOURCES += ./arch/x86/vmx/peh-x86vmx-ucode-data.c +endif + +# targets +include ../runtime.mk + diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/svm/peh-x86-amd64svm-entry.S b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/svm/peh-x86-amd64svm-entry.S new file mode 100644 index 0000000000..4f8241cb15 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/svm/peh-x86-amd64svm-entry.S @@ -0,0 +1,136 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +//peh-x86svm-entry.S +//entry point for EMHF partition event-hub component for AMD x86 svm +//author: amit vasudevan (amitvasudevan@acm.org) + +//---------------------------------------------------------------------- +//globals referenced + .extern g_midtable_numentries + .extern g_midtable + .extern xmhf_parteventhub_arch_x86svm_intercept_handler + +//---------------------------------------------------------------------- +//macros to save and restore GPRs +#define SAVEALL_GPRS \ + pushl %edi ; \ + pushl %esi ; \ + pushl %ebp ; \ + pushl %esp ; \ + pushl %ebx ; \ + pushl %edx ; \ + pushl %ecx ; \ + pushl %eax ; + +#define RESTOREALL_GPRS \ + popl %eax ; \ + popl %ecx ; \ + popl %edx ; \ + popl %ebx ; \ + popl %esp ; \ + popl %ebp ; \ + popl %esi ; \ + popl %edi ; + + +//---------------------------------------------------------------------- +// xmhf_parteventhub_entry_x86svm +// we get control here right after any event within a partition +.section .text +.global xmhf_parteventhub_arch_x86svm_entry +xmhf_parteventhub_arch_x86svm_entry: + + //save EAX as it contains the VMCB address + //pushl %eax + + //step-1: save all CPU GPRs +#ifdef __AMD64__ + // TODO +#elif defined(__I386__) + //SAVEALL_GPRS + pushal +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + + //step-2: get hold of pointer to saved GPRs on stack + movl %esp, %eax + + //step-3: get VCPU * for this core (it is the first DWORD on + //the core stack when we have an intercept, so move past the + //saved GPRs, VMCB address and the return EIP for this function invocation) + //movl 40(%esp), %esi + movl 36(%esp), %esi + + //step-4: invoke "C" handler + //1st argument is VCPU * followed by pointer to saved GPRs +#ifdef __AMD64__ + // TODO +#elif defined(__I386__) + pushl %eax + pushl %esi +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + call xmhf_parteventhub_arch_x86svm_intercept_handler + addl $0x08, %esp + + //step-5: restore all CPU GPRs +#ifdef __AMD64__ + // TODO +#elif defined(__I386__) + //RESTOREALL_GPRS + popal +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + + //restore VMCB address + //popl %eax + + //return + ret diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/svm/peh-x86-i386svm-entry.S b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/svm/peh-x86-i386svm-entry.S new file mode 100644 index 0000000000..4f8241cb15 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/svm/peh-x86-i386svm-entry.S @@ -0,0 +1,136 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +//peh-x86svm-entry.S +//entry point for EMHF partition event-hub component for AMD x86 svm +//author: amit vasudevan (amitvasudevan@acm.org) + +//---------------------------------------------------------------------- +//globals referenced + .extern g_midtable_numentries + .extern g_midtable + .extern xmhf_parteventhub_arch_x86svm_intercept_handler + +//---------------------------------------------------------------------- +//macros to save and restore GPRs +#define SAVEALL_GPRS \ + pushl %edi ; \ + pushl %esi ; \ + pushl %ebp ; \ + pushl %esp ; \ + pushl %ebx ; \ + pushl %edx ; \ + pushl %ecx ; \ + pushl %eax ; + +#define RESTOREALL_GPRS \ + popl %eax ; \ + popl %ecx ; \ + popl %edx ; \ + popl %ebx ; \ + popl %esp ; \ + popl %ebp ; \ + popl %esi ; \ + popl %edi ; + + +//---------------------------------------------------------------------- +// xmhf_parteventhub_entry_x86svm +// we get control here right after any event within a partition +.section .text +.global xmhf_parteventhub_arch_x86svm_entry +xmhf_parteventhub_arch_x86svm_entry: + + //save EAX as it contains the VMCB address + //pushl %eax + + //step-1: save all CPU GPRs +#ifdef __AMD64__ + // TODO +#elif defined(__I386__) + //SAVEALL_GPRS + pushal +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + + //step-2: get hold of pointer to saved GPRs on stack + movl %esp, %eax + + //step-3: get VCPU * for this core (it is the first DWORD on + //the core stack when we have an intercept, so move past the + //saved GPRs, VMCB address and the return EIP for this function invocation) + //movl 40(%esp), %esi + movl 36(%esp), %esi + + //step-4: invoke "C" handler + //1st argument is VCPU * followed by pointer to saved GPRs +#ifdef __AMD64__ + // TODO +#elif defined(__I386__) + pushl %eax + pushl %esi +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + call xmhf_parteventhub_arch_x86svm_intercept_handler + addl $0x08, %esp + + //step-5: restore all CPU GPRs +#ifdef __AMD64__ + // TODO +#elif defined(__I386__) + //RESTOREALL_GPRS + popal +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + + //restore VMCB address + //popl %eax + + //return + ret diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/svm/peh-x86svm-main.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/svm/peh-x86svm-main.c new file mode 100644 index 0000000000..ac1ca2d3e3 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/svm/peh-x86svm-main.c @@ -0,0 +1,476 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// peh-x86svm-main.c +// EMHF partition event-hub for AMD x86 svm +// author: amit vasudevan (amitvasudevan@acm.org) +#include + + +//---IO Intercept handling------------------------------------------------------ +static void _svm_handle_ioio(VCPU *vcpu, struct _svm_vmcbfields *vmcb, struct regs __attribute__((unused)) *r){ + union svmioiointerceptinfo ioinfo; + u32 app_ret_status = APP_IOINTERCEPT_CHAIN; + u32 access_size, access_type; + + ioinfo.rawbits = vmcb->exitinfo1; + + if (ioinfo.fields.rep || ioinfo.fields.str){ + printf("\nCPU(0x%02x): Fatal, unsupported batch I/O ops!", vcpu->id); + HALT(); + } + + if(ioinfo.fields.type) + access_type = IO_TYPE_IN; + else + access_type = IO_TYPE_OUT; + + if(ioinfo.fields.sz8) + access_size = IO_SIZE_BYTE; + else if(ioinfo.fields.sz16) + access_size = IO_SIZE_WORD; + else + access_size = IO_SIZE_DWORD; + + //call our app handler + xmhf_smpguest_arch_x86svm_quiesce(vcpu); + app_ret_status=xmhf_app_handleintercept_portaccess(vcpu, r, ioinfo.fields.port, access_type, + access_size); + xmhf_smpguest_arch_x86svm_endquiesce(vcpu); + + + if(app_ret_status == APP_IOINTERCEPT_CHAIN){ + if (ioinfo.fields.type){ + // IN + if (ioinfo.fields.sz8){ + vmcb->rax &= ~(u64)0x00000000000000FF; + vmcb->rax |= (u8)inb(ioinfo.fields.port); + //*(u8 *)&vmcb->rax = inb(ioinfo.fields.port); + }else if (ioinfo.fields.sz16){ + vmcb->rax &= ~(u64)0x000000000000FFFF; + vmcb->rax |= (u16)inw(ioinfo.fields.port); + //*(u16 *)&vmcb->rax = inw(ioinfo.fields.port); + }else if (ioinfo.fields.sz32){ + vmcb->rax &= ~(u64)0x00000000FFFFFFFF; + vmcb->rax |= (u32)inl(ioinfo.fields.port); + //*(u32 *)&vmcb->rax = inl(ioinfo.fields.port); + }else{ + //h/w should set sz8, sz16 or sz32, we get here if there + //is a non-complaint CPU + printf("\nnon-complaint CPU (ioio intercept). Halting!"); + HALT(); + } + }else{ + // OUT + if (ioinfo.fields.sz8) + outb((u8)vmcb->rax, ioinfo.fields.port); + if (ioinfo.fields.sz16) + outw((u16)vmcb->rax, ioinfo.fields.port); + if (ioinfo.fields.sz32) + outl((u32)vmcb->rax, ioinfo.fields.port); + } + + // exitinfo2 stores the rip of instruction following the IN/OUT + vmcb->rip = vmcb->exitinfo2; + }else{ + //skip the IO instruction, app has taken care of it + vmcb->rip = vmcb->exitinfo2; + } + + +} + + +//---MSR intercept handling----------------------------------------------------- +static void _svm_handle_msr(VCPU *vcpu, struct _svm_vmcbfields *vmcb, struct regs *r){ + HALT_ON_ERRORCOND( (vmcb->exitinfo1 == 0) || (vmcb->exitinfo1 == 1) ); + printf("\nCPU(0x%02x): MSR intercept, type=%u, MSR=0x%08x", vcpu->id, + (u32)vmcb->exitinfo1, r->ecx); + switch(vmcb->exitinfo1){ + case 0:{ //RDMSR with MSR in ECX + rdmsr(r->ecx, &r->eax, &r->edx); + } + break; + + case 1:{ //WRMSR with MSR in ECX + wrmsr(r->ecx, r->eax, r->edx); + } + break; + } + + vmcb->rip += 2; +} + + +//invoked on a nested page-fault +//struct regs *r -> guest OS GPR state +//win_vmcb -> rest of the guest OS state +//win_vmcb->exitinfo1 = error code similar to PF +//win_vmcb->exitinfo2 = faulting guest OS physical address +static void _svm_handle_npf(VCPU *vcpu, struct regs *r){ + struct _svm_vmcbfields *vmcb = (struct _svm_vmcbfields *)vcpu->vmcb_vaddr_ptr; + u32 gpa = vmcb->exitinfo2; + u32 errorcode = vmcb->exitinfo1; + + if(gpa >= g_svm_lapic_base && gpa < (g_svm_lapic_base + PAGE_SIZE_4K)){ + //LAPIC access, xfer control to apropriate handler + HALT_ON_ERRORCOND( vcpu->isbsp == 1); //only BSP gets a NPF during LAPIC SIPI detection + xmhf_smpguest_arch_x86_eventhandler_hwpgtblviolation(vcpu, gpa, errorcode); + } else { + //note: AMD does not provide guest virtual address on a #NPF so we pass zero always + xmhf_smpguest_arch_x86svm_quiesce(vcpu); + xmhf_app_handleintercept_hwpgtblviolation(vcpu, r, gpa, 0, errorcode); + xmhf_smpguest_arch_x86svm_endquiesce(vcpu); + } + + return; +} + + +//---NMI handling--------------------------------------------------------------- +// note: we use NMI for core quiescing, we simply inject the others back +// into the guest in the normal case +static void _svm_handle_nmi(VCPU *vcpu, struct _svm_vmcbfields __attribute__((unused)) *vmcb, struct regs __attribute__((unused)) *r){ + //now we adopt a simple trick, this NMI is pending, the only + //way we can dismiss it is if we set GIF=0 and make GIF=1 so that + //the core thinks it must dispatch the pending NMI :p + (void)vcpu; + + //printf("\nCPU(0x%02x): triggering local NMI in CPU...", vcpu->id); + + __asm__ __volatile__("clgi\r\n"); + __asm__ __volatile__("stgi\r\n"); //at this point we get control in + //our exception handler which handles the rest + //printf("\nCPU(0x%02x): resuming guest...", vcpu->id); +} + + +//---svm int 15 intercept handler----------------------------------------------- +static void _svm_int15_handleintercept(VCPU *vcpu, struct regs *r){ + u16 cs, ip; + u8 *bdamemory = (u8 *)0x4AC; + struct _svm_vmcbfields *vmcb = (struct _svm_vmcbfields *)vcpu->vmcb_vaddr_ptr; + + //if in V86 mode translate the virtual address to physical address + if( (vmcb->cr0 & CR0_PE) && (vmcb->cr0 & CR0_PG) && + (vmcb->rflags & EFLAGS_VM) ){ + u8 *bdamemoryphysical; + #ifdef __XMHF_VERIFICATION__ + bdamemoryphysical = (u8 *)nondet_u32(); + #else + bdamemoryphysical = (u8 *)xmhf_smpguest_arch_x86svm_walk_pagetables(vcpu, (hva_t)bdamemory); + #endif + if((sla_t)bdamemoryphysical < rpb->XtVmmRuntimePhysBase){ + printf("\nINT15 (E820): V86 mode, bdamemory translated from %08lx to %08lx", + (hva_t)bdamemory, (sla_t)bdamemoryphysical); + bdamemory = bdamemoryphysical; + }else{ + printf("\nCPU(0x%02x): INT15 (E820) V86 mode, translated bdamemory points beyond \ + guest physical memory space. Halting!", vcpu->id); + HALT(); + } + } + + //if E820 service then... + if((u16)vmcb->rax == 0xE820){ + //AX=0xE820, EBX=continuation value, 0 for first call + //ES:DI pointer to buffer, ECX=buffer size, EDX='SMAP' + //return value, CF=0 indicated no error, EAX='SMAP' + //ES:DI left untouched, ECX=size returned, EBX=next continuation value + //EBX=0 if last descriptor + printf("\nCPU(0x%02x): INT 15(e820): AX=0x%04x, EDX=0x%08x, EBX=0x%08x, ECX=0x%08x, ES=0x%04x, DI=0x%04x", vcpu->id, + (u16)vmcb->rax, r->edx, r->ebx, r->ecx, (u16)vmcb->es.selector, (u16)r->edi); + + //HALT_ON_ERRORCOND(r->edx == 0x534D4150UL); //'SMAP' should be specified by guest + //HALT_ON_ERRORCOND(r->ebx < rpb->XtVmmE820NumEntries); //invalid continuation value specified by guest! + if( (r->edx == 0x534D4150UL) && (r->ebx < rpb->XtVmmE820NumEntries) ){ + + //copy the e820 descriptor and return its size in ECX + { + + if(((u32)((vmcb->es.base)+(u16)r->edi)) < rpb->XtVmmRuntimePhysBase){ + #ifdef __XMHF_VERIFICATION__ + GRUBE820 pe820entry; + pe820entry.baseaddr_low = g_e820map[r->ebx].baseaddr_low; + pe820entry.baseaddr_high = g_e820map[r->ebx].baseaddr_high; + pe820entry.length_low = g_e820map[r->ebx].length_low; + pe820entry.length_high = g_e820map[r->ebx].length_high; + pe820entry.type = g_e820map[r->ebx].type; + #else + GRUBE820 *pe820entry; + pe820entry = (GRUBE820 *)((hva_t)((vmcb->es.base)+(u16)r->edi)); + + pe820entry->baseaddr_low = g_e820map[r->ebx].baseaddr_low; + pe820entry->baseaddr_high = g_e820map[r->ebx].baseaddr_high; + pe820entry->length_low = g_e820map[r->ebx].length_low; + pe820entry->length_high = g_e820map[r->ebx].length_high; + pe820entry->type = g_e820map[r->ebx].type; + #endif //__XMHF_VERIFICATION__ + }else{ + printf("\nCPU(0x%02x): INT15 E820. Guest buffer is beyond guest \ + physical memory bounds. Halting!", vcpu->id); + HALT(); + } + + } + r->ecx=20; + + //set EAX to 'SMAP' as required by the service call + vmcb->rax=r->edx; + + //we need to update carry flag in the guest EFLAGS register + //however since INT 15 would have pushed the guest FLAGS on stack + //we cannot simply reflect the change by modifying vmcb->rflags + //instead we need to make the change to the pushed FLAGS register on + //the guest stack. the real-mode IRET frame looks like the following + //when viewed at top of stack + //guest_ip (16-bits) + //guest_cs (16-bits) + //guest_flags (16-bits) + //... + + { + //u16 guest_cs, guest_ip, guest_flags; + u16 guest_cs __attribute__((unused)), guest_ip __attribute__((unused)), guest_flags; + u16 *gueststackregion = (u16 *)( (hva_t)vmcb->ss.base + (u16)vmcb->rsp ); + + + //if V86 mode translate the virtual address to physical address + if( (vmcb->cr0 & CR0_PE) && (vmcb->cr0 & CR0_PG) && + (vmcb->rflags & EFLAGS_VM) ){ + #ifdef __XMHF_VERIFICATION__ + u8 *gueststackregionphysical = (u8 *)nondet_u32(); + #else + u8 *gueststackregionphysical = (u8 *)xmhf_smpguest_arch_x86svm_walk_pagetables(vcpu, (hva_t)gueststackregion); + #endif + if((sla_t)gueststackregionphysical < rpb->XtVmmRuntimePhysBase){ + printf("\nINT15 (E820): V86 mode, gueststackregion translated from %08x to %08x", + (hva_t)gueststackregion, (sla_t)gueststackregionphysical); + gueststackregion = (u16 *)gueststackregionphysical; + }else{ + printf("\nCPU(0x%02x): INT15 (E820) V86 mode, translated gueststackregion points beyond \ + guest physical memory space. Halting!", vcpu->id); + HALT(); + } + } + + //get guest IP, CS and FLAGS from the IRET frame + #ifdef __XMHF_VERIFICATION__ + guest_ip = nondet_u16(); + guest_cs = nondet_u16(); + guest_flags = nondet_u16(); + #else + guest_ip = gueststackregion[0]; + guest_cs = gueststackregion[1]; + guest_flags = gueststackregion[2]; + #endif //__XMHF_VERIFICATION__ + + //increment e820 descriptor continuation value + r->ebx=r->ebx+1; + + if(r->ebx > (rpb->XtVmmE820NumEntries-1) ){ + //we have reached the last record, so set CF and make EBX=0 + r->ebx=0; + guest_flags |= (u16)EFLAGS_CF; + #ifndef __XMHF_VERIFICATION__ + gueststackregion[2] = guest_flags; + #endif + }else{ + //we still have more records, so clear CF + guest_flags &= ~(u16)EFLAGS_CF; + #ifndef __XMHF_VERIFICATION__ + gueststackregion[2] = guest_flags; + #endif + } + + } + + }else{ //invalid state specified during INT 15 E820, fail by + //setting carry flag + printf("\nCPU(0x%02x): INT15 (E820), invalid state specified by guest \ + Halting!", vcpu->id); + HALT(); + } + + //update RIP to execute the IRET following the VMCALL instruction + //effectively returning from the INT 15 call made by the guest + vmcb->rip += 3; + + return; + } //E820 service + + //ok, this is some other INT 15h service, so simply chain to the original + //INT 15h handler + +#ifdef __XMHF_VERIFICATION__ + //get IP and CS of the original INT 15h handler + ip = nondet_u16(); + cs = nondet_u16(); +#else + //get IP and CS of the original INT 15h handler + ip = *((u16 *)((hva_t)bdamemory + 4)); + cs = *((u16 *)((hva_t)bdamemory + 6)); +#endif + + //update VMCB with the CS and IP and let go + vmcb->rip = ip; + vmcb->cs.base = cs * 16; + vmcb->cs.selector = cs; +} + + + +//---SVM intercept handler hub-------------------------------------------------- +u32 xmhf_parteventhub_arch_x86svm_intercept_handler(VCPU *vcpu, struct regs *r){ + struct _svm_vmcbfields *vmcb = (struct _svm_vmcbfields *)vcpu->vmcb_vaddr_ptr; + + vmcb->tlb_control = VMCB_TLB_CONTROL_NOTHING; + + //handle intercepts + switch(vmcb->exitcode){ + + //-------------------------------------------------------------- + //xmhf-core and hypapp intercepts + //-------------------------------------------------------------- + + case SVM_VMEXIT_VMMCALL:{ + //check to see if this is a hypercall for INT 15h hooking + if(vmcb->cs.base == (VMX_UG_E820HOOK_CS << 4) && + vmcb->rip == VMX_UG_E820HOOK_IP){ + //we need to be either in real-mode or in protected + //mode with paging and EFLAGS.VM bit set (virtual-8086 mode) + if( !(vmcb->cr0 & CR0_PE) || + ( (vmcb->cr0 & CR0_PE) && (vmcb->cr0 & CR0_PG) && + (vmcb->rflags & EFLAGS_VM) ) ){ + _svm_int15_handleintercept(vcpu, r); + }else{ + printf("\nCPU(0x%02x): unhandled INT 15h request from protected mode", vcpu->id); + printf("\nHalting!"); + HALT(); + } + }else{ //if not E820 hook, give app a chance to handle the hypercall + xmhf_smpguest_arch_x86svm_quiesce(vcpu); + if( xmhf_app_handlehypercall(vcpu, r) != APP_SUCCESS){ + printf("\nCPU(0x%02x): error(halt), unhandled hypercall 0x%08x!", vcpu->id, r->eax); + HALT(); + } + xmhf_smpguest_arch_x86svm_endquiesce(vcpu); + vmcb->rip += 3; + } + } + break; + + //IO interception + case SVM_VMEXIT_IOIO:{ + _svm_handle_ioio(vcpu, vmcb, r); + } + break; + + //Nested Page Fault (NPF) + case SVM_VMEXIT_NPF:{ + _svm_handle_npf(vcpu, r); + } + break; + + case SVM_VMEXIT_INIT:{ + printf("\n***** INIT xmhf_app_handleshutdown\n"); + xmhf_app_handleshutdown(vcpu, r); + printf("\nCPU(0x%02x): Fatal, xmhf_app_handleshutdown returned. Halting!", vcpu->id); + HALT(); + } + break; + + //-------------------------------------------------------------- + //xmhf-core only intercepts + //-------------------------------------------------------------- + + //MSR interception + case SVM_VMEXIT_MSR:{ + _svm_handle_msr(vcpu, vmcb, r); + } + break; + + case SVM_VMEXIT_EXCEPTION_DB:{ + if(vcpu->isbsp == 1){ //LAPIC SIPI detection only happens on BSP + xmhf_smpguest_arch_x86_eventhandler_dbexception(vcpu, r); + }else{ //TODO: reflect back to guest + printf("\nUnexpected DB exception on non-BSP core (0x%02x)", vcpu->id); + printf("\nHalting!"); + HALT(); + } + } + break; + + case SVM_VMEXIT_NMI:{ + _svm_handle_nmi(vcpu, vmcb, r); + } + break; + + default:{ + printf("\nUnhandled Intercept:0x%08llx", vmcb->exitcode); + printf("\n\tCS:EIP=0x%04x:0x%08x", (u16)vmcb->cs.selector, (u32)vmcb->rip); + printf("\n\tedi:%08x esi:%08x ebp:%08x esp:%08llx", + r->edi, r->esi, r->ebp, vmcb->rsp); + printf("\n\tebx:%08x edx:%08x ecx:%08x eax:%08llx", + r->ebx, r->edx, r->ecx, vmcb->rax); + printf("\n\tExitInfo1: %llx", vmcb->exitinfo1); + printf("\n\tExitInfo2: %llx", vmcb->exitinfo2); + HALT(); + } + } //end switch(vmcb->exitcode) + + +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + { + //ensure that whenever a partition is resumed on a vcpu, we have nested paging + //enabled and that the base points to the nested page tables we have initialized + assert( (vmcb->np_enable == 1) ); + assert( (vmcb->n_cr3 == vcpu->npt_vaddr_ptr) ); + } +#endif + + return 0; +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/vmx/peh-x86-amd64vmx-entry.S b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/vmx/peh-x86-amd64vmx-entry.S new file mode 100644 index 0000000000..a686164c7f --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/vmx/peh-x86-amd64vmx-entry.S @@ -0,0 +1,115 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +//peh-x86vmx-entry.S +//entry point for EMHF partition event-hub component for Intel x86 vmx +//author: amit vasudevan (amitvasudevan@acm.org) +#include + +//---------------------------------------------------------------------- +//globals referenced + .extern xmhf_parteventhub_arch_x86vmx_intercept_handler + +//---------------------------------------------------------------------- +// xmhf_parteventhub_entry_x86vmx +// we get control here right after any event within a partition +// note: the h/w is the "caller" so we never actually "return" +.section .text +.global xmhf_parteventhub_arch_x86vmx_entry +xmhf_parteventhub_arch_x86vmx_entry: + // Currently rsp points to VCPU + + //step-1: save all CPU GPRs + pushq %r15 + pushq %r14 + pushq %r13 + pushq %r12 + pushq %r11 + pushq %r10 + pushq %r9 + pushq %r8 + pushq %rax + pushq %rcx + pushq %rdx + pushq %rbx + pushq %rsp + pushq %rbp + pushq %rsi + pushq %rdi + + //step-2: grab VCPU *, put to 1st argument + movq 128(%rsp), %rdi + + //step-4: get hold of pointer to saved GPR on stack, put to 2nd argument + movq %rsp, %rsi + + //step-5: invoke "C" event handler + call xmhf_parteventhub_arch_x86vmx_intercept_handler + + //step-6; restore all CPU GPRs + popq %rdi + popq %rsi + popq %rbp + popq %rsp + popq %rbx + popq %rdx + popq %rcx + popq %rax + popq %r8 + popq %r9 + popq %r10 + popq %r11 + popq %r12 + popq %r13 + popq %r14 + popq %r15 + + //resume partition + vmresume + + //if we get here then vm resume failed, just bail out with a BP exception + int $0x03 + hlt diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/vmx/peh-x86-i386vmx-entry.S b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/vmx/peh-x86-i386vmx-entry.S new file mode 100644 index 0000000000..020c11a5ec --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/vmx/peh-x86-i386vmx-entry.S @@ -0,0 +1,87 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +//peh-x86vmx-entry.S +//entry point for EMHF partition event-hub component for Intel x86 vmx +//author: amit vasudevan (amitvasudevan@acm.org) +#include + +//---------------------------------------------------------------------- +//globals referenced + .extern xmhf_parteventhub_arch_x86vmx_intercept_handler + +//---------------------------------------------------------------------- +// xmhf_parteventhub_entry_x86vmx +// we get control here right after any event within a partition +// note: the h/w is the "caller" so we never actually "return" +.section .text +.global xmhf_parteventhub_arch_x86vmx_entry +xmhf_parteventhub_arch_x86vmx_entry: + //step-1: save all CPU GPRs + pushal + + //step-2: grab VCPU * + movl 32(%esp), %esi + + //step-4: get hold of pointer to saved GPR on stack + movl %esp, %eax + + //step-5: invoke "C" event handler + //1st argument is VCPU * followed by pointer to saved GPRs + pushl %eax + pushl %esi + call xmhf_parteventhub_arch_x86vmx_intercept_handler + addl $0x08, %esp + + //step-6; restore all CPU GPRs + popal + + //resume partition + vmresume + + //if we get here then vm resume failed, just bail out with a BP exception + int $0x03 + hlt diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/vmx/peh-x86-safemsr.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/vmx/peh-x86-safemsr.c new file mode 100644 index 0000000000..6e5a70950e --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/vmx/peh-x86-safemsr.c @@ -0,0 +1,90 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// peh-x86-safemsr.c +// Safely Reading MSRs +// author: Eric Li (xiaoyili@andrew.cmu.edu) +#include + +/* + * Perform RDMSR instruction, r->ecx is input, r->eax and r->edx are outputs. + * If successful, return 0. If RDMSR causes #GP, return 1. + * Implementation similar to Linux's native_read_msr_safe(). + */ +u32 rdmsr_safe(struct regs *r) { + u32 result; + asm volatile ("1:\r\n" + "rdmsr\r\n" + "xor %%ebx, %%ebx\r\n" + "jmp 3f\r\n" + "2:\r\n" + "movl $1, %%ebx\r\n" + "jmp 3f\r\n" + ".section .xcph_table\r\n" +#ifdef __AMD64__ + ".quad 0xd\r\n" + ".quad 1b\r\n" + ".quad 2b\r\n" +#elif defined(__I386__) + ".long 0xd\r\n" + ".long 1b\r\n" + ".long 2b\r\n" +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + ".previous\r\n" + "3:\r\n" +#ifdef __AMD64__ + : "=a"(r->rax), "=d"(r->rdx), "=b"(result) + : "c" (r->rcx)); +#elif defined(__I386__) + : "=a"(r->eax), "=d"(r->edx), "=b"(result) + : "c" (r->ecx)); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + return result; +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/vmx/peh-x86vmx-main.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/vmx/peh-x86vmx-main.c new file mode 100644 index 0000000000..da93255ccf --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/vmx/peh-x86vmx-main.c @@ -0,0 +1,1273 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// peh-x86vmx-main.c +// EMHF partition event-hub for Intel x86 vmx +// author: amit vasudevan (amitvasudevan@acm.org) +#include + + +//---VMX decode assist---------------------------------------------------------- +//map a CPU register index into appropriate VCPU *vcpu or struct regs *r field +//and return the address of the field +#ifdef __AMD64__ +static uintptr_t * _vmx_decode_reg(u32 gpr, VCPU *vcpu, struct regs *r){ + switch(gpr){ + case 0: return &r->rax; + case 1: return &r->rcx; + case 2: return &r->rdx; + case 3: return &r->rbx; + case 4: return (u64*)&vcpu->vmcs.guest_RSP; + case 5: return &r->rbp; + case 6: return &r->rsi; + case 7: return &r->rdi; + case 8: return &r->r8 ; + case 9: return &r->r9 ; + case 10: return &r->r10; + case 11: return &r->r11; + case 12: return &r->r12; + case 13: return &r->r13; + case 14: return &r->r14; + case 15: return &r->r15; + default: { + printf("\n[%02x]%s: invalid gpr value (%u). halting!", vcpu->id, + __FUNCTION__, gpr); + HALT(); + //we will never get here, appease the compiler + return (u64 *)&r->rax; + } + } +} +#elif defined(__I386__) +static uintptr_t * _vmx_decode_reg(u32 gpr, VCPU *vcpu, struct regs *r){ + if ( ((int)gpr >=0) && ((int)gpr <= 7) ){ + + switch(gpr){ + case 0: return ( (u32 *)&r->eax ); + case 1: return ( (u32 *)&r->ecx ); + case 2: return ( (u32 *)&r->edx ); + case 3: return ( (u32 *)&r->ebx ); + case 4: return ( (u32 *)&vcpu->vmcs.guest_RSP); + case 5: return ( (u32 *)&r->ebp ); + case 6: return ( (u32 *)&r->esi ); + case 7: return ( (u32 *)&r->edi ); + } + }else{ + printf("\n[%02x]%s: invalid gpr value (%u). halting!", vcpu->id, + __FUNCTION__, gpr); + HALT(); + } + + //we will never get here, appease the compiler + return (u32 *)&r->eax; +} +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + + +//---intercept handler (CPUID)-------------------------------------------------- +static void _vmx_handle_intercept_cpuid(VCPU *vcpu, struct regs *r){ + //printf("\nCPU(0x%02x): CPUID", vcpu->id); + u32 old_eax = r->eax; + asm volatile ("cpuid\r\n" + :"=a"(r->eax), "=b"(r->ebx), "=c"(r->ecx), "=d"(r->edx) + :"a"(r->eax), "c" (r->ecx)); + if (old_eax == 0x1) { + /* Clear VMX capability */ + r->ecx &= ~(1U << 5); +#ifndef __UPDATE_INTEL_UCODE__ + /* + * Set Hypervisor Present bit. + * Fedora 35's AP will retry updating Intel microcode forever if the + * update fails. So we set the hypervisor present bit to solve this + * problem. + */ + r->ecx |= (1U << 31); +#endif /* !__UPDATE_INTEL_UCODE__ */ + } + vcpu->vmcs.guest_RIP += vcpu->vmcs.info_vmexit_instruction_length; +} + + +//---vmx int 15 intercept handler----------------------------------------------- +static void _vmx_int15_handleintercept(VCPU *vcpu, struct regs *r){ + u16 cs, ip; + u8 *bdamemory = (u8 *)0x4AC; + + //if in V86 mode translate the virtual address to physical address + if( (vcpu->vmcs.guest_CR0 & CR0_PE) && (vcpu->vmcs.guest_CR0 & CR0_PG) && + (vcpu->vmcs.guest_RFLAGS & EFLAGS_VM) ){ + u8 *bdamemoryphysical; + #ifdef __XMHF_VERIFICATION__ + bdamemoryphysical = (u8 *)nondet_u32(); + #else + bdamemoryphysical = (u8 *)xmhf_smpguest_arch_x86vmx_walk_pagetables(vcpu, (hva_t)bdamemory); + #endif + if((sla_t)bdamemoryphysical < rpb->XtVmmRuntimePhysBase){ + printf("\nINT15 (E820): V86 mode, bdamemory translated from %08lx to %08lx", + (hva_t)bdamemory, (sla_t)bdamemoryphysical); + bdamemory = bdamemoryphysical; + }else{ + printf("\nCPU(0x%02x): INT15 (E820) V86 mode, translated bdamemory points beyond \ + guest physical memory space. Halting!", vcpu->id); + HALT(); + } + } + + + //if E820 service then... + if((u16)r->eax == 0xE820){ + //AX=0xE820, EBX=continuation value, 0 for first call + //ES:DI pointer to buffer, ECX=buffer size, EDX='SMAP' + //return value, CF=0 indicated no error, EAX='SMAP' + //ES:DI left untouched, ECX=size returned, EBX=next continuation value + //EBX=0 if last descriptor + printf("\nCPU(0x%02x): INT 15(e820): AX=0x%04x, EDX=0x%08x, EBX=0x%08x, ECX=0x%08x, ES=0x%04x, DI=0x%04x", vcpu->id, + (u16)r->eax, r->edx, r->ebx, r->ecx, (u16)vcpu->vmcs.guest_ES_selector, (u16)r->edi); + + //HALT_ON_ERRORCOND(r->edx == 0x534D4150UL); //'SMAP' should be specified by guest + //HALT_ON_ERRORCOND(r->ebx < rpb->XtVmmE820NumEntries); //invalid continuation value specified by guest! + if( (r->edx == 0x534D4150UL) && (r->ebx < rpb->XtVmmE820NumEntries) ){ + + //copy the e820 descriptor and return its size in ECX + { + + if( ((sla_t)(vcpu->vmcs.guest_ES_base+(u16)r->edi)) < rpb->XtVmmRuntimePhysBase){ + GRUBE820 *pe820entry; + #ifdef __XMHF_VERIFICATION__ + GRUBE820 e820entry; + pe820entry = &e820entry; + #else + pe820entry = (GRUBE820 *)((sla_t)(vcpu->vmcs.guest_ES_base+(u16)r->edi)); + #endif //__XMHF_VERIFICATION__ + pe820entry->baseaddr_low = g_e820map[r->ebx].baseaddr_low; + pe820entry->baseaddr_high = g_e820map[r->ebx].baseaddr_high; + pe820entry->length_low = g_e820map[r->ebx].length_low; + pe820entry->length_high = g_e820map[r->ebx].length_high; + pe820entry->type = g_e820map[r->ebx].type; + /* + * 64-bit: Check whether exceed supported memory. + * 32-bit: Continue even if machine has physical memory > 4G + */ +#ifdef __AMD64__ + { + u64 baseaddr = (((u64)pe820entry->baseaddr_high) << 32) | + pe820entry->baseaddr_low; + u64 length = (((u64)pe820entry->length_high) << 32) | + pe820entry->length_low; + HALT_ON_ERRORCOND(baseaddr + length <= MAX_PHYS_ADDR); + } +#elif !defined(__I386__) + #error "Unsupported Arch" +#endif /* !defined(__I386__) */ + }else{ + printf("\nCPU(0x%02x): INT15 E820. Guest buffer is beyond guest " + "physical memory bounds. Halting!", vcpu->id); + HALT(); + } + + } + r->ecx=20; + + //set EAX to 'SMAP' as required by the service call + r->eax=r->edx; + + //we need to update carry flag in the guest EFLAGS register + //however since INT 15 would have pushed the guest FLAGS on stack + //we cannot simply reflect the change by modifying vmcb->rflags + //instead we need to make the change to the pushed FLAGS register on + //the guest stack. the real-mode IRET frame looks like the following + //when viewed at top of stack + //guest_ip (16-bits) + //guest_cs (16-bits) + //guest_flags (16-bits) + //... + + { + //u16 guest_cs, guest_ip, guest_flags; + u16 guest_cs __attribute__((unused)), guest_ip __attribute__((unused)), guest_flags; + /* Truncate RSP to 16 bits, (higher bits not used in real mode) */ + u16 *gueststackregion = (u16 *)( (hva_t)vcpu->vmcs.guest_SS_base + (u16)vcpu->vmcs.guest_RSP ); + + + //if V86 mode translate the virtual address to physical address + if( (vcpu->vmcs.guest_CR0 & CR0_PE) && (vcpu->vmcs.guest_CR0 & CR0_PG) && + (vcpu->vmcs.guest_RFLAGS & EFLAGS_VM) ){ + #ifdef __XMHF_VERIFICATION__ + u8 *gueststackregionphysical = (u8 *)nondet_u32(); + #else + u8 *gueststackregionphysical = (u8 *)xmhf_smpguest_arch_x86vmx_walk_pagetables(vcpu, (hva_t)gueststackregion); + #endif + if((sla_t)gueststackregionphysical < rpb->XtVmmRuntimePhysBase){ + printf("\nINT15 (E820): V86 mode, gueststackregion translated from %08x to %08x", + (hva_t)gueststackregion, (sla_t)gueststackregionphysical); + gueststackregion = (u16 *)gueststackregionphysical; + }else{ + printf("\nCPU(0x%02x): INT15 (E820) V86 mode, translated gueststackregion points beyond \ + guest physical memory space. Halting!", vcpu->id); + HALT(); + } + } + + + //get guest IP, CS and FLAGS from the IRET frame + #ifdef __XMHF_VERIFICATION__ + guest_ip = nondet_u16(); + guest_cs = nondet_u16(); + guest_flags = nondet_u16(); + #else + guest_ip = gueststackregion[0]; + guest_cs = gueststackregion[1]; + guest_flags = gueststackregion[2]; + #endif //__XMHF_VERIFICATION__ + + + //increment e820 descriptor continuation value + r->ebx=r->ebx+1; + if (r->ebx >= rpb->XtVmmE820NumEntries) { + //we have reached the last record, so make EBX=0 + r->ebx=0; + } + + // clear CF when success + guest_flags &= ~(u16)EFLAGS_CF; + #ifndef __XMHF_VERIFICATION__ + gueststackregion[2] = guest_flags; + #endif + + } + + }else{ //invalid state specified during INT 15 E820, fail by + //setting carry flag + printf("\nCPU(0x%02x): INT15 (E820), invalid state specified by guest \ + Halting!", vcpu->id); + HALT(); + } + + //update RIP to execute the IRET following the VMCALL instruction + //effectively returning from the INT 15 call made by the guest + vcpu->vmcs.guest_RIP += vcpu->vmcs.info_vmexit_instruction_length; + + return; + } //E820 service + + //ok, this is some other INT 15h service, so simply chain to the original + //INT 15h handler + +#ifdef __XMHF_VERIFICATION__ + //get IP and CS of the original INT 15h handler + ip = nondet_u16(); + cs = nondet_u16(); +#else + //get IP and CS of the original INT 15h handler + ip = *((u16 *)((hva_t)bdamemory + 4)); + cs = *((u16 *)((hva_t)bdamemory + 6)); +#endif + + //update VMCS with the CS and IP and let go + vcpu->vmcs.guest_RIP = ip; + vcpu->vmcs.guest_CS_base = cs * 16; + vcpu->vmcs.guest_CS_selector = cs; +} + + + + +//------------------------------------------------------------------------------ +// guest MSR r/w intercept handling +// HAL invokes NT kernel via SYSENTER if CPU supports it. However, +// regular apps using NTDLL will still use INT 2E if registry entry is not +// tweaked. So, we HAVE to emulate SYSENTER_CS/EIP/ESP to ensure that +// NT kernel doesnt panic with SESSION5_INITIALIZATION_FAILED! +// +// This took me nearly a month of disassembly into the HAL, +// NTKERNEL and debugging to figure out..eh? +// +// AMD SVM is neater, only +// when you ask for these MSR intercepts do they get stored and read from +// the VMCB. However, for Intel regardless they get stored and read from VMCS +// for the guest. So we need to have these intercepts bare minimum!! +// A line to this effect would have been much appreciated in the Intel manuals +// doh!!! +//------------------------------------------------------------------------------ + +//---intercept handler (WRMSR)-------------------------------------------------- +static void _vmx_handle_intercept_wrmsr(VCPU *vcpu, struct regs *r){ + u64 write_data = ((u64)r->edx << 32) | (u64)r->eax; + + //printf("\nCPU(0x%02x): WRMSR 0x%08x 0x%08x%08x @ %p", vcpu->id, r->ecx, r->edx, r->eax, vcpu->vmcs.guest_RIP); + + switch(r->ecx){ + case IA32_SYSENTER_CS_MSR: + vcpu->vmcs.guest_SYSENTER_CS = (u32)write_data; + break; + case IA32_SYSENTER_EIP_MSR: + vcpu->vmcs.guest_SYSENTER_EIP = (u64)write_data; + break; + case IA32_SYSENTER_ESP_MSR: + vcpu->vmcs.guest_SYSENTER_ESP = (u64)write_data; + break; + case IA32_MSR_FS_BASE: + vcpu->vmcs.guest_FS_base = (u64)write_data; + break; + case IA32_MSR_GS_BASE: + vcpu->vmcs.guest_GS_base = (u64)write_data; + break; + case MSR_EFER: /* fallthrough */ + case MSR_IA32_PAT: /* fallthrough */ + case MSR_K6_STAR: { + u32 found = 0; + for (u32 i = 0; i < vcpu->vmcs.control_VM_entry_MSR_load_count; i++) { + msr_entry_t *entry = &((msr_entry_t *)vcpu->vmx_vaddr_msr_area_guest)[i]; + if (entry->index == r->ecx) { + entry->data = write_data; + found = 1; + break; + } + } + HALT_ON_ERRORCOND(found != 0); + break; + } + case IA32_MTRRCAP: /* fallthrough */ + case IA32_MTRR_DEF_TYPE: /* fallthrough */ + case IA32_MTRR_FIX64K_00000: /* fallthrough */ + case IA32_MTRR_FIX16K_80000: /* fallthrough */ + case IA32_MTRR_FIX16K_A0000: /* fallthrough */ + case IA32_MTRR_FIX4K_C0000: /* fallthrough */ + case IA32_MTRR_FIX4K_C8000: /* fallthrough */ + case IA32_MTRR_FIX4K_D0000: /* fallthrough */ + case IA32_MTRR_FIX4K_D8000: /* fallthrough */ + case IA32_MTRR_FIX4K_E0000: /* fallthrough */ + case IA32_MTRR_FIX4K_E8000: /* fallthrough */ + case IA32_MTRR_FIX4K_F0000: /* fallthrough */ + case IA32_MTRR_FIX4K_F8000: /* fallthrough */ + case IA32_MTRR_PHYSBASE0: /* fallthrough */ + case IA32_MTRR_PHYSMASK0: /* fallthrough */ + case IA32_MTRR_PHYSBASE1: /* fallthrough */ + case IA32_MTRR_PHYSMASK1: /* fallthrough */ + case IA32_MTRR_PHYSBASE2: /* fallthrough */ + case IA32_MTRR_PHYSMASK2: /* fallthrough */ + case IA32_MTRR_PHYSBASE3: /* fallthrough */ + case IA32_MTRR_PHYSMASK3: /* fallthrough */ + case IA32_MTRR_PHYSBASE4: /* fallthrough */ + case IA32_MTRR_PHYSMASK4: /* fallthrough */ + case IA32_MTRR_PHYSBASE5: /* fallthrough */ + case IA32_MTRR_PHYSMASK5: /* fallthrough */ + case IA32_MTRR_PHYSBASE6: /* fallthrough */ + case IA32_MTRR_PHYSMASK6: /* fallthrough */ + case IA32_MTRR_PHYSBASE7: /* fallthrough */ + case IA32_MTRR_PHYSMASK7: /* fallthrough */ + case IA32_MTRR_PHYSBASE8: /* fallthrough */ + case IA32_MTRR_PHYSMASK8: /* fallthrough */ + case IA32_MTRR_PHYSBASE9: /* fallthrough */ + case IA32_MTRR_PHYSMASK9: + /* + * Need to change EPT to reflect MTRR changes, because host MTRRs + * are not used when EPT is used. + */ + if (xmhf_memprot_arch_x86vmx_mtrr_write(vcpu, r->ecx, write_data)) { + /* + * When designed, xmhf_memprot_arch_x86vmx_mtrr_write() has not + * been observed to fail. This may happen if the guest OS + * performs an invalid WRMSR. Please make sure that in this + * case injecting #GP is the correct action. + */ + HALT_ON_ERRORCOND(0 && "Unexperienced fail in MTRR write"); + goto wrmsr_inject_gp; + } + break; + case IA32_BIOS_UPDT_TRIG: +#ifdef __UPDATE_INTEL_UCODE__ + printf("\nCPU(0x%02x): OS tries to write microcode!", vcpu->id); + printf("\ngva for microcode update: 0x%016llx", write_data); + handle_intel_ucode_update(vcpu, write_data); +#else /* !__UPDATE_INTEL_UCODE__ */ + printf("\nCPU(0x%02x): OS tries to write microcode, ignore", + vcpu->id); +#endif /* __UPDATE_INTEL_UCODE__ */ + break; + case IA32_X2APIC_ICR: + if (xmhf_smpguest_arch_x86vmx_eventhandler_x2apic_icrwrite(vcpu, r) == 0) { + /* Forward to physical APIC */ + asm volatile ("wrmsr\r\n" + : //no outputs + :"a"(r->eax), "c" (r->ecx), "d" (r->edx)); + } + break; + default:{ + asm volatile ("wrmsr\r\n" + : //no outputs + :"a"(r->eax), "c" (r->ecx), "d" (r->edx)); + break; + } + } + + vcpu->vmcs.guest_RIP += vcpu->vmcs.info_vmexit_instruction_length; + //printf("\nCPU(0x%02x): WRMSR end", vcpu->id); + return; + +wrmsr_inject_gp: + { + /* Inject a Hardware exception #GP */ + union { + struct _vmx_event_injection st; + uint32_t ui; + } injection_info; + injection_info.ui = 0; + injection_info.st.vector = 0xd; /* #GP */ + injection_info.st.type = 0x3; /* Hardware Exception */ + injection_info.st.errorcode = 1; /* Deliver error code */ + injection_info.st.valid = 1; + vcpu->vmcs.control_VM_entry_interruption_information = injection_info.ui; + vcpu->vmcs.control_VM_entry_exception_errorcode = 0; + /* Do not increase guest RIP */ + return; + } +} + +//---intercept handler (RDMSR)-------------------------------------------------- +static void _vmx_handle_intercept_rdmsr(VCPU *vcpu, struct regs *r){ + /* After switch statement, will assign this value to r->eax and r->edx */ + u64 read_result = 0; + + //printf("\nCPU(0x%02x): RDMSR 0x%08x @ %p", vcpu->id, r->ecx, vcpu->vmcs.guest_RIP); + + switch(r->ecx){ + case IA32_SYSENTER_CS_MSR: + read_result = (u64)vcpu->vmcs.guest_SYSENTER_CS; + break; + case IA32_SYSENTER_EIP_MSR: + read_result = (u64)vcpu->vmcs.guest_SYSENTER_EIP; + break; + case IA32_SYSENTER_ESP_MSR: + read_result = (u64)vcpu->vmcs.guest_SYSENTER_ESP; + break; + case IA32_MSR_FS_BASE: + read_result = (u64)vcpu->vmcs.guest_FS_base; + break; + case IA32_MSR_GS_BASE: + read_result = (u64)vcpu->vmcs.guest_GS_base; + break; + case MSR_EFER: /* fallthrough */ + case MSR_IA32_PAT: /* fallthrough */ + case MSR_K6_STAR: { + u32 found = 0; + for (u32 i = 0; i < vcpu->vmcs.control_VM_exit_MSR_store_count; i++) { + msr_entry_t *entry = &((msr_entry_t *)vcpu->vmx_vaddr_msr_area_guest)[i]; + if (entry->index == r->ecx) { + read_result = entry->data; + found = 1; + break; + } + } + HALT_ON_ERRORCOND(found != 0); + break; + } + case IA32_MTRR_DEF_TYPE: /* fallthrough */ + case IA32_MTRR_FIX64K_00000: /* fallthrough */ + case IA32_MTRR_FIX16K_80000: /* fallthrough */ + case IA32_MTRR_FIX16K_A0000: /* fallthrough */ + case IA32_MTRR_FIX4K_C0000: /* fallthrough */ + case IA32_MTRR_FIX4K_C8000: /* fallthrough */ + case IA32_MTRR_FIX4K_D0000: /* fallthrough */ + case IA32_MTRR_FIX4K_D8000: /* fallthrough */ + case IA32_MTRR_FIX4K_E0000: /* fallthrough */ + case IA32_MTRR_FIX4K_E8000: /* fallthrough */ + case IA32_MTRR_FIX4K_F0000: /* fallthrough */ + case IA32_MTRR_FIX4K_F8000: /* fallthrough */ + case IA32_MTRR_PHYSBASE0: /* fallthrough */ + case IA32_MTRR_PHYSMASK0: /* fallthrough */ + case IA32_MTRR_PHYSBASE1: /* fallthrough */ + case IA32_MTRR_PHYSMASK1: /* fallthrough */ + case IA32_MTRR_PHYSBASE2: /* fallthrough */ + case IA32_MTRR_PHYSMASK2: /* fallthrough */ + case IA32_MTRR_PHYSBASE3: /* fallthrough */ + case IA32_MTRR_PHYSMASK3: /* fallthrough */ + case IA32_MTRR_PHYSBASE4: /* fallthrough */ + case IA32_MTRR_PHYSMASK4: /* fallthrough */ + case IA32_MTRR_PHYSBASE5: /* fallthrough */ + case IA32_MTRR_PHYSMASK5: /* fallthrough */ + case IA32_MTRR_PHYSBASE6: /* fallthrough */ + case IA32_MTRR_PHYSMASK6: /* fallthrough */ + case IA32_MTRR_PHYSBASE7: /* fallthrough */ + case IA32_MTRR_PHYSMASK7: /* fallthrough */ + case IA32_MTRR_PHYSBASE8: /* fallthrough */ + case IA32_MTRR_PHYSMASK8: /* fallthrough */ + case IA32_MTRR_PHYSBASE9: /* fallthrough */ + case IA32_MTRR_PHYSMASK9: + /* + * When reading MTRR MSRs, IA32_MTRRCAP is the same as host's MSR. + * Other MTRR MSRs come from the shadow in vcpu. + */ + if (xmhf_memprot_arch_x86vmx_mtrr_read(vcpu, r->ecx, &read_result)) { + /* + * When designed, xmhf_memprot_arch_x86vmx_mtrr_read() cannot + * fail. Please make sure injecting #GP is the correct action. + */ + HALT_ON_ERRORCOND(0 && "Unexpected fail in MTRR read"); + goto rdmsr_inject_gp; + } + break; + case IA32_X2APIC_ICR: + // TODO: we can probably just forward it to hardware x2APIC + HALT_ON_ERRORCOND(0 && "TODO: x2APIC ICR read not implemented"); + break; + default:{ + if (rdmsr_safe(r) != 0) { + goto rdmsr_inject_gp; + } + goto no_assign_read_result; + } + } + + /* Assign read_result to r->eax and r->edx */ + { +#ifdef __AMD64__ + r->rax = 0; /* Clear upper 32-bits of RAX */ + r->rdx = 0; /* Clear upper 32-bits of RDX */ +#elif !defined(__I386__) + #error "Unsupported Arch" +#endif /* !defined(__I386__) */ + r->eax = (u32)(read_result); + r->edx = (u32)(read_result >> 32); + } + + //printf("\nCPU(0x%02x): RDMSR (0x%08x)=0x%08x%08x", vcpu->id, r->ecx, r->edx, r->eax); + +no_assign_read_result: + vcpu->vmcs.guest_RIP += vcpu->vmcs.info_vmexit_instruction_length; + return; + +rdmsr_inject_gp: + { + /* Inject a Hardware exception #GP */ + union { + struct _vmx_event_injection st; + uint32_t ui; + } injection_info; + injection_info.ui = 0; + injection_info.st.vector = 0xd; /* #GP */ + injection_info.st.type = 0x3; /* Hardware Exception */ + injection_info.st.errorcode = 1; /* Deliver error code */ + injection_info.st.valid = 1; + vcpu->vmcs.control_VM_entry_interruption_information = injection_info.ui; + vcpu->vmcs.control_VM_entry_exception_errorcode = 0; + /* Do not increase guest RIP */ + return; + } +} + + +//---intercept handler (EPT voilation)---------------------------------- +static void _vmx_handle_intercept_eptviolation(VCPU *vcpu, struct regs *r){ + ulong_t errorcode; + uintptr_t gva; + u64 gpa; + errorcode = (ulong_t)vcpu->vmcs.info_exit_qualification; + gpa = vcpu->vmcs.guest_paddr; + gva = (uintptr_t)vcpu->vmcs.info_guest_linear_address; + + //check if EPT violation is due to LAPIC interception + if(vcpu->isbsp && (gpa >= g_vmx_lapic_base) && (gpa < (g_vmx_lapic_base + PAGE_SIZE_4K)) ){ + xmhf_smpguest_arch_x86_eventhandler_hwpgtblviolation(vcpu, (u32)gpa, errorcode); + }else{ //no, pass it to hypapp + xmhf_smpguest_arch_x86vmx_quiesce(vcpu); + xmhf_app_handleintercept_hwpgtblviolation(vcpu, r, gpa, gva, + (errorcode & 7)); + xmhf_smpguest_arch_x86vmx_endquiesce(vcpu); + } +} + + +//---intercept handler (I/O port access)---------------------------------------- +static void _vmx_handle_intercept_ioportaccess(VCPU *vcpu, struct regs *r){ + u32 access_size, access_type, portnum, stringio; + u32 app_ret_status = APP_IOINTERCEPT_CHAIN; + + access_size = (u32)vcpu->vmcs.info_exit_qualification & 0x00000007UL; + access_type = ((u32)vcpu->vmcs.info_exit_qualification & 0x00000008UL) >> 3; + portnum = ((u32)vcpu->vmcs.info_exit_qualification & 0xFFFF0000UL) >> 16; + stringio = ((u32)vcpu->vmcs.info_exit_qualification & 0x00000010UL) >> 4; + + HALT_ON_ERRORCOND(!stringio); //we dont handle string IO intercepts + + //call our app handler, TODO: it should be possible for an app to + //NOT want a callback by setting up some parameters during appmain + xmhf_smpguest_arch_x86vmx_quiesce(vcpu); + app_ret_status=xmhf_app_handleintercept_portaccess(vcpu, r, portnum, access_type, + access_size); + xmhf_smpguest_arch_x86vmx_endquiesce(vcpu); + + if(app_ret_status == APP_IOINTERCEPT_CHAIN){ + if(access_type == IO_TYPE_OUT){ + if( access_size== IO_SIZE_BYTE) + outb((u8)r->eax, portnum); + else if (access_size == IO_SIZE_WORD) + outw((u16)r->eax, portnum); + else if (access_size == IO_SIZE_DWORD) + outl((u32)r->eax, portnum); + }else{ + if( access_size== IO_SIZE_BYTE){ + r->eax &= 0xFFFFFF00UL; //clear lower 8 bits + r->eax |= (u8)inb(portnum); + }else if (access_size == IO_SIZE_WORD){ + r->eax &= 0xFFFF0000UL; //clear lower 16 bits + r->eax |= (u16)inw(portnum); + }else if (access_size == IO_SIZE_DWORD){ + r->eax = (u32)inl(portnum); + } + } + vcpu->vmcs.guest_RIP += vcpu->vmcs.info_vmexit_instruction_length; + + }else{ + //skip the IO instruction, app has taken care of it + vcpu->vmcs.guest_RIP += vcpu->vmcs.info_vmexit_instruction_length; + } + + return; +} + + +//---CR0 access handler------------------------------------------------- +static void vmx_handle_intercept_cr0access_ug(VCPU *vcpu, struct regs *r, u32 gpr, u32 tofrom){ + u64 cr0_value, old_cr0; + u64 fixed_1_fields; + + HALT_ON_ERRORCOND(tofrom == VMX_CRX_ACCESS_TO); + + cr0_value = *((uintptr_t *)_vmx_decode_reg(gpr, vcpu, r)); + old_cr0 = vcpu->vmcs.guest_CR0; + + //printf("\n[cr0-%02x] MOV TO, old=0x%08llx, new=0x%08llx, shadow=0x%08llx", + // vcpu->id, old_cr0, cr0_value, vcpu->vmcs.control_CR0_shadow); + + /* + * Make the guest think that move to CR0 succeeds (by changing shadow). + * + * control_CR0_mask is set in vmx_initunrestrictedguestVMCS(). The mask + * is the IA32_VMX_CR0_FIXED0 MSR, with PE and PG unset, CD and NW set. + * + * Intel manual says that exceptions to fixed CR0 are CD NW PG PE. + * + * So for all set bits in control_CR0_mask, we force CD and NW to be not + * set, and other bits to be set. + */ + + fixed_1_fields = vcpu->vmcs.control_CR0_mask; + vcpu->vmcs.control_CR0_shadow = cr0_value; + vcpu->vmcs.guest_CR0 = (cr0_value | fixed_1_fields) & ~(CR0_CD | CR0_NW); + + /* + * If CR0.PG, need to update a lot of things for PAE and long mode support. + * As a workaround, we let the guest retry setting CR0.PG and CR0.PE. This + * way we do not need to calculate the VMCS fields in hypervisor. + */ + if ((old_cr0 ^ cr0_value) & CR0_PG) { + u64 pg_pe_mask = (CR0_PG | CR0_PE); + /* Make sure that CR0.PG and CR0.PE are not masked */ + if (!(pg_pe_mask & vcpu->vmcs.control_CR0_mask)) { + /* + * The original MOV CR0 must also change some bits not related to + * CR0.PG or CR0.PE. + */ + HALT_ON_ERRORCOND((old_cr0 ^ cr0_value) & ~pg_pe_mask); + /* + * Change VMCS's guest CR0 to requested value, except CR0.PG and + * CR0.PE. + */ + vcpu->vmcs.guest_CR0 &= ~pg_pe_mask; + vcpu->vmcs.guest_CR0 |= old_cr0 & pg_pe_mask; + //printf("\n[cr0-%02x] RETRY: old=0x%08llx", vcpu->id, + // vcpu->vmcs.guest_CR0); + /* Sanity check: for bits masked, requested value = CR0 shadow */ + HALT_ON_ERRORCOND( + ((cr0_value ^ vcpu->vmcs.control_CR0_shadow) & + vcpu->vmcs.control_CR0_mask) == 0); + /* + * Sanity check: for bits not masked other than CR0.PG and CR0.PE, + * guest CR0 = requested new value. + */ + HALT_ON_ERRORCOND( + ((vcpu->vmcs.guest_CR0 ^ cr0_value) & + ~vcpu->vmcs.control_CR0_mask & ~pg_pe_mask) == 0); + /* Skip incrementing PC (RIP / EIP), retry this instruction */ + return; + } + } + + /* + * If CR0.PG bit changes, need to update guest_PDPTE0 - guest_PDPTE3 if + * PAE is enabled. + * + * x86 XMHF cannot support PAE guests easily because the hypervisor cannot + * access memory above 4GB. + * + * To support amd64 guests, also need to update bit 9 of VM-Entry Controls + * (IA-32e mode guest). This bit should always equal to EFER.LME && CR0.PG + */ + if ((old_cr0 ^ cr0_value) & CR0_PG) { +#ifdef __AMD64__ + u32 value = vcpu->vmcs.control_VM_entry_controls; + u32 lme, pae; + msr_entry_t *efer = &((msr_entry_t *)vcpu->vmx_vaddr_msr_area_guest)[0]; + HALT_ON_ERRORCOND(efer->index == MSR_EFER); + lme = (cr0_value & CR0_PG) && (efer->data & (0x1U << EFER_LME)); + value &= ~(1U << 9); + value |= lme << 9; + vcpu->vmcs.control_VM_entry_controls = value; + + pae = (cr0_value & CR0_PG) && (!lme) && (vcpu->vmcs.guest_CR4 & CR4_PAE); + /* + * TODO: If PAE, need to walk EPT and retrieve values for guest_PDPTE* + * + * The idea is something like the following, but need to make sure + * the guest OS is allowed to access relevant memory (by walking EPT): + * u64 *pdptes = (u64 *)(uintptr_t)(vcpu->vmcs.guest_CR3 & ~0x1FUL); + * vcpu->vmcs.guest_PDPTE0 = pdptes[0]; + * vcpu->vmcs.guest_PDPTE1 = pdptes[1]; + * vcpu->vmcs.guest_PDPTE2 = pdptes[2]; + * vcpu->vmcs.guest_PDPTE3 = pdptes[3]; + */ +#elif defined(__I386__) + u32 pae = (cr0_value & CR0_PG) && (vcpu->vmcs.guest_CR4 & CR4_PAE); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + HALT_ON_ERRORCOND(!pae); + } + + //flush mappings + xmhf_memprot_arch_x86vmx_flushmappings(vcpu); + + vcpu->vmcs.guest_RIP += vcpu->vmcs.info_vmexit_instruction_length; +} + +//---CR4 access handler--------------------------------------------------------- +static void vmx_handle_intercept_cr4access_ug(VCPU *vcpu, struct regs *r, u32 gpr, u32 tofrom){ + if(tofrom == VMX_CRX_ACCESS_TO){ + u64 cr4_proposed_value; + + cr4_proposed_value = *((uintptr_t *)_vmx_decode_reg(gpr, vcpu, r)); + + printf("\nCPU(0x%02x): CS:EIP=0x%04x:0x%08x MOV CR4, xx", vcpu->id, + (u16)vcpu->vmcs.guest_CS_selector, (u32)vcpu->vmcs.guest_RIP); + + printf("\nMOV TO CR4 (flush TLB?), current=0x%08x, proposed=0x%08x", + (u32)vcpu->vmcs.guest_CR4, cr4_proposed_value); + + /* + * CR4 mask is the IA32_VMX_CR4_FIXED0 MSR. Modify CR4 shadow to let the + * guest think MOV CR4 succeeds. + */ + vcpu->vmcs.control_CR4_shadow = cr4_proposed_value; + vcpu->vmcs.guest_CR4 = (cr4_proposed_value | vcpu->vmcs.control_CR4_mask); + + #if defined (__NESTED_PAGING__) + //we need to flush EPT mappings as we emulated CR4 load above + __vmx_invvpid(VMX_INVVPID_SINGLECONTEXT, 1, 0); + #endif + } + + vcpu->vmcs.guest_RIP += vcpu->vmcs.info_vmexit_instruction_length; +} + +//---XSETBV intercept handler------------------------------------------- +static void _vmx_handle_intercept_xsetbv(VCPU *vcpu, struct regs *r){ + u64 xcr_value; + + xcr_value = ((u64)r->edx << 32) + (u64)r->eax; + + if(r->ecx != XCR_XFEATURE_ENABLED_MASK){ + printf("\n%s: unhandled XCR register %u", __FUNCTION__, r->ecx); + HALT(); + } + + //XXX: TODO: check for invalid states and inject GP accordingly + + printf("\n%s: xcr_value=%llx", __FUNCTION__, xcr_value); + + //XXX: debug: dump CR4 contents + { + u32 t_cr4; + t_cr4 = read_cr4(); + printf("\n%s: host cr4 value=%08x", __FUNCTION__, t_cr4); + } + + //set XCR with supplied value + xsetbv(XCR_XFEATURE_ENABLED_MASK, xcr_value); + + //skip the emulated XSETBV instruction + vcpu->vmcs.guest_RIP += vcpu->vmcs.info_vmexit_instruction_length; +} + + +#ifdef __OPTIMIZE_NESTED_VIRT__ + +#define READ_VMCS(encoding, target) \ + do { \ + unsigned long field; \ + HALT_ON_ERRORCOND(__vmx_vmread((encoding), &field)); \ + target = field; \ + } while(0) + +#define WRITE_VMCS(encoding, target) \ + do { \ + unsigned long field; \ + field = (unsigned long) target; \ + HALT_ON_ERRORCOND(__vmx_vmwrite((encoding), field)); \ + } while(0) + +/* + * Optimize xmhf_parteventhub_arch_x86vmx_intercept_handler for some frequently + * used intercepts observed in real operating systems. This reduces number of + * VMREAD / VMWRITE during the intercepts and speeds up when XMHF is running in + * a hypervisor. + * + * The optimizations depend on the logic in the specific handlers. For example, + * if _vmx_handle_intercept_cpuid() accesses more VMCS fields, then the + * optimization may become incorrect. + * + * Return 1 if optimized, or 0 if not optimized. + */ +static u32 _optimize_x86vmx_intercept_handler(VCPU *vcpu, struct regs *r){ + READ_VMCS(0x4402, vcpu->vmcs.info_vmexit_reason); + + switch ((u32)vcpu->vmcs.info_vmexit_reason) { + case VMX_VMEXIT_WRMSR: + /* Only optimize WRMSR for some MSRs */ + switch (r->ecx) { + case 0x6e0: /* IA32_TSC_DEADLINE */ + /* fallthrough */ + case 0x80b: /* IA32_X2APIC_EOI */ + READ_VMCS(0x681E, vcpu->vmcs.guest_RIP); + READ_VMCS(0x440C, vcpu->vmcs.info_vmexit_instruction_length); + _vmx_handle_intercept_wrmsr(vcpu, r); + WRITE_VMCS(0x681E, vcpu->vmcs.guest_RIP); + return 1; + default: + return 0; + } + case VMX_VMEXIT_CPUID: + /* Always optimize CPUID */ + READ_VMCS(0x681E, vcpu->vmcs.guest_RIP); + READ_VMCS(0x440C, vcpu->vmcs.info_vmexit_instruction_length); + _vmx_handle_intercept_cpuid(vcpu, r); + WRITE_VMCS(0x681E, vcpu->vmcs.guest_RIP); + return 1; + case VMX_VMEXIT_EPT_VIOLATION: { + /* Optimize EPT violation due to LAPIC */ + u64 gpa; + READ_VMCS(0x2400, vcpu->vmcs.guest_paddr); + gpa = vcpu->vmcs.guest_paddr; + if(vcpu->isbsp && (gpa >= g_vmx_lapic_base) && (gpa < (g_vmx_lapic_base + PAGE_SIZE_4K)) ){ + READ_VMCS(0x6400, vcpu->vmcs.info_exit_qualification); + READ_VMCS(0x4004, vcpu->vmcs.control_exception_bitmap); + READ_VMCS(0x4824, vcpu->vmcs.guest_interruptibility); + READ_VMCS(0x6820, vcpu->vmcs.guest_RFLAGS); +#ifdef __I386__ + READ_VMCS(0x201A, vcpu->vmcs.control_EPT_pointer_full); + READ_VMCS(0x201B, vcpu->vmcs.control_EPT_pointer_high); +#elif defined(__AMD64__) + READ_VMCS(0x201A, vcpu->vmcs.control_EPT_pointer); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + _vmx_handle_intercept_eptviolation(vcpu, r); + WRITE_VMCS(0x4004, vcpu->vmcs.control_exception_bitmap); + WRITE_VMCS(0x4824, vcpu->vmcs.guest_interruptibility); + WRITE_VMCS(0x6820, vcpu->vmcs.guest_RFLAGS); + return 1; + } + return 0; + } + case VMX_VMEXIT_EXCEPTION: + /* Optimize debug exception (#DB) for LAPIC operation */ + READ_VMCS(0x4404, vcpu->vmcs.info_vmexit_interrupt_information); + if (((u32)vcpu->vmcs.info_vmexit_interrupt_information & + INTR_INFO_VECTOR_MASK) == 1) { + READ_VMCS(0x0802, vcpu->vmcs.guest_CS_selector); + READ_VMCS(0x681E, vcpu->vmcs.guest_RIP); + READ_VMCS(0x4004, vcpu->vmcs.control_exception_bitmap); + READ_VMCS(0x4824, vcpu->vmcs.guest_interruptibility); + READ_VMCS(0x6820, vcpu->vmcs.guest_RFLAGS); +#ifdef __I386__ + READ_VMCS(0x201A, vcpu->vmcs.control_EPT_pointer_full); + READ_VMCS(0x201B, vcpu->vmcs.control_EPT_pointer_high); +#elif defined(__AMD64__) + READ_VMCS(0x201A, vcpu->vmcs.control_EPT_pointer); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + xmhf_smpguest_arch_x86_eventhandler_dbexception(vcpu, r); + WRITE_VMCS(0x4004, vcpu->vmcs.control_exception_bitmap); + WRITE_VMCS(0x4824, vcpu->vmcs.guest_interruptibility); + WRITE_VMCS(0x6820, vcpu->vmcs.guest_RFLAGS); + return 1; + } + return 0; + default: + return 0; + } +} + +#undef READ_VMCS +#undef WRITE_VMCS + +#endif /* __OPTIMIZE_NESTED_VIRT__ */ + + +//---hvm_intercept_handler------------------------------------------------------ +u32 xmhf_parteventhub_arch_x86vmx_intercept_handler(VCPU *vcpu, struct regs *r){ +#ifdef __OPTIMIZE_NESTED_VIRT__ + if (_optimize_x86vmx_intercept_handler(vcpu, r)) { + return 1; + } +#endif /* __OPTIMIZE_NESTED_VIRT__ */ + //read VMCS from physical CPU/core +#ifndef __XMHF_VERIFICATION__ + xmhf_baseplatform_arch_x86vmx_getVMCS(vcpu); +#endif //__XMHF_VERIFICATION__ + //sanity check for VM-entry errors + if( (u32)vcpu->vmcs.info_vmexit_reason & 0x80000000UL ){ + printf("\nCPU(0x%02x): VM-ENTRY error: reason=0x%08x, qualification=0x%016llx", + vcpu->id, (u32)vcpu->vmcs.info_vmexit_reason, + (u64)vcpu->vmcs.info_exit_qualification); + xmhf_baseplatform_arch_x86vmx_dumpVMCS(vcpu); + HALT(); + } + + /* + * Cannot print anything before event handler returns if this intercept + * is for quiescing (vcpu->vmcs.info_vmexit_reason == VMX_VMEXIT_EXCEPTION), + * otherwise will deadlock. See xmhf_smpguest_arch_x86vmx_quiesce(). + */ +// if (vcpu->vmcs.info_vmexit_reason != VMX_VMEXIT_EXCEPTION) { +// printf("{%d,%d}", vcpu->id, (u32)vcpu->vmcs.info_vmexit_reason); +// } + + //handle intercepts + switch((u32)vcpu->vmcs.info_vmexit_reason){ + //-------------------------------------------------------------- + //xmhf-core and hypapp intercepts + //-------------------------------------------------------------- + + case VMX_VMEXIT_VMCALL:{ + //if INT 15h E820 hypercall, then let the xmhf-core handle it + if(vcpu->vmcs.guest_CS_base == (VMX_UG_E820HOOK_CS << 4) && + vcpu->vmcs.guest_RIP == VMX_UG_E820HOOK_IP){ + //we need to be either in real-mode or in protected + //mode with paging and EFLAGS.VM bit set (virtual-8086 mode) + HALT_ON_ERRORCOND( !(vcpu->vmcs.guest_CR0 & CR0_PE) || + ( (vcpu->vmcs.guest_CR0 & CR0_PE) && (vcpu->vmcs.guest_CR0 & CR0_PG) && + (vcpu->vmcs.guest_RFLAGS & EFLAGS_VM) ) ); + _vmx_int15_handleintercept(vcpu, r); + }else{ //if not E820 hook, give hypapp a chance to handle the hypercall + xmhf_smpguest_arch_x86vmx_quiesce(vcpu); + if( xmhf_app_handlehypercall(vcpu, r) != APP_SUCCESS){ + printf("\nCPU(0x%02x): error(halt), unhandled hypercall 0x%08x!", vcpu->id, r->eax); + HALT(); + } + xmhf_smpguest_arch_x86vmx_endquiesce(vcpu); + vcpu->vmcs.guest_RIP += vcpu->vmcs.info_vmexit_instruction_length; + } + } + break; + + case VMX_VMEXIT_IOIO:{ + _vmx_handle_intercept_ioportaccess(vcpu, r); + } + break; + + case VMX_VMEXIT_EPT_VIOLATION:{ + _vmx_handle_intercept_eptviolation(vcpu, r); + } + break; + + case VMX_VMEXIT_INIT:{ + printf("\n***** VMEXIT_INIT xmhf_app_handleshutdown\n"); + xmhf_app_handleshutdown(vcpu, r); + printf("\nCPU(0x%02x): Fatal, xmhf_app_handleshutdown returned. Halting!", vcpu->id); + HALT(); + } + break; + + //-------------------------------------------------------------- + //xmhf-core only intercepts + //-------------------------------------------------------------- + case VMX_VMEXIT_HLT: + if(!vcpu->vmx_guest_unrestricted){ + printf("\nCPU(0x%02x): V86 monitor based real-mode exec. unsupported!", vcpu->id); + HALT(); + }else{ + printf("\nCPU(0x%02x): Unexpected HLT intercept in UG, Halting!", vcpu->id); + HALT(); + } + break; + + case VMX_VMEXIT_EXCEPTION:{ + switch( ((u32)vcpu->vmcs.info_vmexit_interrupt_information & INTR_INFO_VECTOR_MASK) ){ + case 0x01: + xmhf_smpguest_arch_x86_eventhandler_dbexception(vcpu, r); + break; + + case 0x02: //NMI + #ifndef __XMHF_VERIFICATION__ + //we currently discharge quiescing via manual inspection + xmhf_smpguest_arch_x86vmx_eventhandler_nmiexception(vcpu, r, 1); + #endif // __XMHF_VERIFICATION__ + break; + + default: + printf("\nVMEXIT-EXCEPTION:"); + printf("\ncontrol_exception_bitmap=0x%08lx", + (unsigned long)vcpu->vmcs.control_exception_bitmap); + printf("\ninterruption information=0x%08lx", + (unsigned long)vcpu->vmcs.info_vmexit_interrupt_information); + printf("\nerrorcode=0x%08lx", + (unsigned long)vcpu->vmcs.info_vmexit_interrupt_error_code); + HALT(); + } + } + break; + + case VMX_VMEXIT_NMI_WINDOW: { + /* Clear NMI windowing */ + vcpu->vmcs.control_VMX_cpu_based &= ~(1U << 22); + /* Check whether the CPU can handle NMI */ + if (vcpu->vmcs.control_exception_bitmap & CPU_EXCEPTION_NMI) { + /* + * TODO: hypapp has chosen to intercept NMI so callback. + * Currently not implemented. One way is to drop the NMI + * interrupt. + * + * For example, TrustVisor should use VCPU_gnmiblock_set() to + * block NMIs when running PALs. For now, halt to make sure + * hypapp developer notices the problem. + */ + printf("\nCPU(0x%02x): HALT because dropping NMI", vcpu->id); + HALT_ON_ERRORCOND(0); + } else { + /* Inject NMI to guest */ + vcpu->vmcs.control_VM_entry_exception_errorcode = 0; + vcpu->vmcs.control_VM_entry_interruption_information = NMI_VECTOR | + INTR_TYPE_NMI | + INTR_INFO_VALID_MASK; + printf("\nCPU(0x%02x): inject NMI", vcpu->id); + } + } + break; + + case VMX_VMEXIT_CRX_ACCESS:{ + u32 tofrom, gpr, crx; + //printf("\nVMEXIT_CRX_ACCESS:"); + //printf("\ninstruction length: %u", info_vmexit_instruction_length); + crx=(u32) ((u64)vcpu->vmcs.info_exit_qualification & 0x000000000000000FULL); + gpr= + (u32) (((u64)vcpu->vmcs.info_exit_qualification & 0x0000000000000F00ULL) >> (u64)8); + tofrom = + (u32) (((u64)vcpu->vmcs.info_exit_qualification & 0x0000000000000030ULL) >> (u64)4); + //printf("\ncrx=%u, gpr=%u, tofrom=%u", crx, gpr, tofrom); + +#ifdef __AMD64__ + if ( ((int)gpr >=0) && ((int)gpr <= 15) ){ +#elif defined(__I386__) + if ( ((int)gpr >=0) && ((int)gpr <= 7) ){ +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + switch(crx){ + case 0x0: //CR0 access + vmx_handle_intercept_cr0access_ug(vcpu, r, gpr, tofrom); + break; + + case 0x4: //CR4 access + if(!vcpu->vmx_guest_unrestricted){ + printf("\nHALT: v86 monitor based real-mode exec. unsupported!"); + HALT(); + }else{ + vmx_handle_intercept_cr4access_ug(vcpu, r, gpr, tofrom); + } + break; + + default: + printf("\nunhandled crx, halting!"); + HALT(); + } + }else{ + printf("\n[%02x]%s: invalid gpr value (%u). halting!", vcpu->id, + __FUNCTION__, gpr); + HALT(); + } + } + break; + + case VMX_VMEXIT_RDMSR: + _vmx_handle_intercept_rdmsr(vcpu, r); + break; + + case VMX_VMEXIT_WRMSR: + _vmx_handle_intercept_wrmsr(vcpu, r); + break; + + case VMX_VMEXIT_CPUID: + _vmx_handle_intercept_cpuid(vcpu, r); + break; + + case VMX_VMEXIT_TASKSWITCH:{ + u32 idt_v = vcpu->vmcs.info_IDT_vectoring_information & VECTORING_INFO_VALID_MASK; + u32 type = vcpu->vmcs.info_IDT_vectoring_information & VECTORING_INFO_TYPE_MASK; + u32 reason = vcpu->vmcs.info_exit_qualification >> 30; + u16 tss_selector = (u16)vcpu->vmcs.info_exit_qualification; + + if(reason == TASK_SWITCH_GATE && type == INTR_TYPE_NMI){ + printf("\nCPU(0x%02x): NMI received (MP guest shutdown?)", vcpu->id); + xmhf_app_handleshutdown(vcpu, r); + printf("\nCPU(0x%02x): warning, xmhf_app_handleshutdown returned!", vcpu->id); + printf("\nCPU(0x%02x): HALTING!", vcpu->id); + HALT(); + }else{ + printf("\nCPU(0x%02x): Unhandled Task Switch. Halt!", vcpu->id); + printf("\n idt_v=0x%08x, type=0x%08x, reason=0x%08x, tsssel=0x%04x", + idt_v, type, reason, tss_selector); + } + HALT(); + } + break; + + case VMX_VMEXIT_XSETBV:{ + _vmx_handle_intercept_xsetbv(vcpu, r); + } + break; + + + default:{ +#ifdef __AMD64__ + if (vcpu->vmcs.control_VM_entry_controls & (1U << 9)) { + /* amd64 mode */ + printf("\nCPU(0x%02x): Unhandled intercept in long mode: %d (0x%08x)", + vcpu->id, (u32)vcpu->vmcs.info_vmexit_reason, + (u32)vcpu->vmcs.info_vmexit_reason); + printf("\n CPU(0x%02x): RFLAGS=0x%016llx", + vcpu->id, vcpu->vmcs.guest_RFLAGS); + printf("\n SS:RSP =0x%04x:0x%016llx", + (u16)vcpu->vmcs.guest_SS_selector, + vcpu->vmcs.guest_RSP); + printf("\n CS:RIP =0x%04x:0x%016llx", + (u16)vcpu->vmcs.guest_CS_selector, + vcpu->vmcs.guest_RIP); + printf("\n IDTR base:limit=0x%016llx:0x%04x", + vcpu->vmcs.guest_IDTR_base, + (u16)vcpu->vmcs.guest_IDTR_limit); + printf("\n GDTR base:limit=0x%016llx:0x%04x", + vcpu->vmcs.guest_GDTR_base, + (u16)vcpu->vmcs.guest_GDTR_limit); + if(vcpu->vmcs.info_IDT_vectoring_information & 0x80000000){ + printf("\nCPU(0x%02x): HALT; Nested events unhandled 0x%08x", + vcpu->id, vcpu->vmcs.info_IDT_vectoring_information); + } + HALT(); + } +#elif !defined(__I386__) + #error "Unsupported Arch" +#endif /* !defined(__I386__) */ + /* x86 mode */ + printf("\nCPU(0x%02x): Unhandled intercept: %d (0x%08x)", + vcpu->id, (u32)vcpu->vmcs.info_vmexit_reason, + (u32)vcpu->vmcs.info_vmexit_reason); + printf("\n CPU(0x%02x): EFLAGS=0x%08x", + vcpu->id, (u32)vcpu->vmcs.guest_RFLAGS); + printf("\n SS:ESP =0x%04x:0x%08x", + (u16)vcpu->vmcs.guest_SS_selector, + (u32)vcpu->vmcs.guest_RSP); + printf("\n CS:EIP =0x%04x:0x%08x", + (u16)vcpu->vmcs.guest_CS_selector, + (u32)vcpu->vmcs.guest_RIP); + printf("\n IDTR base:limit=0x%08x:0x%04x", + (u32)vcpu->vmcs.guest_IDTR_base, + (u16)vcpu->vmcs.guest_IDTR_limit); + printf("\n GDTR base:limit=0x%08x:0x%04x", + (u32)vcpu->vmcs.guest_GDTR_base, + (u16)vcpu->vmcs.guest_GDTR_limit); + if(vcpu->vmcs.info_IDT_vectoring_information & 0x80000000){ + printf("\nCPU(0x%02x): HALT; Nested events unhandled 0x%08x", + vcpu->id, vcpu->vmcs.info_IDT_vectoring_information); + } + HALT(); + } + } //end switch((u32)vcpu->vmcs.info_vmexit_reason) + + + /* + * Check and clear guest interruptibility state. + * However, ignore bit 3, because it is for virtual NMI. + */ + if ((vcpu->vmcs.guest_interruptibility & ~(1U << 3)) != 0){ + vcpu->vmcs.guest_interruptibility &= (1U << 3); + } + + //make sure we have no nested events + if(vcpu->vmcs.info_IDT_vectoring_information & 0x80000000){ + printf("\nCPU(0x%02x): HALT; Nested events unhandled with hwp:0x%08x", + vcpu->id, vcpu->vmcs.info_IDT_vectoring_information); + HALT(); + } + + //write updated VMCS back to CPU +#ifndef __XMHF_VERIFICATION__ + xmhf_baseplatform_arch_x86vmx_putVMCS(vcpu); +#endif // __XMHF_VERIFICATION__ + + +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + //ensure that whenever a partition is resumed on a vcpu, we have extended paging + //enabled and that the base points to the extended page tables we have initialized + assert( (vcpu->vmcs.control_VMX_seccpu_based & 0x2) ); + assert( (vcpu->vmcs.control_EPT_pointer == (hva2spa((void*)vcpu->vmx_vaddr_ept_pml4_table) | 0x1E)) ); +#endif + + return 1; +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/vmx/peh-x86vmx-ucode-data.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/vmx/peh-x86vmx-ucode-data.c new file mode 100644 index 0000000000..c4838402d5 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/vmx/peh-x86vmx-ucode-data.c @@ -0,0 +1,259 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// peh-x86vmx-ucode-data.c +// Recognized Intel microcode update SHA-1 hashes +// author: Eric Li (xiaoyili@andrew.cmu.edu) +#include + +unsigned char ucode_recognized_sha1s[][SHA_DIGEST_LENGTH] = { + {0x63, 0x7e, 0x40, 0x17, 0x6f, 0x07, 0x6f, 0x5e, 0x6f, 0xee, 0xcc, 0x3e, 0x78, 0x8d, 0x33, 0xaa, 0x0b, 0xe2, 0xad, 0x79}, /* file 06-03-02, bytes 0 - 2048 */ + {0xc6, 0xc5, 0x66, 0x49, 0xcf, 0x68, 0xbb, 0x80, 0xe9, 0x5a, 0xb8, 0x79, 0xa6, 0x9c, 0xa2, 0xaa, 0x26, 0xb9, 0xd2, 0x28}, /* file 06-05-00, bytes 0 - 2048 */ + {0x4f, 0x63, 0x32, 0x98, 0x0d, 0xd6, 0x79, 0x5d, 0xb8, 0x5a, 0xbe, 0x90, 0xd8, 0x78, 0x4b, 0x9a, 0x92, 0xb0, 0x76, 0xfa}, /* file 06-05-00, bytes 2048 - 4096 */ + {0xd7, 0xcb, 0x57, 0xa5, 0x82, 0xa5, 0x45, 0xd5, 0x26, 0x12, 0x51, 0x68, 0x47, 0x04, 0x03, 0xe0, 0x57, 0x01, 0xc9, 0x62}, /* file 06-05-00, bytes 4096 - 6144 */ + {0x9f, 0xe5, 0xd3, 0xdb, 0x8f, 0xb4, 0xb5, 0x47, 0xc4, 0xd7, 0xb9, 0xd6, 0xc9, 0x6f, 0x64, 0x23, 0x32, 0x13, 0x28, 0x3b}, /* file 06-05-01, bytes 0 - 2048 */ + {0x02, 0xdf, 0x3b, 0xbd, 0x96, 0x1e, 0xeb, 0xfc, 0xe2, 0x04, 0xd7, 0xa8, 0xd8, 0xae, 0x9e, 0xc4, 0x06, 0x00, 0xa8, 0xaa}, /* file 06-05-02, bytes 0 - 2048 */ + {0x6a, 0x32, 0xae, 0x29, 0x98, 0x02, 0xcc, 0xdb, 0x8a, 0x95, 0x2d, 0x32, 0x00, 0xe5, 0x29, 0xe3, 0x28, 0x4f, 0x60, 0xd7}, /* file 06-05-02, bytes 2048 - 4096 */ + {0x6e, 0xe9, 0x81, 0xee, 0x15, 0x26, 0x6b, 0xe1, 0x3f, 0xb8, 0x32, 0x6a, 0x1b, 0x21, 0x03, 0xfc, 0x67, 0xd0, 0xc2, 0xc1}, /* file 06-05-02, bytes 4096 - 6144 */ + {0x65, 0xaa, 0x13, 0x29, 0x33, 0x57, 0x52, 0x0a, 0xf8, 0x47, 0xb9, 0xfc, 0xcd, 0xff, 0x79, 0x0c, 0x42, 0x91, 0x67, 0x9d}, /* file 06-05-03, bytes 0 - 2048 */ + {0x7f, 0x25, 0x95, 0x2c, 0x37, 0x18, 0x53, 0xf9, 0x7b, 0x33, 0x26, 0x56, 0x04, 0xc4, 0xd0, 0xcc, 0x1d, 0x48, 0xea, 0xba}, /* file 06-05-03, bytes 2048 - 4096 */ + {0x71, 0x98, 0x6b, 0x2a, 0x33, 0x13, 0x9d, 0x65, 0x35, 0x87, 0x7d, 0x37, 0xfd, 0x78, 0xd2, 0xe4, 0xaf, 0x4b, 0xf9, 0x96}, /* file 06-05-03, bytes 4096 - 6144 */ + {0xbb, 0x52, 0x61, 0x34, 0xb2, 0x8e, 0x97, 0x1b, 0x71, 0x8b, 0xcf, 0xb9, 0x10, 0x85, 0x8b, 0x00, 0xc9, 0x30, 0x5b, 0x6b}, /* file 06-05-03, bytes 6144 - 8192 */ + {0x30, 0xf7, 0x66, 0xf7, 0x5a, 0x09, 0x8d, 0xbc, 0xb3, 0xa5, 0x24, 0xde, 0x1c, 0x47, 0xbb, 0x76, 0xfe, 0x11, 0x96, 0xde}, /* file 06-06-00, bytes 0 - 2048 */ + {0x8f, 0x5e, 0xb7, 0x03, 0x05, 0xff, 0x26, 0x6e, 0x8e, 0x4d, 0xa9, 0x4b, 0xf4, 0x3c, 0x43, 0xf8, 0x85, 0x2f, 0x83, 0x76}, /* file 06-06-05, bytes 0 - 2048 */ + {0xd0, 0x68, 0x34, 0xee, 0x4e, 0xf9, 0xce, 0x77, 0x8c, 0x1a, 0xb7, 0x3f, 0x57, 0x6c, 0x5d, 0x8f, 0xe2, 0xba, 0x47, 0xb8}, /* file 06-06-0a, bytes 0 - 2048 */ + {0x51, 0xb5, 0x09, 0x7f, 0x95, 0x78, 0x09, 0xd1, 0xd2, 0x50, 0x7f, 0x41, 0xa4, 0xc7, 0x9e, 0xfc, 0x1f, 0x4f, 0xbe, 0xaf}, /* file 06-06-0a, bytes 2048 - 4096 */ + {0xcd, 0xcb, 0xa6, 0x7f, 0x17, 0x99, 0x30, 0x9a, 0x42, 0x64, 0x44, 0x14, 0x4c, 0x73, 0x0d, 0x63, 0xe6, 0x7a, 0x0b, 0x8b}, /* file 06-06-0a, bytes 4096 - 6144 */ + {0x1f, 0x1b, 0x37, 0x22, 0x55, 0xc0, 0xea, 0xca, 0xa3, 0xd5, 0x38, 0x1d, 0xd7, 0x7f, 0x62, 0x03, 0x0c, 0xe6, 0xf1, 0x7e}, /* file 06-06-0d, bytes 0 - 2048 */ + {0xab, 0x87, 0x4e, 0xbc, 0x9c, 0xbb, 0xab, 0x54, 0xa5, 0xeb, 0x64, 0x66, 0xe2, 0x48, 0xeb, 0xa5, 0x08, 0x56, 0xca, 0xa4}, /* file 06-06-0d, bytes 2048 - 4096 */ + {0x9c, 0xc1, 0x4e, 0xf3, 0xb3, 0xe8, 0xf0, 0x39, 0x2b, 0xbd, 0x05, 0x03, 0x71, 0x8b, 0xb4, 0x32, 0x3a, 0x53, 0x55, 0x94}, /* file 06-06-0d, bytes 4096 - 6144 */ + {0x6c, 0x60, 0x4b, 0xf6, 0x13, 0xb2, 0x58, 0x3b, 0x1d, 0xca, 0x1e, 0xd6, 0x94, 0x05, 0x6b, 0xbe, 0xed, 0x26, 0x1c, 0x07}, /* file 06-07-01, bytes 0 - 2048 */ + {0x59, 0x36, 0xe3, 0xf1, 0xec, 0x8d, 0xc1, 0xa0, 0x13, 0x3d, 0xbc, 0x35, 0x24, 0xb1, 0xf2, 0x1e, 0x73, 0x5f, 0xc6, 0x74}, /* file 06-07-02, bytes 0 - 2048 */ + {0x7e, 0xf8, 0x10, 0xfd, 0x6c, 0x79, 0xc2, 0x38, 0x10, 0xa1, 0x50, 0x9e, 0x3a, 0x13, 0x9c, 0xb3, 0xb7, 0x50, 0x21, 0xb6}, /* file 06-07-03, bytes 0 - 2048 */ + {0x5a, 0xcd, 0x25, 0x7a, 0x91, 0xfa, 0x8c, 0x95, 0x96, 0x8a, 0xf6, 0xea, 0xce, 0xfa, 0x73, 0x30, 0x69, 0x6a, 0x8f, 0x9d}, /* file 06-08-01, bytes 0 - 2048 */ + {0x40, 0x45, 0xd8, 0xa0, 0x07, 0x06, 0x6a, 0x03, 0x2c, 0xda, 0xca, 0xdd, 0x09, 0x7d, 0x77, 0x11, 0x7b, 0x82, 0x13, 0xf9}, /* file 06-08-01, bytes 2048 - 4096 */ + {0x3d, 0xb8, 0xa0, 0x60, 0x71, 0x52, 0xa8, 0x89, 0xb6, 0x40, 0x65, 0x17, 0xde, 0x4a, 0x7d, 0xaf, 0x73, 0xb0, 0xa8, 0x52}, /* file 06-08-01, bytes 4096 - 6144 */ + {0x91, 0xaa, 0xb8, 0x7c, 0x37, 0xf4, 0x1a, 0xdf, 0x30, 0xea, 0x92, 0x49, 0xa6, 0x83, 0xbf, 0x89, 0xd8, 0x7e, 0x71, 0x27}, /* file 06-08-01, bytes 6144 - 8192 */ + {0xa5, 0x62, 0x72, 0xca, 0x3b, 0x9e, 0x64, 0xd2, 0xaa, 0xb2, 0x01, 0xbb, 0xbc, 0x6e, 0x56, 0xa5, 0x64, 0xd1, 0x7b, 0x44}, /* file 06-08-01, bytes 8192 - 10240 */ + {0x07, 0xa5, 0x16, 0xde, 0x13, 0xf7, 0x6a, 0xa0, 0xe5, 0x13, 0x66, 0xb0, 0xff, 0x80, 0x95, 0x89, 0x44, 0xa4, 0xb8, 0x2e}, /* file 06-08-03, bytes 0 - 2048 */ + {0xfb, 0x17, 0xb4, 0xba, 0x5f, 0x42, 0x5d, 0xaf, 0x6b, 0x18, 0xe8, 0x88, 0xe0, 0xb1, 0x7a, 0x9f, 0x53, 0xee, 0xe4, 0xef}, /* file 06-08-03, bytes 2048 - 4096 */ + {0xfa, 0xdb, 0x75, 0xaa, 0xf5, 0x19, 0xa9, 0x79, 0x29, 0x29, 0x44, 0x3d, 0x9d, 0xfd, 0x52, 0x5e, 0xe5, 0x9a, 0x1b, 0xf9}, /* file 06-08-06, bytes 0 - 2048 */ + {0x29, 0xf2, 0xc4, 0x00, 0x1a, 0x87, 0xa7, 0x39, 0x4e, 0x58, 0xad, 0xd0, 0x29, 0xef, 0x9b, 0xc9, 0x9e, 0x69, 0x2c, 0x27}, /* file 06-08-06, bytes 2048 - 4096 */ + {0x8a, 0x8b, 0x42, 0x5c, 0xa1, 0xf0, 0x65, 0x59, 0x3f, 0x37, 0x98, 0xdd, 0x85, 0xae, 0xb2, 0xf2, 0x8b, 0x80, 0xfa, 0xfa}, /* file 06-08-06, bytes 4096 - 6144 */ + {0xa2, 0xd8, 0xc8, 0x8f, 0x41, 0x64, 0xb2, 0xd3, 0x83, 0xa3, 0x4e, 0x4c, 0x7d, 0xe5, 0x22, 0xd6, 0x71, 0xe1, 0x55, 0x0e}, /* file 06-08-06, bytes 6144 - 8192 */ + {0x2f, 0xbb, 0xe6, 0x60, 0xee, 0xa8, 0xac, 0x59, 0xdc, 0x5e, 0x76, 0xb4, 0xcb, 0x2f, 0xa7, 0x35, 0x98, 0xd2, 0x4c, 0x0f}, /* file 06-08-06, bytes 8192 - 10240 */ + {0x6a, 0x30, 0xc1, 0xb5, 0xf4, 0x43, 0xe6, 0x0b, 0xee, 0xc3, 0xc4, 0x1c, 0x28, 0xd5, 0x5c, 0xe3, 0xc7, 0xe0, 0x6d, 0x97}, /* file 06-08-0a, bytes 0 - 2048 */ + {0xd5, 0xa5, 0xf8, 0xfd, 0xce, 0x71, 0x15, 0xb9, 0xf4, 0xe6, 0xd7, 0x43, 0x0a, 0xfa, 0x65, 0x52, 0xc6, 0xba, 0x01, 0x47}, /* file 06-08-0a, bytes 2048 - 4096 */ + {0x29, 0x90, 0x5c, 0x92, 0x4d, 0xc5, 0xfd, 0xe3, 0x9e, 0xf3, 0x30, 0x63, 0xc3, 0xb9, 0xae, 0x1d, 0x13, 0x6e, 0xd4, 0x2b}, /* file 06-08-0a, bytes 4096 - 6144 */ + {0x95, 0x2d, 0x30, 0x16, 0x0e, 0x92, 0xa7, 0xbb, 0x7d, 0xb0, 0x39, 0x9b, 0x75, 0xc7, 0xf5, 0xc8, 0xe8, 0xc2, 0x1f, 0xb4}, /* file 06-09-05, bytes 0 - 2048 */ + {0x9b, 0x14, 0xd5, 0xa4, 0x93, 0x60, 0xa7, 0x20, 0x2b, 0x9f, 0x1d, 0xc1, 0x4d, 0x13, 0xce, 0x9b, 0xe2, 0x64, 0x06, 0x74}, /* file 06-09-05, bytes 2048 - 4096 */ + {0x81, 0xa7, 0xec, 0x40, 0xe8, 0x7e, 0x52, 0x28, 0xe1, 0x79, 0x88, 0x85, 0xb3, 0x3d, 0x53, 0x07, 0xec, 0x59, 0xe1, 0x6e}, /* file 06-09-05, bytes 4096 - 6144 */ + {0x9b, 0xb0, 0x63, 0x88, 0xa0, 0x3a, 0xd9, 0xb7, 0x20, 0x39, 0xc0, 0x22, 0x73, 0x26, 0x1b, 0x3f, 0x68, 0x78, 0x55, 0xae}, /* file 06-0a-00, bytes 0 - 2048 */ + {0xfa, 0xea, 0x33, 0xbe, 0x37, 0x8d, 0x82, 0xfa, 0x11, 0x04, 0x5f, 0x0a, 0x33, 0x51, 0xb6, 0x90, 0x0c, 0x05, 0x7a, 0x3a}, /* file 06-0a-01, bytes 0 - 2048 */ + {0x83, 0x56, 0xbb, 0x2b, 0x3e, 0x50, 0x3b, 0x54, 0x0a, 0xcd, 0xa3, 0xa3, 0x71, 0xbe, 0xb8, 0x63, 0x17, 0x38, 0xc6, 0xce}, /* file 06-0b-01, bytes 0 - 2048 */ + {0x9a, 0x80, 0x41, 0xaf, 0x6d, 0x1a, 0xe1, 0x63, 0xbc, 0x44, 0xe6, 0x3f, 0x95, 0x82, 0x51, 0x6f, 0x76, 0x6f, 0xdb, 0x94}, /* file 06-0b-01, bytes 2048 - 4096 */ + {0xda, 0x22, 0x25, 0x5a, 0x81, 0x62, 0x49, 0x7c, 0x85, 0xe7, 0xe6, 0x03, 0x91, 0x51, 0x9f, 0x32, 0x79, 0xd5, 0x5f, 0x1f}, /* file 06-0b-04, bytes 0 - 2048 */ + {0x20, 0xdf, 0x76, 0xc4, 0x0a, 0x29, 0x37, 0x09, 0x26, 0x05, 0xea, 0xbb, 0xa7, 0xb6, 0x29, 0xb6, 0x75, 0xba, 0x03, 0xbe}, /* file 06-0b-04, bytes 2048 - 4096 */ + {0x9e, 0x18, 0x1b, 0x62, 0xc6, 0xf2, 0xe2, 0xeb, 0xea, 0x81, 0xcd, 0xbf, 0x87, 0xc4, 0x8f, 0x36, 0x9f, 0xf3, 0x72, 0x41}, /* file 06-0d-06, bytes 0 - 2048 */ + {0x3b, 0xe6, 0x98, 0xc7, 0x7c, 0x2b, 0xfb, 0xc7, 0x26, 0xfd, 0xf9, 0xbb, 0xc1, 0xf5, 0x20, 0xe6, 0x1a, 0xf7, 0xc8, 0xf4}, /* file 06-0e-08, bytes 0 - 4096 */ + {0xfa, 0x0c, 0xae, 0x0a, 0x9f, 0x00, 0x54, 0xf7, 0xbb, 0xf0, 0x8b, 0x10, 0x81, 0x63, 0xfc, 0x19, 0x20, 0x97, 0x84, 0xad}, /* file 06-0e-0c, bytes 0 - 4096 */ + {0xc4, 0x65, 0xde, 0x26, 0x32, 0xaf, 0xf5, 0xf1, 0x3c, 0xc6, 0xe2, 0x03, 0x73, 0xbe, 0xd2, 0x74, 0x64, 0xb0, 0x69, 0xd5}, /* file 06-0e-0c, bytes 4096 - 8192 */ + {0x79, 0x7d, 0xa5, 0xfa, 0xc8, 0x2f, 0x16, 0x9b, 0xb8, 0x49, 0xb7, 0x99, 0xd2, 0x91, 0x71, 0x6f, 0x24, 0x68, 0xd1, 0x5b}, /* file 06-0f-02, bytes 0 - 4096 */ + {0x48, 0x3d, 0xed, 0xfa, 0xf3, 0x67, 0x59, 0x49, 0x73, 0xd8, 0x10, 0x98, 0x6d, 0xa6, 0x4f, 0xcd, 0x20, 0x40, 0x5b, 0x14}, /* file 06-0f-02, bytes 4096 - 8192 */ + {0x12, 0xf8, 0x8e, 0xec, 0x0e, 0x1d, 0xb9, 0x9f, 0xd9, 0x6f, 0x6c, 0x50, 0xe4, 0xa6, 0x9d, 0x29, 0xd1, 0xba, 0xb3, 0xd7}, /* file 06-0f-06, bytes 0 - 4096 */ + {0x21, 0x9d, 0x64, 0x9b, 0xbd, 0x03, 0xee, 0xd7, 0x94, 0x07, 0x31, 0x46, 0x61, 0x5a, 0xef, 0xa8, 0xdb, 0x78, 0xd4, 0xc2}, /* file 06-0f-06, bytes 4096 - 8192 */ + {0x4f, 0x33, 0xcc, 0x27, 0xdc, 0xc9, 0x48, 0xa6, 0xdc, 0x88, 0x54, 0x2d, 0xbf, 0xe0, 0x5a, 0xfc, 0xf4, 0xf4, 0xcd, 0x63}, /* file 06-0f-06, bytes 8192 - 12288 */ + {0xd3, 0x85, 0x24, 0x71, 0xd1, 0xd6, 0xf3, 0xa4, 0x3a, 0xdf, 0x9b, 0xa0, 0x78, 0x31, 0xe9, 0x2a, 0xd5, 0x09, 0xdb, 0xd7}, /* file 06-0f-07, bytes 0 - 4096 */ + {0x97, 0x23, 0x32, 0xa7, 0x4e, 0xa0, 0xf6, 0x25, 0xd3, 0x8e, 0x2a, 0xbc, 0x28, 0xb4, 0xf9, 0xf7, 0xd3, 0x9b, 0xba, 0x08}, /* file 06-0f-07, bytes 4096 - 8192 */ + {0x5d, 0x88, 0xe2, 0xd3, 0x32, 0x7a, 0x93, 0x47, 0xd4, 0x2a, 0x53, 0x9a, 0x85, 0x7c, 0x3e, 0xe9, 0x45, 0x5c, 0x5b, 0xc4}, /* file 06-0f-0a, bytes 0 - 4096 */ + {0x77, 0x57, 0x7c, 0xa3, 0x49, 0x53, 0x2e, 0xa4, 0x44, 0x32, 0x19, 0x66, 0x70, 0xc9, 0x73, 0xa2, 0xdd, 0x40, 0x6b, 0x64}, /* file 06-0f-0b, bytes 0 - 4096 */ + {0x3e, 0xe8, 0xce, 0x47, 0x9d, 0xb3, 0xe0, 0x98, 0x8f, 0xae, 0x1a, 0xd8, 0xfa, 0x0f, 0x1f, 0xa1, 0x7c, 0x3f, 0xb7, 0xa2}, /* file 06-0f-0b, bytes 4096 - 8192 */ + {0xbd, 0x35, 0x8e, 0xad, 0x30, 0xa7, 0xd2, 0xcb, 0x23, 0xfe, 0x35, 0xaa, 0xa8, 0x2a, 0x5c, 0x8c, 0xec, 0x82, 0xdb, 0x0d}, /* file 06-0f-0b, bytes 8192 - 12288 */ + {0x40, 0x50, 0xd9, 0x48, 0x59, 0xbf, 0x5f, 0x5e, 0x50, 0x1c, 0xc3, 0x15, 0x36, 0xad, 0xd1, 0x96, 0xb2, 0xaf, 0xa2, 0xfd}, /* file 06-0f-0b, bytes 12288 - 16384 */ + {0xfe, 0x0a, 0x0f, 0x5a, 0x0d, 0x7f, 0xac, 0xb8, 0x1a, 0x2d, 0x11, 0xb6, 0xd2, 0xb6, 0x50, 0x4d, 0xb1, 0x0e, 0xd9, 0xf8}, /* file 06-0f-0b, bytes 16384 - 20480 */ + {0xcb, 0xa3, 0x00, 0xe6, 0xc5, 0x77, 0xd1, 0x7c, 0xde, 0x98, 0x61, 0x76, 0xc8, 0x40, 0xe1, 0xb3, 0x3f, 0x20, 0x03, 0x70}, /* file 06-0f-0b, bytes 20480 - 24576 */ + {0x74, 0x4f, 0x9a, 0xe0, 0xd2, 0xf7, 0xfa, 0x18, 0xb4, 0xa0, 0x7e, 0x0e, 0x78, 0x86, 0x41, 0x66, 0x0f, 0x31, 0xa6, 0x52}, /* file 06-0f-0b, bytes 24576 - 28672 */ + {0xd1, 0x75, 0xf2, 0x42, 0x79, 0x0f, 0x94, 0x0a, 0x74, 0xe1, 0xe7, 0xa9, 0x85, 0x49, 0xfa, 0x42, 0x05, 0x87, 0x96, 0xa7}, /* file 06-0f-0d, bytes 0 - 4096 */ + {0x3e, 0x66, 0x8e, 0x02, 0x48, 0x0a, 0x1f, 0xe8, 0xd1, 0xdc, 0x05, 0x1e, 0x33, 0x13, 0xd1, 0x2f, 0xa4, 0xe0, 0xbe, 0xfc}, /* file 06-0f-0d, bytes 4096 - 8192 */ + {0x82, 0xf5, 0x8d, 0x66, 0x97, 0xcc, 0x9e, 0x87, 0xb6, 0x66, 0xc6, 0xcc, 0xd1, 0x20, 0xcb, 0xdd, 0x66, 0xad, 0xea, 0x98}, /* file 06-0f-0d, bytes 8192 - 12288 */ + {0xc3, 0x91, 0x15, 0x13, 0xb3, 0xa5, 0x78, 0x36, 0x82, 0x71, 0x21, 0x74, 0x4d, 0xc9, 0x82, 0x84, 0xf7, 0xcf, 0x98, 0x44}, /* file 06-16-01, bytes 0 - 4096 */ + {0x2f, 0x24, 0x78, 0x27, 0x1e, 0x09, 0xa4, 0xe0, 0xff, 0x7a, 0x41, 0x3f, 0xe9, 0x59, 0xaf, 0x44, 0x69, 0x9a, 0x61, 0xfa}, /* file 06-16-01, bytes 4096 - 8192 */ + {0xa8, 0x5f, 0x8b, 0xa6, 0xc4, 0x94, 0x1b, 0xee, 0x51, 0x98, 0x61, 0x8a, 0x3d, 0x6a, 0xbe, 0x0d, 0xdf, 0xf2, 0x10, 0x0c}, /* file 06-16-01, bytes 8192 - 12288 */ + {0x02, 0x42, 0x83, 0x01, 0xf3, 0x50, 0xbc, 0xba, 0xb6, 0x89, 0xad, 0x29, 0x13, 0x70, 0xd3, 0x93, 0xeb, 0xb3, 0x9a, 0xba}, /* file 06-17-06, bytes 0 - 4096 */ + {0x4b, 0x74, 0xe8, 0x94, 0x6c, 0x1b, 0xf1, 0x3e, 0xeb, 0x48, 0x8c, 0x5e, 0x6f, 0x66, 0x8d, 0xda, 0xb3, 0xc1, 0x97, 0xd0}, /* file 06-17-06, bytes 4096 - 8192 */ + {0xb0, 0xc1, 0x1d, 0x46, 0x9e, 0x92, 0xaf, 0x6a, 0x27, 0x47, 0x2e, 0x24, 0x59, 0x44, 0xda, 0x48, 0x62, 0x99, 0xb1, 0x7c}, /* file 06-17-06, bytes 8192 - 12288 */ + {0xaa, 0x61, 0x99, 0x65, 0xd3, 0xb9, 0x2b, 0x9c, 0x94, 0x60, 0x24, 0x42, 0x67, 0x29, 0x53, 0xfc, 0x3a, 0x83, 0xc6, 0x20}, /* file 06-17-06, bytes 12288 - 16384 */ + {0x04, 0xfe, 0xf9, 0xc9, 0x77, 0x27, 0xea, 0xac, 0xfa, 0xaa, 0x1c, 0xaa, 0xcd, 0xf2, 0x1d, 0xec, 0x3a, 0xf6, 0x1d, 0x46}, /* file 06-17-06, bytes 16384 - 20480 */ + {0x58, 0x7e, 0x51, 0xfc, 0xda, 0xcb, 0xe9, 0xce, 0xb4, 0x56, 0x49, 0x7b, 0x77, 0x6f, 0x7c, 0x05, 0x58, 0xb8, 0xb1, 0xed}, /* file 06-17-07, bytes 0 - 4096 */ + {0x83, 0xd6, 0x07, 0x2d, 0xc0, 0x7b, 0x3d, 0x06, 0xc0, 0x59, 0x06, 0xd3, 0x91, 0xe6, 0x92, 0x39, 0x60, 0x0e, 0xc3, 0xbd}, /* file 06-17-0a, bytes 0 - 8192 */ + {0x0e, 0xff, 0x7c, 0x14, 0xa0, 0x04, 0x33, 0x82, 0x36, 0x49, 0x3e, 0x71, 0x79, 0x4c, 0x78, 0x66, 0x1a, 0x12, 0x64, 0xe2}, /* file 06-17-0a, bytes 8192 - 16384 */ + {0x95, 0xed, 0x2a, 0xef, 0x0a, 0xa2, 0x06, 0xb3, 0x14, 0xa8, 0x21, 0xe4, 0xc2, 0x16, 0x88, 0xf6, 0xbd, 0x7a, 0xf1, 0x26}, /* file 06-17-0a, bytes 16384 - 24576 */ + {0xbc, 0x06, 0xc0, 0x72, 0x13, 0x82, 0x1f, 0x94, 0x7c, 0xd7, 0x59, 0x6b, 0x61, 0xa9, 0x03, 0xc3, 0xe8, 0xbc, 0xd0, 0x9d}, /* file 06-1a-04, bytes 0 - 14336 */ + {0xc2, 0x07, 0x89, 0xf7, 0x66, 0x8c, 0x2d, 0xa2, 0xb7, 0x9c, 0x90, 0xd1, 0xa0, 0x41, 0x36, 0x26, 0x9c, 0xbb, 0x16, 0xfe}, /* file 06-1a-05, bytes 0 - 12288 */ + {0x85, 0x4b, 0x43, 0x75, 0x9a, 0x1e, 0x8b, 0x31, 0x36, 0x85, 0xcd, 0x7b, 0x14, 0x2a, 0x39, 0xb1, 0xe4, 0xce, 0x14, 0xdf}, /* file 06-1c-02, bytes 0 - 5120 */ + {0xeb, 0x29, 0xcf, 0xec, 0x83, 0x06, 0x9b, 0x05, 0xfd, 0x2c, 0xdb, 0x37, 0x52, 0x66, 0xbd, 0xf6, 0xc4, 0x8d, 0x95, 0xab}, /* file 06-1c-02, bytes 5120 - 10240 */ + {0x9b, 0xc7, 0xdd, 0x71, 0x09, 0x3d, 0x92, 0x29, 0x3c, 0x22, 0x82, 0x9b, 0x2b, 0x4a, 0x78, 0xfc, 0x2c, 0xb8, 0x13, 0xda}, /* file 06-1c-02, bytes 10240 - 15360 */ + {0xaa, 0xc3, 0x91, 0xf2, 0x7e, 0x02, 0x69, 0xd8, 0x91, 0xc1, 0xc1, 0x85, 0xeb, 0x57, 0xb4, 0x67, 0xc1, 0xc6, 0x87, 0x0b}, /* file 06-1c-0a, bytes 0 - 5120 */ + {0xeb, 0x4e, 0x8d, 0x70, 0xd1, 0x6e, 0xe8, 0x57, 0x63, 0x7a, 0xb8, 0x97, 0x33, 0x48, 0xce, 0x31, 0x5b, 0x84, 0xc2, 0x56}, /* file 06-1c-0a, bytes 5120 - 10240 */ + {0xd0, 0x19, 0x26, 0x6d, 0x39, 0xbc, 0x12, 0x8a, 0x60, 0x8b, 0x49, 0xb5, 0x36, 0x61, 0x30, 0xd9, 0x9a, 0x00, 0xfd, 0x92}, /* file 06-1c-0a, bytes 10240 - 15360 */ + {0x83, 0x06, 0x96, 0xec, 0x42, 0x7f, 0x05, 0x79, 0xeb, 0xeb, 0x5d, 0xd5, 0x59, 0x25, 0x87, 0x2f, 0xe3, 0xae, 0x78, 0x76}, /* file 06-1c-0a, bytes 15360 - 20480 */ + {0x7b, 0xcf, 0x45, 0xf0, 0xb7, 0xbd, 0xa7, 0x03, 0xeb, 0x76, 0x2b, 0x2a, 0x7a, 0xb3, 0x22, 0x9d, 0xad, 0x2a, 0x14, 0x20}, /* file 06-1d-01, bytes 0 - 4096 */ + {0x80, 0x1c, 0xd4, 0x4b, 0x62, 0x77, 0xfa, 0xe0, 0x79, 0x2a, 0xa7, 0x7f, 0x24, 0xd7, 0x84, 0xf4, 0x7d, 0x92, 0x24, 0x18}, /* file 06-1e-05, bytes 0 - 9216 */ + {0x4e, 0x97, 0xb4, 0x5a, 0x38, 0xbd, 0xfc, 0xe2, 0xa1, 0x09, 0x5e, 0x34, 0xd8, 0xbc, 0xd5, 0xca, 0x92, 0xa0, 0x40, 0x1a}, /* file 06-25-02, bytes 0 - 9216 */ + {0x48, 0x70, 0x94, 0x85, 0xcb, 0xd2, 0x72, 0x9e, 0x96, 0xd8, 0xd0, 0x8e, 0xcc, 0x31, 0x77, 0xad, 0x57, 0xfd, 0x95, 0x2b}, /* file 06-25-05, bytes 0 - 4096 */ + {0xca, 0x25, 0x92, 0x6e, 0x81, 0xa5, 0x29, 0x41, 0xd8, 0x82, 0xc9, 0xa9, 0x69, 0x6d, 0xcc, 0x9b, 0xa0, 0x08, 0x7e, 0x35}, /* file 06-26-01, bytes 0 - 5120 */ + {0x9f, 0xce, 0x33, 0xbd, 0x23, 0x39, 0xd6, 0x7f, 0x1c, 0x43, 0x5c, 0xaa, 0xac, 0xaf, 0x1e, 0x3e, 0x0e, 0x8a, 0x70, 0xd5}, /* file 06-26-01, bytes 5120 - 10240 */ + {0x68, 0x83, 0xee, 0xbc, 0xa7, 0x76, 0x5a, 0x4c, 0x3e, 0xfc, 0x9d, 0xe0, 0xed, 0x15, 0x62, 0x41, 0x5e, 0x43, 0xf4, 0x35}, /* file 06-2a-07, bytes 0 - 12288 */ + {0x91, 0xeb, 0xd7, 0x34, 0xb1, 0x63, 0x97, 0x2b, 0x05, 0x4c, 0x1d, 0x26, 0x7f, 0x03, 0x6b, 0x72, 0x2b, 0xd7, 0xe3, 0x53}, /* file 06-2c-02, bytes 0 - 11264 */ + {0x2f, 0x3f, 0xb1, 0xcb, 0x59, 0x5b, 0x70, 0x65, 0x57, 0x08, 0x24, 0x16, 0xc3, 0xed, 0x83, 0x2b, 0xab, 0x94, 0x74, 0x6e}, /* file 06-2d-06, bytes 0 - 18432 */ + {0x45, 0x12, 0xc8, 0x14, 0x9e, 0x63, 0xe5, 0xed, 0x15, 0xf4, 0x50, 0x05, 0xd7, 0xfb, 0x5b, 0xe0, 0x04, 0x1f, 0x66, 0xf6}, /* file 06-2d-07, bytes 0 - 19456 */ + {0x34, 0x0b, 0x4b, 0x3d, 0xbd, 0xa0, 0xe0, 0x2a, 0x1e, 0xd8, 0x0c, 0x77, 0xf2, 0x48, 0x40, 0xdf, 0x99, 0x5d, 0x6a, 0x81}, /* file 06-2e-06, bytes 0 - 9216 */ + {0xbf, 0xd0, 0xa9, 0xa0, 0x43, 0xba, 0x17, 0x7f, 0x75, 0x55, 0x22, 0x1f, 0xaf, 0x31, 0xcd, 0xa2, 0x43, 0x3f, 0xd8, 0x95}, /* file 06-2f-02, bytes 0 - 14336 */ + {0xa6, 0x45, 0x0a, 0x2f, 0x52, 0xd9, 0x32, 0xaf, 0xb8, 0x21, 0x47, 0xab, 0x94, 0xfb, 0x45, 0xfb, 0x4e, 0xaa, 0x32, 0xac}, /* file 06-37-08, bytes 0 - 52224 */ + {0x19, 0x98, 0x78, 0xc9, 0x03, 0xf7, 0x62, 0xbb, 0x98, 0x9d, 0x18, 0x71, 0x43, 0xa2, 0xb4, 0x0d, 0xb9, 0xa2, 0xaa, 0x3e}, /* file 06-37-08, bytes 52224 - 104448 */ + {0x05, 0x38, 0xd8, 0x40, 0x0a, 0xaf, 0x1f, 0x2d, 0x44, 0xf6, 0x7a, 0xb7, 0x4a, 0x94, 0x73, 0x80, 0x6f, 0x15, 0x41, 0xfe}, /* file 06-37-09, bytes 0 - 52224 */ + {0x64, 0x0f, 0xc9, 0xa7, 0xad, 0x3b, 0xff, 0x48, 0x80, 0x1a, 0x37, 0x88, 0x98, 0x25, 0xd6, 0x88, 0xb8, 0xb7, 0x0a, 0xce}, /* file 06-3a-09, bytes 0 - 14336 */ + {0x9d, 0x82, 0x7a, 0x9f, 0xb2, 0x07, 0x4a, 0x62, 0xa3, 0xcb, 0x00, 0x6c, 0x66, 0x4c, 0xf6, 0xae, 0xdf, 0x53, 0x1b, 0x4a}, /* file 06-3c-03, bytes 0 - 23552 */ + {0x1c, 0x9e, 0x13, 0x8e, 0xa7, 0xf6, 0x61, 0xa9, 0xc3, 0x95, 0x11, 0x4a, 0xd2, 0xb1, 0x65, 0x7b, 0x93, 0x39, 0x6b, 0x85}, /* file 06-3d-04, bytes 0 - 19456 */ + {0x69, 0x90, 0xaf, 0x73, 0x0d, 0x7c, 0xb7, 0x01, 0xe8, 0xb0, 0x09, 0xed, 0x7a, 0x70, 0x91, 0xfc, 0xa1, 0x6c, 0xce, 0x67}, /* file 06-3e-04, bytes 0 - 16384 */ + {0xff, 0xf2, 0xdf, 0x19, 0xf5, 0xf9, 0xf5, 0xfd, 0x87, 0x3e, 0xc7, 0xe8, 0xca, 0x3c, 0x4e, 0xbe, 0x20, 0xf2, 0x5b, 0x3e}, /* file 06-3e-06, bytes 0 - 11264 */ + {0xc1, 0x83, 0x8a, 0x65, 0xce, 0xb1, 0x89, 0x40, 0x05, 0xb3, 0x6f, 0x60, 0x71, 0xff, 0x67, 0x46, 0xad, 0x71, 0xb3, 0x2e}, /* file 06-3e-07, bytes 0 - 17408 */ + {0x14, 0x88, 0xbe, 0xb6, 0x89, 0xb5, 0xec, 0x15, 0x3a, 0x68, 0x28, 0x0c, 0x28, 0x41, 0xc0, 0x05, 0x4b, 0x44, 0xd3, 0xf4}, /* file 06-3f-02, bytes 0 - 38912 */ + {0x85, 0x92, 0xb1, 0x47, 0xab, 0xc0, 0x35, 0x6e, 0x7a, 0x8f, 0x19, 0x9e, 0x3e, 0x5f, 0x8b, 0x90, 0x34, 0x62, 0xd6, 0xfc}, /* file 06-3f-04, bytes 0 - 23552 */ + {0x93, 0x0e, 0xff, 0x4f, 0xc2, 0x51, 0x19, 0xda, 0xb5, 0x89, 0xe5, 0x3d, 0xe4, 0x25, 0x3c, 0x18, 0xf7, 0xd3, 0xb2, 0xaf}, /* file 06-45-01, bytes 0 - 22528 */ + {0xc7, 0xbc, 0x12, 0xec, 0x0c, 0xa9, 0x35, 0x70, 0xc5, 0x31, 0x6e, 0xb4, 0xb0, 0xcf, 0x3c, 0xc6, 0xcc, 0x60, 0x24, 0xa0}, /* file 06-46-01, bytes 0 - 25600 */ + {0x2a, 0x07, 0x4e, 0xde, 0xbb, 0xef, 0x89, 0x9c, 0x98, 0xbb, 0xa5, 0xd5, 0xd8, 0x62, 0xc7, 0x1b, 0xa5, 0x50, 0x62, 0x62}, /* file 06-47-01, bytes 0 - 14336 */ + {0xcb, 0x8d, 0xc0, 0xa1, 0x7d, 0x4f, 0x48, 0xcd, 0x33, 0x8c, 0x7f, 0xf5, 0x7a, 0xc9, 0x6c, 0x77, 0x47, 0x98, 0xbe, 0x0b}, /* file 06-4c-03, bytes 0 - 69632 */ + {0x40, 0xff, 0x40, 0x9f, 0x5f, 0x15, 0x67, 0xef, 0xff, 0x00, 0x66, 0x8e, 0x64, 0x81, 0x1b, 0xe9, 0xba, 0x10, 0x09, 0x53}, /* file 06-4c-04, bytes 0 - 68608 */ + {0x8d, 0xaf, 0xa8, 0xdb, 0x9c, 0x92, 0xf0, 0xb2, 0x0b, 0xde, 0xfe, 0x0a, 0x62, 0x35, 0xe7, 0x9f, 0x01, 0x10, 0x93, 0xc0}, /* file 06-4d-08, bytes 0 - 84992 */ + {0xd9, 0x49, 0xa8, 0x54, 0x3d, 0x24, 0x64, 0xd9, 0x55, 0xf5, 0xdc, 0x4b, 0x07, 0x77, 0xca, 0xc8, 0x63, 0xf4, 0x87, 0x29}, /* file 06-4e-03, bytes 0 - 105472 */ + {0x77, 0x76, 0xea, 0x67, 0x86, 0xe6, 0xe4, 0xc0, 0x3d, 0x53, 0xac, 0xb3, 0x9d, 0x7e, 0x2d, 0x13, 0xf0, 0x14, 0xa0, 0x68}, /* file 06-4f-01, bytes 0 - 35840 */ + {0x98, 0x19, 0x91, 0x9f, 0x04, 0xd9, 0xe0, 0x25, 0xce, 0x92, 0xe1, 0x74, 0x30, 0x26, 0x2d, 0x01, 0xd1, 0x45, 0x70, 0xb9}, /* file 06-55-03, bytes 0 - 34816 */ + {0x76, 0xb6, 0x41, 0x37, 0x5d, 0x13, 0x6c, 0x08, 0xf5, 0xfe, 0xb4, 0x6a, 0xac, 0xeb, 0xee, 0x40, 0x46, 0x8a, 0xc0, 0x85}, /* file 06-55-04, bytes 0 - 43008 */ + {0xb0, 0x14, 0xe3, 0x74, 0xf1, 0xdb, 0x58, 0x35, 0x89, 0xec, 0xe2, 0x3f, 0x91, 0x61, 0x23, 0x61, 0x61, 0xf8, 0xf7, 0x8c}, /* file 06-55-05, bytes 0 - 47104 */ + {0x04, 0x3e, 0x8f, 0x20, 0xf2, 0xf3, 0x75, 0x79, 0x6d, 0xcc, 0xdf, 0xf4, 0x41, 0x27, 0xc0, 0x3b, 0x5d, 0x67, 0xf2, 0xca}, /* file 06-55-06, bytes 0 - 35840 */ + {0xd4, 0x0a, 0x9a, 0x72, 0x2b, 0x78, 0xf5, 0x4f, 0xaa, 0xf4, 0x90, 0x7c, 0x42, 0x58, 0x6a, 0xe4, 0x54, 0xd6, 0x9d, 0xd3}, /* file 06-55-07, bytes 0 - 36864 */ + {0x31, 0x95, 0xe4, 0x1d, 0x32, 0xf5, 0x4c, 0x19, 0xed, 0xb5, 0xd3, 0xfe, 0x2b, 0x3b, 0x25, 0xd0, 0xcc, 0xad, 0x08, 0x77}, /* file 06-55-0b, bytes 0 - 28672 */ + {0x30, 0x69, 0xeb, 0xa0, 0x3e, 0xf7, 0xdc, 0x5d, 0x48, 0xf9, 0x5c, 0x5f, 0xa0, 0x14, 0x17, 0xc8, 0x45, 0xfe, 0xe3, 0xa3}, /* file 06-56-02, bytes 0 - 32768 */ + {0x26, 0xcb, 0x19, 0xea, 0x23, 0x76, 0x77, 0xee, 0x80, 0x94, 0x84, 0x3e, 0x28, 0x19, 0xc2, 0x13, 0x65, 0x3b, 0xf6, 0x37}, /* file 06-56-03, bytes 0 - 28672 */ + {0x66, 0x1c, 0xf4, 0x57, 0x5f, 0x0e, 0x87, 0x3b, 0xd0, 0xd2, 0x32, 0xa5, 0x6f, 0x6d, 0x69, 0x3f, 0xb4, 0x16, 0xa7, 0x0a}, /* file 06-56-04, bytes 0 - 27648 */ + {0xb8, 0x96, 0x8b, 0x1f, 0xfc, 0xca, 0x87, 0x58, 0xc7, 0xa2, 0x60, 0x75, 0xd8, 0x79, 0x56, 0xf1, 0x7c, 0x8d, 0x11, 0xf7}, /* file 06-56-05, bytes 0 - 23552 */ + {0x00, 0x52, 0xf3, 0xb5, 0x49, 0xa0, 0xed, 0xbb, 0x5a, 0xc7, 0x0c, 0x1c, 0xab, 0x0d, 0x8c, 0x1f, 0xcb, 0xde, 0x61, 0x8b}, /* file 06-5c-02, bytes 0 - 15360 */ + {0xbf, 0x68, 0xa1, 0x8c, 0x2c, 0x4b, 0x14, 0x7f, 0xb5, 0xac, 0xbf, 0x42, 0x9d, 0x87, 0xdb, 0x98, 0xe4, 0xb6, 0xfc, 0x57}, /* file 06-5c-09, bytes 0 - 17408 */ + {0xa9, 0x8a, 0x1c, 0x25, 0x68, 0xb8, 0x4b, 0xf3, 0x28, 0xec, 0xf7, 0x34, 0xe5, 0xef, 0x7a, 0x97, 0x79, 0x7c, 0x80, 0xea}, /* file 06-5c-0a, bytes 0 - 16384 */ + {0x64, 0x58, 0xbf, 0x25, 0xda, 0x49, 0x06, 0x47, 0x9a, 0x01, 0xff, 0xdc, 0xaa, 0x6d, 0x46, 0x6e, 0x22, 0x72, 0x2e, 0x01}, /* file 06-5e-03, bytes 0 - 108544 */ + {0x9f, 0x5a, 0x56, 0x3a, 0x1e, 0x87, 0x64, 0x43, 0xd8, 0xbc, 0xd5, 0xd5, 0xf7, 0xdf, 0xdf, 0x4f, 0x73, 0x1b, 0xfb, 0x9a}, /* file 06-5f-01, bytes 0 - 11264 */ + {0x0f, 0x29, 0xbe, 0x80, 0xbf, 0x2d, 0xf0, 0xe9, 0x7b, 0x1b, 0x5e, 0x08, 0xe2, 0x66, 0xc8, 0x62, 0x2a, 0xa2, 0xa7, 0xdf}, /* file 06-66-03, bytes 0 - 87040 */ + {0x8b, 0x10, 0x8c, 0x55, 0x9f, 0x05, 0xe0, 0x22, 0x1b, 0x6b, 0x3e, 0x12, 0x1e, 0x35, 0x73, 0x81, 0x44, 0xb0, 0x74, 0x99}, /* file 06-6a-05, bytes 0 - 283648 */ + {0xa0, 0xc1, 0x88, 0xb9, 0xbe, 0x3e, 0x3b, 0x54, 0x48, 0x9e, 0x02, 0x76, 0x10, 0x12, 0xbd, 0x5c, 0xa8, 0xea, 0x51, 0xea}, /* file 06-6a-06, bytes 0 - 291840 */ + {0x96, 0x2b, 0xd7, 0x5a, 0x5c, 0x86, 0xa5, 0x88, 0x95, 0x66, 0x6e, 0xc4, 0x47, 0xbd, 0x0a, 0x6c, 0x71, 0xf1, 0x77, 0x68}, /* file 06-7a-01, bytes 0 - 74752 */ + {0xfc, 0xfb, 0xe4, 0xc6, 0x04, 0x4b, 0xa2, 0xff, 0xc6, 0xb3, 0x90, 0x0d, 0xa0, 0x84, 0x4c, 0x98, 0xbc, 0x2d, 0x06, 0xb0}, /* file 06-7a-08, bytes 0 - 75776 */ + {0xe0, 0x79, 0x4b, 0x0c, 0x2a, 0xa1, 0xf7, 0x7f, 0xa6, 0x2f, 0x69, 0x2a, 0x90, 0xdf, 0x71, 0x29, 0x99, 0x81, 0xe1, 0x75}, /* file 06-7e-05, bytes 0 - 110592 */ + {0xf1, 0x21, 0x9a, 0x29, 0x3a, 0xc8, 0x06, 0x3d, 0x81, 0x75, 0x71, 0xcd, 0x74, 0xe3, 0x4e, 0xdf, 0x7e, 0x46, 0xb5, 0x1f}, /* file 06-8a-01, bytes 0 - 34816 */ + {0x48, 0xb3, 0xae, 0x8d, 0x27, 0xd8, 0x13, 0x8b, 0x5b, 0x47, 0x05, 0x2d, 0x2f, 0x81, 0x84, 0xbf, 0x55, 0x5a, 0xd1, 0x8e}, /* file 06-8c-01, bytes 0 - 109568 */ + {0xcd, 0xf4, 0xe9, 0x01, 0x07, 0x8c, 0x4b, 0x16, 0x23, 0x2d, 0x8c, 0x6c, 0x11, 0x85, 0x23, 0x38, 0x74, 0x87, 0x90, 0x0f}, /* file 06-8c-02, bytes 0 - 96256 */ + {0x2a, 0xea, 0x03, 0x7b, 0x7c, 0x95, 0x7a, 0xb2, 0x2b, 0x2f, 0x06, 0x38, 0x81, 0xec, 0x9a, 0x8c, 0x4f, 0x23, 0x61, 0xb8}, /* file 06-8d-01, bytes 0 - 101376 */ + {0x95, 0xaf, 0xe6, 0xf6, 0xd1, 0xd0, 0x90, 0x28, 0xc8, 0xec, 0x1d, 0xc3, 0x3d, 0xa2, 0xf8, 0xf0, 0xd7, 0xfa, 0x8c, 0x58}, /* file 06-8e-09, bytes 0 - 104448 */ + {0x36, 0xdf, 0x33, 0x8e, 0x8a, 0x60, 0x16, 0xde, 0xc0, 0xc5, 0xa4, 0x35, 0xe3, 0xf3, 0x25, 0x6a, 0x8c, 0x8a, 0xe8, 0xe5}, /* file 06-8e-09, bytes 104448 - 208896 */ + {0x6c, 0x41, 0xa6, 0xad, 0x41, 0x2f, 0x48, 0xf8, 0x1a, 0x9d, 0x5e, 0xdf, 0x59, 0xdc, 0xde, 0xcc, 0x35, 0x83, 0x98, 0xbf}, /* file 06-8e-0a, bytes 0 - 103424 */ + {0x89, 0xdd, 0x0d, 0xe5, 0x98, 0xc8, 0x3e, 0xb9, 0x71, 0x4f, 0x68, 0x39, 0x49, 0x9f, 0x32, 0x2d, 0xfc, 0xe2, 0xb6, 0x93}, /* file 06-8e-0b, bytes 0 - 104448 */ + {0x22, 0x5e, 0xa3, 0x49, 0xb9, 0xcb, 0x3b, 0x1b, 0x94, 0xe2, 0x37, 0xde, 0xb7, 0x97, 0xe0, 0xc6, 0x0d, 0x14, 0xa8, 0x4c}, /* file 06-8e-0c, bytes 0 - 104448 */ + {0xa5, 0x64, 0x05, 0xde, 0x5b, 0x4c, 0xe5, 0x94, 0xc7, 0x9a, 0xf0, 0xf2, 0x09, 0xeb, 0xb0, 0xbf, 0x66, 0x2c, 0x3c, 0x5c}, /* file 06-96-01, bytes 0 - 20480 */ + {0x26, 0xa2, 0x8f, 0xdd, 0xe7, 0xff, 0xc6, 0xcb, 0xdb, 0x4d, 0x01, 0x93, 0x4a, 0x1b, 0x69, 0xb7, 0x38, 0xb2, 0xb9, 0xfc}, /* file 06-9c-00, bytes 0 - 20480 */ + {0xfc, 0x5c, 0x02, 0x06, 0xfe, 0x39, 0x2a, 0x0d, 0xda, 0xd4, 0xdc, 0x93, 0x63, 0xfd, 0xe2, 0xd3, 0xe3, 0xd1, 0xe6, 0x81}, /* file 06-9e-09, bytes 0 - 106496 */ + {0x12, 0x80, 0x02, 0x07, 0x6e, 0x4a, 0xc3, 0xc7, 0x56, 0x97, 0xfb, 0x4e, 0xfd, 0xf1, 0xf8, 0xdd, 0xcc, 0x97, 0x1f, 0xbe}, /* file 06-9e-0a, bytes 0 - 102400 */ + {0xac, 0x8c, 0x38, 0x65, 0xa1, 0x43, 0xb2, 0xe0, 0x38, 0x69, 0xf1, 0x5a, 0x5b, 0x86, 0xe5, 0x60, 0xf6, 0x0a, 0xd6, 0x32}, /* file 06-9e-0b, bytes 0 - 104448 */ + {0x6e, 0x3d, 0x69, 0x52, 0x90, 0xde, 0xf5, 0x17, 0x85, 0x7c, 0x8e, 0x74, 0x3d, 0xc6, 0x51, 0x61, 0x47, 0x9f, 0x0c, 0x04}, /* file 06-9e-0c, bytes 0 - 103424 */ + {0x58, 0xb1, 0xec, 0x5f, 0xee, 0x7d, 0xd1, 0xa7, 0x61, 0xed, 0x90, 0x1b, 0x37, 0x4c, 0xcb, 0x97, 0x87, 0x37, 0xa9, 0x79}, /* file 06-9e-0d, bytes 0 - 103424 */ + {0x85, 0x2b, 0xa0, 0x99, 0xd5, 0x2e, 0x9c, 0x26, 0x7f, 0xc7, 0xce, 0x78, 0xe5, 0x4c, 0x3e, 0x6e, 0x3f, 0x8c, 0x7a, 0x7d}, /* file 06-a5-02, bytes 0 - 93184 */ + {0xef, 0x1c, 0xb3, 0xe8, 0x7c, 0x46, 0x33, 0xf0, 0xce, 0xda, 0xa8, 0xe4, 0xd8, 0x11, 0xaf, 0xf7, 0xd0, 0xa9, 0x85, 0x3a}, /* file 06-a5-03, bytes 0 - 94208 */ + {0x6f, 0xdc, 0x02, 0x7a, 0xdc, 0xba, 0x80, 0x84, 0x7b, 0x2a, 0x4e, 0xc3, 0x4f, 0xd3, 0x16, 0x0b, 0x3d, 0x57, 0x4e, 0x4d}, /* file 06-a5-05, bytes 0 - 94208 */ + {0x55, 0xd4, 0x77, 0xda, 0x8b, 0x1c, 0x60, 0x75, 0xeb, 0x35, 0x13, 0x73, 0xba, 0xec, 0xa0, 0x6a, 0x71, 0xa0, 0x63, 0xc0}, /* file 06-a6-00, bytes 0 - 94208 */ + {0x82, 0x76, 0x5a, 0xf3, 0x5f, 0xd0, 0x3a, 0x57, 0x7f, 0x5f, 0x03, 0x03, 0x3a, 0x1d, 0x84, 0x86, 0xc3, 0x1b, 0x2d, 0x01}, /* file 06-a6-01, bytes 0 - 93184 */ + {0x74, 0xda, 0x77, 0x48, 0x7f, 0x9f, 0xf6, 0xfa, 0xf8, 0xe3, 0xc2, 0xf2, 0xdd, 0x6f, 0x1d, 0x60, 0x7c, 0xb7, 0x3e, 0x77}, /* file 06-a7-01, bytes 0 - 102400 */ + {0x50, 0x39, 0x92, 0x85, 0xa7, 0xe0, 0xaf, 0x39, 0xea, 0xb8, 0x20, 0x8f, 0x9e, 0x24, 0x2b, 0x05, 0x31, 0x72, 0x65, 0x86}, /* file 0f-00-07, bytes 0 - 2048 */ + {0x42, 0xc4, 0xc5, 0x5a, 0xeb, 0x0e, 0x16, 0xfa, 0x10, 0x55, 0xe0, 0x0e, 0xf5, 0x9e, 0x46, 0xc6, 0x8c, 0x02, 0xa2, 0x88}, /* file 0f-00-07, bytes 2048 - 4096 */ + {0xbe, 0xcc, 0xfa, 0x3a, 0xf4, 0x6f, 0x08, 0x70, 0x4d, 0xf1, 0x1c, 0x1b, 0xa7, 0x05, 0x64, 0xff, 0x8b, 0x3e, 0xc4, 0x63}, /* file 0f-00-0a, bytes 0 - 2048 */ + {0x89, 0xb4, 0xa4, 0xf2, 0x89, 0xd9, 0x0b, 0x5d, 0x10, 0xad, 0x94, 0x72, 0xdf, 0x69, 0x39, 0x51, 0xe3, 0xd8, 0xf7, 0xbc}, /* file 0f-00-0a, bytes 2048 - 4096 */ + {0x53, 0x4f, 0x9c, 0x0c, 0xdb, 0x6c, 0x87, 0x42, 0x1b, 0xb4, 0x4d, 0x18, 0xde, 0xda, 0xe9, 0xa1, 0xf5, 0xc0, 0x60, 0xd7}, /* file 0f-00-0a, bytes 4096 - 6144 */ + {0x45, 0xe0, 0x46, 0xa2, 0x2e, 0xb8, 0x6f, 0xdc, 0xde, 0x60, 0xae, 0x17, 0x82, 0x23, 0xb2, 0x6f, 0x5b, 0x57, 0xb5, 0xde}, /* file 0f-01-02, bytes 0 - 2048 */ + {0x4d, 0x75, 0x38, 0x8a, 0x13, 0x6f, 0x7a, 0xb7, 0x6d, 0x8f, 0x8e, 0x0b, 0xda, 0xc8, 0x84, 0xdb, 0x7d, 0xd7, 0xd5, 0x9e}, /* file 0f-02-04, bytes 0 - 2048 */ + {0x6a, 0x56, 0x0b, 0x60, 0x6a, 0x3e, 0x63, 0xe7, 0xdf, 0xa4, 0x33, 0x5c, 0x06, 0x43, 0x36, 0xe2, 0x57, 0x20, 0xeb, 0xb8}, /* file 0f-02-04, bytes 2048 - 4096 */ + {0x7f, 0xb3, 0xb5, 0x6f, 0x69, 0x6d, 0xe9, 0x37, 0xf0, 0x5c, 0xdd, 0x4f, 0x06, 0x5c, 0xab, 0xc8, 0x2d, 0xfe, 0xf2, 0xab}, /* file 0f-02-04, bytes 4096 - 6144 */ + {0xfa, 0x5c, 0x38, 0xd3, 0x29, 0x65, 0x4d, 0x10, 0xf5, 0x94, 0x8e, 0x29, 0x7e, 0xec, 0x7e, 0x54, 0x9b, 0x75, 0x70, 0x27}, /* file 0f-02-05, bytes 0 - 2048 */ + {0x37, 0x3d, 0x72, 0x91, 0x5a, 0xa4, 0x3d, 0xd0, 0xef, 0x46, 0xed, 0xbb, 0x61, 0xe1, 0xa5, 0xcd, 0x4a, 0x3b, 0x87, 0x27}, /* file 0f-02-05, bytes 2048 - 4096 */ + {0x2a, 0xe5, 0x66, 0x08, 0xcf, 0x2b, 0x91, 0x08, 0xc7, 0x42, 0xcd, 0x14, 0x14, 0x53, 0x82, 0xf3, 0xef, 0x86, 0x10, 0xbd}, /* file 0f-02-05, bytes 4096 - 6144 */ + {0xc7, 0xfd, 0xdf, 0x8a, 0xdf, 0x95, 0x1b, 0xdc, 0xd1, 0xd4, 0x2c, 0xa2, 0x1a, 0xc4, 0xdf, 0x88, 0x51, 0x1c, 0x1c, 0x8c}, /* file 0f-02-05, bytes 6144 - 8192 */ + {0x64, 0x7e, 0x33, 0x89, 0x3c, 0xe9, 0xe5, 0x75, 0x70, 0xf9, 0x3b, 0x8f, 0xbd, 0xf7, 0x2f, 0xd9, 0xec, 0x71, 0x78, 0x61}, /* file 0f-02-06, bytes 0 - 2048 */ + {0x76, 0x44, 0x96, 0xa4, 0x62, 0xfd, 0xb7, 0xdb, 0x6b, 0x89, 0xc4, 0x91, 0x95, 0xf5, 0xae, 0x26, 0xa9, 0x95, 0x7c, 0xbb}, /* file 0f-02-07, bytes 0 - 2048 */ + {0x52, 0xad, 0xf1, 0xda, 0x63, 0xd1, 0x3a, 0x4f, 0x5c, 0x85, 0xde, 0xe1, 0x78, 0x06, 0xb2, 0xd8, 0xbf, 0x23, 0x06, 0x17}, /* file 0f-02-07, bytes 2048 - 4096 */ + {0x29, 0xf2, 0xdf, 0xe6, 0x5c, 0xd9, 0xea, 0xc8, 0x7e, 0xaa, 0xb1, 0x32, 0x23, 0xc4, 0x30, 0x1e, 0x2c, 0xd6, 0xb4, 0xdf}, /* file 0f-02-07, bytes 4096 - 6144 */ + {0xce, 0x2d, 0x63, 0x5f, 0xe8, 0xc4, 0x4e, 0x6f, 0xbb, 0x84, 0xf9, 0x7f, 0x28, 0x52, 0x75, 0xb4, 0xaa, 0x35, 0xd4, 0xde}, /* file 0f-02-09, bytes 0 - 2048 */ + {0x24, 0x0d, 0xc3, 0xe0, 0xdc, 0x2d, 0x65, 0xe9, 0x30, 0x7b, 0x19, 0xb4, 0x49, 0xcd, 0xdb, 0xe8, 0x42, 0x83, 0xf4, 0x57}, /* file 0f-02-09, bytes 2048 - 4096 */ + {0xa3, 0x92, 0x9c, 0x58, 0x9d, 0x34, 0xd1, 0x92, 0x1c, 0xaa, 0x50, 0xdc, 0xaf, 0xac, 0x80, 0x78, 0x04, 0x7c, 0x67, 0xa7}, /* file 0f-02-09, bytes 4096 - 6144 */ + {0x39, 0xe7, 0x59, 0xd1, 0x60, 0x82, 0xe2, 0xa2, 0x3f, 0x5b, 0xd3, 0xea, 0xcc, 0xee, 0xe3, 0xb5, 0x35, 0x97, 0x58, 0xb0}, /* file 0f-03-02, bytes 0 - 2048 */ + {0x3d, 0xdc, 0x7c, 0xe4, 0x81, 0x08, 0x8b, 0xdc, 0x4b, 0x4f, 0x4f, 0xa9, 0x4b, 0x7a, 0x54, 0x20, 0x90, 0xf9, 0x4c, 0xa8}, /* file 0f-03-03, bytes 0 - 2048 */ + {0x62, 0x17, 0x0f, 0xa6, 0xed, 0x4f, 0x02, 0xdb, 0x28, 0xff, 0x92, 0xdf, 0xae, 0xe3, 0xb8, 0x83, 0x64, 0x28, 0x44, 0xa6}, /* file 0f-03-04, bytes 0 - 7168 */ + {0xf6, 0x9a, 0x78, 0xf2, 0xab, 0xf4, 0xbd, 0xaf, 0x3e, 0x95, 0xa1, 0x76, 0x23, 0xc6, 0xf3, 0x32, 0xec, 0x6e, 0xba, 0xb8}, /* file 0f-04-01, bytes 0 - 5120 */ + {0x37, 0xfd, 0x0d, 0x8f, 0x71, 0xad, 0xbb, 0xf7, 0x2c, 0xa9, 0xf0, 0x06, 0xb9, 0xa5, 0xcf, 0x54, 0xbf, 0x00, 0x70, 0x2d}, /* file 0f-04-01, bytes 5120 - 10240 */ + {0x7d, 0x80, 0x7a, 0x1f, 0x4e, 0x2a, 0xff, 0x6f, 0x8d, 0xe5, 0x53, 0xce, 0xc8, 0x1e, 0xfb, 0x03, 0x69, 0x9f, 0x65, 0x31}, /* file 0f-04-03, bytes 0 - 2048 */ + {0x53, 0xf8, 0x9f, 0xab, 0xb6, 0x78, 0x78, 0xbd, 0x3b, 0x63, 0x45, 0x91, 0x56, 0xee, 0x7b, 0x5a, 0x97, 0x67, 0x7b, 0x7a}, /* file 0f-04-04, bytes 0 - 3072 */ + {0xd6, 0x44, 0x5a, 0xc1, 0x39, 0xb1, 0xba, 0x6c, 0xfb, 0x92, 0x97, 0xac, 0x4f, 0x00, 0x14, 0x98, 0xac, 0x10, 0x54, 0x51}, /* file 0f-04-07, bytes 0 - 3072 */ + {0x62, 0x90, 0x30, 0x07, 0x07, 0x56, 0xf8, 0xc5, 0x35, 0xce, 0x2c, 0x4a, 0x61, 0x20, 0xee, 0x52, 0xa1, 0xd1, 0x7b, 0x38}, /* file 0f-04-08, bytes 0 - 3072 */ + {0x09, 0x9d, 0x26, 0xf8, 0xf9, 0x29, 0xf8, 0xc0, 0x8e, 0x5f, 0x38, 0x8e, 0x3d, 0xc5, 0x9b, 0x71, 0xa7, 0x10, 0xbc, 0x9b}, /* file 0f-04-08, bytes 3072 - 6144 */ + {0x98, 0xe2, 0xd9, 0xfb, 0x5d, 0xea, 0x02, 0x5b, 0xb3, 0x74, 0xe5, 0x72, 0xec, 0xa1, 0x75, 0x5a, 0x09, 0x09, 0x5b, 0x8d}, /* file 0f-04-08, bytes 6144 - 9216 */ + {0x89, 0x53, 0x42, 0xe1, 0x33, 0x6d, 0xc1, 0xf5, 0xce, 0x63, 0xf9, 0xa7, 0xc5, 0xc6, 0xa4, 0xde, 0x8f, 0x81, 0x7a, 0x6e}, /* file 0f-04-09, bytes 0 - 2048 */ + {0xac, 0xb0, 0x7c, 0x14, 0x09, 0x3d, 0xdc, 0xee, 0x56, 0x30, 0x55, 0x29, 0x2f, 0xe1, 0xbe, 0x6b, 0xe4, 0x2a, 0xea, 0xc2}, /* file 0f-04-0a, bytes 0 - 2048 */ + {0xa0, 0x5e, 0x93, 0x40, 0xb6, 0x8f, 0xae, 0x50, 0xa1, 0xe0, 0x25, 0x9c, 0x13, 0x6e, 0x77, 0xb9, 0x6e, 0x7a, 0x53, 0x9d}, /* file 0f-04-0a, bytes 2048 - 4096 */ + {0x6c, 0xfc, 0x64, 0x25, 0x93, 0x79, 0x82, 0x17, 0x45, 0x6f, 0x0a, 0x54, 0xd2, 0x24, 0x01, 0xca, 0x09, 0x30, 0x50, 0x24}, /* file 0f-06-02, bytes 0 - 3072 */ + {0x8d, 0xb6, 0x71, 0x2e, 0x0b, 0x38, 0x4b, 0xbe, 0x41, 0x77, 0xd1, 0xd6, 0x3b, 0xf7, 0xe2, 0xf7, 0x92, 0x9f, 0x43, 0x2b}, /* file 0f-06-04, bytes 0 - 3072 */ + {0xee, 0x31, 0x41, 0x13, 0x01, 0x69, 0x53, 0xbc, 0x3a, 0x60, 0x55, 0x8b, 0x58, 0xac, 0xa2, 0x26, 0xdb, 0xcc, 0xb4, 0x80}, /* file 0f-06-04, bytes 3072 - 6144 */ + {0xbc, 0x90, 0x24, 0x5b, 0x0e, 0x5e, 0xfc, 0xec, 0x3f, 0xe6, 0xe5, 0x8f, 0x16, 0xc0, 0x37, 0x67, 0xa3, 0x0c, 0x74, 0xc6}, /* file 0f-06-05, bytes 0 - 2048 */ + {0x31, 0x61, 0xe2, 0xb4, 0x7f, 0xaf, 0xc3, 0x1f, 0x78, 0xda, 0xa8, 0xca, 0xd2, 0x27, 0x2a, 0x87, 0xb4, 0x00, 0x0c, 0xc1}, /* file 0f-06-08, bytes 0 - 2048 */ +}; + +u32 ucode_recognized_sha1s_len = sizeof(ucode_recognized_sha1s) / sizeof(ucode_recognized_sha1s[0]); + diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/vmx/peh-x86vmx-ucode.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/vmx/peh-x86vmx-ucode.c new file mode 100644 index 0000000000..e6f02a2bf4 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-eventhub/arch/x86/vmx/peh-x86vmx-ucode.c @@ -0,0 +1,275 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// peh-x86vmx-ucode.c +// Handle Intel microcode update +// author: Eric Li (xiaoyili@andrew.cmu.edu) +#include + +#include +#include + +extern unsigned char ucode_recognized_sha1s[][SHA_DIGEST_LENGTH]; +extern u32 ucode_recognized_sha1s_len; + +/* + * Maximum supported microcode size. For some CPUs this may need to be much + * larger (e.g. > 256K). + */ +#define UCODE_TOTAL_SIZE_MAX (PAGE_SIZE_4K) + +/* Space to temporarily copy microcode update (prevent TOCTOU attack) */ +static u8 ucode_copy_area[MAX_VCPU_ENTRIES * UCODE_TOTAL_SIZE_MAX] +__attribute__(( section(".bss.palign_data") )); + +typedef struct __attribute__ ((packed)) { + u32 header_version; + u32 update_version; + u32 date; + u32 processor_signature; + u32 checksum; + u32 loader_version; + u32 processor_flags; + u32 data_size; + u32 total_size; + u32 reserved[3]; + u8 update_data[0]; +} intel_ucode_update_t; + +typedef struct __attribute__ ((packed)) { + u32 processor_signature; + u32 processor_flags; + u32 checksum; +} intel_ucode_ext_sign_t; + +typedef struct __attribute__ ((packed)) { + u32 extended_signature_count; + u32 extended_processor_signature_table_checksum; + u32 reserved[3]; + intel_ucode_ext_sign_t signatures[0]; +} intel_ucode_ext_sign_table_t; + +typedef struct { + hptw_ctx_t guest_ctx; + hptw_ctx_t host_ctx; +} ucode_hptw_ctx_pair_t; + +static hpt_pa_t ucode_host_ctx_ptr2pa(void *vctx, void *ptr) +{ + (void)vctx; + return hva2spa(ptr); +} + +static void* ucode_host_ctx_pa2ptr(void *vctx, hpt_pa_t spa, size_t sz, hpt_prot_t access_type, hptw_cpl_t cpl, size_t *avail_sz) +{ + (void)vctx; + (void)access_type; + (void)cpl; + *avail_sz = sz; + return spa2hva(spa); +} + +static hpt_pa_t ucode_guest_ctx_ptr2pa(void __attribute__((unused)) *ctx, void *ptr) +{ + return hva2gpa(ptr); +} + +static void* ucode_guest_ctx_pa2ptr(void *vctx, hpt_pa_t gpa, size_t sz, hpt_prot_t access_type, hptw_cpl_t cpl, size_t *avail_sz) +{ + ucode_hptw_ctx_pair_t *ctx_pair = vctx; + + return hptw_checked_access_va(&ctx_pair->host_ctx, + access_type, + cpl, + gpa, + sz, + avail_sz); +} + +static void* ucode_ctx_unimplemented(void *vctx, size_t alignment, size_t sz) +{ + (void)vctx; + (void)alignment; + (void)sz; + HALT_ON_ERRORCOND(0 && "Not implemented"); + return NULL; +} + +/* + * Check SHA-1 hash of the update + * Return 1 if the update is recognized, 0 otherwise + */ +static int ucode_check_sha1(intel_ucode_update_t *header) +{ + const unsigned char *buffer = (const unsigned char *) header; + unsigned char md[SHA_DIGEST_LENGTH]; + HALT_ON_ERRORCOND(sha1_buffer(buffer, header->total_size, md) == 0); + print_hex("SHA1(update) = ", md, SHA_DIGEST_LENGTH); + for (u32 i = 0; i < ucode_recognized_sha1s_len; i++) { + if (memcmp(md, ucode_recognized_sha1s[i], SHA_DIGEST_LENGTH) == 0) { + return 1; + } + } + return 0; +} + +/* + * Check the processor flags of the update + * Return 1 if the update is for this processor, 0 otherwise + */ +static int ucode_check_processor_flags(u32 processor_flags) +{ + u64 flag = 1 << ((rdmsr64(IA32_PLATFORM_ID) >> 50) & 0x7); + return !!(processor_flags & flag); +} + +/* + * Check the processor signature and processor flags of the update + * Return 1 if the update is for this processor, 0 otherwise + */ +static int ucode_check_processor(intel_ucode_update_t *header) +{ + u32 eax, ebx, ecx, edx; + cpuid(1, &eax, &ebx, &ecx, &edx); + HALT_ON_ERRORCOND(header->header_version == 1); + if (header->processor_signature == eax) { + return ucode_check_processor_flags(header->processor_flags); + } else if (header->total_size > header->data_size + 48) { + intel_ucode_ext_sign_table_t *ext_sign_table; + u32 n; + u32 ext_size = header->total_size - (header->data_size + 48); + HALT_ON_ERRORCOND(ext_size >= sizeof(intel_ucode_ext_sign_table_t)); + ext_sign_table = ((void *) header) + (header->data_size + 48); + n = ext_sign_table->extended_signature_count; + HALT_ON_ERRORCOND(ext_size >= sizeof(intel_ucode_ext_sign_table_t) + + n * sizeof(intel_ucode_ext_sign_t)); + for (u32 i = 0; i < n; i++) { + intel_ucode_ext_sign_t *signature = &ext_sign_table->signatures[i]; + if (signature->processor_signature == eax) { + return ucode_check_processor_flags(signature->processor_flags); + } + } + } + return 0; +} + +/* + * Update microcode. + * This function should be called when handling WRMSR to IA32_BIOS_UPDT_TRIG. + * update_data should be EDX:EAX, which is the guest virtual address of "Update + * Data". The header and other metadata (e.g. size) starts at 48 bytes before + * this address. + */ +void handle_intel_ucode_update(VCPU *vcpu, u64 update_data) +{ + hpt_type_t guest_t = hpt_emhf_get_guest_hpt_type(vcpu); + ucode_hptw_ctx_pair_t ctx_pair = { + .guest_ctx = { + .ptr2pa = ucode_guest_ctx_ptr2pa, + .pa2ptr = ucode_guest_ctx_pa2ptr, + .gzp = ucode_ctx_unimplemented, + .root_pa = hpt_cr3_get_address(guest_t, vcpu->vmcs.guest_CR3), + .t = guest_t, + }, + .host_ctx = { + .ptr2pa = ucode_host_ctx_ptr2pa, + .pa2ptr = ucode_host_ctx_pa2ptr, + .gzp = ucode_ctx_unimplemented, + .root_pa = hpt_eptp_get_address(HPT_TYPE_EPT, + vcpu->vmcs.control_EPT_pointer), + .t = HPT_TYPE_EPT, + } + }; + hptw_ctx_t *ctx = &ctx_pair.guest_ctx; + u64 va_header = update_data - sizeof(intel_ucode_update_t); + u8 *copy_area; + intel_ucode_update_t *header; + int result; + size_t size; + HALT_ON_ERRORCOND(vcpu->idx < UCODE_TOTAL_SIZE_MAX); + copy_area = ucode_copy_area + UCODE_TOTAL_SIZE_MAX * vcpu->idx; + /* Copy header of microcode update */ + header = (intel_ucode_update_t *) copy_area; + size = sizeof(intel_ucode_update_t); + result = hptw_checked_copy_from_va(ctx, 0, header, va_header, size); + HALT_ON_ERRORCOND(result == 0); + printf("\nCPU(0x%02x): date(mmddyyyy)=%08x, dsize=%d, tsize=%d", + vcpu->id, header->date, header->data_size, header->total_size); + /* If the following check fails, increase UCODE_TOTAL_SIZE_MAX */ + HALT_ON_ERRORCOND(header->total_size <= UCODE_TOTAL_SIZE_MAX); + /* Copy the rest of of microcode update */ + size = header->total_size - size; + result = hptw_checked_copy_from_va(ctx, 0, &header->update_data, + update_data, size); + /* Check the hash of the update */ + if (!ucode_check_sha1(header)) { + printf("\nCPU(0x%02x): Unrecognized microcode update, HALT!", vcpu->id); + HALT(); + } + /* Check whether update is for the processor */ + if (!ucode_check_processor(header)) { + printf("\nCPU(0x%02x): Incompatible microcode update, HALT!", vcpu->id); + HALT(); + } + /* + for (u32 i = 0; i < header->total_size; i++) { + if (i % 16 == 0) { + printf("\n%08x ", i); + } else if (i % 8 == 0) { + printf(" "); + } else { + printf(" "); + } + printf("%02x", copy_area[i]); + } + */ + /* Forward microcode update to host */ + printf("\nCPU(0x%02x): Calling physical ucode update at 0x%08lx", + vcpu->id, &header->update_data); + wrmsr64(IA32_BIOS_UPDT_TRIG, (uintptr_t) &header->update_data); + printf("\nCPU(0x%02x): Physical ucode update returned", vcpu->id); +} + diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-memprot/Makefile b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-memprot/Makefile new file mode 100644 index 0000000000..ce8f7aaada --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-memprot/Makefile @@ -0,0 +1,17 @@ +# makefile for xmhf-memprot (EMHF memory protection component) +# author: amit vasudevan (amitvasudevan@acm.org) + +# source files +AS_SOURCES = +C_SOURCES = memp-interface.c +C_SOURCES += ./arch/x86/memp-x86.c + +C_SOURCES += ./arch/x86/vmx/memp-x86vmx.c +C_SOURCES += ./arch/x86/vmx/memp-x86vmx-data.c + +C_SOURCES += ./arch/x86/svm/memp-x86svm.c +C_SOURCES += ./arch/x86/svm/memp-x86svm-data.c + +# targets +include ../runtime.mk + diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-memprot/arch/x86/memp-x86.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-memprot/arch/x86/memp-x86.c new file mode 100644 index 0000000000..fec11b8742 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-memprot/arch/x86/memp-x86.c @@ -0,0 +1,196 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF memory protection component +// generic x86 arch. backend implementation +// author: amit vasudevan (amitvasudevan@acm.org) + +#include + +// initialize memory protection structures for a given core (vcpu) +void xmhf_memprot_arch_initialize(VCPU *vcpu){ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_AMD || vcpu->cpu_vendor == CPU_VENDOR_INTEL); + if(vcpu->cpu_vendor == CPU_VENDOR_AMD){ + xmhf_memprot_arch_x86svm_initialize(vcpu); + printf("\nCPU(0x%02x): Activated SVM NPTs.", vcpu->id); + }else{ //CPU_VENDOR_INTEL + xmhf_memprot_arch_x86vmx_initialize(vcpu); + printf("\nCPU(0x%02x): Activated VMX EPTs.", vcpu->id); + } +} + +// get level-1 page map address +u64 * xmhf_memprot_arch_get_lvl1_pagemap_address(VCPU *vcpu){ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_AMD || vcpu->cpu_vendor == CPU_VENDOR_INTEL); + + if (vcpu->cpu_vendor == CPU_VENDOR_AMD) + return (u64 *)vcpu->npt_vaddr_pts; + else //CPU_VENDOR_INTEL + return (u64 *)vcpu->vmx_vaddr_ept_p_tables; +} + +//get level-2 page map address +u64 * xmhf_memprot_arch_get_lvl2_pagemap_address(VCPU *vcpu){ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_AMD || vcpu->cpu_vendor == CPU_VENDOR_INTEL); + + if (vcpu->cpu_vendor == CPU_VENDOR_AMD) + return (u64 *)vcpu->npt_vaddr_pdts; + else //CPU_VENDOR_INTEL + return (u64 *)vcpu->vmx_vaddr_ept_pd_tables; +} + +//get level-3 page map address +u64 * xmhf_memprot_arch_get_lvl3_pagemap_address(VCPU *vcpu){ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_AMD || vcpu->cpu_vendor == CPU_VENDOR_INTEL); + + if (vcpu->cpu_vendor == CPU_VENDOR_AMD) + return (u64 *)vcpu->npt_vaddr_ptr; + else //CPU_VENDOR_INTEL + return (u64 *)vcpu->vmx_vaddr_ept_pdp_table; +} + +//get level-4 page map address +u64 * xmhf_memprot_arch_get_lvl4_pagemap_address(VCPU *vcpu){ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_INTEL); //we don;t have a level-4 pagemap for AMD + + return (u64 *)vcpu->vmx_vaddr_ept_pml4_table; +} + +//get default root page map address +u64 * xmhf_memprot_arch_get_default_root_pagemap_address(VCPU *vcpu){ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_AMD || vcpu->cpu_vendor == CPU_VENDOR_INTEL); + + if(vcpu->cpu_vendor == CPU_VENDOR_AMD) + return (u64*)vcpu->npt_vaddr_ptr; + else //CPU_VENDOR_INTEL + return (u64*)vcpu->vmx_vaddr_ept_pml4_table; +} + + +//flush hardware page table mappings (TLB) +void xmhf_memprot_arch_flushmappings(VCPU *vcpu){ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_AMD || vcpu->cpu_vendor == CPU_VENDOR_INTEL); + + if(vcpu->cpu_vendor == CPU_VENDOR_AMD) + xmhf_memprot_arch_x86svm_flushmappings(vcpu); + else //CPU_VENDOR_INTEL + xmhf_memprot_arch_x86vmx_flushmappings(vcpu); + +} + +//flush the TLB of all nested page tables in the current core +void xmhf_memprot_arch_flushmappings_localtlb(VCPU *vcpu){ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_AMD || vcpu->cpu_vendor == CPU_VENDOR_INTEL); + + if(vcpu->cpu_vendor == CPU_VENDOR_AMD) + xmhf_memprot_arch_x86svm_flushmappings(vcpu); + else //CPU_VENDOR_INTEL + xmhf_memprot_arch_x86vmx_flushmappings_localtlb(vcpu); +} + +//set protection for a given physical memory address +void xmhf_memprot_arch_setprot(VCPU *vcpu, u64 gpa, u32 prottype){ +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + assert ( (vcpu != NULL) ); + assert ( ( (gpa < rpb->XtVmmRuntimePhysBase) || + (gpa >= (rpb->XtVmmRuntimePhysBase + rpb->XtVmmRuntimeSize)) + ) ); + assert ( ( (prottype > 0) && + (prottype <= MEMP_PROT_MAXVALUE) + ) ); + assert ( + (prottype == MEMP_PROT_NOTPRESENT) || + ((prottype & MEMP_PROT_PRESENT) && (prottype & MEMP_PROT_READONLY) && (prottype & MEMP_PROT_EXECUTE)) || + ((prottype & MEMP_PROT_PRESENT) && (prottype & MEMP_PROT_READWRITE) && (prottype & MEMP_PROT_EXECUTE)) || + ((prottype & MEMP_PROT_PRESENT) && (prottype & MEMP_PROT_READONLY) && (prottype & MEMP_PROT_NOEXECUTE)) || + ((prottype & MEMP_PROT_PRESENT) && (prottype & MEMP_PROT_READWRITE) && (prottype & MEMP_PROT_NOEXECUTE)) + ); +#endif + + //invoke appropriate sub arch. backend + if(vcpu->cpu_vendor == CPU_VENDOR_AMD) + xmhf_memprot_arch_x86svm_setprot(vcpu, gpa, prottype); + else //CPU_VENDOR_INTEL + xmhf_memprot_arch_x86vmx_setprot(vcpu, gpa, prottype); +} + +//get protection for a given physical memory address +u32 xmhf_memprot_arch_getprot(VCPU *vcpu, u64 gpa){ + //invoke appropriate sub arch. backend + if(vcpu->cpu_vendor == CPU_VENDOR_AMD) + return xmhf_memprot_arch_x86svm_getprot(vcpu, gpa); + else //CPU_VENDOR_INTEL + return xmhf_memprot_arch_x86vmx_getprot(vcpu, gpa); +} + +// On 32bit machine, we always return 0 - 4G as the machine physical address range, no matter how many memory is installed +// On 64-bit machine, the function queries the E820 map for the used memory region. +bool xmhf_arch_get_machine_paddr_range(spa_t* machine_base_spa, spa_t* machine_limit_spa) +{ + // Sanity checks + if(!machine_base_spa || !machine_limit_spa) + return false; + +#ifdef __AMD64__ + // Get the base and limit used system physical address from the E820 map + if (!xmhf_baseplatform_x86_e820_paddr_range(machine_base_spa, machine_limit_spa)) + { + printf("\n%s: Get system physical address range error! Halting!", __FUNCTION__); + return false; + } + + // 4K-align the return the address + *machine_base_spa = PAGE_ALIGN_4K(*machine_base_spa); + *machine_limit_spa = PAGE_ALIGN_UP_4K(*machine_limit_spa); +#elif defined(__I386__) + *machine_base_spa = 0; + *machine_limit_spa = ADDR_4GB; +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + + return true; +} \ No newline at end of file diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-memprot/arch/x86/svm/memp-x86svm-data.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-memprot/arch/x86/svm/memp-x86svm-data.c new file mode 100644 index 0000000000..f088132b78 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-memprot/arch/x86/svm/memp-x86svm-data.c @@ -0,0 +1,66 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/** + * EMHF memory protection component + * AMD SVM arch. backend implementation data + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//SVM NPT PDPT buffers +//memprot +u8 g_svm_npt_pdpt_buffers[PAGE_SIZE_4K * MAX_VCPU_ENTRIES] __attribute__(( section(".bss.palign_data") )); + +//SVM NPT PDT buffers +//memprot +u8 g_svm_npt_pdts_buffers[PAE_PTRS_PER_PDPT * PAGE_SIZE_4K * MAX_VCPU_ENTRIES]__attribute__(( section(".bss.palign_data") )); + + +//SVM NPT PT buffers +//memprot +u8 g_svm_npt_pts_buffers[PAE_PTRS_PER_PDPT * PAE_PTRS_PER_PDT * PAGE_SIZE_4K * MAX_VCPU_ENTRIES]__attribute__(( section(".bss.palign_data") )); diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-memprot/arch/x86/svm/memp-x86svm.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-memprot/arch/x86/svm/memp-x86svm.c new file mode 100644 index 0000000000..60e6914ed9 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-memprot/arch/x86/svm/memp-x86svm.c @@ -0,0 +1,206 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF memory protection component +// AMD SVM arch. backend implementation +// author: amit vasudevan (amitvasudevan@acm.org) + +#include + +//---------------------------------------------------------------------- +// local (static) support function forward declarations +static void _svm_nptinitialize(hva_t npt_pdpt_base, hva_t npt_pdts_base, hva_t npt_pts_base); + +//====================================================================== +// global interfaces (functions) exported by this component + +// initialize memory protection structures for a given core (vcpu) +void xmhf_memprot_arch_x86svm_initialize(VCPU *vcpu){ + struct _svm_vmcbfields *vmcb = (struct _svm_vmcbfields *)vcpu->vmcb_vaddr_ptr; + + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_AMD); + +#ifndef __XMHF_VERIFICATION__ + _svm_nptinitialize(vcpu->npt_vaddr_ptr, vcpu->npt_vaddr_pdts, vcpu->npt_vaddr_pts); +#endif + vmcb->n_cr3 = hva2spa((void*)vcpu->npt_vaddr_ptr); + vmcb->np_enable |= 1ULL; + vmcb->guest_asid = vcpu->npt_asid; +} + +//---------------------------------------------------------------------- +// local (static) support functions follow +//---npt initialize------------------------------------------------------------- +static void _svm_nptinitialize(hva_t npt_pdpt_base, hva_t npt_pdts_base, hva_t npt_pts_base){ + pdpt_t pdpt; + pdt_t pdt; + pt_t pt; + u32 paddr=0, i, j, k; + spa_t y, z; + u64 flags; + + printf("\n%s: pdpt=0x%08x, pdts=0x%08x, pts=0x%08x", __FUNCTION__, npt_pdpt_base, npt_pdts_base, npt_pts_base); + + pdpt=(pdpt_t)npt_pdpt_base; + + for(i = 0; i < PAE_PTRS_PER_PDPT; i++){ + y = hva2spa((void*)(npt_pdts_base + (i << PAGE_SHIFT_4K))); + flags = (u64)(_PAGE_PRESENT); + pdpt[i] = pae_make_pdpe(y, flags); + pdt=(pdt_t)(npt_pdts_base + (i << PAGE_SHIFT_4K)); + + for(j=0; j < PAE_PTRS_PER_PDT; j++){ + z=hva2spa((void*)(npt_pts_base + ((i * PAE_PTRS_PER_PDT + j) << (PAGE_SHIFT_4K)))); + flags = (u64)(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER); + pdt[j] = pae_make_pde(z, flags); + pt=(pt_t)(npt_pts_base + ((i * PAE_PTRS_PER_PDT + j) << (PAGE_SHIFT_4K))); + + for(k=0; k < PAE_PTRS_PER_PT; k++){ + //the XMHF memory region includes the secure loader + + //the runtime (core + app). this runs from + //(rpb->XtVmmRuntimePhysBase - PAGE_SIZE_2M) with a size + //of (rpb->XtVmmRuntimeSize+PAGE_SIZE_2M) + //make XMHF physical pages inaccessible + if( (paddr >= (rpb->XtVmmRuntimePhysBase - PAGE_SIZE_2M)) && + (paddr < (rpb->XtVmmRuntimePhysBase + rpb->XtVmmRuntimeSize)) ) + flags = 0; //not-present + else + flags = (u64)(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER); //present + pt[k] = pae_make_pte((u64)paddr, flags); + paddr+= PAGE_SIZE_4K; + } + } + } + +} + +//flush hardware page table mappings (TLB) +void xmhf_memprot_arch_x86svm_flushmappings(VCPU *vcpu){ + ((struct _svm_vmcbfields *)(vcpu->vmcb_vaddr_ptr))->tlb_control=VMCB_TLB_CONTROL_FLUSHALL; +} + +//set protection for a given physical memory address +void xmhf_memprot_arch_x86svm_setprot(VCPU *vcpu, u64 gpa, u32 prottype){ + u32 pfn; + u64 *pt; + u64 flags=0; + +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + assert ( (vcpu != NULL) ); + assert ( ( (gpa < rpb->XtVmmRuntimePhysBase) || + (gpa >= (rpb->XtVmmRuntimePhysBase + rpb->XtVmmRuntimeSize)) + ) ); + assert ( ( (prottype > 0) && + (prottype <= MEMP_PROT_MAXVALUE) + ) ); + assert ( + (prottype == MEMP_PROT_NOTPRESENT) || + ((prottype & MEMP_PROT_PRESENT) && (prottype & MEMP_PROT_READONLY) && (prottype & MEMP_PROT_EXECUTE)) || + ((prottype & MEMP_PROT_PRESENT) && (prottype & MEMP_PROT_READWRITE) && (prottype & MEMP_PROT_EXECUTE)) || + ((prottype & MEMP_PROT_PRESENT) && (prottype & MEMP_PROT_READONLY) && (prottype & MEMP_PROT_NOEXECUTE)) || + ((prottype & MEMP_PROT_PRESENT) && (prottype & MEMP_PROT_READWRITE) && (prottype & MEMP_PROT_NOEXECUTE)) + ); +#endif + + pfn = (u32)gpa / PAGE_SIZE_4K; //grab page frame number + pt = (u64 *)vcpu->npt_vaddr_pts; + + //default is not-present, read-only, no-execute + flags = (u64)0x8000000000000000ULL; + + //map high level protection type to NPT protection bits + if(prottype & MEMP_PROT_PRESENT){ + flags |= 0x1; //present + + if(prottype & MEMP_PROT_READWRITE) + flags |= 0x2; //read-write + + if(prottype & MEMP_PROT_EXECUTE) + flags &= ~(u64)0x8000000000000000ULL; //execute + } + + pt[pfn] &= ~(u64)0x8000000000000003ULL; //clear all previous flags + pt[pfn] |= flags; //set new flags +} + +//get protection for a given physical memory address +u32 xmhf_memprot_arch_x86svm_getprot(VCPU *vcpu, u64 gpa){ + u32 pfn = (u32)gpa / PAGE_SIZE_4K; //grab page frame number + u64 *pt = (u64 *)vcpu->npt_vaddr_pts; + + u64 entry = pt[pfn]; + u32 prottype; + + if(! (entry & 0x1) ){ + prottype = MEMP_PROT_NOTPRESENT; + return prottype; + } + + prottype = MEMP_PROT_PRESENT; + + if( entry & 0x2 ) + prottype |= MEMP_PROT_READWRITE; + else + prottype |= MEMP_PROT_READONLY; + + if( !(entry & 0x8000000000000000ULL) ) + prottype |= MEMP_PROT_EXECUTE; + else + prottype |= MEMP_PROT_NOEXECUTE; + + return prottype; +} + +u64 xmhf_memprot_arch_x86svm_get_h_cr3(VCPU *vcpu) +{ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_AMD); + return ((struct _svm_vmcbfields*)vcpu->vmcb_vaddr_ptr)->n_cr3; +} +void xmhf_memprot_arch_x86svm_set_h_cr3(VCPU *vcpu, u64 n_cr3) +{ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_AMD); + ((struct _svm_vmcbfields*)vcpu->vmcb_vaddr_ptr)->n_cr3 = n_cr3; +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-memprot/arch/x86/vmx/memp-x86vmx-data.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-memprot/arch/x86/vmx/memp-x86vmx-data.c new file mode 100644 index 0000000000..448016fba2 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-memprot/arch/x86/vmx/memp-x86vmx-data.c @@ -0,0 +1,69 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/** + * EMHF memory protection component + * Intel VMX arch. backend implementation data + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//VMX EPT PML4 table buffers +//memprot +u8 g_vmx_ept_pml4_table_buffers[PAGE_SIZE_4K * P4L_NPLM4T * MAX_VCPU_ENTRIES] __attribute__(( section(".bss.palign_data") )); + +//VMX EPT PDP table buffers +//memprot +u8 g_vmx_ept_pdp_table_buffers[PAGE_SIZE_4K * P4L_NPDPT * MAX_VCPU_ENTRIES] __attribute__(( section(".bss.palign_data") )); + +//VMX EPT PD table buffers +//memprot +u8 g_vmx_ept_pd_table_buffers[PAGE_SIZE_4K * P4L_NPDT * MAX_VCPU_ENTRIES] __attribute__(( section(".bss.palign_data") )); + +//VMX EPT P table buffers +//memprot +u8 g_vmx_ept_p_table_buffers[PAGE_SIZE_4K * P4L_NPT * MAX_VCPU_ENTRIES] __attribute__(( section(".bss.palign_data") )); diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-memprot/arch/x86/vmx/memp-x86vmx.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-memprot/arch/x86/vmx/memp-x86vmx.c new file mode 100644 index 0000000000..3f61c1f3c2 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-memprot/arch/x86/vmx/memp-x86vmx.c @@ -0,0 +1,619 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF memory protection component +// intel VMX arch. backend implementation +// author: amit vasudevan (amitvasudevan@acm.org) + +#include + +//---------------------------------------------------------------------- +// Structure that captures fixed MTRR properties +struct _fixed_mtrr_prop_t { + u32 msr; /* MSR register address (ECX in RDMSR / WRMSR) */ + u32 start; /* Start address */ + u32 step; /* Size of each range */ + u32 end; /* End address (start + 8 * step == end) */ +} fixed_mtrr_prop[NUM_FIXED_MTRRS] = { + {IA32_MTRR_FIX64K_00000, 0x00000000, 0x00010000, 0x00080000}, + {IA32_MTRR_FIX16K_80000, 0x00080000, 0x00004000, 0x000A0000}, + {IA32_MTRR_FIX16K_A0000, 0x000A0000, 0x00004000, 0x000C0000}, + {IA32_MTRR_FIX4K_C0000, 0x000C0000, 0x00001000, 0x000C8000}, + {IA32_MTRR_FIX4K_C8000, 0x000C8000, 0x00001000, 0x000D0000}, + {IA32_MTRR_FIX4K_D0000, 0x000D0000, 0x00001000, 0x000D8000}, + {IA32_MTRR_FIX4K_D8000, 0x000D8000, 0x00001000, 0x000E0000}, + {IA32_MTRR_FIX4K_E0000, 0x000E0000, 0x00001000, 0x000E8000}, + {IA32_MTRR_FIX4K_E8000, 0x000E8000, 0x00001000, 0x000F0000}, + {IA32_MTRR_FIX4K_F0000, 0x000F0000, 0x00001000, 0x000F8000}, + {IA32_MTRR_FIX4K_F8000, 0x000F8000, 0x00001000, 0x00100000}, +}; + +//---------------------------------------------------------------------- +// local (static) support function forward declarations +static void _vmx_gathermemorytypes(VCPU *vcpu); +static u32 _vmx_getmemorytypeforphysicalpage(VCPU *vcpu, u64 pagebaseaddr); +static void _vmx_setupEPT(VCPU *vcpu); + +//====================================================================== +// global interfaces (functions) exported by this component + +// initialize memory protection structures for a given core (vcpu) +void xmhf_memprot_arch_x86vmx_initialize(VCPU *vcpu){ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_INTEL); + + _vmx_gathermemorytypes(vcpu); +#ifndef __XMHF_VERIFICATION__ + _vmx_setupEPT(vcpu); +#endif + + vcpu->vmcs.control_VMX_seccpu_based |= (1 << 1); //enable EPT + vcpu->vmcs.control_VMX_seccpu_based |= (1 << 5); //enable VPID + vcpu->vmcs.control_vpid = 1; //VPID=0 is reserved for hypervisor + vcpu->vmcs.control_EPT_pointer = hva2spa((void*)vcpu->vmx_vaddr_ept_pml4_table) | 0x1E; //page walk of 4 and WB memory + vcpu->vmcs.control_VMX_cpu_based &= ~(1 << 15); //disable CR3 load exiting + vcpu->vmcs.control_VMX_cpu_based &= ~(1 << 16); //disable CR3 store exiting +} + + +//---------------------------------------------------------------------- +// local (static) support functions follow + +/* Check whether an MTRR type is valid, return 1 on valid, or 0 on invalid */ +static u32 _vmx_mtrr_checktype(u32 type) { + return (type == 0 || type == 1 || type == 4 || type == 5 || type == 6); +} + +/* + * Check whether IA32_MTRR_DEF_TYPE value is valid + * When valid, the following pointers are filled; when invalid, pointers not + * modified. + * pe: whether MTRRs are enabled + * pfe: whether fixed MTRRs are enabled + * ptype: default mtrr type + */ +static u32 _vmx_mtrr_checkdeftype(u64 msrval, u32 *pe, u32 *pfe, u32 *ptype) { + u32 e, fe, type; + /* Check reserved bits */ + if (msrval & ~0xCFFULL) { + return 0; + } + e = (msrval & 0x800U) ? 1 : 0; + fe = (msrval & 0x400U) ? 1 : 0; + type = msrval & 0xFFU; + /* If MTRRs are enabled, make sure type is valid */ + if (e && _vmx_mtrr_checktype(type) == 0) { + return 0; + } + *pe = e; + *pfe = fe; + *ptype = type; + return 1; +} + +/* Check whether a fixed MTRR is valid (e.g. IA32_MTRR_FIX64K_00000) */ +static u32 _vmx_mtrr_checkfixed(u64 msrval) { + for (u32 i = 0; i < 8; i++) { + if (!_vmx_mtrr_checktype((u8) (msrval >> (i * 8)))) { + return 0; + } + } + return 1; +} + +/* Check whether a variable MTRR is valid (e.g. IA32_MTRR_PHYSBASE0) */ +static u32 _vmx_mtrr_checkvariable(VCPU *vcpu, u64 baseval, u64 maskval) { + u32 v, type; + /* Check reserved bits */ + if (baseval & ~(vcpu->vmx_ept_paddrmask | 0xFFULL)) { + return 0; + } + if (maskval & ~(vcpu->vmx_ept_paddrmask | 0x800ULL)) { + return 0; + } + v = maskval & 0x800U; + type = baseval & 0xFFU; + if (v && _vmx_mtrr_checktype(type) == 0) { + return 0; + } + return 1; +} + +//---gather memory types for system physical memory------------------------------ +static void _vmx_gathermemorytypes(VCPU *vcpu){ + u32 eax, ebx, ecx, edx; + u32 num_vmtrrs=0; //number of variable length MTRRs supported by the CPU + + //0. sanity check + //check MTRR support + eax=0x00000001; + ecx=0x00000000; + #ifndef __XMHF_VERIFICATION__ + asm volatile ("cpuid\r\n" + :"=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) + :"a"(eax), "c" (ecx)); + #endif + + if( !(edx & (u32)(1 << 12)) ){ + printf("\nCPU(0x%02x): CPU does not support MTRRs!", vcpu->id); + HALT(); + } + + //check MTRR caps + rdmsr(IA32_MTRRCAP, &eax, &edx); + num_vmtrrs = (u8)eax; + vcpu->vmx_guestmtrrmsrs.var_count = num_vmtrrs; + printf("\nIA32_MTRRCAP: VCNT=%u, FIX=%u, WC=%u, SMRR=%u", + num_vmtrrs, ((eax & (1 << 8)) >> 8), ((eax & (1 << 10)) >> 10), + ((eax & (1 << 11)) >> 11)); + //sanity check that fixed MTRRs are supported + HALT_ON_ERRORCOND( ((eax & (1 << 8)) >> 8) ); + //ensure number of variable MTRRs are within the maximum supported + HALT_ON_ERRORCOND( (num_vmtrrs <= MAX_VARIABLE_MTRR_PAIRS) ); + + // Obtain MAXPHYADDR and compute paddrmask + { + u32 eax, ebx, ecx, edx; + /* Check whether CPUID 0x80000008 is supported */ + cpuid(0x80000000U, &eax, &ebx, &ecx, &edx); + HALT_ON_ERRORCOND(eax >= 0x80000008U); + /* Compute paddrmask from CPUID.80000008H:EAX[7:0] (max phy addr) */ + cpuid(0x80000008U, &eax, &ebx, &ecx, &edx); + eax &= 0xFFU; + HALT_ON_ERRORCOND(eax >= 32 && eax < 64); + vcpu->vmx_ept_paddrmask = (1ULL << eax) - 0x1000ULL; + } + + // Read MTRR default type register + { + u32 valid; + u64 msrval = rdmsr64(IA32_MTRR_DEF_TYPE); + vcpu->vmx_guestmtrrmsrs.def_type = msrval; + valid = _vmx_mtrr_checkdeftype(msrval, &vcpu->vmx_ept_mtrr_enable, + &vcpu->vmx_ept_fixmtrr_enable, + &vcpu->vmx_ept_defaulttype); + HALT_ON_ERRORCOND(valid); + } + + // Fill guest MTRR shadow MSRs + for (u32 i = 0; i < NUM_FIXED_MTRRS; i++) { + u64 val = rdmsr64(fixed_mtrr_prop[i].msr); + HALT_ON_ERRORCOND(_vmx_mtrr_checkfixed(val)); + vcpu->vmx_guestmtrrmsrs.fix_mtrrs[i] = val; + } + for (u32 i = 0; i < num_vmtrrs; i++) { + u64 baseval = rdmsr64(IA32_MTRR_PHYSBASE0 + 2 * i); + u64 maskval = rdmsr64(IA32_MTRR_PHYSMASK0 + 2 * i); + HALT_ON_ERRORCOND(_vmx_mtrr_checkvariable(vcpu, baseval, maskval)); + vcpu->vmx_guestmtrrmsrs.var_mtrrs[i].base = baseval; + vcpu->vmx_guestmtrrmsrs.var_mtrrs[i].mask = maskval; + } +} + +//---get memory type for a given physical page address-------------------------- +// +//11.11.4.1 MTRR Precedences +// 0. if MTRRs are not enabled --> MTRR_TYPE_UC +// if enabled then + //if physaddr < 1MB use fixed MTRR ranges return type + //else if within a valid variable range MTRR then + //if a single match, return type + //if two or more and one is UC, return UC + //if two or more and WB and WT, return WT + //else invalid combination + //else + // return default memory type +// +static u32 _vmx_getmemorytypeforphysicalpage(VCPU *vcpu, u64 pagebaseaddr){ + u32 prev_type = MTRR_TYPE_RESV; + /* If MTRRs not enabled, return UC */ + if (!vcpu->vmx_ept_mtrr_enable) { + return MTRR_TYPE_UC; + } + /* If fixed MTRRs are enabled, and addr < 1M, use them */ + if (pagebaseaddr < 0x100000ULL && vcpu->vmx_ept_fixmtrr_enable) { + for (u32 i = 0; i < NUM_FIXED_MTRRS; i++) { + struct _fixed_mtrr_prop_t *prop = &fixed_mtrr_prop[i]; + if (pagebaseaddr < prop->end) { + u32 index = (prop->start - pagebaseaddr) / prop->step; + u64 msrval = vcpu->vmx_guestmtrrmsrs.fix_mtrrs[i]; + return (u8) (msrval >> (index * 8)); + } + } + /* + * Should be impossible because the last entry in fixed_mtrr_prop is 1M. + */ + HALT_ON_ERRORCOND(0 && "Unknown fixed MTRR"); + } + /* Compute variable MTRRs */ + for (u32 i = 0; i < vcpu->vmx_guestmtrrmsrs.var_count; i++) { + u64 base = vcpu->vmx_guestmtrrmsrs.var_mtrrs[i].base; + u64 mask = vcpu->vmx_guestmtrrmsrs.var_mtrrs[i].mask; + u32 cur_type = base & 0xFFU; + /* Check valid bit */ + if (!(mask & (1ULL << 11))) { + continue; + } + /* Clear lower bits, test whether address in range */ + base &= ~0xFFFULL; + mask &= ~0xFFFULL; + if ((pagebaseaddr & mask) != (base & mask)) { + continue; + } + /* Check for conflict resolutions: UC + * = UC; WB + WT = WT */ + if (prev_type == MTRR_TYPE_RESV || prev_type == cur_type) { + prev_type = cur_type; + } else if (prev_type == MTRR_TYPE_UC || cur_type == MTRR_TYPE_UC) { + prev_type = MTRR_TYPE_UC; + } else if (prev_type == MTRR_TYPE_WB && cur_type == MTRR_TYPE_WT) { + prev_type = MTRR_TYPE_WT; + } else if (prev_type == MTRR_TYPE_WT && cur_type == MTRR_TYPE_WB) { + prev_type = MTRR_TYPE_WT; + } else { + printf("\nConflicting MTRR types (%u, %u), HALT!", prev_type, cur_type); + HALT(); + } + } + /* If not covered by any MTRR, use default type */ + if (prev_type == MTRR_TYPE_RESV) { + prev_type = vcpu->vmx_ept_defaulttype; + } + return prev_type; +} + + +//---setup EPT for VMX---------------------------------------------------------- +static void _vmx_setupEPT(VCPU *vcpu){ + //step-1: tie in EPT PML4 structures + u64 *pml4_entry = (u64 *)vcpu->vmx_vaddr_ept_pml4_table; + u64 *pdp_entry = (u64 *)vcpu->vmx_vaddr_ept_pdp_table; + u64 *pd_entry = (u64 *)vcpu->vmx_vaddr_ept_pd_tables; + u64 *p_entry = (u64 *)vcpu->vmx_vaddr_ept_p_tables; + u64 pdp_table = hva2spa((void*)vcpu->vmx_vaddr_ept_pdp_table); + u64 pd_table = hva2spa((void*)vcpu->vmx_vaddr_ept_pd_tables); + u64 p_table = hva2spa((void*)vcpu->vmx_vaddr_ept_p_tables); + // TODO: for amd64, likely can use 1G / 2M pages. + // If so, also need to change _vmx_getmemorytypeforphysicalpage() + + for (gpa_t paddr = 0; paddr < MAX_PHYS_ADDR; paddr += PA_PAGE_SIZE_4K) { + if (PA_PAGE_ALIGNED_512G(paddr)) { + /* Create PML4E */ + gpa_t i = paddr >> PAGE_SHIFT_512G; + pml4_entry[i] = (pdp_table + (i << PAGE_SHIFT_4K)) | 0x7; + } + if (PA_PAGE_ALIGNED_1G(paddr)) { + /* Create PDPE */ + gpa_t i = paddr >> PAGE_SHIFT_1G; + pdp_entry[i] = (pd_table + (i << PAGE_SHIFT_4K)) | 0x7; + } + if (PA_PAGE_ALIGNED_2M(paddr)) { + /* Create PDE */ + gpa_t i = paddr >> PAGE_SHIFT_2M; + pd_entry[i] = (p_table + (i << PAGE_SHIFT_4K)) | 0x7; + } + /* PA_PAGE_ALIGNED_4K */ + { + /* Create PE */ + gpa_t i = paddr >> PAGE_SHIFT_4K; + u64 memorytype = _vmx_getmemorytypeforphysicalpage(vcpu, paddr); + u64 lower; + /* + * For memorytype equal to 0 (UC), 1 (WC), 4 (WT), 5 (WP), 6 (WB), + * MTRR memory type and EPT memory type are the same encoding. + * Currently other encodings are reserved. + */ + HALT_ON_ERRORCOND(memorytype == 0 || memorytype == 1 || + memorytype == 4 || memorytype == 5 || + memorytype == 6); + if ((paddr >= (rpb->XtVmmRuntimePhysBase - PA_PAGE_SIZE_2M)) && + (paddr < (rpb->XtVmmRuntimePhysBase + rpb->XtVmmRuntimeSize))) { + lower = 0x0; /* not present */ + } else { + lower = 0x7; /* present */ + } + p_entry[i] = paddr | (memorytype << 3) | lower; + } + } +} + +/* + * Update EPT in respond to change in memory type (usually MTRRs) + * start: start of address range to be updated + * end: end of address range to be updated + */ +static void _vmx_updateEPT_memtype(VCPU *vcpu, u64 start, u64 end){ + u64 *p_entry = (u64 *)vcpu->vmx_vaddr_ept_p_tables; + HALT_ON_ERRORCOND(PA_PAGE_ALIGNED_4K(start)); + HALT_ON_ERRORCOND(PA_PAGE_ALIGNED_4K(end)); + for (u64 paddr = start; paddr < end; paddr += PA_PAGE_SIZE_4K) { + u64 i = paddr / PA_PAGE_SIZE_4K; + u64 memorytype = _vmx_getmemorytypeforphysicalpage(vcpu, paddr); + HALT_ON_ERRORCOND(memorytype == 0 || memorytype == 1 || + memorytype == 4 || memorytype == 5 || + memorytype == 6); + p_entry[i] = (p_entry[i] & ~0x38ULL) | (memorytype << 3); + } +} + +/* + * Read a guest MTRR value from shadow, return 0 if successful read, + * return non-zero if unsuccessful read (should report error to guest OS) + */ +u32 xmhf_memprot_arch_x86vmx_mtrr_read(VCPU *vcpu, u32 msr, u64 *val) { + if (msr == IA32_MTRR_DEF_TYPE) { + /* Default type register */ + *val = vcpu->vmx_guestmtrrmsrs.def_type; + return 0; + } else if (IA32_MTRR_PHYSBASE0 <= msr && + msr <= IA32_MTRR_PHYSMASK0 + 2 * vcpu->vmx_guestmtrrmsrs.var_count) { + /* Variable MTRR */ + if ((msr - IA32_MTRR_PHYSBASE0) % 2 == 0) { + u32 index = (msr - IA32_MTRR_PHYSBASE0) / 2; + *val = vcpu->vmx_guestmtrrmsrs.var_mtrrs[index].base; + } else { + u32 index = (msr - IA32_MTRR_PHYSMASK0) / 2; + *val = vcpu->vmx_guestmtrrmsrs.var_mtrrs[index].mask; + } + return 0; + } else { + /* Fixed MTRR */ + for (u32 i = 0; i < NUM_FIXED_MTRRS; i++) { + if (fixed_mtrr_prop[i].msr == msr) { + *val = vcpu->vmx_guestmtrrmsrs.fix_mtrrs[i]; + return 0; + } + } + printf("\nCannot find MTRR, the caller (XMHF code) is wrong."); + HALT(); + /* Placate compiler */ + return 1; + } +} + +/* + * Write a guest MTRR value to shadow and update EPT, return 0 if successful, + * return non-zero if unsuccessful write (should report error to guest OS) + */ +u32 xmhf_memprot_arch_x86vmx_mtrr_write(VCPU *vcpu, u32 msr, u64 val) { + u32 hypapp_status; + u64 skip_ept_update = 0; + /* Logging */ + { + u64 oldval; + HALT_ON_ERRORCOND(xmhf_memprot_arch_x86vmx_mtrr_read(vcpu, msr, &oldval) == 0); + printf("\nCPU(0x%02x): WRMSR (MTRR) 0x%08x 0x%016llx (old = 0x%016llx)", + vcpu->id, msr, val, oldval); + } + /* Check whether hypapp allows modifying MTRR */ + xmhf_smpguest_arch_x86vmx_quiesce(vcpu); + hypapp_status = xmhf_app_handlemtrr(vcpu, msr, val); + xmhf_smpguest_arch_x86vmx_endquiesce(vcpu); + if (hypapp_status != APP_SUCCESS) { + printf("\nCPU(0x%02x): Hypapp does not allow changing MTRRs. Halt!", + vcpu->id); + HALT(); + } + if (msr == IA32_MTRR_DEF_TYPE) { + /* Default type register */ + if (val == vcpu->vmx_guestmtrrmsrs.def_type) { + /* No change to MSR value */ + return 0; + } + if (!_vmx_mtrr_checkdeftype(val, &vcpu->vmx_ept_mtrr_enable, + &vcpu->vmx_ept_fixmtrr_enable, + &vcpu->vmx_ept_defaulttype)) { + return 1; + } + vcpu->vmx_guestmtrrmsrs.def_type = val; + } else if (IA32_MTRR_PHYSBASE0 <= msr && + msr <= IA32_MTRR_PHYSMASK0 + 2 * vcpu->vmx_guestmtrrmsrs.var_count) { + /* Variable MTRR */ + u32 index; + u64 baseval = val, maskval = val; + if ((msr - IA32_MTRR_PHYSBASE0) % 2 == 0) { + /* Want to set baseval, retrieve maskval from shadow */ + index = (msr - IA32_MTRR_PHYSBASE0) / 2; + maskval = vcpu->vmx_guestmtrrmsrs.var_mtrrs[index].mask; + if (baseval == vcpu->vmx_guestmtrrmsrs.var_mtrrs[index].base) { + /* No change to MSR value */ + return 0; + } + } else { + /* Want to set maskval, retrieve baseval from shadow */ + index = (msr - IA32_MTRR_PHYSMASK0) / 2; + baseval = vcpu->vmx_guestmtrrmsrs.var_mtrrs[index].base; + if (maskval == vcpu->vmx_guestmtrrmsrs.var_mtrrs[index].mask) { + /* No change to MSR value */ + return 0; + } + } + /* Sanity check */ + if (!_vmx_mtrr_checkvariable(vcpu, baseval, maskval)) { + return 1; + } + /* Only one write will be effective, but this saves if-else blocks */ + vcpu->vmx_guestmtrrmsrs.var_mtrrs[index].base = baseval; + vcpu->vmx_guestmtrrmsrs.var_mtrrs[index].mask = maskval; + /* If MTRRs are not enabled, no need to update EPT */ + if (!vcpu->vmx_ept_mtrr_enable) { + skip_ept_update = 1; + } + } else { + /* Fixed MTRR */ + u32 found = 0; + if (!_vmx_mtrr_checkfixed(val)) { + return 1; + } + for (u32 i = 0; i < NUM_FIXED_MTRRS; i++) { + if (fixed_mtrr_prop[i].msr == msr) { + if (val == vcpu->vmx_guestmtrrmsrs.fix_mtrrs[i]) { + /* No change to MSR value */ + return 0; + } + vcpu->vmx_guestmtrrmsrs.fix_mtrrs[i] = val; + found = 1; + break; + } + } + if (!found) { + printf("\nCannot find MTRR, the caller (XMHF code) is wrong."); + HALT(); + } + /* If MTRRs / fixed MTRRs are not enabled, no need to update EPT */ + if (!vcpu->vmx_ept_mtrr_enable || !vcpu->vmx_ept_fixmtrr_enable) { + skip_ept_update = 1; + } + } + + /* Update EPT and flush EPT's TLB */ + if (!skip_ept_update) { + /* + * Currently updating all of EPT (from 0 to MAX_PHYS_ADDR). It is + * possible to only update a part of EPT, depending on what MTRR is + * changed and the value before and after change. However, this needs a + * complicated logic. + */ + printf("\nCPU(0x%02x): Update EPT memory types due to MTRR", vcpu->id); + _vmx_updateEPT_memtype(vcpu, 0, MAX_PHYS_ADDR); + xmhf_memprot_arch_x86vmx_flushmappings_localtlb(vcpu); + } + return 0; +} + +//flush hardware page table mappings (TLB) +void xmhf_memprot_arch_x86vmx_flushmappings(VCPU *vcpu){ + __vmx_invept(VMX_INVEPT_SINGLECONTEXT, + (u64)vcpu->vmcs.control_EPT_pointer); +} + +//flush hardware page table mappings (TLB) +void xmhf_memprot_arch_x86vmx_flushmappings_localtlb(VCPU *vcpu){ + (void)vcpu; + __vmx_invept(VMX_INVEPT_GLOBAL, + (u64)0); +} + +//set protection for a given physical memory address +void xmhf_memprot_arch_x86vmx_setprot(VCPU *vcpu, u64 gpa, u32 prottype){ + u32 pfn; + u64 *pt; + u32 flags =0; + +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + assert ( (vcpu != NULL) ); + assert ( ( (gpa < rpb->XtVmmRuntimePhysBase) || + (gpa >= (rpb->XtVmmRuntimePhysBase + rpb->XtVmmRuntimeSize)) + ) ); + assert ( ( (prottype > 0) && + (prottype <= MEMP_PROT_MAXVALUE) + ) ); + assert ( + (prottype == MEMP_PROT_NOTPRESENT) || + ((prottype & MEMP_PROT_PRESENT) && (prottype & MEMP_PROT_READONLY) && (prottype & MEMP_PROT_EXECUTE)) || + ((prottype & MEMP_PROT_PRESENT) && (prottype & MEMP_PROT_READWRITE) && (prottype & MEMP_PROT_EXECUTE)) || + ((prottype & MEMP_PROT_PRESENT) && (prottype & MEMP_PROT_READONLY) && (prottype & MEMP_PROT_NOEXECUTE)) || + ((prottype & MEMP_PROT_PRESENT) && (prottype & MEMP_PROT_READWRITE) && (prottype & MEMP_PROT_NOEXECUTE)) + ); +#endif + + pfn = (u32)gpa / PAGE_SIZE_4K; //grab page frame number + pt = (u64 *)vcpu->vmx_vaddr_ept_p_tables; + + //default is not-present, read-only, no-execute + pt[pfn] &= ~(u64)7; //clear all previous flags + + //map high level protection type to EPT protection bits + if(prottype & MEMP_PROT_PRESENT){ + flags=1; //present is defined by the read bit in EPT + + if(prottype & MEMP_PROT_READWRITE) + flags |= 0x2; + + if(prottype & MEMP_PROT_EXECUTE) + flags |= 0x4; + } + + //set new flags + pt[pfn] |= flags; +} + + +//get protection for a given physical memory address +u32 xmhf_memprot_arch_x86vmx_getprot(VCPU *vcpu, u64 gpa){ + u32 pfn = (u32)gpa / PAGE_SIZE_4K; //grab page frame number + u64 *pt = (u64 *)vcpu->vmx_vaddr_ept_p_tables; + u64 entry = pt[pfn]; + u32 prottype; + + if(! (entry & 0x1) ){ + prottype = MEMP_PROT_NOTPRESENT; + return prottype; + } + + prottype = MEMP_PROT_PRESENT; + + if( entry & 0x2 ) + prottype |= MEMP_PROT_READWRITE; + else + prottype |= MEMP_PROT_READONLY; + + if( entry & 0x4 ) + prottype |= MEMP_PROT_EXECUTE; + else + prottype |= MEMP_PROT_NOEXECUTE; + + return prottype; +} + +u64 xmhf_memprot_arch_x86vmx_get_EPTP(VCPU *vcpu) +{ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_INTEL); + return vcpu->vmcs.control_EPT_pointer; +} +void xmhf_memprot_arch_x86vmx_set_EPTP(VCPU *vcpu, u64 eptp) +{ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_INTEL); + vcpu->vmcs.control_EPT_pointer = eptp; +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-memprot/memp-interface.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-memprot/memp-interface.c new file mode 100644 index 0000000000..da31530c8d --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-memprot/memp-interface.c @@ -0,0 +1,141 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF memory protection component +// implementation +// author: amit vasudevan (amitvasudevan@acm.org) + +#include + +// initialize memory protection structures for a given core (vcpu) +void xmhf_memprot_initialize(VCPU *vcpu){ + xmhf_memprot_arch_initialize(vcpu); +} + +// get level-1 page map address +u64 * xmhf_memprot_get_lvl1_pagemap_address(VCPU *vcpu){ + return xmhf_memprot_arch_get_lvl1_pagemap_address(vcpu); +} + +//get level-2 page map address +u64 * xmhf_memprot_get_lvl2_pagemap_address(VCPU *vcpu){ + return xmhf_memprot_arch_get_lvl2_pagemap_address(vcpu); +} + +//get level-3 page map address +u64 * xmhf_memprot_get_lvl3_pagemap_address(VCPU *vcpu){ + return xmhf_memprot_arch_get_lvl3_pagemap_address(vcpu); +} + +//get level-4 page map address +u64 * xmhf_memprot_get_lvl4_pagemap_address(VCPU *vcpu){ + return xmhf_memprot_arch_get_lvl4_pagemap_address(vcpu); +} + +//get default root page map address +u64 * xmhf_memprot_get_default_root_pagemap_address(VCPU *vcpu){ + return xmhf_memprot_arch_get_default_root_pagemap_address(vcpu); +} + + +//flush hardware page table mappings (TLB) +void xmhf_memprot_flushmappings(VCPU *vcpu){ + xmhf_memprot_arch_flushmappings(vcpu); +} + +//flush the TLB of all nested page tables in the current core +void xmhf_memprot_flushmappings_localtlb(VCPU *vcpu){ + //printf("\nCPU(0x%02x): \n", vcpu->id); + xmhf_memprot_arch_flushmappings_localtlb(vcpu); +} + + +//set protection for a given physical memory address +void xmhf_memprot_setprot(VCPU *vcpu, u64 gpa, u32 prottype){ +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + assert ( (vcpu != NULL) ); + assert ( ( (gpa < rpb->XtVmmRuntimePhysBase) || + (gpa >= (rpb->XtVmmRuntimePhysBase + rpb->XtVmmRuntimeSize)) + ) ); + assert ( ( (prottype > 0) && + (prottype <= MEMP_PROT_MAXVALUE) + ) ); + assert ( + (prottype == MEMP_PROT_NOTPRESENT) || + ((prottype & MEMP_PROT_PRESENT) && (prottype & MEMP_PROT_READONLY) && (prottype & MEMP_PROT_EXECUTE)) || + ((prottype & MEMP_PROT_PRESENT) && (prottype & MEMP_PROT_READWRITE) && (prottype & MEMP_PROT_EXECUTE)) || + ((prottype & MEMP_PROT_PRESENT) && (prottype & MEMP_PROT_READONLY) && (prottype & MEMP_PROT_NOEXECUTE)) || + ((prottype & MEMP_PROT_PRESENT) && (prottype & MEMP_PROT_READWRITE) && (prottype & MEMP_PROT_NOEXECUTE)) + ); +#endif + + xmhf_memprot_arch_setprot(vcpu, gpa, prottype); +} + + +//get protection for a given physical memory address +u32 xmhf_memprot_getprot(VCPU *vcpu, u64 gpa){ + return xmhf_memprot_arch_getprot(vcpu, gpa); +} + +// Is the given system paddr belong to mHV (XMHF + hypapp)? +bool xmhf_is_mhv_memory(spa_t spa) +{ + u64 base = rpb->XtVmmRuntimePhysBase; + size_t size = rpb->XtVmmRuntimeSize; + + if((spa >= base) && (spa < base + size)) + return true; + + return false; +} + +// On 32bit machine, we always return 0 - 4G as the machine physical address range, no matter how many memory is installed +// On 64-bit machine, the function queries the E820 map for the used memory region. +bool xmhf_get_machine_paddr_range(spa_t* machine_base_spa, spa_t* machine_limit_spa) +{ + return xmhf_arch_get_machine_paddr_range(machine_base_spa, machine_limit_spa); +} \ No newline at end of file diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-mm/Makefile b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-mm/Makefile new file mode 100644 index 0000000000..92dc629487 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-mm/Makefile @@ -0,0 +1,12 @@ +# makefile for xmhf-startup component +# author: amit vasudevan (amitvasudevan@acm.org) + +# source files +AS_SOURCES = + +C_SOURCES = xmhf-tlsf.c +C_SOURCES += xmhf-mm.c + +# targets +include ../runtime.mk + diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-mm/xmhf-mm.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-mm/xmhf-mm.c new file mode 100644 index 0000000000..4e8a62dfdf --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-mm/xmhf-mm.c @@ -0,0 +1,139 @@ +// author: Miao Yu + +#include +#include "xmhf-tlsf.h" + +static u8 g_xmhf_heap[XMHF_HEAP_SIZE] __attribute__(( section(".bss.palign_data") )); +static xmhf_tlsf_pool g_pool; + +// [Ticket 156][TODO] [SecBase][SecOS] Use Slab + Page Allocator to save memory space + +void xmhf_mm_init(void) +{ + g_pool = xmhf_tlsf_create(g_xmhf_heap, XMHF_HEAP_SIZE); +} + +void xmhf_mm_fini(void) +{ + if(g_pool) + { + xmhf_tlsf_destroy(g_xmhf_heap); + g_pool = NULL; + } +} + +void* xmhf_mm_malloc_align(uint32_t alignment, size_t size) +{ + void *p = NULL; + + p = xmhf_tlsf_memalign(g_pool, alignment, size); + + if(p) + memset(p, 0, size); + return p; +} + +void* xmhf_mm_malloc(size_t size) +{ + return xmhf_mm_malloc_align(0, size); +} + +void* xmhf_mm_alloc_page(uint32_t num_pages) +{ + return xmhf_mm_malloc_align(PAGE_SIZE_4K, num_pages * PAGE_SIZE_4K); +} + + +void xmhf_mm_free(void* ptr) +{ + xmhf_tlsf_free(g_pool, ptr); +} + +//! Allocate an aligned memory from the heap of XMHF. Also it records the allocation in the +void* xmhf_mm_alloc_align_with_record(XMHFList* mm_alloc_infolist, uint32_t alignment, size_t size) +{ + void* p = NULL; + struct xmhf_mm_alloc_info* record = NULL; + + if(!mm_alloc_infolist) + return NULL; + + p = xmhf_mm_malloc_align(alignment, size); + if(!p) + return NULL; + + record = xmhf_mm_malloc(sizeof(struct xmhf_mm_alloc_info)); + if(!record) + { + xmhf_mm_free(p); + return NULL; + } + + record->hva = p; + record->alignment = alignment; + record->size = size; + xmhfstl_list_enqueue(mm_alloc_infolist, record); + + return p; +} + +//! Allocate a piece of memory from the heap of XMHF. Also it records the allocation in the +void* xmhf_mm_malloc_with_record(XMHFList* mm_alloc_infolist, size_t size) +{ + return xmhf_mm_alloc_align_with_record(mm_alloc_infolist, 0, size); +} + +//! Allocate a memory page from the heap of XMHF. Also it records the allocation in the +void* xmhf_mm_alloc_page_with_record(XMHFList* mm_alloc_infolist, uint32_t num_pages) +{ + return xmhf_mm_alloc_align_with_record(mm_alloc_infolist, PAGE_SIZE_4K, num_pages * PAGE_SIZE_4K); +} + +//! Free the memory allocated from the heap of XMHF. And also remove the record in the +void xmhf_mm_free_from_record(XMHFList* mm_alloc_infolist, void* ptr) +{ + // void* p = NULL; + struct xmhf_mm_alloc_info* record = NULL; + XMHFListNode* node = NULL; + + if(!mm_alloc_infolist || !ptr) + return; + + { + XMHFLIST_FOREACH(mm_alloc_infolist, first, next, cur) + { + record = (struct xmhf_mm_alloc_info*)cur->value; + + if(record->hva == ptr) + { + node = cur; + break; + } + } + } + + xmhfstl_list_remove(mm_alloc_infolist, node); + + xmhf_mm_free(record->hva); + xmhf_mm_free(record); +} + +//! @brief Free all the recorded memory +void xmhf_mm_free_all_records(XMHFList* mm_alloc_infolist) +{ + struct xmhf_mm_alloc_info* record = NULL; + + if(!mm_alloc_infolist) + return; + + { + XMHFLIST_FOREACH(mm_alloc_infolist, first, next, cur) + { + record = (struct xmhf_mm_alloc_info*)cur->value; + + xmhf_mm_free(record->hva); + } + } + + xmhfstl_list_clear_destroy(mm_alloc_infolist); +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-mm/xmhf-tlsf.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-mm/xmhf-tlsf.c new file mode 100644 index 0000000000..a86fb6dd1c --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-mm/xmhf-tlsf.c @@ -0,0 +1,982 @@ +#include +#include +#include +#include +#include +#include + +#include "xmhf-tlsf.h" +#include "xmhf-tlsfbits.h" + +/*- +** Two Level Segregated Fit memory allocator, version 1.9. +** Written by Matthew Conte, and placed in the Public Domain. +** http://xmhf_tlsf.baisoku.org +** +** Based on the original documentation by Miguel Masmano: +** http://rtportal.upv.es/rtmalloc/allocators/xmhf_tlsf/index.shtml +** +** Please see the accompanying Readme.txt for implementation +** notes and caveats. +** +** This implementation was written to the specification +** of the document, therefore no GPL restrictions apply. +*/ + +/** + * Modified for TrustVisor. + */ + +/* +** Constants. +*/ + +/* Public constants: may be modified. */ +enum xmhf_tlsf_public +{ + /* log2 of number of linear subdivisions of block sizes. */ + SL_INDEX_COUNT_LOG2 = 5, +}; + +/* Private constants: do not modify. */ +enum xmhf_tlsf_private +{ +#if defined (xmhf_tlsf_64BIT) + /* All allocation sizes and addresses are aligned to 8 bytes. */ + ALIGN_SIZE_LOG2 = 3, +#else + /* All allocation sizes and addresses are aligned to 4 bytes. */ + ALIGN_SIZE_LOG2 = 2, +#endif + ALIGN_SIZE = (1 << ALIGN_SIZE_LOG2), + + /* + ** We support allocations of sizes up to (1 << FL_INDEX_MAX) bits. + ** However, because we linearly subdivide the second-level lists, and + ** our minimum size granularity is 4 bytes, it doesn't make sense to + ** create first-level lists for sizes smaller than SL_INDEX_COUNT * 4, + ** or (1 << (SL_INDEX_COUNT_LOG2 + 2)) bytes, as there we will be + ** trying to split size ranges into more slots than we have available. + ** Instead, we calculate the minimum threshold size, and place all + ** blocks below that size into the 0th first-level list. + */ + +#if defined (xmhf_tlsf_64BIT) + /* + ** TODO: We can increase this to support larger sizes, at the expense + ** of more overhead in the xmhf_tlsf structure. + */ + FL_INDEX_MAX = 32, +#else + FL_INDEX_MAX = 30, +#endif + SL_INDEX_COUNT = (1 << SL_INDEX_COUNT_LOG2), + FL_INDEX_SHIFT = (SL_INDEX_COUNT_LOG2 + ALIGN_SIZE_LOG2), + FL_INDEX_COUNT = (FL_INDEX_MAX - FL_INDEX_SHIFT + 1), + + SMALL_BLOCK_SIZE = (1 << FL_INDEX_SHIFT), +}; + +/* +** Cast and min/max macros. +*/ + +#define xmhf_tlsf_cast(t, exp) ((t) (exp)) +#define xmhf_tlsf_min(a, b) ((a) < (b) ? (a) : (b)) +#define xmhf_tlsf_max(a, b) ((a) > (b) ? (a) : (b)) + +/* +** Set assert macro, if it has not been provided by the user. +*/ +#if !defined (xmhf_tlsf_assert) +#define xmhf_tlsf_assert assert +#endif + +/* +** Static assertion mechanism. +*/ + +#define _xmhf_tlsf_glue2(x, y) x ## y +#define _xmhf_tlsf_glue(x, y) _xmhf_tlsf_glue2(x, y) +#define xmhf_tlsf_static_assert(exp) \ + typedef char _xmhf_tlsf_glue(static_assert, __LINE__) [(exp) ? 1 : -1] + +/* This code has been tested on 32- and 64-bit (LP/LLP) architectures. */ +xmhf_tlsf_static_assert(sizeof(int) * CHAR_BIT == 32); +xmhf_tlsf_static_assert(sizeof(size_t) * CHAR_BIT >= 32); +xmhf_tlsf_static_assert(sizeof(size_t) * CHAR_BIT <= 64); + +/* SL_INDEX_COUNT must be <= number of bits in sl_bitmap's storage type. */ +xmhf_tlsf_static_assert(sizeof(unsigned int) * CHAR_BIT >= SL_INDEX_COUNT); + +/* Ensure we've properly tuned our sizes. */ +xmhf_tlsf_static_assert(ALIGN_SIZE == SMALL_BLOCK_SIZE / SL_INDEX_COUNT); + +/* +** Data structures and associated constants. +*/ + +/* +** Block header structure. +** +** There are several implementation subtleties involved: +** - The prev_phys_block field is only valid if the previous block is free. +** - The prev_phys_block field is actually stored at the end of the +** previous block. It appears at the beginning of this structure only to +** simplify the implementation. +** - The next_free / prev_free fields are only valid if the block is free. +*/ +typedef struct block_header_t +{ + /* Points to the previous physical block. */ + struct block_header_t* prev_phys_block; + + /* The size of this block, excluding the block header. */ + size_t size; + + /* Next and previous free blocks. */ + struct block_header_t* next_free; + struct block_header_t* prev_free; +} block_header_t; + +/* +** Since block sizes are always at least a multiple of 4, the two least +** significant bits of the size field are used to store the block status: +** - bit 0: whether block is busy or free +** - bit 1: whether previous block is busy or free +*/ +static const size_t block_header_free_bit = 1 << 0; +static const size_t block_header_prev_free_bit = 1 << 1; + +/* +** The size of the block header exposed to used blocks is the size field. +** The prev_phys_block field is stored *inside* the previous free block. +*/ +static const size_t block_header_overhead = sizeof(size_t); + +/* User data starts directly after the size field in a used block. */ +static const size_t block_start_offset = + offsetof(block_header_t, size) + sizeof(size_t); + +/* +** A free block must be large enough to store its header minus the size of +** the prev_phys_block field, and no larger than the number of addressable +** bits for FL_INDEX. +*/ +static const size_t block_size_min = + sizeof(block_header_t) - sizeof(block_header_t*); +static const size_t block_size_max = xmhf_tlsf_cast(size_t, 1) << FL_INDEX_MAX; + + +/* The xmhf_tlsf pool structure. */ +typedef struct pool_t +{ + /* Empty lists point at this block to indicate they are free. */ + block_header_t block_null; + + /* Bitmaps for free lists. */ + unsigned int fl_bitmap; + unsigned int sl_bitmap[FL_INDEX_COUNT]; + + /* Head of free lists. */ + block_header_t* blocks[FL_INDEX_COUNT][SL_INDEX_COUNT]; +} pool_t; + +/* A type used for casting when doing pointer arithmetic. */ +typedef ptrdiff_t xmhf_tlsfptr_t; + +/* +** block_header_t member functions. +*/ + +static size_t block_size(const block_header_t* block) +{ + return block->size & ~(block_header_free_bit | block_header_prev_free_bit); +} + +static void block_set_size(block_header_t* block, size_t size) +{ + const size_t oldsize = block->size; + block->size = size | (oldsize & (block_header_free_bit | block_header_prev_free_bit)); +} + +static int block_is_last(const block_header_t* block) +{ + return 0 == block_size(block); +} + +static int block_is_free(const block_header_t* block) +{ + return xmhf_tlsf_cast(int, block->size & block_header_free_bit); +} + +static void block_set_free(block_header_t* block) +{ + block->size |= block_header_free_bit; +} + +static void block_set_used(block_header_t* block) +{ + block->size &= ~block_header_free_bit; +} + +static int block_is_prev_free(const block_header_t* block) +{ + return xmhf_tlsf_cast(int, block->size & block_header_prev_free_bit); +} + +static void block_set_prev_free(block_header_t* block) +{ + block->size |= block_header_prev_free_bit; +} + +static void block_set_prev_used(block_header_t* block) +{ + block->size &= ~block_header_prev_free_bit; +} + +static block_header_t* block_from_ptr(const void* ptr) +{ + return xmhf_tlsf_cast(block_header_t*, + xmhf_tlsf_cast(unsigned char*, ptr) - block_start_offset); +} + +static void* block_to_ptr(const block_header_t* block) +{ + return xmhf_tlsf_cast(void*, + xmhf_tlsf_cast(unsigned char*, block) + block_start_offset); +} + +/* Return location of next block after block of given size. */ +static block_header_t* offset_to_block(const void* ptr, size_t size) +{ + return xmhf_tlsf_cast(block_header_t*, xmhf_tlsf_cast(xmhf_tlsfptr_t, ptr) + size); +} + +/* Return location of previous block. */ +static block_header_t* block_prev(const block_header_t* block) +{ + return block->prev_phys_block; +} + +/* Return location of next existing block. */ +static block_header_t* block_next(const block_header_t* block) +{ + block_header_t* next = offset_to_block(block_to_ptr(block), + block_size(block) - block_header_overhead); + xmhf_tlsf_assert(!block_is_last(block)); + return next; +} + +/* Link a new block with its physical neighbor, return the neighbor. */ +static block_header_t* block_link_next(block_header_t* block) +{ + block_header_t* next = block_next(block); + next->prev_phys_block = block; + return next; +} + +static void block_mark_as_free(block_header_t* block) +{ + /* Link the block to the next block, first. */ + block_header_t* next = block_link_next(block); + block_set_prev_free(next); + block_set_free(block); +} + +static void block_mark_as_used(block_header_t* block) +{ + block_header_t* next = block_next(block); + block_set_prev_used(next); + block_set_used(block); +} + +static size_t align_up(size_t x, size_t align) +{ + xmhf_tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two"); + return (x + (align - 1)) & ~(align - 1); +} + +static size_t align_down(size_t x, size_t align) +{ + xmhf_tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two"); + return x - (x & (align - 1)); +} + +static void* align_ptr(const void* ptr, size_t align) +{ + const xmhf_tlsfptr_t aligned = + (xmhf_tlsf_cast(xmhf_tlsfptr_t, ptr) + (align - 1)) & ~(align - 1); + xmhf_tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two"); + return xmhf_tlsf_cast(void*, aligned); +} + +/* +** Adjust an allocation size to be aligned to word size, and no smaller +** than internal minimum. +*/ +static size_t adjust_request_size(size_t size, size_t align) +{ + size_t adjust = 0; + if (size && size < block_size_max) + { + const size_t aligned = align_up(size, align); + adjust = xmhf_tlsf_max(aligned, block_size_min); + } + return adjust; +} + +/* +** xmhf_tlsf utility functions. In most cases, these are direct translations of +** the documentation found in the white paper. +*/ + +static void mapping_insert(size_t size, int* fli, int* sli) +{ + int fl, sl; + if (size < SMALL_BLOCK_SIZE) + { + /* Store small blocks in first list. */ + fl = 0; + sl = xmhf_tlsf_cast(int, size) / (SMALL_BLOCK_SIZE / SL_INDEX_COUNT); + } + else + { + fl = xmhf_tlsf_fls_sizet(size); + sl = xmhf_tlsf_cast(int, size >> (fl - SL_INDEX_COUNT_LOG2)) ^ (1 << SL_INDEX_COUNT_LOG2); + fl -= (FL_INDEX_SHIFT - 1); + } + *fli = fl; + *sli = sl; +} + +/* This version rounds up to the next block size (for allocations) */ +static void mapping_search(size_t size, int* fli, int* sli) +{ + if (size >= (1 << SL_INDEX_COUNT_LOG2)) + { + const size_t round = (1 << (xmhf_tlsf_fls_sizet(size) - SL_INDEX_COUNT_LOG2)) - 1; + size += round; + } + mapping_insert(size, fli, sli); +} + +static block_header_t* search_suitable_block(pool_t* pool, int* fli, int* sli) +{ + int fl = *fli; + int sl = *sli; + + /* + ** First, search for a block in the list associated with the given + ** fl/sl index. + */ + unsigned int sl_map = pool->sl_bitmap[fl] & (~0UL << sl); + if (!sl_map) + { + /* No block exists. Search in the next largest first-level list. */ + const unsigned int fl_map = pool->fl_bitmap & (~0UL << (fl + 1)); + if (!fl_map) + { + /* No free blocks available, memory has been exhausted. */ + return 0; + } + + fl = xmhf_tlsf_ffs(fl_map); + *fli = fl; + sl_map = pool->sl_bitmap[fl]; + } + xmhf_tlsf_assert(sl_map && "internal error - second level bitmap is null"); + sl = xmhf_tlsf_ffs(sl_map); + *sli = sl; + + /* Return the first block in the free list. */ + return pool->blocks[fl][sl]; +} + +/* Remove a free block from the free list.*/ +static void remove_free_block(pool_t* pool, block_header_t* block, int fl, int sl) +{ + block_header_t* prev = block->prev_free; + block_header_t* next = block->next_free; + xmhf_tlsf_assert(prev && "prev_free field can not be null"); + xmhf_tlsf_assert(next && "next_free field can not be null"); + next->prev_free = prev; + prev->next_free = next; + + /* If this block is the head of the free list, set new head. */ + if (pool->blocks[fl][sl] == block) + { + pool->blocks[fl][sl] = next; + + /* If the new head is null, clear the bitmap. */ + if (next == &pool->block_null) + { + pool->sl_bitmap[fl] &= ~(1 << sl); + + /* If the second bitmap is now empty, clear the fl bitmap. */ + if (!pool->sl_bitmap[fl]) + { + pool->fl_bitmap &= ~(1 << fl); + } + } + } +} + +/* Insert a free block into the free block list. */ +static void insert_free_block(pool_t* pool, block_header_t* block, int fl, int sl) +{ + block_header_t* current = pool->blocks[fl][sl]; + xmhf_tlsf_assert(current && "free list cannot have a null entry"); + xmhf_tlsf_assert(block && "cannot insert a null entry into the free list"); + block->next_free = current; + block->prev_free = &pool->block_null; + current->prev_free = block; + + xmhf_tlsf_assert(block_to_ptr(block) == align_ptr(block_to_ptr(block), ALIGN_SIZE) + && "block not aligned properly"); + /* + ** Insert the new block at the head of the list, and mark the first- + ** and second-level bitmaps appropriately. + */ + pool->blocks[fl][sl] = block; + pool->fl_bitmap |= (1 << fl); + pool->sl_bitmap[fl] |= (1 << sl); +} + +/* Remove a given block from the free list. */ +static void block_remove(pool_t* pool, block_header_t* block) +{ + int fl, sl; + mapping_insert(block_size(block), &fl, &sl); + remove_free_block(pool, block, fl, sl); +} + +/* Insert a given block into the free list. */ +static void block_insert(pool_t* pool, block_header_t* block) +{ + int fl, sl; + mapping_insert(block_size(block), &fl, &sl); + insert_free_block(pool, block, fl, sl); +} + +static int block_can_split(block_header_t* block, size_t size) +{ + return block_size(block) >= sizeof(block_header_t) + size; +} + +/* Split a block into two, the second of which is free. */ +static block_header_t* block_split(block_header_t* block, size_t size) +{ + /* Calculate the amount of space left in the remaining block. */ + block_header_t* remaining = + offset_to_block(block_to_ptr(block), size - block_header_overhead); + + const size_t remain_size = block_size(block) - (size + block_header_overhead); + + xmhf_tlsf_assert(block_to_ptr(remaining) == align_ptr(block_to_ptr(remaining), ALIGN_SIZE) + && "remaining block not aligned properly"); + + xmhf_tlsf_assert(block_size(block) == remain_size + size + block_header_overhead); + block_set_size(remaining, remain_size); + xmhf_tlsf_assert(block_size(remaining) >= block_size_min && "block split with invalid size"); + + block_set_size(block, size); + block_mark_as_free(remaining); + + return remaining; +} + +/* Absorb a free block's storage into an adjacent previous free block. */ +static block_header_t* block_absorb(block_header_t* prev, block_header_t* block) +{ + xmhf_tlsf_assert(!block_is_last(prev) && "previous block can't be last!"); + /* Note: Leaves flags untouched. */ + prev->size += block_size(block) + block_header_overhead; + block_link_next(prev); + return prev; +} + +/* Merge a just-freed block with an adjacent previous free block. */ +static block_header_t* block_merge_prev(pool_t* pool, block_header_t* block) +{ + if (block_is_prev_free(block)) + { + block_header_t* prev = block_prev(block); + xmhf_tlsf_assert(prev && "prev physical block can't be null"); + xmhf_tlsf_assert(block_is_free(prev) && "prev block is not free though marked as such"); + block_remove(pool, prev); + block = block_absorb(prev, block); + } + + return block; +} + +/* Merge a just-freed block with an adjacent free block. */ +static block_header_t* block_merge_next(pool_t* pool, block_header_t* block) +{ + block_header_t* next = block_next(block); + xmhf_tlsf_assert(next && "next physical block can't be null"); + + if (block_is_free(next)) + { + xmhf_tlsf_assert(!block_is_last(block) && "previous block can't be last!"); + block_remove(pool, next); + block = block_absorb(block, next); + } + + return block; +} + +/* Trim any trailing block space off the end of a block, return to pool. */ +static void block_trim_free(pool_t* pool, block_header_t* block, size_t size) +{ + xmhf_tlsf_assert(block_is_free(block) && "block must be free"); + if (block_can_split(block, size)) + { + block_header_t* remaining_block = block_split(block, size); + block_link_next(block); + block_set_prev_free(remaining_block); + block_insert(pool, remaining_block); + } +} + +/* Trim any trailing block space off the end of a used block, return to pool. */ +static void block_trim_used(pool_t* pool, block_header_t* block, size_t size) +{ + xmhf_tlsf_assert(!block_is_free(block) && "block must be used"); + if (block_can_split(block, size)) + { + /* If the next block is free, we must coalesce. */ + block_header_t* remaining_block = block_split(block, size); + block_set_prev_used(remaining_block); + + remaining_block = block_merge_next(pool, remaining_block); + block_insert(pool, remaining_block); + } +} + +static block_header_t* block_trim_free_leading(pool_t* pool, block_header_t* block, size_t size) +{ + block_header_t* remaining_block = block; + if (block_can_split(block, size)) + { + /* We want the 2nd block. */ + remaining_block = block_split(block, size - block_header_overhead); + block_set_prev_free(remaining_block); + + block_link_next(block); + block_insert(pool, block); + } + + return remaining_block; +} + +static block_header_t* block_locate_free(pool_t* pool, size_t size) +{ + int fl = 0, sl = 0; + block_header_t* block = 0; + + if (size) + { + mapping_search(size, &fl, &sl); + block = search_suitable_block(pool, &fl, &sl); + } + + if (block) + { + xmhf_tlsf_assert(block_size(block) >= size); + remove_free_block(pool, block, fl, sl); + } + + return block; +} + +static void* block_prepare_used(pool_t* pool, block_header_t* block, size_t size) +{ + void* p = 0; + if (block) + { + block_trim_free(pool, block, size); + block_mark_as_used(block); + p = block_to_ptr(block); + } + return p; +} + +/* Clear structure and point all empty lists at the null block. */ +static void pool_construct(pool_t* pool) +{ + int i, j; + + pool->block_null.next_free = &pool->block_null; + pool->block_null.prev_free = &pool->block_null; + + pool->fl_bitmap = 0; + for (i = 0; i < FL_INDEX_COUNT; ++i) + { + pool->sl_bitmap[i] = 0; + for (j = 0; j < SL_INDEX_COUNT; ++j) + { + pool->blocks[i][j] = &pool->block_null; + } + } +} + +/* +** Debugging utilities. +*/ + +typedef struct integrity_t +{ + int prev_status; + int status; +} integrity_t; + +#define xmhf_tlsf_insist(x) { xmhf_tlsf_assert(x); if (!(x)) { status--; } } + +static void integrity_walker(void* ptr, size_t size, int used, void* user) +{ + block_header_t* block = block_from_ptr(ptr); + integrity_t* integ = xmhf_tlsf_cast(integrity_t*, user); + const int this_prev_status = block_is_prev_free(block) ? 1 : 0; + const int this_status = block_is_free(block) ? 1 : 0; + const size_t this_block_size = block_size(block); + + int status = 0; + xmhf_tlsf_insist(integ->prev_status == this_prev_status && "prev status incorrect"); + xmhf_tlsf_insist(size == this_block_size && "block size incorrect"); + + integ->prev_status = this_status; + integ->status += status; + + used = used; /* appease compiler */ +} + +int xmhf_tlsf_check_heap(xmhf_tlsf_pool xmhf_tlsf) +{ + int i, j; + + pool_t* pool = xmhf_tlsf_cast(pool_t*, xmhf_tlsf); + int status = 0; + + /* Check that the blocks are physically correct. */ + integrity_t integ = { 0, 0 }; + xmhf_tlsf_walk_heap(xmhf_tlsf, integrity_walker, &integ); + status = integ.status; + + /* Check that the free lists and bitmaps are accurate. */ + for (i = 0; i < FL_INDEX_COUNT; ++i) + { + for (j = 0; j < SL_INDEX_COUNT; ++j) + { + const int fl_map = pool->fl_bitmap & (1 << i); + const int sl_list = pool->sl_bitmap[i]; + const int sl_map = sl_list & (1 << j); + const block_header_t* block = pool->blocks[i][j]; + + /* Check that first- and second-level lists agree. */ + if (!fl_map) + { + xmhf_tlsf_insist(!sl_map && "second-level map must be null"); + } + + if (!sl_map) + { + xmhf_tlsf_insist(block == &pool->block_null && "block list must be null"); + continue; + } + + /* Check that there is at least one free block. */ + xmhf_tlsf_insist(sl_list && "no free blocks in second-level map"); + xmhf_tlsf_insist(block != &pool->block_null && "block should not be null"); + + while (block != &pool->block_null) + { + int fli, sli; + xmhf_tlsf_insist(block_is_free(block) && "block should be free"); + xmhf_tlsf_insist(!block_is_prev_free(block) && "blocks should have coalesced"); + xmhf_tlsf_insist(!block_is_free(block_next(block)) && "blocks should have coalesced"); + xmhf_tlsf_insist(block_is_prev_free(block_next(block)) && "block should be free"); + xmhf_tlsf_insist(block_size(block) >= block_size_min && "block not minimum size"); + + mapping_insert(block_size(block), &fli, &sli); + xmhf_tlsf_insist(fli == i && sli == j && "block size indexed in wrong list"); + block = block->next_free; + } + } + } + + return status; +} + +#undef xmhf_tlsf_insist + +static void default_walker(void* ptr, size_t size, int used, void* user) +{ + (void)user; + printf("\t%p %s size: %x (%p)\n", ptr, used ? "used" : "free", (unsigned int)size, block_from_ptr(ptr)); +} + +void xmhf_tlsf_walk_heap(xmhf_tlsf_pool pool, xmhf_tlsf_walker walker, void* user) +{ + xmhf_tlsf_walker heap_walker = walker ? walker : default_walker; + block_header_t* block = + offset_to_block(pool, sizeof(pool_t) - block_header_overhead); + + while (block && !block_is_last(block)) + { + heap_walker( + block_to_ptr(block), + block_size(block), + !block_is_free(block), + user); + block = block_next(block); + } +} + +size_t xmhf_tlsf_block_size(void* ptr) +{ + size_t size = 0; + if (ptr) + { + const block_header_t* block = block_from_ptr(ptr); + size = block_size(block); + } + return size; +} + +/* +** Overhead of the xmhf_tlsf structures in a given memory block passed to +** xmhf_tlsf_create, equal to the size of a pool_t plus overhead of the initial +** free block and the sentinel block. +*/ +size_t xmhf_tlsf_overhead() +{ + const size_t pool_overhead = sizeof(pool_t) + 2 * block_header_overhead; + return pool_overhead; +} + +/* +** xmhf_tlsf main interface. Right out of the white paper. +*/ + +xmhf_tlsf_pool xmhf_tlsf_create(void* mem, size_t bytes) +{ + block_header_t* block; + block_header_t* next; + + const size_t pool_overhead = xmhf_tlsf_overhead(); + const size_t pool_bytes = align_down(bytes - pool_overhead, ALIGN_SIZE); + pool_t* pool = xmhf_tlsf_cast(pool_t*, mem); + +#if _DEBUG + /* Verify ffs/fls work properly. */ + int rv = 0; + rv += (xmhf_tlsf_ffs(0) == -1) ? 0 : 0x1; + rv += (xmhf_tlsf_fls(0) == -1) ? 0 : 0x2; + rv += (xmhf_tlsf_ffs(1) == 0) ? 0 : 0x4; + rv += (xmhf_tlsf_fls(1) == 0) ? 0 : 0x8; + rv += (xmhf_tlsf_ffs(0x80000000) == 31) ? 0 : 0x10; + rv += (xmhf_tlsf_ffs(0x80008000) == 15) ? 0 : 0x20; + rv += (xmhf_tlsf_fls(0x80000008) == 31) ? 0 : 0x40; + rv += (xmhf_tlsf_fls(0x7FFFFFFF) == 30) ? 0 : 0x80; + +#if defined (xmhf_tlsf_64BIT) + rv += (xmhf_tlsf_fls_sizet(0x80000000) == 31) ? 0 : 0x100; + rv += (xmhf_tlsf_fls_sizet(0x100000000) == 32) ? 0 : 0x200; + rv += (xmhf_tlsf_fls_sizet(0xffffffffffffffff) == 63) ? 0 : 0x400; + if (rv) + { + printf("xmhf_tlsf_create: %x ffs/fls tests failed!\n", rv); + return 0; + } +#endif +#endif + + if (pool_bytes < block_size_min || pool_bytes > block_size_max) + { +#if defined (xmhf_tlsf_64BIT) + printf("xmhf_tlsf_create: Pool size must be at least %d bytes.\n", + (unsigned int)(pool_overhead + block_size_min)); +#else + printf("xmhf_tlsf_create: Pool size must be between %u and %u bytes.\n", + (unsigned int)(pool_overhead + block_size_min), + (unsigned int)(pool_overhead + block_size_max)); +#endif + return 0; + } + + /* Construct a valid pool object. */ + pool_construct(pool); + + /* + ** Create the main free block. Offset the start of the block slightly + ** so that the prev_phys_block field falls inside of the pool + ** structure - it will never be used. + */ + block = offset_to_block( + xmhf_tlsf_cast(void*, pool), sizeof(pool_t) - block_header_overhead); + block_set_size(block, pool_bytes); + block_set_free(block); + block_set_prev_used(block); + block_insert(pool, block); + + /* Split the block to create a zero-size pool sentinel block. */ + next = block_link_next(block); + block_set_size(next, 0); + block_set_used(next); + block_set_prev_free(next); + + return xmhf_tlsf_cast(xmhf_tlsf_pool, pool); +} + +void xmhf_tlsf_destroy(xmhf_tlsf_pool pool) +{ + /* Nothing to do. */ + pool = pool; +} + +void* xmhf_tlsf_malloc(xmhf_tlsf_pool xmhf_tlsf, size_t size) +{ + pool_t* pool = xmhf_tlsf_cast(pool_t*, xmhf_tlsf); + const size_t adjust = adjust_request_size(size, ALIGN_SIZE); + block_header_t* block = block_locate_free(pool, adjust); + return block_prepare_used(pool, block, adjust); +} + +void* xmhf_tlsf_memalign(xmhf_tlsf_pool xmhf_tlsf, size_t align, size_t size) +{ + pool_t* pool = xmhf_tlsf_cast(pool_t*, xmhf_tlsf); + const size_t adjust = adjust_request_size(size, ALIGN_SIZE); + + /* + ** We must allocate an additional minimum block size bytes so that if + ** our free block will leave an alignment gap which is smaller, we can + ** trim a leading free block and release it back to the heap. We must + ** do this because the previous physical block is in use, therefore + ** the prev_phys_block field is not valid, and we can't simply adjust + ** the size of that block. + */ + const size_t gap_minimum = sizeof(block_header_t); + const size_t size_with_gap = adjust_request_size(adjust + align + gap_minimum, align); + + /* If alignment is less than or equals base alignment, we're done. */ + const size_t aligned_size = (align <= ALIGN_SIZE) ? adjust : size_with_gap; + + block_header_t* block = block_locate_free(pool, aligned_size); + + /* This can't be a static assert. */ + xmhf_tlsf_assert(sizeof(block_header_t) == block_size_min + block_header_overhead); + + if (block) + { + void* ptr = block_to_ptr(block); + void* aligned = align_ptr(ptr, align); + size_t gap = xmhf_tlsf_cast(size_t, + xmhf_tlsf_cast(xmhf_tlsfptr_t, aligned) - xmhf_tlsf_cast(xmhf_tlsfptr_t, ptr)); + + /* If gap size is too small, offset to next aligned boundary. */ + if (gap && gap < gap_minimum) + { + const size_t gap_remain = gap_minimum - gap; + const size_t offset = xmhf_tlsf_max(gap_remain, align); + const void* next_aligned = xmhf_tlsf_cast(void*, + xmhf_tlsf_cast(xmhf_tlsfptr_t, aligned) + offset); + + aligned = align_ptr(next_aligned, align); + gap = xmhf_tlsf_cast(size_t, + xmhf_tlsf_cast(xmhf_tlsfptr_t, aligned) - xmhf_tlsf_cast(xmhf_tlsfptr_t, ptr)); + } + + if (gap) + { + xmhf_tlsf_assert(gap >= gap_minimum && "gap size too small"); + block = block_trim_free_leading(pool, block, gap); + } + } + + return block_prepare_used(pool, block, adjust); +} + +void xmhf_tlsf_free(xmhf_tlsf_pool xmhf_tlsf, void* ptr) +{ + /* Don't attempt to free a NULL pointer. */ + if (ptr) + { + pool_t* pool = xmhf_tlsf_cast(pool_t*, xmhf_tlsf); + block_header_t* block = block_from_ptr(ptr); + block_mark_as_free(block); + block = block_merge_prev(pool, block); + block = block_merge_next(pool, block); + block_insert(pool, block); + } +} + +/* +** The xmhf_tlsf block information provides us with enough information to +** provide a reasonably intelligent implementation of realloc, growing or +** shrinking the currently allocated block as required. +** +** This routine handles the somewhat esoteric edge cases of realloc: +** - a non-zero size with a null pointer will behave like malloc +** - a zero size with a non-null pointer will behave like free +** - a request that cannot be satisfied will leave the original buffer +** untouched +** - an extended buffer size will leave the newly-allocated area with +** contents undefined +*/ +void* xmhf_tlsf_realloc(xmhf_tlsf_pool xmhf_tlsf, void* ptr, size_t size) +{ + pool_t* pool = xmhf_tlsf_cast(pool_t*, xmhf_tlsf); + void* p = 0; + + /* Zero-size requests are treated as free. */ + if (ptr && size == 0) + { + xmhf_tlsf_free(xmhf_tlsf, ptr); + } + /* Requests with NULL pointers are treated as malloc. */ + else if (!ptr) + { + p = xmhf_tlsf_malloc(xmhf_tlsf, size); + } + else + { + block_header_t* block = block_from_ptr(ptr); + block_header_t* next = block_next(block); + + const size_t cursize = block_size(block); + const size_t combined = cursize + block_size(next) + block_header_overhead; + const size_t adjust = adjust_request_size(size, ALIGN_SIZE); + + /* + ** If the next block is used, or when combined with the current + ** block, does not offer enough space, we must reallocate and copy. + */ + if (adjust > cursize && (!block_is_free(next) || adjust > combined)) + { + p = xmhf_tlsf_malloc(xmhf_tlsf, size); + if (p) + { + const size_t minsize = xmhf_tlsf_min(cursize, size); + memcpy(p, ptr, minsize); + xmhf_tlsf_free(xmhf_tlsf, ptr); + } + } + else + { + /* Do we need to expand to the next block? */ + if (adjust > cursize) + { + block_merge_next(pool, block); + block_mark_as_used(block); + } + + /* Trim the resulting block and return the original pointer. */ + block_trim_used(pool, block, adjust); + p = ptr; + } + } + + return p; +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-mm/xmhf-tlsf.h b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-mm/xmhf-tlsf.h new file mode 100644 index 0000000000..894e4b3762 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-mm/xmhf-tlsf.h @@ -0,0 +1,53 @@ +#ifndef INCLUDED_xmhf_tlsf +#define INCLUDED_xmhf_tlsf + +/* +** Two Level Segregated Fit memory allocator, version 1.9. +** Written by Matthew Conte, and placed in the Public Domain. +** http://xmhf_tlsf.baisoku.org +** +** Based on the original documentation by Miguel Masmano: +** http://rtportal.upv.es/rtmalloc/allocators/xmhf_tlsf/index.shtml +** +** Please see the accompanying Readme.txt for implementation +** notes and caveats. +** +** This implementation was written to the specification +** of the document, therefore no GPL restrictions apply. +*/ + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Create/destroy a memory pool. */ +typedef void* xmhf_tlsf_pool; +xmhf_tlsf_pool xmhf_tlsf_create(void* mem, size_t bytes); +void xmhf_tlsf_destroy(xmhf_tlsf_pool pool); + +/* malloc/memalign/realloc/free replacements. */ +void* xmhf_tlsf_malloc(xmhf_tlsf_pool pool, size_t bytes); +void* xmhf_tlsf_memalign(xmhf_tlsf_pool pool, size_t align, size_t bytes); +void* xmhf_tlsf_realloc(xmhf_tlsf_pool pool, void* ptr, size_t size); +void xmhf_tlsf_free(xmhf_tlsf_pool pool, void* ptr); + +/* Debugging. */ +typedef void (*xmhf_tlsf_walker)(void* ptr, size_t size, int used, void* user); +void xmhf_tlsf_walk_heap(xmhf_tlsf_pool pool, xmhf_tlsf_walker walker, void* user); +/* Returns nonzero if heap check fails. */ +int xmhf_tlsf_check_heap(xmhf_tlsf_pool pool); + +/* Returns internal block size, not original request size */ +size_t xmhf_tlsf_block_size(void* ptr); + +/* Overhead of per-pool internal structures. */ +size_t xmhf_tlsf_overhead(void); + +#if defined(__cplusplus) +}; +#endif + +#endif diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-mm/xmhf-tlsfbits.h b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-mm/xmhf-tlsfbits.h new file mode 100644 index 0000000000..d1d00622c3 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-mm/xmhf-tlsfbits.h @@ -0,0 +1,180 @@ +#ifndef INCLUDED_xmhf_tlsfbits +#define INCLUDED_xmhf_tlsfbits + +#if defined(__cplusplus) +#define xmhf_tlsf_decl inline +#else +#define xmhf_tlsf_decl static +#endif + +/* +** Architecture-specific bit manipulation routines. +** +** xmhf_tlsf achieves O(1) cost for malloc and free operations by limiting +** the search for a free block to a free list of guaranteed size +** adequate to fulfill the request, combined with efficient free list +** queries using bitmasks and architecture-specific bit-manipulation +** routines. +** +** Most modern processors provide instructions to count leading zeroes +** in a word, find the lowest and highest set bit, etc. These +** specific implementations will be used when available, falling back +** to a reasonably efficient generic implementation. +** +** NOTE: xmhf_tlsf spec relies on ffs/fls returning value 0..31. +** ffs/fls return 1-32 by default, returning 0 for error. +*/ + +/* +** Detect whether or not we are building for a 32- or 64-bit (LP/LLP) +** architecture. There is no reliable portable method at compile-time. +*/ +#if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) \ + || defined (_WIN64) || defined (__LP64__) || defined (__LLP64__) +#define xmhf_tlsf_64BIT +#endif + +/* +** gcc 3.4 and above have builtin support, specialized for architecture. +** Some compilers masquerade as gcc; patchlevel test filters them out. +*/ +#if defined (__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) \ + && defined (__GNUC_PATCHLEVEL__) + +xmhf_tlsf_decl int xmhf_tlsf_ffs(unsigned int word) +{ + return __builtin_ffs(word) - 1; +} + +xmhf_tlsf_decl int xmhf_tlsf_fls(unsigned int word) +{ + const int bit = word ? 32 - __builtin_clz(word) : 0; + return bit - 1; +} + +#elif defined (_MSC_VER) && defined (_M_IX86) && (_MSC_VER >= 1400) +/* Microsoft Visual C++ 2005 support on x86 architectures. */ + +#include + +#pragma intrinsic(_BitScanReverse) +#pragma intrinsic(_BitScanForward) + +xmhf_tlsf_decl int xmhf_tlsf_fls(unsigned int word) +{ + unsigned long index; + return _BitScanReverse(&index, word) ? index : -1; +} + +xmhf_tlsf_decl int xmhf_tlsf_ffs(unsigned int word) +{ + unsigned long index; + return _BitScanForward(&index, word) ? index : -1; +} + +#elif defined (_MSC_VER) && defined (_M_PPC) +/* Microsoft Visual C++ support on PowerPC architectures. */ + +#include + +xmhf_tlsf_decl int xmhf_tlsf_fls(unsigned int word) +{ + const int bit = 32 - _CountLeadingZeros(word); + return bit - 1; +} + +xmhf_tlsf_decl int xmhf_tlsf_ffs(unsigned int word) +{ + const unsigned int reverse = word & (~word + 1); + const int bit = 32 - _CountLeadingZeros(reverse); + return bit - 1; +} + +#elif defined (__ARMCC_VERSION) +/* RealView Compilation Tools for ARM */ + +xmhf_tlsf_decl int xmhf_tlsf_ffs(unsigned int word) +{ + const unsigned int reverse = word & (~word + 1); + const int bit = 32 - __clz(reverse); + return bit - 1; +} + +xmhf_tlsf_decl int xmhf_tlsf_fls(unsigned int word) +{ + const int bit = word ? 32 - __clz(word) : 0; + return bit - 1; +} + +#elif defined (__ghs__) +/* Green Hills support for PowerPC */ + +#include + +xmhf_tlsf_decl int xmhf_tlsf_ffs(unsigned int word) +{ + const unsigned int reverse = word & (~word + 1); + const int bit = 32 - __CLZ32(reverse); + return bit - 1; +} + +xmhf_tlsf_decl int xmhf_tlsf_fls(unsigned int word) +{ + const int bit = word ? 32 - __CLZ32(word) : 0; + return bit - 1; +} + +#else +/* Fall back to generic implementation. */ + +xmhf_tlsf_decl int xmhf_tlsf_fls_generic(unsigned int word) +{ + int bit = 32; + + if (!word) bit -= 1; + if (!(word & 0xffff0000)) { word <<= 16; bit -= 16; } + if (!(word & 0xff000000)) { word <<= 8; bit -= 8; } + if (!(word & 0xf0000000)) { word <<= 4; bit -= 4; } + if (!(word & 0xc0000000)) { word <<= 2; bit -= 2; } + if (!(word & 0x80000000)) { word <<= 1; bit -= 1; } + + return bit; +} + +/* Implement ffs in terms of fls. */ +xmhf_tlsf_decl int xmhf_tlsf_ffs(unsigned int word) +{ + return xmhf_tlsf_fls_generic(word & (~word + 1)) - 1; +} + +xmhf_tlsf_decl int xmhf_tlsf_fls(unsigned int word) +{ + return xmhf_tlsf_fls_generic(word) - 1; +} + +#endif + +/* Possibly 64-bit version of xmhf_tlsf_fls. */ +#if defined (xmhf_tlsf_64BIT) +xmhf_tlsf_decl int xmhf_tlsf_fls_sizet(size_t size) +{ + int high = (int)(size >> 32); + int bits = 0; + if (high) + { + bits = 32 + xmhf_tlsf_fls(high); + } + else + { + bits = xmhf_tlsf_fls((int)size & 0xffffffff); + + } + return bits; +} +#else +#define xmhf_tlsf_fls_sizet xmhf_tlsf_fls +#endif + +#undef xmhf_tlsf_decl + +#endif diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/Makefile b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/Makefile new file mode 100644 index 0000000000..dccf7269ec --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/Makefile @@ -0,0 +1,16 @@ +# makefile for xmhf-partition (EMHF component for handling partition +# setup and instantiation) +# author: amit vasudevan (amitvasudevan@acm.org) + +# source files +AS_SOURCES = ./arch/x86/vmx/part-x86-$(TARGET_SUBARCH)vmx-sup.S +AS_SOURCES += ./arch/x86/svm/part-x86-$(TARGET_SUBARCH)svm-sup.S + +C_SOURCES = part-interface.c +C_SOURCES += ./arch/x86/part-x86.c +C_SOURCES += ./arch/x86/vmx/part-x86vmx.c +C_SOURCES += ./arch/x86/svm/part-x86svm.c + +# targets +include ../runtime.mk + diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/arch/x86/part-x86.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/arch/x86/part-x86.c new file mode 100644 index 0000000000..57489950ff --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/arch/x86/part-x86.c @@ -0,0 +1,98 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF partition component interface + * x86 backend + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//initialize partition monitor for a given CPU +void xmhf_partition_arch_initializemonitor(VCPU *vcpu){ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_AMD || vcpu->cpu_vendor == CPU_VENDOR_INTEL); + + if(vcpu->cpu_vendor == CPU_VENDOR_AMD){ + xmhf_partition_arch_x86svm_initializemonitor(vcpu); + }else{ //CPU_VENDOR_INTEL + xmhf_partition_arch_x86vmx_initializemonitor(vcpu); + } + +} + +//setup guest OS state for the partition +void xmhf_partition_arch_setupguestOSstate(VCPU *vcpu){ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_AMD || vcpu->cpu_vendor == CPU_VENDOR_INTEL); + + if(vcpu->cpu_vendor == CPU_VENDOR_AMD){ + xmhf_partition_arch_x86svm_setupguestOSstate(vcpu); + }else{ //CPU_VENDOR_INTEL + xmhf_partition_arch_x86vmx_setupguestOSstate(vcpu); + } +} + +//start executing the partition and guest OS +void xmhf_partition_arch_start(VCPU *vcpu){ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_AMD || vcpu->cpu_vendor == CPU_VENDOR_INTEL); + + if(vcpu->cpu_vendor == CPU_VENDOR_AMD){ + xmhf_partition_arch_x86svm_start(vcpu); + }else{ //CPU_VENDOR_INTEL + xmhf_partition_arch_x86vmx_start(vcpu); + } + +} + +//set legacy I/O protection for the partition +void xmhf_partition_arch_legacyIO_setprot(VCPU *vcpu, u32 port, u32 size, u32 prottype){ + if(vcpu->cpu_vendor == CPU_VENDOR_AMD){ + xmhf_partition_arch_x86svm_legacyIO_setprot(vcpu, port, size, prottype); + }else{ //CPU_VENDOR_INTEL + xmhf_partition_arch_x86vmx_legacyIO_setprot(vcpu, port, size, prottype); + } + +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/arch/x86/svm/part-x86-amd64svm-sup.S b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/arch/x86/svm/part-x86-amd64svm-sup.S new file mode 100644 index 0000000000..e1d166d07e --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/arch/x86/svm/part-x86-amd64svm-sup.S @@ -0,0 +1,117 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +//islayersup_svm.S +//implements supporting low-level routines for SVM isolation layer +//author: amit vasudevan (amitvasudevan@acm.org) + +#include + +//---globals referenced by this module------------------------------------------ +.extern g_midtable_numentries +.extern g_midtable +.extern xmhf_parteventhub_arch_x86svm_entry + +#define SAVEALL_GPRS \ + pushl %edi ; \ + pushl %esi ; \ + pushl %ebp ; \ + pushl %esp ; \ + pushl %ebx ; \ + pushl %edx ; \ + pushl %ecx ; \ + pushl %eax ; + +#define RESTOREALL_GPRS \ + popl %eax ; \ + popl %ecx ; \ + popl %edx ; \ + popl %ebx ; \ + popl %esp ; \ + popl %ebp ; \ + popl %esi ; \ + popl %edi ; + +.extern svm_intercept_handler + +.section .text + +//---__svm_start_hvm------------------------------------------------------------ +//we dont care about saving any CPU GPRs as we enter startHVM +.global __svm_start_hvm +__svm_start_hvm: + movl 0x4(%esp), %ebx //ebx = vcpu vaddr of current CPU + movl 0x8(%esp), %eax //eax = vmcb phys. addr of current CPU + + //XX: save vcpu vaddr +#ifdef __AMD64__ + pushq %rbx +#elif defined(__I386__) + pushl %ebx +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + + //real-mode setup just like the BIOS + movl $0x0, %ebx + movl $0x0, %ecx + movl $0x80, %edx + movl $0x0, %ebp + movl $0x0, %esi + movl $0x0, %edi + +__svm_resume_hvm: + //execute the HVM + //stgi + vmrun + //clgi + //stgi + + //invoke EMHF partition event-hub entry-point + call xmhf_parteventhub_arch_x86svm_entry + + //resume HVM + jmp __svm_resume_hvm diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/arch/x86/svm/part-x86-i386svm-sup.S b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/arch/x86/svm/part-x86-i386svm-sup.S new file mode 100644 index 0000000000..e1d166d07e --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/arch/x86/svm/part-x86-i386svm-sup.S @@ -0,0 +1,117 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +//islayersup_svm.S +//implements supporting low-level routines for SVM isolation layer +//author: amit vasudevan (amitvasudevan@acm.org) + +#include + +//---globals referenced by this module------------------------------------------ +.extern g_midtable_numentries +.extern g_midtable +.extern xmhf_parteventhub_arch_x86svm_entry + +#define SAVEALL_GPRS \ + pushl %edi ; \ + pushl %esi ; \ + pushl %ebp ; \ + pushl %esp ; \ + pushl %ebx ; \ + pushl %edx ; \ + pushl %ecx ; \ + pushl %eax ; + +#define RESTOREALL_GPRS \ + popl %eax ; \ + popl %ecx ; \ + popl %edx ; \ + popl %ebx ; \ + popl %esp ; \ + popl %ebp ; \ + popl %esi ; \ + popl %edi ; + +.extern svm_intercept_handler + +.section .text + +//---__svm_start_hvm------------------------------------------------------------ +//we dont care about saving any CPU GPRs as we enter startHVM +.global __svm_start_hvm +__svm_start_hvm: + movl 0x4(%esp), %ebx //ebx = vcpu vaddr of current CPU + movl 0x8(%esp), %eax //eax = vmcb phys. addr of current CPU + + //XX: save vcpu vaddr +#ifdef __AMD64__ + pushq %rbx +#elif defined(__I386__) + pushl %ebx +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + + //real-mode setup just like the BIOS + movl $0x0, %ebx + movl $0x0, %ecx + movl $0x80, %edx + movl $0x0, %ebp + movl $0x0, %esi + movl $0x0, %edi + +__svm_resume_hvm: + //execute the HVM + //stgi + vmrun + //clgi + //stgi + + //invoke EMHF partition event-hub entry-point + call xmhf_parteventhub_arch_x86svm_entry + + //resume HVM + jmp __svm_resume_hvm diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/arch/x86/svm/part-x86svm.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/arch/x86/svm/part-x86svm.c new file mode 100644 index 0000000000..e847800f1b --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/arch/x86/svm/part-x86svm.c @@ -0,0 +1,331 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF partition component interface (x86 SVM backend) + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//---init SVM------------------------------------------------------------------- +static void _svm_initSVM(VCPU *vcpu){ + u32 eax, edx, ecx, ebx; + u64 hsave_pa; + + //check if CPU supports SVM extensions + cpuid(0x80000001, &eax, &ebx, &ecx, &edx); + if( !(ecx & (1<id); + HALT(); + } + + //check if SVM extensions are disabled by the BIOS + rdmsr(VM_CR_MSR, &eax, &edx); + if( eax & (1<id); + HALT(); + } + + // check for nested paging support and number of ASIDs + cpuid(0x8000000A, &eax, &ebx, &ecx, &edx); + if(!(edx & 0x1)){ + printf("\nCPU(0x%02x): No support for Nested Paging, HALTING!", vcpu->id); + HALT(); + } + + printf("\nCPU(0x%02x): Nested paging support present", vcpu->id); + if( (ebx-1) < 2 ){ + printf("\nCPU(0x%02x): Total number of ASID is too low, HALTING!", vcpu->id); + HALT(); + } + + printf("\nCPU(0x%02x): Total ASID is valid", vcpu->id); + + // enable SVM and debugging support (if required) + rdmsr((u32)VM_CR_MSR, &eax, &edx); + eax &= (~(1<id); + + rdmsr((u32)MSR_EFER, &eax, &edx); + eax |= (1<id); + + // Initialize the HSA + //printf("\nHSAVE area=0x%08X", vcpu->hsave_vaddr_ptr); + hsave_pa = hva2spa((void*)vcpu->hsave_vaddr_ptr); + //printf("\nHSAVE physaddr=0x%08x", hsave_pa); + eax = (u32)hsave_pa; + edx = (u32)(hsave_pa >> 32); + wrmsr((u32)VM_HSAVE_PA, eax, edx); + printf("\nCPU(0x%02x): SVM HSAVE initialized", vcpu->id); + + // enable NX protections + rdmsr(MSR_EFER, &eax, &edx); + eax |= (1 << EFER_NXE); + wrmsr(MSR_EFER, eax, edx); + printf("\nCPU(0x%02x): NX protection enabled", vcpu->id); + + return; +} + + +//---svm int 15 hook enabling function------------------------------------------ +static void _svm_int15_initializehook(VCPU *vcpu){ + //we should only be called from the BSP + HALT_ON_ERRORCOND(vcpu->isbsp); + + { + /* use BDA reserved memory at 0040:00AC */ + volatile u8 *bdamemory = (volatile u8 *)0x4AC; + + /* 32-bit CS:IP for IVT INT 15 handler */ + volatile u16 *ivt_int15 = (volatile u16 *)(0x54); + + printf("\nCPU(0x%02x): original INT 15h handler at 0x%04x:0x%04x", vcpu->id, + ivt_int15[1], ivt_int15[0]); + + //we need 8 bytes (4 for the VMCALL followed by IRET and 4 for the + //original IVT INT 15h handler address + + //implant VMMCALL followed by IRET at 0040:04AC + bdamemory[0]= 0x0f; //VMMCALL + bdamemory[1]= 0x01; + bdamemory[2]= 0xd9; + bdamemory[3]= 0xcf; //IRET + + //store original INT 15h handler CS:IP following VMCALL and IRET + *((volatile u16 *)(&bdamemory[4])) = ivt_int15[0]; //original INT 15h IP + *((volatile u16 *)(&bdamemory[6])) = ivt_int15[1]; //original INT 15h CS + + //point IVT INT15 handler to the VMCALL instruction + ivt_int15[0]=0x00AC; + ivt_int15[1]=0x0040; + } +} + + +//---setup VMCB----------------------------------------------------------------- +static void _svm_initVMCB(VCPU *vcpu){ + + struct _svm_vmcbfields *vmcb = (struct _svm_vmcbfields *)vcpu->vmcb_vaddr_ptr; + + printf("\nCPU(0x%02x): VMCB at 0x%08x", vcpu->id, (hva_t)vmcb); + #ifndef __XMHF_VERIFICATION__ + memset(vmcb, 0, sizeof(struct _svm_vmcbfields)); + #endif + + // set up CS descr + vmcb->cs.selector = 0x0; + vmcb->cs.base = 0x0; + vmcb->cs.limit = 0x0ffff; // 64K limit since g=0 + vmcb->cs.attrib = 0x009b; + + // set up DS descr + vmcb->ds.selector = 0x0; + vmcb->ds.base = 0x0; + vmcb->ds.limit = 0x0ffff; // 64K limit since g=0 + vmcb->ds.attrib = 0x0093; // read/write + + // set up ES descr + vmcb->es.selector = 0x0; + vmcb->es.base = 0x0; + vmcb->es.limit = 0x0ffff; // 64K limit since g=0 + vmcb->es.attrib = 0x0093; // read/write + + // set up FS descr + vmcb->fs.selector = 0x0; + vmcb->fs.base = 0x0; + vmcb->fs.limit = 0x0ffff; // 64K limit since g=0 + vmcb->fs.attrib = 0x0093; // read/write + + // set up GS descr + vmcb->gs.selector = 0x0; + vmcb->gs.base = 0x0; + vmcb->gs.limit = 0x0ffff; // 64K limit since g=0 + vmcb->gs.attrib = 0x0093; // read/write + + // set up SS descr + vmcb->ss.selector = 0x0; + vmcb->ss.base = 0x0; + vmcb->ss.limit = 0x0ffff; // 64K limit since g=0 + vmcb->ss.attrib = 0x0093; // read/write + + vmcb->idtr.limit = 0x03ff; + + // SVME needs to be set in EFER for vmrun to execute + vmcb->efer |= (1 << EFER_SVME); + + // set guest PAT to state at reset. + vmcb->g_pat = 0x0007040600070406ULL; + + // other-non general purpose registers/state + vmcb->guest_asid = 1; // ASID 0 reserved for host + vmcb->cpl = 0; // set cpl to 0 for real mode + + // general purpose registers + vmcb->rax= 0x0ULL; + vmcb->rsp= 0x0ULL; + + if(vcpu->isbsp){ + printf("\nBSP(0x%02x): copying boot-module to boot guest", vcpu->id); + #ifndef __XMHF_VERIFICATION__ + memcpy((void *)__GUESTOSBOOTMODULE_BASE, (void *)rpb->XtGuestOSBootModuleBase, rpb->XtGuestOSBootModuleSize); + #endif + vmcb->rip = 0x7c00ULL; + }else{ + +#ifdef __NESTED_PAGING__ + vmcb->cs.selector = (vcpu->sipivector * PAGE_SIZE_4K) >> 4; + vmcb->cs.base = (vcpu->sipivector * PAGE_SIZE_4K); + vmcb->rip = 0x0ULL; +#endif + + } + vmcb->rflags = 0x0ULL; + + vmcb->cr0 = 0x00000010ULL; + vmcb->cr2 = 0ULL; + vmcb->cr3 = 0x0ULL; + vmcb->cr4 = 0ULL; + + vmcb->dr6 = 0xffff0ff0ULL; + vmcb->dr7 = 0x00000400ULL; + + + // intercept all SVM instructions + vmcb->class2_intercepts_bitmask |= (u32)(SVM_CLASS2_INTERCEPT_VMRUN | + SVM_CLASS2_INTERCEPT_VMMCALL | + SVM_CLASS2_INTERCEPT_VMLOAD | + SVM_CLASS2_INTERCEPT_VMSAVE | + SVM_CLASS2_INTERCEPT_STGI | + SVM_CLASS2_INTERCEPT_CLGI | + SVM_CLASS2_INTERCEPT_SKINIT | + SVM_CLASS2_INTERCEPT_ICEBP); + + //INT 15h E820 hook enablement for VMX unrestricted guest mode + //note: this only happens for the BSP + if(vcpu->isbsp){ + printf("\nCPU(0x%02x, BSP): initializing INT 15 hook...", vcpu->id); + _svm_int15_initializehook(vcpu); + } + + + //intercept NMIs, required for core quiescing support + vmcb->class1_intercepts_bitmask |= (u32) SVM_CLASS1_INTERCEPT_NMI; + + //setup IO interception + vmcb->iopm_base_pa = hva2spa((void *)vcpu->svm_vaddr_iobitmap); //setup vmcb iopm + vmcb->class1_intercepts_bitmask |= (u32) SVM_CLASS1_INTERCEPT_IOIO_PROT; + + //setup MSR interception + #ifndef __XMHF_VERIFICATION__ + memset((void *)g_svm_msrpm, 0, SIZEOF_MSRPM_BITMAP); //clear bitmap buffer + #endif + vmcb->msrpm_base_pa = hva2spa(g_svm_msrpm); //setup vmcb msrpm + vmcb->class1_intercepts_bitmask |= (u32) SVM_CLASS1_INTERCEPT_MSR_PROT; + + + return; +} + + + +//initialize partition monitor for a given CPU +void xmhf_partition_arch_x86svm_initializemonitor(VCPU *vcpu){ + //initialize SVM + _svm_initSVM(vcpu); + +} + +//setup guest OS state for the partition +void xmhf_partition_arch_x86svm_setupguestOSstate(VCPU *vcpu){ + //setup VMCB + _svm_initVMCB(vcpu); + +} + +//start executing the partition and guest OS +void xmhf_partition_arch_x86svm_start(VCPU *vcpu){ + struct _svm_vmcbfields *vmcb; + vmcb = (struct _svm_vmcbfields *)vcpu->vmcb_vaddr_ptr; + printf("\nCPU(0x%02x): Starting HVM using CS:EIP=0x%04x:0x%08x...", vcpu->id, + (u16)vmcb->cs.selector, (u32)vmcb->rip); + +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + //ensure that whenever a partition is started on a vcpu, we have nested paging + //enabled and that the base points to the nested page tables we have initialized + assert( (vmcb->np_enable == 1) ); + assert( (vmcb->n_cr3 == vcpu->npt_vaddr_ptr) ); +#endif + +#ifndef __XMHF_VERIFICATION__ + __svm_start_hvm(vcpu, hva2spa((void*)vcpu->vmcb_vaddr_ptr)); + //we never get here, if we do, we just return and our caller is responsible + //for halting the core as something really bad happened! +#endif + +} + +//set legacy I/O protection for the partition +void xmhf_partition_arch_x86svm_legacyIO_setprot(VCPU *vcpu, u32 port, u32 size, u32 prottype){ + u8 *bit_vector = (u8 *)vcpu->svm_vaddr_iobitmap; + u32 byte_offset, bit_offset; + u32 i; + + for(i=0; i < size; i++){ + byte_offset = (port+i) / 8; + bit_offset = (port+i) % 8; + if(prottype & PART_LEGACYIO_NOACCESS){ + bit_vector[byte_offset] |= (1 << bit_offset); + }else{ + prottype = PART_LEGACYIO_READWRITE; + bit_vector[byte_offset] &= ~((1 << bit_offset)); + } + } +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/arch/x86/vmx/part-x86-amd64vmx-sup.S b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/arch/x86/vmx/part-x86-amd64vmx-sup.S new file mode 100644 index 0000000000..4809e34048 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/arch/x86/vmx/part-x86-amd64vmx-sup.S @@ -0,0 +1,131 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// islayer low-level support for VMX +// author: amit vasudevan (amitvasudevan@acm.org) + +#include + +//---globals and externs referenced by this module------------------------------------------ +.extern x_gdt_start + +.section .text + +//---------------------------------------------------------------------- +// start HVM on a given physical core +// on success: this function will not return +// on failure: 1 if a valid error code is present, 0 if no error code, +// 2 if invalid error info. (should never happen) +//---------------------------------------------------------------------- + .global __vmx_start_hvm + __vmx_start_hvm: + + //save GPRs + pushq %r15 + pushq %r14 + pushq %r13 + pushq %r12 + pushq %r11 + pushq %r10 + pushq %r9 + pushq %r8 + pushq %rax + pushq %rcx + pushq %rdx + pushq %rbx + pushq %rsp + pushq %rbp + pushq %rsi + pushq %rdi + + //real-mode setup just like the BIOS + movl $0x0, %eax + movl $0x0, %ebx + movl $0x0, %ecx + movq %rdi, %rdx // First argument to this function + movl $0x0, %ebp + movl $0x0, %esi + movl $0x0, %edi + + //attempt to instantiate the HVM + vmlaunch + + //if we get here then some error happened during the launch + + //restore stack frame for a return from this procedure + popq %rdi + popq %rsi + popq %rbp + popq %rsp + popq %rbx + popq %rdx + popq %rcx + popq %rax + popq %r8 + popq %r9 + popq %r10 + popq %r11 + popq %r12 + popq %r13 + popq %r14 + popq %r15 + + //there are two possible causes of failure, VMFailInvalid or + //VMFailValid (VM instruction error field contains the error code) + //check which happened and return appropriate value in eax + jc __vmx_start_hvm_failinvalid + + jnz __vmx_start_hvm_undefinedimplementation + movl $0x1, %eax + ret //return 1 as we have error code + +__vmx_start_hvm_undefinedimplementation: + movl $0x2, %eax //violation of VMLAUNCH specs., handle it anyways + ret + +__vmx_start_hvm_failinvalid: + xorl %eax, %eax //return 0 as we have no error code available + ret diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/arch/x86/vmx/part-x86-i386vmx-sup.S b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/arch/x86/vmx/part-x86-i386vmx-sup.S new file mode 100644 index 0000000000..d8fa8b6b79 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/arch/x86/vmx/part-x86-i386vmx-sup.S @@ -0,0 +1,101 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// islayer low-level support for VMX +// author: amit vasudevan (amitvasudevan@acm.org) + +#include + +//---globals and externs referenced by this module------------------------------------------ +.extern x_gdt_start + +.section .text + +//---------------------------------------------------------------------- +// start HVM on a given physical core +// on success: this function will not return +// on failure: 1 if a valid error code is present, 0 if no error code, +// 2 if invalid error info. (should never happen) +//---------------------------------------------------------------------- + .global __vmx_start_hvm + __vmx_start_hvm: + + //save GPRs + pushal + + //real-mode setup just like the BIOS + movl $0x0, %eax + movl $0x0, %ebx + movl $0x0, %ecx + movl 8*4+4(%esp), %edx // First argument to this function + movl $0x0, %ebp + movl $0x0, %esi + movl $0x0, %edi + + //attempt to instantiate the HVM + vmlaunch + + //if we get here then some error happened during the launch + + //restore stack frame for a return from this procedure + popal + + //there are two possible causes of failure, VMFailInvalid or + //VMFailValid (VM instruction error field contains the error code) + //check which happened and return appropriate value in eax + jc __vmx_start_hvm_failinvalid + + jnz __vmx_start_hvm_undefinedimplementation + movl $0x1, %eax + ret //return 1 as we have error code + +__vmx_start_hvm_undefinedimplementation: + movl $0x2, %eax //violation of VMLAUNCH specs., handle it anyways + ret + +__vmx_start_hvm_failinvalid: + xorl %eax, %eax //return 0 as we have no error code available + ret diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/arch/x86/vmx/part-x86vmx.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/arch/x86/vmx/part-x86vmx.c new file mode 100644 index 0000000000..ca2a698326 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/arch/x86/vmx/part-x86vmx.c @@ -0,0 +1,726 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF partition component interface (x86 VMX backend) + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//---globals referenced by this module------------------------------------------ +//TODO: need to remove these direct references +extern u32 x_gdt_start[], x_idt_start[]; //runtimesup.S + + +//critical MSRs that need to be saved/restored across guest VM switches +// _vmx_handle_intercept_rdmsr() relies on the order of elements in this array +static const u32 vmx_msr_area_msrs[] = { + MSR_EFER, + MSR_IA32_PAT, + MSR_K6_STAR, +}; +//count of critical MSRs that need to be saved/restored across VM switches +static const unsigned int vmx_msr_area_msrs_count = (sizeof(vmx_msr_area_msrs)/sizeof(vmx_msr_area_msrs[0])); + + +//---initVT: initializes CPU VT------------------------------------------------- +static void _vmx_initVT(VCPU *vcpu){ + //step-0: to enable VMX on a core, we require it to have a TR loaded, + //so load it for this core + //__vmx_loadTR(); + { + hva_t gdtstart = (hva_t)&x_gdt_start; + u16 trselector = __TRSEL; + #ifndef __XMHF_VERIFICATION__ +#ifdef __AMD64__ + asm volatile("movq %0, %%rdi\r\n" + "xorq %%rax, %%rax\r\n" + "movw %1, %%ax\r\n" + "addq %%rax, %%rdi\r\n" //%rdi is pointer to TSS descriptor in GDT + "addq $0x4, %%rdi\r\n" //%rdi points to 2nd byte of 128-bit TSS desc. + "lock andl $0xFFFF00FF, (%%rdi)\r\n" + "lock orl $0x00008900, (%%rdi)\r\n" + "ltr %%ax\r\n" //load TR + : + : "m"(gdtstart), "m"(trselector) + : "rdi", "rax" + ); +#elif defined(__I386__) + asm volatile("movl %0, %%edi\r\n" + "xorl %%eax, %%eax\r\n" + "movw %1, %%ax\r\n" + "addl %%eax, %%edi\r\n" //%edi is pointer to TSS descriptor in GDT + "addl $0x4, %%edi\r\n" //%edi points to top 32-bits of 64-bit TSS desc. + "lock andl $0xFFFF00FF, (%%edi)\r\n" + "lock orl $0x00008900, (%%edi)\r\n" + "ltr %%ax\r\n" //load TR + : + : "m"(gdtstart), "m"(trselector) + : "edi", "eax" + ); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + #endif + } + + + + //step-1: check if intel CPU + { + #ifndef __XMHF_VERIFICATION__ + if (get_cpu_vendor_or_die() != CPU_VENDOR_INTEL) { + printf("\nCPU(0x%02x) is not an Intel CPU. Halting!", vcpu->id); + HALT(); + } + #endif + } + + //step-2: check VT support + { + #ifndef __XMHF_VERIFICATION__ + u32 eax, ebx, ecx, edx; + cpuid(1, &eax, &ebx, &ecx, &edx); + if ( ( ecx & (1<<5) ) == 0 ){ + printf("CPU(0x%02x) does not support VT. Halting!", vcpu->id); + HALT(); + } + #endif + } + + //step-3: save contents of VMX MSRs as well as MSR EFER and EFCR + //into vcpu + { + u32 i; + u32 eax, edx; + #ifndef __XMHF_VERIFICATION__ + for(i=0; i < IA32_VMX_MSRCOUNT; i++){ + #else + for(i=0; i < 1; i++){ + #endif + rdmsr( (IA32_VMX_BASIC_MSR + i), &eax, &edx); + vcpu->vmx_msrs[i] = (u64)edx << 32 | (u64) eax; + } + + rdmsr(MSR_EFER, &eax, &edx); + vcpu->vmx_msr_efer = (u64)edx << 32 | (u64) eax; + rdmsr(MSR_EFCR, &eax, &edx); + vcpu->vmx_msr_efcr = (u64)edx << 32 | (u64) eax; + + //[debug: dump contents of MSRs] + //for(i=0; i < IA32_VMX_MSRCOUNT; i++) + // printf("\nCPU(0x%02x): VMX MSR 0x%08x = 0x%08x%08x", vcpu->id, IA32_VMX_BASIC_MSR+i, + // (u32)((u64)vcpu->vmx_msrs[i] >> 32), (u32)vcpu->vmx_msrs[i]); + + //check if VMX supports unrestricted guest, if so we don't need the + //v86 monitor and the associated state transition handling + if( (u32)((u64)vcpu->vmx_msrs[IA32_VMX_MSRCOUNT-1] >> 32) & 0x80 ) + vcpu->vmx_guest_unrestricted = 1; + else + vcpu->vmx_guest_unrestricted = 0; + + #if defined(__DISABLE_UG__) + //for now disable unrestricted bit, as we still need to intercept + //E820 mem-map access and VMX doesnt provide software INT intercept :( + vcpu->guest_unrestricted=0; + #endif + + if(vcpu->vmx_guest_unrestricted) + printf("\nCPU(0x%02x): UNRESTRICTED-GUEST supported.", vcpu->id); + + printf("\nCPU(0x%02x): MSR_EFER=0x%08x%08x", vcpu->id, (u32)((u64)vcpu->vmx_msr_efer >> 32), + (u32)vcpu->vmx_msr_efer); + printf("\nCPU(0x%02x): MSR_EFCR=0x%08x%08x", vcpu->id, (u32)((u64)vcpu->vmx_msr_efcr >> 32), + (u32)vcpu->vmx_msr_efcr); + + } + + //step-4: enable VMX by setting CR4 + #ifndef __XMHF_VERIFICATION__ +#ifdef __AMD64__ + asm( " mov %%cr4, %%rax \n"\ + " bts $13, %%rax \n"\ + " mov %%rax, %%cr4 " ::: "rax" ); +#elif defined(__I386__) + asm( " mov %%cr4, %%eax \n"\ + " bts $13, %%eax \n"\ + " mov %%eax, %%cr4 " ::: "eax" ); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + #endif + printf("\nCPU(0x%02x): enabled VMX", vcpu->id); + + //step-5:enter VMX root operation using VMXON + { + u32 retval=0; + u64 vmxonregion_paddr = hva2spa((void*)vcpu->vmx_vmxonregion_vaddr); + //set VMCS rev id + #ifndef __XMHF_VERIFICATION__ + *((u32 *)vcpu->vmx_vmxonregion_vaddr) = (u32)vcpu->vmx_msrs[INDEX_IA32_VMX_BASIC_MSR]; + #endif + + #ifndef __XMHF_VERIFICATION__ +#ifdef __AMD64__ + asm( "vmxon %1 \n" + "jbe vmfail \n" + "movq $0x1, %%rax \n" + "movq %%rax, %0 \n" + "jmp vmsuccess \n" + "vmfail: \n" + "movq $0x0, %%rax \n" + "movq %%rax, %0 \n" + "vmsuccess: \n" + : "=m" (retval) + : "m"(vmxonregion_paddr) + : "rax"); +#elif defined(__I386__) + asm( "vmxon %1 \n" + "jbe vmfail \n" + "movl $0x1, %%eax \n" + "movl %%eax, %0 \n" + "jmp vmsuccess \n" + "vmfail: \n" + "movl $0x0, %%eax \n" + "movl %%eax, %0 \n" + "vmsuccess: \n" + : "=m" (retval) + : "m"(vmxonregion_paddr) + : "eax"); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + #endif + + if(!retval){ + printf("\nCPU(0x%02x): Fatal, unable to enter VMX root operation", vcpu->id); + HALT(); + } + + printf("\nCPU(0x%02x): Entered VMX root operation", vcpu->id); + } + +} + +//---vmx int 15 hook enabling function------------------------------------------ +static void _vmx_int15_initializehook(VCPU *vcpu){ + //we should only be called from the BSP + HALT_ON_ERRORCOND(vcpu->isbsp); + + { + /* use BDA reserved memory at 0040:00AC */ + volatile u8 *bdamemory = (volatile u8 *)0x4AC; + + /* 32-bit CS:IP for IVT INT 15 handler */ + volatile u16 *ivt_int15 = (volatile u16 *)(0x54); + + printf("\nCPU(0x%02x): original INT 15h handler at 0x%04x:0x%04x", vcpu->id, + ivt_int15[1], ivt_int15[0]); + + //we need 8 bytes (4 for the VMCALL followed by IRET and 4 for the + //original IVT INT 15h handler address + + //implant VMCALL followed by IRET at 0040:04AC + bdamemory[0]= 0x0f; //VMCALL + bdamemory[1]= 0x01; + bdamemory[2]= 0xc1; + bdamemory[3]= 0xcf; //IRET + + //store original INT 15h handler CS:IP following VMCALL and IRET + *((volatile u16 *)(&bdamemory[4])) = ivt_int15[0]; //original INT 15h IP + *((volatile u16 *)(&bdamemory[6])) = ivt_int15[1]; //original INT 15h CS + + + //point IVT INT15 handler to the VMCALL instruction + ivt_int15[0]=0x00AC; + ivt_int15[1]=0x0040; + } +} + +/* Return nonzero if this CPU supports INVPCID according to CPUID */ +static uint32_t _vmx_check_invpcid_support(void) { + uintptr_t eax, ebx, ecx, edx; + cpuid(0x7U, &eax, &ebx, &ecx, &edx); + return ebx & (1U << 10); +} + +/* Return nonzero if this CPU supports RDTSCP according to CPUID */ +static uint32_t _vmx_check_rdtscp_support(void) { + uintptr_t eax, ebx, ecx, edx; + cpuid(0x80000001U, &eax, &ebx, &ecx, &edx); + return edx & (1U << 27); +} + +//--initunrestrictedguestVMCS: initializes VMCS for unrestricted guest --------- +void vmx_initunrestrictedguestVMCS(VCPU *vcpu){ + u32 lodword, hidword; + + //setup host state + vcpu->vmcs.host_CR0 = read_cr0(); + vcpu->vmcs.host_CR4 = read_cr4(); + vcpu->vmcs.host_CR3 = read_cr3(); + vcpu->vmcs.host_CS_selector = read_segreg_cs(); + vcpu->vmcs.host_DS_selector = read_segreg_ds(); + vcpu->vmcs.host_ES_selector = read_segreg_es(); + vcpu->vmcs.host_FS_selector = read_segreg_fs(); + vcpu->vmcs.host_GS_selector = read_segreg_gs(); + vcpu->vmcs.host_SS_selector = read_segreg_ss(); + vcpu->vmcs.host_TR_selector = read_tr_sel(); + vcpu->vmcs.host_GDTR_base = (u64)(hva_t)x_gdt_start; + vcpu->vmcs.host_IDTR_base = (u64)(hva_t)xmhf_xcphandler_get_idt_start(); + vcpu->vmcs.host_TR_base = (u64)(hva_t)g_runtime_TSS; + vcpu->vmcs.host_RIP = (u64)(hva_t)xmhf_parteventhub_arch_x86vmx_entry; + +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + if( vcpu->vmcs.host_RIP == (u64)(hva_t)xmhf_parteventhub_arch_x86vmx_entry) + vcpu->vmcs.host_RIP = 0xDEADBEEF; +#endif //__XMHF_VERIFICATION__ + + //store vcpu at TOS +#ifdef __AMD64__ + vcpu->rsp = vcpu->rsp - sizeof(hva_t); +#elif defined(__I386__) + vcpu->esp = vcpu->esp - sizeof(hva_t); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +#ifndef __XMHF_VERIFICATION__ +#ifdef __AMD64__ + *(hva_t *)vcpu->rsp = (hva_t)vcpu; +#elif defined(__I386__) + *(hva_t *)vcpu->esp = (hva_t)vcpu; +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +#endif +#ifdef __AMD64__ + vcpu->vmcs.host_RSP = (u64)vcpu->rsp; +#elif defined(__I386__) + vcpu->vmcs.host_RSP = (u64)vcpu->esp; +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + + +#ifndef __XMHF_VERIFICATION__ + rdmsr(IA32_SYSENTER_CS_MSR, &lodword, &hidword); + vcpu->vmcs.host_SYSENTER_CS = lodword; + rdmsr(IA32_SYSENTER_ESP_MSR, &lodword, &hidword); + vcpu->vmcs.host_SYSENTER_ESP = (u64) (((u64)hidword << 32) | (u64)lodword); + rdmsr(IA32_SYSENTER_EIP_MSR, &lodword, &hidword); + vcpu->vmcs.host_SYSENTER_EIP = (u64) (((u64)hidword << 32) | (u64)lodword); + rdmsr(IA32_MSR_FS_BASE, &lodword, &hidword); + vcpu->vmcs.host_FS_base = (u64) (((u64)hidword << 32) | (u64)lodword); + rdmsr(IA32_MSR_GS_BASE, &lodword, &hidword); + vcpu->vmcs.host_GS_base = (u64) (((u64)hidword << 32) | (u64)lodword); +#endif + + //setup default VMX controls + vcpu->vmcs.control_VMX_pin_based = vcpu->vmx_msrs[INDEX_IA32_VMX_PINBASED_CTLS_MSR]; + vcpu->vmcs.control_VMX_cpu_based = vcpu->vmx_msrs[INDEX_IA32_VMX_PROCBASED_CTLS_MSR]; + vcpu->vmcs.control_VM_exit_controls = vcpu->vmx_msrs[INDEX_IA32_VMX_EXIT_CTLS_MSR]; + vcpu->vmcs.control_VM_entry_controls = vcpu->vmx_msrs[INDEX_IA32_VMX_ENTRY_CTLS_MSR]; + +#ifdef __AMD64__ + /* + * For amd64, set the Host address-space size (bit 9) in + * control_VM_exit_controls. First check whether setting this bit is + * allowed through bit (9 + 32) in the MSR. + */ + HALT_ON_ERRORCOND(vcpu->vmx_msrs[INDEX_IA32_VMX_EXIT_CTLS_MSR] & (1UL << (9 + 32))); + vcpu->vmcs.control_VM_exit_controls |= (1UL << 9); +#elif !defined(__I386__) + #error "Unsupported Arch" +#endif /* !defined(__I386__) */ + + //IO bitmap support + { + u64 addr = hva2spa((void*)vcpu->vmx_vaddr_iobitmap); + vcpu->vmcs.control_IO_BitmapA_address = addr; + } + { + u64 addr = hva2spa( ((void*)vcpu->vmx_vaddr_iobitmap + PAGE_SIZE_4K) ); + vcpu->vmcs.control_IO_BitmapB_address = addr; + } + vcpu->vmcs.control_VMX_cpu_based |= (1 << 25); //enable use IO Bitmaps + + //Critical MSR load/store + { + u32 i; + msr_entry_t *hmsr = (msr_entry_t *)vcpu->vmx_vaddr_msr_area_host; + msr_entry_t *gmsr = (msr_entry_t *)vcpu->vmx_vaddr_msr_area_guest; + + #ifndef __XMHF_VERIFICATION__ + //store initial values of the MSRs + for(i=0; i < vmx_msr_area_msrs_count; i++){ + u32 msr, eax, edx; + msr = vmx_msr_area_msrs[i]; + rdmsr(msr, &eax, &edx); + hmsr[i].index = gmsr[i].index = msr; + hmsr[i].data = gmsr[i].data = ((u64)edx << 32) | (u64)eax; +#ifdef __AMD64__ + if (msr == MSR_EFER) { + /* + * Host is in amd64, but guest should enter from x86. + * Need to manually clear MSR_EFER's 8th bit (LME) and + * 10th bit (LMA). Otherwise when guest enables paging + * a #GP exception will occur. + */ + gmsr[i].data &= ~((1LU << EFER_LME) | (1LU << EFER_LMA)); + } +#elif !defined(__I386__) + #error "Unsupported Arch" +#endif /* !defined(__I386__) */ + } + #endif + + //host MSR load on exit, we store it ourselves before entry + { + u64 addr = hva2spa((void*)vcpu->vmx_vaddr_msr_area_host); + vcpu->vmcs.control_VM_exit_MSR_load_address=addr; + } + vcpu->vmcs.control_VM_exit_MSR_load_count= vmx_msr_area_msrs_count; + + //guest MSR load on entry, store on exit + { + u64 addr = (u32)hva2spa((void*)vcpu->vmx_vaddr_msr_area_guest); + vcpu->vmcs.control_VM_entry_MSR_load_address=addr; + } + vcpu->vmcs.control_VM_entry_MSR_load_count=vmx_msr_area_msrs_count; + { + u64 addr = (u32)hva2spa((void*)vcpu->vmx_vaddr_msr_area_guest); + vcpu->vmcs.control_VM_exit_MSR_store_address=addr; + } + vcpu->vmcs.control_VM_exit_MSR_store_count=vmx_msr_area_msrs_count; + } + + + vcpu->vmcs.control_pagefault_errorcode_mask = 0x00000000; //dont be concerned with + vcpu->vmcs.control_pagefault_errorcode_match = 0x00000000; //guest page-faults + vcpu->vmcs.control_exception_bitmap = 0; + vcpu->vmcs.control_CR3_target_count = 0; + + //setup guest state + //CR0, real-mode, PE and PG bits cleared, set ET bit + vcpu->vmcs.guest_CR0 = vcpu->vmx_msrs[INDEX_IA32_VMX_CR0_FIXED0_MSR]; + vcpu->vmcs.guest_CR0 &= ~(CR0_PE); + vcpu->vmcs.guest_CR0 &= ~(CR0_PG); + vcpu->vmcs.guest_CR0 |= CR0_ET; + //CR4, required bits set (usually VMX enabled bit) + vcpu->vmcs.guest_CR4 = vcpu->vmx_msrs[INDEX_IA32_VMX_CR4_FIXED0_MSR]; + //CR3 set to 0, does not matter + vcpu->vmcs.guest_CR3 = 0; + //IDTR + vcpu->vmcs.guest_IDTR_base = 0; + if (vcpu->isbsp) { + vcpu->vmcs.guest_IDTR_limit = 0x3ff; //16-bit IVT + } else { + vcpu->vmcs.guest_IDTR_limit = 0xffff; + } + //GDTR + vcpu->vmcs.guest_GDTR_base = 0; + if (vcpu->isbsp) { + vcpu->vmcs.guest_GDTR_limit = 0; //no GDT + } else { + vcpu->vmcs.guest_GDTR_limit = 0xffff; + } + //LDTR, unusable + vcpu->vmcs.guest_LDTR_base = 0; + if (vcpu->isbsp) { + vcpu->vmcs.guest_LDTR_limit = 0; + } else { + vcpu->vmcs.guest_LDTR_limit = 0xffff; + } + vcpu->vmcs.guest_LDTR_selector = 0; + vcpu->vmcs.guest_LDTR_access_rights = 0x10000; + // TR, should be usable for VMX to work, but not used by guest + // In 32-bit guest, TR access rights can be 0x83 (16-bit busy TSS) or 0x8b + // (32-bit busy TSS). In 64-bit guest, it has to be 0x8b. So use 0x8b + // (64-bit busy TSS). So use 0x8b here. + vcpu->vmcs.guest_TR_base = 0; + vcpu->vmcs.guest_TR_limit = 0; + vcpu->vmcs.guest_TR_selector = 0; + vcpu->vmcs.guest_TR_access_rights = 0x8b; //present, 32/64-bit busy TSS + //DR7 + vcpu->vmcs.guest_DR7 = 0x400; + //RSP + vcpu->vmcs.guest_RSP = 0x0; + //RIP + if(vcpu->isbsp){ + printf("\nBSP(0x%02x): copying boot-module to boot guest", vcpu->id); + #ifndef __XMHF_VERIFICATION__ + memcpy((void *)__GUESTOSBOOTMODULE_BASE, (void *)rpb->XtGuestOSBootModuleBase, rpb->XtGuestOSBootModuleSize); + #endif + vcpu->vmcs.guest_CS_selector = 0; + vcpu->vmcs.guest_CS_base = 0; + vcpu->vmcs.guest_RIP = 0x7c00ULL; + }else{ + vcpu->vmcs.guest_CS_selector = (vcpu->sipivector * PAGE_SIZE_4K) >> 4; + vcpu->vmcs.guest_CS_base = (vcpu->sipivector * PAGE_SIZE_4K); + vcpu->vmcs.guest_RIP = 0x0ULL; + } + + //RFLAGS + vcpu->vmcs.guest_RFLAGS = (1<<1); // reserved 1-bits + if (vcpu->isbsp) { + vcpu->vmcs.guest_RFLAGS &= ~((1<<3)|(1<<5)|(1<<15)); // reserved 0-bits + vcpu->vmcs.guest_RFLAGS |= (1<<9); // IF = enable + vcpu->vmcs.guest_RFLAGS &= ~(1<<14); // Nested Task = disable + } + + //CS, DS, ES, FS, GS and SS segments + vcpu->vmcs.guest_CS_limit = 0xFFFF; //64K + vcpu->vmcs.guest_CS_access_rights = 0x93; //present, system, read-write accessed + vcpu->vmcs.guest_DS_selector = 0; + vcpu->vmcs.guest_DS_base = 0; + vcpu->vmcs.guest_DS_limit = 0xFFFF; //64K + vcpu->vmcs.guest_DS_access_rights = 0x93; //present, system, read-write accessed + vcpu->vmcs.guest_ES_selector = 0; + vcpu->vmcs.guest_ES_base = 0; + vcpu->vmcs.guest_ES_limit = 0xFFFF; //64K + vcpu->vmcs.guest_ES_access_rights = 0x93; //present, system, read-write accessed + vcpu->vmcs.guest_FS_selector = 0; + vcpu->vmcs.guest_FS_base = 0; + vcpu->vmcs.guest_FS_limit = 0xFFFF; //64K + vcpu->vmcs.guest_FS_access_rights = 0x93; //present, system, read-write accessed + vcpu->vmcs.guest_GS_selector = 0; + vcpu->vmcs.guest_GS_base = 0; + vcpu->vmcs.guest_GS_limit = 0xFFFF; //64K + vcpu->vmcs.guest_GS_access_rights = 0x93; //present, system, read-write accessed + vcpu->vmcs.guest_SS_selector = 0x0; + vcpu->vmcs.guest_SS_base = 0x0; + vcpu->vmcs.guest_SS_limit = 0xFFFF; //64K + vcpu->vmcs.guest_SS_access_rights = 0x93; //present, system, read-write accessed + + //activate secondary processor controls + vcpu->vmcs.control_VMX_seccpu_based = vcpu->vmx_msrs[INDEX_IA32_VMX_PROCBASED_CTLS2_MSR]; + vcpu->vmcs.control_VMX_cpu_based |= (1 << 31); //activate secondary processor controls + + //setup unrestricted guest + vcpu->vmcs.control_VMX_seccpu_based |= (1 << 7); //enable unrestricted guest + + //allow INVPCID (used by Debian 11) + if (_vmx_check_invpcid_support()) { + vcpu->vmcs.control_VMX_seccpu_based |= (1 << 12); //enable INVPCID + } + + //allow RDTSCP (used by Debian 11) + if (_vmx_check_rdtscp_support()) { + vcpu->vmcs.control_VMX_seccpu_based |= (1 << 3); //enable RDTSCP + } + + //setup VMCS link pointer + vcpu->vmcs.guest_VMCS_link_pointer = (u64)0xFFFFFFFFFFFFFFFFULL; + + //setup NMI intercept for core-quiescing + vcpu->vmcs.control_VMX_pin_based |= (1 << 3); //intercept NMIs + vcpu->vmcs.control_VMX_pin_based |= (1 << 5); //enable virtual NMIs + vcpu->vmx_guest_inject_nmi = 0; + + //trap access to CR0 fixed 1-bits + // Make sure to change vmx_handle_intercept_cr0access_ug() if changing + // control_CR0_mask. + vcpu->vmcs.control_CR0_mask = vcpu->vmx_msrs[INDEX_IA32_VMX_CR0_FIXED0_MSR]; + vcpu->vmcs.control_CR0_mask &= ~(CR0_PE); + vcpu->vmcs.control_CR0_mask &= ~(CR0_PG); + vcpu->vmcs.control_CR0_mask |= CR0_CD; + vcpu->vmcs.control_CR0_mask |= CR0_NW; + if (vcpu->isbsp) { + /* 0x00000010U (e.g. after QEMU's SeaBIOS jumps to 0x7c00) */ + vcpu->vmcs.control_CR0_shadow = CR0_ET; + } else { + /* 0x60000010U (Intel's spec on processor state after INIT) */ + vcpu->vmcs.control_CR0_shadow = CR0_CD | CR0_NW | CR0_ET; + } + + //trap access to CR4 fixed bits (this includes the VMXE bit) + // Make sure to change vmx_handle_intercept_cr4access_ug() if changing + // control_CR4_mask. + vcpu->vmcs.control_CR4_mask = vcpu->vmx_msrs[INDEX_IA32_VMX_CR4_FIXED0_MSR]; + vcpu->vmcs.control_CR4_shadow = 0; + + //flush guest TLB to start with + xmhf_memprot_arch_x86vmx_flushmappings(vcpu); +} + + + +//---initVMCS - intialize VMCS for guest boot----------------------------------- +static void _vmx_initVMCS(VCPU *vcpu){ + vmx_initunrestrictedguestVMCS(vcpu); +} + + +//---start a HVM---------------------------------------------------------------- +static void _vmx_start_hvm(VCPU *vcpu, u32 vmcs_phys_addr){ + //clear VMCS + if(!__vmx_vmclear((u64)vmcs_phys_addr)){ + printf("\nCPU(0x%02x): VMCLEAR failed, HALT!", vcpu->id); + HALT(); + } + printf("\nCPU(0x%02x): VMCLEAR success.", vcpu->id); + + + //set VMCS revision id + *((u32 *)vcpu->vmx_vmcs_vaddr) = (u32)vcpu->vmx_msrs[INDEX_IA32_VMX_BASIC_MSR]; + + //load VMPTR + if(!__vmx_vmptrld((u64)vmcs_phys_addr)){ + printf("\nCPU(0x%02x): VMPTRLD failed, HALT!", vcpu->id); + HALT(); + } + printf("\nCPU(0x%02x): VMPTRLD success.", vcpu->id); + + //put VMCS to CPU + xmhf_baseplatform_arch_x86vmx_putVMCS(vcpu); + printf("\nCPU(0x%02x): VMWRITEs success.", vcpu->id); + HALT_ON_ERRORCOND( vcpu->vmcs.guest_VMCS_link_pointer == 0xFFFFFFFFFFFFFFFFULL ); + + { + u32 errorcode; + /* + * For BSP, use boot drive number (usually RDX=0x80 for frist HDD). + * For AP, use RDX=0x000n06xx (Intel's spec on processor state after INIT). + */ + uintptr_t rdx = (uintptr_t)rpb->XtGuestOSBootDrive; + if (!vcpu->isbsp) { + u32 _eax, _ebx, _ecx, _edx; + cpuid(0x80000001U, &_eax, &_ebx, &_ecx, &_edx); + rdx = 0x00000600UL | (0x000f0000UL & _eax); + } + errorcode=__vmx_start_hvm(rdx); + HALT_ON_ERRORCOND(errorcode != 2); //this means the VMLAUNCH implementation violated the specs. + //get CPU VMCS into VCPU structure + xmhf_baseplatform_arch_x86vmx_getVMCS(vcpu); + + switch(errorcode){ + case 0: //no error code, VMCS pointer is invalid + printf("\nCPU(0x%02x): VMLAUNCH error; VMCS pointer invalid?. HALT!", vcpu->id); + break; + case 1:{//error code available, so dump it + unsigned long code=5; + HALT_ON_ERRORCOND(__vmx_vmread(0x4400, &code)); + printf("\nCPU(0x%02x): VMLAUNCH error; code=0x%lx. HALT!", vcpu->id, code); + xmhf_baseplatform_arch_x86vmx_dumpVMCS(vcpu); + break; + } + } + HALT(); + } + + HALT(); +} + + + + +//initialize partition monitor for a given CPU +void xmhf_partition_arch_x86vmx_initializemonitor(VCPU *vcpu){ + + //initialize VT + _vmx_initVT(vcpu); + + + #ifndef __XMHF_VERIFICATION__ + //clear VMCS + memset((void *)&vcpu->vmcs, 0, sizeof(struct _vmx_vmcsfields)); + #endif + + //INT 15h E820 hook enablement for VMX unrestricted guest mode + //note: this only happens for the BSP + if(vcpu->isbsp){ + printf("\nCPU(0x%02x, BSP): initializing INT 15 hook for UG mode...", vcpu->id); + _vmx_int15_initializehook(vcpu); + } + +} + + + +//setup guest OS state for the partition +void xmhf_partition_arch_x86vmx_setupguestOSstate(VCPU *vcpu){ + //initialize VMCS + _vmx_initVMCS(vcpu); + +} + +//start executing the partition and guest OS +void xmhf_partition_arch_x86vmx_start(VCPU *vcpu){ + +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + //ensure that whenever a partition is started on a vcpu, we have extended paging + //enabled and that the base points to the extended page tables we have initialized + assert( vcpu->vmcs.control_EPT_pointer == (hva2spa((void*)vcpu->vmx_vaddr_ept_pml4_table) | 0x1E) ); + assert( (vcpu->vmcs.control_VMX_seccpu_based & 0x2) ); + assert( vcpu->vmcs.host_RIP == 0xDEADBEEF); +#endif + +#ifndef __XMHF_VERIFICATION__ + _vmx_start_hvm(vcpu, hva2spa((void*)vcpu->vmx_vmcs_vaddr)); + //we never get here, if we do, we just return and our caller is responsible + //for halting the core as something really bad happened! +#endif + +} + +//set legacy I/O protection for the partition +void xmhf_partition_arch_x86vmx_legacyIO_setprot(VCPU *vcpu, u32 port, u32 size, u32 prottype){ + u8 *bit_vector = (u8 *)vcpu->vmx_vaddr_iobitmap; + u32 byte_offset, bit_offset; + u32 i; + + for(i=0; i < size; i++){ + byte_offset = (port+i) / 8; + bit_offset = (port+i) % 8; + if(prottype & PART_LEGACYIO_NOACCESS){ + bit_vector[byte_offset] |= (1 << bit_offset); + }else{ + prottype = PART_LEGACYIO_READWRITE; + bit_vector[byte_offset] &= ~((1 << bit_offset)); + } + } +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/part-interface.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/part-interface.c new file mode 100644 index 0000000000..7631df5265 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-partition/part-interface.c @@ -0,0 +1,72 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF partition component interface + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//initialize partition monitor for a given CPU +void xmhf_partition_initializemonitor(VCPU *vcpu){ + xmhf_partition_arch_initializemonitor(vcpu); +} + +//setup guest OS state for the partition +void xmhf_partition_setupguestOSstate(VCPU *vcpu){ + xmhf_partition_arch_setupguestOSstate(vcpu); +} + +//start executing the partition and guest OS +void xmhf_partition_start(VCPU *vcpu){ + xmhf_partition_arch_start(vcpu); +} + +//set legacy I/O protection for the partition +void xmhf_partition_legacyIO_setprot(VCPU *vcpu, u32 port, u32 size, u32 prottype){ + xmhf_partition_arch_legacyIO_setprot(vcpu, port, size, prottype); +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-smpguest/Makefile b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-smpguest/Makefile new file mode 100644 index 0000000000..1f43957fc3 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-smpguest/Makefile @@ -0,0 +1,17 @@ +# makefile for xmhf-smpguest (EMHF SMP guest component) +# author: amit vasudevan (amitvasudevan@acm.org) + +# source files +AS_SOURCES = +C_SOURCES = smpg-interface.c +C_SOURCES += ./arch/x86/smpg-x86.c + +C_SOURCES += ./arch/x86/svm/smpg-x86svm.c +C_SOURCES += ./arch/x86/svm/smpg-x86svm-data.c + +C_SOURCES += ./arch/x86/vmx/smpg-x86vmx.c +C_SOURCES += ./arch/x86/vmx/smpg-x86vmx-data.c + +# targets +include ../runtime.mk + diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-smpguest/arch/x86/smpg-x86.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-smpguest/arch/x86/smpg-x86.c new file mode 100644 index 0000000000..e463d1fca0 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-smpguest/arch/x86/smpg-x86.c @@ -0,0 +1,192 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF symmetric multiprocessor (SMP) guest component +// x86 arch. backend implementation +// author: amit vasudevan (amitvasudevan@acm.org) + +#include + +//initialize SMP guest logic +void xmhf_smpguest_arch_initialize(VCPU *vcpu){ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_AMD || vcpu->cpu_vendor == CPU_VENDOR_INTEL); + + /* + * When DRT is enabled, hypervisor will block NMIs. This may cause failures + * in quiescing. So unblock NMIs here (regardless of DRT to be safe). + */ + if (vcpu->cpu_vendor == CPU_VENDOR_INTEL) { + xmhf_smpguest_arch_x86vmx_unblock_nmi(); + } + +#if defined(__MP_VERSION__) + //TODOs: + //1. conceal g_midtable_numentries behind "baseplatform" component interface + //2. remove g_isl dependency + // Only 1 CPU available, just make sure we are BSP and do nothing + if (g_midtable_numentries <= 1) { + HALT_ON_ERRORCOND(vcpu->isbsp); + if(vcpu->cpu_vendor == CPU_VENDOR_AMD){ + /* Not implmented */ + HALT(); + }else{ //CPU_VENDOR_INTEL + xmhf_smpguest_arch_x86vmx_initialize(vcpu, 0); + printf("\nCPU(0x%02x): x86vmx SMP but only one CPU", vcpu->id); + } + return; + } + + //if we are the BSP and platform has more than 1 CPU, setup SIPI interception to tackle SMP guests + if(vcpu->isbsp){ + if(vcpu->cpu_vendor == CPU_VENDOR_AMD){ + xmhf_smpguest_arch_x86svm_initialize(vcpu); + printf("\nCPU(0x%02x): setup x86svm SMP guest capabilities", vcpu->id); + }else{ //CPU_VENDOR_INTEL + xmhf_smpguest_arch_x86vmx_initialize(vcpu, 1); + printf("\nCPU(0x%02x): setup x86vmx SMP guest capabilities", vcpu->id); + } + }else{ //we are an AP, so just wait for SIPI signal + printf("\nCPU(0x%02x): AP, waiting for SIPI signal...", vcpu->id); + #ifndef __XMHF_VERIFICATION__ + while(!vcpu->sipireceived); + #endif + printf("\nCPU(0x%02x): SIPI signal received, vector=0x%02x", vcpu->id, vcpu->sipivector); + + //g_isl->hvm_initialize_csrip(vcpu, ((vcpu->sipivector * PAGE_SIZE_4K) >> 4), + // (vcpu->sipivector * PAGE_SIZE_4K), 0x0ULL); + + //perform required setup after a guest awakens a new CPU + xmhf_smpguest_arch_x86_postCPUwakeup(vcpu); + } +#else + //UP version, we just let the BSP continue and stall the APs + if(vcpu->isbsp) + return; + + //we are an AP, so just lockup + printf("\nCPU(0x%02x): AP, locked!", vcpu->id); + while(1); +#endif + + +} + + +//handle LAPIC access #DB (single-step) exception event +void xmhf_smpguest_arch_x86_eventhandler_dbexception(VCPU *vcpu, + struct regs *r){ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_AMD || vcpu->cpu_vendor == CPU_VENDOR_INTEL); + if(vcpu->cpu_vendor == CPU_VENDOR_AMD){ + xmhf_smpguest_arch_x86svm_eventhandler_dbexception(vcpu, r); + }else{ //CPU_VENDOR_INTEL + xmhf_smpguest_arch_x86vmx_eventhandler_dbexception(vcpu, r); + } +} + +//handle LAPIC access #NPF (nested page fault) event +void xmhf_smpguest_arch_x86_eventhandler_hwpgtblviolation(VCPU *vcpu, u32 gpa, u32 errorcode){ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_AMD || vcpu->cpu_vendor == CPU_VENDOR_INTEL); + if(vcpu->cpu_vendor == CPU_VENDOR_AMD){ + xmhf_smpguest_arch_x86svm_eventhandler_hwpgtblviolation(vcpu, gpa, errorcode); + }else{ //CPU_VENDOR_INTEL + xmhf_smpguest_arch_x86vmx_eventhandler_hwpgtblviolation(vcpu, gpa, errorcode); + } + +} + +//quiescing handler for #NMI (non-maskable interrupt) exception event +void xmhf_smpguest_arch_x86_eventhandler_nmiexception(VCPU *vcpu, struct regs *r, u32 from_guest){ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_AMD || vcpu->cpu_vendor == CPU_VENDOR_INTEL); + if(vcpu->cpu_vendor == CPU_VENDOR_AMD){ + xmhf_smpguest_arch_x86svm_eventhandler_nmiexception(vcpu, r); + }else{ //CPU_VENDOR_INTEL + xmhf_smpguest_arch_x86vmx_eventhandler_nmiexception(vcpu, r, from_guest); + } +} + +//perform required setup after a guest awakens a new CPU +void xmhf_smpguest_arch_x86_postCPUwakeup(VCPU *vcpu){ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_AMD || vcpu->cpu_vendor == CPU_VENDOR_INTEL); + + if(vcpu->cpu_vendor == CPU_VENDOR_AMD){ + xmhf_smpguest_arch_x86svm_postCPUwakeup(vcpu); + }else{ //CPU_VENDOR_INTEL + xmhf_smpguest_arch_x86vmx_postCPUwakeup(vcpu); + } + +} + +//walk guest page tables; returns pointer to corresponding guest physical address +//note: returns 0xFFFFFFFF if there is no mapping +u8 * xmhf_smpguest_arch_walk_pagetables(VCPU *vcpu, u32 vaddr){ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_AMD || vcpu->cpu_vendor == CPU_VENDOR_INTEL); + + if(vcpu->cpu_vendor == CPU_VENDOR_AMD){ + return xmhf_smpguest_arch_x86svm_walk_pagetables(vcpu, vaddr); + }else{ //CPU_VENDOR_INTEL + return xmhf_smpguest_arch_x86vmx_walk_pagetables(vcpu, vaddr); + } +} + +//quiesce interface to switch all guest cores into hypervisor mode +void xmhf_smpguest_arch_quiesce(VCPU *vcpu){ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_AMD || vcpu->cpu_vendor == CPU_VENDOR_INTEL); + if(vcpu->cpu_vendor == CPU_VENDOR_AMD){ + xmhf_smpguest_arch_x86svm_quiesce(vcpu); + }else{ //CPU_VENDOR_INTEL + xmhf_smpguest_arch_x86vmx_quiesce(vcpu); + } +} + +//endquiesce interface to resume all guest cores after a quiesce +void xmhf_smpguest_arch_endquiesce(VCPU *vcpu){ + HALT_ON_ERRORCOND(vcpu->cpu_vendor == CPU_VENDOR_AMD || vcpu->cpu_vendor == CPU_VENDOR_INTEL); + if(vcpu->cpu_vendor == CPU_VENDOR_AMD){ + xmhf_smpguest_arch_x86svm_endquiesce(vcpu); + }else{ //CPU_VENDOR_INTEL + xmhf_smpguest_arch_x86vmx_endquiesce(vcpu); + } +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-smpguest/arch/x86/svm/smpg-x86svm-data.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-smpguest/arch/x86/svm/smpg-x86svm-data.c new file mode 100644 index 0000000000..406d8dc18a --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-smpguest/arch/x86/svm/smpg-x86svm-data.c @@ -0,0 +1,99 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/** + * smpg-x86svm-data.c + * EMHF SMP guest component x86 (SVM) backend data + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//the BSP LAPIC base address - smpguest x86svm +u32 g_svm_lapic_base __attribute__(( section(".data") )) = 0; + +//the quiesce counter, all CPUs except for the one requesting the +//quiesce will increment this when they get their quiesce signal +//smpguest x86svm +u32 g_svm_quiesce_counter __attribute__(( section(".data") )) = 0; + +//SMP lock to access the above variable +//smpguest x86svm +u32 g_svm_lock_quiesce_counter __attribute__(( section(".data") )) = 1; + +//resume counter to rally all CPUs after resumption from quiesce +//smpguest x86svm +u32 g_svm_quiesce_resume_counter __attribute__(( section(".data") )) = 0; + +//SMP lock to access the above variable +//smpguest x86svm +u32 g_svm_lock_quiesce_resume_counter __attribute__(( section(".data") )) = 1; + +//the "quiesce" variable, if 1, then we have a quiesce in process +//smpguest x86svm +u32 g_svm_quiesce __attribute__(( section(".data") )) = 0;; + +//SMP lock to access the above variable +//smpguest x86svm +u32 g_svm_lock_quiesce __attribute__(( section(".data") )) = 1; + +//resume signal, becomes 1 to signal resume after quiescing +//smpguest x86svm +u32 g_svm_quiesce_resume_signal __attribute__(( section(".data") )) = 0; + +//SMP lock to access the above variable +//smpguest x86svm +u32 g_svm_lock_quiesce_resume_signal __attribute__(( section(".data") )) = 1; + + +//4k buffer which is the virtual LAPIC page that guest reads and writes from/to +//during INIT-SIPI-SIPI emulation +//smpguest x86svm +u8 g_svm_virtual_LAPIC_base[PAGE_SIZE_4K] __attribute__(( section(".bss.palign_data") )); + +//SVM SIPI page buffers used for guest INIT-SIPI-SIPI emulation +//smpguest x86svm +u8 g_svm_sipi_page_buffers[PAGE_SIZE_4K * MAX_VCPU_ENTRIES]__attribute__(( section(".bss.palign_data") )); diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-smpguest/arch/x86/svm/smpg-x86svm.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-smpguest/arch/x86/svm/smpg-x86svm.c new file mode 100644 index 0000000000..f43259d072 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-smpguest/arch/x86/svm/smpg-x86svm.c @@ -0,0 +1,647 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// smpg-x86svm - EMHF SMP guest component x86 (SVM) backend +// implementation +// author: amit vasudevan (amitvasudevan@acm.org) +#include + +//====================================================================== +//LOCALS +//the LAPIC register that is being accessed during emulation +static u32 g_svm_lapic_reg __attribute__(( section(".data") )) = 0; + +//the LAPIC operation that is being performed during emulation +static u32 g_svm_lapic_op __attribute__(( section(".data") )) = LAPIC_OP_RSVD; + + +//---------------------------------------------------------------------- +//svm_lapic_changemapping +//change LAPIC mappings to handle SMP guest bootup + +#define SVM_LAPIC_MAP ((u64)(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER)) +#define SVM_LAPIC_UNMAP 0 + +static void svm_lapic_changemapping(VCPU *vcpu, u32 lapic_paddr, u32 new_lapic_paddr, u64 mapflag){ +#ifndef __XMHF_VERIFICATION__ + u64 *pts; + u32 lapic_page; + + pts = (u64 *)vcpu->npt_vaddr_pts; + + lapic_page=lapic_paddr/PAGE_SIZE_4K; + pts[lapic_page] &= ~(u64)0xFFFFFFFFFFFFFFFFULL; + pts[lapic_page] |= pae_make_pte(new_lapic_paddr, mapflag); + + xmhf_memprot_arch_x86svm_flushmappings(vcpu); +#endif //__XMHF_VERIFICATION__ +} +//---------------------------------------------------------------------- + + +//------------------------------------------------------------------------------ +static inline void clgi(void){ + __asm__ __volatile__ ("clgi\r\n"); +} +static inline void stgi(void){ + __asm__ __volatile__ ("stgi\r\n"); +} + +//---checks if all logical cores have received SIPI +//returns 1 if yes, 0 if no +static u32 have_all_cores_recievedSIPI(void){ + u32 i; + VCPU *vcpu; + + //iterate through all logical processors in master-id table + for(i=0; i < g_midtable_numentries; i++){ + vcpu = (VCPU *)g_midtable[i].vcpu_vaddr_ptr; + if(vcpu->isbsp) + continue; //BSP does not receive SIPI + + if(!vcpu->sipireceived) + return 0; //one or more logical cores have not received SIPI + } + + return 1; //all logical cores have received SIPI +} + + +//---SIPI processing logic------------------------------------------------------ +//return 1 if lapic interception has to be discontinued, typically after +//all aps have received their SIPI, else 0 +static u32 processSIPI(VCPU *vcpu, u32 icr_low_value, u32 icr_high_value){ + //we assume that destination is always physical and + //specified via top 8 bits of icr_high_value + u32 dest_lapic_id; + VCPU *dest_vcpu = (VCPU *)0; + + HALT_ON_ERRORCOND( (icr_low_value & 0x000C0000) == 0x0 ); + + dest_lapic_id= icr_high_value >> 24; + + printf("\n%s: dest_lapic_id is 0x%02x", __FUNCTION__, dest_lapic_id); + + //find the vcpu entry of the core with dest_lapic_id + { + int i; + for(i=0; i < (int)g_midtable_numentries; i++){ + if(g_midtable[i].cpu_lapic_id == dest_lapic_id){ + dest_vcpu = (VCPU *)g_midtable[i].vcpu_vaddr_ptr; + HALT_ON_ERRORCOND( dest_vcpu->id == dest_lapic_id ); + break; + } + } + + HALT_ON_ERRORCOND( dest_vcpu != (VCPU *)0 ); + } + + printf("\nfound AP to pass SIPI to; id=0x%02x, vcpu=0x%08x", + dest_vcpu->id, (hva_t)dest_vcpu); + + + //send the sipireceived flag to trigger the AP to start the HVM + if(dest_vcpu->sipireceived){ + printf("\nCPU(0x%02x): destination CPU #0x%02x has already received SIPI, ignoring", vcpu->id, dest_vcpu->id); + }else{ + dest_vcpu->sipivector = (u8)icr_low_value; + dest_vcpu->sipireceived = 1; + printf("\nCPU(0x%02x): Sent SIPI command to AP, should awaken it!", + vcpu->id); + } + + if(have_all_cores_recievedSIPI()) + return 1; //all cores have received SIPI, we can discontinue LAPIC interception + else + return 0; //some cores are still to receive SIPI, continue LAPIC interception +} + + + + +//====================================================================== +//GLOBALS +void xmhf_smpguest_arch_x86svm_initialize(VCPU *vcpu){ + u32 eax, edx; + + //read APIC base address from MSR + rdmsr(MSR_APIC_BASE, &eax, &edx); + HALT_ON_ERRORCOND( edx == 0 ); //APIC is below 4G + + g_svm_lapic_base = eax & 0xFFFFF000UL; + printf("\nBSP(0x%02x): Local APIC base=0x%08x", vcpu->id, g_svm_lapic_base); + + //unmap LAPIC page + svm_lapic_changemapping(vcpu, g_svm_lapic_base, g_svm_lapic_base, SVM_LAPIC_UNMAP); +} + + +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + bool g_svm_lapic_npf_verification_guesttrapping = false; + bool g_svm_lapic_npf_verification_pre = false; +#endif + +//---------------------------------------------------------------------- +//xmhf_smpguest_arch_x86svm_eventhandler_hwpgtblviolation +//handle LAPIC accesses by the guest, used for SMP guest boot +u32 xmhf_smpguest_arch_x86svm_eventhandler_hwpgtblviolation(VCPU *vcpu, u32 paddr, u32 errorcode){ + struct _svm_vmcbfields *vmcb = (struct _svm_vmcbfields *)vcpu->vmcb_vaddr_ptr; + + //get LAPIC register being accessed + g_svm_lapic_reg = (paddr - g_svm_lapic_base); + +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + g_svm_lapic_npf_verification_pre = (errorcode & VMCB_NPT_ERRORCODE_RW) && + ((g_svm_lapic_reg == LAPIC_ICR_LOW) || (g_svm_lapic_reg == LAPIC_ICR_HIGH)); +#endif + + + if(errorcode & VMCB_NPT_ERRORCODE_RW){ //LAPIC write + if(g_svm_lapic_reg == LAPIC_ICR_LOW || g_svm_lapic_reg == LAPIC_ICR_HIGH ){ + g_svm_lapic_op = LAPIC_OP_WRITE; + svm_lapic_changemapping(vcpu, g_svm_lapic_base, hva2spa(g_svm_virtual_LAPIC_base), SVM_LAPIC_MAP); + }else{ + g_svm_lapic_op = LAPIC_OP_RSVD; + svm_lapic_changemapping(vcpu, g_svm_lapic_base, g_svm_lapic_base, SVM_LAPIC_MAP); + } + + //setup #DB intercept in vmcb + vmcb->exception_intercepts_bitmask |= (u32)EXCEPTION_INTERCEPT_DB; + + //set guest TF + vmcb->rflags |= (u64)EFLAGS_TF; + + #ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + g_svm_lapic_npf_verification_guesttrapping = true; + #endif + + //disable interrupts on this CPU until we get control in + //lapic_access_dbexception after a DB exception + clgi(); + + }else{ //LAPIC read + if(g_svm_lapic_reg == LAPIC_ICR_LOW || g_svm_lapic_reg == LAPIC_ICR_HIGH ){ + g_svm_lapic_op = LAPIC_OP_READ; + svm_lapic_changemapping(vcpu, g_svm_lapic_base, hva2spa(g_svm_virtual_LAPIC_base), SVM_LAPIC_MAP); + }else{ + g_svm_lapic_op = LAPIC_OP_RSVD; + svm_lapic_changemapping(vcpu, g_svm_lapic_base, g_svm_lapic_base, SVM_LAPIC_MAP); + } + + //setup #DB intercept in vmcb + vmcb->exception_intercepts_bitmask |= (u32)EXCEPTION_INTERCEPT_DB; + + //set guest TF + vmcb->rflags |= (u64)EFLAGS_TF; + + #ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + g_svm_lapic_npf_verification_guesttrapping = true; + #endif + + //disable interrupts on this CPU until we get control in + //lapic_access_dbexception after a DB exception + clgi(); + } + +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + assert(!g_svm_lapic_npf_verification_pre || g_svm_lapic_npf_verification_guesttrapping); +#endif + +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + assert ( ((g_svm_lapic_op == LAPIC_OP_RSVD) || + (g_svm_lapic_op == LAPIC_OP_READ) || + (g_svm_lapic_op == LAPIC_OP_WRITE)) + ); + + assert ( ((g_svm_lapic_reg >= 0) && + (g_svm_lapic_reg < PAGE_SIZE_4K)) + ); +#endif + + return 0; // XXX TODO: currently meaningless +} + +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + bool g_svm_lapic_db_verification_coreprotected = false; + bool g_svm_lapic_db_verification_pre = false; +#endif + + + +//------------------------------------------------------------------------------ +//xmhf_smpguest_arch_x86svm_eventhandler_dbexception +//handle instruction that performed the LAPIC operation + +void xmhf_smpguest_arch_x86svm_eventhandler_dbexception(VCPU *vcpu, struct regs *r){ + struct _svm_vmcbfields *vmcb = (struct _svm_vmcbfields *)vcpu->vmcb_vaddr_ptr; + u32 delink_lapic_interception=0; + + (void)r; + +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + //this handler relies on two global symbols apart from the parameters, set them + //to non-deterministic values with correct range + //note: LAPIC #npf handler ensures this at runtime + g_svm_lapic_op = (nondet_u32() % 3) + 1; + g_svm_lapic_reg = (nondet_u32() % PAGE_SIZE_4K); +#endif + + + if(g_svm_lapic_op == LAPIC_OP_WRITE){ //LAPIC write + hva_t src_registeraddress, dst_registeraddress; + uintptr_t value_tobe_written; + + HALT_ON_ERRORCOND( (g_svm_lapic_reg == LAPIC_ICR_LOW) || (g_svm_lapic_reg == LAPIC_ICR_HIGH) ); + + src_registeraddress = (hva_t)g_svm_virtual_LAPIC_base + g_svm_lapic_reg; + dst_registeraddress = (hva_t)g_svm_lapic_base + g_svm_lapic_reg; + + +#ifdef __XMHF_VERIFICATION__ + //TODO: hardware modeling + value_tobe_written= nondet_u32(); + + #ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + g_svm_lapic_db_verification_pre = (g_svm_lapic_op == LAPIC_OP_WRITE) && + (g_svm_lapic_reg == LAPIC_ICR_LOW) && + (((value_tobe_written & 0x00000F00) == 0x500) || ( (value_tobe_written & 0x00000F00) == 0x600 )); + #endif + +#else + value_tobe_written= *((uintptr_t *)src_registeraddress); +#endif + + if(g_svm_lapic_reg == LAPIC_ICR_LOW){ + if ( (value_tobe_written & 0x00000F00) == 0x500){ + //this is an INIT IPI, we just void it + printf("\n0x%04x:0x%08x -> (ICR=0x%08x write) INIT IPI detected and skipped, value=0x%08x", + (u16)vmcb->cs.selector, (u32)vmcb->rip, g_svm_lapic_reg, value_tobe_written); + #ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + g_svm_lapic_db_verification_coreprotected = true; + #endif + + }else if( (value_tobe_written & 0x00000F00) == 0x600 ){ + //this is a STARTUP IPI + u32 icr_value_high = *((u32 *)((hva_t)g_svm_virtual_LAPIC_base + (u32)LAPIC_ICR_HIGH)); + printf("\n0x%04x:0x%08x -> (ICR=0x%08x write) STARTUP IPI detected, value=0x%08x", + (u16)vmcb->cs.selector, (u32)vmcb->rip, g_svm_lapic_reg, value_tobe_written); + #ifdef __XMHF_VERIFICATION__ + #ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + g_svm_lapic_db_verification_coreprotected = true; + #endif + #else + delink_lapic_interception=processSIPI(vcpu, value_tobe_written, icr_value_high); + #endif + }else{ + //neither an INIT or SIPI, just propagate this IPI to physical LAPIC + #ifndef __XMHF_VERIFICATION__ + *((uintptr_t *)dst_registeraddress) = value_tobe_written; + #endif //TODO: hardware modeling + } + }else{ + #ifndef __XMHF_VERIFICATION__ + *((uintptr_t *)dst_registeraddress) = value_tobe_written; + #endif //TODO: hardware modeling + } + + }else if( g_svm_lapic_op == LAPIC_OP_READ){ //LAPIC read + hva_t src_registeraddress; + u32 value_read __attribute__((unused)); + HALT_ON_ERRORCOND( (g_svm_lapic_reg == LAPIC_ICR_LOW) || (g_svm_lapic_reg == LAPIC_ICR_HIGH) ); + + src_registeraddress = (hva_t)g_svm_virtual_LAPIC_base + g_svm_lapic_reg; + + //TODO: hardware modeling + #ifndef __XMHF_VERIFICATION__ + value_read = *((u32 *)src_registeraddress); + #else + value_read = nondet_u32(); + #endif + + } + + //clear #DB intercept in VMCB + vmcb->exception_intercepts_bitmask &= ~(u32)EXCEPTION_INTERCEPT_DB; + + //clear guest TF + vmcb->rflags &= ~(u64)EFLAGS_TF; + + //remove LAPIC interception if all cores have booted up + if(delink_lapic_interception){ + printf("\n%s: delinking LAPIC interception since all cores have SIPI", __FUNCTION__); + svm_lapic_changemapping(vcpu, g_svm_lapic_base, g_svm_lapic_base, SVM_LAPIC_MAP); + }else{ + svm_lapic_changemapping(vcpu, g_svm_lapic_base, g_svm_lapic_base, SVM_LAPIC_UNMAP); + } + + //enable interrupts on this CPU + stgi(); + +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + assert(!g_svm_lapic_db_verification_pre || g_svm_lapic_db_verification_coreprotected); +#endif + +} + +//---------------------------------------------------------------------- +//Queiscing interfaces +//---------------------------------------------------------------------- + +static void _svm_send_quiesce_signal(VCPU __attribute__((unused)) *vcpu, struct _svm_vmcbfields __attribute__((unused)) *vmcb){ + volatile u32 *icr_low = (u32 *)(0xFEE00000 + 0x300); + volatile u32 *icr_high = (u32 *)(0xFEE00000 + 0x310); + u32 icr_high_value= 0xFFUL << 24; + u32 prev_icr_high_value; + u32 delivered; + + prev_icr_high_value = *icr_high; + + *icr_high = icr_high_value; //send to all but self + //printf("\n%s: CPU(0x%02x): firing NMIs...", __FUNCTION__, vcpu->id); + *icr_low = 0x000C0400UL; //send NMI + + //check if IPI has been delivered successfully +#ifndef __XMHF_VERIFICATION__ + do{ + delivered = *icr_high; + delivered &= 0x00001000; + }while(delivered); +#else + //TODO: plug in h/w model of LAPIC, for now assume hardware just + //works +#endif + + + //restore icr high + *icr_high = prev_icr_high_value; + + //printf("\n%s: CPU(0x%02x): NMIs fired!", __FUNCTION__, vcpu->id); +} + + +//quiesce interface to switch all guest cores into hypervisor mode +void xmhf_smpguest_arch_x86svm_quiesce(VCPU *vcpu){ + struct _svm_vmcbfields *vmcb = (struct _svm_vmcbfields *)vcpu->vmcb_vaddr_ptr; + + //printf("\nCPU(0x%02x): got quiesce signal...", vcpu->id); + //grab hold of quiesce lock + spin_lock(&g_svm_lock_quiesce); + //printf("\nCPU(0x%02x): grabbed quiesce lock.", vcpu->id); + + vcpu->quiesced = 1; + + spin_lock(&g_svm_lock_quiesce_counter); + g_svm_quiesce_counter=0; + spin_unlock(&g_svm_lock_quiesce_counter); + + //send all the other CPUs the quiesce signal + g_svm_quiesce=1; //we are now processing quiesce + _svm_send_quiesce_signal(vcpu, vmcb); + + //wait for all the remaining CPUs to quiesce + //printf("\nCPU(0x%02x): waiting for other CPUs to respond...", vcpu->id); + while(g_svm_quiesce_counter < (g_midtable_numentries-1) ); + //printf("\nCPU(0x%02x): all CPUs quiesced successfully.", vcpu->id); +} + +//endquiesce interface to resume all guest cores after a quiesce +void xmhf_smpguest_arch_x86svm_endquiesce(VCPU __attribute__((unused)) *vcpu){ + //set resume signal to resume the cores that are quiesced + //Note: we do not need a spinlock for this since we are in any + //case the only core active until this point + g_svm_quiesce_resume_counter=0; + //printf("\nCPU(0x%02x): waiting for other CPUs to resume...", vcpu->id); + g_svm_quiesce_resume_signal=1; + + while(g_svm_quiesce_resume_counter < (g_midtable_numentries-1) ); + + vcpu->quiesced = 0; + g_svm_quiesce=0; // we are out of quiesce at this point + + + //printf("\nCPU(0x%02x): all CPUs resumed successfully.", vcpu->id); + + //reset resume signal + spin_lock(&g_svm_lock_quiesce_resume_signal); + g_svm_quiesce_resume_signal=0; + spin_unlock(&g_svm_lock_quiesce_resume_signal); + + //release quiesce lock + //printf("\nCPU(0x%02x): releasing quiesce lock.", vcpu->id); + spin_unlock(&g_svm_lock_quiesce); +} + +//quiescing handler for #NMI (non-maskable interrupt) exception event +//this function executes atomically. i.e., other NMIs (if any) are +//held pending by the platform until we return +void xmhf_smpguest_arch_x86svm_eventhandler_nmiexception(VCPU *vcpu, struct regs *r){ + struct _svm_vmcbfields *vmcb = (struct _svm_vmcbfields *)vcpu->vmcb_vaddr_ptr; + u32 nmiinhvm; //1 if NMI was triggered while in hypervisor, 0 if it was triggered in guest + (void)r; + + + nmiinhvm = (vmcb->exitcode == SVM_VMEXIT_NMI) ? 0 : 1; + + //printf("\n%s[%02x]: nmiinhvm=%u, g_svm_quiesce=%u", __FUNCTION__, vcpu->id, + // nmiinhvm, g_svm_quiesce); + + + if(g_svm_quiesce){ //if g_svm_quiesce is 1 we process quiesce regardless of where NMI originated from + if(vcpu->quiesced) + return; + + vcpu->quiesced=1; + + //ok this NMI is because of g_svm_quiesce. note: g_svm_quiesce can be 1 and + //this could be a NMI for the guest. we have no way of distinguising + //this. however, since g_svm_quiesce=1, we can handle this NMI as a g_svm_quiesce NMI + //and rely on the platform h/w to reissue the NMI later + //printf("\nCPU(0x%02x): NMI for core g_svm_quiesce", vcpu->id); + //printf("\nCPU(0x%02x): CS:EIP=0x%04x:0x%08x", vcpu->id, (u16)vmcb->cs.selector, (u32)vmcb->rip); + + //printf("\nCPU(0x%02x): quiesced, updating counter. awaiting EOQ...", vcpu->id); + spin_lock(&g_svm_lock_quiesce_counter); + g_svm_quiesce_counter++; + spin_unlock(&g_svm_lock_quiesce_counter); + + while(!g_svm_quiesce_resume_signal); + //printf("\nCPU(0x%02x): EOQ received, resuming...", vcpu->id); + + spin_lock(&g_svm_lock_quiesce_resume_counter); + g_svm_quiesce_resume_counter++; + spin_unlock(&g_svm_lock_quiesce_resume_counter); + + //printf("\nCPU(0x%08x): Halting!", vcpu->id); + //HALT(); + vcpu->quiesced=0; + + }else{ + //we are not in quiesce + //inject the NMI if it was triggered in guest mode + + if(nmiinhvm){ + if(vmcb->exception_intercepts_bitmask & CPU_EXCEPTION_NMI){ + //TODO: hypapp has chosen to intercept NMI so callback + printf("%s[%02x]:NMI handler: hypapp intercepts NMI, ignoring for now", __FUNCTION__, vcpu->id); + + }else{ + printf("%s[%02x]:NMI handler: injecting NMI into guest", __FUNCTION__, vcpu->id); + vmcb->eventinj.vector=0; + vmcb->eventinj.type = EVENTINJ_TYPE_NMI; + vmcb->eventinj.ev=0; + vmcb->eventinj.v=1; + vmcb->eventinj.errorcode=0; + } + }else{ + printf("%s[%02x]:NMI handler: NMI in hypervisor, ignoring", __FUNCTION__, vcpu->id); + } + } + +} + +//---------------------------------------------------------------------- + + +//perform required setup after a guest awakens a new CPU +void xmhf_smpguest_arch_x86svm_postCPUwakeup(VCPU *vcpu){ + //setup guest CS and EIP as specified by the SIPI vector + struct _svm_vmcbfields *vmcb; + + vmcb = (struct _svm_vmcbfields *)vcpu->vmcb_vaddr_ptr; + vmcb->cs.selector = ((vcpu->sipivector * PAGE_SIZE_4K) >> 4); + vmcb->cs.base = (vcpu->sipivector * PAGE_SIZE_4K); + vmcb->rip = 0x0ULL; +} + +//walk guest page tables; returns pointer to corresponding guest physical address +//note: returns 0xFFFFFFFF if there is no mapping +u8 * xmhf_smpguest_arch_x86svm_walk_pagetables(VCPU *vcpu, u32 vaddr){ + struct _svm_vmcbfields *vmcb = (struct _svm_vmcbfields *)vcpu->vmcb_vaddr_ptr; + + if((u32)vmcb->cr4 & CR4_PAE ){ + //PAE paging used by guest + u32 kcr3 = (u32)vmcb->cr3; + u32 pdpt_index, pd_index, pt_index, offset; + u64 paddr; + pdpt_t kpdpt; + pdt_t kpd; + pt_t kpt; + u32 pdpt_entry, pd_entry, pt_entry; + uintptr_t tmp; + + // get fields from virtual addr + pdpt_index = pae_get_pdpt_index(vaddr); + pd_index = pae_get_pdt_index(vaddr); + pt_index = pae_get_pt_index(vaddr); + offset = pae_get_offset_4K_page(vaddr); + + //grab pdpt entry + tmp = pae_get_addr_from_32bit_cr3(kcr3); + kpdpt = (pdpt_t)((uintptr_t)tmp); + pdpt_entry = kpdpt[pdpt_index]; + + //grab pd entry + tmp = pae_get_addr_from_pdpe(pdpt_entry); + kpd = (pdt_t)((uintptr_t)tmp); + pd_entry = kpd[pd_index]; + + if ( (pd_entry & _PAGE_PSE) == 0 ) { + // grab pt entry + tmp = (uintptr_t)pae_get_addr_from_pde(pd_entry); + kpt = (pt_t)((uintptr_t)tmp); + pt_entry = kpt[pt_index]; + + // find physical page base addr from page table entry + paddr = (u64)pae_get_addr_from_pte(pt_entry) + offset; + } + else { // 2MB page + offset = pae_get_offset_big(vaddr); + paddr = (u64)pae_get_addr_from_pde_big(pd_entry); + paddr += (u64)offset; + } + + return (u8 *)(uintptr_t)paddr; + + }else{ + //non-PAE 2 level paging used by guest + u32 kcr3 = (u32)vmcb->cr3; + u32 pd_index, pt_index, offset; + u64 paddr; + npdt_t kpd; + npt_t kpt; + u32 pd_entry, pt_entry; + uintptr_t tmp; + + // get fields from virtual addr + pd_index = npae_get_pdt_index(vaddr); + pt_index = npae_get_pt_index(vaddr); + offset = npae_get_offset_4K_page(vaddr); + + // grab pd entry + tmp = npae_get_addr_from_32bit_cr3(kcr3); + kpd = (npdt_t)((uintptr_t)tmp); + pd_entry = kpd[pd_index]; + + if ( (pd_entry & _PAGE_PSE) == 0 ) { + // grab pt entry + tmp = (uintptr_t)npae_get_addr_from_pde(pd_entry); + kpt = (npt_t)((uintptr_t)tmp); + pt_entry = kpt[pt_index]; + + // find physical page base addr from page table entry + paddr = (u64)npae_get_addr_from_pte(pt_entry) + offset; + } + else { // 4MB page + offset = npae_get_offset_big(vaddr); + paddr = (u64)npae_get_addr_from_pde_big(pd_entry); + paddr += (u64)offset; + } + + return (u8 *)(uintptr_t)paddr; + } + + +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-smpguest/arch/x86/vmx/smpg-x86vmx-data.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-smpguest/arch/x86/vmx/smpg-x86vmx-data.c new file mode 100644 index 0000000000..3fd8297c9b --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-smpguest/arch/x86/vmx/smpg-x86vmx-data.c @@ -0,0 +1,99 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/** + * smpg-x86vmx-data.c + * EMHF SMP guest component x86 (VMX) backend data + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//the BSP LAPIC base address +//smpguest x86vmx +u32 g_vmx_lapic_base __attribute__(( section(".data") )) = 0; + +//4k buffer which is the virtual LAPIC page that guest reads and writes from/to +//during INIT-SIPI-SIPI emulation +//smpguest x86vmx +u8 g_vmx_virtual_LAPIC_base[PAGE_SIZE_4K] __attribute__(( section(".bss.palign_data") )); + +//the quiesce counter, all CPUs except for the one requesting the +//quiesce will increment this when they get their quiesce signal +//smpguest x86vmx +volatile u32 g_vmx_quiesce_counter __attribute__(( section(".data") )) = 0; + +//SMP lock to access the above variable +//smpguest x86vmx +volatile u32 g_vmx_lock_quiesce_counter __attribute__(( section(".data") )) = 1; + +//resume counter to rally all CPUs after resumption from quiesce +//smpguest x86vmx +volatile u32 g_vmx_quiesce_resume_counter __attribute__(( section(".data") )) = 0; + +//SMP lock to access the above variable +//smpguest x86vmx +volatile u32 g_vmx_lock_quiesce_resume_counter __attribute__(( section(".data") )) = 1; + +//the "quiesce" variable, if 1, then we have a quiesce in process +//smpguest x86vmx +volatile u32 g_vmx_quiesce __attribute__(( section(".data") )) = 0;; + +//SMP lock to access the above variable +//smpguest x86vmx +volatile u32 g_vmx_lock_quiesce __attribute__(( section(".data") )) = 1; + +//resume signal, becomes 1 to signal resume after quiescing +//smpguest x86vmx +volatile u32 g_vmx_quiesce_resume_signal __attribute__(( section(".data") )) = 0; + +//SMP lock to access the above variable +//smpguest x86vmx +volatile u32 g_vmx_lock_quiesce_resume_signal __attribute__(( section(".data") )) = 1; + +//Flush all EPT TLB on all cores +//smpguest x86vmx +volatile u32 g_vmx_flush_all_tlb_signal __attribute__(( section(".data") )) = 0; diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-smpguest/arch/x86/vmx/smpg-x86vmx.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-smpguest/arch/x86/vmx/smpg-x86vmx.c new file mode 100644 index 0000000000..02fb5cdee7 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-smpguest/arch/x86/vmx/smpg-x86vmx.c @@ -0,0 +1,839 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// smpg-x86vmx - EMHF SMP guest component x86 (VMX) backend +// implementation +// author: amit vasudevan (amitvasudevan@acm.org) +#include + +//the LAPIC register that is being accessed during emulation +static u32 g_vmx_lapic_reg __attribute__(( section(".data") )) = 0; + +//the LAPIC operation that is being performed during emulation +static u32 g_vmx_lapic_op __attribute__(( section(".data") )) = LAPIC_OP_RSVD; + +//guest TF and IF bit values during LAPIC emulation +static u32 g_vmx_lapic_guest_eflags_tfifmask __attribute__(( section(".data") )) = 0; + +//guest "Blocking by NMI" bit in Interruptibility State, for LAPIC interception +static u32 g_vmx_lapic_guest_intr_nmimask __attribute__(( section(".data") )) = 0; + +//guest exception bitmap during LAPIC emulation +static u32 g_vmx_lapic_exception_bitmap __attribute__(( section(".data") )) = 0; + +/* + * xmhf_smpguest_arch_x86vmx_quiesce() needs to access printf locks defined + * in xmhfc-putchar.c + */ +extern void *emhfc_putchar_linelock_arg; +extern void emhfc_putchar_linelock(void *arg); +extern void emhfc_putchar_lineunlock(void *arg); + +//---------------------------------------------------------------------- +//vmx_lapic_changemapping +//change LAPIC mappings to handle SMP guest bootup + +#define VMX_LAPIC_MAP ((u64)EPT_PROT_READ | (u64)EPT_PROT_WRITE) +#define VMX_LAPIC_UNMAP 0 + +static void vmx_lapic_changemapping(VCPU *vcpu, u32 lapic_paddr, u32 new_lapic_paddr, u64 mapflag){ +#ifndef __XMHF_VERIFICATION__ + u64 *pts; + u32 lapic_page; + u64 value; + + pts = (u64 *)vcpu->vmx_vaddr_ept_p_tables; + lapic_page=lapic_paddr/PAGE_SIZE_4K; + value = (u64)new_lapic_paddr | mapflag; + + pts[lapic_page] = value; + + xmhf_memprot_arch_x86vmx_flushmappings(vcpu); +#endif //__XMHF_VERIFICATION__ +} +//---------------------------------------------------------------------- + + +//---checks if all logical cores have received SIPI +//returns 1 if yes, 0 if no +static u32 have_all_cores_recievedSIPI(void){ + u32 i; + VCPU *vcpu; + + //iterate through all logical processors in master-id table + for(i=0; i < g_midtable_numentries; i++){ + vcpu = (VCPU *)g_midtable[i].vcpu_vaddr_ptr; + if(vcpu->isbsp) + continue; //BSP does not receive SIPI + + if(!vcpu->sipireceived) + return 0; //one or more logical cores have not received SIPI + } + + return 1; //all logical cores have received SIPI +} + +//---SIPI processing logic------------------------------------------------------ +//return 1 if lapic interception has to be discontinued, typically after +//all aps have received their SIPI, else 0 +static u32 processSIPI(VCPU *vcpu, u32 icr_low_value, u32 icr_high_value){ + //we assume that destination is always physical and + //specified via top 8 bits of icr_high_value + u32 dest_lapic_id; + VCPU *dest_vcpu = (VCPU *)0; + + HALT_ON_ERRORCOND( (icr_low_value & 0x000C0000) == 0x0 ); + + dest_lapic_id= icr_high_value >> 24; + + printf("\nCPU(0x%02x): %s, dest_lapic_id is 0x%02x", + vcpu->id, __FUNCTION__, dest_lapic_id); + + //find the vcpu entry of the core with dest_lapic_id + { + int i; + for(i=0; i < (int)g_midtable_numentries; i++){ + if(g_midtable[i].cpu_lapic_id == dest_lapic_id){ + dest_vcpu = (VCPU *)g_midtable[i].vcpu_vaddr_ptr; + HALT_ON_ERRORCOND( dest_vcpu->id == dest_lapic_id ); + break; + } + } + + HALT_ON_ERRORCOND( dest_vcpu != (VCPU *)0 ); + } + + printf("\nCPU(0x%02x): found AP to pass SIPI; id=0x%02x, vcpu=0x%08x", + vcpu->id, dest_vcpu->id, (uintptr_t)dest_vcpu); + + + //send the sipireceived flag to trigger the AP to start the HVM + if(dest_vcpu->sipireceived){ + printf("\nCPU(0x%02x): destination CPU #0x%02x has already received SIPI, ignoring", vcpu->id, dest_vcpu->id); + }else{ + dest_vcpu->sipivector = (u8)icr_low_value; + dest_vcpu->sipireceived = 1; + printf("\nCPU(0x%02x): Sent SIPI command to AP, should awaken it!", + vcpu->id); + } + + if(have_all_cores_recievedSIPI()) + return 1; //all cores have received SIPI, we can discontinue LAPIC interception + else + return 0; //some cores are still to receive SIPI, continue LAPIC interception +} + + + +//---------------------------------------------------------------------- +//xmhf_smpguest_arch_x86vmx_initialize +//initialize LAPIC interception machinery +//note: called from the BSP +// If more than 1 CPU will be used, set unmaplapic to 1. APIC will be mapped +// When all APs receive SIPI. Otherwise, set unmaplapic to 0 so that APIC will +// not be unmapped. +void xmhf_smpguest_arch_x86vmx_initialize(VCPU *vcpu, u32 unmaplapic){ + u32 eax, edx; + + //read LAPIC base address from MSR + rdmsr(MSR_APIC_BASE, &eax, &edx); + HALT_ON_ERRORCOND( edx == 0 ); //APIC should be below 4G + + g_vmx_lapic_base = eax & 0xFFFFF000UL; + //printf("\nBSP(0x%02x): LAPIC base=0x%08x", vcpu->id, g_vmx_lapic_base); + + if (unmaplapic) { + //unmap LAPIC page + vmx_lapic_changemapping(vcpu, g_vmx_lapic_base, g_vmx_lapic_base, VMX_LAPIC_UNMAP); + } +} +//---------------------------------------------------------------------- + + + + + +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + bool g_vmx_lapic_npf_verification_guesttrapping = false; + bool g_vmx_lapic_npf_verification_pre = false; +#endif +//---------------------------------------------------------------------- +//xmhf_smpguest_arch_x86vmx_eventhandler_hwpgtblviolation +//handle LAPIC accesses by the guest, used for SMP guest boot +u32 xmhf_smpguest_arch_x86vmx_eventhandler_hwpgtblviolation(VCPU *vcpu, u32 paddr, u32 errorcode){ + + //get LAPIC register being accessed + g_vmx_lapic_reg = (paddr - g_vmx_lapic_base); + +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + g_vmx_lapic_npf_verification_pre = (errorcode & EPT_ERRORCODE_WRITE) && + ((g_vmx_lapic_reg == LAPIC_ICR_LOW) || (g_vmx_lapic_reg == LAPIC_ICR_HIGH)); +#endif + + + if(errorcode & EPT_ERRORCODE_WRITE){ //LAPIC write + + if(g_vmx_lapic_reg == LAPIC_ICR_LOW || g_vmx_lapic_reg == LAPIC_ICR_HIGH ){ + g_vmx_lapic_op = LAPIC_OP_WRITE; + vmx_lapic_changemapping(vcpu, g_vmx_lapic_base, hva2spa(&g_vmx_virtual_LAPIC_base), VMX_LAPIC_MAP); + }else{ + g_vmx_lapic_op = LAPIC_OP_RSVD; + vmx_lapic_changemapping(vcpu, g_vmx_lapic_base, g_vmx_lapic_base, VMX_LAPIC_MAP); + } + + }else{ //LAPIC read + if(g_vmx_lapic_reg == LAPIC_ICR_LOW || g_vmx_lapic_reg == LAPIC_ICR_HIGH ){ + g_vmx_lapic_op = LAPIC_OP_READ; + vmx_lapic_changemapping(vcpu, g_vmx_lapic_base, hva2spa(&g_vmx_virtual_LAPIC_base), VMX_LAPIC_MAP); + }else{ + g_vmx_lapic_op = LAPIC_OP_RSVD; + vmx_lapic_changemapping(vcpu, g_vmx_lapic_base, g_vmx_lapic_base, VMX_LAPIC_MAP); + } + } + + //save guest IF and TF masks + g_vmx_lapic_guest_eflags_tfifmask = (u32)vcpu->vmcs.guest_RFLAGS & ((u32)EFLAGS_IF | (u32)EFLAGS_TF); + + //set guest TF + vcpu->vmcs.guest_RFLAGS |= EFLAGS_TF; + + #ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + g_vmx_lapic_npf_verification_guesttrapping = true; + #endif + + //disable interrupts by clearing guest IF on this CPU until we get + //control in lapic_access_dbexception after a DB exception + vcpu->vmcs.guest_RFLAGS &= ~(EFLAGS_IF); + + //disable NMIs + g_vmx_lapic_guest_intr_nmimask = vcpu->vmcs.guest_interruptibility & (1U << 3); + vcpu->vmcs.guest_interruptibility |= (1U << 3); + + //intercept all exceptions (XMHF will panic if the guest's APIC access resuls + //in an exception) + g_vmx_lapic_exception_bitmap = vcpu->vmcs.control_exception_bitmap; + vcpu->vmcs.control_exception_bitmap = 0xffffffff; + +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + assert(!g_vmx_lapic_npf_verification_pre || g_vmx_lapic_npf_verification_guesttrapping); +#endif + +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + assert ( ((g_vmx_lapic_op == LAPIC_OP_RSVD) || + (g_vmx_lapic_op == LAPIC_OP_READ) || + (g_vmx_lapic_op == LAPIC_OP_WRITE)) + ); + + assert ( ((g_vmx_lapic_reg >= 0) && + (g_vmx_lapic_reg < PAGE_SIZE_4K)) + ); +#endif + + return 0; // TODO: currently meaningless +} +//---------------------------------------------------------------------- + + + +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + bool g_vmx_lapic_db_verification_coreprotected = false; + bool g_vmx_lapic_db_verification_pre = false; +#endif +//------------------------------------------------------------------------------ +//xmhf_smpguest_arch_x86vmx_eventhandler_dbexception +//handle instruction that performed the LAPIC operation +void xmhf_smpguest_arch_x86vmx_eventhandler_dbexception(VCPU *vcpu, struct regs *r){ + u32 delink_lapic_interception=0; + + (void)r; + +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + //this handler relies on two global symbols apart from the parameters, set them + //to non-deterministic values with correct range + //note: LAPIC #npf handler ensures this at runtime + g_vmx_lapic_op = (nondet_u32() % 3) + 1; + g_vmx_lapic_reg = (nondet_u32() % PAGE_SIZE_4K); +#endif + + + if(g_vmx_lapic_op == LAPIC_OP_WRITE){ //LAPIC write + hva_t src_registeraddress, dst_registeraddress; + u32 value_tobe_written; + + HALT_ON_ERRORCOND( (g_vmx_lapic_reg == LAPIC_ICR_LOW) || (g_vmx_lapic_reg == LAPIC_ICR_HIGH) ); + + src_registeraddress = (hva_t)&g_vmx_virtual_LAPIC_base + g_vmx_lapic_reg; + dst_registeraddress = (hva_t)g_vmx_lapic_base + g_vmx_lapic_reg; + + #ifdef __XMHF_VERIFICATION__ + //TODO: hardware modeling + value_tobe_written= nondet_u32(); + #ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + g_vmx_lapic_db_verification_pre = (g_vmx_lapic_op == LAPIC_OP_WRITE) && + (g_vmx_lapic_reg == LAPIC_ICR_LOW) && + (((value_tobe_written & 0x00000F00) == 0x500) || ( (value_tobe_written & 0x00000F00) == 0x600 )); + #endif + + #else + value_tobe_written= *((uintptr_t *)src_registeraddress); + #endif + + + if(g_vmx_lapic_reg == LAPIC_ICR_LOW){ + if ( (value_tobe_written & 0x00000F00) == 0x500){ + //this is an INIT IPI, we just void it + printf("\n0x%04x:0x%08x -> (ICR=0x%08x write) INIT IPI detected and skipped, value=0x%08x", + (u16)vcpu->vmcs.guest_CS_selector, (u32)vcpu->vmcs.guest_RIP, g_vmx_lapic_reg, value_tobe_written); + #ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + g_vmx_lapic_db_verification_coreprotected = true; + #endif + + }else if( (value_tobe_written & 0x00000F00) == 0x600 ){ + //this is a STARTUP IPI + u32 icr_value_high = *((u32 *)((hva_t)&g_vmx_virtual_LAPIC_base + (u32)LAPIC_ICR_HIGH)); + printf("\n0x%04x:0x%08x -> (ICR=0x%08x write) STARTUP IPI detected, value=0x%08x", + (u16)vcpu->vmcs.guest_CS_selector, (u32)vcpu->vmcs.guest_RIP, g_vmx_lapic_reg, value_tobe_written); + + #ifdef __XMHF_VERIFICATION__ + #ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + g_vmx_lapic_db_verification_coreprotected = true; + #endif + #else + delink_lapic_interception=processSIPI(vcpu, value_tobe_written, icr_value_high); + #endif + }else{ + #ifndef __XMHF_VERIFICATION__ + //neither an INIT or SIPI, just propagate this IPI to physical LAPIC + *((u32 *)dst_registeraddress) = value_tobe_written; + #endif //TODO: hardware modeling + } + }else{ + #ifndef __XMHF_VERIFICATION__ + *((u32 *)dst_registeraddress) = value_tobe_written; + #endif //TODO: hardware modeling + } + + }else if( g_vmx_lapic_op == LAPIC_OP_READ){ //LAPIC read + hva_t src_registeraddress; + u32 value_read __attribute__((unused)); + HALT_ON_ERRORCOND( (g_vmx_lapic_reg == LAPIC_ICR_LOW) || (g_vmx_lapic_reg == LAPIC_ICR_HIGH) ); + + src_registeraddress = (hva_t)&g_vmx_virtual_LAPIC_base + g_vmx_lapic_reg; + + //TODO: hardware modeling + #ifndef __XMHF_VERIFICATION__ + value_read = *((u32 *)src_registeraddress); + #else + value_read = nondet_u32(); + #endif + } + + //remove LAPIC interception if all cores have booted up + if(delink_lapic_interception){ + printf("\n%s: delinking LAPIC interception since all cores have SIPI", __FUNCTION__); + vmx_lapic_changemapping(vcpu, g_vmx_lapic_base, g_vmx_lapic_base, VMX_LAPIC_MAP); + }else{ + vmx_lapic_changemapping(vcpu, g_vmx_lapic_base, g_vmx_lapic_base, VMX_LAPIC_UNMAP); + } + + //restore guest IF and TF + vcpu->vmcs.guest_RFLAGS &= ~(EFLAGS_IF); + vcpu->vmcs.guest_RFLAGS &= ~(EFLAGS_TF); + vcpu->vmcs.guest_RFLAGS |= g_vmx_lapic_guest_eflags_tfifmask; + + //restore NMI blocking (likely enable NMIs) + vcpu->vmcs.guest_interruptibility |= g_vmx_lapic_guest_intr_nmimask; + + //restore exception bitmap + vcpu->vmcs.control_exception_bitmap = g_vmx_lapic_exception_bitmap; + +#ifdef __XMHF_VERIFICATION_DRIVEASSERTS__ + assert(!g_vmx_lapic_db_verification_pre || g_vmx_lapic_db_verification_coreprotected); +#endif + +} + +/* + * This function is called by WRMSR interception where ECX=0x830. Return 1 if + * smpguest handles this WRMSR. Return 0 if smpguest does not recognize it + * (should forward the write to physical x2APIC). + */ +int xmhf_smpguest_arch_x86vmx_eventhandler_x2apic_icrwrite(VCPU *vcpu, struct regs *r){ + switch (r->eax & 0x00000F00) { + case 0x500: + /* INIT IPI, we just void it */ + printf("\n0x%04x:0x%08llx -> (x2APIC ICR write) INIT IPI skipped, EAX=0x%08x, EDX=0x%08x", + (u16)vcpu->vmcs.guest_CS_selector, vcpu->vmcs.guest_RIP, r->eax, r->edx); + return 1; + case 0x600: + /* STARTUP IPI */ + printf("\n0x%04x:0x%08llx -> (x2APIC ICR write) STARTUP IPI detected, EAX=0x%08x, EDX=0x%08x", + (u16)vcpu->vmcs.guest_CS_selector, vcpu->vmcs.guest_RIP, r->eax, r->edx); + /* + * In LAPIC, the destination field is bit 56-63. In x2APIC is 32-63. + * As a workaround, we simply left shift the destination field in + * x2APIC. The disadvantage is that this only supports 256 LAPIC IDs. + */ + HALT_ON_ERRORCOND(r->edx <= 0xff); + if (processSIPI(vcpu, r->eax, (r->edx << 24))) { + /* + * Ideally the guest should only be using x2APIC and not APIC. + * But we nevertheless delink LAPIC interception. + */ + printf("\n%s: delinking LAPIC interception since all cores have SIPI", __FUNCTION__); + vmx_lapic_changemapping(vcpu, g_vmx_lapic_base, g_vmx_lapic_base, VMX_LAPIC_MAP); + } + return 1; + default: + return 0; + } +} + +//---------------------------------------------------------------------- + + +//---------------------------------------------------------------------- +//Queiscing interfaces +//---------------------------------------------------------------------- + +static void _vmx_send_quiesce_signal(VCPU __attribute__((unused)) *vcpu){ + u32 eax, edx; + + /* Check whether x2APIC is enabled */ + rdmsr(MSR_APIC_BASE, &eax, &edx); + + if (eax & (1U << 10)) { + /* x2APIC enabled, use it */ + u32 eax = 0x000C0400UL; + u32 edx = 0xFFFFFFFFUL; + u32 send_pending; + wrmsr(IA32_X2APIC_ICR, eax, edx); + do { + rdmsr(IA32_X2APIC_ICR, &eax, &edx); + send_pending = eax & 0x00001000U; + } while (send_pending); + } else { + /* use LAPIC */ + volatile u32 *icr_low = (u32 *)(0xFEE00000 + 0x300); + volatile u32 *icr_high = (u32 *)(0xFEE00000 + 0x310); + u32 icr_high_value= 0xFFUL << 24; + u32 prev_icr_high_value; + u32 delivered; + + prev_icr_high_value = *icr_high; + + *icr_high = icr_high_value; //send to all but self + *icr_low = 0x000C0400UL; //send NMI + + //check if IPI has been delivered successfully + //printf("\n%s: CPU(0x%02x): firing NMIs...", __FUNCTION__, vcpu->id); +#ifndef __XMHF_VERIFICATION__ + do { + // TODO: should this be icr_low? + delivered = *icr_high; + delivered &= 0x00001000; + } while (delivered); +#else + //TODO: plug in h/w model of LAPIC, for now assume hardware just + //works +#endif + + //restore icr high + *icr_high = prev_icr_high_value; + } + + //printf("\n%s: CPU(0x%02x): NMIs fired!", __FUNCTION__, vcpu->id); +} + +/* Unblock NMI by executing iret, but do not jump to somewhere else */ +void xmhf_smpguest_arch_x86vmx_unblock_nmi(void) { +#ifdef __AMD64__ + asm volatile ( + "movq %%rsp, %%rsi \r\n" + "xorq %%rax, %%rax \r\n" + "movw %%ss, %%ax \r\n" + "pushq %%rax \r\n" + "pushq %%rsi \r\n" + "pushfq \r\n" + "xorq %%rax, %%rax \r\n" + "movw %%cs, %%ax \r\n" + "pushq %%rax \r\n" + "pushq $1f \r\n" + "iretq \r\n" + "1: nop \r\n" + : // no output + : // no input + : "%rax", "%rsi", "cc", "memory"); +#elif defined(__I386__) + asm volatile ( + "pushfl \r\n" + "xorl %%eax, %%eax \r\n" + "movw %%cs, %%ax \r\n" + "pushl %%eax \r\n" + "pushl $1f \r\n" + "iretl \r\n" + "1: nop \r\n" + : // no output + : // no input + : "%eax", "cc", "memory"); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +} + +//quiesce interface to switch all guest cores into hypervisor mode +//note: we are in atomic processsing mode for this "vcpu" +void xmhf_smpguest_arch_x86vmx_quiesce(VCPU *vcpu){ + + //printf("\nCPU(0x%02x): got quiesce signal...", vcpu->id); + //grab hold of quiesce lock + spin_lock(&g_vmx_lock_quiesce); + //printf("\nCPU(0x%02x): grabbed quiesce lock.", vcpu->id); + + /* Acquire the printf lock to prevent deadlock */ + emhfc_putchar_linelock(emhfc_putchar_linelock_arg); + + vcpu->quiesced = 1; + //reset quiesce counter + spin_lock(&g_vmx_lock_quiesce_counter); + g_vmx_quiesce_counter=0; + spin_unlock(&g_vmx_lock_quiesce_counter); + + //send all the other CPUs the quiesce signal + g_vmx_quiesce=1; //we are now processing quiesce + _vmx_send_quiesce_signal(vcpu); + + //wait for all the remaining CPUs to quiesce + //printf("\nCPU(0x%02x): waiting for other CPUs to respond...", vcpu->id); + while(g_vmx_quiesce_counter < (g_midtable_numentries-1) ); + //printf("\nCPU(0x%02x): all CPUs quiesced successfully.", vcpu->id); + + /* + * Release the printf lock to allow printing things after this function + * returns. + * + * This unlock can be placed either before the while loop for + * g_vmx_quiesce_counter or after. + * If unlock after waiting for g_vmx_quiesce_counter, will deadlock if + * NMI handling code in other CPUs calls printf. + * If unlock before waiting for g_vmx_quiesce_counter, will deadlock + * when the other CPUs acquire the lock, and then interrupted by NMI. + * + * So in production, should place this unlock after waiting for + * g_vmx_quiesce_counter. While debugging, if need to use printf in + * NMI handling code, can change the while loop to release printf lock + * after a large number of iterations. + */ + emhfc_putchar_lineunlock(emhfc_putchar_linelock_arg); + +} + +void xmhf_smpguest_arch_x86vmx_endquiesce(VCPU *vcpu){ + + /* + * g_vmx_quiesce=0 must be before g_vmx_quiesce_resume_signal=1, + * otherwise if another CPU enters NMI exception handler again, + * a deadlock may occur. + */ + g_vmx_quiesce=0; // we are out of quiesce at this point + + //set resume signal to resume the cores that are quiesced + //Note: we do not need a spinlock for this since we are in any + //case the only core active until this point + g_vmx_quiesce_resume_counter=0; + //printf("\nCPU(0x%02x): waiting for other CPUs to resume...", vcpu->id); + g_vmx_quiesce_resume_signal=1; + + while(g_vmx_quiesce_resume_counter < (g_midtable_numentries-1) ); + + vcpu->quiesced=0; + + //printf("\nCPU(0x%02x): all CPUs resumed successfully.", vcpu->id); + + //reset resume signal + spin_lock(&g_vmx_lock_quiesce_resume_signal); + g_vmx_quiesce_resume_signal=0; + spin_unlock(&g_vmx_lock_quiesce_resume_signal); + + // Reset flush all TLB signal + if(g_vmx_flush_all_tlb_signal) + g_vmx_flush_all_tlb_signal = 0; + + //release quiesce lock + //printf("\nCPU(0x%02x): releasing quiesce lock.", vcpu->id); + spin_unlock(&g_vmx_lock_quiesce); + +} + +//quiescing handler for #NMI (non-maskable interrupt) exception event +//note: we are in atomic processsing mode for this "vcpu" +// from_guest: 1 if NMI originated from the HVM (i.e. caller is intercept handler), +// otherwise 0 (within the hypervisor, i.e. caller is exception handler) +void xmhf_smpguest_arch_x86vmx_eventhandler_nmiexception(VCPU *vcpu, struct regs *r, u32 from_guest){ + (void)r; + + /* + * If g_vmx_quiesce = 1, process quiesce regardless of where NMI originated + * from. + * + * If vcpu->quiesced = 1 (i.e. this core has been quiesced), simply return. + * This can only happen for the CPU calling + * xmhf_smpguest_arch_x86vmx_quiesce(). For other CPUs, NMIs are + * blocked during the time where vcpu->quiesced = 1. + */ + /* + * Issue 1: If two cores request CPU quiescing at the same time, will an NMI be incorrectly injected to guest? + * Issue 2: Will it be simpler to use an exception (e.g., one reserved exception in 22-27, see https://wiki.osdev.org/Exceptions) + * instead of NMI? + * Issue 3: The function always inject NMI to the *current* guest, not the *correct* guest. Will it cause problem? For + * example, NMIs may be injected to PALs, not the red OS. + * Issue 4: If we decide (1) not using NMI for CPU quiescing, and (2) the function always inject NMI to the current guest + * for simplicity, then TrustVisor must be modified to inject NMI to the red OS. + * Issue 5: Will the "__control_VMX_cpu_based" code in and + * virtual NMI VMExit mismatch when there are multiple guests/domains? In other words, they are reading/writing different VMCS. + */ + + // The function handles NMI as follows: + // (1) If XMHF on core i requests quiesce and the current core is not quiesced yet, XMHF must quiesce the current core + // (2) If XMHF on core i requests quiesce and the current core is quiesced, then some device must issue NMI after core i + // requesting quiesce. This NMI should be injected to a guest. XMHF currently injects NMI to the trapped guest. + // - [TODO] XMHF should query hypapp to find out which guest should receive this NMI + // (3) If no one requests quiesce and the current core receives NMI, then it should be injected to the trapped guest. + if(g_vmx_quiesce && !vcpu->quiesced){ + vcpu->quiesced=1; + + //increment quiesce counter + spin_lock(&g_vmx_lock_quiesce_counter); + g_vmx_quiesce_counter++; + spin_unlock(&g_vmx_lock_quiesce_counter); + + //wait until quiesceing is finished + //printf("\nCPU(0x%02x): Quiesced", vcpu->id); + while(!g_vmx_quiesce_resume_signal); + //printf("\nCPU(0x%02x): EOQ received, resuming...", vcpu->id); + + // Flush EPT TLB, if instructed so + if(g_vmx_flush_all_tlb_signal) + xmhf_memprot_flushmappings_localtlb(vcpu); + + spin_lock(&g_vmx_lock_quiesce_resume_counter); + g_vmx_quiesce_resume_counter++; + spin_unlock(&g_vmx_lock_quiesce_resume_counter); + + vcpu->quiesced=0; + }else{ + //we are not in quiesce, inject the NMI to guest + + /* + * We want to set vcpu->vmcs.control_VMX_cpu_based, but we may be in an + * exception handler that is interrupting an intercept handler using + * vcpu->vmcs.control_VMX_cpu_based. This can cause race conditions. + * + * We know that this function only wants to set the 22nd bit of + * vcpu->vmcs.control_VMX_cpu_based. + * + * We observe that the intercept handlers are always having the + * following logic: + * 1. VMREAD reg + * 2. vcpu->vmcs.control_VMX_cpu_based = reg + * 3. update vcpu->vmcs.control_VMX_cpu_based + * 4. reg = vcpu->vmcs.control_VMX_cpu_based + * 5. VMWRITE reg + * + * Step 1 and 2 are in xmhf_baseplatform_arch_x86vmx_getVMCS(). Step + * 3 is body of the intercept handler. Step 4 and 5 are in + * xmhf_baseplatform_arch_x86vmx_putVMCS(). + * + * To solve the problem, this function also sets + * vcpu->vmx_guest_inject_nmi. After step 5, + * xmhf_baseplatform_arch_x86vmx_putVMCS() checks whether + * vcpu->vmx_guest_inject_nmi is set. If so, it will perform another + * VMWRITE. + * + * So the updated logic of intercept handlers become + * 1. vcpu->vmx_guest_inject_nmi = 0 + * 2. VMREAD reg + * 3. vcpu->vmcs.control_VMX_cpu_based = reg + * 4. Update vcpu->vmcs.control_VMX_cpu_based + * 5. reg = vcpu->vmcs.control_VMX_cpu_based + * 6. VMWRITE reg + * 7. if (vcpu->vmx_guest_inject_nmi) { + * 8. VMREAD reg + * 9. set bit 22 of reg + * 10. VMWRITE reg + * 11.} + * + * The logic of this function is (appears atomic) + * 1. VMREAD reg + * 2. set bit 22 of reg + * 3. VMWRITE reg + * 4. vcpu->vmx_guest_inject_nmi = 1 + * + * Consider different places this function interleaves with the + * intercept handler: + * a. before step 2: VMREAD at step 2 gets updated value, good + * b. between 2 - 6: VMREAD at step 2 gets old value, this function + * writes new value, then overwritten by VMWRITE at step 6. But the + * vmx_guest_inject_nmi flag bit will cause the intercept handler to + * set the bit in VMCS correctly. + * c. between 6 - 7: this function will read the new value, good. + * then step 7 will set bit 22 again, but it does not affect + * correctness. + * d. after step 7: the bit 22 will finally be set, and the change to + * the VMCS field made by the intercept handle is always preserved. + */ + //printf("\nCPU(0x%02x): Regular NMI, injecting back to guest...", vcpu->id); + // TODO: if hypapp has multiple VMCS, need to select which one to inject + /* Cannot be u32 in amd64, because VMREAD writes 64-bits */ + unsigned long __control_VMX_cpu_based; + HALT_ON_ERRORCOND(__vmx_vmread(0x4002, &__control_VMX_cpu_based)); + __control_VMX_cpu_based |= (1U << 22); + HALT_ON_ERRORCOND(__vmx_vmwrite(0x4002, __control_VMX_cpu_based)); + vcpu->vmx_guest_inject_nmi = 1; + } + + /* Unblock NMI in hypervisor */ + if (from_guest) { + xmhf_smpguest_arch_x86vmx_unblock_nmi(); + } +} + +//---------------------------------------------------------------------- + + +//perform required setup after a guest awakens a new CPU +void xmhf_smpguest_arch_x86vmx_postCPUwakeup(VCPU *vcpu){ + //setup guest CS and EIP as specified by the SIPI vector + vcpu->vmcs.guest_CS_selector = ((vcpu->sipivector * PAGE_SIZE_4K) >> 4); + vcpu->vmcs.guest_CS_base = (vcpu->sipivector * PAGE_SIZE_4K); + vcpu->vmcs.guest_RIP = 0x0ULL; +} + +//walk guest page tables; returns pointer to corresponding guest physical address +//note: returns 0xFFFFFFFF if there is no mapping +u8 * xmhf_smpguest_arch_x86vmx_walk_pagetables(VCPU *vcpu, u32 vaddr){ + if((u32)vcpu->vmcs.guest_CR4 & CR4_PAE ){ + //PAE paging used by guest + u32 kcr3 = (u32)vcpu->vmcs.guest_CR3; + u32 pdpt_index, pd_index, pt_index, offset; + u64 paddr; + pdpt_t kpdpt; + pdt_t kpd; + pt_t kpt; + u32 pdpt_entry, pd_entry, pt_entry; + uintptr_t tmp; + + // get fields from virtual addr + pdpt_index = pae_get_pdpt_index(vaddr); + pd_index = pae_get_pdt_index(vaddr); + pt_index = pae_get_pt_index(vaddr); + offset = pae_get_offset_4K_page(vaddr); + + //grab pdpt entry + tmp = pae_get_addr_from_32bit_cr3(kcr3); + kpdpt = (pdpt_t)((uintptr_t)tmp); + pdpt_entry = kpdpt[pdpt_index]; + + //grab pd entry + tmp = pae_get_addr_from_pdpe(pdpt_entry); + kpd = (pdt_t)((uintptr_t)tmp); + pd_entry = kpd[pd_index]; + + if ( (pd_entry & _PAGE_PSE) == 0 ) { + // grab pt entry + tmp = (uintptr_t)pae_get_addr_from_pde(pd_entry); + kpt = (pt_t)((uintptr_t)tmp); + pt_entry = kpt[pt_index]; + + // find physical page base addr from page table entry + paddr = (u64)pae_get_addr_from_pte(pt_entry) + offset; + } + else { // 2MB page + offset = pae_get_offset_big(vaddr); + paddr = (u64)pae_get_addr_from_pde_big(pd_entry); + paddr += (u64)offset; + } + + return (u8 *)(uintptr_t)paddr; + + }else{ + //non-PAE 2 level paging used by guest + u32 kcr3 = (u32)vcpu->vmcs.guest_CR3; + u32 pd_index, pt_index, offset; + u64 paddr; + npdt_t kpd; + npt_t kpt; + u32 pd_entry, pt_entry; + uintptr_t tmp; + + // get fields from virtual addr + pd_index = npae_get_pdt_index(vaddr); + pt_index = npae_get_pt_index(vaddr); + offset = npae_get_offset_4K_page(vaddr); + + // grab pd entry + tmp = npae_get_addr_from_32bit_cr3(kcr3); + kpd = (npdt_t)((uintptr_t)tmp); + pd_entry = kpd[pd_index]; + + if ( (pd_entry & _PAGE_PSE) == 0 ) { + // grab pt entry + tmp = (uintptr_t)npae_get_addr_from_pde(pd_entry); + kpt = (npt_t)((uintptr_t)tmp); + pt_entry = kpt[pt_index]; + + // find physical page base addr from page table entry + paddr = (u64)npae_get_addr_from_pte(pt_entry) + offset; + } + else { // 4MB page + offset = npae_get_offset_big(vaddr); + paddr = (u64)npae_get_addr_from_pde_big(pd_entry); + paddr += (u64)offset; + } + + return (u8 *)(uintptr_t)paddr; + } +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-smpguest/smpg-interface.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-smpguest/smpg-interface.c new file mode 100644 index 0000000000..1c451add76 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-smpguest/smpg-interface.c @@ -0,0 +1,86 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// EMHF symmetric multiprocessor (SMP) guest component +// implementation +// author: amit vasudevan (amitvasudevan@acm.org) + +#include + +// we implement the smp guest component in a way that if +// we run a uniprocessor guest then we can safely do away +// with this component + +// functions exported +// 1. g_isl->hvm_apic_setup(vcpu); //runtime +// 2. vmx/svm_lapic_access_handler(vcpu, gpa, errorcode); //eventhub +// 3. vmx/svm_lapic_access_dbexception(vcpu, r); //eventhub + + +//initialize SMP guest logic +void xmhf_smpguest_initialize(VCPU *vcpu){ + xmhf_smpguest_arch_initialize(vcpu); +} + + +//quiesce interface to switch all guest cores into hypervisor mode +static void xmhf_smpguest_quiesce(VCPU *vcpu) __attribute__((unused)); +static void xmhf_smpguest_quiesce(VCPU *vcpu){ + xmhf_smpguest_arch_quiesce(vcpu); +} + +//endquiesce interface to resume all guest cores after a quiesce +static void xmhf_smpguest_endquiesce(VCPU *vcpu) __attribute__((unused)); +static void xmhf_smpguest_endquiesce(VCPU *vcpu){ + xmhf_smpguest_arch_endquiesce(vcpu); +} + + +//walk guest page tables; returns pointer to corresponding guest physical address +//note: returns 0xFFFFFFFF if there is no mapping +u8 * xmhf_smpguest_walk_pagetables(VCPU *vcpu, u32 vaddr){ + return xmhf_smpguest_arch_walk_pagetables(vcpu, vaddr); +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-startup/Makefile b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-startup/Makefile new file mode 100644 index 0000000000..355b64db9a --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-startup/Makefile @@ -0,0 +1,14 @@ +# makefile for xmhf-startup component +# author: amit vasudevan (amitvasudevan@acm.org) + +# source files +AS_SOURCES = + +C_SOURCES = runtime.c +C_SOURCES += rntm-data.c + +C_SOURCES += ./arch/x86/rntm-x86-data.c + +# targets +include ../runtime.mk + diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-startup/arch/x86/rntm-x86-data.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-startup/arch/x86/rntm-x86-data.c new file mode 100644 index 0000000000..a715b03296 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-startup/arch/x86/rntm-x86-data.c @@ -0,0 +1,132 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/** + * rntm-x86-data.c + * EMHF runtime data definitions - x86 specific + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//runtime GDT +u64 x_gdt_start[] __attribute__(( section(".data"), aligned(16) )) = { +#ifdef __AMD64__ + 0x0000000000000000ULL, /* 0x00: NULL selector */ + 0x00af9a000000ffffULL, /* 0x08: 64-bit CODE selector */ + 0x00cf9a000000ffffULL, /* 0x10: 32-bit CODE selector */ + 0x00cf92000000ffffULL, /* 0x18: 32-bit DATA selector */ + 0x0000000000000000ULL, /* 0x20: TSS low (set by secure loader) */ + 0x0000000000000000ULL /* 0x28: TSS high (set by secure loader) */ +#elif defined(__I386__) + 0x0000000000000000ULL, + 0x00cf9a000000ffffULL, + 0x00cf92000000ffffULL, + 0x0000000000000000ULL +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ +}; + +//runtime GDT descriptor +arch_x86_gdtdesc_t x_gdt __attribute__(( section(".data"), aligned(16) )) = { + .size=sizeof(x_gdt_start)-1, + .base=(uintptr_t)&x_gdt_start, +}; + + +#ifdef __AMD64__ +// runtime 4-level page tables +u8 x_4level_pml4[P4L_NPLM4T * PAGE_SIZE_4K] __attribute__((section(".bss.palign_data"))); +u8 x_4level_pdpt[P4L_NPDPT * PAGE_SIZE_4K] __attribute__((section(".bss.palign_data"))); +u8 x_4level_pdt[P4L_NPDT * PAGE_SIZE_4K] __attribute__((section(".bss.palign_data"))); +#elif defined(__I386__) +//runtime PAE page tables +u8 x_3level_pdpt[PAGE_SIZE_4K] __attribute__(( section(".bss.palign_data") )); +u8 x_3level_pdt[PAE_PTRS_PER_PDPT * PAGE_SIZE_4K] __attribute__(( section(".bss.palign_data") )); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + +//runtime stack +u8 x_init_stack[RUNTIME_STACK_SIZE] __attribute__(( section(".bss.stack") )); + + +RPB arch_rpb __attribute__(( section(".s_rpb") )) = { + .magic= RUNTIME_PARAMETER_BLOCK_MAGIC, + .XtVmmEntryPoint= (hva_t)xmhf_runtime_entry, +#ifdef __AMD64__ + .XtVmmPml4Base= (hva_t)x_4level_pml4, + .XtVmmPdptBase= (hva_t)x_4level_pdpt, + .XtVmmPdtsBase= (hva_t)x_4level_pdt, +#elif defined(__I386__) + .XtVmmPdptBase= (hva_t)x_3level_pdpt, + .XtVmmPdtsBase= (hva_t)x_3level_pdt, +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + .XtGuestOSBootModuleBase= 0, + .XtGuestOSBootModuleSize= 0, + .runtime_appmodule_base= 0, + .runtime_appmodule_size= 0, + .XtGuestOSBootDrive = 0x80u, + .XtVmmStackBase= (hva_t)x_init_stack, + .XtVmmStackSize= 8192, + .XtVmmGdt= (hva_t)&x_gdt, + .XtVmmIdt= (hva_t)xmhf_xcphandler_idt, + .XtVmmIdtFunctionPointers= (hva_t)xmhf_xcphandler_exceptionstubs, + .XtVmmIdtEntries= 32, + .XtVmmRuntimePhysBase= 0, + .XtVmmRuntimeVirtBase= 0, + .XtVmmRuntimeSize= 0, + .XtVmmE820Buffer= (hva_t)g_e820map, + .XtVmmE820NumEntries= 0, + .XtVmmMPCpuinfoBuffer= (hva_t)g_cpumap, + .XtVmmMPCpuinfoNumEntries= 0, + .XtVmmTSSBase= (hva_t)g_runtime_TSS, + .RtmUartConfig = {0, 0, 0, 0, 0, 0, 0}, + .isEarlyInit=1, //1 for an "early init" else 0 (late-init) +}; diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-startup/rntm-data.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-startup/rntm-data.c new file mode 100644 index 0000000000..0326481e80 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-startup/rntm-data.c @@ -0,0 +1,68 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/** + * rntm-data.c + * EMHF runtime data definitions + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//runtime parameter block pointer +RPB *rpb __attribute__(( section(".data") )); + +//runtime DMA protection buffer +u8 g_rntm_dmaprot_buffer[SIZE_G_RNTM_DMAPROT_BUFFER] __attribute__(( section(".bss.palign_data") )); + +//variable that is incremented by 1 by all cores that cycle through appmain +//successfully, this should be finally equal to g_midtable_numentries at +//runtime which signifies that EMHF appmain executed successfully on all +//cores +u32 volatile g_appmain_success_counter __attribute__(( section(".data") )) = 0; + +//SMP lock for the above variable +u32 volatile g_lock_appmain_success_counter __attribute__(( section(".data") )) = 1; diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-startup/runtime.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-startup/runtime.c new file mode 100644 index 0000000000..0353a4b861 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-startup/runtime.c @@ -0,0 +1,308 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +// runtime.c +// author: amit vasudevan (amitvasudevan@acm.org) + +//---includes------------------------------------------------------------------- +#include + +#if defined(__DRT__) && !defined(__DMAP__) + +// This macro is defined in xmhf-dmaprot.h. However when !__DMAP__ this header +// is not included. So define it here. +#define ACPI_MAX_RSDT_ENTRIES (256) + +static void vmx_eap_zap(void) +{ + ACPI_RSDP rsdp; + ACPI_RSDT rsdt; + u32 num_rsdtentries; + uintptr_t rsdtentries[ACPI_MAX_RSDT_ENTRIES]; + uintptr_t status; + VTD_DMAR dmar; + u32 i, dmarfound; + spa_t dmaraddrphys, remappingstructuresaddrphys; + spa_t rsdt_xsdt_spaddr = INVALID_SPADDR; + hva_t rsdt_xsdt_vaddr = INVALID_VADDR; + + // zero out rsdp and rsdt structures + memset(&rsdp, 0, sizeof(ACPI_RSDP)); + memset(&rsdt, 0, sizeof(ACPI_RSDT)); + + // get ACPI RSDP + // [TODO] Unify the name of and , and then remove the following #ifdef + status = xmhf_baseplatform_arch_x86_acpi_getRSDP(&rsdp); + HALT_ON_ERRORCOND(status != 0); // we need a valid RSDP to proceed + printf("\n%s: RSDP at %08x", __FUNCTION__, status); + + // [Superymk] Use RSDT if it is ACPI v1, or use XSDT addr if it is ACPI v2 + if (rsdp.revision == 0) // ACPI v1 + { + printf("\n%s: ACPI v1", __FUNCTION__); + rsdt_xsdt_spaddr = rsdp.rsdtaddress; + } + else if (rsdp.revision == 0x2) // ACPI v2 + { + printf("\n%s: ACPI v2", __FUNCTION__); + rsdt_xsdt_spaddr = (spa_t)rsdp.xsdtaddress; + } + else // Unrecognized ACPI version + { + printf("\n%s: ACPI unsupported version!", __FUNCTION__); + return; + } + + // grab ACPI RSDT + // Note: in i386, should be in lower 4GB. So the conversion to vaddr is fine. + rsdt_xsdt_vaddr = (hva_t)rsdt_xsdt_spaddr; + + xmhf_baseplatform_arch_flat_copy((u8 *)&rsdt, (u8 *)rsdt_xsdt_vaddr, sizeof(ACPI_RSDT)); + printf("\n%s: RSDT at %08x, len=%u bytes, hdrlen=%u bytes", + __FUNCTION__, rsdt_xsdt_vaddr, rsdt.length, sizeof(ACPI_RSDT)); + + // get the RSDT entry list + num_rsdtentries = (rsdt.length - sizeof(ACPI_RSDT)) / sizeof(u32); + HALT_ON_ERRORCOND(num_rsdtentries < ACPI_MAX_RSDT_ENTRIES); + xmhf_baseplatform_arch_flat_copy((u8 *)&rsdtentries, (u8 *)(rsdt_xsdt_vaddr + sizeof(ACPI_RSDT)), + sizeof(u32) * num_rsdtentries); + printf("\n%s: RSDT entry list at %08x, len=%u", __FUNCTION__, + (rsdt_xsdt_vaddr + sizeof(ACPI_RSDT)), num_rsdtentries); + + // find the VT-d DMAR table in the list (if any) + for (i = 0; i < num_rsdtentries; i++) + { + xmhf_baseplatform_arch_flat_copy((u8 *)&dmar, (u8 *)rsdtentries[i], sizeof(VTD_DMAR)); + if (dmar.signature == VTD_DMAR_SIGNATURE) + { + dmarfound = 1; + break; + } + } + + // if no DMAR table, bail out + if (!dmarfound) + return; + + dmaraddrphys = rsdtentries[i]; // DMAR table physical memory address; + printf("\n%s: DMAR at %08x", __FUNCTION__, dmaraddrphys); + + i = 0; + remappingstructuresaddrphys = dmaraddrphys + sizeof(VTD_DMAR); + printf("\n%s: remapping structures at %08x", __FUNCTION__, remappingstructuresaddrphys); + + // zap VT-d presence in ACPI table... + // TODO: we need to be a little elegant here. eventually need to setup + // EPT/NPTs such that the DMAR pages are unmapped for the guest + xmhf_baseplatform_arch_flat_writeu32(dmaraddrphys, 0UL); + + // success + printf("\n%s: success, leaving...", __FUNCTION__); +} +#endif /* defined(__DRT__) && !defined(__DMAP__) */ + +//---runtime main--------------------------------------------------------------- +void xmhf_runtime_entry(void){ + u32 cpu_vendor; + + //get CPU vendor + cpu_vendor = xmhf_baseplatform_getcpuvendor(); + (void)cpu_vendor; + + //initialize Runtime Parameter Block (rpb) + rpb = (RPB *)&arch_rpb; + + //setup debugging + xmhf_debug_init((char *)&rpb->RtmUartConfig); + printf("\nruntime initializing..."); + + //initialize basic platform elements + xmhf_baseplatform_initialize(); + + //[debug] dump E820 and MP table + #ifndef __XMHF_VERIFICATION__ + printf("\nNumber of E820 entries = %u", rpb->XtVmmE820NumEntries); + { + int i; + for(i=0; i < (int)rpb->XtVmmE820NumEntries; i++){ + printf("\n0x%08x%08x, size=0x%08x%08x (%u)", + g_e820map[i].baseaddr_high, g_e820map[i].baseaddr_low, + g_e820map[i].length_high, g_e820map[i].length_low, + g_e820map[i].type); + } + } + printf("\nNumber of MP entries = %u", rpb->XtVmmMPCpuinfoNumEntries); + { + int i; + for(i=0; i < (int)rpb->XtVmmMPCpuinfoNumEntries; i++) + printf("\nCPU #%u: bsp=%u, lapic_id=0x%02x", i, g_cpumap[i].isbsp, g_cpumap[i].lapic_id); + } + #endif //__XMHF_VERIFICATION__ + + + #ifndef __XMHF_VERIFICATION__ + //setup EMHF exception handler component + xmhf_xcphandler_initialize(); + #endif + +#if defined (__DMAP__) + // TODO: DMAP code not ported to amd64 yet + { + #define ADDR_512GB (PAGE_SIZE_512G) + u64 protectedbuffer_paddr; + hva_t protectedbuffer_vaddr; + u32 protectedbuffer_size; + + protectedbuffer_paddr = hva2spa(&g_rntm_dmaprot_buffer); + protectedbuffer_vaddr = (hva_t)&g_rntm_dmaprot_buffer; + protectedbuffer_size = xmhf_dmaprot_getbuffersize(DMAPROT_PHY_ADDR_SPACE_SIZE); // ADDR_512GB + HALT_ON_ERRORCOND(protectedbuffer_size <= SIZE_G_RNTM_DMAPROT_BUFFER); + + printf("\nRuntime: Re-initializing DMA protection (physical address space size:0x%llX)...", DMAPROT_PHY_ADDR_SPACE_SIZE); + if(!xmhf_dmaprot_initialize(protectedbuffer_paddr, protectedbuffer_vaddr, protectedbuffer_size)){ + printf("\nRuntime: Unable to re-initialize DMA protection. HALT!"); + HALT(); + } + + //protect SL and runtime memory regions + xmhf_dmaprot_protect(rpb->XtVmmRuntimePhysBase - PAGE_SIZE_2M, rpb->XtVmmRuntimeSize+PAGE_SIZE_2M); + printf("\nRuntime: Protected SL+Runtime (%08lx-%08x) from DMA.", rpb->XtVmmRuntimePhysBase - PAGE_SIZE_2M, rpb->XtVmmRuntimePhysBase+rpb->XtVmmRuntimeSize); + } + +#else //!__DMAP__ + + #if defined (__DRT__) + //if __DRT__ is enabled without DMA protections, zap DMAR device + //from ACPI tables + if(cpu_vendor == CPU_VENDOR_INTEL){ + vmx_eap_zap(); + } + #endif //__DRT__ + +#endif + + //initialize base platform with SMP + xmhf_baseplatform_smpinitialize(); + + printf("\nRuntime: We should NEVER get here!"); + HALT_ON_ERRORCOND(0); +} + +//we get control here in the context of *each* physical CPU core +//vcpu->isbsp = 1 if the core is a BSP or 0 if its an AP +//isEarlyInit = 1 if we were boot-strapped by the BIOS and is 0 +//in the event we were launched from a running OS +void xmhf_runtime_main(VCPU *vcpu, u32 isEarlyInit){ + + //initialize CPU + xmhf_baseplatform_cpuinitialize(); + + //initialize partition monitor (i.e., hypervisor) for this CPU + xmhf_partition_initializemonitor(vcpu); + + //setup guest OS state for partition + xmhf_partition_setupguestOSstate(vcpu); + + //initialize memory protection for this core + xmhf_memprot_initialize(vcpu); + + //initialize application parameter block and call app main + { + APP_PARAM_BLOCK appParamBlock; + + appParamBlock.bootsector_ptr = rpb->XtGuestOSBootModuleBase; + appParamBlock.bootsector_size = rpb->XtGuestOSBootModuleSize; + appParamBlock.optionalmodule_ptr = rpb->runtime_appmodule_base; + appParamBlock.optionalmodule_size = rpb->runtime_appmodule_size; + appParamBlock.runtimephysmembase = rpb->XtVmmRuntimePhysBase; + appParamBlock.boot_drive = rpb->XtGuestOSBootDrive; + COMPILE_TIME_ASSERT(sizeof(appParamBlock.cmdline) >= sizeof(rpb->cmdline)); + #ifndef __XMHF_VERIFICATION__ + strncpy(appParamBlock.cmdline, rpb->cmdline, sizeof(appParamBlock.cmdline)); + #endif + + //call app main + if(xmhf_app_main(vcpu, &appParamBlock)){ + printf("\nCPU(0x%02x): EMHF app. failed to initialize. HALT!", vcpu->id); + HALT(); + } + } + +#ifndef __XMHF_VERIFICATION__ + //increment app main success counter + spin_lock(&g_lock_appmain_success_counter); + g_appmain_success_counter++; + spin_unlock(&g_lock_appmain_success_counter); + + //if BSP, wait for all cores to go through app main successfully + //TODO: conceal g_midtable_numentries behind interface + //xmhf_baseplatform_getnumberofcpus + if(vcpu->isbsp && (g_midtable_numentries > 1)){ + printf("\nCPU(0x%02x): Waiting for all cores to cycle through appmain...", vcpu->id); + while(g_appmain_success_counter < g_midtable_numentries); + printf("\nCPU(0x%02x): All cores have successfully been through appmain.", vcpu->id); + } +#endif + + //late initialization is still WiP and we can get only this far + //currently + if(!isEarlyInit){ + printf("\nCPU(0x%02x): Late-initialization, WiP, HALT!", vcpu->id); + HALT(); + } + +#ifndef __XMHF_VERIFICATION__ + //initialize support for SMP guests + xmhf_smpguest_initialize(vcpu); +#endif + + //start partition (guest) + printf("\n%s[%02x]: starting partition...", __FUNCTION__, vcpu->id); + xmhf_partition_start(vcpu); + + printf("\nCPU(0x%02x): FATAL, should not be here. HALTING!", vcpu->id); + HALT(); +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-tpm/Makefile b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-tpm/Makefile new file mode 100644 index 0000000000..c868b9af21 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-tpm/Makefile @@ -0,0 +1,18 @@ +# makefile for EMHF TPM component +# author: amit vasudevan (amitvasudevan@acm.org) + +# source files +AS_SOURCES = +C_SOURCES = tpm-interface.c +C_SOURCES += ./arch/x86/tpm-x86.c +C_SOURCES += ./arch/x86/svm/tpm-x86svm.c +C_SOURCES += ./arch/x86/vmx/tpm-x86vmx.c + +C_SOURCES_BL = tpm-interface.c +C_SOURCES_BL += ./arch/x86/tpm-x86.c +C_SOURCES_BL += ./arch/x86/svm/tpm-x86svm.c +C_SOURCES_BL += ./arch/x86/vmx/tpm-x86vmx.c + +# targets +include ../runtime.mk + diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-tpm/arch/x86/svm/tpm-x86svm.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-tpm/arch/x86/svm/tpm-x86svm.c new file mode 100644 index 0000000000..138220e5fe --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-tpm/arch/x86/svm/tpm-x86svm.c @@ -0,0 +1,68 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/** + * EMHF TPM component x86 SVM subarch. backend + * author: amit vasudevan (amitvasudevan@acm.org) and Jonathan M. McCune + */ + +#include + +//open TPM locality +int xmhf_tpm_arch_x86svm_open_locality(int locality){ + // some systems leave locality 0 open for legacy software + //dump_locality_access_regs(); + xmhf_tpm_arch_deactivate_all_localities(); + //dump_locality_access_regs(); + + if(TPM_SUCCESS == tpm_wait_cmd_ready(locality)) { + printf("\n%s: TPM successfully opened in Locality %d.", __FUNCTION__, locality); + return 0; + } else { + printf("\n%s: TPM ERROR: Locality %d could not be opened.\n", __FUNCTION__, locality); + return 1; + } +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-tpm/arch/x86/tpm-x86.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-tpm/arch/x86/tpm-x86.c new file mode 100644 index 0000000000..e9928e8d66 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-tpm/arch/x86/tpm-x86.c @@ -0,0 +1,624 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/** + * EMHF TPM component x86 arch. backend + * author: amit vasudevan (amitvasudevan@acm.org) and Jonathan M. McCune + */ + +#include + + +//====================================================================== +//static (local) decls./defns. +//====================================================================== + +static void cpu_relax(void){ + __asm__ __volatile__ ("pause"); +} + + +static void _read_tpm_reg(int locality, u32 reg, u8 *_raw, size_t size) +{ + size_t i; + for ( i = 0; i < size; i++ ) + _raw[i] = readb((TPM_LOCALITY_BASE_N(locality) | reg) + i); +} + +static void _write_tpm_reg(int locality, u32 reg, u8 *_raw, size_t size) +{ + size_t i; + for ( i = 0; i < size; i++ ) + writeb((TPM_LOCALITY_BASE_N(locality) | reg) + i, _raw[i]); +} + + +static tpm_timeout_t g_timeout = {TIMEOUT_A, + TIMEOUT_B, + TIMEOUT_C, + TIMEOUT_D}; + +static bool tpm_validate_locality(uint32_t locality) +{ + uint32_t i; + tpm_reg_access_t reg_acc; + + for ( i = TPM_VALIDATE_LOCALITY_TIME_OUT; i > 0; i-- ) { + /* + * TCG spec defines reg_acc.tpm_reg_valid_sts bit to indicate whether + * other bits of access reg are valid.( but this bit will also be 1 + * while this locality is not available, so check seize bit too) + * It also defines that reading reg_acc.seize should always return 0 + */ + read_tpm_reg(locality, TPM_REG_ACCESS, ®_acc); + if ( reg_acc.tpm_reg_valid_sts == 1 && reg_acc.seize == 0) + return true; + cpu_relax(); + } + + if ( i <= 0 ) + printf("\nTPM: tpm_validate_locality timeout\n"); + + return false; +} + +/* +static void dump_locality_access_regs(void) { + tpm_reg_access_t reg_acc; + uint32_t locality; + + printf("\n%s():\n", __FUNCTION__); + for(locality=0; locality <= 3; locality++) { + read_tpm_reg(locality, TPM_REG_ACCESS, ®_acc); + printf(" TPM: Locality %d Access reg content: 0x%02x\n", + locality, (uint32_t)reg_acc._raw[0]); + if ( reg_acc.tpm_reg_valid_sts == 0 ) { + printf(" TPM: Access reg not valid\n"); + } + } +}*/ + + + +static uint32_t tpm_get_flags(uint32_t locality, uint32_t flag_id, + uint8_t *flags, uint32_t flag_size) +{ + uint32_t ret, offset, resp_size; + uint8_t sub_cap[sizeof(flag_id)]; + tpm_structure_tag_t tag; + + if ( flags == NULL ) { + printf("TPM: tpm_get_flags() bad parameter\n"); + return TPM_BAD_PARAMETER; + } + + offset = 0; + UNLOAD_INTEGER(sub_cap, offset, flag_id); + + resp_size = flag_size; + ret = tpm_get_capability(locality, TPM_CAP_FLAG, sizeof(sub_cap), + sub_cap, &resp_size, flags); + +#ifdef TPM_TRACE + printf("TPM: get flags %08X, return value = %08X\n", flag_id, ret); +#endif + if ( ret != TPM_SUCCESS ) + return ret; + + /* 1.2 spec, main part 2, rev 103 add one more byte to permanent flags, to + be backward compatible, not assume all expected bytes can be gotten */ + if ( resp_size > flag_size ) { + printf("TPM: tpm_get_flags() response size too small\n"); + return TPM_FAIL; + } + + offset = 0; + LOAD_INTEGER(flags, offset, tag); + offset = 0; + UNLOAD_BLOB_TYPE(flags, offset, &tag); + + return ret; +} + + +static uint32_t tpm_get_timeout(uint32_t locality, + uint8_t *prop, uint32_t prop_size) +{ + uint32_t ret, offset, resp_size, prop_id = TPM_CAP_PROP_TIS_TIMEOUT; + uint8_t sub_cap[sizeof(prop_id)]; + uint32_t resp[4]; + + if ( (prop == NULL) || (prop_size < sizeof(resp)) ) { + printf("TPM: tpm_get_timeout() bad parameter\n"); + return TPM_BAD_PARAMETER; + } + + offset = 0; + UNLOAD_INTEGER(sub_cap, offset, prop_id); + + resp_size = prop_size; + ret = tpm_get_capability(locality, TPM_CAP_PROPERTY, sizeof(sub_cap), + sub_cap, &resp_size, prop); + +#ifdef TPM_TRACE + printf("TPM: get prop %08X, return value = %08X\n", prop_id, ret); +#endif + if ( ret != TPM_SUCCESS ) + return ret; + + if ( resp_size != prop_size ) { + printf("TPM: tpm_get_property() response size incorrect\n"); + return TPM_FAIL; + } + + offset = 0; + LOAD_INTEGER(prop, offset, resp); + offset = 0; + UNLOAD_BLOB_TYPE(prop, offset, &resp); + + return ret; +} + + +/* ensure TPM is ready to accept commands */ +static bool is_tpm_ready(uint32_t locality) +{ + tpm_permanent_flags_t pflags; + tpm_stclear_flags_t vflags; + uint32_t timeout[4]; + uint32_t ret; + + if ( !tpm_validate_locality(locality) ) { + printf("TPM is not available.\n"); + return false; + } + + /* make sure tpm is not disabled/deactivated */ + memset(&pflags, 0, sizeof(pflags)); + ret = tpm_get_flags(locality, TPM_CAP_FLAG_PERMANENT, + (uint8_t *)&pflags, sizeof(pflags)); + if ( ret != TPM_SUCCESS ) { + printf("TPM is disabled or deactivated.\n"); + return false; + } + if ( pflags.disable ) { + printf("TPM is disabled.\n"); + return false; + } + + memset(&vflags, 0, sizeof(vflags)); + ret = tpm_get_flags(locality, TPM_CAP_FLAG_VOLATILE, + (uint8_t *)&vflags, sizeof(vflags)); + if ( ret != TPM_SUCCESS ) { + printf("TPM is disabled or deactivated.\n"); + return false; + } + if ( vflags.deactivated ) { + printf("TPM is deactivated.\n"); + return false; + } + + printf("TPM is ready\n"); + printf("TPM nv_locked: %s\n", (pflags.nv_locked != 0) ? "TRUE" : "FALSE"); + + /* get tpm timeout values */ + ret = tpm_get_timeout(locality, (uint8_t *)&timeout, sizeof(timeout)); + if ( ret != TPM_SUCCESS ) + printf("TPM timeout values are not achieved, " + "default values will be used.\n"); + else { + /* + * timeout_x represents the number of milliseconds for the timeout + * and timeout[x] represents the number of microseconds. + */ + g_timeout.timeout_a = timeout[0]/1000; + g_timeout.timeout_b = timeout[1]/1000; + g_timeout.timeout_c = timeout[2]/1000; + g_timeout.timeout_d = timeout[3]/1000; + printf("TPM timeout values: A: %u, B: %u, C: %u, D: %u\n", + g_timeout.timeout_a, g_timeout.timeout_b, g_timeout.timeout_c, + g_timeout.timeout_d); + /* + * if any timeout values are less than default values, set to default + * value (due to bug with some TPMs) + */ + if ( g_timeout.timeout_a < TIMEOUT_A ) g_timeout.timeout_a = TIMEOUT_A; + if ( g_timeout.timeout_b < TIMEOUT_B ) g_timeout.timeout_b = TIMEOUT_B; + if ( g_timeout.timeout_c < TIMEOUT_C ) g_timeout.timeout_c = TIMEOUT_C; + if ( g_timeout.timeout_d < TIMEOUT_D ) g_timeout.timeout_d = TIMEOUT_D; + } + + return true; +} + + +static bool release_locality(uint32_t locality) +{ + uint32_t i; + tpm_reg_access_t reg_acc; +#ifdef TPM_TRACE + printf("TPM: releasing locality %u\n", locality); +#endif + + if ( !tpm_validate_locality(locality) ) + return true; + + read_tpm_reg(locality, TPM_REG_ACCESS, ®_acc); + if ( reg_acc.active_locality == 0 ) + return true; + + /* make inactive by writing a 1 */ + reg_acc._raw[0] = 0; + reg_acc.active_locality = 1; + write_tpm_reg(locality, TPM_REG_ACCESS, ®_acc); + + i = 0; + do { + read_tpm_reg(locality, TPM_REG_ACCESS, ®_acc); + if ( reg_acc.active_locality == 0 ) + return true; + else + cpu_relax(); + i++; + } while ( i <= TPM_ACTIVE_LOCALITY_TIME_OUT ); + + printf("TPM: access reg release locality timeout\n"); + return false; +} + +//====================================================================== +//ARCH. Backends +//====================================================================== + +//deactivate all TPM localities +void xmhf_tpm_arch_deactivate_all_localities(void) { + tpm_reg_access_t reg_acc; + uint32_t locality; + + printf("\nTPM: %s()\n", __FUNCTION__); + for(locality=0; locality <= 3; locality++) { + reg_acc._raw[0] = 0; + reg_acc.active_locality = 1; + write_tpm_reg(locality, TPM_REG_ACCESS, ®_acc); + } +} + + +//check if TPM is ready for use +bool xmhf_tpm_arch_is_tpm_ready(uint32_t locality){ + return is_tpm_ready(locality); +} + + +//open TPM locality +int xmhf_tpm_arch_open_locality(int locality){ + u32 cpu_vendor = get_cpu_vendor_or_die(); + + if(cpu_vendor == CPU_VENDOR_INTEL) { + return xmhf_tpm_arch_x86vmx_open_locality(locality); + + } else { /* AMD */ + return xmhf_tpm_arch_x86svm_open_locality(locality); + } +} + +//prepare TPM for use +bool xmhf_tpm_arch_prepare_tpm(void){ + /* + * must ensure TPM_ACCESS_0.activeLocality bit is clear + * (: locality is not active) + */ + + return release_locality(0); +} + + + +//====================================================================== +// libtpm environment specific function definitions +//====================================================================== + + +uint32_t tpm_wait_cmd_ready(uint32_t locality) +{ + uint32_t i; + tpm_reg_access_t reg_acc; + tpm_reg_sts_t reg_sts; + +/* //temporary debug prints */ +/* dump_locality_access_regs(); */ +/* deactivate_all_localities(); */ +/* dump_locality_access_regs(); */ + + /* ensure the contents of the ACCESS register are valid */ + read_tpm_reg(locality, TPM_REG_ACCESS, ®_acc); +#ifdef TPM_TRACE + printf("\nTPM: Access reg content: 0x%02x\n", (uint32_t)reg_acc._raw[0]); +#endif + if ( reg_acc.tpm_reg_valid_sts == 0 ) { + printf("TPM: Access reg not valid\n"); + return TPM_FAIL; + } + + /* request access to the TPM from locality N */ + reg_acc._raw[0] = 0; + reg_acc.request_use = 1; + write_tpm_reg(locality, TPM_REG_ACCESS, ®_acc); + + i = 0; + do { + read_tpm_reg(locality, TPM_REG_ACCESS, ®_acc); + if ( reg_acc.active_locality == 1 ) + break; + else + cpu_relax(); + i++; + } while ( i <= TPM_ACTIVE_LOCALITY_TIME_OUT); + + if ( i > TPM_ACTIVE_LOCALITY_TIME_OUT ) { + printf("TPM: access reg request use timeout (i=%d)\n", i); + return TPM_FAIL; + } + + /* ensure the TPM is ready to accept a command */ +#ifdef TPM_TRACE + printf("TPM: wait for cmd ready "); +#endif + i = 0; + do { + /* write 1 to TPM_STS_x.commandReady to let TPM enter ready state */ + memset((void *)®_sts, 0, sizeof(reg_sts)); + reg_sts.command_ready = 1; + write_tpm_reg(locality, TPM_REG_STS, ®_sts); + cpu_relax(); + + /* then see if it has */ + read_tpm_reg(locality, TPM_REG_STS, ®_sts); +#ifdef TPM_TRACE + printf("."); +#endif + if ( reg_sts.command_ready == 1 ) + break; + else + cpu_relax(); + i++; + } while ( i <= TPM_CMD_READY_TIME_OUT ); +#ifdef TPM_TRACE + printf("\n"); +#endif + + if ( i > TPM_CMD_READY_TIME_OUT ) { + printf("TPM: status reg content: %02x %02x %02x\n", + (uint32_t)reg_sts._raw[0], + (uint32_t)reg_sts._raw[1], + (uint32_t)reg_sts._raw[2]); + printf("TPM: tpm timeout for command_ready\n"); + goto RelinquishControl; + } + return TPM_SUCCESS; + +RelinquishControl: + /* deactivate current locality */ + reg_acc._raw[0] = 0; + reg_acc.active_locality = 1; + write_tpm_reg(locality, TPM_REG_ACCESS, ®_acc); + + return TPM_FAIL; +} + +/* + * locality : TPM locality (0 - 3) + * in : All bytes for a single TPM command, including TAG, SIZE, + * ORDINAL, and other arguments. All data should be in big-endian + * style. The in MUST NOT be NULL, containing at least 10 bytes. + * 0 1 2 3 4 5 6 7 8 9 10 ... + * ------------------------------------------------------------- + * | TAG | SIZE | ORDINAL | arguments ... + * ------------------------------------------------------------- + * in_size : The size of the whole command contained within the in buffer. + * It should equal to the SIZE contained in the in buffer. + * out : All bytes of the TPM response to a single command. All data + * within it will be in big-endian style. The out MUST not be + * NULL, and will return at least 10 bytes. + * 0 1 2 3 4 5 6 7 8 9 10 ... + * ------------------------------------------------------------- + * | TAG | SIZE | RETURN CODE | other data ... + * ------------------------------------------------------------- + * out_size : In/out paramter. As in, it is the size of the out buffer; + * as out, it is the size of the response within the out buffer. + * The out_size MUST NOT be NULL. + * return : 0 = success; if not 0, it equal to the RETURN CODE in out buf. + */ + +uint32_t tpm_write_cmd_fifo(uint32_t locality, uint8_t *in, + uint32_t in_size, uint8_t *out, + uint32_t *out_size) +{ + uint32_t i, rsp_size, offset, ret; + uint16_t row_size; + tpm_reg_access_t reg_acc; + tpm_reg_sts_t reg_sts; + + if ( locality >= TPM_NR_LOCALITIES ) { + printf("TPM: Invalid locality for tpm_write_cmd_fifo()\n"); + return TPM_BAD_PARAMETER; + } + if ( in == NULL || out == NULL || out_size == NULL ) { + printf("TPM: Invalid parameter for tpm_write_cmd_fifo()\n"); + return TPM_BAD_PARAMETER; + } + if ( in_size < CMD_HEAD_SIZE || *out_size < RSP_HEAD_SIZE ) { + printf("TPM: in/out buf size must be larger than 10 bytes\n"); + return TPM_BAD_PARAMETER; + } + + if ( !tpm_validate_locality(locality) ) { + printf("TPM: Locality %d is not open\n", locality); + return TPM_FAIL; + } + + ret = tpm_wait_cmd_ready(locality); + if ( ret != TPM_SUCCESS ) + return ret; + +#ifdef TPM_TRACE + { + printf("TPM: cmd size = %d\nTPM: cmd content: ", in_size); + print_hex("TPM: \t", in, in_size); + } +#endif + + /* write the command to the TPM FIFO */ + offset = 0; + do { + i = 0; + do { + read_tpm_reg(locality, TPM_REG_STS, ®_sts); + /* find out how many bytes the TPM can accept in a row */ + row_size = reg_sts.burst_count; + if ( row_size > 0 ) + break; + else + cpu_relax(); + i++; + } while ( i <= TPM_CMD_WRITE_TIME_OUT ); + if ( i > TPM_CMD_WRITE_TIME_OUT ) { + printf("TPM: write cmd timeout\n"); + ret = TPM_FAIL; + goto RelinquishControl; + } + + for ( ; row_size > 0 && offset < in_size; row_size--, offset++ ) + write_tpm_reg(locality, TPM_REG_DATA_FIFO, + (tpm_reg_data_fifo_t *)&in[offset]); + } while ( offset < in_size ); + + /* command has been written to the TPM, it is time to execute it. */ + memset(®_sts, 0, sizeof(reg_sts)); + reg_sts.tpm_go = 1; + write_tpm_reg(locality, TPM_REG_STS, ®_sts); + + /* check for data available */ + i = 0; + do { + read_tpm_reg(locality,TPM_REG_STS, ®_sts); + if ( reg_sts.sts_valid == 1 && reg_sts.data_avail == 1 ) + break; + else + cpu_relax(); + i++; + } while ( i <= TPM_DATA_AVAIL_TIME_OUT ); + if ( i > TPM_DATA_AVAIL_TIME_OUT ) { + printf("TPM: wait for data available timeout\n"); + ret = TPM_FAIL; + goto RelinquishControl; + } + + rsp_size = 0; + offset = 0; + do { + /* find out how many bytes the TPM returned in a row */ + i = 0; + do { + read_tpm_reg(locality, TPM_REG_STS, ®_sts); + row_size = reg_sts.burst_count; + if ( row_size > 0 ) + break; + else + cpu_relax(); + i++; + } while ( i <= TPM_RSP_READ_TIME_OUT ); + if ( i > TPM_RSP_READ_TIME_OUT ) { + printf("TPM: read rsp timeout\n"); + ret = TPM_FAIL; + goto RelinquishControl; + } + + for ( ; row_size > 0 && offset < *out_size; row_size--, offset++ ) { + if ( offset < *out_size ) + read_tpm_reg(locality, TPM_REG_DATA_FIFO, + (tpm_reg_data_fifo_t *)&out[offset]); + else { + /* discard the responded bytes exceeding out buf size */ + tpm_reg_data_fifo_t discard; + read_tpm_reg(locality, TPM_REG_DATA_FIFO, + (tpm_reg_data_fifo_t *)&discard); + } + + /* get outgoing data size */ + if ( offset == RSP_RST_OFFSET - 1 ) { + reverse_copy(&rsp_size, &out[RSP_SIZE_OFFSET], + sizeof(rsp_size)); + } + } + } while ( offset < RSP_RST_OFFSET || + (offset < rsp_size && offset < *out_size) ); + + *out_size = (*out_size > rsp_size) ? rsp_size : *out_size; + + /* out buffer contains the complete outgoing data, get return code */ + reverse_copy(&ret, &out[RSP_RST_OFFSET], sizeof(ret)); + +#ifdef TPM_TRACE + { + printf("TPM: response size = %d\n", *out_size); + printf("TPM: response content: "); + print_hex("TPM: \t", out, *out_size); + } +#endif + + memset(®_sts, 0, sizeof(reg_sts)); + reg_sts.command_ready = 1; + write_tpm_reg(locality, TPM_REG_STS, ®_sts); + +RelinquishControl: + /* deactivate current locality */ + reg_acc._raw[0] = 0; + reg_acc.active_locality = 1; + write_tpm_reg(locality, TPM_REG_ACCESS, ®_acc); + + return ret; +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-tpm/arch/x86/vmx/tpm-x86vmx.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-tpm/arch/x86/vmx/tpm-x86vmx.c new file mode 100644 index 0000000000..47c8ef4e01 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-tpm/arch/x86/vmx/tpm-x86vmx.c @@ -0,0 +1,78 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/** + * EMHF TPM component x86 VMX subarch. backend + * author: amit vasudevan (amitvasudevan@acm.org) and Jonathan M. McCune + */ + +#include + +//open TPM locality +int xmhf_tpm_arch_x86vmx_open_locality(int locality){ + txt_didvid_t didvid; + txt_ver_fsbif_emif_t ver; + + // display chipset fuse and device and vendor id info + didvid._raw = read_pub_config_reg(TXTCR_DIDVID); + printf("\n%s: chipset ids: vendor: 0x%x, device: 0x%x, revision: 0x%x", __FUNCTION__, + didvid.vendor_id, didvid.device_id, didvid.revision_id); + ver._raw = read_pub_config_reg(TXTCR_VER_FSBIF); + if ( (ver._raw & 0xffffffff) == 0xffffffff || + (ver._raw & 0xffffffff) == 0x00 ) /* need to use VER.EMIF */ + ver._raw = read_pub_config_reg(TXTCR_VER_EMIF); + printf("\n%s: chipset production fused: %x", __FUNCTION__, ver.prod_fused); + + if(txt_is_launched()) { + write_priv_config_reg(locality == 1 ? TXTCR_CMD_OPEN_LOCALITY1 + : TXTCR_CMD_OPEN_LOCALITY2, 0x01); + read_priv_config_reg(TXTCR_E2STS); /* just a fence, so ignore return */ + return 0; + } else { + printf("\n%s: ERROR: Locality opening UNIMPLEMENTED on Intel without SENTER\n", __FUNCTION__); + return 1; + } +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-tpm/tpm-interface.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-tpm/tpm-interface.c new file mode 100644 index 0000000000..c4c6c9e85a --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-tpm/tpm-interface.c @@ -0,0 +1,105 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/** + * Common EMHF-specific functions for initiating and terminating + * communication with the TPM. Motivation is that AMD and Intel have + * slightly different requirements, since Intel uses some TXT-specific + * registers if late launch has already completed. + * + * TODO: For dynamic hypervisor launch after the legacy OS is booted, + * support to "play nice" with the legacy OS's TPM driver probably + * goes in here. + * + * Author: Jonathan McCune and Amit Vasudevan (amitvasudevan@acm.org) + */ + +#include + +//open TPM locality +int xmhf_tpm_open_locality(int locality){ + /* We expect locality 1 or 2 */ + if(locality < 1 || locality > 2) { + return 1; + } + + if(xmhf_tpm_arch_open_locality(locality)) { + printf("\n%s: FAILED to open TPM locality %d\n", __FUNCTION__, locality); + return 1; + }; + + if(!xmhf_tpm_is_tpm_ready(locality)) { + printf("\n%s: ERROR TPM is not ready, failed to open locality %d\n", __FUNCTION__, locality); + return 1; + } + + printf("\n%s: opened TPM locality %d", __FUNCTION__, locality); + return 0; +} + +//check if TPM is ready for use +bool xmhf_tpm_is_tpm_ready(uint32_t locality){ + return xmhf_tpm_arch_is_tpm_ready(locality); +} + +//deactivate all TPM localities +void xmhf_tpm_deactivate_all_localities(void){ + xmhf_tpm_arch_deactivate_all_localities(); +} + +//prepare TPM for use +bool xmhf_tpm_prepare_tpm(void){ + return xmhf_tpm_arch_prepare_tpm(); +} + + + + +/* Local Variables: */ +/* mode:c */ +/* indent-tabs-mode:'t */ +/* tab-width:2 */ +/* End: */ diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xcphandler/Makefile b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xcphandler/Makefile new file mode 100644 index 0000000000..a8b4e02eed --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xcphandler/Makefile @@ -0,0 +1,11 @@ +# makefile for xmhf-xcphandler (EMHF exception handler component) +# author: amit vasudevan (amitvasudevan@acm.org) + +# source files +AS_SOURCES = ./arch/x86/xcph-stubs-$(TARGET_SUBARCH).S +C_SOURCES = xcph-interface.c +C_SOURCES += ./arch/x86/xcph-x86.c + +# targets +include ../runtime.mk + diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xcphandler/arch/x86/xcph-stubs-amd64.S b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xcphandler/arch/x86/xcph-stubs-amd64.S new file mode 100644 index 0000000000..d199416cd6 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xcphandler/arch/x86/xcph-stubs-amd64.S @@ -0,0 +1,207 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF exception handler component low-level stubs + */ + +#include +#include + +.altmacro +.macro XtRtmEmitIdtStub vector skip_err_code + .section .text + + //notes: + //1. we only handle exceptions (0-31) and nothing else + //2. descriptor type for all exception handlers are 0x8E + // i.e., they are all interrupt gates, so when we get called + // EFLAGS.IF = 0 (interrupts disabled) + //3. there are no stack switches as everything in the hypervisor + // is CPL=0 + //4. stack layout is as follows when we enter + // EFLAGS (32-bits) + // CS (32-bits) + // EIP (32-bits) + // error-code (32-bits, depends on the exception) + + XtRtmIdtStub&vector&: + + // push GPR values on stack to construct struct regs *r + pushq %r15 + pushq %r14 + pushq %r13 + pushq %r12 + pushq %r11 + pushq %r10 + pushq %r9 + pushq %r8 + pushq %rax + pushq %rcx + pushq %rdx + pushq %rbx + pushq %rsp + pushq %rbp + pushq %rsi + pushq %rdi + + /* We want %rsp to be the value before the first push */ + addq $(12 * 8), 24(%rsp) + + movq %rsp, %rsi // RSI (second argument) = struct regs * + movq $0x&vector&, %rdi // RDI (first argument) = vector + call xmhf_xcphandler_hub // call C-land hub + + // push GPR values, except RSP + popq %rdi + popq %rsi + popq %rbp + leaq 8(%rsp), %rsp + popq %rbx + popq %rdx + popq %rcx + popq %rax + popq %r8 + popq %r9 + popq %r10 + popq %r11 + popq %r12 + popq %r13 + popq %r14 + popq %r15 + + /* If the exception puts an error code on the stack, ignore it */ + .if &skip_err_code& + leaq 8(%rsp), %rsp + .endif + + // return from exception + iretq + +.endm + +XtRtmEmitIdtStub 0 0 +XtRtmEmitIdtStub 1 0 +XtRtmEmitIdtStub 2 0 +XtRtmEmitIdtStub 3 0 +XtRtmEmitIdtStub 4 0 +XtRtmEmitIdtStub 5 0 +XtRtmEmitIdtStub 6 0 +XtRtmEmitIdtStub 7 0 +XtRtmEmitIdtStub 8 1 +XtRtmEmitIdtStub 9 0 +XtRtmEmitIdtStub a 1 +XtRtmEmitIdtStub b 1 +XtRtmEmitIdtStub c 1 +XtRtmEmitIdtStub d 1 +XtRtmEmitIdtStub e 1 +XtRtmEmitIdtStub f 0 +XtRtmEmitIdtStub 10 0 +XtRtmEmitIdtStub 11 1 +XtRtmEmitIdtStub 12 0 +XtRtmEmitIdtStub 13 0 +XtRtmEmitIdtStub 14 0 +XtRtmEmitIdtStub 15 0 +XtRtmEmitIdtStub 16 0 +XtRtmEmitIdtStub 17 0 +XtRtmEmitIdtStub 18 0 +XtRtmEmitIdtStub 19 0 +XtRtmEmitIdtStub 1a 0 +XtRtmEmitIdtStub 1b 0 +XtRtmEmitIdtStub 1c 0 +XtRtmEmitIdtStub 1d 0 +XtRtmEmitIdtStub 1e 0 +XtRtmEmitIdtStub 1f 0 + + +.section .data + //EMHF interrupt descriptor table + .global xmhf_xcphandler_idt + xmhf_xcphandler_idt: + .word xmhf_xcphandler_idt_end - xmhf_xcphandler_idt_start + .quad xmhf_xcphandler_idt_start + .align 16 + .global xmhf_xcphandler_idt_start + xmhf_xcphandler_idt_start: + .fill (EMHF_XCPHANDLER_MAXEXCEPTIONS * 16), 1, 0 + xmhf_xcphandler_idt_end: + + + .align 16 + .global xmhf_xcphandler_exceptionstubs + xmhf_xcphandler_exceptionstubs: + .quad XtRtmIdtStub0 + .quad XtRtmIdtStub1 + .quad XtRtmIdtStub2 + .quad XtRtmIdtStub3 + .quad XtRtmIdtStub4 + .quad XtRtmIdtStub5 + .quad XtRtmIdtStub6 + .quad XtRtmIdtStub7 + .quad XtRtmIdtStub8 + .quad XtRtmIdtStub9 + .quad XtRtmIdtStuba + .quad XtRtmIdtStubb + .quad XtRtmIdtStubc + .quad XtRtmIdtStubd + .quad XtRtmIdtStube + .quad XtRtmIdtStubf + .quad XtRtmIdtStub10 + .quad XtRtmIdtStub11 + .quad XtRtmIdtStub12 + .quad XtRtmIdtStub13 + .quad XtRtmIdtStub14 + .quad XtRtmIdtStub15 + .quad XtRtmIdtStub16 + .quad XtRtmIdtStub17 + .quad XtRtmIdtStub18 + .quad XtRtmIdtStub19 + .quad XtRtmIdtStub1a + .quad XtRtmIdtStub1b + .quad XtRtmIdtStub1c + .quad XtRtmIdtStub1d + .quad XtRtmIdtStub1e + .quad XtRtmIdtStub1f diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xcphandler/arch/x86/xcph-stubs-i386.S b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xcphandler/arch/x86/xcph-stubs-i386.S new file mode 100644 index 0000000000..75ddb0d698 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xcphandler/arch/x86/xcph-stubs-i386.S @@ -0,0 +1,180 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF exception handler component low-level stubs + */ + +#include +#include + +.altmacro +.macro XtRtmEmitIdtStub vector skip_err_code + .section .text + + //notes: + //1. we only handle exceptions (0-31) and nothing else + //2. descriptor type for all exception handlers are 0x8E + // i.e., they are all interrupt gates, so when we get called + // EFLAGS.IF = 0 (interrupts disabled) + //3. there are no stack switches as everything in the hypervisor + // is CPL=0 + //4. stack layout is as follows when we enter + // EFLAGS (32-bits) + // CS (32-bits) + // EIP (32-bits) + // error-code (32-bits, depends on the exception) + + XtRtmIdtStub&vector&: + + //push GPR values on stack to construct a + //struct regs *r + pushal + + movw $(__DS), %ax + movw %ax, %ds //load DS + movl %esp, %eax //EAX = struct regs * + + pushl %eax //struct regs *r + pushl $0x&vector& //vector + call xmhf_xcphandler_hub //call C-land hub + addl $0x08, %esp //remove params from stack + + //restore GPRs + popal + + /* If the exception puts an error code on the stack, ignore it */ + .if &skip_err_code& + leal 4(%esp), %esp + .endif + + //return from exception + iretl + +.endm + +XtRtmEmitIdtStub 0 0 +XtRtmEmitIdtStub 1 0 +XtRtmEmitIdtStub 2 0 +XtRtmEmitIdtStub 3 0 +XtRtmEmitIdtStub 4 0 +XtRtmEmitIdtStub 5 0 +XtRtmEmitIdtStub 6 0 +XtRtmEmitIdtStub 7 0 +XtRtmEmitIdtStub 8 1 +XtRtmEmitIdtStub 9 0 +XtRtmEmitIdtStub a 1 +XtRtmEmitIdtStub b 1 +XtRtmEmitIdtStub c 1 +XtRtmEmitIdtStub d 1 +XtRtmEmitIdtStub e 1 +XtRtmEmitIdtStub f 0 +XtRtmEmitIdtStub 10 0 +XtRtmEmitIdtStub 11 1 +XtRtmEmitIdtStub 12 0 +XtRtmEmitIdtStub 13 0 +XtRtmEmitIdtStub 14 0 +XtRtmEmitIdtStub 15 0 +XtRtmEmitIdtStub 16 0 +XtRtmEmitIdtStub 17 0 +XtRtmEmitIdtStub 18 0 +XtRtmEmitIdtStub 19 0 +XtRtmEmitIdtStub 1a 0 +XtRtmEmitIdtStub 1b 0 +XtRtmEmitIdtStub 1c 0 +XtRtmEmitIdtStub 1d 0 +XtRtmEmitIdtStub 1e 0 +XtRtmEmitIdtStub 1f 0 + + +.section .data + //EMHF interrupt descriptor table + .global xmhf_xcphandler_idt + xmhf_xcphandler_idt: + .word xmhf_xcphandler_idt_end - xmhf_xcphandler_idt_start - 1 + .long xmhf_xcphandler_idt_start + .align 16 + .global xmhf_xcphandler_idt_start + xmhf_xcphandler_idt_start: + .fill 1024, 1, 0 + xmhf_xcphandler_idt_end: + + + .align 16 + .global xmhf_xcphandler_exceptionstubs + xmhf_xcphandler_exceptionstubs: + .long XtRtmIdtStub0 + .long XtRtmIdtStub1 + .long XtRtmIdtStub2 + .long XtRtmIdtStub3 + .long XtRtmIdtStub4 + .long XtRtmIdtStub5 + .long XtRtmIdtStub6 + .long XtRtmIdtStub7 + .long XtRtmIdtStub8 + .long XtRtmIdtStub9 + .long XtRtmIdtStuba + .long XtRtmIdtStubb + .long XtRtmIdtStubc + .long XtRtmIdtStubd + .long XtRtmIdtStube + .long XtRtmIdtStubf + .long XtRtmIdtStub10 + .long XtRtmIdtStub11 + .long XtRtmIdtStub12 + .long XtRtmIdtStub13 + .long XtRtmIdtStub14 + .long XtRtmIdtStub15 + .long XtRtmIdtStub16 + .long XtRtmIdtStub17 + .long XtRtmIdtStub18 + .long XtRtmIdtStub19 + .long XtRtmIdtStub1a + .long XtRtmIdtStub1b + .long XtRtmIdtStub1c + .long XtRtmIdtStub1d + .long XtRtmIdtStub1e + .long XtRtmIdtStub1f diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xcphandler/arch/x86/xcph-x86.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xcphandler/arch/x86/xcph-x86.c new file mode 100644 index 0000000000..67a8b833cf --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xcphandler/arch/x86/xcph-x86.c @@ -0,0 +1,292 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF exception handler component interface + * x86 arch. backend + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + +//---function to obtain the vcpu of the currently executing core---------------- +// XXX: TODO, move this into baseplatform as backend +// note: this always returns a valid VCPU pointer +static VCPU *_svm_and_vmx_getvcpu(void){ + int i; + u32 eax, edx, *lapic_reg; + u32 lapic_id; + + //read LAPIC id of this core + rdmsr(MSR_APIC_BASE, &eax, &edx); + HALT_ON_ERRORCOND( edx == 0 ); //APIC is below 4G + if (eax & (1U << 10)) { + /* x2APIC is enabled, use it */ + rdmsr(IA32_X2APIC_APICID, &eax, &edx); + lapic_id = eax; + } else { + eax &= (u32)0xFFFFF000UL; + lapic_reg = (u32 *)((uintptr_t)eax + (uintptr_t)LAPIC_ID); + lapic_id = *lapic_reg; + //printf("\n%s: lapic base=0x%08x, id reg=0x%08x", __FUNCTION__, eax, lapic_id); + lapic_id = lapic_id >> 24; + //printf("\n%s: lapic_id of core=0x%02x", __FUNCTION__, lapic_id); + } + + for(i=0; i < (int)g_midtable_numentries; i++){ + if(g_midtable[i].cpu_lapic_id == lapic_id) + return( (VCPU *)g_midtable[i].vcpu_vaddr_ptr ); + } + + printf("\n%s: fatal, unable to retrieve vcpu for id=0x%02x", __FUNCTION__, lapic_id); + HALT(); return NULL; // will never return presently +} + +//initialize EMHF core exception handlers +void xmhf_xcphandler_arch_initialize(void){ + uintptr_t *pexceptionstubs; + uintptr_t i; + + printf("\n%s: setting up runtime IDT...", __FUNCTION__); + + pexceptionstubs = (uintptr_t *)&xmhf_xcphandler_exceptionstubs; + + for(i=0; i < EMHF_XCPHANDLER_MAXEXCEPTIONS; i++){ + idtentry_t *idtentry=(idtentry_t *)((hva_t)xmhf_xcphandler_arch_get_idt_start()) + i; + idtentry->isrLow16 = (u16)(pexceptionstubs[i]); + idtentry->isrHigh16 = (u16)(pexceptionstubs[i] >> 16); +#ifdef __AMD64__ + idtentry->isrHigh32 = (u32)(pexceptionstubs[i] >> 32); + idtentry->reserved_zero = 0x0; +#elif !defined(__I386__) + #error "Unsupported Arch" +#endif /* !defined(__I386__) */ + idtentry->isrSelector = __CS; + idtentry->count = 0x0; // for now, set IST to 0 + idtentry->type = 0x8E; // 32-bit / 64-bit interrupt gate + // present=1, DPL=00b, system=0, type=1110b + } + + printf("\n%s: IDT setup done.", __FUNCTION__); +} + + +//get IDT start address +u8 * xmhf_xcphandler_arch_get_idt_start(void){ + return (u8 *)&xmhf_xcphandler_idt_start; +} + +extern uint8_t _begin_xcph_table[]; +extern uint8_t _end_xcph_table[]; + +//EMHF exception handler hub +void xmhf_xcphandler_arch_hub(uintptr_t vector, struct regs *r){ + VCPU *vcpu; + + vcpu = _svm_and_vmx_getvcpu(); + + /* + * Cannot print anything before event handler returns if this exception + * is for quiescing (vector == CPU_EXCEPTION_NMI), otherwise will deadlock. + * See xmhf_smpguest_arch_x86vmx_quiesce(). + */ + + switch(vector){ + case CPU_EXCEPTION_NMI: + xmhf_smpguest_arch_x86_eventhandler_nmiexception(vcpu, r, 0); + break; + + default: + { + /* + * Search for matching exception in .xcph_table section. + * Each entry in .xcph_table has 3 long values. If the first value + * matches the exception vector and the second value matches the + * current PC, then jump to the third value. + * + * In x86, these names should be interpreted as EIP and EFLAGS, not + * RIP and RFLAGS. + */ + uintptr_t exception_cs, exception_rip, exception_rflags; + u32 error_code_available = 0; + hva_t *found = NULL; + + // skip error code on stack if applicable + if (vector == CPU_EXCEPTION_DF || + vector == CPU_EXCEPTION_TS || + vector == CPU_EXCEPTION_NP || + vector == CPU_EXCEPTION_SS || + vector == CPU_EXCEPTION_GP || + vector == CPU_EXCEPTION_PF || + vector == CPU_EXCEPTION_AC) { + error_code_available = 1; +#ifdef __AMD64__ + r->rsp += sizeof(uintptr_t); +#elif defined(__I386__) + r->esp += sizeof(uintptr_t); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + } + +#ifdef __AMD64__ + exception_rip = ((uintptr_t *)(r->rsp))[0]; + exception_cs = ((uintptr_t *)(r->rsp))[1]; + exception_rflags = ((uintptr_t *)(r->rsp))[2]; +#elif defined(__I386__) + exception_rip = ((uintptr_t *)(r->esp))[0]; + exception_cs = ((uintptr_t *)(r->esp))[1]; + exception_rflags = ((uintptr_t *)(r->esp))[2]; +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + + for (hva_t *i = (hva_t *)_begin_xcph_table; + i < (hva_t *)_end_xcph_table; i += 3) { + if (i[0] == vector && i[1] == exception_rip) { + found = i; + break; + } + } + + if (found) { + /* Found in xcph table; Modify EIP on stack and iret */ + printf("\nFound in xcph table"); +#ifdef __AMD64__ + ((uintptr_t *)(r->rsp))[0] = found[2]; +#elif defined(__I386__) + ((uintptr_t *)(r->esp))[0] = found[2]; +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + break; + } + + /* Print exception and halt */ + printf("\n[%02x]: unhandled exception %d (0x%x), halting!", + vcpu->id, vector, vector); + if (error_code_available) { +#ifdef __AMD64__ + printf("\n[%02x]: error code: 0x%016lx", vcpu->id, ((uintptr_t *)(r->rsp))[-1]); +#elif defined(__I386__) + printf("\n[%02x]: error code: 0x%08lx", vcpu->id, ((uintptr_t *)(r->esp))[-1]); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + } + printf("\n[%02x]: state dump follows...", vcpu->id); + // things to dump +#ifdef __AMD64__ + printf("\n[%02x] CS:RIP 0x%04x:0x%016lx with RFLAGS=0x%016lx", vcpu->id, + (u16)exception_cs, exception_rip, exception_rflags); + printf("\n[%02x]: VCPU at 0x%016lx", vcpu->id, (uintptr_t)vcpu, vcpu->id); + printf("\n[%02x] RAX=0x%016lx RBX=0x%016lx", vcpu->id, r->rax, r->rbx); + printf("\n[%02x] RCX=0x%016lx RDX=0x%016lx", vcpu->id, r->rcx, r->rdx); + printf("\n[%02x] RSI=0x%016lx RDI=0x%016lx", vcpu->id, r->rsi, r->rdi); + printf("\n[%02x] RBP=0x%016lx RSP=0x%016lx", vcpu->id, r->rbp, r->rsp); + printf("\n[%02x] R8 =0x%016lx R9 =0x%016lx", vcpu->id, r->r8 , r->r9 ); + printf("\n[%02x] R10=0x%016lx R11=0x%016lx", vcpu->id, r->r10, r->r11); + printf("\n[%02x] R12=0x%016lx R13=0x%016lx", vcpu->id, r->r12, r->r13); + printf("\n[%02x] R14=0x%016lx R15=0x%016lx", vcpu->id, r->r14, r->r15); +#elif defined(__I386__) + printf("\n[%02x] CS:EIP 0x%04x:0x%08x with EFLAGS=0x%08x", vcpu->id, + (u16)exception_cs, exception_rip, exception_rflags); + printf("\n[%02x]: VCPU at 0x%08x", vcpu->id, (u32)vcpu, vcpu->id); + printf("\n[%02x] EAX=0x%08x EBX=0x%08x ECX=0x%08x EDX=0x%08x", vcpu->id, + r->eax, r->ebx, r->ecx, r->edx); + printf("\n[%02x] ESI=0x%08x EDI=0x%08x EBP=0x%08x ESP=0x%08x", vcpu->id, + r->esi, r->edi, r->ebp, r->esp); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + printf("\n[%02x] CS=0x%04x, DS=0x%04x, ES=0x%04x, SS=0x%04x", vcpu->id, + (u16)read_segreg_cs(), (u16)read_segreg_ds(), + (u16)read_segreg_es(), (u16)read_segreg_ss()); + printf("\n[%02x] FS=0x%04x, GS=0x%04x", vcpu->id, + (u16)read_segreg_fs(), (u16)read_segreg_gs()); + printf("\n[%02x] TR=0x%04x", vcpu->id, (u16)read_tr_sel()); + + //do a stack dump in the hopes of getting more info. + { + //vcpu->rsp is the TOS + uintptr_t i; + printf("\n[%02x]-----stack dump-----", vcpu->id); +#ifdef __AMD64__ + for(i=r->rsp; i < vcpu->rsp; i+=sizeof(uintptr_t)){ + printf("\n[%02x] Stack(0x%016lx) -> 0x%016lx", vcpu->id, i, *(uintptr_t *)i); + } +#elif defined(__I386__) + for(i=r->esp; i < vcpu->esp; i+=sizeof(uintptr_t)){ + printf("\n[%02x] Stack(0x%08x) -> 0x%08x", vcpu->id, i, *(uintptr_t *)i); + } +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + printf("\n[%02x]-----end------------", vcpu->id); + } + + // Exception #BP may be caused by failed VMRESUME. Dump VMCS + if (vector == CPU_EXCEPTION_BP && + get_cpu_vendor_or_die() == CPU_VENDOR_INTEL) { + xmhf_baseplatform_arch_x86vmx_getVMCS(vcpu); +#ifdef __I386__ + /* + * For i386 XMHF, cannot run amd64 guest OS (this is a hardware + * limit). Try to detect it and print a user-friendly message. + */ + if (vcpu->vmcs.control_VM_entry_controls & (1UL << 9)) { + printf("\nHALT: guest OS entering long mode in i386 XMHF"); + HALT(); + } +#elif !defined(__AMD64__) + #error "Unsupported Arch" +#endif /* !defined(__AMD64__) */ + xmhf_baseplatform_arch_x86vmx_dump_vcpu(vcpu); + } + HALT(); + } + } +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xcphandler/xcph-interface.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xcphandler/xcph-interface.c new file mode 100644 index 0000000000..14165bfbbe --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xcphandler/xcph-interface.c @@ -0,0 +1,70 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* + * EMHF exception handler component interface + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + + +//initialize EMHF core exception handlers +void xmhf_xcphandler_initialize(void){ + xmhf_xcphandler_arch_initialize(); +} + + +//get IDT start address +u8 * xmhf_xcphandler_get_idt_start(void){ + return xmhf_xcphandler_arch_get_idt_start(); +} + + +//EMHF exception handler hub +void xmhf_xcphandler_hub(uintptr_t vector, struct regs *r){ + xmhf_xcphandler_arch_hub(vector, r); +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xmhfcbackend/Makefile b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xmhfcbackend/Makefile new file mode 100644 index 0000000000..ef57208eb1 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xmhfcbackend/Makefile @@ -0,0 +1,14 @@ +# makefile for xmhf-xmhfcbackend (libxmhfc backend component) +# author: amit vasudevan (amitvasudevan@acm.org) + +# source files +AS_SOURCES = +C_SOURCES = xmhfc-putchar.c +C_SOURCES += ./stl/xmhfc-bitmap.c +C_SOURCES += ./stl/xmhfc-dlist.c + +C_SOURCES_BL = xmhfc-putchar.c + +# targets +include ../runtime.mk + diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xmhfcbackend/stl/xmhfc-bitmap.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xmhfcbackend/stl/xmhfc-bitmap.c new file mode 100644 index 0000000000..eba054c35a --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xmhfcbackend/stl/xmhfc-bitmap.c @@ -0,0 +1,178 @@ +#include + +XMHF_STL_BITMAP* xmhfstl_bitmap_create(uint32_t num_bits) +{ + XMHF_STL_BITMAP* result = NULL; + ulong_t num_pages = 0; + + result = (XMHF_STL_BITMAP*)xmhf_mm_malloc(sizeof(XMHF_STL_BITMAP)); + if(!result) + return NULL; + + // TODO: change num_bits's type to ulong_t, then remove type cast + num_pages = BYTES_TO_PAGE4K((ulong_t)BITS_TO_BYTES(num_bits)); + result->max_bits = num_bits; + result->mem_table = (char**)xmhf_mm_malloc(num_pages * sizeof(char*)); + if(!result->mem_table) + return NULL; + + result->bits_stat = (uint16_t*)xmhf_mm_malloc(num_pages * sizeof(uint16_t)); + if(!result->bits_stat) + return NULL; + return result; +} + +void xmhfstl_bitmap_destroy(XMHF_STL_BITMAP* bitmap) +{ + ulong_t num_pages; + ulong_t i = 0; + + if(!bitmap) + return; + + // TODO: change bitmap->max_bits's type to ulong_t, then remove type cast + num_pages = BYTES_TO_PAGE4K((ulong_t)BITS_TO_BYTES(bitmap->max_bits)); + for(i = 0; i < num_pages; i++) + { + char* mem = bitmap->mem_table[i]; + + if(mem) + { + xmhf_mm_free(mem); + mem = NULL; + } + } + + if(bitmap->mem_table) + { + xmhf_mm_free(bitmap->mem_table); + bitmap->mem_table = NULL; + } + + if(bitmap->bits_stat) + { + xmhf_mm_free(bitmap->bits_stat); + bitmap->mem_table = NULL; + } + + xmhf_mm_free(bitmap); +} + +bool xmhfstl_bitmap_set_bit(XMHF_STL_BITMAP* bitmap, const uint32_t bit_idx) +{ + uint32_t bit_offset; + uint32_t byte_offset; + uint32_t pg_offset; + uint32_t bits_stat; + char test_bit; + + // Sanity check + if(!bitmap) + return false; + + if(bit_idx >= bitmap->max_bits) + return false; + + bit_offset = bit_idx % BITS_PER_BYTE; + byte_offset = BITS_TO_BYTES(bit_idx) % PAGE_SIZE_4K; + pg_offset = BITS_TO_BYTES(bit_idx) >> PAGE_SHIFT_4K; + + bits_stat = bitmap->bits_stat[pg_offset]; + + if(!bits_stat) + { + // There is no page to hold the bitmap content + bitmap->mem_table[pg_offset] = (char*) xmhf_mm_malloc_align(PAGE_SIZE_4K, PAGE_SIZE_4K); + if(!bitmap->mem_table[pg_offset]) + return false; + } + + test_bit = bitmap->mem_table[pg_offset][byte_offset]; + if(test_bit & (1 << bit_offset)) + return true; // already set + else + bitmap->mem_table[pg_offset][byte_offset] = (char)(test_bit | (1 << bit_offset)); + bitmap->bits_stat[pg_offset] = bits_stat + 1; + + return true; +} + + +bool xmhfstl_bitmap_clear_bit(XMHF_STL_BITMAP* bitmap, const uint32_t bit_idx) +{ + uint32_t bit_offset; + uint32_t byte_offset; + uint32_t pg_offset; + uint32_t bits_stat; + char test_bit; + + // Sanity check + if(!bitmap) + return false; + + if(bit_idx >= bitmap->max_bits) + return false; + + bit_offset = bit_idx % BITS_PER_BYTE; + byte_offset = BITS_TO_BYTES(bit_idx) % PAGE_SIZE_4K; + pg_offset = BITS_TO_BYTES(bit_idx) >> PAGE_SHIFT_4K; + bits_stat = bitmap->bits_stat[pg_offset]; + + if(!bits_stat) + return true; + + test_bit = bitmap->mem_table[pg_offset][byte_offset]; + if(test_bit & (1 << bit_offset)) + { + // The bit is set, so we need to clear it in the next + bitmap->mem_table[pg_offset][byte_offset] = (char)(test_bit & ~(1 << bit_offset)); + bitmap->bits_stat[pg_offset] = bits_stat - 1; + } + + if(!bits_stat && bitmap->mem_table[pg_offset]) + { + // There is no page to hold the xmhfstl_bitmap content + xmhf_mm_free(bitmap->mem_table[pg_offset]); + bitmap->mem_table[pg_offset] = NULL; + } + + return true; +} + +bool xmhfstl_bitmap_is_bit_set(XMHF_STL_BITMAP* bitmap, const uint32_t bit_idx) +{ + uint32_t bit_offset; + uint32_t byte_offset; + uint32_t pg_offset; + + bit_offset = bit_idx % BITS_PER_BYTE; + byte_offset = BITS_TO_BYTES(bit_idx) % PAGE_SIZE_4K; + pg_offset = BITS_TO_BYTES(bit_idx) >> PAGE_SHIFT_4K; + + if( !bitmap->mem_table[pg_offset]) + return false; + + if(bitmap->mem_table[pg_offset][byte_offset] & (1 << bit_offset)) + return true; + else + return false; +} + +bool xmhfstl_bitmap_is_bit_clear(XMHF_STL_BITMAP* bitmap, const uint32_t bit_idx) +{ + uint32_t bit_offset; + uint32_t byte_offset; + uint32_t pg_offset; + + bit_offset = bit_idx % BITS_PER_BYTE; + byte_offset = BITS_TO_BYTES(bit_idx) % PAGE_SIZE_4K; + pg_offset = BITS_TO_BYTES(bit_idx) >> PAGE_SHIFT_4K; + + if(!bitmap->mem_table[pg_offset]) + return true; + + if(bitmap->mem_table[pg_offset][byte_offset] & (1 << bit_offset)) + return false; + else + return true; +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xmhfcbackend/stl/xmhfc-dlist.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xmhfcbackend/stl/xmhfc-dlist.c new file mode 100644 index 0000000000..6db78feb6a --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xmhfcbackend/stl/xmhfc-dlist.c @@ -0,0 +1,167 @@ +#include + +XMHFList* xmhfstl_list_create(void) +{ + XMHFList* result = (XMHFList*)xmhf_mm_malloc(sizeof(XMHFList)); + if(!result) + return NULL; + result->count = 0; + result->first = NULL; + result->last = NULL; + return result; +} + +void xmhfstl_list_destroy(XMHFList *list) +{ + XMHFListNode *iter = NULL, *cur = NULL, *next = NULL; + if(!list) + return; + + iter = xmhfstl_list_first(list); + + while((iter != NULL)) + { + cur = iter; + next = iter->next; + + if(cur) + { + cur->prev = NULL; + cur->next = NULL; + xmhf_mm_free(cur); + } + iter = next; + } + + xmhf_mm_free(list); +} + +void xmhfstl_list_clear(XMHFList *list) +{ + if(!list) + return; + + { // due to the "mixed declarations and code" warning + XMHFLIST_FOREACH(list, first, next, cur) + { + if(cur->value) + xmhf_mm_free(cur->value); + } + } +} + +void xmhfstl_list_clear_destroy(XMHFList *list) +{ + xmhfstl_list_clear(list); + xmhfstl_list_destroy(list); +} + +XMHFListNode* xmhfstl_list_push(XMHFList *list, void *value) +{ + XMHFListNode* node = NULL; + + if(!list) + return NULL; + + node = (XMHFListNode*)xmhf_mm_malloc(sizeof(XMHFListNode)); + if(!node) + return NULL; + + node->next = NULL; + node->value = value; + + if(list->last == NULL) { + list->first = node; + list->last = node; + } else { + list->last->next = node; + node->prev = list->last; + list->last = node; + } + + list->count++; + +//error: + return node; +} + +void* xmhfstl_list_pop(XMHFList *list) +{ + XMHFListNode *node; + + if(!list) + return NULL; + + node = list->last; + return node != NULL ? xmhfstl_list_remove(list, node) : NULL; +} + +void* xmhfstl_list_dequeue(XMHFList *list) +{ + XMHFListNode *node; + + if(!list) + return NULL; + + node = list->first; + return node != NULL ? xmhfstl_list_remove(list, node) : NULL; +} + + +XMHFListNode* xmhfstl_list_last(XMHFList *list) +{ + XMHFListNode *node; + + if(!list) + return NULL; + + node = list->last; + return node; +} + +XMHFListNode* xmhfstl_list_first(XMHFList *list) +{ + XMHFListNode *node; + + if(!list) + return NULL; + + node = list->first; + return node; +} + +void* xmhfstl_list_remove(XMHFList *list, XMHFListNode *node) +{ + void *result = NULL; + + if(!list || !node) + return NULL; + + //check(list->first && list->last, "XMHFList is empty."); + //check(node, "node can't be NULL"); + + if(node == list->first && node == list->last) { + list->first = NULL; + list->last = NULL; + } else if(node == list->first) { + list->first = node->next; + //check(list->first != NULL, "Invalid list, somehow got a first that is NULL."); + list->first->prev = NULL; + } else if (node == list->last) { + list->last = node->prev; + //check(list->last != NULL, "Invalid list, somehow got a next that is NULL."); + list->last->next = NULL; + } else { + XMHFListNode *after = node->next; + XMHFListNode *before = node->prev; + after->prev = before; + before->next = after; + } + + list->count--; + result = node->value; + xmhf_mm_free(node); + +//error: + return result; +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xmhfcbackend/xmhfc-putchar.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xmhfcbackend/xmhfc-putchar.c new file mode 100644 index 0000000000..186d2c4d02 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-runtime/xmhf-xmhfcbackend/xmhfc-putchar.c @@ -0,0 +1,68 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include + +void *emhfc_putchar_arg; + +static u32 emhfc_putchar_linelock_spinlock = 1; +void *emhfc_putchar_linelock_arg = &emhfc_putchar_linelock_spinlock; + +void emhfc_putchar(int ch, void *arg) +{ + (void)arg; + xmhf_debug_arch_putc(ch); +} + +void emhfc_putchar_linelock(void *arg) +{ + spin_lock(arg); +} + +void emhfc_putchar_lineunlock(void *arg) +{ + spin_unlock(arg); +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/Makefile b/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/Makefile new file mode 100644 index 0000000000..912932b01a --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/Makefile @@ -0,0 +1,91 @@ +# makefile for "sl" +# author: amit vasudevan (amitvasudevan@acm.org) + +# source files +AS_SOURCES = ./arch/x86/sl-x86-$(TARGET_SUBARCH)-entry.S +AS_SOURCES += ./arch/x86/sl-x86-$(TARGET_SUBARCH)-sup.S + +C_SOURCES = sl.c +C_SOURCES += ./arch/x86/sl-x86.c + + +OBJECTS = $(patsubst %.S, %.o, $(AS_SOURCES)) +OBJECTS += $(patsubst %.c, %.o, $(C_SOURCES)) + + +#tie components used by SL +OBJECTS_PRECOMPILED = ../xmhf-runtime/xmhf-debug/lib.a + +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-tpm/tpm-interface.o +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-tpm/arch/x86/tpm-x86.o +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-tpm/arch/x86/svm/tpm-x86svm.o +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-tpm/arch/x86/vmx/tpm-x86vmx.o + +ifeq ($(DMAP), y) +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-dmaprot/dmap-interface-earlyinit.o +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-dmaprot/arch/x86/dmap-x86-earlyinit.o +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-dmaprot/arch/x86/svm/dmap-svm.o +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-dmaprot/arch/x86/vmx/dmap-vmx-earlyinit.o +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-dmaprot/arch/x86/vmx/dmap-vmx-internal.o +endif + +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-baseplatform/bplt-interface.o +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86.o +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-pci.o +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-acpi.o +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-$(TARGET_SUBARCH)-smplock.o +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-addressing.o +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-baseplatform/arch/x86/bplt-x86-cpu.o + + +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx.o +ifeq ($(DRT), y) +OBJECTS_PRECOMPILED += ../xmhf-runtime/xmhf-baseplatform/arch/x86/vmx/bplt-x86vmx-mtrrs.o +endif + +# separate from OBJECTS_PRECOMPILED becasue needs to come after libs on link line +OBJECTS_PRECOMPILED_LIBBACKENDS = ../xmhf-runtime/xmhf-xmhfcbackend/xmhfc-putchar.o + +# FIXME: ADDL_INCLUDES is overly general; sl/ doesn't need all of them +CFLAGS += $(ADDL_INCLUDES) + +I_SOURCES = $(wildcard $(INCLUDEDIR)/*.h) + +# CFLAGS += -fPIC + +# RUNTIME_INTEGRITY_HASH should be set by parent Makefile +ifdef RUNTIME_INTEGRITY_HASH +CFLAGS += -D___RUNTIME_INTEGRITY_HASH___=\"$(RUNTIME_INTEGRITY_HASH)\" +endif + +# targets +.PHONY: all + +all: sl.bin + +# FIXME: ADDL_LIBS is overly general; sl/ doesn't need all of them +sl.bin: $(OBJECTS) $(OBJECTS_PRECOMPILED) sl.lds + $(LD) -T sl.lds -o sl.exe $(OBJECTS) $(OBJECTS_PRECOMPILED) $(ADDL_LIBS) $(OBJECTS_PRECOMPILED_LIBBACKENDS) -L$(CCLIB) -lgcc + $(CP) sl.exe sl_syms.exe + $(STRIP) -s sl.exe + $(OBJCOPY) --output-format=binary sl.exe sl.bin + # Optional: use sparse file to reduce fs space usage + -fallocate -d sl.exe + -fallocate -d sl.bin + -fallocate -d sl_syms.exe + # Compute sha-1 hash + dd if=sl.bin bs=1024 count=64 | sha1sum > sl-below.sha1 + dd if=sl.bin bs=1024 skip=64 count=1984 | sha1sum > sl-above.sha1 + +sl.lds: sl.lds.S + gcc -E -x c $(ASFLAGS) $< | grep -v '^#' > $@ + +.PHONY: clean +clean: + $(RM) -rf *.o + $(RM) -rf ./arch/x86/*.o + $(RM) -rf *.exe + $(RM) -rf *.bin + $(RM) -rf *.gz + $(RM) -rf *.sha1 + diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/arch/x86/sl-x86-amd64-entry.S b/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/arch/x86/sl-x86-amd64-entry.S new file mode 100644 index 0000000000..f98d13c1ec --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/arch/x86/sl-x86-amd64-entry.S @@ -0,0 +1,397 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* EMHF secure loader component entry point + authors: amit vasudevan (amitvasudevan@acm.org) and jonmccune@cmu.edu +*/ + +#include + +/*---------------------------------------------------------------------- + CODE +---------------------------------------------------------------------- + +our C main*/ + +.extern xmhf_sl_main + +/* The first 3 pages of the SL serve different purposes depending on + whether the system has an AMD or Intel CPU. On an AMD system, the + first four bytes of the first page comprise the SLB Header. The + remainder goes to waste (3*4K-4B). + + On Intel, these first three pages are used as the MLE Page Tables. + These are constructed in software with the txt.c:build_mle_pagetable() + function. The AMD header will be clobbered in the process. + + These 3 pages are placed at the very beginning of the SL (byte 0) + by our linker script. Our SL is always padded to 64K in size + regardless of the actual size of the code or data. The linker + relocation base for our SL is always 0. The SL must be position- + independent. */ + +.section .sl_header, "aw" + .global _mle_page_table_start + _mle_page_table_start: + + .global _sl_header + _sl_header: /* AMD-specific header format for Secure Loader Block (SLB). */ + .word _sl_start /* SL entry point relative to header (bits 0-15).*/ + .word 0xFFFF /*SL size including the header (bits 16-32),*/ + /*i.e, 0 through 65535 inclusive = 64K */ + + + /* Three 4K pages to hold the "MLE page tables" for an Intel-specific + DRTM using GETSEC[SENTER]. See 2.2.4.1 in Intel MLE + Developer's Guide (Dec. 2009 revision).*/ + .align 4096 // remainder of first page + + .global g_sl_protected_dmabuffer + g_sl_protected_dmabuffer: + .fill 4096, 1, 0 /* second page*/ + .fill 4096, 1, 0 /* third page*/ + .global _mle_page_table_end + _mle_page_table_end: + + +.section .text + /* Make room for MLE header at beginning*/ + .global _mle_hdr + _mle_hdr: + .fill TEMPORARY_MAX_MLE_HEADER_SIZE, 1, 0x90 /* XXX TODO just a guess; should really be sizeof(mle_hdr_t) */ + + .global _sl_start + _sl_start: + + .code32 + + /* get (physical location of secure loader - link location) in EBP */ + call 1f +1: popl %ebp // put EIP into EAX + subl $1b, %ebp + + /* XXX require EBP to be 2M-aligned, or page table will mis-align */ + movl $0x1fffff, %eax + testl %ebp, %eax + je 5f +6: hlt + jmp 6b +5: + + /* load 64-bit GDT */ + /* + * TODO: for AMD processors, use SS instead of DS. + * Need to follow sl-x86-entry.S to query CPUID. + * See "Cross-processor challenge:" comment in that file. + */ + addl %ebp, %ds:sl_gdt_ptr(%ebp) + lgdt %ds:sl_gdt(%ebp) + + /* set CR4 (enable PAE) */ + movl %cr4, %eax + orl $(CR4_PAE), %eax + movl %eax, %cr4 + + /* set up identity-map page table */ + + /* clear memory, because page table is in untrusted region */ + leal sl_long_pt_begin(%ebp), %eax + leal sl_long_pt_end(%ebp), %ebx +2: cmpl %eax, %ebx + jbe 3f + movl $0, %ds:(%eax) + addl $4, %eax + jmp 2b +3: + + /* set PML4T (1 entry, 512 GiB per entry) */ + leal sl_pdpt(%ebp), %eax + orl $0x3, %eax /* set P and R/W bits */ + movl %eax, %ds:sl_pml4t(%ebp) /* store PML4T[0] */ + + /* set PDPT (4 entries, 1 GiB per entry) */ + leal sl_pdt_0(%ebp), %eax + orl $0x3, %eax /* set P and R/W bits */ + movl %eax, %ds:sl_pdpt+8*0(%ebp) /* store PDPT[0] */ + leal sl_pdt_1(%ebp), %eax + orl $0x3, %eax + movl %eax, %ds:sl_pdpt+8*1(%ebp) /* store PDPT[1] */ + leal sl_pdt_2(%ebp), %eax + orl $0x3, %eax + movl %eax, %ds:sl_pdpt+8*2(%ebp) /* store PDPT[2] */ + leal sl_pdt_3(%ebp), %eax + orl $0x3, %eax + movl %eax, %ds:sl_pdpt+8*3(%ebp) /* store PDPT[3] */ + + /* set PDT (512*4 = 2048 entries, 2 MiB per entry) */ + movl $0, %eax + movl $2048, %ecx +4: movl %eax, %ebx + shll $21, %ebx + orl $0x83, %ebx + movl %ebx, %ds:sl_pdt(%ebp, %eax, 8) /* store PDT[EAX] */ + incl %eax + cmpl %eax, %ecx + ja 4b + + /* set CR3 (location of PML4T) */ + leal sl_pml4t(%ebp), %eax + movl %eax, %cr3 + + /* set EFER MSR LME */ + movl $(MSR_EFER), %ecx + rdmsr + btsl $(EFER_LME), %eax + wrmsr + + /* setup jump to 64-bit mode */ + pushl $(__CS) /* 2nd entry in GDT (64-bit CODE) */ + leal _sl_start_64(%ebp), %eax + pushl %eax + + /* enable paging */ + movl %cr0, %eax + orl $(CR0_PG), %eax + movl %eax, %cr0 + + /* jump to 64-bit mode */ + lret + + .code64 + + _sl_start_64: + + /* Load new segment selectors for DS, ES, FS, GS, and SS */ + movw $(__DS), %bx + movw %bx, %ds + movw %bx, %es + movw %bx, %fs + movw %bx, %gs + movw %bx, %ss + + /* + * Modify the page table so that (VA + RBP) % 4GiB = PA. + * When address is now too high, VA + RBP = PA. + * There is PA = RBP + link time address, so VA = link time address. + * In x86 mode this was implemented using GDT. Now we use page table. + * Assumption: SL is less than a page (2 MiB) + * We also need to access PA < RBP, so we implement (VA + RBP) % 4GiB = PA. + */ + + /* calculate RBP (was EBP) again */ + + leaq (%rip), %rbp +1: subq $1b, %rbp + + /* we need RBP to be 2M-aligned */ + movq $0x1fffff, %rax + testq %rbp, %rax + je 3f +2: hlt + jmp 2b +3: + + /* check RBP == 0 */ + testq %rbp, %rbp + jz _sl_skip_page_table_change /* unlikely to jump */ + + /* change PDT[0] */ + movq %rbp, %rbx + orq $0x83, %rbx + movq %rbx, sl_pdt(%ebp) /* store PDT[0] */ + + /* jump to virtual page 0 */ + movq $4f, %rax /* RAX now has link time address */ + jmpq *%rax +4: + + /* PDT[1:] will be set in C code */ + + _sl_skip_page_table_change: + + /* Now we only need RBP */ + xorq %rax, %rax + xorq %rbx, %rbx + xorq %rcx, %rcx + xorq %rdx, %rdx + + /* Setup ESP to top of 64K (it will already be there on AMD)*/ + movl $0x10000, %esp /* XXX TODO Get rid of magic number*/ + +#ifndef PERF_CRIT + /*get cycle count using rdtsc; useful to evaluate how long DRTM + takes*/ + cpuid /*Serializing instruction; causes more overhead :(*/ + rdtsc + pushq %rdx + pushq %rax +#endif + + /* Determine processor type to perform some low-level initialization + after DRTM. On AMD CPUs, we need to clear R_INIT, DIS_A20M and + CR_DPD (to enable HDT access) in VM_CR_MSR.*/ +sl_cpu_vendor: + xor %eax, %eax + cpuid + cmpl $(INTEL_STRING_DWORD1), %ebx + jne sl_cpu_vendor_notintel + cmpl $(INTEL_STRING_DWORD2), %edx + jne sl_cpu_vendor_notintel + cmpl $(INTEL_STRING_DWORD3), %ecx + jne sl_cpu_vendor_notintel + movl $(CPU_VENDOR_INTEL), %esi + jmp sl_cpu_intel +sl_cpu_vendor_notintel: + cmpl $(AMD_STRING_DWORD1), %ebx + jne sl_cpu_vendor_unknown + cmpl $(AMD_STRING_DWORD2), %edx + jne sl_cpu_vendor_unknown + cmpl $(AMD_STRING_DWORD3), %ecx + jne sl_cpu_vendor_unknown + movl $(CPU_VENDOR_AMD), %esi + jmp sl_cpu_amd +sl_cpu_vendor_unknown: + //this should never happen, but we have a fallback in case + ud2 + hlt + + /* If AMD CPU enable a few things that SKINIT disables. + Enable HDT debugging, also clear R_INIT and DIS_A20M. + XXX TODO Disable HDT debugging; represents a security vulnerability*/ +sl_cpu_amd: + movl $(VM_CR_MSR), %ecx + rdmsr + andl $(~(1< + +.section .text +/*------------------------------------------------------------------------------*/ + .global xmhf_sl_arch_x86_invoke_runtime_entrypoint +xmhf_sl_arch_x86_invoke_runtime_entrypoint: +/*------------------------------------------------------------------------------*/ + /* test whether sla == spa */ + cmpq $0, %r9 + je skip_jump + + /* save arguments */ + push %r9 /* sla2spa(0) */ + push %r8 /* cr3 */ + push %rcx /* stacktop */ + push %rdx /* entrypoint */ + push %rsi /* idtbase */ + push %rdi /* gdtbase */ + + /* modify sl page table to be able to jump back */ + movq $0, %rdi + call xmhf_setup_sl_paging + + /* restore arguments */ + pop %rdi + pop %rsi + pop %rdx + pop %rcx + pop %r8 + pop %r9 + + leaq 1f(%r9), %rax /* physical address of $1f */ + jmpq *%rax +1: + + skip_jump: + + /* switch to runtime paging */ + movq %r8, %cr3 + + /* switch to runtime gdt */ + lgdt (%rdi) + lidt (%rsi) + + /* + * the structure of sl GDT and runtime gdt are mostly the same, so no need + * to change segment etc. + */ + + /* set segment registers (should be no-op) */ + movw $(__DS), %ax + movw %ax, %ss + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + + /* initialize runtime stack */ + movq %rcx, %rsp + + /* clear flags */ + pushq $0 + popf + + /* jump to runtime entry point */ + jmpq *%rdx diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/arch/x86/sl-x86-i386-entry.S b/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/arch/x86/sl-x86-i386-entry.S new file mode 100644 index 0000000000..9d2e0dc50f --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/arch/x86/sl-x86-i386-entry.S @@ -0,0 +1,346 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/* EMHF secure loader component entry point + authors: amit vasudevan (amitvasudevan@acm.org) and jonmccune@cmu.edu +*/ + +#include + +/*---------------------------------------------------------------------- + CODE +---------------------------------------------------------------------- + +our C main*/ + +.extern xmhf_sl_main + +/* The first 3 pages of the SL serve different purposes depending on + whether the system has an AMD or Intel CPU. On an AMD system, the + first four bytes of the first page comprise the SLB Header. The + remainder goes to waste (3*4K-4B). + + On Intel, these first three pages are used as the MLE Page Tables. + These are constructed in software with the txt.c:build_mle_pagetable() + function. The AMD header will be clobbered in the process. + + These 3 pages are placed at the very beginning of the SL (byte 0) + by our linker script. Our SL is always padded to 64K in size + regardless of the actual size of the code or data. The linker + relocation base for our SL is always 0. The SL must be position- + independent. */ + +.section .sl_header, "aw" + .global _mle_page_table_start + _mle_page_table_start: + + .global _sl_header + _sl_header: /* AMD-specific header format for Secure Loader Block (SLB). */ + .word _sl_start /* SL entry point relative to header (bits 0-15).*/ + .word 0xFFFF /*SL size including the header (bits 16-32),*/ + /*i.e, 0 through 65535 inclusive = 64K */ + + + /* Three 4K pages to hold the "MLE page tables" for an Intel-specific + DRTM using GETSEC[SENTER]. See 2.2.4.1 in Intel MLE + Developer's Guide (Dec. 2009 revision).*/ + .align 4096 // remainder of first page + + .global g_sl_protected_dmabuffer + g_sl_protected_dmabuffer: + .fill 4096, 1, 0 /* second page*/ + .fill 4096, 1, 0 /* third page*/ + .global _mle_page_table_end + _mle_page_table_end: + + +.section .text + /* Make room for MLE header at beginning*/ + .global _mle_hdr + _mle_hdr: + .fill TEMPORARY_MAX_MLE_HEADER_SIZE, 1, 0x90 /* XXX TODO just a guess; should really be sizeof(mle_hdr_t) */ + + .global _sl_start + _sl_start: + +#ifndef PERF_CRIT + /*get cycle count using rdtsc; useful to evaluate how long DRTM + takes*/ + cpuid /*Serializing instruction; causes more overhead :(*/ + rdtsc + pushl %edx + pushl %eax +#endif + + /*save EAX, for AMD and the stub SENTER DRTM this contains the + 64K aligned physical memory address where the sl was loaded + movl %eax, %ebp + AMD leaves base addr in EAX, but Intel does not. Since both CS and SS + are valid, read and align EIP to discover base addr + + Figure out our own base address and place into EAX. + On AMD, this value is already in EAX. However, on Intel + it is not guaranteed to be available (*might* be in ECX; + TODO is to check whether ECX value is reliable on Intel). + Cross-processor solution is call/pop/align.*/ + call 1f +1: popl %eax // put EIP into EAX + andl $0xffff0000, %eax // 64K-align + movl %eax, %ebp + + /*Other assumptions: common to both Intel and AMD: + EFLAGS_IF=0 (GIF=0 on AMD) so we are running with no interruptions + CR0.PG=0, i.e., paging is off*/ + + /* Determine processor type to perform some low-level initialization + after DRTM. On AMD CPUs, we need to clear R_INIT, DIS_A20M and + CR_DPD (to enable HDT access) in VM_CR_MSR.*/ +sl_cpu_vendor: + xor %eax, %eax + cpuid + cmpl $(INTEL_STRING_DWORD1), %ebx + jne sl_cpu_vendor_notintel + cmpl $(INTEL_STRING_DWORD2), %edx + jne sl_cpu_vendor_notintel + cmpl $(INTEL_STRING_DWORD3), %ecx + jne sl_cpu_vendor_notintel + movl $(CPU_VENDOR_INTEL), %esi + jmp sl_cpu_intel + sl_cpu_vendor_notintel: + cmpl $(AMD_STRING_DWORD1), %ebx + jne sl_cpu_vendor_unknown + cmpl $(AMD_STRING_DWORD2), %edx + jne sl_cpu_vendor_unknown + cmpl $(AMD_STRING_DWORD3), %ecx + jne sl_cpu_vendor_unknown + movl $(CPU_VENDOR_AMD), %esi + jmp sl_cpu_amd + sl_cpu_vendor_unknown: + //this should never happen, but we have a fallback in case + ud2 + hlt + + /* If AMD CPU enable a few things that SKINIT disables. + Enable HDT debugging, also clear R_INIT and DIS_A20M. + XXX TODO Disable HDT debugging; represents a security vulnerability*/ +sl_cpu_amd: + movl $(VM_CR_MSR), %ecx + rdmsr + andl $(~(1< + +.section .text +/*------------------------------------------------------------------------------*/ + .global xmhf_sl_arch_x86_invoke_runtime_entrypoint +xmhf_sl_arch_x86_invoke_runtime_entrypoint: +/*------------------------------------------------------------------------------*/ + /*turn on paging*/ + movl $(0x00000030), %eax //CR4_PAE | CR4_PSE + movl %eax, %cr4 + movl 0x14(%esp), %edi //EDI = page table base address + movl %edi, %cr3 + movl $(0x80000015), %eax // ET, EM, PE, PG + movl %eax, %cr0 //turn on paging + + /*grab gdtbase and idtbase parameters*/ + movl 0x4(%esp), %esi + movl 0x8(%esp), %edi + + /*load runtime gdt and idt*/ + subl $0x8, %esp + + movw %fs:(%esi), %ax + movw %ax, (%esp) + movl %fs:0x2(%esi), %eax + movl %eax, 0x2(%esp) + + lgdt (%esp) + + movw %fs:(%edi), %ax + movw %ax, (%esp) + movl %fs:0x2(%edi), %eax + movl %eax, 0x2(%esp) + + lidt (%esp) + + addl $0x8, %esp + + /*grab entrypoint and topofstack parameters*/ + movl 0xC(%esp), %edi + movl 0x10(%esp), %esi + + /*load runtime segment selectors*/ + movw $(__DS), %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + + /*initialize runtime stack*/ + movw %ax, %ss + movl %esi,%esp + + /*clear flags*/ + pushl $0 + popf + + /*far jump to runtime entry point*/ + pushl $(__CS) + pushl %edi + lret diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/arch/x86/sl-x86.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/arch/x86/sl-x86.c new file mode 100644 index 0000000000..47ccb6cf03 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/arch/x86/sl-x86.c @@ -0,0 +1,379 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +/** + * sl-x86.c + * EMHF secure loader x86 arch. backend + * author: amit vasudevan (amitvasudevan@acm.org) + */ + +#include + + +//we only have confidence in the runtime's expected value here in the SL +//static INTEGRITY_MEASUREMENT_VALUES g_sl_gold /* __attribute__(( section("") )) */ = { +// .sha_runtime = ___RUNTIME_INTEGRITY_HASH___, +// .sha_slabove64K = BAD_INTEGRITY_HASH, +// .sha_slbelow64K = BAD_INTEGRITY_HASH +//}; + +#ifdef __AMD64__ +/* Access page table as an array */ +extern u64 sl_pdt[2048]; + +/* Used to access physical addresses in C code */ +extern u32 xmhf_baseplatform_arch_flat_va_offset; + +/* Setup paging for secureloader */ +void xmhf_setup_sl_paging(u32 baseaddr) { + u64 default_flags; + xmhf_baseplatform_arch_flat_va_offset = baseaddr; + /* + * The first page (contains sl code and stack) is set up by assembly. + * This function sets up paging for the rest virtual pages (up to 4 GiB). + */ + default_flags = (u64)(_PAGE_PRESENT | _PAGE_RW | _PAGE_PSE); + for (u64 i = 1; i < (PAGE_ALIGN_UP_2M(ADDR_4GB) >> PAGE_SHIFT_2M); i++) { + u64 sla = (i << PAGE_SHIFT_2M); + u64 hva = sla + (u64)baseaddr; + hva &= ADDR_4GB - 1ULL; /* wrap around for low physical addresses */ + sl_pdt[i] = p4l_make_pde_big(hva, default_flags); + } +} +#elif !defined(__I386__) + #error "Unsupported Arch" +#endif /* !defined(__I386__) */ + +#ifndef __XMHF_VERIFICATION__ + +#ifdef __AMD64__ +//---runtime paging setup------------------------------------------------------- +//build a 4-level paging that identity maps the lowest 4GiB memory +//returns 64-bit address of PML4 Table (can be loaded into CR3) +u64 xmhf_sl_arch_x86_setup_runtime_paging(RPB *rpb, spa_t runtime_spa, hva_t runtime_sva, hva_t totalsize) +{ + pml4t_t xpml4; + pdpt_t xpdpt; + pdt_t xpdt; + u64 i, default_flags; + + printf("\nSL (%s): runtime_spa=%016lx, runtime_sva=%016lx, totalsize=%016lx", + __FUNCTION__, runtime_spa, runtime_sva, totalsize); + + HALT_ON_ERRORCOND(runtime_spa == runtime_sva); + HALT_ON_ERRORCOND(runtime_spa < ADDR_4GB); + HALT_ON_ERRORCOND(totalsize < ADDR_4GB); + HALT_ON_ERRORCOND(runtime_spa + totalsize < ADDR_4GB); + + xpml4= hva2sla((void *)rpb->XtVmmPml4Base); + xpdpt= hva2sla((void *)rpb->XtVmmPdptBase); + xpdt = hva2sla((void *)rpb->XtVmmPdtsBase); + + printf("\n\tpa xpml4=0x%p, xpdpt=0x%p, xpdt=0x%p", xpml4, xpdpt, xpdt); + + /* PML4E -> PDPT */ + default_flags = (u64)(_PAGE_PRESENT | _PAGE_RW); + for (i = 0; i < (PAGE_ALIGN_UP_512G(MAX_PHYS_ADDR) >> PAGE_SHIFT_512G); i++) { + u64 pdpt_spa = sla2spa((void *)xpdpt) + (i << PAGE_SHIFT_4K); + xpml4[i] = p4l_make_plm4e(pdpt_spa, default_flags); + } + + /* PDPTE -> PDT */ + default_flags = (u64)(_PAGE_PRESENT | _PAGE_RW); + for (i = 0; i < (PAGE_ALIGN_UP_1G(MAX_PHYS_ADDR) >> PAGE_SHIFT_1G); i++) { + u64 pdt_spa = sla2spa((void *)xpdt) + (i << PAGE_SHIFT_4K); + xpdpt[i] = p4l_make_pdpe(pdt_spa, default_flags); + } + + /* PDE -> 2 MiB page */ + default_flags = (u64)(_PAGE_PRESENT | _PAGE_RW | _PAGE_PSE); + for(i = 0; i < (PAGE_ALIGN_UP_2M(MAX_PHYS_ADDR) >> PAGE_SHIFT_2M); i++) { + hva_t hva = i << PAGE_SHIFT_2M; + spa_t spa = hva2spa((void *)hva); + u64 flags = default_flags; + if(spa == 0xfee00000 || spa == 0xfec00000) { + // Unity-map some MMIO regions with Page Cache disabled + // 0xfed00000 contains Intel TXT config regs & TPM MMIO + // 0xfee00000 contains LAPIC base + HALT_ON_ERRORCOND(hva == spa); // expecting these to be unity-mapped + flags |= (u64)(_PAGE_PCD); + } + xpdt[i] = p4l_make_pde_big(spa, flags); + } + + return sla2spa((void *)xpml4); +} +#elif defined(__I386__) +//---runtime paging setup------------------------------------------------------- +//physaddr and virtaddr are assumed to be 2M aligned +//returns 32-bit base address of page table root (can be loaded into CR3) +u32 xmhf_sl_arch_x86_setup_runtime_paging(RPB *rpb, u32 runtime_spa, u32 runtime_sva, u32 totalsize){ + pdpt_t xpdpt; + pdt_t xpdt; + hva_t hva=0; + u32 i; + u64 default_flags; + + printf("\nSL (%s): runtime_spa=%08x, runtime_sva=%08x, totalsize=%08x", + __FUNCTION__, runtime_spa, runtime_sva, totalsize); + + xpdpt= hva2sla((void *)rpb->XtVmmPdptBase); + xpdt = hva2sla((void *)rpb->XtVmmPdtsBase); + + printf("\n pa xpdpt=0x%p, xpdt=0x%p", xpdpt, xpdt); + + default_flags = (u64)(_PAGE_PRESENT); + + //init pdpt + for(i = 0; i < PAE_PTRS_PER_PDPT; i++) { + u64 pdt_spa = sla2spa((void *)xpdt) + (i << PAGE_SHIFT_4K); + xpdpt[i] = pae_make_pdpe(pdt_spa, default_flags); + } + + //init pdts with unity mappings + default_flags = (u64)(_PAGE_PRESENT | _PAGE_RW | _PAGE_PSE); + for(i = 0, hva = 0; + i < (ADDR_4GB >> (PAE_PDT_SHIFT)); + i ++, hva += PAGE_SIZE_2M) { + u64 spa = hva2spa((void*)hva); + u64 flags = default_flags; + + if(spa == 0xfee00000 || spa == 0xfec00000) { + //Unity-map some MMIO regions with Page Cache disabled + //0xfed00000 contains Intel TXT config regs & TPM MMIO + //0xfee00000 contains LAPIC base + HALT_ON_ERRORCOND(hva==spa); // expecting these to be unity-mapped + flags |= (u64)(_PAGE_PCD); + } + + xpdt[i] = pae_make_pde_big(spa, flags); + } + + return sla2spa((void *)xpdpt); +} +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + +#endif //__XMHF_VERIFICATION__ + + +/* XXX TODO Read PCR values and sanity-check that DRTM was successful + * (i.e., measurements match expectations), and integrity-check the + * runtime. */ +/* Note: calling this *before* paging is enabled is important. */ +/*bool xmhf_sl_arch_integrity_check(u8* runtime_base_addr, size_t runtime_len) { + int ret; + u32 locality = EMHF_TPM_LOCALITY_PREF; + tpm_pcr_value_t pcr17, pcr18; + (void)g_sl_gold; + + print_hex("SL: Golden Runtime SHA-1: ", g_sl_gold.sha_runtime, SHA_DIGEST_LENGTH); + + printf("\nSL: CR0 %08lx, CD bit %ld", read_cr0(), read_cr0() & CR0_CD); + hashandprint("SL: Computed Runtime SHA-1: ", + runtime_base_addr, runtime_len); + + if(xmhf_tpm_open_locality(locality)) { + printf("SL: FAILED to open TPM locality %d\n", locality); + return false; + } + + if((ret = tpm_pcr_read(locality, 17, &pcr17)) != TPM_SUCCESS) { + printf("TPM: ERROR: tpm_pcr_read FAILED with error code 0x%08x\n", ret); + return false; + } + print_hex("PCR-17: ", &pcr17, sizeof(pcr17)); + + if((ret = tpm_pcr_read(locality, 18, &pcr18)) != TPM_SUCCESS) { + printf("TPM: ERROR: tpm_pcr_read FAILED with error code 0x%08x\n", ret); + return false; + } + print_hex("PCR-18: ", &pcr18, sizeof(pcr18)); + + // free TPM so that OS driver works as expected + xmhf_tpm_arch_deactivate_all_localities(); + + return true; +} +*/ + + +#ifdef __DRT__ +void xmhf_sl_arch_sanitize_post_launch(void){ + #ifndef __XMHF_VERIFICATION__ + + if(get_cpu_vendor_or_die() == CPU_VENDOR_INTEL) { + txt_heap_t *txt_heap; + os_mle_data_t *os_mle_data; + + // sl.c unity-maps 0xfed00000 for 2M so these should work fine + txt_heap = get_txt_heap(); + printf("\nSL: txt_heap = 0x%08lx", (uintptr_t)txt_heap); + /// compensate for special DS here in SL + os_mle_data = get_os_mle_data_start((txt_heap_t*)((uintptr_t)txt_heap - sl_baseaddr)); + printf("\nSL: os_mle_data = 0x%08lx", (uintptr_t)os_mle_data); + // restore pre-SENTER MTRRs that were overwritten for SINIT launch + if(!validate_mtrrs(&(os_mle_data->saved_mtrr_state))) { + printf("\nSECURITY FAILURE: validate_mtrrs() failed.\n"); + HALT(); + } + + printf("\nSL: Restoring mtrrs..."); + + restore_mtrrs(&(os_mle_data->saved_mtrr_state)); + } + + #endif +} +#endif /* __DRT__ */ + +#ifdef __DMAP__ +void xmhf_sl_arch_early_dmaprot_init(u32 runtime_size) +{ + + { + spa_t protectedbuffer_paddr; + sla_t protectedbuffer_vaddr; + u32 protectedbuffer_size; + spa_t memregionbase_paddr; + u32 memregion_size; + u32 cpu_vendor = get_cpu_vendor_or_die(); + + HALT_ON_ERRORCOND(cpu_vendor == CPU_VENDOR_AMD || cpu_vendor == CPU_VENDOR_INTEL); + + + if(cpu_vendor == CPU_VENDOR_AMD){ + protectedbuffer_paddr = sl_baseaddr + (sla_t)&g_sl_protected_dmabuffer; + protectedbuffer_vaddr = (sla_t)&g_sl_protected_dmabuffer; + protectedbuffer_size = (2 * PAGE_SIZE_4K); + }else{ //CPU_VENDOR_INTEL + protectedbuffer_paddr = sl_baseaddr + 0x100000; + protectedbuffer_vaddr = 0x100000; + protectedbuffer_size = (2 * PAGE_SIZE_4K); + } + + memregionbase_paddr = sl_baseaddr; + memregion_size = (runtime_size + PAGE_SIZE_2M); + + printf("\nSL: Initializing DMA protections..."); + + + if(!xmhf_dmaprot_earlyinitialize(protectedbuffer_paddr, + protectedbuffer_vaddr, protectedbuffer_size, + memregionbase_paddr, memregion_size)){ + printf("\nSL: Fatal, could not initialize DMA protections. Halting!"); + HALT(); + } + + printf("\nSL: Initialized DMA protections successfully"); + + } + +} +#endif /* __DMAP__ */ + + +void xmhf_sl_arch_xfer_control_to_runtime(RPB *rpb){ + u32 ptba; //page table base address + TSSENTRY *t; + hva_t tss_base; + hva_t gdt_base; + + #ifndef __XMHF_VERIFICATION__ + //setup runtime TSS + tss_base=(hva_t)rpb->XtVmmTSSBase; + gdt_base= *(hva_t *)(hva2sla((void *)(rpb->XtVmmGdt + 2))); + #else + tss_base=PAGE_SIZE_2M+PAGE_SIZE_4K; + gdt_base=PAGE_SIZE_2M+PAGE_SIZE_4K+2048; + #endif + + //fix TSS descriptor, 18h + t= (TSSENTRY *)((hva_t)(hva2sla((void *)gdt_base)) + __TRSEL ); + t->attributes1= 0x89; + t->limit16_19attributes2= 0x10; +#ifdef __AMD64__ + t->baseAddr0_15= (u16)(tss_base & 0x000000000000FFFF); + t->baseAddr16_23= (u8)((tss_base & 0x0000000000FF0000) >> 16); + t->baseAddr24_31= (u8)((tss_base & 0x00000000FF000000) >> 24); + t->baseAddr32_63= (u32)((tss_base & 0xFFFFFFFF00000000) >> 32); +#elif defined(__I386__) + t->baseAddr0_15= (u16)(tss_base & 0x0000FFFF); + t->baseAddr16_23= (u8)((tss_base & 0x00FF0000) >> 16); + t->baseAddr24_31= (u8)((tss_base & 0xFF000000) >> 24); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + t->limit0_15=0x67; + printf("\nSL: setup runtime TSS."); + + #ifndef __XMHF_VERIFICATION__ + //setup paging structures for runtime + ptba=xmhf_sl_arch_x86_setup_runtime_paging(rpb, rpb->XtVmmRuntimePhysBase, __TARGET_BASE, PAGE_ALIGN_UP_2M(rpb->XtVmmRuntimeSize)); + #endif + + printf("\nSL: setup runtime paging structures."); + + printf("\nTransferring control to runtime"); + //printf("\nGDT=%08x, IDT=%08x, EntryPoint=%08x", rpb->XtVmmGdt, rpb->XtVmmIdt, rpb->XtVmmEntryPoint); + //printf("\nTop-of-stack=%08x, CR3=%08x", (rpb->XtVmmStackBase+rpb->XtVmmStackSize), ptba); + + + #ifndef __XMHF_VERIFICATION__ + //transfer control to runtime and never return + xmhf_sl_arch_x86_invoke_runtime_entrypoint(rpb->XtVmmGdt, rpb->XtVmmIdt, +#ifdef __AMD64__ + rpb->XtVmmEntryPoint, (rpb->XtVmmStackBase+rpb->XtVmmStackSize), ptba, sla2spa((void *)0)); +#elif defined(__I386__) + rpb->XtVmmEntryPoint, (rpb->XtVmmStackBase+rpb->XtVmmStackSize), ptba); +#else /* !defined(__I386__) && !defined(__AMD64__) */ + #error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + #else + return; + #endif +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/arch/x86/tempdebug/sl-x86-entry.S.debug b/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/arch/x86/tempdebug/sl-x86-entry.S.debug new file mode 100644 index 0000000000..f2280b4fef --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/arch/x86/tempdebug/sl-x86-entry.S.debug @@ -0,0 +1,456 @@ +// EMHF secure loader component entry point +// authors: amit vasudevan (amitvasudevan@acm.org) and jonmccune@cmu.edu + +#include + +///--- ALL COMMENTS BEGINNING WITH ///--- ARE RELATED TO JON'S +///--- EFFORTS TO DEBUG SENTER SUPPORT. LEAVING THEM IN FOR NOW. +///--- THEY CAN BE REMOVED ONCE I HARVEST THE USEFUL DEBUG SNIPPETS +///--- TO ANOTHER LOCATION + +///--- .macro OUT2VGA +///--- movl %ecx, %eax +///--- rol $8, %eax +///--- call dumpal +///--- movl %ecx, %eax +///--- rol $16, %eax +///--- call dumpal +///--- movl %ecx, %eax +///--- rol $24, %eax +///--- call dumpal +///--- movl %ecx, %eax +///--- call dumpal +///--- call aspace +///--- .endm + + +//our C main +.extern slmain + +/* The first 3 pages of the SL serve different purposes depending on + whether the system has an AMD or Intel CPU. On an AMD system, the + first four bytes of the first page comprise the SLB Header. The + remainder goes to waste (3*4K-4B). + + On Intel, these first three pages are used as the MLE Page Tables. + These are constructed in software with the txt.c:build_mle_pagetable() + function. The AMD header will be clobbered in the process. + + These 3 pages are placed at the very beginning of the SL (byte 0) + by our linker script. Our SL is always padded to 64K in size + regardless of the actual size of the code or data. The linker + relocation base for our SL is always 0. The SL must be position- + independent. */ + +.section .sl_header, "aw" + .global _mle_page_table_start + _mle_page_table_start: + + .global _sl_header + _sl_header: // AMD-specific header format for Secure Loader Block (SLB). + .word _sl_start // SL entry point relative to header (bits 0-15). + .word 0xFFFF // SL size including the header (bits 16-32), + // i.e, 0 through 65535 inclusive = 64K + + + // Three 4K pages to hold the "MLE page tables" for an Intel-specific + // DRTM using GETSEC[SENTER]. See 2.2.4.1 in Intel MLE + // Developer's Guide (Dec. 2009 revision). + .align 4096 // remainder of first page + + .global g_sl_protected_dmabuffer + g_sl_protected_dmabuffer: + .fill 4096, 1, 0 // second page + .fill 4096, 1, 0 // third page + .global _mle_page_table_end + _mle_page_table_end: + + +.section .text + // Make room for MLE header at beginning + .global _mle_hdr + _mle_hdr: + .fill TEMPORARY_MAX_MLE_HEADER_SIZE, 1, 0x90 ///XXX TODO just a guess; should really be sizeof(mle_hdr_t) + + .global _sl_start + _sl_start: + +///--- // LET'S FIGURE OUT REG VALUES UPON ENTRY INTO MLE (ON INTEL) +///--- pushl %eax +///--- pushl %ebx +///--- pushl %ecx +///--- pushl %edx +///--- pushl %edi +///--- pushl %esi +///--- pushl %esp +///--- pushl %ebp + + + //Get cycle count using rdtsc; useful to evaluate how long DRTM + //takes +#ifndef PERF_CRIT + cpuid // Serializing instruction; causes more overhead :( + rdtsc + pushl %edx + pushl %eax +#endif + //save EAX, for AMD and the stub SENTER DRTM this contains the + //64K aligned physical memory address where the sl was loaded + // movl %eax, %ebp + // AMD leaves base addr in EAX, but Intel does not. Since both CS and SS + // are valid, read and align EIP to discover base addr + + // Figure out our own base address and place into EAX. + // On AMD, this value is already in EAX. However, on Intel + // it is not guaranteed to be available (*might* be in ECX; + // TODO is to check whether ECX value is reliable on Intel). + // Cross-processor solution is call/pop/align. + call 1f +1: popl %eax // put EIP into EAX + andl $0xffff0000, %eax // 64K-align + movl %eax, %ebp + + // Other assumptions: common to both Intel and AMD: + // EFLAGS_IF=0 (GIF=0 on AMD) so we are running with no interruptions + // CR0.PG=0, i.e., paging is off + + + // Determine processor type to perform some low-level initialization + // after DRTM. On AMD CPUs, we need to clear R_INIT, DIS_A20M and + // CR_DPD (to enable HDT access) in VM_CR_MSR. +sl_cpu_vendor: + xor %eax, %eax + cpuid + cmpl $(INTEL_STRING_DWORD1), %ebx + jne sl_cpu_vendor_notintel + cmpl $(INTEL_STRING_DWORD2), %edx + jne sl_cpu_vendor_notintel + cmpl $(INTEL_STRING_DWORD3), %ecx + jne sl_cpu_vendor_notintel + movl $(CPU_VENDOR_INTEL), %esi + jmp sl_cpu_intel + sl_cpu_vendor_notintel: + cmpl $(AMD_STRING_DWORD1), %ebx + jne sl_cpu_vendor_unknown + cmpl $(AMD_STRING_DWORD2), %edx + jne sl_cpu_vendor_unknown + cmpl $(AMD_STRING_DWORD3), %ecx + jne sl_cpu_vendor_unknown + movl $(CPU_VENDOR_AMD), %esi + jmp sl_cpu_amd + sl_cpu_vendor_unknown: + //this should never happen, but we have a fallback in case + ud2 + hlt + + // If AMD CPU enable a few things that SKINIT disables. + // Enable HDT debugging, also clear R_INIT and DIS_A20M. + //XXX TODO Disable HDT debugging; represents a security vulnerability +sl_cpu_amd: + movl $(VM_CR_MSR), %ecx + rdmsr + andl $(~(1< 0x3132 +///--- mov %al, %ah // duplicate byte +///--- and $0x0f, %al // keep only low nibble +///--- shr $4, %ah // shift right to access high nibble +///--- and $0x0f, %ah // keep only low nibble +///--- low: +///--- cmp $0xa, %al +///--- jge lowletter +///--- lowdigit: +///--- add $0x30, %al // convert digit from numerical value to ASCII +///--- jmp high +///--- lowletter: +///--- add $0x57, %al // convert digit from numerical value to ASCII + +///--- high: +///--- cmp $0xa, %ah +///--- jge highletter +///--- highdigit: +///--- add $0x30, %ah +///--- ret +///--- highletter: +///--- add $0x57, %ah // - 0xa + 'a' +///--- ret + +///--- nomoredebug: +///--- jmp nomoredebug +///--- //-- END DEBUG STUFF --------------------------- + + +.section .data + + //the secure loader GDT + sl_gdt: + .word sl_gdt_end - sl_gdt_start + 1 // XXX WAS PREVIOUSLY -1 !!! + .long sl_gdt_start // This will be fixed up to sl load-base + .align 16 + sl_gdt_start: + .quad 0x0000000000000000 //0x00: NULL selector +// .quad 0x00409a000000ffff //0x08: 64K CODE selector +// .quad 0x004092000000ffff //0x10: 64K DATA selector + .quad 0x00cf9a000000ffff //0x08: 4G CODE selector with sl load-base + .quad 0x00cf92000000ffff //0x10: 4G DATA selector with sl load-base + .quad 0x00cf92000000ffff //0x18: 4G DATA selector with zero base + .quad 0x0000000000000000 //0x20: NULL selector + sl_gdt_end: + + +// sl stack, this is just a placeholder and ensures that the linker +// actually "allocates" the stack up until 0x10000 +.section .sl_stack + .fill 4096, 1, 0 + +//this section is the input parameter section for the secure loader +//parameters from "init" are placed here. ordering of the variables +//MUST match that in include/target.h +//this section is currently a pagesize in length and resides above +//the 64K sl image +//.section .sl_params + +// .global slpb_buffer +// slpb_buffer: +// .long SL_PARAMETER_BLOCK_MAGIC //magic +// .long 0 //hashSL +// .long 0 //errorHandler +// .long 0 //isEarlyInit +// .long 0 //numE820Entries +// .fill (SIZE_STRUCT_GRUBE820 * MAX_E820_ENTRIES), 1, 0 //grub E820 map buffer +// .long 0 //numCPUEntries +// .fill (SIZE_STRUCT_PCPU * MAX_PCPU_ENTRIES), 1, 0 //cpu table buffer +// .long 0 //size of the runtime image +// .long 0 //guest OS boot module base +// .long 0 //guest OS boot module size + + +//---------------------------------------------------------------------- +// DEBUG CODE +//---------------------------------------------------------------------- + + diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/arch/x86/tempdebug/slheader.S.crazydebug b/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/arch/x86/tempdebug/slheader.S.crazydebug new file mode 100644 index 0000000000..70926539e0 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/arch/x86/tempdebug/slheader.S.crazydebug @@ -0,0 +1,391 @@ +// secure loader support routines +// authors: amit vasudevan (amitvasudevan@acm.org) and jonmccune@gmail.com + +#include +#include +#include +#include + +.macro OUT2VGA + movl %ecx, %eax + rol $8, %eax + call dumpal + movl %ecx, %eax + rol $16, %eax + call dumpal + movl %ecx, %eax + rol $24, %eax + call dumpal + movl %ecx, %eax + call dumpal + call aspace +.endm + + +//our C main +.extern slmain +.extern serial_putc + +/* The first 3 pages of the SL serve different purposes depending on + whether the system has an AMD or Intel CPU. On an AMD system, the + first four bytes of the first page comprise the SLB Header. The + remainder goes to waste (3*4K-4B). + + On Intel, these first three pages are used as the MLE Page Tables. + These are constructed in software with the txt.c:build_mle_pagetable() + function. The AMD header will be clobbered in the process. + + These 3 pages are placed at the very beginning of the SL (byte 0) + by our linker script. Our SL is always padded to 64K in size + regardless of the actual size of the code or data. The linker + relocation base for our SL is always 0. The SL must be position- + independent. */ + +.section .sl_header + .global _mle_page_table_start + _mle_page_table_start: + + .global _sl_header + _sl_header: // AMD-specific header format for Secure Loader Block (SLB) + .word _sl_start //SL entry point relative to header (bits 0-15) + .word 0xFFFF //SL size including the header (bits 16-32) + //i.e, 0 through 65535 inclusive = 64K + + + // Three 4K pages to hold the "MLE page tables" for an Intel-specific + // DRTM using GETSEC[SENTER]. See 2.2.4.1 in Intel MLE + // Developer's Guide (Dec. 2009 revision). + .align 4096 // remainder of first page + .fill 4096, 1, 0 // second page + .fill 4096, 1, 0 // third page + .global _mle_page_table_end + _mle_page_table_end: + + +.section .text + // Make room for MLE header at beginning + .global _mle_hdr + _mle_hdr: + .fill TEMPORARY_MAX_MLE_HEADER_SIZE, 1, 0x90 ///XXX TODO just a guess; should really be sizeof(mle_hdr_t) + + + .global _sl_start + _sl_start: + + // LET'S FIGURE OUT REG VALUES UPON ENTRY HERE (ON INTEL) + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + pushl %edi + pushl %esi + pushl %esp + pushl %ebp + + //save EAX, for AMD and the stub SENTER DRTM this contains the + //64K aligned physical memory address where the sl was loaded +// movl %eax, %ebp + // AMD leaves base addr in EAX, but Intel does not. Since both CS and SS + // are valid, read and align EIP to discover base addr + call 1f +1: popl %eax // put EIP into EAX + andl $0xffff0000, %eax // 64K-align + movl %eax, %ebp + + /*** DELAY OF ABOUT 15 seconds ***/ +// movl $0x0, %edx +// movl $0x5, %ecx // this line affects delay +// outer: movl $0x0, %eax +// movl $0xffffffff, %ebx +// inner: addl $0x1, %eax +// cmp %ebx, %eax +// jne inner +// addl $0x1, %edx +// cmp %ecx, %edx +// jne outer + + //other assumptions: common to both Intel and AMD (?) + //CS and SS as flat code and data segment selectors + //EFLAGS_IF=0 (GIF=0 on AMD) so we are running with no interruptions + //CR0.PG= 0 i.e, paging is off + + + //determine processor type, we need to perform some low-level inits + //after DRTM depending on the processor. for example on the AMD CPUs + //we need to clear R_INIT, DIS_A20M and CR_DPD in VM_CR_MSR +sl_cpu_vendor: + xor %eax, %eax + cpuid + cmpl $(INTEL_STRING_DWORD1), %ebx + jne sl_cpu_vendor_notintel + cmpl $(INTEL_STRING_DWORD2), %edx + jne sl_cpu_vendor_notintel + cmpl $(INTEL_STRING_DWORD3), %ecx + jne sl_cpu_vendor_notintel + movl $(CPU_VENDOR_INTEL), %esi + jmp sl_cpu_vendor_done + sl_cpu_vendor_notintel: + cmpl $(AMD_STRING_DWORD1), %ebx + jne sl_cpu_vendor_unknown + cmpl $(AMD_STRING_DWORD2), %edx + jne sl_cpu_vendor_unknown + cmpl $(AMD_STRING_DWORD3), %ecx + jne sl_cpu_vendor_unknown + movl $(CPU_VENDOR_AMD), %esi + jmp sl_cpu_vendor_done + sl_cpu_vendor_unknown: + //this should never happen, but we have a fallback in case + ud2 + hlt + sl_cpu_vendor_done: + //%esi contains vendor CPU_VENDOR_INTEL or CPU_VENDOR_AMD + + //if AMD CPU enable a few things that SKINIT disables + //enable HDT debugging, also clear R_INIT and DIS_A20M + //XXX TODO Disable HDT debugging; represents a security vulnerability + cmpl $(CPU_VENDOR_AMD), %esi + jne sl_cpu_intel +sl_cpu_amd: + movl $(VM_CR_MSR), %ecx + rdmsr + andl $(~(1< 0x3132 + mov %al, %ah // duplicate byte + and $0x0f, %al // keep only low nibble + shr $4, %ah // shift right to access high nibble + and $0x0f, %ah // keep only low nibble +low: + cmp $0xa, %al + jge lowletter +lowdigit: + add $0x30, %al // convert digit from numerical value to ASCII + jmp high +lowletter: + add $0x57, %al // convert digit from numerical value to ASCII + +high: + cmp $0xa, %ah + jge highletter +highdigit: + add $0x30, %ah + ret +highletter: + add $0x57, %ah // - 0xa + 'a' + ret + +nomoredebug: + jmp nomoredebug +//-- END DEBUG STUFF --------------------------- + + +.section .data + + //the secure loader GDT + sl_gdt: + .word sl_gdt_end - sl_gdt_start + 1 // XXX WAS PREVIOUSLY -1 !!! + .long sl_gdt_start //this will be fixed up to sl load-base + .align 16 + sl_gdt_start: + .quad 0x0000000000000000 //0x00: NULL selector +// .quad 0x00409a000000ffff //0x08: 64K CODE selector +// .quad 0x004092000000ffff //0x10: 64K DATA selector + .quad 0x00cf9a000000ffff //0x08: 4G CODE selector with sl load-base + .quad 0x00cf92000000ffff //0x10: 4G DATA selector with sl load-base + .quad 0x00cf92000000ffff //0x18: 4G DATA selector with zero base + .quad 0x0000000000000000 //0x20: NULL selector + sl_gdt_end: + + +//sl stack, this is just a placeholder and ensures that the linker +//actually "allocates" the stack up until 0x10000 +.section .sl_stack + .fill 4096, 1, 0 + +//this section is the input parameter section for the secure loader +//parameters from "init" are placed here. ordering of the variables +//MUST match that in include/target.h +//this section is currently a pagesize in length and resides above +//the 64K sl image +//.section .sl_params + +// .global slpb_buffer +// slpb_buffer: +// .long SL_PARAMETER_BLOCK_MAGIC //magic +// .long 0 //hashSL +// .long 0 //errorHandler +// .long 0 //isEarlyInit +// .long 0 //numE820Entries +// .fill (SIZE_STRUCT_GRUBE820 * MAX_E820_ENTRIES), 1, 0 //grub E820 map buffer +// .long 0 //numCPUEntries +// .fill (SIZE_STRUCT_PCPU * MAX_PCPU_ENTRIES), 1, 0 //cpu table buffer +// .long 0 //size of the runtime image +// .long 0 //guest OS boot module base +// .long 0 //guest OS boot module size diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/sl.c b/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/sl.c new file mode 100644 index 0000000000..575da623cd --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/sl.c @@ -0,0 +1,214 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +//sl.c +//secure loader implementation +//author: amit vasudevan (amitvasudevan@acm.org) + +#include + +RPB * rpb; +u32 sl_baseaddr=0; + +//this is the SL parameter block and is placed in a seperate UNTRUSTED +//section. It is populated by the "init" (late or early) loader, which +//uses the late-launch mechanism to load the SL +struct _sl_parameter_block slpb __attribute__(( section(".sl_untrusted_params") )) = { + .magic = SL_PARAMETER_BLOCK_MAGIC, +}; + + +//we get here from slheader.S +// rdtsc_* are valid only if PERF_CRIT is not defined. slheader.S +// sets them to 0 otherwise. +void xmhf_sl_main(u32 cpu_vendor, u32 baseaddr, u32 rdtsc_eax, u32 rdtsc_edx){ + + + u32 runtime_physical_base; + u32 runtime_size_2Maligned; + +#ifdef __AMD64__ + xmhf_setup_sl_paging(baseaddr); +#elif !defined(__I386__) + #error "Unsupported Arch" +#endif /* !defined(__I386__) */ + + //linker relocates sl image starting from 0, so + //parameter block must be at offset 0x10000 + HALT_ON_ERRORCOND( (sla_t)&slpb == 0x10000 ); + + //do we have the required MAGIC? + HALT_ON_ERRORCOND( slpb.magic == SL_PARAMETER_BLOCK_MAGIC); + + //we currently only support x86 (AMD and Intel) + HALT_ON_ERRORCOND (cpu_vendor == CPU_VENDOR_AMD || cpu_vendor == CPU_VENDOR_INTEL); + + //initialize debugging early on + xmhf_debug_init((char *)&slpb.uart_config); + + //initialze sl_baseaddr variable and print its value out + sl_baseaddr = baseaddr; + + //is our launch before the OS has been loaded (early) is loaded or + //is it after the OS has been loaded (late) + if(slpb.isEarlyInit) + printf("\nSL(early-init): at 0x%08x, starting...", sl_baseaddr); + else + printf("\nSL(late-init): at 0x%08x, starting...", sl_baseaddr); + + //debug: dump SL parameter block + printf("\nSL: slpb at = 0x%08lx", (sla_t)&slpb); + printf("\n errorHandler=0x%08x", slpb.errorHandler); + printf("\n isEarlyInit=0x%08x", slpb.isEarlyInit); + printf("\n numE820Entries=%u", slpb.numE820Entries); + printf("\n system memory map buffer at 0x%08lx", (sla_t)&slpb.memmapbuffer); + printf("\n numCPUEntries=%u", slpb.numCPUEntries); + printf("\n cpuinfo buffer at 0x%08lx", (sla_t)&slpb.cpuinfobuffer); + printf("\n runtime size= %u bytes", slpb.runtime_size); + printf("\n OS bootmodule at 0x%08x, size=%u bytes", + slpb.runtime_osbootmodule_base, slpb.runtime_osbootmodule_size); + printf("\n OS boot_drive is 0x%02x", (u32)slpb.runtime_osbootdrive); + printf("\n\tcmdline = \"%s\"", slpb.cmdline); + + //debug: if we are doing some performance measurements + slpb.rdtsc_after_drtm = (u64)rdtsc_eax | ((u64)rdtsc_edx << 32); + printf("\nSL: RDTSC before_drtm 0x%llx, after_drtm 0x%llx", + slpb.rdtsc_before_drtm, slpb.rdtsc_after_drtm); + printf("\nSL: [PERF] RDTSC DRTM elapsed cycles: 0x%llx", + slpb.rdtsc_after_drtm - slpb.rdtsc_before_drtm); + + //get runtime physical base + runtime_physical_base = sl_baseaddr + PAGE_SIZE_2M; //base of SL + 2M + + //compute 2M aligned runtime size + runtime_size_2Maligned = PAGE_ALIGN_UP_2M((ulong_t)slpb.runtime_size); + + printf("\nSL: runtime at 0x%08x; size=0x%08x bytes adjusted to 0x%08x bytes (2M aligned)", + runtime_physical_base, slpb.runtime_size, runtime_size_2Maligned); + + //setup runtime parameter block with required parameters + { + #ifndef __XMHF_VERIFICATION__ + //get a pointer to the runtime header and make sure its sane + rpb=(RPB *)PAGE_SIZE_2M; //runtime starts at offset 2M from sl base + #else + //setup runtime parameter block pointer + //actual definitions + extern RPB _xrpb; + rpb = (RPB *)&_xrpb; + #endif + + printf("\nSL: RPB, magic=0x%08x", rpb->magic); + HALT_ON_ERRORCOND(rpb->magic == RUNTIME_PARAMETER_BLOCK_MAGIC); + + //populate runtime parameter block fields + rpb->isEarlyInit = slpb.isEarlyInit; //tell runtime if we started "early" or "late" + + //store runtime physical and virtual base addresses along with size + rpb->XtVmmRuntimePhysBase = runtime_physical_base; + rpb->XtVmmRuntimeVirtBase = __TARGET_BASE; + rpb->XtVmmRuntimeSize = slpb.runtime_size; + + //store revised E820 map and number of entries + #ifndef __XMHF_VERIFICATION__ + memcpy(hva2sla((void *)rpb->XtVmmE820Buffer), (void *)&slpb.memmapbuffer, (sizeof(slpb.memmapbuffer)) ); + #endif + rpb->XtVmmE820NumEntries = slpb.numE820Entries; + + //store CPU table and number of CPUs + #ifndef __XMHF_VERIFICATION__ + memcpy(hva2sla((void *)rpb->XtVmmMPCpuinfoBuffer), (void *)&slpb.cpuinfobuffer, (sizeof(PCPU) * slpb.numCPUEntries) ); + #endif + rpb->XtVmmMPCpuinfoNumEntries = slpb.numCPUEntries; + + //setup guest OS boot module info in LPB + rpb->XtGuestOSBootModuleBase=(hva_t)(slpb.runtime_osbootmodule_base); + rpb->XtGuestOSBootModuleSize=(hva_t)(slpb.runtime_osbootmodule_size); + + //pass optional app module if any + rpb->runtime_appmodule_base = (hva_t)(slpb.runtime_appmodule_base); + rpb->runtime_appmodule_size = (hva_t)(slpb.runtime_appmodule_size); + + rpb->XtGuestOSBootDrive = slpb.runtime_osbootdrive; + + #if defined (__DEBUG_SERIAL__) + //pass along UART config for serial debug output + rpb->RtmUartConfig = slpb.uart_config; + #endif + + //pass command line configuration forward + COMPILE_TIME_ASSERT(sizeof(slpb.cmdline) == sizeof(rpb->cmdline)); + #ifndef __XMHF_VERIFICATION__ + strncpy(rpb->cmdline, slpb.cmdline, sizeof(slpb.cmdline)); + #endif + + } + + //initialize basic platform elements + xmhf_baseplatform_initialize(); + + //sanitize cache/MTRR/SMRAM (most important is to ensure that MTRRs + //do not contain weird mappings) +#if defined (__DRT__) + xmhf_sl_arch_sanitize_post_launch(); +#endif //__DRT__ + +#if defined (__DMAP__) + //setup DMA protection on runtime (secure loader is already DMA protected) + xmhf_sl_arch_early_dmaprot_init(slpb.runtime_size); +#endif + + //transfer control to runtime + xmhf_sl_arch_xfer_control_to_runtime(rpb); + +#ifndef __XMHF_VERIFICATION__ + //we should never get here + printf("\nSL: Fatal, should never be here!"); + HALT(); +#else + return; +#endif +} diff --git a/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/sl.lds.S b/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/sl.lds.S new file mode 100644 index 0000000000..ff97dc8558 --- /dev/null +++ b/xmhf-64/xmhf/src/xmhf-core/xmhf-secureloader/sl.lds.S @@ -0,0 +1,163 @@ +/* + * @XMHF_LICENSE_HEADER_START@ + * + * eXtensible, Modular Hypervisor Framework (XMHF) + * Copyright (c) 2009-2012 Carnegie Mellon University + * Copyright (c) 2010-2012 VDG Inc. + * All Rights Reserved. + * + * Developed by: XMHF Team + * Carnegie Mellon University / CyLab + * VDG Inc. + * http://xmhf.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the names of Carnegie Mellon or VDG Inc, nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @XMHF_LICENSE_HEADER_END@ + */ + +#include + +/* gcc -m32 will define i386, but we do not want it */ +#ifdef i386 +#undef i386 +#endif /* i386 */ + +#ifdef __I386__ +OUTPUT_ARCH(i386) +#elif defined(__AMD64__) +OUTPUT_ARCH(i386:x86-64) +#else /* !defined(__I386__) && !defined(__AMD64__) */ +#error "Unsupported Arch" +#endif /* !defined(__I386__) && !defined(__AMD64__) */ + +ENTRY(_sl_start) + +/* Goal: constrain the size of the trusted portion of the SL to 64K. AMD + * systems limit the Secure Loader Block to 64K max. Intel permits a + * larger MLE (their name for SLB), but we want to remain compatible + * with both. + */ + +/* Useful reference: + * http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/4/html/Using_ld_the_GNU_Linker/memory.html + */ + +MEMORY +{ + low (rwxai) : ORIGIN = 0, LENGTH = 64K + high (rwxai) : ORIGIN = 64K, LENGTH = 1984K /* balance of 2M total */ + debug (rwxai) : ORIGIN = 0, LENGTH = 1024M + unaccounted (rwxai) : ORIGIN = 0, LENGTH = 0 /* see section .unaccounted at end */ +} + + +SECTIONS +{ + . = 0x00000000; + .sl_header : { + *(.sl_header) + . = ALIGN(4096); + } >low + + .text : { + *(.text) + *(.text.unlikely) + } >low + + .data : { + *(.data) + } >low + + .rodata : { + *(.rodata) + *(.rodata.str1.*) + } >low + + .bss : { + *(.bss) + /*. = ALIGN(4096);*/ + . = ALIGN(16); + } >low + + /* protected DMA protection buffer for DMA protection boot-strapping */ + /*.protdmabuffer : { + *(.protdmabuffer) + } >low*/ + + .sl_stack : { + *(.sl_stack) + . = ALIGN(0x10000); + } >low + + /* Content below is UNTRUSTED. + * SL *MUST* sanitize any data here prior to use! + */ + .sl_untrusted_params : { + *(.sl_untrusted_params) + *(.comment) + . = ALIGN(4096); + /* .sl_long_pt is only used in amd64 XMHF */ + *(.sl_long_pt) + . = ALIGN(0x200000); + } >high + + /* .eh_frame overflows our memory limits when building on some platforms. + * Shouldn't be necessary since we don't use exceptions. + */ + /DISCARD/ : { + *(.eh_frame) + *(.note.gnu.property) + *(.gnu.build.attributes) + } >low + + /* debug sections */ + .debug_abbrev : { *(.debug_abbrev) } >debug + .debug_aranges : { *(.debug_aranges) } >debug + .debug_info : { *(.debug_info) } >debug + .debug_line : { *(.debug_line) } >debug + .debug_line_str : { *(.debug_line_str) } >debug + .debug_loc : { *(.debug_loc) } >debug + .debug_loclists : { *(.debug_loclists) } >debug + .debug_ranges : { *(.debug_ranges) } >debug + .debug_rnglists : { *(.debug_rnglists) } >debug + .debug_str : { *(.debug_str) } >debug + + /* this is to cause the link to fail if there is + * anything we didn't explicitly place. + * when this does cause link to fail, temporarily comment + * this part out to see what sections end up in the output + * which are not handled above, and handle them. + */ + .unaccounted : { + *(*) + } >unaccounted +} diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/Doxyfile b/xmhf-64/xmhf/third-party/libtomcrypt/Doxyfile new file mode 100644 index 0000000000..f07c339bf7 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/Doxyfile @@ -0,0 +1,1155 @@ +# Doxyfile 1.3.9.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = LibTomCrypt + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 1.17 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc/doxygen + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of source +# files, where putting all generated files in the same directory would otherwise +# cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is used +# as the annotated text. Otherwise, the brief description is used as-is. If left +# blank, the following values are used ("$name" is automatically replaced with the +# name of the entity): "The $name class" "The $name widget" "The $name file" +# "is" "provides" "specifies" "contains" "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited +# members of a class in the documentation of that class as if those members were +# ordinary class members. Constructors, destructors and assignment operators of +# the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = src + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = src/headers + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = YES + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = YES + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = YES + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = src + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp +# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories +# that are symbolic links (a Unix filesystem feature) are excluded from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = YES + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = NO + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = doc/header.html + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = doc/footer.html + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 1 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = YES + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = src/headers + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse the +# parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. Note that this +# option is superseded by the HAVE_DOT option below. This is only a fallback. It is +# recommended to install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = NO + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes that +# lay further from the root node will be omitted. Note that setting this option to +# 1 or 2 may greatly reduce the computation time needed for large code bases. Also +# note that a graph may be further truncated if the graph's image dimensions are +# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). +# If 0 is used for the depth value (the default), the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/LICENSE b/xmhf-64/xmhf/third-party/libtomcrypt/LICENSE new file mode 100644 index 0000000000..5d678c5f4e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/LICENSE @@ -0,0 +1,5 @@ +LibTomCrypt is public domain. As should all quality software be. + +Tom St Denis + + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/README b/xmhf-64/xmhf/third-party/libtomcrypt/README new file mode 100644 index 0000000000..1e1bd859f6 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/README @@ -0,0 +1,3 @@ +See doc/crypt.pdf + + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/TODO b/xmhf-64/xmhf/third-party/libtomcrypt/TODO new file mode 100644 index 0000000000..30c6e4f8a2 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/TODO @@ -0,0 +1,3 @@ +for 1.18 +- document new ECC functions +- add test for new functions diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/build.sh b/xmhf-64/xmhf/third-party/libtomcrypt/build.sh new file mode 100644 index 0000000000..a04867042b --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/build.sh @@ -0,0 +1,20 @@ +#!/bin/bash +echo "$1 ($2, $3)..." +make clean 1>/dev/null 2>/dev/null +echo -n "building..." +CFLAGS="$2 $CFLAGS $4" EXTRALIBS="$5" make -j4 -f $3 test tv_gen 1>gcc_1.txt 2>gcc_2.txt || (echo "build $1 failed see gcc_2.txt for more information" && cat gcc_2.txt && exit 1) +echo -n "testing..." +if [ -a test ] && [ -f test ] && [ -x test ]; then + ((./test >test_std.txt 2>test_err.txt && ./tv_gen > tv.txt) && echo "$1 test passed." && echo "y" > testok.txt) || (echo "$1 test failed" && cat test_err.txt && exit 1) + if find *_tv.txt -type f 1>/dev/null 2>/dev/null ; then + for f in *_tv.txt; do if (diff --ignore-case $f notes/$f) then true; else (echo "tv_gen $f failed" && rm -f testok.txt && exit 1); fi; done + fi +fi +if [ -a testok.txt ] && [ -f testok.txt ]; then + exit 0 +fi +exit 1 + +# $Source: /cvs/libtom/libtomcrypt/build.sh,v $ +# $Revision: 1.9 $ +# $Date: 2006/03/18 14:10:55 $ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/build_armcc.sh b/xmhf-64/xmhf/third-party/libtomcrypt/build_armcc.sh new file mode 100755 index 0000000000..9ada2bfb27 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/build_armcc.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +export CC=armcc +export IGNORE_SPEED=1 # armcc doesn't understand -funroll-loops etc. +export EXTRALIBS="-ltommath" # use libtommath. not most performant, but very portable +CFLAGS="-DLTM_DESC" # include libtommath descriptor +CFLAGS+=" -DUSE_LTM" # use libtommath descriptor in any compiled executables +CFLAGS+=" -D_WCHAR_T_DEFINED" # prevent from trying to redefine wchar_t +CFLAGS+=" -I/home/jnewsome/src/libtommath" # point to libtommath headers +CFLAGS+=" --cpu=Cortex-A8 --fpu=None --fpmode=none" # CPU spec +export CFLAGS +export LDFLAGS="-L/home/jnewsome/src/libtommath" # point to libtommath libs +make + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/changes b/xmhf-64/xmhf/third-party/libtomcrypt/changes new file mode 100644 index 0000000000..85a9c69cac --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/changes @@ -0,0 +1,1571 @@ +May 12th, 2007 +v1.17 -- Cryptography Research Inc. contributed another small volley of patches, one to fix __WCHAR_DEFINED__ for BSD platforms, + another to silence MSVC warnings. + -- Added LTC_XCBC_PURE to XCBC mode which lets you use it in three-key mode. + -- [CRI] Added libtomcrypt.dsp for Visual C++ users. + -- [CRI] Added more functions for manipulating the ECC fixed point cache (including saving and loading) + -- [CRI] Modified ecc_make_key() to always produce keys smaller than base point order, for standards-compliance + -- Elliptic Semiconductor contributed XTS chaining mode to the cipher suite (subsequently optimized it) + -- Fixed xcbc_init() keylen when using single key mode. + -- Bruce Fortune pointed out a typo in the hmac_process() description in the manual. Fixed. + -- Added variable width counter support to CTR mode + -- Fixed CMAC (aka OMAC) when using 64-bit block ciphers and LTC_FAST ... my bad. + -- Fixed bug in ecc_is_valid() that would basically always return true + -- renamed a lot of macros to add the LTC_ prefix [e.g. RIJNDAEL => LTC_RIJNDAEL] + +December 16th, 2006 +v1.16 -- Brian Gladman pointed out that a recent change to GCM broke how the IV was handled. Currently the code complies against his test vectors + so the code should be considered frozen now. + -- Trevor from Cryptography Research Inc. submitted patches to convert the ECC code to be generic allowing curve parameters to be submitted + at runtime. + -- Fixed various doxygen comments + -- Added UTF8 support to the ASN1 code + -- Fixed STOREXXH macros for x86 platforms (Fix found at Elliptic Inc.) + -- Added makefile.unix which is BSD compatible, you have to manually tweak it since well I don't use it normally + -- removed a few lingering memcpy's + -- Fixed memory free errors in ecc_sign_hash() that can arise if the mp_init_multi() fails + -- Fixed incorrect return value in pkcs_1_pss_decode() which would correctly set res to 0 (indicating an incorrect signature) but + would return CRYPT_OK to the caller + -- ltc_ecc_mulmod() could leak memory if mp_init(&mu) failed, fixed. Would you believe that ltc_ecc_mulmod_timing() had the same + bug? Also fixed. :-) + -- Added Shamir's trick to the ECC side (defined as LTC_ECC_SHAMIR, enabled by default), gets ~1.34x to ~1.40x faster ECC verifications + -- Added Brian's vector #46 to the GCM code. It catches the ctr counter error from v1.15. Originally I was going to add all of his vectors, + but they're not as easy to parse and I got a lot of other things to do. Regression! + -- Various other small fixes to the ECC code to clean up error handling (I think most of that was from the move in 1.06 to the plugins) + All of the errors were in cleaning up from heap failures. So they were not likely to be triggered in normal usage + Made similar fixes to the RSA and DSA code (my bad) + -- Cryptography Research Inc. contributed a bunch of fixes to silence warnings (with MSVC) w.r.t. assigned data to unsigned char types. + -- Martin Marko suggested some fixes to make the RNG build with WinCE. + -- Updates to the manual for print (some fixes thanks to Martin Marko) + + +November 17th, 2006 +v1.15 -- Andreas Lange found that if sha256_init DID fail in fortuna it wouldn't clean up the state correctly. Thanks. + Fortunately sha256_init cannot fail (as of v1.14) :-) + -- Andreas Lange contributed RMD-256 and RMD-320 code. + -- Removed mutex locks from fortuna_import as they create a deadlock and aren't required anyways [Avi Zelmanovich] + -- Added LTC_NO_PROTOTYPES to avoid prototyping functions like memset/memcpy. Required for fans of GCC 3.3.x + -- David Eder caught a off by one overrun bug in pmac_done() which can be exploited if your output tag buffer is + smaller than the block size of the cipher, e.g. if you have a 4-byte buffer and you tell pmac_done that you want + a 4-byte TAG it will store 4 bytes but return an outlen of 5. + -- Added signatures to the ECC and RSA benchmarks + -- Added LTC_PROFILE to run the PK tests only once in the timing demo (so you can capture events properly) + -- Andreas contributed PKCS #1 v1.5 code that merged cleanly with the existing PKCS code. w00t. + (update: I had to fix it to include the digestInfo and what not. Bad Andreas, bad! hehehe) + -- Fixed a signed variable error in gcm_process() (hard to trigger bug fortunately) + -- Removed all memcmp/memset/memcpy from the source (replaced with X macros) + -- Renamed macros HMAC/OMAC/PMAC to have a LTC_ prefix. If you pass these on the command line please update your makefiles + -- Added XCBC-MAC support [RFC 3566] + -- fixed LOAD32H and LOAD64H to stop putting out that darn warning :-) + -- Added the Korean SEED block cipher [RFC 4269] + -- Added LTC_VALGRIND define which makes SOBER-128 and RC4 a pure PRNG (and not a stream cipher). Useful if you use + Valgrind to debug your code (reported by Andreas Lange) + -- Made SOBER-128 more portable by removing the ASCII key in the test function (my bad, sorry). + -- Martin Mocko pointed out that if you have no PRNGs defined the lib won't build. Fixed, also fixed for if you have no + hashes defined. + -- Sped up F8 mode with LTC_FAST + -- Made CTR mode RFC 3686 compliant (increment counter first), to enable, OR the value LTC_CTR_RFC3686 to the "mode" + parameter you pass to ctr_start(), otherwise it will be LTC compliant (e.g. encrypt then increment) + -- Added ctr_test() to test CTR mode against RFC 3686 + -- Added crypt_fsa() ... O_o + -- Fixed LTC_ECC_TIMING_RESISTANT so it once again builds properly (pt add/dbl are through the plugin now) + -- Added ANSI X9.63 (sec 4.3.6) import/export of public keys (cannot export to compressed formats but will import + hybrid compressed) + -- Added SECP curves for 112, 128, and 160 bits (only the 'r1' curves) + -- Added 3GPP-F9 MAC (thanks to Greg Rose for the test vectors) + -- Added the KASUMI block cipher + -- Added F9/XCBC/OMAC callbacks to the cipher plugin + -- Added RSA PKCS #1 v1.5 signature/encrypt tests to rsa_test.c + -- Fix to yarrow_test() to not call yarrow_done() which is invalid in that context (thanks Valgrind) + -- Christophe Devine pointed out that Anubis would fail on various 64-bit UNIX boxes when "x>>24" was used as an index, we needed + to mask it with 0xFF. Thanks. Fixed. + +August 0x1E, 0x07D6 +v1.14 -- Renamed the chaining mode macros from XXX to LTC_XXX_MODE. Should help avoid polluting the macro name space. + -- clean up of SHA-256 + -- Chris Colman pointed out that der_decode_sequence_* allows LTC_ASN1_SETOF to accept SEQUENCEs and vice versa. + Decoder [non-flexi decoder that is] is more strict now and requires a match. + -- Steffen Jaeckel pointed out a typo in the user manual (re: rsa_exptmod). Fixed. This disproves the notion that + nobody reads it. :-) + -- Made GCM a bit more portable w.r.t. handling the CTR IV (e.g. & with 255) + -- Add LTC_VERBOSE if you really want to see what test is doing :-) + -- Added SSE2 support to GCM [use GCM_TABLES_SSE2 to enable], shaves 2 cycles per byte on Opteron processors + Shaved 4 cycles on a Prescott (Intel P4) + Requires you align your gcm_state on a 16 byte boundary, see gcm_memory() for more info + -- Added missing prototype for f8_test_mode() + -- two fixes to CCM for corner cases [L+noncelen > 15] and fixing the CTR pad to encrypt the CBC-MAC tag + -- Franz Glasner pointed out the ARGTYPE=4 is not actually valid. Fixed. + -- Fixed bug in f8_start() if your key < saltkey unspecified behaviour occurs. :-( + -- Documented F8 mode. Yeah, because you read the manual. + -- Minor updates to the technotes. + + +June 17th, 2006 +v1.13 -- Fixed to fortuna_start() to clean up state if an error occurs. Not really useful at this stage (sha256 can't fail) but useful + if I ever make fortuna pluggable + -- Mike Marin submitted a whole bunch of patches for fixing up the libs on traditional UNIX platforms. Go AIX! Thanks! + -- One of bugs found in the multi demo highlights that at least with gcc you need to pass integers with a UL prefix to ensure + they're unsigned long + -- Updated the FP ECC code to use affine points. It's teh fast. + -- Made it so many functions which return CRYPT_BUFFER_OVERFLOW now also indicate the required buffer size, note that not all functions + do this (most do though). + -- Added F8 chaining mode. It's super neato. + +May 29th, 2006 +v1.12 -- Fixed OID encoder/decoder/length to properly handle the first two parts of an OID, matches 2002 X.690 now. + -- [Wesley Shields] Allows both GMP/LTM and TFM to be defined now. + -- [Wesley Shields] GMP pluggin is cleaner now and doesn't use deprecated symbols. Yipee + -- Added count_lsb_bits to get the number of leading LSB zero bits there are. + -- Fixed a bug in the INTEGER encoders for values of -(256**k)/2 + -- Added BOOLEAN type to ASN.1 thingy-ma-do-hicky + -- Testprof doesn't strictly require GMP ... oops [Nils Durner] + -- Added LTC_CALL and LTC_EXPORT macros in tomcrypt_cfg.h to support various calling and linker conventions + (Thanks to John Kirk from Demonware) + -- In what has to be the best thing since sliced bread I bring you MECC_FP which is the fixed point + ECC point multiplier. It's fast, it's sexy and what's more it's hella fast [did I mention it's fast?] + You can tune it somewhat with FP_LUT (default to 8) for look-up width. + Read section 8.2 of the manual for more info. + It is disabled by default, you'll have to build LTC with it defined to get it. + -- Fixed bug in ecc_test.c (from testprof) to include the 521 [not 512] bit curve. :-) + +April 4th, 2006 +v1.11 -- Removed printf's from lrw_test ... whoops + -- lrw_process now checks the return of the cipher ecb encrypt/decrypt calls + -- lrw_start was not using num_rounds ... + -- Adam Miller reported a bug in the flexi decoder with elements past the end of a sequence. Fixed. + -- Bruce Guenter suggested I use --tag=CC for libtool builds where the compiler may think it's C++. (I applied this to LTM and TFM) + -- Optimized the ECC for TFM a bit by removing the useless "if" statements (most TFM functions don't return error codes) + Actually shaved a good chunk of time off and made the code smaller. By default with TFM the stock LTC point add/dbl functions + will be totally omitted (ECC-256 make key times on a Prescott for old vs. new are 11.03M vs. 9.59M cycles) + -- added missing CVS tags to ltc_ecc_mulmod.c + -- corrected typo in tomcrypt_cfg.h about what the file has been called + -- corrected my address in the user manual. A "bit" out of date. + -- added lrw_gen to tv_gen + -- added GMP plugin, only tested on a AMD64 and x86_32 Gentoo Linux box so be aware + -- made testme.sh runs diff case insensitivityly [whatever...] cuz GMP outputs lowercase satan text + -- added LDFLAGS to the makefile to allow cross porting linking options + -- added lrw_test() to the header file ... whoops + -- changed libtomcrypt.org to libtomcrypt.com .... mumble mumble + -- Updates to detect __STRICT_ANSI__ which is defined in --std=c99 modes (note -ansi is not supported as it lacks long long) so you can + build LTC out of the box with c99 (note: it'll be slower as there is no asm in this case) + -- Updated pelican.c and aes_tab.c to undef tables not-required. The tables are static so both AES and Pelican MAC would have copies. Save a few KB in the final binary. + -- Added LTC_NO_FAST to the makefile.icc to compensate for the fact ICC v9 can't handle it (Pelican MAC fails for instance) + +February 11th, 2006 +v1.10 -- Free ecb/cbc/ctr/lrw structures in timing code by calling the "done" function + -- fixed bug in lrw_process() which would always use the slow update ... + -- vastly sped up gcm_gf_mult() when LTC_FAST is defined. This speeds up LRW and GCM state creation, useful for servers with GCM + -- Removed NLS since there are some attacks against it. + -- fixed memory leak in rsa_import reported by John Kuhns + ++ re-released as the rsa fix was incorrect (bad John bad ... hehehe) and I missed some NULLs in the static descriptor entry for ciphers + +January 26th, 2006 +v1.09 -- Added missing doxygen comments to some of the ASN.1 routines + -- Added "easy button" define LTC_EASY and LTC will build with a subset of all the algos. Reduces build times for typical + configurations. Tunable [see tomcrypt_custom.h] + -- Added some error detection to reg_algs() of the testprof.a library to detect when the PRNG is not setup correctly (took me 10 mins to figure out, PITA!) + -- Similar fixes to timing demo (MD5 not defined when EASY is defined) + -- Added the NLS enc+mac stream cipher from QUALCOMM, disabled for this release, waiting on test vectors + -- Finally added an auto-update script for the makefiles. So when I add new files/dirs it can automatically fix up the makefiles [all four of them...] + -- Added LRW to the list of cipher modes supported + -- cleaned up ciphers definitions to remove cbc/cfb/ofb/ctr/etc from the namespace when not used. + +November 24th, 2005 +v1.08 -- Added SET and SET OF support to the ASN.1 side + -- Fixed up X macros, added QSORT to the mix [thanks SET/SETOF] + -- Added XMEMCMP to the list of X macros + -- In der_decode_sequence() the SHORT_INTEGER type was not being handled correctly [oddly enough it worked just enough to make RSA work ... go figure!] + -- Fixed bug in math descriptors where if you hadn't defined MECC (ECC support) you would get linker errors + -- Added RSA accelerators to the math descriptors to make it possible to not include the stock routines if you supply your own. + -- dsa_decrypt_key() was erroneously dependent on MECC not MDSA ... whoops + -- Moved DSA size limits to tomcrypt_pk.h so they're defined with LTC_NO_PK+MDSA + -- cleaned up tomcrypt_custom.h to make customizable PK easier (and also cleaned up the error traps so they're correctly reported) + +November 18th, 2005 +v1.07 -- Craig Schlenter pointed out the "encrypt" demo doesn't call ctr_start() correctly. That's because as of a few releases ago + I added support to set the mode of the counter at init time + -- Fixed some "testprof" make issues + -- Added RSA keygen to the math descriptors + -- Fixed install_test target ... oops + -- made the "ranlib" program renamable useful for cross-compiling + -- Made the cipher accelerators return error codes. :-) + -- Made CCM accept a pre-scheduled key to speed it up if you use the same key for multiple packets + -- Added "Katja" public key crypto. It's based on the recent N = p^2q work by Katja. I added OAEP padding + to it. Note this code has been disabled not because it doesn't work but because it hasn't been thoroughly + analyzed. It does carry some advantages over RSA (slightly smaller public key, faster decrypt) but also + some annoying "setup" issues like the primes are smaller which makes ECM factoring more plausible. + -- Made makefile accept a NODOCS flag to disable the requirement of tetex to install LTC for you no tetex people... all 3 of ya :-) + -- Cleaned up rsa_export() since "zero" was handled with a SHORT_INTEGER + -- Cleaned up the LIBTEST_S definitions in both GNU makefiles. A few minor touchups as well. + -- Made the cipher ecb encrypt/decrypt return an int as well, changed ALL dependent code to check for this. + -- der_decode_choice() would fail to mark a NULL as "used" when decoding. Fixed + -- ecc_decrypt_key() now uses find_hash_oid() to clean up the code ;-) + -- Added mp_neg() to the math descriptors. + -- Swapped arguments for the pkcs_1_mgf1() function so the hash_idx is the first param (to be more consistent) + -- Made the math descriptors buildable when RSA has been undefined + -- ECC timing demo now capable of detecting which curves have been defined + -- Refactored the ECC code so it's easier to maintain. (note: the form of this code hasn't really changed since I first added ECC ... :-/) + -- Updated the documentation w.r.t. ECC and the accelerators to keep it current + -- Fixed bug in ltc_init_multi() which would fail to free all allocated memory on error. + -- Fixed bug in ecc_decrypt_key() which could possibly lead to overflows (if MAXBLOCKSIZE > ECC_BUF_SIZE and you have a hash that emits MAXBLOCKSIZE bytes) + -- Added encrypt/decrypt to the DSA side (basically DH with DSA parameters) + -- Updated makefiles to remove references to the old DH object files and the ecc_sys.o crap ... clean code ahead! + -- ecc_import() now checks if the point it reads in lies on the curve (to prevent degenerative points from being used) + -- ECC code now ALWAYS uses the accelerator interface. This allows people who use the accelerators to not have the stock + ECC point add/dbl/mul code linked in. Yeah space savings! Rah Rah Rah. + -- Added LTC_MUTEX_* support to Yarrow and Fortuna allowing you to use respective prng_state as a global PRNG state [e.g. thread-safe] if you define one of the LTC_* defines at + build time (e.g. LTC_PTHREAD == pthreads) + -- Added PPC32 support to the rotate macros (tested on an IBM PPC 405) and LTC_FAST macros (it aint fast but it's faster than stock) + -- Added ltc_mp checks in all *_make_key() and *_import() which will help catch newbs who don't register their bignum first :-) + -- the UTCTIME type was missing from der_length_sequence() [oops, oh like you've never done that] + -- the main makefile allows you to rename the make command [e.g. MAKE=gmake gmake install] so you can build LTC on platforms where the default make command sucks [e.g. BSD] + -- Added DER flexi decoder which allows the decoding of arbitrary DER encoded packets without knowing + their structure in advance (thanks to MSVC for finding 3 bugs in it just prior to release! ... don't ask) + +August 1st, 2005 +v1.06 -- Fixed rand_prime() to accept negative inputs as a signal for BBS primes. [Fredrik Olsson] + -- Added fourth ARGCHK type which outputs to stderr and continues. Useful if you trap sigsegv. [Valient Gough] + -- Removed the DH code from the tree + -- Made the ECC code fully public (you can access ecc_mulmod directly now) useful for debuging + -- Added ecc test to tv_gen + -- Added hmac callback to hash descriptors. + -- Fixed two doxy comment errors in the UTCTIME functions + -- rsa_import() can now read OpenSSL format DER public keys as well as the PKCS #1 RSAPublicKey format. + Note that rsa_export() **ONLY** writes PKCS #1 formats + -- Changed MIN/MAX to only define if not already present. -- Kirk J from Demonware ... + -- Ported tv_gen to new framework (and yes, I made ecc vectors BEFORE changing the API and YES they match now :-)) + -- ported testing scripts to support pluggable math. yipee! + -- Wrote a TFM descriptor ... yipee + -- Cleaned up LTC_FAST in CBC mode a bit + -- Merged in patches from Michael Brown for the sparc/sparc64 targets + -- Added find_hash_oid() to search for a hash by its OID + -- Cleaned up a few stray CLEAN_STACKs that should have been LTC_CLEAN_STACK + -- Added timing resistant ECC, enable by defining LTC_ECC_TIMING_RESISTANT then use ECC API as normal + -- Updated the ECC documentation as it was a bit out of date + +June 27th, 2005 +v1.05 + -- Added Technote #6 which covers the current PK compliance. + -- Fixed buffer overflow in OAEP decoder + -- Added CHOICE to the list of ASN.1 types + -- Added UTCTIME to the list of ASN.1 types + -- Added MUTEX locks around descriptor table functions [but not on the functions that are dependent on them] + All functions call *_is_valid() before using a descriptor index which means the respective table must be unlocked before + it can be accessed. However, during the operation [e.g. CCM] if the descriptor has been altered the results will be + undefined. + -- Minor updates to the manual to reflect recent changes + -- Added a catch to for an error that should never come up in rsa_exptmod(). Just being thorough. + +June 15th, 2005 +v1.04 + -- Fixed off by one [bit] error in dsa_make_key() it was too high by one bit [not a security problem just inconsistent] + -- ECC-224 curve was wrong [it was an ok curve just not NIST, so no security flaw just interoperability]. + -- Removed point compression since it slows down ECC ops to save a measly couple bytes. + This makes the ecc export format incompatible with 1.03 [it shouldn't change in the future] + -- Removed ECC-160 from timing and added the other curves + +June 9th, 2005 +v1.03 + -- Users may want to note that on a P4/GCC3.4 platform "-fno-regmove" greatly accelerates the ciphers/hashes. + -------------------------------------------------------------------------------------------------------------- + -- Made it install the testing library in the icc/static makefiles + -- Found bug in ccm_memory.c which would fail to compile when LTC_CLEAN_STACK was enabled + -- Simon Johnson proposed I do a fully automated test suite. Hence "testme.sh" was born + -- Added LTC_NO_TEST which forces test vectors off (regardless of what tomcrypt_custom.h has) + -- Added LTC_NO_TABLES which disables large tables (where possible, regardless of what tomcrypt_custom.h has) + -- New test script found a bug in twofish.c when TABLES was disabled. Yeah testing! + -- Added a LTC_FAST specific test to the testing software. + -- Updated test driver to actually halt on errors and just print them out (useful for say... automated testing...) + -- Added bounds checking to Pelican MAC + -- Added BIT and OCTET STRING to the ASN.1 side of things. + -- Pekka Riikonen pointed out that my ctr_start() function should accept the counter mode. + -- Cleaned up warnings in testprof + -- Removed redundant mu and point mapping in ecc_verify_hash() so it should be a bit faster now + -- Pekka pointed out that the AES key structure was using 32 bytes more than it ought to. + -- Added quick defines to remove entire classes of algorithms. This makes it easier if you want to build with just + one algorithm (say AES or SHA-256). Defines are LTC_NO_CIPHERS, LTC_NO_MODES, LTC_NO_HASHES, LTC_NO_MACS, + LTC_NO_PRNGS, LTC_NO_PK, LTC_NO_PKCS + -- As part of the move for ECC to X9.62 I've changed the signature algorithm to EC DSA. No API changes. + -- Pekka helped me clean up the PKCS #1 v2.1 [OAEP/PSS] code + -- Wrote new DER SEQUENCE coder/decoder + -- RSA, DSA and ECDSA now use the DER SEQUENCE code (saves a lot of code!) + -- DSA output is now a DER SEQUENCE (so not compatible with previous releases). + -- Added Technote #5 which shows how to build LTC on an AMD64 to have a variety of algorithms in only ~80KB of code. + -- Changed temp variable in LOAD/STORE macros to "ulong32" for 32-bit ops. Makes it safer on Big endian platforms + -- Added INSTALL_GROUP and INSTALL_USER which you can specify on the build to override the default USER/GROUP the library + is to be installed as + -- Removed "testprof" from the default build. + -- Added IA5, NULL and Object Identifier to the list of ASN.1 DER supported types + -- The "no_oops" target (part of zipup) now scans for non-cvs files. This helps prevent temp/scratch files from appearing in releases ;-) + -- Added DERs for missing hashes, but just the OID not the PKCS #1 v1.5 additions. + -- Removed PKCS #1 v1.5 from the tree since it's taking up space and you ought to use v2.1 anyways + -- Kevin Kenny pointed out a few stray // comments + -- INTEGER code properly supports negatives and zero padding [Pekka!] + -- Sorted asn1/der/ directory ... less of a mess now ;-) + -- Added PRINTABLE STRING type + -- Removed ECC-160 as it wasn't a standard curve + -- Made ecc_shared_secret() ANSI X9.63 compliant + -- Changed "printf" to "fprintf(stderr, " in the testbench... ;-) + -- Optimized the GCM table creation. On 1KB packets [with key switching] the new GCM is 12.7x faster than before. + -- Changed OID representation for hashes to be just a list of unsigned longs (so you can compare against them nicely after decoding a sequence) + -- ECC code now uses Montgomery reduction ... it's even faster [ECC-256 make key down from 37.4M to 4.6M cycles on an Athlon64] + -- Added SHORT_INTEGER so users can easily store DER encoded INTEGER types without using the bignum math library + -- Fixed OMAC code so that with LTC_FAST it doesn't require that LTC_FAST_TYPE divides 16 [it has to divide the block size instead] + -- ECC key export is now a simple [and documented] SEQUENCE, the "encrypt_key" also uses a new SEQUENCE format. + -- Thanks goes to the following testers + Michael Brown - Solaris 10/uSPARCII + Richard Outerbridge - MacOS + Martin Carpenter - Solaris 8/uSPARCII [Thanks for cleaning up the scripts] + Greg Rose - ... SunOS 5.8/SPARC [... what's with the SPARCS?] + Matt Johnston - MacOS X [Thanks for pointing out GCC 4 problems with -Os] + +April 19th, 2005 +v1.02 + -- Added LTC_TEST support to gcm_test() + -- "pt/ct" can now be NULL in gcm_process() if you are processing zero bytes + -- Optimized GCM by removing the "double copy" handling of the plaintext/aad + -- Richard Outerbridge pointed out that x86_prof won't build on MACOS and that the manual + erroneously refers to "mycrypt" all over the place. Fixed. + +April 17th, 2005 +v1.01 + ** Secure Science Corporation has supported this release cycle by sponsoring the development time taken. Their + continuing support of this project has helped me maintain a steady pace in order to keep LibTomCrypt up to date, + stable and more efficient. + ----------------------------------------------------------------------------------------------------- + -- Updated base64_decode.c so if there are more than 3 '=' signs it would stop parsing + -- Merged in latest mpi that fixed a few bugs here and there + -- Updated OAEP encoder/decoder to catch when the hash output is too large + Cleaned up PSS code too + -- Andy Bontoft fixed a bug in my demos/tests/makefile.msvc ... seems "dsa_test.c" isn't an object + afterall. Thanks. + -- Made invalid ECC key sizes (configuration) not hard fault the program (it returns an error code now) + -- SAFER has been re-enabled after I was pointed to http://www.ciphersbyritter.com/NEWS2/95032301.HTM + [Mark Kotiaho] + -- Added CCM mode to the encauth list (now has EAX, OCB and CCM, c'est un treo magnifique!) + -- Added missing ASN.1 header to the RSA keys ... oops... now the rsa_export/import are FULLY compatible + with other libs like OpenSSL (comment: Test vectors would go a long way RSA...) + -- Manually merged in fix to the prime_random_ex() LTM function that ensures the 2nd MSB is set properly. Now + When you say "I want a 1024/8 byte RSA key" the MSB bit of the modulus is set as expected. Note I generally + don't view this as a "huge issue" but it's just one less nit to worry about. [Bryan Klisch] + -- A new CVS has been setup on my Athlon64 box... if you want developer access send me an email (and at this point the email would have to be awesome). + -- Updated API for ECB and CBC shell code. Now can process N whole blocks in one call (like $DEITY intended) + -- Introduced a new "hardware accel" framework that can be used to speed up cipher ECB, CBC and CTR mode + calls. Later on dependent code (e.g. OMAC, CCM) will be re-written to use the generic cbc/ctr functions. But now + if you [say] call ctr_encrypt() with a cipher descriptor that has hardware CTR it will automatically + be used (e.g. no code rewrites) + -- Now ships with 20% more love. + -- x86_prof now uses ECB shell code (hint: accelerators) and outputs cycles per BLOCK not byte. This will make it a bit + easier to compare hardware vs. software cipher implementations. It also emits timings for CBC and CTR modes + -- [Peter LaDow] fixed a typo w.r.t. XREALLOC macro (spelling counts kids!) + -- Fixed bug with __x86_64__ where ROL64/ROR64 with LTC_NO_ROLC would be the 32-bit versions instead... + -- Shipping with preliminary GCM code (disabled). It's buggy (stack overflow hidden somewhere). If anyone can spot it let me know. + -- Added Pelican MAC [it's an AES based fast MAC] to the list of supported MACs + -- Added LTC_FAST [and you can disable by defining LTC_NO_FAST] so that CBC and CTR mode XOR whole words [e.g. 32 or 64 bits] at a time + instead of one byte. On my AMD64 this reduced the overhead for AES-128-CBC from 4.56 cycles/byte to around 1 cycle/byte. This requires + that you either allow unaligned read/writes [e.g. x86_32/x86_64] or align all your data. It won't go out of it's way to ensure + aligned access. Only enabled for x86_* platforms by default since they allow unaligned read/writes. + -- Added LTC_FAST support to PMAC (drops the cycle/byte by about 9 cycles on my AMD64) [note: I later rewrote this prior to release] + -- Updated "profiled" target to work with the new directory layout + -- Added [demo only] optimized RC5-CTR code to x86_prof demo to show off how to make an accelerator + [This has been removed prior to release... It may re-appear later] + -- Added CCM acelerator callbacks to the list [now supports ECB, CTR, CBC and now CCM]. + -- Added chapter to manual about accelerators (you know you want it) + -- Added "bswap" optimizations to x86 LOAD/STORE with big endian. Can be disabled by defining LTC_NO_BSWAP + -- LTC_NO_ASM is now the official "disable all non-portable stuff" macro. When defined it will make the code endian-neutral, + disable any form of ASM and disable LTC_FAST load/stores. Essentially build the library with this defined if you're having + trouble building the library (old GCCs for instance dislike the ROLc macro) + -- Added tomcrypt_mac.h and moved MAC/encMAC functions from tomcrypt_hash.h into it + -- Added "done" function to ciphers and the five chaining modes [and things like omac/pmac/etc] + -- Changed install group to "wheel" from "root". + -- Replaced // comments with /**/ so it will build on older UNIX-like platforms + -- x86_prof builds and runs with IntelCC fine now + -- Added "stest" build to intel CC to test static linked from within the dir (so you don't have to install to test) + -- Moved testing/benchmark into testprof directory and build it as part of the build. Now you can link against libtomcrypt_prof.a to get + testing info (hint: hardware developers ;-) ) + -- Added CCM to tv_gen + -- Added demos to MSVC makefile + -- Removed -funroll-all-loops from GCC makefile and replaced with -funroll-loops which is a bit more sane (P4 ain't got much cache for the IDATA) + -- Fixed GCM prior to release and re-enabled it. It has not been optimized but it does conform when compiled with optimizations. + -- I've since optimized GCM and CCM. They're close in speed but GCM is more flexible imho (though EAX is more flexible than both) + -- For kicks I optimized the ECC code to use projective points. Gets between 3.21x (Prescott P4) to 4.53x (AMD64) times faster than before at 160-bit keys and the + speedup grows as the keysize grows. Basically removing most practical reasons to "not use the ECC code". Enjoy. + -- Added LTC_FAST support to OMAC/PMAC and doubled it's speed on my amd64 [faster on the P4 too I guess] + -- Added GCM to tv_gen + -- Removed "makefile.cygwin_dll" as it's not really used by anyone and not worth the effort (hell I hardly maintain the MSVC makefiles ...) + -- Updated a few files in the "misc" directory to have correct @file comments for doxygen + -- Removed "profile" target since it was slower anyways (go figure...) + +December 31st, 2004 +v1.00 + -- Added "r,s == 0" check to dsa_verify_hash() + -- Added "multi block" helpers for hash, hmac, pmac and omac routines so you can process multiple non-adjacent + blocks of data with one call (added demos/multi.c to make sure they work) + -- Note these are not documented but they do have doxygen comments inside them + -- Also I don't use them in other functions (like pkcs_5_2()) because I didn't have the time. Job for the new LTC maintainer ;-) + -- Added tweaked Anubis test vectors and made it default (undefined ANUBIS_TWEAK to get original Anubis) + -- Merged in fix for mp_prime_random_ex() to deal with MSB and LSB "bugs" + -- Removed tim_exptmod() completely, updated several RSA functions (notably v15 and the decrypt/verify) so they + don't require a prng now + -- This release brought to you by the fine tunes of Macy Gray. We miss you. + +December 23rd, 2004 +v1.00rc1 + -- Renamed "mycrypt_*" to "tomcrypt_*" to be more specific and professional + Now just include "tomcrypt.h" instead of "mycrypt.h" to get LTC ;-) + -- Cleaned up makefiles to ensure all headers are correctly installed + -- Added "rotate by constant" macros for portable, x86-32 and x86-64 + You can disable this new code with LTC_NO_ROLC which is useful for older GCCs + -- Cleaned up detection of x86-64 so it works for ROL/ROR macros + -- Fixed rsa_import() so that it would detect multi-prime RSA keys and error appropriately + -- Sorted the source files by category and updated the makefiles appropriately + -- Added LTC_DER define so you can trim out DER code if not required + -- Fixed up RSA's decrypt functions changing "res" to "stat" to be more in sync + with the signature variables nomenclature. (no code change just renamed the arguments) + -- Removed all labels starting with __ and replaced with LBL_ to avoid namespace conflicts (Randy Howard) + -- Merged in LTM fix to mp_prime_random_ex() which zap'ed the most significant byte if the bit size + requested was a multiple of eight. + -- Made RSA_TIMING off by default as it's not terribly useful [and likely to be deprecated] + -- Renamed SMALL_CODE, CLEAN_STACK and NO_FILE to have a LTC_ prefix to avoid namespace collisions + with other programs. e.g. SMALL_CODE => LTC_SMALL_CODE + -- Zed Shaw pointed out that on certain systems installing libs as "root" isn't possible as the super-user + is not root. Now the makefiles allow this to be changed easily. + -- Renamed "struct _*_descriptor" to "struct ltc_*_descriptor" to avoid using a leading _ + Also renamed _ARGCHK to LTC_ARGCHK + -- Zed Shaw pointed out that I still defined the prng structs in tomcrypt_prng.h even if they + weren't defined. This made undef'ing FORTUNA break the build. + -- Added LTC_NO_ASM to disable inline asm macros [ROL/ROR/etc] + -- Changed RSA decrypt functions to change the output length variable name from "keylen" to "outlen" to make + it more consistent. + -- Added the 64-bit Khazad block cipher [NESSIE] + -- Added the 128-bit Anubis block cipher [with key support for 128...320 bit keys] [NESSIE] + -- Changes to several MAC functions to rename input arguments to more sensible names + -- Removed FAST_PK support from dh_sys.c + -- Declared deskey() from des.c as static instead of a global + -- Added pretty much all practical GCC warning tests to the GCC [related] makefiles. These additional + warnings can easily be disabled for those with older copies of GCC [or even non GNU cc's] + -- Added doxygen @ tags to the code... phew that was a hell of a lot of [repetitive] work + -- Also added pre-configured Doxygen script. + -- Cleaned up quite a few functions [ciphers, pk, etc] to make the parameters naming style consistent + E.g. ciphers keys are called "skey" consistently now. The input to PK encryption is called "in", etc. + These changes require no code changes on the behalf of developers fortunately + -- Started a SAFER+ optimizer [does encrypt only] which shaves a good 30 or so cycles/byte on my AMD64 + at an expense of huge code. It's in notes/etc/saferp_optimizer.c + -- DSA sign/verify now uses DER encoded output/inputs and no LTC style headers. + -- Matt Johnston found a missing semi-colon in mp_exptmod(). Fix has been merged in. + +October 29th, 2004 +v0.99 -- Merged in the latest version of LTM which includes all of the recent bug fixes + -- Deprecated LTMSSE and removed it (to be replaced with TFM later on) + -- Stefan Arentz pointed out that mp_s_rmap should be extern + -- Kristian Gj?steen pointed out that there are typos in the + "test" makefile and minor issues in Yarrow and Sober [just cosmetics really] + -- Matthew P. Cashdollar pointed out that "export" is a C++ keyword + so changed the PRNG api to use "pexport" and "pimport" + -- Updated "hashsum" demo so it builds ;-) + -- Added automatic support for x86-64 (will configure for 64-bit little endian automagically) + -- Zhi Chen pointed out a bug in rsa_exptmod which would leak memory on error. + -- Made hash functions "init" return an int. slight change to API ;-( + -- Added "CHC" mode which turns any cipher into a hash the other LTC functions can use + -- Added CHC mode stuff to demos such as tv_gen and hashsum + -- Added "makefile.shared" which builds and installs shared/static object copies + of the library. + -- Added DER for bignum support + -- RSA is now fully joy. rsa_export/rsa_import use PKCS #1 encodings and should be + compatible with other crypto libs that use the format. + -- Added support for x86-64 for the ROL/ROR macros + -- Changed the DLL and SO makefiles to optimize for speed, commented SMALL_CODE in + mycrypt_custom.h and added -DSMALL_CODE to the default makefile + -- Updated primality testing code so it does a minimum of 5 tests [of Miller-Rabin] + (AFAIK not a security fix, just warm fuzzies) + -- Minor updates to the OMAC code (additional __ARGCHK and removed printf from omac_test... oops!) + -- Update build and configuration info which was really really really out of date. (Chapter 14) + ++ Minor update, switch RSA to use the PKCS style CRT + +August 6th, 2004 +v0.98 -- Update to hmac_init to free all allocated memory on error + -- Update to PRNG API to fix import/export functions of Fortuna and Yarrow + -- Added test functions to PRNG api, RC4 now conforms ;-) [was a minor issue] + -- Added the SOBER-128 PRNG based off of code donated by Greg Rose. + -- Added Tech Note #4 [notes/tech0004.txt] + -- Changed RC4 back [due to request]. It will now XOR the output so you can use it like + a stream cipher easily. + -- Update Fortuna's export() to emit a hash of each pool. This means that the accumulated + entropy that was spread over all the pools isn't entirely lost when you export/import. + -- Zhi Chen suggested a comment for rsa_encrypt_key() to let users know [easily] that it was + PKCS #1 v2.0 padding. (updated other rsa_* functions) + -- Cleaned up Noekeon to remove unrolling [wasn't required, was messy and actually slower with GCC/ICC] + -- Updated RC4 so that when you feed it >256 bytes of entropy it quietly ignores additional + bytes. Also removed the % from the key setup to speed it up a bit. + -- Added cipher/hash/prng tests to x86_prof to help catch bugs while testing + -- Made the PRNG "done" return int, fixed sprng_done to not require prng* to be non-null + -- Spruced up mycrypt_custom.h to trap more errors and also help prevent LTMSSE from being defined + on non-i386 platforms by accident. + -- Added RSA/ECC/DH speed tests to x86_prof and cleaned it up to build with zero warnings + -- Changed Fortuna to count only entropy [not the 2 byte header] added to pool[0] into the + reseed mechanism. + -- Added "export_size" member to prng_descriptor tables so you can know in advance the size of + the exported state for any given PRNG. + -- Ported over patch on LTM 0.30 [not ready to release LTM 0.31] that fixes bug in mp_mul()/mp_div() + that used to result in negative zeroes when you multiplied zero by a negative integer. + (patch due to "Wolfgang Ehrhardt" ) + -- Fixed rsa_*decrypt_key() and rsa_*verify_hash() to default to invalid "stat" or "res". This way + if any of the higher level functions fail [before you get to the padding] the result will be in + a known state]. Applied to both v2 and v1.5 padding helpers. + -- Added MACs to x86_prof + -- Fixed up "warnings" in x86_prof and tv_gen + -- Added a "profiled" target back [for GCC 3.4 and ICC v8]. Doesn't seem to help but might be worth + tinkering with. + -- Beefed up load/store test in demos/test + + ++ New note, in order to use the optimized LOAD/STORE macros your platform + must support unaligned 32/64 bit load/stores. The x86s support this + but some [ARM for instance] do not. If your platform cannot perform + unaligned operations you must use the endian neutral code which is safe for + any sort of platform. + +July 23rd, 2004 +v0.97b -- Added PKCS #1 v1.5 RSA encrypt/sign helpers (like rsa_sign_hash, etc...) + -- Added missing prng check to rsa_decrypt_key() [not critical as I don't use + descriptors directly in that function] + -- Merged in LTM-SSE, define LTMSSE before you build and you will get SSE2 optimized math ;-) + (roughly 3x faster on a P4 Northwood). By default it will compile as ISO C portable + code (when LTMSSE is undefined). + -- Fixed bug in ltc_tommath.h where I had the kara/toom cutoffs not marked as ``extern'' + Thanks to "Stefan Arentz" + -- Steven Dake and Richard Amacker submitted patches to + fix pkcs_5_2(). It now matches the output of another crypto library. Whoops... hehehe + -- Updated PRNG api. Added Fortuna PRNG to the list of supported PRNGs + -- Fixed up the descriptor tables since globals are automatically zero'ed on startup. + -- Changed RC4 to store it's output. If you want to encrypt with RC4 + you'll have to do the XOR yourself. + -- Fixed buffer overflows/overruns in the HMAC code. + + ++ API change for the PRNGs there now is a done() function per PRNG. You + should call it when you are done with a prng state. So far it's + not absolutely required (won't cause problems) but is a good idea to + start. + + +June 23rd, 2004 +v0.97a ++ Fixed several potentially crippling bugs... [read on] + -- Fixed bug in OAEP decoder that would incorrectly report + buffer overflows. [Zhi Chen] + -- Fixed headers which had various C++ missing [extern "C"]'s + -- Added "extern" to sha384_desc descriptor which I removed by mistake + -- Fixed bugs in ENDIAN_BIG macros using the wrong byte order [Matt Johnston] + -- Updated tiger.c and des.c to not shadow "round" which is intrinsic on + some C compilers. + -- Updated demos/test/rsa_test.c to test the RSA functionality better + ++ This update has been tested with GCC [v3.3.3], ICC [v8] and MSVC [v6+SP6] + all on a x86 P4 [GCC/ICC tested in Gentoo Linux, MSVC in WinXP] + ++ Outcome: The bug Zhi Chen pointed out has been fixed. So have the bugs + that Matt Johnston found. + +June 19th, 2004 +v0.97 -- Removed spurious unused files [arrg!] + -- Patched buffer overflow in tim_exptmod() + -- Fixed buffer overrun bug in pkcs_1_v15_es_decode() + -- Reduced stack usage in PKCS #1 v2.0 padding functions (by several KBs) + -- Removed useless extern's that were an artifact from the project start... ;-) + -- Replaced memcpy/memset with XMEMCPY and XMEMSET for greater flexibility + -- fixed bugs in hmac_done()/hmac_init()/[various others()] where I didn't trap errors + -- Reduced stack usage in OMAC/PMAC/HMAC/EAX/OCB/PKCS#5 by mallocing any significant sized + arrays (e.g. > 100 bytes or so). Only in non-critical functions (e.g. eax_init()) + -- "Zhi Chen" pointed out that rsa_decrypt_key() requires + an incorrect output size (too large). Fixed. + -- Added a "pretty" target to the GCC makefile. Requires PERL. It is NEAT! + -- Minor updates to ch1 of the manual. + -- Cleaned up the indentation and added comments to rsa_make_key(), rsa_exptmod() and + rsa_verify_hash() + -- Updated makefile.icc so the "install" target would work ;-) + -- Removed demos/test.c [deprecated from demos/test/test.c] + -- Changed MAXBLOCKSIZE from 128 to 64 to reflect the true size... + +May 30th, 2004 +v0.96 -- Removed GF and Keyring code + -- Extended OAEP decoder to distinguish better [and use a more uniform API] + -- Changed PSS/OAEP API slightly to be more consistent with other PK functions (order of arguments) + -- rsa_exptmod() now pads with leading zeroes as per I2OSP. + -- added error checking to yarrow code + -- pointed out that tommath.h from this distro will overwrite tommath.h + from libtommath. I changed this to ltc_tommath.h to avoid any such problems. + -- Fixed bug in PSS encoder/decoder that didn't handle the MSB properly + -- refactored AES, now sports an "encrypt only" descriptor which uses half as much code space. + -- modded Yarrow to try and use refactored AES code and added WHIRLPOOL support (d'oh) ;-) + -- updated ECB, OCB and CBC decrypt functions to detect when "encrypt only" descriptor is used. + -- replaced old RSA code with new code that uses PKCS #1 v2.0 padding + -- replaced old test harness with new over-engineer'ed one in /demos/test/ + -- updated cbc/cfb/ofb/ctr code with setiv/getiv functions to change/read the IV without re-keying. + -- Added PKCS #1 v1.5 RSA encryption and signature padding routines + -- Added DER OID's to most hash descriptors (as many as I could find) + -- modded rsa_exptmod() to use timing-resilient tim_exptmod() when doing private key operations + added #define RSA_TIMING which can turn on/off this feature. + -- No more config.pl so please just read mycrypt_custom.h for build-time tweaks + -- Small update to rand_prime() + -- Updated sha1, md5 and sha256 so they are smaller when SMALL_CODE is defined. If you want speed though, + you're going to have to undefine SMALL_CODE ;-) + -- Worked over AES so that it's even smaller now [in both modes]. + +May 12th, 2004 +v0.95 -- Optimized AES and WHIRLPOOL for SMALL_CODE by taking advantage of the fact + the transforms are circulant. AES dropped 5KB and WHIRLPOOL dropped 13KB + using the default build options on the x86. + -- Updated eax so the eax_done() would clear the state [like hmac,pmac,ocb] when + CLEAN_STACK has been defined. + -- added LTC_TEST support to rmd160 + -- updates to mycrypt_pk.h + -- updated rand_prime() to faciliate making RSA composites + -- DSA/RSA now makes composites of the exact size desired. + -- Refactored quite a bit of the code, fewer functions per C file + -- cleaned up the makefiles to organize the objects logically + -- added ICC makefile along with "profiled" targets for both GNU and ICC compilers + -- Marked functions for removal before v1.00 see PLAN for more information + -- GCC 3.4.0 tested and seems to work + -- Added PKCS #5 support + -- Fixed typo in comment header of .C files ;-) + -- Added PKCS #1 OAEP and PSS support. + +Feb 20th, 2004 +v0.94 -- removed unused variables from ocb.c and fixed it to match known test vectors. + -- Added PMAC support, minor changes to OMAC/EAX code [I think....] + -- Teamed up with Brian Gladman. His code verifies against my vectors and my code + verifies against his test vectors. Hazaa for co-operation! + -- Various small changes (added missing ARGCHKs and cleaned up indentation) + -- Optimization to base64, removed unused variable "c" + -- Added base64 gen to demos/tv_gen.c + -- Fix to demos/x86_prof.c to correctly identify the i386 architecture... weird... + -- Fixed up all of the PK code by adding missing error checking, removed "res" variables, + shrunk some stack variables, removed non-required stack variables and added proper + error conversion from MPI to LTC codes. I also spotted a few "off by one" error + checking which could have been used to force the code to read past the end of + the buffer (in theory, haven't checked if it would work) by a few bytes. + -- Added checks to OUTPUT_BIGNUM so the *_export() functions cannot overflow the output and I + also modded it so it stores in the output provided to the function (that is not on + the local stack) which saves memory and time. + -- Made SAFER default to disabled for now (plans are to cleanhouse write an implementation later) + -- Added the 512-bit one-way hash WHIRLPOOL which clocks in at 138 cycles per byte on my + Athlon XP [for comparison, SHA-512 clocks in at 77 cycles per byte]. This code uses the + teams new sbox design (not the original NESSIE one). + + +Jan 25th, 2004 +v0.93 -- [note: deleted v0.93 changes by accident... recreating from memory...] + -- Fix to RC2 to not deference pointer before ARGCHK + -- Fix to NOEKEON to match published test vectors as well as cleaned up the code a bit + -- Optimized Twofish [down to 28 cycles/byte on my box] and Blowfish + -- Fix to OMAC to test cipher block size first [prevents wasting any time] + -- Added more OMAC test vectors + -- Added EAX Encrypt+Authenticate support + -- Fix to DSA to check return of a few LTM functions I forgot [mp_to_unsigned_bin] + -- Added common headers to all C files + -- CTR mode supports big and little [default] endian counters now. + -- fix to find_cipher_any() so that it can handle a fragmented cipher_descriptor table. + -- added find_hash_any() akin to find_cipher_any(). + -- Added EAX code to demos/tv_gen.c Hazaa! + -- Removed SONY defines and files from codebase. + -- Added OCB support [patents be damned] and to demos/tv_gen.c + -- Merge all of the INPUT/OUTPUT BIGNUM macros (less toc) into mycrypt_pk.h + -- Made appropriate changes to the debug string in crypt.c + +Dec 24th, 2003 +v0.92 -- Updated the config.pl script so the options have more details. + -- Updated demos/tv_gen to include RIPEMD hashes + -- Updated Twofish so when TWOFISH_ALL_TABLES is defined a pre-computed RS table + is included [speedup: slight, about 4k cycles on my Athlon]. + -- Re-wrote the twofish large key generation [the four 8x32 key dependent tables]. Now about twice as fast. + With both optimizations [e.g. TWOFISH_ALL_TABLES defined] a 128-bit Twofish key can now be scheduled + in 26,000 cycles on my Athlon XP [as opposed to 49,000 before] when optimized for size. + -- config.pl has been updated so rmd128.o and rmd160.o are objects included in the build [oops] + -- Andrew Mann found a bug in rsa_exptmod() which wouldn't indicate if the wrong type of key was specified + (e.g. not PK_PRIVATE or PK_PUBLIC) + -- Fixed up demos/x86_prof so it sorts the output now :-) + -- The project is now powered by radioactive rubber pants. + -- Fixed dh_encrypt_key() so if you pass it a hash with a smaller output than the input key it + will return CRYPT_INVALID_HASH [to match what ecc_encrypt_key() will do] + -- Merge the store/encrypt key part of ecc_encrypt_key() as per dh_encrypt_key() [can you guess what I'm upto?] + -- Massive updates to the prime generation code. I use the LTM random prime functions [and provide a nice + interface between the LTC PRNG's and the LTM generic prng prototype]. I also use a variable number of tests + depending on the input size. This nicely speeds up most prime generation/testing within the library. + -- Added SHA-224 to the list of hashes. + -- Made HMAC test vectors constant and static [takes ROM space instead of RAM] + -- This release was brought to you by the letter P which stands for Patent Infringement. + -- Added generic HASH_PROCESS macro to mycrypt_hash.h which simplifies the hash "process" functions + I also optimized the compression functions of all but MD2 to not perform input copies when avoidable. + -- Removed the division from the Blowfish setup function [dropped 3k cycles on my Athlon] + -- Added stack cleaning to rijndael, cast5 so now all ciphers have CLEAN_STACK code. + -- Added Skipjack to the list of ciphers [made appropriate changes to demos/test.c, demos/tv_gen.c and + demos/x86_prof.c] + -- Added mechanical testing to cipher test vector routines. Now it encrypts 1000 times, then decrypts and + compares. Any fault (e.g. bug in code, compiler) in the routines is likely to show through. Doesn't + stress test the key gen though... + -- Matt Johnson found a bug in the blowfish.c apparently I was out of my mind and put twofish defines in there + The code now builds with any config. Thanks. + -- Added OMAC1 Message Authentication Code support to the library. + -- Re-prototyped the hash "process" and "done" to prevent buffer overflows [which don't seem easy to exploit]. + Updated HMAC code to use them too. Hazaa! + -- Fixed bug in ECC code which wouldn't do an _ARGCHK on stat in ecc_verify_hash(). + -- Fixed [temp fix] bug in all PK where the OUTPUT_BIGNUM macros would not trap errors on the to_unsigned_bin + conversion [now returns CRYPT_MEM, will fix it up better later] + -- Added DSA to the list of supported PK algorithms. + -- Fixed up various ciphers to &255 the input key bytes where required [e.g. where used to index a table] to prevent + problems on platforms where CHAR_BIT != 8 + -- Merged in LibTomMath v0.28 + -- Updated demos/x86_prof.c to use Yarrow during the key sched testing [was horribly slow on platforms with blockable + /dev/random]. + -- Added OMAC/HMAC tests to demos/tv_gen and I now store the output of this in notes/ + -- Fixed a bug in config.pl that wouldn't have TWOFISH_TABLES defined by default (too many commas on the line) + -- Fixed bug in hmac_done(). Apparently FIPS-198 [HMAC] specifies that the output can be truncated. My code + would not support that (does now just like the new OMAC code). + -- Removed "hashsize" from hmac_state as it wasn't being used. + -- Made demos/test.c stop if OMAC or HMAC tests fail (instead of just printing a failed message and keep going). + -- Updated notes/tech0003.txt to take into account the existence of Skipjack [also I fixed a few typos]. + -- Slight changes to Noekeon, with SMALL_CODE undefined it uses a fully unrolled version. Dropped +10 cycles/byte + on my Athlon (35 cycles per byte or 410.4Mbit/sec at 1795Mhz) + -- Added _ARGCHK() calls to is_prime() for the two input pointers. + +Sept 25th, 2003 +v0.91 -- HMAC fix of 0.90 was incorrect for keys larger than the block size of the hash. + -- Added error CRYPT_FILE_NOTFOUND for the file [hmac/hash] routines. + -- Added RIPEMD hashes to the hashsum demo. + -- Added hashsum demo to MSVC makefile. + -- Added RMD160 to the x86_prof demo [oops] + -- Merged in LibTomMath-0.27 with a patch to mp_shrink() that will be in LibTomMath-0.28 + Fixes another potential memory leak. + +Sept 7th, 2003 +v0.90 -- new ROL/ROR for x86 GCC + -- Jochen Katz submitted a patch to the makefile to prevent "make" from making the .a library + when not required. + == By default the KR code is not enabled [it's only a demo anyways!] + -- changed the "buf" in ecc_make_key from 4KB to 128 bytes [since the largest key is 65 bytes] + -- hmac_done() now requires you pass it the size of the destination buffer to prevent + buffer overflows. (API CHANGE) + -- hmac/hash filebased routines now return CRYPT_NOP if NO_FILE is defined. + -- I've removed the primes from dh.c and replaced them with DR safe primes suitable for the default + configuration of LibTomMath. Check out these comparisons on a 1.3Ghz Athlon XP, optimized for size, + +768-bit, 4 vs. 10 +1024-bit, 8 vs. 18 +1280-bit, 12 vs. 34 +1536-bit, 20 vs. 56 +1792-bit 28 vs. 88 +2048-bit, 40 vs. 124 +2560-bit, 71 vs. 234 +3072-bit, 113 vs. 386 +4096-bit, 283 vs. 916 + + Times are all in milliseconds for key generation. New primes times on the left. This makes the code binary + incompatible with previous releases. However, this addition is long overdue as LibTomMath has supported DR + reductions for quite some time. + -- Added RIPE-MD 128 and 160 to the list of supported hashes [10 in total]. + -- The project has been released as public domain. TDCAL no longer applies. + +July 15th, 2003 +v0.89 -- Fix a bug in bits.c which would prevent it from building with msvc + -- Merged in LibTomMath v0.24 [and I used the alloc/free macros this time!] + -- Removed the LTC version of next_prime() and replaced it with a call to the + mp_prime_next_prime() from LibTomMath + -- reverted bits.c to the 0.86 copy since the new one doesn't build in MSVC + or cygwin. + +Jul 10th, 2003 +v0.88 -- Sped up CAST5 key schedule for MSVC + -- added "ulong32" which allows people on 64-bit platforms to force the 32-bit tables in + ciphers like blowfish and AES to be 32-bits. E.g. when unsigned long is 64-bits. + -- Optimized the SAFER-SK64, SAFER-SK128, SAFER+, RC5 and RC6 key schedule [big time!] + -- Optimized SHA-1 and SHA-256 quite a bit too. + -- Fixed up the makefile to use -fomit-frame-pointer more liberally + -- Added tv_gen program which makes test vectors for ciphers/hashes + -- Merged in LibTomMath v0.22 + +Jun 19th, 2003 +v0.87 -- Many MSVC optimizations to the code base + -- Improved the AES and Twofish key schedule [faster, more constant time] + -- Tons of optimizations here and there. + +Jun 15th, 2003 +v0.86 -- Fixed up AES to workaround MSVC optimizer bug + -- Merged in fresh LTM base [based on v0.20] so there are no warnings with MSVC + -- Wrote x86_prof which will time the hashes and ciphers downto cycles per byte. + -- Fixed up demos/encrypt to remove serpent_desc from the list + -- Re-enabled MSVC optimizations w00t w00t + -- Replaced "errno" with "err" in all functions that had it so it wouldn't clash + with the global "errno" + -- Removed a set of unused variables from certain functions + -- Removed {#line 0 "..."} stuff from mpi.c to comply with ISO C :-) + +Jun 11th, 2003 +v0.85 -- Swapped in a new AES routine + -- Removed Serpent + -- Added TDCAL policy document + +Jun 1st, 2003 +v0.84 -- Removed a 4KB buffer from rsa_decrypt_key that wasn't being used no more + -- Fixed another potential buffer problem. Not an overflow but could cause the + PK import routines to read past the end of the buffer. + -- Optimized the ECC mulmod more by removing a if condition that will always be false + -- Optimized prime.c to not include a 2nd prime table, removed code from is_prime calls prime + test from LibTomMath now + -- Added LTC_TEST define which when defined will enable the test vector routines [see mycrypt_custom.h] + -- Removed ampi.o from the depends cuz it ain't no not working in *nix with it [routines are in mpi.c now]. + + +Mar 29th, 2003 +v0.83 -- Optimized the ecc_mulmod, it's faster and takes less heap/stack space + -- Fixed a free memory error in ecc_mulmod and del_point which would try to free NULL + -- Fixed two serious bugs in rsa_decrypt_key and rsa_verify_hash that would allow a trivialy + buffer overflow. + -- Fixed a bug in the hmac testing code if you don't register all the hashes it won't return + errors now. + +Mar 15th, 2003 +v0.82 -- Manual updated + -- Added MSVC makefile [back, actually its written from scratch to work with NMAKE] + -- Change to HMAC helper functions API to avoid buffer overflow [source changes] + -- the rsa_encrypt_key was supposed to reject key sizes out of bounds ... + same fix to the rsa_sign_hash + -- Added code to ensure that that chaining mode code (cfb/ofb/ctr/cbc) have valid + structures when being called. E.g. the indexes to the pad/ivs are not out of bounds + -- Cleaned up the DES code and simplified the core desfunc routine. + -- Simplified one of the boolean functions in MD4 + +Jan 16th, 2003 +v0.81 -- Merged in new makefile from Clay Culver and Mike Frysinger + -- Sped up the ECC mulmod() routine by making the word size adapt to the input. Saves a whopping 9 point + operations on 521-bit keys now (translates to about 8ms on my Athlon XP). I also now use barrett reduction + as much as possible. This sped the routine up quite a bit. + -- Fixed a huge flaw in ecc_verify_hash() where it would return CRYPT_OK on error... Now fixed. + -- Fixed up config.pl by fixing an invalid query and the file is saved in non-windows [e.g. not CR/LF] format + (fix due to Mika Bostr?m) + -- Merged in LibTomMath for kicks + -- Changed the build process so that by default "mycrypt_custom.h" is included and provided + The makefile doesn't include any build options anymore + -- Removed the PS2 and VC makefiles. + +Dec 16th, 2002 +v0.80 -- Found a change I made to the MPI that is questionable. Not quite a bug but definately not desired. Had todo + with the digit shifting. In v0.79 I simply truncated without zeroing. It didn't cause problems during my + testing but I fixed it up none the less. + -- Optimized s_mp_mul_dig() from MPI to do a minimal number of passes. + -- Fixed in rsa_exptmod() where I was getting the size of the result. Basically it accomplishes the same thing + but the fixed code is more readable. + -- Fixed slight bug in dh_sign_hash() where the random "k" value was 1 byte shorter than it should have been. I've + also made the #define FAST_PK speed up signatures as well. Essentially FAST_PK tells the DH sub-system to + limit any private exponent to 256-bits. Note that when FAST_PK is defined does not make the library + binary or source incompatible with a copy of the library with it undefined. + -- Removed the DSA code. If you want fast diffie-hellman just define FAST_PK :-) + -- Updated dh_sign_hash()/dh_verify_hash() to export "unsigned" bignums. Saves two bytes but is not binary + compatible with the previous release... sorry! I've performed the same fix to the ecc code as well. + -- Fixed up the PK code to remove all use of mp_toraw() and mp_read_raw() [get all the changes out of the way now] + -- Fixed a bug in the DH code where it missed trapping a few errors if they occurred. + -- Fixed a slight "its-not-a-bug-but-could-be-done-better" bug in the next_prime() function. Essentially it was + testing to ensure that in the loop that searches for the next candidate that the step never grows beyond + 65000. Should have been testing for MP_DIGIT_MAX + -- Spruced up the config.pl script. It now makes a header file "mycrypt_custom.h" which can be included *before* + you include mycrypt.h. This allows you to add libtomcrypt to a project without completely changing your make + system around. Note that you should use the makefile it writes to at least build the library initially. + -- Used splint to check alot of the code out. Tons of minor fixes and explicit casts added. + -- Also made all the internal functions of MPI are now static to avoid poluting the namespace + -- **Notice**: There are no planned future releases for at least a month from the this release date. + +Dec 14th, 2002 +v0.79 -- Change to PK code [binary and source]. I made it so you have to pass the buffer size to the *_decrypt_key and + *_verify_hash functions. This prevents malformed packets from performing buffer overflows. I've also trimmed + the packet header size [by 4 bytes]. + -- Made the test program halt on the first error it occurs. Also made it trap more errors than before. + -- Wrote the first chapter of my new book [DRAFT!], not in this package but check my website! + -- Included a perl script "config.pl" that will make "makefile.out" according to the users needs. + -- Added shell script to look for latest release + -- Merge DH and ECC key defines from mycrypt_cfg.h into the makefiles + -- updated the makefile to use BSD friendly archiving invokations + -- Changed the DH and ECC code to use base64 static key settings [e.g. the primes]. Dropped the code size by 3KB + and is ever-so-slightly faster than before. + -- added "mp_shrink" function to shrink the size of bignums. Specially useful for PK code :-) + -- Added new exptmod function that calculates a^b mod c with fewer multiplies then before [~20% for crypto + sized numbers]. Also added a "low mem" variant that doesn't use more than 20KB [upto 4096 bit nums] of + heap todo the calculation. Both are #define'able controlled + -- Added XREALLOC macro to provide realloc() functionality. + -- Added fix where in rsa_import() if you imported a public key or a non-optimized key it would free the mp_int's + not being used. + -- Fixed potential bug in the ECC code. Only would occur on platforms where char is not eight bits [which isn't + often!] + -- Fixed up the ECC point multiplication, its about 15% faster now + -- While I was at it [since the lib isn't binary backwards compatible anyways] I've fixed the PK export routines + so they export as "unsigned" types saving 1 byte per bignum outputted. Not a lot but heck why not. + +Nov 28th, 2002 +v0.78 -- Made the default ARGCHK macro a function call instead which reduced the code size from 264KB to 239KB. + -- Fixed a bug in the XTEA keysize function which called ARGCHK incorrectly. + -- Added Noekeon block cipher at 2,800 bytes of object code and 345Mbit/sec it is a welcome addition. + -- Made the KR code check if the other PK systems are included [provides error when building otherwise]. + -- Made "aes" an alias for Rijndael via a pre-processor macro. Now you can use "aes_ecb_encrypt", etc... :-) + Thanks to Jean-Luc Cooke for the "buzzword conformance" suggestion. + -- Removed the old PK code entirely (e.g. rsa_sign, dh_encrypt). The *_sign_hash and *_encrypt_key functions + are all that is to remain. + -- **NOTE** Changed the PK *_import (including the keyring) routine to accept a "inlen" parameter. This fixes a + bug where improperly made key packets could result in reading passed the end of the buffer. This means + the code is no longer source compatible but still binary compatible. + -- Fixed a few other minor bugs in the PK import code while I was at it. + +Nov 26th, 2002 +v0.77 -- Updated the XTEA code to use pre-computed keys. With optimizations for speed it achieves 222Mbit/sec + compared to the 121Mbit/sec before. It is 288 bytes bigger than before. + -- Cleaned up some of the ciphers and hashes (coding style, cosmetic changes) + -- Optimized AES slightly for 256-bit keys [only one if statement now, still two for 192-bit keys] + -- Removed most test cases from Blowfish, left three of them there. Makes it smaller and faster to test. + -- Changed the primality routines around. I now use 8 rounds of Rabin-Miller, I use 256 primes in the sieve + step and the "rand_prime" function uses a modified sieve that avoids alot of un-needed bignum work. + -- Fixed a bug in the ECC/DH signatures where the keys "setting" value was not checked for validity. This means + that a invalid value could have caused segfaults, etc... + -- **NOTE** Changed the way the ECC/DH export/import functions work. They are source but not binary compatible + with v0.76. Essentially insteading of exporting the setting index like before I export the key size. Now + if you ever re-configure which key settings are supported the lib will still be able to make use of your + keys. + -- Optimized Blowfish by inlining the round function, unrolling it for four rounds then using a for loop for the + rest. It achieves a rate of 425Mbit/sec with the new code compared to 314Mbit/sec before. The new blowfish + object file is 7,813 bytes compared to 8,663 before and is 850 bytes smaller. So the code is both smaller and + faster! + -- Optimized Twofish as well by inlining the round function. Gets ~400Mbit/sec compared to 280Mbit/sec before + and the code is only 78 bytes larger than the previous copy. + -- Removed SMALL_PRIME_TAB build option. I use the smaller table always. + -- Fixed some mistakes concerning prime generation in the manual. + -- [Note: sizes/speeds are for GCC 3.2 on an x86 Athlon XP @ 1.53Ghz] + +Nov 25th, 2002 +v0.76 -- Updated makefiles a bit more, use "-Os" instead of "-O2" to optimize for size. Got the lib + downto 265KB using GCC 3.2 on my x86 box. + -- Updated the SAFER+, Twofish and Rijndael test vector routine to use the table driven design. + -- Updated all other test vector routines to return as soon as an error is found + -- fixed a bug in the test program where errors in the hash test routines would not be reported + correctly. I found this by temporarily changing one of the bytes of the test vectors. All the + hashes check out [the demos/test.c would still have reported an error, just the wrong one]. + + +Nov 24th, 2002 +v0.75 -- Fixed a flaw in hash_filehandle, it should ARGCHK that the filehandle is not NULL + -- Fixed a bug where in hash_file if the call to hash_filehandle failed the open file would + not be closed. + -- Added more strict rules to build process, starting to weed out "oh this works in GCC" style code + In the next release "-Wconversion" will be enabled which will deal with all implicit casts. + +Nov 22nd, 2002 [later in the day] +v0.74 -- Wrote a small variant of SAFER+ which shaved 50KB off the size of the library on x86 platforms + -- Wrote a build option to remove the PK packet functions [keeps the encrypt_key/sign_hash functions] + -- Wrote a small variant of Rijndael (trimmed 13KB) + -- Trimmed the TIGER/192 hash function a bit + -- Overall the entire lib compiled is 295KB [down from 400KB before] + -- Fixed a few minor oversights in the MSVC makefile + +Nov 22nd, 2002 +v0.73 -- Fixed bug in RC4 code where it could only use 255 byte keys. + -- Fixed bug in yarrow code where it would allow cast5 or md2 to be used with it... + -- Removed the ecc compress/expand points from the global scope. Reduces namespace polution + -- Fixed bug where if you used the SPRNG you couldn't pass NULL as your prng_state which you should be + able todo since the SPRNG has no state... + -- Corrected some oversights in the manual and the examples... + -- By default the GF(2^W) math library is excluded from the build. The source is maintained because I wrote it + and like it :-). This way the built library is a tad smaller + -- the MSVC makefile will now build for a SPACE optimized library rather than TIME optimized. + +Nov 21th, 2002 +v0.72 -- Fixed bug in the prime testing. In the Miller-Rabin test I was raising the base to "N-1" not "r". + The math still worked out fine because in effect it was performing a Fermat test. Tested the new code and it + works properly + -- Fixed some of the code where it was still using the old error syntax + -- Sped up the RSA decrypt/sign routines + -- Optimized the ecc_shared_secret routine to not use so much stack + -- Fixed up the makefile to make releases where the version # is in the file name and directory it will unzip + to + +Nov 19th, 2002 +v0.71 -- HELP TOM. I need tuition for the January semester. Now I don't want to force donations [nor will I ever] + but I really need the help! See my website http://tom.iahu.ca/help_tom.html for more details. Please help + if you can! + -------------------------------------------------------------------------------------------------------------- + -- Officially the library is no longer supported in GCC 3.2 in windows [cygwin]. + In windows you can either use GCC 2.95.3 or try your luck with 3.2 It seems that + "-fomit-frame-pointer" is broken in the windows build [but not the linux x86 build???] + If you simply must use 3.2 then I suggest you limit the optimizations to simply "-O2" + -- Started new error handling API. Similar to the previous except there are more error codes than just + CRYPT_ERROR + -- Added my implementation of the MD2 hash function [despite the errors in the RFC I managed to get it right!] + -- Merged in more changes from Sky Schulz. I have to make mention here that he has been a tremendous help in + getting me motivated to make some much needed updates to the library! + -- Fixed one of the many mistakes in the manual as pointed out by Daniel Richards + -- Fixed a bug in the RC4 code [wasn't setting up the key correctly] + -- Added my implementation of the CAST5 [aka CAST-128] block cipher (conforms...) + -- Fixed numerous bugs in the PK code. Essentially I was "freeing" keys when the import failed. This is neither + required nor a good a idea [double free]. + -- Tom needs a job. + -- Fixed up the test harness as requested by Sky Schulz. Also modifed the timing routines to run for X seconds + and count # of ops performed. This is more suitable than say encrypting 10 million blocks on a slow processor + where it could take minutes! + -- Modified test programs hashsum/encrypt to use the new algorithms and error handling syntax + -- Removed the PKCS code since it was incomplete. In the future I plan on writing a "add-on" library that + provides PKCS support... + -- updated the config system so the #defines are in the makefiles instead of mycrypt_cfg.h + -- Willing to work on an hourly basis for 15$ CDN per hour. + -- updated the test program to not test ciphers not included + -- updated the makefile to make "rsa_sys.c" a dependency of rsa.o [helps develop the code...] + -- fixed numerous failures to detect buffer overflows [minor] in the PK code. + -- fixed the safer [64-bit block version] test routines which didn't check the returns of the setup + function + -- check out my CV at http://tom.iahu.ca/cv.html + -- removed the GBA makefile and code from demos/test.c [not a particularly useful demo...] + -- merged in rudimentary [for testing] PS2 RNG from Sky Schulz + -- merged in PS2 timer code [only shell included due to NDA reasons...] + -- updated HMAC code to return errors where possible + -- Thanks go to Sky Schulz who bought me a RegCode for TextPad [the official editor of libtomcrypt] + +Nov 12th, 2002 +v0.70 -- Updated so you can swap out the default malloc/calloc/free routines at build time with others. (Sky Schulz) + -- Sky Schulz contributed some code towards autodetecting the PS2 in mycrypt_cfg.h + -- Added PS2 makefile contributed by Sky Schulz [see a pattern forming?] + -- Added ability to have no FILE I/O functions at all (see makefile), Sky Schulz.... + -- Added support for substituting out the clock() function (Sky Schulz) + -- Fixed up makefile to include new headers in the HEADERS variable + -- Removed "coin.c" as its not really useful anyways + -- Removed many "debug" printfs that would show up on failures. Basically I wanted to ensure the only output + would be from the developer themselves. + -- Added "rc4.c" a RC4 implementation with a PRNG interface. Since RC4 isn't a block cipher it wouldn't work + too well as a block cipher. + -- Fixed ARGCHK macro usage when ARGTYPE=1 throughout the code + -- updated makefile to make subdirectory properly (Sku Schulz) + -- Started towards new API setup. Instead of checking for "== CRYPT_ERROR" you should check "!= CRYPT_OK" + In future releases functions will return things other than CRYPT_ERROR on error to give more useful + thread safe error reporting. The manual will be updated to reflect this. For this release all + errors are returned as CRYPT_ERROR (except as noted) but in future releases this will change. + -- Removed the zlib branch since its not really required anyways. Makes the package smaller + +Nov 11th, 2002 +v0.69 -- Added ARGCHK (see mycrypt_argchk.h) "arguement checking" to all functions that accept pointers + -- Note I forgot to change the CRYPT version tag in v0.68... fixed now. + +Nov 8th, 2002 +v0.68 -- Fixed flaw in kr_import/kr_export that wasted 4 bytes. Source but not binary compatible with v0.67 + -- Fixed bug in kr_find_name that used memcmp to match strings. Uses strncmp now. + -- kr_clear now sets the pointer to NULL to facilate debugging [e.g. using the keyring after clearing] + -- static functions in _write/_read in keyring.c now check the return of ctr_encrypt/ctr_decrypt. + -- Updated blowfish/rc2/rc5/rc6 keysize() function to not reject keys larger than the biggest key the + respective ciphers can use. + -- Fixed a bug in hashsum demo that would report the hash for files that don't exist! + +Oct 16th, 2002 +v0.67 -- Moved the function prototypes into files mycrypt_*.h. To "install" the lib just copy all the + header files "*.h" from the base of this project into your global include path. + -- Made the OFB/CFB/CTR functions use "unsigned long" for the length instead of "int" + -- Added keyring support for the PK functions + -- ***API CHANGE*** changed the ecc_make_key and dh_make_key to act more like rsa_make_key. Basically + move the first argument to the next to last. + -- Fixed bug in dh_test() that wouldn't test the primality of the order of the sub-group + -- replaced the primes in the DH code with new ones that are larger than the size they are + associated with. That is a 1024-bit DH key will have a 1025-bit prime as the modulus + -- cleaned up all the PK code, changed a bit of the API around [not source compatible with v0.66] + -- major editing of the manual, started Docer program + -- added 160 and 224 bit key settings for ECC. This makes the DH and ECC binary wise incompatible with v0.66 + -- Added an additional check for memory errors in is_prime() and cleaned up prime.c a bit + -- Removed ID_TAG from all files [meh, not a big fan...] + -- Removed unused variable from yarrow state and made AES/SHA256 the default cipher/hash combo + -- Fixed a bug in the Yarrow code that called prng_is_valid instead of cipher_is_valid from yarrow_start() + -- The ECB/CBC/OFB/CFB/CTR wrappers now check that the cipher is valid in the encrypt/decrypt calls + Returns int now instead of void. + +Sept 24th, 2002 +v0.66 -- Updated the /demos/test.c program to time the hashes correctly. Also it uses the yarrow PRNG for all of the + tests meaning its possible to run on RNG less platforms + -- Updated the /demos/hashsum.c program to hash from the standard input + -- Updated the RSA code to make keys a bit quicker [update by Wayne Scott] by not making both primes at the same + time. + -- Dan Kaminsky suggested some cleanups for the code and the MPI config + Code ships in unix LF format by default now too... will still build in MSVC and all... but if you want + to read the stuff you'll have to convert it + -- Changes to the manual to reflect new API [e.g. hash_memory/file have v0.65 prototypes]and some typos fixed + +Sept 20th, 2002 +v0.65 -- Wayne Scott (wscott@bitmover.com) made a few of suggestions to improve the library. Most + importantly he pointed out the math lib is not really required. He's also tested the lib on 18 + different platforms. According to him with only a few troubles [lack of /dev/random, etc] the + library worked as it was supposed to. You can find the list at + http://www.bitkeeper.com/Products.BitKeeper.Platforms.html + -- Updated the hash_file and hash_memory functions to keep track of the size of the output + -- Wayne Scott updated the demos/test.c file to use the SPRNG less and Yarrow more + -- Modified the mycrypt_cfg.h to autodetect x86-32 machines + +Sept 19th, 2002 +v0.64 -- wrote makefile for the GBA device [and hacked the demos/test.c file to support it conditionally] + -- Fixed error in PK (e.g. ECC, RSA, DH) import functions where I was clobbering the packet error messages + -- fixed more typos in the manual + -- removed all unused variables from the core library (ignore the ID_TAG stuff) + -- added "const char *crypt_build_settings" string which is a build time constant that gives a listing + of all the build time options. Useful for debugging since you can send that to me and I will know what + exactly you had set for the mycrypt_cfg.h file. + -- Added control over endianess. Out of the box it defaults to endianess neutral but you can trivially + configure the library for your platform. Using this I boosted RC5 from 660Mbit/sec to 785Mbit/sec on my + Athlon box. See "mycrypt_cfg.h" for more information. + +Sept 11th, 2002 +v0.63 -- Made hashsum demo output like the original md5sum program + -- Made additions to the examples in the manual (fixed them up a bunch) + -- Merged in the base64 code from Wayne Scott (wscott@bitmover.com) + +Aug 29th, 2002 +v0.62 -- Added the CLEAN_STACK functionality to several of the hashes I forgot to update. + +Aug 9th, 2002 +v0.61 -- Fixed a bug in the DES code [oops I read something wrong]. + +Aug 8th, 2002 +v0.60 -- Merged in DES code [and wrote 3DES-EDE code based on it] from Dobes V. + +Aug 7th, 2002 +v0.59 -- Fixed a "unsigned long long" bug that caused v0.58 not to build in MSVC. + -- Cleaned up a little in the makefile + -- added code that times the hash functions too in the test program + +Aug 3rd, 2002 +v0.58 -- Added more stack cleaning conditionals throughout the code. + -- corrected some CLEAR_STACK conditionals... should have been CLEAN_STACK + -- Simplified the RSA, DH and ECC encrypt() routines where they use CTR to encode the message + now they only make one call to ctr_encrypt()/ctr_decrypt(). + +Aug 2nd, 2002 +v0.57 -- Fixed a few errors messages in the SAFER code to actually report the correct cipher name. + -- rsa_encrypt() uses the "keysize()" method of the cipher being used to more accurately pick a + key size. By default rsa_encrypt() will choose to use a 256-bit key but the cipher can turn that + down if required. + -- The rsa_exptmod() function will now more reliably detect invalid inputs (e.g. greater than the modulus). + -- The padding method for RSA is more clearly documented. Namely if you want to encrypt/sign something of length + N then your modulus must be of length 1+3N. So to sign a message with say SHA-384 [48 bytes] you need a + 145 byte (1160 bits) modulus. This is all in the manual now. + -- Added build option CLEAN_STACK which will allow you to choose whether you want to clean the stack or not after every + cipher/hash call + -- Sped up the hash "process()" functions by not copying one byte at a time. + ++ (added just after I uploaded...) + MD4 process() now handles input buffers > 64 bytes + +Aug 1st, 2002 +v0.56 -- Cleaned up the comments in the Blowfish code. + -- Oh yeah, in v0.55 I made all of the descriptor elements constant. I just forgot to mention it. + -- fixed a couple of places where descriptor indexes were tested wrong. Not a huge bug but now its harder + to mess up. + -- Added the SAFER [64-bit block] ciphers K64, SK64, K128 and SK128 to the library. + -- Added the RC2 block cipher to the library. + -- Changed the SAFER define for the SAFER+ cipher to SAFERP so that the new SAFER [64-bit] ciphers + can use them with less confusion. + +July 29th, 2002 +v0.55 -- My god stupid Blowfish has yet again been fixed. I swear I hate that cipher. Next bug in it and boom its out of the + library. Use AES or something else cuz I really hate Blowfish at this stage.... + -- Partial PKCS support [hint DONT USE IT YET CUZ ITS UNTESTED!] + +July 19th, 2002 +v0.54 -- Blowfish now conforms to known test vectors. Silly bad coding tom! + -- RC5/RC6/Serpent all have more test vectors now [and they seemed to have been working before] + +July 18th, 2002 +v0.53 -- Added more test vectors to the blowfish code just for kicks [and they are const now too :-)] + -- added prng/hash/cipher is_valid functions and used them in all of the PK code so you can't enter the code + with an invalid index ever now. + -- Simplified the Yarrow code once again :-) + +July 12th, 2002 +v0.52 -- Fixed a bug in MD4 where the hash descriptor ID was the same as SHA-512. Now MD4 will work with + all the routines... + -- Fixed the comments in SHA-512 to be a bit more meaningful + -- In md4 I made the PADDING array const [again to store it in ROM] + -- in hash_file I switched the constant "512" to "sizeof(buf)" to be a bit safer + -- in SHA-1's test routine I fixed the string literal to say SHA-1 not sha1 + -- Fixed a logical error in the CTR code which would make it skip the first IV value. This means + the CTR code from v0.52 will be incompatible [binary wise] with previous releases but it makes more + sense this way. + -- Added {} braces for as many if/for/blocks of code I could find. My rule is that every for/if/while/do block + must have {} braces around it. + -- made the rounds table in saferp_setup const [again for the ROM think about the ROM!] + -- fixed RC5 since it no longer requires rc5 to be registered in the lib. It used to since the descriptors used to + be part of the table... + -- the packet.c code now makes crypt_error literal string errors when an error occurs + -- cleaned up the SAFER+ key schedule to be a bit easier to read. + -- fixed a huge bug in Twofish with the TWOFISH_SMALL define. Because I clean the stack now I had + changed the "g_func()" to be called indirectly. I forgot to actually return the return of the Twofish + g_func() function which caused it not to work... [does now :-)] + +July 11th, 2002 +v0.51 -- Fixed a bug in SHA512/384 code for multi-block messages. + -- Added more test vectors to the SHA384/512 and TIGER hash functions + -- cleaned up the hash done routines to make more sense + +July 10th, 2002 +v0.50 -- Fixed yarrow.c so that the cipher/hash used would be registered. Also fixed + a bug where the SAFER+ name was "safer" but should have been "safer+". + -- Added an element to the hash descriptors that gives the size of a block [sent into the compressor] + -- Cleaned up the support for HMAC's + -- Cleaned up the test vector routines to make the test vector data const. This means on some platforms it will be + placed in ROM not RAM now. + -- Added MD4 code submited by Dobes Vandermeer (dobes@smartt.com) + -- Added "burn_stack" function [idea taken from another source of crypto code]. The idea is if a function has + alot of variables it will clean up better. Functions like the ecb serpent and twofish code will now have their + stacks cleaned and the rest of the code is getting much more straightforward. + -- Added a hashing demo by Daniel Richards (kyhwana@world-net.co.nz) + -- I (Tom) modified some of the test vector routines to use more vectors ala Dobes style. + For example, the MD5/SHA1 code now uses all of the test vectors from the RFC/FIPS spec. + -- Fixed the register/unregister functions to properly report errors in crypt_error + -- Correctly updated yarrow code to remove a few unused variables. + -- Updated manual to fix a few erroneous examples. + -- Added section on Hash based Message Authentication Codes (HMAC) to the manual + +June 19th, 2002 +v0.46 -- Added in HMAC code from Dobes Vandermeer (dobes@smartt.com) + +June 8th, 2002 +v0.45 -- Fixed bug in rc5.c where if you called rc5_setup() before registering RC5 it would cause + undefined behaviour. + -- Fixed mycrypt_cfg.h to eliminate the 224 bit ECC key. + -- made the "default" makefile target have depends on mycrypt.h and mycrypt_cfg.h + +Apr 4th, 2002 +v0.44 -- Fixed bug in ecc.c::new_point() where if the initial malloc fails it would not catch it. + +Mar 22nd, 2002 +v0.43 -- Changed the ZLIB code over to the 1.1.4 code base to avoid the "double free" bug. + -- Updated the GCC makefile not to use -O3 or -funroll-loops + -- Version tag in mycrypt.h has been updated :-) + +Mar 10th, 2002 +v0.42 -- The RNG code can now use /dev/urandom before trying /dev/random (J. Klapste) + +Mar 3rd, 2002 +v0.41 -- Added support to link and use ciphers at compile time. This can greatly reduce the code size! + -- Added a demo to show off how small an application can get... 46kb! + -- Disastry pointed out that Blowfish is supposed to be high endian. + -- Made registry code for the PRNGs as well [now the smallest useable link is 43kb] + +Feb 11th, 2002 +v0.40 -- RSA signatures use [and check for] fixed padding scheme. + -- I'm developing in Linux now :-) + -- No more warnings from GCC 2.96 + +Feb 5th, 2002 +v0.39 -- Updated the XTEA code to work in accordance with the XTEA design + +January 24th, 2002 +v0.38 -- CFB and OFB modes can now handle blocks of variable size like the CTR code + -- Wrote a wrapper around the memory compress functions in Zlib that act like the functions + in the rest of my crypto lib + +January 23rd, 2002 +v0.37 -- Added support code so that if a hash size and key size for a cipher don't match up they will + use the next lower key supported. (mainly for the PK code). So you can now use SHA-1 with + Twofish, etc... + -- Added more options for Twofish. You can now tell it to use precomputed sboxes and MDS multiplications + This will speed up the TWOFISH_SMALL implementation by increasing the code size by 1024 bytes. + -- Fixed a bug in prime.c that would not use the correct table if you undefined SMALL_PRIME_TAB + -- Fixed all of the PK packet code to use the same header format [see packet.c]. This makes the PK code + binary wise incompatible with previous releases while the API has not changed at all. + +January 22nd, 2002 +v0.36 -- Corrections to the manual + -- Made a modification to Twofish which lets you build a "small ram" variant. It requires + about 190 bytes of ram for the key storage compared to the 4,200 bytes the normal + variant requires. + -- Reduced the stack space used in all of the PK routines. + +January 19th, 2002 +v0.35 -- If you removed the first hash or cipher from the library it wouldn't return an error if + you used an ID=0 [i.e blowfish or sha256] in any routine. Now it checks for that and will + return an error like it should + -- Merged in new routines from Clay Culver. These routines are for the PK code so you can easily + encode a symmetric key for multiple recipients. + -- Made the ecc and DH make_key() routines make secret keys of the same size as the keysize listed. + Originally I wanted to ensure that the keys were smaller than the order of the field used + However, the bias is so insignifcant using full sizes. For example, with a ECC-192 key the order + is about 2^191.99, so instead I rounded down and used a 184-bit secret key. Now I simply use a full 192-bit + key the code will work just the same except that some 192-bit keys will be duplicates which is not a big + deal since 1/2^192 is a very small bias! + -- Made the configuration a bit simpler and more exacting. You can for example now select which DH or ECC + key settings you wish to support without including the data for all other key settings. I put the #defines + in a new file called "mycrypt_cfg.h" + -- Configured "mpi-config.h" so its a bit more conservative with the memory required and code space used + -- Jason Klapste submitted bug fixes to the yarrow, hash and various other issues. The yarrow code will now + use what ever remaining hash/cipher combo is left [after you #undef them] at build time. He also suggested + a fix to remove unused structures from the symmetric_key and hash_state unions. + -- Made the CTR code handle variable length blocks better. It will buffer the encryption pad so you can + encrypt messages any size block at a time. + -- Simplified the yarrow code to take advantage of the new CTR code. + -- Added a 4096-bit DH key setting. That took me about 36 hours to find! + -- Changed the base64 routines to use a real base64 encoding scheme. + -- Added in DH and ECC "encrypt_key()" functions. They are still rather "beta"ish. + -- Added **Twofish** to the list of ciphers! + +January 18th, 2002 +v0.34 -- Added "sha512" to the list of hashes. Produces a 512-bit message digest. Note that with the current + padding with the rsa_sign() function you cannot use sha512 with a key less than 1536 bits for signatures. + -- Cleaned up the other hash functions to use the LOAD and STORE macros... + +January 17th, 2002 +v0.33 -- Made the lower limit on keysizes for RSA 1024 bits again because I realized that 768 bit keys wouldn't + work with the padding scheme and large symmetric keys. + -- Added information concerning the Zlib license to the manual + -- Added a 3072-bit key setting for the DH code. + -- Made the "find_xyz()" routines take "const char *" as per Clay Culver's suggestion. + -- Fixed an embarassing typo in the manual concerning the hashes. Thank's Clay for finding it! + -- Fixed rand_prime() so that it makes primes bigger than the setting you give. For example, + if you want a 1024-bit prime it would make a 1023-bit one. Now it ensures that the prime + it makes is always greater than 2^(8n) (n == bytes in prime). This doesn't have a huge + impact on security but I corrected it just the same. + -- Fixed the CTR routine to work on platforms where char != 8-bits + -- Fixed sha1/sha256/md5/blowfish to not assume "unsigned long == 32-bits", Basically any operation with carries + I "AND" with 0xFFFFFFFF. That forces only the lower 32-bits to have information in it. On x86 platforms + most compilers optimize out the AND operation since its a nop. + +January 16th, 2002 +v0.32 -- Made Rijndael's setup function fully static so it is thread safe + -- Svante Seleborg suggested a cosmetic style fixup for aes.c, + basically to remove some of the #defines to clean it up + -- Made the PK routines not export the ASCII version of the names of ciphers/hashes which makes + the PK message formats *incompatible* with previous releases. + -- Merge in Zlib :-) + + +January 15th, 2002 +v0.31 -- The RSA routines can now use CRT to speed up decryption/signatures. The routines are backwards + compatible with previous releases. + -- Fixed another bug that Svante Seleborg found. Basically you could buffer-overrun the + rsa_exptmod() function itself if you're not careful. That's fixed now. Fixed another bug in + rsa_exptmod() where if it knows the buffer you passed is too small it wouldn't free all used + memory. + -- improved the readability of the PK import/export functions + -- Added a fix to RSA.C by Clay Culver + -- Changed the CONST64 macro for MSVC to use the "unsigned __int64" type, e.g. "ui64" instead of "i64". + +January 14th, 2002 +v0.30 -- Major change to the Yarrow PRNG code, fixed a bug that Eugene Starokoltsev found. + Basically if you added entropy to the pool in small increments it could in fact + cancel out. Now I hash the pool with the new data which is way smarter. + +January 12th, 2002 +v0.29 -- Added MPI code written by Svante Seleborg to the library. This will make the PK code much + easier to follow and debug. Actually I've already fixed a memory leak in dh_shared_secret(). + -- Memory leaks found and correct in all three PK routines. The leaks would occur when a bignum + operation fails so it wouldn't normally turn up in the course of a program + -- Fixed bugs in dh_key_size and ecc_key_size which would return garbage for invalid key idx'es + +January 11th, 2002 +v0.28 -- Cleaned up some code so that it doesn't assume "char == 8bits". Mainly SAFER+ has been + changed. + -- ***HUGE*** changes in the PK code. I check all return values in the bignum code so if there + are errors [insufficient memory, etc..] it will be reported. This makes the code fairly more + robust and likely to catch any errors. + -- Updated the is_prime() function to use a new prototype [it can return errors now] and it also + does trial divisions against more primes before the Rabin Miller steps + -- Added OFB, CFB and ECB generic wrappers for the symmetric ciphers to round out the implementations. + -- Added Xtea to the list of ciphers, to the best of my ability I have verified this implementation. + I should note that there is not alot of concrete information about the cipher. "Ansi C" versions + I found did not address endianess and were not even portable!. This code is portable and to the + best of my knowledge implements the Xtea algorithm as per the [short] X-Tea paper. + -- Reformated the manual to include the **FULL** source code optimized to be pritable. + +January 9th, 2002 +v0.27 -- Changed the char constants to numerical values. It is backwards compatible and should work on + platforms where 'd' != 100 [for example]. + -- Made a change to rand_prime() which takes the input length as a signed type so you can pass + a negative len to get a "3 mod 4" style prime... oops + -- changed the MSVC makefile to build with a warning level of three, no warnings! + +January 8th, 2002 +v0.26 -- updated SHA-256 to use ROR() for a rotate so 64-bit machines won't corrupt + the output + -- Changed #include <> to #include "" for local .h files as per Richard Heathfields' suggestions. + -- Fixed bug in MPI [well bug in MSVC] that compiled code incorrectly in mp_set_int() + I added a work around that catches the error and continues normally. + +January 8th, 2002 +v0.25 -- Added a stupid define so MSVC 6.00 can build the library. + -- Big thanks to sci.crypt and "Ajay K. Agrawal" for helping me port this to MSVC + +January 7th, 2002 +v0.24 -- Sped up Blowfish by unrolling and removing the swaps. + -- Made the code comply with more traditional ANSI C standards + Should compile with MSVC with less errors + -- moved the demos and documentation into their own directories + so you can easily build the library with other tool chains + by compiling the files in the root + -- converted functions with length of outputs to use + "unsigned long" so 16-bit platforms will like this library more. + +January 5th, 2002 +v0.23 -- Fixed a small error in the MPI config it should build fine anywhere. + +January 4th, 2002 +v0.22 -- faster gf_mul() code + -- gf_shl() and gf_shr() are safe on 64-bit platforms now + -- Fixed an error in the hashes that Brian Gladman found. + Basically if the message has exactly 56 bytes left to be + compressed I handled them incorrectly. + +January 4th, 2002 +v0.21 -- sped up the ECC code by removing redundant divisions in the + point add and double routines. I also extract the bits more + efficiently in "ecc_mulmod()" now. + -- sped up [and documented] the rand_prime() function. Now it just + makes a random integer and increments by two until a prime is found + This is faster since it doesn't require alot of calls to the PRNG and + it doesn't require loading huge integers over and over. rand_prime() + can also make primes congruent to 3 mod 4 [i.e for a blum integer] + -- added a gf_sqrt() function that finds square roots in a GF(2^w) field + -- fixed a bug in gf_div() that would return the wrong results if the divisor had a greator + divisor than the dividend. + +January 4th, 2002 +v0.20 -- Added the fixed MPI back in so RSA and DH are much faster again + +v0.19 -- Updated the manual to reflect the fact that Brian Gladman wrote the AES and Serpent code. + -- DH, ECC and RSA signature/decryption functions check if the key is private + -- new DH signature/verification code works just like the RSA/ECC versions + +January 3rd, 2002 +v0.18 -- Added way more comments to each .C file + -- fixed a bug in cbc_decrypt(pt, ct, key) where pt == ct [i.e same buffer] + -- fixed RC5 so it reads the default rounds out of the cipher_descriptor table + -- cleaned up ecc_export() + -- Cleaned up dh_import() and ecc_import() which also perform more + error checking now + -- Fixed a serious flaw in rsa_import() with private keys. + +January 2nd, 2002 +v0.17 -- Fixed a bug in the random prime generator that fixes the wrong bits to one + -- ECC and DH code verify that the moduli and orders are in fact prime. That + slows down the test routines alot but what are you gonna do? + -- Fixed a huge bug in the mp_exptmod() function which incorrectly calculates g^x mod p for some + values of p. I replaced it with a slow function. Once the author of MPI fixes his faster routine + I will switch back. + +January 1st, 2002 [whoa new year!] +v0.16 -- Improved GF division code that is faster. + -- documented the GF code + +December 31st, 2001 +v0.15 -- A 1792-bit and 2048-bit DH setting was added. Took me all night to + find a 1792 and 2048-bit strong prime but what the heck + -- Library now has polynomial-basis GF(2^w) routines I wrote myself. Can be used to perform + ECC over GF(2^w) later on.... + -- Fixed a bug with the defines that allows it to build in windows + +December 30th, 2001 +v0.14 -- Fixed the xxx_encrypt() packet routines to make an IV of appropriate size + for the cipher used. It was defaulting to making a 256-bit IV... + -- base64_encode() now appends a NULL byte, um "duh" stupid mistake now fixed... + -- spell checked the manual again... :-) + +December 30th, 2001 +v0.13 -- Switching back to older copy of MPI since it works! arrg.. + -- Added sign/verify functions for ECC + -- all signature verification routines default to invalid signatures. + -- Changed all calls to memset to zeromem. Fixed up some buffer problems + in other routines. All calls to zeromem let the compiler determine the size + of the data to wipe. + +December 29th, 2001 +v0.12 -- Imported a new version of MPI [the bignum library] that should + be a bit more stable [if you want to write your own bignum + routines with the library that is...] + -- Manual has way more info + -- hash_file() clears stack now [like it should] + -- The artificial cap on the hash input size of 2^32 bits has been + removed. Basically I was too lazy todo 64-bit math before + [don't ask why... I can't remember]. Anyways the hashes + support the size of 2^64 bits [if you ever use that many bits in a message + that's just wierd...] + -- The hashes now wipe the "hash_state" after the digest is computed. This helps + prevent the internal state of the hash being leaked accidently [i.e stack problems] + +December 29th, 2001 +v0.11 -- Made #define's so you can trim the library down by removing + ciphers, hashs, modes of operation, prngs, and even PK algorithms + For example, the library with rijndael+ctr+sha1+ECC is 91KB compared + to the 246kb the full library takes. + -- Added ECC packet routines for encrypt/decrypt/sign/verify much akin to + the RSA packet routines. + -- ECC now compresses the public key, a ECC-192 public key takes 33 bytes + for example.... + +December 28th, 2001 +v0.10 -- going to restart the manual from scratch to make it more + clear and professional + -- Added ECC over Z/pZ. Basically provides as much as DH + except its faster since the numbers are smaller. For example, + A comparable 256-bit ECC key provides as much security as expected + from a DH key over 1024-bits. + -- Cleaned up the DH code to not export the symbol "sets[]" + -- Fixed a bug in the DH code that would not make the correct size + random string if you made the key short. For instance if you wanted + a 512-bit DH key it would make a 768-bit one but only make up 512-bits + for the exponent... now it makes the full 768 bits [or whatever the case + is] + -- Fixed another ***SERIOUS*** bug in the DH code that would default to 768-bit + keys by mistake. + +December 25th, 2001 +v0.09 -- Includes a demo program called file_crypt which shows off + how to use the library to make a command line tool which + allows the user to encode/decode a file with any + hash (on the passphrase) and cipher in CTR mode. + -- Switched everything to use typedef's now to clear up the code. + -- Added AES (128/192 and 256 bit key modes) + +December 24th, 2001 +v0.08 -- fixed a typo in the manual. MPI stores its bignums in + BIG endian not little. + -- Started adding a RNG to the library. Right now it tries + to open /dev/random and if that fails it uses either the + MS CSP or the clock drift RNG. It also allows callbacks + since the drift RNG is slow (about 3.5 bytes/sec) + -- the RNG can also automatically setup a PRNG as well now + +v0.07 -- Added basic DH routines sufficient to + negotiate shared secrets + [see the manual for a complete example!] + -- Fixed rsa_import to detect when the input + could be corrupt. + -- added more to the manual. + +December 22nd, 2001 +v0.06 -- Fixed some formatting errors in + the hash functions [just source code cleaning] + -- Fixed a typo in the error message for sha256 :-) + -- Fixed an error in base64_encode() that + would fail to catch all buffer overruns + -- Test program times the RSA and symmetric cipher + routines for kicks... + -- Added the "const" modifier to alot of routines to + clear up the purpose of each function. + -- Changed the name of the library to "TomCrypt" + following a suggestion from a sci.crypt reader.... + +v0.05 -- Fixed the ROL/ROR macro to be safe on platforms + where unsigned long is not 32-bits + -- I have added a bit more to the documentation + manual "crypt.pdf" provided. + -- I have added a makefile for LCC-Win32. It should be + easy to port to other LCC platforms by changing a few lines. + -- Ran a spell checker over the manual. + -- Changed the header and library from "crypt" to "mycrypt" to not + clash with the *nix package "crypt". + +v0.04 -- Fixed a bug in the RC5,RC6,Blowfish key schedules + where if the key was not a multiple of 4 bytes it would + not get loaded correctly. + +December 21st, 2001 + +v0.03 -- Added Serpent to the list of ciphers. + +v0.02 -- Changed RC5 to only allow 12 to 24 rounds + -- Added more to the manual. + +v0.01 -- We will call this the first version. + +/* $Source: /cvs/libtom/libtomcrypt/changes,v $ */ +/* $Revision: 1.288 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/crypt.lof b/xmhf-64/xmhf/third-party/libtomcrypt/crypt.lof new file mode 100644 index 0000000000..ba16c2d8df --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/crypt.lof @@ -0,0 +1,24 @@ +\addvspace {10\p@ } +\addvspace {10\p@ } +\contentsline {figure}{\numberline {2.1}{\ignorespaces Load And Store Macros}}{9}{figure.2.1} +\contentsline {figure}{\numberline {2.2}{\ignorespaces Rotate Macros}}{9}{figure.2.2} +\addvspace {10\p@ } +\contentsline {figure}{\numberline {3.1}{\ignorespaces Built--In Software Ciphers}}{19}{figure.3.1} +\contentsline {figure}{\numberline {3.2}{\ignorespaces Twofish Build Options}}{21}{figure.3.2} +\addvspace {10\p@ } +\contentsline {figure}{\numberline {4.1}{\ignorespaces Built--In Software Hashes}}{59}{figure.4.1} +\addvspace {10\p@ } +\addvspace {10\p@ } +\contentsline {figure}{\numberline {6.1}{\ignorespaces List of Provided PRNGs}}{84}{figure.6.1} +\addvspace {10\p@ } +\addvspace {10\p@ } +\addvspace {10\p@ } +\contentsline {figure}{\numberline {9.1}{\ignorespaces DSA Key Sizes}}{121}{figure.9.1} +\addvspace {10\p@ } +\contentsline {figure}{\numberline {10.1}{\ignorespaces List of ASN.1 Supported Types}}{129}{figure.10.1} +\addvspace {10\p@ } +\addvspace {10\p@ } +\contentsline {figure}{\numberline {12.1}{\ignorespaces RSA/DH Key Strength}}{151}{figure.12.1} +\contentsline {figure}{\numberline {12.2}{\ignorespaces ECC Key Strength}}{151}{figure.12.2} +\addvspace {10\p@ } +\addvspace {10\p@ } diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/crypt.tex b/xmhf-64/xmhf/third-party/libtomcrypt/crypt.tex new file mode 100644 index 0000000000..31bf399b96 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/crypt.tex @@ -0,0 +1,6568 @@ +\documentclass[synpaper]{book} +\usepackage[dvips]{geometry} +\usepackage{hyperref} +\usepackage{makeidx} +\usepackage{amssymb} +\usepackage{color} +\usepackage{alltt} +\usepackage{graphicx} +\usepackage{layout} +\usepackage{fancyhdr} +\def\union{\cup} +\def\intersect{\cap} +\def\getsrandom{\stackrel{\rm R}{\gets}} +\def\cross{\times} +\def\cat{\hspace{0.5em} \| \hspace{0.5em}} +\def\catn{$\|$} +\def\divides{\hspace{0.3em} | \hspace{0.3em}} +\def\nequiv{\not\equiv} +\def\approx{\raisebox{0.2ex}{\mbox{\small $\sim$}}} +\def\lcm{{\rm lcm}} +\def\gcd{{\rm gcd}} +\def\log{{\rm log}} +\def\ord{{\rm ord}} +\def\abs{{\mathit abs}} +\def\rep{{\mathit rep}} +\def\mod{{\mathit\ mod\ }} +\renewcommand{\pmod}[1]{\ ({\rm mod\ }{#1})} +\newcommand{\floor}[1]{\left\lfloor{#1}\right\rfloor} +\newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil} +\def\Or{{\rm\ or\ }} +\def\And{{\rm\ and\ }} +\def\iff{\hspace{1em}\Longleftrightarrow\hspace{1em}} +\def\implies{\Rightarrow} +\def\undefined{{\rm \textit{undefined}}} +\def\Proof{\vspace{1ex}\noindent {\bf Proof:}\hspace{1em}} +\let\oldphi\phi +\def\phi{\varphi} +\def\Pr{{\rm Pr}} +\newcommand{\str}[1]{{\mathbf{#1}}} +\def\F{{\mathbb F}} +\def\N{{\mathbb N}} +\def\Z{{\mathbb Z}} +\def\R{{\mathbb R}} +\def\C{{\mathbb C}} +\def\Q{{\mathbb Q}} +\definecolor{DGray}{gray}{0.5} +\newcommand{\emailaddr}[1]{\mbox{$<${#1}$>$}} +\def\twiddle{\raisebox{0.3ex}{\mbox{\tiny $\sim$}}} +\def\gap{\vspace{0.5ex}} +\makeindex +\newcommand{\mysection}[1] % Re-define the chaptering command to use + { % THESE headers. + \section{#1} + \markboth{\textsf{www.libtom.org}}{\thesection ~ {#1}} + } + +\newcommand{\mystarsection}[1] % Re-define the chaptering command to use + { % THESE headers. + \section*{#1} + \markboth{\textsf{www.libtom.org}}{{#1}} + } +\pagestyle{empty} +\begin{document} +\frontmatter +\pagestyle{empty} + +~ + +\vspace{2in} + +~ + +\begin{center} +\begin{Huge}LibTomCrypt\end{Huge} + +~ + +\begin{large}Developer Manual\end{large} + +~ + +\vspace{15mm} + + +\begin{tabular}{c} +Tom St Denis \\ +LibTom Projects +\end{tabular} +\end{center} +\vfil +\newpage +This document is part of the LibTomCrypt package and is hereby released into the public domain. + +~ + +Open Source. Open Academia. Open Minds. + +~ + +\begin{flushright} +Tom St Denis +~ + +Ottawa, Ontario +~ + +Canada +~ +\vfil +\end{flushright} +\newpage + +\tableofcontents +\listoffigures +\pagestyle{myheadings} +\mainmatter +\chapter{Introduction} +\mysection{What is the LibTomCrypt?} +LibTomCrypt is a portable ISO C cryptographic library meant to be a tool set for cryptographers who are +designing cryptosystems. It supports symmetric ciphers, one-way hashes, pseudo-random number generators, +public key cryptography (via PKCS \#1 RSA, DH or ECCDH), and a plethora of support routines. + +The library was designed such that new ciphers/hashes/PRNGs can be added at run-time and the existing API +(and helper API functions) are able to use the new designs automatically. There exists self-check functions for each +block cipher and hash function to ensure that they compile and execute to the published design specifications. The library +also performs extensive parameter error checking to prevent any number of run-time exploits or errors. + +\subsection{What the library IS for?} + +The library serves as a toolkit for developers who have to solve cryptographic problems. Out of the box LibTomCrypt +does not process SSL or OpenPGP messages, it doesn't read X.509 certificates, or write PEM encoded data. It does, however, +provide all of the tools required to build such functionality. LibTomCrypt was designed to be a flexible library that +was not tied to any particular cryptographic problem. + +\mysection{Why did I write it?} +You may be wondering, \textit{Tom, why did you write a crypto library. I already have one.} Well the reason falls into +two categories: +\begin{enumerate} + \item I am too lazy to figure out someone else's API. I'd rather invent my own simpler API and use that. + \item It was (still is) good coding practice. +\end{enumerate} + +The idea is that I am not striving to replace OpenSSL or Crypto++ or Cryptlib or etc. I'm trying to write my +{\bf own} crypto library and hopefully along the way others will appreciate the work. + +With this library all core functions (ciphers, hashes, prngs, and bignum) have the same prototype definition. They all load +and store data in a format independent of the platform. This means if you encrypt with Blowfish on a PPC it should decrypt +on an x86 with zero problems. The consistent API also means that if you learn how to use Blowfish with the library you +know how to use Safer+, RC6, or Serpent as well. With all of the core functions there are central descriptor tables +that can be used to make a program automatically pick between ciphers, hashes and PRNGs at run-time. That means your +application can support all ciphers/hashes/prngs/bignum without changing the source code. + +Not only did I strive to make a consistent and simple API to work with but I also attempted to make the library +configurable in terms of its build options. Out of the box the library will build with any modern version of GCC +without having to use configure scripts. This means that the library will work with platforms where development +tools may be limited (e.g. no autoconf). + +On top of making the build simple and the API approachable I've also attempted for a reasonably high level of +robustness and efficiency. LibTomCrypt traps and returns a series of errors ranging from invalid +arguments to buffer overflows/overruns. It is mostly thread safe and has been clocked on various platforms +with \textit{cycles per byte} timings that are comparable (and often favourable) to other libraries such as OpenSSL and +Crypto++. + +\subsection{Modular} +The LibTomCrypt package has also been written to be very modular. The block ciphers, one--way hashes, +pseudo--random number generators (PRNG), and bignum math routines are all used within the API through \textit{descriptor} tables which +are essentially structures with pointers to functions. While you can still call particular functions +directly (\textit{e.g. sha256\_process()}) this descriptor interface allows the developer to customize their +usage of the library. + +For example, consider a hardware platform with a specialized RNG device. Obviously one would like to tap +that for the PRNG needs within the library (\textit{e.g. making a RSA key}). All the developer has to do +is write a descriptor and the few support routines required for the device. After that the rest of the +API can make use of it without change. Similarly imagine a few years down the road when AES2 +(\textit{or whatever they call it}) has been invented. It can be added to the library and used within applications +with zero modifications to the end applications provided they are written properly. + +This flexibility within the library means it can be used with any combination of primitive algorithms and +unlike libraries like OpenSSL is not tied to direct routines. For instance, in OpenSSL there are CBC block +mode routines for every single cipher. That means every time you add or remove a cipher from the library +you have to update the associated support code as well. In LibTomCrypt the associated code (\textit{chaining modes in this case}) +are not directly tied to the ciphers. That is a new cipher can be added to the library by simply providing +the key setup, ECB decrypt and encrypt and test vector routines. After that all five chaining mode routines +can make use of the cipher right away. + +\mysection{License} + +The project is hereby released as public domain. + +\mysection{Patent Disclosure} + +The author (Tom St Denis) is not a patent lawyer so this section is not to be treated as legal advice. To the best +of the author's knowledge the only patent related issues within the library are the RC5 and RC6 symmetric block ciphers. +They can be removed from a build by simply commenting out the two appropriate lines in \textit{tomcrypt\_custom.h}. The rest +of the ciphers and hashes are patent free or under patents that have since expired. + +The RC2 and RC4 symmetric ciphers are not under patents but are under trademark regulations. This means you can use +the ciphers you just can't advertise that you are doing so. + +\mysection{Thanks} +I would like to give thanks to the following people (in no particular order) for helping me develop this project from +early on: +\begin{enumerate} + \item Richard van de Laarschot + \item Richard Heathfield + \item Ajay K. Agrawal + \item Brian Gladman + \item Svante Seleborg + \item Clay Culver + \item Jason Klapste + \item Dobes Vandermeer + \item Daniel Richards + \item Wayne Scott + \item Andrew Tyler + \item Sky Schulz + \item Christopher Imes +\end{enumerate} + +There have been quite a few other people as well. Please check the change log to see who else has contributed from +time to time. + +\chapter{The Application Programming Interface (API)} +\mysection{Introduction} +\index{CRYPT\_ERROR} \index{CRYPT\_OK} + +In general the API is very simple to memorize and use. Most of the functions return either {\bf void} or {\bf int}. Functions +that return {\bf int} will return {\bf CRYPT\_OK} if the function was successful, or one of the many error codes +if it failed. Certain functions that return int will return $-1$ to indicate an error. These functions will be explicitly +commented upon. When a function does return a CRYPT error code it can be translated into a string with + +\index{error\_to\_string()} +\begin{verbatim} +const char *error_to_string(int err); +\end{verbatim} + +An example of handling an error is: +\begin{small} +\begin{verbatim} +void somefunc(void) +{ + int err; + + /* call a cryptographic function */ + if ((err = some_crypto_function(...)) != CRYPT_OK) { + printf("A crypto error occurred, %s\n", error_to_string(err)); + /* perform error handling */ + } + /* continue on if no error occurred */ +} +\end{verbatim} +\end{small} + +There is no initialization routine for the library and for the most part the code is thread safe. The only thread +related issue is if you use the same symmetric cipher, hash or public key state data in multiple threads. Normally +that is not an issue. + +To include the prototypes for \textit{LibTomCrypt.a} into your own program simply include \textit{tomcrypt.h} like so: +\begin{small} +\begin{verbatim} +#include +int main(void) { + return 0; +} +\end{verbatim} +\end{small} + +The header file \textit{tomcrypt.h} also includes \textit{stdio.h}, \textit{string.h}, \textit{stdlib.h}, \textit{time.h} and \textit{ctype.h}. + +\mysection{Macros} + +There are a few helper macros to make the coding process a bit easier. The first set are related to loading and storing +32/64-bit words in little/big endian format. The macros are: + +\index{STORE32L} \index{STORE64L} \index{LOAD32L} \index{LOAD64L} \index{STORE32H} \index{STORE64H} \index{LOAD32H} \index{LOAD64H} \index{BSWAP} +\newpage +\begin{figure}[hpbt] +\begin{small} +\begin{center} +\begin{tabular}{|c|c|c|} + \hline STORE32L(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $x \to y[0 \ldots 3]$ \\ + \hline STORE64L(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $x \to y[0 \ldots 7]$ \\ + \hline LOAD32L(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $y[0 \ldots 3] \to x$ \\ + \hline LOAD64L(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $y[0 \ldots 7] \to x$ \\ + \hline STORE32H(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $x \to y[3 \ldots 0]$ \\ + \hline STORE64H(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $x \to y[7 \ldots 0]$ \\ + \hline LOAD32H(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $y[3 \ldots 0] \to x$ \\ + \hline LOAD64H(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $y[7 \ldots 0] \to x$ \\ + \hline BSWAP(x) & {\bf unsigned long} x & Swap bytes \\ + \hline +\end{tabular} +\caption{Load And Store Macros} +\end{center} +\end{small} +\end{figure} + +There are 32 and 64-bit cyclic rotations as well: +\index{ROL} \index{ROR} \index{ROL64} \index{ROR64} \index{ROLc} \index{RORc} \index{ROL64c} \index{ROR64c} +\begin{figure}[hpbt] +\begin{small} +\begin{center} +\begin{tabular}{|c|c|c|} + \hline ROL(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x << y, 0 \le y \le 31$ \\ + \hline ROLc(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x << y, 0 \le y \le 31$ \\ + \hline ROR(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x >> y, 0 \le y \le 31$ \\ + \hline RORc(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x >> y, 0 \le y \le 31$ \\ + \hline && \\ + \hline ROL64(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x << y, 0 \le y \le 63$ \\ + \hline ROL64c(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x << y, 0 \le y \le 63$ \\ + \hline ROR64(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x >> y, 0 \le y \le 63$ \\ + \hline ROR64c(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x >> y, 0 \le y \le 63$ \\ + \hline +\end{tabular} +\caption{Rotate Macros} +\end{center} +\end{small} +\end{figure} + +\mysection{Functions with Variable Length Output} +Certain functions such as (for example) \textit{rsa\_export()} give an output that is variable length. To prevent buffer overflows you +must pass it the length of the buffer where the output will be stored. For example: +\index{rsa\_export()} \index{error\_to\_string()} \index{variable length output} +\begin{small} +\begin{verbatim} +#include +int main(void) { + rsa_key key; + unsigned char buffer[1024]; + unsigned long x; + int err; + + /* ... Make up the RSA key somehow ... */ + + /* lets export the key, set x to the size of the + * output buffer */ + x = sizeof(buffer); + if ((err = rsa_export(buffer, &x, PK_PUBLIC, &key)) != CRYPT_OK) { + printf("Export error: %s\n", error_to_string(err)); + return -1; + } + + /* if rsa_export() was successful then x will have + * the size of the output */ + printf("RSA exported key takes %d bytes\n", x); + + /* ... do something with the buffer */ + + return 0; +} +\end{verbatim} +\end{small} +In the above example if the size of the RSA public key was more than 1024 bytes this function would return an error code +indicating a buffer overflow would have occurred. If the function succeeds, it stores the length of the output back into +\textit{x} so that the calling application will know how many bytes were used. + +As of v1.13, most functions will update your length on failure to indicate the size required by the function. Not all functions +support this so please check the source before you rely on it doing that. + +\mysection{Functions that need a PRNG} +\index{Pseudo Random Number Generator} \index{PRNG} +Certain functions such as \textit{rsa\_make\_key()} require a Pseudo Random Number Generator (PRNG). These functions do not setup +the PRNG themselves so it is the responsibility of the calling function to initialize the PRNG before calling them. + +Certain PRNG algorithms do not require a \textit{prng\_state} argument (sprng for example). The \textit{prng\_state} argument +may be passed as \textbf{NULL} in such situations. + +\index{register\_prng()} \index{rsa\_make\_key()} +\begin{small} +\begin{verbatim} +#include +int main(void) { + rsa_key key; + int err; + + /* register the system RNG */ + register_prng(&sprng_desc) + + /* make a 1024-bit RSA key with the system RNG */ + if ((err = rsa_make_key(NULL, find_prng("sprng"), 1024/8, 65537, &key)) + != CRYPT_OK) { + printf("make_key error: %s\n", error_to_string(err)); + return -1; + } + + /* use the key ... */ + + return 0; +} +\end{verbatim} +\end{small} + +\mysection{Functions that use Arrays of Octets} +Most functions require inputs that are arrays of the data type \textit{unsigned char}. Whether it is a symmetric key, IV +for a chaining mode or public key packet it is assumed that regardless of the actual size of \textit{unsigned char} only the +lower eight bits contain data. For example, if you want to pass a 256 bit key to a symmetric ciphers setup routine, you +must pass in (a pointer to) an array of 32 \textit{unsigned char} variables. Certain routines (such as SAFER+) take +special care to work properly on platforms where an \textit{unsigned char} is not eight bits. + +For the purposes of this library, the term \textit{byte} will refer to an octet or eight bit word. Typically an array of +type \textit{byte} will be synonymous with an array of type \textit{unsigned char.} + +\chapter{Symmetric Block Ciphers} +\mysection{Core Functions} +LibTomCrypt provides several block ciphers with an ECB block mode interface. It is important to first note that you +should never use the ECB modes directly to encrypt data. Instead you should use the ECB functions to make a chaining mode, +or use one of the provided chaining modes. All of the ciphers are written as ECB interfaces since it allows the rest of +the API to grow in a modular fashion. + +\subsection{Key Scheduling} +All ciphers store their scheduled keys in a single data type called \textit{symmetric\_key}. This allows all ciphers to +have the same prototype and store their keys as naturally as possible. This also removes the need for dynamic memory +allocation, and allows you to allocate a fixed sized buffer for storing scheduled keys. All ciphers must provide six visible +functions which are (given that XXX is the name of the cipher) the following: +\index{Cipher Setup} +\begin{verbatim} +int XXX_setup(const unsigned char *key, + int keylen, + int rounds, + symmetric_key *skey); +\end{verbatim} + +The XXX\_setup() routine will setup the cipher to be used with a given number of rounds and a given key length (in bytes). +The number of rounds can be set to zero to use the default, which is generally a good idea. + +If the function returns successfully the variable \textit{skey} will have a scheduled key stored in it. It's important to note +that you should only used this scheduled key with the intended cipher. For example, if you call \textit{blowfish\_setup()} do not +pass the scheduled key onto \textit{rc5\_ecb\_encrypt()}. All built--in setup functions do not allocate memory off the heap so +when you are done with a key you can simply discard it (e.g. they can be on the stack). However, to maintain proper coding +practices you should always call the respective XXX\_done() function. This allows for quicker porting to applications with +externally supplied plugins. + +\subsection{ECB Encryption and Decryption} +To encrypt or decrypt a block in ECB mode there are these two functions per cipher: +\index{Cipher Encrypt} \index{Cipher Decrypt} +\begin{verbatim} +int XXX_ecb_encrypt(const unsigned char *pt, + unsigned char *ct, + symmetric_key *skey); + +int XXX_ecb_decrypt(const unsigned char *ct, + unsigned char *pt, + symmetric_key *skey); +\end{verbatim} +These two functions will encrypt or decrypt (respectively) a single block of text\footnote{The size of which depends on +which cipher you are using.}, storing the result in the \textit{ct} buffer (\textit{pt} resp.). It is possible that the input and output buffer are +the same buffer. For the encrypt function \textit{pt}\footnote{pt stands for plaintext.} is the input and +\textit{ct}\footnote{ct stands for ciphertext.} is the output. For the decryption function it's the opposite. They both +return \textbf{CRYPT\_OK} on success. To test a particular cipher against test vectors\footnote{As published in their design papers.} +call the following self-test function. + +\subsection{Self--Testing} +\index{Cipher Testing} +\begin{verbatim} +int XXX_test(void); +\end{verbatim} +This function will return {\bf CRYPT\_OK} if the cipher matches the test vectors from the design publication it is +based upon. + +\subsection{Key Sizing} +For each cipher there is a function which will help find a desired key size. It is specified as follows: +\index{Key Sizing} +\begin{verbatim} +int XXX_keysize(int *keysize); +\end{verbatim} +Essentially, it will round the input keysize in \textit{keysize} down to the next appropriate key size. This function +will return {\bf CRYPT\_OK} if the key size specified is acceptable. For example: +\begin{small} +\begin{verbatim} +#include +int main(void) +{ + int keysize, err; + + /* now given a 20 byte key what keysize does Twofish want to use? */ + keysize = 20; + if ((err = twofish_keysize(&keysize)) != CRYPT_OK) { + printf("Error getting key size: %s\n", error_to_string(err)); + return -1; + } + printf("Twofish suggested a key size of %d\n", keysize); + return 0; +} +\end{verbatim} +\end{small} +This should indicate a keysize of sixteen bytes is suggested by storing 16 in \textit{keysize.} + +\subsection{Cipher Termination} +When you are finished with a cipher you can de--initialize it with the done function. +\begin{verbatim} +void XXX_done(symmetric_key *skey); +\end{verbatim} +For the software based ciphers within LibTomCrypt, these functions will not do anything. However, user supplied +cipher descriptors may require to be called for resource management purposes. To be compliant, all functions which call a cipher +setup function must also call the respective cipher done function when finished. + +\subsection{Simple Encryption Demonstration} +An example snippet that encodes a block with Blowfish in ECB mode. + +\index{blowfish\_setup()} \index{blowfish\_ecb\_encrypt()} \index{blowfish\_ecb\_decrypt()} \index{blowfish\_done()} +\begin{small} +\begin{verbatim} +#include +int main(void) +{ + unsigned char pt[8], ct[8], key[8]; + symmetric_key skey; + int err; + + /* ... key is loaded appropriately in key ... */ + /* ... load a block of plaintext in pt ... */ + + /* schedule the key */ + if ((err = blowfish_setup(key, /* the key we will use */ + 8, /* key is 8 bytes (64-bits) long */ + 0, /* 0 == use default # of rounds */ + &skey) /* where to put the scheduled key */ + ) != CRYPT_OK) { + printf("Setup error: %s\n", error_to_string(err)); + return -1; + } + + /* encrypt the block */ + blowfish_ecb_encrypt(pt, /* encrypt this 8-byte array */ + ct, /* store encrypted data here */ + &skey); /* our previously scheduled key */ + + /* now ct holds the encrypted version of pt */ + + /* decrypt the block */ + blowfish_ecb_decrypt(ct, /* decrypt this 8-byte array */ + pt, /* store decrypted data here */ + &skey); /* our previously scheduled key */ + + /* now we have decrypted ct to the original plaintext in pt */ + + /* Terminate the cipher context */ + blowfish_done(&skey); + + return 0; +} +\end{verbatim} +\end{small} + +\mysection{Key Sizes and Number of Rounds} +\index{Symmetric Keys} +As a general rule of thumb, do not use symmetric keys under 80 bits if you can help it. Only a few of the ciphers support smaller +keys (mainly for test vectors anyways). Ideally, your application should be making at least 256 bit keys. This is not +because you are to be paranoid. It is because if your PRNG has a bias of any sort the more bits the better. For +example, if you have $\mbox{Pr}\left[X = 1\right] = {1 \over 2} \pm \gamma$ where $\vert \gamma \vert > 0$ then the +total amount of entropy in N bits is $N \cdot -log_2\left ({1 \over 2} + \vert \gamma \vert \right)$. So if $\gamma$ +were $0.25$ (a severe bias) a 256-bit string would have about 106 bits of entropy whereas a 128-bit string would have +only 53 bits of entropy. + +The number of rounds of most ciphers is not an option you can change. Only RC5 allows you to change the number of +rounds. By passing zero as the number of rounds all ciphers will use their default number of rounds. Generally the +ciphers are configured such that the default number of rounds provide adequate security for the given block and key +size. + +\mysection{The Cipher Descriptors} +\index{Cipher Descriptor} +To facilitate automatic routines an array of cipher descriptors is provided in the array \textit{cipher\_descriptor}. An element +of this array has the following (partial) format (See Section \ref{sec:cipherdesc}): + +\begin{small} +\begin{verbatim} +struct _cipher_descriptor { + /** name of cipher */ + char *name; + + /** internal ID */ + unsigned char ID; + + /** min keysize (octets) */ + int min_key_length, + + /** max keysize (octets) */ + max_key_length, + + /** block size (octets) */ + block_length, + + /** default number of rounds */ + default_rounds; +...... +}; +\end{verbatim} +\end{small} + +Where \textit{name} is the lower case ASCII version of the name. The fields \textit{min\_key\_length} and \textit{max\_key\_length} +are the minimum and maximum key sizes in bytes. The \textit{block\_length} member is the block size of the cipher +in bytes. As a good rule of thumb it is assumed that the cipher supports +the min and max key lengths but not always everything in between. The \textit{default\_rounds} field is the default number +of rounds that will be used. + +For a plugin to be compliant it must provide at least each function listed before the accelerators begin. Accelerators are optional, +and if missing will be emulated in software. + +The remaining fields are all pointers to the core functions for each cipher. The end of the cipher\_descriptor array is +marked when \textit{name} equals {\bf NULL}. + +As of this release the current cipher\_descriptors elements are the following: +\vfil +\index{Cipher descriptor table} +\index{blowfish\_desc} \index{xtea\_desc} \index{rc2\_desc} \index{rc5\_desc} \index{rc6\_desc} \index{saferp\_desc} \index{aes\_desc} \index{twofish\_desc} +\index{des\_desc} \index{des3\_desc} \index{noekeon\_desc} \index{skipjack\_desc} \index{anubis\_desc} \index{khazad\_desc} \index{kseed\_desc} \index{kasumi\_desc} +\begin{figure}[hpbt] +\begin{small} +\begin{center} +\begin{tabular}{|c|c|c|c|c|c|} + \hline \textbf{Name} & \textbf{Descriptor Name} & \textbf{Block Size} & \textbf{Key Range} & \textbf{Rounds} \\ + \hline Blowfish & blowfish\_desc & 8 & 8 $\ldots$ 56 & 16 \\ + \hline X-Tea & xtea\_desc & 8 & 16 & 32 \\ + \hline RC2 & rc2\_desc & 8 & 8 $\ldots$ 128 & 16 \\ + \hline RC5-32/12/b & rc5\_desc & 8 & 8 $\ldots$ 128 & 12 $\ldots$ 24 \\ + \hline RC6-32/20/b & rc6\_desc & 16 & 8 $\ldots$ 128 & 20 \\ + \hline SAFER+ & saferp\_desc &16 & 16, 24, 32 & 8, 12, 16 \\ + \hline AES & aes\_desc & 16 & 16, 24, 32 & 10, 12, 14 \\ + & aes\_enc\_desc & 16 & 16, 24, 32 & 10, 12, 14 \\ + \hline Twofish & twofish\_desc & 16 & 16, 24, 32 & 16 \\ + \hline DES & des\_desc & 8 & 8 & 16 \\ + \hline 3DES (EDE mode) & des3\_desc & 8 & 24 & 16 \\ + \hline CAST5 (CAST-128) & cast5\_desc & 8 & 5 $\ldots$ 16 & 12, 16 \\ + \hline Noekeon & noekeon\_desc & 16 & 16 & 16 \\ + \hline Skipjack & skipjack\_desc & 8 & 10 & 32 \\ + \hline Anubis & anubis\_desc & 16 & 16 $\ldots$ 40 & 12 $\ldots$ 18 \\ + \hline Khazad & khazad\_desc & 8 & 16 & 8 \\ + \hline SEED & kseed\_desc & 16 & 16 & 16 \\ + \hline KASUMI & kasumi\_desc & 8 & 16 & 8 \\ + \hline +\end{tabular} +\end{center} +\end{small} +\caption{Built--In Software Ciphers} +\end{figure} + +\subsection{Notes} +\begin{small} +\begin{enumerate} +\item +For AES, (also known as Rijndael) there are four descriptors which complicate issues a little. The descriptors +rijndael\_desc and rijndael\_enc\_desc provide the cipher named \textit{rijndael}. The descriptors aes\_desc and +aes\_enc\_desc provide the cipher name \textit{aes}. Functionally both \textit{rijndael} and \textit{aes} are the same cipher. The +only difference is when you call find\_cipher() you have to pass the correct name. The cipher descriptors with \textit{enc} +in the middle (e.g. rijndael\_enc\_desc) are related to an implementation of Rijndael with only the encryption routine +and tables. The decryption and self--test function pointers of both \textit{encrypt only} descriptors are set to \textbf{NULL} and +should not be called. + +The \textit{encrypt only} descriptors are useful for applications that only use the encryption function of the cipher. Algorithms such +as EAX, PMAC and OMAC only require the encryption function. So far this \textit{encrypt only} functionality has only been implemented for +Rijndael as it makes the most sense for this cipher. + +\item +Note that for \textit{DES} and \textit{3DES} they use 8 and 24 byte keys but only 7 and 21 [respectively] bytes of the keys are in +fact used for the purposes of encryption. My suggestion is just to use random 8/24 byte keys instead of trying to make a 8/24 +byte string from the real 7/21 byte key. + +\item +Note that \textit{Twofish} has additional configuration options (Figure \ref{fig:twofishopts}) that take place at build time. These options are found in +the file \textit{tomcrypt\_cfg.h}. The first option is \textit{TWOFISH\_SMALL} which when defined will force the Twofish code +to not pre-compute the Twofish \textit{$g(X)$} function as a set of four $8 \times 32$ s-boxes. This means that a scheduled +key will require less ram but the resulting cipher will be slower. The second option is \textit{TWOFISH\_TABLES} which when +defined will force the Twofish code to use pre-computed tables for the two s-boxes $q_0, q_1$ as well as the multiplication +by the polynomials 5B and EF used in the MDS multiplication. As a result the code is faster and slightly larger. The +speed increase is useful when \textit{TWOFISH\_SMALL} is defined since the s-boxes and MDS multiply form the heart of the +Twofish round function. + +\begin{figure}[hpbt] +\index{Twofish build options} \index{TWOFISH\_SMALL} \index{TWOFISH\_TABLES} +\begin{small} +\begin{center} +\begin{tabular}{|l|l|l|} +\hline \textbf{TWOFISH\_SMALL} & \textbf{TWOFISH\_TABLES} & \textbf{Speed and Memory (per key)} \\ +\hline undefined & undefined & Very fast, 4.2KB of ram. \\ +\hline undefined & defined & Faster key setup, larger code. \\ +\hline defined & undefined & Very slow, 0.2KB of ram. \\ +\hline defined & defined & Faster, 0.2KB of ram, larger code. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Twofish Build Options} +\label{fig:twofishopts} +\end{figure} +\end{enumerate} +\end{small} + +To work with the cipher\_descriptor array there is a function: +\index{find\_cipher()} +\begin{verbatim} +int find_cipher(char *name) +\end{verbatim} +Which will search for a given name in the array. It returns $-1$ if the cipher is not found, otherwise it returns +the location in the array where the cipher was found. For example, to indirectly setup Blowfish you can also use: +\begin{small} +\index{register\_cipher()} \index{find\_cipher()} \index{error\_to\_string()} +\begin{verbatim} +#include +int main(void) +{ + unsigned char key[8]; + symmetric_key skey; + int err; + + /* you must register a cipher before you use it */ + if (register_cipher(&blowfish_desc)) == -1) { + printf("Unable to register Blowfish cipher."); + return -1; + } + + /* generic call to function (assuming the key + * in key[] was already setup) */ + if ((err = + cipher_descriptor[find_cipher("blowfish")]. + setup(key, 8, 0, &skey)) != CRYPT_OK) { + printf("Error setting up Blowfish: %s\n", error_to_string(err)); + return -1; + } + + /* ... use cipher ... */ +} +\end{verbatim} +\end{small} + +A good safety would be to check the return value of \textit{find\_cipher()} before accessing the desired function. In order +to use a cipher with the descriptor table you must register it first using: +\index{register\_cipher()} +\begin{verbatim} +int register_cipher(const struct _cipher_descriptor *cipher); +\end{verbatim} +Which accepts a pointer to a descriptor and returns the index into the global descriptor table. If an error occurs such +as there is no more room (it can have 32 ciphers at most) it will return {\bf{-1}}. If you try to add the same cipher more +than once it will just return the index of the first copy. To remove a cipher call: +\index{unregister\_cipher()} +\begin{verbatim} +int unregister_cipher(const struct _cipher_descriptor *cipher); +\end{verbatim} +Which returns {\bf CRYPT\_OK} if it removes the cipher, otherwise it returns {\bf CRYPT\_ERROR}. +\begin{small} +\begin{verbatim} +#include +int main(void) +{ + int err; + + /* register the cipher */ + if (register_cipher(&rijndael_desc) == -1) { + printf("Error registering Rijndael\n"); + return -1; + } + + /* use Rijndael */ + + /* remove it */ + if ((err = unregister_cipher(&rijndael_desc)) != CRYPT_OK) { + printf("Error removing Rijndael: %s\n", error_to_string(err)); + return -1; + } + + return 0; +} +\end{verbatim} +\end{small} +This snippet is a small program that registers Rijndael. + +\mysection{Symmetric Modes of Operations} +\subsection{Background} +A typical symmetric block cipher can be used in chaining modes to effectively encrypt messages larger than the block +size of the cipher. Given a key $k$, a plaintext $P$ and a cipher $E$ we shall denote the encryption of the block +$P$ under the key $k$ as $E_k(P)$. In some modes there exists an initial vector denoted as $C_{-1}$. + +\subsubsection{ECB Mode} +\index{ECB mode} +ECB or Electronic Codebook Mode is the simplest method to use. It is given as: +\begin{equation} +C_i = E_k(P_i) +\end{equation} +This mode is very weak since it allows people to swap blocks and perform replay attacks if the same key is used more +than once. + +\subsubsection{CBC Mode} +\index{CBC mode} +CBC or Cipher Block Chaining mode is a simple mode designed to prevent trivial forms of replay and swap attacks on ciphers. +It is given as: +\begin{equation} +C_i = E_k(P_i \oplus C_{i - 1}) +\end{equation} +It is important that the initial vector be unique and preferably random for each message encrypted under the same key. + +\subsubsection{CTR Mode} +\index{CTR mode} +CTR or Counter Mode is a mode which only uses the encryption function of the cipher. Given a initial vector which is +treated as a large binary counter the CTR mode is given as: +\begin{eqnarray} +C_{-1} = C_{-1} + 1\mbox{ }(\mbox{mod }2^W) \nonumber \\ +C_i = P_i \oplus E_k(C_{-1}) +\end{eqnarray} +Where $W$ is the size of a block in bits (e.g. 64 for Blowfish). As long as the initial vector is random for each message +encrypted under the same key replay and swap attacks are infeasible. CTR mode may look simple but it is as secure +as the block cipher is under a chosen plaintext attack (provided the initial vector is unique). + +\subsubsection{CFB Mode} +\index{CFB mode} +CFB or Ciphertext Feedback Mode is a mode akin to CBC. It is given as: +\begin{eqnarray} +C_i = P_i \oplus C_{-1} \nonumber \\ +C_{-1} = E_k(C_i) +\end{eqnarray} +Note that in this library the output feedback width is equal to the size of the block cipher. That is this mode is used +to encrypt whole blocks at a time. However, the library will buffer data allowing the user to encrypt or decrypt partial +blocks without a delay. When this mode is first setup it will initially encrypt the initial vector as required. + +\subsubsection{OFB Mode} +\index{OFB mode} +OFB or Output Feedback Mode is a mode akin to CBC as well. It is given as: +\begin{eqnarray} +C_{-1} = E_k(C_{-1}) \nonumber \\ +C_i = P_i \oplus C_{-1} +\end{eqnarray} +Like the CFB mode the output width in CFB mode is the same as the width of the block cipher. OFB mode will also +buffer the output which will allow you to encrypt or decrypt partial blocks without delay. + +\subsection{Choice of Mode} +My personal preference is for the CTR mode since it has several key benefits: +\begin{enumerate} + \item No short cycles which is possible in the OFB and CFB modes. + \item Provably as secure as the block cipher being used under a chosen plaintext attack. + \item Technically does not require the decryption routine of the cipher. + \item Allows random access to the plaintext. + \item Allows the encryption of block sizes that are not equal to the size of the block cipher. +\end{enumerate} +The CTR, CFB and OFB routines provided allow you to encrypt block sizes that differ from the ciphers block size. They +accomplish this by buffering the data required to complete a block. This allows you to encrypt or decrypt any size +block of memory with either of the three modes. + +The ECB and CBC modes process blocks of the same size as the cipher at a time. Therefore, they are less flexible than the +other modes. + +\subsection{Ciphertext Stealing} +\index{Ciphertext stealing} +Ciphertext stealing is a method of dealing with messages in CBC mode which are not a multiple of the block length. This is accomplished +by encrypting the last ciphertext block in ECB mode, and XOR'ing the output against the last partial block of plaintext. LibTomCrypt does not +support this mode directly but it is fairly easy to emulate with a call to the cipher's ecb\_encrypt() callback function. + +The more sane way to deal with partial blocks is to pad them with zeroes, and then use CBC normally. + +\subsection{Initialization} +\index{CBC Mode} \index{CTR Mode} +\index{OFB Mode} \index{CFB Mode} +The library provides simple support routines for handling CBC, CTR, CFB, OFB and ECB encoded messages. Assuming the mode +you want is XXX there is a structure called \textit{symmetric\_XXX} that will contain the information required to +use that mode. They have identical setup routines (except CTR and ECB mode): +\index{ecb\_start()} \index{cfb\_start()} \index{cbc\_start()} \index{ofb\_start()} \index{ctr\_start()} +\begin{verbatim} +int XXX_start( int cipher, + const unsigned char *IV, + const unsigned char *key, + int keylen, + int num_rounds, + symmetric_XXX *XXX); + +int ctr_start( int cipher, + const unsigned char *IV, + const unsigned char *key, + int keylen, + int num_rounds, + int ctr_mode, + symmetric_CTR *ctr); + +int ecb_start( int cipher, + const unsigned char *key, + int keylen, + int num_rounds, + symmetric_ECB *ecb); +\end{verbatim} + +In each case, \textit{cipher} is the index into the cipher\_descriptor array of the cipher you want to use. The \textit{IV} value is +the initialization vector to be used with the cipher. You must fill the IV yourself and it is assumed they are the same +length as the block size\footnote{In other words the size of a block of plaintext for the cipher, e.g. 8 for DES, 16 for AES, etc.} +of the cipher you choose. It is important that the IV be random for each unique message you want to encrypt. The +parameters \textit{key}, \textit{keylen} and \textit{num\_rounds} are the same as in the XXX\_setup() function call. The final parameter +is a pointer to the structure you want to hold the information for the mode of operation. + +The routines return {\bf CRYPT\_OK} if the cipher initialized correctly, otherwise, they return an error code. + +\subsubsection{CTR Mode} +In the case of CTR mode there is an additional parameter \textit{ctr\_mode} which specifies the mode that the counter is to be used in. +If \textbf{CTR\_COUNTER\_ LITTLE\_ENDIAN} was specified then the counter will be treated as a little endian value. Otherwise, if +\textbf{CTR\_COUNTER\_BIG\_ENDIAN} was specified the counter will be treated as a big endian value. As of v1.15 the RFC 3686 style of +increment then encrypt is also supported. By OR'ing \textbf{LTC\_CTR\_RFC3686} with the CTR \textit{mode} value, ctr\_start() will increment +the counter before encrypting it for the first time. + +As of V1.17, the library supports variable length counters for CTR mode. The (optional) counter length is specified by OR'ing the octet +length of the counter against the \textit{ctr\_mode} parameter. The default, zero, indicates that a full block length counter will be used. This also +ensures backwards compatibility with software that uses older versions of the library. + +\begin{small} +\begin{verbatim} +symmetric_CTR ctr; +int err; +unsigned char IV[16], key[16]; + +/* use a 32-bit little endian counter */ +if ((err = ctr_start(find_cipher("aes"), + IV, key, 16, 0, + CTR_COUNTER_LITTLE_ENDIAN | 4, + &ctr)) != CRYPT_OK) { + handle_error(err); +} +\end{verbatim} +\end{small} + +Changing the counter size has little (really no) effect on the performance of the CTR chaining mode. It is provided for compatibility +with other software (and hardware) which have smaller fixed sized counters. + +\subsection{Encryption and Decryption} +To actually encrypt or decrypt the following routines are provided: +\index{ecb\_encrypt()} \index{ecb\_decrypt()} \index{cfb\_encrypt()} \index{cfb\_decrypt()} +\index{cbc\_encrypt()} \index{cbc\_decrypt()} \index{ofb\_encrypt()} \index{ofb\_decrypt()} \index{ctr\_encrypt()} \index{ctr\_decrypt()} +\begin{verbatim} +int XXX_encrypt(const unsigned char *pt, + unsigned char *ct, + unsigned long len, + symmetric_YYY *YYY); + +int XXX_decrypt(const unsigned char *ct, + unsigned char *pt, + unsigned long len, + symmetric_YYY *YYY); +\end{verbatim} +Where \textit{XXX} is one of $\lbrace ecb, cbc, ctr, cfb, ofb \rbrace$. + +In all cases, \textit{len} is the size of the buffer (as number of octets) to encrypt or decrypt. The CTR, OFB and CFB modes are order sensitive but not +chunk sensitive. That is you can encrypt \textit{ABCDEF} in three calls like \textit{AB}, \textit{CD}, \textit{EF} or two like \textit{ABCDE} and \textit{F} +and end up with the same ciphertext. However, encrypting \textit{ABC} and \textit{DABC} will result in different ciphertexts. All +five of the modes will return {\bf CRYPT\_OK} on success from the encrypt or decrypt functions. + +In the ECB and CBC cases, \textit{len} must be a multiple of the ciphers block size. In the CBC case, you must manually pad the end of your message (either with +zeroes or with whatever your protocol requires). + +To decrypt in either mode, perform the setup like before (recall you have to fetch the IV value you used), and use the decrypt routine on all of the blocks. + +\subsection{IV Manipulation} +To change or read the IV of a previously initialized chaining mode use the following two functions. +\index{cbc\_setiv()} \index{cbc\_getiv()} \index{ofb\_setiv()} \index{ofb\_getiv()} \index{cfb\_setiv()} \index{cfb\_getiv()} +\index{ctr\_setiv()} \index{ctr\_getiv()} +\begin{verbatim} +int XXX_getiv(unsigned char *IV, + unsigned long *len, + symmetric_XXX *XXX); + +int XXX_setiv(const unsigned char *IV, + unsigned long len, + symmetric_XXX *XXX); +\end{verbatim} + +The XXX\_getiv() functions will read the IV out of the chaining mode and store it into \textit{IV} along with the length of the IV +stored in \textit{len}. The XXX\_setiv will initialize the chaining mode state as if the original IV were the new IV specified. The length +of the IV passed in must be the size of the ciphers block size. + +The XXX\_setiv() functions are handy if you wish to change the IV without re--keying the cipher. + +What the \textit{setiv} function will do depends on the mode being changed. In CBC mode, the new IV replaces the existing IV as if it +were the last ciphertext block. In CFB mode, the IV is encrypted as if it were the prior encrypted pad. In CTR mode, the IV is encrypted without +first incrementing it (regardless of the LTC\_RFC\_3686 flag presence). In F8 mode, the IV is encrypted and becomes the new pad. It does not change +the salted IV, and is only meant to allow seeking within a session. In LRW, it changes the tweak, forcing a computation of the tweak pad, allowing for +seeking within the session. In OFB mode, the IV is encrypted and becomes the new pad. + +\subsection{Stream Termination} +To terminate an open stream call the done function. + +\index{ecb\_done()} \index{cbc\_done()}\index{cfb\_done()}\index{ofb\_done()} \index{ctr\_done()} +\begin{verbatim} +int XXX_done(symmetric_XXX *XXX); +\end{verbatim} + +This will terminate the stream (by terminating the cipher) and return \textbf{CRYPT\_OK} if successful. + +\newpage +\subsection{Examples} +\begin{small} +\begin{verbatim} +#include +int main(void) +{ + unsigned char key[16], IV[16], buffer[512]; + symmetric_CTR ctr; + int x, err; + + /* register twofish first */ + if (register_cipher(&twofish_desc) == -1) { + printf("Error registering cipher.\n"); + return -1; + } + + /* somehow fill out key and IV */ + + /* start up CTR mode */ + if ((err = ctr_start( + find_cipher("twofish"), /* index of desired cipher */ + IV, /* the initial vector */ + key, /* the secret key */ + 16, /* length of secret key (16 bytes) */ + 0, /* 0 == default # of rounds */ + CTR_COUNTER_LITTLE_ENDIAN, /* Little endian counter */ + &ctr) /* where to store the CTR state */ + ) != CRYPT_OK) { + printf("ctr_start error: %s\n", error_to_string(err)); + return -1; + } + + /* somehow fill buffer than encrypt it */ + if ((err = ctr_encrypt( buffer, /* plaintext */ + buffer, /* ciphertext */ + sizeof(buffer), /* length of plaintext pt */ + &ctr) /* CTR state */ + ) != CRYPT_OK) { + printf("ctr_encrypt error: %s\n", error_to_string(err)); + return -1; + } + + /* make use of ciphertext... */ + + /* now we want to decrypt so let's use ctr_setiv */ + if ((err = ctr_setiv( IV, /* the initial IV we gave to ctr_start */ + 16, /* the IV is 16 bytes long */ + &ctr) /* the ctr state we wish to modify */ + ) != CRYPT_OK) { + printf("ctr_setiv error: %s\n", error_to_string(err)); + return -1; + } + + if ((err = ctr_decrypt( buffer, /* ciphertext */ + buffer, /* plaintext */ + sizeof(buffer), /* length of plaintext */ + &ctr) /* CTR state */ + ) != CRYPT_OK) { + printf("ctr_decrypt error: %s\n", error_to_string(err)); + return -1; + } + + /* terminate the stream */ + if ((err = ctr_done(&ctr)) != CRYPT_OK) { + printf("ctr_done error: %s\n", error_to_string(err)); + return -1; + } + + /* clear up and return */ + zeromem(key, sizeof(key)); + zeromem(&ctr, sizeof(ctr)); + + return 0; +} +\end{verbatim} +\end{small} + +\subsection{LRW Mode} +LRW mode is a cipher mode which is meant for indexed encryption like used to handle storage media. It is meant to have efficient seeking and overcome the +security problems of ECB mode while not increasing the storage requirements. It is used much like any other chaining mode except with two key differences. + +The key is specified as two strings the first key $K_1$ is the (normally AES) key and can be any length (typically 16, 24 or 32 octets long). The second key +$K_2$ is the \textit{tweak} key and is always 16 octets long. The tweak value is \textbf{NOT} a nonce or IV value it must be random and secret. + +To initialize LRW mode use: + +\index{lrw\_start()} +\begin{verbatim} +int lrw_start( int cipher, + const unsigned char *IV, + const unsigned char *key, + int keylen, + const unsigned char *tweak, + int num_rounds, + symmetric_LRW *lrw); +\end{verbatim} + +This will initialize the LRW context with the given (16 octet) \textit{IV}, cipher $K_1$ \textit{key} of length \textit{keylen} octets and the (16 octet) $K_2$ \textit{tweak}. +While LRW was specified to be used only with AES, LibTomCrypt will allow any 128--bit block cipher to be specified as indexed by \textit{cipher}. The +number of rounds for the block cipher \textit{num\_rounds} can be 0 to use the default number of rounds for the given cipher. + +To process data use the following functions: + +\index{lrw\_encrypt()} \index{lrw\_decrypt()} +\begin{verbatim} +int lrw_encrypt(const unsigned char *pt, + unsigned char *ct, + unsigned long len, + symmetric_LRW *lrw); + +int lrw_decrypt(const unsigned char *ct, + unsigned char *pt, + unsigned long len, + symmetric_LRW *lrw); +\end{verbatim} + +These will encrypt (or decrypt) the plaintext to the ciphertext buffer (or vice versa). The length is specified by \textit{len} in octets but must be a multiple +of 16. The LRW code uses a fast tweak update such that consecutive blocks are encrypted faster than if random seeking where used. + +To manipulate the IV use the following functions: + +\index{lrw\_getiv()} \index{lrw\_setiv()} +\begin{verbatim} +int lrw_getiv(unsigned char *IV, + unsigned long *len, + symmetric_LRW *lrw); + +int lrw_setiv(const unsigned char *IV, + unsigned long len, + symmetric_LRW *lrw); +\end{verbatim} +These will get or set the 16--octet IV. Note that setting the IV is the same as \textit{seeking} and unlike other modes is not a free operation. It requires +updating the entire tweak which is slower than sequential use. Avoid seeking excessively in performance constrained code. + +To terminate the LRW state use the following: + +\index{lrw\_done()} +\begin{verbatim} +int lrw_done(symmetric_LRW *lrw); +\end{verbatim} + +\subsection{XTS Mode} +As of v1.17, LibTomCrypt supports XTS mode with code donated by Elliptic Semiconductor Inc.\footnote{www.ellipticsemi.com}. +XTS is a chaining mode for 128--bit block ciphers, recommended by IEEE (P1619) +for disk encryption. It is meant to be an encryption mode with random access to the message data without compromising privacy. It requires two private keys (of equal +length) to perform the encryption process. Each encryption invocation includes a sector number or unique identifier specified as a 128--bit string. + +To initialize XTS mode use the following function call: + +\index{xts\_start()} +\begin{verbatim} +int xts_start( int cipher, + const unsigned char *key1, + const unsigned char *key2, + unsigned long keylen, + int num_rounds, + symmetric_xts *xts) +\end{verbatim} +This will start the XTS mode with the two keys pointed to by \textit{key1} and \textit{key2} of length \textit{keylen} octets each. + +To encrypt or decrypt a sector use the following calls: + +\index{xts\_encrypt()} \index{xts\_decrypt()} +\begin{verbatim} +int xts_encrypt( + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + const unsigned char *tweak, + symmetric_xts *xts); + +int xts_decrypt( + const unsigned char *ct, unsigned long ptlen, + unsigned char *pt, + const unsigned char *tweak, + symmetric_xts *xts); +\end{verbatim} +The first will encrypt the plaintext pointed to by \textit{pt} of length \textit{ptlen} octets, and store the ciphertext in the array pointed to by +\textit{ct}. It uses the 128--bit tweak pointed to by \textit{tweak} to encrypt the block. The decrypt function performs the opposite operation. Both +functions support ciphertext stealing (blocks that are not multiples of 16 bytes). + +The P1619 specification states the tweak for sector number shall be represented as a 128--bit little endian string. + +To terminate the XTS state call the following function: + +\index{xts\_done()} +\begin{verbatim} +void xts_done(symmetric_xts *xts); +\end{verbatim} + + +\subsection{F8 Mode} +\index{F8 Mode} +The F8 Chaining mode (see RFC 3711 for instance) is yet another chaining mode for block ciphers. It behaves much like CTR mode in that it XORs a keystream +against the plaintext to encrypt. F8 mode comes with the additional twist that the counter value is secret, encrypted by a \textit{salt key}. We +initialize F8 mode with the following function call: + +\index{f8\_start()} +\begin{verbatim} +int f8_start( int cipher, + const unsigned char *IV, + const unsigned char *key, + int keylen, + const unsigned char *salt_key, + int skeylen, + int num_rounds, + symmetric_F8 *f8); +\end{verbatim} +This will start the F8 mode state using \textit{key} as the secret key, \textit{IV} as the counter. It uses the \textit{salt\_key} as IV encryption key +(\textit{m} in the RFC 3711). The salt\_key can be shorter than the secret key but it should not be longer. + +To encrypt or decrypt data we use the following two functions: + +\index{f8\_encrypt()} \index{f8\_decrypt()} +\begin{verbatim} +int f8_encrypt(const unsigned char *pt, + unsigned char *ct, + unsigned long len, + symmetric_F8 *f8); + +int f8_decrypt(const unsigned char *ct, + unsigned char *pt, + unsigned long len, + symmetric_F8 *f8); +\end{verbatim} +These will encrypt or decrypt a variable length array of bytes using the F8 mode state specified. The length is specified in bytes and does not have to be a multiple +of the ciphers block size. + +To change or retrieve the current counter IV value use the following functions: +\index{f8\_getiv()} \index{f8\_setiv()} +\begin{verbatim} +int f8_getiv(unsigned char *IV, + unsigned long *len, + symmetric_F8 *f8); + +int f8_setiv(const unsigned char *IV, + unsigned long len, + symmetric_F8 *f8); +\end{verbatim} +These work with the current IV value only and not the encrypted IV value specified during the call to f8\_start(). The purpose of these two functions is to be +able to seek within a current session only. If you want to change the session IV you will have to call f8\_done() and then start a new state with +f8\_start(). + +To terminate an F8 state call the following function: + +\index{f8\_done()} +\begin{verbatim} +int f8_done(symmetric_F8 *f8); +\end{verbatim} + +\vfil +\mysection{Encrypt and Authenticate Modes} + +\subsection{EAX Mode} +LibTomCrypt provides support for a mode called EAX\footnote{See +M. Bellare, P. Rogaway, D. Wagner, A Conventional Authenticated-Encryption Mode.} in a manner similar to the way it was intended to be used +by the designers. First, a short description of what EAX mode is before we explain how to use it. EAX is a mode that requires a cipher, +CTR and OMAC support and provides encryption and +authentication\footnote{Note that since EAX only requires OMAC and CTR you may use \textit{encrypt only} cipher descriptors with this mode.}. +It is initialized with a random \textit{nonce} that can be shared publicly, a \textit{header} which can be fixed and public, and a random secret symmetric key. + +The \textit{header} data is meant to be meta--data associated with a stream that isn't private (e.g., protocol messages). It can +be added at anytime during an EAX stream, and is part of the authentication tag. That is, changes in the meta-data can be detected by changes in the output tag. + +The mode can then process plaintext producing ciphertext as well as compute a partial checksum. The actual checksum +called a \textit{tag} is only emitted when the message is finished. In the interim, the user can process any arbitrary +sized message block to send to the recipient as ciphertext. This makes the EAX mode especially suited for streaming modes +of operation. + +The mode is initialized with the following function. +\index{eax\_init()} +\begin{verbatim} +int eax_init( eax_state *eax, + int cipher, + const unsigned char *key, + unsigned long keylen, + const unsigned char *nonce, + unsigned long noncelen, + const unsigned char *header, + unsigned long headerlen); +\end{verbatim} + +Where \textit{eax} is the EAX state. The \textit{cipher} parameter is the index of the desired cipher in the descriptor table. +The \textit{key} parameter is the shared secret symmetric key of length \textit{keylen} octets. The \textit{nonce} parameter is the +random public string of length \textit{noncelen} octets. The \textit{header} parameter is the random (or fixed or \textbf{NULL}) header for the +message of length \textit{headerlen} octets. + +When this function completes, the \textit{eax} state will be initialized such that you can now either have data decrypted or +encrypted in EAX mode. Note: if \textit{headerlen} is zero you may pass \textit{header} as \textbf{NULL} to indicate there is no initial header data. + +To encrypt or decrypt data in a streaming mode use the following. +\index{eax\_encrypt()} \index{eax\_decrypt()} +\begin{verbatim} +int eax_encrypt( eax_state *eax, + const unsigned char *pt, + unsigned char *ct, + unsigned long length); + +int eax_decrypt( eax_state *eax, + const unsigned char *ct, + unsigned char *pt, + unsigned long length); +\end{verbatim} +The function \textit{eax\_encrypt} will encrypt the bytes in \textit{pt} of \textit{length} octets, and store the ciphertext in +\textit{ct}. Note: \textit{ct} and \textit{pt} may be the same region in memory. This function will also send the ciphertext +through the OMAC function. The function \textit{eax\_decrypt} decrypts \textit{ct}, and stores it in \textit{pt}. This also allows +\textit{pt} and \textit{ct} to be the same region in memory. + +You cannot both encrypt or decrypt with the same \textit{eax} context. For bi--directional communication you will need to initialize +two EAX contexts (preferably with different headers and nonces). + +Note: both of these functions allow you to send the data in any granularity but the order is important. While +the eax\_init() function allows you to add initial header data to the stream you can also add header data during the +EAX stream with the following. + +\index{eax\_addheader()} +\begin{verbatim} +int eax_addheader( eax_state *eax, + const unsigned char *header, + unsigned long length); +\end{verbatim} +This will add the \textit{length} octet from \textit{header} to the given \textit{eax} header. Once the message is finished, the +\textit{tag} (checksum) may be computed with the following function: + +\index{eax\_done()} +\begin{verbatim} +int eax_done( eax_state *eax, + unsigned char *tag, + unsigned long *taglen); +\end{verbatim} +This will terminate the EAX state \textit{eax}, and store up to \textit{taglen} bytes of the message tag in \textit{tag}. The function +then stores how many bytes of the tag were written out back in to \textit{taglen}. + +The EAX mode code can be tested to ensure it matches the test vectors by calling the following function: +\index{eax\_test()} +\begin{verbatim} +int eax_test(void); +\end{verbatim} +This requires that the AES (or Rijndael) block cipher be registered with the cipher\_descriptor table first. + +\begin{verbatim} +#include +int main(void) +{ + int err; + eax_state eax; + unsigned char pt[64], ct[64], nonce[16], key[16], tag[16]; + unsigned long taglen; + + if (register_cipher(&rijndael_desc) == -1) { + printf("Error registering Rijndael"); + return EXIT_FAILURE; + } + + /* ... make up random nonce and key ... */ + + /* initialize context */ + if ((err = eax_init( &eax, /* context */ + find_cipher("rijndael"), /* cipher id */ + nonce, /* the nonce */ + 16, /* nonce is 16 bytes */ + "TestApp", /* example header */ + 7) /* header length */ + ) != CRYPT_OK) { + printf("Error eax_init: %s", error_to_string(err)); + return EXIT_FAILURE; + } + + /* now encrypt data, say in a loop or whatever */ + if ((err = eax_encrypt( &eax, /* eax context */ + pt, /* plaintext (source) */ + ct, /* ciphertext (destination) */ + sizeof(pt) /* size of plaintext */ + ) != CRYPT_OK) { + printf("Error eax_encrypt: %s", error_to_string(err)); + return EXIT_FAILURE; + } + + /* finish message and get authentication tag */ + taglen = sizeof(tag); + if ((err = eax_done( &eax, /* eax context */ + tag, /* where to put tag */ + &taglen /* length of tag space */ + ) != CRYPT_OK) { + printf("Error eax_done: %s", error_to_string(err)); + return EXIT_FAILURE; + } + + /* now we have the authentication tag in "tag" and + * it's taglen bytes long */ +} +\end{verbatim} + +You can also perform an entire EAX state on a block of memory in a single function call with the +following functions. + + +\index{eax\_encrypt\_authenticate\_memory} \index{eax\_decrypt\_verify\_memory} +\begin{verbatim} +int eax_encrypt_authenticate_memory( + int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen); + +int eax_decrypt_verify_memory( + int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + unsigned char *tag, unsigned long taglen, + int *res); +\end{verbatim} + +Both essentially just call eax\_init() followed by eax\_encrypt() (or eax\_decrypt() respectively) and eax\_done(). The parameters +have the same meaning as with those respective functions. + +The only difference is eax\_decrypt\_verify\_memory() does not emit a tag. Instead you pass it a tag as input and it compares it against +the tag it computed while decrypting the message. If the tags match then it stores a $1$ in \textit{res}, otherwise it stores a $0$. + +\subsection{OCB Mode} +LibTomCrypt provides support for a mode called OCB\footnote{See +P. Rogaway, M. Bellare, J. Black, T. Krovetz, \textit{OCB: A Block Cipher Mode of Operation for Efficient Authenticated Encryption}.} +. OCB is an encryption protocol that simultaneously provides authentication. It is slightly faster to use than EAX mode +but is less flexible. Let's review how to initialize an OCB context. + +\index{ocb\_init()} +\begin{verbatim} +int ocb_init( ocb_state *ocb, + int cipher, + const unsigned char *key, + unsigned long keylen, + const unsigned char *nonce); +\end{verbatim} + +This will initialize the \textit{ocb} context using cipher descriptor \textit{cipher}. It will use a \textit{key} of length \textit{keylen} +and the random \textit{nonce}. Note that \textit{nonce} must be a random (public) string the same length as the block ciphers +block size (e.g. 16 bytes for AES). + +This mode has no \textit{Associated Data} like EAX mode does which means you cannot authenticate metadata along with the stream. +To encrypt or decrypt data use the following. + +\index{ocb\_encrypt()} \index{ocb\_decrypt()} +\begin{verbatim} +int ocb_encrypt( ocb_state *ocb, + const unsigned char *pt, + unsigned char *ct); + +int ocb_decrypt( ocb_state *ocb, + const unsigned char *ct, + unsigned char *pt); +\end{verbatim} + +This will encrypt (or decrypt for the latter) a fixed length of data from \textit{pt} to \textit{ct} (vice versa for the latter). +They assume that \textit{pt} and \textit{ct} are the same size as the block cipher's block size. Note that you cannot call +both functions given a single \textit{ocb} state. For bi-directional communication you will have to initialize two \textit{ocb} +states (with different nonces). Also \textit{pt} and \textit{ct} may point to the same location in memory. + +\subsubsection{State Termination} + +When you are finished encrypting the message you call the following function to compute the tag. + +\index{ocb\_done\_encrypt()} +\begin{verbatim} +int ocb_done_encrypt( ocb_state *ocb, + const unsigned char *pt, + unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, + unsigned long *taglen); +\end{verbatim} + +This will terminate an encrypt stream \textit{ocb}. If you have trailing bytes of plaintext that will not complete a block +you can pass them here. This will also encrypt the \textit{ptlen} bytes in \textit{pt} and store them in \textit{ct}. It will also +store up to \textit{taglen} bytes of the tag into \textit{tag}. + +Note that \textit{ptlen} must be less than or equal to the block size of block cipher chosen. Also note that if you have +an input message equal to the length of the block size then you pass the data here (not to ocb\_encrypt()) only. + +To terminate a decrypt stream and compared the tag you call the following. + +\index{ocb\_done\_decrypt()} +\begin{verbatim} +int ocb_done_decrypt( ocb_state *ocb, + const unsigned char *ct, + unsigned long ctlen, + unsigned char *pt, + const unsigned char *tag, + unsigned long taglen, + int *res); +\end{verbatim} +Similarly to the previous function you can pass trailing message bytes into this function. This will compute the +tag of the message (internally) and then compare it against the \textit{taglen} bytes of \textit{tag} provided. By default +\textit{res} is set to zero. If all \textit{taglen} bytes of \textit{tag} can be verified then \textit{res} is set to one (authenticated +message). + +\subsubsection{Packet Functions} +To make life simpler the following two functions are provided for memory bound OCB. + +%\index{ocb\_encrypt\_authenticate\_memory()} +\begin{verbatim} +int ocb_encrypt_authenticate_memory( + int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen); +\end{verbatim} + +This will OCB encrypt the message \textit{pt} of length \textit{ptlen}, and store the ciphertext in \textit{ct}. The length \textit{ptlen} +can be any arbitrary length. + +\index{ocb\_decrypt\_verify\_memory()} +\begin{verbatim} +int ocb_decrypt_verify_memory( + int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + const unsigned char *tag, unsigned long taglen, + int *res); +\end{verbatim} + +Similarly, this will OCB decrypt, and compare the internally computed tag against the tag provided. \textit{res} is set +appropriately. + +\subsection{CCM Mode} +CCM is a NIST proposal for encrypt + authenticate that is centered around using AES (or any 16--byte cipher) as a primitive. Unlike EAX and OCB mode, +it is only meant for \textit{packet} mode where the length of the input is known in advance. Since it is a packet mode function, CCM only has one +function that performs the protocol. + +\index{ccm\_memory()} +\begin{verbatim} +int ccm_memory( + int cipher, + const unsigned char *key, unsigned long keylen, + symmetric_key *uskey, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); +\end{verbatim} + +This performs the \textit{CCM} operation on the data. The \textit{cipher} variable indicates which cipher in the descriptor table to use. It must have a +16--byte block size for CCM. + +The key can be specified in one of two fashions. First, it can be passed as an array of octets in \textit{key} of length \textit{keylen}. Alternatively, +it can be passed in as a previously scheduled key in \textit{uskey}. The latter fashion saves time when the same key is used for multiple packets. If +\textit{uskey} is not \textbf{NULL}, then \textit{key} may be \textbf{NULL} (and vice-versa). + +The nonce or salt is \textit{nonce} of length \textit{noncelen} octets. The header is meta--data you want to send with the message but not have +encrypted, it is stored in \textit{header} of length \textit{headerlen} octets. The header can be zero octets long (if $headerlen = 0$ then +you can pass \textit{header} as \textbf{NULL}). + +The plaintext is stored in \textit{pt}, and the ciphertext in \textit{ct}. The length of both are expected to be equal and is passed in as \textit{ptlen}. It is +allowable that $pt = ct$. The \textit{direction} variable indicates whether encryption (direction $=$ \textbf{CCM\_ENCRYPT}) or +decryption (direction $=$ \textbf{CCM\_DECRYPT}) is to be performed. + +As implemented, this version of CCM cannot handle header or plaintext data longer than $2^{32} - 1$ octets long. + +You can test the implementation of CCM with the following function. + +\index{ccm\_test()} +\begin{verbatim} +int ccm_test(void); +\end{verbatim} + +This will return \textbf{CRYPT\_OK} if the CCM routine passes known test vectors. It requires AES or Rijndael to be registered previously, otherwise it will +return \textbf{CRYPT\_NOP}. + +\subsubsection{CCM Example} +The following is a sample of how to call CCM. + +\begin{small} +\begin{verbatim} +#include +int main(void) +{ + unsigned char key[16], nonce[12], pt[32], ct[32], + tag[16], tagcp[16]; + unsigned long taglen; + int err; + + /* register cipher */ + register_cipher(&aes_desc); + + /* somehow fill key, nonce, pt */ + + /* encrypt it */ + taglen = sizeof(tag); + if ((err = + ccm_memory(find_cipher("aes"), + key, 16, /* 128-bit key */ + NULL, /* not prescheduled */ + nonce, 12, /* 96-bit nonce */ + NULL, 0, /* no header */ + pt, 32, /* 32-byte plaintext */ + ct, /* ciphertext */ + tag, &taglen, + CCM_ENCRYPT)) != CRYPT_OK) { + printf("ccm_memory error %s\n", error_to_string(err)); + return -1; + } + /* ct[0..31] and tag[0..15] now hold the output */ + + /* decrypt it */ + taglen = sizeof(tagcp); + if ((err = + ccm_memory(find_cipher("aes"), + key, 16, /* 128-bit key */ + NULL, /* not prescheduled */ + nonce, 12, /* 96-bit nonce */ + NULL, 0, /* no header */ + ct, 32, /* 32-byte ciphertext */ + pt, /* plaintext */ + tagcp, &taglen, + CCM_DECRYPT)) != CRYPT_OK) { + printf("ccm_memory error %s\n", error_to_string(err)); + return -1; + } + + /* now pt[0..31] should hold the original plaintext, + tagcp[0..15] and tag[0..15] should have the same contents */ +} +\end{verbatim} +\end{small} + +\subsection{GCM Mode} +Galois counter mode is an IEEE proposal for authenticated encryption (also it is a planned NIST standard). Like EAX and OCB mode, it can be used in a streaming capacity +however, unlike EAX it cannot accept \textit{additional authentication data} (meta--data) after plaintext has been processed. This mode also only works with +block ciphers with a 16--byte block. + +A GCM stream is meant to be processed in three modes, one after another. First, the initial vector (per session) data is processed. This should be +unique to every session. Next, the the optional additional authentication data is processed, and finally the plaintext (or ciphertext depending on the direction). + +\subsubsection{Initialization} +To initialize the GCM context with a secret key call the following function. + +\index{gcm\_init()} +\begin{verbatim} +int gcm_init( gcm_state *gcm, + int cipher, + const unsigned char *key, + int keylen); +\end{verbatim} +This initializes the GCM state \textit{gcm} for the given cipher indexed by \textit{cipher}, with a secret key \textit{key} of length \textit{keylen} octets. The cipher +chosen must have a 16--byte block size (e.g., AES). + +\subsubsection{Initial Vector} +After the state has been initialized (or reset) the next step is to add the session (or packet) initial vector. It should be unique per packet encrypted. + +\index{gcm\_add\_iv()} +\begin{verbatim} +int gcm_add_iv( gcm_state *gcm, + const unsigned char *IV, + unsigned long IVlen); +\end{verbatim} +This adds the initial vector octets from \textit{IV} of length \textit{IVlen} to the GCM state \textit{gcm}. You can call this function as many times as required +to process the entire IV. + +Note: the GCM protocols provides a \textit{shortcut} for 12--byte IVs where no pre-processing is to be done. If you want to minimize per packet latency it is ideal +to only use 12--byte IVs. You can just increment it like a counter for each packet. + +\subsubsection{Additional Authentication Data} +After the entire IV has been processed, the additional authentication data can be processed. Unlike the IV, a packet/session does not require additional +authentication data (AAD) for security. The AAD is meant to be used as side--channel data you want to be authenticated with the packet. Note: once +you begin adding AAD to the GCM state you cannot return to adding IV data until the state has been reset. + +\index{gcm\_add\_aad()} +\begin{verbatim} +int gcm_add_aad( gcm_state *gcm, + const unsigned char *adata, + unsigned long adatalen); +\end{verbatim} +This adds the additional authentication data \textit{adata} of length \textit{adatalen} to the GCM state \textit{gcm}. + +\subsubsection{Plaintext Processing} +After the AAD has been processed, the plaintext (or ciphertext depending on the direction) can be processed. + +\index{gcm\_process()} +\begin{verbatim} +int gcm_process( gcm_state *gcm, + unsigned char *pt, + unsigned long ptlen, + unsigned char *ct, + int direction); +\end{verbatim} +This processes message data where \textit{pt} is the plaintext and \textit{ct} is the ciphertext. The length of both are equal and stored in \textit{ptlen}. Depending on +the mode \textit{pt} is the input and \textit{ct} is the output (or vice versa). When \textit{direction} equals \textbf{GCM\_ENCRYPT} the plaintext is read, +encrypted and stored in the ciphertext buffer. When \textit{direction} equals \textbf{GCM\_DECRYPT} the opposite occurs. + +\subsubsection{State Termination} +To terminate a GCM state and retrieve the message authentication tag call the following function. + +\index{gcm\_done()} +\begin{verbatim} +int gcm_done( gcm_state *gcm, + unsigned char *tag, + unsigned long *taglen); +\end{verbatim} +This terminates the GCM state \textit{gcm} and stores the tag in \textit{tag} of length \textit{taglen} octets. + +\subsubsection{State Reset} +The call to gcm\_init() will perform considerable pre--computation (when \textbf{GCM\_TABLES} is defined) and if you're going to be dealing with a lot of packets +it is very costly to have to call it repeatedly. To aid in this endeavour, the reset function has been provided. + +\index{gcm\_reset()} +\begin{verbatim} +int gcm_reset(gcm_state *gcm); +\end{verbatim} + +This will reset the GCM state \textit{gcm} to the state that gcm\_init() left it. The user would then call gcm\_add\_iv(), gcm\_add\_aad(), etc. + +\subsubsection{One--Shot Packet} +To process a single packet under any given key the following helper function can be used. + +\index{gcm\_memory()} +\begin{verbatim} +int gcm_memory( + int cipher, + const unsigned char *key, + unsigned long keylen, + const unsigned char *IV, unsigned long IVlen, + const unsigned char *adata, unsigned long adatalen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); +\end{verbatim} + +This will initialize the GCM state with the given key, IV and AAD value then proceed to encrypt or decrypt the message text and store the final +message tag. The definition of the variables is the same as it is for all the manual functions. + +If you are processing many packets under the same key you shouldn't use this function as it invokes the pre--computation with each call. + +\subsubsection{Example Usage} +The following is an example usage of how to use GCM over multiple packets with a shared secret key. + +\begin{small} +\begin{verbatim} +#include + +int send_packet(const unsigned char *pt, unsigned long ptlen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *aad, unsigned long aadlen, + gcm_state *gcm) +{ + int err; + unsigned long taglen; + unsigned char tag[16]; + + /* reset the state */ + if ((err = gcm_reset(gcm)) != CRYPT_OK) { + return err; + } + + /* Add the IV */ + if ((err = gcm_add_iv(gcm, iv, ivlen)) != CRYPT_OK) { + return err; + } + + /* Add the AAD (note: aad can be NULL if aadlen == 0) */ + if ((err = gcm_add_aad(gcm, aad, aadlen)) != CRYPT_OK) { + return err; + } + + /* process the plaintext */ + if ((err = + gcm_process(gcm, pt, ptlen, pt, GCM_ENCRYPT)) != CRYPT_OK) { + return err; + } + + /* Finish up and get the MAC tag */ + taglen = sizeof(tag); + if ((err = gcm_done(gcm, tag, &taglen)) != CRYPT_OK) { + return err; + } + + /* ... send a header describing the lengths ... */ + + /* depending on the protocol and how IV is + * generated you may have to send it too... */ + send(socket, iv, ivlen, 0); + + /* send the aad */ + send(socket, aad, aadlen, 0); + + /* send the ciphertext */ + send(socket, pt, ptlen, 0); + + /* send the tag */ + send(socket, tag, taglen, 0); + + return CRYPT_OK; +} + +int main(void) +{ + gcm_state gcm; + unsigned char key[16], IV[12], pt[PACKET_SIZE]; + int err, x; + unsigned long ptlen; + + /* somehow fill key/IV with random values */ + + /* register AES */ + register_cipher(&aes_desc); + + /* init the GCM state */ + if ((err = + gcm_init(&gcm, find_cipher("aes"), key, 16)) != CRYPT_OK) { + whine_and_pout(err); + } + + /* handle us some packets */ + for (;;) { + ptlen = make_packet_we_want_to_send(pt); + + /* use IV as counter (12 byte counter) */ + for (x = 11; x >= 0; x--) { + if (++IV[x]) { + break; + } + } + + if ((err = send_packet(pt, ptlen, iv, 12, NULL, 0, &gcm)) + != CRYPT_OK) { + whine_and_pout(err); + } + } + return EXIT_SUCCESS; +} +\end{verbatim} +\end{small} + +\chapter{One-Way Cryptographic Hash Functions} +\mysection{Core Functions} +Like the ciphers, there are hash core functions and a universal data type to hold the hash state called \textit{hash\_state}. To initialize hash +XXX (where XXX is the name) call: +\index{Hash Functions} +\begin{verbatim} +void XXX_init(hash_state *md); +\end{verbatim} + +This simply sets up the hash to the default state governed by the specifications of the hash. To add data to the message being hashed call: +\begin{verbatim} +int XXX_process( hash_state *md, + const unsigned char *in, + unsigned long inlen); +\end{verbatim} +Essentially all hash messages are virtually infinitely\footnote{Most hashes are limited to $2^{64}$ bits or 2,305,843,009,213,693,952 bytes.} long message which +are buffered. The data can be passed in any sized chunks as long as the order of the bytes are the same the message digest (hash output) will be the same. For example, +this means that: +\begin{verbatim} +md5_process(&md, "hello ", 6); +md5_process(&md, "world", 5); +\end{verbatim} +Will produce the same message digest as the single call: +\index{Message Digest} +\begin{verbatim} +md5_process(&md, "hello world", 11); +\end{verbatim} + +To finally get the message digest (the hash) call: +\begin{verbatim} +int XXX_done( hash_state *md, + unsigned char *out); +\end{verbatim} + +This function will finish up the hash and store the result in the \textit{out} array. You must ensure that \textit{out} is long +enough for the hash in question. Often hashes are used to get keys for symmetric ciphers so the \textit{XXX\_done()} functions +will wipe the \textit{md} variable before returning automatically. + +To test a hash function call: +\begin{verbatim} +int XXX_test(void); +\end{verbatim} + +This will return {\bf CRYPT\_OK} if the hash matches the test vectors, otherwise it returns an error code. An +example snippet that hashes a message with md5 is given below. +\begin{small} +\begin{verbatim} +#include +int main(void) +{ + hash_state md; + unsigned char *in = "hello world", out[16]; + + /* setup the hash */ + md5_init(&md); + + /* add the message */ + md5_process(&md, in, strlen(in)); + + /* get the hash in out[0..15] */ + md5_done(&md, out); + + return 0; +} +\end{verbatim} +\end{small} + +\mysection{Hash Descriptors} +Like the set of ciphers, the set of hashes have descriptors as well. They are stored in an array called \textit{hash\_descriptor} and +are defined by: +\begin{verbatim} +struct _hash_descriptor { + char *name; + + unsigned long hashsize; /* digest output size in bytes */ + unsigned long blocksize; /* the block size the hash uses */ + + void (*init) (hash_state *hash); + + int (*process)( hash_state *hash, + const unsigned char *in, + unsigned long inlen); + + int (*done) (hash_state *hash, unsigned char *out); + + int (*test) (void); +}; +\end{verbatim} + +\index{find\_hash()} +The \textit{name} member is the name of the hash function (all lowercase). The \textit{hashsize} member is the size of the digest output +in bytes, while \textit{blocksize} is the size of blocks the hash expects to the compression function. Technically, this detail is not important +for high level developers but is useful to know for performance reasons. + +The \textit{init} member initializes the hash, \textit{process} passes data through the hash, \textit{done} terminates the hash and retrieves the +digest. The \textit{test} member tests the hash against the specified test vectors. + +There is a function to search the array as well called \textit{int find\_hash(char *name)}. It returns -1 if the hash is not found, otherwise, the +position in the descriptor table of the hash. + +In addition, there is also find\_hash\_oid() which finds a hash by the ASN.1 OBJECT IDENTIFIER string. +\index{find\_hash\_oid()} +\begin{verbatim} +int find_hash_oid(const unsigned long *ID, unsigned long IDlen); +\end{verbatim} + +You can use the table to indirectly call a hash function that is chosen at run-time. For example: +\begin{small} +\begin{verbatim} +#include +int main(void) +{ + unsigned char buffer[100], hash[MAXBLOCKSIZE]; + int idx, x; + hash_state md; + + /* register hashes .... */ + if (register_hash(&md5_desc) == -1) { + printf("Error registering MD5.\n"); + return -1; + } + + /* register other hashes ... */ + + /* prompt for name and strip newline */ + printf("Enter hash name: \n"); + fgets(buffer, sizeof(buffer), stdin); + buffer[strlen(buffer) - 1] = 0; + + /* get hash index */ + idx = find_hash(buffer); + if (idx == -1) { + printf("Invalid hash name!\n"); + return -1; + } + + /* hash input until blank line */ + hash_descriptor[idx].init(&md); + while (fgets(buffer, sizeof(buffer), stdin) != NULL) + hash_descriptor[idx].process(&md, buffer, strlen(buffer)); + hash_descriptor[idx].done(&md, hash); + + /* dump to screen */ + for (x = 0; x < hash_descriptor[idx].hashsize; x++) + printf("%02x ", hash[x]); + printf("\n"); + return 0; +} +\end{verbatim} +\end{small} + +Note the usage of \textbf{MAXBLOCKSIZE}. In LibTomCrypt, no symmetric block, key or hash digest is larger than \textbf{MAXBLOCKSIZE} in +length. This provides a simple size you can set your automatic arrays to that will not get overrun. + +There are three helper functions to make working with hashes easier. The first is a function to hash a buffer, and produce the digest in a single +function call. + +\index{hash\_memory()} +\begin{verbatim} +int hash_memory( int hash, + const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen); +\end{verbatim} + +This will hash the data pointed to by \textit{in} of length \textit{inlen}. The hash used is indexed by the \textit{hash} parameter. The message +digest is stored in \textit{out}, and the \textit{outlen} parameter is updated to hold the message digest size. + +The next helper function allows for the hashing of a file based on a file name. +\index{hash\_file()} +\begin{verbatim} +int hash_file( int hash, + const char *fname, + unsigned char *out, + unsigned long *outlen); +\end{verbatim} + +This will hash the file named by \textit{fname} using the hash indexed by \textit{hash}. The file named in this function call must be readable by the +user owning the process performing the request. This function can be omitted by the \textbf{LTC\_NO\_FILE} define, which forces it to return \textbf{CRYPT\_NOP} +when it is called. The message digest is stored in \textit{out}, and the \textit{outlen} parameter is updated to hold the message digest size. + +\index{hash\_filehandle()} +\begin{verbatim} +int hash_filehandle( int hash, + FILE *in, + unsigned char *out, + unsigned long *outlen); +\end{verbatim} + +This will hash the file identified by the handle \textit{in} using the hash indexed by \textit{hash}. This will begin hashing from the current file pointer position, and +will not rewind the file pointer when finished. This function can be omitted by the \textbf{LTC\_NO\_FILE} define, which forces it to return \textbf{CRYPT\_NOP} +when it is called. The message digest is stored in \textit{out}, and the \textit{outlen} parameter is updated to hold the message digest size. + +To perform the above hash with md5 the following code could be used: +\begin{small} +\begin{verbatim} +#include +int main(void) +{ + int idx, err; + unsigned long len; + unsigned char out[MAXBLOCKSIZE]; + + /* register the hash */ + if (register_hash(&md5_desc) == -1) { + printf("Error registering MD5.\n"); + return -1; + } + + /* get the index of the hash */ + idx = find_hash("md5"); + + /* call the hash */ + len = sizeof(out); + if ((err = + hash_memory(idx, "hello world", 11, out, &len)) != CRYPT_OK) { + printf("Error hashing data: %s\n", error_to_string(err)); + return -1; + } + return 0; +} +\end{verbatim} +\end{small} + +\subsection{Hash Registration} +Similar to the cipher descriptor table you must register your hash algorithms before you can use them. These functions +work exactly like those of the cipher registration code. The functions are: +\index{register\_hash()} \index{unregister\_hash()} +\begin{verbatim} +int register_hash(const struct _hash_descriptor *hash); + +int unregister_hash(const struct _hash_descriptor *hash); +\end{verbatim} + +The following hashes are provided as of this release within the LibTomCrypt library: +\index{Hash descriptor table} + +\begin{figure}[here] +\begin{center} +\begin{tabular}{|c|c|c|} + \hline \textbf{Name} & \textbf{Descriptor Name} & \textbf{Size of Message Digest (bytes)} \\ + \hline WHIRLPOOL & whirlpool\_desc & 64 \\ + \hline SHA-512 & sha512\_desc & 64 \\ + \hline SHA-384 & sha384\_desc & 48 \\ + \hline RIPEMD-320 & rmd160\_desc & 40 \\ + \hline SHA-256 & sha256\_desc & 32 \\ + \hline RIPEMD-256 & rmd160\_desc & 32 \\ + \hline SHA-224 & sha224\_desc & 28 \\ + \hline TIGER-192 & tiger\_desc & 24 \\ + \hline SHA-1 & sha1\_desc & 20 \\ + \hline RIPEMD-160 & rmd160\_desc & 20 \\ + \hline RIPEMD-128 & rmd128\_desc & 16 \\ + \hline MD5 & md5\_desc & 16 \\ + \hline MD4 & md4\_desc & 16 \\ + \hline MD2 & md2\_desc & 16 \\ + \hline +\end{tabular} +\end{center} +\caption{Built--In Software Hashes} +\end{figure} +\vfil + +\mysection{Cipher Hash Construction} +\index{Cipher Hash Construction} +An addition to the suite of hash functions is the \textit{Cipher Hash Construction} or \textit{CHC} mode. In this mode +applicable block ciphers (such as AES) can be turned into hash functions that other LTC functions can use. In +particular this allows a cryptosystem to be designed using very few moving parts. + +In order to use the CHC system the developer will have to take a few extra steps. First the \textit{chc\_desc} hash +descriptor must be registered with register\_hash(). At this point the CHC hash cannot be used to hash +data. While it is in the hash system you still have to tell the CHC code which cipher to use. This is accomplished +via the chc\_register() function. + +\index{chc\_register()} +\begin{verbatim} +int chc_register(int cipher); +\end{verbatim} + +A cipher has to be registered with CHC (and also in the cipher descriptor tables with +register\_cipher()). The chc\_register() function will bind a cipher to the CHC system. Only one cipher can +be bound to the CHC hash at a time. There are additional requirements for the system to work. + +\begin{enumerate} + \item The cipher must have a block size greater than 64--bits. + \item The cipher must allow an input key the size of the block size. +\end{enumerate} + +Example of using CHC with the AES block cipher. + +\begin{verbatim} +#include +int main(void) +{ + int err; + + /* register cipher and hash */ + if (register_cipher(&aes_enc_desc) == -1) { + printf("Could not register cipher\n"); + return EXIT_FAILURE; + } + if (register_hash(&chc_desc) == -1) { + printf("Could not register hash\n"); + return EXIT_FAILURE; + } + + /* start chc with AES */ + if ((err = chc_register(find_cipher("aes"))) != CRYPT_OK) { + printf("Error binding AES to CHC: %s\n", + error_to_string(err)); + } + + /* now you can use chc_hash in any LTC function + * [aside from pkcs...] */ +} +\end{verbatim} + + +\mysection{Notice} +It is highly recommended that you \textbf{not} use the MD4 or MD5 hashes for the purposes of digital signatures or authentication codes. +These hashes are provided for completeness and they still can be used for the purposes of password hashing or one-way accumulators +(e.g. Yarrow). + +The other hashes such as the SHA-1, SHA-2 (that includes SHA-512, SHA-384 and SHA-256) and TIGER-192 are still considered secure +for all purposes you would normally use a hash for. + +\chapter{Message Authentication Codes} +\mysection{HMAC Protocol} +Thanks to Dobes Vandermeer, the library now includes support for hash based message authentication codes, or HMAC for short. An HMAC +of a message is a keyed authentication code that only the owner of a private symmetric key will be able to verify. The purpose is +to allow an owner of a private symmetric key to produce an HMAC on a message then later verify if it is correct. Any impostor or +eavesdropper will not be able to verify the authenticity of a message. + +The HMAC support works much like the normal hash functions except that the initialization routine requires you to pass a key +and its length. The key is much like a key you would pass to a cipher. That is, it is simply an array of octets stored in +unsigned characters. The initialization routine is: +\index{hmac\_init()} +\begin{verbatim} +int hmac_init( hmac_state *hmac, + int hash, + const unsigned char *key, + unsigned long keylen); +\end{verbatim} +The \textit{hmac} parameter is the state for the HMAC code. The \textit{hash} parameter is the index into the descriptor table of the hash you want +to use to authenticate the message. The \textit{key} parameter is the pointer to the array of chars that make up the key. The \textit{keylen} parameter is the +length (in octets) of the key you want to use to authenticate the message. To send octets of a message through the HMAC system you must use the following function: +\index{hmac\_process()} +\begin{verbatim} +int hmac_process( hmac_state *hmac, + const unsigned char *in, + unsigned long inlen); +\end{verbatim} +\textit{hmac} is the HMAC state you are working with. \textit{in} is the array of octets to send into the HMAC process. \textit{inlen} is the +number of octets to process. Like the hash process routines, you can send the data in arbitrarily sized chunks. When you +are finished with the HMAC process you must call the following function to get the HMAC code: +\index{hmac\_done()} +\begin{verbatim} +int hmac_done( hmac_state *hmac, + unsigned char *out, + unsigned long *outlen); +\end{verbatim} +The \textit{hmac} parameter is the HMAC state you are working with. The \textit{out} parameter is the array of octets where the HMAC code should be stored. +You must set \textit{outlen} to the size of the destination buffer before calling this function. It is updated with the length of the HMAC code +produced (depending on which hash was picked). If \textit{outlen} is less than the size of the message digest (and ultimately +the HMAC code) then the HMAC code is truncated as per FIPS-198 specifications (e.g. take the first \textit{outlen} bytes). + +There are two utility functions provided to make using HMACs easier to do. They accept the key and information about the +message (file pointer, address in memory), and produce the HMAC result in one shot. These are useful if you want to avoid +calling the three step process yourself. + +\index{hmac\_memory()} +\begin{verbatim} +int hmac_memory( + int hash, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +\end{verbatim} +This will produce an HMAC code for the array of octets in \textit{in} of length \textit{inlen}. The index into the hash descriptor +table must be provided in \textit{hash}. It uses the key from \textit{key} with a key length of \textit{keylen}. +The result is stored in the array of octets \textit{out} and the length in \textit{outlen}. The value of \textit{outlen} must be set +to the size of the destination buffer before calling this function. Similarly for files there is the following function: +\index{hmac\_file()} +\begin{verbatim} +int hmac_file( + int hash, + const char *fname, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen); +\end{verbatim} +\textit{hash} is the index into the hash descriptor table of the hash you want to use. \textit{fname} is the filename to process. +\textit{key} is the array of octets to use as the key of length \textit{keylen}. \textit{out} is the array of octets where the +result should be stored. + +To test if the HMAC code is working there is the following function: +\index{hmac\_test()} +\begin{verbatim} +int hmac_test(void); +\end{verbatim} +Which returns {\bf CRYPT\_OK} if the code passes otherwise it returns an error code. Some example code for using the +HMAC system is given below. + +\begin{small} +\begin{verbatim} +#include +int main(void) +{ + int idx, err; + hmac_state hmac; + unsigned char key[16], dst[MAXBLOCKSIZE]; + unsigned long dstlen; + + /* register SHA-1 */ + if (register_hash(&sha1_desc) == -1) { + printf("Error registering SHA1\n"); + return -1; + } + + /* get index of SHA1 in hash descriptor table */ + idx = find_hash("sha1"); + + /* we would make up our symmetric key in "key[]" here */ + + /* start the HMAC */ + if ((err = hmac_init(&hmac, idx, key, 16)) != CRYPT_OK) { + printf("Error setting up hmac: %s\n", error_to_string(err)); + return -1; + } + + /* process a few octets */ + if((err = hmac_process(&hmac, "hello", 5) != CRYPT_OK) { + printf("Error processing hmac: %s\n", error_to_string(err)); + return -1; + } + + /* get result (presumably to use it somehow...) */ + dstlen = sizeof(dst); + if ((err = hmac_done(&hmac, dst, &dstlen)) != CRYPT_OK) { + printf("Error finishing hmac: %s\n", error_to_string(err)); + return -1; + } + printf("The hmac is %lu bytes long\n", dstlen); + + /* return */ + return 0; +} +\end{verbatim} +\end{small} + +\mysection{OMAC Support} +\index{OMAC} \index{CMAC} +OMAC\footnote{\url{http://crypt.cis.ibaraki.ac.jp/omac/omac.html}}, which stands for \textit{One-Key CBC MAC} is an +algorithm which produces a Message Authentication Code (MAC) using only a block cipher such as AES. Note: OMAC has been standardized as +CMAC within NIST, for the purposes of this library OMAC and CMAC are synonymous. From an API standpoint, the OMAC routines work much like the +HMAC routines. Instead, in this case a cipher is used instead of a hash. + +To start an OMAC state you call +\index{omac\_init()} +\begin{verbatim} +int omac_init( omac_state *omac, + int cipher, + const unsigned char *key, + unsigned long keylen); +\end{verbatim} +The \textit{omac} parameter is the state for the OMAC algorithm. The \textit{cipher} parameter is the index into the cipher\_descriptor table +of the cipher\footnote{The cipher must have a 64 or 128 bit block size. Such as CAST5, Blowfish, DES, AES, Twofish, etc.} you +wish to use. The \textit{key} and \textit{keylen} parameters are the keys used to authenticate the data. + +To send data through the algorithm call +\index{omac\_process()} +\begin{verbatim} +int omac_process( omac_state *state, + const unsigned char *in, + unsigned long inlen); +\end{verbatim} +This will send \textit{inlen} bytes from \textit{in} through the active OMAC state \textit{state}. Returns \textbf{CRYPT\_OK} if the +function succeeds. The function is not sensitive to the granularity of the data. For example, + +\begin{verbatim} +omac_process(&mystate, "hello", 5); +omac_process(&mystate, " world", 6); +\end{verbatim} + +Would produce the same result as, + +\begin{verbatim} +omac_process(&mystate, "hello world", 11); +\end{verbatim} + +When you are done processing the message you can call the following to compute the message tag. + +\index{omac\_done()} +\begin{verbatim} +int omac_done( omac_state *state, + unsigned char *out, + unsigned long *outlen); +\end{verbatim} +Which will terminate the OMAC and output the \textit{tag} (MAC) to \textit{out}. Note that unlike the HMAC and other code +\textit{outlen} can be smaller than the default MAC size (for instance AES would make a 16-byte tag). Part of the OMAC +specification states that the output may be truncated. So if you pass in $outlen = 5$ and use AES as your cipher than +the output MAC code will only be five bytes long. If \textit{outlen} is larger than the default size it is set to the default +size to show how many bytes were actually used. + +Similar to the HMAC code the file and memory functions are also provided. To OMAC a buffer of memory in one shot use the +following function. + +\index{omac\_memory()} +\begin{verbatim} +int omac_memory( + int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +\end{verbatim} +This will compute the OMAC of \textit{inlen} bytes of \textit{in} using the key \textit{key} of length \textit{keylen} bytes and the cipher +specified by the \textit{cipher}'th entry in the cipher\_descriptor table. It will store the MAC in \textit{out} with the same +rules as omac\_done. + +To OMAC a file use +\index{omac\_file()} +\begin{verbatim} +int omac_file( + int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen); +\end{verbatim} + +Which will OMAC the entire contents of the file specified by \textit{filename} using the key \textit{key} of length \textit{keylen} bytes +and the cipher specified by the \textit{cipher}'th entry in the cipher\_descriptor table. It will store the MAC in \textit{out} with +the same rules as omac\_done. + +To test if the OMAC code is working there is the following function: +\index{omac\_test()} +\begin{verbatim} +int omac_test(void); +\end{verbatim} +Which returns {\bf CRYPT\_OK} if the code passes otherwise it returns an error code. Some example code for using the +OMAC system is given below. + +\begin{small} +\begin{verbatim} +#include +int main(void) +{ + int idx, err; + omac_state omac; + unsigned char key[16], dst[MAXBLOCKSIZE]; + unsigned long dstlen; + + /* register Rijndael */ + if (register_cipher(&rijndael_desc) == -1) { + printf("Error registering Rijndael\n"); + return -1; + } + + /* get index of Rijndael in cipher descriptor table */ + idx = find_cipher("rijndael"); + + /* we would make up our symmetric key in "key[]" here */ + + /* start the OMAC */ + if ((err = omac_init(&omac, idx, key, 16)) != CRYPT_OK) { + printf("Error setting up omac: %s\n", error_to_string(err)); + return -1; + } + + /* process a few octets */ + if((err = omac_process(&omac, "hello", 5) != CRYPT_OK) { + printf("Error processing omac: %s\n", error_to_string(err)); + return -1; + } + + /* get result (presumably to use it somehow...) */ + dstlen = sizeof(dst); + if ((err = omac_done(&omac, dst, &dstlen)) != CRYPT_OK) { + printf("Error finishing omac: %s\n", error_to_string(err)); + return -1; + } + printf("The omac is %lu bytes long\n", dstlen); + + /* return */ + return 0; +} +\end{verbatim} +\end{small} + +\mysection{PMAC Support} +The PMAC\footnote{J.Black, P.Rogaway, \textit{A Block--Cipher Mode of Operation for Parallelizable Message Authentication}} +protocol is another MAC algorithm that relies solely on a symmetric-key block cipher. It uses essentially the same +API as the provided OMAC code. + +A PMAC state is initialized with the following. + +\index{pmac\_init()} +\begin{verbatim} +int pmac_init( pmac_state *pmac, + int cipher, + const unsigned char *key, + unsigned long keylen); +\end{verbatim} +Which initializes the \textit{pmac} state with the given \textit{cipher} and \textit{key} of length \textit{keylen} bytes. The chosen cipher +must have a 64 or 128 bit block size (e.x. AES). + +To MAC data simply send it through the process function. + +\index{pmac\_process()} +\begin{verbatim} +int pmac_process( pmac_state *state, + const unsigned char *in, + unsigned long inlen); +\end{verbatim} +This will process \textit{inlen} bytes of \textit{in} in the given \textit{state}. The function is not sensitive to the granularity of the +data. For example, + +\begin{verbatim} +pmac_process(&mystate, "hello", 5); +pmac_process(&mystate, " world", 6); +\end{verbatim} + +Would produce the same result as, + +\begin{verbatim} +pmac_process(&mystate, "hello world", 11); +\end{verbatim} + +When a complete message has been processed the following function can be called to compute the message tag. + +\index{pmac\_done()} +\begin{verbatim} +int pmac_done( pmac_state *state, + unsigned char *out, + unsigned long *outlen); +\end{verbatim} +This will store up to \textit{outlen} bytes of the tag for the given \textit{state} into \textit{out}. Note that if \textit{outlen} is larger +than the size of the tag it is set to the amount of bytes stored in \textit{out}. + +Similar to the OMAC code the file and memory functions are also provided. To PMAC a buffer of memory in one shot use the +following function. + +\index{pmac\_memory()} +\begin{verbatim} +int pmac_memory( + int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +\end{verbatim} +This will compute the PMAC of \textit{msglen} bytes of \textit{msg} using the key \textit{key} of length \textit{keylen} bytes, and the cipher +specified by the \textit{cipher}'th entry in the cipher\_descriptor table. It will store the MAC in \textit{out} with the same +rules as pmac\_done(). + +To PMAC a file use +\index{pmac\_file()} +\begin{verbatim} +int pmac_file( + int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen); +\end{verbatim} + +Which will PMAC the entire contents of the file specified by \textit{filename} using the key \textit{key} of length \textit{keylen} bytes, +and the cipher specified by the \textit{cipher}'th entry in the cipher\_descriptor table. It will store the MAC in \textit{out} with +the same rules as pmac\_done(). + +To test if the PMAC code is working there is the following function: +\index{pmac\_test()} +\begin{verbatim} +int pmac_test(void); +\end{verbatim} +Which returns {\bf CRYPT\_OK} if the code passes otherwise it returns an error code. + +\mysection{Pelican MAC} +Pelican MAC is a new (experimental) MAC by the AES team that uses four rounds of AES as a \textit{mixing function}. It achieves a very high +rate of processing and is potentially very secure. It requires AES to be enabled to function. You do not have to register\_cipher() AES first though +as it calls AES directly. + +\index{pelican\_init()} +\begin{verbatim} +int pelican_init( pelican_state *pelmac, + const unsigned char *key, + unsigned long keylen); +\end{verbatim} +This will initialize the Pelican state with the given AES key. Once this has been done you can begin processing data. + +\index{pelican\_process()} +\begin{verbatim} +int pelican_process( pelican_state *pelmac, + const unsigned char *in, + unsigned long inlen); +\end{verbatim} +This will process \textit{inlen} bytes of \textit{in} through the Pelican MAC. It's best that you pass in multiples of 16 bytes as it makes the +routine more efficient but you may pass in any length of text. You can call this function as many times as required to process +an entire message. + +\index{pelican\_done()} +\begin{verbatim} +int pelican_done(pelican_state *pelmac, unsigned char *out); +\end{verbatim} +This terminates a Pelican MAC and writes the 16--octet tag to \textit{out}. + +\subsection{Example} + +\begin{verbatim} +#include +int main(void) +{ + pelican_state pelstate; + unsigned char key[32], tag[16]; + int err; + + /* somehow initialize a key */ + + /* initialize pelican mac */ + if ((err = pelican_init(&pelstate, /* the state */ + key, /* user key */ + 32 /* key length in octets */ + )) != CRYPT_OK) { + printf("Error initializing Pelican: %s", + error_to_string(err)); + return EXIT_FAILURE; + } + + /* MAC some data */ + if ((err = pelican_process(&pelstate, /* the state */ + "hello world", /* data to mac */ + 11 /* length of data */ + )) != CRYPT_OK) { + printf("Error processing Pelican: %s", + error_to_string(err)); + return EXIT_FAILURE; + } + + /* Terminate the MAC */ + if ((err = pelican_done(&pelstate,/* the state */ + tag /* where to store the tag */ + )) != CRYPT_OK) { + printf("Error terminating Pelican: %s", + error_to_string(err)); + return EXIT_FAILURE; + } + + /* tag[0..15] has the MAC output now */ + + return EXIT_SUCCESS; +} +\end{verbatim} + +\mysection{XCBC-MAC} +As of LibTomCrypt v1.15, XCBC-MAC (RFC 3566) has been provided to support TLS encryption suites. Like OMAC, it computes a message authentication code +by using a cipher in CBC mode. It also uses a single key which it expands into the requisite three keys for the MAC function. A XCBC--MAC state is +initialized with the following function: + +\index{xcbc\_init()} +\begin{verbatim} +int xcbc_init( xcbc_state *xcbc, + int cipher, + const unsigned char *key, + unsigned long keylen); +\end{verbatim} + +This will initialize the XCBC--MAC state \textit{xcbc}, with the key specified in \textit{key} of length \textit{keylen} octets. The cipher indicated +by the \textit{cipher} index can be either a 64 or 128--bit block cipher. This will return \textbf{CRYPT\_OK} on success. + +\index{LTC\_XCBC\_PURE} +It is possible to use XCBC in a three key mode by OR'ing the value \textbf{LTC\_XCBC\_PURE} against the \textit{keylen} parameter. In this mode, the key is +interpretted as three keys. If the cipher has a block size of $n$ octets, the first key is then $keylen - 2n$ octets and is the encryption key. The next +$2n$ octets are the $K_1$ and $K_2$ padding keys (used on the last block). For example, to use AES--192 \textit{keylen} should be $24 + 2 \cdot 16 = 56$ octets. +The three keys are interpretted as if they were concatenated in the \textit{key} buffer. + + +To process data through XCBC--MAC use the following function: + +\index{xcbc\_process()} +\begin{verbatim} +int xcbc_process( xcbc_state *state, + const unsigned char *in, + unsigned long inlen); +\end{verbatim} + +This will add the message octets pointed to by \textit{in} of length \textit{inlen} to the XCBC--MAC state pointed to by \textit{state}. Like the other MAC functions, +the granularity of the input is not important but the order is. This will return \textbf{CRYPT\_OK} on success. + +To compute the MAC tag value use the following function: + +\index{xcbc\_done()} +\begin{verbatim} +int xcbc_done( xcbc_state *state, + unsigned char *out, + unsigned long *outlen); +\end{verbatim} + +This will retrieve the XCBC--MAC tag from the state pointed to by \textit{state}, and store it in the array pointed to by \textit{out}. The \textit{outlen} parameter +specifies the maximum size of the destination buffer, and is updated to hold the final size of the tag when the function returns. This will return \textbf{CRYPT\_OK} on success. + +Helper functions are provided to make parsing memory buffers and files easier. The following functions are provided: + +\index{xcbc\_memory()} +\begin{verbatim} +int xcbc_memory( + int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +\end{verbatim} +This will compute the XCBC--MAC of \textit{msglen} bytes of \textit{msg}, using the key \textit{key} of length \textit{keylen} bytes, and the cipher +specified by the \textit{cipher}'th entry in the cipher\_descriptor table. It will store the MAC in \textit{out} with the same rules as xcbc\_done(). + +To xcbc a file use +\index{xcbc\_file()} +\begin{verbatim} +int xcbc_file( + int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen); +\end{verbatim} + +Which will XCBC--MAC the entire contents of the file specified by \textit{filename} using the key \textit{key} of length \textit{keylen} bytes, and the cipher +specified by the \textit{cipher}'th entry in the cipher\_descriptor table. It will store the MAC in \textit{out} with the same rules as xcbc\_done(). + + +To test XCBC--MAC for RFC 3566 compliance use the following function: + +\index{xcbc\_test()} +\begin{verbatim} +int xcbc_test(void); +\end{verbatim} + +This will return \textbf{CRYPT\_OK} on success. This requires the AES or Rijndael descriptor be previously registered, otherwise, it will return +\textbf{CRYPT\_NOP}. + +\mysection{F9--MAC} +The F9--MAC is yet another CBC--MAC variant proposed for the 3GPP standard. Originally specified to be used with the KASUMI block cipher, it can also be used +with other ciphers. For LibTomCrypt, the F9--MAC code can use any cipher. + +\subsection{Usage Notice} +F9--MAC differs slightly from the other MAC functions in that it requires the caller to perform the final message padding. The padding quite simply is a direction +bit followed by a 1 bit and enough zeros to make the message a multiple of the cipher block size. If the message is byte aligned, the padding takes on the form of +a single 0x40 or 0xC0 byte followed by enough 0x00 bytes to make the message proper multiple. + +If the user simply wants a MAC function (hint: use OMAC) padding with a single 0x40 byte should be sufficient for security purposes and still be reasonably compatible +with F9--MAC. + +\subsection{F9--MAC Functions} +A F9--MAC state is initialized with the following function: +\index{f9\_init()} +\begin{verbatim} +int f9_init( f9_state *f9, + int cipher, + const unsigned char *key, + unsigned long keylen); +\end{verbatim} + +This will initialize the F9--MAC state \textit{f9}, with the key specified in \textit{key} of length \textit{keylen} octets. The cipher indicated +by the \textit{cipher} index can be either a 64 or 128--bit block cipher. This will return \textbf{CRYPT\_OK} on success. + +To process data through F9--MAC use the following function: +\index{f9\_process()} +\begin{verbatim} +int f9_process( f9_state *state, + const unsigned char *in, + unsigned long inlen); +\end{verbatim} + +This will add the message octets pointed to by \textit{in} of length \textit{inlen} to the F9--MAC state pointed to by \textit{state}. Like the other MAC functions, +the granularity of the input is not important but the order is. This will return \textbf{CRYPT\_OK} on success. + +To compute the MAC tag value use the following function: + +\index{f9\_done()} +\begin{verbatim} +int f9_done( f9_state *state, + unsigned char *out, + unsigned long *outlen); +\end{verbatim} + +This will retrieve the F9--MAC tag from the state pointed to by \textit{state}, and store it in the array pointed to by \textit{out}. The \textit{outlen} parameter +specifies the maximum size of the destination buffer, and is updated to hold the final size of the tag when the function returns. This will return +\textbf{CRYPT\_OK} on success. + +Helper functions are provided to make parsing memory buffers and files easier. The following functions are provided: + +\index{f9\_memory()} +\begin{verbatim} +int f9_memory( + int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +\end{verbatim} +This will compute the F9--MAC of \textit{msglen} bytes of \textit{msg}, using the key \textit{key} of length \textit{keylen} bytes, and the cipher +specified by the \textit{cipher}'th entry in the cipher\_descriptor table. It will store the MAC in \textit{out} with the same rules as f9\_done(). + +To F9--MAC a file use +\index{f9\_file()} +\begin{verbatim} +int f9_file( + int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen); +\end{verbatim} + +Which will F9--MAC the entire contents of the file specified by \textit{filename} using the key \textit{key} of length \textit{keylen} bytes, and the cipher +specified by the \textit{cipher}'th entry in the cipher\_descriptor table. It will store the MAC in \textit{out} with the same rules as f9\_done(). + + +To test f9--MAC for RFC 3566 compliance use the following function: + +\index{f9\_test()} +\begin{verbatim} +int f9_test(void); +\end{verbatim} + +This will return \textbf{CRYPT\_OK} on success. This requires the AES or Rijndael descriptor be previously registered, otherwise, it will return +\textbf{CRYPT\_NOP}. + +\chapter{Pseudo-Random Number Generators} +\mysection{Core Functions} +The library provides an array of core functions for Pseudo-Random Number Generators (PRNGs) as well. A cryptographic PRNG is +used to expand a shorter bit string into a longer bit string. PRNGs are used wherever random data is required such as Public Key (PK) +key generation. There is a universal structure called \textit{prng\_state}. To initialize a PRNG call: +\index{PRNG start} +\begin{verbatim} +int XXX_start(prng_state *prng); +\end{verbatim} + +This will setup the PRNG for future use and not seed it. In order for the PRNG to be cryptographically useful you must give it +entropy. Ideally you'd have some OS level source to tap like in UNIX. To add entropy to the PRNG call: +\index{PRNG add\_entropy} +\begin{verbatim} +int XXX_add_entropy(const unsigned char *in, + unsigned long inlen, + prng_state *prng); +\end{verbatim} +Which returns {\bf CRYPT\_OK} if the entropy was accepted. Once you think you have enough entropy you call another +function to put the entropy into action. +\index{PRNG ready} +\begin{verbatim} +int XXX_ready(prng_state *prng); +\end{verbatim} + +Which returns {\bf CRYPT\_OK} if it is ready. Finally to actually read bytes call: +\index{PRNG read} +\begin{verbatim} +unsigned long XXX_read(unsigned char *out, + unsigned long outlen, + prng_state *prng); +\end{verbatim} + +Which returns the number of bytes read from the PRNG. When you are finished with a PRNG state you call +the following. + +\index{PRNG done} +\begin{verbatim} +void XXX_done(prng_state *prng); +\end{verbatim} + +This will terminate a PRNG state and free any memory (if any) allocated. To export a PRNG state +so that you can later resume the PRNG call the following. + +\index{PRNG export} +\begin{verbatim} +int XXX_export(unsigned char *out, + unsigned long *outlen, + prng_state *prng); +\end{verbatim} + +This will write a \textit{PRNG state} to the buffer \textit{out} of length \textit{outlen} bytes. The idea of +the export is meant to be used as a \textit{seed file}. That is, when the program starts up there will not likely +be that much entropy available. To import a state to seed a PRNG call the following function. + +\index{PRNG import} +\begin{verbatim} +int XXX_import(const unsigned char *in, + unsigned long inlen, + prng_state *prng); +\end{verbatim} + +This will call the start and add\_entropy functions of the given PRNG. It will use the state in +\textit{in} of length \textit{inlen} as the initial seed. You must pass the same seed length as was exported +by the corresponding export function. + +Note that importing a state will not \textit{resume} the PRNG from where it left off. That is, if you export +a state, emit (say) 8 bytes and then import the previously exported state the next 8 bytes will not +specifically equal the 8 bytes you generated previously. + +When a program is first executed the normal course of operation is: + +\begin{enumerate} + \item Gather entropy from your sources for a given period of time or number of events. + \item Start, use your entropy via add\_entropy and ready the PRNG yourself. +\end{enumerate} + +When your program is finished you simply call the export function and save the state to a medium (disk, +flash memory, etc). The next time your application starts up you can detect the state, feed it to the +import function and go on your way. It is ideal that (as soon as possible) after start up you export a +fresh state. This helps in the case that the program aborts or the machine is powered down without +being given a chance to exit properly. + +Note that even if you have a state to import it is important to add new entropy to the state. However, +there is less pressure to do so. + +To test a PRNG for operational conformity call the following functions. + +\index{PRNG test} +\begin{verbatim} +int XXX_test(void); +\end{verbatim} + +This will return \textbf{CRYPT\_OK} if PRNG is operating properly. + +\subsection{Remarks} + +It is possible to be adding entropy and reading from a PRNG at the same time. For example, if you first seed the PRNG +and call ready() you can now read from it. You can also keep adding new entropy to it. The new entropy will not be used +in the PRNG until ready() is called again. This allows the PRNG to be used and re-seeded at the same time. No real error +checking is guaranteed to see if the entropy is sufficient, or if the PRNG is even in a ready state before reading. + +\subsection{Example} +Below is a simple snippet to read 10 bytes from Yarrow. It is important to note that this snippet is {\bf NOT} secure since +the entropy added is not random. + +\begin{verbatim} +#include +int main(void) +{ + prng_state prng; + unsigned char buf[10]; + int err; + + /* start it */ + if ((err = yarrow_start(&prng)) != CRYPT_OK) { + printf("Start error: %s\n", error_to_string(err)); + } + /* add entropy */ + if ((err = yarrow_add_entropy("hello world", 11, &prng)) + != CRYPT_OK) { + printf("Add_entropy error: %s\n", error_to_string(err)); + } + /* ready and read */ + if ((err = yarrow_ready(&prng)) != CRYPT_OK) { + printf("Ready error: %s\n", error_to_string(err)); + } + printf("Read %lu bytes from yarrow\n", + yarrow_read(buf, sizeof(buf), &prng)); + return 0; +} +\end{verbatim} + +\mysection{PRNG Descriptors} +\index{PRNG Descriptor} +PRNGs have descriptors that allow plugin driven functions to be created using PRNGs. The plugin descriptors are stored in the structure \textit{prng\_descriptor}. The +format of an element is: +\begin{verbatim} +struct _prng_descriptor { + char *name; + int export_size; /* size in bytes of exported state */ + + int (*start) (prng_state *); + + int (*add_entropy)(const unsigned char *, unsigned long, + prng_state *); + + int (*ready) (prng_state *); + + unsigned long (*read)(unsigned char *, unsigned long len, + prng_state *); + + void (*done)(prng_state *); + + int (*export)(unsigned char *, unsigned long *, prng_state *); + + int (*import)(const unsigned char *, unsigned long, prng_state *); + + int (*test)(void); +}; +\end{verbatim} + +To find a PRNG in the descriptor table the following function can be used: +\index{find\_prng()} +\begin{verbatim} +int find_prng(const char *name); +\end{verbatim} +This will search the PRNG descriptor table for the PRNG named \textit{name}. It will return -1 if the PRNG is not found, otherwise, it returns +the index into the descriptor table. + +Just like the ciphers and hashes, you must register your prng before you can use it. The two functions provided work exactly as those for the cipher registry functions. +They are the following: +\index{register\_prng()} \index{unregister\_prng()} +\begin{verbatim} +int register_prng(const struct _prng_descriptor *prng); +int unregister_prng(const struct _prng_descriptor *prng); +\end{verbatim} + +The register function will register the PRNG, and return the index into the table where it was placed (or -1 for error). It will avoid registering the same +descriptor twice, and will return the index of the current placement in the table if the caller attempts to register it more than once. The unregister function +will return \textbf{CRYPT\_OK} if the PRNG was found and removed. Otherwise, it returns \textbf{CRYPT\_ERROR}. + +\subsection{PRNGs Provided} +\begin{figure}[here] +\begin{center} +\begin{small} +\begin{tabular}{|c|c|l|} +\hline \textbf{Name} & \textbf{Descriptor} & \textbf{Usage} \\ +\hline Yarrow & yarrow\_desc & Fast short-term PRNG \\ +\hline Fortuna & fortuna\_desc & Fast long-term PRNG (recommended) \\ +\hline RC4 & rc4\_desc & Stream Cipher \\ +\hline SOBER-128 & sober128\_desc & Stream Cipher (also very fast PRNG) \\ +\hline +\end{tabular} +\end{small} +\end{center} +\caption{List of Provided PRNGs} +\end{figure} + +\subsubsection{Yarrow} +Yarrow is fast PRNG meant to collect an unspecified amount of entropy from sources +(keyboard, mouse, interrupts, etc), and produce an unbounded string of random bytes. + +\textit{Note:} This PRNG is still secure for most tasks but is no longer recommended. Users +should use Fortuna instead. + +\subsubsection{Fortuna} + +Fortuna is a fast attack tolerant and more thoroughly designed PRNG suitable for long term +usage. It is faster than the default implementation of Yarrow\footnote{Yarrow has been implemented +to work with most cipher and hash combos based on which you have chosen to build into the library.} while +providing more security. + +Fortuna is slightly less flexible than Yarrow in the sense that it only works with the AES block cipher +and SHA--256 hash function. Technically, Fortuna will work with any block cipher that accepts a 256--bit +key, and any hash that produces at least a 256--bit output. However, to make the implementation simpler +it has been fixed to those choices. + +Fortuna is more secure than Yarrow in the sense that attackers who learn parts of the entropy being +added to the PRNG learn far less about the state than that of Yarrow. Without getting into to many +details Fortuna has the ability to recover from state determination attacks where the attacker starts +to learn information from the PRNGs output about the internal state. Yarrow on the other hand, cannot +recover from that problem until new entropy is added to the pool and put to use through the ready() function. + +\subsubsection{RC4} + +RC4 is an old stream cipher that can also double duty as a PRNG in a pinch. You key RC4 by +calling add\_entropy(), and setup the key by calling ready(). You can only add up to 256 bytes via +add\_entropy(). + +When you read from RC4, the output is XOR'ed against your buffer you provide. In this manner, you can use rc4\_read() +as an encrypt (and decrypt) function. + +You really should not use RC4. This is not because RC4 is weak, (though biases are known to exist) but simply due to +the fact that faster alternatives exist. + +\subsubsection{SOBER-128} + +SOBER--128 is a stream cipher designed by the QUALCOMM Australia team. Like RC4, you key it by +calling add\_entropy(). There is no need to call ready() for this PRNG as it does not do anything. + +Note: this cipher has several oddities about how it operates. The first call to add\_entropy() sets the cipher's key. +Every other time call to the add\_entropy() function sets the cipher's IV variable. The IV mechanism allows you to +encrypt several messages with the same key, and not re--use the same key material. + +Unlike Yarrow and Fortuna, all of the entropy (and hence security) of this algorithm rests in the data +you pass it on the \textbf{first} call to add\_entropy(). All buffers sent to add\_entropy() must have a length +that is a multiple of four bytes. + +Like RC4, the output of SOBER--128 is XOR'ed against the buffer you provide it. In this manner, you can use +sober128\_read() as an encrypt (and decrypt) function. + +Since SOBER-128 has a fixed keying scheme, and is very fast (faster than RC4) the ideal usage of SOBER-128 is to +key it from the output of Fortuna (or Yarrow), and use it to encrypt messages. It is also ideal for +simulations which need a high quality (and fast) stream of bytes. + +\subsubsection{Example Usage} +\begin{small} +\begin{verbatim} +#include +int main(void) +{ + prng_state prng; + unsigned char buf[32]; + int err; + + if ((err = rc4_start(&prng)) != CRYPT_OK) { + printf("RC4 init error: %s\n", error_to_string(err)); + exit(-1); + } + + /* use "key" as the key */ + if ((err = rc4_add_entropy("key", 3, &prng)) != CRYPT_OK) { + printf("RC4 add entropy error: %s\n", error_to_string(err)); + exit(-1); + } + + /* setup RC4 for use */ + if ((err = rc4_ready(&prng)) != CRYPT_OK) { + printf("RC4 ready error: %s\n", error_to_string(err)); + exit(-1); + } + + /* encrypt buffer */ + strcpy(buf,"hello world"); + if (rc4_read(buf, 11, &prng) != 11) { + printf("RC4 read error\n"); + exit(-1); + } + return 0; +} +\end{verbatim} +\end{small} +To decrypt you have to do the exact same steps. + +\mysection{The Secure RNG} +\index{Secure RNG} +An RNG is related to a PRNG in many ways, except that it does not expand a smaller seed to get the data. They generate their random bits +by performing some computation on fresh input bits. Possibly the hardest thing to get correctly in a cryptosystem is the +PRNG. Computers are deterministic that try hard not to stray from pre--determined paths. This makes gathering entropy needed to seed a PRNG +a hard task. + +There is one small function that may help on certain platforms: +\index{rng\_get\_bytes()} +\begin{verbatim} +unsigned long rng_get_bytes( + unsigned char *buf, + unsigned long len, + void (*callback)(void)); +\end{verbatim} + +Which will try one of three methods of getting random data. The first is to open the popular \textit{/dev/random} device which +on most *NIX platforms provides cryptographic random bits\footnote{This device is available in Windows through the Cygwin compiler suite. It emulates \textit{/dev/random} via the Microsoft CSP.}. +The second method is to try the Microsoft Cryptographic Service Provider, and read the RNG. The third method is an ANSI C +clock drift method that is also somewhat popular but gives bits of lower entropy. The \textit{callback} parameter is a pointer to a function that returns void. It is +used when the slower ANSI C RNG must be used so the calling application can still work. This is useful since the ANSI C RNG has a throughput of roughly three +bytes a second. The callback pointer may be set to {\bf NULL} to avoid using it if you do not want to. The function returns the number of bytes actually read from +any RNG source. There is a function to help setup a PRNG as well: +\index{rng\_make\_prng()} +\begin{verbatim} +int rng_make_prng( int bits, + int wprng, + prng_state *prng, + void (*callback)(void)); +\end{verbatim} +This will try to initialize the prng with a state of at least \textit{bits} of entropy. The \textit{callback} parameter works much like +the callback in \textit{rng\_get\_bytes()}. It is highly recommended that you use this function to setup your PRNGs unless you have a +platform where the RNG does not work well. Example usage of this function is given below: + +\begin{small} +\begin{verbatim} +#include +int main(void) +{ + ecc_key mykey; + prng_state prng; + int err; + + /* register yarrow */ + if (register_prng(&yarrow_desc) == -1) { + printf("Error registering Yarrow\n"); + return -1; + } + + /* setup the PRNG */ + if ((err = rng_make_prng(128, find_prng("yarrow"), &prng, NULL)) + != CRYPT_OK) { + printf("Error setting up PRNG, %s\n", error_to_string(err)); + return -1; + } + + /* make a 192-bit ECC key */ + if ((err = ecc_make_key(&prng, find_prng("yarrow"), 24, &mykey)) + != CRYPT_OK) { + printf("Error making key: %s\n", error_to_string(err)); + return -1; + } + return 0; +} +\end{verbatim} +\end{small} + +\subsection{The Secure PRNG Interface} +It is possible to access the secure RNG through the PRNG interface, and in turn use it within dependent functions such +as the PK API. This simplifies the cryptosystem on platforms where the secure RNG is fast. The secure PRNG never +requires to be started, that is you need not call the start, add\_entropy, or ready functions. For example, consider +the previous example using this PRNG. + +\begin{small} +\begin{verbatim} +#include +int main(void) +{ + ecc_key mykey; + int err; + + /* register SPRNG */ + if (register_prng(&sprng_desc) == -1) { + printf("Error registering SPRNG\n"); + return -1; + } + + /* make a 192-bit ECC key */ + if ((err = ecc_make_key(NULL, find_prng("sprng"), 24, &mykey)) + != CRYPT_OK) { + printf("Error making key: %s\n", error_to_string(err)); + return -1; + } + return 0; +} +\end{verbatim} +\end{small} + +\chapter{RSA Public Key Cryptography} + +\mysection{Introduction} +RSA wrote the PKCS \#1 specifications which detail RSA Public Key Cryptography. In the specifications are +padding algorithms for encryption and signatures. The standard includes the \textit{v1.5} and \textit{v2.1} algorithms. +To simplify matters a little the v2.1 encryption and signature padding algorithms are called OAEP and PSS respectively. + +\mysection{PKCS \#1 Padding} +PKCS \#1 v1.5 padding is so simple that both signature and encryption padding are performed by the same function. Note: the +signature padding does \textbf{not} include the ASN.1 padding required. That is performed by the rsa\_sign\_hash\_ex() function +documented later on in this chapter. + +\subsection{PKCS \#1 v1.5 Encoding} +The following function performs PKCS \#1 v1.5 padding: +\index{pkcs\_1\_v1\_5\_encode()} +\begin{verbatim} +int pkcs_1_v1_5_encode( + const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + prng_state *prng, + int prng_idx, + unsigned char *out, + unsigned long *outlen); +\end{verbatim} + +This will encode the message pointed to by \textit{msg} of length \textit{msglen} octets. The \textit{block\_type} parameter must be set to +\textbf{LTC\_PKCS\_1\_EME} to perform encryption padding. It must be set to \textbf{LTC\_PKCS\_1\_EMSA} to perform signature padding. The \textit{modulus\_bitlen} +parameter indicates the length of the modulus in bits. The padded data is stored in \textit{out} with a length of \textit{outlen} octets. The output will not be +longer than the modulus which helps allocate the correct output buffer size. + +Only encryption padding requires a PRNG. When performing signature padding the \textit{prng\_idx} parameter may be left to zero as it is not checked for validity. + +\subsection{PKCS \#1 v1.5 Decoding} +The following function performs PKCS \#1 v1.5 de--padding: +\index{pkcs\_1\_v1\_5\_decode()} +\begin{verbatim} +int pkcs_1_v1_5_decode( + const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + unsigned char *out, + unsigned long *outlen, + int *is_valid); +\end{verbatim} +\index{LTC\_PKCS\_1\_EME} \index{LTC\_PKCS\_1\_EMSA} +This will remove the PKCS padding data pointed to by \textit{msg} of length \textit{msglen}. The decoded data is stored in \textit{out} of length +\textit{outlen}. If the padding is valid, a 1 is stored in \textit{is\_valid}, otherwise, a 0 is stored. The \textit{block\_type} parameter must be set to either +\textbf{LTC\_PKCS\_1\_EME} or \textbf{LTC\_PKCS\_1\_EMSA} depending on whether encryption or signature padding is being removed. + +\mysection{PKCS \#1 v2.1 Encryption} +PKCS \#1 RSA Encryption amounts to OAEP padding of the input message followed by the modular exponentiation. As far as this portion of +the library is concerned we are only dealing with th OAEP padding of the message. + +\subsection{OAEP Encoding} + +The following function performs PKCS \#1 v2.1 encryption padding: + +\index{pkcs\_1\_oaep\_encode()} +\begin{alltt} +int pkcs_1_oaep_encode( + const unsigned char *msg, + unsigned long msglen, + const unsigned char *lparam, + unsigned long lparamlen, + unsigned long modulus_bitlen, + prng_state *prng, + int prng_idx, + int hash_idx, + unsigned char *out, + unsigned long *outlen); +\end{alltt} + +This accepts \textit{msg} as input of length \textit{msglen} which will be OAEP padded. The \textit{lparam} variable is an additional system specific +tag that can be applied to the encoding. This is useful to identify which system encoded the message. If no variance is desired then +\textit{lparam} can be set to \textbf{NULL}. + +OAEP encoding requires the length of the modulus in bits in order to calculate the size of the output. This is passed as the parameter +\textit{modulus\_bitlen}. \textit{hash\_idx} is the index into the hash descriptor table of the hash desired. PKCS \#1 allows any hash to be +used but both the encoder and decoder must use the same hash in order for this to succeed. The size of hash output affects the maximum + sized input message. \textit{prng\_idx} and \textit{prng} are the random number generator arguments required to randomize the padding process. +The padded message is stored in \textit{out} along with the length in \textit{outlen}. + +If $h$ is the length of the hash and $m$ the length of the modulus (both in octets) then the maximum payload for \textit{msg} is +$m - 2h - 2$. For example, with a $1024$--bit RSA key and SHA--1 as the hash the maximum payload is $86$ bytes. + +Note that when the message is padded it still has not been RSA encrypted. You must pass the output of this function to +rsa\_exptmod() to encrypt it. + +\subsection{OAEP Decoding} + +\index{pkcs\_1\_oaep\_decode()} +\begin{alltt} +int pkcs_1_oaep_decode( + const unsigned char *msg, + unsigned long msglen, + const unsigned char *lparam, + unsigned long lparamlen, + unsigned long modulus_bitlen, + int hash_idx, + unsigned char *out, + unsigned long *outlen, + int *res); +\end{alltt} + +This function decodes an OAEP encoded message and outputs the original message that was passed to the OAEP encoder. \textit{msg} is the +output of pkcs\_1\_oaep\_encode() of length \textit{msglen}. \textit{lparam} is the same system variable passed to the OAEP encoder. If it does not +match what was used during encoding this function will not decode the packet. \textit{modulus\_bitlen} is the size of the RSA modulus in bits +and must match what was used during encoding. Similarly the \textit{hash\_idx} index into the hash descriptor table must match what was used +during encoding. + +If the function succeeds it decodes the OAEP encoded message into \textit{out} of length \textit{outlen} and stores a +$1$ in \textit{res}. If the packet is invalid it stores $0$ in \textit{res} and if the function fails for another reason +it returns an error code. + +\mysection{PKCS \#1 Digital Signatures} + +\subsection{PSS Encoding} +PSS encoding is the second half of the PKCS \#1 standard which is padding to be applied to messages that are signed. + +\index{pkcs\_1\_pss\_encode()} +\begin{alltt} +int pkcs_1_pss_encode( + const unsigned char *msghash, + unsigned long msghashlen, + unsigned long saltlen, + prng_state *prng, + int prng_idx, + int hash_idx, + unsigned long modulus_bitlen, + unsigned char *out, + unsigned long *outlen); +\end{alltt} + +This function assumes the message to be PSS encoded has previously been hashed. The input hash \textit{msghash} is of length +\textit{msghashlen}. PSS allows a variable length random salt (it can be zero length) to be introduced in the signature process. +\textit{hash\_idx} is the index into the hash descriptor table of the hash to use. \textit{prng\_idx} and \textit{prng} are the random +number generator information required for the salt. + +Similar to OAEP encoding \textit{modulus\_bitlen} is the size of the RSA modulus (in bits). It limits the size of the salt. If $m$ is the length +of the modulus $h$ the length of the hash output (in octets) then there can be $m - h - 2$ bytes of salt. + +This function does not actually sign the data it merely pads the hash of a message so that it can be processed by rsa\_exptmod(). + +\subsection{PSS Decoding} + +To decode a PSS encoded signature block you have to use the following. + +\index{pkcs\_1\_pss\_decode()} +\begin{alltt} +int pkcs_1_pss_decode( + const unsigned char *msghash, + unsigned long msghashlen, + const unsigned char *sig, + unsigned long siglen, + unsigned long saltlen, + int hash_idx, + unsigned long modulus_bitlen, + int *res); +\end{alltt} +This will decode the PSS encoded message in \textit{sig} of length \textit{siglen} and compare it to values in \textit{msghash} of length +\textit{msghashlen}. If the block is a valid PSS block and the decoded hash equals the hash supplied \textit{res} is set to non--zero. Otherwise, +it is set to zero. The rest of the parameters are as in the PSS encode call. + +It's important to use the same \textit{saltlen} and hash for both encoding and decoding as otherwise the procedure will not work. + +\mysection{RSA Key Operations} +\subsection{Background} + +RSA is a public key algorithm that is based on the inability to find the \textit{e-th} root modulo a composite of unknown +factorization. Normally the difficulty of breaking RSA is associated with the integer factoring problem but they are +not strictly equivalent. + +The system begins with with two primes $p$ and $q$ and their product $N = pq$. The order or \textit{Euler totient} of the +multiplicative sub-group formed modulo $N$ is given as $\phi(N) = (p - 1)(q - 1)$ which can be reduced to +$\mbox{lcm}(p - 1, q - 1)$. The public key consists of the composite $N$ and some integer $e$ such that +$\mbox{gcd}(e, \phi(N)) = 1$. The private key consists of the composite $N$ and the inverse of $e$ modulo $\phi(N)$ +often simply denoted as $de \equiv 1\mbox{ }(\mbox{mod }\phi(N))$. + +A person who wants to encrypt with your public key simply forms an integer (the plaintext) $M$ such that +$1 < M < N-2$ and computes the ciphertext $C = M^e\mbox{ }(\mbox{mod }N)$. Since finding the inverse exponent $d$ +given only $N$ and $e$ appears to be intractable only the owner of the private key can decrypt the ciphertext and compute +$C^d \equiv \left (M^e \right)^d \equiv M^1 \equiv M\mbox{ }(\mbox{mod }N)$. Similarly the owner of the private key +can sign a message by \textit{decrypting} it. Others can verify it by \textit{encrypting} it. + +Currently RSA is a difficult system to cryptanalyze provided that both primes are large and not close to each other. +Ideally $e$ should be larger than $100$ to prevent direct analysis. For example, if $e$ is three and you do not pad +the plaintext to be encrypted than it is possible that $M^3 < N$ in which case finding the cube-root would be trivial. +The most often suggested value for $e$ is $65537$ since it is large enough to make such attacks impossible and also well +designed for fast exponentiation (requires 16 squarings and one multiplication). + +It is important to pad the input to RSA since it has particular mathematical structure. For instance +$M_1^dM_2^d = (M_1M_2)^d$ which can be used to forge a signature. Suppose $M_3 = M_1M_2$ is a message you want +to have a forged signature for. Simply get the signatures for $M_1$ and $M_2$ on their own and multiply the result +together. Similar tricks can be used to deduce plaintexts from ciphertexts. It is important not only to sign +the hash of documents only but also to pad the inputs with data to remove such structure. + +\subsection{RSA Key Generation} + +For RSA routines a single \textit{rsa\_key} structure is used. To make a new RSA key call: +\index{rsa\_make\_key()} +\begin{verbatim} +int rsa_make_key(prng_state *prng, + int wprng, + int size, + long e, + rsa_key *key); +\end{verbatim} + +Where \textit{wprng} is the index into the PRNG descriptor array. The \textit{size} parameter is the size in bytes of the RSA modulus desired. +The \textit{e} parameter is the encryption exponent desired, typical values are 3, 17, 257 and 65537. Stick with 65537 since it is big enough to prevent +trivial math attacks, and not super slow. The \textit{key} parameter is where the constructed key is placed. All keys must be at +least 128 bytes, and no more than 512 bytes in size (\textit{that is from 1024 to 4096 bits}). + +\index{rsa\_free()} +Note: the \textit{rsa\_make\_key()} function allocates memory at run--time when you make the key. Make sure to call +\textit{rsa\_free()} (see below) when you are finished with the key. If \textit{rsa\_make\_key()} fails it will automatically +free the memory allocated. + +\index{PK\_PRIVATE} \index{PK\_PUBLIC} +There are two types of RSA keys. The types are {\bf PK\_PRIVATE} and {\bf PK\_PUBLIC}. The first type is a private +RSA key which includes the CRT parameters\footnote{As of v0.99 the PK\_PRIVATE\_OPTIMIZED type has been deprecated, and has been replaced by the +PK\_PRIVATE type.} in the form of a RSAPrivateKey (PKCS \#1 compliant). The second type, is a public RSA key which only includes the modulus and public exponent. +It takes the form of a RSAPublicKey (PKCS \#1 compliant). + +\subsection{RSA Exponentiation} +To do raw work with the RSA function, that is without padding, use the following function: +\index{rsa\_exptmod()} +\begin{verbatim} +int rsa_exptmod(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + int which, + rsa_key *key); +\end{verbatim} +This will load the bignum from \textit{in} as a big endian integer in the format PKCS \#1 specifies, raises it to either \textit{e} or \textit{d} and stores the result +in \textit{out} and the size of the result in \textit{outlen}. \textit{which} is set to {\bf PK\_PUBLIC} to use \textit{e} +(i.e. for encryption/verifying) and set to {\bf PK\_PRIVATE} to use \textit{d} as the exponent (i.e. for decrypting/signing). + +Note: the output of this function is zero--padded as per PKCS \#1 specification. This allows this routine to work with PKCS \#1 padding functions properly. + +\mysection{RSA Key Encryption} +Normally RSA is used to encrypt short symmetric keys which are then used in block ciphers to encrypt a message. +To facilitate encrypting short keys the following functions have been provided. + +\index{rsa\_encrypt\_key()} +\begin{verbatim} +int rsa_encrypt_key( + const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + const unsigned char *lparam, + unsigned long lparamlen, + prng_state *prng, + int prng_idx, + int hash_idx, + rsa_key *key); +\end{verbatim} +This function will OAEP pad \textit{in} of length \textit{inlen} bytes, RSA encrypt it, and store the ciphertext +in \textit{out} of length \textit{outlen} octets. The \textit{lparam} and \textit{lparamlen} are the same parameters you would pass +to \index{pkcs\_1\_oaep\_encode()} pkcs\_1\_oaep\_encode(). + +\subsection{Extended Encryption} +As of v1.15, the library supports both v1.5 and v2.1 PKCS \#1 style paddings in these higher level functions. The following is the extended +encryption function: + +\index{rsa\_encrypt\_key\_ex()} +\begin{verbatim} +int rsa_encrypt_key_ex( + const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + const unsigned char *lparam, + unsigned long lparamlen, + prng_state *prng, + int prng_idx, + int hash_idx, + int padding, + rsa_key *key); +\end{verbatim} + +\index{LTC\_PKCS\_1\_OAEP} \index{LTC\_PKCS\_1\_V1\_5} +The parameters are all the same as for rsa\_encrypt\_key() except for the addition of the \textit{padding} parameter. It must be set to +\textbf{LTC\_PKCS\_1\_V1\_5} to perform v1.5 encryption, or set to \textbf{LTC\_PKCS\_1\_OAEP} to perform v2.1 encryption. + +When performing v1.5 encryption, the hash and lparam parameters are totally ignored and can be set to \textbf{NULL} or zero (respectively). + +\mysection{RSA Key Decryption} +\index{rsa\_decrypt\_key()} +\begin{verbatim} +int rsa_decrypt_key( + const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + const unsigned char *lparam, + unsigned long lparamlen, + int hash_idx, + int *stat, + rsa_key *key); +\end{verbatim} +This function will RSA decrypt \textit{in} of length \textit{inlen} then OAEP de-pad the resulting data and store it in +\textit{out} of length \textit{outlen}. The \textit{lparam} and \textit{lparamlen} are the same parameters you would pass +to pkcs\_1\_oaep\_decode(). + +If the RSA decrypted data is not a valid OAEP packet then \textit{stat} is set to $0$. Otherwise, it is set to $1$. + +\subsection{Extended Decryption} +As of v1.15, the library supports both v1.5 and v2.1 PKCS \#1 style paddings in these higher level functions. The following is the extended +decryption function: + +\index{rsa\_decrypt\_key\_ex()} +\begin{verbatim} +int rsa_decrypt_key_ex( + const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + const unsigned char *lparam, + unsigned long lparamlen, + int hash_idx, + int padding, + int *stat, + rsa_key *key); +\end{verbatim} + +Similar to the extended encryption, the new parameter \textit{padding} indicates which version of the PKCS \#1 standard to use. +It must be set to \textbf{LTC\_PKCS\_1\_V1\_5} to perform v1.5 decryption, or set to \textbf{LTC\_PKCS\_1\_OAEP} to perform v2.1 decryption. + +When performing v1.5 decryption, the hash and lparam parameters are totally ignored and can be set to \textbf{NULL} or zero (respectively). + + +\mysection{RSA Signature Generation} +Similar to RSA key encryption RSA is also used to \textit{digitally sign} message digests (hashes). To facilitate this +process the following functions have been provided. + +\index{rsa\_sign\_hash()} +\begin{verbatim} +int rsa_sign_hash(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + prng_state *prng, + int prng_idx, + int hash_idx, + unsigned long saltlen, + rsa_key *key); +\end{verbatim} + +This will PSS encode the message digest pointed to by \textit{in} of length \textit{inlen} octets. Next, the PSS encoded hash will be RSA +\textit{signed} and the output stored in the buffer pointed to by \textit{out} of length \textit{outlen} octets. + +The \textit{hash\_idx} parameter indicates which hash will be used to create the PSS encoding. It should be the same as the hash used to +hash the message being signed. The \textit{saltlen} parameter indicates the length of the desired salt, and should typically be small. A good +default value is between 8 and 16 octets. Strictly, it must be small than $modulus\_len - hLen - 2$ where \textit{modulus\_len} is the size of +the RSA modulus (in octets), and \textit{hLen} is the length of the message digest produced by the chosen hash. + +\subsection{Extended Signatures} + +As of v1.15, the library supports both v1.5 and v2.1 signatures. The extended signature generation function has the following prototype: + +\index{rsa\_sign\_hash\_ex()} +\begin{verbatim} +int rsa_sign_hash_ex( + const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + int padding, + prng_state *prng, + int prng_idx, + int hash_idx, + unsigned long saltlen, + rsa_key *key); +\end{verbatim} + +This will PKCS encode the message digest pointed to by \textit{in} of length \textit{inlen} octets. Next, the PKCS encoded hash will be RSA +\textit{signed} and the output stored in the buffer pointed to by \textit{out} of length \textit{outlen} octets. The \textit{padding} parameter +must be set to \textbf{LTC\_PKCS\_1\_V1\_5} to produce a v1.5 signature, otherwise, it must be set to \textbf{LTC\_PKCS\_1\_PSS} to produce a +v2.1 signature. + +When performing a v1.5 signature the \textit{prng}, \textit{prng\_idx}, and \textit{hash\_idx} parameters are not checked and can be left to any +values such as $\lbrace$\textbf{NULL}, 0, 0$\rbrace$. + +\mysection{RSA Signature Verification} +\index{rsa\_verify\_hash()} +\begin{verbatim} +int rsa_verify_hash(const unsigned char *sig, + unsigned long siglen, + const unsigned char *msghash, + unsigned long msghashlen, + int hash_idx, + unsigned long saltlen, + int *stat, + rsa_key *key); +\end{verbatim} + +This will RSA \textit{verify} the signature pointed to by \textit{sig} of length \textit{siglen} octets. Next, the RSA decoded data is PSS decoded +and the extracted hash is compared against the message digest pointed to by \textit{msghash} of length \textit{msghashlen} octets. + +If the RSA decoded data is not a valid PSS message, or if the PSS decoded hash does not match the \textit{msghash} +value, \textit{res} is set to $0$. Otherwise, if the function succeeds, and signature is valid \textit{res} is set to $1$. + +\subsection{Extended Verification} + +As of v1.15, the library supports both v1.5 and v2.1 signature verification. The extended signature verification function has the following prototype: + +\index{rsa\_verify\_hash\_ex()} +\begin{verbatim} +int rsa_verify_hash_ex( + const unsigned char *sig, + unsigned long siglen, + const unsigned char *hash, + unsigned long hashlen, + int padding, + int hash_idx, + unsigned long saltlen, + int *stat, + rsa_key *key); +\end{verbatim} + +This will RSA \textit{verify} the signature pointed to by \textit{sig} of length \textit{siglen} octets. Next, the RSA decoded data is PKCS decoded +and the extracted hash is compared against the message digest pointed to by \textit{msghash} of length \textit{msghashlen} octets. + +If the RSA decoded data is not a valid PSS message, or if the PKCS decoded hash does not match the \textit{msghash} +value, \textit{res} is set to $0$. Otherwise, if the function succeeds, and signature is valid \textit{res} is set to $1$. + +The \textit{padding} parameter must be set to \textbf{LTC\_PKCS\_1\_V1\_5} to perform a v1.5 verification. Otherwise, it must be set to +\textbf{LTC\_PKCS\_1\_PSS} to perform a v2.1 verification. When performing a v1.5 verification the \textit{hash\_idx} parameter is ignored. + +\mysection{RSA Encryption Example} +\begin{small} +\begin{verbatim} +#include +int main(void) +{ + int err, hash_idx, prng_idx, res; + unsigned long l1, l2; + unsigned char pt[16], pt2[16], out[1024]; + rsa_key key; + + /* register prng/hash */ + if (register_prng(&sprng_desc) == -1) { + printf("Error registering sprng"); + return EXIT_FAILURE; + } + + /* register a math library (in this case TomsFastMath) + ltc_mp = tfm_desc; + + if (register_hash(&sha1_desc) == -1) { + printf("Error registering sha1"); + return EXIT_FAILURE; + } + hash_idx = find_hash("sha1"); + prng_idx = find_prng("sprng"); + + /* make an RSA-1024 key */ + if ((err = rsa_make_key(NULL, /* PRNG state */ + prng_idx, /* PRNG idx */ + 1024/8, /* 1024-bit key */ + 65537, /* we like e=65537 */ + &key) /* where to store the key */ + ) != CRYPT_OK) { + printf("rsa_make_key %s", error_to_string(err)); + return EXIT_FAILURE; + } + + /* fill in pt[] with a key we want to send ... */ + l1 = sizeof(out); + if ((err = rsa_encrypt_key(pt, /* data we wish to encrypt */ + 16, /* data is 16 bytes long */ + out, /* where to store ciphertext */ + &l1, /* length of ciphertext */ + "TestApp", /* our lparam for this program */ + 7, /* lparam is 7 bytes long */ + NULL, /* PRNG state */ + prng_idx, /* prng idx */ + hash_idx, /* hash idx */ + &key) /* our RSA key */ + ) != CRYPT_OK) { + printf("rsa_encrypt_key %s", error_to_string(err)); + return EXIT_FAILURE; + } + + /* now let's decrypt the encrypted key */ + l2 = sizeof(pt2); + if ((err = rsa_decrypt_key(out, /* encrypted data */ + l1, /* length of ciphertext */ + pt2, /* where to put plaintext */ + &l2, /* plaintext length */ + "TestApp", /* lparam for this program */ + 7, /* lparam is 7 bytes long */ + hash_idx, /* hash idx */ + &res, /* validity of data */ + &key) /* our RSA key */ + ) != CRYPT_OK) { + printf("rsa_decrypt_key %s", error_to_string(err)); + return EXIT_FAILURE; + } + /* if all went well pt == pt2, l2 == 16, res == 1 */ +} +\end{verbatim} +\end{small} + +\mysection{RSA Key Format} + +The RSA key format adopted for exporting and importing keys is the PKCS \#1 format defined by the ASN.1 constructs known as +RSAPublicKey and RSAPrivateKey. Additionally, the OpenSSL key format is supported by the import function only. + +\subsection{RSA Key Export} +To export a RSA key use the following function. + +\index{rsa\_export()} +\begin{verbatim} +int rsa_export(unsigned char *out, + unsigned long *outlen, + int type, + rsa_key *key); +\end{verbatim} +This will export the RSA key in either a RSAPublicKey or RSAPrivateKey (PKCS \#1 types) depending on the value of \textit{type}. When it is +set to \textbf{PK\_PRIVATE} the export format will be RSAPrivateKey and otherwise it will be RSAPublicKey. + +\subsection{RSA Key Import} +To import a RSA key use the following function. + +\index{rsa\_import()} +\begin{verbatim} +int rsa_import(const unsigned char *in, + unsigned long inlen, + rsa_key *key); +\end{verbatim} + +This will import the key stored in \textit{inlen} and import it to \textit{key}. If the function fails it will automatically free any allocated memory. This +function can import both RSAPublicKey and RSAPrivateKey formats. + +As of v1.06 this function can also import OpenSSL DER formatted public RSA keys. They are essentially encapsulated RSAPublicKeys. LibTomCrypt will +import the key, strip off the additional data (it's the preferred hash) and fill in the rsa\_key structure as if it were a native RSAPublicKey. Note that +there is no function provided to export in this format. + +\chapter{Elliptic Curve Cryptography} + +\mysection{Background} +The library provides a set of core ECC functions as well that are designed to be the Elliptic Curve analogy of all of the +Diffie-Hellman routines in the previous chapter. Elliptic curves (of certain forms) have the benefit that they are harder +to attack (no sub-exponential attacks exist unlike normal DH crypto) in fact the fastest attack requires the square root +of the order of the base point in time. That means if you use a base point of order $2^{192}$ (which would represent a +192-bit key) then the work factor is $2^{96}$ in order to find the secret key. + +The curves in this library are taken from the following website: +\begin{verbatim} +http://csrc.nist.gov/cryptval/dss.htm +\end{verbatim} + +As of v1.15 three new curves from the SECG standards are also included they are the secp112r1, secp128r1, and secp160r1 curves. These curves were added to +support smaller devices which do not need as large keys for security. + +They are all curves over the integers modulo a prime. The curves have the basic equation that is: +\begin{equation} +y^2 = x^3 - 3x + b\mbox{ }(\mbox{mod }p) +\end{equation} + +The variable $b$ is chosen such that the number of points is nearly maximal. In fact the order of the base points $\beta$ +provided are very close to $p$ that is $\vert \vert \phi(\beta) \vert \vert \approx \vert \vert p \vert \vert$. The curves +range in order from $\approx 2^{112}$ points to $\approx 2^{521}$. According to the source document any key size greater +than or equal to 256-bits is sufficient for long term security. + +\mysection{Fixed Point Optimizations} +\index{Fixed Point ECC} +\index{MECC\_FP} +As of v1.12 of LibTomCrypt, support for Fixed Point ECC point multiplication has been added. It is a generic optimization that is +supported by any conforming math plugin. It is enabled by defining \textbf{MECC\_FP} during the build, such as + +\begin{verbatim} +CFLAGS="-DTFM_DESC -DMECC_FP" make +\end{verbatim} + +which will build LTC using the TFM math library and enabling this new feature. The feature is not enabled by default as it is \textbf{NOT} thread +safe (by default). It supports the LTC locking macros (such as by enabling LTC\_PTHREAD), but by default is not locked. + +\index{FP\_ENTRIES} +The optimization works by using a Fixed Point multiplier on any base point you use twice or more in a short period of time. It has a limited size +cache (of FP\_ENTRIES entries) which it uses to hold recent bases passed to ltc\_ecc\_mulmod(). Any base detected to be used twice is sent through the +pre--computation phase, and then the fixed point algorithm can be used. For example, if you use a NIST base point twice in a row, the 2$^{nd}$ and +all subsequent point multiplications with that point will use the faster algorithm. + +\index{FP\_LUT} +The optimization uses a window on the multiplicand of FP\_LUT bits (default: 8, min: 2, max: 12), and this controls the memory/time trade-off. The larger the +value the faster the algorithm will be but the more memory it will take. The memory usage is $3 \cdot 2^{FP\_LUT}$ integers which by default +with TFM amounts to about 400kB of memory. Tuning TFM (by changing FP\_SIZE) can decrease the usage by a fair amount. Memory is only used by a cache entry +if it is active. Both FP\_ENTRIES and FP\_LUT are definable on the command line if you wish to override them. For instance, + +\begin{verbatim} +CFLAGS="-DTFM_DESC -DMECC_FP -DFP_ENTRIES=8 -DFP_LUT=6" make +\end{verbatim} + +\begin{flushleft} +\index{FP\_SIZE} \index{TFM} \index{tfm.h} +would define a window of 6 bits and limit the cache to 8 entries. Generally, it is better to first tune TFM by adjusting FP\_SIZE (from tfm.h). It defaults +to 4096 bits (512 bytes) which is way more than what is required by ECC. At most, you need 1152 bits to accommodate ECC--521. If you're only using (say) +ECC--256 you will only need 576 bits, which would reduce the memory usage by 700\%. +\end{flushleft} + +\mysection{Key Format} +LibTomCrypt uses a unique format for ECC public and private keys. While ANSI X9.63 partially specifies key formats, it does it in a less than ideally simple manner. \ +In the case of LibTomCrypt, it is meant \textbf{solely} for NIST and SECG $GF(p)$ curves. The format of the keys is as follows: + +\index{ECC Key Format} +\begin{small} +\begin{verbatim} +ECCPublicKey ::= SEQUENCE { + flags BIT STRING(0), -- public/private flag (always zero), + keySize INTEGER, -- Curve size (in bits) divided by eight + -- and rounded down, e.g. 521 => 65 + pubkey.x INTEGER, -- The X co-ordinate of the public key point + pubkey.y INTEGER, -- The Y co-ordinate of the public key point +} + +ECCPrivateKey ::= SEQUENCE { + flags BIT STRING(1), -- public/private flag (always one), + keySize INTEGER, -- Curve size (in bits) divided by eight + -- and rounded down, e.g. 521 => 65 + pubkey.x INTEGER, -- The X co-ordinate of the public key point + pubkey.y INTEGER, -- The Y co-ordinate of the public key point + secret.k INTEGER, -- The secret key scalar +} +\end{verbatim} +\end{small} + +The first flags bit denotes whether the key is public (zero) or private (one). + +\vfil + +\mysection{ECC Curve Parameters} +The library uses the following structure to describe an elliptic curve. This is used internally, as well as by the new +extended ECC functions which allow the user to specify their own curves. + +\index{ltc\_ecc\_set\_type} +\begin{verbatim} +/** Structure defines a NIST GF(p) curve */ +typedef struct { + /** The size of the curve in octets */ + int size; + + /** name of curve */ + char *name; + + /** The prime that defines the field (encoded in hex) */ + char *prime; + + /** The fields B param (hex) */ + char *B; + + /** The order of the curve (hex) */ + char *order; + + /** The x co-ordinate of the base point on the curve (hex) */ + char *Gx; + + /** The y co-ordinate of the base point on the curve (hex) */ + char *Gy; +} ltc_ecc_set_type; +\end{verbatim} + +The curve must be of the form $y^2 = x^3 - 3x + b$, and all of the integer parameters are encoded in hexadecimal format. + +\mysection{Core Functions} +\subsection{ECC Key Generation} +There is a key structure called \textit{ecc\_key} used by the ECC functions. There is a function to make a key: +\index{ecc\_make\_key()} +\begin{verbatim} +int ecc_make_key(prng_state *prng, + int wprng, + int keysize, + ecc_key *key); +\end{verbatim} + +The \textit{keysize} is the size of the modulus in bytes desired. Currently directly supported values are 12, 16, 20, 24, 28, 32, 48, and 65 bytes which +correspond to key sizes of 112, 128, 160, 192, 224, 256, 384, and 521 bits respectively. If you pass a key size that is between any key size it will round +the keysize up to the next available one. + +The function will free any internally allocated resources if there is an error. + +\subsection{Extended Key Generation} +As of v1.16, the library supports an extended key generation routine which allows the user to specify their own curve. It is specified as follows: + +\index{ecc\_make\_key\_ex()} +\begin{verbatim} +int ecc_make_key_ex( + prng_state *prng, + int wprng, + ecc_key *key, + const ltc_ecc_set_type *dp); +\end{verbatim} + +This function generates a random ECC key over the curve specified by the parameters by \textit{dp}. The rest of the parameters are equivalent to +those from the original key generation function. + +\subsection{ECC Key Free} +To free the memory allocated by a ecc\_make\_key(), ecc\_make\_key\_ex(), ecc\_import(), or ecc\_import\_ex() call use the following function: +\index{ecc\_free()} +\begin{verbatim} +void ecc_free(ecc_key *key); +\end{verbatim} + +\subsection{ECC Key Export} +To export an ECC key using the LibTomCrypt format call the following function: +\index{ecc\_export()} +\begin{verbatim} +int ecc_export(unsigned char *out, + unsigned long *outlen, + int type, + ecc_key *key); +\end{verbatim} +This will export the key with the given \textit{type} (\textbf{PK\_PUBLIC} or \textbf{PK\_PRIVATE}), and store it to \textit{out}. + +\subsection{ECC Key Import} +The following function imports a LibTomCrypt format ECC key: +\index{ecc\_import()} +\begin{verbatim} +int ecc_import(const unsigned char *in, + unsigned long inlen, + ecc_key *key); +\end{verbatim} +This will import the ECC key from \textit{in}, and store it in the ecc\_key structure pointed to by \textit{key}. If the operation fails it will free +any allocated memory automatically. + +\subsection{Extended Key Import} + +The following function imports a LibTomCrypt format ECC key using a specified set of curve parameters: +\index{ecc\_import\_ex()} +\begin{verbatim} +int ecc_import_ex(const unsigned char *in, + unsigned long inlen, + ecc_key *key, + const ltc_ecc_set_type *dp); +\end{verbatim} +This will import the key from the array pointed to by \textit{in} of length \textit{inlen} octets. The key is stored in +the ECC structure pointed to by \textit{key}. The curve is specified by the parameters pointed to by \textit{dp}. The function will free +all internally allocated memory upon error. + +\subsection{ANSI X9.63 Export} +The following function exports an ECC public key in the ANSI X9.63 format: + +\index{ecc\_ansi\_x963\_export()} +\begin{verbatim} +int ecc_ansi_x963_export( ecc_key *key, + unsigned char *out, + unsigned long *outlen); +\end{verbatim} +The ECC key pointed to by \textit{key} is exported in public fashion to the array pointed to by \textit{out}. The ANSI X9.63 format used is from +section 4.3.6 of the standard. It does not allow for the export of private keys. + +\subsection{ANSI X9.63 Import} +The following function imports an ANSI X9.63 section 4.3.6 format public ECC key: + +\index{ecc\_ansi\_x963\_import()} +\begin{verbatim} +int ecc_ansi_x963_import(const unsigned char *in, + unsigned long inlen, + ecc_key *key); +\end{verbatim} +This will import the key stored in the array pointed to by \textit{in} of length \textit{inlen} octets. The imported key is stored in the ECC key pointed to by +\textit{key}. The function will free any allocated memory upon error. + +\subsection{Extended ANSI X9.63 Import} +The following function allows the importing of an ANSI x9.63 section 4.3.6 format public ECC key using user specified domain parameters: + +\index{ecc\_ansi\_x963\_import\_ex()} +\begin{verbatim} +int ecc_ansi_x963_import_ex(const unsigned char *in, + unsigned long inlen, + ecc_key *key, + ltc_ecc_set_type *dp); +\end{verbatim} +This will import the key stored in the array pointed to by \textit{in} of length \textit{inlen} octets using the domain parameters pointed to by \textit{dp}. +The imported key is stored in the ECC key pointed to by \textit{key}. The function will free any allocated memory upon error. + +\subsection{ECC Shared Secret} +To construct a Diffie-Hellman shared secret with a private and public ECC key, use the following function: +\index{ecc\_shared\_secret()} +\begin{verbatim} +int ecc_shared_secret( ecc_key *private_key, + ecc_key *public_key, + unsigned char *out, + unsigned long *outlen); +\end{verbatim} +The \textit{private\_key} is typically the local private key, and \textit{public\_key} is the key the remote party has shared. +Note: this function stores only the $x$ co-ordinate of the shared elliptic point as described in ANSI X9.63 ECC--DH. + +\mysection{ECC Diffie-Hellman Encryption} +ECC--DH Encryption is performed by producing a random key, hashing it, and XOR'ing the digest against the plaintext. It is not strictly ANSI X9.63 compliant +but it is very similar. It has been extended by using an ASN.1 sequence and hash object identifiers to allow portable usage. The following function +encrypts a short string (no longer than the message digest) using this technique: + +\subsection{ECC-DH Encryption} +\index{ecc\_encrypt\_key()} +\begin{verbatim} +int ecc_encrypt_key(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + prng_state *prng, + int wprng, + int hash, + ecc_key *key); +\end{verbatim} + +As the name implies this function encrypts a (symmetric) key, and is not intended for encrypting long messages directly. It will encrypt the +plaintext in the array pointed to by \textit{in} of length \textit{inlen} octets. It uses the public ECC key pointed to by \textit{key}, and +hash algorithm indexed by \textit{hash} to construct a shared secret which may be XOR'ed against the plaintext. The ciphertext is stored in +the output buffer pointed to by \textit{out} of length \textit{outlen} octets. + +The data is encrypted to the public ECC \textit{key} such that only the holder of the private key can decrypt the payload. To have multiple +recipients multiple call to this function for each public ECC key is required. + +\subsection{ECC-DH Decryption} +\index{ecc\_decrypt\_key()} +\begin{verbatim} +int ecc_decrypt_key(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + ecc_key *key); +\end{verbatim} + +This function will decrypt an encrypted payload. The \textit{key} provided must be the private key corresponding to the public key +used during encryption. If the wrong key is provided the function will not specifically return an error code. It is important +to use some form of challenge response in that case (e.g. compute a MAC of a known string). + +\subsection{ECC Encryption Format} +The packet format for the encrypted keys is the following ASN.1 SEQUENCE: + +\begin{verbatim} +ECCEncrypt ::= SEQUENCE { + hashID OBJECT IDENTIFIER, -- OID of hash used + pubkey OCTET STRING , -- Encapsulated ECCPublicKey + skey OCTET STRING -- xor of plaintext and + --"hash of shared secret" +} +\end{verbatim} + +\mysection{EC DSA Signatures} + +There are also functions to sign and verify messages. They use the ANSI X9.62 EC-DSA algorithm to generate and verify signatures in the +ANSI X9.62 format. + +\subsection{EC-DSA Signature Generation} +To sign a message digest (hash) use the following function: + +\index{ecc\_sign\_hash()} +\begin{verbatim} +int ecc_sign_hash(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + prng_state *prng, + int wprng, + ecc_key *key); +\end{verbatim} + +This function will EC--DSA sign the message digest stored in the array pointed to by \textit{in} of length \textit{inlen} octets. The signature +will be stored in the array pointed to by \textit{out} of length \textit{outlen} octets. The function requires a properly seeded PRNG, and +the ECC \textit{key} provided must be a private key. + +\subsection{EC-DSA Signature Verification} +\index{ecc\_verify\_hash()} +\begin{verbatim} +int ecc_verify_hash(const unsigned char *sig, + unsigned long siglen, + const unsigned char *hash, + unsigned long hashlen, + int *stat, + ecc_key *key); +\end{verbatim} + +This function will verify the EC-DSA signature in the array pointed to by \textit{sig} of length \textit{siglen} octets, against the message digest +pointed to by the array \textit{hash} of length \textit{hashlen}. It will store a non--zero value in \textit{stat} if the signature is valid. Note: +the function will not return an error if the signature is invalid. It will return an error, if the actual signature payload is an invalid format. +The ECC \textit{key} must be the public (or private) ECC key corresponding to the key that performed the signature. + +\subsection{Signature Format} +The signature code is an implementation of X9.62 EC--DSA, and the output is compliant for GF(p) curves. + +\mysection{ECC Keysizes} +With ECC if you try to sign a hash that is bigger than your ECC key you can run into problems. The math will still work, and in effect the signature will still +work. With ECC keys the strength of the signature is limited by the size of the hash, or the size of they key, whichever is smaller. For example, if you sign with +SHA256 and an ECC-192 key, you in effect have 96--bits of security. + +The library will not warn you if you make this mistake, so it is important to check yourself before using the signatures. + +\chapter{Digital Signature Algorithm} +\mysection{Introduction} +The Digital Signature Algorithm (or DSA) is a variant of the ElGamal Signature scheme which has been modified to +reduce the bandwidth of the signatures. For example, to have \textit{80-bits of security} with ElGamal, you need a group with an order of at least 1024--bits. +With DSA, you need a group of order at least 160--bits. By comparison, the ElGamal signature would require at least 256 bytes of storage, whereas the DSA signature +would require only at least 40 bytes. + +\mysection{Key Format} +Since no useful public standard for DSA key storage was presented to me during the course of this development I made my own ASN.1 SEQUENCE which I document +now so that others can interoperate with this library. + +\begin{verbatim} +DSAPublicKey ::= SEQUENCE { + publicFlags BIT STRING(0), -- must be 0 + g INTEGER , -- base generator + -- check that g^q mod p == 1 + -- and that 1 < g < p - 1 + p INTEGER , -- prime modulus + q INTEGER , -- order of sub-group + -- (must be prime) + y INTEGER , -- public key, specifically, + -- g^x mod p, + -- check that y^q mod p == 1 + -- and that 1 < y < p - 1 +} + +DSAPrivateKey ::= SEQUENCE { + publicFlags BIT STRING(1), -- must be 1 + g INTEGER , -- base generator + -- check that g^q mod p == 1 + -- and that 1 < g < p - 1 + p INTEGER , -- prime modulus + q INTEGER , -- order of sub-group + -- (must be prime) + y INTEGER , -- public key, specifically, + -- g^x mod p, + -- check that y^q mod p == 1 + -- and that 1 < y < p - 1 + x INTEGER -- private key +} +\end{verbatim} + +The leading BIT STRING has a single bit in it which is zero for public keys and one for private keys. This makes the structure uniquely decodable, +and easy to work with. + +\mysection{Key Generation} +To make a DSA key you must call the following function +\begin{verbatim} +int dsa_make_key(prng_state *prng, + int wprng, + int group_size, + int modulus_size, + dsa_key *key); +\end{verbatim} +The variable \textit{prng} is an active PRNG state and \textit{wprng} the index to the descriptor. \textit{group\_size} and +\textit{modulus\_size} control the difficulty of forging a signature. Both parameters are in bytes. The larger the +\textit{group\_size} the more difficult a forgery becomes upto a limit. The value of $group\_size$ is limited by +$15 < group\_size < 1024$ and $modulus\_size - group\_size < 512$. Suggested values for the pairs are as follows. + +\begin{figure}[here] +\begin{center} +\begin{tabular}{|c|c|c|} +\hline \textbf{Bits of Security} & \textbf{group\_size} & \textbf{modulus\_size} \\ +\hline 80 & 20 & 128 \\ +\hline 120 & 30 & 256 \\ +\hline 140 & 35 & 384 \\ +\hline 160 & 40 & 512 \\ +\hline +\end{tabular} +\end{center} +\caption{DSA Key Sizes} +\end{figure} + +When you are finished with a DSA key you can call the following function to free the memory used. +\index{dsa\_free()} +\begin{verbatim} +void dsa_free(dsa_key *key); +\end{verbatim} + +\mysection{Key Verification} +Each DSA key is composed of the following variables. + +\begin{enumerate} + \item $q$ a small prime of magnitude $256^{group\_size}$. + \item $p = qr + 1$ a large prime of magnitude $256^{modulus\_size}$ where $r$ is a random even integer. + \item $g = h^r \mbox{ (mod }p\mbox{)}$ a generator of order $q$ modulo $p$. $h$ can be any non-trivial random + value. For this library they start at $h = 2$ and step until $g$ is not $1$. + \item $x$ a random secret (the secret key) in the range $1 < x < q$ + \item $y = g^x \mbox{ (mod }p\mbox{)}$ the public key. +\end{enumerate} + +A DSA key is considered valid if it passes all of the following tests. + +\begin{enumerate} + \item $q$ must be prime. + \item $p$ must be prime. + \item $g$ cannot be one of $\lbrace -1, 0, 1 \rbrace$ (modulo $p$). + \item $g$ must be less than $p$. + \item $(p-1) \equiv 0 \mbox{ (mod }q\mbox{)}$. + \item $g^q \equiv 1 \mbox{ (mod }p\mbox{)}$. + \item $1 < y < p - 1$ + \item $y^q \equiv 1 \mbox{ (mod }p\mbox{)}$. +\end{enumerate} + +Tests one and two ensure that the values will at least form a field which is required for the signatures to +function. Tests three and four ensure that the generator $g$ is not set to a trivial value which would make signature +forgery easier. Test five ensures that $q$ divides the order of multiplicative sub-group of $\Z/p\Z$. Test six +ensures that the generator actually generates a prime order group. Tests seven and eight ensure that the public key +is within range and belongs to a group of prime order. Note that test eight does not prove that $g$ generated $y$ only +that $y$ belongs to a multiplicative sub-group of order $q$. + +The following function will perform these tests. + +\index{dsa\_verify\_key()} +\begin{verbatim} +int dsa_verify_key(dsa_key *key, int *stat); +\end{verbatim} + +This will test \textit{key} and store the result in \textit{stat}. If the result is $stat = 0$ the DSA key failed one of the tests +and should not be used at all. If the result is $stat = 1$ the DSA key is valid (as far as valid mathematics are concerned). + +\mysection{Signatures} +\subsection{Signature Generation} +To generate a DSA signature call the following function: + +\index{dsa\_sign\_hash()} +\begin{verbatim} +int dsa_sign_hash(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + prng_state *prng, + int wprng, + dsa_key *key); +\end{verbatim} + +Which will sign the data in \textit{in} of length \textit{inlen} bytes. The signature is stored in \textit{out} and the size +of the signature in \textit{outlen}. If the signature is longer than the size you initially specify in \textit{outlen} nothing +is stored and the function returns an error code. The DSA \textit{key} must be of the \textbf{PK\_PRIVATE} persuasion. + +\subsection{Signature Verification} +To verify a hash created with that function use the following function: + +\index{dsa\_verify\_hash()} +\begin{verbatim} +int dsa_verify_hash(const unsigned char *sig, + unsigned long siglen, + const unsigned char *hash, + unsigned long inlen, + int *stat, + dsa_key *key); +\end{verbatim} +Which will verify the data in \textit{hash} of length \textit{inlen} against the signature stored in \textit{sig} of length \textit{siglen}. +It will set \textit{stat} to $1$ if the signature is valid, otherwise it sets \textit{stat} to $0$. + +\mysection{DSA Encrypt and Decrypt} +As of version 1.07, the DSA keys can be used to encrypt and decrypt small payloads. It works similar to the ECC encryption where +a shared key is computed, and the hash of the shared key XOR'ed against the plaintext forms the ciphertext. The format used is functional port of +the ECC encryption format to the DSA algorithm. + +\subsection{DSA Encryption} +This function will encrypt a small payload with a recipients public DSA key. + +\index{dsa\_encrypt\_key()} +\begin{verbatim} +int dsa_encrypt_key(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + prng_state *prng, + int wprng, + int hash, + dsa_key *key); +\end{verbatim} + +This will encrypt the payload in \textit{in} of length \textit{inlen} and store the ciphertext in the output buffer \textit{out}. The +length of the ciphertext \textit{outlen} must be originally set to the length of the output buffer. The DSA \textit{key} can be +a public key. + +\subsection{DSA Decryption} + +\index{dsa\_decrypt\_key()} +\begin{verbatim} +int dsa_decrypt_key(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + dsa_key *key); +\end{verbatim} +This will decrypt the ciphertext \textit{in} of length \textit{inlen}, and store the original payload in \textit{out} of length \textit{outlen}. +The DSA \textit{key} must be a private key. + +\mysection{DSA Key Import and Export} + +\subsection{DSA Key Export} +To export a DSA key so that it can be transported use the following function: +\index{dsa\_export()} +\begin{verbatim} +int dsa_export(unsigned char *out, + unsigned long *outlen, + int type, + dsa_key *key); +\end{verbatim} +This will export the DSA \textit{key} to the buffer \textit{out} and set the length in \textit{outlen} (which must have been previously +initialized to the maximum buffer size). The \textit{type} variable may be either \textbf{PK\_PRIVATE} or \textbf{PK\_PUBLIC} +depending on whether you want to export a private or public copy of the DSA key. + +\subsection{DSA Key Import} +To import an exported DSA key use the following function +: +\index{dsa\_import()} +\begin{verbatim} +int dsa_import(const unsigned char *in, + unsigned long inlen, + dsa_key *key); +\end{verbatim} + +This will import the DSA key from the buffer \textit{in} of length \textit{inlen} to the \textit{key}. If the process fails the function +will automatically free all of the heap allocated in the process (you don't have to call dsa\_free()). + +\chapter{Standards Support} +\mysection{ASN.1 Formats} +LibTomCrypt supports a variety of ASN.1 data types encoded with the Distinguished Encoding Rules (DER) suitable for various cryptographic protocols. The data types +are all provided with three basic functions with \textit{similar} prototypes. One function has been dedicated to calculate the length in octets of a given +format, and two functions have been dedicated to encoding and decoding the format. + +On top of the basic data types are the SEQUENCE and SET data types which are collections of other ASN.1 types. They are provided +in the same manner as the other data types except they use list of objects known as the \textbf{ltc\_asn1\_list} structure. It is defined as the following: + +\index{ltc\_asn1\_list structure} +\begin{verbatim} +typedef struct { + int type; + void *data; + unsigned long size; + int used; + struct ltc_asn1_list_ *prev, *next, + *child, *parent; +} ltc_asn1_list; +\end{verbatim} + +\index{LTC\_SET\_ASN1 macro} +The \textit{type} field is one of the following ASN.1 field definitions. The \textit{data} pointer is a void pointer to the data to be encoded (or the destination) and the +\textit{size} field is specific to what you are encoding (e.g. number of bits in the BIT STRING data type). The \textit{used} field is primarily for the CHOICE decoder +and reflects if the particular member of a list was the decoded data type. To help build the lists in an orderly fashion the macro +\textit{LTC\_SET\_ASN1(list, index, Type, Data, Size)} has been provided. + +It will assign to the \textit{index}th position in the \textit{list} the triplet (Type, Data, Size). An example usage would be: + +\begin{small} +\begin{verbatim} +... +ltc_asn1_list sequence[3]; +unsigned long three=3; + +LTC_SET_ASN1(sequence, 0, LTC_ASN1_IA5_STRING, "hello", 5); +LTC_SET_ASN1(sequence, 1, LTC_ASN1_SHORT_INTEGER, &three, 1); +LTC_SET_ASN1(sequence, 2, LTC_ASN1_NULL, NULL, 0); +\end{verbatim} +\end{small} + +The macro is relatively safe with respect to modifying variables, for instance the following code is equivalent. + +\begin{small} +\begin{verbatim} +... +ltc_asn1_list sequence[3]; +unsigned long three=3; +int x=0; +LTC_SET_ASN1(sequence, x++, LTC_ASN1_IA5_STRING, "hello", 5); +LTC_SET_ASN1(sequence, x++, LTC_ASN1_SHORT_INTEGER, &three, 1); +LTC_SET_ASN1(sequence, x++, LTC_ASN1_NULL, NULL, 0); +\end{verbatim} +\end{small} + +\begin{figure}[here] +\begin{center} +\begin{small} +\begin{tabular}{|l|l|} +\hline \textbf{Definition} & \textbf{ASN.1 Type} \\ +\hline LTC\_ASN1\_EOL & End of a ASN.1 list structure. \\ +\hline LTC\_ASN1\_BOOLEAN & BOOLEAN type \\ +\hline LTC\_ASN1\_INTEGER & INTEGER (uses mp\_int) \\ +\hline LTC\_ASN1\_SHORT\_INTEGER & INTEGER (32--bit using unsigned long) \\ +\hline LTC\_ASN1\_BIT\_STRING & BIT STRING (one bit per char) \\ +\hline LTC\_ASN1\_OCTET\_STRING & OCTET STRING (one octet per char) \\ +\hline LTC\_ASN1\_NULL & NULL \\ +\hline LTC\_ASN1\_OBJECT\_IDENTIFIER & OBJECT IDENTIFIER \\ +\hline LTC\_ASN1\_IA5\_STRING & IA5 STRING (one octet per char) \\ +\hline LTC\_ASN1\_UTF8\_STRING & UTF8 STRING (one wchar\_t per char) \\ +\hline LTC\_ASN1\_PRINTABLE\_STRING & PRINTABLE STRING (one octet per char) \\ +\hline LTC\_ASN1\_UTCTIME & UTCTIME (see ltc\_utctime structure) \\ +\hline LTC\_ASN1\_SEQUENCE & SEQUENCE (and SEQUENCE OF) \\ +\hline LTC\_ASN1\_SET & SET \\ +\hline LTC\_ASN1\_SETOF & SET OF \\ +\hline LTC\_ASN1\_CHOICE & CHOICE \\ +\hline +\end{tabular} +\caption{List of ASN.1 Supported Types} +\end{small} +\end{center} +\end{figure} + +\subsection{SEQUENCE Type} +The SEQUENCE data type is a collection of other ASN.1 data types encapsulated with a small header which is a useful way of sending multiple data types in one packet. + +\subsubsection{SEQUENCE Encoding} +To encode a sequence a \textbf{ltc\_asn1\_list} array must be initialized with the members of the sequence and their respective pointers. The encoding is performed +with the following function. + +\index{der\_encode\_sequence()} +\begin{verbatim} +int der_encode_sequence(ltc_asn1_list *list, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen); +\end{verbatim} +This encodes a sequence of items pointed to by \textit{list} where the list has \textit{inlen} items in it. The SEQUENCE will be encoded to \textit{out} and of length \textit{outlen}. The +function will terminate when it reads all the items out of the list (upto \textit{inlen}) or it encounters an item in the list with a type of \textbf{LTC\_ASN1\_EOL}. + +The \textit{data} pointer in the list would be the same pointer you would pass to the respective ASN.1 encoder (e.g. der\_encode\_bit\_string()) and it is simply passed on +verbatim to the dependent encoder. The list can contain other SEQUENCE or SET types which enables you to have nested SEQUENCE and SET definitions. In these cases +the \textit{data} pointer is simply a pointer to another \textbf{ltc\_asn1\_list}. + +\subsubsection{SEQUENCE Decoding} + +\index{der\_decode\_sequence()} + +Decoding a SEQUENCE is similar to encoding. You set up an array of \textbf{ltc\_asn1\_list} where in this case the \textit{size} member is the maximum size +(in certain cases). For types such as IA5 STRING, BIT STRING, OCTET STRING (etc) the \textit{size} field is updated after successful decoding to reflect how many +units of the respective type has been loaded. + +\begin{verbatim} +int der_decode_sequence(const unsigned char *in, + unsigned long inlen, + ltc_asn1_list *list, + unsigned long outlen); +\end{verbatim} + +This will decode upto \textit{outlen} items from the input buffer \textit{in} of length \textit{inlen} octets. The function will stop (gracefully) when it runs out of items to decode. +It will fail (for among other reasons) when it runs out of input bytes to read, a data type is invalid or a heap failure occurred. + +For the following types the \textit{size} field will be updated to reflect the number of units read of the given type. +\begin{enumerate} + \item BIT STRING + \item OCTET STRING + \item OBJECT IDENTIFIER + \item IA5 STRING + \item PRINTABLE STRING +\end{enumerate} + +\subsubsection{SEQUENCE Length} + +The length of a SEQUENCE can be determined with the following function. + +\index{der\_length\_sequence()} +\begin{verbatim} +int der_length_sequence(ltc_asn1_list *list, + unsigned long inlen, + unsigned long *outlen); +\end{verbatim} + +This will get the encoding size for the given \textit{list} of length \textit{inlen} and store it in \textit{outlen}. + +\subsubsection{SEQUENCE Multiple Argument Lists} + +For small or simple sequences an encoding or decoding can be performed with one of the following two functions. + +\index{der\_encode\_sequence\_multi()} +\index{der\_decode\_sequence\_multi()} + +\begin{verbatim} +int der_encode_sequence_multi(unsigned char *out, + unsigned long *outlen, ...); + +int der_decode_sequence_multi(const unsigned char *in, + unsigned long inlen, ...); +\end{verbatim} + +These either encode or decode (respectively) a SEQUENCE data type where the items in the sequence are specified after the length parameter. + +The list of items are specified as a triple of the form \textit{(type, size, data)} where \textit{type} is an \textbf{int}, \textit{size} is a \textbf{unsigned long} +and \textit{data} is \textbf{void} pointer. The list of items must be terminated with an item with the type \textbf{LTC\_ASN1\_EOL}. + +It is ideal that you cast the \textit{size} values to unsigned long to ensure that the proper data type is passed to the function. Constants such as \textit{1} without +a cast or prototype are of type \textbf{int} by default. Appending \textit{UL} or pre-pending \textit{(unsigned long)} is enough to cast it to the correct type. + +\begin{small} +\begin{verbatim} +unsigned char buf[MAXBUFSIZE]; +unsigned long buflen; +int err; + + buflen = sizeof(buf); + if ((err = + der_encode_sequence_multi(buf, &buflen, + LTC_ASN1_IA5_STRING, 5UL, "Hello", + LTC_ASN1_IA5_STRING, 7UL, " World!", + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + // error handling + } +\end{verbatim} +\end{small} + +This example encodes a SEQUENCE with two IA5 STRING types containing ``Hello'' and `` World!'' respectively. Note the usage of the \textbf{UL} modifier +on the size parameters. This forces the compiler to pass the numbers as the required \textbf{unsigned long} type that the function expects. + +\subsection{SET and SET OF} + +\index{SET} \index{SET OF} +SET and SET OF are related to the SEQUENCE type in that they can be pretty much be decoded with the same code. However, they are different, and they should +be carefully noted. The SET type is an unordered array of ASN.1 types sorted by the TAG (type identifier), whereas the SET OF type is an ordered array of +a \textbf{single} ASN.1 object sorted in ascending order by the DER their respective encodings. + +\subsubsection{SET Encoding} + +SETs use the same array structure of ltc\_asn1\_list that the SEQUENCE functions use. They are encoded with the following function: + +\index{der\_encode\_set()} +\begin{verbatim} +int der_encode_set(ltc_asn1_list *list, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen); +\end{verbatim} + +This will encode the list of ASN.1 objects in \textit{list} of length \textit{inlen} objects, and store the output in \textit{out} of length \textit{outlen} bytes. +The function will make a copy of the list provided, and sort it by the TAG. Objects with identical TAGs are additionally sorted on their original placement in the +array (to make the process deterministic). + +This function will \textbf{NOT} recognize \textit{DEFAULT} objects, and it is the responsibility of the caller to remove them as required. + +\subsubsection{SET Decoding} + +The SET type can be decoded with the following function. + +\index{der\_decode\_set()} +\begin{verbatim} +int der_decode_set(const unsigned char *in, + unsigned long inlen, + ltc_asn1_list *list, + unsigned long outlen); +\end{verbatim} + +This will decode the SET specified by \textit{list} of length \textit{outlen} objects from the input buffer \textit{in} of length \textit{inlen} octets. + +It handles the fact that SETs are not strictly ordered and will make multiple passes (as required) through the list to decode all the objects. + +\subsubsection{SET Length} +The length of a SET can be determined by calling der\_length\_sequence() since they have the same encoding length. + +\subsubsection{SET OF Encoding} +A \textit{SET OF} object is an array of identical objects (e.g. OCTET STRING) sorted in ascending order by the DER encoding of the object. They are +used to store objects deterministically based solely on their encoding. It uses the same array structure of ltc\_asn1\_list that the SEQUENCE functions +use. They are encoded with the following function. + +\index{der\_encode\_setof()} +\begin{verbatim} +int der_encode_setof(ltc_asn1_list *list, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen); +\end{verbatim} + +This will encode a \textit{SET OF} containing the \textit{list} of \textit{inlen} ASN.1 objects and store the encoding in the output buffer \textit{out} of length \textit{outlen}. + +The routine will first encode the SET OF in an unordered fashion (in a temporary buffer) then sort using the XQSORT macro and copy back to the output buffer. This +means you need at least enough memory to keep an additional copy of the output on the heap. + +\subsubsection{SET OF Decoding} +Since the decoding of a \textit{SET OF} object is unambiguous it can be decoded with der\_decode\_sequence(). + +\subsubsection{SET OF Length} +Like the SET type the der\_length\_sequence() function can be used to determine the length of a \textit{SET OF} object. + +\subsection{ASN.1 INTEGER} + +To encode or decode INTEGER data types use the following functions. + +\index{der\_encode\_integer()}\index{der\_decode\_integer()}\index{der\_length\_integer()} +\begin{verbatim} +int der_encode_integer( void *num, + unsigned char *out, + unsigned long *outlen); + +int der_decode_integer(const unsigned char *in, + unsigned long inlen, + void *num); + +int der_length_integer( void *num, + unsigned long *len); +\end{verbatim} + +These will encode or decode a signed INTEGER data type using the bignum data type to store the large INTEGER. To encode smaller values without allocating +a bignum to store the value, the \textit{short} INTEGER functions were made available. + +\index{der\_encode\_short\_integer()}\index{der\_decode\_short\_integer()}\index{der\_length\_short\_integer()} +\begin{verbatim} +int der_encode_short_integer(unsigned long num, + unsigned char *out, + unsigned long *outlen); + +int der_decode_short_integer(const unsigned char *in, + unsigned long inlen, + unsigned long *num); + +int der_length_short_integer(unsigned long num, + unsigned long *outlen); +\end{verbatim} + +These will encode or decode an unsigned \textbf{unsigned long} type (only reads upto 32--bits). For values in the range $0 \dots 2^{32} - 1$ the integer +and short integer functions can encode and decode each others outputs. + +\subsection{ASN.1 BIT STRING} + +\index{der\_encode\_bit\_string()}\index{der\_decode\_bit\_string()}\index{der\_length\_bit\_string()} +\begin{verbatim} +int der_encode_bit_string(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen); + +int der_decode_bit_string(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen); + +int der_length_bit_string(unsigned long nbits, + unsigned long *outlen); +\end{verbatim} + +These will encode or decode a BIT STRING data type. The bits are passed in (or read out) using one \textbf{char} per bit. A non--zero value will be interpreted +as a one bit, and a zero value a zero bit. + +\subsection{ASN.1 OCTET STRING} + +\index{der\_encode\_octet\_string()}\index{der\_decode\_octet\_string()}\index{der\_length\_octet\_string()} +\begin{verbatim} +int der_encode_octet_string(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen); + +int der_decode_octet_string(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen); + +int der_length_octet_string(unsigned long noctets, + unsigned long *outlen); +\end{verbatim} + +These will encode or decode an OCTET STRING data type. The octets are stored using one \textbf{unsigned char} each. + +\subsection{ASN.1 OBJECT IDENTIFIER} + +\index{der\_encode\_object\_identifier()}\index{der\_decode\_object\_identifier()}\index{der\_length\_object\_identifier()} +\begin{verbatim} +int der_encode_object_identifier(unsigned long *words, + unsigned long nwords, + unsigned char *out, + unsigned long *outlen); + +int der_decode_object_identifier(const unsigned char *in, + unsigned long inlen, + unsigned long *words, + unsigned long *outlen); + +int der_length_object_identifier(unsigned long *words, + unsigned long nwords, + unsigned long *outlen); +\end{verbatim} + +These will encode or decode an OBJECT IDENTIFIER object. The words of the OID are stored in individual \textbf{unsigned long} elements, and must be in the range +$0 \ldots 2^{32} - 1$. + +\subsection{ASN.1 IA5 STRING} + +\index{der\_encode\_ia5\_string()}\index{der\_decode\_ia5\_string()}\index{der\_length\_ia5\_string()} +\begin{verbatim} +int der_encode_ia5_string(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen); + +int der_decode_ia5_string(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen); + +int der_length_ia5_string(const unsigned char *octets, + unsigned long noctets, + unsigned long *outlen); +\end{verbatim} + +These will encode or decode an IA5 STRING. The characters are read or stored in individual \textbf{char} elements. These functions performs internal character +to numerical conversions based on the conventions of the compiler being used. For instance, on an x86\_32 machine 'A' == 65 but the same may not be true on +say a SPARC machine. Internally, these functions have a table of literal characters and their numerical ASCII values. This provides a stable conversion provided +that the build platform honours the run--time platforms character conventions. + +\subsection{ASN.1 PRINTABLE STRING} + +\index{der\_encode\_printable\_string()}\index{der\_decode\_printable\_string()}\index{der\_length\_printable\_string()} +\begin{verbatim} +int der_encode_printable_string(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen); + +int der_decode_printable_string(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen); + +int der_length_printable_string(const unsigned char *octets, + unsigned long noctets, + unsigned long *outlen); +\end{verbatim} + +These will encode or decode an PRINTABLE STRING. The characters are read or stored in individual \textbf{char} elements. These functions performs internal character +to numerical conversions based on the conventions of the compiler being used. For instance, on an x86\_32 machine 'A' == 65 but the same may not be true on +say a SPARC machine. Internally, these functions have a table of literal characters and their numerical ASCII values. This provides a stable conversion provided +that the build platform honours the run-time platforms character conventions. + +\subsection{ASN.1 UTF8 STRING} + +\index{der\_encode\_utf8\_string()}\index{der\_decode\_utf8\_string()}\index{der\_length\_utf8\_string()} +\begin{verbatim} +int der_encode_utf8_string(const wchar_t *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen); + +int der_decode_utf8_string(const unsigned char *in, + unsigned long inlen, + wchar_t *out, + unsigned long *outlen); + +int der_length_utf8_string(const wchar_t *octets, + unsigned long noctets, + unsigned long *outlen); +\end{verbatim} + +These will encode or decode an UTF8 STRING. The characters are read or stored in individual \textbf{wchar\_t} elements. These function performs no internal +mapping and treat the characters as literals. + +These functions use the \textbf{wchar\_t} type which is not universally available. In those cases, the library will typedef it to \textbf{unsigned long}. If you +intend to use the ISO C functions for working with wide--char arrays, you should make sure that wchar\_t has been defined previously. + +\subsection{ASN.1 UTCTIME} + +The UTCTIME type is to store a date and time in ASN.1 format. It uses the following structure to organize the time. + +\index{ltc\_utctime structure} +\begin{verbatim} +typedef struct { + unsigned YY, /* year 00--99 */ + MM, /* month 01--12 */ + DD, /* day 01--31 */ + hh, /* hour 00--23 */ + mm, /* minute 00--59 */ + ss, /* second 00--59 */ + off_dir, /* timezone offset direction 0 == +, 1 == - */ + off_hh, /* timezone offset hours */ + off_mm; /* timezone offset minutes */ +} ltc_utctime; +\end{verbatim} + +The time can be offset plus or minus a set amount of hours (off\_hh) and minutes (off\_mm). When \textit{off\_dir} is zero, the time will be added otherwise it +will be subtracted. For instance, the array $\lbrace 5, 6, 20, 22, 4, 00, 0, 5, 0 \rbrace$ represents the current time of +\textit{2005, June 20th, 22:04:00} with a time offset of +05h00. + +\index{der\_encode\_utctime()}\index{der\_decode\_utctime()}\index{der\_length\_utctime()} +\begin{verbatim} +int der_encode_utctime( ltc_utctime *utctime, + unsigned char *out, + unsigned long *outlen); + +int der_decode_utctime(const unsigned char *in, + unsigned long *inlen, + ltc_utctime *out); + +int der_length_utctime( ltc_utctime *utctime, + unsigned long *outlen); +\end{verbatim} + +The encoder will store time in one of the two ASN.1 formats, either \textit{YYMMDDhhmmssZ} or \textit{YYMMDDhhmmss$\pm$hhmm}, and perform minimal error checking on the +input. The decoder will read all valid ASN.1 formats and perform range checking on the values (not complete but rational) useful for catching packet errors. + +It is suggested that decoded data be further scrutinized (e.g. days of month in particular). + +\subsection{ASN.1 CHOICE} + +The CHOICE ASN.1 type represents a union of ASN.1 types all of which are stored in a \textit{ltc\_asn1\_list}. There is no encoder for the CHOICE type, only a +decoder. The decoder will scan through the provided list attempting to use the appropriate decoder on the input packet. The list can contain any ASN.1 data +type\footnote{Except it cannot have LTC\_ASN1\_INTEGER and LTC\_ASN1\_SHORT\_INTEGER simultaneously.} except for other CHOICE types. + +There is no encoder for the CHOICE type as the actual DER encoding is the encoding of the chosen type. + +\index{der\_decode\_choice()} +\begin{verbatim} +int der_decode_choice(const unsigned char *in, + unsigned long *inlen, + ltc_asn1_list *list, + unsigned long outlen); +\end{verbatim} + +This will decode the input in the \textit{in} field of length \textit{inlen}. It uses the provided ASN.1 list specified in the \textit{list} field which has +\textit{outlen} elements. The \textit{inlen} field will be updated with the length of the decoded data type, as well as the respective entry in the \textit{list} field +will have the \textit{used} flag set to non--zero to reflect it was the data type decoded. + +\subsection{ASN.1 Flexi Decoder} +The ASN.1 \textit{flexi} decoder allows the developer to decode arbitrary ASN.1 DER packets (provided they use data types LibTomCrypt supports) without first knowing +the structure of the data. Where der\_decode \_sequence() requires the developer to specify the data types to decode in advance the flexi decoder is entirely +free form. + +The flexi decoder uses the same \textit{ltc\_asn1\_list} but instead of being stored in an array it uses the linked list pointers \textit{prev}, \textit{next}, \textit{parent} +and \textit{child}. The list works as a \textit{doubly-linked list} structure where decoded items at the same level are siblings (using next and prev) and items +encoded in a SEQUENCE are stored as a child element. + +When a SEQUENCE or SET has been encountered a SEQUENCE (or SET resp.) item will be added as a sibling (e.g. list.type == LTC\_ASN1\_SEQUENCE) and the child +pointer points to a new list of items contained within the object. + +\index{der\_decode\_sequence\_flexi()} +\begin{verbatim} +int der_decode_sequence_flexi(const unsigned char *in, + unsigned long *inlen, + ltc_asn1_list **out); +\end{verbatim} + +This will decode items in the \textit{in} buffer of max input length \textit{inlen} and store the newly created pointer to the list in \textit{out}. This function allocates +all required memory for the decoding. It stores the number of octets read back into \textit{inlen}. + +The function will terminate when either it hits an invalid ASN.1 tag, or it reads \textit{inlen} octets. An early termination is a soft error, and returns +normally. The decoded list \textit{out} will point to the very first element of the list (e.g. both parent and prev pointers will be \textbf{NULL}). + +An invalid decoding will terminate the process, and free the allocated memory automatically. + +\textbf{Note:} the list decoded by this function is \textbf{NOT} in the correct form for der\_encode\_sequence() to use directly. You will have to first +have to convert the list by first storing all of the siblings in an array then storing all the children as sub-lists of a sequence using the \textit{.data} +pointer. Currently no function in LibTomCrypt provides this ability. + +\subsubsection{Sample Decoding} +Suppose we decode the following structure: +\begin{small} +\begin{verbatim} +User ::= SEQUENCE { + Name IA5 STRING + LoginToken SEQUENCE { + passwdHash OCTET STRING + pubkey ECCPublicKey + } + LastOn UTCTIME +} +\end{verbatim} +\end{small} +\begin{flushleft}and we decoded it with the following code:\end{flushleft} + +\begin{small} +\begin{verbatim} +unsigned char inbuf[MAXSIZE]; +unsigned long inbuflen; +ltc_asn1_list *list; +int err; + +/* somehow fill inbuf/inbuflen */ +if ((err = der_decode_sequence_flexi(inbuf, inbuflen, &list)) != CRYPT_OK) { + printf("Error decoding: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); +} +\end{verbatim} +\end{small} + +At this point \textit{list} would point to the SEQUENCE identified by \textit{User}. It would have no sibblings (prev or next), and only a child node. Walking to the child +node with the following code will bring us to the \textit{Name} portion of the SEQUENCE: +\begin{small} +\begin{verbatim} +list = list->child; +\end{verbatim} +\end{small} +Now \textit{list} points to the \textit{Name} member (with the tag IA5 STRING). The \textit{data}, \textit{size}, and \textit{type} members of \textit{list} should reflect +that of an IA5 STRING. The sibbling will now be the \textit{LoginToken} SEQUENCE. The sibbling has a child node which points to the \textit{passwdHash} OCTET STRING. +We can walk to this node with the following code: +\begin{small} +\begin{verbatim} +/* list already pointing to 'Name' */ +list = list->next->child; +\end{verbatim} +\end{small} +At this point, \textit{list} will point to the \textit{passwdHash} member of the innermost SEQUENCE. This node has a sibbling, the \textit{pubkey} member of the SEQUENCE. +The \textit{LastOn} member of the SEQUENCE is a sibbling of the LoginToken node, if we wanted to walk there we would have to go up and over via: +\begin{small} +\begin{verbatim} +list = list->parent->next; +\end{verbatim} +\end{small} +At this point, we are pointing to the last node of the list. Lists are terminated in all directions by a \textbf{NULL} pointer. All nodes are doubly linked so that you +can walk up and down the nodes without keeping pointers lying around. + + + + + +\subsubsection{Free'ing a Flexi List} +To free the list use the following function. + +\index{der\_sequence\_free()} +\begin{verbatim} +void der_sequence_free(ltc_asn1_list *in); +\end{verbatim} + +This will free all of the memory allocated by der\_decode\_sequence\_flexi(). + +\mysection{Password Based Cryptography} +\subsection{PKCS \#5} +\index{PKCS \#5} +In order to securely handle user passwords for the purposes of creating session keys and chaining IVs the PKCS \#5 was drafted. PKCS \#5 +is made up of two algorithms, Algorithm One and Algorithm Two. Algorithm One is the older fairly limited algorithm which has been implemented +for completeness. Algorithm Two is a bit more modern and more flexible to work with. + +\subsection{Algorithm One} +Algorithm One accepts as input a password, an 8--byte salt, and an iteration counter. The iteration counter is meant to act as delay for +people trying to brute force guess the password. The higher the iteration counter the longer the delay. This algorithm also requires a hash +algorithm and produces an output no longer than the output of the hash. + +\index{pkcs\_5\_alg1()} +\begin{alltt} +int pkcs_5_alg1(const unsigned char *password, + unsigned long password_len, + const unsigned char *salt, + int iteration_count, + int hash_idx, + unsigned char *out, + unsigned long *outlen) +\end{alltt} +Where \textit{password} is the user's password. Since the algorithm allows binary passwords you must also specify the length in \textit{password\_len}. +The \textit{salt} is a fixed size 8--byte array which should be random for each user and session. The \textit{iteration\_count} is the delay desired +on the password. The \textit{hash\_idx} is the index of the hash you wish to use in the descriptor table. + +The output of length up to \textit{outlen} is stored in \textit{out}. If \textit{outlen} is initially larger than the size of the hash functions output +it is set to the number of bytes stored. If it is smaller than not all of the hash output is stored in \textit{out}. + +\subsection{Algorithm Two} + +Algorithm Two is the recommended algorithm for this task. It allows variable length salts, and can produce outputs larger than the +hash functions output. As such, it can easily be used to derive session keys for ciphers and MACs as well initial vectors as required +from a single password and invocation of this algorithm. + +\index{pkcs\_5\_alg2()} +\begin{alltt} +int pkcs_5_alg2(const unsigned char *password, + unsigned long password_len, + const unsigned char *salt, + unsigned long salt_len, + int iteration_count, + int hash_idx, + unsigned char *out, + unsigned long *outlen) +\end{alltt} +Where \textit{password} is the users password. Since the algorithm allows binary passwords you must also specify the length in \textit{password\_len}. +The \textit{salt} is an array of size \textit{salt\_len}. It should be random for each user and session. The \textit{iteration\_count} is the delay desired +on the password. The \textit{hash\_idx} is the index of the hash you wish to use in the descriptor table. The output of length up to +\textit{outlen} is stored in \textit{out}. + +\begin{verbatim} +/* demo to show how to make session state material + * from a password */ +#include +int main(void) +{ + unsigned char password[100], salt[100], + cipher_key[16], cipher_iv[16], + mac_key[16], outbuf[48]; + int err, hash_idx; + unsigned long outlen, password_len, salt_len; + + /* register hash and get it's idx .... */ + + /* get users password and make up a salt ... */ + + /* create the material (100 iterations in algorithm) */ + outlen = sizeof(outbuf); + if ((err = pkcs_5_alg2(password, password_len, salt, + salt_len, 100, hash_idx, outbuf, + &outlen)) + != CRYPT_OK) { + /* error handle */ + } + + /* now extract it */ + memcpy(cipher_key, outbuf, 16); + memcpy(cipher_iv, outbuf+16, 16); + memcpy(mac_key, outbuf+32, 16); + + /* use material (recall to store the salt in the output) */ +} +\end{verbatim} + +\chapter{Miscellaneous} +\mysection{Base64 Encoding and Decoding} +The library provides functions to encode and decode a RFC 1521 base--64 coding scheme. The characters used in the mappings are: +\begin{verbatim} +ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ +\end{verbatim} +Those characters are supported in the 7-bit ASCII map, which means they can be used for transport over +common e-mail, usenet and HTTP mediums. The format of an encoded stream is just a literal sequence of ASCII characters +where a group of four represent 24-bits of input. The first four chars of the encoders output is the length of the +original input. After the first four characters is the rest of the message. + +Often, it is desirable to line wrap the output to fit nicely in an e-mail or usenet posting. The decoder allows you to +put any character (that is not in the above sequence) in between any character of the encoders output. You may not however, +break up the first four characters. + +To encode a binary string in base64 call: +\index{base64\_encode()} \index{base64\_decode()} +\begin{verbatim} +int base64_encode(const unsigned char *in, + unsigned long len, + unsigned char *out, + unsigned long *outlen); +\end{verbatim} +Where \textit{in} is the binary string and \textit{out} is where the ASCII output is placed. You must set the value of \textit{outlen} prior +to calling this function and it sets the length of the base64 output in \textit{outlen} when it is done. To decode a base64 +string call: +\begin{verbatim} +int base64_decode(const unsigned char *in, + unsigned long len, + unsigned char *out, + unsigned long *outlen); +\end{verbatim} + +\mysection{Primality Testing} +\index{Primality Testing} +The library includes primality testing and random prime functions as well. The primality tester will perform the test in +two phases. First it will perform trial division by the first few primes. Second it will perform eight rounds of the +Rabin-Miller primality testing algorithm. If the candidate passes both phases it is declared prime otherwise it is declared +composite. No prime number will fail the two phases but composites can. Each round of the Rabin-Miller algorithm reduces +the probability of a pseudo-prime by $1 \over 4$ therefore after sixteen rounds the probability is no more than +$\left ( { 1 \over 4 } \right )^{8} = 2^{-16}$. In practice the probability of error is in fact much lower than that. + +When making random primes the trial division step is in fact an optimized implementation of \textit{Implementation of Fast RSA Key Generation on Smart Cards}\footnote{Chenghuai Lu, Andre L. M. dos Santos and Francisco R. Pimentel}. +In essence a table of machine-word sized residues are kept of a candidate modulo a set of primes. When the candidate +is rejected and ultimately incremented to test the next number the residues are updated without using multi-word precision +math operations. As a result the routine can scan ahead to the next number required for testing with very little work +involved. + +In the event that a composite did make it through it would most likely cause the the algorithm trying to use it to fail. For +instance, in RSA two primes $p$ and $q$ are required. The order of the multiplicative sub-group (modulo $pq$) is given +as $\phi(pq)$ or $(p - 1)(q - 1)$. The decryption exponent $d$ is found as $de \equiv 1\mbox{ }(\mbox{mod } \phi(pq))$. If either $p$ or $q$ is composite the value of $d$ will be incorrect and the user +will not be able to sign or decrypt messages at all. Suppose $p$ was prime and $q$ was composite this is just a variation of +the multi-prime RSA. Suppose $q = rs$ for two primes $r$ and $s$ then $\phi(pq) = (p - 1)(r - 1)(s - 1)$ which clearly is +not equal to $(p - 1)(rs - 1)$. + +These are not technically part of the LibTomMath library but this is the best place to document them. +To test if a \textit{mp\_int} is prime call: +\begin{verbatim} +int is_prime(mp_int *N, int *result); +\end{verbatim} +This puts a one in \textit{result} if the number is probably prime, otherwise it places a zero in it. It is assumed that if +it returns an error that the value in \textit{result} is undefined. To make +a random prime call: +\begin{verbatim} +int rand_prime( mp_int *N, + unsigned long len, + prng_state *prng, + int wprng); +\end{verbatim} +Where \textit{len} is the size of the prime in bytes ($2 \le len \le 256$). You can set \textit{len} to the negative size you want +to get a prime of the form $p \equiv 3\mbox{ }(\mbox{mod } 4)$. So if you want a 1024-bit prime of this sort pass +\textit{len = -128} to the function. Upon success it will return {\bf CRYPT\_OK} and \textit{N} will contain an integer which +is very likely prime. + +\chapter{Programming Guidelines} + +\mysection{Secure Pseudo Random Number Generators} +Probably the single most vulnerable point of any cryptosystem is the PRNG. Without one, generating and protecting secrets +would be impossible. The requirement that one be setup correctly is vitally important, and to address this point the library +does provide two RNG sources that will address the largest amount of end users as possible. The \textit{sprng} PRNG provides an easy to +access source of entropy for any application on a UNIX (and the like) or Windows computer. + +However, when the end user is not on one of these platforms, the application developer must address the issue of finding +entropy. This manual is not designed to be a text on cryptography. I would just like to highlight that when you design +a cryptosystem make sure the first problem you solve is getting a fresh source of entropy. + +\mysection{Preventing Trivial Errors} +Two simple ways to prevent trivial errors is to prevent overflows, and to check the return values. All of the functions +which output variable length strings will require you to pass the length of the destination. If the size of your output +buffer is smaller than the output it will report an error. Therefore, make sure the size you pass is correct! + +Also, virtually all of the functions return an error code or {\bf CRYPT\_OK}. You should detect all errors, as simple +typos can cause algorithms to fail to work as desired. + +\mysection{Registering Your Algorithms} +To avoid linking and other run--time errors it is important to register the ciphers, hashes and PRNGs you intend to use +before you try to use them. This includes any function which would use an algorithm indirectly through a descriptor table. + +A neat bonus to the registry system is that you can add external algorithms that are not part of the library without +having to hack the library. For example, suppose you have a hardware specific PRNG on your system. You could easily +write the few functions required plus a descriptor. After registering your PRNG, all of the library functions that +need a PRNG can instantly take advantage of it. The same applies for ciphers, hashes, and bignum math routines. + +\mysection{Key Sizes} + +\subsection{Symmetric Ciphers} +For symmetric ciphers, use as large as of a key as possible. For the most part \textit{bits are cheap} so using a 256--bit key +is not a hard thing to do. As a good rule of thumb do not use a key smaller than 128 bits. + +\subsection{Asymmetric Ciphers} +The following chart gives the work factor for solving a DH/RSA public key using the NFS. The work factor for a key of order +$n$ is estimated to be +\begin{equation} +e^{1.923 \cdot ln(n)^{1 \over 3} \cdot ln(ln(n))^{2 \over 3}} +\end{equation} + +Note that $n$ is not the bit-length but the magnitude. For example, for a 1024-bit key $n = 2^{1024}$. The work required +is: +\begin{figure}[here] +\begin{center} +\begin{tabular}{|c|c|} + \hline RSA/DH Key Size (bits) & Work Factor ($log_2$) \\ + \hline 512 & 63.92 \\ + \hline 768 & 76.50 \\ + \hline 1024 & 86.76 \\ + \hline 1536 & 103.37 \\ + \hline 2048 & 116.88 \\ + \hline 2560 & 128.47 \\ + \hline 3072 & 138.73 \\ + \hline 4096 & 156.49 \\ + \hline +\end{tabular} +\end{center} +\caption{RSA/DH Key Strength} +\end{figure} + +The work factor for ECC keys is much higher since the best attack is still fully exponential. Given a key of magnitude +$n$ it requires $\sqrt n$ work. The following table summarizes the work required: +\begin{figure}[here] +\begin{center} +\begin{tabular}{|c|c|} + \hline ECC Key Size (bits) & Work Factor ($log_2$) \\ + \hline 112 & 56 \\ + \hline 128 & 64 \\ + \hline 160 & 80 \\ + \hline 192 & 96 \\ + \hline 224 & 112 \\ + \hline 256 & 128 \\ + \hline 384 & 192 \\ + \hline 521 & 260.5 \\ + \hline +\end{tabular} +\end{center} +\caption{ECC Key Strength} +\end{figure} + +Using the above tables the following suggestions for key sizes seems appropriate: +\begin{center} +\begin{tabular}{|c|c|c|} + \hline Security Goal & RSA/DH Key Size (bits) & ECC Key Size (bits) \\ + \hline Near term & 1024 & 160 \\ + \hline Short term & 1536 & 192 \\ + \hline Long Term & 2560 & 384 \\ + \hline +\end{tabular} +\end{center} + +\mysection{Thread Safety} +The library is not fully thread safe but several simple precautions can be taken to avoid any problems. The registry functions +such as register\_cipher() are not thread safe no matter what you do. It is best to call them from your programs initialization +code before threads are initiated. + +The rest of the code uses state variables you must pass it such as hash\_state, hmac\_state, etc. This means that if each +thread has its own state variables then they will not affect each other, and are fully thread safe. This is fairly simple with symmetric ciphers +and hashes. + +\index{LTC\_PTHREAD} +The only sticky issue is a shared PRNG which can be alleviated with the careful use of mutex devices. Defining LTC\_PTHREAD for instance, enables +pthreads based mutex locking in various routines such as the Yarrow and Fortuna PRNGs, the fixed point ECC multiplier, and other routines. + +\chapter{Configuring and Building the Library} +\mysection{Introduction} +The library is fairly flexible about how it can be built, used, and generally distributed. Additions are being made with +each new release that will make the library even more flexible. Each of the classes of functions can be disabled during +the build process to make a smaller library. This is particularly useful for shared libraries. + +As of v1.06 of the library, the build process has been moved to two steps for the typical LibTomCrypt application. This is because +LibTomCrypt no longer provides a math API on its own and relies on third party libraries (such as LibTomMath, GnuMP, or TomsFastMath). + +The build process now consists of installing a math library first, and then building and installing LibTomCrypt with a math library +configured. Note that LibTomCrypt can be built with no internal math descriptors. This means that one must be provided at either +build, or run time for the application. LibTomCrypt comes with three math descriptors that provide a standard interface to math +libraries. + +\mysection{Makefile variables} + +All GNU driven makefiles (including the makefile for ICC) use a set of common variables to control the build and install process. Most of the +settings can be overwritten from the command line which makes custom installation a breeze. + +\index{MAKE}\index{CC}\index{AR} +\subsection{MAKE, CC and AR} +The MAKE, CC and AR flags can all be overwritten. They default to \textit{make}, \textit{\$CC} and \textit{\$AR} respectively. +Changing MAKE allows you to change what program will be invoked to handle sub--directories. For example, this + +\begin{verbatim} +MAKE=gmake gmake install +\end{verbatim} + +\begin{flushleft} will build and install the libraries with the \textit{gmake} tool. Similarly, \end{flushleft} + +\begin{verbatim} +CC=arm-gcc AR=arm-ar make +\end{verbatim} + +\begin{flushleft} will build the library using \textit{arm--gcc} as the compiler and \textit{arm--ar} as the archiver. \end{flushleft} + +\subsection{IGNORE\_SPEED} +\index{IGNORE\_SPEED} +When \textbf{IGNORE\_SPEED} has been defined the default optimization flags for CFLAGS will be disabled which allows the developer to specify new +CFLAGS on the command line. E.g. to add debugging + +\begin{verbatim} +CFLAGS="-g3" make IGNORE_SPEED=1 +\end{verbatim} + +This will turn off optimizations and add \textit{-g3} to the CFLAGS which enables debugging. + +\subsection{LIBNAME and LIBNAME\_S} +\index{LIBNAME} \index{LIBNAME\_S} +\textbf{LIBNAME} is the name of the output library (archive) to create. It defaults to \textit{libtomcrypt.a} for static builds and \textit{libtomcrypt.la} for +shared. The \textbf{LIBNAME\_S} variable is the static name while doing shared builds. Ideally they should have the same prefix but don't have to. + +\index{LIBTEST} \index{LIBTEST\_S} +Similarly \textbf{LIBTEST} and \textbf{LIBTEST\_S} are the names for the profiling and testing library. The default is \textit{libtomcrypt\_prof.a} for +static and \textit{libtomcrypt\_prof.la} for shared. + +\subsection{Installation Directories} +\index{DESTDIR} \index{LIBPATH} \index{INCPATH} \index{DATADIR} +\textbf{DESTDIR} is the prefix for the installation directories. It defaults to an empty string. \textbf{LIBPATH} is the prefix for the library +directory which defaults to \textit{/usr/lib}. \textbf{INCPATH} is the prefix for the header file directory which defaults to \textit{/usr/include}. +\textbf{DATADIR} is the prefix for the data (documentation) directory which defaults to \textit{/usr/share/doc/libtomcrypt/pdf}. + +All four can be used to create custom install locations depending on the nature of the OS and file system in use. + +\begin{verbatim} +make LIBPATH=/home/tom/project/lib INCPATH=/home/tom/project/include \ + DATAPATH=/home/tom/project/docs install +\end{verbatim} + +This will build the library and install it to the directories under \textit{/home/tom/project/}. e.g. + +\begin{small} +\begin{verbatim} +/home/tom/project/: +total 1 +drwxr-xr-x 2 tom users 80 Jul 30 16:02 docs +drwxr-xr-x 2 tom users 528 Jul 30 16:02 include +drwxr-xr-x 2 tom users 80 Jul 30 16:02 lib + +/home/tom/project/docs: +total 452 +-rwxr-xr-x 1 tom users 459009 Jul 30 16:02 crypt.pdf + +/home/tom/project/include: +total 132 +-rwxr-xr-x 1 tom users 2482 Jul 30 16:02 tomcrypt.h +-rwxr-xr-x 1 tom users 702 Jul 30 16:02 tomcrypt_argchk.h +-rwxr-xr-x 1 tom users 2945 Jul 30 16:02 tomcrypt_cfg.h +-rwxr-xr-x 1 tom users 22763 Jul 30 16:02 tomcrypt_cipher.h +-rwxr-xr-x 1 tom users 5174 Jul 30 16:02 tomcrypt_custom.h +-rwxr-xr-x 1 tom users 11314 Jul 30 16:02 tomcrypt_hash.h +-rwxr-xr-x 1 tom users 11571 Jul 30 16:02 tomcrypt_mac.h +-rwxr-xr-x 1 tom users 13614 Jul 30 16:02 tomcrypt_macros.h +-rwxr-xr-x 1 tom users 14714 Jul 30 16:02 tomcrypt_math.h +-rwxr-xr-x 1 tom users 632 Jul 30 16:02 tomcrypt_misc.h +-rwxr-xr-x 1 tom users 10934 Jul 30 16:02 tomcrypt_pk.h +-rwxr-xr-x 1 tom users 2634 Jul 30 16:02 tomcrypt_pkcs.h +-rwxr-xr-x 1 tom users 7067 Jul 30 16:02 tomcrypt_prng.h +-rwxr-xr-x 1 tom users 1467 Jul 30 16:02 tomcrypt_test.h + +/home/tom/project/lib: +total 1073 +-rwxr-xr-x 1 tom users 1096284 Jul 30 16:02 libtomcrypt.a +\end{verbatim} +\end{small} + +\mysection{Extra libraries} +\index{EXTRALIBS} +\textbf{EXTRALIBS} specifies any extra libraries required to link the test programs and shared libraries. They are specified in the notation +that GCC expects for global archives. + +\begin{verbatim} +CFLAGS="-DTFM_DESC -DUSE_TFM" EXTRALIBS=-ltfm make install \ + test timing +\end{verbatim} + +This will install the library using the TomsFastMath library and link the \textit{libtfm.a} library out of the default library search path. The two +defines are explained below. You can specify multiple archives (say if you want to support two math libraries, or add on additional code) to +the \textbf{EXTRALIBS} variable by separating them by a space. + +Note that \textbf{EXTRALIBS} is not required if you are only making and installing the static library but none of the test programs. + +\mysection{Building a Static Library} + +Building a static library is fairly trivial as it only requires one invocation of the GNU make command. + +\begin{verbatim} +CFLAGS="-DTFM_DESC" make install +\end{verbatim} + +That will build LibTomCrypt (including the TomsFastMath descriptor), and install it in the default locations indicated previously. You can enable +the built--in LibTomMath descriptor as well (or in place of the TomsFastMath descriptor). Similarly, you can build the library with no built--in +math descriptors. + +\begin{verbatim} +make install +\end{verbatim} + +In this case, no math descriptors are present in the library and they will have to be made available at build or run time before you can use any of the +public key functions. + +Note that even if you include the built--in descriptors you must link against the source library as well. + +\begin{verbatim} +gcc -DTFM_DESC myprogram.c -ltomcrypt -ltfm -o myprogram +\end{verbatim} + +This will compile \textit{myprogram} and link it against the LibTomCrypt library as well as TomsFastMath (which must have been previously installed). Note that +we define \textbf{TFM\_DESC} for compilation. This is so that the TFM descriptor symbol will be defined for the client application to make use of without +giving warnings. + +\mysection{Building a Shared Library} + +LibTomCrypt can also be built as a shared library through the \textit{makefile.shared} make script. It is similar to use as the static script except +that you \textbf{must} specify the \textbf{EXTRALIBS} variable at install time. + +\begin{verbatim} +CFLAGS="-DTFM_DESC" EXTRALIBS=-ltfm make -f makefile.shared install +\end{verbatim} + +This will build and install the library and link the shared object against the TomsFastMath library (which must be installed as a shared object as well). The +shared build process requires libtool to be installed. + +\mysection{Header Configuration} +The file \textit{tomcrypt\_cfg.h} is what lets you control various high level macros which control the behaviour of the library. Build options are also +stored in \textit{tomcrypt\_custom.h} which allow the enabling and disabling of various algorithms. + +\subsubsection{ARGTYPE} +This lets you control how the LTC\_ARGCHK macro will behave. The macro is used to check pointers inside the functions against +NULL. There are four settings for ARGTYPE. When set to 0, it will have the default behaviour of printing a message to +stderr and raising a SIGABRT signal. This is provided so all platforms that use LibTomCrypt can have an error that functions +similarly. When set to 1, it will simply pass on to the assert() macro. When set to 2, the macro will display the error to +stderr then return execution to the caller. This could lead to a segmentation fault (e.g. when a pointer is \textbf{NULL}) but is useful +if you handle signals on your own. When set to 3, it will resolve to a empty macro and no error checking will be performed. Finally, when set +to 4, it will return CRYPT\_INVALID\_ARG to the caller. + +\subsubsection{Endianess} +There are five macros related to endianess issues. For little endian platforms define, \textbf{ENDIAN\_LITTLE}. For big endian +platforms define \textbf{ENDIAN\_BIG}. Similarly when the default word size of an \textit{unsigned long} is 32-bits define \textbf{ENDIAN\_32BITWORD} +or define \textbf{ENDIAN\_64BITWORD} when its 64-bits. If you do not define any of them the library will automatically use \textbf{ENDIAN\_NEUTRAL} +which will work on all platforms. + +Currently LibTomCrypt will detect x86-32, x86-64, MIPS R5900, SPARC and SPARC64 running GCC as well as x86-32 running MSVC. + +\mysection{The Configure Script} +There are also options you can specify from the \textit{tomcrypt\_custom.h} header file. + +\subsection{X memory routines} +\index{XMALLOC}\index{XCALLOC}\index{XREALLOC}\index{XFREE} +At the top of tomcrypt\_custom.h are a series of macros denoted as XMALLOC, XCALLOC, XREALLOC, XFREE, and so on. They resolve to +the name of the respective functions from the standard C library by default. This lets you substitute in your own memory routines. +If you substitute in your own functions they must behave like the standard C library functions in terms of what they expect as input and +output. + +These macros are handy for working with platforms which do not have a standard C library. For instance, the OLPC\footnote{See http://dev.laptop.org/git?p=bios-crypto;a=summary} +bios code uses these macros to redirect to very compact heap and string operations. + +\subsection{X clock routines} +The rng\_get\_bytes() function can call a function that requires the clock() function. These macros let you override +the default clock() used with a replacement. By default the standard C library clock() function is used. + +\subsection{LTC\_NO\_FILE} +During the build if LTC\_NO\_FILE is defined then any function in the library that uses file I/O will not call the file I/O +functions and instead simply return CRYPT\_NOP. This should help resolve any linker errors stemming from a lack of +file I/O on embedded platforms. + +\subsection{LTC\_CLEAN\_STACK} +When this functions is defined the functions that store key material on the stack will clean up afterwards. +Assumes that you have no memory paging with the stack. + +\subsection{LTC\_TEST} +When this has been defined the various self--test functions (for ciphers, hashes, prngs, etc) are included in the build. This is the default configuration. +If LTC\_NO\_TEST has been defined, the testing routines will be compacted and only return CRYPT\_NOP. + +\subsection{LTC\_NO\_FAST} +When this has been defined the library will not use faster word oriented operations. By default, they are only enabled for platforms +which can be auto-detected. This macro ensures that they are never enabled. + +\subsection{LTC\_FAST} +This mode (auto-detected with x86\_32,x86\_64 platforms with GCC or MSVC) configures various routines such as ctr\_encrypt() or +cbc\_encrypt() that it can safely XOR multiple octets in one step by using a larger data type. This has the benefit of +cutting down the overhead of the respective functions. + +This mode does have one downside. It can cause unaligned reads from memory if you are not careful with the functions. This is why +it has been enabled by default only for the x86 class of processors where unaligned accesses are allowed. Technically LTC\_FAST +is not \textit{portable} since unaligned accesses are not covered by the ISO C specifications. + +In practice however, you can use it on pretty much any platform (even MIPS) with care. + +By design the \textit{fast} mode functions won't get unaligned on their own. For instance, if you call ctr\_encrypt() right after calling +ctr\_start() and all the inputs you gave are aligned than ctr\_encrypt() will perform aligned memory operations only. However, if you +call ctr\_encrypt() with an odd amount of plaintext then call it again the CTR pad (the IV) will be partially used. This will +cause the ctr routine to first use up the remaining pad bytes. Then if there are enough plaintext bytes left it will use +whole word XOR operations. These operations will be unaligned. + +The simplest precaution is to make sure you process all data in power of two blocks and handle \textit{remainder} at the end. e.g. If you are +CTR'ing a long stream process it in blocks of (say) four kilobytes and handle any remaining incomplete blocks at the end of the stream. + +\index{LTC\_FAST\_TYPE} +If you do plan on using the \textit{LTC\_FAST} mode you have to also define a \textit{LTC\_FAST\_TYPE} macro which resolves to an optimal sized +data type you can perform integer operations with. Ideally it should be four or eight bytes since it must properly divide the size +of your block cipher (e.g. 16 bytes for AES). This means sadly if you're on a platform with 57--bit words (or something) you can't +use this mode. So sad. + +\subsection{LTC\_NO\_ASM} +When this has been defined the library will not use any inline assembler. Only a few platforms support assembler inlines but various versions of ICC and GCC +cannot handle all of the assembler functions. + +\subsection{Symmetric Ciphers, One-way Hashes, PRNGS and Public Key Functions} +There are a plethora of macros for the ciphers, hashes, PRNGs and public key functions which are fairly +self-explanatory. When they are defined the functionality is included otherwise it is not. There are some +dependency issues which are noted in the file. For instance, Yarrow requires CTR chaining mode, a block +cipher and a hash function. + +Also see technical note number five for more details. + +\subsection{LTC\_EASY} +When defined the library is configured to build fewer algorithms and modes. Mostly it sticks to NIST and ANSI approved algorithms. See +the header file \textit{tomcrypt\_custom.h} for more details. It is meant to provide literally an easy method of trimming the library +build to the most minimum of useful functionality. + +\subsection{TWOFISH\_SMALL and TWOFISH\_TABLES} +Twofish is a 128-bit symmetric block cipher that is provided within the library. The cipher itself is flexible enough +to allow some trade-offs in the implementation. When TWOFISH\_SMALL is defined the scheduled symmetric key for Twofish +requires only 200 bytes of memory. This is achieved by not pre-computing the substitution boxes. Having this +defined will also greatly slow down the cipher. When this macro is not defined Twofish will pre-compute the +tables at a cost of 4KB of memory. The cipher will be much faster as a result. + +When TWOFISH\_TABLES is defined the cipher will use pre-computed (and fixed in code) tables required to work. This is +useful when TWOFISH\_SMALL is defined as the table values are computed on the fly. When this is defined the code size +will increase by approximately 500 bytes. If this is defined but TWOFISH\_SMALL is not the cipher will still work but +it will not speed up the encryption or decryption functions. + +\subsection{GCM\_TABLES} +When defined GCM will use a 64KB table (per GCM state) which will greatly speed up the per--packet latency. +It also increases the initialization time and is not suitable when you are going to use a key a few times only. + +\subsection{GCM\_TABLES\_SSE2} +\index{SSE2} +When defined GCM will use the SSE2 instructions to perform the $GF(2^x)$ multiply using 16 128--bit XOR operations. It shaves a few cycles per byte +of GCM output on both the AMD64 and Intel Pentium 4 platforms. Requires GCC and an SSE2 equipped platform. + +\subsection{LTC\_SMALL\_CODE} +When this is defined some of the code such as the Rijndael and SAFER+ ciphers are replaced with smaller code variants. +These variants are slower but can save quite a bit of code space. + +\subsection{LTC\_PTHREAD} +When this is activated all of the descriptor table functions will use pthread locking to ensure thread safe updates to the tables. Note that +it doesn't prevent a thread that is passively using a table from being messed up by another thread that updates the table. + +Generally the rule of thumb is to setup the tables once at startup and then leave them be. This added build flag simply makes updating +the tables safer. + +\subsection{LTC\_ECC\_TIMING\_RESISTANT} +When this has been defined the ECC point multiplier (built--in to the library) will use a timing resistant point multiplication +algorithm which prevents leaking key bits of the private key (scalar). It is a slower algorithm but useful for situations +where timing side channels pose a significant threat. + +\subsection{Math Descriptors} +The library comes with three math descriptors that allow you to interface the public key cryptography API to freely available math +libraries. When \textbf{GMP\_DESC}, \textbf{LTM\_DESC}, or \textbf{TFM\_DESC} are defined +descriptors for the respective library are built and included in the library as \textit{gmp\_desc}, \textit{ltm\_desc}, or \textit{tfm\_desc} respectively. + +In the test demos that use the libraries the additional flags \textbf{USE\_GMP}, \textbf{USE\_LTM}, and \textbf{USE\_TFM} can be defined +to tell the program which library to use. Only one of the USE flags can be defined at once. + +\index{GMP\_DESC} \index{USE\_GMP} \index{LTM\_DESC} \index{TFM\_DESC} \index{USE\_LTM} \index{USE\_TFM} +\begin{small} +\begin{verbatim} +CFLAGS="-DGMP_DESC -DLTM_DESC -DTFM_DESC -DUSE_TFM" \ +EXTRALIBS="-lgmp -ltommath -ltfm" make -f makefile.shared install timing +\end{verbatim} +\end{small} + +That will build and install the library with all descriptors (and link against all), but only use TomsFastMath in the timing demo. + +\chapter{Optimizations} +\mysection{Introduction} +The entire API was designed with plug and play in mind at the low level. That is you can swap out any cipher, hash, PRNG or bignum library and the dependent API will not +require updating. This has the nice benefit that one can add ciphers (etc.) not have to re--write portions of the API. For the most part, LibTomCrypt has also been written +to be highly portable and easy to build out of the box on pretty much any platform. As such there are no assembler inlines throughout the code, I make no assumptions +about the platform, etc... + +That works well for most cases but there are times where performance is of the essence. This API allows optimized routines to be dropped in--place of the existing +portable routines. For instance, hand optimized assembler versions of AES could be provided. Any existing function that uses the cipher could automatically use +the optimized code without re--writing. This also paves the way for hardware drivers that can access hardware accelerated cryptographic devices. + +At the heart of this flexibility is the \textit{descriptor} system. A descriptor is essentially just a C \textit{struct} which describes the algorithm and provides pointers +to functions that do the required work. For a given class of operation (e.g. cipher, hash, prng, bignum) the functions of a descriptor have identical prototypes which makes +development simple. In most dependent routines all an end developer has to do is register\_XXX() the descriptor and they are set. + +\mysection{Ciphers} +The ciphers in LibTomCrypt are accessed through the ltc\_cipher\_descriptor structure. + +\label{sec:cipherdesc} +\begin{small} +\begin{verbatim} +struct ltc_cipher_descriptor { + /** name of cipher */ + char *name; + + /** internal ID */ + unsigned char ID; + + /** min keysize (octets) */ + int min_key_length, + + /** max keysize (octets) */ + max_key_length, + + /** block size (octets) */ + block_length, + + /** default number of rounds */ + default_rounds; + + /** Setup the cipher + @param key The input symmetric key + @param keylen The length of the input key (octets) + @param num_rounds The requested number of rounds (0==default) + @param skey [out] The destination of the scheduled key + @return CRYPT_OK if successful + */ + int (*setup)(const unsigned char *key, + int keylen, + int num_rounds, + symmetric_key *skey); + + /** Encrypt a block + @param pt The plaintext + @param ct [out] The ciphertext + @param skey The scheduled key + @return CRYPT_OK if successful + */ + int (*ecb_encrypt)(const unsigned char *pt, + unsigned char *ct, + symmetric_key *skey); + + /** Decrypt a block + @param ct The ciphertext + @param pt [out] The plaintext + @param skey The scheduled key + @return CRYPT_OK if successful + */ + int (*ecb_decrypt)(const unsigned char *ct, + unsigned char *pt, + symmetric_key *skey); + + /** Test the block cipher + @return CRYPT_OK if successful, + CRYPT_NOP if self-testing has been disabled + */ + int (*test)(void); + + /** Terminate the context + @param skey The scheduled key + */ + void (*done)(symmetric_key *skey); + + /** Determine a key size + @param keysize [in/out] The size of the key desired + The suggested size + @return CRYPT_OK if successful + */ + int (*keysize)(int *keysize); + +/** Accelerators **/ + /** Accelerated ECB encryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_ecb_encrypt)(const unsigned char *pt, + unsigned char *ct, + unsigned long blocks, + symmetric_key *skey); + + /** Accelerated ECB decryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_ecb_decrypt)(const unsigned char *ct, + unsigned char *pt, + unsigned long blocks, + symmetric_key *skey); + + /** Accelerated CBC encryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_cbc_encrypt)(const unsigned char *pt, + unsigned char *ct, + unsigned long blocks, + unsigned char *IV, + symmetric_key *skey); + + /** Accelerated CBC decryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_cbc_decrypt)(const unsigned char *ct, + unsigned char *pt, + unsigned long blocks, + unsigned char *IV, + symmetric_key *skey); + + /** Accelerated CTR encryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param mode little or big endian counter (mode=0 or mode=1) + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_ctr_encrypt)(const unsigned char *pt, + unsigned char *ct, + unsigned long blocks, + unsigned char *IV, + int mode, + symmetric_key *skey); + + /** Accelerated LRW + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param tweak The LRW tweak + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_lrw_encrypt)(const unsigned char *pt, + unsigned char *ct, + unsigned long blocks, + unsigned char *IV, + const unsigned char *tweak, + symmetric_key *skey); + + /** Accelerated LRW + @param ct Ciphertext + @param pt Plaintext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param tweak The LRW tweak + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_lrw_decrypt)(const unsigned char *ct, + unsigned char *pt, + unsigned long blocks, + unsigned char *IV, + const unsigned char *tweak, + symmetric_key *skey); + + /** Accelerated CCM packet (one-shot) + @param key The secret key to use + @param keylen The length of the secret key (octets) + @param uskey A previously scheduled key [can be NULL] + @param nonce The session nonce [use once] + @param noncelen The length of the nonce + @param header The header for the session + @param headerlen The length of the header (octets) + @param pt [out] The plaintext + @param ptlen The length of the plaintext (octets) + @param ct [out] The ciphertext + @param tag [out] The destination tag + @param taglen [in/out] The max size and resulting size + of the authentication tag + @param direction Encrypt or Decrypt direction (0 or 1) + @return CRYPT_OK if successful + */ + int (*accel_ccm_memory)( + const unsigned char *key, unsigned long keylen, + symmetric_key *uskey, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); + + /** Accelerated GCM packet (one shot) + @param key The secret key + @param keylen The length of the secret key + @param IV The initial vector + @param IVlen The length of the initial vector + @param adata The additional authentication data (header) + @param adatalen The length of the adata + @param pt The plaintext + @param ptlen The length of the plaintext/ciphertext + @param ct The ciphertext + @param tag [out] The MAC tag + @param taglen [in/out] The MAC tag length + @param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT) + @return CRYPT_OK on success + */ + int (*accel_gcm_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *IV, unsigned long IVlen, + const unsigned char *adata, unsigned long adatalen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); + + /** Accelerated one shot OMAC + @param key The secret key + @param keylen The key length (octets) + @param in The message + @param inlen Length of message (octets) + @param out [out] Destination for tag + @param outlen [in/out] Initial and final size of out + @return CRYPT_OK on success + */ + int (*omac_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + + /** Accelerated one shot XCBC + @param key The secret key + @param keylen The key length (octets) + @param in The message + @param inlen Length of message (octets) + @param out [out] Destination for tag + @param outlen [in/out] Initial and final size of out + @return CRYPT_OK on success + */ + int (*xcbc_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + + /** Accelerated one shot F9 + @param key The secret key + @param keylen The key length (octets) + @param in The message + @param inlen Length of message (octets) + @param out [out] Destination for tag + @param outlen [in/out] Initial and final size of out + @return CRYPT_OK on success + @remark Requires manual padding + */ + int (*f9_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +}; +\end{verbatim} +\end{small} + +\subsection{Name} +\index{find\_cipher()} +The \textit{name} parameter specifies the name of the cipher. This is what a developer would pass to find\_cipher() to find the cipher in the descriptor +tables. + +\subsection{Internal ID} +This is a single byte Internal ID you can use to distinguish ciphers from each other. + +\subsection{Key Lengths} +The minimum key length is \textit{min\_key\_length} and is measured in octets. Similarly the maximum key length is \textit{max\_key\_length}. They can be equal +and both must valid key sizes for the cipher. Values in between are not assumed to be valid though they may be. + +\subsection{Block Length} +The size of the ciphers plaintext or ciphertext is \textit{block\_length} and is measured in octets. + +\subsection{Rounds} +Some ciphers allow different number of rounds to be used. Usually you just use the default. The default round count is \textit{default\_rounds}. + +\subsection{Setup} +To initialize a cipher (for ECB mode) the function setup() was provided. It accepts an array of key octets \textit{key} of length \textit{keylen} octets. The user +can specify the number of rounds they want through \textit{num\_rounds} where $num\_rounds = 0$ means use the default. The destination of a scheduled key is stored +in \textit{skey}. + +Inside the \textit{symmetric\_key} union there is a \textit{void *data} which you can use to allocate data if you need a data structure that does not fit with the existing +ones provided. Just make sure in your \textit{done()} function that you free the allocated memory. + +\subsection{Single block ECB} +To process a single block in ECB mode the ecb\_encrypt() and ecb\_decrypt() functions were provided. The plaintext and ciphertext buffers are allowed to overlap so you +must make sure you do not overwrite the output before you are finished with the input. + +\subsection{Testing} +The test() function is used to self--test the \textit{device}. It takes no arguments and returns \textbf{CRYPT\_OK} if all is working properly. You may return +\textbf{CRYPT\_NOP} to indicate that no testing was performed. + +\subsection{Key Sizing} +Occasionally, a function will want to find a suitable key size to use since the input is oddly sized. The keysize() function is for this case. It accepts a +pointer to an integer which represents the desired size. The function then has to match it to the exact or a lower key size that is valid for the cipher. For +example, if the input is $25$ and $24$ is valid then it stores $24$ back in the pointed to integer. It must not round up and must return an error if the keysize + cannot be mapped to a valid key size for the cipher. + +\subsection{Acceleration} +The next set of functions cover the accelerated functionality of the cipher descriptor. Any combination of these functions may be set to \textbf{NULL} to indicate +it is not supported. In those cases the software defaults are used (using the single ECB block routines). + +\subsubsection{Accelerated ECB} +These two functions are meant for cases where a user wants to encrypt (in ECB mode no less) an array of blocks. These functions are accessed +through the accel\_ecb\_encrypt and accel\_ecb\_decrypt pointers. The \textit{blocks} count is the number of complete blocks to process. + +\subsubsection{Accelerated CBC} +These two functions are meant for accelerated CBC encryption. These functions are accessed through the accel\_cbc\_encrypt and accel\_cbc\_decrypt pointers. +The \textit{blocks} value is the number of complete blocks to process. The \textit{IV} is the CBC initial vector. It is an input upon calling this function and must be +updated by the function before returning. + +\subsubsection{Accelerated CTR} +This function is meant for accelerated CTR encryption. It is accessible through the accel\_ctr\_encrypt pointer. +The \textit{blocks} value is the number of complete blocks to process. The \textit{IV} is the CTR counter vector. It is an input upon calling this function and must be +updated by the function before returning. The \textit{mode} value indicates whether the counter is big (mode = CTR\_COUNTER\_BIG\_ENDIAN) or +little (mode = CTR\_COUNTER\_LITTLE\_ENDIAN) endian. + +This function (and the way it's called) differs from the other two since ctr\_encrypt() allows any size input plaintext. The accelerator will only be +called if the following conditions are met. + +\begin{enumerate} + \item The accelerator is present + \item The CTR pad is empty + \item The remaining length of the input to process is greater than or equal to the block size. +\end{enumerate} + +The \textit{CTR pad} is empty when a multiple (including zero) blocks of text have been processed. That is, if you pass in seven bytes to AES--CTR mode you would have to +pass in a minimum of nine extra bytes before the accelerator could be called. The CTR accelerator must increment the counter (and store it back into the +buffer provided) before encrypting it to create the pad. + +The accelerator will only be used to encrypt whole blocks. Partial blocks are always handled in software. + +\subsubsection{Accelerated LRW} +These functions are meant for accelerated LRW. They process blocks of input in lengths of multiples of 16 octets. They must accept the \textit{IV} and \textit{tweak} +state variables and updated them prior to returning. Note that you may want to disable \textbf{LRW\_TABLES} in \textit{tomcrypt\_custom.h} if you intend +to use accelerators for LRW. + +While both encrypt and decrypt accelerators are not required it is suggested as it makes lrw\_setiv() more efficient. + +Note that calling lrw\_done() will only invoke the cipher\_descriptor[].done() function on the \textit{symmetric\_key} parameter of the LRW state. That means +if your device requires any (LRW specific) resources you should free them in your ciphers() done function. The simplest way to think of it is to write +the plugin solely to do LRW with the cipher. That way cipher\_descriptor[].setup() means to init LRW resources and cipher\_descriptor[].done() means to +free them. + +\subsubsection{Accelerated CCM} +This function is meant for accelerated CCM encryption or decryption. It processes the entire packet in one call. You can optimize the work flow somewhat +by allowing the caller to call the setup() function first to schedule the key if your accelerator cannot do the key schedule on the fly (for instance). This +function MUST support both key passing methods. + +\begin{center} +\begin{small} +\begin{tabular}{|r|r|l|} +\hline \textbf{key} & \textbf{uskey} & \textbf{Source of key} \\ +\hline NULL & NULL & Error, not supported \\ +\hline non-NULL & NULL & Use key, do a key schedule \\ +\hline NULL & non-NULL & Use uskey, key schedule not required \\ +\hline non-NULL & non-NULL & Use uskey, key schedule not required \\ +\hline +\end{tabular} +\end{small} +\end{center} + +\index{ccm\_memory()} This function is called when the user calls ccm\_memory(). + +\subsubsection{Accelerated GCM} +\index{gcm\_memory()} +This function is meant for accelerated GCM encryption or decryption. It processes the entire packet in one call. Note that the setup() function will not +be called prior to this. This function must handle scheduling the key provided on its own. It is called when the user calls gcm\_memory(). + +\subsubsection{Accelerated OMAC} +\index{omac\_memory()} +This function is meant to perform an optimized OMAC1 (CMAC) message authentication code computation when the user calls omac\_memory(). + +\subsubsection{Accelerated XCBC-MAC} +\index{xcbc\_memory()} +This function is meant to perform an optimized XCBC-MAC message authentication code computation when the user calls xcbc\_memory(). + +\subsubsection{Accelerated F9} +\index{f9\_memory()} +This function is meant to perform an optimized F9 message authentication code computation when the user calls f9\_memory(). Like f9\_memory(), it requires +the caller to perform any 3GPP related padding before calling in order to ensure proper compliance with F9. + + +\mysection{One--Way Hashes} +The hash functions are accessed through the ltc\_hash\_descriptor structure. + +\begin{small} +\begin{verbatim} +struct ltc_hash_descriptor { + /** name of hash */ + char *name; + + /** internal ID */ + unsigned char ID; + + /** Size of digest in octets */ + unsigned long hashsize; + + /** Input block size in octets */ + unsigned long blocksize; + + /** ASN.1 OID */ + unsigned long OID[16]; + + /** Length of DER encoding */ + unsigned long OIDlen; + + /** Init a hash state + @param hash The hash to initialize + @return CRYPT_OK if successful + */ + int (*init)(hash_state *hash); + + /** Process a block of data + @param hash The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful + */ + int (*process)( hash_state *hash, + const unsigned char *in, + unsigned long inlen); + + /** Produce the digest and store it + @param hash The hash state + @param out [out] The destination of the digest + @return CRYPT_OK if successful + */ + int (*done)( hash_state *hash, + unsigned char *out); + + /** Self-test + @return CRYPT_OK if successful, + CRYPT_NOP if self-tests have been disabled + */ + int (*test)(void); + + /* accelerated hmac callback: if you need to-do + multiple packets just use the generic hmac_memory + and provide a hash callback + */ + int (*hmac_block)(const unsigned char *key, + unsigned long keylen, + const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen); +}; +\end{verbatim} +\end{small} + +\subsection{Name} +This is the name the hash is known by and what find\_hash() will look for. + +\subsection{Internal ID} +This is the internal ID byte used to distinguish the hash from other hashes. + +\subsection{Digest Size} +The \textit{hashsize} variable indicates the length of the output in octets. + +\subsection{Block Size} +The \textit{blocksize} variable indicates the length of input (in octets) that the hash processes in a given +invocation. + +\subsection{OID Identifier} +This is the universal ASN.1 Object Identifier for the hash. + +\subsection{Initialization} +The init function initializes the hash and prepares it to process message bytes. + +\subsection{Process} +This processes message bytes. The algorithm must accept any length of input that the hash would allow. The input is not +guaranteed to be a multiple of the block size in length. + +\subsection{Done} +The done function terminates the hash and returns the message digest. + +\subsection{Acceleration} +A compatible accelerator must allow processing data in any granularity which may require internal padding on the driver side. + +\subsection{HMAC Acceleration} +The hmac\_block() callback is meant for single--shot optimized HMAC implementations. It is called directly by hmac\_memory() if present. If you need +to be able to process multiple blocks per MAC then you will have to simply provide a process() callback and use hmac\_memory() as provided in LibTomCrypt. + +\mysection{Pseudo--Random Number Generators} +The pseudo--random number generators are accessible through the ltc\_prng\_descriptor structure. + +\begin{small} +\begin{verbatim} +struct ltc_prng_descriptor { + /** Name of the PRNG */ + char *name; + + /** size in bytes of exported state */ + int export_size; + + /** Start a PRNG state + @param prng [out] The state to initialize + @return CRYPT_OK if successful + */ + int (*start)(prng_state *prng); + + /** Add entropy to the PRNG + @param in The entropy + @param inlen Length of the entropy (octets) + @param prng The PRNG state + @return CRYPT_OK if successful + */ + int (*add_entropy)(const unsigned char *in, + unsigned long inlen, + prng_state *prng); + + /** Ready a PRNG state to read from + @param prng The PRNG state to ready + @return CRYPT_OK if successful + */ + int (*ready)(prng_state *prng); + + /** Read from the PRNG + @param out [out] Where to store the data + @param outlen Length of data desired (octets) + @param prng The PRNG state to read from + @return Number of octets read + */ + unsigned long (*read)(unsigned char *out, + unsigned long outlen, + prng_state *prng); + + /** Terminate a PRNG state + @param prng The PRNG state to terminate + @return CRYPT_OK if successful + */ + int (*done)(prng_state *prng); + + /** Export a PRNG state + @param out [out] The destination for the state + @param outlen [in/out] The max size and resulting size + @param prng The PRNG to export + @return CRYPT_OK if successful + */ + int (*pexport)(unsigned char *out, + unsigned long *outlen, + prng_state *prng); + + /** Import a PRNG state + @param in The data to import + @param inlen The length of the data to import (octets) + @param prng The PRNG to initialize/import + @return CRYPT_OK if successful + */ + int (*pimport)(const unsigned char *in, + unsigned long inlen, + prng_state *prng); + + /** Self-test the PRNG + @return CRYPT_OK if successful, + CRYPT_NOP if self-testing has been disabled + */ + int (*test)(void); +}; +\end{verbatim} +\end{small} + +\subsection{Name} +The name by which find\_prng() will find the PRNG. + +\subsection{Export Size} +When an PRNG state is to be exported for future use you specify the space required in this variable. + +\subsection{Start} +Initialize the PRNG and make it ready to accept entropy. + +\subsection{Entropy Addition} +Add entropy to the PRNG state. The exact behaviour of this function depends on the particulars of the PRNG. + +\subsection{Ready} +This function makes the PRNG ready to read from by processing the entropy added. The behaviour of this function depends +on the specific PRNG used. + +\subsection{Read} +Read from the PRNG and return the number of bytes read. This function does not have to fill the buffer but it is best +if it does as many protocols do not retry reads and will fail on the first try. + +\subsection{Done} +Terminate a PRNG state. The behaviour of this function depends on the particular PRNG used. + +\subsection{Exporting and Importing} +An exported PRNG state is data that the PRNG can later import to resume activity. They're not meant to resume \textit{the same session} +but should at least maintain the same level of state entropy. + +\mysection{BigNum Math Descriptors} +The library also makes use of the math descriptors to access math functions. While bignum math libraries usually differ in implementation +it hasn't proven hard to write \textit{glue} to use math libraries so far. The basic descriptor looks like. + +\begin{small} +\begin{verbatim} +/** math descriptor */ +typedef struct { + /** Name of the math provider */ + char *name; + + /** Bits per digit, amount of bits must fit in an unsigned long */ + int bits_per_digit; + +/* ---- init/deinit functions ---- */ + + /** initialize a bignum + @param a The number to initialize + @return CRYPT_OK on success + */ + int (*init)(void **a); + + /** init copy + @param dst The number to initialize and write to + @param src The number to copy from + @return CRYPT_OK on success + */ + int (*init_copy)(void **dst, void *src); + + /** deinit + @param a The number to free + @return CRYPT_OK on success + */ + void (*deinit)(void *a); + +/* ---- data movement ---- */ + + /** copy + @param src The number to copy from + @param dst The number to write to + @return CRYPT_OK on success + */ + int (*copy)(void *src, void *dst); + +/* ---- trivial low level functions ---- */ + + /** set small constant + @param a Number to write to + @param n Source upto bits_per_digit (meant for small constants) + @return CRYPT_OK on success + */ + int (*set_int)(void *a, unsigned long n); + + /** get small constant + @param a Small number to read + @return The lower bits_per_digit of the integer (unsigned) + */ + unsigned long (*get_int)(void *a); + + /** get digit n + @param a The number to read from + @param n The number of the digit to fetch + @return The bits_per_digit sized n'th digit of a + */ + unsigned long (*get_digit)(void *a, int n); + + /** Get the number of digits that represent the number + @param a The number to count + @return The number of digits used to represent the number + */ + int (*get_digit_count)(void *a); + + /** compare two integers + @param a The left side integer + @param b The right side integer + @return LTC_MP_LT if a < b, + LTC_MP_GT if a > b and + LTC_MP_EQ otherwise. (signed comparison) + */ + int (*compare)(void *a, void *b); + + /** compare against int + @param a The left side integer + @param b The right side integer (upto bits_per_digit) + @return LTC_MP_LT if a < b, + LTC_MP_GT if a > b and + LTC_MP_EQ otherwise. (signed comparison) + */ + int (*compare_d)(void *a, unsigned long n); + + /** Count the number of bits used to represent the integer + @param a The integer to count + @return The number of bits required to represent the integer + */ + int (*count_bits)(void * a); + + /** Count the number of LSB bits which are zero + @param a The integer to count + @return The number of contiguous zero LSB bits + */ + int (*count_lsb_bits)(void *a); + + /** Compute a power of two + @param a The integer to store the power in + @param n The power of two you want to store (a = 2^n) + @return CRYPT_OK on success + */ + int (*twoexpt)(void *a , int n); + +/* ---- radix conversions ---- */ + + /** read ascii string + @param a The integer to store into + @param str The string to read + @param radix The radix the integer has been represented in (2-64) + @return CRYPT_OK on success + */ + int (*read_radix)(void *a, const char *str, int radix); + + /** write number to string + @param a The integer to store + @param str The destination for the string + @param radix The radix the integer is to be represented in (2-64) + @return CRYPT_OK on success + */ + int (*write_radix)(void *a, char *str, int radix); + + /** get size as unsigned char string + @param a The integer to get the size + @return The length of the integer in octets + */ + unsigned long (*unsigned_size)(void *a); + + /** store an integer as an array of octets + @param src The integer to store + @param dst The buffer to store the integer in + @return CRYPT_OK on success + */ + int (*unsigned_write)(void *src, unsigned char *dst); + + /** read an array of octets and store as integer + @param dst The integer to load + @param src The array of octets + @param len The number of octets + @return CRYPT_OK on success + */ + int (*unsigned_read)( void *dst, + unsigned char *src, + unsigned long len); + +/* ---- basic math ---- */ + + /** add two integers + @param a The first source integer + @param b The second source integer + @param c The destination of "a + b" + @return CRYPT_OK on success + */ + int (*add)(void *a, void *b, void *c); + + /** add two integers + @param a The first source integer + @param b The second source integer + (single digit of upto bits_per_digit in length) + @param c The destination of "a + b" + @return CRYPT_OK on success + */ + int (*addi)(void *a, unsigned long b, void *c); + + /** subtract two integers + @param a The first source integer + @param b The second source integer + @param c The destination of "a - b" + @return CRYPT_OK on success + */ + int (*sub)(void *a, void *b, void *c); + + /** subtract two integers + @param a The first source integer + @param b The second source integer + (single digit of upto bits_per_digit in length) + @param c The destination of "a - b" + @return CRYPT_OK on success + */ + int (*subi)(void *a, unsigned long b, void *c); + + /** multiply two integers + @param a The first source integer + @param b The second source integer + (single digit of upto bits_per_digit in length) + @param c The destination of "a * b" + @return CRYPT_OK on success + */ + int (*mul)(void *a, void *b, void *c); + + /** multiply two integers + @param a The first source integer + @param b The second source integer + (single digit of upto bits_per_digit in length) + @param c The destination of "a * b" + @return CRYPT_OK on success + */ + int (*muli)(void *a, unsigned long b, void *c); + + /** Square an integer + @param a The integer to square + @param b The destination + @return CRYPT_OK on success + */ + int (*sqr)(void *a, void *b); + + /** Divide an integer + @param a The dividend + @param b The divisor + @param c The quotient (can be NULL to signify don't care) + @param d The remainder (can be NULL to signify don't care) + @return CRYPT_OK on success + */ + int (*div)(void *a, void *b, void *c, void *d); + + /** divide by two + @param a The integer to divide (shift right) + @param b The destination + @return CRYPT_OK on success + */ + int (*div_2)(void *a, void *b); + + /** Get remainder (small value) + @param a The integer to reduce + @param b The modulus (upto bits_per_digit in length) + @param c The destination for the residue + @return CRYPT_OK on success + */ + int (*modi)(void *a, unsigned long b, unsigned long *c); + + /** gcd + @param a The first integer + @param b The second integer + @param c The destination for (a, b) + @return CRYPT_OK on success + */ + int (*gcd)(void *a, void *b, void *c); + + /** lcm + @param a The first integer + @param b The second integer + @param c The destination for [a, b] + @return CRYPT_OK on success + */ + int (*lcm)(void *a, void *b, void *c); + + /** Modular multiplication + @param a The first source + @param b The second source + @param c The modulus + @param d The destination (a*b mod c) + @return CRYPT_OK on success + */ + int (*mulmod)(void *a, void *b, void *c, void *d); + + /** Modular squaring + @param a The first source + @param b The modulus + @param c The destination (a*a mod b) + @return CRYPT_OK on success + */ + int (*sqrmod)(void *a, void *b, void *c); + + /** Modular inversion + @param a The value to invert + @param b The modulus + @param c The destination (1/a mod b) + @return CRYPT_OK on success + */ + int (*invmod)(void *, void *, void *); + +/* ---- reduction ---- */ + + /** setup Montgomery + @param a The modulus + @param b The destination for the reduction digit + @return CRYPT_OK on success + */ + int (*montgomery_setup)(void *a, void **b); + + /** get normalization value + @param a The destination for the normalization value + @param b The modulus + @return CRYPT_OK on success + */ + int (*montgomery_normalization)(void *a, void *b); + + /** reduce a number + @param a The number [and dest] to reduce + @param b The modulus + @param c The value "b" from montgomery_setup() + @return CRYPT_OK on success + */ + int (*montgomery_reduce)(void *a, void *b, void *c); + + /** clean up (frees memory) + @param a The value "b" from montgomery_setup() + @return CRYPT_OK on success + */ + void (*montgomery_deinit)(void *a); + +/* ---- exponentiation ---- */ + + /** Modular exponentiation + @param a The base integer + @param b The power (can be negative) integer + @param c The modulus integer + @param d The destination + @return CRYPT_OK on success + */ + int (*exptmod)(void *a, void *b, void *c, void *d); + + /** Primality testing + @param a The integer to test + @param b The destination of the result (FP_YES if prime) + @return CRYPT_OK on success + */ + int (*isprime)(void *a, int *b); + +/* ---- (optional) ecc point math ---- */ + + /** ECC GF(p) point multiplication (from the NIST curves) + @param k The integer to multiply the point by + @param G The point to multiply + @param R The destination for kG + @param modulus The modulus for the field + @param map Boolean indicated whether to map back to affine or not + (can be ignored if you work in affine only) + @return CRYPT_OK on success + */ + int (*ecc_ptmul)( void *k, + ecc_point *G, + ecc_point *R, + void *modulus, + int map); + + /** ECC GF(p) point addition + @param P The first point + @param Q The second point + @param R The destination of P + Q + @param modulus The modulus + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success + */ + int (*ecc_ptadd)(ecc_point *P, + ecc_point *Q, + ecc_point *R, + void *modulus, + void *mp); + + /** ECC GF(p) point double + @param P The first point + @param R The destination of 2P + @param modulus The modulus + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success + */ + int (*ecc_ptdbl)(ecc_point *P, + ecc_point *R, + void *modulus, + void *mp); + + /** ECC mapping from projective to affine, + currently uses (x,y,z) => (x/z^2, y/z^3, 1) + @param P The point to map + @param modulus The modulus + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success + @remark The mapping can be different but keep in mind a + ecc_point only has three integers (x,y,z) so if + you use a different mapping you have to make it fit. + */ + int (*ecc_map)(ecc_point *P, void *modulus, void *mp); + + /** Computes kA*A + kB*B = C using Shamir's Trick + @param A First point to multiply + @param kA What to multiple A by + @param B Second point to multiply + @param kB What to multiple B by + @param C [out] Destination point (can overlap with A or B) + @param modulus Modulus for curve + @return CRYPT_OK on success + */ + int (*ecc_mul2add)(ecc_point *A, void *kA, + ecc_point *B, void *kB, + ecc_point *C, + void *modulus); + + +/* ---- (optional) rsa optimized math (for internal CRT) ---- */ + + /** RSA Key Generation + @param prng An active PRNG state + @param wprng The index of the PRNG desired + @param size The size of the key in octets + @param e The "e" value (public key). + e==65537 is a good choice + @param key [out] Destination of a newly created private key pair + @return CRYPT_OK if successful, upon error all allocated ram is freed + */ + int (*rsa_keygen)(prng_state *prng, + int wprng, + int size, + long e, + rsa_key *key); + + /** RSA exponentiation + @param in The octet array representing the base + @param inlen The length of the input + @param out The destination (to be stored in an octet array format) + @param outlen The length of the output buffer and the resulting size + (zero padded to the size of the modulus) + @param which PK_PUBLIC for public RSA and PK_PRIVATE for private RSA + @param key The RSA key to use + @return CRYPT_OK on success + */ + int (*rsa_me)(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int which, + rsa_key *key); +} ltc_math_descriptor; +\end{verbatim} +\end{small} + +Most of the functions are fairly straightforward and do not need documentation. We'll cover the basic conventions of the API and then explain the accelerated functions. + +\subsection{Conventions} + +All \textit{bignums} are accessed through an opaque \textit{void *} data type. You must internally cast the pointer if you need to access members of your bignum structure. During +the init calls a \textit{void **} will be passed where you allocate your structure and set the pointer then initialize the number to zero. During the deinit calls you must +free the bignum as well as the structure you allocated to place it in. + +All functions except the Montgomery reductions work from left to right with the arguments. For example, mul(a, b, c) computes $c \leftarrow ab$. + +All functions (except where noted otherwise) return \textbf{CRYPT\_OK} to signify a successful operation. All error codes must be valid LibTomCrypt error codes. + +The digit routines (including functions with the \textit{i} suffix) use a \textit{unsigned long} to represent the digit. If your internal digit is larger than this you must +then partition your digits. Normally this does not matter as \textit{unsigned long} will be the same size as your register size. Note that if your digit is smaller +than an \textit{unsigned long} that is also acceptable as the \textit{bits\_per\_digit} parameter will specify this. + +\subsection{ECC Functions} +The ECC system in LibTomCrypt is based off of the NIST recommended curves over $GF(p)$ and is used to implement EC-DSA and EC-DH. The ECC functions work with +the \textbf{ecc\_point} structure and assume the points are stored in Jacobian projective format. + +\begin{verbatim} +/** A point on a ECC curve, stored in Jacobian format such + that (x,y,z) => (x/z^2, y/z^3, 1) when interpreted as affine */ +typedef struct { + /** The x co-ordinate */ + void *x; + /** The y co-ordinate */ + void *y; + /** The z co-ordinate */ + void *z; +} ecc_point; +\end{verbatim} + +All ECC functions must use this mapping system. The only exception is when you remap all ECC callbacks which will allow you to have more control +over how the ECC math will be implemented. Out of the box you only have three parameters per point to use $(x, y, z)$ however, these are just void pointers. They +could point to anything you want. The only further exception is the export functions which expects the values to be in affine format. + +\subsubsection{Point Multiply} +This will multiply the point $G$ by the scalar $k$ and store the result in the point $R$. The value should be mapped to affine only if $map$ is set to one. + +\subsubsection{Point Addition} +This will add the point $P$ to the point $Q$ and store it in the point $R$. The $mp$ parameter is the \textit{b} value from the montgomery\_setup() call. The input points +may be in either affine (with $z = 1$) or projective format and the output point is always projective. + +\subsubsection{Point Mapping} +This will map the point $P$ back from projective to affine. The output point $P$ must be of the form $(x, y, 1)$. + +\subsubsection{Shamir's Trick} +\index{Shamir's Trick} +\index{ltc\_ecc\_mul2add()} +To accelerate EC--DSA verification the library provides a built--in function called ltc\_ecc\_mul2add(). This performs two point multiplications and an addition in +roughly the time of one point multiplication. It is called from ecc\_verify\_hash() if an accelerator is not present. The acclerator function must allow the points to +overlap (e.g., $A \leftarrow k_1A + k_2B$) and must return the final point in affine format. + + +\subsection{RSA Functions} +The RSA Modular Exponentiation (ME) function is used by the RSA API to perform exponentiations for private and public key operations. In particular for +private key operations it uses the CRT approach to lower the time required. It is passed an RSA key with the following format. + +\begin{verbatim} +/** RSA PKCS style key */ +typedef struct Rsa_key { + /** Type of key, PK_PRIVATE or PK_PUBLIC */ + int type; + /** The public exponent */ + void *e; + /** The private exponent */ + void *d; + /** The modulus */ + void *N; + /** The p factor of N */ + void *p; + /** The q factor of N */ + void *q; + /** The 1/q mod p CRT param */ + void *qP; + /** The d mod (p - 1) CRT param */ + void *dP; + /** The d mod (q - 1) CRT param */ + void *dQ; +} rsa_key; +\end{verbatim} + +The call reads the \textit{in} buffer as an unsigned char array in big endian format. Then it performs the exponentiation and stores the output in big endian format +to the \textit{out} buffer. The output must be zero padded (leading bytes) so that the length of the output matches the length of the modulus (in bytes). For example, +for RSA--1024 the output is always 128 bytes regardless of how small the numerical value of the exponentiation is. + +Since the function is given the entire RSA key (for private keys only) CRT is possible as prescribed in the PKCS \#1 v2.1 specification. + +\newpage +\markboth{Index}{Index} +\input{crypt.ind} + +\end{document} + +% $Source: /cvs/libtom/libtomcrypt/crypt.tex,v $ +% $Revision: 1.128 $ +% $Date: 2007/03/10 23:59:54 $ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/demos/encrypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/demos/encrypt.c new file mode 100644 index 0000000000..4bab91b32b --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/demos/encrypt.c @@ -0,0 +1,241 @@ +/* encrypt V1.1 Fri Oct 18 04:28:03 NZDT 2002 */ +/* File de/encryption, using libtomcrypt */ +/* Written by Daniel Richards */ +/* Help from Tom St Denis with various bits */ +/* This code is public domain, no rights reserved. */ +/* Encrypts by default, -d flag enables decryption */ +/* ie: ./encrypt blowfish story.txt story.ct */ +/* ./encrypt -d blowfish story.ct story.pt */ + +#include + +int errno; + +int usage(char *name) +{ + int x; + + printf("Usage: %s [-d](ecrypt) cipher infile outfile\nCiphers:\n", name); + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + printf("%s\n",cipher_descriptor[x].name); + } + exit(1); +} + +void register_algs(void) +{ + int x; + +#ifdef LTC_RIJNDAEL + register_cipher (&aes_desc); +#endif +#ifdef LTC_BLOWFISH + register_cipher (&blowfish_desc); +#endif +#ifdef LTC_XTEA + register_cipher (&xtea_desc); +#endif +#ifdef LTC_RC5 + register_cipher (&rc5_desc); +#endif +#ifdef LTC_RC6 + register_cipher (&rc6_desc); +#endif +#ifdef LTC_SAFERP + register_cipher (&saferp_desc); +#endif +#ifdef LTC_TWOFISH + register_cipher (&twofish_desc); +#endif +#ifdef LTC_SAFER + register_cipher (&safer_k64_desc); + register_cipher (&safer_sk64_desc); + register_cipher (&safer_k128_desc); + register_cipher (&safer_sk128_desc); +#endif +#ifdef LTC_RC2 + register_cipher (&rc2_desc); +#endif +#ifdef LTC_DES + register_cipher (&des_desc); + register_cipher (&des3_desc); +#endif +#ifdef LTC_CAST5 + register_cipher (&cast5_desc); +#endif +#ifdef LTC_NOEKEON + register_cipher (&noekeon_desc); +#endif +#ifdef LTC_SKIPJACK + register_cipher (&skipjack_desc); +#endif +#ifdef LTC_KHAZAD + register_cipher (&khazad_desc); +#endif +#ifdef LTC_ANUBIS + register_cipher (&anubis_desc); +#endif + + if (register_hash(&sha256_desc) == -1) { + printf("Error registering LTC_SHA256\n"); + exit(-1); + } + + if (register_prng(&yarrow_desc) == -1) { + printf("Error registering yarrow PRNG\n"); + exit(-1); + } + + if (register_prng(&sprng_desc) == -1) { + printf("Error registering sprng PRNG\n"); + exit(-1); + } +} + +int main(int argc, char *argv[]) +{ + unsigned char plaintext[512],ciphertext[512]; + unsigned char tmpkey[512], key[MAXBLOCKSIZE], IV[MAXBLOCKSIZE]; + unsigned char inbuf[512]; /* i/o block size */ + unsigned long outlen, y, ivsize, x, decrypt; + symmetric_CTR ctr; + int cipher_idx, hash_idx, ks; + char *infile, *outfile, *cipher; + prng_state prng; + FILE *fdin, *fdout; + + /* register algs, so they can be printed */ + register_algs(); + + if (argc < 4) { + return usage(argv[0]); + } + + if (!strcmp(argv[1], "-d")) { + decrypt = 1; + cipher = argv[2]; + infile = argv[3]; + outfile = argv[4]; + } else { + decrypt = 0; + cipher = argv[1]; + infile = argv[2]; + outfile = argv[3]; + } + + /* file handles setup */ + fdin = fopen(infile,"rb"); + if (fdin == NULL) { + perror("Can't open input for reading"); + exit(-1); + } + + fdout = fopen(outfile,"wb"); + if (fdout == NULL) { + perror("Can't open output for writing"); + exit(-1); + } + + cipher_idx = find_cipher(cipher); + if (cipher_idx == -1) { + printf("Invalid cipher entered on command line.\n"); + exit(-1); + } + + hash_idx = find_hash("sha256"); + if (hash_idx == -1) { + printf("LTC_SHA256 not found...?\n"); + exit(-1); + } + + ivsize = cipher_descriptor[cipher_idx].block_length; + ks = hash_descriptor[hash_idx].hashsize; + if (cipher_descriptor[cipher_idx].keysize(&ks) != CRYPT_OK) { + printf("Invalid keysize???\n"); + exit(-1); + } + + printf("\nEnter key: "); + fgets((char *)tmpkey,sizeof(tmpkey), stdin); + outlen = sizeof(key); + if ((errno = hash_memory(hash_idx,tmpkey,strlen((char *)tmpkey),key,&outlen)) != CRYPT_OK) { + printf("Error hashing key: %s\n", error_to_string(errno)); + exit(-1); + } + + if (decrypt) { + /* Need to read in IV */ + if (fread(IV,1,ivsize,fdin) != ivsize) { + printf("Error reading IV from input.\n"); + exit(-1); + } + + if ((errno = ctr_start(cipher_idx,IV,key,ks,0,CTR_COUNTER_LITTLE_ENDIAN,&ctr)) != CRYPT_OK) { + printf("ctr_start error: %s\n",error_to_string(errno)); + exit(-1); + } + + /* IV done */ + do { + y = fread(inbuf,1,sizeof(inbuf),fdin); + + if ((errno = ctr_decrypt(inbuf,plaintext,y,&ctr)) != CRYPT_OK) { + printf("ctr_decrypt error: %s\n", error_to_string(errno)); + exit(-1); + } + + if (fwrite(plaintext,1,y,fdout) != y) { + printf("Error writing to file.\n"); + exit(-1); + } + } while (y == sizeof(inbuf)); + fclose(fdin); + fclose(fdout); + + } else { /* encrypt */ + /* Setup yarrow for random bytes for IV */ + + if ((errno = rng_make_prng(128, find_prng("yarrow"), &prng, NULL)) != CRYPT_OK) { + printf("Error setting up PRNG, %s\n", error_to_string(errno)); + } + + /* You can use rng_get_bytes on platforms that support it */ + /* x = rng_get_bytes(IV,ivsize,NULL);*/ + x = yarrow_read(IV,ivsize,&prng); + if (x != ivsize) { + printf("Error reading PRNG for IV required.\n"); + exit(-1); + } + + if (fwrite(IV,1,ivsize,fdout) != ivsize) { + printf("Error writing IV to output.\n"); + exit(-1); + } + + if ((errno = ctr_start(cipher_idx,IV,key,ks,0,CTR_COUNTER_LITTLE_ENDIAN,&ctr)) != CRYPT_OK) { + printf("ctr_start error: %s\n",error_to_string(errno)); + exit(-1); + } + + do { + y = fread(inbuf,1,sizeof(inbuf),fdin); + + if ((errno = ctr_encrypt(inbuf,ciphertext,y,&ctr)) != CRYPT_OK) { + printf("ctr_encrypt error: %s\n", error_to_string(errno)); + exit(-1); + } + + if (fwrite(ciphertext,1,y,fdout) != y) { + printf("Error writing to output.\n"); + exit(-1); + } + } while (y == sizeof(inbuf)); + fclose(fdout); + fclose(fdin); + } + return 0; +} + +/* $Source: /cvs/libtom/libtomcrypt/demos/encrypt.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/demos/hashsum.c b/xmhf-64/xmhf/third-party/libtomcrypt/demos/hashsum.c new file mode 100644 index 0000000000..2aef50b376 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/demos/hashsum.c @@ -0,0 +1,119 @@ +/* + * Written by Daniel Richards 6/7/2002 + * hash.c: This app uses libtomcrypt to hash either stdin or a file + * This file is Public Domain. No rights are reserved. + * Compile with 'gcc hashsum.c -o hashsum -ltomcrypt' + * This example isn't really big enough to warrent splitting into + * more functions ;) +*/ + +#include + +int errno; + +void register_algs(); + +int main(int argc, char **argv) +{ + int idx, x, z; + unsigned long w; + unsigned char hash_buffer[MAXBLOCKSIZE]; + hash_state md; + + /* You need to register algorithms before using them */ + register_algs(); + if (argc < 2) { + printf("usage: ./hash algorithm file [file ...]\n"); + printf("Algorithms:\n"); + for (x = 0; hash_descriptor[x].name != NULL; x++) { + printf(" %s (%d)\n", hash_descriptor[x].name, hash_descriptor[x].ID); + } + exit(EXIT_SUCCESS); + } + + idx = find_hash(argv[1]); + if (idx == -1) { + fprintf(stderr, "\nInvalid hash specified on command line.\n"); + return -1; + } + + if (argc == 2) { + hash_descriptor[idx].init(&md); + do { + x = fread(hash_buffer, 1, sizeof(hash_buffer), stdin); + hash_descriptor[idx].process(&md, hash_buffer, x); + } while (x == sizeof(hash_buffer)); + hash_descriptor[idx].done(&md, hash_buffer); + for (x = 0; x < (int)hash_descriptor[idx].hashsize; x++) { + printf("%02x",hash_buffer[x]); + } + printf(" (stdin)\n"); + } else { + for (z = 2; z < argc; z++) { + w = sizeof(hash_buffer); + if ((errno = hash_file(idx,argv[z],hash_buffer,&w)) != CRYPT_OK) { + printf("File hash error: %s\n", error_to_string(errno)); + } else { + for (x = 0; x < (int)hash_descriptor[idx].hashsize; x++) { + printf("%02x",hash_buffer[x]); + } + printf(" %s\n", argv[z]); + } + } + } + return EXIT_SUCCESS; +} + +void register_algs(void) +{ + int err; + +#ifdef LTC_TIGER + register_hash (&tiger_desc); +#endif +#ifdef LTC_MD2 + register_hash (&md2_desc); +#endif +#ifdef LTC_MD4 + register_hash (&md4_desc); +#endif +#ifdef LTC_MD5 + register_hash (&md5_desc); +#endif +#ifdef LTC_SHA1 + register_hash (&sha1_desc); +#endif +#ifdef LTC_SHA224 + register_hash (&sha224_desc); +#endif +#ifdef LTC_SHA256 + register_hash (&sha256_desc); +#endif +#ifdef LTC_SHA384 + register_hash (&sha384_desc); +#endif +#ifdef LTC_SHA512 + register_hash (&sha512_desc); +#endif +#ifdef LTC_RIPEMD128 + register_hash (&rmd128_desc); +#endif +#ifdef LTC_RIPEMD160 + register_hash (&rmd160_desc); +#endif +#ifdef LTC_WHIRLPOOL + register_hash (&whirlpool_desc); +#endif +#ifdef LTC_CHC_HASH + register_hash(&chc_desc); + if ((err = chc_register(register_cipher(&aes_enc_desc))) != CRYPT_OK) { + printf("chc_register error: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } +#endif + +} + +/* $Source: /cvs/libtom/libtomcrypt/demos/hashsum.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/demos/multi.c b/xmhf-64/xmhf/third-party/libtomcrypt/demos/multi.c new file mode 100644 index 0000000000..a202694c6e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/demos/multi.c @@ -0,0 +1,110 @@ +/* test the multi helpers... */ +#include + +int main(void) +{ + unsigned char key[16], buf[2][MAXBLOCKSIZE]; + unsigned long len, len2; + + +/* register algos */ + register_hash(&sha256_desc); + register_cipher(&aes_desc); + +/* HASH testing */ + len = sizeof(buf[0]); + hash_memory(find_hash("sha256"), (unsigned char*)"hello", 5, buf[0], &len); + len2 = sizeof(buf[0]); + hash_memory_multi(find_hash("sha256"), buf[1], &len2, (unsigned char*)"hello", 5, NULL); + if (len != len2 || memcmp(buf[0], buf[1], len)) { + printf("Failed: %d %lu %lu\n", __LINE__, len, len2); + return EXIT_FAILURE; + } + len2 = sizeof(buf[0]); + hash_memory_multi(find_hash("sha256"), buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL, 0); + if (len != len2 || memcmp(buf[0], buf[1], len)) { + printf("Failed: %d %lu %lu\n", __LINE__, len, len2); + return EXIT_FAILURE; + } + len2 = sizeof(buf[0]); + hash_memory_multi(find_hash("sha256"), buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL); + if (len != len2 || memcmp(buf[0], buf[1], len)) { + printf("Failed: %d %lu %lu\n", __LINE__, len, len2); + return EXIT_FAILURE; + } + +/* LTC_HMAC */ + len = sizeof(buf[0]); + hmac_memory(find_hash("sha256"), key, 16, (unsigned char*)"hello", 5, buf[0], &len); + len2 = sizeof(buf[0]); + hmac_memory_multi(find_hash("sha256"), key, 16, buf[1], &len2, (unsigned char*)"hello", 5UL, NULL); + if (len != len2 || memcmp(buf[0], buf[1], len)) { + printf("Failed: %d %lu %lu\n", __LINE__, len, len2); + return EXIT_FAILURE; + } + len2 = sizeof(buf[0]); + hmac_memory_multi(find_hash("sha256"), key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL); + if (len != len2 || memcmp(buf[0], buf[1], len)) { + printf("Failed: %d %lu %lu\n", __LINE__, len, len2); + return EXIT_FAILURE; + } + len2 = sizeof(buf[0]); + hmac_memory_multi(find_hash("sha256"), key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL); + if (len != len2 || memcmp(buf[0], buf[1], len)) { + printf("Failed: %d %lu %lu\n", __LINE__, len, len2); + return EXIT_FAILURE; + } + +/* LTC_OMAC */ + len = sizeof(buf[0]); + omac_memory(find_cipher("aes"), key, 16, (unsigned char*)"hello", 5, buf[0], &len); + len2 = sizeof(buf[0]); + omac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"hello", 5UL, NULL); + if (len != len2 || memcmp(buf[0], buf[1], len)) { + printf("Failed: %d %lu %lu\n", __LINE__, len, len2); + return EXIT_FAILURE; + } + len2 = sizeof(buf[0]); + omac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL); + if (len != len2 || memcmp(buf[0], buf[1], len)) { + printf("Failed: %d %lu %lu\n", __LINE__, len, len2); + return EXIT_FAILURE; + } + len2 = sizeof(buf[0]); + omac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL); + if (len != len2 || memcmp(buf[0], buf[1], len)) { + printf("Failed: %d %lu %lu\n", __LINE__, len, len2); + return EXIT_FAILURE; + } + +/* PMAC */ + len = sizeof(buf[0]); + pmac_memory(find_cipher("aes"), key, 16, (unsigned char*)"hello", 5, buf[0], &len); + len2 = sizeof(buf[0]); + pmac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"hello", 5, NULL); + if (len != len2 || memcmp(buf[0], buf[1], len)) { + printf("Failed: %d %lu %lu\n", __LINE__, len, len2); + return EXIT_FAILURE; + } + len2 = sizeof(buf[0]); + pmac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL); + if (len != len2 || memcmp(buf[0], buf[1], len)) { + printf("Failed: %d %lu %lu\n", __LINE__, len, len2); + return EXIT_FAILURE; + } + len2 = sizeof(buf[0]); + pmac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL); + if (len != len2 || memcmp(buf[0], buf[1], len)) { + printf("Failed: %d %lu %lu\n", __LINE__, len, len2); + return EXIT_FAILURE; + } + + + printf("All passed\n"); + return EXIT_SUCCESS; +} + + +/* $Source: /cvs/libtom/libtomcrypt/demos/multi.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/demos/small.c b/xmhf-64/xmhf/third-party/libtomcrypt/demos/small.c new file mode 100644 index 0000000000..301974546f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/demos/small.c @@ -0,0 +1,14 @@ +/* small demo app that just includes a cipher/hash/prng */ +#include + +int main(void) +{ + register_cipher(&rijndael_enc_desc); + register_prng(&yarrow_desc); + register_hash(&sha256_desc); + return 0; +} + +/* $Source: /cvs/libtom/libtomcrypt/demos/small.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2006/06/07 22:25:09 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/demos/test.c b/xmhf-64/xmhf/third-party/libtomcrypt/demos/test.c new file mode 100644 index 0000000000..b45ff3dd51 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/demos/test.c @@ -0,0 +1,36 @@ +#include + +int main(void) +{ + int x; + reg_algs(); + +#ifdef USE_LTM + ltc_mp = ltm_desc; +#elif defined(USE_TFM) + ltc_mp = tfm_desc; +#elif defined(USE_GMP) + ltc_mp = gmp_desc; +#else + extern ltc_math_descriptor EXT_MATH_LIB; + ltc_mp = EXT_MATH_LIB; +#endif + + printf("build == \n%s\n", crypt_build_settings); + printf("\nstore_test...."); fflush(stdout); x = store_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); + printf("\ncipher_test..."); fflush(stdout); x = cipher_hash_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); + printf("\nmodes_test...."); fflush(stdout); x = modes_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); + printf("\nder_test......"); fflush(stdout); x = der_tests(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); + printf("\nmac_test......"); fflush(stdout); x = mac_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); + printf("\npkcs_1_test..."); fflush(stdout); x = pkcs_1_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); + printf("\nrsa_test......"); fflush(stdout); x = rsa_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); + printf("\necc_test......"); fflush(stdout); x = ecc_tests(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); + printf("\ndsa_test......"); fflush(stdout); x = dsa_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); + printf("\nkatja_test...."); fflush(stdout); x = katja_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); + printf("\n"); + return EXIT_SUCCESS; +} + +/* $Source: /cvs/libtom/libtomcrypt/demos/test.c,v $ */ +/* $Revision: 1.28 $ */ +/* $Date: 2006/05/25 10:50:08 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/demos/timing.c b/xmhf-64/xmhf/third-party/libtomcrypt/demos/timing.c new file mode 100644 index 0000000000..becc7c0ea0 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/demos/timing.c @@ -0,0 +1,42 @@ +#include + +int main(void) +{ + +init_timer(); +reg_algs(); + +#ifdef USE_LTM + ltc_mp = ltm_desc; +#elif defined(USE_TFM) + ltc_mp = tfm_desc; +#elif defined(USE_GMP) + ltc_mp = gmp_desc; +#else + extern ltc_math_descriptor EXT_MATH_LIB; + ltc_mp = EXT_MATH_LIB; +#endif + +time_keysched(); +time_cipher(); +time_cipher2(); +time_cipher3(); +time_cipher4(); +time_hash(); +time_macs(); +time_encmacs(); +time_prng(); +time_mult(); +time_sqr(); +time_rsa(); +time_ecc(); +#ifdef USE_LTM +time_katja(); +#endif +return EXIT_SUCCESS; + +} + +/* $Source: /cvs/libtom/libtomcrypt/demos/timing.c,v $ */ +/* $Revision: 1.61 $ */ +/* $Date: 2006/12/03 03:08:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/demos/tv_gen.c b/xmhf-64/xmhf/third-party/libtomcrypt/demos/tv_gen.c new file mode 100644 index 0000000000..8174a1468c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/demos/tv_gen.c @@ -0,0 +1,786 @@ +#include + +void reg_algs(void) +{ + int err; + +#ifdef LTC_RIJNDAEL + register_cipher (&aes_desc); +#endif +#ifdef LTC_BLOWFISH + register_cipher (&blowfish_desc); +#endif +#ifdef LTC_XTEA + register_cipher (&xtea_desc); +#endif +#ifdef LTC_RC5 + register_cipher (&rc5_desc); +#endif +#ifdef LTC_RC6 + register_cipher (&rc6_desc); +#endif +#ifdef LTC_SAFERP + register_cipher (&saferp_desc); +#endif +#ifdef LTC_TWOFISH + register_cipher (&twofish_desc); +#endif +#ifdef LTC_SAFER + register_cipher (&safer_k64_desc); + register_cipher (&safer_sk64_desc); + register_cipher (&safer_k128_desc); + register_cipher (&safer_sk128_desc); +#endif +#ifdef LTC_RC2 + register_cipher (&rc2_desc); +#endif +#ifdef LTC_DES + register_cipher (&des_desc); + register_cipher (&des3_desc); +#endif +#ifdef LTC_CAST5 + register_cipher (&cast5_desc); +#endif +#ifdef LTC_NOEKEON + register_cipher (&noekeon_desc); +#endif +#ifdef LTC_SKIPJACK + register_cipher (&skipjack_desc); +#endif +#ifdef LTC_ANUBIS + register_cipher (&anubis_desc); +#endif +#ifdef LTC_KHAZAD + register_cipher (&khazad_desc); +#endif + +#ifdef LTC_TIGER + register_hash (&tiger_desc); +#endif +#ifdef LTC_MD2 + register_hash (&md2_desc); +#endif +#ifdef LTC_MD4 + register_hash (&md4_desc); +#endif +#ifdef LTC_MD5 + register_hash (&md5_desc); +#endif +#ifdef LTC_SHA1 + register_hash (&sha1_desc); +#endif +#ifdef LTC_SHA224 + register_hash (&sha224_desc); +#endif +#ifdef LTC_SHA256 + register_hash (&sha256_desc); +#endif +#ifdef LTC_SHA384 + register_hash (&sha384_desc); +#endif +#ifdef LTC_SHA512 + register_hash (&sha512_desc); +#endif +#ifdef LTC_RIPEMD128 + register_hash (&rmd128_desc); +#endif +#ifdef LTC_RIPEMD160 + register_hash (&rmd160_desc); +#endif +#ifdef LTC_WHIRLPOOL + register_hash (&whirlpool_desc); +#endif +#ifdef LTC_CHC_HASH + register_hash(&chc_desc); + if ((err = chc_register(register_cipher(&aes_desc))) != CRYPT_OK) { + printf("chc_register error: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } +#endif + +#ifdef USE_LTM + ltc_mp = ltm_desc; +#elif defined(USE_TFM) + ltc_mp = tfm_desc; +#elif defined(USE_GMP) + ltc_mp = gmp_desc; +#else + extern ltc_math_descriptor EXT_MATH_LIB; + ltc_mp = EXT_MATH_LIB; +#endif + + +} + +void hash_gen(void) +{ + unsigned char md[MAXBLOCKSIZE], *buf; + unsigned long outlen, x, y, z; + FILE *out; + int err; + + out = fopen("hash_tv.txt", "w"); + if (out == NULL) { + perror("can't open hash_tv"); + } + + fprintf(out, "Hash Test Vectors:\n\nThese are the hashes of nn bytes '00 01 02 03 .. (nn-1)'\n\n"); + for (x = 0; hash_descriptor[x].name != NULL; x++) { + buf = XMALLOC(2 * hash_descriptor[x].blocksize + 1); + if (buf == NULL) { + perror("can't alloc mem"); + exit(EXIT_FAILURE); + } + fprintf(out, "Hash: %s\n", hash_descriptor[x].name); + for (y = 0; y <= (hash_descriptor[x].blocksize * 2); y++) { + for (z = 0; z < y; z++) { + buf[z] = (unsigned char)(z & 255); + } + outlen = sizeof(md); + if ((err = hash_memory(x, buf, y, md, &outlen)) != CRYPT_OK) { + printf("hash_memory error: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + fprintf(out, "%3lu: ", y); + for (z = 0; z < outlen; z++) { + fprintf(out, "%02X", md[z]); + } + fprintf(out, "\n"); + } + fprintf(out, "\n"); + XFREE(buf); + } + fclose(out); +} + +void cipher_gen(void) +{ + unsigned char *key, pt[MAXBLOCKSIZE]; + unsigned long x, y, z, w; + int err, kl, lastkl; + FILE *out; + symmetric_key skey; + + out = fopen("cipher_tv.txt", "w"); + + fprintf(out, +"Cipher Test Vectors\n\nThese are test encryptions with key of nn bytes '00 01 02 03 .. (nn-1)' and original PT of the same style.\n" +"The output of step N is used as the key and plaintext for step N+1 (key bytes repeated as required to fill the key)\n\n"); + + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + fprintf(out, "Cipher: %s\n", cipher_descriptor[x].name); + + /* three modes, smallest, medium, large keys */ + lastkl = 10000; + for (y = 0; y < 3; y++) { + switch (y) { + case 0: kl = cipher_descriptor[x].min_key_length; break; + case 1: kl = (cipher_descriptor[x].min_key_length + cipher_descriptor[x].max_key_length)/2; break; + case 2: kl = cipher_descriptor[x].max_key_length; break; + } + if ((err = cipher_descriptor[x].keysize(&kl)) != CRYPT_OK) { + printf("keysize error: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + if (kl == lastkl) break; + lastkl = kl; + fprintf(out, "Key Size: %d bytes\n", kl); + + key = XMALLOC(kl); + if (key == NULL) { + perror("can't malloc memory"); + exit(EXIT_FAILURE); + } + + for (z = 0; (int)z < kl; z++) { + key[z] = (unsigned char)z; + } + if ((err = cipher_descriptor[x].setup(key, kl, 0, &skey)) != CRYPT_OK) { + printf("setup error: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + + for (z = 0; (int)z < cipher_descriptor[x].block_length; z++) { + pt[z] = (unsigned char)z; + } + for (w = 0; w < 50; w++) { + cipher_descriptor[x].ecb_encrypt(pt, pt, &skey); + fprintf(out, "%2lu: ", w); + for (z = 0; (int)z < cipher_descriptor[x].block_length; z++) { + fprintf(out, "%02X", pt[z]); + } + fprintf(out, "\n"); + + /* reschedule a new key */ + for (z = 0; z < (unsigned long)kl; z++) { + key[z] = pt[z % cipher_descriptor[x].block_length]; + } + if ((err = cipher_descriptor[x].setup(key, kl, 0, &skey)) != CRYPT_OK) { + printf("cipher setup2 error: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + } + fprintf(out, "\n"); + XFREE(key); + } + fprintf(out, "\n"); + } + fclose(out); +} + +void hmac_gen(void) +{ + unsigned char key[MAXBLOCKSIZE], output[MAXBLOCKSIZE], *input; + int x, y, z, err; + FILE *out; + unsigned long len; + + out = fopen("hmac_tv.txt", "w"); + + fprintf(out, +"LTC_HMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are LTC_HMACed. The initial key is\n" +"of the same format (the same length as the HASH output size). The LTC_HMAC key in step N+1 is the LTC_HMAC output of\n" +"step N.\n\n"); + + for (x = 0; hash_descriptor[x].name != NULL; x++) { + fprintf(out, "LTC_HMAC-%s\n", hash_descriptor[x].name); + + /* initial key */ + for (y = 0; y < (int)hash_descriptor[x].hashsize; y++) { + key[y] = (y&255); + } + + input = XMALLOC(hash_descriptor[x].blocksize * 2 + 1); + if (input == NULL) { + perror("Can't malloc memory"); + exit(EXIT_FAILURE); + } + + for (y = 0; y <= (int)(hash_descriptor[x].blocksize * 2); y++) { + for (z = 0; z < y; z++) { + input[z] = (unsigned char)(z & 255); + } + len = sizeof(output); + if ((err = hmac_memory(x, key, hash_descriptor[x].hashsize, input, y, output, &len)) != CRYPT_OK) { + printf("Error hmacing: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + fprintf(out, "%3d: ", y); + for (z = 0; z <(int) len; z++) { + fprintf(out, "%02X", output[z]); + } + fprintf(out, "\n"); + + /* forward the key */ + memcpy(key, output, hash_descriptor[x].hashsize); + } + XFREE(input); + fprintf(out, "\n"); + } + fclose(out); +} + +void omac_gen(void) +{ + unsigned char key[MAXBLOCKSIZE], output[MAXBLOCKSIZE], input[MAXBLOCKSIZE*2+2]; + int err, x, y, z, kl; + FILE *out; + unsigned long len; + + out = fopen("omac_tv.txt", "w"); + + fprintf(out, +"LTC_OMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are LTC_OMAC'ed. The initial key is\n" +"of the same format (length specified per cipher). The LTC_OMAC key in step N+1 is the LTC_OMAC output of\n" +"step N (repeated as required to fill the array).\n\n"); + + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + kl = cipher_descriptor[x].block_length; + + /* skip ciphers which do not have 64 or 128 bit block sizes */ + if (kl != 8 && kl != 16) continue; + + if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) { + kl = cipher_descriptor[x].max_key_length; + } + fprintf(out, "LTC_OMAC-%s (%d byte key)\n", cipher_descriptor[x].name, kl); + + /* initial key/block */ + for (y = 0; y < kl; y++) { + key[y] = (y & 255); + } + + for (y = 0; y <= (int)(cipher_descriptor[x].block_length*2); y++) { + for (z = 0; z < y; z++) { + input[z] = (unsigned char)(z & 255); + } + len = sizeof(output); + if ((err = omac_memory(x, key, kl, input, y, output, &len)) != CRYPT_OK) { + printf("Error omacing: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + fprintf(out, "%3d: ", y); + for (z = 0; z <(int)len; z++) { + fprintf(out, "%02X", output[z]); + } + fprintf(out, "\n"); + + /* forward the key */ + for (z = 0; z < kl; z++) { + key[z] = output[z % len]; + } + } + fprintf(out, "\n"); + } + fclose(out); +} + +void pmac_gen(void) +{ + unsigned char key[MAXBLOCKSIZE], output[MAXBLOCKSIZE], input[MAXBLOCKSIZE*2+2]; + int err, x, y, z, kl; + FILE *out; + unsigned long len; + + out = fopen("pmac_tv.txt", "w"); + + fprintf(out, +"PMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are LTC_OMAC'ed. The initial key is\n" +"of the same format (length specified per cipher). The LTC_OMAC key in step N+1 is the LTC_OMAC output of\n" +"step N (repeated as required to fill the array).\n\n"); + + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + kl = cipher_descriptor[x].block_length; + + /* skip ciphers which do not have 64 or 128 bit block sizes */ + if (kl != 8 && kl != 16) continue; + + if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) { + kl = cipher_descriptor[x].max_key_length; + } + fprintf(out, "PMAC-%s (%d byte key)\n", cipher_descriptor[x].name, kl); + + /* initial key/block */ + for (y = 0; y < kl; y++) { + key[y] = (y & 255); + } + + for (y = 0; y <= (int)(cipher_descriptor[x].block_length*2); y++) { + for (z = 0; z < y; z++) { + input[z] = (unsigned char)(z & 255); + } + len = sizeof(output); + if ((err = pmac_memory(x, key, kl, input, y, output, &len)) != CRYPT_OK) { + printf("Error omacing: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + fprintf(out, "%3d: ", y); + for (z = 0; z <(int)len; z++) { + fprintf(out, "%02X", output[z]); + } + fprintf(out, "\n"); + + /* forward the key */ + for (z = 0; z < kl; z++) { + key[z] = output[z % len]; + } + } + fprintf(out, "\n"); + } + fclose(out); +} + +void eax_gen(void) +{ + int err, kl, x, y1, z; + FILE *out; + unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2], header[MAXBLOCKSIZE*2], + plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE]; + unsigned long len; + + out = fopen("eax_tv.txt", "w"); + fprintf(out, "EAX Test Vectors. Uses the 00010203...NN-1 pattern for header/nonce/plaintext/key. The outputs\n" + "are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous\n" + "step repeated sufficiently.\n\n"); + + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + kl = cipher_descriptor[x].block_length; + + /* skip ciphers which do not have 64 or 128 bit block sizes */ + if (kl != 8 && kl != 16) continue; + + if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) { + kl = cipher_descriptor[x].max_key_length; + } + fprintf(out, "EAX-%s (%d byte key)\n", cipher_descriptor[x].name, kl); + + /* the key */ + for (z = 0; z < kl; z++) { + key[z] = (z & 255); + } + + for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){ + for (z = 0; z < y1; z++) { + plaintext[z] = (unsigned char)(z & 255); + nonce[z] = (unsigned char)(z & 255); + header[z] = (unsigned char)(z & 255); + } + len = sizeof(tag); + if ((err = eax_encrypt_authenticate_memory(x, key, kl, nonce, y1, header, y1, plaintext, y1, plaintext, tag, &len)) != CRYPT_OK) { + printf("Error EAX'ing: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + fprintf(out, "%3d: ", y1); + for (z = 0; z < y1; z++) { + fprintf(out, "%02X", plaintext[z]); + } + fprintf(out, ", "); + for (z = 0; z <(int)len; z++) { + fprintf(out, "%02X", tag[z]); + } + fprintf(out, "\n"); + + /* forward the key */ + for (z = 0; z < kl; z++) { + key[z] = tag[z % len]; + } + } + fprintf(out, "\n"); + } + fclose(out); +} + +void ocb_gen(void) +{ + int err, kl, x, y1, z; + FILE *out; + unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2], + plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE]; + unsigned long len; + + out = fopen("ocb_tv.txt", "w"); + fprintf(out, "OCB Test Vectors. Uses the 00010203...NN-1 pattern for nonce/plaintext/key. The outputs\n" + "are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous\n" + "step repeated sufficiently. The nonce is fixed throughout.\n\n"); + + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + kl = cipher_descriptor[x].block_length; + + /* skip ciphers which do not have 64 or 128 bit block sizes */ + if (kl != 8 && kl != 16) continue; + + if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) { + kl = cipher_descriptor[x].max_key_length; + } + fprintf(out, "OCB-%s (%d byte key)\n", cipher_descriptor[x].name, kl); + + /* the key */ + for (z = 0; z < kl; z++) { + key[z] = (z & 255); + } + + /* fixed nonce */ + for (z = 0; z < cipher_descriptor[x].block_length; z++) { + nonce[z] = z; + } + + for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){ + for (z = 0; z < y1; z++) { + plaintext[z] = (unsigned char)(z & 255); + } + len = sizeof(tag); + if ((err = ocb_encrypt_authenticate_memory(x, key, kl, nonce, plaintext, y1, plaintext, tag, &len)) != CRYPT_OK) { + printf("Error OCB'ing: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + fprintf(out, "%3d: ", y1); + for (z = 0; z < y1; z++) { + fprintf(out, "%02X", plaintext[z]); + } + fprintf(out, ", "); + for (z = 0; z <(int)len; z++) { + fprintf(out, "%02X", tag[z]); + } + fprintf(out, "\n"); + + /* forward the key */ + for (z = 0; z < kl; z++) { + key[z] = tag[z % len]; + } + } + fprintf(out, "\n"); + } + fclose(out); +} + + +void ccm_gen(void) +{ + int err, kl, x, y1, z; + FILE *out; + unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2], + plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE]; + unsigned long len; + + out = fopen("ccm_tv.txt", "w"); + fprintf(out, "CCM Test Vectors. Uses the 00010203...NN-1 pattern for nonce/header/plaintext/key. The outputs\n" + "are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous\n" + "step repeated sufficiently. The nonce is fixed throughout at 13 bytes 000102...\n\n"); + + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + kl = cipher_descriptor[x].block_length; + + /* skip ciphers which do not have 128 bit block sizes */ + if (kl != 16) continue; + + if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) { + kl = cipher_descriptor[x].max_key_length; + } + fprintf(out, "CCM-%s (%d byte key)\n", cipher_descriptor[x].name, kl); + + /* the key */ + for (z = 0; z < kl; z++) { + key[z] = (z & 255); + } + + /* fixed nonce */ + for (z = 0; z < cipher_descriptor[x].block_length; z++) { + nonce[z] = z; + } + + for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){ + for (z = 0; z < y1; z++) { + plaintext[z] = (unsigned char)(z & 255); + } + len = sizeof(tag); + if ((err = ccm_memory(x, key, kl, NULL, nonce, 13, plaintext, y1, plaintext, y1, plaintext, tag, &len, CCM_ENCRYPT)) != CRYPT_OK) { + printf("Error CCM'ing: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + fprintf(out, "%3d: ", y1); + for (z = 0; z < y1; z++) { + fprintf(out, "%02X", plaintext[z]); + } + fprintf(out, ", "); + for (z = 0; z <(int)len; z++) { + fprintf(out, "%02X", tag[z]); + } + fprintf(out, "\n"); + + /* forward the key */ + for (z = 0; z < kl; z++) { + key[z] = tag[z % len]; + } + } + fprintf(out, "\n"); + } + fclose(out); +} + +void gcm_gen(void) +{ + int err, kl, x, y1, z; + FILE *out; + unsigned char key[MAXBLOCKSIZE], plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE]; + unsigned long len; + + out = fopen("gcm_tv.txt", "w"); + fprintf(out, "GCM Test Vectors. Uses the 00010203...NN-1 pattern for nonce/header/plaintext/key. The outputs\n" + "are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous\n" + "step repeated sufficiently. The nonce is fixed throughout at 13 bytes 000102...\n\n"); + + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + kl = cipher_descriptor[x].block_length; + + /* skip ciphers which do not have 128 bit block sizes */ + if (kl != 16) continue; + + if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) { + kl = cipher_descriptor[x].max_key_length; + } + fprintf(out, "GCM-%s (%d byte key)\n", cipher_descriptor[x].name, kl); + + /* the key */ + for (z = 0; z < kl; z++) { + key[z] = (z & 255); + } + + for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){ + for (z = 0; z < y1; z++) { + plaintext[z] = (unsigned char)(z & 255); + } + len = sizeof(tag); + if ((err = gcm_memory(x, key, kl, plaintext, y1, plaintext, y1, plaintext, y1, plaintext, tag, &len, GCM_ENCRYPT)) != CRYPT_OK) { + printf("Error GCM'ing: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + fprintf(out, "%3d: ", y1); + for (z = 0; z < y1; z++) { + fprintf(out, "%02X", plaintext[z]); + } + fprintf(out, ", "); + for (z = 0; z <(int)len; z++) { + fprintf(out, "%02X", tag[z]); + } + fprintf(out, "\n"); + + /* forward the key */ + for (z = 0; z < kl; z++) { + key[z] = tag[z % len]; + } + } + fprintf(out, "\n"); + } + fclose(out); +} + +void base64_gen(void) +{ + FILE *out; + unsigned char dst[256], src[32]; + unsigned long x, y, len; + + out = fopen("base64_tv.txt", "w"); + fprintf(out, "Base64 vectors. These are the base64 encodings of the strings 00,01,02...NN-1\n\n"); + for (x = 0; x <= 32; x++) { + for (y = 0; y < x; y++) { + src[y] = y; + } + len = sizeof(dst); + base64_encode(src, x, dst, &len); + fprintf(out, "%2lu: %s\n", x, dst); + } + fclose(out); +} + +void math_gen(void) +{ +} + +void ecc_gen(void) +{ + FILE *out; + unsigned char str[512]; + void *k, *order, *modulus; + ecc_point *G, *R; + int x; + + out = fopen("ecc_tv.txt", "w"); + fprintf(out, "ecc vectors. These are for kG for k=1,3,9,27,...,3**n until k > order of the curve outputs are triplets\n\n"); + G = ltc_ecc_new_point(); + R = ltc_ecc_new_point(); + mp_init(&k); + mp_init(&order); + mp_init(&modulus); + + for (x = 0; ltc_ecc_sets[x].size != 0; x++) { + fprintf(out, "ECC-%d\n", ltc_ecc_sets[x].size*8); + mp_set(k, 1); + + mp_read_radix(order, (char *)ltc_ecc_sets[x].order, 16); + mp_read_radix(modulus, (char *)ltc_ecc_sets[x].prime, 16); + mp_read_radix(G->x, (char *)ltc_ecc_sets[x].Gx, 16); + mp_read_radix(G->y, (char *)ltc_ecc_sets[x].Gy, 16); + mp_set(G->z, 1); + + while (mp_cmp(k, order) == LTC_MP_LT) { + ltc_mp.ecc_ptmul(k, G, R, modulus, 1); + mp_tohex(k, (char*)str); fprintf(out, "%s, ", (char*)str); + mp_tohex(R->x, (char*)str); fprintf(out, "%s, ", (char*)str); + mp_tohex(R->y, (char*)str); fprintf(out, "%s\n", (char*)str); + mp_mul_d(k, 3, k); + } + } + mp_clear_multi(k, order, modulus, NULL); + ltc_ecc_del_point(G); + ltc_ecc_del_point(R); + fclose(out); +} + +void lrw_gen(void) +{ + FILE *out; + unsigned char tweak[16], key[16], iv[16], buf[1024]; + int x, y, err; + symmetric_LRW lrw; + + /* initialize default key and tweak */ + for (x = 0; x < 16; x++) { + tweak[x] = key[x] = iv[x] = x; + } + + out = fopen("lrw_tv.txt", "w"); + for (x = 16; x < (int)(sizeof(buf)); x += 16) { + if ((err = lrw_start(find_cipher("aes"), iv, key, 16, tweak, 0, &lrw)) != CRYPT_OK) { + fprintf(stderr, "Error starting LRW-AES: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + + /* encrypt incremental */ + for (y = 0; y < x; y++) { + buf[y] = y & 255; + } + + if ((err = lrw_encrypt(buf, buf, x, &lrw)) != CRYPT_OK) { + fprintf(stderr, "Error encrypting with LRW-AES: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + + /* display it */ + fprintf(out, "%d:", x); + for (y = 0; y < x; y++) { + fprintf(out, "%02x", buf[y]); + } + fprintf(out, "\n"); + + /* reset IV */ + if ((err = lrw_setiv(iv, 16, &lrw)) != CRYPT_OK) { + fprintf(stderr, "Error setting IV: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + + /* copy new tweak, iv and key */ + for (y = 0; y < 16; y++) { + key[y] = buf[y]; + iv[y] = buf[(y+16)%x]; + tweak[y] = buf[(y+32)%x]; + } + + if ((err = lrw_decrypt(buf, buf, x, &lrw)) != CRYPT_OK) { + fprintf(stderr, "Error decrypting with LRW-AES: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + + /* display it */ + fprintf(out, "%d:", x); + for (y = 0; y < x; y++) { + fprintf(out, "%02x", buf[y]); + } + fprintf(out, "\n"); + lrw_done(&lrw); + } + fclose(out); +} + +int main(void) +{ + reg_algs(); + printf("Generating hash vectors..."); fflush(stdout); hash_gen(); printf("done\n"); + printf("Generating cipher vectors..."); fflush(stdout); cipher_gen(); printf("done\n"); + printf("Generating LTC_HMAC vectors..."); fflush(stdout); hmac_gen(); printf("done\n"); + printf("Generating LTC_OMAC vectors..."); fflush(stdout); omac_gen(); printf("done\n"); + printf("Generating PMAC vectors..."); fflush(stdout); pmac_gen(); printf("done\n"); + printf("Generating EAX vectors..."); fflush(stdout); eax_gen(); printf("done\n"); + printf("Generating OCB vectors..."); fflush(stdout); ocb_gen(); printf("done\n"); + printf("Generating CCM vectors..."); fflush(stdout); ccm_gen(); printf("done\n"); + printf("Generating GCM vectors..."); fflush(stdout); gcm_gen(); printf("done\n"); + printf("Generating LTC_BASE64 vectors..."); fflush(stdout); base64_gen(); printf("done\n"); + printf("Generating MATH vectors..."); fflush(stdout); math_gen(); printf("done\n"); + printf("Generating ECC vectors..."); fflush(stdout); ecc_gen(); printf("done\n"); + printf("Generating LRW vectors..."); fflush(stdout); lrw_gen(); printf("done\n"); + return 0; +} + +/* $Source: /cvs/libtom/libtomcrypt/demos/tv_gen.c,v $ */ +/* $Revision: 1.21 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/doc/crypt.pdf b/xmhf-64/xmhf/third-party/libtomcrypt/doc/crypt.pdf new file mode 100644 index 0000000000..b4668a99db Binary files /dev/null and b/xmhf-64/xmhf/third-party/libtomcrypt/doc/crypt.pdf differ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/doc/footer.html b/xmhf-64/xmhf/third-party/libtomcrypt/doc/footer.html new file mode 100644 index 0000000000..26e169107e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/doc/footer.html @@ -0,0 +1,10 @@ +
+Code by Tom
+Docs using doxygen + + + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/doc/header.html b/xmhf-64/xmhf/third-party/libtomcrypt/doc/header.html new file mode 100644 index 0000000000..231475d1de --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/doc/header.html @@ -0,0 +1,12 @@ + + +LibTomCrypt: Main Page + + + + + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/filter.pl b/xmhf-64/xmhf/third-party/libtomcrypt/filter.pl new file mode 100644 index 0000000000..11ba62fba6 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/filter.pl @@ -0,0 +1,30 @@ +#!/usr/bin/perl + +# we want to filter every between START_INS and END_INS out and then insert crap from another file (this is fun) + +$dst = shift; +$ins = shift; + +open(SRC,"<$dst"); +open(INS,"<$ins"); +open(TMP,">tmp.delme"); + +$l = 0; +while () { + if ($_ =~ /START_INS/) { + print TMP $_; + $l = 1; + while () { + print TMP $_; + } + close INS; + } elsif ($_ =~ /END_INS/) { + print TMP $_; + $l = 0; + } elsif ($l == 0) { + print TMP $_; + } +} + +close TMP; +close SRC; diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/fixupind.pl b/xmhf-64/xmhf/third-party/libtomcrypt/fixupind.pl new file mode 100644 index 0000000000..543ae967d8 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/fixupind.pl @@ -0,0 +1,11 @@ +open(IN,"crypt.ind.tmp"); +$a = ; +print OUT "$a\n\\addcontentsline{toc}{chapter}{Index}\n"; +while () { + print OUT $_; +} +close OUT; +close IN; +system("mv -f crypt.ind.tmp crypt.ind"); + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/genlist.sh b/xmhf-64/xmhf/third-party/libtomcrypt/genlist.sh new file mode 100644 index 0000000000..03e13b3fc2 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/genlist.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# aes_tab.o is a pseudo object as it's made from aes.o and MPI is optional +export a=`echo -n "src/ciphers/aes/aes_enc.o " ; find . -type f | sort | grep "[.]/src" | grep "[.]c" | grep -v "sha224" | grep -v "sha384" | grep -v "aes_tab" | grep -v "twofish_tab" | grep -v "whirltab" | grep -v "dh_sys" | grep -v "ecc_sys" | grep -v "mpi[.]c" | grep -v "sober128tab" | sed -e 'sE\./EE' | sed -e 's/\.c/\.o/' | xargs` +perl ./parsenames.pl OBJECTS "$a" +export a=`find . -type f | grep [.]/src | grep [.]h | sed -e 'se\./ee' | xargs` +perl ./parsenames.pl HEADERS "$a" + +# $Source: /cvs/libtom/libtomcrypt/genlist.sh,v $ +# $Revision: 1.4 $ +# $Date: 2005/07/17 23:15:12 $ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/libtomcrypt.dsp b/xmhf-64/xmhf/third-party/libtomcrypt/libtomcrypt.dsp new file mode 100644 index 0000000000..a6dbe7a351 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/libtomcrypt.dsp @@ -0,0 +1,1634 @@ +# Microsoft Developer Studio Project File - Name="libtomcrypt" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=libtomcrypt - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "libtomcrypt.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "libtomcrypt.mak" CFG="libtomcrypt - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "libtomcrypt - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "libtomcrypt - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "libtomcrypt" +# PROP Scc_LocalPath "." +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "libtomcrypt - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "src\headers" /I "..\libtommath" /D "NDEBUG" /D "LTM_DESC" /D "WIN32" /D "_MBCS" /D "_LIB" /D "LTC_SOURCE" /D "USE_LTM" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"Release\tomcrypt.lib" + +!ELSEIF "$(CFG)" == "libtomcrypt - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src\headers" /I "..\libtommath" /D "_DEBUG" /D "LTM_DESC" /D "WIN32" /D "_MBCS" /D "_LIB" /D "LTC_SOURCE" /D "USE_LTM" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"Debug\tomcrypt.lib" + +!ENDIF + +# Begin Target + +# Name "libtomcrypt - Win32 Release" +# Name "libtomcrypt - Win32 Debug" +# Begin Group "ciphers" + +# PROP Default_Filter "" +# Begin Group "aes" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\ciphers\aes\aes.c + +!IF "$(CFG)" == "libtomcrypt - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build +InputPath=.\src\ciphers\aes\aes.c + +BuildCmds= \ + cl /nologo /MLd /W3 /Gm /GX /ZI /Od /I "src\headers" /I "..\libtommath" /D "_DEBUG" /D "LTM_DESC" /D "WIN32" /D "_MBCS" /D "_LIB" /D "LTC_SOURCE" /D "USE_LTM" /Fp"Release/libtomcrypt.pch" /YX /Fo"Release/" /Fd"Release/" /FD /GZ /c $(InputPath) \ + cl /nologo /DENCRYPT_ONLY /MLd /W3 /Gm /GX /ZI /Od /I "src\headers" /I "..\libtommath" /D "_DEBUG" /D "LTM_DESC" /D "WIN32" /D "_MBCS" /D "_LIB" /D "LTC_SOURCE" /D "USE_LTM" /Fp"Release/libtomcrypt.pch" /YX /Fo"Release/aes_enc.obj" /Fd"Release/" /FD /GZ /c $(InputPath) \ + + +"Release/aes.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"Release/aes_enc.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) +# End Custom Build + +!ELSEIF "$(CFG)" == "libtomcrypt - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build +InputPath=.\src\ciphers\aes\aes.c + +BuildCmds= \ + cl /nologo /MLd /W3 /Gm /GX /ZI /Od /I "src\headers" /I "..\libtommath" /D "_DEBUG" /D "LTM_DESC" /D "WIN32" /D "_MBCS" /D "_LIB" /D "LTC_SOURCE" /D "USE_LTM" /Fp"Debug/libtomcrypt.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c $(InputPath) \ + cl /nologo /DENCRYPT_ONLY /MLd /W3 /Gm /GX /ZI /Od /I "src\headers" /I "..\libtommath" /D "_DEBUG" /D "LTM_DESC" /D "WIN32" /D "_MBCS" /D "_LIB" /D "LTC_SOURCE" /D "USE_LTM" /Fp"Debug/libtomcrypt.pch" /YX /Fo"Debug/aes_enc.obj" /Fd"Debug/" /FD /GZ /c $(InputPath) \ + + +"Debug/aes.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"Debug/aes_enc.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\src\ciphers\aes\aes_tab.c +# PROP Exclude_From_Build 1 +# End Source File +# End Group +# Begin Group "safer" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\ciphers\safer\safer.c +# End Source File +# Begin Source File + +SOURCE=.\src\ciphers\safer\safer_tab.c +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\src\ciphers\safer\saferp.c +# End Source File +# End Group +# Begin Group "twofish" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\ciphers\twofish\twofish.c +# End Source File +# Begin Source File + +SOURCE=.\src\ciphers\twofish\twofish_tab.c +# PROP Exclude_From_Build 1 +# End Source File +# End Group +# Begin Source File + +SOURCE=.\src\ciphers\anubis.c +# End Source File +# Begin Source File + +SOURCE=.\src\ciphers\blowfish.c +# End Source File +# Begin Source File + +SOURCE=.\src\ciphers\cast5.c +# End Source File +# Begin Source File + +SOURCE=.\src\ciphers\des.c +# End Source File +# Begin Source File + +SOURCE=.\src\ciphers\kasumi.c +# End Source File +# Begin Source File + +SOURCE=.\src\ciphers\khazad.c +# End Source File +# Begin Source File + +SOURCE=.\src\ciphers\kseed.c +# End Source File +# Begin Source File + +SOURCE=.\src\ciphers\multi2.c +# End Source File +# Begin Source File + +SOURCE=.\src\ciphers\noekeon.c +# End Source File +# Begin Source File + +SOURCE=.\src\ciphers\rc2.c +# End Source File +# Begin Source File + +SOURCE=.\src\ciphers\rc5.c +# End Source File +# Begin Source File + +SOURCE=.\src\ciphers\rc6.c +# End Source File +# Begin Source File + +SOURCE=.\src\ciphers\skipjack.c +# End Source File +# Begin Source File + +SOURCE=.\src\ciphers\xtea.c +# End Source File +# End Group +# Begin Group "encauth" + +# PROP Default_Filter "" +# Begin Group "ccm" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\encauth\ccm\ccm_memory.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\ccm\ccm_test.c +# End Source File +# End Group +# Begin Group "eax" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\encauth\eax\eax_addheader.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\eax\eax_decrypt.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\eax\eax_decrypt_verify_memory.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\eax\eax_done.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\eax\eax_encrypt.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\eax\eax_encrypt_authenticate_memory.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\eax\eax_init.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\eax\eax_test.c +# End Source File +# End Group +# Begin Group "gcm" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\encauth\gcm\gcm_add_aad.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\gcm\gcm_add_iv.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\gcm\gcm_done.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\gcm\gcm_gf_mult.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\gcm\gcm_init.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\gcm\gcm_memory.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\gcm\gcm_mult_h.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\gcm\gcm_process.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\gcm\gcm_reset.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\gcm\gcm_test.c +# End Source File +# End Group +# Begin Group "ocb" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\encauth\ocb\ocb_decrypt.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\ocb\ocb_decrypt_verify_memory.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\ocb\ocb_done_decrypt.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\ocb\ocb_done_encrypt.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\ocb\ocb_encrypt.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\ocb\ocb_encrypt_authenticate_memory.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\ocb\ocb_init.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\ocb\ocb_ntz.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\ocb\ocb_shift_xor.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\ocb\ocb_test.c +# End Source File +# Begin Source File + +SOURCE=.\src\encauth\ocb\s_ocb_done.c +# End Source File +# End Group +# End Group +# Begin Group "hashes" + +# PROP Default_Filter "" +# Begin Group "helper" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\hashes\helper\hash_file.c +# End Source File +# Begin Source File + +SOURCE=.\src\hashes\helper\hash_filehandle.c +# End Source File +# Begin Source File + +SOURCE=.\src\hashes\helper\hash_memory.c +# End Source File +# Begin Source File + +SOURCE=.\src\hashes\helper\hash_memory_multi.c +# End Source File +# End Group +# Begin Group "sha2" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\hashes\sha2\sha224.c +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\src\hashes\sha2\sha256.c +# End Source File +# Begin Source File + +SOURCE=.\src\hashes\sha2\sha384.c +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\src\hashes\sha2\sha512.c +# End Source File +# End Group +# Begin Group "whirl" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\hashes\whirl\whirl.c +# End Source File +# Begin Source File + +SOURCE=.\src\hashes\whirl\whirltab.c +# PROP Exclude_From_Build 1 +# End Source File +# End Group +# Begin Source File + +SOURCE=.\src\hashes\chc\chc.c +# End Source File +# Begin Source File + +SOURCE=.\src\hashes\md2.c +# End Source File +# Begin Source File + +SOURCE=.\src\hashes\md4.c +# End Source File +# Begin Source File + +SOURCE=.\src\hashes\md5.c +# End Source File +# Begin Source File + +SOURCE=.\src\hashes\rmd128.c +# End Source File +# Begin Source File + +SOURCE=.\src\hashes\rmd160.c +# End Source File +# Begin Source File + +SOURCE=.\src\hashes\rmd256.c +# End Source File +# Begin Source File + +SOURCE=.\src\hashes\rmd320.c +# End Source File +# Begin Source File + +SOURCE=.\src\hashes\sha1.c +# End Source File +# Begin Source File + +SOURCE=.\src\hashes\tiger.c +# End Source File +# End Group +# Begin Group "mac" + +# PROP Default_Filter "" +# Begin Group "f9" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\mac\f9\f9_done.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\f9\f9_file.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\f9\f9_init.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\f9\f9_memory.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\f9\f9_memory_multi.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\f9\f9_process.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\f9\f9_test.c +# End Source File +# End Group +# Begin Group "hmac" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\mac\hmac\hmac_done.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\hmac\hmac_file.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\hmac\hmac_init.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\hmac\hmac_memory.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\hmac\hmac_memory_multi.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\hmac\hmac_process.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\hmac\hmac_test.c +# End Source File +# End Group +# Begin Group "omac" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\mac\omac\omac_done.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\omac\omac_file.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\omac\omac_init.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\omac\omac_memory.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\omac\omac_memory_multi.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\omac\omac_process.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\omac\omac_test.c +# End Source File +# End Group +# Begin Group "pelican" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\mac\pelican\pelican.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\pelican\pelican_memory.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\pelican\pelican_test.c +# End Source File +# End Group +# Begin Group "pmac" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\mac\pmac\pmac_done.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\pmac\pmac_file.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\pmac\pmac_init.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\pmac\pmac_memory.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\pmac\pmac_memory_multi.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\pmac\pmac_ntz.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\pmac\pmac_process.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\pmac\pmac_shift_xor.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\pmac\pmac_test.c +# End Source File +# End Group +# Begin Group "xcbc" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\mac\xcbc\xcbc_done.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\xcbc\xcbc_file.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\xcbc\xcbc_init.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\xcbc\xcbc_memory.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\xcbc\xcbc_memory_multi.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\xcbc\xcbc_process.c +# End Source File +# Begin Source File + +SOURCE=.\src\mac\xcbc\xcbc_test.c +# End Source File +# End Group +# End Group +# Begin Group "math" + +# PROP Default_Filter "" +# Begin Group "fp" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\math\fp\ltc_ecc_fp_mulmod.c +# End Source File +# End Group +# Begin Source File + +SOURCE=.\src\math\gmp_desc.c +# End Source File +# Begin Source File + +SOURCE=.\src\math\ltm_desc.c +# End Source File +# Begin Source File + +SOURCE=.\src\math\multi.c +# End Source File +# Begin Source File + +SOURCE=.\src\math\rand_prime.c +# End Source File +# Begin Source File + +SOURCE=.\src\math\tfm_desc.c +# End Source File +# End Group +# Begin Group "misc" + +# PROP Default_Filter "" +# Begin Group "base64" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\misc\base64\base64_decode.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\base64\base64_encode.c +# End Source File +# End Group +# Begin Group "crypt" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt_argchk.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt_cipher_descriptor.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt_cipher_is_valid.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt_find_cipher.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt_find_cipher_any.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt_find_cipher_id.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt_find_hash.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt_find_hash_any.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt_find_hash_id.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt_find_hash_oid.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt_find_prng.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt_fsa.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt_hash_descriptor.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt_hash_is_valid.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt_ltc_mp_descriptor.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt_prng_descriptor.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt_prng_is_valid.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt_register_cipher.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt_register_hash.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt_register_prng.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt_unregister_cipher.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt_unregister_hash.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\crypt\crypt_unregister_prng.c +# End Source File +# End Group +# Begin Group "pkcs" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\misc\pkcs5\pkcs_5_1.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\pkcs5\pkcs_5_2.c +# End Source File +# End Group +# Begin Source File + +SOURCE=.\src\misc\burn_stack.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\error_to_string.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\zeromem.c +# End Source File +# End Group +# Begin Group "modes" + +# PROP Default_Filter "" +# Begin Group "cbc" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\modes\cbc\cbc_decrypt.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\cbc\cbc_done.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\cbc\cbc_encrypt.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\cbc\cbc_getiv.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\cbc\cbc_setiv.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\cbc\cbc_start.c +# End Source File +# End Group +# Begin Group "cfb" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\modes\cfb\cfb_decrypt.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\cfb\cfb_done.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\cfb\cfb_encrypt.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\cfb\cfb_getiv.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\cfb\cfb_setiv.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\cfb\cfb_start.c +# End Source File +# End Group +# Begin Group "ctr" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\modes\ctr\ctr_decrypt.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\ctr\ctr_done.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\ctr\ctr_encrypt.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\ctr\ctr_getiv.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\ctr\ctr_setiv.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\ctr\ctr_start.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\ctr\ctr_test.c +# End Source File +# End Group +# Begin Group "ecb" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\modes\ecb\ecb_decrypt.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\ecb\ecb_done.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\ecb\ecb_encrypt.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\ecb\ecb_start.c +# End Source File +# End Group +# Begin Group "f8" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\modes\f8\f8_decrypt.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\f8\f8_done.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\f8\f8_encrypt.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\f8\f8_getiv.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\f8\f8_setiv.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\f8\f8_start.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\f8\f8_test_mode.c +# End Source File +# End Group +# Begin Group "lrw" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\modes\lrw\lrw_decrypt.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\lrw\lrw_done.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\lrw\lrw_encrypt.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\lrw\lrw_getiv.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\lrw\lrw_process.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\lrw\lrw_setiv.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\lrw\lrw_start.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\lrw\lrw_test.c +# End Source File +# End Group +# Begin Group "ofb" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\modes\ofb\ofb_decrypt.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\ofb\ofb_done.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\ofb\ofb_encrypt.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\ofb\ofb_getiv.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\ofb\ofb_setiv.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\ofb\ofb_start.c +# End Source File +# End Group +# Begin Group "xts" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\modes\xts\xts_decrypt.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\xts\xts_done.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\xts\xts_encrypt.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\xts\xts_init.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\xts\xts_mult_x.c +# End Source File +# Begin Source File + +SOURCE=.\src\modes\xts\xts_test.c +# End Source File +# End Group +# End Group +# Begin Group "pk" + +# PROP Default_Filter "" +# Begin Group "asn1" + +# PROP Default_Filter "" +# Begin Group "der" + +# PROP Default_Filter "" +# Begin Group "bit" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\pk\asn1\der\bit\der_decode_bit_string.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\bit\der_encode_bit_string.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\bit\der_length_bit_string.c +# End Source File +# End Group +# Begin Group "boolean" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\pk\asn1\der\boolean\der_decode_boolean.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\boolean\der_encode_boolean.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\boolean\der_length_boolean.c +# End Source File +# End Group +# Begin Group "choice" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\pk\asn1\der\choice\der_decode_choice.c +# End Source File +# End Group +# Begin Group "ia5" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\pk\asn1\der\ia5\der_decode_ia5_string.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\ia5\der_encode_ia5_string.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\ia5\der_length_ia5_string.c +# End Source File +# End Group +# Begin Group "integer" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\pk\asn1\der\integer\der_decode_integer.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\integer\der_encode_integer.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\integer\der_length_integer.c +# End Source File +# End Group +# Begin Group "object_identifier" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\pk\asn1\der\object_identifier\der_decode_object_identifier.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\object_identifier\der_encode_object_identifier.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\object_identifier\der_length_object_identifier.c +# End Source File +# End Group +# Begin Group "octet" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\pk\asn1\der\octet\der_decode_octet_string.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\octet\der_encode_octet_string.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\octet\der_length_octet_string.c +# End Source File +# End Group +# Begin Group "printable_string" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\pk\asn1\der\printable_string\der_decode_printable_string.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\printable_string\der_encode_printable_string.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\printable_string\der_length_printable_string.c +# End Source File +# End Group +# Begin Group "sequence" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\pk\asn1\der\sequence\der_decode_sequence_ex.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\sequence\der_decode_sequence_flexi.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\sequence\der_decode_sequence_multi.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\sequence\der_encode_sequence_ex.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\sequence\der_encode_sequence_multi.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\sequence\der_length_sequence.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\sequence\der_sequence_free.c +# End Source File +# End Group +# Begin Group "set" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\pk\asn1\der\set\der_encode_set.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\set\der_encode_setof.c +# End Source File +# End Group +# Begin Group "short_integer" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\pk\asn1\der\short_integer\der_decode_short_integer.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\short_integer\der_encode_short_integer.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\short_integer\der_length_short_integer.c +# End Source File +# End Group +# Begin Group "utctime" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\pk\asn1\der\utctime\der_decode_utctime.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\utctime\der_encode_utctime.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\utctime\der_length_utctime.c +# End Source File +# End Group +# Begin Group "utf8" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\pk\asn1\der\utf8\der_decode_utf8_string.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\utf8\der_encode_utf8_string.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\asn1\der\utf8\der_length_utf8_string.c +# End Source File +# End Group +# End Group +# End Group +# Begin Group "dsa" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\pk\dsa\dsa_decrypt_key.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\dsa\dsa_encrypt_key.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\dsa\dsa_export.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\dsa\dsa_free.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\dsa\dsa_import.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\dsa\dsa_make_key.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\dsa\dsa_shared_secret.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\dsa\dsa_sign_hash.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\dsa\dsa_verify_hash.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\dsa\dsa_verify_key.c +# End Source File +# End Group +# Begin Group "ecc" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\pk\ecc\ecc.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\ecc\ecc_ansi_x963_export.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\ecc\ecc_ansi_x963_import.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\ecc\ecc_decrypt_key.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\ecc\ecc_encrypt_key.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\ecc\ecc_export.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\ecc\ecc_free.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\ecc\ecc_get_size.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\ecc\ecc_import.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\ecc\ecc_make_key.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\ecc\ecc_shared_secret.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\ecc\ecc_sign_hash.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\ecc\ecc_sizes.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\ecc\ecc_test.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\ecc\ecc_verify_hash.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\ecc\ltc_ecc_is_valid_idx.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\ecc\ltc_ecc_map.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\ecc\ltc_ecc_mul2add.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\ecc\ltc_ecc_mulmod.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\ecc\ltc_ecc_mulmod_timing.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\ecc\ltc_ecc_points.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\ecc\ltc_ecc_projective_add_point.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\ecc\ltc_ecc_projective_dbl_point.c +# End Source File +# End Group +# Begin Group "katja" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\pk\katja\katja_decrypt_key.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\katja\katja_encrypt_key.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\katja\katja_export.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\katja\katja_exptmod.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\katja\katja_free.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\katja\katja_import.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\katja\katja_make_key.c +# End Source File +# End Group +# Begin Group "pkcs1" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\pk\pkcs1\pkcs_1_i2osp.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\pkcs1\pkcs_1_mgf1.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\pkcs1\pkcs_1_oaep_decode.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\pkcs1\pkcs_1_oaep_encode.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\pkcs1\pkcs_1_os2ip.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\pkcs1\pkcs_1_pss_decode.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\pkcs1\pkcs_1_pss_encode.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\pkcs1\pkcs_1_v1_5_decode.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\pkcs1\pkcs_1_v1_5_encode.c +# End Source File +# End Group +# Begin Group "rsa" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\pk\rsa\rsa_decrypt_key.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\rsa\rsa_encrypt_key.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\rsa\rsa_export.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\rsa\rsa_exptmod.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\rsa\rsa_free.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\rsa\rsa_import.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\rsa\rsa_make_key.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\rsa\rsa_sign_hash.c +# End Source File +# Begin Source File + +SOURCE=.\src\pk\rsa\rsa_verify_hash.c +# End Source File +# End Group +# End Group +# Begin Group "prngs" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\prngs\fortuna.c +# End Source File +# Begin Source File + +SOURCE=.\src\prngs\rc4.c +# End Source File +# Begin Source File + +SOURCE=.\src\prngs\rng_get_bytes.c +# End Source File +# Begin Source File + +SOURCE=.\src\prngs\rng_make_prng.c +# End Source File +# Begin Source File + +SOURCE=.\src\prngs\sober128.c +# End Source File +# Begin Source File + +SOURCE=.\src\prngs\sober128tab.c +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\src\prngs\sprng.c +# End Source File +# Begin Source File + +SOURCE=.\src\prngs\yarrow.c +# End Source File +# End Group +# Begin Group "headers" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\headers\tomcrypt.h +# End Source File +# Begin Source File + +SOURCE=.\src\headers\tomcrypt_argchk.h +# End Source File +# Begin Source File + +SOURCE=.\src\headers\tomcrypt_cfg.h +# End Source File +# Begin Source File + +SOURCE=.\src\headers\tomcrypt_cipher.h +# End Source File +# Begin Source File + +SOURCE=.\src\headers\tomcrypt_custom.h +# End Source File +# Begin Source File + +SOURCE=.\src\headers\tomcrypt_hash.h +# End Source File +# Begin Source File + +SOURCE=.\src\headers\tomcrypt_mac.h +# End Source File +# Begin Source File + +SOURCE=.\src\headers\tomcrypt_macros.h +# End Source File +# Begin Source File + +SOURCE=.\src\headers\tomcrypt_math.h +# End Source File +# Begin Source File + +SOURCE=.\src\headers\tomcrypt_misc.h +# End Source File +# Begin Source File + +SOURCE=.\src\headers\tomcrypt_pk.h +# End Source File +# Begin Source File + +SOURCE=.\src\headers\tomcrypt_pkcs.h +# End Source File +# Begin Source File + +SOURCE=.\src\headers\tomcrypt_prng.h +# End Source File +# End Group +# End Target +# End Project diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/makefile b/xmhf-64/xmhf/third-party/libtomcrypt/makefile new file mode 100644 index 0000000000..d41acf3e92 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/makefile @@ -0,0 +1,407 @@ +# MAKEFILE for linux GCC +# +# Tom St Denis +# Modified by Clay Culver + +srcdir := $(dir $(lastword $(MAKEFILE_LIST))) +vpath %.c $(srcdir) +vpath %.h $(srcdir) + +# The version +VERSION=1.17 + +PLATFORM := $(shell uname | sed -e 's/_.*//') + +# Compiler and Linker Names +#CC=gcc +#LD=ld + +# Archiver [makes .a files] +#AR=ar +#ARFLAGS=r + +ifndef MAKE + MAKE=make +endif + +# ranlib tools +ifndef RANLIB +ifeq ($(PLATFORM), Darwin) +RANLIB=ranlib -c +else +RANLIB=ranlib +endif +endif + +# Compilation flags. Note the += does not write over the user's CFLAGS! +CFLAGS += -c -I./testprof/ -I$(srcdir)src/headers/ -DLTC_SOURCE + +ifneq ($(CC), armcc) +CFLAGS += -Wall -Wsign-compare -W -Wshadow -Wno-unused-parameter +endif + +# additional warnings (newer GCC 3.4 and higher) +ifdef GCC_34 +CFLAGS += -Wsystem-headers -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wmissing-prototypes \ + -Wmissing-declarations -Wpointer-arith +endif + +ifndef IGNORE_SPEED + +# optimize for SPEED +CFLAGS += -O3 -funroll-loops + +# add -fomit-frame-pointer. hinders debugging! +CFLAGS += -fomit-frame-pointer + +# optimize for SIZE +#CFLAGS += -Os -DLTC_SMALL_CODE + +endif + +# older GCCs can't handle the "rotate with immediate" ROLc/RORc/etc macros +# define this to help +#CFLAGS += -DLTC_NO_ROLC + +# compile for DEBUGING (required for ccmalloc checking!!!) +#CFLAGS += -g3 -DLTC_NO_ASM + +#Output filenames for various targets. +ifndef LIBNAME + LIBNAME=libtomcrypt.a +endif +ifndef LIBTEST + LIBTEST=libtomcrypt_prof.a +endif +LIBTEST_S=$(LIBTEST) + +HASH=hashsum +CRYPT=encrypt +SMALL=small +PROF=x86_prof +TV=tv_gen +MULTI=multi +TIMING=timing +TEST=test + +#LIBPATH-The directory for libtomcrypt to be installed to. +#INCPATH-The directory to install the header files for libtomcrypt. +#DATAPATH-The directory to install the pdf docs. +ifndef DESTDIR + DESTDIR= +endif + +ifndef LIBPATH + LIBPATH=/usr/lib +endif +ifndef INCPATH + INCPATH=/usr/include +endif +ifndef DATAPATH + DATAPATH=/usr/share/doc/libtomcrypt/pdf +endif + +#Who do we install as? +ifdef INSTALL_USER +USER=$(INSTALL_USER) +else +USER=root +endif + +ifdef INSTALL_GROUP +GROUP=$(INSTALL_GROUP) +else +GROUP=wheel +endif + +#List of objects to compile. +#START_INS +OBJECTS=src/ciphers/aes/aes_enc.o src/ciphers/aes/aes.o src/ciphers/anubis.o src/ciphers/blowfish.o \ +src/ciphers/cast5.o src/ciphers/des.o src/ciphers/kasumi.o src/ciphers/khazad.o src/ciphers/kseed.o \ +src/ciphers/multi2.o src/ciphers/noekeon.o src/ciphers/rc2.o src/ciphers/rc5.o src/ciphers/rc6.o \ +src/ciphers/safer/safer.o src/ciphers/safer/saferp.o src/ciphers/safer/safer_tab.o \ +src/ciphers/skipjack.o src/ciphers/twofish/twofish.o src/ciphers/xtea.o src/encauth/ccm/ccm_memory.o \ +src/encauth/ccm/ccm_test.o src/encauth/eax/eax_addheader.o src/encauth/eax/eax_decrypt.o \ +src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o \ +src/encauth/eax/eax_encrypt_authenticate_memory.o src/encauth/eax/eax_encrypt.o \ +src/encauth/eax/eax_init.o src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o \ +src/encauth/gcm/gcm_add_iv.o src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o \ +src/encauth/gcm/gcm_init.o src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_mult_h.o \ +src/encauth/gcm/gcm_process.o src/encauth/gcm/gcm_reset.o src/encauth/gcm/gcm_test.o \ +src/encauth/ocb/ocb_decrypt.o src/encauth/ocb/ocb_decrypt_verify_memory.o \ +src/encauth/ocb/ocb_done_decrypt.o src/encauth/ocb/ocb_done_encrypt.o \ +src/encauth/ocb/ocb_encrypt_authenticate_memory.o src/encauth/ocb/ocb_encrypt.o \ +src/encauth/ocb/ocb_init.o src/encauth/ocb/ocb_ntz.o src/encauth/ocb/ocb_shift_xor.o \ +src/encauth/ocb/ocb_test.o src/encauth/ocb/s_ocb_done.o src/hashes/chc/chc.o \ +src/hashes/helper/hash_file.o src/hashes/helper/hash_filehandle.o src/hashes/helper/hash_memory.o \ +src/hashes/helper/hash_memory_multi.o src/hashes/md2.o src/hashes/md4.o src/hashes/md5.o \ +src/hashes/rmd128.o src/hashes/rmd160.o src/hashes/rmd256.o src/hashes/rmd320.o src/hashes/sha1.o \ +src/hashes/sha2/sha256.o src/hashes/sha2/sha512.o src/hashes/tiger.o src/hashes/whirl/whirl.o \ +src/mac/f9/f9_done.o src/mac/f9/f9_file.o src/mac/f9/f9_init.o src/mac/f9/f9_memory.o \ +src/mac/f9/f9_memory_multi.o src/mac/f9/f9_process.o src/mac/f9/f9_test.o src/mac/hmac/hmac_done.o \ +src/mac/hmac/hmac_file.o src/mac/hmac/hmac_init.o src/mac/hmac/hmac_memory.o \ +src/mac/hmac/hmac_memory_multi.o src/mac/hmac/hmac_process.o src/mac/hmac/hmac_test.o \ +src/mac/omac/omac_done.o src/mac/omac/omac_file.o src/mac/omac/omac_init.o src/mac/omac/omac_memory.o \ +src/mac/omac/omac_memory_multi.o src/mac/omac/omac_process.o src/mac/omac/omac_test.o \ +src/mac/pelican/pelican.o src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o \ +src/mac/pmac/pmac_done.o src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \ +src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o src/mac/pmac/pmac_process.o \ +src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/mac/xcbc/xcbc_done.o \ +src/mac/xcbc/xcbc_file.o src/mac/xcbc/xcbc_init.o src/mac/xcbc/xcbc_memory.o \ +src/mac/xcbc/xcbc_memory_multi.o src/mac/xcbc/xcbc_process.o src/mac/xcbc/xcbc_test.o \ +src/math/fp/ltc_ecc_fp_mulmod.o src/math/gmp_desc.o src/math/ltm_desc.o src/math/multi.o \ +src/math/rand_prime.o src/math/tfm_desc.o src/misc/base64/base64_decode.o \ +src/misc/base64/base64_encode.o src/misc/burn_stack.o src/misc/crypt/crypt_argchk.o \ +src/misc/crypt/crypt.o src/misc/crypt/crypt_cipher_descriptor.o src/misc/crypt/crypt_cipher_is_valid.o \ +src/misc/crypt/crypt_find_cipher_any.o src/misc/crypt/crypt_find_cipher.o \ +src/misc/crypt/crypt_find_cipher_id.o src/misc/crypt/crypt_find_hash_any.o \ +src/misc/crypt/crypt_find_hash.o src/misc/crypt/crypt_find_hash_id.o \ +src/misc/crypt/crypt_find_hash_oid.o src/misc/crypt/crypt_find_prng.o src/misc/crypt/crypt_fsa.o \ +src/misc/crypt/crypt_hash_descriptor.o src/misc/crypt/crypt_hash_is_valid.o \ +src/misc/crypt/crypt_ltc_mp_descriptor.o src/misc/crypt/crypt_prng_descriptor.o \ +src/misc/crypt/crypt_prng_is_valid.o src/misc/crypt/crypt_register_cipher.o \ +src/misc/crypt/crypt_register_hash.o src/misc/crypt/crypt_register_prng.o \ +src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \ +src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/pkcs5/pkcs_5_1.o \ +src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o \ +src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o \ +src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o \ +src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o \ +src/modes/cfb/cfb_start.o src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_done.o \ +src/modes/ctr/ctr_encrypt.o src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o \ +src/modes/ctr/ctr_start.o src/modes/ctr/ctr_test.o src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o \ +src/modes/ecb/ecb_encrypt.o src/modes/ecb/ecb_start.o src/modes/f8/f8_decrypt.o src/modes/f8/f8_done.o \ +src/modes/f8/f8_encrypt.o src/modes/f8/f8_getiv.o src/modes/f8/f8_setiv.o src/modes/f8/f8_start.o \ +src/modes/f8/f8_test_mode.o src/modes/lrw/lrw_decrypt.o src/modes/lrw/lrw_done.o \ +src/modes/lrw/lrw_encrypt.o src/modes/lrw/lrw_getiv.o src/modes/lrw/lrw_process.o \ +src/modes/lrw/lrw_setiv.o src/modes/lrw/lrw_start.o src/modes/lrw/lrw_test.o \ +src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o src/modes/ofb/ofb_encrypt.o \ +src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o src/modes/ofb/ofb_start.o \ +src/modes/xts/xts_decrypt.o src/modes/xts/xts_done.o src/modes/xts/xts_encrypt.o \ +src/modes/xts/xts_init.o src/modes/xts/xts_mult_x.o src/modes/xts/xts_test.o \ +src/pk/asn1/der/bit/der_decode_bit_string.o src/pk/asn1/der/bit/der_encode_bit_string.o \ +src/pk/asn1/der/bit/der_length_bit_string.o src/pk/asn1/der/boolean/der_decode_boolean.o \ +src/pk/asn1/der/boolean/der_encode_boolean.o src/pk/asn1/der/boolean/der_length_boolean.o \ +src/pk/asn1/der/choice/der_decode_choice.o src/pk/asn1/der/ia5/der_decode_ia5_string.o \ +src/pk/asn1/der/ia5/der_encode_ia5_string.o src/pk/asn1/der/ia5/der_length_ia5_string.o \ +src/pk/asn1/der/integer/der_decode_integer.o src/pk/asn1/der/integer/der_encode_integer.o \ +src/pk/asn1/der/integer/der_length_integer.o \ +src/pk/asn1/der/object_identifier/der_decode_object_identifier.o \ +src/pk/asn1/der/object_identifier/der_encode_object_identifier.o \ +src/pk/asn1/der/object_identifier/der_length_object_identifier.o \ +src/pk/asn1/der/octet/der_decode_octet_string.o src/pk/asn1/der/octet/der_encode_octet_string.o \ +src/pk/asn1/der/octet/der_length_octet_string.o \ +src/pk/asn1/der/printable_string/der_decode_printable_string.o \ +src/pk/asn1/der/printable_string/der_encode_printable_string.o \ +src/pk/asn1/der/printable_string/der_length_printable_string.o \ +src/pk/asn1/der/sequence/der_decode_sequence_ex.o \ +src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \ +src/pk/asn1/der/sequence/der_decode_sequence_multi.o \ +src/pk/asn1/der/sequence/der_encode_sequence_ex.o \ +src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \ +src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/set/der_encode_set.o \ +src/pk/asn1/der/set/der_encode_setof.o src/pk/asn1/der/short_integer/der_decode_short_integer.o \ +src/pk/asn1/der/short_integer/der_encode_short_integer.o \ +src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \ +src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \ +src/pk/asn1/der/utf8/der_decode_utf8_string.o src/pk/asn1/der/utf8/der_encode_utf8_string.o \ +src/pk/asn1/der/utf8/der_length_utf8_string.o src/pk/dsa/dsa_decrypt_key.o \ +src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o \ +src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_shared_secret.o src/pk/dsa/dsa_sign_hash.o \ +src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc_ansi_x963_export.o \ +src/pk/ecc/ecc_ansi_x963_import.o src/pk/ecc/ecc.o src/pk/ecc/ecc_decrypt_key.o \ +src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_size.o \ +src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.o src/pk/ecc/ecc_shared_secret.o \ +src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o src/pk/ecc/ecc_verify_hash.o \ +src/pk/ecc/ltc_ecc_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o src/pk/ecc/ltc_ecc_mul2add.o \ +src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \ +src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \ +src/pk/katja/katja_decrypt_key.o src/pk/katja/katja_encrypt_key.o src/pk/katja/katja_export.o \ +src/pk/katja/katja_exptmod.o src/pk/katja/katja_free.o src/pk/katja/katja_import.o \ +src/pk/katja/katja_make_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \ +src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ +src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v1_5_decode.o \ +src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \ +src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \ +src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \ +src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \ +src/prngs/sprng.o src/prngs/yarrow.o + +HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \ +src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \ +src/headers/tomcrypt_pk.h src/headers/tomcrypt_hash.h src/headers/tomcrypt_math.h \ +src/headers/tomcrypt_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \ +src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h + +#END_INS + +TESTOBJECTS=demos/test.o +HASHOBJECTS=demos/hashsum.o +CRYPTOBJECTS=demos/encrypt.o +SMALLOBJECTS=demos/small.o +TVS=demos/tv_gen.o +MULTIS=demos/multi.o +TIMINGS=demos/timing.o +TESTS=demos/test.o + +#Files left over from making the crypt.pdf. +LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind *.out + +#Compressed filenames +COMPRESSED=crypt-$(VERSION).tar.bz2 crypt-$(VERSION).zip + +#The default rule for make builds the libtomcrypt library. +default:library + +#ciphers come in two flavours... enc+dec and enc +src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c + mkdir -p $(dir $@) + $(CC) -c $(CFLAGS) -DENCRYPT_ONLY $(CPPFLAGS) -o $@ $< + +#These are the rules to make certain object files. +src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c +src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c +src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c +src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c +src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c + +#This rule makes the libtomcrypt library. +library: $(LIBNAME) + +$(OBJECTS): $(HEADERS) + +testprof/$(LIBTEST): + cd testprof ; CFLAGS="$(CFLAGS)" LIBTEST_S=$(LIBTEST_S) $(MAKE) + +$(LIBNAME): $(OBJECTS) + $(AR) $(ARFLAGS) $@ $(OBJECTS) + $(RANLIB) $@ + +#This rule makes the hash program included with libtomcrypt +hashsum: library $(HASHOBJECTS) + $(CC) $(HASHOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(HASH) $(WARN) + +#makes the crypt program +crypt: library $(CRYPTOBJECTS) + $(CC) $(CRYPTOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(CRYPT) $(WARN) + +#makes the small program +small: library $(SMALLOBJECTS) + $(CC) $(SMALLOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(SMALL) $(WARN) + +tv_gen: library $(TVS) + $(CC) $(LDFLAGS) $(TVS) $(LIBNAME) $(EXTRALIBS) -o $(TV) + +multi: library $(MULTIS) + $(CC) $(MULTIS) $(LIBNAME) $(EXTRALIBS) -o $(MULTI) + +timing: library testprof/$(LIBTEST) $(TIMINGS) + $(CC) $(LDFLAGS) $(TIMINGS) testprof/$(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TIMING) + +test: library testprof/$(LIBTEST) $(TESTS) + $(CC) $(LDFLAGS) $(TESTS) testprof/$(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TEST) + +#This rule installs the library and the header files. This must be run +#as root in order to have a high enough permission to write to the correct +#directories and to set the owner and group to root. +ifndef NODOCS +install: library docs +else +install: library +endif + install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) + install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) + install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(DATAPATH) + install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH) + install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) +ifndef NODOCS + install -g $(GROUP) -o $(USER) doc/crypt.pdf $(DESTDIR)$(DATAPATH) +endif + +install_test: testprof/$(LIBTEST) + install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) + install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) + install -g $(GROUP) -o $(USER) testprof/$(LIBTEST) $(DESTDIR)$(LIBPATH) + +profile: + CFLAGS="$(CFLAGS) -fprofile-generate" $(MAKE) timing EXTRALIBS="$(EXTRALIBS) -lgcov" + ./timing + rm -f timing `find . -type f | grep [.][ao] | xargs` + CFLAGS="$(CFLAGS) -fprofile-use" $(MAKE) timing EXTRALIBS="$(EXTRALIBS) -lgcov" + + +#This rule cleans the source tree of all compiled code, not including the pdf +#documentation. +clean: + rm -f `find . -type f | grep "[.]o" | xargs` + rm -f `find . -type f | grep "[.]lo" | xargs` + rm -f `find . -type f | grep "[.]a" | xargs` + rm -f `find . -type f | grep "[.]la" | xargs` + rm -f `find . -type f | grep "[.]obj" | xargs` + rm -f `find . -type f | grep "[.]lib" | xargs` + rm -f `find . -type f | grep "[.]exe" | xargs` + rm -f `find . -type f | grep "[.]gcda" | xargs` + rm -f `find . -type f | grep "[.]gcno" | xargs` + rm -f `find . -type f | grep "[.]il" | xargs` + rm -f `find . -type f | grep "[.]dyn" | xargs` + rm -f `find . -type f | grep "[.]dpi" | xargs` + rm -rf `find . -type d | grep "[.]libs" | xargs` + rm -f crypt.aux crypt.dvi crypt.idx crypt.ilg crypt.ind crypt.log crypt.toc + rm -f $(TV) $(PROF) $(SMALL) $(CRYPT) $(HASHSUM) $(MULTI) $(TIMING) $(TEST) + rm -rf doc/doxygen + rm -f doc/*.pdf + rm -f *.txt + +#build the doxy files (requires Doxygen, tetex and patience) +doxy: + doxygen + cd doc/doxygen/latex ; ${MAKE} ; mv -f refman.pdf ../../. + echo The huge doxygen PDF should be available as doc/refman.pdf + +#This builds the crypt.pdf file. Note that the rm -f *.pdf has been removed +#from the clean command! This is because most people would like to keep the +#nice pre-compiled crypt.pdf that comes with libtomcrypt! We only need to +#delete it if we are rebuilding it. +docs: crypt.tex + rm -f doc/crypt.pdf $(LEFTOVERS) + echo "hello" > crypt.ind + latex crypt > /dev/null + latex crypt > /dev/null + makeindex crypt.idx > /dev/null + perl fixupind.pl + latex crypt > /dev/null + dvipdf crypt + mv -ivf crypt.pdf doc/crypt.pdf + rm -f $(LEFTOVERS) + +docdvi: crypt.tex + echo hello > crypt.ind + latex crypt > /dev/null + latex crypt > /dev/null + makeindex crypt.idx + perl fixupind.pl + latex crypt > /dev/null + latex crypt > /dev/null + +#zipup the project (take that!) +no_oops: clean + cd .. ; cvs commit + echo Scanning for scratch/dirty files + find . -type f | grep -v CVS | xargs -n 1 bash mess.sh + +zipup: no_oops docs + cd .. ; rm -rf crypt* libtomcrypt-$(VERSION) ; mkdir libtomcrypt-$(VERSION) ; \ + cp -R ./libtomcrypt/* ./libtomcrypt-$(VERSION)/ ; \ + cd libtomcrypt-$(VERSION) ; rm -rf `find . -type d | grep CVS | xargs` ; cd .. ; \ + tar -cjvf crypt-$(VERSION).tar.bz2 libtomcrypt-$(VERSION) ; \ + zip -9r crypt-$(VERSION).zip libtomcrypt-$(VERSION) ; \ + gpg -b -a crypt-$(VERSION).tar.bz2 ; gpg -b -a crypt-$(VERSION).zip ; \ + mv -fv crypt* ~ ; rm -rf libtomcrypt-$(VERSION) + +%.o : %.c + mkdir -p $(dir $@) + $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< + +# $Source: /cvs/libtom/libtomcrypt/makefile,v $ +# $Revision: 1.150 $ +# $Date: 2007/02/16 16:36:25 $ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/makefile.icc b/xmhf-64/xmhf/third-party/libtomcrypt/makefile.icc new file mode 100644 index 0000000000..c1ff1630ae --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/makefile.icc @@ -0,0 +1,295 @@ +# MAKEFILE for linux ICC (Intel C compiler) +# +# Tested with ICC v8.... +# +# Be aware that ICC isn't quite as stable as GCC and several optimization switches +# seem to break the code (that GCC and MSVC compile just fine). In particular +# "-ip" and "-x*" seem to break the code (ROL/ROR macro problems). As the makefile +# is shipped the code will build and execute properly. +# +# Also note that ICC often makes code that is slower than GCC. This is probably due to +# a mix of not being able to use "-ip" and just having fewer optimization algos than GCC. +# +# Tom St Denis + +# Compiler and Linker Names +CC=icc + +#LD=ld + +# Archiver [makes .a files] +#AR=ar +#ARFLAGS=r + +# Compilation flags. Note the += does not write over the user's CFLAGS! +CFLAGS += -c -Isrc/headers/ -Itestprof/ -DINTEL_CC -DLTC_SOURCE + +#ICC v9 doesn't support LTC_FAST for things like Pelican MAC +#Despite the fact I can't see what's wrong with my code +#Oh well +CFLAGS += -DLTC_NO_FAST + +#The default rule for make builds the libtomcrypt library. +default:library + +# optimize for SPEED +# +# -mcpu= can be pentium, pentiumpro (covers PII through PIII) or pentium4 +# -ax? specifies make code specifically for ? but compatible with IA-32 +# -x? specifies compile solely for ? [not specifically IA-32 compatible] +# +# where ? is +# K - PIII +# W - first P4 [Williamette] +# N - P4 Northwood +# P - P4 Prescott +# B - Blend of P4 and PM [mobile] +# +# Default to just generic max opts +ifdef LTC_SMALL +CFLAGS += -O2 -xP -ip +endif + +ifndef IGNORE_SPEED +CFLAGS += -O3 -xP -ip +endif + +# want to see stuff? +#CFLAGS += -opt_report + +#These flags control how the library gets built. + +#Output filenames for various targets. +ifndef LIBNAME + LIBNAME=libtomcrypt.a +endif +ifndef LIBTEST + LIBTEST=libtomcrypt_prof.a + LIBTEST_S=$(LIBTEST) +endif +HASH=hashsum +CRYPT=encrypt +SMALL=small +PROF=x86_prof +TV=tv_gen +MULTI=multi +TIMING=timing +TEST=test + +#LIBPATH-The directory for libtomcrypt to be installed to. +#INCPATH-The directory to install the header files for libtomcrypt. +#DATAPATH-The directory to install the pdf docs. +ifndef DESTDIR + DESTDIR= +endif +ifndef LIBPATH + LIBPATH=/usr/lib +endif +ifndef INCPATH + INCPATH=/usr/include +endif +ifndef DATAPATH + DATAPATH=/usr/share/doc/libtomcrypt/pdf +endif + +#List of objects to compile. +#START_INS +OBJECTS=src/ciphers/aes/aes_enc.o src/ciphers/aes/aes.o src/ciphers/anubis.o src/ciphers/blowfish.o \ +src/ciphers/cast5.o src/ciphers/des.o src/ciphers/kasumi.o src/ciphers/khazad.o src/ciphers/kseed.o \ +src/ciphers/multi2.o src/ciphers/noekeon.o src/ciphers/rc2.o src/ciphers/rc5.o src/ciphers/rc6.o \ +src/ciphers/safer/safer.o src/ciphers/safer/saferp.o src/ciphers/safer/safer_tab.o \ +src/ciphers/skipjack.o src/ciphers/twofish/twofish.o src/ciphers/xtea.o src/encauth/ccm/ccm_memory.o \ +src/encauth/ccm/ccm_test.o src/encauth/eax/eax_addheader.o src/encauth/eax/eax_decrypt.o \ +src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o \ +src/encauth/eax/eax_encrypt_authenticate_memory.o src/encauth/eax/eax_encrypt.o \ +src/encauth/eax/eax_init.o src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o \ +src/encauth/gcm/gcm_add_iv.o src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o \ +src/encauth/gcm/gcm_init.o src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_mult_h.o \ +src/encauth/gcm/gcm_process.o src/encauth/gcm/gcm_reset.o src/encauth/gcm/gcm_test.o \ +src/encauth/ocb/ocb_decrypt.o src/encauth/ocb/ocb_decrypt_verify_memory.o \ +src/encauth/ocb/ocb_done_decrypt.o src/encauth/ocb/ocb_done_encrypt.o \ +src/encauth/ocb/ocb_encrypt_authenticate_memory.o src/encauth/ocb/ocb_encrypt.o \ +src/encauth/ocb/ocb_init.o src/encauth/ocb/ocb_ntz.o src/encauth/ocb/ocb_shift_xor.o \ +src/encauth/ocb/ocb_test.o src/encauth/ocb/s_ocb_done.o src/hashes/chc/chc.o \ +src/hashes/helper/hash_file.o src/hashes/helper/hash_filehandle.o src/hashes/helper/hash_memory.o \ +src/hashes/helper/hash_memory_multi.o src/hashes/md2.o src/hashes/md4.o src/hashes/md5.o \ +src/hashes/rmd128.o src/hashes/rmd160.o src/hashes/rmd256.o src/hashes/rmd320.o src/hashes/sha1.o \ +src/hashes/sha2/sha256.o src/hashes/sha2/sha512.o src/hashes/tiger.o src/hashes/whirl/whirl.o \ +src/mac/f9/f9_done.o src/mac/f9/f9_file.o src/mac/f9/f9_init.o src/mac/f9/f9_memory.o \ +src/mac/f9/f9_memory_multi.o src/mac/f9/f9_process.o src/mac/f9/f9_test.o src/mac/hmac/hmac_done.o \ +src/mac/hmac/hmac_file.o src/mac/hmac/hmac_init.o src/mac/hmac/hmac_memory.o \ +src/mac/hmac/hmac_memory_multi.o src/mac/hmac/hmac_process.o src/mac/hmac/hmac_test.o \ +src/mac/omac/omac_done.o src/mac/omac/omac_file.o src/mac/omac/omac_init.o src/mac/omac/omac_memory.o \ +src/mac/omac/omac_memory_multi.o src/mac/omac/omac_process.o src/mac/omac/omac_test.o \ +src/mac/pelican/pelican.o src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o \ +src/mac/pmac/pmac_done.o src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \ +src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o src/mac/pmac/pmac_process.o \ +src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/mac/xcbc/xcbc_done.o \ +src/mac/xcbc/xcbc_file.o src/mac/xcbc/xcbc_init.o src/mac/xcbc/xcbc_memory.o \ +src/mac/xcbc/xcbc_memory_multi.o src/mac/xcbc/xcbc_process.o src/mac/xcbc/xcbc_test.o \ +src/math/fp/ltc_ecc_fp_mulmod.o src/math/gmp_desc.o src/math/ltm_desc.o src/math/multi.o \ +src/math/rand_prime.o src/math/tfm_desc.o src/misc/base64/base64_decode.o \ +src/misc/base64/base64_encode.o src/misc/burn_stack.o src/misc/crypt/crypt_argchk.o \ +src/misc/crypt/crypt.o src/misc/crypt/crypt_cipher_descriptor.o src/misc/crypt/crypt_cipher_is_valid.o \ +src/misc/crypt/crypt_find_cipher_any.o src/misc/crypt/crypt_find_cipher.o \ +src/misc/crypt/crypt_find_cipher_id.o src/misc/crypt/crypt_find_hash_any.o \ +src/misc/crypt/crypt_find_hash.o src/misc/crypt/crypt_find_hash_id.o \ +src/misc/crypt/crypt_find_hash_oid.o src/misc/crypt/crypt_find_prng.o src/misc/crypt/crypt_fsa.o \ +src/misc/crypt/crypt_hash_descriptor.o src/misc/crypt/crypt_hash_is_valid.o \ +src/misc/crypt/crypt_ltc_mp_descriptor.o src/misc/crypt/crypt_prng_descriptor.o \ +src/misc/crypt/crypt_prng_is_valid.o src/misc/crypt/crypt_register_cipher.o \ +src/misc/crypt/crypt_register_hash.o src/misc/crypt/crypt_register_prng.o \ +src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \ +src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/pkcs5/pkcs_5_1.o \ +src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o \ +src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o \ +src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o \ +src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o \ +src/modes/cfb/cfb_start.o src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_done.o \ +src/modes/ctr/ctr_encrypt.o src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o \ +src/modes/ctr/ctr_start.o src/modes/ctr/ctr_test.o src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o \ +src/modes/ecb/ecb_encrypt.o src/modes/ecb/ecb_start.o src/modes/f8/f8_decrypt.o src/modes/f8/f8_done.o \ +src/modes/f8/f8_encrypt.o src/modes/f8/f8_getiv.o src/modes/f8/f8_setiv.o src/modes/f8/f8_start.o \ +src/modes/f8/f8_test_mode.o src/modes/lrw/lrw_decrypt.o src/modes/lrw/lrw_done.o \ +src/modes/lrw/lrw_encrypt.o src/modes/lrw/lrw_getiv.o src/modes/lrw/lrw_process.o \ +src/modes/lrw/lrw_setiv.o src/modes/lrw/lrw_start.o src/modes/lrw/lrw_test.o \ +src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o src/modes/ofb/ofb_encrypt.o \ +src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o src/modes/ofb/ofb_start.o \ +src/modes/xts/xts_decrypt.o src/modes/xts/xts_done.o src/modes/xts/xts_encrypt.o \ +src/modes/xts/xts_init.o src/modes/xts/xts_mult_x.o src/modes/xts/xts_test.o \ +src/pk/asn1/der/bit/der_decode_bit_string.o src/pk/asn1/der/bit/der_encode_bit_string.o \ +src/pk/asn1/der/bit/der_length_bit_string.o src/pk/asn1/der/boolean/der_decode_boolean.o \ +src/pk/asn1/der/boolean/der_encode_boolean.o src/pk/asn1/der/boolean/der_length_boolean.o \ +src/pk/asn1/der/choice/der_decode_choice.o src/pk/asn1/der/ia5/der_decode_ia5_string.o \ +src/pk/asn1/der/ia5/der_encode_ia5_string.o src/pk/asn1/der/ia5/der_length_ia5_string.o \ +src/pk/asn1/der/integer/der_decode_integer.o src/pk/asn1/der/integer/der_encode_integer.o \ +src/pk/asn1/der/integer/der_length_integer.o \ +src/pk/asn1/der/object_identifier/der_decode_object_identifier.o \ +src/pk/asn1/der/object_identifier/der_encode_object_identifier.o \ +src/pk/asn1/der/object_identifier/der_length_object_identifier.o \ +src/pk/asn1/der/octet/der_decode_octet_string.o src/pk/asn1/der/octet/der_encode_octet_string.o \ +src/pk/asn1/der/octet/der_length_octet_string.o \ +src/pk/asn1/der/printable_string/der_decode_printable_string.o \ +src/pk/asn1/der/printable_string/der_encode_printable_string.o \ +src/pk/asn1/der/printable_string/der_length_printable_string.o \ +src/pk/asn1/der/sequence/der_decode_sequence_ex.o \ +src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \ +src/pk/asn1/der/sequence/der_decode_sequence_multi.o \ +src/pk/asn1/der/sequence/der_encode_sequence_ex.o \ +src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \ +src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/set/der_encode_set.o \ +src/pk/asn1/der/set/der_encode_setof.o src/pk/asn1/der/short_integer/der_decode_short_integer.o \ +src/pk/asn1/der/short_integer/der_encode_short_integer.o \ +src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \ +src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \ +src/pk/asn1/der/utf8/der_decode_utf8_string.o src/pk/asn1/der/utf8/der_encode_utf8_string.o \ +src/pk/asn1/der/utf8/der_length_utf8_string.o src/pk/dsa/dsa_decrypt_key.o \ +src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o \ +src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_shared_secret.o src/pk/dsa/dsa_sign_hash.o \ +src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc_ansi_x963_export.o \ +src/pk/ecc/ecc_ansi_x963_import.o src/pk/ecc/ecc.o src/pk/ecc/ecc_decrypt_key.o \ +src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_size.o \ +src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.o src/pk/ecc/ecc_shared_secret.o \ +src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o src/pk/ecc/ecc_verify_hash.o \ +src/pk/ecc/ltc_ecc_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o src/pk/ecc/ltc_ecc_mul2add.o \ +src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \ +src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \ +src/pk/katja/katja_decrypt_key.o src/pk/katja/katja_encrypt_key.o src/pk/katja/katja_export.o \ +src/pk/katja/katja_exptmod.o src/pk/katja/katja_free.o src/pk/katja/katja_import.o \ +src/pk/katja/katja_make_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \ +src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ +src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v1_5_decode.o \ +src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \ +src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \ +src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \ +src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \ +src/prngs/sprng.o src/prngs/yarrow.o + +HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \ +src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \ +src/headers/tomcrypt_pk.h src/headers/tomcrypt_hash.h src/headers/tomcrypt_math.h \ +src/headers/tomcrypt_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \ +src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h + +#END_INS + +#Who do we install as? +ifdef INSTALL_USER +USER=$(INSTALL_USER) +else +USER=root +endif + +ifdef INSTALL_GROUP +GROUP=$(INSTALL_GROUP) +else +GROUP=wheel +endif + +#ciphers come in two flavours... enc+dec and enc +aes_enc.o: aes.c aes_tab.c + $(CC) $(CFLAGS) -DENCRYPT_ONLY -c aes.c -o aes_enc.o + +HASHOBJECTS=demos/hashsum.o +CRYPTOBJECTS=demos/encrypt.o +SMALLOBJECTS=demos/small.o +TVS=demos/tv_gen.o +TIMINGS=demos/timing.o +TESTS=demos/test.o + +#ciphers come in two flavours... enc+dec and enc +src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c + $(CC) $(CFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes.c -o src/ciphers/aes/aes_enc.o + +#These are the rules to make certain object files. +src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c +src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c +src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c +src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c +src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c + +#This rule makes the libtomcrypt library. +library: $(LIBNAME) + +testprof/$(LIBTEST): + cd testprof ; LIBTEST_S=$(LIBTEST) CFLAGS="$(CFLAGS)" make -f makefile.icc + +$(LIBNAME): $(OBJECTS) + $(AR) $(ARFLAGS) $@ $(OBJECTS) + ranlib $@ + +#This rule makes the hash program included with libtomcrypt +hashsum: library $(HASHOBJECTS) + $(CC) $(HASHOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(HASH) $(WARN) + +#makes the crypt program +crypt: library $(CRYPTOBJECTS) + $(CC) $(CRYPTOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(CRYPT) $(WARN) + +#makes the small program +small: library $(SMALLOBJECTS) + $(CC) $(SMALLOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(SMALL) $(WARN) + +tv_gen: library $(TVS) + $(CC) $(TVS) $(LIBNAME) $(EXTRALIBS) -o $(TV) + +timing: library $(TIMINGS) testprof/$(LIBTEST) + $(CC) $(TIMINGS) testprof/$(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TIMING) + +test: library $(TESTS) testprof/$(LIBTEST) + $(CC) $(TESTS) testprof/$(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TEST) + +#This rule installs the library and the header files. This must be run +#as root in order to have a high enough permission to write to the correct +#directories and to set the owner and group to root. +install: library + install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) + install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) + install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH) + install -g $(GROUP) -o $(USER) $(LIBTEST) $(DESTDIR)$(LIBPATH) + install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) + +# $Source: /cvs/libtom/libtomcrypt/makefile.icc,v $ +# $Revision: 1.76 $ +# $Date: 2007/02/16 16:36:25 $ + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/makefile.msvc b/xmhf-64/xmhf/third-party/libtomcrypt/makefile.msvc new file mode 100644 index 0000000000..7f41ad9988 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/makefile.msvc @@ -0,0 +1,152 @@ +#MSVC Makefile [tested with MSVC 6.00 with SP5] +# +#Tom St Denis +CFLAGS = /Isrc/headers/ /Itestprof/ /Ox /DWIN32 /DLTC_SOURCE /W3 /Fo$@ $(CF) + +#START_INS +OBJECTS=src/ciphers/aes/aes_enc.obj src/ciphers/aes/aes.obj src/ciphers/anubis.obj src/ciphers/blowfish.obj \ +src/ciphers/cast5.obj src/ciphers/des.obj src/ciphers/kasumi.obj src/ciphers/khazad.obj src/ciphers/kseed.obj \ +src/ciphers/multi2.obj src/ciphers/noekeon.obj src/ciphers/rc2.obj src/ciphers/rc5.obj src/ciphers/rc6.obj \ +src/ciphers/safer/safer.obj src/ciphers/safer/saferp.obj src/ciphers/safer/safer_tab.obj \ +src/ciphers/skipjack.obj src/ciphers/twofish/twofish.obj src/ciphers/xtea.obj src/encauth/ccm/ccm_memory.obj \ +src/encauth/ccm/ccm_test.obj src/encauth/eax/eax_addheader.obj src/encauth/eax/eax_decrypt.obj \ +src/encauth/eax/eax_decrypt_verify_memory.obj src/encauth/eax/eax_done.obj \ +src/encauth/eax/eax_encrypt_authenticate_memory.obj src/encauth/eax/eax_encrypt.obj \ +src/encauth/eax/eax_init.obj src/encauth/eax/eax_test.obj src/encauth/gcm/gcm_add_aad.obj \ +src/encauth/gcm/gcm_add_iv.obj src/encauth/gcm/gcm_done.obj src/encauth/gcm/gcm_gf_mult.obj \ +src/encauth/gcm/gcm_init.obj src/encauth/gcm/gcm_memory.obj src/encauth/gcm/gcm_mult_h.obj \ +src/encauth/gcm/gcm_process.obj src/encauth/gcm/gcm_reset.obj src/encauth/gcm/gcm_test.obj \ +src/encauth/ocb/ocb_decrypt.obj src/encauth/ocb/ocb_decrypt_verify_memory.obj \ +src/encauth/ocb/ocb_done_decrypt.obj src/encauth/ocb/ocb_done_encrypt.obj \ +src/encauth/ocb/ocb_encrypt_authenticate_memory.obj src/encauth/ocb/ocb_encrypt.obj \ +src/encauth/ocb/ocb_init.obj src/encauth/ocb/ocb_ntz.obj src/encauth/ocb/ocb_shift_xor.obj \ +src/encauth/ocb/ocb_test.obj src/encauth/ocb/s_ocb_done.obj src/hashes/chc/chc.obj \ +src/hashes/helper/hash_file.obj src/hashes/helper/hash_filehandle.obj src/hashes/helper/hash_memory.obj \ +src/hashes/helper/hash_memory_multi.obj src/hashes/md2.obj src/hashes/md4.obj src/hashes/md5.obj \ +src/hashes/rmd128.obj src/hashes/rmd160.obj src/hashes/rmd256.obj src/hashes/rmd320.obj src/hashes/sha1.obj \ +src/hashes/sha2/sha256.obj src/hashes/sha2/sha512.obj src/hashes/tiger.obj src/hashes/whirl/whirl.obj \ +src/mac/f9/f9_done.obj src/mac/f9/f9_file.obj src/mac/f9/f9_init.obj src/mac/f9/f9_memory.obj \ +src/mac/f9/f9_memory_multi.obj src/mac/f9/f9_process.obj src/mac/f9/f9_test.obj src/mac/hmac/hmac_done.obj \ +src/mac/hmac/hmac_file.obj src/mac/hmac/hmac_init.obj src/mac/hmac/hmac_memory.obj \ +src/mac/hmac/hmac_memory_multi.obj src/mac/hmac/hmac_process.obj src/mac/hmac/hmac_test.obj \ +src/mac/omac/omac_done.obj src/mac/omac/omac_file.obj src/mac/omac/omac_init.obj src/mac/omac/omac_memory.obj \ +src/mac/omac/omac_memory_multi.obj src/mac/omac/omac_process.obj src/mac/omac/omac_test.obj \ +src/mac/pelican/pelican.obj src/mac/pelican/pelican_memory.obj src/mac/pelican/pelican_test.obj \ +src/mac/pmac/pmac_done.obj src/mac/pmac/pmac_file.obj src/mac/pmac/pmac_init.obj src/mac/pmac/pmac_memory.obj \ +src/mac/pmac/pmac_memory_multi.obj src/mac/pmac/pmac_ntz.obj src/mac/pmac/pmac_process.obj \ +src/mac/pmac/pmac_shift_xor.obj src/mac/pmac/pmac_test.obj src/mac/xcbc/xcbc_done.obj \ +src/mac/xcbc/xcbc_file.obj src/mac/xcbc/xcbc_init.obj src/mac/xcbc/xcbc_memory.obj \ +src/mac/xcbc/xcbc_memory_multi.obj src/mac/xcbc/xcbc_process.obj src/mac/xcbc/xcbc_test.obj \ +src/math/fp/ltc_ecc_fp_mulmod.obj src/math/gmp_desc.obj src/math/ltm_desc.obj src/math/multi.obj \ +src/math/rand_prime.obj src/math/tfm_desc.obj src/misc/base64/base64_decode.obj \ +src/misc/base64/base64_encode.obj src/misc/burn_stack.obj src/misc/crypt/crypt_argchk.obj \ +src/misc/crypt/crypt.obj src/misc/crypt/crypt_cipher_descriptor.obj src/misc/crypt/crypt_cipher_is_valid.obj \ +src/misc/crypt/crypt_find_cipher_any.obj src/misc/crypt/crypt_find_cipher.obj \ +src/misc/crypt/crypt_find_cipher_id.obj src/misc/crypt/crypt_find_hash_any.obj \ +src/misc/crypt/crypt_find_hash.obj src/misc/crypt/crypt_find_hash_id.obj \ +src/misc/crypt/crypt_find_hash_oid.obj src/misc/crypt/crypt_find_prng.obj src/misc/crypt/crypt_fsa.obj \ +src/misc/crypt/crypt_hash_descriptor.obj src/misc/crypt/crypt_hash_is_valid.obj \ +src/misc/crypt/crypt_ltc_mp_descriptor.obj src/misc/crypt/crypt_prng_descriptor.obj \ +src/misc/crypt/crypt_prng_is_valid.obj src/misc/crypt/crypt_register_cipher.obj \ +src/misc/crypt/crypt_register_hash.obj src/misc/crypt/crypt_register_prng.obj \ +src/misc/crypt/crypt_unregister_cipher.obj src/misc/crypt/crypt_unregister_hash.obj \ +src/misc/crypt/crypt_unregister_prng.obj src/misc/error_to_string.obj src/misc/pkcs5/pkcs_5_1.obj \ +src/misc/pkcs5/pkcs_5_2.obj src/misc/zeromem.obj src/modes/cbc/cbc_decrypt.obj src/modes/cbc/cbc_done.obj \ +src/modes/cbc/cbc_encrypt.obj src/modes/cbc/cbc_getiv.obj src/modes/cbc/cbc_setiv.obj \ +src/modes/cbc/cbc_start.obj src/modes/cfb/cfb_decrypt.obj src/modes/cfb/cfb_done.obj \ +src/modes/cfb/cfb_encrypt.obj src/modes/cfb/cfb_getiv.obj src/modes/cfb/cfb_setiv.obj \ +src/modes/cfb/cfb_start.obj src/modes/ctr/ctr_decrypt.obj src/modes/ctr/ctr_done.obj \ +src/modes/ctr/ctr_encrypt.obj src/modes/ctr/ctr_getiv.obj src/modes/ctr/ctr_setiv.obj \ +src/modes/ctr/ctr_start.obj src/modes/ctr/ctr_test.obj src/modes/ecb/ecb_decrypt.obj src/modes/ecb/ecb_done.obj \ +src/modes/ecb/ecb_encrypt.obj src/modes/ecb/ecb_start.obj src/modes/f8/f8_decrypt.obj src/modes/f8/f8_done.obj \ +src/modes/f8/f8_encrypt.obj src/modes/f8/f8_getiv.obj src/modes/f8/f8_setiv.obj src/modes/f8/f8_start.obj \ +src/modes/f8/f8_test_mode.obj src/modes/lrw/lrw_decrypt.obj src/modes/lrw/lrw_done.obj \ +src/modes/lrw/lrw_encrypt.obj src/modes/lrw/lrw_getiv.obj src/modes/lrw/lrw_process.obj \ +src/modes/lrw/lrw_setiv.obj src/modes/lrw/lrw_start.obj src/modes/lrw/lrw_test.obj \ +src/modes/ofb/ofb_decrypt.obj src/modes/ofb/ofb_done.obj src/modes/ofb/ofb_encrypt.obj \ +src/modes/ofb/ofb_getiv.obj src/modes/ofb/ofb_setiv.obj src/modes/ofb/ofb_start.obj \ +src/modes/xts/xts_decrypt.obj src/modes/xts/xts_done.obj src/modes/xts/xts_encrypt.obj \ +src/modes/xts/xts_init.obj src/modes/xts/xts_mult_x.obj src/modes/xts/xts_test.obj \ +src/pk/asn1/der/bit/der_decode_bit_string.obj src/pk/asn1/der/bit/der_encode_bit_string.obj \ +src/pk/asn1/der/bit/der_length_bit_string.obj src/pk/asn1/der/boolean/der_decode_boolean.obj \ +src/pk/asn1/der/boolean/der_encode_boolean.obj src/pk/asn1/der/boolean/der_length_boolean.obj \ +src/pk/asn1/der/choice/der_decode_choice.obj src/pk/asn1/der/ia5/der_decode_ia5_string.obj \ +src/pk/asn1/der/ia5/der_encode_ia5_string.obj src/pk/asn1/der/ia5/der_length_ia5_string.obj \ +src/pk/asn1/der/integer/der_decode_integer.obj src/pk/asn1/der/integer/der_encode_integer.obj \ +src/pk/asn1/der/integer/der_length_integer.obj \ +src/pk/asn1/der/object_identifier/der_decode_object_identifier.obj \ +src/pk/asn1/der/object_identifier/der_encode_object_identifier.obj \ +src/pk/asn1/der/object_identifier/der_length_object_identifier.obj \ +src/pk/asn1/der/octet/der_decode_octet_string.obj src/pk/asn1/der/octet/der_encode_octet_string.obj \ +src/pk/asn1/der/octet/der_length_octet_string.obj \ +src/pk/asn1/der/printable_string/der_decode_printable_string.obj \ +src/pk/asn1/der/printable_string/der_encode_printable_string.obj \ +src/pk/asn1/der/printable_string/der_length_printable_string.obj \ +src/pk/asn1/der/sequence/der_decode_sequence_ex.obj \ +src/pk/asn1/der/sequence/der_decode_sequence_flexi.obj \ +src/pk/asn1/der/sequence/der_decode_sequence_multi.obj \ +src/pk/asn1/der/sequence/der_encode_sequence_ex.obj \ +src/pk/asn1/der/sequence/der_encode_sequence_multi.obj src/pk/asn1/der/sequence/der_length_sequence.obj \ +src/pk/asn1/der/sequence/der_sequence_free.obj src/pk/asn1/der/set/der_encode_set.obj \ +src/pk/asn1/der/set/der_encode_setof.obj src/pk/asn1/der/short_integer/der_decode_short_integer.obj \ +src/pk/asn1/der/short_integer/der_encode_short_integer.obj \ +src/pk/asn1/der/short_integer/der_length_short_integer.obj src/pk/asn1/der/utctime/der_decode_utctime.obj \ +src/pk/asn1/der/utctime/der_encode_utctime.obj src/pk/asn1/der/utctime/der_length_utctime.obj \ +src/pk/asn1/der/utf8/der_decode_utf8_string.obj src/pk/asn1/der/utf8/der_encode_utf8_string.obj \ +src/pk/asn1/der/utf8/der_length_utf8_string.obj src/pk/dsa/dsa_decrypt_key.obj \ +src/pk/dsa/dsa_encrypt_key.obj src/pk/dsa/dsa_export.obj src/pk/dsa/dsa_free.obj src/pk/dsa/dsa_import.obj \ +src/pk/dsa/dsa_make_key.obj src/pk/dsa/dsa_shared_secret.obj src/pk/dsa/dsa_sign_hash.obj \ +src/pk/dsa/dsa_verify_hash.obj src/pk/dsa/dsa_verify_key.obj src/pk/ecc/ecc_ansi_x963_export.obj \ +src/pk/ecc/ecc_ansi_x963_import.obj src/pk/ecc/ecc.obj src/pk/ecc/ecc_decrypt_key.obj \ +src/pk/ecc/ecc_encrypt_key.obj src/pk/ecc/ecc_export.obj src/pk/ecc/ecc_free.obj src/pk/ecc/ecc_get_size.obj \ +src/pk/ecc/ecc_import.obj src/pk/ecc/ecc_make_key.obj src/pk/ecc/ecc_shared_secret.obj \ +src/pk/ecc/ecc_sign_hash.obj src/pk/ecc/ecc_sizes.obj src/pk/ecc/ecc_test.obj src/pk/ecc/ecc_verify_hash.obj \ +src/pk/ecc/ltc_ecc_is_valid_idx.obj src/pk/ecc/ltc_ecc_map.obj src/pk/ecc/ltc_ecc_mul2add.obj \ +src/pk/ecc/ltc_ecc_mulmod.obj src/pk/ecc/ltc_ecc_mulmod_timing.obj src/pk/ecc/ltc_ecc_points.obj \ +src/pk/ecc/ltc_ecc_projective_add_point.obj src/pk/ecc/ltc_ecc_projective_dbl_point.obj \ +src/pk/katja/katja_decrypt_key.obj src/pk/katja/katja_encrypt_key.obj src/pk/katja/katja_export.obj \ +src/pk/katja/katja_exptmod.obj src/pk/katja/katja_free.obj src/pk/katja/katja_import.obj \ +src/pk/katja/katja_make_key.obj src/pk/pkcs1/pkcs_1_i2osp.obj src/pk/pkcs1/pkcs_1_mgf1.obj \ +src/pk/pkcs1/pkcs_1_oaep_decode.obj src/pk/pkcs1/pkcs_1_oaep_encode.obj src/pk/pkcs1/pkcs_1_os2ip.obj \ +src/pk/pkcs1/pkcs_1_pss_decode.obj src/pk/pkcs1/pkcs_1_pss_encode.obj src/pk/pkcs1/pkcs_1_v1_5_decode.obj \ +src/pk/pkcs1/pkcs_1_v1_5_encode.obj src/pk/rsa/rsa_decrypt_key.obj src/pk/rsa/rsa_encrypt_key.obj \ +src/pk/rsa/rsa_export.obj src/pk/rsa/rsa_exptmod.obj src/pk/rsa/rsa_free.obj src/pk/rsa/rsa_import.obj \ +src/pk/rsa/rsa_make_key.obj src/pk/rsa/rsa_sign_hash.obj src/pk/rsa/rsa_verify_hash.obj src/prngs/fortuna.obj \ +src/prngs/rc4.obj src/prngs/rng_get_bytes.obj src/prngs/rng_make_prng.obj src/prngs/sober128.obj \ +src/prngs/sprng.obj src/prngs/yarrow.obj + +HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \ +src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \ +src/headers/tomcrypt_pk.h src/headers/tomcrypt_hash.h src/headers/tomcrypt_math.h \ +src/headers/tomcrypt_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \ +src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h + +#END_INS + +default: library + +#ciphers come in two flavours... enc+dec and enc +src/ciphers/aes/aes_enc.obj: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c + $(CC) $(CFLAGS) /DENCRYPT_ONLY /c src/ciphers/aes/aes.c /Fosrc/ciphers/aes/aes_enc.obj + +library: $(OBJECTS) + lib /out:tomcrypt.lib $(OBJECTS) + cd testprof + nmake -f makefile.msvc + cd .. + +tv_gen: demos/tv_gen.c library + cl $(CFLAGS) demos/tv_gen.c tomcrypt.lib advapi32.lib $(EXTRALIBS) + +hashsum: demos/hashsum.c library + cl $(CFLAGS) demos/hashsum.c tomcrypt.lib advapi32.lib $(EXTRALIBS) + +test: demos/test.c library + cl $(CFLAGS) demos/test.c testprof/tomcrypt_prof.lib tomcrypt.lib advapi32.lib $(EXTRALIBS) + +timing: demos/timing.c library + cl $(CFLAGS) demos/timing.c testprof/tomcrypt_prof.lib tomcrypt.lib advapi32.lib $(EXTRALIBS) + +# $Source: /cvs/libtom/libtomcrypt/makefile.msvc,v $ +# $Revision: 1.54 $ +# $Date: 2007/02/16 16:36:25 $ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/makefile.shared b/xmhf-64/xmhf/third-party/libtomcrypt/makefile.shared new file mode 100644 index 0000000000..dd575d9490 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/makefile.shared @@ -0,0 +1,282 @@ +# MAKEFILE for linux GCC +# +# This makefile produces a shared object and requires libtool to be installed. +# +# Thanks to Zed Shaw for helping debug this on BSD/OSX. +# Tom St Denis + +# The version +VERSION=0:117 + +# Compiler and Linker Names +CC=libtool --mode=compile --tag=CC gcc + +# ranlib tools +ifndef RANLIB + RANLIB=ranlib +endif + +# Compilation flags. Note the += does not write over the user's CFLAGS! +CFLAGS += -c -I./src/headers/ -Wall -Wsign-compare -W -Wshadow -DLTC_SOURCE + +# additional warnings (newer GCC 3.4 and higher) +ifdef GCC_34 +CFLAGS += -Wsystem-headers -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wmissing-prototypes \ + -Wmissing-declarations -Wpointer-arith +endif + + +ifndef IGNORE_SPEED + +# optimize for SPEED +CFLAGS += -O3 -funroll-loops + +# add -fomit-frame-pointer. hinders debugging! +CFLAGS += -fomit-frame-pointer + +# optimize for SIZE +#CFLAGS += -Os -DLTC_SMALL_CODE + +endif + +# compile for DEBUGING (required for ccmalloc checking!!!) +#CFLAGS += -g3 + +# older GCCs can't handle the "rotate with immediate" ROLc/RORc/etc macros +# define this to help +#CFLAGS += -DLTC_NO_ROLC + +#Output filenames for various targets. +ifndef LIBTEST_S + LIBTEST_S=libtomcrypt_prof.a +endif +ifndef LIBTEST + LIBTEST=libtomcrypt_prof.la +endif +ifndef LIBNAME + LIBNAME=libtomcrypt.la +endif +ifndef LIBNAME_S + LIBNAME_S=libtomcrypt.a +endif + +HASH=hashsum +CRYPT=encrypt +SMALL=small +PROF=x86_prof +TV=tv_gen +TEST=test +TIMING=timing + +#LIBPATH-The directory for libtomcrypt to be installed to. +#INCPATH-The directory to install the header files for libtomcrypt. +#DATAPATH-The directory to install the pdf docs. +ifndef DESTDIR + DESTDIR= +endif +ifndef LIBPATH + LIBPATH=/usr/lib +endif +ifndef INCPATH + INCPATH=/usr/include +endif +ifndef DATAPATH + DATAPATH=/usr/share/doc/libtomcrypt/pdf +endif + +#Who do we install as? +ifdef INSTALL_USER +USER=$(INSTALL_USER) +else +USER=root +endif + +ifdef INSTALL_GROUP +GROUP=$(INSTALL_GROUP) +else +GROUP=wheel +endif + +#List of objects to compile. +#START_INS +OBJECTS=src/ciphers/aes/aes_enc.o src/ciphers/aes/aes.o src/ciphers/anubis.o src/ciphers/blowfish.o \ +src/ciphers/cast5.o src/ciphers/des.o src/ciphers/kasumi.o src/ciphers/khazad.o src/ciphers/kseed.o \ +src/ciphers/multi2.o src/ciphers/noekeon.o src/ciphers/rc2.o src/ciphers/rc5.o src/ciphers/rc6.o \ +src/ciphers/safer/safer.o src/ciphers/safer/saferp.o src/ciphers/safer/safer_tab.o \ +src/ciphers/skipjack.o src/ciphers/twofish/twofish.o src/ciphers/xtea.o src/encauth/ccm/ccm_memory.o \ +src/encauth/ccm/ccm_test.o src/encauth/eax/eax_addheader.o src/encauth/eax/eax_decrypt.o \ +src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o \ +src/encauth/eax/eax_encrypt_authenticate_memory.o src/encauth/eax/eax_encrypt.o \ +src/encauth/eax/eax_init.o src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o \ +src/encauth/gcm/gcm_add_iv.o src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o \ +src/encauth/gcm/gcm_init.o src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_mult_h.o \ +src/encauth/gcm/gcm_process.o src/encauth/gcm/gcm_reset.o src/encauth/gcm/gcm_test.o \ +src/encauth/ocb/ocb_decrypt.o src/encauth/ocb/ocb_decrypt_verify_memory.o \ +src/encauth/ocb/ocb_done_decrypt.o src/encauth/ocb/ocb_done_encrypt.o \ +src/encauth/ocb/ocb_encrypt_authenticate_memory.o src/encauth/ocb/ocb_encrypt.o \ +src/encauth/ocb/ocb_init.o src/encauth/ocb/ocb_ntz.o src/encauth/ocb/ocb_shift_xor.o \ +src/encauth/ocb/ocb_test.o src/encauth/ocb/s_ocb_done.o src/hashes/chc/chc.o \ +src/hashes/helper/hash_file.o src/hashes/helper/hash_filehandle.o src/hashes/helper/hash_memory.o \ +src/hashes/helper/hash_memory_multi.o src/hashes/md2.o src/hashes/md4.o src/hashes/md5.o \ +src/hashes/rmd128.o src/hashes/rmd160.o src/hashes/rmd256.o src/hashes/rmd320.o src/hashes/sha1.o \ +src/hashes/sha2/sha256.o src/hashes/sha2/sha512.o src/hashes/tiger.o src/hashes/whirl/whirl.o \ +src/mac/f9/f9_done.o src/mac/f9/f9_file.o src/mac/f9/f9_init.o src/mac/f9/f9_memory.o \ +src/mac/f9/f9_memory_multi.o src/mac/f9/f9_process.o src/mac/f9/f9_test.o src/mac/hmac/hmac_done.o \ +src/mac/hmac/hmac_file.o src/mac/hmac/hmac_init.o src/mac/hmac/hmac_memory.o \ +src/mac/hmac/hmac_memory_multi.o src/mac/hmac/hmac_process.o src/mac/hmac/hmac_test.o \ +src/mac/omac/omac_done.o src/mac/omac/omac_file.o src/mac/omac/omac_init.o src/mac/omac/omac_memory.o \ +src/mac/omac/omac_memory_multi.o src/mac/omac/omac_process.o src/mac/omac/omac_test.o \ +src/mac/pelican/pelican.o src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o \ +src/mac/pmac/pmac_done.o src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \ +src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o src/mac/pmac/pmac_process.o \ +src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/mac/xcbc/xcbc_done.o \ +src/mac/xcbc/xcbc_file.o src/mac/xcbc/xcbc_init.o src/mac/xcbc/xcbc_memory.o \ +src/mac/xcbc/xcbc_memory_multi.o src/mac/xcbc/xcbc_process.o src/mac/xcbc/xcbc_test.o \ +src/math/fp/ltc_ecc_fp_mulmod.o src/math/gmp_desc.o src/math/ltm_desc.o src/math/multi.o \ +src/math/rand_prime.o src/math/tfm_desc.o src/misc/base64/base64_decode.o \ +src/misc/base64/base64_encode.o src/misc/burn_stack.o src/misc/crypt/crypt_argchk.o \ +src/misc/crypt/crypt.o src/misc/crypt/crypt_cipher_descriptor.o src/misc/crypt/crypt_cipher_is_valid.o \ +src/misc/crypt/crypt_find_cipher_any.o src/misc/crypt/crypt_find_cipher.o \ +src/misc/crypt/crypt_find_cipher_id.o src/misc/crypt/crypt_find_hash_any.o \ +src/misc/crypt/crypt_find_hash.o src/misc/crypt/crypt_find_hash_id.o \ +src/misc/crypt/crypt_find_hash_oid.o src/misc/crypt/crypt_find_prng.o src/misc/crypt/crypt_fsa.o \ +src/misc/crypt/crypt_hash_descriptor.o src/misc/crypt/crypt_hash_is_valid.o \ +src/misc/crypt/crypt_ltc_mp_descriptor.o src/misc/crypt/crypt_prng_descriptor.o \ +src/misc/crypt/crypt_prng_is_valid.o src/misc/crypt/crypt_register_cipher.o \ +src/misc/crypt/crypt_register_hash.o src/misc/crypt/crypt_register_prng.o \ +src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \ +src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/pkcs5/pkcs_5_1.o \ +src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o \ +src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o \ +src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o \ +src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o \ +src/modes/cfb/cfb_start.o src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_done.o \ +src/modes/ctr/ctr_encrypt.o src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o \ +src/modes/ctr/ctr_start.o src/modes/ctr/ctr_test.o src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o \ +src/modes/ecb/ecb_encrypt.o src/modes/ecb/ecb_start.o src/modes/f8/f8_decrypt.o src/modes/f8/f8_done.o \ +src/modes/f8/f8_encrypt.o src/modes/f8/f8_getiv.o src/modes/f8/f8_setiv.o src/modes/f8/f8_start.o \ +src/modes/f8/f8_test_mode.o src/modes/lrw/lrw_decrypt.o src/modes/lrw/lrw_done.o \ +src/modes/lrw/lrw_encrypt.o src/modes/lrw/lrw_getiv.o src/modes/lrw/lrw_process.o \ +src/modes/lrw/lrw_setiv.o src/modes/lrw/lrw_start.o src/modes/lrw/lrw_test.o \ +src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o src/modes/ofb/ofb_encrypt.o \ +src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o src/modes/ofb/ofb_start.o \ +src/modes/xts/xts_decrypt.o src/modes/xts/xts_done.o src/modes/xts/xts_encrypt.o \ +src/modes/xts/xts_init.o src/modes/xts/xts_mult_x.o src/modes/xts/xts_test.o \ +src/pk/asn1/der/bit/der_decode_bit_string.o src/pk/asn1/der/bit/der_encode_bit_string.o \ +src/pk/asn1/der/bit/der_length_bit_string.o src/pk/asn1/der/boolean/der_decode_boolean.o \ +src/pk/asn1/der/boolean/der_encode_boolean.o src/pk/asn1/der/boolean/der_length_boolean.o \ +src/pk/asn1/der/choice/der_decode_choice.o src/pk/asn1/der/ia5/der_decode_ia5_string.o \ +src/pk/asn1/der/ia5/der_encode_ia5_string.o src/pk/asn1/der/ia5/der_length_ia5_string.o \ +src/pk/asn1/der/integer/der_decode_integer.o src/pk/asn1/der/integer/der_encode_integer.o \ +src/pk/asn1/der/integer/der_length_integer.o \ +src/pk/asn1/der/object_identifier/der_decode_object_identifier.o \ +src/pk/asn1/der/object_identifier/der_encode_object_identifier.o \ +src/pk/asn1/der/object_identifier/der_length_object_identifier.o \ +src/pk/asn1/der/octet/der_decode_octet_string.o src/pk/asn1/der/octet/der_encode_octet_string.o \ +src/pk/asn1/der/octet/der_length_octet_string.o \ +src/pk/asn1/der/printable_string/der_decode_printable_string.o \ +src/pk/asn1/der/printable_string/der_encode_printable_string.o \ +src/pk/asn1/der/printable_string/der_length_printable_string.o \ +src/pk/asn1/der/sequence/der_decode_sequence_ex.o \ +src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \ +src/pk/asn1/der/sequence/der_decode_sequence_multi.o \ +src/pk/asn1/der/sequence/der_encode_sequence_ex.o \ +src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \ +src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/set/der_encode_set.o \ +src/pk/asn1/der/set/der_encode_setof.o src/pk/asn1/der/short_integer/der_decode_short_integer.o \ +src/pk/asn1/der/short_integer/der_encode_short_integer.o \ +src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \ +src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \ +src/pk/asn1/der/utf8/der_decode_utf8_string.o src/pk/asn1/der/utf8/der_encode_utf8_string.o \ +src/pk/asn1/der/utf8/der_length_utf8_string.o src/pk/dsa/dsa_decrypt_key.o \ +src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o \ +src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_shared_secret.o src/pk/dsa/dsa_sign_hash.o \ +src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc_ansi_x963_export.o \ +src/pk/ecc/ecc_ansi_x963_import.o src/pk/ecc/ecc.o src/pk/ecc/ecc_decrypt_key.o \ +src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_size.o \ +src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.o src/pk/ecc/ecc_shared_secret.o \ +src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o src/pk/ecc/ecc_verify_hash.o \ +src/pk/ecc/ltc_ecc_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o src/pk/ecc/ltc_ecc_mul2add.o \ +src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \ +src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \ +src/pk/katja/katja_decrypt_key.o src/pk/katja/katja_encrypt_key.o src/pk/katja/katja_export.o \ +src/pk/katja/katja_exptmod.o src/pk/katja/katja_free.o src/pk/katja/katja_import.o \ +src/pk/katja/katja_make_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \ +src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ +src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v1_5_decode.o \ +src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \ +src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \ +src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \ +src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \ +src/prngs/sprng.o src/prngs/yarrow.o + +HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \ +src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \ +src/headers/tomcrypt_pk.h src/headers/tomcrypt_hash.h src/headers/tomcrypt_math.h \ +src/headers/tomcrypt_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \ +src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h + +#END_INS + +TESTOBJECTS=demos/test.o +HASHOBJECTS=demos/hashsum.o +CRYPTOBJECTS=demos/encrypt.o +SMALLOBJECTS=demos/small.o +TVS=demos/tv_gen.o +TESTS=demos/test.o +TIMINGS=demos/timing.o + +#The default rule for make builds the libtomcrypt library. +default:library + +#ciphers come in two flavours... enc+dec and enc +src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c + $(CC) $(CFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes.c -o src/ciphers/aes/aes_enc.o + +#These are the rules to make certain object files. +src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c +src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c +src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c +src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c +src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c + +#This rule makes the libtomcrypt library. +library: $(LIBNAME) + +testprof/$(LIBTEST): + cd testprof ; CFLAGS="$(CFLAGS)" GROUP=$(GROUP) USER=$(USER) VERSION=$(VERSION) LIBPATH=$(LIBPATH) LIBTEST=$(LIBTEST) LIBTEST_S=$(LIBTEST_S) make -f makefile.shared + +objs: $(OBJECTS) + +$(LIBNAME): $(OBJECTS) testprof/$(LIBTEST) + libtool --silent --mode=link gcc $(CFLAGS) `find . -type f | grep "[.]lo" | grep "src/" | xargs` $(EXTRALIBS) -o $(LIBNAME) -rpath $(LIBPATH) -version-info $(VERSION) + +install: $(LIBNAME) + install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) + cd testprof ; CFLAGS="$(CFLAGS)" GROUP=$(GROUP) USER=$(USER) VERSION=$(VERSION) LIBPATH=$(LIBPATH) LIBTEST=$(LIBTEST) LIBTEST_S=$(LIBTEST_S) DESTDIR=$(DESTDIR) make -f makefile.shared install + libtool --silent --mode=install install -c libtomcrypt.la $(DESTDIR)$(LIBPATH)/libtomcrypt.la + install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) + install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) + +#This rule makes the hash program included with libtomcrypt +hashsum: library + gcc $(CFLAGS) demos/hashsum.c -o hashsum.o + gcc -o hashsum hashsum.o -ltomcrypt $(EXTRALIBS) + +#makes the crypt program +crypt: library + gcc $(CFLAGS) demos/encrypt.c -o encrypt.o + gcc -o crypt encrypt.o -ltomcrypt $(EXTRALIBS) + +tv_gen: library $(TVS) + gcc -o tv_gen $(TVS) -ltomcrypt $(EXTRALIBS) + +test: library testprof/$(LIBTEST) $(TESTS) + gcc -o $(TEST) $(TESTS) -ltomcrypt_prof -ltomcrypt $(EXTRALIBS) + +timing: library testprof/$(LIBTEST) $(TIMINGS) + gcc -o $(TIMING) $(TIMINGS) -ltomcrypt_prof -ltomcrypt $(EXTRALIBS) + +# $Source: /cvs/libtom/libtomcrypt/makefile.shared,v $ +# $Revision: 1.80 $ +# $Date: 2007/02/16 16:36:25 $ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/makefile.unix b/xmhf-64/xmhf/third-party/libtomcrypt/makefile.unix new file mode 100644 index 0000000000..bb8f29c3ad --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/makefile.unix @@ -0,0 +1,242 @@ +# MAKEFILE for bsd make +# +# Tom St Denis + +# Compiler and Linker Names +CC=cc +LD=ld + +# Archiver [makes .a files] +AR=ar +ARFLAGS=r + +# Compilation flags. Note the += does not write over the user's CFLAGS! +CFLAGS = -c -I./testprof/ -I./src/headers/ -DLTC_SOURCE -O2 ${CFLAGS_OPTS} -o $@ + +LIBNAME=libtomcrypt.a +LIBTEST=libtomcrypt_prof.a +LIBTEST_S=$(LIBTEST) + +HASH=hashsum +CRYPT=encrypt +SMALL=small +PROF=x86_prof +TV=tv_gen +MULTI=multi +TIMING=timing +TEST=test + +#LIBPATH-The directory for libtomcrypt to be installed to. +#INCPATH-The directory to install the header files for libtomcrypt. +#DATAPATH-The directory to install the pdf docs. +LIBPATH=/usr/local/lib +INCPATH=/usr/local/include +DATAPATH=/usr/local/share/doc/libtomcrypt/pdf + +#Who do we install as? +USER=root + +GROUP=wheel + +#List of objects to compile. +#START_INS +OBJECTS=src/ciphers/aes/aes_enc.o src/ciphers/aes/aes.o src/ciphers/anubis.o src/ciphers/blowfish.o \ +src/ciphers/cast5.o src/ciphers/des.o src/ciphers/kasumi.o src/ciphers/khazad.o src/ciphers/kseed.o \ +src/ciphers/multi2.o src/ciphers/noekeon.o src/ciphers/rc2.o src/ciphers/rc5.o src/ciphers/rc6.o \ +src/ciphers/safer/safer.o src/ciphers/safer/saferp.o src/ciphers/safer/safer_tab.o \ +src/ciphers/skipjack.o src/ciphers/twofish/twofish.o src/ciphers/xtea.o src/encauth/ccm/ccm_memory.o \ +src/encauth/ccm/ccm_test.o src/encauth/eax/eax_addheader.o src/encauth/eax/eax_decrypt.o \ +src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o \ +src/encauth/eax/eax_encrypt_authenticate_memory.o src/encauth/eax/eax_encrypt.o \ +src/encauth/eax/eax_init.o src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o \ +src/encauth/gcm/gcm_add_iv.o src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o \ +src/encauth/gcm/gcm_init.o src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_mult_h.o \ +src/encauth/gcm/gcm_process.o src/encauth/gcm/gcm_reset.o src/encauth/gcm/gcm_test.o \ +src/encauth/ocb/ocb_decrypt.o src/encauth/ocb/ocb_decrypt_verify_memory.o \ +src/encauth/ocb/ocb_done_decrypt.o src/encauth/ocb/ocb_done_encrypt.o \ +src/encauth/ocb/ocb_encrypt_authenticate_memory.o src/encauth/ocb/ocb_encrypt.o \ +src/encauth/ocb/ocb_init.o src/encauth/ocb/ocb_ntz.o src/encauth/ocb/ocb_shift_xor.o \ +src/encauth/ocb/ocb_test.o src/encauth/ocb/s_ocb_done.o src/hashes/chc/chc.o \ +src/hashes/helper/hash_file.o src/hashes/helper/hash_filehandle.o src/hashes/helper/hash_memory.o \ +src/hashes/helper/hash_memory_multi.o src/hashes/md2.o src/hashes/md4.o src/hashes/md5.o \ +src/hashes/rmd128.o src/hashes/rmd160.o src/hashes/rmd256.o src/hashes/rmd320.o src/hashes/sha1.o \ +src/hashes/sha2/sha256.o src/hashes/sha2/sha512.o src/hashes/tiger.o src/hashes/whirl/whirl.o \ +src/mac/f9/f9_done.o src/mac/f9/f9_file.o src/mac/f9/f9_init.o src/mac/f9/f9_memory.o \ +src/mac/f9/f9_memory_multi.o src/mac/f9/f9_process.o src/mac/f9/f9_test.o src/mac/hmac/hmac_done.o \ +src/mac/hmac/hmac_file.o src/mac/hmac/hmac_init.o src/mac/hmac/hmac_memory.o \ +src/mac/hmac/hmac_memory_multi.o src/mac/hmac/hmac_process.o src/mac/hmac/hmac_test.o \ +src/mac/omac/omac_done.o src/mac/omac/omac_file.o src/mac/omac/omac_init.o src/mac/omac/omac_memory.o \ +src/mac/omac/omac_memory_multi.o src/mac/omac/omac_process.o src/mac/omac/omac_test.o \ +src/mac/pelican/pelican.o src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o \ +src/mac/pmac/pmac_done.o src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \ +src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o src/mac/pmac/pmac_process.o \ +src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/mac/xcbc/xcbc_done.o \ +src/mac/xcbc/xcbc_file.o src/mac/xcbc/xcbc_init.o src/mac/xcbc/xcbc_memory.o \ +src/mac/xcbc/xcbc_memory_multi.o src/mac/xcbc/xcbc_process.o src/mac/xcbc/xcbc_test.o \ +src/math/fp/ltc_ecc_fp_mulmod.o src/math/gmp_desc.o src/math/ltm_desc.o src/math/multi.o \ +src/math/rand_prime.o src/math/tfm_desc.o src/misc/base64/base64_decode.o \ +src/misc/base64/base64_encode.o src/misc/burn_stack.o src/misc/crypt/crypt_argchk.o \ +src/misc/crypt/crypt.o src/misc/crypt/crypt_cipher_descriptor.o src/misc/crypt/crypt_cipher_is_valid.o \ +src/misc/crypt/crypt_find_cipher_any.o src/misc/crypt/crypt_find_cipher.o \ +src/misc/crypt/crypt_find_cipher_id.o src/misc/crypt/crypt_find_hash_any.o \ +src/misc/crypt/crypt_find_hash.o src/misc/crypt/crypt_find_hash_id.o \ +src/misc/crypt/crypt_find_hash_oid.o src/misc/crypt/crypt_find_prng.o src/misc/crypt/crypt_fsa.o \ +src/misc/crypt/crypt_hash_descriptor.o src/misc/crypt/crypt_hash_is_valid.o \ +src/misc/crypt/crypt_ltc_mp_descriptor.o src/misc/crypt/crypt_prng_descriptor.o \ +src/misc/crypt/crypt_prng_is_valid.o src/misc/crypt/crypt_register_cipher.o \ +src/misc/crypt/crypt_register_hash.o src/misc/crypt/crypt_register_prng.o \ +src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \ +src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/pkcs5/pkcs_5_1.o \ +src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o \ +src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o \ +src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o \ +src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o \ +src/modes/cfb/cfb_start.o src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_done.o \ +src/modes/ctr/ctr_encrypt.o src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o \ +src/modes/ctr/ctr_start.o src/modes/ctr/ctr_test.o src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o \ +src/modes/ecb/ecb_encrypt.o src/modes/ecb/ecb_start.o src/modes/f8/f8_decrypt.o src/modes/f8/f8_done.o \ +src/modes/f8/f8_encrypt.o src/modes/f8/f8_getiv.o src/modes/f8/f8_setiv.o src/modes/f8/f8_start.o \ +src/modes/f8/f8_test_mode.o src/modes/lrw/lrw_decrypt.o src/modes/lrw/lrw_done.o \ +src/modes/lrw/lrw_encrypt.o src/modes/lrw/lrw_getiv.o src/modes/lrw/lrw_process.o \ +src/modes/lrw/lrw_setiv.o src/modes/lrw/lrw_start.o src/modes/lrw/lrw_test.o \ +src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o src/modes/ofb/ofb_encrypt.o \ +src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o src/modes/ofb/ofb_start.o \ +src/modes/xts/xts_decrypt.o src/modes/xts/xts_done.o src/modes/xts/xts_encrypt.o \ +src/modes/xts/xts_init.o src/modes/xts/xts_mult_x.o src/modes/xts/xts_test.o \ +src/pk/asn1/der/bit/der_decode_bit_string.o src/pk/asn1/der/bit/der_encode_bit_string.o \ +src/pk/asn1/der/bit/der_length_bit_string.o src/pk/asn1/der/boolean/der_decode_boolean.o \ +src/pk/asn1/der/boolean/der_encode_boolean.o src/pk/asn1/der/boolean/der_length_boolean.o \ +src/pk/asn1/der/choice/der_decode_choice.o src/pk/asn1/der/ia5/der_decode_ia5_string.o \ +src/pk/asn1/der/ia5/der_encode_ia5_string.o src/pk/asn1/der/ia5/der_length_ia5_string.o \ +src/pk/asn1/der/integer/der_decode_integer.o src/pk/asn1/der/integer/der_encode_integer.o \ +src/pk/asn1/der/integer/der_length_integer.o \ +src/pk/asn1/der/object_identifier/der_decode_object_identifier.o \ +src/pk/asn1/der/object_identifier/der_encode_object_identifier.o \ +src/pk/asn1/der/object_identifier/der_length_object_identifier.o \ +src/pk/asn1/der/octet/der_decode_octet_string.o src/pk/asn1/der/octet/der_encode_octet_string.o \ +src/pk/asn1/der/octet/der_length_octet_string.o \ +src/pk/asn1/der/printable_string/der_decode_printable_string.o \ +src/pk/asn1/der/printable_string/der_encode_printable_string.o \ +src/pk/asn1/der/printable_string/der_length_printable_string.o \ +src/pk/asn1/der/sequence/der_decode_sequence_ex.o \ +src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \ +src/pk/asn1/der/sequence/der_decode_sequence_multi.o \ +src/pk/asn1/der/sequence/der_encode_sequence_ex.o \ +src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \ +src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/set/der_encode_set.o \ +src/pk/asn1/der/set/der_encode_setof.o src/pk/asn1/der/short_integer/der_decode_short_integer.o \ +src/pk/asn1/der/short_integer/der_encode_short_integer.o \ +src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \ +src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \ +src/pk/asn1/der/utf8/der_decode_utf8_string.o src/pk/asn1/der/utf8/der_encode_utf8_string.o \ +src/pk/asn1/der/utf8/der_length_utf8_string.o src/pk/dsa/dsa_decrypt_key.o \ +src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o \ +src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_shared_secret.o src/pk/dsa/dsa_sign_hash.o \ +src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc_ansi_x963_export.o \ +src/pk/ecc/ecc_ansi_x963_import.o src/pk/ecc/ecc.o src/pk/ecc/ecc_decrypt_key.o \ +src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_size.o \ +src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.o src/pk/ecc/ecc_shared_secret.o \ +src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o src/pk/ecc/ecc_verify_hash.o \ +src/pk/ecc/ltc_ecc_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o src/pk/ecc/ltc_ecc_mul2add.o \ +src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \ +src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \ +src/pk/katja/katja_decrypt_key.o src/pk/katja/katja_encrypt_key.o src/pk/katja/katja_export.o \ +src/pk/katja/katja_exptmod.o src/pk/katja/katja_free.o src/pk/katja/katja_import.o \ +src/pk/katja/katja_make_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \ +src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ +src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v1_5_decode.o \ +src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \ +src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \ +src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \ +src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \ +src/prngs/sprng.o src/prngs/yarrow.o + +HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \ +src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \ +src/headers/tomcrypt_pk.h src/headers/tomcrypt_hash.h src/headers/tomcrypt_math.h \ +src/headers/tomcrypt_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \ +src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h + +#END_INS + +TESTOBJECTS=demos/test.o +HASHOBJECTS=demos/hashsum.o +CRYPTOBJECTS=demos/encrypt.o +SMALLOBJECTS=demos/small.o +TVS=demos/tv_gen.o +MULTIS=demos/multi.o +TIMINGS=demos/timing.o +TESTS=demos/test.o + +#Files left over from making the crypt.pdf. +LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind *.out + +#Compressed filenames +COMPRESSED=crypt-$(VERSION).tar.bz2 crypt-$(VERSION).zip + +#The default rule for make builds the libtomcrypt library. +default:library + +#ciphers come in two flavours... enc+dec and enc +src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c + $(CC) $(CFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes.c -o src/ciphers/aes/aes_enc.o + +#These are the rules to make certain object files. +src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c +src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c +src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c +src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c +src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c + +#This rule makes the libtomcrypt library. +library: $(LIBNAME) + +testprof/$(LIBTEST): + cd testprof ; CFLAGS="$(CFLAGS)" LIBTEST_S=$(LIBTEST_S) $(MAKE) + +$(LIBNAME): $(OBJECTS) + $(AR) $(ARFLAGS) $@ $(OBJECTS) + $(RANLIB) $@ + +#This rule makes the hash program included with libtomcrypt +hashsum: library $(HASHOBJECTS) + $(CC) $(HASHOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(HASH) $(WARN) + +#makes the crypt program +crypt: library $(CRYPTOBJECTS) + $(CC) $(CRYPTOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(CRYPT) $(WARN) + +#makes the small program +small: library $(SMALLOBJECTS) + $(CC) $(SMALLOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(SMALL) $(WARN) + +tv_gen: library $(TVS) + $(CC) $(LDFLAGS) $(TVS) $(LIBNAME) $(EXTRALIBS) -o $(TV) + +multi: library $(MULTIS) + $(CC) $(MULTIS) $(LIBNAME) $(EXTRALIBS) -o $(MULTI) + +timing: library testprof/$(LIBTEST) $(TIMINGS) + $(CC) $(LDFLAGS) $(TIMINGS) testprof/$(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TIMING) + +test: library testprof/$(LIBTEST) $(TESTS) + $(CC) $(LDFLAGS) $(TESTS) testprof/$(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TEST) + +#This rule installs the library and the header files. This must be run +#as root in order to have a high enough permission to write to the correct +#directories and to set the owner and group to root. +install: library + install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) + install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) + install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(DATAPATH) + install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH) + install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) + +install_test: testprof/$(LIBTEST) + install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) + install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) + install -g $(GROUP) -o $(USER) testprof/$(LIBTEST) $(DESTDIR)$(LIBPATH) + +# $Source: /cvs/libtom/libtomcrypt/makefile.unix,v $ +# $Revision: 1.7 $ +# $Date: 2007/02/16 16:36:25 $ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/mess.sh b/xmhf-64/xmhf/third-party/libtomcrypt/mess.sh new file mode 100644 index 0000000000..bd8dc19cae --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/mess.sh @@ -0,0 +1,4 @@ +#!/bin/bash +if cvs log $1 >/dev/null 2>/dev/null; then exit 0; else echo "$1 shouldn't be here, removed"; rm -f $1 ; fi + + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/notes/base64_tv.txt b/xmhf-64/xmhf/third-party/libtomcrypt/notes/base64_tv.txt new file mode 100644 index 0000000000..01c8a4e746 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/notes/base64_tv.txt @@ -0,0 +1,35 @@ +Base64 vectors. These are the base64 encodings of the strings 00,01,02...NN-1 + + 0: + 1: AA== + 2: AAE= + 3: AAEC + 4: AAECAw== + 5: AAECAwQ= + 6: AAECAwQF + 7: AAECAwQFBg== + 8: AAECAwQFBgc= + 9: AAECAwQFBgcI +10: AAECAwQFBgcICQ== +11: AAECAwQFBgcICQo= +12: AAECAwQFBgcICQoL +13: AAECAwQFBgcICQoLDA== +14: AAECAwQFBgcICQoLDA0= +15: AAECAwQFBgcICQoLDA0O +16: AAECAwQFBgcICQoLDA0ODw== +17: AAECAwQFBgcICQoLDA0ODxA= +18: AAECAwQFBgcICQoLDA0ODxAR +19: AAECAwQFBgcICQoLDA0ODxAREg== +20: AAECAwQFBgcICQoLDA0ODxAREhM= +21: AAECAwQFBgcICQoLDA0ODxAREhMU +22: AAECAwQFBgcICQoLDA0ODxAREhMUFQ== +23: AAECAwQFBgcICQoLDA0ODxAREhMUFRY= +24: AAECAwQFBgcICQoLDA0ODxAREhMUFRYX +25: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGA== +26: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBk= +27: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBka +28: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGw== +29: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxw= +30: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwd +31: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHg== +32: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8= diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/notes/ccm_tv.txt b/xmhf-64/xmhf/third-party/libtomcrypt/notes/ccm_tv.txt new file mode 100644 index 0000000000..3ff4b77a5f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/notes/ccm_tv.txt @@ -0,0 +1,214 @@ +CCM Test Vectors. Uses the 00010203...NN-1 pattern for nonce/header/plaintext/key. The outputs +are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous +step repeated sufficiently. The nonce is fixed throughout at 13 bytes 000102... + +CCM-aes (16 byte key) + 0: , 54C92FE45510D6B3B0D46EAC2FEE8E63 + 1: DA, 7A8984228DCF944903936CA9D7709ACF + 2: B95E, 1056DE0CBBEEA760ED2053FFEB554EA6 + 3: 58FF3B, A42DE1A812D29BBC6C1C5AC808565437 + 4: 9D6E6FB6, 5E8E0422792999381ED669CE17601D34 + 5: 40D49E851D, B076B4ED79BF0155B39A743550593944 + 6: 015356B9A6E1, 8D62CEFC451CAE4A21C1C579C6CAA128 + 7: A2CF0A77AE0DE2, 97B9D201740FA59E863513EDACC59FFB + 8: A44C68E52F95B48B, A461B79D4D9B8ADF6C6618E6ECDC059A + 9: F56B8AD68AA31F22B9, C5C7D2E6FE34D94CE72B86DA55679080 + 10: 5C17EEBF4E348CBE3278, 29FAE7B470CB652C501343FE23B25894 + 11: 1EE960BFAE360302D834E3, 8F8F475EB9BAB29CE14A9CF42C30B148 + 12: EFF6BA1F2B1389237C6C045E, C895302DD8E75096951EF5CA63BFDD67 + 13: 5A1179A4047334CCD9162F36EB, 110987D37F45422625DEA402BD7580EB + 14: F26E2C27E7D287B182FA42879978, 530FDE90C13A01EBCA86449073A3B035 + 15: 77BFE79B4BC87116EC5232606E890F, 280994EB0E16C7CF10F31BB60DBF52C8 + 16: 9926A4CE1AD70B89CC0050A58B958742, A635B4272EBFA1F83DAE270452D877E7 + 17: BAAF99CAE4753E3304D6F8F9C0CD366C68, A6F606AACD0B87923B43C3EB61AC3965 + 18: F72453C6765352A31494FA02B388E407B1FB, 0A446D28B7C5845C3621B4D3A0FA98DB + 19: A7372589A86B2E137F124A96618095EB5E1435, 3C59A6A858947FEBFD32441E37309F1A + 20: 5683E13A4E82A1AB8B3DC2051B6DBF2E1F2BB417, 459D1B0D2CF2C30B5ED5C237D07DFC19 + 21: 33594C4B84536C23DA5AB2117E9267258CCE5DEC3B, 6E4BB70A72343E142AC4E31CE0FE6A77 + 22: 332EDC9A3BDB90DBCCF317AC55BE5855CA9BCA2A73C4, 9FB310E5FFF5C754EE1E5FFF865F1656 + 23: 734618677055469335FFD574B008F2C68B78633F79010E, FAD31386E42BB4EA76A643A9004A8CB4 + 24: BA6F6ABA2AF35895F7F966D71F4E91A0BDD1DD551826F861, 25A3EC1C91C26283BAA5975390285AB2 + 25: FF519213E858E36AC8D92450F81CA46C8CA8AB129A997EBB36, 0D4AB2B7A5EB02242C01A81CEBF5D84E + 26: B1F80058C3B4316EA86E9A898CD0B9C0366DFCB2AEC0799312D5, 0F4FF2759EDDF6349F4E23F284FAAD2E + 27: 00BDC15012F8183112D5C3A135DC60DC9C764A04BD39A8E041F1D9, 0C68BC9E6A6BF1B01743F3183C9B7C80 + 28: 3022FD12969D925365C553D98D59E5D1EC494540909D1FA794F41E18, 05E61844943E78DB9BD417DDDE9C98B2 + 29: 4F4A4554BFED6BAA09E3D8843C4EA3807B8762799C1D21289A46575389, 3A59A6DC9230020FE061466A92BBCAFD + 30: 6AE735EB15D9B39C8AD0E54F45307AAD97DB9F8A2A66BDC9BABCCFBD54A3, 0BDB365E493A9E160EEFD7DE24101870 + 31: 4AF19F00EAE55FED2304B94FBCA29383042F2BE711041323C1D9F14BA63383, 94561581E496553D068052BA698683D2 + 32: C2438BC46A92A465E0DB41E638CC6C8E0029C4DA842CA4140D73F90985EABA9C, 0F5A69F52AA8D8508D09E642511E54E5 + +CCM-rc6 (16 byte key) + 0: , D01FACF2BB577BFA6194800E53FB4A00 + 1: 65, 92E48F7300FA2697E9E0FF80DD187237 + 2: AF5C, 332863BC515649D5BCAB6A2FE5F5250D + 3: E7C89D, 49A641F027C65A15100009D99E79CF3F + 4: ACB36D46, 53DE328A8B4B14CAD363BED53DACE8A1 + 5: C3ADAE6CCF, F713F5079BD77046F95D8685CDF522DC + 6: 5A8CABC912DA, FB97B059D2BE1273497FA8D2739A1505 + 7: 27F101DD6D0894, 266ACEF34476A0E64410D209219335D0 + 8: 66164DA09BE2F46D, EFC64C01890A5B562AF39ADFC48E1CA9 + 9: 1B0018895394753995, FA894E1C882D96E35A4C238708931F3D + 10: D346062826187BAEFC3B, A036AE1D3C02E2AD23541DE095AC7B84 + 11: EFB375BA1138339FA1B504, CDD4232FF4664D59D5AC6BE32CBE1B35 + 12: AFCF494078D7D7E6D9803FD5, 07E06ED923F76150BE82C1DDCB62C4DD + 13: 75DF2EC91379408DA426A444E4, 440ACDF2A6567FA3A5009DDFE502A1A1 + 14: 3B36B62B01E324E702694305DD29, 4093598607DCD9993845D1837D211FE2 + 15: 7DF6595C9711B164C99CB246B4D57E, F364993B2C187058F466B62D11E0F94D + 16: D317EE9EE1746D1B89A4CC52D88F0819, 41856B0B229D38344FA718E04CA57A8B + 17: 85252277A97CA7553007995BD5A0DCD372, BDEEAB636BD1ACC8D5A23F658150FA30 + 18: 36FF305AC6EF662C155A1C15A6C195D3EC88, 9AC48EF07A510E308E06E79C0C80C3A0 + 19: 51645A614313E978F6DCE7BBDDEDC33E3284AB, E9F7723E763AD50161C0671C4034FD0A + 20: 3CB9E6D0730FE05F903D338708AD8E34BFBB3285, 8A12185DAD518049F0FAC945A8FB305A + 21: 276E37D246C40ABF32DC83007B95390EE801CDA6E3, 73FA1D310D031E0A0A3A1421661B4697 + 22: 4444BB070EDFBD1AC59D0BF70D66F48F0830069F3562, 9DCB6A99CBCCE3C8AEF29F06AF5057FB + 23: D16BA084CF82EDD2E43349311140BF3A2E37DE40544BF3, CB93C5AD60C700D4EA653136101AACCC + 24: 3FBAEBB36E2B74014043BA7D72F899B0D8DED883F592D778, 54DEA31D7EEA863A06A16D6C9B25DC13 + 25: 3614B5428B790793F31E23670A38A070B65DB8E51C61FEA9C9, A91B750FD7ABFF18376C982DFA0C8872 + 26: AC15FD90A4C254BA1406BE7DBA5694BB2625F634C69F45CCCD04, E6F97BCC8526BE3C04BA139EB50E65DF + 27: B506E83557E48553BD8557411D2C17D64005E734BA5A5FF1CF98B1, 6FA001758A19F783A71C97AF1AA61F94 + 28: F07721663400838947EA1B9404D9683556F2D911429A9F59E3F5AD31, 376A1165A30C919E96C3706A4AB5DB37 + 29: 98B5EB8FE0005E515A585D8F44D838FA590054EA5201CD444366B6F71E, D8C58448F601F2C05F24ED2CC349C78B + 30: E36E2FC225767CC1E2C388BEBC2C81C340FEF5B504575D5FA49682E1C214, CFED56F38CA4F84E6E1E16CEF50A6154 + 31: 7A9FDD8E481B822B3D282AAF726944101ED61DAE73782DE055D7D305E36B27, 328B10841E977041CBD13C39CD70F03F + 32: 48AE8B5FA027930A7BCEC27468D795D0D8E6099C5F0558361B3AD20C1ECFF89F, B180AA9353E9EB6A22710A4DE872FACB + +CCM-safer+ (16 byte key) + 0: , E106F41D61402E532662213EBA471BFF + 1: 05, 1749600C7045647DCB3293C0724E7A21 + 2: 2355, 80DD597665723F4AEFFF760C5C6C5EE2 + 3: 5F4CD8, 59AE54E63A8CF4DBAD050B42CE922013 + 4: 75F63A43, C31B6BD3125C036C99507DDEE0197201 + 5: 51D4D87B8D, 0F3872088CDEB0E958C35F343677AC24 + 6: 8CF6D81A274C, C8E688954E72A052B5F8D1CA46FB44B0 + 7: 5EB8283B299AB1, 5977CB96C8D439DE3A86AE0452A2EE34 + 8: 829B1A4EA8643EAA, 1E892D3DFB73A469035CA81DD7F937D1 + 9: 0FEEF9504CF0F4E282, EDCBED7C61E8E2D24392B4145218F0AB + 10: DEF7679D3073D461A94C, D7ABAE561901CBB30FD7D9467C088B3B + 11: 625FD679C7354A74D62893, 450E3954857640DDF4C7A95A6E202A1E + 12: 3C9E76E4E2D4D95FEABD5C90, CD4467F695B7ED8973AEED5A822B347A + 13: B1B6294ECEAE6AEE4853731CA9, 6042302DAE598822BE8554BE038119CF + 14: 204BF480582D4BA408BAD23CEB52, 4D6B87334E1BFB9BA2D42B89B24165B2 + 15: 277591770E3E2DB97A3011D9616991, 75D0A4B9937748EAE7794056F7A8A7FE + 16: 5669F75D0C908BFF7B82095231B86DAA, 3E816776A73FB89276534A3646C0F8FB + 17: 37E621EF5A043A83FC98A65329891BC031, 159A823EA61B3A47B42EFCF12F304725 + 18: 18AC6ECF3F478A0797BF813C871235A9D309, 9B415B1B3A933B22C9027E2D72764956 + 19: 671484C7587DAAB885C7F2FAF030081B452CC6, 574A63D113A5ECEC877D5A368A3160AA + 20: D7AB0F7D46B7ED976C8F6E7D0C6AABE3CAAA5A6E, 266C7A025C4EDF657DD42EB82BB6616A + 21: D60E4CFC6500E237276A69F35AE4BBAE17371392EF, 6ED2A1673F8B4DB795547D9D93D76D8B + 22: FAC6E21979D8D9896C790CB883C29F84D6820AE4FD4B, 1C7B6D73200E3C2DC5C701152F38EE8E + 23: 39240DC2B544CA8BEBBB4EA499FD48A5EE707198AE8AC8, E7FFD169552665ADE7B9C0DFFDD04EBD + 24: 6BE2C24172CAA192D55CC3E640E34675DD7F441CE5DB0FC0, 760CA976355281F76E49A2856A4EC7A0 + 25: 0E20427218D6447D6E23FA4832CB8D2A172B23FDC542B41524, 27D0F37E109252FF5E6F6F703CA784F5 + 26: 0AF75BD89028A5691B8B7993B9CE4FD24334A312DE28212C8B2C, AFE4C6B193B0F1796FC9E6C23292C060 + 27: 6830D8E2E6DEC1476796DA44C982D36409E268F966283A66E801ED, 9E2C92D5B30EB0943E17869ED4C789EC + 28: 75ED280BEECD7768F7E032071F0E06D9D6BF1C9FF8E5DEB536DCD4BA, BF0DD11D633DBA5DCD25F4172765570B + 29: DF1FAECC1DB24718236B18B90B354F405FD5DE1257EC43F811F4A43DCD, 48D182E572E794350BBDA91FD76B86BC + 30: 176681E38ACACCD3C625F554C1F7A2D7C2C474C9444EAC8929B8C36EC05E, 080E109FFC5D247F1007217DD642BBA3 + 31: 8A8172C21D88A1FDD43089C545C308507617F7BDB02C47CF2719F1484407E2, 1A0D10B0AF5BE21BF19D570D3FDA5BCE + 32: 0A93CAE2B95517773A4009FD3438231A207B9D46AABAE83FC4E1057EA4E2D6B4, 717AEF2F55DC8669F7E2D0298F8A7BE9 + +CCM-twofish (16 byte key) + 0: , 33B3DF1B59C84DD3C15E4FEB66173303 + 1: BF, 92DCEBF1C11DD0B028DEC944A555E4C6 + 2: 8A4F, A859C7F76291326D821BB3C7519657C0 + 3: BAE755, 14D7C2EFBCA1063460FEFCEBAE3AD79A + 4: 25695BC6, 9358BC434B14B59ED17F9C0D3F51DCB1 + 5: 1D9FC70ECE, 2A86578FA3A8C702E2E6723DB9A9893F + 6: AC39F1DF3661, 3F9C71EE0506FD2BAFFEE7200D22CD92 + 7: D330A915EED9D0, 22DC25EDF5ACDEF8358BE2A3082112BC + 8: EF913ADAE6380507, E87D72BB6395EEEF2AD4F546B4033DE8 + 9: 5EC16994E762BCE467, D7700F7BF4FE026A2076F161C3383A0A + 10: 7EEB4910B7C2B540B490, 40C88A977E1DCDDABD749ABC9A0C60F8 + 11: E5DD32FF54D39451CC2AF8, 541B1558B5AFF6E9EFBEE496D60AD65C + 12: 242C2900F859966B6627FF5C, 1CED148098350F3A5D1B5634180817A3 + 13: EEF025B9E4EB867B127EBD19D4, AD0179A07AD1418C25F40E123C2BEF47 + 14: C5E812B0AE37098686E2C4452C12, 02FC88AAA62E34742BB8577A651E922B + 15: 7BCAB32D1A871A62F9C781AFCAC60C, 2CD1C11EE197D9E130359F76E7F49251 + 16: 1E82D8B8EED9A730D1670F0DCFF17B60, B7730261560EA6CF715FF7006D5FEFE2 + 17: 0E1966992E360DC81312B28ECA6865B811, 10C40ACD169CB0F2A6FFC99F9A5516EA + 18: 5F5418C1322BF7EB828CF27C1F72086515BE, 90F8ED0447171A10476DED39F7518075 + 19: 6C552506FA167FB8AA12E9F416930031487D4E, C992009F83F31A7BF922BFAE68C4134B + 20: 38429D966676406B17638DB7F9F7205250408BB2, 3385A50E9789D2C63835A80EFE9CFAE4 + 21: 56EF426315EF96BE4C60B49F41C9BDDE2E0CDB3C22, 2D51D5B4F5B04BEF3BC1A7CF1AEA70E9 + 22: 314B075C097EE531ECCE6AD7CEF22A72AAFCEFB02029, FB7A7D84D23FF524D060871D90FAC106 + 23: 61CCCF7E2A9B3E46CD0A94D7F4A7617BB0DBA2D989907A, B3F4D46094732F3EDD81E0755F0C52EB + 24: 7A812A3BCED4E0A72FB81218BD5A4E33D69CA18834FFAE61, 487F80588B41F4E1198124708987667D + 25: DBFAB77EF07AA4C9ED2B05500BDFA00FE3F19F15F97A74880A, 84504D9EECBC6CE11B18BD105DE55E2C + 26: E676D4739B01B5101E36BF8D9F4FAE8F767C028E83A6D5B39664, 3141A05669807BCA30F0934F599FD077 + 27: D8FEBD069D87C1EE504CB8F72ADFF2166B14BA40B17B4DAA439668, 1D99A301943041C2F7A71432DA736FE0 + 28: D98E2A1CFFAB28341F92C41971A21AD0FDDE733EA25F2607967CD0C3, 42E05A53BF4F1A6C5B7F84742ECE031B + 29: 13FA412B484945C1FE8291A7EB8F8FB78D2DC2C72C5132386EA82BF4A6, A1A8E8B026DD116B0F9C73EB14C1C7CD + 30: 10ABD2DC25C8BA594FBFA9312E69C1A2DBF326475AF2080E55E3611FBC0E, 49DF8A5171DAC3FB684BA2CF7FBB3D3B + 31: F401D2123619B81F54F307B783362CC40FB4FB2433CF51F5543A147BCD1FE5, ACBB670CB3722059B4B9FBEE67703E98 + 32: 839A9BFA1D3CA37924BC6648DED2291FC61736A3638906D9C5DA28A66AA684AC, CD07B83C8E0C3E6FB4115A149BDF6FDA + +CCM-noekeon (16 byte key) + 0: , FF73C6775C61DB36D9B5EEC812091FF7 + 1: 5F, 7D2AEA62A5202E3C4FBE05F33EBE4CC5 + 2: 0EA5, 312ED15FDDAB6EEEAC6AF9BE9CE698FA + 3: 968F95, FA1AD58B85B93B5A4B5096C881F773C3 + 4: 9A8F4069, 8911063ADDF79E27D9DCEFF3F440E6D7 + 5: A5C0376E27, 9553F44B0BA8039527F8E05CD70AD8B0 + 6: 5B097736F3DA, 405B7EC685FC94903B36AC8E700558B8 + 7: 616810AE303B2C, 64C95A2DF5263F7BE6D1F9F3CF88EADE + 8: C8D69A2E1170532C, 073A7E426266237FD73D8109F55AE5D3 + 9: 3E42CDB7DA4A72F2E0, 48675EA4302CA6BFE5992DE96CE43BB3 + 10: 88532CC1F3E321F66D64, 528B3516C6D9A4B5390DD32C2A2E6C19 + 11: 9216A8FC9A961E7F602F7D, B03047186B783844F5B6757057576B38 + 12: 89B0858D4FDE6795EDE19CCC, F4530A2DCA823307AEDE5AF34E5C4191 + 13: A676E20BB0A5E84FD0B9149BF7, 11B823B315DA93B0E15780851526D4BD + 14: 903AD5C108C43A80436FE2117EF0, EB1C79C7DF20CE2967A99783EA8D6EF8 + 15: 81774C36F46F67159B7FFC24C080D7, 2E9E4812D9A92977EC34922782B6420D + 16: 63FD1C3F692D64B2DA3982FCD474A5D4, 04171AE84857713A9BABBD4564875D33 + 17: B1BF6AD99F83C9173C6C021ACA74C5431C, 38D17D4F6AA3C24B8F3B465EAACE0A1E + 18: 0948D1ED59F07DE44A96A76E05B0B6F7C309, 1848D886FCFF35E85B0DC3CBE5BEE7FA + 19: 3458E5911222F9C555A1054C7D9748876DA39A, 584AFAE72FB6065A74BE016CF39D2E86 + 20: 641F3867185D0605E9D666AB605187E75A1299EF, 6F9332E6FB5EA0CE811E3345593CD163 + 21: 0676622D07733EF31A765AAB1E713FCE329277FB16, 88547474050FFC986930CC04BA8A03F0 + 22: 79861EC2FD2BCC5C12B69F30A1575FC66AC1405281BB, FC68EEAC8F39ED69D312AEABF8000084 + 23: CB2731835A576F7F8F2C2786D786FB6186E2F85D89DA3B, 3ED9E95BC51CF6368E6EF63667B35BD8 + 24: 3CB1C02FADB6DD5483BC5D3C03D944102CFCEDF82B913402, 1C3F60C989A6FBF41A7AF4F29115C334 + 25: E69FAEA5E3D0B76EF9E70F99C5918D934D0E9836F248DB9EEE, 7F1916B2CF7C9A5E3F5581D365ADBD31 + 26: 36779AD755A9DF2DC3C5824DC2F7DD4FFE038628A4E1A1C33AE7, 2BDED3703468D267F8AB7EC0AF8F1E65 + 27: E9D325646A41EE5AA7DABCDE98DE83440A7DC02714BA0AEE017E22, 972F4D7832F3371C60DCD04A6DEDEA15 + 28: 0FAAE3F6028A28A80BBFE71FA7AA9042E538B41A0D514D6EB4EE6029, F7B3925495E260249ACC6E1CBE956BC5 + 29: A9CC39EFFEE354C0E0579256AA85CBAA7B10E670DD3828A7A05DA0F49D, 28D9D20187AFE70AD9DD16759F0EFEB5 + 30: 032F4BBB4EBF2E65758C541FDAFF2107DDBED399739849F8EBB41AF9711F, A3436981ED637CE5EEE01B380C46ACAD + 31: 7B321ED831CE96A603668E3E74BBC7453749A03D04A1B38E95966E6CC488F0, 88D1DADF2C1EE0BA579D0A8A90C1E62A + 32: D862B0BD0E2178AE05AEFB14F34C791547C5956F1F3B5BD525926578DE383A94, BF32CFE059F27222DC55D3E7CE7C5F10 + +CCM-anubis (16 byte key) + 0: , C85F41475E06F25682F855C3D45A6523 + 1: 25, 437BD73ECB8CFFAD9B2876F08D4BDA36 + 2: 5ADC, 5C762058A5EF71278B69F567F18CBE51 + 3: 95E541, DF099E8218AEDE8087791B38298334E9 + 4: 2DAA84E4, 7437094198E4AD2647C2618248769A26 + 5: B9641C5855, 91B02EC44D22460BFF22BB40C799E20C + 6: 102012BCEFA5, E60488DA65D683182F0EFDF9DA52A78C + 7: 8F14972CA4F8EA, C26B51F20ACDEC7DCA911500CF1241ED + 8: ED2714B652972256, 8BA29459D5D370FC608EE362B55B7633 + 9: BF58A269A4F59CE0A4, D69080820F836E5B5CA8F393E61ED009 + 10: 44AF1F715ADAF26C6EF0, FEFBC7DB75ECDDBA4A13CBF9A57873D8 + 11: 77CDE1B951F0803893642D, FBF8B80B061703504D8D3A7718366B6E + 12: DE599BAAC9D3EFD9FCD47E44, F636EC35D172D661F01746FF86688B95 + 13: A792B8359050C4866572977415, AE67D4EED92E63A14003FBC936EEF43E + 14: 62D5A7A4DFB78A175831627987CB, 25F7B440DBE9902C28B28E50BF02C516 + 15: B6F289459F924C76586F4EEA0C1CAA, 54266B4424C3AF6E81F6CC4F2437F54E + 16: 884B7DF3395F063DCA26BDF9F2FEF4EA, E3C2BFA1964EFDF78FDB9559C8031C50 + 17: 774962377B8731F2F301B930487518801F, F35B54264711D843D23636BA6CFA3E4C + 18: E9C8D1164F2B196C7305406179B232E45F1F, 2A13E034A136EBC0ED3361737EAD214C + 19: D3DCD242C952C5589E00B65CD826CA87691B8F, 9D624D482042798DB896B55D801EAD98 + 20: 57065B2655D4799C0478FE7E8463A2215E758875, C8FB052F14F9DF6731A9C8B566E71D53 + 21: FF736FDBD23593D9BC9A0D8CA7D819F550EF969322, 5CC3023029790BFD43204B27D52D7D7E + 22: C562B7387B8F1D3DBA22DD1636C9C4AB443F2FF15F70, 195C928EAF88BB4ACBA8A01B4EBAEE6E + 23: D0AC6EA8A804DC261304D4821E6AD7FCC2F0DC1A299B9A, 34FE2034CCF09A98DD50581DA8BCBE39 + 24: B65933A7D7C8EF19C1BDEAABE2B4CE5E821459D953565EF8, 42B20EF142EB228803D6AF47C6482BEB + 25: F1F4FCE842EFEF563F6F047956E6706DC9B178D00D82776D74, 3ECE3050D8C80319821D5F57A7CA7066 + 26: 4A3F10F4E34210A5CA1B81AD4269CBC3FD68AC662BF0E9DC9935, 0BC0724AA9A194D8C75EE6FC8E7F28F1 + 27: 077F3C055303FD669BC1A370B18AA7F31D3C8CBFF5A69381404FBB, 872C7946401BE70E677B79EA13FB0F58 + 28: FD39D32B27FE5BB8E6512C642D490E0AD0866E386580AE115C85ED2B, EE81712EA57DD54DDEE98EAB3285E6EE + 29: B45ED179290A6064188AFF6B722B37F8C3E984EC37AB5F47B353229B12, 186B3AD0C9F60D57E84992CBB2B0F71B + 30: 83FF1FD179D518A414148C15BE566BE4CC3DBE9FF5319A651E862811F152, 4B2942C66565EB9139A83C2EFD549D55 + 31: B8176469E6A0D5797ED6421A871FEECDE48ACF011E394981C43AC917E8FFD5, E9B01383DB1A32E6126BD802A6C6F47E + 32: AB6A0AA29B687D05735167D78DB697BA2478BD14ECD059AE9D1239E7F2AB48FD, A560A30FD87CF28BA66F5B2638567E4B + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/notes/cipher_tv.txt b/xmhf-64/xmhf/third-party/libtomcrypt/notes/cipher_tv.txt new file mode 100644 index 0000000000..c649d26a0e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/notes/cipher_tv.txt @@ -0,0 +1,1967 @@ +Cipher Test Vectors + +These are test encryptions with key of nn bytes '00 01 02 03 .. (nn-1)' and original PT of the same style. +The output of step N is used as the key and plaintext for step N+1 (key bytes repeated as required to fill the key) + +Cipher: aes +Key Size: 16 bytes + 0: 0A940BB5416EF045F1C39458C653EA5A + 1: 2B20AF92A928562CF645B1B824F2E6D9 + 2: FC29C3356937ECC3159D8D6EF5E883A1 + 3: 4C07B5A2EF31A3229C87AB2E4DE88602 + 4: 93AFA1147E793FFCC3D852695A62D008 + 5: D4BCC317DC9AFE0E6C7AD1E76F79DBE9 + 6: FEDB3371F3C65162AFCCDC6D18C79A65 + 7: 4AF2A76F93F07C14161C16B5C176E439 + 8: 00A1A596AF7CF44FD12981FA12CB1515 + 9: 8013D7006AB38AEBD40D0DC10328751C +10: 81A077F3A262FA4D00D98EE4D1BEC390 +11: 0CCBC99A3135F26D2BE824D633C0366F +12: CDBB5568610AD428706408B64DB66E50 +13: CE94461EB0D57C8DB6AEB2BC8E8CE1D2 +14: 06F14868F4298979462595C0FBF33F5A +15: FE22A7097513246074B7C8DFD57D32B2 +16: 0F2D936610F6D9E32C0E624568BB8E6F +17: F32BCD92B563D475E98322E5850AC277 +18: 6E6FCB72930D81469F9E05B20FD406C0 +19: 42FF674CBA6C19C4AD84D42816173099 +20: 41C12474A49B6B2B5E7D38E03A4DD4E0 +21: F9E234E3CE3FCED184C775B6140AD733 +22: 7EB5CC6B183D8B3EB4FBA4717CD8838A +23: CB6C5D78F9721E5BF8E980F0EDCAD4AF +24: B3F20EF6C26FD9301576D82DA6D50809 +25: F9375037377D86599FB4F241166C43E9 +26: 98BAF9AB7402479C2DA356F5DAE35D5F +27: 58D1A8E0DC3BC53FD995BB0F60F25FE7 +28: 0A75C0D22D2627C97BA2A7344B9B8C74 +29: 88C299B2F8C9EDAF86A301BBF534BDA7 +30: 755E3A17420281F2C619588A6B521FF9 +31: 0E540DD25C0C147461146E11F832A63D +32: DC5B58691C6BA5B243036A41301BD7D1 +33: E9299A7336C2D8A51D6C7E2BD1B8F054 +34: 78CA6F682FC649DB289DD62D28D3A22D +35: 98D96EDA081DE416083650B22BD3869D +36: E747DE96D122CE1EF6F89BDE0FAE75FF +37: E48DDF2EDDEB54C861A1E42F5B649EEE +38: C650C2CF1E903B7F9C8536A2446CA762 +39: CF0BCDCE0F1FE7EB40016C1231FB2962 +40: 37B1C8BE3812147E0D5D115A797663EF +41: 45DD8184581049C4B28FBC0809690C5D +42: 11B0D889F96E677EEC2E934E9F7F5398 +43: CEC30BC1128A96CD506E406B5ADFAE19 +44: DE67D5439BF83D5338D53F362FCF79B6 +45: 724FBB2D95CBEABC568AA44941D9B6E5 +46: C63F480DA3C73B2A661F1FBC3E4D1F89 +47: 225CD18789D18FF09C982EF38AEF0AAF +48: B493DEC7E3D11911DEF8788102453670 +49: 23E0B12A67DF025CB77CBDF9E295FCAF + +Key Size: 24 bytes + 0: 0060BFFE46834BB8DA5CF9A61FF220AE + 1: 597FA00D03EDDC81C2575B4DD6B6AEFD + 2: 4881E4EF69005DCB9110BA327CAC8460 + 3: FC4A968AF65FCFF45E4698455918673D + 4: 3079D7B27A3DA5C0805A61CC37109EE0 + 5: 9B3F2C7C35806276E2C53826EC1B3C84 + 6: FCDFCB1FD9FCF1B63E1AB6737FC154E8 + 7: 4A8012AFD410D29CE2CEE0FD195EF9DA + 8: 9F4201C4174C71A3AEF8FD6822197D67 + 9: DE3E5E98DA60E895389A1C17E3D50DA1 +10: 20C9064A076C01D1BC121A5A2A1F913C +11: BA41A36CD24B515545B8B464B244E5BE +12: 2CC1DE9DBCAC45269C6DBBC9203095F4 +13: 2ED2499CFEB30203E6305B3E1C329C4D +14: FD709FC0AB48B204C95B74AD189C8832 +15: 7ED298B472C53A4CB7A3BAE588805E86 +16: CB0C6FE2BA76901F9EDE752634DCC31D +17: 6C5CA6EFCF7101881507AB8770ACF1DE +18: DEC3C5209E98BBFAA469C5FE6C02A674 +19: CFAC040C1198C8264679CACEAA7E9DE7 +20: EF990992EBA8ECA7E5F95E3B9D69D3A4 +21: 8FC1B640EB55A96D08D83D1184B77769 +22: E1F3DFB9D055BCB2D6CED6DCB8361BFB +23: 6621F47057706F2A079819DBC0197B9C +24: 882611AC68778CBD6A46FB5DD4611A37 +25: F35E1367A283CC641FBCE26512A8F2F1 +26: 5A4A71F69056CFBAB67DDA777F5CD945 +27: C446F2BFAD060A9E9E17F71B05ADABD0 +28: 1F0E50F71A67FAA7D169A7A1017FFD65 +29: A6A38588848915509451A2354D2AAC8E +30: 4C887574F2C5DB00ED4FBAF814A70302 +31: 1B642944162A049CCA9FD0284D7AB4C3 +32: 431BD9293C5BFD12F948C255C838880B +33: 32CD23A30039AE2FB80B804B905362B1 +34: EBB30E07E7517580A645CD1B5F664182 +35: 292F2BB28BB172620B05C7621BA347D6 +36: 46C06E1223F392D57B98EFCF4C832C18 +37: 451DFBAD2AA92080204F85432236A42C +38: 768D6206D2B3DD1B9C26FAA5977A6477 +39: 3705F9CEBFE8F91ECE07F84578C05494 +40: 085EB0DCF360F5403FF1E7402A0F7A03 +41: 2A0D56F2E7C7FCE3095F511BDE4AD9A2 +42: A8AB2F3643A61AF164F99FEFAE2CE1B4 +43: E73FD4B1FAE0E5E6A6A31CCC2AF96386 +44: 578E84FD1AA16FF350374E4FD5FDD529 +45: EEAE301DD57084801DB01F8B9C4036CE +46: 1C44A93B404298327857F71962E0604C +47: B5F64CD5835C85A68DC23E26D4B8FF80 +48: 6C6F97850A87088AF195D0500B3F5D78 +49: 0BAB3A60A25CD1A750C2C443AA01C57A + +Key Size: 32 bytes + 0: 5A6E045708FB7196F02E553D02C3A692 + 1: 5F7229D6AACF0DAFE3B518C0D4ADBAB4 + 2: 96477F47C0A6F482AC4036D2C60FAAD8 + 3: 7F791D54914F12E9F0D92F4416EFBEC0 + 4: 87DDB19415BEDC42BD361FE380553C5A + 5: 8EDB2A09DC8731DB76D9F67A03AC4D9E + 6: 269A7C08C28D5E4D9355DDBA161F862E + 7: 042A3397BA5029C443DD76755008DB2A + 8: 469C82A94BC5F7B2DF57F0CE1716EE74 + 9: 5A84A93077FA19146078310035F4B7E4 +10: 28CAF1C0D811F86CFD3C5EFC30DF79F9 +11: 05B575D06C2D593B708F7C695CE97571 +12: B7E8CACF0A0BD7F2F5DA0B09CC8B8AEC +13: 0ADDE90F66F1BCF38CEC63EFBF9DBD46 +14: 9BF99E7F5B8F176DD686AF017D5196E2 +15: ABC189EE80D4A4588B3D54DDACCD9778 +16: A57405378580B1E8A8D877791300374C +17: D1EF03F72FAB3DB68022FC60A2CEC13D +18: 3D2406231BA17FF7CC973C5E203872DF +19: C3E07233BD101502953D6186001838E4 +20: DC281C0CE02A83098C80D6C9463F3449 +21: A923023D2390B2230FCE9217776AAAFC +22: 92E28E69009959FB84046C5ED1B64D1A +23: CEF8F684EC64A31C651280CDC942DFC2 +24: 5A954684B22691F9CFC60442A654EF61 +25: 56A38A0D93188BAA50DFAF2CB799A76C +26: 54503340C5DE26679AA5F35215DE85EA +27: E74BFAF64946DFD699583FF9C47A1EAF +28: 01F234F9868B085E9B1A2EC84738E2DB +29: BBCA3DAEAB24EF25BC7B623F4D9FD680 +30: 3956C880F7F7D94ABC259D3D86157F27 +31: 4672C2149054C839C537BDA1F5BBF8F4 +32: CF1E9ACBEB391062593BD88C7948F64D +33: CA5B4E867AE9D8BA2D4416C908EB99F1 +34: 36666180C768636CF1708CC5C85A6875 +35: 53E396D2755218675494C7AA515A2310 +36: C2B7D31A59A602A65E155F80353DB83D +37: 0EBCE19FF6FC03E327A2602F858D835E +38: E47CC2A5E6C7FEF185806E2CFB304D91 +39: D61F15FF75E0F523FA3872132A09AF42 +40: DCC25495052980986AE30756BA0417DA +41: 451BF5B7C1F1AED9F3D5E18A391EA4DA +42: 1B6B105C580083D23F3A8EACE41B7984 +43: 8C2F86CD6C86B67C9EBDCAFC5720E4F8 +44: 41360BDB3E4C6836BE0D15B659CEC5AA +45: F972104AD851BAE0AD963817A3F03F58 +46: 396095F7C102B5A238110DD3D6D4ADFF +47: F58391AEB9A5D8BB32A3055B37556E81 +48: A23789B146CE89C876F3C331901261D8 +49: 2684AF345C4B13FA154E93A3E2CD2A90 + + +Cipher: blowfish +Key Size: 8 bytes + 0: 84BF44A1442B8217 + 1: 3981205BDD22C01E + 2: 0ACC5CCBA118CD07 + 3: DF76980D5E089145 + 4: A8503E8D849C599D + 5: 5E56574687038F5F + 6: D63296B036996F50 + 7: FD2FD7A0669A9E7A + 8: BC6583720A962585 + 9: 4B38C2856256103E +10: 48A4FA354DB3A8A6 +11: EF97C32734BE2A10 +12: A7467E9C729F8123 +13: 04D2507F9C4B5854 +14: 57F76A4D406B22D1 +15: ED0A3B26D842C8F2 +16: 047CB457E9730CD1 +17: 9F13BB1A97BF5E2F +18: 628CA4F77161C95A +19: 37C7D8EF718DFD50 +20: 2C9A9C655B839B1E +21: AB222D66579DBE0D +22: 57950CDEAD6FAE88 +23: 67AAB3669431E403 +24: 6B35C87144F6B748 +25: 94C2E8A1DBC963C2 +26: ECD68F56EED1F78E +27: 2E7BE0B866B1D3C7 +28: 6671DCDCB3D8EED4 +29: 8ACBE7A2F77FBB35 +30: 0BF0AC4EAE284F93 +31: 29928AE5DC8A57C6 +32: 84E48C27E21264DF +33: 4EF0E943E4F48ED3 +34: DA155BEFBFFD2638 +35: 611EC83E0931FFBE +36: 3BDDEC15BC543A92 +37: D7B9564BBAEE19FC +38: DE44907E9F0A1F11 +39: C8638C0594D13614 +40: 9E67F1B15418BF14 +41: EDF531A083F72852 +42: 7E5F8F9A72890BB3 +43: 2A0B060E3EDDE9C3 +44: 9B4B0F6FE6511106 +45: 328658F222C7FCE4 +46: F6F1B50B4F9F9C93 +47: A620519E69952F5E +48: 24DA24DFE96AD818 +49: 226C43435FBDA34A + +Key Size: 32 bytes + 0: 46CDCC4D4D14BA2E + 1: C079641BD6584E5A + 2: 38828DF8B4C4920C + 3: B4ABCF6B78A721F3 + 4: 8E7E2914CBBA708C + 5: C0EBE7002C888495 + 6: C60F404DE7CF9B78 + 7: B29E843E1771EF26 + 8: 983033386CA6A09B + 9: 76F1F89AFDCF7130 +10: BED4E2114F4376FA +11: 879A2B9D19AFAB87 +12: 366201BC87532AE5 +13: 6F409580FA907A64 +14: F7A202F00A38863E +15: 98B0A9C79FFC27B1 +16: 1CB68D9BBF8A1A8A +17: C21A2C54E5471D23 +18: 76A81C3DFC149934 +19: C7A0627412FC323A +20: A034684D7058E7A6 +21: AC87722F27029BC2 +22: 36A6C2AF10245E3E +23: 1F85B90D11217EBE +24: 9C2A0C383A4AB7D5 +25: 11D5C689039CA179 +26: B0B38C7077E1450B +27: C59C7DCCC3B8A1BB +28: 9BC539F29208AC24 +29: 8546F17C77C60C05 +30: B189C3E92AF53844 +31: 3C7689163B8D2776 +32: 6AFEB9A0671156A8 +33: 05514E39F2990008 +34: C941E31A2A1F42BF +35: 87C3777C74A730A0 +36: 2861667755C8B727 +37: AF75A0312433B151 +38: F76939331E9C9792 +39: 819FF8C81FC7C8DC +40: 31E7B07EB03D170D +41: 696E5EC1A741170E +42: 6C5BF0E0BA48FEC3 +43: 6D751BCCDC475797 +44: BB5A91D0CA7E60F4 +45: 7F7EC0531C88B14C +46: 9F302392529B70E8 +47: CAC9A1A88F09AC1D +48: 39D56A652E02D5B0 +49: 13641D42BC126517 + +Key Size: 56 bytes + 0: 373C66BBA50EB9CC + 1: A4E8C602AE3A2CEB + 2: A59F08BA78502F32 + 3: D0D4968015F4E4FF + 4: 0D3C2F291E6C2EE0 + 5: 3F99F5DADAD5FD2C + 6: 5BA41EC1A506396D + 7: 0BDE3B5B50591D35 + 8: 5C4A6AEFA69A115D + 9: ADABFE96D6D159E8 +10: F97F0B9C88ACD5C0 +11: 8882A163F0F02BB2 +12: F00556C9F5A56A32 +13: 257615BEC96CC228 +14: D58DAEC547DD8B89 +15: E677F4953EC44097 +16: 20156D066DC37000 +17: 6F18E01C6FDF947E +18: C8DFF24F12621237 +19: 032F91C5119AE308 +20: 394194AD8BC1E5CF +21: 6F24E937F3925581 +22: 086A4510D95759F3 +23: 073204BADF0EE942 +24: 5BC8B8E402D90F43 +25: A10B7E9D01DD3809 +26: 22C0B183AFFDA506 +27: 216306AE6DDBAF3F +28: E275E1F52430A1FD +29: C3BDB49D588D31BB +30: B860818C5923B688 +31: BE1BC7A444B0E141 +32: E4C4B67900DBC8DB +33: 36D7B7ECB6679A9C +34: C1EAD201EE34BEF7 +35: 9ABBC877CE825B14 +36: 3B211121C0C3C09A +37: BE3B34FF2E83F5A7 +38: 46C2B3E628A53EAD +39: B7E7DDE16C7DFF62 +40: 3C9A14C4226EBCC5 +41: C5FD46242DB29704 +42: D45A96723FF62201 +43: BB015D10878CF70D +44: 71DB021BE398D41A +45: 06F52D237F06C260 +46: 3552F47E8CCFC73F +47: 769E33828AD5D88E +48: 659861DDF080AA67 +49: CF7A13782F317342 + + +Cipher: xtea +Key Size: 16 bytes + 0: 256004E1F55BC0C7 + 1: 2D385C151A691C42 + 2: F93BFEA758A7DDB4 + 3: 2A905D97C0CA3E48 + 4: 12C7C2787B913AE6 + 5: FB24B1F32549EF59 + 6: 2A8BFF867FB4FF73 + 7: 5692243526C6BA77 + 8: 4CD423ADFCDD1B6C + 9: 9B99AFC35EB2FED0 +10: 416B4AA4E07DA7F4 +11: 4DBC9052ABFF9510 +12: 8AF9457F8E599216 +13: BC3CA2B1C7267395 +14: E4BE31DF42282F7A +15: B344CA8AA57E9E40 +16: 57A1F94CD2F4576D +17: 96177FCD28BFF1BB +18: 78A1F63A0EBAAC33 +19: 5F3FCBCD7442B617 +20: D6F7CD5ECA688967 +21: D92EDF70CBDE703F +22: E2E2C2EE5D18E58E +23: 4BF00478CB7833C3 +24: F9936D550815FE8F +25: 19A3B07B3E47D7D8 +26: ACA441F099A7E30C +27: F70183F199988E3F +28: 0A41FC22F369310A +29: ABFAF40853A4A38C +30: 6B5D29DB1155D96B +31: 0DD0C08A27561D66 +32: 4C56E22292F17AA3 +33: 3F925ED65613DF4A +34: 521B4C97081DC901 +35: 2B1EC3E1C8CF84EC +36: 2A412556F42A48F6 +37: 0A57B8A527DFE507 +38: EB55C9C157E3C922 +39: 6E6D6E9AB925ED92 +40: A4C5C90A0D4A8F16 +41: 7F9F9F658C427D55 +42: 9A5139994FF04C3F +43: 9054771F027E29BC +44: 90543E7BAED313BD +45: 5DEC1EBE6A617D36 +46: 19AB6A708CDB9B2D +47: BABB97BB5CF9D4E4 +48: 2C2ADC05AF255861 +49: 52266710153E3F7E + + +Cipher: rc5 +Key Size: 8 bytes + 0: 04F6B9B18E6828C1 + 1: BEA50D165E50EA04 + 2: 6F3728FE19F09B03 + 3: C682C26278B372FE + 4: 78BCC81E144E1B0F + 5: B62775716366450F + 6: 5BC49690F97CBCFC + 7: 359414E9EACDE379 + 8: D3331D8ECBF684FF + 9: 13129FB10EAFC82E +10: 7F29218421CC4B5A +11: FC225A4F31A75162 +12: 29BF8BFDA8A15D37 +13: 6854AC5BD98EEE95 +14: DEF05AB6D102E992 +15: 317C3EA6F0600016 +16: D6F3658B2E80B77F +17: 7C1DF7ED6C92C23D +18: F8665145BAFE28C5 +19: 9D8059C34B79F0EF +20: DC8D1617D3EBC7DB +21: 2D8FF59FCA19BE6C +22: 5C6956743715EA13 +23: 91160BE1F4F3D4A0 +24: 1D482C2359EC93F5 +25: 9C21D1A3755A7251 +26: E48D1BB926D51E63 +27: 08A054946263F617 +28: 9C900BA37199B7C7 +29: 0C6C58743EC83082 +30: B24197EEB5603D3D +31: CF5B735F8A492E49 +32: 337C504698BBE553 +33: 3A2BCCC88BE9ED51 +34: F3E9241743203ABF +35: B67BCC625815C585 +36: F8E96E4EEBC2566C +37: E27D162006C67C8D +38: 08CE8C1A5E3C169A +39: 0CF8AD04125EFCD8 +40: 6712F9F044864FAA +41: 0FD465AFFD64085E +42: 6BA8C82B3974391F +43: A5FFF24CE9659357 +44: 0947F81E1EB4970E +45: DEA966CA50243067 +46: 1F1BE4866F48E39F +47: 03A7D7CE793F52C7 +48: A1FADE3F801B414A +49: DE7DA6D14A50E305 + +Key Size: 68 bytes + 0: C8704ABBDA9624EE + 1: C719C645E301FC16 + 2: 32D82553B0E35EF8 + 3: C63C77EE6C2A6E36 + 4: F84EDA1E77ECB5F0 + 5: 382C1E72AA1FD1BC + 6: 6B00939F535F9C83 + 7: 3CE0825AE10C2B0E + 8: 1F9E7738602BDD0A + 9: 9273E7933CED0B0A +10: 4CAB45EEA45C32DC +11: FD0208C6A89FB519 +12: 520D8E6912E9551D +13: 5B88684544868BD5 +14: 32AA2A8EE58135D4 +15: 281045702DD38766 +16: 26D68E073C996747 +17: 23DFB9E174D86192 +18: E32FD5AF5101E45C +19: 3DEFB679670A143C +20: E616394D859BFE94 +21: 217B9BE0ED47DDAD +22: 4F7901A5620EA484 +23: 6654C042783F5737 +24: 752AA74BACF9BE65 +25: 2FAEBEB8B325F89B +26: 6FEA020B058F32CB +27: 2A32682A36691665 +28: 338C8AB628A30105 +29: DFAE9DD082DFE38C +30: 51B451C29DBA19C4 +31: A2993DA9B8C1D5FD +32: 24D92FA331E2F93A +33: 821A961C0524C89D +34: A07BF305EE8964D9 +35: 981652361262C5CE +36: 3DD770C3761B695B +37: F36359AFE1C8A07C +38: BEBC629B8938F4A3 +39: 2E31DC53F77898B3 +40: 52E4104C4E8E6901 +41: 75C912DA610525EA +42: 2F280F70963F82DE +43: D7E3FCCA75AEE5DF +44: 8EBC7E825A14A2BB +45: C1138701F64187DB +46: 1294E21ED2550DFA +47: 577820D772BE2C8E +48: 48CE93C46BFD33CD +49: 3B50D264382E03BC + +Key Size: 128 bytes + 0: 236CF0A207576E8E + 1: AC12D8F1AE55F057 + 2: CEC4230F747B547A + 3: 61EA1B510D033B26 + 4: E064F51998E20804 + 5: 6247797DF02BAEF7 + 6: D25A766244063A7F + 7: 2C2B3FDDA0E07067 + 8: 04EED646C3F6FF90 + 9: 05487E7702865E4A +10: 6C0A92AC23ED07C5 +11: 6E54E768C797F797 +12: A7C53BF7B252A884 +13: 731052795E12C80B +14: 3E4DAD15A826C43D +15: 10B1191B4012C2A0 +16: ADD244B33AEAEF7E +17: F6CC7B5F0885E056 +18: E23489F3B7BE438E +19: B0C27661692FDE4C +20: E81CE014DA769F07 +21: 7A8BE0D2D52623A8 +22: 082F444E00D5E127 +23: AE42F684ADD1DAC7 +24: 9061BA686F76A450 +25: 9BEB7141B8F6F5F0 +26: 38CBA9933AEF85E7 +27: C66F4245901CB341 +28: 8659AA47E6B06BC3 +29: 357AB20DCE2DDA3E +30: 236689C2F36976D9 +31: 331EFD7D5CF7AD50 +32: C373526C2D44DB80 +33: 79F7ACBA770F5C92 +34: 64325C5A67F364F6 +35: DF2F720829FF1694 +36: 9EE17F47ED487BC6 +37: C41067896AF4CFC5 +38: 5776E1E5FBE59933 +39: 07A05B1508B739E0 +40: B19EF72A65B3C035 +41: F8BF5FF4095C0173 +42: 7F1226C6CA7B4072 +43: 8A6C8F26A97DD33B +44: 62948A9A627E98AD +45: 9EC58E3F8A477D21 +46: A656F285AE0684B4 +47: 8489690681A53EE5 +48: 940915E733721837 +49: 1221956BCEE0143B + + +Cipher: rc6 +Key Size: 8 bytes + 0: 6533F7041D69B9B883A5305180A85520 + 1: 496683D6356950E8F4AF4582630BE46C + 2: CA421828FCFCEF2F042F6D81F14CBE76 + 3: 92DB67F2F057858FC806E071D239F245 + 4: 203CDFE0C36434AEDDBE2DA68ADC5EF0 + 5: 8EB23BDBD58A279C1F3BF75199FC9E34 + 6: 8FA8BB4E772E09DD1EFBE03090E77FF8 + 7: 2018803BFD91D157AE20C6E8FF1894B0 + 8: 267319634294F0684AFA7B26EB612B3C + 9: 108745E1F2E80864D9043582CD5550EE +10: E4F9EFE5A6C426BB719EA17174890D0A +11: EFFD4CAE649740B3309692AA19ACA227 +12: EB909E6D0789F649538E7EA1686FC0F9 +13: 0216851E23EDAE52D9964939DA0A7493 +14: D6A9CD3429D1679D26A9599EBDE5409A +15: 5DCDECA6E89A7F0EB40649EFDE6420AF +16: B74FD556B06C07BA8D9E517348CC66CC +17: 9A22CB5B73EF1DDE68A5AEF1B1510ECC +18: 77F78557143E08A7449A75A13098FEF8 +19: 548FE6700BD17D0AE247B07C2F1AB0E7 +20: B7DFD8CB428A36733BBE9A51CF45C072 +21: E7E8B7AA2D93E3DE99C543A473CC6760 +22: 3FA5821248B0F0AEB5CF00EEF7958F5E +23: 0A655AC6C51DB33849BCDA72DAE106F1 +24: 9EE93EAB01E1A1DC57B698C266469481 +25: A7D398720E0ABA2D0D143D8306FD5AC8 +26: 98A46C94125BD2E5600BD26EEA420F2A +27: F4789EDC3C50BC4186816F14A86403D1 +28: F8AFBA8EC652EFDC3AF5EA5CFE143E16 +29: CEEEBD4B6724A30E1859A5B4EF9B2B3D +30: 766715B4C4FA7CD4B365A2A67C79E48A +31: 92C5EB7BE61155D79DE0A6F55715DA22 +32: 42CF0C9B2BAACB085CB1603688037D0F +33: 6C4BE816F7B573CCFA8BB6E399EEB17F +34: B6D7E606CC99D267ECCFDBC006878691 +35: 2048B58B74F9A721B2E33D2EB86F5991 +36: 3E458C1015ECB08CC7B8980135E71893 +37: E4E28A032CF2F3C8262CD4BBE7A4CDF8 +38: 701EAA449AD9E5AF81DF3F436AB25620 +39: D1C3FB7C16F5249503EB389A692B112F +40: 7012790DB65526DC87F9A2BF0FBB5664 +41: B782A3104FFE65DDB340F713ACFFE25B +42: A155F033E4536FB1176EBDF9EB5FEC4C +43: 8898BCC7A008127014850D5529327352 +44: 8F4B3BE150FAA0371CDE69891E52A3C9 +45: D371C8283F68DE983C98D98A7563B934 +46: DEB679915E8F0D0B65B37918BE4596F7 +47: 84D74F7FA199304A47BB37B8AF893CF0 +48: 5367B0187496539F6DF6CCE0965B376D +49: 4B9C6011D43CF2D8FAFA2E7105D85024 + +Key Size: 68 bytes + 0: 6BBF763FF30876A4BBB68A7E7E290770 + 1: 59852279E82E98B8B680E5CEE12BB99A + 2: F96989565E5B163EA483FF74ACA22DC9 + 3: 221F7A410F5AD73C1C67DEBA99683E0A + 4: 55F058D1D9B8C372E2A28AB6E953A851 + 5: 24A8F7E07620A55D69CC3981B92E5CCE + 6: F4D9DA95BF66FE28BA3A84E77E62822D + 7: EE7EAC2BD34DDE6F83E6D4F23C0A49D3 + 8: 4218AA697FB7C5D897E66EB00A9FB489 + 9: 55A8CDF8608A3B1A6B14275E2258A096 +10: 18D50743982F5C8A5C528BDB5896CDFC +11: 391403B889F0CEE865893EBE9F1BF90A +12: F3CA9C30C163C510432D3207DB6967EA +13: B14B6574DF53257BE4508DBE78843B47 +14: F52F1E5FD6FB19C1F5466276F9C33A97 +15: 9D5AABA86E8B65E4F633B6EDE17516E8 +16: 9038CF746F722DA1A0C34461359FD378 +17: 398E317E9CC074C2293B59598F72EA64 +18: 9D75D897D487DD2B5BC534B4B223ADD1 +19: 6C6DFF734BFB9700EDD6B3CFC6E311F7 +20: E27591407CA9771F227A5B6B3A77C928 +21: 1618F15FFA8E2692A3B3EF8EB6151427 +22: FA426AC6161F31F0D63FC9DA97A6A393 +23: 1281869E9959DED2CF75F50DA7FAB66A +24: E8BF17E4B76D6DC5C1D07DC80970665A +25: 9A869B6C5EEF391C7E7C4585FFD9FF3A +26: 59564F799AFC984D39A8168D1A30C8C8 +27: 1D3927AA2E2C48E6CFEF88D04ADD30DE +28: 39BF89DE1365DF15A8ABA86856ED074B +29: 0CCC4A4DEB36A000E7EB271F5EE54543 +30: 26476623D35A514B8833D868426A2BE9 +31: C3C85993EA15AB2D056D670707851802 +32: BF5F7ED18E1320BAD536DCEDEE1A9AF7 +33: 337BDC5FF0F7AD44E6A3F5D6712BD5DF +34: 7DBA76B3D9C818D0CE1A530BC79E77D2 +35: 20DF55E617CD2598F18534DA7A22B555 +36: B0A0C1BDF9E81B4F07F47D31A9CC8408 +37: CB9586F4B27F759B9B9C6C7DB01D26A8 +38: 1E79A2894906A64098AC43799CEFED38 +39: 82FA120F237EB0B3A1F8B52379B8346F +40: 3DB9848603E3B1134585E5C9001D119B +41: A750875900E244996887EC995131D151 +42: 12133748D3745F77C161470A921F73BD +43: A265C351694574B44517FDAD8816133F +44: 5E50CC8281C2A69FD376250D99620DD3 +45: 443ABBC1AD5605A0BA05B8E6ABA5D2A1 +46: 73546A87B39C54F0639EBEC118ADA007 +47: 380244C822817453C75405B727D67C4B +48: 73F1E23DFF05EFAB5D39E503031C4165 +49: 8030071491490590A8913AE4B5D082CC + +Key Size: 128 bytes + 0: 24B06811BD97AE9512B3799E3189DCD3 + 1: 92DBA6269E880F8D8A09143D792A46DE + 2: F956F459C333DFBA4C6A309C613DD661 + 3: C31488EA551CC0FC8885F6817CA696FF + 4: F59634FE907F9DF9467BD1059F82DAAC + 5: 051AF11DD2FCF742169B58A786128CE7 + 6: 87326A3A4A98CC15B23DFBFFC5AE16D3 + 7: 58FCDE2E88A79D5682729ADB4D971142 + 8: EAA787D68EB68CA79CCC6BFAC3BE9247 + 9: 8BCF6980AEED36AF38B68A50DD454AF0 +10: 4B0E31AE48E903DFF52939800BB16DC0 +11: 19766AA929B40840715D53D9170C986F +12: F9CAEB36F03CE7B3BB363AC7EB3ACF99 +13: C8E34A6BDEDA4DB836DF3D863D02A6EB +14: 370547CEA441FDCBAFD281A8653BE2D4 +15: 77E0F33343158A8C3AC3C6D14FD69431 +16: 7A985B1368F842C644538C654D081FD3 +17: 60E0C8933F43D40003030196E8E881AC +18: 3473474B58AE6BC7582ADD7AE24711B7 +19: 75936C8D46F6D5AF5C7EE0E8DCEB5AB2 +20: 4A04F619FB0E05F7B07C43F4B9F2E134 +21: FD53A5A7F4F0B9D933E38D9F07AC88CD +22: F62EE43B20F582AC77879AD7E66FCCAC +23: 4436AD771624896683D7D29E8879F89F +24: F88F3C0EF2B9FD0CA997BEF17787DA2F +25: FF5576F42CE9A0665A1D6A2420A691D0 +26: C077D6AEBA65B61CD1A9AAE17FCFC04D +27: 84D0D7C52D6DB3979BC3F6F34456CB91 +28: F163121D9EB7569CA7DE3B7619E0BE51 +29: 727D23FB43215467B57DC67A8890CF26 +30: 60BA577F3C6627267D7B33E693FB7BCB +31: 82C66B23586CCEA2AE1480B469B3F3C3 +32: A65092726D6CF2F77CE00648E2D117B0 +33: EC30662CBA891A3380B846DA6C64024E +34: CE1B253FBCE36B217ED1EFBAAAD2E783 +35: 9D963CD5E65A9ECD2DAEE93B6C6C1178 +36: 1B8E3D07E7BD4BB4248B6A7DF8935980 +37: DBC3FD5888B80C4CEFC6C5E170E271CE +38: 307CA8CDDFE5DA152B66E10346BB2E1C +39: 8858250F933650D978B403A4504EA581 +40: F06005FA6E56E0C0D96988A3FAD359FC +41: 816CBE37FDE3719804DBFD093E3FD87D +42: 4878C07B127D696214393DDC66F5EB36 +43: EFBA6045243050C0D8D82046B17008E8 +44: 3D30C3E5892D32BA3C685DC5B186E959 +45: D4A4C41F0E6687E4021FB90D7A8A9F81 +46: FE1057B2013308C4CE839B4186F43B4C +47: D7333AC65F66ED6D4BB8D069E265020F +48: 33C262F58BF0D91DF2047E799BAA5F37 +49: B960A18764D7A6E17FA1F88487EFF192 + + +Cipher: safer+ +Key Size: 16 bytes + 0: 7D42607880B424C27E5A73A34FECE686 + 1: 1A99D469F1946EA46523083FBAA79CBB + 2: 831385E400FD681C8A30AAD9477F1ABB + 3: 5C1BB8F259CDEC2C1BE0B803C7D9447F + 4: C57C1CBB18D87FCF72A87B247392752D + 5: 1625183B0C595A33FE0E8AE0DCE40ADE + 6: 4AF3A9D6733DC4FFF3422AA5BE5ADC94 + 7: 853133894C87A23318DFAD2B247FBFF3 + 8: 8C7F68E01A8413D19B9A479246E54722 + 9: 8620898ECD3BF91A47CC54E6D9987FA7 +10: 33F12ABB7CC6A9041543A2073AEDFFA7 +11: A096E46F2834F79C096D0B655EDC9A63 +12: 3DD0D7824A87C9F5D8D25F5AF57E70B7 +13: 6B7C99E5CD29AC1C5A8D66AB460E5AD5 +14: 95A9F6009AB4DD2AC7E8E45F36D91E9C +15: 60CCEFC6630329C341782B17365995A2 +16: 0276C96A7B1191BC16C8A9C98468DB05 +17: 1F352CB77C21139C058837B8194E3E64 +18: 2DB8E340F58844705F217551782F6B4D +19: 34E99832E0722C5AE8F0CA1A50E9E7E2 +20: 7E1538DC10C1F56C3723A87BFD127743 +21: 36B9714A8ACDC8B8A17E85E2803A8C88 +22: 11848329B0DB9DC7768C07D95F0CF662 +23: 93ECEDEB4C6369AC56AF1F49345720A6 +24: A3ED7F9D17067C2650728E266B623124 +25: F33574590B435D1DDBBA925F0D0EA8AD +26: 87E542DBD40DCBD80C4AB52555C264C1 +27: 6D806991AB8E3604C8267AC1EBEC2E21 +28: 4B7333F87EBB46BB2A8ECD392C85A12B +29: 4FF49ACA62898F558AC065B66CAD0234 +30: 62DE7B2133B09544EDD0DF66DC4F5E2A +31: 82195B39FF7B8A85D7F0EE52D19E510F +32: 24FA56176A4F0B37F851CBAB176C9702 +33: 85FA9230D9B93CDCC0752FC738211703 +34: D441132032BDAC6715F4453CBC2434D8 +35: 438AB9BEA8A900368D84EF870EAF7E84 +36: 433BE5BFE1529BFA7C5688CFE3BD4DE5 +37: 2A79FB6F37AA08533445B8BEA5098EA2 +38: B9C986EE45D204B6A1CA152944912C9F +39: 8289C9F78760D02AA71873FD97E2ECB8 +40: 48B0D1244523165055BE9A5E95CF852E +41: 471E211E5E784C2AF476DB3CB555CF35 +42: F290CBEB1F1009D250F7B12E044B80C3 +43: 1B9796D80C3976FE3071B1C01154D42E +44: A80E21A1A1007B69E8BCAE728BBE6A92 +45: 652058EF0FAF8549424F998669660931 +46: 89418FB4740E9801F6DFFEDC593FA32E +47: 907561A69CFA117F167A52B88777D89C +48: EA2EB4B1EE739320F99894B476A8A51E +49: E627E64AAB6E2FF6B99643A7FBB84BFC + +Key Size: 24 bytes + 0: E8975F94A8B1392FBA78CBDDCC8E8F08 + 1: 708CEFB68A0281AEA424B3D4698D2F2B + 2: 21A0DE56545BC950FCE4DF209C96CE6F + 3: F2CA4103B703264D46CBC09E13D5B8EE + 4: 2892101077FEE427C434CCFBBAB598B5 + 5: C2F191CC5C681CBFC098B264C479B2AD + 6: 308C3B794C8A7971BBA96FE4C727F48E + 7: 8A4F9D4463B5DC4DD461ED0763CDAEA2 + 8: B7E1BBBE455AEDF18329A6EECD6E222C + 9: C80DAAE7FBDF56DE05A897FBDBB53DEC +10: 6A3D38758BF0390156F22F83C20F0262 +11: CA493DF771E37A93822D6117ED14B60C +12: 623012748826A08F3C59B71FF3D66327 +13: A283BCB126B9795D306B129035BCC2DC +14: 3790A6704BB0F119139A0264F7E8B2C8 +15: 9B369BBC095428EBD712517B2C4D06F0 +16: 0F488018162193ADB11E4C39CFDEE0DC +17: 8AFB7C6FD7D6DD64C2C77DA3A0D91EE2 +18: B8BEFA241BA339BF6F059464C533F9F0 +19: E76141C8CD54200FAB2F8C2B76AF5FEE +20: 80B4FE57851C0240D81E78DA8200F195 +21: 8BF1C690EF5FCE7ADC74E31C24F83F5E +22: D30C4F78703BDE91750E0E49FA0E8982 +23: 86C5D1E0B88EF0AF9B899850510000EB +24: FDE727442BCC0305A7B06E6EE179D836 +25: 0B4A719342F9226FA680796887A98FA5 +26: 980D4BE9AF3E3CF9D4558478D1DD03AB +27: 03ECD11992D3D5864B8D1987966BA544 +28: 8DBC2931D7D17657BF38E3931F486850 +29: 76AE069E39FA7308BBF507ABE35BC1E8 +30: 9541B59CE18EA255CDC06DFD3FFCD1C1 +31: 5A382748AE3641ABF6D9CA24A35B2002 +32: 9B7A49DCC2CFC5A6078AB41E6F62B4CD +33: 91B2EAC878E5628DBCC7C876B91B73D1 +34: 31125CFFC41A0D3528FB16BAE761C47A +35: 916D2A769DA002ADCA8C87F8241BB50D +36: 681C3F601EE5D82F9B040932F2FB4AEF +37: 6B6F32E5EAC2F424074C33F7C988D5FE +38: D15A5FDC2A4956DE61BA6E1C98867242 +39: 0747BCFE1B979E947EED5225FAFCA44F +40: 133B43C85CCBC360DF8649BBBD2EB45B +41: 052D943062A6D475D30100EA412C30EE +42: BD6401C591D585F4A82CDCF678679D5B +43: F95D1A5E338F56760C425D972D67B57B +44: 9B1569308608CA00BB1E2BC9E20289A7 +45: B6454C52C64F64D69F1D36D2D224A222 +46: 529B5B013AE3F37E38BE340D1D200A64 +47: 1B65904F177212AC8E9ED4D8DB287810 +48: CD5CAC56236E0B9A25A5D306F12D8C4B +49: 01DF7E1D0F5F7A5DAA0B379388425126 + +Key Size: 32 bytes + 0: 7FBC212996ECE9CA2C4D5BD88FA0B3D9 + 1: EA3D788C25CF3BE7F4101EDECF23455B + 2: BD0B98481366AE0869ABA11DB18D1E95 + 3: 53393E2B757C90489EB6B47F67837337 + 4: E1D350640CCA6C13648C3B57BE00B950 + 5: 951E1EF99E6DE72744A9D8D9EBFBA94E + 6: 433E4D4E64B41818097BD5E2EBA01D8E + 7: 8FCBD07E303B381B2935FB82CA0CBF13 + 8: CF46569005BD968B9310149E892B4D69 + 9: F1B672657C2657AD53BFFE2BA5DDE1D2 +10: 0035337210703240F9CF2F5A9184FDB7 +11: 773951841F77DCF8A6730109DEDF3E9A +12: E47DC0FB381DB86EBD208A0D649E7B03 +13: 0D9E34ADB257146EAB95AF14636301D2 +14: AB5D5C106E52AC7662C26F9F27F2CD55 +15: 6938F205DC23C3500B7723281E9F626F +16: 3CABD52558D7F418CAF6B41CEC334DAD +17: D2192F1E5AFC3B989C42C396B3764862 +18: 59D32E3A41141C6CAA2A8F44FD587D94 +19: 483CFECF65D71CB2994E1C12A1A7F907 +20: 8F086AD81B1FD5B13195EDB4DAB7DC73 +21: EFEB1328CE7AE6A63E7D8B3ECA9E12B9 +22: 362AAE308B3BBA588DBCFBB7197E693C +23: B817A136EB30CD127B5015A85A7B6E95 +24: 03796E7F244CC916BE02AF61E5FEC42F +25: 5854F2889CFF44B0688718C23B0A822D +26: 0F772AC6E37364AA7B844AEACB33F4A2 +27: B3E95F5195BA646DAF333AA89130451F +28: 911A32AF7CC44309B37D75E158A4AB18 +29: 232CFE228EB72A949616B307C2BEED15 +30: 7C8989F135B8DE6FD26C7792B8354F35 +31: E79231779BFB9F792BD179C0625280A8 +32: 015F6CCAE8A1275A2E836A207D8254EA +33: 4EB94709245CE1FBF7C6D9587FA92D40 +34: 63D82005320F974EFDC4C021FB73ABB5 +35: 0F15B2E8E389C2D59289D7DA41ABD07D +36: CEE7FBBF766540D4E39903D0494DB797 +37: FB564C18A15D53108C1954FCD3518FC1 +38: A67C5F4A4A95AF2BD8E4FC1182B2EEBB +39: 0D354E664C35B9364E4EE9DB8DE0CA76 +40: 3295826D52F3B980B50EFF3E9317F1CB +41: BC65592A9C0BADD84F363A175EE6BC54 +42: 58DE762ADA621FE2A7A6A83F68E93213 +43: AD774FC8402F7DDBB881B703EC836057 +44: F1C95AD5E004AF35AE315AE88A2577FA +45: 968775A2C3485875B024B008D96182EC +46: 623E736238B5800ACD9B67D76C84D236 +47: 1C5E9F65D43343D743E50C80D0E0F648 +48: A62E4A197E15CF90C2569DC38D9FC915 +49: 165B139BE483A71381B9A8E93D9473DA + + +Cipher: twofish +Key Size: 16 bytes + 0: 9FB63337151BE9C71306D159EA7AFAA4 + 1: 8CC5A931DEC29B4C7D85595D24FF8405 + 2: E867FC0E144FDEA24FEA88D22D8776EA + 3: B450A2969C67D93E1AE3A4093BA4C48F + 4: 7AEA41F9956149F336612E868E42B3C4 + 5: F201FBB730E6E58CF9E5AD1DC4844C4C + 6: 13D8869E66412C6C288B5D7F37F2D94A + 7: CD57DDDDB782C0A04C40E47D920799DC + 8: 65371C8ABC919EC09004A7D63D9302BF + 9: CC31DFD3B7DCCC86866CC79D45A89C3F +10: 541D548D311714EF8661BFA721568D16 +11: 269F3AA2D2D10DBD3DD3992BFEE23C05 +12: F86DA5D73AFBA94A9D592D02B5855D25 +13: EAD8D785B50E036437E39F3B27DB4657 +14: 2AD0A13C493B9F3EDD259E11A495B205 +15: C05F9D72AA384F05B28A3519AF218CA9 +16: D442072F588D38AC8B9D447762E9FCF3 +17: FDD3BFB91EFD127196FF9F19ADADBF28 +18: F56717661B424E41D7DE1CD13E21DF89 +19: 0F6C952D9BE6CA49B5147EFD44455A92 +20: 6C214935726364F2766BE7B4C2B64362 +21: 5D5316D7E057FF481CCC10C7452D1A17 +22: 56C78DBD802CC9B040446A3EFF3F12AC +23: A38CEADA8448DBE29C2D11DF2A487715 +24: CB2F786AB8063350F3FAE11EC8C65A5B +25: F5B7298B6F558E2C4FCC11744AD22653 +26: 01BF89C1B48C5F6918FC6BDC10B12A21 +27: A031F25AAFF294EE79220BC76E73E52E +28: 42C94B50E12499DA35F14BB6BB6E684D +29: FD68B6840DC9A271CDE2032EF0200295 +30: A9863C1B04B3FE3945D29966F67B87E2 +31: 6226D4CEEC1E8AEC1B7B3E13D80A83FF +32: 6100A71B1E3ABBBA48A9ED280DD1617E +33: 5CE93A26D4EFF0CC7DFA2DD43A511871 +34: 282D165BFBA0F7F229161BE533BFC4D9 +35: E6AC479970891392972B2845C949A068 +36: 4E4A887368F8443BE51FA7CD16CF0B87 +37: 121AFC81AA2750572B35D100BDC34DB5 +38: 7C41FA7E0A18A87E44BE488F331B35E0 +39: C8847D295E1F505C04E2F5CE2CBF5E00 +40: 4686EE8628BC1BBB92CE825F04B1D5E8 +41: 397DFACD19C283B3FC27D3FCBE952254 +42: 815B6C69608B5A379E3C9E67FB1BA15A +43: A73E72B912EB3AA4929E9EAF73A448BB +44: 5BC4E2C88512BCD55408CC5AEAD15A91 +45: EF20B2BF297456DED1F4AB7BE0747902 +46: 3D876135E19BB56B98050450C6B0FD06 +47: D68100E1BAD07B438786337C0957471D +48: CE85A91938049B5E21C983F7C45ECA3E +49: 9FACEFFB9D08BB65DDC34E3C575B8442 + +Key Size: 24 bytes + 0: 95ACCC625366547617F8BE4373D10CD7 + 1: 99AEB25CCE73B3796C351A19791ACD52 + 2: 56B9D6689830275C1A3E4266B3D56D53 + 3: 2F5F822E11F087BCB8A0F428414855A0 + 4: 65400F729990FE175AAA894BCFBB1A59 + 5: 947BA33D20194BBB0D4904023FB32FFB + 6: 116B0C6744D215AE98DEB1F9FF1D36C0 + 7: BA6964C101FA044ED06877E46D540850 + 8: A36B18526FA0004CF557C99A3AC1423A + 9: 573099674B8AFC2DD6424A2E4C581B89 +10: F46169CFE9496A2696A93EEB7EC561FB +11: 2C64BC052898F3F3A2B78F2591F2BF1E +12: E8A0D40B08585459199DD6ECC108A490 +13: 47927989BE5EB55B9A0F294C04FF035F +14: 54A3024E3AD86005A2C44E4B8BDBBEFB +15: D0AD51D1DADFAD7ED0EBCC756DBCDCC9 +16: 5DE698B7014C34AA6F0099CBB5937A20 +17: 9BA30F49470C6DB9632C5EDE34F8EE73 +18: 0BDF558A2AE9298288E60616442D3408 +19: 25F6DD23BA4E090E1CFFA6EE3487AFA7 +20: DAC5FB99E299D2672F79F0C38E177D83 +21: 58CB113430895C9890D96EA60E3DDC23 +22: 48A0771F0049B776A44AE8877B57EFFB +23: 2F12B26A4BF7065076417530CDEE14CC +24: AA6ADCB0176D5324C4C1FFD640D502EE +25: 384B52A66F4C7A70ED36091BC3FEA09C +26: 2AFE7ACF071C6B0FD69930A09D6DD5E5 +27: 9A2DB9A5E7712A5BFB095D2C09453CA3 +28: 716C0EF522A13EA05A48F16BAD3FD10A +29: 44AB46F3CCFD02BDD2C77A332293A4D9 +30: CE6AB27A0F60F410B1B3CACD9AB923A8 +31: 69EAFAFC171C55D1D90ED1C6E1F3A48F +32: 5EEEB0B7833121AD7D27BCFAF2D4F8ED +33: 47133445A4EBCC60E27B29FCC160FA75 +34: 9F1BFEB9715A20D5FA7BA3BFF1A27BBC +35: 516D4615F07756B4DBE7D37EBBF4684E +36: B88744E53073BDA0F1B115E3DB224E83 +37: 1B77C3D067BBE00420450BA5CD9A83CA +38: 94B87AC96F8CBFF36B01A68E0651E591 +39: 52ACE87A1A8E46655935536FB3701290 +40: B406BB632D5B7985400EC78D621C8801 +41: 20F9ABCBF97A9917EC6C5DE3CB2C925B +42: 539A8AF920833F9E81A20A6D10543176 +43: B79AFB8BB39B0351094F37C6EC93F8A9 +44: 5830BD21289FED3F95C3E3740AC6C5BF +45: 86C4AF5839ECB9860B175642ADA32895 +46: A6427E5E08CEA2A50B8426B063AEE189 +47: 2E872129B5BC5F535BCE2B81F013A103 +48: 2203EB9B2BF51FC2025549D0BF1924A7 +49: 6A5E383A4FC78F6E03B9B276F81195BE + +Key Size: 32 bytes + 0: 8EF0272C42DB838BCF7B07AF0EC30F38 + 1: 9F8801E94E41A7DC875665663BFA7912 + 2: EBE2CA6B45A0BEE83B54402E1A843A3B + 3: F6C5A1187AEF4B5A88E97E866CD757A1 + 4: B3E62CD473E53812EDF9ECE875F39F5B + 5: D8C38B1EC23264BB7C42B5589C1300B2 + 6: BE315EB75B944EC9E51F5EAE65F70BD2 + 7: D4275409941A44993037364886B60598 + 8: FC34F1D4E9C4A634C1349F6D4E9AB94E + 9: BE712387C59A40A8A35F854333A0302E +10: 1F1FE164834BABC71DBFDFCCA7D2B4B6 +11: BB2413CCB5347B5157651819E698D988 +12: 6EB5523A968ECE965D9AA4B975D7C2EF +13: B5DD49AB7E269F9D8516FB57EB47D57D +14: 74F5D81856F192D49A70B3743945BFC0 +15: 95437BB00D57CD88BD52DE0A66D934C6 +16: AE4804A975D67C6B6F99176F407AAA3C +17: 5E5B2FB9B2A028A5467B56F8BDBA6980 +18: 8C617FF1F9C50A36BE2EC19A629BA96B +19: E3401F7CBE177A1D224117894E7EA08A +20: F8451D9DD31A08BE828FA9AF39708921 +21: 5BE66DD577826804817B85A07BCEDE28 +22: E426227780943AA1A830B7E7D7F7CA0A +23: B39C7277C3A5CA21897563DBD8DD6D94 +24: FA9992385396F959841D1E0E68CCE00D +25: E1DE89B1DD5CC31685558A51CC731E6C +26: 64618455C46C6FF117F19FF300B3B557 +27: 882758C02B3C11D406A21012977D4BF8 +28: F948B62F8038D3A3AFB73041B2F263AE +29: AE3BF626020D2877052B90B31E70B8A4 +30: F1C6DBBC166985C9EC2E1A3A61BD8E75 +31: 82C343FA36B6D4E9E7AF6D0B7741FB09 +32: 0BFB756EC55AC63BEA71E4A8187C2B10 +33: F1941AD10BE60DAD3FBA33CB899B63A3 +34: 18236A39CD34743DE7B60B2575A9B204 +35: AA37FBC2525F74710D7561D316E8D90B +36: 413E0F72C2B349FE2691554F77162B5C +37: 5B9E6F98B2CA0F637E463BE4A6EFD39E +38: 1B4A4CA36DC60D51BA981392D6070379 +39: B1E26163A90F339E33F86D252EFBAB99 +40: BB98F9F844FA81B25ECC89A8482404BE +41: CE142F512A42A28F4788847B971AA7E9 +42: C5CE782936F3D28C69C2BD45FD7BC117 +43: 9B6E142582E0A309EDB550DED51238B0 +44: 0D9D80C01612977FF3A2C7A982D0894A +45: A7630C752B1F787B07C382693334C6AF +46: 9F24990F270D575881C746481A59C245 +47: C38B5E11479C200B5ACE1D6522FC6B1F +48: 99118D8114D24B6559CC5D9456F1BEDB +49: F8B974A4BC134F39BE9B27BD8B2F1129 + + +Cipher: safer-k64 +Key Size: 8 bytes + 0: 533F0CD7CCC6DDF6 + 1: C3CD66BB1E5E5C17 + 2: 079DFD68F6AF9A79 + 3: 84EB4922264A1204 + 4: 31F3A7D739C7E42C + 5: 381F88FB46E1DCA2 + 6: CAF4AC443E50EF47 + 7: 2914E255DA9BDDBB + 8: A160A24120E4FECC + 9: F748C6009FFBC465 +10: 8B3CB5784846D2B0 +11: 4F98C1621473399B +12: B486B0BC365ABEE9 +13: 314EAB2B4E9F7840 +14: 613FE3637968A8FE +15: 28935352361E1239 +16: 0DCB090233B8EB3C +17: CF0BC7F307586C8B +18: 64DF354F96CB0781 +19: D2B73C6BAACA7FB1 +20: 638FCEEF49A29743 +21: 204C4E0E0C0A8B63 +22: F041EF6BE046D8AA +23: 76954D822F5E2C32 +24: 6700C60971A73C9E +25: 80019293AA929DF2 +26: 8EF4DE13F054ED98 +27: 41DDF9845ABA2B7A +28: B91834079643850C +29: 8F44EC823D5D70DC +30: EC2FF8DE726C84CE +31: 25DF59DC2EA22CB5 +32: FC1130B511794ABB +33: ED3259359D2E68D4 +34: D7773C04804033F6 +35: C1A32C114589251C +36: 51647E61EE32542E +37: B95A8037457C8425 +38: 4F84B3D483F239EE +39: 458401C3787BCA5E +40: F59B5A93FD066F8A +41: 1450E10189CC4000 +42: 0F758B71804B3AB3 +43: 51B744B271554626 +44: B55ADA1ED1B29F0D +45: 585DF794461FEBDA +46: 3790CC4DCA437505 +47: 7F7D46616FF05DFA +48: 6AE981921DFCFB13 +49: FE89299D55465BC6 + + +Cipher: safer-sk64 +Key Size: 8 bytes + 0: 14A391FCE1DECD95 + 1: 16A5418C990D77F4 + 2: EE33161465F7E2DD + 3: AB85A34464D58EC4 + 4: 3D247C84C1B98737 + 5: D88D275545132F17 + 6: 00B45A81780E3441 + 7: 6830FAE6C4A6D0D3 + 8: 93DF6918E1975723 + 9: 15AB9036D02AA290 +10: 0933666F0BA4486E +11: 93F42DEE726D949C +12: 756E7BA3A6D4DE2E +13: 4922DCE8EED38CFD +14: 8EC07AFBD42DF21C +15: E82BEBCFB1D7C6B4 +16: B3EDB4CB62B8A9BA +17: 5521307CA52DD2F3 +18: 54B5D75512E1F8F3 +19: 1A736293F2D460A8 +20: 778C71384545F710 +21: CBC041D3BF742253 +22: 9C47FC0FDA1FE8D9 +23: B84E290D4BF6EE66 +24: FC3E514CE66BB9E3 +25: E8742C92E3640AA8 +26: 4DA275A571BDE1F0 +27: C5698E3F6AC5ED9D +28: AC3E758DBC7425EA +29: B1D316FC0C5A59FD +30: 2861C78CA59069B9 +31: E742B9B6525201CF +32: 2072746EDF9B32A6 +33: 41EF55A26D66FEBC +34: EC57905E4EED5AC9 +35: 5854E6D1C2FB2B88 +36: 492D7E4A699EA6D6 +37: D3E6B9298813982C +38: 65071A860261288B +39: 401EEF4839AC3C2E +40: 1025CA9BD9109F1D +41: 0C28B570A1AE84EA +42: BFBE239720E4B3C5 +43: 09FB0339ACCEC228 +44: DFF2E0E2631B556D +45: ECE375020575B084 +46: 1C4C14890D44EB42 +47: EA9062A14D4E1F7F +48: 82773D9EEFCAB1AB +49: 516C78FF770B6A2F + + +Cipher: safer-k128 +Key Size: 16 bytes + 0: 4D791DB28D724E55 + 1: 53788205114E1200 + 2: 4472BCCAF3DDEF59 + 3: FE9B3640ED11589C + 4: 4DDD7859819857D7 + 5: 6BF901C4B46CC9DB + 6: 930DBFC0DE0F5007 + 7: E89F702158A00D82 + 8: BEB661953BF46D50 + 9: 6F0DA64C0FD101F9 +10: 4EBBCE4E5A37BED8 +11: 996EAA0AF92A09AC +12: AED6BB9522E0B00F +13: DF9C643624A271B4 +14: 2E5C789DD44EF0CF +15: 86A5BA1060177330 +16: 2385DBA4DEBEB4A3 +17: 82E2FC765722094D +18: B3CA2161757695EF +19: F8A4C6081F3ABC06 +20: 6422316E1BEFFAC8 +21: C178511BFBFF380E +22: 049B8CBEDE5942A9 +23: 0E181292C1B1DEFC +24: C347BA0632A49E55 +25: 32FDA46669714F99 +26: 0523743E30C16788 +27: 782BE96A93769ED0 +28: 9F99C9E8BD4A69D8 +29: 104C094F120C926D +30: 1F7EA3C4654D59E6 +31: 90C263629BC81D53 +32: 1803469BE59FED9E +33: 1478C7C176B86336 +34: 362FE111601411FF +35: 6428417432ECC3C8 +36: D74C42FCC6946FC5 +37: 1A8F3A82C78C2BE6 +38: EE22C641DC096375 +39: 59D34A0187C5C021 +40: F68CC96F09686A30 +41: CF8C608BDCC4A7FC +42: D2896AB16C284A85 +43: 8375C5B139D93189 +44: 0F0462F9D8EBAED0 +45: C3359B7CF78B3963 +46: E4F7233D6F05DCC9 +47: 8533D1062397119B +48: 4B300915F320DFCE +49: A050956A4F705DB9 + + +Cipher: safer-sk128 +Key Size: 16 bytes + 0: 511E4D5D8D70B37E + 1: 3C688F629490B796 + 2: 41CB15571FE700C6 + 3: F1CBFE79F0AD23C8 + 4: 0A0DC4AA14C2E8AA + 5: 05740CF7CD1CA039 + 6: 24E886AD6E0C0A67 + 7: EEF14D7B967066BC + 8: 6ABDF6D8AF85EAA0 + 9: 0EB947521357ED27 +10: BDD2C15957F9EC95 +11: 0989B87A74A2D454 +12: 04C793BA2FAB7462 +13: 3DAD2FACDDFA3C45 +14: D1194935CC4E1BD7 +15: BAC0A2C8248FF782 +16: 7DD5894A82298C64 +17: A59F552A4377C08B +18: 8DDDE41AB4586151 +19: 7CC4261B38FFA833 +20: E99204D6584158EC +21: AACC8ED0803CB5C4 +22: C105CA72A7688E79 +23: 3D662FDC35B88C09 +24: A4BCEDC0AE99E30E +25: EAECF9B6024D353C +26: 214651A3D34AFF40 +27: 807099325F9D73C2 +28: 45EC21AEB6B90A24 +29: DCED39526687F219 +30: 2CC248E301D3101D +31: C7F37AB8570BA13C +32: BB9B31A34A39641B +33: 5314570844948CAC +34: 4581F837C02CD4F4 +35: 4E036B1B62303BF3 +36: 7B3B88DE1F5492A4 +37: CEF2865C14875035 +38: 14DE8BEE09A155DE +39: 3AA284C74867161B +40: 3616B4607369D597 +41: 07512F57E75EDEF7 +42: 710D1641FCE64DC2 +43: DB2A089E87C867A2 +44: A192D7B392AA2E2F +45: 8D797A62FBFE6C81 +46: E52CE898E19BF110 +47: 72695C25158CB870 +48: 29F945B733FB498F +49: 27057037E976F3FB + + +Cipher: rc2 +Key Size: 8 bytes + 0: 83B189DE87161805 + 1: 7DCB9C9E50D15508 + 2: C724D535853CDE79 + 3: 113AFD4BA7D3D7E3 + 4: CFA06CFB93C2280C + 5: B3F291C1AAD9CB07 + 6: 606F74D9AAD4FA71 + 7: 1CC3F7AD551C5F89 + 8: 43F8772BA6C6B60D + 9: 2F933E12F57689DD +10: 2BC1AF0D5571D17E +11: 4123AAFABDB254E5 +12: 413E0AD5C709DCE0 +13: 6B3CF01A7542BD2F +14: 1E5E2CA0CD605999 +15: D0F7C9DC472A0709 +16: 00482798857A2BB9 +17: EED583440CFA8B48 +18: DFB377FE1EE5E055 +19: 30511C4C565E8F75 +20: F74A72482B43B99E +21: 1EE4EA7849B0B070 +22: DB7A4ACF022706FD +23: 2D7EBABC8C8E4DD4 +24: 6F0369BF66A8B637 +25: 59E5D13B247EE0F6 +26: C7BAB430AA89A5FE +27: AE0F03746D38138B +28: 942DF0B523D02482 +29: 929CE0963CFA46B1 +30: F8C68A91DC53B7CC +31: 5735395C63E15094 +32: 7821605C18D83D42 +33: DEC892FD743BA6DC +34: 77AC80C1177963D3 +35: 3E223EB4EA297456 +36: AF63B231D671D9DC +37: 665CA287AF32E92C +38: E451EAB337DC1EB6 +39: 95B179EC950992CA +40: B8937115492802AE +41: 355A6E5EDF40A939 +42: 353E77D4A5A28D79 +43: C958FA5903F921B8 +44: C334E296BCB24ABE +45: 4F37F7F652FE31ED +46: 77304A655B03ED67 +47: 3548A4209ACB6EE2 +48: 696E712B1911B695 +49: E4B63641D22A3DDD + +Key Size: 68 bytes + 0: 7ED68E8B30A7D5DA + 1: 867E18AE64B783EE + 2: 032E554D6AAD7055 + 3: 26BD785D0DDAD48B + 4: FFBD4009ABF53D03 + 5: A71006E1E30C3855 + 6: 92638EE741BE65B5 + 7: FC8C5F28CB38C83D + 8: F03F145CBCC4CF80 + 9: A28A7C63F67DDE7B +10: 3089486A2247B72A +11: CDD6E6BA5ED53A8D +12: B75A2DE8CB96A267 +13: F74D72A2CD68CEF5 +14: 3865AC8D170EEDBA +15: B1B520CE5FC2BA39 +16: 658DACFDD701B4EA +17: 6B5C1DA9484FCEDF +18: E3CDFB5755BDFFC1 +19: 56DAFF7E9A908880 +20: B6F8B970F68BC2BD +21: 7A00DEE6977A91F2 +22: 6C0CE4FD2D02B36C +23: 8EDA10D868504648 +24: 76FB106689E66EA7 +25: 67F45BB28A20E110 +26: 5F3207099AF93B07 +27: F5E382F7266AB342 +28: 0E31AC2E4CEFFBDC +29: 8DBA1B2FC6980FF0 +30: 311368E62EC2A9E2 +31: 50DD1F7A319727EB +32: F0DE146C9ECF5662 +33: 81CE0842CE223F15 +34: 4C442535A8BC9AD2 +35: 06EE8869DB91EBDA +36: 4078E7CAC29DCEE7 +37: 115D619FB705F289 +38: 3D3F8A380DCB8FB1 +39: 9044E5AB8049D21A +40: 66327F00B07CFC76 +41: 811AB23A4AD3F132 +42: D4A507E96BB39BC2 +43: 51C9E4C9318F87D9 +44: D2255C13DBD09E88 +45: ECB76BCB961F812D +46: 83D7E39727BBBEC5 +47: 415540F0AE34DD65 +48: 232D20F9E188E2C7 +49: EE37261ABA270B22 + +Key Size: 128 bytes + 0: 8A8F8E5C5A04C73B + 1: B197CF922883CE71 + 2: 8AF3F896460CC597 + 3: 755F313AEB18D3B8 + 4: F1DB52688BB879A8 + 5: 29D68EA6456B1CF9 + 6: BE7C444267A7925D + 7: 46A7BF7DED575933 + 8: E2C7AD7C902E5E15 + 9: 90A38AE1DD69C2EA +10: AA95FA050CD3388C +11: 23822B6AD5B83018 +12: 8FD42F0DBFF3FEE1 +13: 645098BC94FDE21B +14: 7E43D43EAC50E992 +15: 2F540FC66A9E0F43 +16: 453E52EA7B2D1F92 +17: F6F731E8C5A32C54 +18: B1E89646504E4D7C +19: AB8168452A7984E1 +20: 044BB0758DB5435B +21: E9BAE7C99A152BFF +22: B758F70708B6597E +23: 23A1EFD0AA925D7E +24: CA60DD174CBA23DC +25: 5E916F2DF7B6B3CF +26: F2723A9BFD82BB62 +27: 2BC381F6C048687E +28: 573BFD71896A4133 +29: 03DF7250C3D69801 +30: 8639060454669BCB +31: E31945F0A87221AB +32: AA39447BBF0A77EA +33: 174F1B65BF6A34A3 +34: 2712F966022A9589 +35: B6358876D6D56D16 +36: 2A92C131E68B77BE +37: 040C6935F4CFC43B +38: F23503C74121C660 +39: EDD120883F1F813D +40: AFC6500D34BD9D33 +41: 963117444417BDD3 +42: 2FC3A58861B4A58E +43: CFDB70ED8BCD1173 +44: 91B75760CF38B8D5 +45: 93A59048B78B3415 +46: 7E60C5E75225D45F +47: D4212C6422878FFA +48: DDD1B241E0E0EF6E +49: 20337DB931078078 + + +Cipher: des +Key Size: 8 bytes + 0: E1B246E5A7C74CBC + 1: 9262AFD8AD571E2E + 2: 36D2067D960EB870 + 3: 319834DC66705192 + 4: B4508A7C5F012C93 + 5: CAD1DECDDEE81342 + 6: AE9E1CBB71C719E6 + 7: D7FBB1CDAFD5B2C1 + 8: BE1A70564E3BFB5A + 9: 96D9EC1407A1BD34 +10: 05E4B9AF3A4DABB3 +11: 0DC77419E1F12C02 +12: F73E62369190A5E3 +13: 830C1CA7820ABA2D +14: D2574B6AEED0A4F4 +15: BC08782E293546A1 +16: A35DCC9AAD1EBFB3 +17: 79B2224667B33706 +18: F9462FFD2808233A +19: D6421CD0D9697DC5 +20: 57CB2173D67E7001 +21: DBE2DB0BDC07644F +22: 014E72E7E99C969F +23: 37901B1963D0B29B +24: 8E12C23929125686 +25: 73AA9E2A60C327A1 +26: 54A19D07D941EAC2 +27: ADB8CBBAEE1848D6 +28: 3997E866119856B5 +29: 4D647526FE7E1E27 +30: D574FE7342104F93 +31: B84383E34A790E11 +32: 322214BE9B93BB6F +33: D4C8E0B7AA139D68 +34: 2B9747CD280E48C8 +35: F92EB2E3711FEE2C +36: 5CEE84E124B7882B +37: 82427488597FF618 +38: B1E8B313D2DC76CF +39: 03E237CD40D7F214 +40: 8C8DC1299293E15D +41: D6C7463FE86D4EF8 +42: CF1550CACE647779 +43: B998B3D32B69F00B +44: 1B94C342C3D91107 +45: ABD4551B27F58BE8 +46: 2B24D978D1BFB3DA +47: 85361D36950635CB +48: 448009F38F1DBB4A +49: 6B901B2B79B6950C + + +Cipher: 3des +Key Size: 24 bytes + 0: 58ED248F77F6B19E + 1: DA5C39983FD34F30 + 2: 0BD322177B935920 + 3: 9D093F3174EDBAE3 + 4: 756B1F2CDF02B791 + 5: 57C31C2A913C1126 + 6: CF936257517C53FA + 7: 5F06305849E5E158 + 8: 9A85DFD788C59D19 + 9: 6392279BBE29DC1F +10: 76B0AF835D79C4E8 +11: 7073F36DB1E31464 +12: 276258605F2CAB3B +13: 3B69E97811FDA996 +14: 3E6E491D2862A1F3 +15: F8F3F68BDB006520 +16: FD376E66D401A097 +17: CA2FE47825804996 +18: 6F5C256F84FD14AF +19: D7B07F5C40FF0CDE +20: 73F2E074F1324496 +21: 0B2A35016F24BD21 +22: B040D2E3B311C193 +23: 3938DEA347112E2E +24: 9D7C1703CEC0BFAA +25: A07949F76BDFAF68 +26: 43087EEF52564C4C +27: 11132B599734AF0E +28: 62A04C819FDD9A8C +29: B74F0E5649D33690 +30: 8E77E5009B0AA322 +31: 5174134B9A1889B9 +32: 053E33441D11AE63 +33: 01EF381013F86E4C +34: BCA358DEF35DFD60 +35: 5908A88513E2E5A0 +36: A3214C8367E04B05 +37: B2CBBE851A54BE9C +38: B271817F63B3B76A +39: 08AFBF82ABB97D8A +40: 2CE02ED014186B86 +41: 63F3011C97F6E990 +42: C392351F432738D9 +43: 0534DDA50E685725 +44: 1509456871F5CC20 +45: 2383029935901342 +46: 8714F1A53CCB213A +47: 2491B2FD3CE6A7CB +48: 4BB02399D85BB66E +49: B8AC2CDFF7AC22C1 + + +Cipher: cast5 +Key Size: 5 bytes + 0: 9B32EF7653DAB4E6 + 1: 48AEB06B1BDB2397 + 2: B530927183622D58 + 3: 0ECC8F24BA742216 + 4: F6352F9B6461D82C + 5: AF6315AE98E12A71 + 6: C364D4B506EF28B9 + 7: 817061BEDF5E0A5D + 8: C19DE7B1F2066C04 + 9: A6E1345E3AA1B79D +10: 06B036B04785428F +11: 244DAB3F7223F567 +12: B9CF3791F6C79F4A +13: 86C5A02AF0517C5E +14: A16E3198F1317E04 +15: CF72A44C01E36DDD +16: 199C72ECD5E632ED +17: 0BC66BF05EB7887A +18: AE1F696F3D6B7952 +19: 685C92084F600885 +20: DBC1353A95AD2097 +21: F481E98CB36CAB3B +22: 8F1C06A482C70BB6 +23: EA087739954A9CE5 +24: 6D0AD727D8E4EF9D +25: 61CA0F7965FEE246 +26: 0D664CA16BA785DA +27: 2359D363755605B9 +28: 6B6E3A216ABFB55A +29: 6FBCCF7B0342D3C9 +30: 3431F4572E2CBE57 +31: 36D84FCE6D5D8FE4 +32: C234F6AD41E34E76 +33: 522F12E8D0617263 +34: AD8199B6E94D4E74 +35: 56DEC7C21C83B2AD +36: 22CDBFBC5B476E69 +37: 70BAD497381F378D +38: 4584F15DBC0EB7F3 +39: DE0603CEE19BCFCD +40: EA8D582C1CE62FC9 +41: 4299C28A912CE568 +42: 7208AB000E3FA9D4 +43: 7AAE6CB398D01665 +44: 33A6AA42B6D7949C +45: 2AEC5640AD535D69 +46: 74D37D9DD7B67248 +47: A5300FFF5CF85833 +48: 834F83398D591C38 +49: 85C787A8B7E519DB + +Key Size: 10 bytes + 0: 95827CB504BD43C7 + 1: 8FBF4EBCB8413ABF + 2: 5CFF411BECED9971 + 3: CEE2AEB4415E0A5D + 4: BB3A8DF7C54FA88F + 5: D508B933EF335111 + 6: 993745722EF0D8D3 + 7: 04EFB233AA88E796 + 8: 478A7DCEAF243F90 + 9: 269CC3D138ED48E7 +10: 88EBD14D2F999C89 +11: B7441626D4487A20 +12: 46A6E2CE6C66058E +13: 60687D2D5381757F +14: 885D05ABBF187B89 +15: 5032A7ECD3D51521 +16: 50BAF36BC5C14A8B +17: 8E805499569FBB0E +18: F8359B18AF3E69C5 +19: F24E415CB4D2AA95 +20: 361805D4E45B56B4 +21: 3172336F01E3530C +22: 333A551E0A03C4A3 +23: E2B991995A2D2962 +24: 067CEEDD8F213B67 +25: FEC3F306851F8616 +26: 4B80DAE6AB11894F +27: 250C26E21A8273A2 +28: 313F2A505915C909 +29: 42E0DC3D4816B38D +30: 9FAEEF0510DEE721 +31: 3BB5F5EF74B4CD7E +32: 0FBC9007F462BEAC +33: B9D1467B0D7A1043 +34: D9B991C9348DF321 +35: 061D577806C50742 +36: 48AEA67AAAB6FA23 +37: 22F7910383BDA87C +38: 9987087EDBA56FD8 +39: 2FCC8341B69BAA14 +40: 29DEDB6C2A433F50 +41: E067D2746B99A9CB +42: A5C9CB975A856D57 +43: AAFEFD3A82D6185B +44: BBE8952CC93CCCC8 +45: FC08CE0934EF2E25 +46: E44E642DBA7CF3F0 +47: CC26F0E8E85AB372 +48: D95D63B8389082E0 +49: BCA941C921B91E16 + +Key Size: 16 bytes + 0: 20B42D77A79EBAE5 + 1: 96CF6C91E5183CA2 + 2: BD87E77A38DDB4E2 + 3: E7454CA30B69DE2D + 4: 888F278D219384EE + 5: 972CB887CDE920F8 + 6: 49BEC1E7913F3CAE + 7: 96A81B37FEF63CA5 + 8: 408DD23A6DA940FC + 9: DA86E92BB735755F +10: 2032F2D972F228BD +11: 8F9EF7DEEF74EFEA +12: 547C92025DCAF9F4 +13: 80CD440DFF2EA62A +14: 7D6141D102E1B941 +15: 307596ABF5C9A6B2 +16: 82E3F1B17EBD52FE +17: 5917DDD11EDB55A3 +18: 2909F77166F24F9F +19: 88BDE9D686328942 +20: 8F987B737F6A011A +21: A74B3D1D6433B9F4 +22: DA8F95DE949482EC +23: 953BA9B26B9AC476 +24: 76A52FE193CBFAF9 +25: 4BB7D2597A78F2D8 +26: 5C8BE951251F4B1D +27: 6E8AB32A4A279D84 +28: BB94BC9937B42848 +29: FF0EE686F97BF8DB +30: 4146656AB1477E13 +31: 1BFCA7053E6DB8AC +32: 4B9A6A349BFA926E +33: 3B5F6FDD127B0A87 +34: 53C996E956598599 +35: 62C142E63C28B5EE +36: BBB71D6548F32693 +37: 107576AA26352455 +38: DE32E31FFE02B6F9 +39: 4C5DB81D1715FF5C +40: 8E5C706206F493A6 +41: 4BBC51E184A67C92 +42: AAE216B413DE2A06 +43: 77AE26F467233B06 +44: E8680D0E71F6AAD6 +45: 7061DCED4BC94F78 +46: 06772D63818C7E86 +47: EE5B9CFC06CBD639 +48: 5784B3EFCDC28DD4 +49: 4F962107A2EF843C + + +Cipher: noekeon +Key Size: 16 bytes + 0: 18A6ECE528AA797328B2C091A02F54C5 + 1: 2A570E89CD8B7EEEE2C0249C8B68682E + 2: 828F4F6E3F3CB82EEEF26F37B26AEA78 + 3: A3CA71833499F244BF26F487620266A4 + 4: 333ACCE84B0A9DE91A22D1407F9DA83C + 5: 224285F3DB3D0D184D53F8FFDC8008D0 + 6: DE39E2973025FE9EC1ACDE8F06985F91 + 7: 2F00F45A01B1B0AA979E164DC5CCFE10 + 8: 43775F3CBEE629EF6A9BA77CA36171D9 + 9: 1E6A67ABF1B6ACF59FB484866AC15A86 +10: 70490989E2CD2145730921CCC37F0A17 +11: 67B0DD0EA903486B1CB56591FCF42678 +12: 774AAB71FF28E49A30E1E718D98114E8 +13: DF4797990E1C65C9F6735BD967164D45 +14: DE2779DF26FC1B99F576ED4CFBAE76CB +15: A13AD17440641B3460A01175E3274AB9 +16: 1166499165F2A1196CA2DB831F264E77 +17: 35D24A385416CF2A44AB97A4AEC45E14 +18: D3D0E0DC962B1AD1AED92F57129088B2 +19: 00EF3E246B32634ABAF8BEE31D5C592A +20: 79BBF3F807675B9F264BABC67DF4C2AB +21: F391F2D58F0998F24BC9E5FA75DB9E99 +22: 066EF13C2617E97E6015B86BA1E059B2 +23: 5B0E2D7AE1E2734B9D5734C87F7BE272 +24: CDF7020212B7CF21F4817829386A6F8E +25: 24873E1A0EF4908DF85114ED9BDB0168 +26: 99904360C843472F71AB86B26DC78A00 +27: BEE70B3735A67268578FF107C328940B +28: 97DBB283536BC8AE8DBF56F3474C7740 +29: 2F4C903975EF709E004D24DC132A8A51 +30: 3EF0859A281782F905198C607FBE5C43 +31: 2D9CD48BC6A99E86468CBDD2A55C7D5F +32: 5518D3ED18D5E5A62752CDF0846D0C77 +33: F751E9CAF107BAD8A1F1F9C374277A6A +34: C5BA4DE907C41221FBABC5EC43710D0C +35: 5CA48836330870365A10E7B676695C9D +36: 937A964E0EA4D246E97293375B167EFD +37: C0A876CB6957717541A90CCCB034BFB8 +38: A57C93A09F9160A28D3D4DEDC987746C +39: 1FFA1E0B5EE0F0A18425F62717254419 +40: 8411C87262AE482CFC43C3092BEAFD90 +41: 0B9BB379FB3587A9ACEEED4771D8DC20 +42: 3B32EDBF9557E1DFBCEEC269B51FA494 +43: D1104E2888679A9EF6A13AE00ED7E1FB +44: 0EC9849BAD58A279B42B5BA629B0045B +45: CF206E8D3399918E75DE4765DD743060 +46: 55CCEB28E27D4DC7CE2546454FFD2C33 +47: 6E2339281583420B76E1750D35296C12 +48: 7800EC3D8C344BE7F2D2812F5AFF3DA4 +49: B80F4B0BDAA54A04D5A26BCA185F4EA2 + + +Cipher: skipjack +Key Size: 10 bytes + 0: F62E83484FE30190 + 1: 03B4DFE5423A117B + 2: 8CE4DAA2307CF018 + 3: 77D8C958DAE4336D + 4: 00D367D5C1FC95D8 + 5: C1F1305A5B01A474 + 6: C3956225C846F695 + 7: 2A8977DC186749A3 + 8: 433AC6B56AE5C200 + 9: 10489A7E87F803CE +10: F176DF022D02D136 +11: 1395AE1C0C00AA1B +12: 0C1C3FF32E93F789 +13: 901EAAD562EE92DF +14: 59D55D9EE3EA0154 +15: D9135CE0BBF68AC7 +16: 90A8E4A8E76349A3 +17: C04ED52AA69D1ED0 +18: 19E842698B5008A4 +19: 26FCA0FA3AA7718D +20: 62635FD1A542C7C0 +21: 5A3695398C979E40 +22: 34998BB72108D89F +23: F889CF892998D689 +24: 2C6A4D61F468F19C +25: EC70D59FC906349B +26: B95F11FD098B34A6 +27: 32F86206BB4E525B +28: E6BE51063B60CB9A +29: 8964E47BAC22F995 +30: B1C297883819747B +31: F2AE1F39F55FB6C2 +32: E633EA2DE342767E +33: AF1F0ECBCA788A28 +34: 6A898F4407696B27 +35: CD9CB5374EA080BD +36: 15881B0200AE6A42 +37: 579D05E5F5DE7840 +38: 86F8C683D23EB976 +39: FDAC7DC6C8F7777D +40: 10D6F7641409F027 +41: FCDAA0872D1EC61A +42: 7A353991A81344DC +43: 43661187956D3F8D +44: 5190FDFB904A78F0 +45: EF651E67F65CCD57 +46: 5E539C61748BDE3D +47: E11E23BA8BEBA42E +48: BAEF0956173B32AD +49: 0AAB29DF65861F4C + + +Cipher: anubis +Key Size: 16 bytes + 0: 30FF064629BF7EF5B010830BF3D4E1E9 + 1: DD7A8E87CFD352AF9F63EA24ADA7E353 + 2: 0D0BE8F05510EBD6A3EC842E5BD9FC2A + 3: 330F09581FDC897B3FE6EC1A5056A410 + 4: 30349D965F43C295B9484C389C4D942C + 5: 9225343F0056BC355060C0282C638D02 + 6: E3A85D41B5337533C4D87730948A9D4E + 7: 09DA0DDB65FF431081CAB08A28010B76 + 8: 6C0D0BD6CEAFB9783B31023FD455DAC6 + 9: FBE6F26B7CA322A45312856D586DE2EE +10: 1F269EC072D0FBA72E87CA77F8B983FB +11: CFFAE9ADE3006BD511ED172D42F16D05 +12: 73F0E9DE89F4C7541506F052D181BAC2 +13: FCFA3E2E89FF769834295C77431EF7CE +14: 0452360383D56F827C81263F6B0855BC +15: 40744E07299D6A2A210BE5598835221B +16: 2F0FC61148C36F4C7B42DF274AD0DDE0 +17: 2EA0E9BE9E4E4DF85488FE6E7CFCD6E3 +18: 0AD1254FA64C3996BBD485D41A3687A0 +19: 5B55988652DF200348A114F802FD3C03 +20: C32906AF76934C1436CA60BAD58A0C66 +21: 59D87987DE9DD485C4537F3A95A164A0 +22: 0A706ADF488D84632C96F4BEC43D9FA8 +23: 0B74E0CDD14D984B37491E2D9FA63CAE +24: 47CB1827D151A60473E67BD5D233102F +25: F455B4B665D3D0AFB25FDE4A3312AFF6 +26: F9A0649421D45DF604206854F681DBDB +27: 21477F5546339E4B6D8215368EE9F884 +28: 577640F23CA73345701B0906DFABA4B7 +29: 89F8D08A6E173759020DD7301E0FE361 +30: 44EF7AF7043FD4B8112345CEE42BC969 +31: D7CF0CE04A57253F4C63CABC4A5CB034 +32: AF73D3F4CED32593B315E27079131D22 +33: F6E603E3455359FE43A3B83AAF3AF0C5 +34: DCC3FB557F2C301B631DEF499097E4FD +35: 8285A25CF6F7E701644708E12081C62C +36: EC702DD0293F4C646B1C9C2606762816 +37: 289491E5A65DCA605B78E88DA8A9F8AB +38: D82FBC14452BE34C5840DAD81FC2A65E +39: B88A340EB1BF8D5ADE6A4E6C16104FC8 +40: C9FC3D70D2BA26C4059BD3D34134264C +41: 18CE3D2920E3BDEFA91C369E9DE57BF4 +42: 50917AE58278E15A18A47B284D8027A3 +43: BDA6F9DE33704302CE056412143B4F82 +44: C287898C1451774675EB7A964C004E0D +45: 3BDE73E0D357319AB06D3675F1D3E28D +46: 30FF4326C89C0FFE4D31D2E92CC0BF9B +47: F69816F304ED892232F220F290320A8D +48: 1368153F1A54EFF8D61F93A2D6AF21E3 +49: 06DD274894B6EDF3159A1403F47F09C7 + +Key Size: 28 bytes + 0: 7828B1997D3D050201DC6EE45C8521B5 + 1: 0D77F896F9CEF16DAAFCF962C2257AAE + 2: 89C27B0623F5EECCA38BAE1AD86AE156 + 3: 44EC09834052009CC3CD66E1BA11AF01 + 4: F922BFDB03FB186A069C1E7B48222E3D + 5: 277F7971955D8984AAECF287C32B8211 + 6: E77ED0144A3ED827B71453B91562FE25 + 7: 1760EFD04477AE527BC37F72C8BBBCAE + 8: 26259425ACD58207AE328B3F1A217AC1 + 9: 0876C4DC51D22657C4121E9067C2C3BA +10: 0214981592C9CEDD4D654F84AF1793A5 +11: 3E11FA027BC4F15048D27B187062259A +12: 24E7D61BB21EA90B5282B43AAFB0DBDC +13: 688F56ECB45B7C242000653460F04A23 +14: DFA587501A875ACDE8687A04AE404861 +15: 4C21CC3FBB768CC9AF2242FA206FE406 +16: 5CA0B03FA7751DEBBE70CB21AA61765A +17: 4879B3AC26270C422645B9CA29CAD8BB +18: 24F941E1B9AF84C18D03885EAACE16E3 +19: 05E163A0150123C2664131A81B20AFC1 +20: D606CAA85362E23598E5B8BD60C60506 +21: 33BD0AE751019BB751C151AE47BD5811 +22: 75DA523F5F793F90034144A3599DC5E6 +23: CD4709B56521EA306F5AD95CCA878183 +24: 6A4EC2EDDEBBBFEB62C1F13F7A59BF20 +25: 2A36272DC4EFDFC03F4DCF049ED2ADFF +26: FD4F3904E8E37E7C31508E5829482965 +27: BA64BAE1C2ABB8599A31B245DBAD1153 +28: 757E0151783A50FC92AE55861DCD797D +29: 5E63BDA3217ECB544972CA14A9074DA5 +30: E52F1195921767FA2410BA095EA5C328 +31: 6D7E42D67E329D669299B5A590017E8D +32: 0516F6F7D99ADE5DC42E635BB5832E80 +33: 57FB4E6B82ED2A3091248DCEF9C27F14 +34: 25231D0E9B96534977D2F2AF93DD10AB +35: 847C4C524A586568D19EFA3ECA343F1C +36: 52448814064E0F33A4EA89368C2E1ACC +37: 461275466FAA7BC16ABAD9EC459BD67A +38: 16C8324A383A00DA06DBEC419B69C551 +39: 5F26F7CF715FF2649DCC3C71EB6B92DF +40: 575363411FB07C067CD4357A1CD1D695 +41: AB70F08BAB51C5F57139A107EE858A12 +42: 887F62AE3D700EC5323EDA231C6B4C48 +43: 7B9851B01DC9083293F3B226690A54F4 +44: 36E03DF51C574E35EF2077DB7A49548E +45: E238A564246B163F97EDD733A235EDEB +46: 30679CE080915DC3BFA91D0DAFF5E82E +47: 7C2E8145D803D4FE18EE32995AAC16B0 +48: 24D6F61ECC87206804885D33BFA7B2CA +49: 1F4F81751CB3FAFDC9F9C27E639F370B + +Key Size: 40 bytes + 0: 31C3221C218E4CA1762B0DE77B964528 + 1: 0B6E4BD937773597647FFE0A3859BB12 + 2: 67A116E5F762619DE72F99AD1562A943 + 3: B6A841663FB466ACAF89C8DA5BA080F0 + 4: 0442708BF804642B9B1C69F5D905817E + 5: BC77391EAB530B96CA35319E510DB306 + 6: AED37991A50AECB70C1B99137D5B38F2 + 7: 8735F7AF0BF6C5C7E3C98021E83A31EE + 8: A614243B1B871D80BDCE4A23AD00F9FA + 9: 16AC67B139A92AD777871C990D3DA571 +10: B1774A2A12A8CAB25D28A575B67CEF5D +11: 4C9B1A120BC6A33C62AF903FEEC3AF5F +12: 7B128F00480E497C5754EE333457EE5E +13: AB56D578229492B95ED309C0EC566658 +14: 42FAF577855FEDB3446D40B4B6677445 +15: 84E0C19B4A4512001F663E22D3184F0A +16: 8B01680D049F5A9421BA9BED100CC272 +17: 2B1D70B92A5DF12CE0FA6A7AA43E4CEE +18: C7F61340D1B2321A1884E54D74576657 +19: 153C07C56B32530866722C4DEAC86A50 +20: 2EACBEFC4A29D1250EEAFD12A1D4AE77 +21: FCCB40B0997E47512295066F1A0344DD +22: C149A543345E2A1B8249F71CB9F903A4 +23: 3FD0688A8D0BE5F06F157C234C29BF9A +24: 6A3F813F396D77C7F4641ECC3E0BF3AA +25: E2888B9D2A6D819367F61C5792866A8F +26: 1A8A000F91AF4E600DDD88E098BD938B +27: 2283E758C04548EF8C37FA9F5700A7AD +28: 4FD6D8E1678D2B85520B96C038C582BF +29: D13C0B228F792EF88F09ED192C571029 +30: 1A2A06B1987BE0DADA4B558AE5E6A128 +31: 097B0460C47F1801986F5706A69EB01C +32: DD17BAC0737515C6386ECA6A6D6C02B6 +33: 5989BD1D46FD6EC14D4C55D5D6D17F99 +34: 431002E0224BD34B0B93988356C19E7C +35: 37DB7570296DCCE45ABDDE36EBE4731D +36: 4731DE78EEBAA1D02568EEEA2E04A2F5 +37: 1F879753A7964AF44C84FD5765D8E080 +38: 54F120726F68EA4B0501365CD2A84759 +39: 366E43BB744C615999E896D01A0D1D0E +40: 18747BD79F1D0529D09CAC70F4D08948 +41: 4F9854BAE0834A0C5FD12381225958F2 +42: 7C14ADF94A0B61828996D902E4CCFF3E +43: 242F0E9CE96E4E208A9E0C5D76F8E698 +44: 27EE179E2A9301B521B2C94ED3D36A77 +45: 892C84A5E77E88A67F5F00F3597F4C04 +46: FC7880D7860E90DE17E935700FC8C030 +47: BC49373F775BF9CD6BDC22C87F71E192 +48: 365646D0DE092AF42EC8F12A19840342 +49: 62D0E9C210A20ECD2FF191AD3495DE6F + + +Cipher: khazad +Key Size: 16 bytes + 0: 9C4C292A989175FC + 1: F49E366AF89BD6B7 + 2: 9E859C8F323666F9 + 3: 349EC57A02451059 + 4: 59E34CF03134A662 + 5: 436C16BAB80E3E2D + 6: 81C35012B08A194C + 7: 056CCC9991C1F087 + 8: 0A59F24C4715B303 + 9: 3C2CFF98AE8500FD +10: 9136C3FCC332D974 +11: FA3FA726E6BEBA65 +12: DD84E4F9F39FB7EE +13: A3F397CC9FB771F5 +14: E2D6ECC1F40A51C7 +15: 6704A1A705163A02 +16: BD820F5AF7DEEB04 +17: E21E37CC122027FF +18: E319085D8E2C1F4F +19: 0DDFE55B199A49A9 +20: B70F39CCCB2BA9A6 +21: 3F2F25723AED2E29 +22: 751FACD5F517AB2F +23: D32CE55FBF217CE9 +24: 91393018EA847012 +25: D50F1C54BABE7081 +26: C73350FBC5B3A82B +27: E9A054F709FD5C57 +28: 94BD5121B25746D4 +29: EE19F88B28BEB4B7 +30: CE6845FD13A3B78A +31: 566729D0183496BC +32: DC0E1D38CB5E03A8 +33: 251AD2B2842C75E3 +34: D344AC41190F3594 +35: 579B956A36ADA3A8 +36: 5F83D3AFEE9A6F25 +37: 2D3FF8708A03C600 +38: 32A732C7BEEBB693 +39: F437276FAA05BB39 +40: 58DDD4CD0281C5FD +41: ECC2C84BD8C0A4DC +42: BAB24C2CEFE23531 +43: 5244BFA3E2821E7D +44: A4B273E960946B2C +45: 039376D02A8D6788 +46: D3EB7074E3B05206 +47: 89C18FFA26ED0836 +48: 1F05A2D2D78927D9 +49: 0133E1745856C44C + + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/notes/eax_tv.txt b/xmhf-64/xmhf/third-party/libtomcrypt/notes/eax_tv.txt new file mode 100644 index 0000000000..95cd7c1ab7 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/notes/eax_tv.txt @@ -0,0 +1,461 @@ +EAX Test Vectors. Uses the 00010203...NN-1 pattern for header/nonce/plaintext/key. The outputs +are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous +step repeated sufficiently. + +EAX-aes (16 byte key) + 0: , 9AD07E7DBFF301F505DE596B9615DFFF + 1: 47, 57C4AC75A42D05260AFA093ACD4499ED + 2: C4E2, 26C5AB00325306772E6F6E4C8093F3D2 + 3: 16177B, 852260F91F27898D4FC176E311F6E1D1 + 4: F09F68BE, 700766CA231643B5D60C3B91B1B700C1 + 5: 8472705EDF, AC4C3359326EEA4CF71FC03E0E0292F2 + 6: 14C25EB5FD0D, 8DBD749CA79CCF11C1B370F8C975858C + 7: F6A37F60670A85, AFBD1D5921557187504ADE61014C9622 + 8: 1AACFEAE8FBAD833, 82F477325D6F76BB81940AE25F9801C2 + 9: 069414324EC293697C, B980E21C09CA129B69E9032D980A9DC5 + 10: D8174DE9A2FC92B7DA9C, 1E42CC58BA2C8BFD83806444EA29DB61 + 11: 2C087DEA30F8B7EE510990, 83DB400A080C4D43CAA6EC3F1085A923 + 12: F36B93C272A703D3422C6A11, 1370C3AF2F3392916364BBBCC2C62EC1 + 13: A0F33477BAE2E28E6747AA3193, B626DC719528CAC65DB0EF94E35422CE + 14: FCF5193506052E8BFA095C1A5205, F5BD02E0B3C91CC7D6FAAA8A9A76CE6A + 15: 3797D7F8599B8EEAB39C56241880DC, 0B70003E77146B903F06EF294FECD517 + 16: C4BAD0E0356FFD369110C048D45D81BE, DE7C2B1D83BE2CC8EA402ABE1038BB79 + 17: AF5C358BD31CDCAC2F0EA5252F1C3BE1E4, 2D700986F93B22DFE6695C2A243B4E42 + 18: 7DEF9056FBDAF491D7206B26B19DEF617AA1, E71A7D00BE972D85C77931D7591B2151 + 19: 6E9B2C0A90BF9D38A6EA3B5D2B9B2D97F938EB, 5B483D7F15C39602C2918181E57DA341 + 20: 7C5F68DEE9BBA3B04F11D5FC7C9C7FE6E8B5025C, 0AE6A12D37A9C10BB1A494E16705DC05 + 21: AF0A886BF673BC72045FC074F06A0176C96105E2E6, 06B2DC9A2868C23F86D710E01E37E07B + 22: 5F228A986DFE4301EDBAF07A02E114F1B30932995CD1, 74EBF68627C78B1FD024A59B56B2A8FA + 23: 911322F60555118CBECD8DD82F186AC19514316E8D48BA, B6A8BAF2F175CD0C71B63B1EF37E185E + 24: E7F52730CFB808EFDB376A5D5DF31A7EF8292DC5FC37E9BC, BA2AD158A2D2E5CE01296402B592E1DB + 25: B3F8D7CA47D8D86E94D670AFBAFA3B8D9E186C97DC029D4705, 709D2D2B9975D4729C19D4EAC430E65E + 26: 7178FEC027AFADDC2C03518E75CF34D207CAC2EB1537A0DBA520, A315F034CE5E66601444402520F55DE2 + 27: FC230B2B8522F53459D0B968421469BBA7E683ACB0190393B2870F, 48679A78E470E175CF3D3E9B46CEDFCE + 28: 35A641127C78C721ECDC50866C21637FDC9515E41CE60F09015EA713, 0062987222F6412B7AAF8A9ABF6FBF98 + 29: 3D42D6C113421743C08A6F682CFA0E517D5531BB66241C02EC4DCC26F7, B1AAFE11FA2D6E0C870177DDD7F98FF0 + 30: DAD065B4669B7C59C8392D8E7BD7E64BC01CEFFF27E335B25A328D356F0E, 8973B9B9ECF26DAB58CCF0787EE928E5 + 31: EBE626F9E241FD233D9781C359430C982667AA26921B62E98FAEC502C01B0B, 2AC0D7052A2CDCCE8E26FEA7595198AA + 32: 64D842B66796A797C2B4C6905742FDF2148FFC445E192F9E03B53810C082F788, 9778B345EC12D222DCC6DBABD2651750 + +EAX-blowfish (8 byte key) + 0: , D8C4C23A6AC0B7B7 + 1: 2A, 5E0E4BDDB60772FB + 2: 7695, 7581B16CCC9C45F1 + 3: EB14C8, 6223A121CFA216C7 + 4: 5A5C809C, 4A47658796337D6A + 5: 8BC2041181, E1FBA8DBA00571FC + 6: 89C666F015FA, 2B4A76A0E699FCFE + 7: 86C1FA92484AF6, 31B3B738A261D6F5 + 8: D1F401C145C9328B, 4C4A045EB489F59C + 9: 70C9C7753698324A73, AB298B5B20567EB4 + 10: A50D9D88DC101B6DC8D2, 529DFCBFD13B8E6C + 11: 7CC2885C2BE79C44F28FF2, 566255022B40C81C + 12: 6902D58347C29250EE07981C, 34619AF18E14C690 + 13: AB6C3C4AD3EC45143392B642DA, E6D2DD323DA175BB + 14: 7065B28BA8AB67B2FB7B6D5E3FAF, AEDCAA54F4B0772F + 15: CBBA14A74AD4ADC0EF036EDAE42D51, F2BFFA4D81BAC034 + 16: 60A315193F58144F5701D547C79FEEED, 912FDBDB05467DF5 + +EAX-xtea (16 byte key) + 0: , 86881D824E3BC561 + 1: EE, 4C3505F04611D9C2 + 2: 80C8, 6A3428BEEAD60738 + 3: BF88E7, 04F1E99E9F5906C2 + 4: E06574B7, 33B0153AAEF9776F + 5: 42D950AF63, 4A0F415640322FDF + 6: C30F6AD46EC9, 9646FE909D2B95CB + 7: A0049FCA856A14, A0257289C6BBF278 + 8: 2814B0C1358440E0, C4B0A2354925E887 + 9: BF4F062B52C1E489CF, B56442A3CA57A041 + 10: 63DF433956831B8780FC, ADF9ED0B46DCA19E + 11: C317FD079817F50E0E8A16, 2EA0EC993FC603AE + 12: 2BD12FDDD81EB11660346D2A, FBC6F69125BBA88D + 13: 85D356536FE2843C6BBE60EDBC, BB2FEFD04F230E79 + 14: 22493009DB01B4746F4927A8C4FB, 64CC08471D93C9AC + 15: C0F3C0DB08DC93FBA725D1E02DE084, 77B762213DDCCFFE + 16: 568B66D3112556BD98FF9339E9C002E5, C8355F508219FE0C + +EAX-rc5 (8 byte key) + 0: , 169C7954341EF44D + 1: 22, DABFDA9A0B0BA067 + 2: 2E54, 6A3D6D9AA5877C5A + 3: 2A6ECF, 2A34A3AF5DE8919E + 4: 9CC5F84F, D3F673EDAF75E3B5 + 5: FF5611756C, CC647FAAC8D49BF1 + 6: 74C939BEB31C, C335999CCFE8F5FA + 7: 7976B6F7709B5F, 2A7969C5FD063A88 + 8: 421EEC5022276174, 2C9BFB1EAC3C54A2 + 9: 6A4761CD266B1C0ECB, 3EA3CCEBC85FAC4E + 10: 7C09201098E764239A2E, 8043ABA9BF4D5AEE + 11: 8CE26277562F646DE33C88, D72AED48895E3B40 + 12: 52150F44D37D121560DA87F6, 58E865E22B485906 + 13: BA0A73B45F93ECFBFC3AB3D8D0, 683D52FA47FB1A52 + 14: 96546CBE01054AD24CC95DB54724, D80D0D530E5D1DDE + 15: 61E654BB18CD26FC36C09F874DC2C7, C65884CB9D9FEC1E + 16: 1D77B8BF02CDEAB4A707C07628826D5B, F18D1730C3D64701 + +EAX-rc6 (16 byte key) + 0: , 1DF8B0B92A3F0C951C425AF4830E63FD + 1: 1A, 8A2959EBBE90180999994DEB7036DB85 + 2: 435D, 7EF00CB57DB7B4155DB530D75CE6B025 + 3: 08A6CF, 2ED6AF0F2D5BAB05F623D389480A01F2 + 4: A86E54D3, FC69547C8BD922A5BF2F7B26C4D20F98 + 5: ED0822E439, 0007A3C6DEFC6C912C0E5B853B520368 + 6: 7BEFC7FD4054, D32C43A4D1086D57C5BCFAEE04EBC600 + 7: 5235E58E79287C, A27E9C781327C0FC7C55410EB0C828A9 + 8: CEB5EE99BE521F4D, 547F46383987F2A3582A81A3BCF9B280 + 9: 0358B063D5F99C3770, C0A73730512CDA6AD49599775D59EDA1 + 10: 434B9AEE07DFADD0A332, 499BD88881E558E09A8E822BE27D2496 + 11: D47849E650F350BB622D74, 638E37A84E7FAAF8F5D77F1B061773DC + 12: 814592F568284085E79A024B, 9EB1405E8422FE50BC0D88D837A2C650 + 13: 6F2B55EC91B591082053AF692E, C48F91EF01AA43A1EE3B36D233DDD48B + 14: 506CBDD2901838EE2F178B6953DA, 03778957F536509BFCA577B23A18F726 + 15: 446EE435D3D1848B51BB8C5F7BE4A1, 1129EAEAADE534940546D43242A4C839 + 16: FB9D2B150C42465B1685D8F069CC06DB, 41E2940F5DC63CB4E2FBEC25ED8A31E6 + 17: 9684F683260107BE8FEBBEE1D3EEDAA7BD, BAE7C116F7FF96631F4ACEE95C65CEF3 + 18: 5082B1FE48CD3AB58F63C2DCFDD4069AC736, 19AC7B8EE315CBB7131A283851B32266 + 19: 8C72AE495B6F003A3C784D144E84E88885F78E, FA4CEC023740A8D670E351FBCF62C1CB + 20: 815D6361C7AE34C9D796ADF9C71ABC46AEF88BC9, 9A1F7288C61A6623B9A82748137ED7CC + 21: 904A853E2E96BD2B85AAB3F5DFB900E9B3642EE667, 9AA90DBDD461CAD20495DCFBCB513DD2 + 22: 79D738A462F727B3D3C529ED999B6FDCCD991D1C5A4D, BF0987BEDDE650D73CAE7D380FED3431 + 23: B2DEFDB7D503A84E83155A04B8DE8C8DBB68C2FC475007, B7CE900CF43CD518024123C76F6DA328 + 24: 9E723E15439E12F6C46DF8A309AE1E97B6FD18436259CFB0, DF8B6E1E23512CC4CF5FF531A1908F69 + 25: A7F0AD03CEBCC9202718AA164886E1026975306A664C5AC7A9, 4A771BF8B9A4325705C85E5499FD98E9 + 26: A53A92AD1C6835F28E04EF591E783D36F3D76E489B31B87BEB7A, AA263B52A6E6A043DE4D7029D4DC73F5 + 27: 79BE3C38291A7F77E932C8A9DEAC08DE6442EA9B3895B101A14E7B, 33B84DE06342E675E019CD0237292ED0 + 28: FA108123C5A69571CFDFE8C3D00535121FDE3096DDC0D700F8F26A5A, 764025D7CA1A3F2C54D28956423B0C77 + 29: 36EC2D67FD977BD2B73DB6D8EB756B3EADA13690E1B6DFC12A4781B34B, 4BC6B38DE3B02283D92F4DF19A5C48C5 + 30: 96D3243C945905C9732B5927E46F00886D511463B38C86002FC26B65AB8C, 5B5511CDEC35687AB8425AB22D58B4F1 + 31: 9CF83B87BEA3374AF7722E999863E3DABB858B0383383EAC7757F5B80FD44B, 1E0CBC961940FDA93B73A92DACFD67F3 + 32: CE3BC3C9FA5EF4AFE5272B3EDD24B1B003FED2C2E501528CFF44D3FABFF52CB4, DC94FDDC78AAB2B7CAA1E1EF149AC355 + +EAX-safer+ (16 byte key) + 0: , B120C7B37450C46189712E4DFD1F0C44 + 1: CA, 82BA1869C5FF1EF2A4F6ADC1E7DC1F1D + 2: DD20, 6BD5601B16C9943A84AC1F99A176E6D1 + 3: C1C09F, 0911DC63AA414C004E2BD825BECDC93B + 4: 27E43F59, BD858F084B082F76814DC385E1FB20D1 + 5: 2A9A92F246, 5ADC4A32491934AC0BD00FCE686B26F1 + 6: 52C78C0CD6F4, F35886F46C03EDCA10B3D01CF07B1E0A + 7: 23E0D3CED3795F, FE33D96FC98B78A30C0A412C60E93992 + 8: CD3FC9961559F239, 9982364A61609FC41068260267231EE9 + 9: 6EA46CB7AD7505C1BC, BB15053EF0F78B9091B3064118F3E9BF + 10: 05D9BA230A56CCA0703A, 1338E68E3DC992B6EB2685C668E75869 + 11: 7AAD6049DFDCA6771AE42B, 35267E431051E1812495615324C4CBE6 + 12: 8695091532B83B23C296F620, 7B2EEA861E9A91E6B6A911E10FC3FDD1 + 13: D909DA4BC7372ACAEA78E6A0EE, EA6C1CD16180DF0B07F4E204A4B4FACB + 14: 7DEC8443600D0563AEFE87A2064F, DA454728069B3B409889664783588189 + 15: C042FE656742CD2FE5D9C212D18C6C, 5929E4AECC2CA047BAE948E7023FE4D0 + 16: 0B84D3CF59EEF7319633F4A397D47CF8, 31F892FFDB7535DF5D9143456E404163 + 17: 8C9E57AAFA7969B142742B63AB73286600, C418231C44F96660DDBA8C26B3BB3681 + 18: E9EED66D370A3A6A39C7E0E570D96F807EAC, A4AFE8D1D3C31B956A3BDBD043E7A665 + 19: 1A5D47992DA5597D1449B4C8DD47B7404C7657, F3ECEE5182014FC3365FDBC4C33CC06A + 20: E7C7945FD1AFD3F5DCE666D8A5A2E8A3C11A7A5F, 86D78B2FBA7597B8806BED505B52BDF6 + 21: 9E2165B47B29CBC4ACD50660E011D691F061209969, E9B1E860BD02085177E1A94E1EE6F3F0 + 22: 48EA2945C8DD3FE09407BAC8973A861DB15B788C8FFD, 502926712EDB1B3DD13806052C6C75D7 + 23: F37D46B35B60819EA52B00457D79155C04B55972D0DFA9, BB2B7D210BF0570F422640BF81F39B9E + 24: 12E85C0C78227205CC682360C79E35BF58EC6551CF8FE2D0, 042990D7A58D458C570A15DD375DB4E7 + 25: 4F6C15109DE980DD14A7F4C27F48671E4787C53A564232F427, B097A5990D8067DD89C21473150C070F + 26: AAC472E49DB101B564A8A01E2C80C0C6AE9065D332C2DE79FAB6, ACDD587A7DB86542E195DF73AF1C1CBC + 27: B9912CE18019C31692A1F7E11D9CCB20297ACCB9DC62C47C01D2C2, B0ACBF028CA5B15E0035D2EB8CA916BE + 28: B4F2B1FE14A1ECDC9C8EA1A0120395E6ED1E69D3FC85DD0F3F90F350, 9A561EBC769369B95B9CB74FC6AC27D3 + 29: 3FE397C8AD02689B7437A37861F0907AF1F6014A293B46419348771C5A, 6B7BEB9BD5018FECD71BE5081C7C2544 + 30: 5019089142199F7207E1B7731B8B247A18A685B231499DF12A73F5D67D37, 307E93446777005BA1B088F178A0DB6E + 31: EAE8F9F02F8DB3D70B78B08CFB0949D99F1A86C958A8E3823736BCEAB86BE1, 6C94F48591C18BF9C450515B73379973 + 32: B9C795F7A87305B4AD36DBA10B3B1C70B329D29E49C8C6A932D96A74334AEE4A, D18E6E233FEFD6E5C7148BDC1504299C + +EAX-twofish (16 byte key) + 0: , DB0C02CB069E3773296D3BD4A87A381B + 1: 99, 7D21D19E9C440F68E99F1F2EA2668694 + 2: 0696, EA590EC417C88E23FD23917F9ECFB0C6 + 3: B9B082, 82D4C9B68DDB02C906496413E13A2D68 + 4: D6B29D74, 5BCE5CA4F662E883BF7FCAAE5FB2CE01 + 5: A59C9CB009, CBFB04226D1029A7EC9D64A48A6729BE + 6: F4924FE3E355, 3D85B3900DECA0528C815F1447A1F209 + 7: 679C88D52FB519, 931C7A863C3701D8015FDBD8696C6C30 + 8: 26DA41C0D115375E, 7627E23E791A4DCB0FA5ED71B1ED2288 + 9: 8FEC6EB7016AD2B178, F65ED0286A724F0CB2EA317D5022B0D8 + 10: B5F22415B1334133C531, 87C4F3A8991BBB85984BC4D3305A5CF1 + 11: 23E1D0ED2E820AFE7DA2FE, 100499F1093FAB2ECF73B643594E98E3 + 12: 79519ABA91F46B8DAD6D5335, FBDCD1FCDB20AB99135F28A714C6992F + 13: 5968D0B4198A0AAD3D0395018F, 781F22E2DA98F83398FCF911B2010057 + 14: 4E55B14432B601E3EF2EF567CB15, 8BF6E53D7657E56EA3DA1BFD9C9EC06E + 15: 6ED89651CE19B3DD1EE5C8780B5015, 131CFD657D32D4E1B35140ADDCA0E13A + 16: 2295A968B4D072D12757756247554850, F35FAC95C2AA4155450EAAA6E2E789B5 + 17: F9B2AA2AA502EA79BBA0C5EAD932B8E1EE, 0ED81AA40B9BF39A9AAEDDDB7A04BEA6 + 18: 385055F1C1C26C0472A504B4CD225DCA55FE, 24831680B56368231AC54227D737F582 + 19: 771529585C741A3F8B1C973709892F255A99EE, 2A132B4BF96FD5109DB04459103F5E84 + 20: E7A2197D9FAA8AB8B303B5EC71AE34AD5EC5DD66, CCAB6518371EC8E0A9E9EE4F7CA5878B + 21: 279E54F755EAC6B57375B9EC4406E43DB3139D740C, 7B6F26F2C0ECC9F2DF4EDD7513E6E0B7 + 22: 27816AA94CBA2BF98E49E595AF5B3FAD12BF1D6F1AC6, D04876C5492D275F15C834E3CF794F0E + 23: B5658DC148855F68B282211D879F688F3C142FE555CF81, 4539CDA8A65DB9047AAD76B421B81120 + 24: 72F0BD4F939C2C9B4FA734DCB0AE4FB9BD342BC8459ED2FE, CEA8469BC0457EBF3418C1114288C904 + 25: 70568245E6E6BD5D11AD0C74030D7AE08BA05057DEA0FBF4AD, 71554FDE6B87477A51EE4499D78783D2 + 26: 8702D35BE07D7ADF70684046CC6C72FBBBF821E0BBCCBC973601, 33CC6FBFDA15E306919E0C3BB2E22BB6 + 27: 0BA23F4A6174165D4A8BA80B7C875340B0F8B2A6967D34E106BC22, 00E6679496714236EECEC84B9AF3072E + 28: B9E25ABA84C6BD95B5149E7616FE2E1D6FAACEAAD77A636C60279176, 8D8AD0B9D4C709E1DA370EE01611482A + 29: 74759711F6D542581F9F83498FB616638D092732BA07109BF4B5BE045C, 71A40DC777BD09F75362F7B20E0B7576 + 30: ADBF7E98926484BA2C7F6CD7CD9734FC19265F68AF3BFCAEB025F6296E37, 8DF15B5F69B67F7DABE44E3666B55047 + 31: 2DC26D449379997D110309B2A0DC2760FCE8CADB4B14ED580F86C70F69C9BA, EFCB60EB2B25737E256BC76700B198EF + 32: 2B1890EB9FC0B8293E45D42D2126F4072754AA54E220C853C5F20FBA86BE0795, 1A1B15BBC287372FB9AF035FB124B6A1 + +EAX-safer-k64 (8 byte key) + 0: , 9065118C8F6F7842 + 1: A1, 1926B3F5112C33BA + 2: 2E9A, 5FA6078A0AA7B7C8 + 3: 56FCE2, 984E385F9441FEC8 + 4: C33ACE8A, 24AC1CBBCCD0D00A + 5: 24307E196B, DD2D52EFCA571B68 + 6: 31471EAA5155, EB41C2B36FAAA774 + 7: 03D397F6CFFF62, 7DFBC8485C8B169B + 8: 8FA39E282C21B5B2, 2C7EC769966B36D7 + 9: FEA5402D9A8BE34946, A058E165B5FFB556 + 10: 6CDEF76554CA845193F0, FED516001FFE039A + 11: DC50D19E98463543D94820, 8F9CCF32394498A1 + 12: 42D8DC34F1974FB4EB2535D7, 77F648526BCBB5AF + 13: B75F1299EF6211A6318F6A8EAA, C5086AEA1BE7640B + 14: 1E28D68373330829DD1FFC5D083E, 33EDA06A7B5929A2 + 15: 85529CF87C4706751B0D47CC89CEA6, D031905D6141CBED + 16: FE5CB61BAF93B30ED3C296EE85F51864, CC484888F0ABD922 + +EAX-safer-sk64 (8 byte key) + 0: , 5254AB3079CDCB78 + 1: 75, 798DCF14FEF8F4D1 + 2: 0300, D5FCA75DAC97849C + 3: 520F98, 10E357957CE20898 + 4: 80E2764D, 5C7F46656C6A46EA + 5: C48960CDAA, 3CCF44BD41F01CA8 + 6: E0E60BD9AA2C, EBB493983FCEE79D + 7: D13D8804906A1B, 6EDDCA919978F0B6 + 8: B7AE14C37A343BFB, 2369E38A9B686747 + 9: 5DE326BBCC7D0D35E9, 041E5EE8568E941C + 10: 13494F5B0635BA3D6E53, EAEEA8AFA55141DD + 11: A9BB35B14C831FDA0D83F7, 4002A696F1363987 + 12: E242043A1C355409819FABFC, 63A085B8886C5FDC + 13: 204598B889272C6FE694BDBB4D, 194A1530138EFECE + 14: EE3F39E0823A82615679C664DEBF, 1EFF8134C8BEFB3A + 15: 8579D87FD3B5E2780BC229665F1D1B, A832CD3E1C1C2289 + 16: 74D7290D72DA67C4A9EAD434AE3A0A85, 96BAA615A5253CB5 + +EAX-safer-k128 (16 byte key) + 0: , 7E32E3F943777EE7 + 1: D1, BA00336F561731A7 + 2: F6D7, 8E3862846CD1F482 + 3: 5323B5, BD1B8C27B061969B + 4: A3EC3416, 170BBB9CE17D1D62 + 5: 0C74D66716, 7BD024B890C5CE01 + 6: 6158A630EB37, B5C5BD0652ACB712 + 7: 17F2D0E019947D, F9FF81E2638EC21C + 8: 68E135CC154509C8, AA9EAEF8426886AA + 9: EDB1ABE0B486749C21, 355C99E4651C0400 + 10: DB0C30E9367A72E8F5B2, 631B5671B8A1DB9A + 11: D4E5453D9A4C9DB5170FCE, 75A2DF0042E14D82 + 12: 3F429CC9A550CBDA44107AA7, 2C2977EA13FEBD45 + 13: A7CA22A97C2361171B415E7083, BFE81185F31727A8 + 14: 170F79D8B0E3F77299C44208C5B1, D5ED9F9459DF9C22 + 15: 2E24312D2AE5D5F09D5410900A4BBA, 2FC865CA96EA5A7E + 16: 8F3C49A316BA27067FF2C6D99EC8C846, 9D840F40CDB62E4B + +EAX-safer-sk128 (16 byte key) + 0: , 22D90A75BBA5F298 + 1: 3F, 98C31AB2DE61DE82 + 2: 584D, F4701D4A1A09928C + 3: B9DEAD, 6E221A98505153DA + 4: 06D4A6EB, 0E57C51B96BA13B6 + 5: 7B58B441CA, E28CCF271F5D0A29 + 6: 7950E0D1EC24, 2ACDDE6E38180C07 + 7: 65A4F4E098D7C6, 7DC1C9E9602BACF2 + 8: FEBE4E72BAA0848F, C4607EA3F138BAD9 + 9: 9B7BD6D6D655985AA3, 8B2C58A9530EA6AC + 10: 60C92F925D1478470203, 51E6F5F6DC996F84 + 11: 7B40769370E651F64AA654, 74F1F8A8D3F4B9AF + 12: 7215832C2FB9C54DF7A9C686, 9BF9AEF14F9151D1 + 13: AD0F9C79008572AB8AE2466EFF, F375D0583D921B69 + 14: C05076E2C330A0D25D7CEC80597F, 843C12F84B00A8E0 + 15: D18F0563AB0278140B0CD9A9B07B34, 262B1688E16A171E + 16: 650747091F5C532EE37D2D78EE1EC605, 1BAC36144F9A0E8D + +EAX-rc2 (8 byte key) + 0: , D6CC8632EEE0F46B + 1: 4C, EA19572CB8970CB4 + 2: 5537, 3EDD3253F6D0C1A8 + 3: 206FA6, 20FA88F03F240D31 + 4: 17EE8B40, 702E8194F1FCBFDE + 5: 2A89287136, 31C5534786E15FB3 + 6: 3A6AEDC7066B, 3C663A4081E1D243 + 7: 8BC5203947A644, 6AAC806C92BFBD6E + 8: 2E0274BBE14D21A3, CEB0E0CB73C3664C + 9: 9C4B292B0CF17E3A29, F23CD535559023EC + 10: 8E322734308F85662877, 46363D7EFC322821 + 11: C413C405767FF5F98E3667, E7BA35D8F3678E7E + 12: D77806B7A218098B1569EADC, BA67C306E5C0181B + 13: 4BE5EF74F9E9799A4D636FEA9F, 4C511C44ADBA4030 + 14: 7E19969170C2C8D8AEBA8C7FBC2C, 54CC6D466A2DF6DA + 15: 2EF1CEDC1DD3403CF440FC5561BE33, 61C6FB277E93701F + 16: DE052719153EBACE9D7B19F52AC4282F, 4AC2A96F2FA8634C + +EAX-des (8 byte key) + 0: , 44048B7F240B6F5F + 1: 0A, 37009B7D4E09953A + 2: 03BA, BFD2FD7758961728 + 3: 37EE10, 16A6AF96DE888A19 + 4: 07F44290, 100CA84AA0EDAA1D + 5: 389EF0023B, 9614FB800A533268 + 6: 3F4DBA8AA01C, EFA6B55B7ED5E40F + 7: 8C7B837896EAE7, C113CE8F664CE3D4 + 8: 7011D993D8EDB0C7, B4C370A919F60497 + 9: 0DEB30A31351B13D7B, 00ABC82DC5F3A1AF + 10: 8D3897B2CBE323D6EE1C, 7A2D15627CA1441B + 11: DBC002C817DEBFB419F94B, D8EB87F86D6ACDEF + 12: 17048E2976FA85AA849E9A80, 229FCD1C9D1E3B9C + 13: 30B989EF646544885A478AC198, C1B7EB4F799105C8 + 14: 5C2E12A7F118A08D6FD585F9C839, C358679FEE6FE7D7 + 15: 8D1A1E888BBB8648E638C4E74E11B8, 685E006C441448B8 + 16: 93AE906B8BE4EAC8ED6D8F48F04A7AFF, 71DD7AF752FE28FB + +EAX-3des (24 byte key) + 0: , 8914311BB990B725 + 1: D8, 2094EDC5D03E54B1 + 2: FEE5, 781CFB0EBE3895CA + 3: DECF5E, 59918E8A5C4B459B + 4: BD583AAD, 2013BEEBEEA795A1 + 5: 2BC01C6C78, 0B1134DBBEAB5D3F + 6: 4D5EAF01A895, AB4D17516ECBA50A + 7: AF229F90614480, D3113C0A9D133CD4 + 8: BCA6F375DF4568E0, 8E9EAEC8E77786BC + 9: 575F34219E6DD8DB4C, B40C75139E5D1860 + 10: A199B8AC433B615EC96F, 774AF803698ADE3D + 11: 718A2975DD9A872A68AE10, 3B9460F849CBA7FB + 12: AB38E148180F6E2FFBB96F91, E3EE3B8FC50DADBC + 13: EB10E0233507459D4A6C29EE80, 8D90B46BB1EAB27E + 14: EB48559C320DFB056C37458E19B5, 9315F0C4AF8500EB + 15: 9E8C73EADA105749B5D8D97392EDC3, 2E749EE66C1E6A16 + 16: 600FA4149AF252C87B828C780AEFF8BC, 33D7D11DCDC19936 + +EAX-cast5 (8 byte key) + 0: , 382FB8F7E9F69FDC + 1: 99, 20DA959849B3F7AB + 2: C54B, D05547C6AFA3484A + 3: 579836, AAA92B2321FC50C5 + 4: FEB7AE55, 639EDF01C4FB965D + 5: EA8A6023FA, 01274B3ED5CE102C + 6: B7C4E995121F, 712BFE27CAFF6DDE + 7: F44236660B0004, FAC51D1DF8EC7093 + 8: 01CD7E3D0BF29E8A, 049C47A45D868D0B + 9: DAB170493DFD6E0365, 6F3AEDD9A3ECF4FD + 10: 82C9EEC4803D9CD11FA8, 32683C0A9128C6EA + 11: 324AC59E87B244ECE0F32F, F6B095AAB49353CF + 12: DBDDAB11D02C9CA5843C406E, EA728FC46DDD3B04 + 13: D67376C2A4AD92E7DD80E39303, CAF72B7E7C237EB3 + 14: F2B9BBEF08036C2982C6DDD06918, 70A29D780C22752C + 15: 96E3D9141F8EBF520540C2BC9A9C23, CEFC86A1CD48203D + 16: 70CABBA983179106AE7FCD5F1F31D5C3, BF7F9168F4F82F56 + +EAX-noekeon (16 byte key) + 0: , 556805EEA595CFB9A30FAD196103D7FD + 1: F5, 0A7DAEDFB656526CEF4DDBA8087A227A + 2: 7B8C, 249895D79962D5B4D18FE07366281B72 + 3: ACFF15, DCC489D24832EB106F576AE6B6EB957A + 4: 08ADE7DB, 0D3215999E9960EDAB29B78744C7F139 + 5: 66139213F6, 505E1E7141D043E903C26EE0959EEECD + 6: 078B79F880A8, 35B7EB326A55E50332866EEDB682EC20 + 7: 2809E34D9667D4, FFDEC555F68524A09A6ABACA372077D9 + 8: 93D267DE1EC635D3, 4FF3561990A56E4B374618722EF850FF + 9: F377A4D93FF32F4A51, 91D4070423A90FC54D305169C03F49ED + 10: 6244B717E082993EB7A1, 2E3A8A354AFA9473667ED7FDD46BE9FC + 11: E917559625D25E6E5F2EDA, 19295C37A70314CC9A1D11FDE8D23C92 + 12: 1E6DF2EE112A893AB14DFA92, 12C4A89D4CD65F8116A03A135AFD3701 + 13: 47B18CD762E011770E203CF605, 434909A97E118B20D3AEDC79AFE33A9E + 14: 72D9A1A7DA6F33D5E0B927F9F32C, 779C23714FCAA2B2321EC7FB5B03E222 + 15: DA8B830FFCB3DB274807F780D33240, EDC2F1C8A401F328A53392597730B007 + 16: B53DD2BB840AD933D36A7B5FFDCCFBBB, 4EC0E6D1F916BF633869239B672B37A1 + 17: 42936BB9A936C30408660855F4F47F3314, F0DAA6DDA15585E1697ABBB4790B15B5 + 18: 00372E47F5BA016F1B2A1E680B76AB02052A, CDBF3D241BF7FF96D3DFBEDDB872E901 + 19: 8AA236B0C8BEF6F67A97C2DF90628F6E5838FF, 731DCD61F7F26004C03519F9500EA824 + 20: 55338647812FC9D86CBDDCED7120268A4D43F8BA, 0E61B3C835CAD95FD49FEF002C014E72 + 21: 435820B28E52154B47A04D5E635D8FE37FA47FC985, F6A96DCE4917E8D7C610923627E80970 + 22: 0D30C15B6FEB4A48B14DD15D41A4B25D442AA677B25C, 28E15CCB74AE992C68BDDC8D87802050 + 23: D9D701F9AD6B0E13D2CDDA15A5194E7CE8BD2C02137391, 2DB9A15884E9C996C3D6B5BDA44B9598 + 24: E2390AC5CE10CCFBC72106A52C7F180CB477E3C193CBACA8, 22D3F7DCD6947EA4E78DF57A8E1A9A59 + 25: ADEFB7D9500658D34996AF6BE6336CD78891064EA1DB8E9785, F239D67D039A15C620A7CD4BE4796B3F + 26: 89964C90ABF54A6DF9F13C3681E70C702D80A17BE79F8160F30E, 6336F729ECE1ED7368669D75B7E2DCBA + 27: 576B2813CECDA4F905BD5D58349EF070FF41B7EB6BB2B01B061B0B, 125324CBF2ACF1011A44A99A11EC8AFC + 28: 430B957481748519A60494F0B5F698F34B1A8235B00AC0D1F0A4442E, 1E80A7FCEBBB8E1E12D6831906154485 + 29: E781BFE5FCDE0BFC056CC86C4A0B9DD3B815BE8CA678204CF47289B5B5, 190D5AAA9EC1CB4CC86FACE53BF1201B + 30: 78BFAC07A9B7B2AE9329BF9F9BF18A1A49DD9587001EFCA00E9AD9752764, 4FB5ECBEEB0995C150EBC66508FA19C1 + 31: 7D6C20694109DE21F7955855A8FF832347518DD496C2A114DF142C68ACDEAA, B25D4BB34056DC091A7A3950D46C32EC + 32: 3E1E4395DEC1AFEA9212B95F37E679B6E2D14DF23C5DE49018C2C8038CC4AD45, 9A6DE7BD41A21918AD504490EF4E581D + +EAX-skipjack (10 byte key) + 0: , 85F74B6AFFB10ACD + 1: 3F, 604DF8BDD98A0B3F + 2: EA87, 792374FE07588BF9 + 3: 0169CA, 489AB8AF69DA3306 + 4: A7AC3EB1, 428DAF508E24B583 + 5: AA9028D5B3, C0A44EDA71FB2C86 + 6: DA97BA88A061, DA2EC34077F42585 + 7: 7E25FAA41CEBC8, 36D4987551E06D5B + 8: F662DA6C9001CBFE, B7DEF76680C316A9 + 9: 6D3F73EC716E1DA897, 5F0F83BAE4D3513B + 10: 2A300F585BEE9C889743, F4756C24DEB72A9C + 11: 80518B010DD77C82D19106, 50FF5CAA365F4A70 + 12: 6E579A2173C861B6F37B4CD3, 81E3E5ABBA8F0292 + 13: 5B04829880A72C38871C7021F3, 6B26F463708A3294 + 14: 934177878E9A9A9FB4DEB3895922, EBC1C32F0A2A3E96 + 15: 07AF486D1C458AAB2DBF13C3243FAD, 87288E41A9E64089 + 16: 84059283DF9A2A8563E7AF69235F26DF, 351652A0DBCE9D6E + +EAX-anubis (16 byte key) + 0: , 8E20F19D9BA22ABA09FB86FDE6B9EF38 + 1: 3B, F4201E546A9160F989191942EC8FD1D3 + 2: 9F38, 4E3CEAE3E1CB954E021A10E814B71732 + 3: 4F4769, 3E8F35A6A5B11200E9F1AA38590066CD + 4: AB41F5FC, EC4C97A8892AAF5433106D4AC8A49843 + 5: 414F95D61B, BF831E34D1E3FECB973A8C730ECA2E6D + 6: 4798322F06D1, 005BBC30BFEDBE6463536C4F80D1A071 + 7: F256B6CD1BF4F5, 468A28F0661884B846B191B530C8D064 + 8: 90906F27A633ADDE, 6D9200A37A7F6A456CB103673184C2E5 + 9: 16CD3C17C9B4EAB135, 6D716E23D7B35109F55B036EDFA7742E + 10: 7AD1C22F1F06298DFB25, B076990F8193543C8F3185D3792BCE56 + 11: 0476F2ABCD057FE6FEE39D, BB2876DB18C00038FADBBD9B264ACC3C + 12: B69EDE336407DBC2EE735857, AB63E5906116A8BE22C52B5DA31B1839 + 13: C3864C1354065A56470669E602, C72BFD3A0BC73BFF051C9AB2F0DFED93 + 14: 296D8F183A59020D33890420DD7B, C9D90B9EB42C32EDCF6223587D1598A6 + 15: 256ED8E9D982616680559979BDF2E9, 179FE4E7BA7E966050D35900317E9916 + 16: D4ED8F30FF9C0470D75B3B16750A3AE4, 5D50F05BB270A292DFF9F67A3BA84675 + 17: 40CDEB6388274143CA3C4F6020BD9A4875, B27C7DFB1BFBB3FCCEE0171852C7924E + 18: 54EF262EC1801D505C7629D038654EBA0594, 9D2060FCD0A2C577511C7752ADE60BBE + 19: F39EE54A37F16DD38B624D7AB8F0D9CBD4B981, BC056C7D2C09D813703CDD63C1C69F44 + 20: F4E7AD474FCA153ABD670E43081ED09EB2C4CC1A, F244BD4D630272F0D98FCA04226C04F1 + 21: 039ECC36A0A16273E7246CA1FF19D213AC87B53F29, 3056DB6916C925DF220B6C9980EE141A + 22: 7DE1DCDEF01447CA2FE83375A48DD84E4A7CB7C01992, 79AFEA4816EAF8DAC8A5E93960F1594F + 23: A886C4B914BF0983003272F226F9B2197EF2DC05ACDDE0, B59D85A0FDA5FA4422F7203C055B97A9 + 24: 00B3E1E91448E250AAFB695C0643A6577AB453EFECFABF53, 4A7EFF1CBC1AB535122A017203616D85 + 25: 85E972E774D66D0531E40B8FE9E264A77B50FA883AB0943080, B18E164BF89B7E7AB0DC256DFEC7C72F + 26: 004849E39334969B392CB0CF3FDEFB3D792DCBBC15F8328C7EDC, 3C51295711F5F878DE8F0B2B5A26A227 + 27: A0BAD6C2264AB1578993BA49E59D4598822FFED20A57D88F756FF1, 2EB9D525697A419A10DB2A84AEEA5FBC + 28: C34DD806EAB5AD823D78BCA78A7709A705FC94ECC521A367D76C9588, 3C57580C7903039D645C06DBAF07B477 + 29: C447EC77512938CF7862388C32AF22ACE6B5E4CBAA998BE4F5CBC4D215, 43425D09B7ACFD90371C08953946A955 + 30: 2C16993AAE624CBA4CDAF34FE3D368559E6BE548292B281439866375013B, 3B7360C3FA8FB1C15D19F567153CB46C + 31: 538E5DFAF14854A786851E4165F2E01CDDA963E318FCE4FB58E31A6B5CFC33, 2F8EA13B7A6873FE556CA535ABA0968B + 32: 5E29CDB7D9695A110043E9C260104BDF020A3A2A139D4112E918AB584BDD7EDA, 9133213AA7BCF062D2BD37F866683D3F + +EAX-khazad (16 byte key) + 0: , 75968E54452F6781 + 1: 95, ADAF5949F09B5A22 + 2: 6B8F, A06B201947424A11 + 3: 5BE668, 3251416625DF347A + 4: 5A92E82B, 33E25772427D9786 + 5: 62F9F2ABCC, DE714F5F5D17D6D0 + 6: 0E3CD825BD8D, A7991C8CB8975ED9 + 7: 4AD0D999503AAD, 53A827D7886F7227 + 8: BB08E6FAED1DAEE8, 91A118749B7AB9F3 + 9: 16E30CB12E20D18495, F8F8B8C1280158F9 + 10: 616DBCC6346959D89E4A, 506BF35A70297D53 + 11: F86B022D4B28FDB1F0B7D3, EA42220C805FD759 + 12: 9B8A3D9CDBADD9BBCCCD2B28, BB478D3CE9A229C9 + 13: CDC4AB4EF2D5B46E87827241F0, 658EDB9497A91823 + 14: 1A113D96B21B4AEBDB13E34C381A, 63AD0C4084AC84B0 + 15: 14DA751E5AF7E01F35B3CE74EE1ACF, 3C76AB64E1724DCE + 16: A13BBC7E408D2C550634CBC64690B8FE, 3D4BBC0C76536730 + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/notes/ecc_tv.txt b/xmhf-64/xmhf/third-party/libtomcrypt/notes/ecc_tv.txt new file mode 100644 index 0000000000..c61729ec25 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/notes/ecc_tv.txt @@ -0,0 +1,1261 @@ +ecc vectors. These are for kG for k=1,3,9,27,...,3**n until k > order of the curve outputs are triplets + +ECC-112 +1, 9487239995A5EE76B55F9C2F098, A89CE5AF8724C0A23E0E0FF77500 +3, CFC1E3447FC33E5C2A7D2BF71298, 5BD6AC32F0A9E7AAB6AF722C3CB7 +9, 3F37CF870B918CD41EE58F58DF14, CEC3FA5A53FF5A372B583CE40F20 +1B, D5E45D28A47A0819F3AA3018E58, B05DB66559FB78876CF830A6ADB4 +51, 869FEFA6DE5F619CA54CA719554B, BB93E27BBC3FAD016BC369766F4A +F3, BF1784B857F668E9459714D80D75, BEE55B564CB923C7018E855A2E05 +2D9, 27067CAB2BC8C9201B1E8F1D54FE, 4A9BCE40D87B0C82EA66D645C931 +88B, 4E9974D7B890442760FE4D05FB8E, 96BF4DDF0043AB6AB78E373DF010 +19A1, 6CCE9122C482A8EDC2DE37142043, BC64E1D358F7293FC9B0C2B81D3A +4CE3, 48268EA8193D8BD0308108411368, 127A6D8E01399DD3F654F713B5AB +E6A9, 46154FB1028BFD86CB29749C1E4C, C4FAD064CA84566739451DC6DEF +2B3FB, 11F16DF4A122B5C99B897921688D, C2CE146C26BB79F7CEA74A40665A +81BF1, 86023D4E9A40252B9943323AC6C2, 98BC7CFD540529771336414B0240 +1853D3, 9FFAADE7C13872809428B28FFEF1, A3383F446BEBF57C93213A70B155 +48FB79, B16EE42EDA484E3E32BFCD300A56, 8D0FEEE47DAAACAA9D8BCF69D2FF +DAF26B, A5B330E8EA36077522FE1C6FB7C3, 88A84BB806A6F5A4BFF3E551AF00 +290D741, 3C586EF3F731E651CA6002C7332F, D059BC68D7BDBD36CFC989CF7BF0 +7B285C3, C2C91FA9E776ED3BA285AB5E107A, C93F41A8A39B2BACBE05E1F93428 +17179149, 354AA3FE191A506359EFE3B9EBC0, 7BEDBBEDEC768086086C474FE9DC +4546B3DB, B0C34C7B4EC509BA7D128D7B880F, D176BF07B375EBE808FB57863382 +CFD41B91, 6752AE66F3D3302EDE020EF64CF5, 7ABCCC45227CE3FBA57F036E5180 +26F7C52B3, C292C0F2205C7DD85C160500C39F, 44704F5CE0FA803B44BA85BD4D26 +74E74F819, 560A5FD4CBEB26EF2C4A81C3AB99, 9A685B6C7F8BD203764B64980068 +15EB5EE84B, BFEC2498A5C662D7CE0EC0795D86, 81EFC44FFFBA1FE5C10EA50E805B +41C21CB8E1, 3EA8636EF746B6A7D42DA2E631DD, D23DB097D9F656B902E5BCAE5923 +C546562AA3, 1189BF2ED2A10F7312F0DC6AC131, 67ACBE20F636DD4B5B342A3C76B9 +24FD3027FE9, 288B4BBDC29EA71196301B8AFE99, 873196BCFCCAED2E2233525917E0 +6EF79077FBB, C89009F3E7A92102202082A4BE35, 84DA334BD6DF4847B23A2204BA5E +14CE6B167F31, 1C3C9F6D15A9B366431579FB48CF, 9AFB81BE81FA8D1A6D067D7CC28 +3E6B41437D93, D96F30DEFAE1F3445067E1BC5126, 5F94C2A388F7F4E7EC9B783DB0CC +BB41C3CA78B9, 5E85D2777031FE74B02214A898E9, 56BDEB0542BC36CC3F6A269667EC +231C54B5F6A2B, 150A2E2416E3AC315569A3820D92, 4DF8FC1F8ACD06B742E611626199 +6954FE21E3E81, 541D5FCCFC84A2C05E8A0145BFC2, 28BFDB73DCF4206857D022AF52FC +13BFEFA65ABB83, A990A2BC3B113A648B9E00D8E750, 3DEB9F5B4AA6913CAB843B8F2BB2 +3B3FCEF3103289, 9A0FC99B826CC66625274DF01B38, A0570619D2047C864B90C0513575 +B1BF6CD930979B, 3BABB8E3761B38E004DB334E568D, 169B474A41D6D0605A39D45C0CE7 +2153E468B91C6D1, B12E873F58C89718B6DD46DA6C05, BDC3684AD8177FFF90861DEF3497 +63FBAD3A2B55473, 6B9B195EA91798FDFEABACC415B7, 40A0693CFF52DE53819A9704DCA8 +12BF307AE81FFD59, 8A0AB24E8E9795B8482FA478A71E, BCC991821FFB5738E066733633F3 +383D9170B85FF80B, 730E403E64D699C16FACD6738B21, 919761D719C12BD2BF229193746A +A8B8B452291FE821, 3333B47B85D23C6D8300F5229461, 48D6FECEA3083B9D31EC469C6B43 +1FA2A1CF67B5FB863, C3F5AE461252F5B26EBC9DF1B5FA, 16DA58A6C565708C13823D1B2E58 +5EE7E56E3721F2929, 6BAEED3E90E849B001207107F7B8, 5E1C7B8EB4B3E367A4CEAF4B73C6 +11CB7B04AA565D7B7B, 3385AC6BBD490AFF201532286DBF, 7B027BFF07B56FDE6F0BCB37752A +3562710DFF03187271, 8146FD74592B1145492D39680AD8, 508AA9E106E7958CF011D8AA71E9 +A0275329FD09495753, B0FE244CAEED9FAEC678BD22CCD2, C97B3257468A23C4F6E883737FBB +1E075F97DF71BDC05F9, 605DCAFF23DDF804CB1CE4FD847D, 68684076591F042B98CDF14148F0 +5A161EC79E5539411EB, B65AA0ACF8A9C8E99A3F64930DF1, 34613D915630023826CAE908918C +10E425C56DAFFABC35C1, 16CFD49EE4D4850F1689FAB0041C, B50DD3663AFA67A306702BB0582E +32AC7150490FF034A143, 4E0EBC80756B99D91663DB7EE498, 6A22D944B1BAECE8B2EAD6AF3F3E +980553F0DB2FD09DE3C9, 603221615965C9EC9E587C34303D, DCB1EE7A0C41E65C08CA8D78983 +1C80FFBD2918F71D9AB5B, AB82F4270F8C35C774344595F48B, 3B4007030E1D65C6F8544508F5F8 +5582FF377B4AE558D0211, BAADF5F7E998465DBFEC5A7A4847, 1282C981EA4D0B8E7C77DE905D5B +10088FDA671E0B00A70633, 6D60A5CD3CA86F79C566F81AE66C, 22587D260CD8D45DAD2E5CE9C2EB +3019AF8F355A2101F51299, 6805F4FC0B350109728B3F56BC41, 63A9870300ED7D0852DA7163A9CC +904D0EADA00E6305DF37CB, 183156FCD56D11B82CE4B689323E, AB6145C5F793442B022B76251767 +1B0E72C08E02B29119DA761, CD59AC87B06C5D8B1EEB8C59B29A, C956728D4A8CF105F2F15B7F128A +512B5841AA0817B34D8F623, 90AA398DA812A180FE8F6C8CCC41, 9EB2C705EC011EC23345E6148DF3 +F38208C4FE184719E8AE269, 2198735C806266C1C47C8AC08161, 5FD1A06C68BE0F8D08A8EE9A2C4E +2DA861A4EFA48D54DBA0A73B, 2F7E0DFD695A6FB3085C4F3E8C91, A51B8EC5C0C1989073E756666E03 +88F924EECEEDA7FE92E1F5B1, 782D992A0601EF4DAFF89C133151, D52680F34F0E03B54F76E4F49F52 +19AEB6ECC6CC8F7FBB8A5E113, BB4C8DC0FE6FD008C8177F0D0C01, 57574AAB071C6338598333210100 +4D0C24C65465AE7F329F1A339, A12F5BBFD3757AD57EBF19FA89AC, B5F12289CFBED9161324EA137009 +E7246E52FD310B7D97DD4E9AB, 6FB82F9A01630129D70A2855DFFB, 32E0E55F5B39C0FD6042126860EA +2B56D4AF8F7932278C797EBD01, 37F034607B71FD0BE1F85ACB818E, 34CC63FF7DC6E54494BE65F82BD8 +82047E0EAE6B9676A56C7C3703, 920ADE8D3AAF24783082AF163FA1, 13A02EC88C9AF237467FAECF980D +1860D7A2C0B42C363F04574A509, D2790CFD605F2D322D213092A58A, 1BD7AF8E6F3710909B7D400F3B51 +492286E8421C84A2BD0D05DEF1B, 7F5E570FE30F7211AF05E245C3FC, 7EED46F891C350470AB27A1CD0F9 +DB6794B8C6558DE83727119CD51, 7541506150DBB1D4C44CBBD8E025, C83F59D03595F97F6FAD1EF00D77 +29236BE2A5300A9B8A57534D67F3, CA36DD2689FC281999437CC412E2, 577E04E806003AAC5A4E27D496B5 +7B6A43A7EF901FD29F05F9E837D9, BA57BDF8F748B946F34F0CE6BA64, 6B9B5A5A98D4D1F0BBA56489B259 +ECC-128 +1, 161FF7528B899B2D0C28607CA52C5B86, CF5AC8395BAFEB13C02DA292DDED7A83 +3, AD632F542942F23AA423B628A304B3B, 7AA67EE421C4E78851E4B4679BCDC41F +9, C732AE957882F6ADEEF94EF4FDFDB5A, 5F832D3A461B9BE0DAB9B6EFBDAAC16A +1B, C3E7FAA2B004CC66DD779D4D4CCC92A3, 898A5F77130726447D7C6A9FF7BB55CA +51, 882E79BE6E2A92F17FCC14EA8F4A004E, 81EFEB830764DE30840441087E0269A7 +F3, FC8786E47911BEB448FC8614FF44F929, 5FE26C7837CAC0E72CC392ABC915BBE9 +2D9, EB3002AF9DE4BCAB7F00CE22E61E638B, BA9555616D61C3DF55F940D9BB9407E6 +88B, AA37332C95651AA27D6C14B1BDC4B9, E062A0B2F0CF02FD0859E2AD452E12CA +19A1, C5364D02273F5AE032FFE5C95BA33FB, 21359BF3D455E8E4FA1B6498CF03C667 +4CE3, 565406637B339CD9E514048D0C1B6669, 33657B7FAE1D43ACB8A52F5D7F0D46F5 +E6A9, F686D8593E675C596913DC20C39196AB, EC3DA164F561288B3BE727ABA99A5BA8 +2B3FB, CBB20B834591ED538A32B71DE5AA1694, 84CC322D35B760E1422B85AB39500CC6 +81BF1, 5768402750F948709BF083D3B43D7062, 7FCB8577F1466DD3B4ADDA5431E601C9 +1853D3, C63158FF3359CE48ABFCC553F4D372B9, B6F020B6798EFB8AAF545D1B9CA83214 +48FB79, C8B1549674C6B1BEEB462953869C1B89, 61EA95C1FBF57EED2FD7443E667D5EF8 +DAF26B, 93D97715A671D51D5901C41772EC79DE, CBC8994EAF9C478A08B6D2E6F95CA1E9 +290D741, 54C38EA59EDE54565FF3B44D0B805C51, 4DF1848B089AB3E49808DC6CFD682BC2 +7B285C3, C51B5FB02D8FF4095E1AFB276A4B7636, E4403921DF02292B81A41CAAD9E2A686 +17179149, 39AF1443D88EBAAFF645D16F7281728B, 79992D9CABB675B1A3067D7CB4C7D2 +4546B3DB, 4B549361136416D85AEB0ED0FCEB3288, 7F1DAD94D1A72737286A3032B6D15639 +CFD41B91, EC268299DEFC5CC003B593F8E9D9D496, F3744002B83FFFC6A545A7EAF0FEFF6A +26F7C52B3, 6710D002065B89EF2277E6CECA7DA7E6, AA5A24DCA5010A0A026F905D357CD35F +74E74F819, 909E50A61A9634AC70A1F36B5EEA62D6, 1EFA89A81D83CC9911CD5E9978878EED +15EB5EE84B, 76AD0DCDA97CE86AFA5578E05BE3EFC4, 7DAAD7E724AE5EB4B3C9D4D0FEB2D30E +41C21CB8E1, 58DB151CE74B0E1242065F332EBC50A2, 8E65CA6336413235C7C1AC14AE2A90C6 +C546562AA3, 8440EBD3BCB98DBD710835CDA523B048, 3B0DA47B14728C63811054EC0F81E8F2 +24FD3027FE9, CDD14651443254E413C608F12C61A7CC, 550272BFD6373BC4FC1831B37BD5ABE0 +6EF79077FBB, 4C192607510F362548461733029B3ED5, B7979006BE6A92F246D7A099F769D35F +14CE6B167F31, DEAB8C0525BF41F5C7B0CBD67C2AAB50, AEBC99F2E54D009E5E2C320F60CAEB7 +3E6B41437D93, 2FD0BB2280BC6C722FE5E80D12D195F, FCA37EAB062A9462C03CA98821509D09 +BB41C3CA78B9, 8A3D3FCCFD5BBFC94D16B9829527ECC8, 7B9FD0406FD2080B8AD0CD3E1783991F +231C54B5F6A2B, 3810114B6C1FE3C3ACD5522AC46AAF97, EC32DBEE521BAA4F82EF77E0619F5C18 +6954FE21E3E81, 405F7016C928A10BF66DA9B03044BB9F, D4698929696E3C37AC7AC9FBBFFA4472 +13BFEFA65ABB83, D67FE4FDD2ECDC8BABAF926A6781F95B, D1D6DC7CCD9136ED7F1A317C32CB21FE +3B3FCEF3103289, 19891D1CCCB0D82DC07E55D8AFD84043, F94A2B60F3612F2F93F089F4C7A7D651 +B1BF6CD930979B, 420D29204148F5C5AE3E01F851DA4999, CED9F97FFBBFD48DC47A73029CCDD177 +2153E468B91C6D1, DAACDE05B55CBF0390619094A2008488, 56EA7F89E84711803150BDB0421763E7 +63FBAD3A2B55473, 6E5E8684280C87E1C00AD9E3D61CDF6, 52874C99CB842257C0B0F379B8BAEC93 +12BF307AE81FFD59, 202E8278E8C3F2C1AF84F5A0F76F2385, 6844CC669644B1AB8EE0FDFD9EB957FB +383D9170B85FF80B, 1076688ADD5CAA1B9DF02110172F23A3, E42D03AE9241C34F9835B58086176E24 +A8B8B452291FE821, 44D019D2CCEAC749E03FED3C21604CFB, FCE1C2B98417DCA06124B3AE6BB791C0 +1FA2A1CF67B5FB863, 127A50F7AB7BEB412F93D71A5CF60EE3, B48160DDAD09C097CB759E77DA097FEC +5EE7E56E3721F2929, B039E3D5C41FCCF03D679CA633E467BB, FD56EF249B88F9F8E94B55531DD41DBA +11CB7B04AA565D7B7B, 604E6D877AEE8F5F9269C930C127D7D8, BE50FC8BE50F050B06110DF717825357 +3562710DFF03187271, E226E23826D762D6F35BC3B3BD3DB950, CFB94DB91B375BF813D12D85245388F7 +A0275329FD09495753, 83501B5274973F7AAC7E3F79952B13EE, C990598F4525E33B280624A451CCAEA4 +1E075F97DF71BDC05F9, DC941F53E570141D154C8A8F6BE9696D, 69E268FD63702FA8EEB92245A64173FD +5A161EC79E5539411EB, 95582E3BA2B92671D1C55968FBFFDADD, B2D2867D6E68519E4972E107222CC2 +10E425C56DAFFABC35C1, 9E55507068B0AA334B61061B55A3FA4C, 76326CA07A608EAF2E44B2850BEEE7D +32AC7150490FF034A143, 645C473D1D29E12DEB103E33788AFC31, 6DBC857B8511CBEE87DBCEE51F1BAFFC +980553F0DB2FD09DE3C9, 972FD74F9090821E1BD8282DAA179367, 31594172934FC8099FE3243C7093A6E7 +1C80FFBD2918F71D9AB5B, 72508D40467FA52802A5E3EAE46A17CB, 6CDBB3294FCC463054987835AA2CF69F +5582FF377B4AE558D0211, F44B0CE30AE8581BF0276E6154BAACF0, 9DEEF0EF522DEB481A57AA528A9EF389 +10088FDA671E0B00A70633, 7CAD62F23B498A629F61C277B78F53DA, 8F848CA28D10758AF2620948FE7FB18D +3019AF8F355A2101F51299, 674D4F80D1E6E600660FE8C745C35137, 8113E9FEFEE67BFA1C5F84DA37B85AC4 +904D0EADA00E6305DF37CB, A2E3298F5B8D5BA408FBD59A0BCF21E7, E19DEA06A7CB2513672EEC09747311A0 +1B0E72C08E02B29119DA761, 82D4054101D260AF59BC6B34D9F7EF0, 44B2678278DB6E19D6D7F679C64E2A83 +512B5841AA0817B34D8F623, 7FF216DEBB005D7D53E8FD83CC0B7399, E326E0E156FF26FE96EB3D139849C187 +F38208C4FE184719E8AE269, 98A614DBD92CAD5D17A0A51BBA6651C, 6168C46592C07BAF794C2018483DF4E0 +2DA861A4EFA48D54DBA0A73B, E15AE151CFFFF7C9BAB06C0C4E02189A, 4FD57A693728B5851B96176BE8A020CA +88F924EECEEDA7FE92E1F5B1, 626AD277498319CEAB580C3DAD611364, D635A54D313CA01AE564D15090E8DDEB +19AEB6ECC6CC8F7FBB8A5E113, FBB841D08716F39105F0C6A0E6B44D34, B23848958CE5573D5E61D77AE65AFBA5 +4D0C24C65465AE7F329F1A339, ED6A4EC608872EDDF0DCCFAB98CAEED0, 380D8EB7DFD27459673189FD0985857C +E7246E52FD310B7D97DD4E9AB, CD713A6FA65C4DECB2E919D81FA26EE3, 7C76DE743916BFD44823F21C97FE6F17 +2B56D4AF8F7932278C797EBD01, 129F5F40B7015CA3182E56DB5BB94527, B547386942DC53B940ABB4D710C573B +82047E0EAE6B9676A56C7C3703, D61FE443E8768B4A7C75C51DFC79B3C1, 3D4EB1AA062D55772A54FA4082629402 +1860D7A2C0B42C363F04574A509, B65B5424B49167FAF49F45D0F95E6BF5, F5B3477C391B4A0DF92B5F54A633225 +492286E8421C84A2BD0D05DEF1B, 9DA44051B7F939BBD5A4D0156AB26975, 9E9A77EA27C4B6281A04C2E8B20C2440 +DB6794B8C6558DE83727119CD51, 4C6F67B418FB5E4E354DCB622F55893, 9CE7E4249148A54EF9F75A23BFF7E163 +29236BE2A5300A9B8A57534D67F3, 84FBDE461ABFB4C47D9F9EF607390113, 2DB9ED91647C0BB98985BFF0BC652C94 +7B6A43A7EF901FD29F05F9E837D9, 111A425699A95CD6E6CFC8B2DE7982A8, DE3C25EB858FF46CFCD755C465EE0EA7 +1723ECAF7CEB05F77DD11EDB8A78B, 418DDDF6455242DC8E3CF706F7357A31, 9874EFD9B781E72D6DEA50907E09F9F5 +456BC60E76C111E679735C929F6A1, 24B1B158EB838752EB7EE82661942D6B, D630B06558D5C804203229D23CB97B1B +D043522B644335B36C5A15B7DE3E3, AA62C51A16D74D572E05D72465A9EAE8, BA546EF43C8432DD112F6F3F33484FA6 +270C9F6822CC9A11A450E41279ABA9, B17D5A63D3E50E0759FACE17139F4C9B, 59F0D096D23A72BCF3990DDDF9B135F +7525DE386865CE34ECF2AC376D02FB, C394A85DDDF3E8DF5A784CC2D94B87B7, 4B812AEC48DCD1A8856522862CE11FED +15F719AA939316A9EC6D804A64708F1, DA54D51C35FBF5D55CE16C5D3551A64F, B5B46E38541FA7D4E8B300F3ECF46299 +41E54CFFBAB943FDC54880DF2D51AD3, D52F7E4371E70669479959E67426F091, AA001B1E7714D0E2B6DE83A839CF3083 +C5AFE6FF302BCBF94FD9829D87F5079, 81C87D44A112676C129F7F0A8AB2FC2E, 734E4D8902E68F34655AD425DE9C4D8F +2510FB4FD908363EBEF8C87D897DF16B, 56CD2AEED77F0DB901402C32DFF4C325, 4AC2237E19DA29D0F281B2B4F18953A0 +6F32F1EF8B18A2BC3CEA59789C79D441, 356212C5077F17620E6A781AF20CD65, D45C73449F6B5F7F271DBDCB09AE90C0 +ECC-160 +1, 4A96B5688EF573284664698968C38BB913CBFC82, 23A628553168947D59DCC912042351377AC5FB32 +3, 7B76FF541EF363F2DF13DE1650BD48DAA958BC59, C915CA790D8C8877B55BE0079D12854FFE9F6F5A +9, 25393E48E2B7B5DF8142CF731E3F00664D93BBB, E75DE5DF76185C0D233F23A2E7B973A954694156 +1B, A3E33AEB16B8B30F28BE00A54ED1D1278EF7E4C3, EA331BABC1F9C850CB6FE00C6E8D595A2F0A526A +51, 734F0EC134FA53E573BE31828ECDCFE969230F18, B39736E2FE9A766947CC8F236627E6551C74F1A3 +F3, B5C70987F380C3A1482499B7E38DE108E49B1B7, DA72E3B069331A4CCCA6C6770C1B0E95BED8F3BB +2D9, A2DCEB63F2DA16B8ACD68B6EFFCC730BC767D400, 23D6DEFF4A0C085D623627D28E991EE25D5AE745 +88B, A33D980E4D1E6EBDE888380645B1F81C28340F61, 47D8D18D8D640105CE735D0570D16B578F7552C4 +19A1, BD52E5C229FA5763E2F048582672D779960952D4, 8EF1779DA5A8AEF223E0AEEC19DC315E19A3402C +4CE3, E7D4964676C3994C0619030152DD1E739166F2E7, 20E6BC678D4C3C0B05147A2DEB123CD659025CC7 +E6A9, 5D0C33FE66FD1DA56FA31E0C1570286875C7A5C3, 917773615CA2E1DE0B6A7E14BC5EFA8AB86947FA +2B3FB, DC7520AE8A604FB5BAFCB40BAB185803F5012D89, 3ACB6E6F454DEEE809D36113FB941A319C004595 +81BF1, 968191992AEA557635F337FA23CD88DA24DEBF4A, E3035E5E5AFFA7019DB899FAF65FAECD2757EA60 +1853D3, 6D278B8467DA43BF84B72675DEC87ED91A6D4893, 2EB55C1C3AD1C98C553CC6B2CB98E6CEFC73C8B5 +48FB79, 31E014D27430CE99E8F8932F36D9FE1321C9AC9, 4EC4FE2EF24BD4244F872AA286ED3BDC182EA410 +DAF26B, 26919D4E3DE999CA8BFA6D00FA8E97C42FAEA85, 2DB843F7603367F4B1F07F6B45403A8F88324BC7 +290D741, 4B7D7FE3FBF73AF19CA0EC13A7F22B8EA31CE7DB, F82DC14B5E53CC35E4275BF639DC21B49F24EBBA +7B285C3, F445903F825EEB5A3BAAD6DD5E7B319B0E9ABC2B, C5BAECCFDEA34B7032BDA2932DF4C9AC10CCB4B4 +17179149, 4183B5F938FBF5F0DC8A95704096DB5931A5D627, 2D7E42949C7703BB0149FF95815F2DFAABB6A73E +4546B3DB, 67EECA2A2448A42FB50F6321F3AB4C06E3D10DA, D2DE1EFE80A29F460F7F7B2DFBDD93A3B87BC1FA +CFD41B91, 306D5FF90BC57AE7B347E8938FBACD5E8C3CB4ED, 3877474EABC5B88D529EA9550A3EB445A4FE01F8 +26F7C52B3, 30DE6E2A4370693BD9FA7D8A600EA5E6D75943C1, C288A48857FA2E8F677DEED44A1DC5B167708287 +74E74F819, 71E796FF669023C714A0A5215D7DE249B96E4CBA, 1D5AE16000FFA8FC848552E930E9D00E2DCFC4CC +15EB5EE84B, F8A8781D8F0844BA0F689184FF56AFD53D876557, 840E775C494738E49D3AE5D0AB7BF6F25F50F385 +41C21CB8E1, 48B5F313F23E31A72D61337E56203892FBD4AE68, BAC7A49986E06088A62FE1AC07CA2B67CBAFBEC7 +C546562AA3, 73CB8D5A5C2941C636B5D7E9EC69C1015982154A, BCB81976F0CF4F9E55887EE4AE7CB5274944F28E +24FD3027FE9, BF90E02AFDA1EBCC34B02D695CB360B150EDE3E9, 7361D6BD46767F2605995A7448154541ABF3A996 +6EF79077FBB, 93F4B601D818A4C11025779BAC80913BA0858801, C31A64DF2E600901674AA123A792168E17AFE90 +14CE6B167F31, D7D857B44C53BBCB5C3C888E15FA2FB31451E28F, 2E0F00931FC5DCB0049FCC78BD2F4B2593FA8F6B +3E6B41437D93, A29B3FFB401FD76A45DCD8F5E87C2133C36FD1ED, 1883EE891DC09A914AB0B456D78876B89F455266 +BB41C3CA78B9, 9FC8C86A7E9F2958C8CD957C89B414A759586954, A76C1576AED305C9491B7EC075D3C7767777C37A +231C54B5F6A2B, 6D348E7C4A319BB00DAA66615C113976AFDBF66, BC6DA4F9545617DD2F800E74B22142EBD2DA2FDA +6954FE21E3E81, DDC68F983A0D9EDA70E0B9E619D71A8F437B6276, 726642668979300161F48BA9696ABC855BB4B795 +13BFEFA65ABB83, F638399A8904AF059B46A6B8B8B8CBDAF598D9C7, 6F267B6C287DF615F54915DC922EE4AE41126D93 +3B3FCEF3103289, FD136674C5A9E5909FF90397A160EB2232983B44, 5143E198C0B9E3F70215E0AF841BC841F7F7F6B3 +B1BF6CD930979B, 483832C21A3569E8F58AD8FCAEA84F7FC4559663, 5CDAA7FC128E85AC5BEFBD9D94AEAAC681F7AC2A +2153E468B91C6D1, 9918DECF01630EEAA5B226AB6AD577A4D9044F8D, F57AD0162569CB722C85DE7CF98466FF4AB0E09F +63FBAD3A2B55473, 56AEDFC9DE5293FA3FA625D6D8F5B54F95754160, 26D366028621815862EC3CDEDCA7BD09654605E2 +12BF307AE81FFD59, D70777E9F2381429250279FFA09A27A1AA7EE866, FDF2FF1D369ED1003C1BB3AEE3F5F6DEAABC0E57 +383D9170B85FF80B, BD3A19DDF16D9281B8F5A35E0458229481ABC2A, B35E3DE71303702A1AA8F9B4845E3B660EF3F4F7 +A8B8B452291FE821, 9D7659C6B17D17DF5104DB2022BC059D85170F82, DEB9A9B784E14ECEA14116443C2FC6D46F723D +1FA2A1CF67B5FB863, C122BBC2034E30588D106375C098006F80DBAAFC, C31567A287D0CF0DF1904CDA7B239EDF4DEF83FD +5EE7E56E3721F2929, 1A1181829744B2D0DBAA23570C1450BDAE6A9388, 23E295A382E8CB2CF6822B7840734712427FBD60 +11CB7B04AA565D7B7B, CCAC921924E4E2CE73B1328BB65D1BEB111D05F9, B6DCF138575699B24E65F8E4509DE3656AB670D +3562710DFF03187271, 46CAE3F8641148620DAC97B2269086E1034508CD, C466FB97D2B63A866079C4EBE5FB6147C4D41C84 +A0275329FD09495753, C3D05A02C096E19F6B823D399F177F33B6661404, 19EB1CE2B123F8AF342A70DBA6BF1B0904DFA277 +1E075F97DF71BDC05F9, 355F10F526DE3DB79A28C4AE4AB83C91F16DE2DA, D93A8F2292847BA20C54E9D4FE376BEC9BDBAED6 +5A161EC79E5539411EB, 69E617B5E403AB15B10932003AA4C754FD585888, 6199B97EB0B634DF4B51987DE8730F7E364CC46B +10E425C56DAFFABC35C1, F230C76976E57CF10DCE884D10713CAF8B46955C, 80C1A15211B1F06919D56CC86360AFF3522AEBFF +32AC7150490FF034A143, 517ABE22245548B18CB7CA541852FB4682C92B54, 7AD5AD7E91F8A28D842F38C1277553D14C1D8EC4 +980553F0DB2FD09DE3C9, 4AD778F7AF703238A93EAA761B305AC36008AAB9, 296C7D40D07C37D5190B9FDB55ABEB8363D598DE +1C80FFBD2918F71D9AB5B, 34589A4F974E2772B581F8B1F9292B4A3221A392, 95F634C03F3461C88C258B6C3496CDF57CA94855 +5582FF377B4AE558D0211, BA1FC48E95584F0881F117C52E9B84D70ADB8CB2, E34B05161D00DE1B9235538B4E6402F8D62DD13E +10088FDA671E0B00A70633, 9EE3D749EA08A4DCF3A7AB51C15A8ECF8F41B016, 3A21E95620AAB5F8B829C494810E9226AA78060F +3019AF8F355A2101F51299, 86135777B50119CEA4C54A768B4D55C14B6EEAFE, E848B2F0072DB1E57BB2BB41FDBEEF6134101918 +904D0EADA00E6305DF37CB, B3EF2035AF9A8FF6A1D541D0F1C6D56F25051C35, 72DF35F50E4540C80E07AD5D49E9F182CEF78AF5 +1B0E72C08E02B29119DA761, 6F8E9E9456805DB0C58ECC6D596766A1A244F60B, 3EDCDBCFACA7A9D5A1319E8AD429A320DF4354C +512B5841AA0817B34D8F623, 93FC2F22165E8A22439C9AC49D0BECE1E2BB8716, 751314404EE1091A09864791FCC91780F94057EF +F38208C4FE184719E8AE269, D341F5018D6AA45C31DEE5341D09E3E04814B56A, 7A3FD8CED82C7DCBD444C2E07691B1711C96C56E +2DA861A4EFA48D54DBA0A73B, 8960BD4CDA88561DA4155542FCE995FBDEEDDF23, 797312B7B2B5E29279A3273192E0A0E148BBCB8E +88F924EECEEDA7FE92E1F5B1, 59396BDCDA965D15F1FC0BF0222F0FC86B2C300D, D4283D03C78C717445AC36328C1A64693FC7BDB4 +19AEB6ECC6CC8F7FBB8A5E113, 40A00776282D3C393BBC1DE7C9D1C1FBBDECF448, 512DF328AAFEE099E889CFB2C6FE9927005FD4EB +4D0C24C65465AE7F329F1A339, DE65CA9A566D89C6788655F1E450324D554B84DF, BF508E8B4FEA2B015E96C03FBE31268A6ED591AF +E7246E52FD310B7D97DD4E9AB, 1F680491EF657A5FC246FBB202A0002923325733, 5553CC698246C9B786179BC5037C9FB01713814F +2B56D4AF8F7932278C797EBD01, F333344C9F419569DEA6CB228D8938CC69FB81E6, 5D193CC5C5A830A12AC4F6C91FA6253E91267B15 +82047E0EAE6B9676A56C7C3703, FD6623768A2373B6BCC6D84569818D332E27B1EC, 72C39291859E0AD1217D23A34B662C4642113024 +1860D7A2C0B42C363F04574A509, 95761AD2BD51DC587A418ACDA16076A4DC844E22, EE5D215DDF7FE9F6EA2774845041EDB2D61C6E85 +492286E8421C84A2BD0D05DEF1B, 4A3C6077D76D09148B0611C8746EC56D0DEDC031, BCA3BC2177F774CF3B15B6E2128986FEB789322C +DB6794B8C6558DE83727119CD51, 2A3C6AD8102997ABB372D9D9C97C4E4EC8BAFF96, E152C4D5C594088B278E2A935EFCABE1E7B1FD6C +29236BE2A5300A9B8A57534D67F3, AB097E5ACB02E4459030895C6E354484EDF251F1, E6FE3BC507244169DC7CAB7DE32B6AE92AA1A6BB +7B6A43A7EF901FD29F05F9E837D9, 129D7BE9C4EC8914B41A2C766D476879D6F76BE4, 587962443B8E295B1CB893E4ED281558A8C8EFBC +1723ECAF7CEB05F77DD11EDB8A78B, 1C96D21218F2851F453D52871557B037B3512E0A, F6B977791E1C83A34B3EDE67CAD7B751CD0C0E92 +456BC60E76C111E679735C929F6A1, EFBF075A3FDCF11C6FC8C3EDAEAB2768A6D30731, 6B729DFA5729476544770F50F915D458B678341C +D043522B644335B36C5A15B7DE3E3, 36BDD9FC45AB77B06CE2173B8B793427D108EF81, B96612AACFB4C44DF74B6E26B12038BFDB7AD69F +270C9F6822CC9A11A450E41279ABA9, FC4D15FEEC11A0EF59622B7D2895970552345A56, 1AB20573F123C149D487E3B1336993D3EF5AD1CC +7525DE386865CE34ECF2AC376D02FB, C4430A83572A1BDC98CB1E457781A43C35050B2A, C3DE096745E831E6CFC7EBB98B747602C96096CB +15F719AA939316A9EC6D804A64708F1, AD78F890515B436B7BAE6A083B2DD5E1C1F7B70E, 4E849C221A61E5D46DA23E3B2F74B8B8EE14E075 +41E54CFFBAB943FDC54880DF2D51AD3, A53BB39DBE63EA5BB49D5D85991666C3490CAD02, 88479ED000F61E28450E1AF1E0F62F5AD1E3F905 +C5AFE6FF302BCBF94FD9829D87F5079, A653F42589F8B26F03067FBA1D3F20082632CF0, 8625B86D912D177E139E4A0FEABB68DB28E8D84A +2510FB4FD908363EBEF8C87D897DF16B, 6A5F2C81A3BA8543858ECC97FBD98BB0990B851B, 20F3777694592F1FFFFC055B716919C1EA625385 +6F32F1EF8B18A2BC3CEA59789C79D441, 1D7A2FAB41A5CF1DB3A235E261C5E3D2B4F92EF4, A1BBC0E673FEBD4D5F409907FBE404B41435395E +14D98D5CEA149E834B6BF0C69D56D7CC3, 2F885A7A345B99E03192A6EED5F969347DA805EC, 623B9D1A9A9012DCDB9BA68958A47ECF4C3CD0AA +3E8CA816BE3DDB89E243D253D80487649, ACA5A382C70ACF6199716A36FB9666F71F8DFF57, 62BA96DCDC4809E71C659228E6CA1FE80597B8AF +BBA5F8443AB9929DA6CB76FB880D962DB, 6ECFE7E695F17D048C516C35458CA3967541651C, 1036FD8DB26A743B7DB499F42C4301F079E5D567 +232F1E8CCB02CB7D8F46264F29828C2891, 44E0AF7A04FE3957C608146CF14B4275C3D7B666, 38A0714252B9B7D3A44EEAE50086DA06A9388999 +698D5BA661086278ADD272ED7C87A479B3, 7088D973680A53E9479DBFFA467A2111BCD3BE0F, 7D5D05994DA529E8E004D671E788FF3BF888CD7C +13CA812F32319276A097758C87596ED6D19, E4A9C3225C1C2EB76CC58CDC6E894973D58D70DD, A7B92C8791C5E5BABAA17466564A7281F9222F36 +3B5F838D9694B763E1C660A5960C4C8474B, 5739713DBD47167D3E32CD79B47A4A6E275AF078, 5DB73EE6DA8D4979FD94A281D633B43AECA6E9D +B21E8AA8C3BE262BA55321F0C224E58D5E1, CF96DC40E4B69CD8C790FBEDC0BB25952C9DE5EC, 366881EDE370510AE1E82532147CD8E01752E8C5 +2165B9FFA4B3A7282EFF965D2466EB0A81A3, CCB043B608DBC63760B564CA50654FB86817EFC5, A0CD38CE52DE2F283CD2A7CA558ED9BA01CB56F3 +64312DFEEE1AF5788CFEC3176D34C11F84E9, 9FA21A21FAEFBFB6E12775F9949ABE24429110FA, EFAE412FD472D2A05ED3F46933B3EDCFB203E723 +12C9389FCCA50E069A6FC4946479E435E8EBB, 5D876339E7170085A3A74848EA70B60B6588BD71, 65A7DA5C09F645BFE10CE52CD00F63B00350388D +385BA9DF65EF2A13CF4F4DBD2D6DACA1BAC31, C7EF4CF57F0BE40146B2D5F6B14443B6D96171E5, C7B0BF0558433FBE1018FA28A80B384596A6B9BE +A912FD9E31CD7E3B6DEDE937884905E530493, 57863906F760EB7472FDBBAA7AB922EDE99A30CD, 470EEE35775797FD7D756306011784D4D1A94B3F +1FB38F8DA95687AB249C9BBA698DB11AF90DB9, 4EE1981D55A77FFFC3844C7DFB87FFEB33D2287F, 411D7A29479A565BEFC56F5FD2952DADBFE3B736 +5F1AAEA8FC0397016DD5D32F3CA91350EB292B, DA706E4409447F41D36634A89DEADD450031EB07, 25E66A476688C499CE354500B69ABF7E54C83CAA +11D500BFAF40AC5044981798DB5FB39F2C17B81, 3B492E0378D8BAC27FCDAFEB53B6DB8E88A678EC, BA3A45947418E51A09B5FB16C808B4A256112E51 +357F023F0DC204F0CDC846CA921F1ADD8447283, 201D6DB45EA1F22E7AFD6D1E226F028123EE9EC9, E69423D5D87FFBF101BA7C85CC3D2F63CD013BB1 +A07D06BD29460ED26958D45FB65D50988CD5789, B23E082FEF3C87F6C431FA42CAB2E70E6B22165A, AAF1370FCD36AFC7EBB188EA3CAC36B6143C4324 +1E17714377BD22C773C0A7D1F2317F1C9A68069B, 2A808829F1789876B2FDE344382EE0B8690C2B00, 3273FA8D18A239DC81FE8294352CD40A408FECA1 +5A4653CA673768565B41F775D6947D55CF3813D1, DFA008B9187788078297F4A9FA02192C4FC0DAE2, ED0614DACFCF34F0125FDA6F9E7AFF7C5DCACCB6 +ECC-192 +1, 188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012, 7192B95FFC8DA78631011ED6B24CDD573F977A11E794811 +3, 76E32A2557599E6EDCD283201FB2B9AADFD0D359CBB263DA, 782C37E372BA4520AA62E0FED121D49EF3B543660CFD05FD +9, 818A4D308B1CABB74E9E8F2BA8D27C9E1D9D375AB980388F, 1D1AA5E208D87CD7C292F7CBB457CDF30EA542176C8E739 +1B, 1C0A558549162FE7C5D7274A730E9F58CE960BC9958D3288, 618AEECD7C6D796F0FA9BA3312490CDBFA0F3488F2FCD59A +51, 46AFF85827C9065133AD79BCF0372820C81880C645F2D928, 1B8911D44F06CFF14B4222E19BCBDA59194F970F34A103E2 +F3, 1C142C97C6CDD5A87475E04FAE2E86708EDCAAA2F33D97D0, 67793727B60FBB2E8D4163C131D2D72F6774827109C02B69 +2D9, 6157465770D08B8E53FB60AC57DD68F88160FD474B9B02B2, BCF67CF4003CDE95B507EAF4E07CD713C2F7A9FB3202B49C +88B, 767B00C09E0D583CEF4F301B727777673EAD242F2593697D, 7CF2510D4FF604A749FA3918DCB4840455CF7E68AB245A0E +19A1, 5A15B62CC74FBDEB931F1271CD38CF9F1D86131213248677, B69BCF78F9BA76C45601EF2486C166D04F34417804E913EC +4CE3, A51BC29BDFB0993FEDE91916D06D609FC744A813033B2F26, 6B0D669EAD4945315E92989358ABE363ACCA90FF09C25120 +E6A9, FF714040AADDF96A94380ED63FDB4D4207E9C94664724C57, A8B1A8B19F339AC663919850BDDB8A43DEAA04C861735987 +2B3FB, 35F80DA2E24E3523F1CF19B44A5C3B3A58C96AE146464293, 7E7B7C4AFFCDD781F641F9C2376E5E24121CCB2B9957901 +81BF1, F29F6F84ACBF1EEE1A4C3CD4D6006E0EEB0AE0A9EE08EE2A, 43CB330E3143943CBFF1F0EB889258E12353A2777F61FD4B +1853D3, 2AADE7388043FFDD4D4ECE26ADF6C85E564AE7119AD601D, B0136CD55AF4DD76C090358324B2D4044FE78519AFD2627F +48FB79, ABFFB427AF19C1618934C4ACF80A73D30CDCB3F5647361B, 577058997D7AF23F88D039AE8D195E1CF20E94A9E55CFEBA +DAF26B, E44F89F1FB04FDBC19DAD570D1EF3588EB47F799F3B31F40, 47509D6BF8F7A072255D4856B021543AB17DDE0F0EEA046B +290D741, 85E180BCF6BE779694A2C71D393AF8043A7A74F076778283, B0D254C1E67B7ED57C4847AEDE7F110FBEB337106517353F +7B285C3, F15B9270198F4ADBCFF3E3719F20F44E9C0786EBF5116BCF, EF12D95EFFE8FA9E4574B948CCB009C59B837B2065D4E754 +17179149, 76D8028D35E2B6760E4270781E2CAF51310433B0A7A525C4, FC2969795EB4BBC23B402842C4BA723D361AC065966C4927 +4546B3DB, 115569333F111A12BE5556453644F009567F4C7B40C5712A, 95776EFF47496BCE215E608F57E2731FAC2445666855BCED +CFD41B91, 181B8097BA5677CB3A3C3BC977AEDB8E861DC7374D5C9D82, F95ECBD7B0952380C21A214F75A69DFC486F2316A7A2BACA +26F7C52B3, B43A147C979080FDC8360039F4985EA31F7CE7D049478450, FB4687DD7D77359C497216FAE50F953C38288FAF271BDA68 +74E74F819, F16191FD000EDFC6F3D0E9C75DDC56ECC0255BD0874B8B40, E6FF81A430405BF3111AE21B28679D3FE6BCE570EBB3ED6F +15EB5EE84B, D88192214F0A25FABAD10EC7A4F7FE0EA6CD328D0E81784F, E8D10332314077FF28378C0D404FDAEB3508BF11C025DB9C +41C21CB8E1, D797A077FC44D1A5398FBCF648FE3CF921EDC23A59C6AA57, 197EBA01F6EBF058D4E19BBCF358EBA512DD4C403095F96A +C546562AA3, 1EA9FE83CD362F5A675DAE672D1229D37FBD501C0DEA7021, 5EB6874C8853B0FD10662F3B25FA9A21F4A66315E790FB8 +24FD3027FE9, 1E3628D25F1AF3C515C0758723BBE2D111AF7E4779DF425F, F991DAA7AC2BEAA1515D823283B67D9FB1B91C1E043B27EF +6EF79077FBB, 6C3F8E8C135BC46234D8B85AB9BA94A9ED2E7FF9B8D9D84D, 1710D8B22CA3F572CCC4F3F7D29B4508FD0EB49737ECFB01 +14CE6B167F31, A1DD7DC14AD895FC0E6DE95019379A4FCA488996903320CA, 34CB85A2D98AAA0FEC199A6DC1F5BD239F9E3AD45D5F9C63 +3E6B41437D93, 8A29236CFDDED1F057141CDB01E2042A36C8584BD1F7EBB1, 41DFA388743EB780842CFA8E90360E21BC957EF0B0943AD5 +BB41C3CA78B9, F0D31E7BA6299CF97D49459746F376976F3F69A254FA430B, 816B3BE3CDA212DCA47942E839460AF55BB368CF82443FD4 +231C54B5F6A2B, B61E3CE7469FB46A5A75E6F369319E86B3EDFDC15FD71139, 6E4A91ACFD67BEC34120A13329B9B94E9334B440F5BF929B +6954FE21E3E81, 1075CC5D277AED7E0603C852EEEEFE98B0111577047C239D, 82FD41C0DBB75F8698F96262EB53EF6C6D166AF078519E12 +13BFEFA65ABB83, C5DCEF887D8AB1FEF1DDB523F4F13B3B9C6692FC8FD8FCA8, 108EBDDDC411685D240CCB72D9046F60388C45D4B380ED7D +3B3FCEF3103289, 1214A2F9361F8F7E450D576A8C2316431EDCE1E0B40A180B, C47699ACD4F1B58348F5AC484B98A91ACD3097E1DD88C01B +B1BF6CD930979B, D590D2A3B6DC021E4E32CDC319EA48CB68FA7E953409C71, C06ECB0FD72F556006DD810E84E0DD1B1209198F013A86D5 +2153E468B91C6D1, 7DF6201144ACD2F93FB748724CD4E4E6F35FDC8C94CB203B, E9A12B853E94CB76FC0BEBA53461441B71C53B5C1061CC07 +63FBAD3A2B55473, 760FCF9057B0FEA16B60C8D3F754D9E2C18B973ABC701BC1, 92BFBA6E586583F61FCFF086CBB54AA070C273D847576A81 +12BF307AE81FFD59, E462BAC637E80D709FC2026CA864349722CFFEB2A8C14034, D6FC9AD4D0D9E3A80900DA823A02D01C20C05CD208217CB3 +383D9170B85FF80B, 2A20664813D23476502D4C405D7E073570F631E4E2527E87, 97F0E060BAAB21323695BEE672AE1A15D7B496176B1F7C25 +A8B8B452291FE821, 8A9FE5C70C8E1B73C0E2A3E5ACE91741F248E36F5E9809ED, 70051C26F338D61010A95921117E6F0B6E9BF0F9CED42EC5 +1FA2A1CF67B5FB863, 22834749F02FBB2D964358D12A7133DBDA532549F1745F35, 673546F13C6994B970C0376F96BD0051D19EB0D7A0CF09D6 +5EE7E56E3721F2929, 4A31DBA1B4EA6F5F5A166B73CF7E83BFBECBCD2CB22D0A65, 89E8AA2325C986557C262BDB2BE805222875242E276D7E6B +11CB7B04AA565D7B7B, 4FE579CA87A004AD36CEA14292F91BB85A6F5964760433EF, D381D212DAED188E721AFB8354CE0D1B7015BA8D8E8244E2 +3562710DFF03187271, B804A5F404DC163EED2D2E571F5FB77F35AA8B078586AE73, A6071F8E16F8C2FC4EC87B3FB20442F4E1A3738E91304568 +A0275329FD09495753, C7F9292AD9FA97DA3AFAACDA2B6D0B9D83E7116F0B2A2B76, C2499ED4938444F34F1D89136C7153A683A84F048A6DB9DC +1E075F97DF71BDC05F9, A5F5374B2F7E07EB06562A1BD3F8F53140F3D43472D1DE8, 5E94BDDB00BE4723D64F58D1C76A5916EE79B9BC08E65754 +5A161EC79E5539411EB, 54665882C939F6938E006794AB3F2EA50148C77F2F3E09A6, DC19F80B200FB36AA3933E7DD2B8BDCD9DEFBFA094C068AE +10E425C56DAFFABC35C1, 6D32C477B9B88E4A2984996C8F586E4CE670ABA7F9317BB7, 47B1FAE5A733CC165666A8E1B1B3C9D36520CA82978B3C4A +32AC7150490FF034A143, 704962F0155A1907D04C921D773827724C1550C9B321E07F, D65D2FDD10F3569EBE0F71CADCED6A08C30C79EC221FE703 +980553F0DB2FD09DE3C9, DD2B09ABEC03C2B6B79C59527BC2506AE8ACE5F5BDF8C9C4, A0F0FA28A86BF4A8EEDC13A4071CA4799E3ED3B7A551FAE4 +1C80FFBD2918F71D9AB5B, DD8D44CE64115353C51BBFE970E1B7F8BEC0A56815641AD9, A1678B2557AF4039AD5FF55592F1B62D16C493144650588C +5582FF377B4AE558D0211, 9F49FC1430F451B4239C265C6FDED93866D82DF30233296A, C5B07F840EB2F171CF4A6786473096BD94070F3D8F9FD80B +10088FDA671E0B00A70633, C3F8B7CF57A281463239C03C51AEC841435FE7D43F1E241A, D9474297A32209AC6577ACDBE59482971D25C811A83524A5 +3019AF8F355A2101F51299, 2F89FF42A3477AF0099EB8D20BFBF246A42BCE28C041BA10, A3958623E8ACDB16662C3F5EAFB757CB912F0E55AF480A6E +904D0EADA00E6305DF37CB, DE9877B73B97DAC40E06560B53557C093F46E2A9FAA70020, B7868444CE638BEEA8C062AF8FDC3D42BA3ED8D384368196 +1B0E72C08E02B29119DA761, 87411F357505BE61E8A2EC83A1C73D414893421E7942A63C, A2F641BA92F59BC2FD0051EC789DC6A22D1B790431CD53A1 +512B5841AA0817B34D8F623, 33EA40EBD183D3CA2E967763711F5EAAC247A83D10F4D8CD, B501868B4942D1DEB3F4DBB18C938BAAEA097B5DC8DCAF06 +F38208C4FE184719E8AE269, 9758347531DE82D0487EA03FE4245747640FA7CC1089C27C, 5F37E601C56ED8B600CC9D1B57B909D21A12EADEB917636A +2DA861A4EFA48D54DBA0A73B, 63D7007A3B25A362767A40411B2A0394AACDBF13A7EEDF3D, A721D1395745E4031DF177B535C09FC94756C0FDA0AE6631 +88F924EECEEDA7FE92E1F5B1, 6C8A8C2394FF380A228917B08B111D76A2A4E9EFD7E4E66E, 2EA61738C24D33C2789A186A5CC15245798CBC62F5A74766 +19AEB6ECC6CC8F7FBB8A5E113, 8DF315820BD24BD6F20122ECCA03EC60783576FF1931D06B, FFA2AC7836B24C3C2EEBB76F24B5A78CE8BDC8144545EB9C +4D0C24C65465AE7F329F1A339, 3CBCE069C8034D233B9C2ADE3C8F3F26D6004D6851BE36EE, F1CCE453C42F608ED79ECBE9DFF05E12D7843DAC2AF0165E +E7246E52FD310B7D97DD4E9AB, BC6196B8E020F764A84E9A7032B2AC38460015DFC3EAC411, 924EB9460BD723CB9ED2DD3E894CB24CC412B0CAE2AF8886 +2B56D4AF8F7932278C797EBD01, 1F9E734CD4742FA8537DB9BBD53A9EEA94D4CD47BCE92196, 2F2FAE55F79ACBE6223AACB30255161AC9B99F3A77087416 +82047E0EAE6B9676A56C7C3703, 6A00F547D2CA07929AD0382EC1CF2DE4240CF04E2ADB958, 9F6A1D2003032B61F65ABA33469464AEE22FFE40BD214EBE +1860D7A2C0B42C363F04574A509, 8607DE682EF40AB177F96540C70830855C1D8A3BB3340364, BC5B59F9E8C983ED333DC75231223668C20CD7D818FE09B1 +492286E8421C84A2BD0D05DEF1B, E40E7B5E5CB42241CC23170739DE4978F0C1FAA44C3B0A66, CAEEAA3DE08BDF32427CDDF8FEBFC42C2555FE38702227A7 +DB6794B8C6558DE83727119CD51, B72BF024B3D76D808D554D4A65334D4FCE8D5010D822C0EA, 3504AC222FE822E481A27F9C16EB584FCB390CAD0FEBB46B +29236BE2A5300A9B8A57534D67F3, 886AEF669BC564617B66F6057D040E60A3AAC8ADFBC5883, 765D1317E730E046228634241626AD17A004D0DEB3E6B8E9 +7B6A43A7EF901FD29F05F9E837D9, 919F5CCE4A889BAA1DEB916BBAB5C95163935DC7D78B35B7, 2AE6C9F8C027135C88DFB1223CF7B9E198D635D7BC8FCA2B +1723ECAF7CEB05F77DD11EDB8A78B, 97564D4FAC349DEAEB4AD24D9C2565CACA598BAD07981E2B, 17621261F147574DC2D663D58A81011CB42C5787424FA570 +456BC60E76C111E679735C929F6A1, 40677079B500B3DDEAA6B0D519C51CC99954B80DEFB416F4, 7A80B080F44C4F71A01CFFC33622E3DFC98656B3A5CF701F +D043522B644335B36C5A15B7DE3E3, 78EA536B23938AF681E0DA7B216815C3A9D62AF7CA76CB8E, 4A44318E21F72E0CF092DDB80A9A145D423505C775330BF2 +270C9F6822CC9A11A450E41279ABA9, 1E4296F8BBBF2BA1416B131712D0D0323CD566D288617A38, C4E33977F7CE998528ABE9899BEA3312FAD976A9D07FDBC1 +7525DE386865CE34ECF2AC376D02FB, 5D37F277984FA15FB5E47EF1B4AB48DA0025E01C70BCF192, 53758437DD9F6CE7214ED99806350E5822C1C022371C986 +15F719AA939316A9EC6D804A64708F1, 45F0D931BE0BECFA19EE77C69F2D6EE2BFD46A3ABA9E7860, 2DD205C736CF8D474508D1D9FEDBAA9B398124C8963AC9AF +41E54CFFBAB943FDC54880DF2D51AD3, C4148ED33A11E3B919F678D0F6DF2E5F19E888252337502, 6BBB5EF5AF0688950B4E9A05B69F3AB4449724CFF38B6D17 +C5AFE6FF302BCBF94FD9829D87F5079, 1F5855C573EA7C76D6E6B34539885B1CADF69A26C4F4D42, 25EC84477867183873938999C5445871630DC9EAC9331B7C +2510FB4FD908363EBEF8C87D897DF16B, 2275194E1FF9F071D0B9D4DAA0C859E9EFAB5DD0131B86EF, CEBA1E77F349F3A9E4E9CD42689FB29E0633174627A9892E +6F32F1EF8B18A2BC3CEA59789C79D441, A2CE1B722AEDD1C545E1FB6E6A3018C2EDCAA5DB7D4B523C, 759070FC0CF663F1D84E885952FD9681898ADCDA47D3DA88 +14D98D5CEA149E834B6BF0C69D56D7CC3, A7BF44284B9EF496941F31B6442EF663627427C9DE50AA10, 993CA2E4B263BAABDBB58D27F3E3C72BC71647D9EC3D0ABE +3E8CA816BE3DDB89E243D253D80487649, 3DB825FC33496FEBCA37FFAF958DBEB50EB870F7193D2BB, D59884A0FA78538B678628374DDA23ED6EEF75A863E3F53A +BBA5F8443AB9929DA6CB76FB880D962DB, 8D6011151337C570552757A22E3A302FCB7BC3D61DF6061E, C455C35E4A071CA2715C80121BE43DAEF519B5D1B768B849 +232F1E8CCB02CB7D8F46264F29828C2891, 1371514D33D4256E50425500708416E4F8706EE52F803A90, 892FC707DCE3352CE8ED23ECE989825FDEB32E79C049C2D3 +698D5BA661086278ADD272ED7C87A479B3, B940EA3133CBF5A3E287F71ED5DEF98FB931BC0965BB6B36, D272093C69411C10DA893316831A3DD11D76C441AE0E38D9 +13CA812F32319276A097758C87596ED6D19, C1BF61C85F79B24A7B30240D42A70BE0BE5E7DE6A0563471, DB49E02EC0BB0401BD566B072013552266F518DF05987BE5 +3B5F838D9694B763E1C660A5960C4C8474B, C0ED93B53A193A35D1794337F74C4DD58D8BA88678929E68, 7DE86FD1C4693DC901A7890DECB307F00EF432CD17A9669B +B21E8AA8C3BE262BA55321F0C224E58D5E1, 71E6E0470A2A76566ACFD8C69786213DFC50FF8449FA9D00, 6FF8607F003A90FB76840D8CA367B4612F8A555BA2C7D07B +2165B9FFA4B3A7282EFF965D2466EB0A81A3, 162376F28E53249611556C1ADD58DD15AA66451D49BDB18C, 9A246765E6CA5B19BF853332B39FEC421739DB52703B6513 +64312DFEEE1AF5788CFEC3176D34C11F84E9, 7F3355A10C96EE64DE95CB40F2C16C6A8BD9AB19F243EFAC, E25ED7D4BF395ACE15CA7AD9CCEF8F82C3B8680B40C5AD8B +12C9389FCCA50E069A6FC4946479E435E8EBB, 65801BF19C26F27BE259A68033096C0F21CB908C2BE431F7, 1CBF7FD180A1FA7673BB20DDD3DEAFDD224992B000DAE969 +385BA9DF65EF2A13CF4F4DBD2D6DACA1BAC31, 2434447503C73CBE250329A649A71BF7FB9235B4D7DB5AAE, 4F1E6B3691512BDFD642B837035EC68B3DDAD08306D0E7BC +A912FD9E31CD7E3B6DEDE937884905E530493, ABE1D7C9D4446CAD96B696E129225ABAE79BFF43CBFF4EAF, A07CD0DA6177938D334381A6CAD4FE2A54189E157DBFB657 +1FB38F8DA95687AB249C9BBA698DB11AF90DB9, 45B3A8DF8C53006D2181D52E578502906DCF166E53B2E490, A4C15F301AD5F5B61F603F93230CC3A817C6DC86AB842DBD +5F1AAEA8FC0397016DD5D32F3CA91350EB292B, CA66D4AE5E37980E54A32EC981AD6FB8F130A811DFA9F283, 2E516FD1176602D650B7687449E87127583E18F8E8AD6B67 +11D500BFAF40AC5044981798DB5FB39F2C17B81, 673AE0961D0B12B6526E82EBF3244BD9C392B92D52ADD0B8, 56F605CEAE8E71F28DFDD4CBAC06CAEDC3EFD0F4FF0C7D7B +357F023F0DC204F0CDC846CA921F1ADD8447283, 2BB6D5B9E52B42C17E34205A523FB4596E83B34E653A1B20, A1F89B4682D8A6F1D07F8CA40A456962BFFE0D0322EA5BA1 +A07D06BD29460ED26958D45FB65D50988CD5789, 5C16C7F871FAA2972D6C00EECCE62B9951CCA91CDD44C978, 53379BC875B840940BE2F0BD83C3BE3A4F73898B2D243D72 +1E17714377BD22C773C0A7D1F2317F1C9A68069B, 985E2871102C0F5BFA09E1D16F677E1076123BEA019DFF0F, 3B0EE452994A31EE10E8B76D4F1E5AFBFEBADDA52BFE5238 +5A4653CA673768565B41F775D6947D55CF3813D1, 85A95B40A2408C88065A6B06A2C70C0F3B1016B850B03FA4, E123762ED9FAADDBD571D4D9D55BAC21635B8F23432CCDF7 +10ED2FB5F35A6390311C5E66183BD78016DA83B73, EE9BCE88E1300A048C6EE04BC7C4D6B14F9C46C4E5E0DC5C, 426DD5BCBADB2B5831B05AE0EE36A4357A9CCB975BE6D97F +32C78F21DA0F2AB093551B3248B38680448F8B259, C8F67DBFA81A917ADE5BC7C680466B6C59A0614CE37CC492, BCBC3245DE309B260381C29A51A08FD7AA7A897A57F60C43 +9856AD658E2D8011B9FF5196DA1A9380CDAEA170B, 102F282C7749464D0B5BAFE7862ADB176CF528959E6FF16, 4471B34D0C427D1B2E6BB4D1D1E7019B19FB29AD3508FD55 +1C9040830AA8880352DFDF4C48E4FBA82690BE4521, A9D88CECC8F30E7367B1826614750C5E62DAC63B4EC69F65, 1DD5CE403B28F8E828AD61FBDE8DDB29AB799E322EE5B12C +55B0C1891FF99809F89F9DE4DAAEF2F873B23ACF63, BBD9BD8DB52BC779DED4D10D87F9A51D6F688EF2AB24DA9D, 3B81E803B4947D886C31DE671C257B8D4AAB9703B1425FA7 +10112449B5FECC81DE9DED9AE900CD8E95B16B06E29, 4D17C614554EF49C3ECA4174BA73E5118E5E60AA0A77C63, 7B6297E167ECBFA4B7BD7FEA88BCED0D846FEE03DD3DCE7B +30336CDD21FC65859BD9C8D0BB0268ABC1144114A7B, 14D38246CEFA8D9795894008CA0C0D126F83C78C83DC92BE, 36411B77CECDAE847590B5677F59939973BE6FF2F64A9042 +909A469765F53090D38D5A7231073A03433CC33DF71, BF7AC1EB3E7190BDE4D71ED57DBD52DE03050EFB40CB5EAA, 8FCAFA78361658F188F43142956A156857563AFE6C1EC45 +1B1CED3C631DF91B27AA80F569315AE09C9B649B9E53, F8D28C0DCAE91C461C70A234D69A2538F29308A11DEC6B7E, 81F11659C6F8F433DAF384B0677656D43AA1043655DD8E5D +5156C7B52959EB5176FF82E03B9410A1D5D22DD2DAF9, F730589659E8FEE715F0A3398A547498C858172E776C9E33, 7725C13706670A811F93D5FB0FC7BEDF0D439335D2FBA1B6 +F404571F7C0DC1F464FE88A0B2BC31E58176897890EB, 3B666DA46C5BB9CF8D8444366602DC2C793281C9FFA16E2A, 933B3919778A797358D4F485D911ED7B8C8C3A3C9B782CB9 +2DC0D055E742945DD2EFB99E2183495B084639C69B2C1, 251F31E3F7B52DD8BD58E5D15E5AE490923752672A578D78, B5D6D075DCD78583BE68D8F37C3A4E6BA38C478BEE16E90D +89427101B5C7BD1978CF2CDA6489DC1118D2AD53D1843, EE4089782BEEEA54B8CE2A2165A343D8D1D111F8BEEA6F7A, 29E6B9FE3066CF09CF8227D8E559A072F36B2382FD3BFCA +19BC753052157374C6A6D868F2D9D94334A7807FB748C9, 87E107AD5A9D73AD3575BB56785B149C7C548689290DE1C7, A57878A169EED1B6D2AB99F88716ED86D5FF090D3C72BB96 +4D355F90F6405A5E53F4893AD88D8BC99DF6817F25DA5B, F0209D045652BEC6993A3B280AB6584EE0FA4CDA8451CF67, FB02EC759B638B43CC694F1FFBFE8DA49EA76C2D17A3793C +E7A01EB2E2C10F1AFBDD9BB089A8A35CD9E3847D718F11, FD1E7CF082B2DC167E1428F12735BE092F295A4A8E1E760D, 3544868B55914D92838E1203C31317C641815972FA81212F +2B6E05C18A8432D50F398D3119CF9EA168DAA8D7854AD33, F0DD616A23DA61FFCE001E709706367C9B3E362E741B638F, 23DCED8532944C2CD408745053B4D8566A1222B4FDCF779 +824A11449F8C987F2DACA7934D6EDBE43A8FFA868FE0799, F7477B1F68BC6780620B206B46251DB5BDB3C3DF7E1E27FA, 31BA57AD0B0BF24867480A9F85FBFB9930274616EA260236 +186DE33CDDEA5C97D8905F6B9E84C93ACAFAFEF93AFA16CB, 96AE79EB0A648DAA2EF738CA6A4FD4DD171A20DD0A36E7F5, 1DA556917FD6DDCFC2ACF833D2DD9D5B8071C305EA1FC052 +4949A9B699BF15C789B11E42DB8E5BB060F0FCEBB0EE4461, 94A09B7C63E9B75B117E09E1784125C65B2B67F98D3F46B3, 922B5F92BA51AA72C51FCE3B6FF14ADCE1248EC839984332 +DBDCFD23CD3D41569D135AC892AB131122D2F6C312CACD23, 59777F6D3BB4D0FBB4030BFB59261F24B9057A9DD29BC2C1, 1C450FC266C1A45AE52864DEB7390A2947BF0C5365092D38 +ECC-224 +1, B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21, BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34 +3, DF1B1D66A551D0D31EFF822558B9D2CC75C2180279FE0D08FD896D04, A3F7F03CADD0BE444C0AA56830130DDF77D317344E1AF3591981A925 +9, 2FDCCCFEE720A77EF6CB3BFBB447F9383117E3DAA4A07E36ED15F78D, 371732E4F41BF4F7883035E6A79FCEDC0E196EB07B48171697517463 +1B, 1989153B5F6636B610854BCC50AFC929E914C03DA51A4A8239F4865B, B9381E6DC79B58E0443CDB009164837AD450A68C19192F126542796C +51, F92767380D3731F228A44AA785B413FD807DBB30FD6E11AE45D1EAC1, 82FC1287153C3E5F1CEF13FE31291C43CC54F10169FC9CA22E5083A6 +F3, 9799481F3A9E0297A75E32DFC88512E777EFDC48E977349C4FC68C74, B6E8E987474C0C8D13AF4F7B8AF9A1F27667ABE8D6571E71B7D8359E +2D9, AB94C2D7A56E82D79C168B3DA45E33D72D45A5B25FA4AB096898C10B, 24899FC8552974E40FC2A5EE9690D11BFF96A38D84FC79DEF9EB70DF +88B, 5AF579EAD2DC6E6B52430A2F79A3BCECDC2B9952F353AA12AED13393, 30379F3012A1B94F83C5B4AD6580D7C8D42001FE29FA6D06F4C49C96 +19A1, CDC4EBC6434E16ED2A94AD8FC5325D69EDBA5FC3F94940C37BDFBB93, 6F3DD0D2C4CAAA54DE14DED296B8067EC04F5EE1709C27E90CC4748B +4CE3, 362946F3E1813D4DBADEA15A78CDF4D04B9DD573B8CE48E082DD249E, 4632F24D670E17161BFEB43737A29FA7EC19CAE59C994DDF38341A05 +E6A9, 198F000B110BB2776BE024C515BC56186CAE13FFA1F420EAFB7D1368, D47DE0455E35D402E5E7D7689AF837621F1E5067C7FBF9653D6D47D8 +2B3FB, EAECA0011B1AF3CC2C81C542AB82C18C5046B4DD642091467B05BAD0, 823E2074A55D4ADC32787285F42B9E6186D38428996442042884E2DD +81BF1, 3FA4321CEF75D9C148069871B21E0E7D621C008CC1E3EB41CB63E306, 674C08B2AEC76DB3DF5FA9FC5F8DAB6CAA14C605536B0CBF26E91E17 +1853D3, 750F11C5424EF88D236F8C0B8F3B858568333C2ACF4C17084FBCB243, EF8D1C2B5094B210852D8E751F28E23FAD4DCA26B985E54B527482ED +48FB79, 6129013EA424933A18B3986C9DCC4166C7A1FC13C0022358894D6F3C, 7251B2A84BB265DC493617FD712CB971FE10C6903FEC82CDA8631312 +DAF26B, D82B5F8A652AD0B923557D68CA5CC42CFFBDC73DF3B00AA8F9F3799C, 5EFA86F7149BCD9FF4A5227C1E331487B9149262561A94E635999A6 +290D741, EE88DEB98E68A56E4046566812F68193A1B8856D09CCF33D6EEBC446, FE5E7FE985E2DE483CD0B6481A1A1900CC3DA0567AD7BCB1AE54B597 +7B285C3, CE9184F33548BA664AE32AE3613640988CCAC3A4A6269577040633B2, 6AA351D10075F5FC6BBAB3E1D6592A258CBCB6D1D6C828B880043A8C +17179149, 3D30DC993405651CF936A840EC2758454B71AD7DBFB9EFD3216B46DA, 8F1E7837F24D3E04F734FD6275C252E56B9F61F40056AAC2CDACFC56 +4546B3DB, CD6075F48F57C66341B821BB05D75E8C5F68C0EC9E5C901DB6E16A96, 2ADCB9E834A6536D26C0325D0A9B8A05F32523B77AAECBB39025990D +CFD41B91, E700466493B51C521C4A7DE071BCB89635ADA469B7CCFBAEDE84E6E7, 2DF8808FB469DF1A5762291BD71A6F47D5A87C8F77849443AD08B3F2 +26F7C52B3, 985809BF0BF34DA2C90ABEDDEB5426E779A05144C233715EA2F1E2C8, B42E15230584FACC51355E602CB536A89EBDE854C1B411313DB3292F +74E74F819, F4183C3B4AA8694A581F6FFC811E8FA2973DB1CA2721C1771DF7B741, 981354E9716A0B3CBB78959211642C5AFE7DB94E7D874B716EDC96D3 +15EB5EE84B, C90D782309B6C358C6A040936A326BC4FBDDD5A3016CD04949F64941, 4C08C351A44BEB5608AC72E9CFEC3BF6D63DDC289023E067870058F2 +41C21CB8E1, F15788A0BBD53A46BAE249FE197DD5DD6FE0E8A0FAAAF9F31DFE0C95, 11F66BEB06E4DCB13B97EB80D31402734EF078D341522662458D33F1 +C546562AA3, FE978F3F57441E1E0999BB12CC774E32D9C8928EE7FF589D21CD90C3, 9E7ECD938870A5E3AABAE92FA7535707777D9D80F9A14DDB31042A50 +24FD3027FE9, AFD87F62D228450B96109E5206CC0553D9DD8760A9FF052B23095339, 56F145952A468E31AB06CACFC7850EFFEFEB6DA967FD39C4FD8C89BA +6EF79077FBB, 5ED036592516527B62775793FF08D45400E50F198583F29BCF6A33E6, 2B9073611B24F7CA6255B95BCCE19A3D9554AD10C7F188F78DF5065C +14CE6B167F31, 60A0A5676AABAAFAD67595EED957F060A8D9342985CB607BA210DBB3, 3AB05338FA134C4978673E91D790E6F5ED28A46DA9433DABEE72024D +3E6B41437D93, BA33BE7DEF4864D1D40DB7E258658258E04AD1D1221909B5BCDEB9ED, 96DA7AD512B69C87A3FF6AF89C146C73612C8FA17DA6FC39ECC2C000 +BB41C3CA78B9, 56591F0AD7964EB69D2C422C7009014FAF45D3C4FC4DFFB66170DF72, AA3DCF0450F22193AA586D18090DE2C2DC456E7017701C79EDCD4BA +231C54B5F6A2B, D4423739B5D2E81AB85B2D9F9BFFFA4D9E2E97238642A1C2A5FCA5B2, 281817D29BCFB1677208EA276B4AAAA031017C252E3D7429604744B2 +6954FE21E3E81, 2FE618ABCD354D14D175B89C2FA8727F754ED05408F8EC953D7A029C, 8A0F74A70F6BFEEA4825AC6D4940709E38A9D241B9B67BC15C1329D1 +13BFEFA65ABB83, 1E79CFBD171425E53246D1649632EA82320D09D104541BF644B43276, FC4265BD80FB46A4694E221E04EF6CE85F2F349476351FBBCF098B77 +3B3FCEF3103289, 2531CC4E788EEE33FF40F03E63FEF997D7BE20AD5AADC02DF93AEE42, A738D399C5B3538219E2121714A316F427B2555F7899F40A6AD899EC +B1BF6CD930979B, A5AC42D6345A9D75DCBC35F3E9895D953EF7D15B54359DF6BCA1D15C, D55EAD112488C576C751C832176EC7AFDD7D31440BCEA86B93345155 +2153E468B91C6D1, 6302D07975E9BC0E0C794DD36ABC39B153DFE291C8C1731DE4A73926, 6032CC140FAC1603602354F3FF99F60FACFFBBD4393B24EA0601A407 +63FBAD3A2B55473, 1FE003B196E5F0BFB88AA343D5919E7C5E19026956DFAEFF10B41D6, 624EB829116A336D847259F80EC45B6B1D644C1F5D8DDC83404D35BF +12BF307AE81FFD59, 907A212C20C70A7E53A9340330BC05493DD188A7CFEE5FA372889778, C3A13E3D77F269C67C6543678E61A35F392DA85F49B992105350D00 +383D9170B85FF80B, DB42BDBE076F7E75C34C2B927E73EC709265995BC4512A7E6F04C132, AE2A41EE109CBCA26E318A18003E2D7D1B557ACC196244CB175DD865 +A8B8B452291FE821, 17F0BAF1779E31ECAE02C138D69109CAA1EBE101F9AD91D825E1D3D5, 24B76AC081C96497AA7B8CDF614E5A5AA53FB53F1D93369B9DA8190E +1FA2A1CF67B5FB863, DEC95AF67977A90F2C831F822A9883FDD3B119C9CCC552E714907F21, B161B842051D2CD8582CF365E5F919411C9E27ECDB896BA6DA21DFEE +5EE7E56E3721F2929, D34CB5030D6158A0BDA99A9AC40235591C0409BECE4A28AA7E989128, 78D670AF8D31D053B53F67854B7755F38CDA6731145F89378E2EDD12 +11CB7B04AA565D7B7B, 806023F600D2D35B2B9DA9BE107802FBD9B04F4FB569055885F84174, 8463DB49296E86750888E06353ED42732C95F5C61AA4696508F9BAB2 +3562710DFF03187271, 24F8274CA5282CD9FD95B53022F5CD1B878ADDED1D7A3DCF46D25786, B0485DAE467D6795EC97DE1FB4487FC2112D5798B77605E5C8D3F77F +A0275329FD09495753, E7D0B41DD20AF5A36176BCC234AEE25FE7F9A12360E62043F11FF2AF, 982BDB1CA14088CF6A80E3A9CD5F329A8CED5AFAD519FFD7A7CB3DAE +1E075F97DF71BDC05F9, 418DD0F298DD0261802CDE28BCE840A007E09CFCFE85F518F7AE4C7A, 766C0AB7B8D4B2351F72A927583A927A46546931BDF66E9D53E7913 +5A161EC79E5539411EB, 26D81F8AAF392DF2216B68C2125115B3AED117A4F20588A13C2D1EE6, BF9575307370151F7F217482C63851895CDA7DF49B406AD83449C633 +10E425C56DAFFABC35C1, 2A2BDAB9F1E3426526EA8A02EDB7504793A023A7B94F1750A35F1290, 46FA41933EA40F859D230D2AF76D309F4B42831964131DA7879AFFAA +32AC7150490FF034A143, F8BC0F7FB724B0E98068DC7C649C86439D9A0CA110D70534C249A957, 567D9D1611222829F765E233F2865CA765C533A75DF52A8CA6E2EE42 +980553F0DB2FD09DE3C9, 3E52D85CBBE66635CEBEC93FFDF099863AC3532248828404C4488A66, 6E32E7FDBA3D4121370E6E7419258EF83434AD93AB0BC2C42ABDD324 +1C80FFBD2918F71D9AB5B, 6B1FF073A3CD8A64AE76CC428B83D25B9DAA0D80830E98B8D30B1AD8, 5D88EC8A26D1CE0065466721A5EBD21983E5212CE7CE0E86412CC4CF +5582FF377B4AE558D0211, F866E3EF3FA7E04BDAEDE69793A48B1A11F184007E2E8BF3E7B0B13F, 89CBCADC39970CDFC908391FC332BE45AB7040C154908B1FA9363E41 +10088FDA671E0B00A70633, 27088BE15042726C5934504CC097EDB828B808E274382184A04865FC, 7E28842B3D3B141A8FAFF4EC5FB4523A817F533BA3878BF62DE490D2 +3019AF8F355A2101F51299, 7612A5EF2A4FE2ACC965E9EA98C980414008820044C8D2494A6E48A1, 804F8875E4FD670460E6E8774E3F8EA7ABE132EB4F8538C0F263E753 +904D0EADA00E6305DF37CB, A2E07EB44A40264D8CFA93118985E2AA715D9834A7A2FCA5337105AB, 82EE99285D88747C9A969C03DD91F97749A795556206937E02EB7070 +1B0E72C08E02B29119DA761, D130DBB6587C74D79A7B2C25467D87D63290201BC142A26A3F7729F8, 593F7B51E5DE8439291758949A287941E2D0C9C16D257B50E59E5657 +512B5841AA0817B34D8F623, 4DB182A30BBE6B0F0C1733FEC0EDCF0F29F6FF3C3224EF165B40135F, 2F1B284FB92E47C7BBE9C49B99A6E63E95A929A2043A3AD156A831C8 +F38208C4FE184719E8AE269, 91507DC0D051315B394C9D8868B523C1580CA006D12AF7A59B742595, 8C35E6ABDEA10E34147ABDD51A338D043A7DE36C66CCEFAE82388521 +2DA861A4EFA48D54DBA0A73B, C869E191772D7416E0854FC627CD4D52C8E1DC706368EDED86C0A5C9, 1958DB34382603897FA5DBB481AB9491B0B4563D9411707DB27E75DB +88F924EECEEDA7FE92E1F5B1, D74520FAD09C24D7C8229D21268D9F796CE671646C7A1F663112E3D7, A39D0856AB0790FC41750BF4B44470685847810C591E9C65497A7003 +19AEB6ECC6CC8F7FBB8A5E113, 6A854252F1E6A0B376BEDAE354AF23012963364589417EE9A0E0C8C5, A8DBF75C9AE8108AEA6407839DB057455E75EFF24B126782DBF17E71 +4D0C24C65465AE7F329F1A339, A7BE78954E6711850881AAEF30A804E95091F4ACE0A451C4EFBBFCC4, AE45F4111709124C24656B5D9A00A2EC632DD1F9E0D19B7C4C74E2BD +E7246E52FD310B7D97DD4E9AB, BB6BF6D52101D7171692B076718926024949B2FC1CACC4C217E22A49, F4E2E945D6A047AA3C19E8AAC06704D6E6A3E6597C965222EF146060 +2B56D4AF8F7932278C797EBD01, FDCAC4F59249609AD294C519C8AC53DE2F000BED9FC04C4C6B8F2B72, 3D2E5C42C563572BC901E922FBEAB3F05362F30FB064927C9F12B6CE +82047E0EAE6B9676A56C7C3703, 78841771E59617F86F26F54E29FB34D0BBBADBE036332D95CDCF99EE, 4301EE6FAB7416ACC553C2717D7CD36D5545F1BBFCC3D9D1AC99CF73 +1860D7A2C0B42C363F04574A509, 34F8CD3C4075CC243E90AD791FCAD0863A0B8780E807349CB95F8356, 66FF86AB3C4FE675957707DDE054751EC4F630313DA1D3EC3248599E +492286E8421C84A2BD0D05DEF1B, C063400A25BC0F494FC7C150ACAB7A62B117A708E912C1898BECF607, 4EA8F6FBB32B3E8919891173164A63BF8B8FB964E0B004E56379E049 +DB6794B8C6558DE83727119CD51, 1C9455B676487BAA9275CF474F25B77C05CD1CEBBA5E83B72E84F8C5, F771F0402BCD3FBE57BA3155E76AF6F1EF4895C072F27575EA674B38 +29236BE2A5300A9B8A57534D67F3, 3E246D1BEAD5B9A65A6462B144D74E9EC9060D5CBDF7199D0271D3BB, 4D96FBC404BB208D2283DCB44F907E563C3725550EC601D11464C4CF +7B6A43A7EF901FD29F05F9E837D9, 44809885890A682AA2E5A3E36DF30F49650E53597A90EDE162E0A663, 32F2EFA01F22C2F5C35E715BCFCCEE8A1D054E31D6BA67E6F66B51D2 +1723ECAF7CEB05F77DD11EDB8A78B, 1ED9A1DA3FF1D896E53DA5AE2D1ABB5531F29D8AECE017EC27333099, 810A5D32B852640F61043D8905CC49F6B9E5E1A8675E114DBD10E28 +456BC60E76C111E679735C929F6A1, 963BC62E52F3E9089A4CFAE8889AC36C02CA5CA870255BBA41D80992, 8283036EC72E77656965A322EAE1835DEFE81BC2BB606BE039AA08B1 +D043522B644335B36C5A15B7DE3E3, 59513B27D32F5487E7BC263CA8163825CA301AD4FCD2AF6BC38CD8A0, 86F10C63D8DDF602FC5FD1FF212BD6018FD8E84EE2DD8AF699030FDD +270C9F6822CC9A11A450E41279ABA9, A6FDB2969639E579FC432045414BE41C70DDA2E08F038A0A5BB42AE3, 676F76DBF44A80DBE674C97E925AD073A225ADED52A66EAD1743E349 +7525DE386865CE34ECF2AC376D02FB, AE3C55F9F92AF86E2E24690093279721BA8BC470C0BB30629DE7A830, B89FD0207A227000BB68B30CB54E30F4FB91D5530153B82D52EC8688 +15F719AA939316A9EC6D804A64708F1, 340E2C333CBC4F554A9D395F81FDC65134504DD940C5C169096B2E6B, E46482D2ACFC6B7DD12794118B3FB4844702E6AD410EBB2572D70C2D +41E54CFFBAB943FDC54880DF2D51AD3, 3DBC30E4C85CB76E7AB13CE933C124BBCE4780ED0E5DD209EF3E0D79, 2436FD101DB483C4A9AED4CA46524814763E33DF799594196FBD5FF0 +C5AFE6FF302BCBF94FD9829D87F5079, 8D232E2CC2BFD2ABF2381EBDF8E2F208EB7221D6051AA3F848BAD7AA, 84379CACC97CB4CC3E038F03F9C3E39A95B2692EF3207992F6BC5A71 +2510FB4FD908363EBEF8C87D897DF16B, 474E806113EBED5D3207F369B9025C92E5781882FD8283DC156FEC94, 92C1255A2357F57D2033F648A07CB8BF6ED976DF92723F83C1742C68 +6F32F1EF8B18A2BC3CEA59789C79D441, EEFFEB6E96579EABA84813CE7D7D8684BC4526783BB99D766412C93F, 7A882D966C41A7776DE16D83627BF26E6AA2438AAAC509ECB59FC188 +14D98D5CEA149E834B6BF0C69D56D7CC3, B6D1C744E5F1B500F7C00FA3ACD776A4D4FDA70A1AD6FF2A28CB5440, B6B1B53BDCF1D5C3388C7B9E89D13B317935DE42E0EA796DB4CD4F95 +3E8CA816BE3DDB89E243D253D80487649, 565A2413DAA241BD78E000D4514586C32A3618B0540EA46E6E404DA1, CE6054C367C0108D3AE4BA143353D0E88B48507206BF70928F2D612C +BBA5F8443AB9929DA6CB76FB880D962DB, FDDB75542EC1312CE37D27C86B713322E71DBD862F7C32225A3A1ABC, F89EE7A1D1C4E4E211A7080BDEC6A5921C285ACBA7F6971C031F1387 +232F1E8CCB02CB7D8F46264F29828C2891, 13957BFCE2EF1DA3867BFE22E31E40720E4D4A58803579FF12CF72FE, B82DE7FAA2528B4A77D62559ECFD2322A4FBE18EE5113D1E43C24D85 +698D5BA661086278ADD272ED7C87A479B3, 860F61F11AF83C2D6B66DA9D942C2E5BF6B315983A58FE19F3827010, 1A6894B0D572A2D5940F2CE046AB40334FC1145DBC8E2DD87FD1E33B +13CA812F32319276A097758C87596ED6D19, C7C67E5E063741E3906B13E7C7D165C8F16D90B837B5294ABB02CA3E, 91394812FD3A35E358B2864C9E9AAE270F948390B3B1B9FFF5D2352C +3B5F838D9694B763E1C660A5960C4C8474B, 8E0628DC2359649255B2FB0BCD820AA5EF46D52FCD4FA9C6D2935704, 815596DDA0D138F90381FC63591F92F6D0ED19028DD6457B8D56B988 +B21E8AA8C3BE262BA55321F0C224E58D5E1, 79C4ADB605F9C0B34F52281817969775FFD63F36B4F696B06790E61F, 22171C082EAE8EE539438A3DEE8404A94A1737F08645403FB32D76FF +2165B9FFA4B3A7282EFF965D2466EB0A81A3, 83E2B541F70B5F49DF385A40E91EEDB42430A123C73BD71573C4AD68, 471064372661A3CE3FD801604676413F29F37E5A076F307D685F8627 +64312DFEEE1AF5788CFEC3176D34C11F84E9, 7E4C45B94EAAC7A463DF23F5D330F9B7D7A130CAF6D9AE253015054C, 4DB6EDDED348A8E3E3260EB7D6A702A7E9DD3706C3EC4001AE1A1304 +12C9389FCCA50E069A6FC4946479E435E8EBB, 5B0E2714AB739379A642EBBB6DF9A42FF8BF3AA08DF2C874E340AD12, D13787A422669EA964C6E694C3E6A2FED4A5BBC54BF7EB6E5CFF54FC +385BA9DF65EF2A13CF4F4DBD2D6DACA1BAC31, 835CEDB242D2FCE30CC25ED413002AF81CA3BE6694BB2740D2C7AFE6, F4F2FA5A1390F06C10373CEE927A2753AD4E6E76E16E82419936FA5C +A912FD9E31CD7E3B6DEDE937884905E530493, CE8ACEA7322FCB9D00F72613D70EECF3634C18CB7CDB86B85DF25B16, F8D7423C003EBEDD38FD283A4581B016554B3B6F19C7A3B21F1B5F49 +1FB38F8DA95687AB249C9BBA698DB11AF90DB9, A5388908704BD7037303452C9CD652B019B90B9102E34C62995109E2, 57B7FBDC820539E6975600AA55C452180385AB6CDB9FA9CCCB39D5B +5F1AAEA8FC0397016DD5D32F3CA91350EB292B, 1846C2A8382CA7D35AE259A5F991765B0FFE6863984CFCB9C5E3F18D, 9217BB8675E5AA70DDC907F9E7B3704D6F7CA78E7AAFA78F4BD3D326 +11D500BFAF40AC5044981798DB5FB39F2C17B81, 4AB209E645972B5875BC6FB67F451B89E1D0E9982FBADEE7F8AE9AE7, E5108B1082281FF1B7E1C00A0AFA7925469B765385B039CF0ACA4A8 +357F023F0DC204F0CDC846CA921F1ADD8447283, 4938C6436695D4BD1BF9390F81C74F9C3F409D29CE8D1C724B1D93AB, AEA0DF59B29A08951F32001E0EC78B67E8BD026B0B0A5E5E8B67A67A +A07D06BD29460ED26958D45FB65D50988CD5789, 513B8E07F4F315E84EDD6AA65D8EC03DF324D3FF8CACDAF578C19BD8, 171A0D3BB9031D3B1A3F395A89BADE2C015FB77FE2F720627913DE5B +1E17714377BD22C773C0A7D1F2317F1C9A68069B, E85227C4F5C7049F7A3E2D1AF6F809D4DD4060586A7DCD8A9632E30D, C50E343E07A9B62BC3F90F568BDBB438119AF291F784F3CF94170B32 +5A4653CA673768565B41F775D6947D55CF3813D1, 5004F41DC75A5100D0C4C94B5F4ABDC830BB70D8A3EF8BA80F8B0106, D01D936E9B1275413D6F5A3AE69C53337F92A9999AC6A174D4BB7BDD +10ED2FB5F35A6390311C5E66183BD78016DA83B73, DA08B4FA25D8EFDAA21CB16AF0BCCC5A1FB84F36B04F01F9ABF7A466, EF5FD5BCA10427BC9E9EB97FE64B52538BD2A42767EE24E28D998F79 +32C78F21DA0F2AB093551B3248B38680448F8B259, 5A3D7E4FF4ACB9E2E42E291CB0A00055E8D564656BF80140A69AC7CD, D44465AB9889071B964EA9D6DD2293C2FD5DEC5F2DA19647E2ADDEC9 +9856AD658E2D8011B9FF5196DA1A9380CDAEA170B, F426C8B26E65590D7E482ED14E0A753A04F748E6CA68A95B109422, AA91BC40AF7E2DB5310AE16A791546327B3F65C6BE9D0D48ADC16B2C +1C9040830AA8880352DFDF4C48E4FBA82690BE4521, F871C97FA218C2B9A246DB1C983950E8ED2A5C1F780D1BA90DCF6D30, 596300CFDC1B550F7AD7073FD71DE02CD7187A9B55E4695364534EF2 +55B0C1891FF99809F89F9DE4DAAEF2F873B23ACF63, D6BD9CE76DB2389E2A9F0282FE09650599A0EDABEFAF94D680041035, FA546DEEFED7B001A773FABCA8FE96217409BD2417D0B3AFDCF9A622 +10112449B5FECC81DE9DED9AE900CD8E95B16B06E29, 5DC7A99F493CA394F30A83B8C3EFBB4ACEDEEA32742791B6E4D96D06, 54B0AE3E89CFDF50F2673CBAED1A2E51FC3AA88D231CD755F3E865F4 +30336CDD21FC65859BD9C8D0BB0268ABC1144114A7B, 3B704A574160450486E281407FCB9F385887E9CED024E0772D956F7F, 7867D7C0F8A58BA59B9ED64300AC618A35D112D7D02EC6630CCF8112 +909A469765F53090D38D5A7231073A03433CC33DF71, EB275092513826241ADD2027C318622FCB610FC48886B0C053F66B9C, 4752DAC073728D4B3E12A23393640A0F38A1ABA1FE514AA952B071ED +1B1CED3C631DF91B27AA80F569315AE09C9B649B9E53, F3A80BEC6326399E5D846455D2AB4D26F80A5467A344B6E53DB51308, A2DEFFF968EB3D918D3348639CD9DFB31DF0A3BFEB8B0C6D68132B2 +5156C7B52959EB5176FF82E03B9410A1D5D22DD2DAF9, 5198983342D72EA3323004852DBE34D2D19BC0666746CD4DBA5BB4A0, D43596CE581C07801F494EB0D2176A71076C5C560039CE26FB2BD990 +F404571F7C0DC1F464FE88A0B2BC31E58176897890EB, ABAFB40DB81416834897227A8062CDB4006F8A2376BC5309787049A7, 31EA667608996EEC5BDA680378000F7246E3728F8F6CEC7989B72F40 +2DC0D055E742945DD2EFB99E2183495B084639C69B2C1, 49AD83CFEB347D0B79D44A50F4EC30D4E50EBE9CBC15208EC8A75E2F, E37F7E851E485A9265037E548F318D689E8213D76258FAF7B70C5179 +89427101B5C7BD1978CF2CDA6489DC1118D2AD53D1843, 84392061F665B5AF5AF5D40C958CA52289AD4F17212C7E25103EFE8E, CFBA07E2045F60399D7E4B11EC70C2ECB1B5EB26EE1557D28D54A5AA +19BC753052157374C6A6D868F2D9D94334A7807FB748C9, 751E83A6AF15280FC00AE31EA3B3607AC9CC25462E8CCF6CCC13C691, 9DB6DBC34AC49A3D0861AFD9C441A1BC177BBC617D470D48C3F5344E +4D355F90F6405A5E53F4893AD88D8BC99DF6817F25DA5B, 646DFFBAD04916E629FF52412143CCFB2EE3A66388BE2F784A67633B, 66D781B41F6D348179275BDC06D41DBC6E8592CC4AB489D246752E0 +E7A01EB2E2C10F1AFBDD9BB089A8A35CD9E3847D718F11, 64CF8470EB59EAB6FEBF0FF401D163EED509CC225A11759D893EB01A, E239DCD5315AC07B34C598E164C23A022660D6B943402173A3E0D85D +2B6E05C18A8432D50F398D3119CF9EA168DAA8D7854AD33, 56FEDA7F730804922645928C5EC38B358B16F5B37F07562CA988FCFB, 3EDCD377E4B203D860DD24FE73D18CA02501FE8F1B9E14EF817D53E +824A11449F8C987F2DACA7934D6EDBE43A8FFA868FE0799, 603959E0F53EDF19D13140C404E972C587A34BC7DAC54863BE600240, 5A729278913677FB173E9F33F4C6B5F2D4F23DB09CB1A491419B46BE +186DE33CDDEA5C97D8905F6B9E84C93ACAFAFEF93AFA16CB, C0BD22730FD9CB9CE51E73FB04300214B11D028EA97FCA25630329B4, 400029E2F127F00EE09724769AD4EA2F0219334A865C466FB686B120 +4949A9B699BF15C789B11E42DB8E5BB060F0FCEBB0EE4461, 8928662533735CC4D2294BB65D62C9348DC54860651C5D8ECE9CC4A2, CF38DB1A99A04631C3EB3D91B75D324B7EC158898847C8E97D0D1CEF +DBDCFD23CD3D41569D135AC892AB131122D2F6C312CACD23, E31F70D450B1C4D908D42FF14ECC288401B4B2351E09039AAC06760B, C05385585CC321BFE1E9CEE4B724B27A1A44073047B2DB23218B8D89 +29396F76B67B7C403D73A1059B80139336878E44938606769, 540CE2017428F8F2C685D3E026400B8B7F85A9111AEB1C7E732EEDCA, 3FAC5B38F1425C92BF205C5807EF49B0E18407015BC8CB8E48BCD654 +7BAC4E64237274C0B85AE310D2803AB9A396AACDBA921363B, D6DEF929A63BC8925B4A4E63173BD90662A8F7FB9D88B4270DE2CE69, 9F4EA22418479B10B4755E8FE107D8ED866CE49DB22A1ACE76718996 +17304EB2C6A575E422910A9327780B02CEAC400692FB63A2B1, BB4670CE0329AFF79258EF269A7BCC959D87DFE80BDCE8BA6459936F, BBA1D31C04E781A900AA8BAF2988D34F340973192F981CD1E83B4564 +4590EC1853F061AC67B31FB9766821086C04C013B8F22AE813, 45E6B1674732B7D2338DD56A0ABD9B3D9A9A59D86BD455DC7FF9616F, A2B85EC52F699E000507B6C8B4660AF31CCB90CE106AF94CCC78BF78 +D0B2C448FBD1250537195F2C63386319440E403B2AD680B839, B837F43BE73BC0B560801DE91A7D47A558D25FB1E4FDAD26357CEB8C, 6789EEDD114F7A3A1B18C5737DF2BCB1FB9EF1996B5DD03EAEB9F10F +272184CDAF3736F0FA54C1D8529A9294BCC2AC0B180838228AB, C8B5377944667B0C017AB22CCC734EF549632F406104D3C1D2FB19D0, 805A0F9CBB7765A78AEDB87FE42AEA6E360C37A4116DDF9BB8329954 +75648E690DA5A4D2EEFE4588F7CFB7BE364804214818A867A01, 4F400F7A8721EF9FC9CE4AD8A8068F74B51B197400AB38B4D10E6C87, 5F9423C807D049F2FE86443FE8F0C6F1A1F656F3D35CA7106D74F8C3 +1602DAB3B28F0EE78CCFAD09AE76F273AA2D80C63D849F936E03, 838D9F9EA47C47AE25896303825C31C1ECA75F22A8D3165BA1B4F090, 9ABD33EC035B387A845CE11E42EFF71C8742DB5EFC4C61B201A96599 +4208901B17AD2CB6A66F071D0B64D75AFE888252B88DDEBA4A09, 9B589D1A1534080FD91DF288F0D88C927D27557FD0A1C6F196A9E3BA, E70E4D2B95236DD2B6573945FFEDAB3C02179D2940B75335444E72BE +C619B05147078623F34D1557222E8610FB9986F829A99C2EDE1B, B60C05EC716F5B18362AEFB4BF529146EB2A3C2F2946FCA74078181A, 98F6988C710D73932AB7F72AD0D91CC7D7EE23DED80CA0C582F473B4 +2524D10F3D516926BD9E74005668B9232F2CC94E87CFCD48C9A51, B1130EAE2B5733BE78E54DC9070BD3ADA67EB19421C9FC19563D2EA7, EA34001A4E9751C94446E85701671D73C8B668E67F950B25660016DF +6F6E732DB7F43B7438DB5C01033A2B698D865BEB976F67DA5CEF3, C91E72D890018B343D3D6D90572BB75000B26EEA1DDEF16709C84F1, E8530B7143DD8E828E10A06135C12CD002E5EFB35F5D9DFCDD636320 +14E4B598927DCB25CAA92140309AE823CA89313C2C64E378F16CD9, 496C1AFC7DCC2F878B24443D4250EE53A2E576FA8DF2DA47AF4136B4, 34B68FA994B037B5DD758CDCF737AC97DAF04C8C6FACA4A036EF6935 +3EAE20C9B77961715FFB63C091D0B86B5F9B93B4852EAA6AD4468B, D92253DC324640172F572A67CB7FDFA2FDAE009020E36F59673CF795, 713535A0A4F70093D3668264512A154FB47A6E63883ECD4627532486 +BC0A625D266C24541FF22B41B57229421ED2BB1D8F8BFF407CD3A1, 9829981ABC910F195474EBA80C8105570E7062D5CA2F698180896058, 2471A6945484D09320F925B9666DCED662FBD278480935075B1080BD +2341F271773446CFC5FD681C520567BC65C783158AEA3FDC1767AE3, E738FA89F04B3B264E3D9148659F8E89FADA75CA07EF94D99E5E4049, 8D7189B1F1E7121972AEF7EDD22F646973F77B7FA2E9BD9642C974C7 +69C5D754659CD46F51F83854F610373531568940A0BEBF9446370A9, B3FC9DE2B39001A55875256F0D573F47E1178870A2EA8749E5F6B0DE, 175F7C353FC68068FB501F3F6A0E6B104322E6430E14B46B3623DBDB +13D5185FD30D67D4DF5E8A8FEE230A59F94039BC1E23C3EBCD2A51FB, 832264CDA085803F497645A5841F9E4AECFAEBB1B91068D05C20D2A8, B0032AE2BE48983FD9696331C744ADC95D2A706D97CE5F6CCC8016C +3B7F491F7928377E9E1B9FAFCA691F0DEBC0AD345A6B4BC3677EF5F1, FD00B3858B888CA0E7A44E42656765F775A748BD75E1E3C6D6555D7F, A6E710390E0AD2AF144746F59758C92C08A9F4B666879B795E9AC9E4 +B27DDB5E6B78A67BDA52DF0F5F3B5D29C342079D0F41E34A367CE1D3, 23B97099A944244533AC76542AB9A004274ACC5ECC9819474681C068, E3C1C5EB1806DA05C3F40EE0296991D5F9019CA998F70E4509EACA4C +ECC-256 +1, 6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296, 4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5 +3, 5ECBE4D1A6330A44C8F7EF951D4BF165E6C6B721EFADA985FB41661BC6E7FD6C, 8734640C4998FF7E374B06CE1A64A2ECD82AB036384FB83D9A79B127A27D5032 +9, EA68D7B6FEDF0B71878938D51D71F8729E0ACB8C2C6DF8B3D79E8A4B90949EE0, 2A2744C972C9FCE787014A964A8EA0C84D714FEAA4DE823FE85A224A4DD048FA +1B, 184FFA5819D80D51DEBA2FAC4611F378576355BD683E54ABF2E201173B0883D1, C0A66E276688F359A4C6D90826CB999545BDECCC63F0491620D242C260906E6F +51, D829AB2D2EED358C8464C3093DC72E911E2A1B96700BB9B12CDCF0C2A8A3B072, 3EC1BBE459CAE899E1F6C7BE2A598059166273E2D406AAF7CF3BC0B0B543775E +F3, A392B26B0503A71F0CE1E02ACADF19D72A84D6211B21C914EE8BC58DFEA92529, 90BB3C9F9F1B598B6F97AED2C48F4C59F12194D8EB011465FF88E7560D1C5493 +2D9, 78D56FA935996DDB7565CD320D2F264F5305BE551F411D49CE17944BBD8009CF, DC5B53BB32F4D146A93A6DDE353B6E25A9FCAFC7A5DE15E01F7746239B88C07F +88B, 51E39E9F111A1FFC74D63499CF065324B86A479BC0FBB3DB0EBB77E95DFA86A1, 8C945F778CDEDCD2DE6D7768005041FFB91C6BC2DA656C104373132AB0C9102D +19A1, 9EE8C552F615C8D0E86A7B983EF37F69BF5906DE3ABB7584493EC15E8C803EF7, 2B0363927BEC85207FFAFF4FA95C20BCF723AEB67862C5EB892A726A41500A27 +4CE3, B97B92F86F23855AE92E8578B23FB85128CE00A4428EE1FD91ABFB48316FEA58, 77DA430A9B98E46C9EBC9F627F507467D05CB06172EDE14FA580CA2782184805 +E6A9, 82D3B3A3A5C7E5B34187CDC1AA0FA9FF0E8AD81F269EBE2A079A1CF9837C0794, 8413A7951DAB0CDB00C790192CE9D7FC142AC2E8BDBCBC37671764B264087D8D +2B3FB, 84D845BDA10BD468A270B290020C440958F2CBA1345F77097590E4F0982C5A97, 952F9B537E6E32499A76AF3432CF0B47C9EF5DE39E7EB8B5D5355C30BE1CFCC7 +81BF1, 48FB22AC3EA85118E91EB21C22CD06C0E9AFF19DB827439BE275553C1232DBC4, C1F09255BE08A671628A64F25A2B562618F0014DD092BBC12FC2FF8A3E59BF6F +1853D3, D547A583C479BDBF65D90A6ABACBE47B2ED9BD5DDB848DAEFC3ADA9F045F8DF5, 7A7E2AA0AFC241FF6B254CB58B36125B87E560AD50B469E562CEEAA1BC626C39 +48FB79, 26A141A8ACBB471D3F3BDFEE5889D101F5F244A1ADA073A28A1ABE4D66AFACDC, DD5E7A714BAEF3F3D20947A3EDB6C9A11D221344B572EB75F075DF225514AE4 +DAF26B, EE8A3A9A685BC75A6A6329537AB447B4EBEFC93DEEE05D92D5481BC5FA2DD2D4, 11C6F3406FC0871FA80021D28B9252BA2A4401CC6DE5DD887E1C102F89194236 +290D741, 6777D49BC45F54537A46598C9EF93D4A260CB2E223883131F90EC013AFC3CA9C, 1B309AD15E576A8F6AFACCC30E14BA222C8278D5942B1D3C4D5F3B2E926E9D8 +7B285C3, 1C38CDF2246338A098DB0E2B0E438FDBC1C9E598BE6B661AB5413D7AAC7365D1, 965E5C9AD86C0BD83BB0EB34F4742D02B4C12372661A5A7792FEDE41A036363B +17179149, 2E1F9230C1189F7303AE23F85A4DEC206FCB2C9B9DAABE775D4350759887E3E7, 853E17E5254608B15FF68DCCE6DD47F5206AD0545A70B0BB8E38AF816D9CF154 +4546B3DB, 6DD8BDFAF3A6ED8A97C35E0B8C0889A45232E5ED8DB12BC03C18B5CEA4D146B1, BDAB741CDD72401A40D3FF40F2FB6C8D49AEDBE01AC8221DA68D922E4EFBF0CD +CFD41B91, F11C444EF887CA44ED031DDCEC54AB09CA839113B84DA5478F5990CFDC4A280A, AC2D493266FC8E5814994EF40C6612D15B8A5FA6435C4499A1ECA1783448EE4 +26F7C52B3, 4CFB521D25D4841B3B3AEA60BF54890744FB04AD389D90751CAB408870AA96E7, 63FF30C411688891F322842464D50CEAB09508CDFFB2518613D07493A68E7D53 +74E74F819, E33DFB2BEBEA0F89F7B24E912C309F1BD2201385E7195A7F86EE8D827D252C48, CF788477541A99C605A5A49A445AE2DC83D332CC2E25C00E8DA74DA1816602B3 +15EB5EE84B, B6F05F7350F984E483866624FD32F344571505D798AF01C76B0037A161898402, BEC64BB72514F0302CD84ADD7F8B839914D169F32C4D7DD7E75BDE14610EFEA3 +41C21CB8E1, E4BE38E3A719C76CBE660756EEDCE585E836F79C252F14ACBC347D1F2B005D03, 6F69C0A3DCD5F48BE6EDF0D787AF6C985591C93FBA8E9844B2E2BA83937A3F06 +C546562AA3, BE14B442FE165FE657CFC0CA8A1A765FAB5D14F96988FD02336F03B96686FD3E, E6E8020E81856E788370FACA0708AFF83831A25F751A8F192BB13B9039338DBC +24FD3027FE9, FFACC9CB1F8FEDC112BE4EBF255956A8C8770686D236862AD1AA51C655A8D6E3, 8301B27043EF5D774421E58E3160AC2B82DF8FEE0C97E0A7D2C3499D1C2D1B91 +6EF79077FBB, B192264B1A443E9AFB9CF79B1ACB997B6664A92AE1B8C84FBEA2FAF6E9FB1841, D499FB416CB4709AF072C78A4CD5ADD0926BE45964F09A37E9B3605B15F62F27 +14CE6B167F31, D4C9949DB9AC21F126575255AF2E99EAA6EC3E2C9658D572594445699B0A811F, 6C88B1474CD419D6D7725FEB2EAB9E0F007DC873F12B11484A06433AFA0ABD54 +3E6B41437D93, 5B582B68144EEB9B4921D698129CC87D4DB79A8057E1DFDF87031FB59617C6EF, 43E9A8B669B41532768550B6FE7885F5E75B114D9802A777A9D6C27224C8F361 +BB41C3CA78B9, CC026A9D0A728EC8994DCBAF79F3CA6BD3A935AD808C606886BD333B031940F0, A44C9033F98079E7F2621A921BDF565C861C125A8E6A977F1847B90F34A0495F +231C54B5F6A2B, B4D0291977B7338239B0087DA7205FEE91AFE4E9502AF60A686F0A4ED6E898D4, EAA998CDC7F5BA3ADA9B4FD1F031C0439B1901FD7839C4E6C57D34981598817 +6954FE21E3E81, C84EFB4200A900E25C11788DCD6486271683966891A1720D4E69A05EFDF75CEB, 7927618CF298C706A84F263214389D2ED3590B0CF56616B17A4F92578AA66F79 +13BFEFA65ABB83, 6873677B3481510BA6C07094667A74758A95955382745C2DC9BFD221D86220E9, A996843948A68261819C67D9832431FDFEE4C4B740468B1D32E634AB54FBE56B +3B3FCEF3103289, 318D2083EDBBDFF616035068099DEF9F8F301C18862819572AF983C0DE1B5766, CF4EB2E4EEA21CB80737146A9FE0A9FA8ED27BA3304B591D044F0B5844BE2440 +B1BF6CD930979B, B9F8D2CD8605FBB34FB2E45CA1B7B551290A9756E4E505B8BC1A24D573A2315D, A7DDE469F7EC6C41AF7106D876E942D6326B0B080FB8974B5FCFF4F57B2FE3DD +2153E468B91C6D1, 4F34B85A6E86EFCE07F2416EA5207584EA73EE563AAEB8BA5718998C3E6BC837, B9E58B8C624FC69CABFFF05F0AE627831D321A7CEFB9B46DC00001BE04557FC3 +63FBAD3A2B55473, C72747417F3EDEE3A825D6812433A765B86A5232C6C6A659C9A4B191B1E1DE94, 6CEEF872773D01CE3DF28BC9CAAF7FAFB99DF1D959F68E72E35B6857E0932F8F +12BF307AE81FFD59, 81FD011C8A99A40DCA8A7C32C79162A5F2D4890896CC78B3A32ED717CA5FA2A4, B9D74EB358E8317836B4AF55570A1D3D12860572CD2A5B2D0DFCC4BD3C4BC987 +383D9170B85FF80B, 40AFAE4C462C69336D891960DFE6E196E9993833E665E049B1954637D43A129E, CD4061C098918CE5A9C8AA6834BB03BD772075E65A409E46D714F355EC60EB8A +A8B8B452291FE821, 74704BD80D4E27078A655E706E2A597ACDC29E436EE80BCBE18FAA84C15C6DA3, D1B40931780C1DA6335FC44FE4692B6484F60E252D02F83BCADDDB3EE7A896C8 +1FA2A1CF67B5FB863, 6B439DDBC100DEDEE0483A0C4FD5A8CDAC1802CA3F97293CA725C279CD7BB08E, 59140C0741B1FA234AAE1DA31DBA65D9791F33969AA7061B0749FDBF88758FD9 +5EE7E56E3721F2929, 7668C2BDC91D291B02650789062D5E751BAFAF59CF998678B898823961062D01, B34EB15AA456E24AFB98C5E6E4DF372DD91D129AEF901E0B130BCF7E9331F5ED +11CB7B04AA565D7B7B, F92C3A38FA5E7DFBEFC60FA0E2456DB43753A261BFE6FF63C62E363EC0878113, EEB2E1B0276140E9BE5305B50B749C7B86A03E318DC329631BADBF3887482246 +3562710DFF03187271, 29E7020497D6ACA67F6763F75F4B42AB5AE4EE8A13AC502FCD3D360F4ED642F3, 4CDE12B3883D75D2E0A6D7609B0AFBDFAC4988D9705AFAB4EC0A1589514E0329 +A0275329FD09495753, 1FAD5E7460F6DFD39F30175930AF50D1BD7C5D7DC6BD042D5C41F2C50CDA39F5, 621FF115E20C9EA82F065D44A3A8E1A5ADFE5BED5A2CCCB7CB41EA3011DEE37 +1E075F97DF71BDC05F9, C32260FF2CA314BF21C9657FE2A67DBCD42F8FEE94801DFBF19B90B5F0391D3D, 4D5C4D7A51DE0E13C84D9F73397E2B60691641DAE21E8A0EC176099E53CA25D6 +5A161EC79E5539411EB, 27A7C9B7C1D4890DA2D7EFF72817674AF89B0252D4C5D475BB3A4465E447FAE5, C5E46F8F273374A13C5946F38885C32EC2A74E0EA841FCC7B89BD8D83F55FB7 +10E425C56DAFFABC35C1, 118A2CAC0A483723089A3E884871DF85AC85AF79F585EBC3DE428161FCDFF17A, 25755E6E4CBE651A0FFADCB9BA725B814120B6C06CDFE5A84F907E6E2A6470DB +32AC7150490FF034A143, 8449173F1EF306C543D0C4B9F2CB93429F34637236E309BE67D53D4157796723, 781842F7C978BB63AA594FAD8A68134335C945AD09177FFE0301E67A0B8578EA +980553F0DB2FD09DE3C9, F5E177E4C208EE73EA60F93CF55AA29C7432F64190151C3C9120EFF544507895, C3A1129403AF90EB0144B02064C808A74E77FF1B8D5D20959F2D1C6485D8201B +1C80FFBD2918F71D9AB5B, E97A1033D8D47612F69417D75A39F45E4D3E2FB2BEF8A236C5B1378403C3C82, A1FF6F7DECBD7908319D1735F7E9FABE8A65C6496586B7773B9DD7F3C8458AA +5582FF377B4AE558D0211, 9B62C7D0DB0A1F1F71060373F50A34A3A8956CB4C6ED4AB95B400369E180F74A, 2074BE51F968B87465918C164637E3388C151DA1454F9F5696D93C0B89F5B795 +10088FDA671E0B00A70633, 57789C6F63C6D8B3E1B8D2DED479226BD3C4E15D76A8F184F6434DFD51C95EB7, 2CEA6ED3DE8E8DA3FC023B7EF1879D4035F6FD58A9F5B2CFC3AC0BA58C6CA623 +3019AF8F355A2101F51299, D8BFACB83417C2B665562F70C8AA2A54049B5490BE83D35219E61F4F3AFA6DFD, FA0EA105DC3EDB5BFB57AB2EB0AFE60439F6FBF7ED372C41E23CF87EA1D7D7A6 +904D0EADA00E6305DF37CB, E05FDA5A217409FA3682C6E5707D440D3DF750C185C58CDCF9FB96D7029E6727, 4E336308069F06AD9140C23FC466A16156F5E96E838213AE77F98CDDB1C36A1B +1B0E72C08E02B29119DA761, 84090FDF8B97262415190B79DB0D272ECE5CB2F374E4C05A524DF214BE291BAB, 1F40013072768A2CBAC51F4C1F1C03FE57BE78DD50630416450C9233682514A7 +512B5841AA0817B34D8F623, A3E2C85B131943FC0D17EAEF2B5A417D31C82139ACB2DBCCE2ABBB47AFB8BD1C, 9BFDD98C5698680E991367A49595BE03693E633F6D3ED8D798D8D16F3B4AF3B6 +F38208C4FE184719E8AE269, 38F0BE60E0FC25D6408D876E330CB8EF1EB27187B105D16B1629173F8D68B2FE, 5EA95CBB1C921B1CDF7B3EAFC19B38B86C0C014C8310ABCD47AE72332FA3476E +2DA861A4EFA48D54DBA0A73B, DC28C706097F7625A596B6A820CBFE34152C1CB3B6E98A45CF408B2FFB9A4212, CA52B09F3E15F24719FF2957437117225F89CD191B926868DF67ABF6300A628A +88F924EECEEDA7FE92E1F5B1, 757C39D0DF71B146F31A43DF4399E4D48D2F4310B4686065D1151C00BA3DD58B, A9EAEFD96F3B04DB4CF7083552BCC39490651B3D25939B976273172EF2148CD0 +19AEB6ECC6CC8F7FBB8A5E113, C5CF26F8A81A725795FDE9E4D87D5D3A65D02C62BA9A314FF3C452287CFCB3BC, 7A6E7E4F2F6F5B01B6BD56D85D5A521E202DBE1C92C26E4EFB53A42E82132FE7 +4D0C24C65465AE7F329F1A339, E4A096A0679B179692D761649FC84D12633A45835BF68FF0F6363BB7ACDA2C20, D583B39C13EB95321119438A0FEF948B6FE153AB86CD3B04D68C1C996E0077F9 +E7246E52FD310B7D97DD4E9AB, 1EF7F3BC67DC61B3FCA443E1BE7D775B88F177DDE0DBBC4F87747F8E1FEA5773, 49D9B998A6E36EDCC36EC02D8FB19FB7B9C62773EFFAD5DDBCE44EA8536DBA19 +2B56D4AF8F7932278C797EBD01, B62940D11E471FDB4D19A1C031BDD77D03D9EB7872F1E346C4D71C84A5FBEB2A, D6A251B89ACC62DE0C334E772BB10CF98D42213CA33A7D80E1D5FD97A6BA7588 +82047E0EAE6B9676A56C7C3703, F19C132F1A7081351289273DC31E2383DCEC911C26A5E72B479310EFDCA4956A, 5DA7EC8045266BCD898B3B74EC70C50F3018F6358DB778DCC03085327A5289E9 +1860D7A2C0B42C363F04574A509, 49E7608848B7D6FEAF1C2E3099BE6C27CB12FA90C152CFF8079245EC7C99FDA, E2D3BEA787376ED5A8068D0DFFC52DF910979622F4C6E7B8C366395E6D79EB1E +492286E8421C84A2BD0D05DEF1B, F1F7EC33D596D85A2DD9F97761DA0EC886A28A8E3785B1C431C808BCA54AB101, F5E265D2AA027AAAFF41EB6C62C0C2B45EA12EB74BFBE90BA24F7AFB2023C613 +DB6794B8C6558DE83727119CD51, A8AE6416C72DA357FE356210B220922D91459F8017B948C939968BAE6A816FD2, 19192FDED9B5BE5F6767116343ABAD2B918D3E1E69324E8394C3AE15D18B363C +29236BE2A5300A9B8A57534D67F3, 802604495D3CAF58CB2DB7EF1B5A9489E8F1EC87EC2FB8755D13A712B9F29F28, 8419F80449048AD209258E35789417524E5279FDC69291AE75C1E2E0FC3BC923 +7B6A43A7EF901FD29F05F9E837D9, 3256A959AD2F07223CCE16C4518C5FC0A048C2F275D6ABF5A0E75D89B4AE4641, 5770511F6606B0A9C31BB70996580A9D594A7352E9F0EAB145521238A1D0E141 +1723ECAF7CEB05F77DD11EDB8A78B, E3DEEE86BAB797332DD6C21DE8E6D3CC40236C52A409B2B2AC77F2EB450EB271, 5149CA7FEAB69D29F8636DE57E8BCCB7D2DB60F41C8D6294F6863E29AD46B6FC +456BC60E76C111E679735C929F6A1, 639346FC6E6328306F4EB3EDFAAB0032027423AC593C6BDE70D6D15FBDFD94FF, 648B19BBAA5AAE60A88FBC1003CBEBB684977372D1DBB7D06109421A3BA65043 +D043522B644335B36C5A15B7DE3E3, EDF2B3D2431C8DF28E2CAEEDDF543B82EB427F9C176F3D6E7A7E2F796B01BB91, 803FA14E1D972D8D1B9731C69B1BECE49B8B5DB5F0F35F0DD83E58960F8067CA +270C9F6822CC9A11A450E41279ABA9, C0851884918A2A184BF17459E52C18138489928D34EB18C4145110525CCB70ED, 5E2BCDBDE7699A6C49D22217799C78B881D07A3F6968F21294AB9FB9BB80CD05 +7525DE386865CE34ECF2AC376D02FB, E86A26AF7DF39DDC653ACDC0FF0C106E9CC39A52950B66C813ACACFD7EAE0396, 894E0A381D815ABFBF2935DEC8B5FCF1AEDADD8C8A733991B7E6A1F46B22E5C0 +15F719AA939316A9EC6D804A64708F1, 3BA575814160D9E223A87EBEA660EE5B7801E07C94FE56CFEBB8C7740B2DCFFE, C057035184B7BBA91FF3B71297AD8482B9DFC0B1BF0395F0365AE5E0EB535019 +41E54CFFBAB943FDC54880DF2D51AD3, 26C0625191AA21183B99D36778865073A8A07CE5EBE1124BC796D027EF884B43, AE8B3BD095D79CB195CDD9FBC1078878B7EF018902B504A3F1B8F8B291C655F8 +C5AFE6FF302BCBF94FD9829D87F5079, 2EC7445C966E75B5096FCD85DB95E5A46B8214C0B412E6483A70DE7AB33E9F61, 1F06DCCB29051713852C3D9120D5DA846B868105F5838993B48E649BE7660104 +2510FB4FD908363EBEF8C87D897DF16B, 515259E8C7DEF6D58539D142D4049D6C1CAD70C1EBAB248E7ACA4113CDA147BB, A25072696182B4EF15DB2A453D4253491A86BEDB929A1BF10AEC1846A68B2A9D +6F32F1EF8B18A2BC3CEA59789C79D441, FC9D89DFFCF825FDE96C6A3E1185639B51ECD409A6EF3FB016D825BBD0275A91, 4BE6FE0665F733F48827BDCC02E14FC0443D3BB6D165956A12F6A49350568051 +14D98D5CEA149E834B6BF0C69D56D7CC3, F43AA390DB46C4DD0B16E616CFB9C56556AF36E3208B7AE109BC31696A12E8A6, 7B26118F753416608949A5425AC4FBA4C73C799A92EA56A07D3C70A60A37CA6A +3E8CA816BE3DDB89E243D253D80487649, C519979CB8BF80734D6122317A41B2B028C00F9D670B2351A2556150D3AF52C0, ACB6ADD534B0D4272B93EAE9F8D77A064F51F9A110427694EA8EE9549C5EF270 +BBA5F8443AB9929DA6CB76FB880D962DB, 3EE87C4796A96E074122A62B1953BD3812489741BB88CA714F20798F8B27B487, 2A8B7621DCD56DBCDAA3A4AC5D7B1CC1D78586969CDC9738F97A0DE7D469527 +232F1E8CCB02CB7D8F46264F29828C2891, D37321D22010BA39741189B284438540BCD88595890B8AEC37C8F50A106214EB, 9384CA1E485F0C77E3CE399D1518021D33F1C09454924EA1C7377BD9F46E4064 +698D5BA661086278ADD272ED7C87A479B3, B0063A950C72BED8F3AA2D87E7F9728CBDE2AC10AA203CF0A507EC2B1F431972, FC9D164F254D82AA6DFFA81F0C0AFBA525B2AF3F5AD1914081A3AA57D8424A0F +13CA812F32319276A097758C87596ED6D19, F46A205F21E8560CE289D4FC7EDA91AA9302B722435F24D3168FAE1176B0EBCE, E1F04C816D7EA9783538D556B58A83DB5ECBC835559CD620D7527BDEF66D2AF7 +3B5F838D9694B763E1C660A5960C4C8474B, 27ACBB5308966BF46CD907C16A73EEA175B6A8DFF72BA8000CFC0C5D8D3CF1B1, 4BA2797C5210175846145355E7DBF420DE8CCED60A0F2C3130EFD226C66C0084 +B21E8AA8C3BE262BA55321F0C224E58D5E1, B5C3E7F3488FCD747D7A654DF687E7229B48D8B4350F3C48A28BDF16616E9989, 6425C6B6A515EC5152ECA6AAA9B7DA7636DADF51C2E54429828F0938BB4934E0 +2165B9FFA4B3A7282EFF965D2466EB0A81A3, 379B3609C349B0E1DAD8C90EDD479E70F278F5BB7CDB365316E23DD044A0516A, DC79E2235CAAFAD8163120508E6A233A60883119E36A625E8A11328957072B9C +64312DFEEE1AF5788CFEC3176D34C11F84E9, 7538AC4A0F08CCB59A0193BFCE0C12DDC80C84807939190B0629C510C804B714, A8B3FC8066FE1C94383F4C4188271EAC8383F2BA6353E289518C7F0F7B04AF7A +12C9389FCCA50E069A6FC4946479E435E8EBB, BBC2076BE1060AD9806A9FEE9C39DCF83E8911CF108ADD64DDD9A1F5913022FB, 99BD974AA1EDC414FFE0CAECB42E3AEE437DA6480E93C5B8A9DD476939B4BAD8 +385BA9DF65EF2A13CF4F4DBD2D6DACA1BAC31, 75064663173439F4642B322604A5CFDBB542E474555FFEFECB1FCE3B5175412, C33956CC23C2B31CF01DA801E18571535C27C5F5A16A868034571259786E3C3C +A912FD9E31CD7E3B6DEDE937884905E530493, 41B3248D83A738F9D18187BD61E3A3DE66127F8C7598320653F4827E74F1ABA9, 535A0212A912E134E0AFF0792062A7E8AB70DDACD27A84E15771D52789D0BE83 +1FB38F8DA95687AB249C9BBA698DB11AF90DB9, CB0D26B71EB1A3F0B6734AC607DAEABA8FC174E58F09431022D27A7EB3E0390E, 98F49A1576BEF607E105FD66233F5F4B3EC2E137E3191309E025233F12338CA7 +5F1AAEA8FC0397016DD5D32F3CA91350EB292B, BBA6B4AAB4E9AFFDA12A1B46BDE8BD974B9BE34927CA1CF60414A9A118145EEC, 1506C0C1C16DD4EB36FC0CCDBF62FF6E83338A315D4FE7D198C41021595C9FED +11D500BFAF40AC5044981798DB5FB39F2C17B81, D31396ADAF5CE28C15DAD95035DA92470821F4EF5F0580A76D47F01A595336DE, 6E15BC1BAF9CB2B85ABE5863AE8174D9C7E7AFF65A253D7627100F21D5805E8F +357F023F0DC204F0CDC846CA921F1ADD8447283, 9D29DA456BC96B1A6098E5D33C6A28D09E30368D2864EA09A392FE65903B926C, 3ED2BEE9A1F81625B56BD99534F4F332FC590960BF879251028785D75AF8B015 +A07D06BD29460ED26958D45FB65D50988CD5789, C9185F8DC5E5920FDC3E7BE8DC01E225FEE33FD36878AB8509F85B5306FFA9BF, E3CB73400EF954633EB052C2521D0AABF57C3E67C24DC52D999486D553C7E85 +1E17714377BD22C773C0A7D1F2317F1C9A68069B, 42A227EEDFAD4F956B08220D22CA0BE899F4B53407968C28DA2D8A1B7DB164AC, 4A907645D663C2685F6FD6DF0DC5A6B6EA158D3711D54C20E269FCDEDBE315BA +5A4653CA673768565B41F775D6947D55CF3813D1, D0D9EE4E36C677D83C325453BF023BDA5AFC8D58E21D23C1054F1BFC64BB53C6, 2AFD68ED137B3D199657BA1818CED99986F51FD25B482035544E6DB6EEC374C1 +10ED2FB5F35A6390311C5E66183BD78016DA83B73, D5B0A27331B72048E0256C1889452B91E366A6174BCE131707D7714A77EAEB72, 5677E46D5757EA41DAC027757C3FA37167EFE9899882365A90088AF78E70864C +32C78F21DA0F2AB093551B3248B38680448F8B259, 601B3A7F661400DC5FE42836C3179183437C2FAB42D177A9B4DB1E3C3D001BCF, AEE8201AB9C8A131A9BE793AA5AD2656E617C9F6756A07A21B6D0CEAC1F986D7 +9856AD658E2D8011B9FF5196DA1A9380CDAEA170B, 20B5805698BF8ABE22E9EEAEA3BAC3997386EB8AD44978C74A96C82285954243, 74717E6B981FFA53DFC4DA6A594F5D1F19502DE455F4E76FD452DBC43C006EE +1C9040830AA8880352DFDF4C48E4FBA82690BE4521, 5DD4513D170D41F1C44A39BD70BA0F893514E621938B46BC7ED527BD56CF229B, AD7E0A11FD54CF08360541F956DC20981C338736AF5CC9CFA02944C25E450DFC +55B0C1891FF99809F89F9DE4DAAEF2F873B23ACF63, BCBA4F7644827255373B8438FF87536AB8B311403E566509EBEACEFA63795C53, 6B33C2E0F5E5295A540DF25382ACF3F7A43A2BBF87F07362500846A09A995928 +10112449B5FECC81DE9DED9AE900CD8E95B16B06E29, 2C4DD6E270226605AA870A557478C45818C2FBE60A3051602938961A898A47DF, 67809BADB323B5771403E5451F1164D30B153BF06264D95C5506ACA551808494 +30336CDD21FC65859BD9C8D0BB0268ABC1144114A7B, 172E760F60F5832A4102279B67D7DBCEE5D6B160D08B3406291B2602B6380123, 6BCF9F3127D34CA4018B2A353188139AD5BB27349343973BFAC8C4C8F7B06FB +909A469765F53090D38D5A7231073A03433CC33DF71, E5EFE6615988FDC242F4897408F12A775E9CE30EA49E86768A50D75B1D29EC2, 811C3E746DB0213AE68C4A59DCEFD8D97B025642ADF378D1D8DAFBEB00902EEE +1B1CED3C631DF91B27AA80F569315AE09C9B649B9E53, 11230F173782A6F4015B5C73F19BBED3B4A77A42194CE966634FBCFBC55FAA79, E7F5601F7142B324399DBF432D96E3EC7DC1E9C1B3038EF671323BF544B3472E +5156C7B52959EB5176FF82E03B9410A1D5D22DD2DAF9, 2932732777DAD6699B771BE1588FD7A8755125F75211256AE80882301402E8E2, 21E71D0914D952CA1EB4BCBDF5245D6063E4F414DD38E7DCB9FF35CA2328D644 +F404571F7C0DC1F464FE88A0B2BC31E58176897890EB, E1DC9FBA51344E8961A9F1BC2457BFEB72E012FFFACF6B7D878AF94685A99783, 2C73575BAE8AF4E6729AC50A8BA3232CE3A508899B82BC40124EDAFFC148662C +2DC0D055E742945DD2EFB99E2183495B084639C69B2C1, 8C4E50B668E48CF16D0424D5DF62FDF56D81664BB1C86D6E227E1148E57F875A, B5A3360FDEA16D4B198319417A0DA67F61B05FD17545DA2F102347D9B854A965 +89427101B5C7BD1978CF2CDA6489DC1118D2AD53D1843, A0E92557F24612657AD7F806B01783729DB117684D1CFD3EEA21AF00239DAC4C, 1E5DBDB219B477DCA45F33FBDCA3563EFC0238A800FE63AF67E229346C093EAB +19BC753052157374C6A6D868F2D9D94334A7807FB748C9, CF09FEEC622B4510F5454E6D607D6A0DEAB9747859F04675E6C82DBB49BC32BD, E4D6AEA583107B538291B8CE6D18BB1D8F88B52613C8DABEAFA634D472EB47E8 +4D355F90F6405A5E53F4893AD88D8BC99DF6817F25DA5B, 9F1E4A1D7B7102C71B2C94FF205E3A5B466D61BA76A38DB5AF85A2FC47A57865, 7A0B26C93C1E627E33806C188F92341507B172B325836CB3A89F9DD153E2C652 +E7A01EB2E2C10F1AFBDD9BB089A8A35CD9E3847D718F11, 6915B63364675BC7AFBAFFDF78D9238D3D7FE8525AE6E40525CE9164C5900F47, 1F922B67DF773EF9DDC0303A9173D4A0D2A294AF23AD0629B8C9D84C29B061D3 +2B6E05C18A8432D50F398D3119CF9EA168DAA8D7854AD33, 88E314A2C7AE62DB858AA1E9795A5A89F2FB360A2AC6D4426D7A3A455EBD3BFF, 27CDD0A660FD359BB4EB9CEA269BBD47D4D09904CE636FC6E470CC7B212AC975 +824A11449F8C987F2DACA7934D6EDBE43A8FFA868FE0799, ABA0CF697B1B733B287C0A97ED1FE76E29ABB4FC913E67443CE35082A92CB204, E4517A1AED272352E021638B812635F6C601BD46D04DF1EF3B38D4136C46C556 +186DE33CDDEA5C97D8905F6B9E84C93ACAFAFEF93AFA16CB, 5E42DC088B475F6118D595BB3E79E896F5B2D8704890A1A0501702EDC00E8994, 1A822DB338757C5660D439700AA2183DF58FDABCB75E7ECDE52727FE5F18B220 +4949A9B699BF15C789B11E42DB8E5BB060F0FCEBB0EE4461, 408FE43D610E979002BCD4BED86DF136D1A75ECAA324A7B9BEA97520C3854EB0, 7986FE1E891C6207C55AF240C7DD10F69A819CE9F62FAA1CE2BCC0CD701EA243 +DBDCFD23CD3D41569D135AC892AB131122D2F6C312CACD23, D16513119B25F3BE15558FE23F5B87BC28C2189B706EBE95719DAAF309273834, F0173989C37D2E786E3110CBD4B6E56C4FDB00D4B21B85723E1784316AA1C047 +29396F76B67B7C403D73A1059B80139336878E44938606769, 3DAB6AD259B5F731E52FBAC416D3BEC5DD302D6EB68C518F7D8D930A134B36C8, 7FF5B6B018B0EA0FE9ADDE3E7375545098B5E3E259CA449FE20C56C2FF496F26 +7BAC4E64237274C0B85AE310D2803AB9A396AACDBA921363B, A5C296195DA154D92C3D19541995F590B88AC659F9F74B9897230977BFDD2D5E, 8904813927D5C1E6B4F3905C8C51C3B14DCAC2719201A8EB05D689628148C1BF +17304EB2C6A575E422910A9327780B02CEAC400692FB63A2B1, BB9CF3584D191A4AEACB45036D831C849DF57560084E52A72067D3BE614E750B, 54AB4A833C01CC422A1A253EF92A60FFA34A20BD82E8BFAD6E15558ABDB6226 +4590EC1853F061AC67B31FB9766821086C04C013B8F22AE813, 5FBE2FC3B80AD6CCE2607AC27C6BAC3653A234BFC23B57A030DAD8514A2C6216, 1ECE4BF22FD472071C1C9F236504A74CC79A830DAC770D5197F39396AE2BFBE7 +D0B2C448FBD1250537195F2C63386319440E403B2AD680B839, B353A8A9EEF105CCDB44FD3199CB6F125CCA844DBCEBD50CA02BAA1600BC50CC, D02DF9BEBB10D532F76D7311D563CA98FAEA4CBA7875285C846A8EA76B0D1EEB +272184CDAF3736F0FA54C1D8529A9294BCC2AC0B180838228AB, 91D63516B8BB7FAEC5F621F5A9675F3650E4C816CCF87E80094CB7D6817A366B, 51747822D2D489E1A9D5082F36C2C15054B2747EF232DD9D08BB1B3BF944BE20 +75648E690DA5A4D2EEFE4588F7CFB7BE364804214818A867A01, 15E0B6AD6FFA887741DE3014BF4FBCFA1022FA8285382D8D5C69EE243EB3541F, D04B1F1C77EDE6A5579397AA35EB012EAB1C31423B2224AA972CD8471DE8D3D8 +1602DAB3B28F0EE78CCFAD09AE76F273AA2D80C63D849F936E03, 18159E5ADFA2E5478A196D3E973758F6D6A24E90BFE666FE0934E3567F212D45, 4241715C90E432F154949B3D82CF2F2EF48F0C17FFE7F532347C8DB4B30DAA1D +4208901B17AD2CB6A66F071D0B64D75AFE888252B88DDEBA4A09, 55F7D55C605C0358BC078616EFAD8E90CCB6E737BD9D1CC10F5BB8A83B49F257, 39345974E4659E643CDE92C9EA5383F2FC74B533B359A701D4369E87C5A87384 +C619B05147078623F34D1557222E8610FB9986F829A99C2EDE1B, C5012B7A288170DA3E0C9B30C558424060777BB1AA385D7BA777D3F2A5CD570B, 269487431A01A4958ACACF309193F80E09E762CD45C228B31D7CF3BE064C0F6D +2524D10F3D516926BD9E74005668B9232F2CC94E87CFCD48C9A51, 494002E29ADAAB3BD42DE827969021162576E562D318A88E6839B0632BEDCE3F, 4B659BC6EB77EEAC9AA62A9B0A25283C285D350002865ED266357C978FA9AFA2 +6F6E732DB7F43B7438DB5C01033A2B698D865BEB976F67DA5CEF3, 8937CFDC5B97748769F993BFF1FC5300A102362694F9CDA200F5A3917E734947, 3D77B10A04A27B8C79375F6CA5F24DB11A02620065B9A5DB088D246DD25BBE52 +14E4B598927DCB25CAA92140309AE823CA89313C2C64E378F16CD9, 2496ED6C44A9C788229A5205D2AB01F491AE4217707F18C27F5E63B567581A1F, E394A06C008B80E00BE7FDA6A79D45D13422B5790A871F010B6C92EEC8AD15A4 +3EAE20C9B77961715FFB63C091D0B86B5F9B93B4852EAA6AD4468B, F21CFFB3EAEE40BA9DF1DACB4CEC7F65DF71910445027153231DED0F452DC3F0, 1D03B97F11FE7BF87ED8485583EC19B6AEF9A236F3DCCF88689EF77211E21AC8 +BC0A625D266C24541FF22B41B57229421ED2BB1D8F8BFF407CD3A1, 645112B55D4EFC904950086C082DC4D3D41A8E164E86C01554909C0118686C2A, 6B68130DCD38D7DDFFB0B6C24F63BB856995DD1A1699847F67935A7EBC07ED95 +2341F271773446CFC5FD681C520567BC65C783158AEA3FDC1767AE3, 93F17111EFE40A080B8ECB79E19B0176E9D80A46C0AC6F68799DEBF64B31F72, FF64A78282EE7D13EDCA84C46F0869C6BD962D02460EFF4DDD8644ADDAE46556 +69C5D754659CD46F51F83854F610373531568940A0BEBF9446370A9, AE69334BA71DBD00B72490AA9EF5BA78A2E20D515F2CA5C6F926D9C08E3B3259, 797BF85C91245664BC1EC92B9A706977FFEA62465783AE9D93FAC6385A74FDA2 +13D5185FD30D67D4DF5E8A8FEE230A59F94039BC1E23C3EBCD2A51FB, 5F038A8AC8431F9321D202C24005781866563A68A2BD832BC55CADCAA0A51AD5, AC0696E2796C5A3112CF6ED1A7D9A08FC3D98AB9A24C8FC23A24228D5AD8C8CB +3B7F491F7928377E9E1B9FAFCA691F0DEBC0AD345A6B4BC3677EF5F1, 82DB9DB3EEC13250057CF1BFE491A65657160DCA8D8B2FEB6FE6FAD546D4F2A7, 84B0E6C31FC401C5305381127E0BA9D69270B4013C54F490E153A075827A6908 +B27DDB5E6B78A67BDA52DF0F5F3B5D29C342079D0F41E34A367CE1D3, 34B824BB7171AE67B8D36BDC03BA146348E472024C48336F253A55FFD92EB98B, F86CB5EEECD0A02BF01D079BA5CF97C797C5AC68FA2710E396C9BD45E0407C69 +21779921B4269F3738EF89D2E1DB2177D49C616D72DC5A9DEA376A579, 279DBD6D1E7C0856C628499CED784DA0E025065E8CD73CF468281147F76695C0, 15C322F07B13711DFFC4F90149E49679A3478FB598C013724570F1C042B1CA97 +6466CB651C73DDA5AACE9D78A59164677DD5244858950FD9BEA63F06B, 88F6C763894E985C100A297CEBEB74F0AC2200A6CE73E1968973F6DC093EE523, DB6E1A86B52B180EC1A61C61CC574DD86F9A75503F905679DEB642617BF36EE4 +12D34622F555B98F1006BD869F0B42D36797F6CD909BF2F8D3BF2BD141, D5D356D043B1536C5D197072C9D15592EFBFE8D34250CF7D20FB1AA7AEB348A5, 56A5F938EDD5FCF99D493874F71D6D893635255A88726D9C35AE85D77194D385 +3879D268E0012CAD30143893DD21C87A36C7E468B1D3D8EA7B3D8373C3, C14DB8C85E0B6D2B676E4C0A250649A85FE73C8D0C7B453F1C4AFEDF67454ABF, 895257DFB694ED1FB4485800DE790065677C29C0EC2D052A884C07D480933A54 +A96D773AA0038607903CA9BB9765596EA457AD3A157B8ABF71B88A5B49, DF7D5C7CF72E94C8C8BBC544B593AC942345A022B8F252D517FEC874AEBB57DB, C7D88559EFD4407D8BCAA17618E49AA4CB144788696020A15507F2FC9C287EB7 +1FC4865AFE00A9216B0B5FD32C6300C4BED0707AE4072A03E55299F11DB, 6F6ED9FE2B4AC0DA65688AB6597A4FECC2569C7A40B8EA464A433C399801B87F, F6081F2CD5035CCE5720C1994CAF29AEECB703F862D6041734049FBF89D00495 +5F4D9310FA01FB6441221F798529024E3C715170AC157E0BAFF7CDD3591, 8BB82D1D4814E632E56B14E7E14A66EB4D199B8DB27688D93109C02A83C03717, 98269529F24CCA3CA4385B62FE340000A315A5BE887C6C914B58A0E71FC2B113 +11DE8B932EE05F22CC3665E6C8F7B06EAB553F45204407A230FE7697A0B3, A33FB3D793FA380AF2F28AF7A62D59A92D6BD0C837D01BABCD439C47C270A090, 4B7DABD362A3CD41D839684D8F247DB031B9EB5A06F808360288B0AF42A645CB +359BA2B98CA11D6864A331B45AE7114C01FFBDCF60CC16E692FB63C6E219, CE26845F94DEE7E0061E9E5C14A7CEA984708362168320A5A0E83029C16A2D9B, C02FB0DF34C761734BAEF1573B4854E24174372E735AAB81E616326D406EF10D +A0D2E82CA5E358392DE9951D10B533E405FF396E226444B3B8F22B54A64B, B859547C4E7207BE3CD43268192AB88A88BBFBBE5687E8533C7AECC6A1D2BF61, 7E53936BC792436E53C10B930321945784E885B43626B26739DB84A713E002C5 +1E278B885F1AA08AB89BCBF57321F9BAC11FDAC4A672CCE1B2AD681FDF2E1, 22CE0FBE44DE6BCDF09CB9D85FEA1FEE51E515EAED6CB21B8977C7BAF5981C38, 1DEE07C7AC027A082F77EC582E2EAFE281F7AC1D709788323DABF79E5A73FBEC +5A76A2991D4FE1A029D363E05965ED30435F904DF35866A51808385F9D8A3, 2ECC1298F418914C6AF79DE90BE8021E3C7F81ACD61F0449D3ABFD9E3DC63997, 8D229C381A022D2AE62A7B4E481F2564202867A4FCA904D4E91CC6B70C3BB10D +10F63E7CB57EFA4E07D7A2BA10C31C790CA1EB0E9DA0933EF4818A91ED89E9, F8F4F6A1955A9B753D766668CE35829F70030A14CD05853AA09E6F610CCB168F, C6AE8802312258020113FFA9576856155057345E8DE06B43F5D8EA9DAAA9942B +32E2BB76207CEEEA1786E82E3249556B25E5C12BD8E1B9BCDD849FB5C89DBB, D7428B9DDAD0BAABB29E93E13F764F941A00E4645F2590D7E2C1EFC84D91568D, 196696F277C70CB49678359D63AB99AD479B6B9644CA1CDFDD2A1BB3EFAD249A +98A832626176CCBE4694B88A96DC004171B143838AA52D36988DDF2159D931, B8E809F295A7623691734C066D59C8FA0D280159ABCBE1D42967A513648664F2, 280F44E7306591A76646D5FAD6869034A5176A4C361B374E8C6D3CFD333D5DA +1C9F897272464663AD3BE299FC49400C45513CA8A9FEF87A3C9A99D640D8B93, AEB5B4C2AAE2B8F67DF988F43BA523740CBA257BE4422213F4F2A162E4A5BE4A, D42994CF1C0EC81D51EF67AC67F7E77FCB1DFF4A0E031ADAC893EFC3EA9C0AB9 +55DE9C5756D2D32B07B3A7CDF4DBC024CFF3B5F9FDFCE96EB5CFCD82C28A2B9, F9BBF4C0749790F216CC5CDAA17232BA85B3729B36A4547F795A74BA4BB31F3, 322EFD9EBCA43A2625AC3DB8A785DB6FDE7288258B64FAB6C824013568E1AA34 +1019BD50604787981171AF769DE93406E6FDB21EDF9F6BC4C216F6888479E82B, 6336F3F2C0287F1ECA291AB6434163DE79B45E68DB62986970DED3A46D38A43D, 4D91C779F2B3505E0952D2BD1C3F59FC91B625546C5087E9E7D39347DEF446E5 +304D37F120D696C834550E63D9BB9C14B4F9165C9EDE434E4644E3998D6DB881, EF7444E99D2F2A08ACE89C4143B0F95078F15B7F4FC7D9341766429383589095, 215F00149824E1739E36F1E6FFE3EAAD9C08DA5CB082F3B1DF0A3F2349DDD9F0 +90E7A7D36283C4589CFF2B2B8D32D43E1EEB4315DC9AC9EAD2CEAACCA8492983, 4B0A4283D9A07E54E2D09B415DEF9C09C5230568EFE290E696F2957F75E2EBCF, 22FB66F09632C8A9B39DAB9BAEA63D364B93FE0D4B508DEEA6F4716C4E5616F6 +ECC-384 +1, AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7, 3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F +3, 77A41D4606FFA1464793C7E5FDC7D98CB9D3910202DCD06BEA4F240D3566DA6B408BBAE5026580D02D7E5C70500C831, C995F7CA0B0C42837D0BBE9602A9FC998520B41C85115AA5F7684C0EDC111EACC24ABD6BE4B5D298B65F28600A2F1DF1 +9, 8F0A39A4049BCB3EF1BF29B8B025B78F2216F7291E6FD3BAC6CB1EE285FB6E21C388528BFEE2B9535C55E4461079118B, 62C77E1438B601D6452C4A5322C3A9799A9B3D7CA3C400C6B7678854AED9B3029E743EFEDFD51B68262DA4F9AC664AF8 +1B, 9C5FA2C13F418E623C316D5A82C8B70508E3ACAA2B4A8D3A4ACB49C0D7BA04E220761BC15898E1B06B4EEDFA23E2E546, F641DE0CB075851A5AFE81503CB7BF6194FDF1B7DA9E59556F015651BD9218E30EF2C4B2213F519B529FB56479F48752 +51, F0091B1080B24C407E983FC77C0527861E28CC8D5C9C5B48B1F416FB8F72FDBAB1BA877E2DC9EA82187A3E46D072AA44, 22492B56C351FC882CD63A572FBB7A794EC8CCC18F16F8F352071D69AF769F4E7ED6077A9A08429B58810F8CFDDCFB8 +F3, 5A815D846315E5DBD155BC729B098C810D68B92B05ECA2849230F66A356158C4A1856A11CF7BA5D563BAA6F3AB3D0087, FB880F0D6F85075B70191837CC459851981406857F03F6C8EA0D2ABC5042F0EFB9FC97561A63C71CF8159381F038E7C +2D9, 2CC6E0DE17D86C60A9D764CA17E6B3BF8FF48AB9E6E38EB0996BB6CB36DCD276B61B24C5DC0F7C1083FCB2A87B493240, C86ECBB06ADD45F4FBC5D411AC0B9BB07292D7CB6FDAC1167728A7B825E226D225A3F90DC40DC7DA4F10106A7412E7A3 +88B, D5BECF937401D03C63994BAA76FF1F359A554953B2613F62908B47497CBE15A5F124488C3DBB9F13DB9409751AC6B9D0, ED2841702966C15664AEA733911FD1C00FF1258A5B6C9F00530C0BE9EB940909D8F519D50D08ADA801D35D6EA04C05EF +19A1, C7A8AC69A56E8F724AFD6FD01CA9EDF2D427C332C596992C5F3B54D57911FC5323D21242E4942135649F382EF9A2CA8B, 4186C16218EBBFD84E4DBE3583E37D7158071639B84B9FAAAECF1FF6955F6AA4B0BD21BD5DC7C2927E76C7AE49585543 +4CE3, A4B32813B19844D83A31C9D638DD87F16D7EE7A32D49A6A99D6A902AC26082E41EB9E77B1D44C02E9F48F247D8DEBF11, FB66140C5C887D1CA28EEAF5B8DB7B25AC4DB1A49FA6BAB93639E4A1DAC6479447E8F4BB1312946E0D07CC09B63FED51 +E6A9, DE58069466D407CB27257473DC08FD2BD09D262036D56ECBC0BA9F582641294B18D7B1285E9290C55764CA0E7167B05A, 4248B42C8B6FF55AC40A50191D86129375C7A6C3595EE62A12F74192C9A431EE1BE1341D824CC31AF10370D8DB358BED +2B3FB, A9EB0041AC0EB5825B04B81B34D2402E1F14638B62F4BAA5E9E3F47320AE724F7257387BC470A0B77E1F9855155018D6, 707400FA47C87C696AB61A610D68A34482EF3FF32D2D954E3543F27C2A9F04B261DD53219E14F61B4D5F9CF9CBD4260F +81BF1, DB70CB69AFC2C9BB0EE647BEBEE4F908F43E04800B8685726E1BBBD19AF36B9CA47D1F460923A00CE54E9F03A462B4D7, 7FBB8BECBB33AC921B3C58DC62ED4E339B1A715D5A24137B5DA6C48D8123DD5A91D3A4FCBF8E1C8DC4FD80F7541202D2 +1853D3, 5B513BCC210FEDDABFAC368CA876F91808FF8D082DFB3DC6DAB494797A547F2643BC1C3D05770E0F39F08A1C52599BEC, F6D2A470961AFBA04D94E96A4DB1DD413DDBFA0449C16A72EB95D39CABA47A3CB4FF90A7C8085CE7CDA3564D0DD971CB +48FB79, 2AEE1407D07D4B8101A86061486B19D9399CE28345A1992A7CB9EAC43F3A13941CAE792E3402867B080BC5054D259F6A, 8383EE4A9984E0CC3F51CB1BDEE6BBA3A14E503D09EF36FBA83BDE79A17BBBD9663CE8AA4CB778C8F8252B309790B120 +DAF26B, 6E640CD04E1AC2A7957987D2FC85EA7688625CAFFBFB587770F26E1A44C682A0D947BE7BE485233006AE59ED12B25625, 1CE1DD4F5752F802D264A68F5137CC5F0C76F24007ADCD6C2585F33A21BF4FEAE0C8E450A6FB79A0B091674BD22BB668 +290D741, 9FBF2CBF74EF244D733676D051D0314BEACE57207E02A53BAD5BF777D99EBF3B217705790EE17CC41EC09809E64F6A27, CCB0A336CF5B42BC181EA33476CC4F348710CBEDE690B39C578115D1E085CFF5E51EF95634C23A71226563FA80E55AF7 +7B285C3, 9D94D0999D059A6E294DAEF56F75809D824E8AD91026BF00C792953330B5997B51848ECA853F5969FEF12BB877A7EC8C, 46C61C9C588D5814B789643D945277D6E7801877A09B2EA726567F11B2DB7A06526FBEF365B6FBFB4D56497814BFD97A +17179149, E6A9F66A755375FEDFE9EF57DBB63A784D541BA6BCB6FED27FE4D4B5605E5A6F83AFA71EC1436091B8B64E2FCC27F5A7, 9E5BBC160854223B74CF1E0E26C7AB304A3BA3E6392C1F74EA1BA8C55680171B01D278EEF74CB3B4D7F390C86005C21B +4546B3DB, F806B14FA71B88D0F6A8B54E3708E45040A85999A70C13D40E06990F3630793A141FC517E95CD0021EA1621C951A4A2D, 72870FE8BE24B5F749322F9197AE03DFF1E4689AAADF78BBD4DF16421D5D59E2AF2A5B499B7A1919EA311053E6EB813E +CFD41B91, 139EE0E2DD813FE72168E8876E14A03EF31F4C3FBFC01595733B809A7C1B8CFE6014626622BFE2F6741E77B27123815F, 3D2F7570CCECF08D7ED8451AFAF7A06D94BA65545A20B8ED6248B24988B724F234962DB05E2A6394D344FF64C772B9B6 +26F7C52B3, 13BAC5430DDE14CDBA331A82158D3A45D2CF09D30CBD950F3606103BDEE195179ABBFCF3BA58B664A5C97156ABFE3374, 74A00DBF0C6E447031269B041121D7C928179937EB907FAD50DD4A9F128FF462BBE3021B01F9DE9C712425BC7508C0F1 +74E74F819, 8959A4D72613CC021D691B8DFB887C22870C01354A6B0C185CBB535945A19AB5AE476A58605A48A2568F3A1489B9827A, E49AC7C932874225A94A3020CC9E83415E9F2FCF77A2D70CF6BFCD2F890D2719DB4E3FD816C76D4D3F3F104AC76C0353 +15EB5EE84B, B54125CA1A5CE47ED09AB99872804FA8149E5B11FC65AB34CD2B30DF03965D147CD39471C2A59549A95D6DD850666D3A, 2BE82D08A0CF2FD28CBBB9373C40A5874F8A155650E860A0B31D19F81B94550B065B405245E0A3A683E35B25214C609C +41C21CB8E1, 9E639E290614EE79CEC390A013A4090318FCF5744AFAD91A33634DB4BF5E36B488FC75E21EA5FC23217DC3FA3E006D69, 2E192259B316A4EFF05925CC2D59571A0197E9D6E06B0215E15E3F3F4DC4E67A9D896FD25A256907A34156B72CD9BFCD +C546562AA3, 358CE79F6387AE804C6EABC6780CFDCD1AEEB836B8F94799CC5739B895D603940C52850062824C35BB8A2B199DC4B617, 6D7EF97FAC79F796FA7704F07FE682AAC28EB9CBCFAA2DE4FBFF47C71673BDDAE56316940DDE58B40B8B7A7D0A5B86B5 +24FD3027FE9, 423CAEFA17D4E092260A7BB3E2DA55D2DFB2E12938BA950E0E6E4BD4FE8B0AD48B0A05DE009DF4B5AFCE1C2868418A91, 69B2DD050A77CC4D204492EEF9D929CA7828B3A322827333F37E82A0E76D34470AB332C981995BF1495AC997724634DE +6EF79077FBB, 618FA99EFBF4A6DBADDBE9A1B0EDF34F5CFB93FE5591E3B20B5488ECC48C79C7F8431175F87F1229B87FB2F211328B04, 48DF2D31CB4625EA7FA198F4142C6ECC70EAF215B8F54B5CDFF0988499559D2AC1154B9D9152A83C462E41291B121A93 +14CE6B167F31, 34DEE1D270606CC9B48F3151F8D3490C37E339A9133D47746D2901DAFFE5D6C5F8FB205B66812B177BE43855D2CF47BD, A20D5FDECCB8DB396B9574EBD8B05A7360BD01C47FC7944B46627B09A4990494BE2FAF15938D83FF4F0038DF61348B13 +3E6B41437D93, 7ECD0A221205D3BE0069AB3C5CA03C967E9F27AADEA2A52C8A0213CCB8C7A20AC299EA5AE268C3F5F7763F5B6F2BDDAB, A4ACE46D02BD9C63DFDE827C213D712AB8F01A8AC000995DC39006A60E0CCD233F8CF069BA9620731FF6FC77175DDA9 +BB41C3CA78B9, FDED8D3CB351E254D1E0726D6C34D7B4A6646F9778C008BD0CC094B803DA1A985BE039CFB438326B7EEF7C55C4B23DF5, FA023A32F20E217FDE376F4C775C6A41121C77B79D5E652F8DB71E7564B0D6B8DF83EEDFA246487E94DC53CC4089F0D5 +231C54B5F6A2B, D17E9C9792D9D2E438536433C676EFDF6BA1480ACB525A12947BE7B7575B873948ABC34A014A4E09BBC7BC766FF1B785, 60416FBCBFAB85E393972216B2675BBE25D050F2AE4CCA15FCA0E9F2803F1C873BE66895C3F3BE92D037FFB0972A7B3E +6954FE21E3E81, 5200FC8B4BDF422B0183CB0A4DABE978847983772893337FE827A02A2791BBD720A6C8FD46CABFD32250C64B5D67DF29, 7B47EBE2F9E20842E512D353E5CF2CBFB802567A6C805EDBF1856A9B46D0971FE5A2494EC51751518F9FB1EE036E62DC +13BFEFA65ABB83, 79609210110637883B2BB4CB017FD531F2F85DA33C75A0BC3FED33B885B31D684B76DAE207A6CDAA91370455FB36814, F4FFEAF18C196E94CDC1BBD09FF52ED957F433F23BEB3751003E2C3FDF037F9F8DAD43DDC956220DA5D69B0D47EE1534 +3B3FCEF3103289, 8D6F8533C380A5CE6B07F860644087788F06E65135CD58D44FED92282A45EB99793CFF0379F81FADC2EEFF5B9FFC4C5E, 1B5302FD186E2C8E57A869470F542C4B633E48A026933D95E6202455262AAEB8015DA857486D2D2D1B45FF07AE30828A +B1BF6CD930979B, E1C2553F742CFF283D608E226C5E762EF88DAFD75A6D68DD79A6E94EB094D4D04A40C8B4BB80B5F4999C3A44151DA19C, 974EA4ABE8955CEA715F0441070BBCBB04ECD686C50EFB44B07E830E5765928495D0635AC8AF0CCC829E7DEDDBD1698E +2153E468B91C6D1, 10821F1D9AD2F1C09929D08F2292B58156E94C0C729DF58BF3AF929E79CE011D3BCA116FD47B21DB9F043C17E20521E0, B6032D349B49DFA2C97EEA10A605A097B51582D653D0BF297CB385E0EBA2DC982CA7E9135A0196031EE0700C8DCC3DEB +63FBAD3A2B55473, 1BBD5C55CCE19CCB0AD30DD7405F5E91E2D2F51DEB09ED974AE09EF7666A8C74616D7779FC5BA74E76F39FE4AABEF089, C827ADAFD48192B2B995FC8378122BD8A360298C79B36643DBAD49BED8453711AE16DE6A1B146443C19BB59E439B14A6 +12BF307AE81FFD59, 4035E13EF898A12EF15E72CB79DF83496D5B3CB5A0BBBD6800193CCDABFB20794297529F34F935F1D80DFC69B3144795, F2E854351506A1C15CD2E2E6DA7ECFD10A0AC16DB2FA937A03AC6C0B874BE34A2438906FD3F22F5E50CB52D2E84D5675 +383D9170B85FF80B, 2AA4B819AC5737D89948634E8A92968B0A9E70CBB47EB67AD08F14B8A59C978C944FCF5039D4032B41C8BA24A6B08069, 3332B17A4F66A018B7398F793D5438C48EF88F9A8B439800B4A3A38E483727871683286179494DD4C84130DB63B98D62 +A8B8B452291FE821, 551AFC585E46CDD5024AE80BEB75B079B435F90FAABBEBCC0A7615938A83FAAC3B51C42B295B8BD7472AE9E4278B5072, 5EEC8C5C1AECB5D4329738942D4004654AC375E486108FEB24FBF2AAD5FD457BD32F6563281A34B670D100F196E563C3 +1FA2A1CF67B5FB863, 19E89C4E47EEB8970573C05931D43B8083D850494645CD6C4B378B3C90CA8015EB9B22C79C8876B3AB7815DC1C9C9620, E97B4F1C222F10610F6DDFB5D18D3FC1993367E2EBA32B94390573E89D43A1658AE798523A114E6AD58A56CE5ABBAE6E +5EE7E56E3721F2929, 3AA7711700EBA565E90B25BC0A1ED92395D92D9DB8FE06A54E455F9FC9C0311882C470E519B2AB2748A3EA8ED5934BF9, CA0EEF27B7FA621893B155320A8CFCC7BAB2C4C0567523A34B3FD17F843226022E5D87025DD4F87B1F6CA4376BBFAFDD +11CB7B04AA565D7B7B, 2BD895DFCBBD85950FFE675BD6CC298963B99DB909F627A5B2B08BE481D86FCC9640823964E2413808625511E3F8DFAB, 5161CCAD4A7968B685ED3CD380F9BB391BC59D9DE08F4C467F0B65F70DD77A367EDE2B66551330E5FC8898E1446E39B2 +3562710DFF03187271, 4A55371E09700D7F1B9547414D6B3E4071F426A30F1580690496F7DA06EA9290D3A2F68EDF64BD75145AC8D60E124ECA, DAE73F39BFBD3F2A9F3AD247EE94FD25AD9E891A079F2AE191625632D9D511DD777FC32E2AE930C5A5B6337385618AB1 +A0275329FD09495753, 6B45A93F4BFC9F903B6380C8E1BF23D330FF66978031B2BC2BA2F9F112E04C242B7E1DB73C7B28BC1FF12A1999249229, 94667AA038152520F1C8CFED64D8C65F60B2A68F1B5F9616A6656FC5E91F3447A35F684187DE651C517A4AA8679B2C8A +1E075F97DF71BDC05F9, 7F0F54C1E4FB427556DA4581F48013F3A2CE46BBED66E872C287120F723818B9CD6816DECAA6E215D629AC01BB5C2078, 470121A7E34B39212107BA473B7DC132E2FA3239DFF3C9287DA6AF1AF46591F015BD962FF0F8C66DBF55DDD02579ED0D +5A161EC79E5539411EB, C7E85917B65250AC843FA5FDA808F01CAABD276DE03A46F54CE92C17ED6019D353FEE8BDEAFB646EA6B645E16D822039, 6D38FB10252426C24D77367F6ED6CD68C1CB3EFAE0EF23A29B8FFF5072C32199D71DAE1204EF30AA8405C2428C093A4E +10E425C56DAFFABC35C1, 36A8B370957DB1F875A6D916D84608B1D4902183518B2E2A3409961E852DC422769A7C6D871996FAA0D68A87D73824E1, 7C0B56B029CCDD9D106E88A8CC4A5384697EB9A5D66041F438753FC0724FC8C32AB2001531AB37BDDAFA2F666A7A8F57 +32AC7150490FF034A143, 65E8324C8CAF05BAC68315E1FA3BAEAA4D7D07B42A0F341960D3881D88AD11D3823CDC06717947BFBC47CF77EF02A288, 236A05EA0CFE71B5D2E6AB212281EE351E380150733F52FDF4097D255994FF9D5E5817B114C1D7E259FB45D61675DEEF +980553F0DB2FD09DE3C9, A7B928461464C1A9873A0BDD6D48B7EBCE933FEA1F455B21B5225B3D1117A5E77EFBBAF60EDFCAA51BDE34E069B539D7, B4BF3523C06B1A71D2217259F39056BE28C34F0862DC37663954111458D8DADAE5CBE146DF1A9033B173FCF5B2C7F147 +1C80FFBD2918F71D9AB5B, 87B28B4555AEE7C57918FDC6B416098D30C9F380228B6227AF9AE72CF98550CCD5B4A5566CEE6FFECD9B8B0E024ED8F8, 70E5D13FD11F0FB5BEF6FFF84864B2C7A50B56B5C25FBF811673011CC98531B15F3318AB9287C6999DF07422AFD1D898 +5582FF377B4AE558D0211, 9B7DD39A6DEA392C0971B2303CDFF0F595B6D9C6F7BA2278FC6B1A292455199CD38CCDB75C6359C7F9FA637735E294F2, 4CBFE074C529177CEE79A3889C2906F51CB420DEAB24D1A2295D14BAD2CE1E63578F8E363266122A5553B095F257C3CC +10088FDA671E0B00A70633, 8EDE71C80007CB8C4066C7593C3139DFCCED7FE42B3F64A1F6CD10DBABBD1E7045579F746E2F8C8ECD83B7F38A0059D5, BB79F8822EACFA328432209422A511FFE4C4C1AFC8E02A826B4F163D886B58541BE647FE9B3C78A8906929E8D76BD966 +3019AF8F355A2101F51299, E49ADBC7FC61A49FF1F42CF80B980335A892F6CF196854A21D7C021821C760797C715E7DE1E985EBA92A2D2A6DCFDC68, 117B5A3BE910325BEE9848A9CD4B80A04A3D7E965D25B0290C7586536F2EBF609520A3D294F75D6FE4033EADC3066FB6 +904D0EADA00E6305DF37CB, 3F7D97C61511354B7012FAAA7D96CA248D218712BAD609F8C8BB582A4390A6FFEC4D84E7BC8C5275D3689280EB3B8F3C, C53855408A0A66DC02FD05315CBB896E4C267FF86927FF60A38FCD6E805285890F2C7A63BAAF85A76B220EE363855CE1 +1B0E72C08E02B29119DA761, 3D47F8DF16209777FEDC6E275C860D4D9A56E8CD3444637C0CA0CD85D2E6178880A962B8E40DFD0DCB149DC6AA93787A, A5D39B548BA391ADB45EF05C36488890D705AC1FCAB71987EDC2802BE6BE90A731598A382482B3BC96ACCD6F6EC59C85 +512B5841AA0817B34D8F623, C322629B606B407C8F1C5F604AAEAA423BA63F61AE9BE78A2B89B47AD8931C212F5CA0A95C1CB320A6B1BD8ADF139255, C6CB476EF4151210C3B251982E760E13E4E5C1441A8283C6F08406BB84CBCC4EFAD80A3C64F9043F31193DF5324DD82E +F38208C4FE184719E8AE269, 3E538420C3C76466E691B6247B0BE38DAF4798B81FD55C709C7C619D4B15D60F883E48D08FA6C053A24FC06E843C3783, 5A6462B1894C0CF98D111685EC276E5FA1AA1B9417A739FEE271668766AFA5FAA2B5B98EA63A5848C858CA487A9DB837 +2DA861A4EFA48D54DBA0A73B, 290B7D67190B64B175521392B310336F3B51EED4E82CAE26BDE9111D40D5A425B8CD7C492B3B428653D4428F21AEA32, FC2CCAE4FE20F15A659B6F07952D7C23DD36E771511DDAB346EFD02713F78F68827B7296CD6EC8BB98F9E53629F967C8 +88F924EECEEDA7FE92E1F5B1, 469599F3D1D7285564D2D19E9FB20E374661B95959F87497F6DD3019DA7D123A7A2794F97F61471FD435C478C7871E52, D6BCC6D99E3F448E7F6786FEC721E8408168CC3A49BF3A5D12D635850DAC424F8AD6CD7908292AA7CB11841B683A784E +19AEB6ECC6CC8F7FBB8A5E113, D8486C5E2126B1C0C745F38AA9A7C2CAB8CDC62677DB993C9179E3E72996CDE33C773D4F90DDEB6BD109EC9D295B3754, 180CAA2EC87EACA14D93E5A8B424090A76DD7E9E53299010848A771B4E565ADD29752719D5D69930AE8DA4662A7133C5 +4D0C24C65465AE7F329F1A339, 2F1767176C2E58E0F08B4A51F500F2036EF4D00E163504A2EAA75A374B2999F0486173A22BC4BFA2131C11590EA9749, 293A321223DD7EEDE4B1FD6C5CAD51FDEC7E11F19BCF3BCD15CA43DBC184944CB382D50E435AF3A7DF069E690FAE6A85 +E7246E52FD310B7D97DD4E9AB, 39C1DB044294452FF3AFA2ECE3A2A5E16D1A239C0B63A22A52386CB4546DD87599DCDD9894B95A9D17D0F15422A64244, FADEDAF6E5224FEC08E3A2B3294916FFA178F12984C3E777E1FBFA571E858F7B28AFDBCC0E24BFA7CF84352790BBC942 +2B56D4AF8F7932278C797EBD01, 9A23F134256199B6922DE8BF63A334D48D13823DD447E505373D5AFDE4FCD39329B5D1DF0A33B0065B769A278A07E525, 88EC25D8A2E33B51E8CA17D685FD9D48C82E420F1B9ACA9E789CF5BAE95BA8579F7D2884C0B61A400B69E75F6CC8972F +82047E0EAE6B9676A56C7C3703, 5DDF3AFB5D6453AFB90D7FBBF3F73EE9C15443A82E11A6E719F45B764E0DAFEFEEE11F1ACFE188F75AA277214E580F13, 220B6401CCA494C4E93E478DB4788C0173036AA99EFA9BA4405F2F82B110D68F24FE771078661FAF4FF4CE87DBB50A31 +1860D7A2C0B42C363F04574A509, B32F67F1555963943858BA0AC73C2B4FC2BA2F54681B923EAC5B129E832BA9AD25028C8DFDB250606E937277A3A85B1D, B0F39895C81FA823465E9DB3008DAE9DB4E7FA06B31C61539CF23429F9CD58FD296AF6761D8B258643C779B932A9A67C +492286E8421C84A2BD0D05DEF1B, CF13701368E0B66045CFC41D45E197A675F4B4C4C5D41BF6CCFC908C3826C6C2277B68B52995F9BE860EBC293A59A56B, 6D018EA175D603E924B10DED802836DCE9F0A44EB36094FD1CAA79B0301556B8FB62DD8886D5B2214F5BCA6731477AF3 +DB6794B8C6558DE83727119CD51, F55FF1C787A82E6DA78187C53100B3186E96DA39C7FBFD7EA069B28E1D0B2A1C67A3A93A0D5C79390CD1E2C9E03FDB3F, 541F5BA6D856B9C9BA325F7F0E60FC23E3CFEEA0D5C1316074ADE10586A292937DBE8D8EE191A5884EA9756A53DFE6EA +29236BE2A5300A9B8A57534D67F3, 3A3868C5F9CD908C3B0F19943EA5552364E99755BA974843D32609F63CC9483645365417A34670EE6D0B53D3ABBB1BB6, 8BCEE0B863EADC2DD0D5E528E9F4F6FE549E84DE48958F61201F3A7782D0FAE523791653CBBA5424B17DF7C650759E8F +7B6A43A7EF901FD29F05F9E837D9, 78D503528BBD16DFEE6EE4A6DC1F395A6F5595184953A790EC01A3B61EB8C5060FA3C5BF362FA6575F8BA54698231748, 10EE2DB69F3B9CC49C55547A1A765DC0D6B738E3EB6ED5FC48311358B5A660EAAD585B0DF4D7D5AD0882E8434FA3FBBB +1723ECAF7CEB05F77DD11EDB8A78B, 83925EB0FED9F743B04F4B5B343F649095C14C8EF51E079DB96936096B3E80B7A2A05550202926D63B93C92A737CB862, B4116BFC49CD206618C3ED100FCFC7789E208F83E5D9D95917FD45A5346D4C37CDA6AF21049E160A628B06A139562423 +456BC60E76C111E679735C929F6A1, B17AC741C6CADF3A76DE0FDF1F24B20129CE3B7249B8ACC3DD8325C09B1708389BB28F7F3DD4C9A0863D076DD614EB81, 1E42CBFF458CDE07A8A615D3E5FE7B519EC20071EE1A82C6B32279F823DB84ED192F310E6BED4F24780DAEA76E1541EE +D043522B644335B36C5A15B7DE3E3, AF1FDDE67323B8ADA15C00E1C5B1622C7EC3D4306AF6BD2CFD1ACC443DED11631E39C851A3564646A2EC4748AE6D2B25, 8FDB4636869020D89FCCBFD052B8ECBDEB72004D6F6745FCFECC1F3C66376DA7312203518B26C4D907C2F4208BF1C24E +270C9F6822CC9A11A450E41279ABA9, 801DB56BD43A50C4857BA92264D312816A1455D6686746FAD8158C380841C578750DC162B7546B14E1BBC5DBD43A5DBD, 4747FD5874A10E40E76DAB3C8D274426946D710857501D1AC4F32D93B3551C3A8E37C3EE12C9D6BE425F26A33BC8B953 +7525DE386865CE34ECF2AC376D02FB, 5562E0CCD78C58F382B98659B6C0BB6071EFF74A52BB1D90DFF09462CE1E1B3D3CF24CB722538E992DB861E8B0459C09, 48DD52612E8E79EB8F68B117A579EE598C4E04997BFC71FDA1E51A98F2E1A071CB95C6D40BC32C1330DC85C52398037E +15F719AA939316A9EC6D804A64708F1, 3C720118EACE572081ED712457E028E01A637A131FC16EBF34DF0B65142A6D66B813DA68A66AD213D18DB5A0A562D0FC, 806E1629250396C00C35240719499C02F8AE734C49BA2ED9095BAB5ED7C1743DC8C77478EFF551B25BC16066BEAC8EFC +41E54CFFBAB943FDC54880DF2D51AD3, A665E9B0F5EE4FEBC8EBAA787135EDDCD4DD64F5566F8C4A0214642D08D2C8E96D4A9F8B6A1DBF946AFBD47E8CC1F6C7, C793540EE4FC8D84C7C7A5C5AFFF7B9213E294EACD48680F184AE550C35C3B609C4E4524EEAC301FB7CA87B89255A9 +C5AFE6FF302BCBF94FD9829D87F5079, 698882343467EAC6E642E0634AE74826F0F8635825CB8631FDD461FCA776DAAFD93AD926AF0F1F723643DDABA86746FB, A15F7C8B2ADDDA5A50E830C56F5637A2701C5AB8E0F3AF776E746F35BDDAFA81200428BDFFC3BBC398FC22D942A32F8C +2510FB4FD908363EBEF8C87D897DF16B, FD10B62E5826880EC655B8FE38D8837F111FCACA1E3389DC9645350A8B17F0F12787B654C02B7D3BF6A72883552B66A, DD69AD5311B203C8709708C2AE9E5ACD6ECCBC71CBE837F05AC59188B2CF5364F9449446899879A40AF9A3C8A94D5172 +6F32F1EF8B18A2BC3CEA59789C79D441, 7D3DE83A27F5501DC3AEB5246AA159119CC20BC592B3A04EAC140383178FBD73DC291C6976DBF62E8FBAEB47E4EEC242, BB6EEA3848808EBA89EBE470AD2C79639BAD34367A4A9FA2BCE07D594416A87A03AD56F47A599484923E3B884CEA2897 +14D98D5CEA149E834B6BF0C69D56D7CC3, 56F6423CA135EDE0065ED6853DC33A5CECEA4BDB0FDCA5DC485812695AAEC1EA62E32F362A89AAF790CE385AA3B227F8, 7A23245FD401F4B8F806D92CB0DC01D070A17200105482F24B334C29DF436C8DE4BF74004C36F1716CE85539315DD47C +3E8CA816BE3DDB89E243D253D80487649, FB7ACF54D6BC1F87053A2A68EB73DB8C041E9BD90BA2D7384C2404D3BA6B989955A23C4A42CBBE592119EA57C7D130FA, 804F17D4B2F4347AFEA0046AD2E3AFEC66F320A40B2EFDC02FD2105A44FA3A4A39D75F8A2349DADF154830911D4C4D79 +BBA5F8443AB9929DA6CB76FB880D962DB, C6051F6AC7C8D3A0FB9617CF6B935BE246366DAC40D6DAB7D5CA3271109E74E9DEF5B5DCD34054C3148E09A8EE376F96, 17D5118CD46CB520EAAE22A5CF953AB6C6BF30C4E9903E5646AE4D3DABC0112D8A9DE529A9A730E11C97BDF6E24CF37D +232F1E8CCB02CB7D8F46264F29828C2891, 8226F16EECDCED762B53A5C236CB0473B1E426B7514DFDEA8E1D5E2236CAC6516A8354C0A9D8AEF2AB25B0AEB5642CDC, 8141785EECC969BA58EBFC3A0E0F92C17878E780C6823DED77CC8634EDB5151A13DAA506436787FBEF21FD02F43E1B0F +698D5BA661086278ADD272ED7C87A479B3, 7C6954982B5BAF090627E007EF96BF45BD189BD7C0AD6A22E5956739B60E534DBB10D4B52849E7F230BD8B0097E27848, 4414332E5758586C495E14D6501BF0BB312A7A93ACA75B4DC3C2E8295469039864A70CFFC1416D17C1D558AAD1B55656 +13CA812F32319276A097758C87596ED6D19, 845E24A572803B02599739D0210BCAE6C383FD36400A5AA96B09B89D88916732A039A546F77EA90718971D2520EE8F89, 8974A58DF0FE67F1B723EA739F578733B40BDA73EEE3DA2BB45BE94D485186CC3E76177C0EE81A32BAA03C681E4AAA39 +3B5F838D9694B763E1C660A5960C4C8474B, FDA6AD1957A6CF2E377D1E44E27DE0DFDE39CDCEAE40A2E830A00D2D514F939B3220FC1DAD3F08FA7EFA9E1D15DCD033, AD850C003BDA4DB0D2CCE0B47476AFAA63087A066FE9D9AB8E50B1E6980A810A485759238FA8FD45675BB4E04253D160 +B21E8AA8C3BE262BA55321F0C224E58D5E1, 430CAEBFF1D8578CF05091DB0C810C191E48C4A7B46A1623862DCB8992C520E62130F66EA8DF65A80874CD088B9172BF, 1360132ED83FB5FE4D26E29B84B4747C0C00E884A2E9FC206D54DC70291B8DC2F0BF0C84EB0FA93B471DC10D49DCE982 +2165B9FFA4B3A7282EFF965D2466EB0A81A3, 6739E6A985EA9F1EC9C93887AC7A821BF68B1833EAC32833602DE1BE88259C01BFEB412BD9352744DB2AA7E099F65C51, 8E364F68331A2812476F1AD0C35366CBF08FCBDE69BE8F74C33961F47212BDCB3F06B1B374F03F81AB41306A10692FD1 +64312DFEEE1AF5788CFEC3176D34C11F84E9, EDEC4A7A3F5843004EC311096F8353655986118E7ED362D24F31A214F9BEDC78BB0A1DCFC3B2826F45F9E5CC423D0915, E0BCFC02BFC1B3243A746B3BD9AEE8CC30861D93A814B41DF90D982E72A95C4E3639448C3BDF9581F1C2F3E629C31F9 +12C9389FCCA50E069A6FC4946479E435E8EBB, 58C6EF296B7580441B6F638E39610323882456B0367745A88AFC81787F1A39B6EECE6CD8E17E9010A9069FDB54C0B4AE, 3287198D302A7CDB02E65472CC8A59B26FCBAB2A3FA5E7A13B29D2A56E29930D9C0A55294507DC563C96010D89897DE1 +385BA9DF65EF2A13CF4F4DBD2D6DACA1BAC31, 8F460CAC5C0E019B2DC8D38FD9D74FC3E0BBCA91E1EBE5DB396CB991B23AF91A763BAAA0E1B192E52CFDE09E734B0675, 9CE93A27A6CFEA9B6928521EB9BBB07CEAD33D0401193CB279FEBEF0C2F5327B2E89EE0DE36B804F5898463912026479 +A912FD9E31CD7E3B6DEDE937884905E530493, CC18138D957D582F79133F05A4C8DE1443E6B02797C255A29C05E99BAA764B1DE0CF9759E5FAE7733AE10CDC105818D0, 82D4403C3DCB1607AD8D980895859E251FDD217725D1F6E543C284E75CB23AA8D6E42F824A943F05F1F1590F2B5194EE +1FB38F8DA95687AB249C9BBA698DB11AF90DB9, AE1E98C0EC6BFEDD0D6D06DFCE8BECBA637BDE30229D08E07BED521F3BAAEE494BD05C044BC69335DECB16A7DDA79863, 33EC3113A34D25DF5837E0A7AC4928C1322BA285F07F4543DBB67D79D9722B2D3A6E11E0C04B3967F422E0E19EA1A4D6 +5F1AAEA8FC0397016DD5D32F3CA91350EB292B, 59EB072C6AF606C6F56CB4EABAADB7FF55CA5F373C968D6D47B2884549AC41C61FC0C7A54928FFFE412D1748827C3797, 7366C6427125F79910555E2724556992738BE7FFE6D74C2211FAEEB7C64DC4DC37EB20B71A1815EECF1CAD70828742FA +11D500BFAF40AC5044981798DB5FB39F2C17B81, 34DCD5BBB389A5288AEC85E92DD3D603A6BDC4B912344A37B3906087666F63A9A5E1B98B51CCC55D8CE71E2C609786E2, CC0592FEA9284D16230652ABE63501DB123F74DFB960E5803B29B5488B8BB6C85F0B16B5CCF652E7E2F6E6F797E9925F +357F023F0DC204F0CDC846CA921F1ADD8447283, 6DF7DBC6C027088596D82132A7CE15311D34D06486A9698B561AA3B8856FC66419FB551B0B070DB0D38CFFCD1FEEAE33, 28FF1E1E95640E7CCB11E267C06284C3E6FB36048B8CE07B69FB8D6050704FD3DB2899A3C795A287D5CEA737BFE4F669 +A07D06BD29460ED26958D45FB65D50988CD5789, BEAE9EDD444F66A2EDC62B5BF8C0F40AA330F1DAD2D9AD97BAFD1A4DF7E126E9E8B48D05324A44C3B2CAD59A6B8ED27, 45CB5D6C9806A848325ED1C701C8D194C4697A4D9907ECE4322980E2143DBF7D300ED3A9F7C27C3A237881A71DF57EA8 +1E17714377BD22C773C0A7D1F2317F1C9A68069B, 8AD64B9BF757181B9C147A77403A713202106DB926B838F1E42B8074650779A3A585073FDDC369151840F72C846FCA80, 41669D2A06284F90A37175944E0AFD30512C02838BE0D3759B8827904086E35F6FD9B7ECE02700026100DBB1C129DB95 +5A4653CA673768565B41F775D6947D55CF3813D1, C3B69AAC77A2DFBC5D3544F50A09FC113E0A5FCB6B05144B9863DE64B42571C2B960DA075BD299BDA28F1C7F553EF53A, F6E91117168706FEDD13B5048AFB9255D8501CF8DDA48CD1E3E9E11D6C520A48A1ABCB7FF39062E7AC44D07001BF1AE0 +10ED2FB5F35A6390311C5E66183BD78016DA83B73, 535245AF848D7BAAEDEE934B11A06399F48DA9DC246649F037AB8FBA0D943667B589B229F3ECAEF118AC301AB40EB26C, F3C69A881DDB19055DF5278E6597220BBC130DBEA8074DD98D8F58F155EE67A180F1DF613749A788B9E1E8A18FCDA398 +32C78F21DA0F2AB093551B3248B38680448F8B259, 6E332109579449BA6BC1159763DD73DAA750407D51A6057F719643B1EE06C6C23D4061768C56C8F991A6DD6A48C045D4, 23D28B89995E355F98AAB3522B85682FAEDC9969D711BFB7907269B1E96EC48EFA09225EB1F0C2772CE3A6022D23564E +9856AD658E2D8011B9FF5196DA1A9380CDAEA170B, EEE848AF3D55232914F20D9D9858F0DA7D88608E3F95DEA3289EB042655E5BFCAE1FEBD1E4757E9A0A87005E9B77331, 9C81AF59270DA297E5A872F7A0295794AC84E9D85DE0C65B4A1CD40AE0690CC98C6E0CD89D6E689758116D1BF4EE7920 +1C9040830AA8880352DFDF4C48E4FBA82690BE4521, 4B44D4ED3C2F032A81CE01F5C3049B9F1E1028A9022E3B0B3C7A4476E9BDAB5FB7BC0CC016456A1DC16AA72838EA56BB, F36803A7483D04F05FB0E0EA52ABFD23AA5C2EF8E2B7097C58BD6FD9DB83AFE98F26FD21EEBC1BACE257FB41071A8356 +55B0C1891FF99809F89F9DE4DAAEF2F873B23ACF63, 6336A76D5D94FDE2A1A625790B044E38959C462C38FD202048B3A81DB7F27048085EF06D13A0F5DEA359285F636F42E4, C52923D0F12679656B59660FFA4BD70312045985A040CD858F7CD07E8E1F03923B92543186D2E87823B64F7CD9981986 +10112449B5FECC81DE9DED9AE900CD8E95B16B06E29, E1FBB64EDCDBF21B448243896D0DC028DFA9CED2AE3F184D978F29582FEF39643F36E0A0AC79DDDC13B5299D20BEBEA5, AE25787C0F1B3FECE1851245D98A149B7877EB90400C23A792145CFEFA26958F187B68ABB7C7A10759AA56FEDA55CD9C +30336CDD21FC65859BD9C8D0BB0268ABC1144114A7B, 269B83C644BD0217E3254DAEE476D3B8BAD3A7854B26A2DA8A49445DDE2D907BAB408CF736F02A654C4E104B82163271, DDC4F14FAB24E5496232BE99D74546EBFD28C9FC486F2EF27908C7A3C44D5248CCBBECA1645E327ADEFBAE66049A2D5E +909A469765F53090D38D5A7231073A03433CC33DF71, 60DE6F9CDB270A1813608B46B985565C1202EDDE62C3750A97792AA1F833A91093EF8F86DEC018FF2D427B849D966BE8, D6AD1734E5E3C4AAAB583F75862868EEE4D6EF2C6E7EFB22E73EA567854BECC038AA804E757D93BA6CA41165C9795E9D +1B1CED3C631DF91B27AA80F569315AE09C9B649B9E53, 917B6E9836F425605F20B8A77749A729C7E4F37A728363B03813AEA1B7B1BBAC195C6254EBB52EB9C5AC8026729E6D3, 77CA655D0D540EA8EFCDC1013A5E6C1FD4B4C9D4070A81047C476B2B78910ECC97DACF8E1A96708BD50F82EF4F13D19F +5156C7B52959EB5176FF82E03B9410A1D5D22DD2DAF9, 3A4894159A887E6C56EF92C6C88C6750BFE1D2D13647FB1B52623C8E96BBF4E4B61C1F0742859A18878A2A4965E685FA, F9E93CB6DC1BBBDA7F4B78CC4F64DA85CF8C70F099DCF2DC1648280B96105EF082140144B244A20249620F2CF5E8925C +F404571F7C0DC1F464FE88A0B2BC31E58176897890EB, F094C286632F41143FFB04A0B2CD8E5B787F09E0C3451DD5318528041D0CA63C5104D91A59640275CE525C0C8F067D76, 67024ADFC008C46A0D483ED77CD5814AE9E0D53C60C60D4D1C7ED25480A1E96002878118055414E1D661811AC3F1822 +2DC0D055E742945DD2EFB99E2183495B084639C69B2C1, 50C86496BE68E05F94DE7582524168D2D2CD8CC0276F49591D5FF71B5453FE91A11A6514C434960FD8C5B81956450BC3, C938D1C2209D48E5433B296B7FED13590C1FA6EE09FD4BF5FDC64743AE764DDAED4A086976530F6F25F9683B153C3F7F +89427101B5C7BD1978CF2CDA6489DC1118D2AD53D1843, 16FE8D74114511776207D5260CB7A18DCFF4BA22B020031A69A674107B65E87989DA9A0F72F63528E70F9915C8203409, 7DB56DFA23AB19BBF58F56576E30FF7D69FF5B5231AD17E315BFFCD97898F70F1A6FA88FB74F11FBA6329709D3EAB05B +19BC753052157374C6A6D868F2D9D94334A7807FB748C9, 20FCA562C8571FFC1F577B5C94FAABE2D5380E392DA26C522A85AC1BBFDA4C8C45806775FFC28A24F5FA0A4A964E9749, 2D2465AF770DA93F5A3F992E2FADBCC6D3EA627D6B32804838ACB0978C4F8C0A26C686C03C49E98F943AC8E7733A92C1 +4D355F90F6405A5E53F4893AD88D8BC99DF6817F25DA5B, E68405FEE3EE25E42DA1AD218C20AACF30D7448C4CF150A9622A8518D8DFC6F1D8469CFAF1C2C979443CC8C2EB1B088C, 889CF33EDE61331625C9F87C68F56417D125FEA6110B72EEF8569A5D005C0BCC8F2DF0F65B068DB4FC4A9AC5C0045D3E +E7A01EB2E2C10F1AFBDD9BB089A8A35CD9E3847D718F11, 4EDBB67E1894CB5A1B274499DB09255A8664299ADD5D4BD7194DD165ECF1F93939422E7B37A91E7DD2A017931F77ADAC, 2541889DFB620C0A68FFAD21565BDF7D1C7EB43A37C428EBCB8BE6748BF04A3513791A304BE52757CF925C1CBE06F027 +2B6E05C18A8432D50F398D3119CF9EA168DAA8D7854AD33, 23EEAD8B04C990E245822318E65390210C6CCC496252AA22BEA07F6BB4E133155E8FB686A27E74660E02484BAACF68A3, 756FEA2D2A57C404D5BB305017064DD529AB9140465FA3E99F812083D6281BD55C2FBB3BC2BD49AB2A8510190E935261 +824A11449F8C987F2DACA7934D6EDBE43A8FFA868FE0799, 257D81AC8456551EFF4807051969ECFF195098C16F7284260A74ECF69326D04269A31C9FD892F61C6DED793838389DF2, A019CAA36E0447BD5EDB2EB775A625024A5723C4296630B4EC4C64F5B4DFF7CBB270705A53C59121BE38A418A0876D1D +186DE33CDDEA5C97D8905F6B9E84C93ACAFAFEF93AFA16CB, B4EA5DA208AB4AC5E396DE24E497BA1AE849E1C051748F9521D52B0FC34220F11DE6D1B2DBB913910A4FA8DC302375F3, 7C9E108A52DB2853D5CCABAB873BBAA565746DD426B5C9C913DB934AC5881ACA09D13ABCC4EAF4C2C2E8807E2470B03F +4949A9B699BF15C789B11E42DB8E5BB060F0FCEBB0EE4461, AB164B4CBCE4672AE7FE5009859092D08DE511B15AC5D93DEC0174AE4183CF3B8E48DFA0E5EB56FF8C1B3DD90A2B58D6, FB3FB21AC0899F5EE414D74B727726B77927E5B803A86618178EF1AE684F9AE59F4AAA0BE668BD2C612225601D76B3A6 +DBDCFD23CD3D41569D135AC892AB131122D2F6C312CACD23, DF4B2ED8CBF816C905D49AB05AEC9207594DABBF714EFC8F4B042F4133B740FB4DBF2180D21A6E7F167F7958489D406F, 346D924EE85217C15047D68E5253C2B874EFA2DC5626572F34765006E0C802E2E63CFC90830E0E56D90F408099188F8F +29396F76B67B7C403D73A1059B80139336878E44938606769, 5A238C0C26189BB0B65A54935B9DEDD95393726976440BF373A6CFBBC6FC4653145CC89BC8B006A07ED37F2A0ECB0BDE, EAABAE89EFC6B022EA3AB568441DCB57B66C6D33C3E419ADBD17787D90FC0436B970DD920EF8417C6BB1D941C9C37DDA +7BAC4E64237274C0B85AE310D2803AB9A396AACDBA921363B, 6F6FD3AA2E7311C2E92A22EA7E6C3328F12298C2C963BE81C6F020F2708899AE1FF38BC6378DF21BED067EE89E78E938, 5701988546F00FC727989B485A1B61B06C2F8E6B9DBC924719F6685B3BC3D6B00EB2E8175217B04059606B2FA0245019 +17304EB2C6A575E422910A9327780B02CEAC400692FB63A2B1, 1CCD7B257AC9A6872C8810A060AB7E19430F7E4CA055FCD3611A3F2144C457ACDBDC241420B559581D2904FE211DE99E, 6492BBC9ACBEA3A180F8DD8692C08287C5EF99197027B35267023B898C97E59F3C97E80F37DF21C76FFA5E3DFFF064F9 +4590EC1853F061AC67B31FB9766821086C04C013B8F22AE813, 26E4BDCB7E4728FDD66386BD84DC8F9D1F970225DFBD3C0FE2F67D181650E1596D7EFFC026BCC5A1DC308E7DEE1E3BEC, 380E5C9DB3696B6FCE63A57F7C07D3B81A8E8E58986AA355AC2C9660B9921403AE264BD6BE95A007E6BCCDA136362967 +D0B2C448FBD1250537195F2C63386319440E403B2AD680B839, D2AA21E3F8C0BF9284D2E68C6825DC582F562A97B7A7CCEB465D842DEEB769A359012496E5CC04D171D4FDBF5982F8DB, 1C5B56811ED04F7178AB50C29B6E3D3D27755BC3359C1EBFF91DD3C768D6333C67074E51A7A349F9B723559177F5E42F +272184CDAF3736F0FA54C1D8529A9294BCC2AC0B180838228AB, 91AC5FEC6C41D4425E3897CADD5AE51ED472C57B703EFEA6AECFC67BE673FB27D8B804F503EADBC871CE70C9D0BE4F93, 47717619E6C0CA27B810F03E29869DB7D32B3471F1DE6B54657FAC227436EA19DDB03638ECF556C684426FEEACD6B87B +75648E690DA5A4D2EEFE4588F7CFB7BE364804214818A867A01, 5262D4A1DD05B932C7111E5AABDD63B28BF8D3D6722A69AA8E519BBD4F2D87EFF12AC973F4DD91BD98F2163F8E430C9D, B212E52DB29F450107779ADB7859DE9978C4674A06D9ED513FC68E4BB363B382486D06760B38B548E0C89074B01361B3 +1602DAB3B28F0EE78CCFAD09AE76F273AA2D80C63D849F936E03, 3EABD0CC3A97810473133BF0E8CCEDA93B3A16646F942219B55A767BE749AF9EDEC5B86FB10CEE90CFAAC82BDE809BCC, EF5D3C16700E6057A37109AB95DD32D86E6702A8A103CA0BF0E95600B128BD0794DC236F442288FB818419AE2D0CE047 +4208901B17AD2CB6A66F071D0B64D75AFE888252B88DDEBA4A09, EFB51FABA5E00921B4FDC615C3656C9E32C6E3FB0319C08E720C0537B42A037CA0D7DBEA1A9D1817663B919F50D6A19, EC313A410871C71DB05472484B0792E8257B781D366A9206AA53EB8DB56F3FE5C25A094CF2D84B147F696B6646EC984B +C619B05147078623F34D1557222E8610FB9986F829A99C2EDE1B, 661219AC4AF8FC7BF8BD2B25F39000A4397C9FFB10FC23440F5A7E33DCC879A1A7ABBEB89ECD462F7B7E895EB7EBBDDF, C8206ADD87BEEC60A01C55CF114D929E2ABFC2F51C8FEE12FEF28379EEC12254F9DE7111D4C1EFF50477C3BB0412D826 +2524D10F3D516926BD9E74005668B9232F2CC94E87CFCD48C9A51, C55C2D48774AE739DAB54C3354FD2FD48663E6CF1CBB52F746E91B8E96BA820B4365F4BB5EAC8ECC5198BF081DF7D44E, DC442CAAA1405C10CC8652B3263C52AA99A788B53CD14D256C1453D20911FC4973E77A5396D064C8D15570AD0177B993 +6F6E732DB7F43B7438DB5C01033A2B698D865BEB976F67DA5CEF3, 654F8444B40DC6ECCEA01F6FCC83E4CE74D39F33612C575F92683B2782A63DC1E34587BD40EDA8A69776E0945CA1FF25, C2D2275E31F42F004918F91901E663053392C1E49FBF375BC7B2188024CDC5499C01367BE41E0820D1F5868133BF0C6A +14E4B598927DCB25CAA92140309AE823CA89313C2C64E378F16CD9, 3F216AA2F0175611B41BC07B9B81F10F84B5469A2DD56BE4E2BF76948B9BE2E88A41A98C1E5CB617FB77548A828605FF, FC2986A007B72EFB5E00BB3E7A4366E08060A995DDF4FF49BA59CAEB193A3DD4BEB1ACF422F9069C59B668CBEA74262E +3EAE20C9B77961715FFB63C091D0B86B5F9B93B4852EAA6AD4468B, 49EC115431A5A9DC1FD1CDB9B3C46C80AB42AF7B02521881F5D2BDF9C14B5CD5D8AAC08FCCDED7B8A05C54F322C700BF, 90DA3972F2DAA834EEB421C6B557BF274410DFDD362410AA89EAA3D9677EE83A4B6EB5805D918E1805AC5AF73316A389 +BC0A625D266C24541FF22B41B57229421ED2BB1D8F8BFF407CD3A1, D0724A40A6DDE3428D9B2BAF2E00DA732AF48EC07698CF79A7CA9EB67CCBA3EFB901DD0063C085B085B9247B6A7AE89E, 72180D820606E4FEA96FD856BF0117AE642FD3D72E26296852D6EB984AFF90AEDE44380B84F8897045EACB6E38E173DF +2341F271773446CFC5FD681C520567BC65C783158AEA3FDC1767AE3, 833ED3838161710EEE4FC1F626831804802621B49ED0374D46F96B647C326F48CF96690B69893E489412B7FD9318CF07, 96FB35E7F381526147249C998456C7C3D7F757499A6D33F7C5093E019C2612A8FD24F7F1BAA032E9B0D7B46CEB052A6 +69C5D754659CD46F51F83854F610373531568940A0BEBF9446370A9, 40F2612CC9F0E96C6879CA085A5616E49DA57FEC8435FA5EBF939CE788845246970CB0E3CE1BC5B2EE613581C60A4A53, C317A1E6132860FAB9880F037C229ED821D812F7833743E6EF1862187D210462A6AE2BEA291A3457A280066E05894BB3 +13D5185FD30D67D4DF5E8A8FEE230A59F94039BC1E23C3EBCD2A51FB, 501750558640FA04A14396E4942F19B56AAC8BEDFE6F0CEA9162FD91DB0ACBC027BF394BC3C5454CC2F14353EB85AFFF, 48AA1ECA7DAD2DF287751FBD4CCA886EBDB1D384757EC24997C0F3D923884103EF6EC9AE271FB548D6715F1640C4E3D3 +3B7F491F7928377E9E1B9FAFCA691F0DEBC0AD345A6B4BC3677EF5F1, DA71BFFA9B3DFCC1C8C69F399535620181F9746CC43D11B7D18A6E058325494AE62D2770FC152C036DF1C34844DDA551, C59A5AF3370D830693263F0995094CC583E3DBA084F4D7A38F1DD12DD23D6F8E112A1B8EFE0B9E9C061931CD6071AD09 +B27DDB5E6B78A67BDA52DF0F5F3B5D29C342079D0F41E34A367CE1D3, C7B30F1ED4C3B57B38B529ED7406C0A3B2BD8B61CE67C1541AFD0CB78D14015271FC4A781367FF73BAB6063B062CAE1A, 8A884288BF9A200A768843EC58E978AD5FCB4D9DB5C3FBBFB46079B58D8E6FCB99187742AA4CEBD9784735107BBC2C36 +21779921B4269F3738EF89D2E1DB2177D49C616D72DC5A9DEA376A579, BF927F2AF838FAEDF98BBAEEF2659F53F63E4E9B56C0AD4B68650A420F70936E1FEC3912DE76ED20BE8A21D0DB77A422, BF0847721A506302EC96C99E6D332B92B09E0897FBEE42F4552D705F3458DC12F47CA0DD88F0D3E510000052D320C011 +6466CB651C73DDA5AACE9D78A59164677DD5244858950FD9BEA63F06B, C9BD2B3FD0F566D809EC8D7B7FD72120B2E626C0F8C641084B6A19A318BEE009A6D53A939E421DC87E713F8D9DEE1F24, 19EC304A50124DDEB962755B2E778741FA3B632B4272BA187D17A7D0EF24AED57AFA884118C32474E16454A5F4203335 +12D34622F555B98F1006BD869F0B42D36797F6CD909BF2F8D3BF2BD141, CAB3A4A9782F3622F212D2D7C0C2D9B6D4129A4A91A93D646BBB5EFB09C822E25800E1D2DA6B7492C4BDD5263C9791CB, 5A495C63C88F6A7BCC513AE17B32B1D787DCFF22EA60ED304158EDB9EE3C9B0D86AD42F77764D6900DF50A4B2EF799C +3879D268E0012CAD30143893DD21C87A36C7E468B1D3D8EA7B3D8373C3, 893E42A8127814CD00941183603F65B853DDE5DD89D33DBD2C7E2BF9CEA93F60B850D70C8CAA53143F6BFD34D9BEE20C, F71C691901A5B8198F97F5AF432760501A8C4948CA35A51EA6143D8A64587F78F794172ADC560320AFCCED3C6FA1567F +A96D773AA0038607903CA9BB9765596EA457AD3A157B8ABF71B88A5B49, 1A94BF7387BCDA5301E6B192C85D2DB9E77A7A018C4156BF22A58D501412379827E113C64E047DCF69BC2A9BE6203, 22434B28AF8DB072919E660298AE0B325B3440E366A6EDA5A22E2BD9A684E26909183EAC51B4DFCDB7FC1C9F497F0162 +1FC4865AFE00A9216B0B5FD32C6300C4BED0707AE4072A03E55299F11DB, 5F83049AD2A8EB2F763D965E30C08DB85ADCBA02904E9FF60352E04C592A2414FF7BDB87A622CEAEEF82B380DCEC45B8, B884E47A9BCD85D71B52B574202973FD66C49D5ED9896ACD9AA95CD70D40088AD0A88CAF5E5D8D24AE541C0118680FC +5F4D9310FA01FB6441221F798529024E3C715170AC157E0BAFF7CDD3591, E6427E2A57BE5CFC7B823528AD5100BC4154789A9CFB5A1D93536A24E72A4CD0D3BD385E4AFB5ACEC9E0FD37F42B832, 775AF7E903ED68D4456252EBEEE04FA5C1FBE917742D179FAB27A2AF16F1BCABA2131F6A66842C26A406098BE0778F63 +11DE8B932EE05F22CC3665E6C8F7B06EAB553F45204407A230FE7697A0B3, 892FD294F87BDDAB30F383CECC76D1597ACF09DF87254C3B4E1C6C8B5135FCEB17A6D37232EFA3D8C45F16F3110B17AC, 4385E858C8E3471A4DC02ADA4584808333B2531B6F5D23466BDDF2A545ECE801B44F800A82357080E53D254436436953 +359BA2B98CA11D6864A331B45AE7114C01FFBDCF60CC16E692FB63C6E219, CA910127E96D2E00398B88A8933D9CF5DB362BEF06FB9A9A465C64C76749F847B914F5DA1761AB26B194EE879F081F5F, 98327BD190C9F4C1B941789842DD0B475B5B81670F80CB823A77901CFA8222D99E538D72217CD5DB2D2834122A711F01 +A0D2E82CA5E358392DE9951D10B533E405FF396E226444B3B8F22B54A64B, 8C4944FAAD1A578DF285E647447C815DBCBC7070CE37468C4F1DBD28EAF0F05375DF76411B609B71042839631F5A858D, 64958FA8D1DF71EA39B7DDC72CD2043669FFDA77B02907D1F34D763645E013019A0A871D73D01B340BC4F45E6340EA4A +1E278B885F1AA08AB89BCBF57321F9BAC11FDAC4A672CCE1B2AD681FDF2E1, FF7E584C289D4D97215C9C4372ACEC259B694574A8AA749056181FFF3F601716FA972FD2DBB10452DA351F10FFB630C0, 108F5B4B48B0FD567D8A7A6DFC3A7FAA288503581320618BBB9C200124D4CD51E479CF32096C3E6DEF66A548A268BB66 +5A76A2991D4FE1A029D363E05965ED30435F904DF35866A51808385F9D8A3, B533B5DCC6D8C4666AE835793FD39E87CEFF57FB7C113A3B99F82D3448FEC01D088F7DB750707B5573ED055E755A320E, E6478E7F94BC2338C551AC03C60D868B0DF6CB6654397F6AC90B8C1251D2A1E1D2FB71D5FFBAF46875FE0CC10B4CA7AE +10F63E7CB57EFA4E07D7A2BA10C31C790CA1EB0E9DA0933EF4818A91ED89E9, D7DDCBBA259A6E4018A0F62DD0DC6AF8412BBA1F0909C88E71B83D9A75CEF1A66F8A27B5A8754AD77B0A9A0C64B8F0FB, C490F422E5A8F64264DA5E82693640C5F0505F924F553105130CC705D4F469E3768D9A29DCC2F9C1FE6EBC4ED8340349 +32E2BB76207CEEEA1786E82E3249556B25E5C12BD8E1B9BCDD849FB5C89DBB, 3AC066784ACFDED2405E992A297EDBF9970631B2F73A069661887ADFFC84DD35121F3C61A16A9DB441A256CAE3AD76FA, 2902428EEE224C9406A319FD6068F958A7AC490A6DFA71A0D5D6DCDF06412C68C2FA3FDEB0D8266BACC42F9B6CEA601B +98A832626176CCBE4694B88A96DC004171B143838AA52D36988DDF2159D931, 90434B263679BCBEC06BAD5BB43B185E912831A31C0622629F80AA005A09C34B650FBBE82E735F4B9755157E1ED7F619, 5FEB842F99CD571202E05EDD9DCEBEEE7133A387A3CF3114DE210C2B076FAB65166B4AD46211137CCBC156446F348A01 +1C9F897272464663AD3BE299FC49400C45513CA8A9FEF87A3C9A99D640D8B93, 2216B8FAEC60F877265A440D0F311E65E6AE312BE03260408A01DAA1DEC1C18003C2965461CEBE6145B99FAD6A4EF282, 5FB5B6A1C7BCAA608AC9C68AB4D3EB4194A035835D45519F34DE59AF4D34B6887C3394500AB59193B7F6458966774AAA +55DE9C5756D2D32B07B3A7CDF4DBC024CFF3B5F9FDFCE96EB5CFCD82C28A2B9, E03EE03D488826AE89725DBB0038E503F879AEC7DBD3C7A88E522246BE8B2C4FE2F1FF10D55B749852AC2BC9F54C5078, DEBBE08771240ABD85A508BC64ED09CC78787F97393C58BAA0748BC9D31F8A107FDF88F018596C200A4EEEF0303D10CE +1019BD50604787981171AF769DE93406E6FDB21EDF9F6BC4C216F6888479E82B, 6CA1BD5FF27D68C0635823A156C58CD842077B12D050729DCCFEF7BDADD7A700ECF11451991C3A304EE485072DEC2339, 75E0EFCF80D47859E030BB4E89D25F36A6E93A4FD19F8193FA267752304C8B084C426C0CD2811BF188603E19B639694 +304D37F120D696C834550E63D9BB9C14B4F9165C9EDE434E4644E3998D6DB881, 6E7FD0CB368344068BE614E8D3C54E920DD4337ECB645AB816BA42032C40AF9E44A78D478A7D00783FC23AD0C6C6D3C5, 6B8146C68094E6FC6877EE99966A4C9BD7B172755454A90BAFFB9B9ECE25D0C1188E723E783D6C2C4A11E22B65DCA5CA +90E7A7D36283C4589CFF2B2B8D32D43E1EEB4315DC9AC9EAD2CEAACCA8492983, B796AC582388B56FEF9D37755BB7E529FC393C59817E2C2A30365352E3058BDEBBC05A17474C9B21BB177E4DADC90A38, 58112D40D3398F49094196A8FD81090B1CF4F60C8FE567D2521C8C0DB5829B75824557C00105D9FE407CA1F222BEFCB +1B2B6F77A278B4D09D6FD8182A7987CBA5CC1C94195D05DC0786C0065F8DB7C89, 6722763349DDE6305488A56BF54C65EDD505C368D147C7C5ABAE253EDD874D927E270641EF606DCC5944EAFB5C816755, 67BECC5F12221AEE2F18EA6EA98B1AC354480566B271A2A95CF15D7AA7C4B40EE41E2A7759D4223E9DF3061A972B9994 +51824E66E76A1E71D84F88487F6C9762F16455BC4C171194169440131EA92759B, 1D7D201EB1E6DB52E1D4EB87C857E0933378768238B02CBF74864BCD3585432670F7970AB150C6CAD21C4CCCCE9ABB7C, 6429429FCD058769C0557F1F591D22804C71E34CF62A92AF3398CA296A3D422DA76326AF7D3401CB0D922C35B60468 +F486EB34B63E5B5588EE98D97E45C628D42D0134E44534BC43BCC0395BFB760D1, 818DDB262DBA224B41A4E6BCB3BC5B06D2E1215295A5795BEE762A2B1AB803ADAB1CF78CA1E9B428678766C7889DC0B0, 2851BBC399216D09B52E3D0F518FC440BC11E65B8F60FD5F61FCDC544740F4AFAA080880158B1E899F4CE19427F89E4F +2DD94C19E22BB12009ACBCA8C7AD1527A7C87039EACCF9E34CB3640AC13F262273, 60D6926E594171B8C88C1B85A317653FA0A5BECF9138BA15BC5CDC34DA139DB3840B90274CA4D92F47BA84D7C045D616, D0872A2E735DEB24AF801252B2096E2A340671F7B4B2B89063C2F2E4D51ED48978B99FBCA36F781F0A805FE8F4AA3304 +898BE44DA68313601D0635FA57073F76F75950ADC066EDA9E61A2C2043BD726759, 6CE00FFE436BEAEB07C97C3E273DD166D9F292D8CDDE885B04697A77267E99C7B3E84CEC74B08974764EFAFCED7971CA, 12FC43F043C8B8BEA9C9E1CA67602DFAE22C2D1B9754CB44F453FAE6710A31F338924DE4FA9AC00DA116B61382D03920 +19CA3ACE8F3893A205712A1EF0515BE64E60BF2094134C8FDB24E8460CB3857360B, 9D96088E2D41DE9BCE458A6AD83BFE9631CF5461616B5CA08F300DB605A0FE950D76176D31B7225F7E13866FB57FE5DC, 5FCBC3C27E8A2E16B95CA9BF832A7EC4186429291164CC134F6DDE96DA9240F13561D5E84FA4EB13A1E41BD6837B4CFA +4D5EB06BADA9BAE610537E5CD0F413B2EB223D61BC39E5AF916EB8D2261A905A221, 2D3410D1606FAC3B4DBF1265C82F2D5F211035E0C2E928D0A9D151323F7B32360E52238D422679200EF62DA2E6C36013, 79B4F256438C02B3DD0A5CDDBA9E1F6E18A9D669D3652F8FADD79A530F8C22C54029015F15B1094179AF5D9B4B9089E9 +E81C114308FD30B230FA7B1672DC3B18C166B82534ADB10EB44C2A76724FB10E663, 172FF498DBFF706541FF31AFF32E3EB9F07FC81748CD84A8AEC1EE9CF35C2E17407A812DDAA5491E32E83F69AF427086, 6F67F66B7BD3FFDE4C80AEEC026E31D1D7CD459A6360ECD900A879A8BD427D340B0A925DA83654C9855C04910B11768E +2B85433C91AF7921692EF71435894B14A4434286F9E09132C1CE47F6356EF132B329, 31626266CF735F78C5A9BA98EF6A9EB3B714077365DEA9ABEDC4CBFE1812E4F819B5FF3123A2A7AC683EA42E578B6DA7, B0FD65EE7A38E4A4389412811F42A0FB7B223183A2292FA0CD8A5C66F054C987D8C1FEE7A571A2B45D8BF126BC1BE5A +828FC9B5B50E6B643B8CE53CA09BE13DECC9C794EDA1B398456AD7E2A04CD398197B, 49B9BE9070D4BBCAEF23333DEAE2A7E39846EA57C853C59249048D6CA3C72EF8AC5C159B371E16F599BFAAA358FCCFC9, C440C717EBFA22023D74BE6945C7F0040B52029A42AC9FDEF1EF3675478C56F01B71AA26BFE0F30E7194C4A9226839FF +187AF5D211F2B422CB2A6AFB5E1D3A3B9C65D56BEC8E51AC8D04087A7E0E67AC84C71, 23D7F597BBA17B451745CA23428D62BA70713DD5B5B5B8FD060BA4D7070F3A8530996EA96CF6C423FEE9F1D28B12C222, 1EB5C7A12590265923F5C803E51052B75479B2AF848C4FAA898C9F93132C3731BBB62E20B33F7069645A6B9802140E57 +4970E17635D81C68617F40F21A57AEB2D5318043C5AAF505A70C196F7A2B37058E553, C52B3E6360111931BBD8070F79BB3F2B1C594D7D8F2900AD14243F19A9D5D739FAA0C88F30D7C6BF9F9832B4230D8D71, BB82ECF98204BBCE23A794D5D049C9925C1321E8F7EDC9528DCAFE06FE96ED1E11C99210CFAA67AF4A70B5551E95B337 +DC52A462A1885539247DC2D64F070C187F9480CB5100DF10F5244C4E6E81A510AAFF9, B2609AFC57A8238AD4A3C14077736B32493452C962D369BA4ED8182550EACE70252EA9DA790C98767F46A8603EC0A53B, 9E83C5FA32789C1E8BD7DBE04D0B96780C93EFF30FCEDD284D023E588FD1268CAD987F5698362DE3ED24D9BF3E29EC97 +294F7ED27E498FFAB6D794882ED1524497EBD8261F3029D32DF6CE4EB4B84EF3200FEB, 2AE916732DE7DCD8C8527890C10AA218688B578078A25033CDBC57FAFE79AF82E308D860BEFE747EAE19F5ED8FA9D136, E5993D6EC3EA6D8E0CB58D40379B6A0C489D455F9AC54297A41D20CBF958CEC7B35A0259E0E244FEED1EDD5EA86B9AC3 +7BEE7C777ADCAFF02486BD988C73F6CDC7C388725D907D7989E46AEC1E28ECD9602FC1, 7A74434DB230C40AAA6E6696EB973AA6A02BB1A85EA9B403B21B7F4F83404FBF79D11B4DC4264C848EE9863D49DF631A, CC6DA04984781D57199BB36EAE63B650402DEF1968216EE194BA36AEB176B7BF40DBDE28F6465ECF3371F040B9A6AFF1 +173CB756670960FD06D9438C9A55BE469574A995718B1786C9DAD40C45A7AC68C208F43, B8F7F463E8DD26A1A5FB48D3DF0C08A4F2ED37877B4A055FE4DBE0BA4E8761C1D572BAADAF2A999C4148B41DAC692700, B9141FD5AC249FCEF63CA1E13852ED4A874314E74C8F7F1595F7742A8626D2852F9EAF31AA1986C3E57A80826D3F4C58 +45B62603351C22F7148BCAA5CF013AD3C05DFCC054A146945D907C24D0F7053A461ADC9, 68E34CB48DBB00929D9BF6FCEF98A117BBD510C2564FA29FD2735680550BAB2CD93DF8AE1E6A4AEF1156A7093BDD07D5, 74FA37802F53F3682BF03F2BCA48C833A7B40D1AEE181FE764459A62EB99AE94E0D92048186717CCF2AAD7C483F6BF19 +D12272099F5468E53DA35FF16D03B07B4119F640FDE3D3BD18B1746E72E50FAED25095B, 4BA1856FE53A35E25635AAB9F080EADD97F9C96CC49D01293F6178F5B09B736C69692401143D1200CEF4E8B52C5984D9, DD8D0BBFF3E6511AA4530671F525ABABFEA2C5D4500C151029232172FDC69CE5C69BB53A2AEAFE99C8F7FCE1EE25FECA +27367561CDDFD3AAFB8EA1FD4470B1171C34DE2C2F9AB7B374A145D4B58AF2F0C76F1C11, 23C4C7322C274C1FD10B4AEEA784FA4C8A7A8E72536EAE3F8A97EB3FB1B2B8D7E880A39B3B0E4DC95F1C704F0ACE2F38, 36FB622E09A43F62A4C543488A3239F341D231115C4BBE0D7577883A109ED94B19974D2B87B6D1A324DFAB73C6DAFE03 +75A36025699F7B00F2ABE5F7CD521345549E9A848ED0271A5DE3D17E20A0D8D2564D5433, 29E716AC4CF5EFA90E79D99EED9DEEB46EC39229B477F887175C6A68CC6345B5ED1A760FBC997E6CF3EEE584679271FC, 2DAFEAD17CDAE27C83A8ACEEBEBD1655719C74495B1BD05C123254CEE24D348B0E6C3649409F391AABE51E6006E45A5C +160EA20703CDE7102D803B1E767F639CFFDDBCF8DAC70754F19AB747A61E28A7702E7FC99, A840D7F9FEB2351C3C6BF1872AC022AC068F265F3FA0D814762119C514BE0010F62DE741E466AEFD5E7F72190AF5C7D, FB0E5DF0996F206E7154411E990D83D0E73397A27FA795B814B68B344F172248B0F1B7789840B792564D83AD898510BC +422BE6150B69B5308880B15B637E2AD6FF9936EA905515FED4D025D6F25A79F6508B7F5CB, BF0DA77B49FBB8EA2BB433C8873D96485B4A623820B8FDF825A34B7BB5EA6F0C415102C6BCE038424BF3D313BBD3E7BB, 38F81B9F33DF390BA1D1001A09530E35E77F91FAA3FE35CB5C95FBE7DB45E89D9BD081E98A0A1D7250866B27030F11D +C683B23F223D1F91998214122A7A8084FECBA4BFB0FF41FC7E707184D70F6DE2F1A27E161, EF1240F5396B769ABB10781B79F9A1D04C94B089512298B1EE4A1E5073C21FDDDF9EA1106E9C73DC0C27636F6B11993, F0451FDAE15BD55E1992AEDB6D907DD0A6EEF5E9A0872BE6042F8E848F536180FD13EB71D792E0F8FA485C8F658BFD13 +2538B16BD66B75EB4CC863C367F6F818EFC62EE3F12FDC5F57B51548E852E49A8D4E77A423, F3B8A70AE9920F885DA2487B839FCC238E78D3D98B24EAB8B29F329159AB1A28557B0154C92F7268CE9F48D8C47DAA92, 7C544793B5EDD523D217EBBB4EA3C36F8075B1166C06567F6538C3FF5212EC7AB422CEDCF5B4CAA86DC9CE28E780F66 +6FAA1443834261C1E6592B4A37E4E84ACF528CABD38F951E071F3FDAB8F8ADCFA7EB66EC69, 5B9900B2E181437F20C7371C9EFB6DDA9709AB3E8320AD75BEDA3D0A2454F5B84CFB98311F0EB15CE447A395482A31FC, D16A898817F2C9FB2DC857485F9BB615A5AE7258BD5992A565FA74D2232FD754E70EA35EAA181355AAC3374B5BD9FED2 +14EFE3CCA89C72545B30B81DEA7AEB8E06DF7A6037AAEBF5A155DBF902AEA096EF7C234C53B, 3B8F1CE353ACB011F49C9064C619BAC0DCF51E18ABE28DEA414A81531A565D5BF948659CC68A92060658E8706B1254B, 6E9316CDD398FD11D8795CA47382106FD573838D14E6125F228D75F9CB9C0658E4583CE3C6A72A977C29F3F89141FAAC +3ECFAB65F9D556FD11922859BF70C2AA149E6F20A700C3E0E40193EB080BE1C4CE7469E4FB1, 6AD6980445D9CAB83CD3537B2EB1672E3FCCFAFEEE9B71367E60A47790A0D46C1DB962810D734F207A1422034C055926, 61CB8721438BAA0F4135DBCBF1FC357611944DBC71C99436874AA3CE288410C02CCBE22225588524E21794FE443C8DDD +BC6F0231ED8004F734B6790D3E5247FE3DDB4D61F5024BA2AC04BBC11823A54E6B5D3DAEF13, 16F274584C49E3A1F20AF403B4F8440FF0D6AB32A1A23C07DA5848183CFC509401EFF5114818FA45ACB81903040C2EC3, 23FED4B22E70E6EA699F33E154A861E4AC2782AEA62D54D7CA1FC5893A584CAC39443F8FAC3AFBCF9C1B07386C209D1 +2354D0695C8800EE59E236B27BAF6D7FAB991E825DF06E2E8040E3343486AEFEB4217B90CD39, 1A5825D393E1A47191EBA134E7D60FF6113489F99384AE7000844A47EF1781079572BFA26BDA0D2951C7BDA1FAC20999, 752EF2C8EAB59125A80DD0FE3C442A2E0D50A69D7E01BF0DFC3A98413C041CA449B8BAC885BCF6F8BD58C604A12B6967 +69FE713C159802CB0DA6A417730E487F02CB5B8719D14A8B80C2A99C9D940CFC1C6472B267AB, 3B82F8F2C80125EE2A43235037F5B95373B0422FA2F571B50F88EB80C2C8131C8D8B3F64DB9FA15CE443CC15989B2BF0, 5D6B663E995289465BBA3CB4288FE2931243CBBAC8B11A24B47F1C9D8796FA8DAB75973446211400DAB640F13E6EF994 +13DFB53B440C8086128F3EC46592AD97D086212954D73DFA28247FCD5D8BC26F4552D58173701, 6D23BEF6019F6DBC92F4397AF380D0BAE72D88EDE78F62C1AC8A66A5B9F7423F3A57362503C9AAC6BF098F3863BE678E, 15621BA770C918EEAC97C8EC21C98FD27DFAFFBF9A2993AD6C111E0070A2E7140ACCB878C2FD39D0D32346C7C4231A47 +3B9F1FB1CC25819237ADBC4D30B808C77192637BFE85B9EE786D7F6818A3474DCFF880845A503, 516A07F49BDDAC28057A613D5C5E8B3DE0B7D33F3DA6FA38DB282959CB5D0DEF0656CB453815DB5D27E04DEE3D5C4979, FC0892ECFD57BCB0BED19F4E9391CEEFA5867C2E497A0B8D537A5B244985A305DEF1E28BD873622A1FCC9DDD20D69B82 +B2DD5F15647084B6A70934E792281A5654B72A73FB912DCB69487E3849E9D5E96FE9818D0EF09, 663334009EEF0F5BDAC82A98842DBA6C290AF03FDED8E8933800DFC77CD1F21F47E19BE9F0E916D6ADD5458FA9AE757E, C145C26410F722906D5AF84E072D953B6BC2A07C6C8966008FD38D12D1B8E514CB467250F0C5BC0CF80D4FF056D1ED2A +218981D402D518E23F51B9EB6B6784F02FE257F5BF2B389623BD97AA8DDBD81BC4FBC84A72CD1B, 695892E7A578108D9605017456CCC44A0228E3A0CEDEC67A8A5CB219F35626A73228C602DFF9600C2481E1A52F881B5, 803E5E1E1BE9ADF9F8B30EFDF941BEB8AE011BD1C2E4C6AF07D20ACBB88E9DA82F24348AB83E3941B75A3D0008A341B2 +649C857C087F4AA6BDF52DC242368ED08FA707E13D81A9C26B38C6FFA99388534EF358DF586751, 8B86E7D53BC4234563A036A2AFA90A98A9FDF86687A4C3BD60878AEA479DA1EC10A9821CEEF5F50F4C72CD8B58D64452, 2BE84EAC8BB312E4B313DD09E302854C38BDF82A1B5E9C0907F1477D8AC09E0E1C77803827E5E0DCCDBAF0B309E37330 +12DD59074197DDFF439DF8946C6A3AC71AEF517A3B884FD4741AA54FEFCBA98F9ECDA0A9E0935F3, A796AEA61F3BB341C35F547715FEACC5AFDA9D48985E424B89251D9BF11C99A5B10F32A8FC31FF136D016E74E7C7415E, EDF583406BFB78341830245DB5EEC7F601CD84AEB9D045A6F1B0AEF7114F5B7D4A6C9A1FA61A3D4C3A16E2FA1056E191 +38980B15C4C799FDCAD9E9BD453EB05550CDF46EB298EF7D5C4FEFEFCF62FCAEDC68E1FDA1BA1D9, 4AE935C284776ACD166F4C343D5D12720C1BE8C88CBB9C7BE9EA1A70466C47A58CA7B5A2E5B8FBCAF23C0DAFF65CFD31, 91F85E4F305B7F1716C9CD45AFE07B797E70EA8B823F25721C58BD89EFE71F7C978D4B1180D7A88AD6883DAFB5B2D40A +A9C821414E56CDF9608DBD37CFBC10FFF269DD4C17CACE7814EFCFCF6E28F60C953AA5F8E52E58B, 63F40B7C626645481A5B538C360EB288121A3EEEA90DCAF7177E7DF8041655109424A7BBDE730D1E09D690855A7B4A1A, C28E69941D0632596D822EC58B9B6AFB16E303D3C63302A9BCEDD5A96E06B683E6ACF1BF544C83893E9E667A425BFFE4 +1FD5863C3EB0469EC21A937A76F3432FFD73D97E447606B683ECF6F6E4A7AE225BFAFF1EAAF8B0A1, 8431F65646F1A9FD64333DA2687925C55EAFA25A69E476E3DA1CF415A1F05DB42C4C05EA4469179EE0F90C2D70213DAC, B0162F02D0FF9D64A3F6F92C0017504EE441EA61242F1BDBDD6FCAB0EB2915B91C538D435C6D3F400315C42C60E7A4A5 +5F8092B4BC10D3DC464FBA6F64D9C98FF85B8C7ACD6214238BC6E4E4ADF70A6713F0FD5C00EA11E3, 720CB31D6AF250CE026759C170577B008337D57F53A751EF3A9FF29F89601490E5F69EE0E2344481AB8C8809ED64910D, 7483272A9609DCB8BEC8FC7127F05F6AD620E65351DF224D768740B155D7D13BBBA239B38640AEEA65D5FEF11C39326F +11E81B81E34327B94D2EF2F4E2E8D5CAFE912A57068263C6AA354AEAE09E51F353BD2F81402BE35A9, 3DF3D364A95EA24C74117A960CD50445ECB524933484713A87342B06622B975313AC26A82357C46824A50E983E794194, D8008224ACFFCCBA4A2978C20794F25215FE7A5767218CF26B017EF7E1DAB692E2A2CBA87E7A95D3BCB35A6110412906 +35B85285A9C9772BE78CD8DEA8BA8160FBB37F0513872B53FE9FE0C0A1DAF5D9FB378E83C083AA0FB, DF2C5508681B1AC68D71B67556F13BB4A0661BD8266593FB948379D2CDEB836B49B5170A9C309284ECB59929B0AF5434, 906F784289214F86A978A719108537B813E3285290705F2F2E10D617554B898F98B72286B96643D7B17D6BFCCE75E72F +A128F790FD5C6583B6A68A9BFA2F8422F31A7D0F3A9581FBFBDFA241E590E18DF1A6AB8B418AFE2F1, 7B07D208B5A058E7D09112F3A875A58D0D080BEF1F931D83C6F276F85398FB7ED40DD192F0315D7AE8DE0DD00E40143C, 1A7551F40AD14AB1911F794C368A53E6735C3F3A5EA54DBEA88D99BF4CDFC051BB6FD19185CF15ADE25859E4C82AFBA9 +1E37AE6B2F815308B23F39FD3EE8E8C68D94F772DAFC085F3F39EE6C5B0B2A4A9D4F402A1C4A0FA8D3, CA85DC8914314A4F365B1F278F28E0A74EE41E7FC277861406E74E23F6B6FC1A4BD2C3858C71098296B98CF738F47105, 4A964F885C21C5F5D39EB292D2449571D1255459696C4DC9C71CDDBE7408538E33DFB7931530F27DE203B1758AF5FBCC +5AA70B418E83F91A16BDADF7BCBABA53A8BEE65890F4191DBDADCB4511217EDFD7EDC07E54DE2EFA79, C1B9607B4E9DE23B63A46331D0C4B5AB9E6EB094EFD7552081A6B2457024209B108BCD6CEA1174282BD06B34DAF330FF, 5B1C62CDC41E849CCA465468171DB1F5484A0EC6C62D5F94DB5C2FCA5CA6D65322A6F36375D810BC5CC972185F843728 +10FF521C4AB8BEB4E443909E736302EFAFA3CB309B2DC4B59390961CF33647C9F87C9417AFE9A8CEF6B, 8B8B73F58F59088BD5E624F68B426656FC6D90812AFC7AE3D4E28F3532F218C65D21BD545D325C4B6A6BEF298894ECD0, C700E0E02F65DB161A44B5A83492654FC519D1CD37C190DA83077452D21681DF52F06DC3C4C44B830A115BEA40B96A2E +32FDF654E02A3C1EACCAB1DB5A2908CF0EEB6191D1894E20BAB1C256D9A2D75DE975BC470FBCFA6CE41, 440D5BC580B0671558717901C5D909422E72AEF58AD0CFF4A2232EC8BCD98619E81B131583F8F7589DB5DD58D9E557F4, F868CD69FFC0AC254E75BE18F5650456EE793CE63DECAD62F674CB71A9B80A010D46B5E4A9CD3FE2DE626873F7E6BE5 +98F9E2FEA07EB45C066015920E7B1A6D2CC224B5749BEA62301547048CE88619BC6134D52F36EF46AC3, BD75A8FD05141C42E256A896D747F31E1FD5E4D9BBEBC6B03AFAF2D787A060582C097329F581B6D39B0A1505FB8A6780, 9E26B1552C65DB9475D1BBA9911355EF925895C906C9C836160192BAAD415C0B1BE80E280E19A3C60B761AB675308060 +1CAEDA8FBE17C1D14132040B62B714F4786466E205DD3BF26903FD50DA6B9924D35239E7F8DA4CDD4049, E5FAC224173981787051EABC0D28F0420B0DC0859F0675E306AD76AF737F5D40821AD62B59035EC94AD2BF9A72FF7A9F, 39F695FD0A751F8910AFF1ED0C9CBA4AD1015C9E098078532E5CB579357277F29D61039650B90D3AC4BFE6C2A34FCE75 +560C8FAF3A474573C3960C2228253EDD692D34A61197B3D73B0BF7F28F42CB6E79F6ADB7EA8EE697C0DB, 2889DF3262DE61C93D8A9AC7A33E9EC88268D744788A4ADE8AD19102E3F647725C622F80AB654275CDF450239027D9A7, C330BB3D4BD5914FD431AB21612DE48893A1A3B25BCC1E9C03E926280BBFE5E5D8DD7A71449707B11B818C6035CB1ED9 +10225AF0DAED5D05B4AC22466786FBC983B879DF234C71B85B123E7D7ADC8624B6DE40927BFACB3C74291, 807E3BF550B32E277C88533440666708A429FE39EDD1FDBFEE02FB855AD4BDBBCCF91048F74A61026C44F550BDCB305D, E7B5A99A3C298578676B57D21B9FF5C0B2A499B1494016860F14F781E21FC883DBD6A5D6F47E2E6143E1BA2CF2E22F58 +306710D290C817111E0466D33694F35C8B296D9D69E555291136BB787095926E249AC1B773F061B55C7B3, F7EFDF8EBCBD56156CA8D4A9F5568481919826980B4F7E667C00FB84360BDC99E2463C7A617B6B81FA6BA95E9E88C098, 327A298A1A2306076C1CB70642AB1DD09A26502D450D370BE6D7976651839A483F015D9042F6906D595FC75C80005097 +91353277B25845335A0D3479A3BEDA15A17C48D83DAFFF7B33A4326951C0B74A6DD045265BD1252015719, CD8AFA2E883373AB1647AFD64DC8A80F61A2003B3A4ABDC2B7576196475EA14E434A874CF46A58F68396B918B1109915, 5A3BC4B19FF83A1F3CCF539475A8A4A0E50F9055E3B381D6A366F4DE1E5E15E7C782ED26E192158E0DFF52934CEE6FE3 +1B39F97671708CF9A0E279D6CEB3C8E40E474DA88B90FFE719AEC973BF54225DF4970CF7313736F604054B, B778EEBEFF27BFE361B2C919A12EE43AF10DE8A0F09F77C682917949CB68AB1A47B8D9C3B414D493A41FDDFF0960B378, CB71031FDC86DF7AC19BD60BCEBFB1B6934E662F83B41326C8247DF23F3ADBC857AD7105E9BE30D96FBF7F5438C7E1D5 +51ADEC635451A6ECE2A76D846C1B5AAC2AD5E8F9A2B2FFB54D0C5C5B3DFC6719DDC526E593A5A4E20C0FE1, 7150F2DBA77739F4177B6564316E12B6316CA42EE135DE214918C4AF468C07AEA8A7F7378689BAEFF4D334D04D418479, F5D215B075DD96B5DF1CEAE9BFB8CD5B77C1D9CE8F28E78A3B000FFB724D6F1D36F15CC6C4138BE0503FE49504F14D9 +F509C529FCF4F4C6A7F6488D445210048081BAECE818FF1FE7251511B9F5354D994F74B0BAF0EEA6242FA3, DC61DBAF71F48C4FCF89940E18949B92B8B6DD2ED84597727FC1676B21D1A6F2C317995A9F3FD7F35ADB0AAE0F17F7AE, 330C903F413F78030C1301ADEF491CA62A5EED46A7B6F3AED2D0124FCCAB7056C25582139A05EA9CA06932A257E7659 +2DF1D4F7DF6DEDE53F7E2D9A7CCF6300D818530C6B84AFD5FB56F3F352DDF9FE8CBEE5E1230D2CBF26C8EE9, CA764475D35AC4A15EADBBF53EBD3D8694B1E0A832793BECE7CDEFCFFA11E75A5DDF23CA2433BC3DED213DC364E50D1C, F0F6559FAC131174B886F2BF1112759FD0A21F9F9991001AFAA28C72D11C62807107DEB6F256A2E0EA935333380608F3 +89D57EE79E49C9AFBE7A88CF766E29028848F925428E0F81F204DBD9F899EDFBA63CB1A36927863D745ACBB, 4385C0B8DC024C0E4E891F56C58987A8DC44A92F6F1CDE15F327D66EDD3A2248D6A733A913A0139DBA833235E6A476D3, BD8B69A56D688E8DDF2E696E363F1C119FA4F9102F4015E99E37C821DD8093984D1888CDB3A45305D2F25DDDBEF2E0A7 +19D807CB6DADD5D0F3B6F9A6E634A7B0798DAEB6FC7AA2E85D60E938DE9CDC9F2F2B614EA3B7692B85D10631, F26EEA9694983171D70E3A5A4FBF178A08C1C087B5452BEF59490F688D3972FA8CF05B9DBB4DB5FC97B71EF47EFC7745, E14DCD1F6B3392DA3E2D39B93D9042435393206764228FC2E07A5A0C9D95655D5F5915551AFC31F8BDE0873A0D2F4F62 +4D88176249098172DB24ECF4B29DF7116CA90C24F56FE8B91822BBAA9BD695DD8D8223EBEB263B8291731293, 469B1D8A201CB9C63D915BA76C776B04DB67DE4A343709F8FC84C3A7569757A14C738A89D1E093FAC28D84E81098C208, 4585BAAFA636261C5FD8B417B98183E8DB4A5FC31F15B9F3607BAB58A5DAA4CDFDAEA9EEDB2C8423B53EE439D630E9B8 +E8984626DB1C8458916EC6DE17D9E53445FB246EE04FBA2B486832FFD383C198A8866BC3C172B287B45937B9, 2224A5B8D0E6DF5C14303F40BA3FEC51120D078CC9E2D3E085FC2E002D79344B5432C0D78C179B5D64B3D26C29E943AE, A055CF02A96E37559A219599FB3DED8D753DD9AF7F2DD3073D6D60DB00593058C12430BAE9668B7F5B1F3C7247121581 +2B9C8D27491558D09B44C549A478DAF9CD1F16D4CA0EF2E81D93898FF7A8B44C9F993434B445817971D0BA72B, E97D762CF98BE3BD1D4421FAC2EDB20F4E84E6D938BF969AAB005123AA6FB407164013C9C33D9983D11D14BD922B7929, 31842B2BE7B7F860187A6D89515656872296A3E190933868AD6B27035F6B8A5FB7701923243A802D4E9625A0209F9CF4 +82D5A775DB400A71D1CE4FDCED6A90ED675D447E5E2CD8B858BA9CAFE6FA1CE5DECB9C9E1CD0846C55722F581, 25915C50000731C1EE573D1977A5B8CC724F0663838BABE67EE11980BDC2618AE387874403DBFC0D3AC4D0DA4CA078A6, A3B49BFEC66C5FCFCAF2ACEEE28A8D01F4D57296AB730B650F488CA03BB3C90E758BF6558DF5D9183920CEC2EF5A1A7D +18880F66191C01F55756AEF96C83FB2C83617CD7B1A868A290A2FD60FB4EE56B19C62D5DA56718D4500568E083, 68582E393203364311515678FD8679A1778E6EF1D69EDBF93F45ECCE63B6498501ACA1EFAEFDAF7433B3A3FFB6208CCE, D34FEF465EBAE7912B706EE27B62BCB27D9A44886B3FD502BCEE62F043383335D1A1209B5932CDF9EC4CB31B0E154E28 +49982E324B5405E006040CEC458BF1858A24768714F939E7B1E8F822F1ECB0414D528818F0354A7CF0103AA189, E319DF8E341DA59683C28497E8F01110A036805A0547AC8F0550A5DC0A98A315C19664457B517FC68BA31E498A593FDB, D28C5DCB4664862FDEDF90C3C9E1C0E187D79F2994F7D1B24E1431D5D037A69D65EF285EA3E690474B6DB46FE06F10FC +DCC88A96E1FC11A0120C26C4D0A3D4909E6D63953EEBADB715BAE868D5C610C3E7F7984AD09FDF76D030AFE49B, D904A712CA3DE0A765BC1E4324D6D501B1E34C0C8223D8A51CD12BAF9F6EF03F3D02BE88AC5A9645C1C91B132E2D8EF4, 25F54CDE887A4DA40FE21141E431B0C4D4985DBB7FEAB4B7FB2070AD309A78AA21DDAB4BB1A34BFC4F29C47C5F1A9E50 +296599FC4A5F434E03624744E71EB7DB1DB482ABFBCC309254130B93A8152324BB7E6C8E071DF9E6470920FADD1, E1030CF841E5BEA460A2BB2BD04162CAC55629B2424D04DC0F653EEF2D139BF86EA6E885A8B7BFA30114FA978733FB26, 6A4AE9C945427E1CD30AC2C2DB4CB0793DC9A1FC31A587EAE1FB86DD800A3758B4C44C3013F815691019DE1EB343B716 +7C30CDF4DF1DC9EA0A26D5CEB55C2791591D8803F36491B6FC3922BAF83F696E327B45AA1559EDB2D51B62F0973, 552AC5C872630618A2DA71D90E05B80D707262AFFD89B7BF1379911B43AE303EE4796FD4C11D9577D20A78D8F8A07670, C6EDABEB5325FAB19B27AA2692CBB58A4AF57642C7E35435EE1A118A618C6FF921715D62FE85404A341877F6429BEB31 +1749269DE9D595DBE1E74816C201476B40B58980BDA2DB524F4AB6830E8BE3C4A9771D0FE400DC9187F5228D1C59, 22541C181BEF319BA4DE0F5A38E5E3AA178683D7359594C9834A698B4882F8EC933B0C2530340861A6458ED7AA3E30E1, F10BADAD71BE09E1B9DCF0D56C22CF5C0AE30DBC3293B97C9F0C76F0A209F72F33CA699D0E24FBBA50F8E73440C920D0 +45DB73D9BD80C193A5B5D8444603D641C2209C8238E891F6EDE023892BA3AB4DFC65572FAC0295B497DF67A7550B, 702A63CB0B2FF15F9319DA8A4CDA259AFA8494CF9F1447B743EBA7EE13BF717754D0E7D207B86F4B1D3E1673022ED9B, B21CE14F336590C7B851224E5C2E480932792034CDD49464EA85C8AAC6FEBF2BE68A7B7B7ED28166FE99741D9456A47F +D1925B8D388244BAF12188CCD20B82C54661D586AAB9B5E4C9A06A9B82EB01E9F530058F0407C11DC79E36F5FF21, AA9985D7AF3E2FB935029511CDEA0DB144B3D8D67E523E98E23E2AAC3469B46DAD414B4522DEB39EC90907851C9D3CD6, 6513494B1E10AA85D4DBFE8992F61A1140A1E7D066DD0C2E7C5C34DD8AB649D31A555A41CD06DFAC4ED92FA325FB748A +274B712A7A986CE30D3649A667622884FD3258094002D21AE5CE13FD288C105BDDF9010AD0C17435956DAA4E1FD63, E8C81D1BC1C3FF2CCEF60F5029D4A63BCD22FF762032AC65B302A0445F11A2EFC60E46BCE00D714E0A246276E9706428, 7B5565840FB95A2D76313483E2DCDF4B17F0F37C6E67B9A998937791323A310D3E75C30F8E40273544F0ACEBCAAE4F9A +75E2537F6FC946A927A2DCF33626798EF797081BC0087650B16A3BF779A4311399EB032072445CA0C048FEEA5F829, DBD7AB5BBA5A5CFBAA7A1416BF065B07B7E3325742AB9BFDCBF78DE111FEABB9F04532FE06604D6056CF61336EE1750B, 66A3559D318D264DFEE5DF77CE521A3F53857383B89800757866D78B64173F1C3F24206DCB8905F5AC0E859ACBB71547 +161A6FA7E4F5BD3FB76E896D9A2736CACE6C51853401962F2143EB3E66CEC933ACDC1096156CD15E240DAFCBF1E87B, FA533E8AA1FC1203A3C8D8E9A9405C71699B75EA71CE0B1246ECDEB000B1BB8117A1377EBCB2A431FB63F4E0D90CE06C, 23A480D5A4C528A8B9A8D790A03D9FE76D9CF8DA3C5370C810B62A1C6F28A0169B3EF0933484DA685DCE40CC5E2D6607 +424F4EF7AEE137BF264B9C48CE75A4606B44F48F9C04C28D63CBC1BB346C5B9B069431C24046741A6C290F63D5B971, 8BF66C05DB5448E6BF481285A14D38ACB18740BC28FD8F77A2CB3049F894F14F6565A0C2E7DA29E387C191B5E3E19D43, 637CEBAEFA425A2C23E6167589A0D68DDE19AA465F59A1E08C46A64383A1A4703FE0510ACB504CCF2129479EEA3ACEE +C6EDECE70CA3A73D72E2D4DA6B60ED2141CEDDAED40E47A82B6345319D4512D113BC9546C0D35C4F447B2E2B812C53, 9F776F4942E963364B571CFE0F2743030869C03A56D35D0F3928F43EB2D9A2179A6D3D4F2BACDAD96F3304EF7FA941A9, 5B0D270FD2C9BDEC2871510D56B5386D52B2B0911AA180EEB027802E5A25A88674C3CA0A42C204E73411877DA612806D +254C9C6B525EAF5B858A87E8F4222C763C56C990C7C2AD6F88229CF94D7CF38733B35BFD4427A14EDCD718A828384F9, DAFDCAE4D6C475716EC405C348AC9A2343D5D67F9B10082B4D3E2675BD85E32785D536C13BEC607D41410BAD609742A1, 2837910E8A7C8D3ADD8BFD714FF5730614698C4D32B8A9828C42C28869F90254DBEF41A5E43B71E78A2069AC85B05666 +6FE5D541F71C0E12909F97BADC668562B5045CB25748084E9867D6EBE876DA959B1A13F7CC76E3EC968549F878A8EEB, C47B4D6351C30544BE020706A3713B8C9BD48BE44FECABDF134B45AC705B7AA5E1D2E0A4C5CEC413591A93D5134AA50B, C9CF3149AB16FCDA4CEE3BBB757AED324007869C47819656EEA647EC16F896C9919E7C58624BEE371C8D4097A204E42E +14FB17FC5E5542A37B1DEC730953390281F0D161705D818EBC93784C3B9648FC0D14E3BE76564ABC5C38FDDE969FACC1, 4D466DECA0E5F2C664B1C170485D0435CC913B4CEDCB8904E7EC68025C5E24F54250FF8EBD1AADBA575CAE796BA20E32, C1B53467F914F7BE0779A44AFC51735B26B644A1ABAFF7027BF87BE11FD80B816CAEB33C735ADC55DBF4C2118608BA58 +3EF147F51AFFC7EA7159C5591BF9AB0785D27424511884AC35BA68E4B2C2DAF4273EAB3B6302E03514AAF99BC3DF0643, 186F34F7D45ACBEF7F7F7F93C57758A2A578981E9939AFA22AAD14879905E3694737867BF73633CF9F7E25C6A598FF24, DD0B1F68005D3588418D13E69D343B10722C96285A12B139049B8D3E1644C2F110D36BB7F919BC40DEB99EAF443D3482 +BCD3D7DF50FF57BF540D500B53ED011691775C6CF3498E04A12F3AAE184890DC75BC01B22908A09F3E00ECD34B9D12C9, 8F6F64EA2755FDA51C99A50B57D7F438DA05A117322884A8F7F7928BA92C78310EF578005B1FCC2FFCFFE79C0802B2E4, D32301BC33B7B167EEAB552E05A20AF64E86E65986D5961C9E9EBF56F4D7F05D428EBDACFAA30907C50D18E3E7F7927 +ECC-528 +1, C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66, 11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650 +3, 1A73D352443DE29195DD91D6A64B5959479B52A6E5B123D9AB9E5AD7A112D7A8DD1AD3F164A3A4832051DA6BD16B59FE21BAEB490862C32EA05A5919D2EDE37AD7D, 13E9B03B97DFA62DDD9979F86C6CAB814F2F1557FA82A9D0317D2F8AB1FA355CEEC2E2DD4CF8DC575B02D5ACED1DEC3C70CF105C9BC93A590425F588CA1EE86C0E5 +9, 1585389E359E1E21826A2F5BF157156D488ED34541B988746992C4AB145B8C6B6657429E1396134DA35F3C556DF725A318F4F50BABD85CD28661F45627967CBE207, 2A2E618C9A8AEDF39F0B55557A27AE938E3088A654EE1CEBB6C825BA263DDB446E0D69E5756057AC840FF56ECF4ABFD87D736C2AE928880F343AA0EA86B9AD2A4E +1B, 160373EDF8218F9B6A762A4D4EB889E646F8739535D0E4F862C33F35187E135854D80B2123DA719D48351353AEDA0D3163CB215604492EC4568357643017002D68B, F1597050014DCFE1C5E5828401AC06A3FA9FD193C5CF52C3BB4A56F78E1A1B22011EFA491ED92EBC5413B874F4A8BB572E463FFE709D45ACB3F3E6AECA5D90B740 +51, 1D1BBA380289A7726BBCD7D76D6D63469CC842DE44D26646BBC45381FD72BE7EE8109F67171227B5C923577F6B0A4731872575A0B029A7B251E5A339416299C8AE0, 1703AEE0F7AD8244CC35BD69E91C0670F3E541C9CE6E3529B902A980E93172EBC8AFEC0368616E1E23B04B4D5DFCA8343EB93B0C8870F7A6662EE1B2160CBB90F01 +F3, 1CB253227B37965174617D5542FC0CA5EB142B4BCB51BAF2D6495008BF2C90BD93043A7377A937E1050B6BB117A81C461A34B14C0832AB26A2785D76462ABDC8B2B, 12FDF35A935AB3008E037D84F5B637C7A745FB21A00884834C9804B4CD3BAC49C9B1DE4AF315EB36E92E1E4A4AEA8351855E70B0BC4BA8904EA3E74E2A5F2ED15EC +2D9, 189607C1793AF3818DA32FA2F94A468BA69B3EE6EAB818B69F889101494155F9516765A8EA7440BE2930179D016B7DF6BB0D89773B072CBEBECFDCD196A56124DBC, 20FFF32EFEF92D8A2FF99E29C3724399CA1B0FC9430F672B5A82F7494787E4EF0DF0727CAB8B82250B0CABE69ABF34CBF4B194D03FD99CD85ACECE083F2B34E9DA +88B, 4E5EB103B19BBB84C89641B7E507308DEDC56060BFF03325AE009A4142D11438A3B2EA22FA8743D6B4AD2CEDB2F0578C98FB6FA857CE3527DD3B746316530116C3, 716F68F81916580A647CCF3036F3C8140D60A63D105B91AD0173BCF6F84CE0CA1BDB1D4049BB7263BE724FC920208014BCF75404D3300C1CD2CACCB07478308AE +19A1, 1D2EF46577B66170D9EF0F1F1486C3E7DEB985FEE76898575B630042DEEB54D8C3E934E6DF77FA7681CAA1AFC7A7C23053E87086932F561BE9B25FF70318BC495F2, 1B0D12E74EB99A8E16F0AFA3BB928B75D2B03E2889F84F3ABBCBAA77027198D5B8E2F72B6BF16937AE709C3026C74D26F2BABE31CE6E0294439928262D66A4AACDC +4CE3, 531C9ABE51563C7C779E89BB2404E00B47891DE3E465286B5177274B12285AED14935FFA8229705B3BD523C93421282EE4C544050F49A79285C61F8F311BDD0FB7, 23B671A070590887AD3388D92AB2FA6A0196BA044186CEA279BE939CC13053702BBFCBE4A8CBCF162D80DDA67E46EDE513B57E5B7D52FDBE040A91C497A2F35CE8 +E6A9, 1EC7605CD3363B524A70C0BC1A258A53FE8F61A982FA3E86337C2B9AADA6C3683717982A9546CD1CC02FCB1F1EB9CD45D91DE8CA29E61E8A88323A6E237A62A28EC, 17CEC602FAA9164AE7D8D342FD9B8A47848D1780F92CB00C221E3A32424DABCF89EE805D1BFC602BC6110012352A15185CC5513116E370B46057A8DF61D9A60F3E8 +2B3FB, CDD2F0F3012DF190BB260CC871FC42A9F17979A329D683503E59E7D4776D8F10F62C390E045D847E7FAF9AA1CC077CDABA6D87F4B1125886F25AFC4D6309199F5A, 417903A05C021068B2FBB9F2009317DC0B51D8A5A1C89B9824D99089D0958AD488C1001BA16E75873ACAC17E0CF711856929255B40B93CB2B95FAF77AC3C8EBF7A +81BF1, 3D8825CF08E2EEC0FCF1BC392D7019ED417E5DDCA47546B14A82F8D7F2EDB9D2DC774C0AC9E9F5478FF1CAE8CCAD02E00A25B8D8179B812D14FBEB962169397004, AB19E783633A89835F7389184681A605E6D5E4E3E9BBD55792E1F05A1EAB5B0F3F72F7333E659AC5EEBEDDB0F6D3E80922C19427CE4E391AAAB8F709613EFAB86F +1853D3, 425EFDBC284A04B79521998BD8199C9C2CA979A33CED4D78A27320B04BC460AB5F504FA2A3B85B09D709B16440BE80DA6391F448C134C2FA99EF5E7D6B0311852, 5B15B0C9DCAC88A1E0DA573948D3E637AC33B3D52B5C365B5F56ABF002624FF68CBC554C37706F33AD005CF0D2F07122AD3A35C8E80389DAFEBB5DBA489A1474E7 +48FB79, F4666458E61E777A01C5CA195BD0BC48C3BDD5F2721F624C448034CEAA54638D8574E56DF526A81CCBB4652BA243713F659B1EDA90CF2D7AB62BEF511B665F843E, 19450B9BC802D91034E580F9568EF80B45DA1F84C1DB1D1D55400D3D3CEDAF64CB01606F3D1EA3C06A5975B09E91173E1573C910F84A98709EBCC9ED1386687D3F9 +DAF26B, 130A85002F8B5DFA04E6AE28359493A64CEBA9CC6E69F799FA502A3E07CC534D9A1E7B3758B6A3C4F95088E03AA1619D778C833EDD1FBA196EEB6AB19FED3D64486, 18233CAC49290DD86F4CFCFDA74A217E141497EE6D3EFCCB1B32C46802AA3ABDB2CDFD3CAD19705580A2BC5C03D42F444AA8B9D98A51634F3B5DF048BDC17D633CA +290D741, 1A55360AB86673AF294A626616B918EB6BB916E45179AE4CB70F5981D71C976BCDEE1979FB76E3F8B04A60D1823E697D7C37168D34EA018F08A79CE901418186E26, D3ACA61B48D79BAF9BF060A0E7E1D9D99C8C1CBC3DE7F8E976EC0786A8075AF407C9B42CC9310D16CBB493CCBC8E816F6CB650C1F8FB5843E5BB43EF79FA639B82 +7B285C3, 15DA0FAD97C5664A014EEA2068AFEB285536825108BC34A61F087FAF171A99D33671EA45F649A5DAF48F34EF86D9808AD8C15FB1780C15399E1E4BED006E11DA035, F78B2177D18B6C6C5FAE8F0EF19C8FBEDB436A41E3495B8C6D0D7FB1FC714E946FAD13B2C1D440C6629C2CEF0766E5A159321C696603B575489CDB5495E69BD8AC +17179149, 1BA1C685592B7F42D16E61C809DAB11F052F214BE908009B25101E39E52F44FBFD0D28E679DF4B830F75A63FCC2EBD52AE1F74345E281DCAFD3C93F5F9F939788BB, C4A69AB266A89B3ADD952780C9B744ED9BE8FAD135579ADBA4E1985872E17A44EC68A34B179E2E5DD6B7590220F5D7629AED0A51184FDFEEFBE69754528F441359 +4546B3DB, 12AAC7907677FFC2B0EA828F9B62CC1D078295332C882FEF4E8D6D83D9774C84DDE3CEAA863B36916728CE0873CF8CAABF1122927922EC7DD748578DD1430F54936, 93DEE239B6A969AC8697F2E66DAF6D86DD382949FE36C628232FAAB7F8ACE756D35F8770B84C0CD91740263801B86EC85D84A707DFE8236920DAA0DB61DB0DA21B +CFD41B91, 1BA7B15DECE55F529F1860709D825B96A0DA2F1B10696EA1411B83E0B1A60AB48419D6332525140733F5A39EC66E9A7E6041CB291BB4A650D28E12E60901151E778, 1124E66E982013045FCBF3AAA04CF16E919DD9584A0ADB75B155569F037F037C9E463B4DC781BE70FCE6E4FD6D064A03DAFBAFB2F1B3BF98AC081A58D9655BFE3E1 +26F7C52B3, 1D5605150C9C55F2AD48D4DCDF57D783CD0FB107F899ACFA8044842BD3EEFF0E14C35FD9D6AF8F5C8CCE32652A44D0485F64D3BB2272B478A4052C07CE083645ABA, BC7178CA8B9F702147D51D9C227AB4ABEADC91CB315BFB4FA0741CEA14A1F093CBC1C9F08070E03E5A363ACCCE3526B398AD79A19B98907C4E83D2F020A615D836 +74E74F819, 881A1909C05C38ABB0B34FB973B0E7F2E67DC887E27B3CC5233F8B4537656DB0B174F85F345B26B26F1691A1C1308E1EA8A3CEEA5957566AC29923E74305027B2C, 1E266B9DF37F657891919442B7AA3BAD7918D1A5BE12CF04057DAB9F2A0548A4473C6114955AED0ACC4E193E185F762F16C8D135C43059083EFDF8FD2E04DCD7BF9 +15EB5EE84B, 1869716D001DAECCFD6765136D256680A68837DC68F2BD235F1A1AB286791F8488373122C50CC598CE10B86845BD722AC0ACBAE9ADFC3A75B77617AFB6481CAD729, 436FE2AAC82F0FE513573C6F2484FD302A46B3D4827BE3B71A26A909479436C9A58D7510CB4FA9435DB86EFB17230EDD1CACA27445115E7B061A62A924444D4B7 +41C21CB8E1, FE3826BD84AB28E075AEB1477999DAF32D238A95CBFF442C09BD1B5EF9447BAE6798F2D8F6FBE0C71CC18F1EDD5A0254D966A6AD84977B88D4C96EE48EBD457AB6, 98C16083605208DB3FB220383B4993E15F5C150B31386642F0BA05F8997713A9238E599628E12BC5B8383E658063394A7C20B0D24C4F7EE5294ABA596D5445F1C +C546562AA3, EC6F7EDA0EB724FBBBCD1642B71BBD0D40F7FE2E47D31C7D02A7AEF1BF89CEFC184B2B6AF7DC8AB5ED0520239EAEB949BE69BD467F0AAA56369A2113FFD5793B76, 846058E5FB3C6F251B6104B0CFB3874CB2DA880F88C48B4C454B1793F0683D21944ECF45D421FE165BF43C1F071FEF68EE89434CB7D540D49500747877255F60F0 +24FD3027FE9, B382CFAF97D0624BD9EB280CEF9DB56B0486194A4CCBAFCBD85AEFC95A12CB624126246F01D1540EA22E94779CA825FFA1DAA6178AC1304F86475D4BADA8D367A1, 1F2BA28968FEE1B6D87B34588AD9636ED261791F2DA1238C5D01A809A01BDDDFBA72C30526542AEF9AD883722BE392D083309705E1D0B79A36B7341E165E3C11B55 +6EF79077FBB, 1781C76DCF27574470E3DD260059BF8A683C7B035EE47DC890A0F22574D58165594F37D2D0723C39C72ADA10E51E5081C60DDBD167AB620CE3CD081BC4705A6D837, 45B969A054784E6F13E3EE16180E1CA0A8D181421D99CF8893A5000435456CABC0DCD5D2369C422D87018B15A81BCB33203A2E48D366D162CB5F4A4EEF0B4B0546 +14CE6B167F31, D3FED2DF278619FA7A3859FB70B813D86E67657BF4E7E3E95D0A8E7B018427BD5F105B54AF8FB6A72E7D8AB8BBD828E5EE05A535E8BE183861163DB1537496F9AA, D8157793E51CD1C45AF217AC773ED035065C5A3E78AD7B14890C66F2403091E7CE1DDDD95970793209CDF9227668A7BC620832D6A8CF8FD07787B1C5E62A1FDDF5 +3E6B41437D93, 1110B187C53AA1B25912B804E1011A16DC86D532691FC2C749FBD2071CE687322798D50FC7F3DE67A6F150D4CE081077F872532FEFA87CDA9A64090A9D96548AB23, 1345A97C14F469E58CB8B9598CAA1E4335F3AEB9174F57BC8D12ACB74995A881A5D4215D834C71CBA3B7EAEE8990AAE324E964A1FE99E4EBDF39D0E30B013E23740 +BB41C3CA78B9, 7EF65FB33141FC3CD577E83C6DD24C9960469C1BA9F8939E83C39E0C561A61C3DDB78B6709FFFF0CFB7300E4149D65554F154D5AC9401C6E6663D1B19B245DBE43, 15E0841BFC562819CF29F603B16F3B4B6ECBFAEA980FA99CAEBB586020182DD2AE3AD469D8E4506A620A261760A08E89D7ADFA6303676DD9B2A2C356A07A21E7558 +231C54B5F6A2B, 5C3F8CC55F447AF2EB183605C74A82F3C0503FC590C286DE08377DC1F84150692145DBEEDB8D94DDD70A2E3DB7C1B20052D9A38A14BF0EAD75E1AB7D96A541DCD7, B2E19C85DF2FA1A6D189A6C4F8F8691E3A535EEE83BC98686A80C6FC5E941AEBDF187964CB68FE5724FE84B51B5B14ABEAF7B9BBF4E9112E29A2F03F83A51D6777 +6954FE21E3E81, 181F180ECA59385A1C1CFD5D73D3D0933E21C3718F5D1EFAEE38A87731B9E337C61D4C1DBAC9FD9C817B1E0D748EC2B54B396C14DAE674D51F1D007A3331F1EF76D, 1A04D11D9CEF25742E0732AFC481E1D86ED617252BBBBCB2BB9E6441167EEB9F5EE4B5CB9DE320C12873A20CF3F9DA34658B3054E17B30939612BAE9FAB3A4572F9 +13BFEFA65ABB83, F09AEB4174243A39E411251C72FB8A141F53F78F6437A92D9F860E7773B8FA2581D9B925EC5AD1A523AE5905F7413745F52A7D8159BDA1C696829F251AC2C87D51, 1FECE716F47B3CF77F2C8564FD0EB11C8705635F31A9B9F456FAD7F7416D2A21CC59AAD8E3A7340F1097164E467224E7553A7C81A279187B08BD8797080334CB642 +3B3FCEF3103289, A4849FFBC7142570E096397E16381C45FCE90C3940F5C506A6DC4363D1A8491A13357ABE330BCE6A9764B8CC517D03038046481FCF18A503C5D8D5BB047311C816, 639FB120417256BB3CE1D55C5F5797D3A9BA21E9E2BEA415536EF6548C2214E80D3D81620702E7EAB848801A408EF6BC9D48C4CE90FC68C80566305D88835E6414 +B1BF6CD930979B, 12C0838ED0101EA04C5AF21B09C2DA4B3FCE8DB0067FC42ABA1FBF319CDEBF33A384BA9407A550C22572FCD41204B4FF01D65E29B9E875970CBEBBC8E6505849783, 1A2D863319E3AECF20C3E9D6F60624A87361177A696D77C559C3EF166240C6B849A986D2BB5214AFB3C1EF5DB60CA5F22A4DD91B0260EFDBCD947536D634D6E17AE +2153E468B91C6D1, 54B1388159170C0C7C4A6ADD5FC41C74FBB1EDF355ECD1D872F9E9582A00D320D0A9205FD2673D3A09FFFAF58C96FAC65527FE5796FAC796371D81502B93FE455F, FAD84EE0FBF823A557B8CA17B3FEB79EB50B631CEBD7C4E43A3362F36DAA89AE7AA44E49459DF34321F7AC9AFAABFC686A00BF2D783909653B3BDAC7593E8E9E01 +63FBAD3A2B55473, 1DD666A051BBAD5E6EB96883A55A9DD77E63C201AB1A143512B774076D0C40AB4F0308D6564CB63D73CDD81DB462FB3C17A57BD33E3B26D7EB96BC2DBBFDE96B260, 50893602BC1EC6F294B5ECD39CE9D1840739C096AC7C1D8C1E4453FA1BAEDD0B18655FF725E6653FDE18EB8FBB6F4F63335FF2DD69AE98F171DCFBF146B86BA08 +12BF307AE81FFD59, 1DE0E9F3E035E3F7D564C189397C21832ADE29F85EC8FC9B1D008871D6B4EEBC84D358C704CB4F7E9D12B909D458E218E9A7A8CFBF1D2C4044B6034EBBA8C477216, 10B2ECEAA69F5F89AC4A7B90EC5A0D8D43613F8E281A63E0727E5B08230689142C3A4BB826F8601CBFADD6282EC2929668EEE0B97995AC796E1335AC32C1A8D419 +383D9170B85FF80B, 118A8A0B98A299F5FFC7CBDE5D89FFB8AD7C24832DE083022DAD4814F3C7A73959F77B6DE807F1DB1879DA1BA9BB547DB38BEBF82707D6A7E66F586B2052DAC77BA, ADD0F1B8DBBFEAD35FD7C4A9F3F8D2076FE42BD91740915B76D090FD31F8AD3365E5A028AD20081EB78B526AD36D46321AAB2FEDC68F0EA3961B699CA015B412A6 +A8B8B452291FE821, C23FC4B56C816757ACDBC3F53C21CD67F660DEE23A06A95D8C8EF751F0060951D343780FB576AB07CDA6B2F68900D6E97C6813E8E3BF40B3D0BAD80909872228E6, 19AABFEB7C4295A5619C5590F209DC72C957654058104E2B0AB4716505C476CF221E541E0264348285961D3ACBB3B148993A06578DC94D7CDC9793C7C2FC8714BA9 +1FA2A1CF67B5FB863, 1FD7232A28A4A37238C080753E6FEBDA89A14C9C44224D77E8E89187C3912EAAAD59EAC55420158B02C1290F665F7DF4BA66D02A82BB379BDBBAABC4315B1DB3BA8, 1909AC430FC4A553DD7285019E0D3627062A6B41D8AAEDAF0B907E2BE68887A568D7298795A0C9470ABFD6ADD29E62AC3B690774EF7B1291A05C61D0DBB47B72E8C +5EE7E56E3721F2929, 1EF6594F94654869B4EBFA95DFBB70B9C735505D45833E17F6DDFF6B02B1C560CE8EE7F4E25F7C1A59C167D6F39573A9A4808BD555C8E8ADAE7AC9678DDF5DFE6E2, 1A47987BA40C43D6A93E5FECB0304973D2EC8E27972524E3E95FF7EB3E1857988C1D37CE6CD9D7E5908919869B8A140FE780CF4EA803FB9124E0BE12E1964B6B9D4 +11CB7B04AA565D7B7B, D25637FE03EF4FF9A71BD0594EA52CBEBF4F16B56E82C566530B0D1C7056EC19099EC1480018CD144D9C91426BC022715BCB190D9BBDB5AC1605B8A102A1E2F63D, 58BB79C16C10D2FB237EF55BB3401B4B9D9FCCBDEF3683C2F5431D4614EDEAC1FE29DDD23D58DD819F2ED64D9E6FE95F1AFDC3C17F70E32D156B416E6308F8BB58 +3562710DFF03187271, B678885DCBE552E09F2C2B9CCD040A76BE73D101CDFF12C1F38427F0B563F2213662D281EDFDD0518E93871490D3C322152B8B99FE156C072AD48A6F246FCEA43D, D98172CD1094736AAA947CBB22A4B9C7CFE82037B816ABBCC70AA20B26B2781AAFD3B8BB597140EF417405AF726F8521918A7B14537480B788DDF7FABD535B4EC4 +A0275329FD09495753, 10F8C57ACF45355ED2C38E40BCAD9BEBD2020CE99D2F445BBD1B2A5C2E9DDC8DE00A6BFB51B85355209E80233075510134E8C44576FC3F33C9390562FF2159DE058, 52CB1CD6F1AC84252B5A69AF5168E00C299C359440CC8E1BF03C49B86CE88794F64DF89563D979F68A166A079A7FB01CF118B46665BFE9C2082F57614D9B48F163 +1E075F97DF71BDC05F9, 45FD2500C1744A0DBB9A28A832FAEC3AE568A8E77E4AE385FCDF45890FF826FA1660018C246E51FCDA6CE0AD7E7BD1C5B9D586495D1D61E1AE1DCDCD2F863A2305, FC6B68E01AD52855522DFB440A5C46171F69047C164E55CA6EBAFDA5908155B166652C487B4024D5B4687F973D90FA1F9DD3F433423583B4EB1B184C0E753D76F9 +5A161EC79E5539411EB, 1496D321897B3869680DB0EF9F0036875B21F27B73E246377ADBB80164A0C8F7AED5572DAF12679DFDA0301B50C7FA50E79CB410143B7E95051ABD52B3DF7944FA0, 12E3332B48AA11E31086040E7B4669F628F17BA333C66E5B4F0602C9348FD5B59333F266A17E7F8185387E4B1B1799759D51DC017811B4E9FD37A506F8656D3810E +10E425C56DAFFABC35C1, AA821872EE88279B74988466C480438447B0B91B8660F1C7427E2A23CC66008E29B5D9AE999C200237C380034E5CEC62C6028DB0B986465EE01EF299FA4051D06, 47871E7FC41A4520303091E7077A820351A6ADDB9B55F75DA39E6C56404EB3897BEA59D9BA933E64A434ECB010256E33B564303B234A8B18ACEBDC9050909228A7 +32AC7150490FF034A143, AEFDEF3E624447E87789B37B9B355B51ED382F62AF2BB9B01722C3D110FB865328AE5973CE920E5BCFED14E6E6FF3369F59F0E0B0DC8C2595B97F3093842BFDA89, 11C15F166282F692177A8025ACAA1E27C6CAA771523400634E083DDF03622E6AA0FE32C97ACD80F74A7AEA83E3C1C46620454F19DC44F695692CFF8C9B5924EEA5 +980553F0DB2FD09DE3C9, 82CEDE98FDEA05EE814A7EE86F73EB5D196FA0529C958F8ACC5DC65EA8566B0D6A7A069C906803C812774D92EA196403326F5CCD84A6E07EB5DCA49D8457017971, 8021ECB6CA72FAD06B69A0963245C26C9D5782ACB28698E3A8ADE1DDAD20C0A3FB0ED90EAD4A7CF0A533AF508884358A6F709F34D9244BAAC40FFD44B6B17EF00F +1C80FFBD2918F71D9AB5B, 1079E822EF5B40CF8050214A2AE16F24F115BB98C379D1D9718EAA33EC9F8FA94C05C017CA59117D2AA5210982D579889C675D61240DFA3C7060C85730DEB36CABE, 133924F6747F6611A1EE66B2E6FCE491EE18A6BF11DD6C56B95AE5E2A96D3DDC9F22C0C3CFEEE18249A5D8078A785D85A271B0F8A6DAC66C440BCCE6A4DE320AE78 +5582FF377B4AE558D0211, 464C7F0BB11C4EFA309221BD9F617FB5C1D286AFE1AB1CF01B8FE713156FB9556592DDF1FC67FD72C382414CB4366E5E17A848928D8DAAD48D1B9D58F410858460, 49D757F4B9D5993E0E7516AF45DE7EFD76E6D433B7B73F90F669ED0084C456F9181E6925BCF62036B9A9CC9E2836B8A3F91CA4E5464DE749392C4D159F681CE6F2 +10088FDA671E0B00A70633, 14395C5F8FEC4BE0611A13208FA0A51884B9B64134D0D490DCD3E226818DB25F60BFDFCAA038DE5EBEEA261832450D85736AD1F5A353E0324A905B004F1175565F2, 1B99F4AECF9C15B1D09195840400CAE567D141A068140DCC08EF11BEC7259B13518FF6786354D09859A04D117E94E76592918C21F78101035F3906232E164019DD1 +3019AF8F355A2101F51299, 1DEDEB355DFB25C0781BF5B8D9DE88C9DAB56DB998BC5C6B061AAED98EE95132173E81FA1515AA8540150E1B6BB80BB696823810A0F8AD17AA41EF6FE3786C91063, 11575AC1A36A174FC9103F22D997C67C7687941093A22E83D04D889A0E4C4228FD13B01A38DAB15CCD7B49E219A6697339C856F72BC99870BBD5EC2DA02C5E50839 +904D0EADA00E6305DF37CB, 16F5861E70F20A1F80908525058B17696A11185F6544C78D4F30258816B2B5DECC7E26B333D31E29DCB26E7B155D34656BAEF5C9D9C9ACB32C5AF0C0571BA8627F4, 1FE3AA95CAE6D2DE7A1CCCDF28F249FBAD507CC03533C992A291429AEE0CE1EB8396F4F960686CA6351C883E5A93628BC28DBDEDBC9CDB89D92ABB6F4DA6D736C45 +1B0E72C08E02B29119DA761, 4E45FDE0FFE64B86818146F92783D1E967C8C4BDCDA44E8927D72F269AFF5F6DF8F4BAD6CE3B2A722E5A1DDD8AFC048C3D7CF02DA3B4C71556D6F2F82C207049A5, 125556AD32950BAAB4C37676815F498FB270A292EAA3C7669A0D13614772C8DBB052C6EA9E753E58E9C65F0D8C4B54A58CB1F25E0C4DC167B4AC0942BF1CC5F0C9A +512B5841AA0817B34D8F623, 1EF25525912F28BC6F2B321C13B7D27237ADE5851431A190C619015DC3571360B3E76452A8A904532512F1F210509FA8EAC2D8E9FD3B6B81050C2026E63CCBCBD78, 7AFB8D42BB5B56C73B38A43015354E85D9E654821E3756C2F57FE1B3206F8BDC693EE96C1166B237C90CE9E9B65A49F1D2CAE4BC4B9A10AC94EA0B505BB233CE4E +F38208C4FE184719E8AE269, F33D784313B9EFFF097C88DFA87ED80B1BFF56340832B5BDAB35E0BEE1D73BAF183D455C977BA643E42B218400FC5B389B1CB9A55B9FAE1D2F66C261EE24B54567, FF1D6CEF8D0E6AAD96D5C9CA827054937CF40AD2F68FE277436E4966D04B64FA071A56B058CA38807C61C5533C9E6525C2FB02266BE222A5ACDFB059CCBED8E255 +2DA861A4EFA48D54DBA0A73B, 1ED6C2C3B4546B41DEC00095940C7A8B629C5C0703F15831096240174D0A18A94376561537C57F8483317B215B00D422D04A7C479035093CD580F1DBFE81BBCAAFD, 1B4AD3B7CDCEB8C34FD7D35FD087D5737A846D7F82C9C3E81D42B35D089E00AAB6197F7956A475727F5FE2899EB19663609C9EBD835C4E066BDC4DE8830138437F0 +88F924EECEEDA7FE92E1F5B1, 1F510CF12AE559559B6D56A7C4CD12B2D6F4E9B211AC80347BE28C544560394E0B77D18909751427F0D72757C95B2288AD53B04EB04C1DE823FFB6599CC12910647, 1C825308C453E4BE1BC25A470AAA262CF256BECF6539005B1835468541B9D137E5A20EFEE41B70BC6109E92C1ED2290DAFE20F523433150AC3A1D4B62A382DA6A4 +19AEB6ECC6CC8F7FBB8A5E113, 1D96F773C1736D046ADBCE278A48CC600A496AC353FD3A0D85B7A39B4F127964577642183E76283976014BEE00E7F8CFAAFDFBF35FC6E79DD637B67FE8AFC22F018, 1B20DBA2B18E31F5620E2231BCA4B4499FBBA844E1D424D2C295F4114AEA4BBEA643C3171126BC9498400E689DA349F3434C692C5598D93689C9CCF7A0E26D197B8 +4D0C24C65465AE7F329F1A339, B69E4A8BF1AA895C618A8DF89CF574C07B737074355578AEEF4534C8D218C975A01D89E699E2BC848643CD5D3D1BCA0468BB0D57AF11B8C90E8C90F415D7DBD14, 8CDEBB41AEF07326AFBBB4CF350B651BE771F46C262914353D64E753FF4616EC07F1421FC38999131449B99A42D460596E53ECAADF9520D8C62936C1945E695CEC +E7246E52FD310B7D97DD4E9AB, 2F44DAC7B64226187E6D4A243122268209B26AF89C369614080A0102CACDDF9FF10A3AD4443AC0895D935E76EC7077FC22D6F8148E43B4EE1ABAFE72DFD4A5C45C, 16811C302BAE1D2139926DFB84E07747F2992E8668A438642E42E0371D0964F5B9E544E8DD50FD4DE7A4FC149FA7CE15705AEBAEBCE2430F98F761E41EDB0348ED +2B56D4AF8F7932278C797EBD01, 599F9A9B5DF7E42F73BFF94099111504BC3FE81340CB7B761A904D8F02E57B1130939C5926BA6D8E7A2F16B6EAD185A67E74BBF32D9C35369EAC094E8404DF08F, 151187A64F516FB7E574009A05FEED58FE9651908128303BECECFAC8833DDF5C33E19EFCF088C2DF944907ED1A7222C55844DD71FEDE063447C3D2B900E3B011932 +82047E0EAE6B9676A56C7C3703, 1F0EE7B47DF0981FB658EAF622151FCD58856F9EF226296F9265FFB4D345D61EC0BE7950BA891C449B1414CA01E824C219E0F95860BBC4C6BD5D5A8082AE156A500, 136C0FDB133DED142D973CF3FFB7AE59F5E379E53ABA3D5B8A773524A947E694B45800AEC0B8E64B1D3BE54569B12B1E96D6F25B6126F03604EB5F205E0C0D2AFF8 +1860D7A2C0B42C363F04574A509, 967C8D057C2C6C527FFEC4B65418CD070D20C917F7ECD53B980352C26E4E8CE1EEF1BD8C18BEC61A3259169AA9573E89BD4A43365AA35238FF792F8831C94F5778, 76A652C96706E490E0642B1B897C1E835FFFF5A0B6B70C7299C0FD1CD7FC902FB5078D58DA583DDC9FAFF4A1E5951C421119DE818EBD78D4B9C645A839DD8FD05E +492286E8421C84A2BD0D05DEF1B, D481529C0B8908B0D26BA5280C36C090539B2C8777DA422782DAC32B8D938CD9FBE48B0F089CCC19E927478344DF6538A12E4C70FB83BB0167BC5F67DEBA96EAC9, 10BCA3006DD8A63F380393337ADA78EA09DBEF67B7341005E5426FEBE6CF6B1D3CE6164C3DA46BB7C583C7EDEE6B3B2CF61DD7170668ECB5780BFBA9363B51D8D7D +DB6794B8C6558DE83727119CD51, 17C0CE40712F4B52705DDEB104DABD27FE0DC8252D732ED96B1EB6D0D2ABC4659B11A7ECF21FE1AD66EFDD6436D4983D1D919334863AF043783A0ED16C91B14FEBC, 680A8191E60E5CD6E64C511B271B665A4A7A3325113C96829FC28FB75305D207BE337A77832A461611F76F63637DC8E2B28383025869AFE5B637E0D6AD57FD5673 +29236BE2A5300A9B8A57534D67F3, 2FAE54CE1D4AE5B9E83ACDDE92C47749C206F41B72A5CD5BAAD031F0AAC34CA679D5F84B81AE4291C7A98BB2C396C22CDE0D896BE34FE237390D27BE54A7533ADD, 173ED43CCD7FCE3B515C941BC744FC62E2B4193E1D95DF624661F795ABB261B5DA5CBFAAA02CF9988B5EF05E095A2C7CB0ACE356D76D919852A1D672E37FB3CB3C6 +7B6A43A7EF901FD29F05F9E837D9, CF6727DD89F1CFC1997BA16862CF19E9217A82FF270B247AED2AA0C992A4526E58B86E23F375BF50B5629312370FAD1E3FA1DA5E3B2E6DDEF7D1F48EB245270489, AB35A48111037289A4C8E360B1AE3000ADDE3FA27917BADEF8245386F1DCC6274522A3D38C74975BFA5264BF1BBCF39E37C7E6EDA0A6D03B896140771991D28890 +1723ECAF7CEB05F77DD11EDB8A78B, 15ED4363F07A28A30112EFA8CA8AA56350AF5752D65AF4EB57007025116EA9F04ECE481F90EB53495798F89D4A54040E5FD4C16D368921865BE454EFCF60AD5FCA5, 68039E8220C159DC30F35F437D9D174574C2AC67D388C966C489462217C2189B2AEDEE9602880578ECDB49034C0B1065C659DD043EDE93ACB1B18EA874CADBA064 +456BC60E76C111E679735C929F6A1, 958CDFC357EC3618C7762B10E3D45E76EADF9157CEB5236A564898DFC4AFAAAE26A07BE8C653A8E16A36DD0F4E448A1E7CC88D6B7542A8E499EB678F78E4B6B2CC, 19723F0CDF33BD23A14BA13A98043FB63B746B0EDB2852963E491E21AD37B959F512DE84F9958BCDF77D22123F887A659ADB27DB668DEED9C90D7D283368651C7D8 +D043522B644335B36C5A15B7DE3E3, 1D6FF827024331C45120C4C71DF35D6888B12C5AF4FB70B5724957FDFE8824A0E713106E888B77D031B740CB73D4D6BD495D80494AD621F0AF8727A6758A455C68C, 19E2DDC3260794B45204C946A2437D266F9F799D6F8AE9886D94ABD5019E7AA7957D5804426AA6195EABA99FD5E2EB8E09363F46FAAFFC262DFBEAA241C79A2E7A1 +270C9F6822CC9A11A450E41279ABA9, 8F963C0D060D273C74B097FF5762CF227BD859561D2FE6195C1EF495DE1B79C97562C7866A34DE56D61B3A8EB42EE87C3E437157EEC3064CA0C7BE6B38F7B259E, BFC2A9BD95034A3B05F63CF91402403BC9987B22290288832D84F33B0F6738C7D010033EA032F3321B6D87720E5F6F564B1BF31BD9A3802FBF2E108126591E707A +7525DE386865CE34ECF2AC376D02FB, 7B9F3B77DAB322FBB3DA19EF73F6F829D881619451B0C5DCDACE17EAF0830AF0204D4D0C51B82ACD94341870BA4C4EEF1A177DA2AAE93092D04B4809DEE94A2047, 44BD3C36192CB52431584F01FD2117C61A0D98B9CEF1AF9D430510B9B9629558DE745AA3CEF2B211BE4EDCB9BFD853DAD9F4B0C2F6DA8954AC0CE29565F5EC1F58 +15F719AA939316A9EC6D804A64708F1, 1F2C1685E8DFBA68D3759869081288CC99224189EACA61392C72BD4C4964C67E3895CE7B5B414F4C0AF73B77691CCB26B592639E3008DD72BD38EB90238150EEFDD, 1141FB62A9474E430A714A2B04743FDFFC938BFF16DF9D4AA8EACD70CF1F05D88A7B9C5B8FF05362083EA0912D36549DC3AE8C1FDA2E7B3DC17295AE0F027C16A45 +41E54CFFBAB943FDC54880DF2D51AD3, 1EA7AFFDECC9D2D173E0B2B2DC0BB570DDD10D7814067F030620B8FD9D8E1BC8B552506418F51396174F99150852490D0F6ADAB392B7C743CF53728ADF7412B3F0A, 10BDE149B34A218B62D35AA3DF252FEF49473C2F730F4868E46FEDB512AC8F176BE2A0C2C339CBCA3A70F9133CE0FEE52DEBB53BE9028901C6CA0B25F7C7F842F2E +C5AFE6FF302BCBF94FD9829D87F5079, FB865DF26CB3AC31F6DFE99E723F631A89D632B63715606D8EFD1ACF7D492A9E974B200B1908E0DD532D564D567E37017777A6BCE040A5EE643950EBB838B601C0, 1CAB509D1E0E6A1B59C2A5D3487D7852CB3DA13533EB1C2FA50A256B805B5B0AF35D95384846CAE1C28EC5329F804F6381BB78ACCF3F737373A2A67FE832D71B6A7 +2510FB4FD908363EBEF8C87D897DF16B, C9F00AA0A548FFACC5478CFA43A2F9F23FD32392FACA4F68AB3FBE66383B2B6E37BA355326F42B58C3A7F6E93E51908D4ED0185D05E5A7844929AE208C3B51B46B, 5B75696DFC684DC9A8432317EFD07C0B2691A237AC0E7498B96730FF547AA7CD9B51B847BBCF2DED8CB93BB0482B67E135F874F5F4C42A8BBE1B70C58600E98F85 +6F32F1EF8B18A2BC3CEA59789C79D441, 1F866ED983E6EF590371618A0BD8FA42B0DD46AAC941F877EC14B24C2B828CEED391ACFECEFC04E35A0DD1FE856426D83AA3FFE1F5556919FD697066BBED3339335, 199585DD07BAFBA24F2DFAE36A30E040AC29EBC63ABDFCFBEA0957702262334EB1A7FA179C3BBFBE928AFBB4D0532A8F0EF113CDB8982134A9D326148CFED21F762 +14D98D5CEA149E834B6BF0C69D56D7CC3, 10CD4E393DF012064B73934CFF7EFBDFC72F3D58CCD733D885EEBAD4B91B64A5E504FDE8F2299F704472772D53CE6D81BB39632B81AB25FFFA7C774E901E1A222F0, 29178F12625748895118D70305535EF88A93113FEE977DE33E330633D40181E9F45DAF7030545F55EE8A612C608B7F41F2812B79D9C26CEE3734DE551026E58CAC +3E8CA816BE3DDB89E243D253D80487649, 171E578DFCDA69BD9D2DA57DBE8A515D48D4C4BA222627FBB8B068ABA56059569031113F60CFE8027D77F3FB990C73F70F1A2E4BF31DE19DD0202334CD1157FF5D3, F1101674FF1C2831E2C145BD2ECCABA19ACC2B87B68A4F5BF5CBD68520C679861800C8366D545A7FCD9124349737AFF5478EC4DAE5F1AE2EECF5F9FB8ADDE9A292 +BBA5F8443AB9929DA6CB76FB880D962DB, 542880C040CC682EFE7BA92DBDE3DBFFC5780584AE3D1F7C2941368F0B44F59C98F27014644580BBFFA2C62C4A81DFA087ACBA7F0A24E7DD877FC26AD10D074040, 18687D13361B2E4DC66E8136E50BBEF079B5D6AF64B839265EC3871B2A9D034FA97A94DCEB81D154C020638D38B4BAE16C6DB8657585EB4F60B71BA08C9EF05CA2F +232F1E8CCB02CB7D8F46264F29828C2891, 1CB8816EC66D80ED05C3172AA33B4F8C8F023816708F2BCE3B41C42AAFD41C6853796F7D014125124230EC2648BDB7088A1AF454B01B4EA6F77E39361AC698138EF, 16503C993B51F6FC4C3EB4A8D408E7370E6EFAE214DF09850DFE12B1C2E7E9B90831B1F495CA81BEB9A96C662E0B223CF4C957E2B3A362AB603B0DD26770C6321FA +698D5BA661086278ADD272ED7C87A479B3, 3B2C55D7171BADAA27F36255458B30A71749AD17F111408543DBC83DDED63CFCA7A232A9A3FFB18073CF39803E8F6F0C1AFB5E745CFC8F923C410B7AE751BE80EA, 8F56701849C8FAF70AFCB92AAE2B0E48C1E85114B78D545635AACE43FB0B51EA53B3CC6D54F13345BF354924FFA4E26C710173F289E49B9A1E10041C2078C1AA64 +13CA812F32319276A097758C87596ED6D19, 1FE012AEF9537E574FE550E8E145F2026F96D3EE1D2301B3D6969D977C4C314E9078F0C5ED85C16C44CBFCE04CB44EC2A7072C5D936495A68A601BE32EDEC595B4D, 1742AC39661002F4DE12307D367F017BB4685AB03035D6B90CFB4389E139DCDFD1B432FE7DA51D87519E46CE9C6E6496A13F59299830B326AA54979477523D547CC +3B5F838D9694B763E1C660A5960C4C8474B, D2B008C3D599CB7CC6C4CCF5F06421B49FA454D80B0503D66E859D02EF0F6A1507FE3B42B5E3BDEC83288AF0C2E79DC348FFC3509A389F223104CFBAC4337B20F0, 158571D28D8179FD934EC4146F45C844BFD806DA4D218567FC4CFB08A1F01B5EC213C8168477816F230DA0FBFB665278E79EE36501C673292F3DE8087B1BD7E16D0 +B21E8AA8C3BE262BA55321F0C224E58D5E1, 4C23E297383022249FAEEC517AFBFC0EBE45AE15602AAF45023BE25A933D3A9A85FAF3B72A2E278528B9A753D3005E299764BEF3A475BFE7DD68EA3C72E7BABF6F, 36D4680C53A60472483B7B8F1845D56BF19FEAF97146E16C66D78A4C5B2EE27088AF0DC602652282269A68ED1CBDEF9FBC6388B28BE732A9BF4DD38C599E3143F8 +2165B9FFA4B3A7282EFF965D2466EB0A81A3, 2F7F9D1A89B72384CF5B5B604246FF8AB4BF00A68EA1DFA7B1DDF8345D2016F570276A2ACBF321772DEC7524128724938E74D5E369F6EF5F919ADF2E8F0B8F87CB, ADABA23841365A83D287BB51C50E3CD0149C369080CDF2C1082A7E359A16506AAA3F0B6DB5F55B3CE9977772D434D7AA0CF8EED7B322BFC16790E2A257AA00B144 +64312DFEEE1AF5788CFEC3176D34C11F84E9, 1EF2DDB94CB948844F7C000FBE090D7878F02C3AE37F722220D92255F5244889AEE0B5D0CA9CC1DFF8EBCF35C4C14D7E33C052C47BC870F5C2F648F3AA9F156E372, 17F3D6D89125ABD457EE45B912AFBE4E9B2008C7A95562303CF7A0F2BE09B69D905E5494E0EB3FAE1C47A48924CAB4C56FA49E970E57599C852E93208AC0B7747D6 +12C9389FCCA50E069A6FC4946479E435E8EBB, 11A0907D5B4E6BAAB05F813A307D7DF94FE31024D96233DD9F52966A94EE19BECAF0D93F6ECCA6217FD70954B37929BFE22ED5B529A1FADE6896ED358668E746F27, FA46B3B6C5694F1B4AC9763E9877623BE6DCB01D6A101088DEDDA69FED18D42B0ED1246C4DDC739D03A411EAB3E6316AFDE71E8CC0E2AA04FC8E5F137B84CB8E30 +385BA9DF65EF2A13CF4F4DBD2D6DACA1BAC31, 1ED6569F5F669F3E6A55A52546060D59D5A1561B0E8DF439602195CC8BA01C90C3F80D7FED2631BB8153EFA46FD56B8CB0DEDE95F9FFD0B0546D23ABEF7996226C2, F4E4A923720917242A16BB7CC62A07C4D017DE653D76AC912783BDEA237F6731AC2C802C7ED70639B1B00026534A9DEC23D7130BF3117475F9F1A0702CDC6D6D59 +A912FD9E31CD7E3B6DEDE937884905E530493, 1EF01E309E9B1FB687AECE947806C35B944D9E5EE06E61DB9390FDE011309E0A91EB0F4FA4A5E62E6D5999E46A4C2D48EA853DCD9313F4BFAF853C4ADD1CF47BD72, 195159841C9D16C350B52E181F559EB969BB113BD08B5159B05A1980F53C799EC1CDB1AA4C8A040B9D9D67B2F794CCA95EE767BB18AF9FD36C45318294BA1668C80 +1FB38F8DA95687AB249C9BBA698DB11AF90DB9, BD9334DD3485BEA7DA10E2ECDC8F5433A34C9BFE42391068BB8C061C129F700FFFF83B6FF9D31B0E1D3E2BF65ACDFEA9BD244D055D50CEE355412A4EF9E8D49356, 1B87707BD5D317EB668D0176B786C728DCFFDB8141EE945BD989B27AB1F31320E5A370C582E6F65D91CA166FF8D99DDAACE7AEFBE1576A86135171ADAC1B3FC412E +5F1AAEA8FC0397016DD5D32F3CA91350EB292B, 142991D8B21AB53FBB5380B3DACAA3E41FC1EE1ECE7641DC7158621418523DBCEC0ABC7CA28DBD6BCCB6C3097C67F5B60B203F0636F9479EB1B7CFBB7557C14D5A2, 1434E44D52CDED2ED19B5A3B68A0C618EB37B217F52BE2E56CCA41B32FB1E04424FCD9E07BABDD36958108C77027311DE4935A203DCB32FAF18345EDF762B4FCE76 +11D500BFAF40AC5044981798DB5FB39F2C17B81, 74FB515E4078D2CA6B1B17E3297A70726EB56C124EA964EC24FEB6139A5DA47D3F196109AFA5D1115B0C64464D8AB116708DA0B760B9903680AF97F30AB5552E18, 13D19498C65A6D9BD7208ABFBD74BE1B67B113B378B58035C2FA0D0691D72EC683BFB7001080C90635E837B87621E618690179E19F580E5DB4F6B3B28E61E6FEA05 +357F023F0DC204F0CDC846CA921F1ADD8447283, 40581EB0C5F1784C5A3173C273ADAB26E7D72EF757D175989BF73BD364812F7391381DC96735990F8F1F0E36E1EACE55F713EE4FFAA31B516838A3C5F878BD963C, 173B41D46C73443E7EED3F153A1744D7047E8ACC8A949AD240F8D315FD681F4FD44855D23C5FA4BAAF050CD21C10F13BB1A041C170295AE19BA25A1DE1C4208E4BC +A07D06BD29460ED26958D45FB65D50988CD5789, 1564AA18C5C10364E75E1211E1D5957C673B0640720CC5003A31BD1367E2647937C29C56B6916F44F73F60B1EAF592FD808D4C4DE874BDDA27E5D88C14A71D75EEA, C53D8A2301F213A680F58774FB4CFF9DD3B6E8E53B94B94FA131BED87DC53CFC4C6BE4C084FF9B94F35590B74551C0350E718D994B10B1C9E44373152E76FEC25C +1E17714377BD22C773C0A7D1F2317F1C9A68069B, D1E6F2EF12C66869F67933B64C2F4E16E93476720B87383E61FC410EF3D0F9684C1A21C5B9315C29BD4D631EDA4DCD1078978E678046660A8FE982DA818C32598F, 185D08D93D463230366480261B90AA10CFBCE2DFA484A5F5BE5627354EC75340611E7EBD3B10B03165040C0E5C50345C298FA9FDF937C5B76384E72AA2A01E3359 +5A4653CA673768565B41F775D6947D55CF3813D1, 9F9A8B3F2C05FC80D9C0897A82B47D657A0A9172DB16C5EF6BF7B7CCFA589BEA69CC9318A9B7DEF5A4E1D69065B5364CED0F097C073562CFDB61A9D9F3829B2FEB, ABF0E1608D995600118FB59CDCAC5D6337E04A79BECED24697291F011F185AEBABF8A4CE35EF5AC09BD274D21A393FF6A25952D959429E6E00A487941A531A9DBF +10ED2FB5F35A6390311C5E66183BD78016DA83B73, 11717702EAEEB89C79271FD5B6E7E04DEE3550E8F4AB75C89ECBD33B636E3698D5EF69DF324BB8B3EC6B87744718501A2C7CC9A9D15B3A75C015DC310A210F09A40, 1BF3ACE0D121D1653E89459C50FAED6562BA69D2A0CBC65EA92DFC5034C2021E29B16C6B43B436BE76FA7D31CA1AFC06C803D43060459DF22BA75312F158A0E32D +32C78F21DA0F2AB093551B3248B38680448F8B259, A3D261D481EBB0969C4A6767013AFC759D91F214A5EC4F85C7E504955FF6BBBA4F7A9F4883D15C4BA8F4A0AA86E5F70E7ACF8447E44126DF957EE85C4BBB37C501, 62472A2C7D924E1AB0C95C9C5A2A205EA31DDBF4D819A0DA4B9F76AEA610BB2FA8AF486C18FA0DC5F33B4BB2309B5162AECA6E7A76C1D783CA9DB7B0405F6E4B2E +9856AD658E2D8011B9FF5196DA1A9380CDAEA170B, 72A122AC271DBAC95F310F20E8D8A0BE4192A7E701C93B600AD4AECE62ED31D56C4B1F5CB180526FE2B898FEE0CA1392368A11284DA1F0D0CAD7F429B5FD2B7DCD, D09B0D1D5B5CF5F9C068B758E333A1017659ADFC6CFC7D251E67778D8D0EEFF6F1A03AFE47ADEACE046B0B6890CF29746EC4D774BAF26D6E2F7A7FFE1ED0991F64 +1C9040830AA8880352DFDF4C48E4FBA82690BE4521, 4C1A20EC2425F70CDCE5358CC7CD25D0DEFB0ACFF160BC4AA218AD3EB91304D17B4A134EA4172933E39EB25D0DEE0B1A0775CE2580B7CFDBB449E2A39B9C596FC3, 1E7B8A2A66FC73F114C81AD17D7FC08DBE776804FD3B83F6D2781B8E87E67C1667461BA0EE0B2BB16A3481E10CD940E8A5815A83785F0A95768358C6D6D43CE2A56 +55B0C1891FF99809F89F9DE4DAAEF2F873B23ACF63, BE5C3F42502CA61D1E5E677D4221FC08CA8F1A4ED3820EF4426EAC78043187379E5261254745F2FC875C90446B4A1E6CBD532F276133AB456BDBEB0E25A0D53D41, 174A4B5868018B84BD3897D160E791211889C3CC956E4D985FB6FFDCAE7D2836B3CC542F037971D2EB442D965C373AB5CD51087090CCE1EFA725AE1EA5DA932F70E +10112449B5FECC81DE9DED9AE900CD8E95B16B06E29, 14868EC0DF006ECFC9D030DB5D1EE2009127F2E91CCF2174B3A4611BC5FCA6A36143D312A1A540D4871C123F6CE5517BC6490A874B09CBEDD30B2761F7ECC64F9CD, 1DB894269EF8C3F60BC6998F0EB3D41A2E2ED7484D1CA927F80F3FF0B5EFCB6797857A114F9E38061EDE7D53B9FDC977F7CD6A53E4ADEF5194AC5A6A1238DFD927E +30336CDD21FC65859BD9C8D0BB0268ABC1144114A7B, 169D74D0DF6E55C842F42DAF2A7576785AA500100528F7859AC23B2279F4F9B48AECED1237856844D87DCCE57D75A38AAEC5FC54468A507FD5630DDECED73C6E781, 4C758619304B7209D2EE9F95698FB440F498369BCCAB059A61E8BDC4BE5636119C03B6D2B7524087CF5CF414A2DCA1801BBD04CF066870B83864731422D3619D48 +909A469765F53090D38D5A7231073A03433CC33DF71, 1CF38F976E1BCA7C2167355075FB849AF27AEE67B5662CE2A0A1431D4E4A93E1EC871FDD78092A42E13D87E16DFFDAF1139A4C097EC77EA6812A6BF24D0EAD26821, 1DA4F590E499D7787F79162DC89C294C8C5D8051FDDF922231EE338FB111E21BCBCA3A6ECEF2FE6E4F894AA507DCCC5C4191A28D848B8C5E80186FA8514B0DAAC47 +1B1CED3C631DF91B27AA80F569315AE09C9B649B9E53, F111900E115DE9D3765613A20DEA4D5E298BED03A193EDF851E0D73BA054F720821B14560BEB25929EA6DC3424E7C7F2D986455A4CA92F96B74B556D6536180B30, 1FA14F416C63E6A126894B3C30B3433A5179A347B0BB479F6F961EE6E3331A0CB4CBA92B0E83976071B67218F8948BBC5F00EADCA8FA26BED3E5BFCF494D8EE358D +5156C7B52959EB5176FF82E03B9410A1D5D22DD2DAF9, 111E666ADECCD8BD3BFE3783FD87F097483AA335F2D8206ED1D37B81F508D19DD61BAF93FCD96AEF68AB142407E61FC8C1FDAA4458D6BB6A0044E6F018AB8686F7D, 131FFCD5B2D80063ED2815BEA13A5A5D1E110458CFCB6F36CCA1BFA55343F8823E68D0AF8043551002A08DBA039245117DD070B88FF61A9A15CFF145AAE0E0F6CA9 +F404571F7C0DC1F464FE88A0B2BC31E58176897890EB, F2D496483584F01E1380FF91B4740B51859EC60ABDED4AE8ACE803C66B822B5FF693892A496649415FDCA986541E35863C3018FE33638CE4D2411F65BAE0D714EA, 8C4CF8529470E0D6EC329ABF9FBAFF170D67885F1EE19FFBE6ACF844FBF233CBD595C6534AF1E27C2F63E85D9EC2F9D6952F4622C0667AF9F85A0EF9F96EDDD2CD +2DC0D055E742945DD2EFB99E2183495B084639C69B2C1, 1B4F041AFC25FF407E0038A9DCF5AA42B7B99542F5AC80FACA31458F36B6F466B6F0660A23264F28CD0EB31144D83A001002058DBA811E1AA6265E34F50654F318B, 7E4D4E645B80E8F070DDE8A3A5FEB2F578FCAB84085112D6E9483775159938B53C8EF5DED2CEC556D200F20DDFE651892E009C8D5BF8CCC95F1A0A5F17E877890D +89427101B5C7BD1978CF2CDA6489DC1118D2AD53D1843, 1526597072116E68F74763B7DB91938AB319D8FAEEDCA942A5BA6482356DEC3DF9E8895C88A7D9DE6590AC9CD327E66D9E75613DCE5A8953032DDE0BEB4B85D8B7F, 961CD4191924722C5EACB285AF255E56A2DD4BAE958CA5952C4538FE5E7AFF79D2AB3515A4B031A11B95F2AC76DC763B40257CFD9D10DB6FB5A1C21DD6A53DA8C9 +19BC753052157374C6A6D868F2D9D94334A7807FB748C9, 499FCBA3AB753869DF5D089B5508BC7A0AF8F5F6A545C7BAE4C57A3A69F8A09AA3B300389C3A04C70D59F5122828B0E9F6EE9385C512FD3348940605D8A57FDADF, 65AB9CC6B5FE8E00634578331B020C3EF09D51386E1904A1BE07AFE833D018FEAB033CB01E854D8CA3433B693C91676986AD310FBC26BB5A1728EAFE3E4B43083 +4D355F90F6405A5E53F4893AD88D8BC99DF6817F25DA5B, 11878C5B974923546375AF0313FB844924EEDE1F76C8035C8EC2A8152D79B03AEB96F71C7618F851B40B4AB5811C402F6B877F233C7F6F77A8CF025BE6819D901C1, 71ADB0A94401E1CD89A353D5089B58493AFA093DCB325D18C3A582AFE1B8B25055467B93C61B1F5C35E8645D90B7E9EB062F36A39D621029BDF6AA0639E25532C6 +E7A01EB2E2C10F1AFBDD9BB089A8A35CD9E3847D718F11, 1EB6B4775061A40AB1C7D14DEA339FB0CEE8EF61EFE340F20EC76D52AD03BF60A1B6630187A1D0B41CB0F062C91FB97CA454E77936B14CCCBD6ECFD39207E98D0E1, 119309EBFBB787F62EC0786D5AD5ECF146D7F8D4758C896680180B5EBF119DABE039D55BD1C503252B25713B29EDB52DF67CCDB83F6859B8E66897E3BB3EC10D9D9 +2B6E05C18A8432D50F398D3119CF9EA168DAA8D7854AD33, A0289125A717D790905F7B1171158B7644ACCCA44BC9DD67F2778C89DC7731B18908040BB3F891AFC5B2E5168E1BC29442B8BF5B5CBC0F3EB208D9980A5D1A73B7, 129540821B079BB7DB7BF9D9075CEA7833458FFF77950DDC90B7DA4D30EDEE52B4CDEE9519DAF6FF5898CA3365CF0107D07D9CA9DD0DA2BA47FDAF821823AAED34A +824A11449F8C987F2DACA7934D6EDBE43A8FFA868FE0799, 1A0D36A91082C697C7FAC4E50887B8A8AB6AF0C82E29B648A7144F60AF2C68A316A90DFEE21303FFEC7DF1F9B6506747943295529A6ABF42F2624B23A60328C3735, EF0B8E839A394FE4AC141BA2F2DDA0DCC357A5461EDD668BDE46239ABAA3A91BEABBA5290463DABC13A426C5F250F26D559CB9131D89D28A953DE7BFE8F2955A3D +186DE33CDDEA5C97D8905F6B9E84C93ACAFAFEF93AFA16CB, 1B099C1AD9DF6B5773444416A28A28BF25744C9E24F80ECD775417AED062C1874E84E3768FCBD1E2753C43EE7B92ABA6CDC2763296B0E3B88316356517292AE9040, 9FE463186297600D62182EFC6D5184758005A894C96DD177491333ECD2738BE64B5575FB0C453D49DC9348BFD9784B9271233E5C3992DAD8D3ABDF1D4567DCB16D +4949A9B699BF15C789B11E42DB8E5BB060F0FCEBB0EE4461, 103A1AE83D0C63E738F7EFB2A35C4688C93A74FE41D0AFCC3ABF8F5E1558F00A172506733113EF0AA7B41B1D8C3A5A6DCCBD252093EC9BD62794DB6FEE9E86D7EA6, 15E4053454D9FCC2D3CA84B7DBEC5C2450DDDA3035FDA7E6788FFA0F8D0F038753A2FBD4C103AFFBF9D7E36A2F8139FE3DCC137D41F061A5C1328A9901FC6B1585D +DBDCFD23CD3D41569D135AC892AB131122D2F6C312CACD23, 662249AE4DD87AB5F98D8BE4E173D91681948232CBC5C3F879AB89654018AE70D797B806967745E9EBDA56102EBF6A72AC9BD5325D3F7551A37D4D123086308F90, 1478866BB350E2AA72AA154037D6D657DD1214072AE0E6BC2B871FE4B178E55F8168A147416D8A90478A4C559C4971CE67C0764D03754EF17100C4A838B82545A6B +29396F76B67B7C403D73A1059B80139336878E44938606769, A2B8066D700AD69186ED471A2015DFDA37D30C72016569F9C57170E78B3B3FD6085B6D2ED83B7FB0FD0135671FDA71375931F4BF21A40600B214F8856801F70BAF, F3C3A4D255BED81E9A43E4417C7F2EF1BB99013BCF9AE93E0AA273DA41B0441E5EEB722558A89A6A5CE50FAC5A513A1C8546845CE4070CBD5A0C520DEA724AA1CB +7BAC4E64237274C0B85AE310D2803AB9A396AACDBA921363B, 6B65E9AE0ADA398071A375F757BCDF809C0DE791D409D711F35278D94A1C56CAE3716EA377E91A5B2465111AA76FD98BDF4A654F975582B7E041E77BCF3B1D737D, D633E4CED977BE21D68CC999596F0ED8C4890B938AB85BC06C5A2EA52A439A8FF5C70C72884DEDB18D90AEC29CDF6B17086C94CE5162E6F84E4A8308C4DC02A95A +17304EB2C6A575E422910A9327780B02CEAC400692FB63A2B1, 17FAA1BFBDADD90A856D9B2FC478F5402B1D2918C87668F55BA10CE65F676F0748168CA0D02BEB2DFAB95ED49399D9C4495A93C6CE137CC3D0B45AE030DE85C41D7, 1163583065327C943A30C9BB603C480727DEADEA437D0D5873E99DF0BD3487DFF2686E8AC8ABF3DAB36D19DB2FA5966155D8AD2C337B65DB70A05D7FB3813B847DF +4590EC1853F061AC67B31FB9766821086C04C013B8F22AE813, 1283BE1296F2AE4C4997BBB632EE6D07944AACA7D641CC8B3DFB8A0905915B005844529B90CBB2EBB4CF6BADD117E2858DCD30DD6560F87CAB349F0501E925ABB82, 13ADC3807C80A9BC519F74419B432F120BFDC918992729A7ADB3AD95206BEB793035960DAA0E5D002EA8E6DFFF927472AC1DDE10AC7E196FE77AE23C5E1A647CCD +D0B2C448FBD1250537195F2C63386319440E403B2AD680B839, A8C3ADC331BF40F457720076577CFA98F6B61201E700DB58FB4CA46C1AEAFBE8EE0BA52B1BA72645A3349B63B98DC252C108914024BF8CF706981993DDD6310D72, 18423EC6B5072CF004A624699C003F2D7FDCE5E243DCDAFDA117273D72746FF3A917EFAA523FC2226D9B39F52569DF509FF340B32E727A6A22F3A33C62F4F1C357A +272184CDAF3736F0FA54C1D8529A9294BCC2AC0B180838228AB, 1FCE7ABC8F809FDE63758D1E935AA2D81077300AEC2C16AACE21DD6EDD93FB9333E04B8B403902C9F1B71C2FDF8A3216C20598BB16DC90ECC6D066794EC63CB591C, 3C61DB1B9DEE067756E94A963A2C6E3F4BB681F28EFA3D2084BA6F8ABEF41419E4FA8947B8A02298542F4A3B1F4122745E1DE106C90A69869E0300C68B8CBA169D +75648E690DA5A4D2EEFE4588F7CFB7BE364804214818A867A01, E6BFBA40FF120E16AA00C0F66A80F7DCDBD7D6FBA8EEEDBBA02A98B760A000705E85DA0C7D50C48740047F0DD69BF9DF9C62A11F0F116ECA18E4EA546AFA1BFD8D, 149A3FC28C6383506634926425F33DD05C0CC9BD9480E0612F0A5D628B4BA963D6B297A44385F3D1895FC16137FD2A38C24A023053356A993BD4DEC457A46DC2282 +1602DAB3B28F0EE78CCFAD09AE76F273AA2D80C63D849F936E03, 1D4CAF57B94C16D0AA062D2550C98F220D11A3225CA0C7D8E072BC3C241EBFE8D4FE18121599EFEC0BE7EA42C096010B3693CB88F236A53337296723A4D5534B667, 74A7A7D6F099C8B93EB56BB9BFF40AA69B864E8CDC6AF09C5DCCF7B6AB3EBF2FEF2707486074BA12BD1CEFC7D0E3A64D952E4079F7A28CE69FB1E550B66D905FE2 +4208901B17AD2CB6A66F071D0B64D75AFE888252B88DDEBA4A09, FCAF330D53AE4078B34A33DCFA771E7DAD5DAD53FA88CD734FF7E32C4C14FC544E0D55DB2CC71F0C877D1C6C8692B582BA5B4C2BE33530E0038495673C8CEB50D0, 569CCC4D8CD0A3B06DFB4AECB1480D22CA7C9212EC22939834F51856FFFA9D4BCE26CBC1F5BB02A19976670AFE3CD0368AAEAF59D859C2C3087B79F9877D404412 +C619B05147078623F34D1557222E8610FB9986F829A99C2EDE1B, 13858A26EC38DA9043362D4E5A46F65F9879B95C1F9D577360331017C3C78940FBE597F3CB320B9167C33AA1EC7014C3216A3C74C6E6FB713BEF1720BFAE6B85D0B, 127E2683B280F8214B351A92F95359ADF1E8EE20A57123460696269FAAEDCB05DA8EE020E114E476A07716DC8D2D290097AAF4D09C6E2EE25D6F5A811BEBC554BF7 +2524D10F3D516926BD9E74005668B9232F2CC94E87CFCD48C9A51, BC920E011597A73E2EA7EE4340517EBDC3DC684021895227723C47989293D8892799C3910A22BAD473DB9B926D7994D89B9E6364C387ADDA4A7EC4F899EE46EAD5, 17C42CB788E5A4074F5AC52BA2C9DE4141C5A98A34C1BF61D6211EAAD6240CD678E800EDFE55F288332BE5CA9363CD4956AC634A5066EC952636E3862847B11AFDB +6F6E732DB7F43B7438DB5C01033A2B698D865BEB976F67DA5CEF3, 9759EC582DCD5670813AFC147091E485081FF3C3D562AD75F6F568F84F64F5146C47402FF67244B573AFD63955706DDBC77009DE6F74C4B9F9981B978CAF2C639D, 1E2933FBBFE103F66C86AC29389D9DAD27B8762225F73A0F3ECC418A02A63872C791F105C33123C562C0CAC2C6E87106DD93344A311F3AEA85AE4B67980B60C9234 +14E4B598927DCB25CAA92140309AE823CA89313C2C64E378F16CD9, 1DBD594A0AF67FC7CC2C2FE844E483B3A597C84573F0FCCD844351D43F5D57ED973880B55C02D48DFC38AFF28405B3194B0A0C4D4675571F2AE5FFCE93F3E08466A, 80D427650E87FC3C73D52BA682597946D0865E3F9B1519B17E2D5FF1C60F2FCF7530EC55FE580F3857872E97749FF95B6D263BC697E29FDC85C51953D8A72096F2 +3EAE20C9B77961715FFB63C091D0B86B5F9B93B4852EAA6AD4468B, 190DEFE7D1685379A0003C2A0D82EE746BDB82DABE09510ACF7204360D43C0A3314D4EE74633741A52771723FF1B6C6C8526A12A557BEC896878EF9D11E1B8F8F0F, 5BE592B217845D4CF9059046C53F85B8726FE113BDA0065FCC6E5ECC0A06F93BCBEE6A64061EB48C4929561B3DF8C86FB0BA979662DF1CF3776BC19D74E205A1B6 +BC0A625D266C24541FF22B41B57229421ED2BB1D8F8BFF407CD3A1, 11B6D026D9F4851F01D34D7F5780701DACB7AB6DD7CDFEC470E25C3652C9C779A982E474CC1208F9EF2BF596D74E1FAAA49B43E973A243F8A5B60D3FB66030DE7E1, 64BF8C1BD5473B0D461B492183C225F0D0F3AA34DB8B7F4C7C3EE06072C87AD140930A462EFFDDB14FA9E1FE435E7180031B7F005D34A1D0CBE48858AA299BEF1B +2341F271773446CFC5FD681C520567BC65C783158AEA3FDC1767AE3, 164AB3523A729201BD1D19382F1DC55E670705610412A8DDC168FF814FEB847BD56849A951696ECF9E227DE82773B6818C92BB2628561BE0D5A1842794AB4CF1F8D, 22C694371AEEAF25C7BC9072A8840B28B59F672AE5D17261C003030E780FFCA5E9D01D97931D2187DCD0359A4FBBAFF5BE89917A0230A7346577B5D2C93B0D1BF4 +69C5D754659CD46F51F83854F610373531568940A0BEBF9446370A9, 4BC724058FBA3F6B8DD55B549FAECDEFF30E9AEC3E1AB403510FABB0F868CF4B169972DE4A859A88C43BDC5203A926582A4826291162059A5F868E08D94FB6A665, F937E3699DC0F1E7516E0CB5ACFB648B32F44E1C2AFA68BB02C512F52723CBE81B887C41CBBA3D694A7C1EAE2395C687CB605F0019E150419D4F4CA4CC4EDFF17D +13D5185FD30D67D4DF5E8A8FEE230A59F94039BC1E23C3EBCD2A51FB, 1D892EDD5504144A3F3B9F007D54525CF4D84A64D2F673559FD7D456029B02C3D7FA010FDCE1CFD670E16376C2DFD746AC5CF39D2B05B6A4545013B78B315A4E55A, C17218A3397CB115A3595DE79809EF3C4BA2B15ADA5EB22CE4015ADE9E4023EA802B8A8DFF386603A670B4987A98421F86868278FE5AA043141596C72AD92A244 +3B7F491F7928377E9E1B9FAFCA691F0DEBC0AD345A6B4BC3677EF5F1, 3C5B2B112CF11BB235AC1B800AF6E31E35471CBF50AED698BF79299C08A3738B41C61042D970202C3913F4D498B0B41B20A13BA313119CB532872B1C4C6232E07E, 1D5AA48D23764FC6359A13D989F58F22BFE9207B146993E1EDB3056170EC936540D0C9953252B7EEBF97E13CA04621AB62CBE5F1112A4A3C6E7C1CDE43755B73563 +B27DDB5E6B78A67BDA52DF0F5F3B5D29C342079D0F41E34A367CE1D3, 10E8673C755C854DFDA62B87D3BD2D7E63AF695636574BBABF04CD343FA7492FECA79AB043031DD2BDB90CCADFE3F691A89E3A131565D66396CE69E22FD6083BB67, 74AEDED0D962A28B5E758F140239A21455273FA8E1913FD4A53357AD5B54668BAD4A2D8A2A1934D3B33EDADCAB0D727508FBD18E8AE38B5A0600D34ADF1276F27 +21779921B4269F3738EF89D2E1DB2177D49C616D72DC5A9DEA376A579, D0729406F428C80837768678BB983027AE7505DE8FE2622C5CC714FBE823AF37E0734CCE94B3B8740489658705A891F8D880C2DBF11A51DFC26A2D2F182B6A68AB, 7CE9DAF11E14AA829DBF52642EDF9B492869835072FB9913CB795BE185C0C3D6AADF859B2AEC23CE27B64D74C2900A9F2EE47A43584EE9F03509C94C6B05A70BB2 +6466CB651C73DDA5AACE9D78A59164677DD5244858950FD9BEA63F06B, 29F0A9A453EBCFD62C1FACADBE38D211E7313D6E2FD33D958E9F6C3C6A611D7DE6A3770D504CC09646C2C4D10977EFAB8471EE836A808455418F7BC9A453705D01, 11F9663DF4E4A066EAED2CDAF290FB828D6250EBFA971A845728D0521EFC09BC3A916FBCA667F548216E624BF530BF81128598D8A1061B040DDFC557CC88F9418D9 +12D34622F555B98F1006BD869F0B42D36797F6CD909BF2F8D3BF2BD141, 11CE6BABCF9E8DDB31FE971D9E45D4A5C849F9D9595BBD6DFD8EE2238EA53AA41F1B5EBF7D0FEB3362A147A29FC186D8169608EBED6530BEFE559C735B59FEF367B, 3B7C2CA6780FB6E5B8A9C322208D68F5E750408A16D5B64EFA80401871D10EFC5FACC14A2B85A29BD03C1D283ECCB737DFC5083E9BEC57B66388AAC211780C4D79 +3879D268E0012CAD30143893DD21C87A36C7E468B1D3D8EA7B3D8373C3, D4767066E75F170297AF0A2DFC8B992DAEB6C9659AE1853C864141DF8986CBA47DB37AFBBA09F3B5ADF21E872A9ACC6B6A55C657BA30A32A546504E05600264B1, 6AF30CAF30BDBEBAE9B7B9E56104D11E6D1A7727F95C0D6B1EA7B2F289D3C422056A752CE684A9A1EF307CC7A343EA4399B09E88AEA783367F3F33BAD7DAC2807B +A96D773AA0038607903CA9BB9765596EA457AD3A157B8ABF71B88A5B49, 17B8CDA732A38BB4F2E5EED4598C0F559C09162C32A7B58DFB5313FD14993A33E3A0DD74F40731E39A57A02FA77C096DB8A80214245500580BE4C012FA5E0656448, 1B544800212017D3135D9414D74622C7EB388485F74CCAE80C7C25E19C313A39A048761521D73D6DB4AAA6A9312A6D72CD64E1DB67325E04C74233C6E6000D2AE59 +1FC4865AFE00A9216B0B5FD32C6300C4BED0707AE4072A03E55299F11DB, ECDA2A3B7F5A1646BCC1D161E8E1166CC2FC436C2112BF60C0929DC435D1BB987CBDB27DB1CD4A6A4CF270D07C9F90243EBE432ABB6F595134F3675324FEAA24CE, 785B5E021B11C2CCE21EDCDCE3DC893638501F9E78642BC8DF1EAA3BF093441F18675F1B371DE21C912A46594F120299813ED460CE1195E475C6AE1A2A05039CBD +5F4D9310FA01FB6441221F798529024E3C715170AC157E0BAFF7CDD3591, 159F88FF1E2F2FFCCEFD23F8D1A38A4FA2C522F6B9B18147E03D72BB12C9C2956BC994634B0A74DEB22194A011C5B665FA0DB05370781A86D683C9E7564AC7DCA3D, 1E724FC8785486A0F677C45DBA1877FC91C6D7CAA4223B2F5916B86AA814A13337A66747AAC5CE9532C804C03410FB8559397059103147D9EA84BB756E0FD56EA18 +11DE8B932EE05F22CC3665E6C8F7B06EAB553F45204407A230FE7697A0B3, 1610A5ECFE3DEF284957B60A5E93D8A1C7535E4B6ED12C761E3B0E471F791D8C18234675F21F30252E776BAC8CD146EDF36A4A8F8E4A53725DF306A0D3673A57E07, 29E8CF5534BF3DDDFE777C2D2990D3AAC191DE1F484A167A58DF107587AA566247DEE42557C156CF1FCBA36F8363CE7C3D84F36CCAFA3E583EAFAA8EF5B9CACFD7 +359BA2B98CA11D6864A331B45AE7114C01FFBDCF60CC16E692FB63C6E219, DEA62C72D6C78050E75C00035E1AF8DF2989C894D670DB01F349FEEE0DE4E546925714AF015AB274EC618C4768BE274DA79CFA22E94527DFFCFE14F4354D16E2CA, 123797023635761679034FA1950AD28C33B0F8D96845EED5D88C02E7568B6CEC7480A8770191CB2FA14D2D6486F0E10E307AAA05C1056995BEAB328C9B7B6DA85E9 +A0D2E82CA5E358392DE9951D10B533E405FF396E226444B3B8F22B54A64B, B87BBD1F611BF92D894169BFD4F23547E36D67DA0336C63B1533A9CE21CDC96A0C64C6FDD178D3F08F9B8FA67C55F28DC47A6FE8790F53517D01A961B276774EC9, 87F7EC1DB9880B43EF8834F32B5F032F7459A9B9ECB2A75EC011D81351E43A6D5B73541A1D9E5A9E518B9B53C4367330B9492A65DA429EA5C8CFC4DFE6D244B67A +1E278B885F1AA08AB89BCBF57321F9BAC11FDAC4A672CCE1B2AD681FDF2E1, 19A34D1B76A18D0E607EF77C8C814FF033602A21062A1E83A740B2862E66F2A1560D4751ACE19B94FA4CE11C865B64A52519C126A400FA1D4488FF945F4FB5DB60C, 90FB5CAF650751DCEFA16B6E8B0CD5730AB7795501630DA548141AD65516DC20A70FB250991D1791906AA8051C841FC95FFEC14B25E103E3A1471D4B33866039B4 +5A76A2991D4FE1A029D363E05965ED30435F904DF35866A51808385F9D8A3, 1D0831B6FD3CABDA8B1D516667759EB49114FFA69F537F417A4BEC464121659E0A1144DE9F9436F071BAFA3D13AB7B4754110B230411F6C5D7B4E56E3B5BEF3D92B, 392535DF0A31A897E6694651A5093FA9A6AAA00EE4CC6BD57469369E023A76E1249117A3F6986AEAD1F62996397319732FFA864536C678167F7278991F7FF35687 +10F63E7CB57EFA4E07D7A2BA10C31C790CA1EB0E9DA0933EF4818A91ED89E9, E0B3D3C63E8B33E1ED24CC6DA33B6D72742A545C2158D0451194B3E1090BF3BADDE24EB99F58FB01C62524164F6188B0884AF18AAA6A448DA00744E2D1C893C432, C63F7AA54C8955D3909A8E319C919DD682AEE6C9FB4A91D1E5F3F9CF2962012D54DD1D681DF2C18840FB220A64F1D7886CAFBE7A91AB1E96DBB0476DE75591BAF3 +32E2BB76207CEEEA1786E82E3249556B25E5C12BD8E1B9BCDD849FB5C89DBB, 1B418A885DBE10F1DE1D4FAA6625E7C5B50E7F103CF198A5D037719732FB02A24742170611D9A17FF4457DD42F57F31D7A6B9297ACA94F588996845555E9127CC20, 13AB37AE7CC6CADCA4771D9C038E99E1D58874AB894F5B9BE8EC9F14F3A775D0CAC19F8B34A3751896D59D4F0592DEAC2D9C5049176E8A68F298432814ED9773A3B +98A832626176CCBE4694B88A96DC004171B143838AA52D36988DDF2159D931, 1A359A1F3D1667CDC519D36C1962CDCFBCEF7602E48910A5B33288A5EE547B6A3F94EFF8BEC2E547B5A9134A922AE48953B5369CF39839F9A69F11081D76A6BF3A5, 1615CCA77AEB96CE15EAB63C51EAA6EEF5261B162C74B3DC084C90B270DD50EF73FD0ECDFBF4B5BD230C1658BF972875D96165F7591EA4814FE4617F3AC7C283754 +1C9F897272464663AD3BE299FC49400C45513CA8A9FEF87A3C9A99D640D8B93, 1E4FE297E703C93E2B75100F44B6A52BEE272AEDE7A21AE9659E4BA43428E4392C1C27E5A6C9B66A3F412F4BF3843ADE045A1C1DB162D1485755F258D365B48F13A, 3AF8C0549DD3F8B0CDAF9755A6492588FB9685D008ED243C25798DA3C09F15795F7F4E1C82BD554B6C08CB80B425F009652D7692F57AD0B312AC9B05C8DDAC1F3D +55DE9C5756D2D32B07B3A7CDF4DBC024CFF3B5F9FDFCE96EB5CFCD82C28A2B9, 20CA37292450109E49A2A9D0686D1B43B69634CDA8CCBF78C6ED7A29FC1815EF3CB53D5222496D5F0EBB9E835C90493B90363E6903A5EEE8B6DB978DE8A5FAD2A9, 730D3811A46FDF1808F58DB195DF5D2B3A4FBDE18C8AA7A4077A76A4EFCAA46CBA96FA112170F6F430373D2CA457B3D57094F486E9B61CF8EDC1552617BF66F1D3 +1019BD50604787981171AF769DE93406E6FDB21EDF9F6BC4C216F6888479E82B, 18D651487BEF70163585C3C8372872EB86E6A990D4E719C978C91F3A746F74A21360A64BBB66865C3EDE964DFAA2743DB4E4BD62221AA9AA11BFA9F5395E7131FD4, 13085D837CC678A887A51F8D71EA4C19D1D0EA6045FEFF3880B267ED7162D2772FB1B71FED0BAC58BB82414F56B0853864D32E03EE2069EA5C2CC977C8DAED23824 +304D37F120D696C834550E63D9BB9C14B4F9165C9EDE434E4644E3998D6DB881, 180F36A0129B527AA2406918B35317A7B46AA598F972066A1A507358AB092859299D3CC5903E4AC88B338D0ACECFD0EB204A3453E01CE0049C01766EF82C5A34928, 6AD97A0F30FCCECEF1FEE695711E3A496E46DC284ADC1CE2026E14B569F7EE27729D55C1F7C0E4511B3719492A6D3DCA83CF1E28DF77201944FC41BBF73A2CBB6A +90E7A7D36283C4589CFF2B2B8D32D43E1EEB4315DC9AC9EAD2CEAACCA8492983, 1A5B4157F0C5FCB90A58A5DC1D14975B15962F49DBBC2EBA31A65B701C238B0AD022E24E47E587ED570595C9162F3E421B7F7804B6154B8D606641A82A7B5BE5CB3, 12F37607BE36AC4DD47DCBE8015B69BB588E6FA0BC01392B2B36C6E290F5E969BF83A2D1B8CA4EFD79AC7E5B224134650C2C39EF047AF43791A410AB4E68852F186 +1B2B6F77A278B4D09D6FD8182A7987CBA5CC1C94195D05DC0786C0065F8DB7C89, E63A4F551D90B514F4832649A06CAD4523914E6BFBC391A726E506ECE986510A5ED3C551794062755E5A228F3E9957B58DEC10D80FF5A0E479809F375F32274A13, 1EAE6C44B101FD4805CAC7FC3BF97BB1A68149BB17C233E85ECF4A8836C5861AC92AA606ED12209EFE1B1E3022CC3870A1D53C9BA1A4348FAA5FB01BD724BCAA3F8 +51824E66E76A1E71D84F88487F6C9762F16455BC4C171194169440131EA92759B, 1F02E70FE3DCAC36151EDAE25C6D72813CA6DFE36476FD4682E562E82DEEA12CDD3E0B37B60AA10F7195BBF9B0FF61927F444A80AC0B4ED1DB14074F4D5A5E4427, B128F9D80F6E58DAE2EFAFD9B2C284E9FDF43681AFCEB6692E2EC590C3F52B527FE574B816FE8542C5253D7FBCAFE011BCED52CEE20F51CD612F57045CF0EFEE1F +F486EB34B63E5B5588EE98D97E45C628D42D0134E44534BC43BCC0395BFB760D1, 9C0007EA99435B2533454E908173396852D76E54753F270D28E8F0B2E17AC7EB3394A052F105538ACEDDE58FA2B7274911F952015058333A123D5262B241933818, 10C2C8283D9D3709E8297555534587F920ACF83CAA8D6B90EA66486F82B02AD9C0C85AAA0C13E1504B70D7C630F71971ADF6E2DE4D672E1AAC0DB2B8DB0C726A680 +2DD94C19E22BB12009ACBCA8C7AD1527A7C87039EACCF9E34CB3640AC13F262273, 10C1903FB8A32CF20C7A12DAD680CEBB307607879242D08DBDC8C903C11BFE85208701BDACFE16108C22B0BD33D030AA9700E9FDEF79C74E86600134A8222D9A502, 13A88FD6D22788E955666D60008D59354B6334AE2516231C5C03C3BEF456BAEA119172DD74301F53E80344D4A7AE740C1F357F71D645E17338587F036D38B383B3B +898BE44DA68313601D0635FA57073F76F75950ADC066EDA9E61A2C2043BD726759, 1A1CD70F1E683ECF127EC2772C379522976477E1D0678A50CDFC7968FDA4927C4DED88D520474D314F322DBD76571A269931ECD5435281D92D7D57E72E7E659F5D4, 1B627A3A526D1D7BC41D5843B213BAFDDA248662BB6E193CBCB2B6DD286960B95DCDCE96403CED7408EE362D21C041BC0F3EFE412D6051D1E59464D472118B87528 +19CA3ACE8F3893A205712A1EF0515BE64E60BF2094134C8FDB24E8460CB3857360B, 5A543EBBB1F837274873B93FD59123E0C45FECCC0F0F52A037F10332960AAF0193402A86485C3FD904C349EA2EE2A9AB3EDD1C3707D2BB7EB00727E33B782FFA0D, F22375846AFCBA67544E2716B6A90EB56AFAF8C5B82E8B3C8B8AFC0FD624D079028EF685471D7EEFBA4F27CFDD34FF45E966698BBB058AB20B0C256AAD7DEC026B +4D5EB06BADA9BAE610537E5CD0F413B2EB223D61BC39E5AF916EB8D2261A905A221, 1F3F9B2CC9C1E07880A96698C753CF5697A3BB8F2043E26A211026C0AA9D3CEF50B0F8A12B7D99E8FDECCA3BF921D143739AE0D9EA28A2E3DB4BC49590FE16BB4AE, DFEFF48E42A737A51014392E0AEBBAC0282FF7B3E566D53EAC71DF1ED5251A8EE6FD08E49077B755498FD5E5A6C9E15697B7EEA93AC94B5AEC19EB0EE7ACB99C +E81C114308FD30B230FA7B1672DC3B18C166B82534ADB10EB44C2A76724FB10E663, FFC1CBB203F198EF41B40F208C5391AC63C9CB2869E21F21BE8CFB881F832430FB6BAB63B6A3895A29EB3BD5701B1F50ABA29B1EED4B8C3AEDC012F1F08B6C12D0, 1DCC33294F3CB76499A8A19D7F89D88181C0CA4912987F9120C909170CA20D2E6B669E42D46D2EB14CC0552833C71872419E098299EE54D96F9BCAEEA80EBDC5FCA +2B85433C91AF7921692EF71435894B14A4434286F9E09132C1CE47F6356EF132B329, 1D6A85F8B70108861307710CB8D7BB3D1B591CAA4610DE8C7F4DF1EAE6DE9B51320F1E21FC6515B1AE7F2CD3C00EE1C9264BD9696D56A7EC83ACBAB9203EF957BCF, 1006A5B1FA539993E8C089225C958EEE173E63065CA68CDADD692E0BF1CB9B34E2100F62B2AF92AB803C6E8A00B2098EB8402596F1472829B756CA66BA3759BC0D7 +828FC9B5B50E6B643B8CE53CA09BE13DECC9C794EDA1B398456AD7E2A04CD398197B, 1E7F332DFF1E2D2459A67A0FF1B84BCA3D46D093F583C29D76E1452BB750A9BB4187B1DFCA2F8B56FF032BD43F0FBB29D6D24933E1197DEFEA1AE89944F94179747, 12CFC33FB4BFEE0FC122E3DE5EDC67ED76B61A13F27CFEA2137B6CAF42C002E8A5F5E61449054FCAA1C5E740E1B2DBF21DE5A816DF2D892C2C20C949C46CE5F860D +187AF5D211F2B422CB2A6AFB5E1D3A3B9C65D56BEC8E51AC8D04087A7E0E67AC84C71, E953F7910E7A89904FB2E7DB9B4F9AC1D62DC5B40173273307270C677B51B36A8DC2FA7953AE188D8519F9FACDE50100063AB4653C0AB071E0596EE90BF675E9C6, 455ACDA2038D64CB38D887D510216B1A1946E148D7955808194CB0680FEA8E43CF69B76C36B79BA7CAB44BE515ECB27D25D96CEBCB4A19AD4927B18CDC7ECDBF71 +4970E17635D81C68617F40F21A57AEB2D5318043C5AAF505A70C196F7A2B37058E553, 5383BDA32EDE6A7575F29F48F9D84289D00645674D61DAA74A1ED23CF20DCBCEBA7C074AFEAC4A472431D3E9AB481D6350AC567F818EE71646C579D45763A0B669, 1CADEAC716DA20F02E7B10F8A7334A7692B5BCF85AD19B8F3AE1A4D7BCED238FB0AB6BACCDA35A12A2F2B8CE9A4E02145A7B3B6CB099F0928E7F47097E6F5F2C7FA +DC52A462A1885539247DC2D64F070C187F9480CB5100DF10F5244C4E6E81A510AAFF9, 1BD4579B3E45CDD3F5375E28A03264DA8774B801C774CCCAC16D102CEC7C6A5803BE118E1AE9FBE8F3CBED76C3C44DD8216826F32B6B01520C195DA3FC88E4B115D, F0E428AD2666FB219A2FE10824D4BC3252A2DFF7837EF9C43B2086249F882692C38E6DAB2F81968709393012FB6295133656D3C8F8E761368961E393F6DB838159 +294F7ED27E498FFAB6D794882ED1524497EBD8261F3029D32DF6CE4EB4B84EF3200FEB, 6B46BB397CE7AB596A2AFB3C34EEE6834DF1491B47F0DE7B3D2990A485753D6C166194484AFB55F38C5175436E5A9F128BE0BE0019B24AB71A34E42842D73748AE, 11925CFEE57807337021C6F47CC72712C03E7EE368DDDC30E0130E9370D807069EDD619A21CE113A07B2063F9839B3954139CE9D1CADC158E638D19307ADB216ED8 +7BEE7C777ADCAFF02486BD988C73F6CDC7C388725D907D7989E46AEC1E28ECD9602FC1, 18729744522369D94181089B87BEEA5BBF0C661F21EC5BFCCB5B3880449E3C4DE92641D043B46E5572F2C9AD3836420981156C5F48760E7C393C29B42687EECAFE1, 16917E1777E8BC48D8E68A06A315ACCCB32A37B6E6EC3FE99E6F8A633DB23544A6191730FD4D64CD60256753E9A07E5423AF425955231452821380617FD34E6859 +173CB756670960FD06D9438C9A55BE469574A995718B1786C9DAD40C45A7AC68C208F43, B8C1A2FAA4A38C6B5C086B3E47FEF5D32F3AC9CBC21BF67EFC711CE011B443F117208A16C3694C16BA84E0712C243C13B2F4F7BEE7B1A37F2AEB6E7E544F21F0D0, 9C51A7F89AEFAD420E44B4DFD3BE16BB66E10342AC8BA42F929F18E25B59D22EA2EB1F83D39078AC903817136B4F472B5E87EA2F6CBF912BB7038F5504FF8C8914 +45B62603351C22F7148BCAA5CF013AD3C05DFCC054A146945D907C24D0F7053A461ADC9, 18AB4B785CBE1161A362E5F03D845438758C58A5EF9620B963D5B42A1EAA8F4C49AD5F9FD2082E22E5065D2FAAE0F0E1C83E294908C99EFCC6064A532E52AD68CF9, 2538470BC76D01561C4666A8E69BC626D44B52FD225043639CC3E9922E38A5C292749F8205D21CFF8CAE96837FE677BA2B9B7C1C8690FC417E8EF2E3FF03F3DD6 +D12272099F5468E53DA35FF16D03B07B4119F640FDE3D3BD18B1746E72E50FAED25095B, E4A52924D439236B1A1BAE96F553B2311FC0AC49B5BB80066B00C26AA289618BE855523C7E699B6AD2AEDD03DED3A9F6EDCA065FE37E5FA697E273215ECF45BFB1, 11168C369531E88137F59DCECD60055F4727B03641476ED173E46EFD6B9E89CEFE115AA4A7A9391141F7A84707C78FA2ED89A26C4DC12DAF7C75245F0EDB85151DA +27367561CDDFD3AAFB8EA1FD4470B1171C34DE2C2F9AB7B374A145D4B58AF2F0C76F1C11, ABD75587F23664C736EE9C39EEF7EA79A8A5E756607E6567E0C2E3EB8A3A6BADB017A40DAB56FD0F56572ECDD2986589941DABCF7D46F840323CD60FE200AD01E6, E5DFB5B010DB7E1A6D634E9AE22E141551A6B43D3DE32B45DDABA4096500ABC1F50E2E2522CD9BDF74C6E6D340F35143E9885550FF2319986F17F6B85456629621 +75A36025699F7B00F2ABE5F7CD521345549E9A848ED0271A5DE3D17E20A0D8D2564D5433, 1F3DC34CB9A1697825462062316E191451238CB41A9826DB5E53A3A082B9BD41DEDD03E90675302C81A35294F0F337D86DCD7F71F3362DC7BCD37A37622A3B9F061, 7258ED67EE1F89F2D00BFD90F18F8D5405CE23509A3F8893B94683794D19D5680FFE4B05C91207C29DD4F44C8D6C9091CB254463ED419E534115A93857D3D99D3C +160EA20703CDE7102D803B1E767F639CFFDDBCF8DAC70754F19AB747A61E28A7702E7FC99, 197339C4DB2660663C9BA318F1A871179FEDD145084F5A4607BF0BE5892C590271AC7A22DC1888F066931DB069CF1F9DFD4A26122C64DA097581DEED417FF021FC6, 1707C2DB68D0658BBDDF5C311A8DD905538FB345321BCD65B7275983B3599873B631AA12BB911AE829523C5542D2709EE3B9F84BB509EEB70F5CFEFB23720E432FC +422BE6150B69B5308880B15B637E2AD6FF9936EA905515FED4D025D6F25A79F6508B7F5CB, 19A9A57FBA49EE9897F17B0D51802625E0CD5635DD00253BC0F86066AA9CBA83E9A44E5CDE14227C29AE0C37476E38E2D9FE4A4E85BAF6E3E4DE8B1E8C1E2B92668, 1E4C99F87C7A0C6E6700882ABBDF476A7EEFAEED07093D36A212F9512A8321B60E3B2C4FBEB0F5119A33AD5340A162882FEA16841521561708EF5335B9C36B27202 +C683B23F223D1F91998214122A7A8084FECBA4BFB0FF41FC7E707184D70F6DE2F1A27E161, AFFADD86FDAECEB5FE87E5D68BCA5D6FC66FAAF75B235D75056C703E5C7D08C8568AFB7FAD0318B455BB742E5C5D573D0E777F1AAA6932F12F1B4CAC01D4F48B9B, 1D46544CE165765D7DB51CF3C4D49E75AAF0D8E19736E38988047627CAABB924A9593FA5F6E986330D6C77350A77B0560BFD3C6A2BE3A4DF3D4A224F033BC1DAB25 +2538B16BD66B75EB4CC863C367F6F818EFC62EE3F12FDC5F57B51548E852E49A8D4E77A423, 9D634B0CFF495B37AC29CA30231766588AEA0BF70E3B50A57BEA4159BFBDF3A728D1A4C508A0B9FFCD7A5FE17060BA9C13CFCDCCB48C73230B8D980E62FBFB3E21, 1AF3E53AD7A892A66757823448E49F147D8FE84A0FD56C34C6D536FB2060DCBFBEFE3D17A4981549D5790028D34BA5673F420B1AB09364195E8DE4B3130D6533117 +6FAA1443834261C1E6592B4A37E4E84ACF528CABD38F951E071F3FDAB8F8ADCFA7EB66EC69, 1A6571DC66DDC875EBC7128C7FD1DD5A6838546BD6E101B7925BF891C74B3CB50D29E517DBCA28A538C5AFA9296854A263CFE612364EAD8566A11B1552474146537, 1C81C3E9D9E771C0BAA09224BD0008A11F17F14B68136C61A02D03876711C08FFD12227570FC67DB8D5A7DEC702E1BC928EA3EA3370A8F7455113338D8A27965279 +14EFE3CCA89C72545B30B81DEA7AEB8E06DF7A6037AAEBF5A155DBF902AEA096EF7C234C53B, 8ECE9055639C581B93707DC57F1EBFA5AC5BC5DBD73A05E230CA4C7C1284FE0D47BD8E42F10BEB6576E2070CA1D307D23E5EFB51D1DC20AE19C50BDDAEADADB666, 16CECEE05BA436340253C616F1DA3DE5CEB5A96BA7C077811E3AEC39A5B06B829A959213655ED6F2646A6AD1F3FCC71D18AB5B6F85BB72A15A8560356D6BF0C43D2 +3ECFAB65F9D556FD11922859BF70C2AA149E6F20A700C3E0E40193EB080BE1C4CE7469E4FB1, 108BD3A64E5D20457FFBA7C8D687322232398D44C8A2AA2CEBA2634ADAAC5B95DE65A32B34CC4A9ABA606E2100ED7D968AA2C29B8726D94060CC82D833926D7B9A2, 10D2C7977E4F7CAE8ECF0D06F93766DCDF35DE069D00D26086193305A6197E392FFA92061D019DABC648A9DCF430AB838F2CD46814A3F627618AACDE1756D712333 +BC6F0231ED8004F734B6790D3E5247FE3DDB4D61F5024BA2AC04BBC11823A54E6B5D3DAEF13, 14E82F5E00E4935979D0512654B1B9D2CABF8257FD5BE4850FE76DA5EAD5E84804975D2DD2866FC1784EEA04618E183F6284FBC7C62AAE47013EBCD4590F2B3D6C2, 1A7194BE49BE87849376BC8109F94547056936DBEF812319CD75656EE7F54A152576840BB0399886E9F80B76148208B21E53E0CA4D28F1505421CBD1C6821CCE476 +2354D0695C8800EE59E236B27BAF6D7FAB991E825DF06E2E8040E3343486AEFEB4217B90CD39, 852E915A7A02E40E80A2A8235C2B7A8D45E147EA0549D43461B4BECE2968967F64D8990FDC738CE9DACBDF1FB766240F6F35998EF1E4AEF80AAE4A6EAC04D820EA, 1767EA9A64894B2F66C3076202B9A2AE8805C46FD459A2C8E6110EC78455439593C5EA721489364487EA6D90F3BF8E67D0A0EC39BB430FBC70527B6EBB951DC0B12 +69FE713C159802CB0DA6A417730E487F02CB5B8719D14A8B80C2A99C9D940CFC1C6472B267AB, 1D7C81ED3CE43F21CE09B33EE9A2A985DFF8AABAC817BAD6A99AAD667F44464B529BE9F198546118D5E3525FF0BABAB2E880CBEB0BE003BB04CCC7A5A5D0941894B, EDED4661C5126B5462FB1901A924B7F8FAB742D6625AA9B70DC077D1AC4FB2D30230EF300FBB29B8B4F2A100104A9E630230346EE34DD00B0FD029130CE8880C4E +13DFB53B440C8086128F3EC46592AD97D086212954D73DFA28247FCD5D8BC26F4552D58173701, F5F9A310F3CA4741EE02E3B2A6FD6D74590E9E0F1BCF0CAE1493FF0F558885F75E7A028DB98F343FA0F64D62AF378597FBDE10796267E481C2F5F13C9379F68C4D, 1DBDD5A00E6232A7ACDF3A1C381DC6C6FFD35DF91393ED9FCFF358CEDD9AD0665EF4BDA23D3DF531EE648C42FE52BACCBA29E6111EBDBAE45AFB075312DDEE6863B +3B9F1FB1CC25819237ADBC4D30B808C77192637BFE85B9EE786D7F6818A3474DCFF880845A503, B7AB75D4B652C91083634B8523C1F2113CE5AA18AF727EB9986929BF5817B90B8242869ADCC673A993B688191E06215D208B31B422AE2E7762CB383F3EEA071B59, 40C822C2A70CD378592127F2B43B1EE965CF4C8B25D60E620245F6040378CEADF42112282101EDAD44F4A1C0089ABF8CFBAC1AB25E429E5B0F9984325216BB2142 +B2DD5F15647084B6A70934E792281A5654B72A73FB912DCB69487E3849E9D5E96FE9818D0EF09, 23BB0BBE506F35E1D04F7DF9F4841129F90F77B6E8B480055464020125C064FE358CBEB08954ECFF1677CBA0D685433C2D3D927F60B18EC557452B59B5B13C16F6, 18710199C5E7B1DE8A3F3E2F8FBB324DFE81C125EF81C54FBB4897FBBFD753FF1F3C5622C2346909D139BDFA7D8C3C0FCA0FC359F427C1FCEDFBF7BB8A6CBF2B312 +218981D402D518E23F51B9EB6B6784F02FE257F5BF2B389623BD97AA8DDBD81BC4FBC84A72CD1B, 19EE555DDFED3875BA08AA6145D62D17D9CAE348EB031320A3CD088150D1F90EDEBDC61B482E97D19AB229EEDB23F1AF9BCC62A6892AD1529FDC7B0E6234222C7A, 9314C13F2224643EE0B019BAD6F3774F7CB60763F83B546D3B8A7946FEC5209857BEF2D099EDD8C2FD215878EE6484B7BE3CC3044EC098CE2FDA83091B264899C5 +649C857C087F4AA6BDF52DC242368ED08FA707E13D81A9C26B38C6FFA99388534EF358DF586751, 16075372C721674577CEE52EA455128D3998292A38BC88B4EA697D42143325AF07DA057F65CE57C90C0365DCE08F7E5B95F2550A1CD0C28D3515861FD0177EDD209, F5BED40444A770145B534AA1D862292CB1340409A356555F75F0EEAA740C4F86CACAF244DC66924CB2280E5CBBA6789F4EAE28A1D08CF0F36A6DBB446B87FB2338 +12DD59074197DDFF439DF8946C6A3AC71AEF517A3B884FD4741AA54FEFCBA98F9ECDA0A9E0935F3, 15515C1294E288CF1596287A48613C5FEBF86E440338DF09FDCE61A7062FA047D1F1233DD630D625AB52A0E2240FAC6D61026C8A11755F4FC14D90B0DBB229A014C, EB06C276F432EA10AF2E558DBF476575772B86AD17DCBF894E0DA79DE89EE46D55A4D5E96CB1AF668353C1CF6B54B3A4A2EFA65BAB36AFC775432624C1D2D26CB1 +38980B15C4C799FDCAD9E9BD453EB05550CDF46EB298EF7D5C4FEFEFCF62FCAEDC68E1FDA1BA1D9, 153A4BC626A9A8D19D8A1646954B1005036DA02A5B519A51540A55C53F3E0861DB7FB007503F805521C6361B6964C3CB41B5FD0902047111A49175F5B24D5F9DC40, 1D5F0402244D4C1D45942553CAAA51107637E7C93FA54A83C9F5D55A80775AFA1AD4374EA2D592008AC100414265377BA8BF3EE11C00FBDFC1DE4CB9A0FE36F9721 +A9C821414E56CDF9608DBD37CFBC10FFF269DD4C17CACE7814EFCFCF6E28F60C953AA5F8E52E58B, F1062444D092FBED2979971EAB4D274A10262112FDAD0629AD5ED2232BA94BD9ABA9A3991686823A631E6FC37A7DEF9C9AF9E93769CA10308E7DDEB39ACB042DA0, 18EEA79622BE1B249B37021D0A2B2F3CB16DD80B8834CBB944BB5B7C648C0E9BF6AEE03209992035AD418C6B3998BE7C7CAA2A9C315236CE808CFE32FAC7F9B5DB +1FD5863C3EB0469EC21A937A76F3432FFD73D97E447606B683ECF6F6E4A7AE225BFAFF1EAAF8B0A1, 16A7B3B8A011629BA8FC3D6B73239D53B2AA8123F398481BA5DEAA77914F223F158F6BFE6A43BC783BD36444340CAB70371871835BEB71F25F38150F2BBBF0AAA20, DE1A1D2DC84533D4CAEDF36862796C7EFE8F3FBB2477516AA2316C5DCAB66ED9D158BFD6475925B8EE68A19C506D04B010B76B73C8953947B450763DA698A95873 +5F8092B4BC10D3DC464FBA6F64D9C98FF85B8C7ACD6214238BC6E4E4ADF70A6713F0FD5C00EA11E3, B3A32B8F0BF1261463F92FFD6CA9D33B7822DAD48CE12E202380D86C1CFA67E1184981A0C2553D72D4145AD6F8A6E2B6CAAD43E36DED935D27F5E58C8CED0ABEE, 7EAAB85F3096772A6BD6715D78ACAB8F3BED1DA00714FFA32D89C84005D252CE762835DDE9E721102105E475C633181680410B3285365E34AE4F7ECDA742DC404A +11E81B81E34327B94D2EF2F4E2E8D5CAFE912A57068263C6AA354AEAE09E51F353BD2F81402BE35A9, 16293E3C8419D299E80B94874AB33A48B6EF4C68F8BDC5383FBD324DB60722AE3C324E634F5EC766F429AA82F9B37519D306C9A9B171B3FE010BFF6FE248E776421, 1EB9D1B34120CA7A75F4422A7FF649DE4A9053CC549688E06F9C9F1601F277BD8EF927BCC5250429612EE754F95E79EBE89D886F20A639022168AD47CF8E6C5B1A9 +35B85285A9C9772BE78CD8DEA8BA8160FBB37F0513872B53FE9FE0C0A1DAF5D9FB378E83C083AA0FB, E8B32CB499ECB3E01DAE281F97368802E734B54A4DD62197D713386ACCC0D268AA6FB0F4B04A17E7571FDEBD7B82D9AAE179B602B002304C0C96B501A601B40106, 185428F1BD795C5C11FB45B9EB69E2D12BB7F2F4608BEEF4C6A9317911B0B8B5740BBD54BF899812AB38EB6ED33A7928AE6B9AC49FDE34C3009281D6C62014596C1 +A128F790FD5C6583B6A68A9BFA2F8422F31A7D0F3A9581FBFBDFA241E590E18DF1A6AB8B418AFE2F1, 28328B0CB88F54810A53575CC43C0C8195C0ECED24B4C4668E6C43A6F1C42FB6FAA8D2A9DFE090F135B3FA4FD80208A03CEB8F5DFBBB41204590A670F250F80A5A, 1E646A13E24FD0ED26166AACF070A913B06502ACC9F4BEAEBE1C1EC4347FF0B56A3BF97A11C55C1EF82CC298C393D836C929A43A6E605BB4CA1E72DD4D02D50282E +1E37AE6B2F815308B23F39FD3EE8E8C68D94F772DAFC085F3F39EE6C5B0B2A4A9D4F402A1C4A0FA8D3, A01C54C9314D22DE68E6F90046F8CB4EB4E06D9F57209D3BD6F1E043AEE9A14056B9FED753DD1B054E8104C060637F8FFB22BFFFE77C8417B1977AE3BFFDA8B0EE, 1DDCA880C7AA445F1B154277E9EFDF46E65E1BD60D49875AFCDFCA1041C5D79F15B825B2F77787D0A38518BA80017215CF3A5A77F0A73E4E99FC8E5CAB3FA417325 +5AA70B418E83F91A16BDADF7BCBABA53A8BEE65890F4191DBDADCB4511217EDFD7EDC07E54DE2EFA79, 1369E0815170D373D37F3288BBCFDAE28DA52FB130FFA71157E472A05E75E9E945E8E04220B3A578EEA28386611C63AB52967841F102985CDB40A5772F091721979, B13A78147B142DC325879992F8539804AF4674B0FDD63B93E945E9E54C000838E76429441F0E8A0F497B9EDA8BAE28437B4600490A88C7DAA6D10C1125B0992A48 +10FF521C4AB8BEB4E443909E736302EFAFA3CB309B2DC4B59390961CF33647C9F87C9417AFE9A8CEF6B, 36DA5963E99910A1A68B127398D3FFAE34EA7CFBA3EDE70E12146FD4BF8C1701FDD1C38CA9F73AED1F6023D5C0A0B2B2B05159464CA22E82AAE4950E46C7754117, 1C7D90BC4A5A2A568E89E2D00AFF0AB0D166581A72786380C5A73FE196B4B5487281681FA883F21BB6C14753E696AD56CF9EDD192B1DFDB6FB9933DEB19F74529F8 +32FDF654E02A3C1EACCAB1DB5A2908CF0EEB6191D1894E20BAB1C256D9A2D75DE975BC470FBCFA6CE41, 16A810D97154E1989F831932E98792A3166E6382CEC6B5283EDCF1DB34A1499215B3D11401B0D43CEF4D1F3FF95AD42B4D8177D292EC288564FDFCF4B231C0939FF, 160AD3F0BD27347233370D71201E3356E37D8770C40C56CD99AD699D5C9AD38FBD2167C8ED288A44F08963FDA2820DDA65C36513FE5C42409542E4802E4BE5B5BFA +98F9E2FEA07EB45C066015920E7B1A6D2CC224B5749BEA62301547048CE88619BC6134D52F36EF46AC3, 1807A09363E63533ECCB0ECF180959E7ADA64C6C0A1048D7AB81DEE383C8466F8F8A1A5098EE5CD6277806412947DAD2686A7FEBE93066D02ADC4AE6E0E4758C884, 50443D8C393AF39EBC95BD1F76F288260FCAB0B5A494A064CAD1F7A2AB1D273DDD7BD520C1D7B91D622F2D9D5FB79A46FE5B3C00A17CD7DD8B750B05D50344F8F +1CAEDA8FBE17C1D14132040B62B714F4786466E205DD3BF26903FD50DA6B9924D35239E7F8DA4CDD4049, AD85E38956CCC0F3D48DCD3D46AE51DCC5BFE7CE21F7FA9C1C757796AE8174CFBC0CEE9B1894E52EC8243D012DF6495C6CFA08665F9C931362EEF089CD4F0C4C44, 146336282DAF91B0A26EE20548F978915DC6A84C1361D019587A98A38BA5D0988EFE56031C71BA4E74F0CA01261321DC3243943D7C9D32ADB45909A938DD3A8A248 +560C8FAF3A474573C3960C2228253EDD692D34A61197B3D73B0BF7F28F42CB6E79F6ADB7EA8EE697C0DB, 1E66D6896F7302DAA54CCEF2172C0265DEAB2BA08847C246A631CE6907D5EAD4CA78C299D41B35C4EA4477EAAA79BE8FBCF9B41B1774F8B1EFB54CD2689A8D65D39, 63AF0ACA68529DA67E4DCE456F667218A32D15EC4EEDC4F6976AD85543DAB81459B2844A463E1EA2378C3EE981C75C219E0CB5AFC5FEF7F368EC32B1F35DF22007 +10225AF0DAED5D05B4AC22466786FBC983B879DF234C71B85B123E7D7ADC8624B6DE40927BFACB3C74291, F5ECF3A8796865EC1A21C55D77D467A56674814842BBAE32EE0A2D0DF0C02EACDAB345798BA853ABEAB13C017B99DA5F7BE4C62950B55263565C7F938D4E8E6EFB, 31BBD71552D2A85EBD6C1C4AE68FA03C8B5C4358F65D39DBFE5F40975611FED7E0068430225CCA1255A1A0F190A81A097243501635111CCAFC62B98CC74587C7D9 +306710D290C817111E0466D33694F35C8B296D9D69E555291136BB787095926E249AC1B773F061B55C7B3, 1E958824845860B6DE2C49F60DB58593C7DE3F3D40DB8C239BDAEE35CBA77E86BD9785D9FC738454364898EF682904FBD69284B4CA8579F819B605A00E90F0D3951, CBF7F4DDC6801FA907A0347DFF562B217555DA0CD819409D1FCA92470279E06FEF56514E434D3E0EAC3F4D81B4CE716A89F061A9FD986626EE7A4EA424CDEEF777 +91353277B25845335A0D3479A3BEDA15A17C48D83DAFFF7B33A4326951C0B74A6DD045265BD1252015719, 1D089469ABBF7F177EE086B20D8F4D560F9D2F65FE301568FCA0E9FF8DCBD99D56A143D898015694A23F7204744A39053CEFABA04AF3FE0713C8599ED422409C3C0, FA0B96A5638E827A73DD30F585BF1F5BF2029C939E003CEB4E27CEDCD24420AFE4B7868B91B0127E534E9E46366EAB6D142B9CB7890E0470F14F0F34BC6CA987EE +1B39F97671708CF9A0E279D6CEB3C8E40E474DA88B90FFE719AEC973BF54225DF4970CF7313736F604054B, 7113015C26BF1BAE03B69F4057736389DA5467B2DA955CC58518E853F93AB4581A8B30A01E2597CD4425DA9EBBACD763EB41B7A4C961EB6F26A07202F0C9A23A79, B4EF5757BC534D27C76A7BA8563CD66ECF1E8D42D1F5EB77512E8DA4A62C68128389A3F61C4DB8EC4241FC177BED538226A825A2582591D69218ECCE47B8DF7240 +51ADEC635451A6ECE2A76D846C1B5AAC2AD5E8F9A2B2FFB54D0C5C5B3DFC6719DDC526E593A5A4E20C0FE1, 1274B0343F67A9984E16FD0EE80743056214310796F34D3976A6A8D43CB020B65C3D88DCF58B6C3B7C75A4F7112DC21B3CEA4BE2A80D099C30C44F3E2F504D3619C, EEC43E2E523577DD55CA396E74B2C6C6CCEF6CD565D5718471A0F73F2F74A152545F336682FDAB3DA0599DD52E46AF2A33F7C5FB466AFAAFCAA5918B7651A9A673 +F509C529FCF4F4C6A7F6488D445210048081BAECE818FF1FE7251511B9F5354D994F74B0BAF0EEA6242FA3, 12E87A58496C08ACDE681A371A002932F96EAD5BE0DC83CD756C0C0FBB69CC5CCB27A0256F78751C9DEC296BD9AC216110ABE2D36FF5C6C0E719646CD9BC9848CAB, 13D51083E33466DAA74CE90C42013673B567A1594DBE189EB584B67E9EB02A9574AEA7C9AFB30539B2D82A25B0A10BCF86CDE5ADA0F29FC861C1582AEF897021475 +2DF1D4F7DF6DEDE53F7E2D9A7CCF6300D818530C6B84AFD5FB56F3F352DDF9FE8CBEE5E1230D2CBF26C8EE9, 1AA70532FA8B2911D34749E66DA1BB5151C87B1411820B84746DA5D9551987848341D861DAE93FFE3FFB9A213D928CE02092C0BCCD00FAF16D22A8E02C8358752D8, 1AB4A1B3E648A8E3620136FF7445826600E94506F09ADE6B253515F8928C2CA997A1A665324082891388FF046C92E5A33B6F34A289BE1D1D2DDD32C9877287FFB57 +89D57EE79E49C9AFBE7A88CF766E29028848F925428E0F81F204DBD9F899EDFBA63CB1A36927863D745ACBB, 1FF46288A30152DA6309081DC1BBA11624FEC902A5A959ABB3A46C03FC445DE1BA6A71C3380CA21D757A1C07AFEC03AD23C0F515F1E9AF43039AF86B0115F13EE6A, 116660F754DCC1AFAD29679A16D50F35C37B60424E29A15D64F4C181A5A38086473EECC9D052E5F87F35492E054762EC80A51892F1A3D8AC963BB801936ADF9E032 +19D807CB6DADD5D0F3B6F9A6E634A7B0798DAEB6FC7AA2E85D60E938DE9CDC9F2F2B614EA3B7692B85D10631, E2E2659D183137629CE339815983912705862D112419B5CD3FC4EA51C9544A90BD1E588801913F12BDD30AF3154E116D9CCB5F745035FB4AD89CFA93FE4A25EA38, 148B85F716EB71EF8E4D698A41073FAEF30832AFA80A36A32D40A1F1B2B5D2663187C80EE5A01DA95D88207D6DE6AD84B50CBFC4D3CAE65C9B7C771F3193468D326 +4D88176249098172DB24ECF4B29DF7116CA90C24F56FE8B91822BBAA9BD695DD8D8223EBEB263B8291731293, FBC226F86D592BD29142CC8317D5B3ABE29449B677CB1B82AC622039DD89DBE1AFCA884E42CB3E07B2EA8115CAA0304E60DB626CFAC619471B750EFF62A4726E7D, DFE3C45B09642026C6DC0863F6F502A698D7188E68170FB79A46023B2C986C245F246FC0D53EC4409A81B26979866B9ABBD4D2083F23B628260B93BB914FA8345A +E8984626DB1C8458916EC6DE17D9E53445FB246EE04FBA2B486832FFD383C198A8866BC3C172B287B45937B9, 7F9538AFB15DD31A0B7EACC6912CC76FE8110FD28A900EEB0AA2910EFB693E2124520AA7DCCA641DF1D78D91091F901C759C932884245DBC6CE6A28D5934515691, 3A9DEBCE202031C250E079E2269CCE0E9E7A1E359E14F3A7F8D54B5A8A65E452F4A7ACDD448849F267C535F9C4DB5DDCE46A5B7F8120F639387415A4C15CA50058 +2B9C8D27491558D09B44C549A478DAF9CD1F16D4CA0EF2E81D93898FF7A8B44C9F993434B445817971D0BA72B, 1E5FD5C9C75CA0C2D3C43ADC8CD5C3FD62AF802CB61953315E9D4A1B8C195A62F5C2F8CDFB283D0B0DF7F11B48B138EF0AF7FB0EEF04E521D643BCE26BF6E279E44, 17967B0FAC085EE5D20FCB0B2709B5C248F24B65306BA860B5415A72D4408C8A2A7EDF85BCD36E65F85B545657B94AA209EE994FCA0D8FA2585F58C32F133DF02C6 +82D5A775DB400A71D1CE4FDCED6A90ED675D447E5E2CD8B858BA9CAFE6FA1CE5DECB9C9E1CD0846C55722F581, 1BC6904BA16978D90118BF7847B561CCEABDEFF76649BF1DD7C7BFC4866BA3890F36A0436475DAEB48036E10BE570A6F3642BF69124C47251AF89A9278CC6E56AA2, 1614884FB58B7765EFB0A666AF4D03FD52940BDB0020AE8B94AA36B4942CB4709F1264DBE0A5AD0BE53F57F8270FA443D4BB44D5534BA201D4704C12ECDD008DCAF +18880F66191C01F55756AEF96C83FB2C83617CD7B1A868A290A2FD60FB4EE56B19C62D5DA56718D4500568E083, 9B1D4C6D7F418D04F09AC17C612276BE0D03341EC838F048CEE9A2ABB73EC54815C99E20C51FE7DB47F8CF2A282DB44AB14A1FE920413F60449964B742F8B02C3F, DF24FB8FCF13B35DFCD676EBFAEE3E8D6DCD9C3623A9465BEA96ADA57E4B41AF31BE04ABD82400ADC1E419CF1A43AEC9C024703710660BF3A0ED096AB88A4F58AE +49982E324B5405E006040CEC458BF1858A24768714F939E7B1E8F822F1ECB0414D528818F0354A7CF0103AA189, DAE4D9F107CC11823DFE8293A1FB69ECBB9E946ECB97384C444B634C39FC02074DA7BE04D7FC5B68F73BE754DC3B32CDFFA82E9E1D6A3AECDA4699D0CB93F7F9BE, 16841ACF02E71D74B2036B6F1B1A9E060BF30E0F3FBDE6C6100D21040633CE7DC894D7FBDC785498155AB8E84582394DAC0341339C1DFC0078F316F9624285DD2D8 +DCC88A96E1FC11A0120C26C4D0A3D4909E6D63953EEBADB715BAE868D5C610C3E7F7984AD09FDF76D030AFE49B, 161107D0364D04CEFA9EC04CA61E26ED28698B8F90C5884003369C845A2AF92396C1501A56A600B818E688AA9B913E90402DD2C11A699640CA5B27961003CAF5C5C, CAE4335DCA78ECC080C6D6251E525E7EA6F29AF9D5220E9100413AEEE592C4C38622F902D5D29B1A8F96BA41E004EA9F3520DF16332A48C5345E600ED1EDAE178A +296599FC4A5F434E03624744E71EB7DB1DB482ABFBCC309254130B93A8152324BB7E6C8E071DF9E6470920FADD1, 1D61CCAAB9B9A1986CFD80B25C58B5BF17349AE6E6AB487D1CE00C445E89568C1584AD342E40F95D39E45008499F525218D7F3F386C8A3818475C4D4D260C9CBF4B, D9052AF5E8194BC8A13EFA0797FD4F1585B4F79D97EE261FEBEEC68C15B0B6E807800483694A5ACBB1993184E7741D78956555510C1CCFE285F7C3FBEB1DD25520 +7C30CDF4DF1DC9EA0A26D5CEB55C2791591D8803F36491B6FC3922BAF83F696E327B45AA1559EDB2D51B62F0973, 1516B4B8A638A216CCF3FDA789F265E0710C5AC5CC7CA9ADBC8C21992A7ED6D0BD282056E99BD2FB920EDB5D6EBC4AA1594C2D49B7F16BC4884F120456BD478C1A9, 97A845B03C195EAF74BDAC8ED9808A4655D7B141023599BAAAF4FB9F4F3383875D12BAE755219B7D1840A88A0994222A1D36AB929B9B12AB3F825E7665200A1AF5 +1749269DE9D595DBE1E74816C201476B40B58980BDA2DB524F4AB6830E8BE3C4A9771D0FE400DC9187F5228D1C59, AA06655EA7BAA2FDC21918D55027FCB1CB702DC30D410703BCE95272371A138C95BD13E63AA1F5CBDF3EE18457EF526DB733067BDE9F926BE6E011A32F0D766316, 14153B0F8B6C4AD4CEC216C28EE58BA2003B3092CE98995FE4F3D90B0814F71E2E027621007EBC567127CC20DBC01BBFC88BB23FA65E3B5D7E62FD21EE041AD3D77 +45DB73D9BD80C193A5B5D8444603D641C2209C8238E891F6EDE023892BA3AB4DFC65572FAC0295B497DF67A7550B, FB33691F370AD3058190F92BA7F06D284FB8DB5B15FE90EEEDFFA7B1DA706AD4EF7ECD864B6249480E8D91FABF770AABF36DBE26B52791DC164ECCFE8647DD6016, A501BB4A888E289FC4EFA7F0C408CA0336725829D5FC875143D4E3184D7C2CABBA5586710AF702B2B45FC1983BDD9C300EA86CDA223B7A59DB8FBB3773A623583E +D1925B8D388244BAF12188CCD20B82C54661D586AAB9B5E4C9A06A9B82EB01E9F530058F0407C11DC79E36F5FF21, 5EEC1A628A508CA7A549E77AE683842FC36D7AF0384F54C610A3334E7FF3AD9431BCB451656DA932DA230FCEED26095A0C7BAB19F5D28CFF45CF0C5E0A1E751173, 734279530B1A50BD84B0D0F8DA98800F2A9728333254F29B99232FDA0D6B0C56BA96D5A84E32E5B0704A06D600D6A40DB0B83CA1C6D01C7A29BA145269136E0553 +274B712A7A986CE30D3649A667622884FD3258094002D21AE5CE13FD288C105BDDF9010AD0C17435956DAA4E1FD63, 1B19DF6C95BDA62FCB386A76487544965A4542943E7BDD4945DA59E897ADEC0FAEB5C298361E7D97144F890C8F6CB4ED5D139E0F2BAE201A6859D59DE0800F6A7BE, 18878C679DE2FC6FF305A3B61B3DBE608A21CD0109A7E4A9A6A8C516CF393F2B5F90CCDE100A07E9E83A1AB3E1B18E3AF7D533F50EEFE25910F8DAAFC12273F12F3 +75E2537F6FC946A927A2DCF33626798EF797081BC0087650B16A3BF779A4311399EB032072445CA0C048FEEA5F829, 175CF3D0E1BBDA63D8E533F978D4B6D0EF6EF292433ECB7186216D15F4D56CDE6B2CD949A58323E7130F9E72A17C89CD58D32A3AB51E2A9E207DEBAAB85324E33D5, 13A0754082205127C4FD65976065B904436EE0731BEB74DD02292431349BFE953B8DCAE9A29AD924F4706E6372F6E30A1A695142815AB6EF3D34208FC8B67D3E2B5 +161A6FA7E4F5BD3FB76E896D9A2736CACE6C51853401962F2143EB3E66CEC933ACDC1096156CD15E240DAFCBF1E87B, 1396B8FCC0B17435E67FF47105282E3090A8DE3A75F43EBEC99041CF94D6679ACB215D84E7F30E5CE8B90548CDFAF598647502434C909F13BBBA7CEB824E96B893E, 7551CBCF404CD416CF86112511C97B90C8AE11B9C38156DC018FF8F97CF0A584FFF3A893B1A7EBCBDFBBA7F25975D1886CB435D671645B344C80EC55268980D3DF +424F4EF7AEE137BF264B9C48CE75A4606B44F48F9C04C28D63CBC1BB346C5B9B069431C24046741A6C290F63D5B971, 658D21B04BB7C57461C88434A25D45E0342EF60B29784C6D89BAEA32CEE97E851C142E8C5FBC5C0DE86CA53B402521B7F68EF42D2A9A7FA59ECB2248DE9FC6A6CA, 77480221F9DE981E3F86871DAA4D6B80931F505FDE7FA3EAB499A15F6159CACD3CCEAA18F8E595CF55C15BBA54F5E9FBBCCED5937B0A4935D87635C6BA9FA2A28C +C6EDECE70CA3A73D72E2D4DA6B60ED2141CEDDAED40E47A82B6345319D4512D113BC9546C0D35C4F447B2E2B812C53, 121980C2C37BEDCE3326677FF35C771AE76BE229B43A01B3C3F5D0C63C5E8CDDFA0D57E54426FD298543F55ABA17F408BF2589704A24F81377B148F92C9AA21199B, C05D2B359801DBC37651649B512F0B3C351569ECDBE80DE9D3860FE9F2BB38A7E84865634AAEFD2EB95C2E2FEA210298E0C09C50C625D2A2BCE61FD7A324C6CBD7 +254C9C6B525EAF5B858A87E8F4222C763C56C990C7C2AD6F88229CF94D7CF38733B35BFD4427A14EDCD718A828384F9, ED37DAE03EF4B2813D2F3E81E66FC87582CC1A5B7032E4E5E63306E079753CE2AC57ABD4D61BDD6ADBA549028144DC56F67B6B63304F38A6934119FD79802C353F, 1E805CD53068D979B31A43CBAC7D2D6449055A6085598CA827FE4A11755D8E320E571FD19F1A761281AC06B2847DD34CBCE12F1ABFD5A1755AD7C167142C0BE36C6 +6FE5D541F71C0E12909F97BADC668562B5045CB25748084E9867D6EBE876DA959B1A13F7CC76E3EC968549F878A8EEB, 1C4C0F57168F21D9D13B2FE10315B35D61AFDCCD8B5C97AE71D2E4305F7DD91B81A1C014D3527805717592BD75AD58308656B11EFE66CC2A1394663BFACBDC1622, 1B5EF0897B34AB0A00061B8D69EBF65B3B275F090686273310475D8448F2C1CA49475E7FA4BFA034D1F429A7C2BBC31882B9979E23C7B22F58A1B3F49C3CE97EE52 +14FB17FC5E5542A37B1DEC730953390281F0D161705D818EBC93784C3B9648FC0D14E3BE76564ABC5C38FDDE969FACC1, 11C0062E9776CED7BFCF6F43C9E15B6CDF00E76E8784374A406294C96FC223FB0C0B0E78D0841EAE90607787D9721851678BD4AB5A36B851E5A3C3B3E53DB11EC36, D6BE3739431207B31B4A752767A352EE066FDFD4C26B0B650ADACB6535B0FA90FB451EF577EAF681D363FF72D0C82D5A46CC4D02D7EC4F44ED97C625F2E2F30118 +3EF147F51AFFC7EA7159C5591BF9AB0785D27424511884AC35BA68E4B2C2DAF4273EAB3B6302E03514AAF99BC3DF0643, 171DFC8EDD79DAE5A63D6B79497C7B5EB4321C8752F0F766B8997AB8EF3B0ACF5A72F2344BB737CD2CBE56969D6CE1A9D71E3C9C53A518C626309D3B9AE0F92F3AF, 183BA878DD292A2271D749D106345546621C5C253767EAC72CA3F0367B50E25EB9201F2A8B3616160115EAE4615625A54646694540889FBA262AD60C3171C6982BE +BCD3D7DF50FF57BF540D500B53ED011691775C6CF3498E04A12F3AAE184890DC75BC01B22908A09F3E00ECD34B9D12C9, F207D39271725932A582154650156D6D38BF9F895640D55CB696C4D786AA53ACD7C1DD39EE7B7E0C2E401E0A3FE5FB3BD1C781449A638D55E49114DCF6837BD28B, 1599FD70519256F1DE4C58AEEC3B51C87AF3D186286678630915A355EE234583AF53DDB7FC4275ED66C68AB3FC2FB9403C601421556A6162F33334CA502498CD2B4 +2367B879DF2FE073DFC27F021FBC70343B4661546D9DCAA0DE38DB00A48D9B295613405167B19E1DDBA02C679E2D7385B, FCC2E5F471839FD7A4E786834F61EF6953B1F133E0473305C42A47F79100863AC8CEB3536FDC24CF7208FA74CD15969A2EDFC3321E15C467115A148DD5F1731A72, 1D24B7C1566DC10BBE2166872A3D96B18A934089BC31E873D1C4C7FAAE1D60FA400EBB57C2C20CE54F9B76F1C2190465E5C0B40FF2BC61BACBEA1D8C6C4B0E7808C +6A37296D9D8FA15B9F477D065F35509CB1D323FD48D95FE29AAA9101EDA8D17C0239C0F43714DA5992E08536DA885A911, 3DF965C45946AD537A86FC2B19944CBB24F90EC64899B98B4AE59BDBDD2D3BE2ABAFA6300D916DE8596C0AD5D539210E8B5013472022D5B7A543B652C2B91C4FAF, E90E42247029EC1E9AAD74EB38BEF22971B531ADC6DC665A7C492772DEE75372183678E0C73BCCB96E925CBAC19A2BFEA9E40610CBF5499189CDC014640F849FD1 +13EA57C48D8AEE412DDD677131D9FF1D615796BF7DA8C1FA7CFFFB305C8FA747406AD42DCA53E8F0CB8A18FA48F990FB33, EAC71B13C1006B0163DBFE5BEE05EE005B56794E505366429AE0000138636EF38C9EE9F38581253984481BD285AE21F0244EAD9BE49B576001A3608BCB9E61D1C0, E815EA8641A20B6E7EA92A82A3D55BD9C4FDF65489CB14B782D11913E0FC0BD546E5BE5D8A8E0334FF7255BF91DA611ADF182455CA65E9BD7C77BBEF0AB33CB658 +3BBF074DA8A0CAC389983653958DFD582406C43E78FA45EF76FFF19115AEF5D5C1407C895EFBBAD2629E4AEEDAECB2F199, 137BFE281C39C1A82BFBBF9E4F8B41477D916BFBC30545AD9868D3A650AECFE9CED818BA87FF07D4991E26FCD4A54E4594F91D16208ACA217E3ACD6EFDB47700D88, 578A287AE50EDDAA7E8449AB5A3450AEBFF0A542648E9D99DE733657F2C41D9D43F82A12AAF71C639D530BF30AAC13F430FB64E1F11BF700982DE54D440987936 +B33D15E8F9E2604A9CC8A2FAC0A9F8086C144CBB6AEED1CE64FFD4B3410CE18143C1759C1CF3307727DAE0CC90C618D4CB, 14ADF84B7B26C3B76CF0CCEEFCBC09A3A92870F7EE60C6F616A790FE2DC627EB28E06C5B2FC2E6890922EFB8383237A58870360231BC5FA2A48489B5AC76ECD152B, 8CDEB8EA82B077D2C87E3F7108A5FC13E3FBC9FB84413D99E03DE8DCFFC6647143266DA21E581C71C8DC68A7067B6EAB15A4396ACF2A1279F0B3E3E7BE1620668B +219B741BAEDA720DFD659E8F041FDE819443CE63240CC756B2EFF7E19C326A483CB4460D456D991657790A265B2524A7E61, 110959607CECAD1C0EEB261F007276A4B530693EB5B1EE3CC676BD743E0B062E80FAFB5CD57A6FD0A3368302B30DFEC3C160B941BCEA235FAE9E0C8395E55A85F9A, 19037164E32E56A58DE230792A5B3A67AEFE55A82F4A7D1CBE8C1FB706B7367FBD5D49A89D39DB27E85167993E9E5A9B9623E20EE463B49E3D30C048AE13C268F30 +64D25C530C8F5629F830DBAD0C5F9B84BCCB6B296C26560418CFE7A4D4973ED8B61CD227D048CB43066B1E73116F6DF7B23, 16F7CA28B99A2EDF84B4BE88B786B6B9A00740C2EF71D1667048A800E4C08C96B278AF7EF10716BC5EBDEA3697530C4D33EDD61DBFDA322DB3E805FAED9595C603E, 1776DBDD44736F14F5965BA7D3494985772D5BFFEFEF6B07109F6EEB71EB0BAA72836F0275819FDAA9F6FDDEB34C79137426EAE4C8BC9DEC3938BD423757E13243F +12E7714F925AE027DE8929307251ED28E3662417C4473020C4A6FB6EE7DC5BC8A2256767770DA61C913415B59344E49E7169, 46093616F98BAF2EB3E175DC458EE3C69E5C6B8B5CF13987E3A7A0A941559684F9229DE2A8E9ECEDD82F2897C03BE32BCF0898DE9E3437489431BD7A123C392F8F, 57381B88BFCE0A557F735D9665C5AB29DF169F254231BBBDE2E155B50DABD5196A9DDD183CCD8176BF4B9FCE09EB011C5FB30140BD79A7440064C90341C7CD89A9 +38B653EEB710A0779B9B7B9156F5C77AAA326C474CD590624DF4F24CB7951359E67036366528F255B39C4120B9CEADDB543B, 426C8875006ACDD8271F635D6E3A882C083690635A6C958932723447CB1358D86DCE4CE707B6E50F5476E7E99D848917231FB51C72B2425DDADA401E6A83785157, 16BDE232C303ACD1CA6FAC26991357278F9ED8BEC7DB42BB50D7E22CA0BC96DD316DCD87D4D0F532877DAAA6885AFDB2298720062B9E591451B5FF6CEFCB5B5F7E0 +AA22FBCC2531E166D2D272B404E1566FFE9744D5E680B126E9DED6E626BF3A0DB350A2A32F7AD7011AD4C3622D6C0991FCB1, 1292687676096BA03D01330426AD90A3F1D3772AE8197B1D2F6279FA31C14C26034B567BBEB7CDDA07BF26D1809A694CF6274539B42A706A3915C2F44046CEA0499, 14C8CBF78462ECF2090C0098CE7EE93C2358E7C308B17A5D599887FC20DDDF520F3CA8A15D1928E0EC67DBBC167DA58808AF42127B1C6994B7F3B18F51EAC57B860 +1FE68F3646F95A4347877581C0EA4034FFBC5CE81B3821374BD9C84B2743DAE2919F1E7E98E708503507E4A2688441CB5F613, 1FBD973F8AA1CD7E7E758F543C4B15962E243BA435A7CE62E75193045D248AC3CC08E7B717D6541F30041C02000311155C2F7B8BC50CAACDF9A20223308BA0B3ED4, 11132F7ECA282F2CD15B135664DC71B307793681D35D355CABE19601048E932287AB606919C7C3196EABE8A1FD7E60BC6EEC595619058B5A3832538FD67ADABB878 +5FB3ADA2D4EC0EC9D696608542BEC09EFF3516B851A863A5E38D58E175CB90A7B4DD5B7BCAB518F09F17ADE7398CC5621E239, 1172C5E0FB6D1E3676490A8F6A6F07BBA0168BA6661A2F81FADB201F9522839975840C028A8B0B60A6931692554EFBE883026A2C152DE91CEA777BDDC6F627A661E, D4AC0F11A8727495E69CD5F60359D12A0A1B11FDE3E00934299C0E83DEBBF7CBAABCDB875B24466CC0A43EDDD5F8D7546E4C227B24F7D4F7732B3E6650AA41983B +11F1B08E87EC42C5D83C3218FC83C41DCFD9F4428F4F92AF1AAA80AA46162B1F71E981273601F4AD1DD4709B5ACA650265A6AB, 1CA5C8ED8414E7F8F6845BAFF4C222176323EA57470A53C69F8C43B5D4760E9041FA400BFA27F538AF1A55FEA6D04F5E14D722A1E728969A8704C96423C25AF247E, 166CA93A22B4587FCB2BDE36253A9B9F990C55119E3DA00619E9FFFAB11F979BA125F9864E0BE3047C5F8574AE27B2D39A081CDBE0DFE725D7D05A5D9DA69334358 +35D511AB97C4C85188B4964AF58B4C596F8DDCC7ADEEB80D4FFF81FED242815E55BC8375A205DE07597D51D2105F2F0730F401, B7E9D6A27F654531FC0F7C786F000863AD0D08FAA424DB04C37F85E91A43905EC1F50CF7E0DE5771279B6D00DBF2CC797B92F428F408DD4F23AEE37903F0EAB72C, 1986D1216BB254A2D161DE42417B688B83A75462BBD00E9C73EDDE6B1BCD3E7F9F0BE17BD038F9C0241974B294FC1278283527FCC83B8B93A0A6611D4B2C592EF7E +A17F3502C74E58F49A1DC2E0E0A1E50C4EA9965709CC2827EFFE85FC76C7841B01358A60E6119A160C77F576311D8D1592DC03, 236D2BF74A2778902DFC71134461968114F6CB85470D0814CAE32C93B1F67B4AD78129CDB257FAB298BCE51088B7C446DC98B20D2F9E591E1FC45737D81B17371B, 764E49450662287FF960F7DB953827D14CA687EAAB6F46FB2754EFAABE7B237033CD52F4C9AFA158494D105F8E284A07CD9061694DEE4AF200144B645BF62FB0D1 +1E47D9F0855EB0ADDCE5948A2A1E5AF24EBFCC3051D647877CFFB91F564568C5103A09F22B234CE422567E0629358A740B89409, D6C48BBDAD09D5C4D21C15913F12DE690D298D78919C30833234F234083C2FBE422C99CA3ED62A84C46B5966DA502C674ABB2D445F084F10EA0325DC725EBA1C6A, 1236C9FA47E0DF713E6FB06AE623DFABED654C699A50C9FE01F0473BE37886B96A20AA210441B28C0778057BF8B2E45421ED2941BC9EFA52791BD477EFBDE2A90B3 +5AD78DD1901C120996B0BD9E7E5B10D6EC3F6490F582D69676FF2B5E02D03A4F30AE1DD68169E6AC67037A127BA09F5C229BC1B, 10271D98E7D157B7462534EC909A78F441E2A76CB8DB4E70A1C3D0F25322440ADAC2398FA7A4B2400EA173209AE764425C3677B93C192CA2316A81C32B9040AE523, 4E1CBEE003FFC3496359FF19DE33ECE2AD87960998B25B7C744B096D4B0829F4553C60C55D34F742D685CBBA36153BF462DD7E516659F1B9619D9E58EC2982B716 +11086A974B054361CC41238DB7B113284C4BE2DB2E08883C364FD821A0870AEED920A5983843DB405350A6E3772E1DE1467D3451, 3C5BF99CBF25A5FBC1ED41341A01727F132CFB9B88F96CB4E205FF7982AE6430EECF9F1CAEB0616377B195F3D6CB32DD2B2521F98A5177D270A586BC03591F4B5, F13C82A9FB0BE0FC3285BBBB387C6EF42ADD9D8B1DAA42FBD9DB171220E7989C13FDCE7F6F049B649BE80E193845DE2B82D34ADB8858B3BDDAB5EB76490076167C +33193FC5E10FCA2564C36AA927133978E4E3A8918A1998B4A2EF8864E19520CC8B61F0C8A8CB91C0F9F1F4AA658A59A3D3779CF3, D974441FF93BD875D32F85621FDA40CC5B8D3E553898195D01951434FF62CEDC9E5EF9F286427798DABCF8D7C86B0177D57414A5BB5BE43E671112602B9CB523AF, 5DDC2DEF5B904E5BAFEC40B0BDB02D4C9FF954EB75454E68A83C0FB2836090AA593ED886780518F113C598BFE901724B64F3219779E9829CD4237173BE3B49A352 +994BBF51A32F5E702E4A3FFB7539AC6AAEAAF9B49E4CCA1DE8CE992EA4BF6265A225D259FA62B542EDD5DDFF309F0CEB7A66D6D9, 3B1130BEAB751C179D55ADBB49C6CC941440104AE070F4D960B6994615B661DC31EA425AEDE1DC4086E3671A82836E5AD425F73E76DE95FED7E11E28E7BDDEB27D, 14028F1E42C5B0B76832EAFFD5DABF2206A2DD8FC481827449AEFA922A0A117EE4D85DE95475FC3038B2D6543538FB0BF037DFCEB6A9199597A1BC2987CC67B23B4 +1CBE33DF4E98E1B508ADEBFF25FAD05400C00ED1DDAE65E59BA6BCB8BEE3E2730E671770DEF281FC8C98199FD91DD26C26F34848B, 15491048378808C7F9ABF6ECFA499A4BAF3208DED49D6048674EC5A7C5118B47748A66B5DE05E4F8D508CB5A38C02A9AB4EE56E6281738C4B24A59AE432B3820B28, 1F0CD96FB51360B9588233605504816284D6C46397DCAF1456CC40669408EE35B8E6F8C21AAECEFAAF135B9E2C051D657A657246EEFF851F80A1B3FE30900BFCEC3 +563A9B9DEBCAA51F1A09C3FD71F070FC02402C75990B31B0D2F4362A3CABA7592B3546529CD785F5A5C84CDF8B59774474D9D8DA1, 744DC5532622CE93265A9BD266A973120840EE42A70231F27735C12F262F486F42B9E34DB4823D824171E3952E39888FEB536BBEF3562F9B7FD08031D32A5AAB9D, 1D36375EDC6231BA3AD055C78BF93CED67B4970235AC69908FFEBCD5201A7D42621CE6742B2A7683BC701286DEBE2F1A576D02A9ED1BDF2CC7EFB8AD92AD9A588F9 +102AFD2D9C35FEF5D4E1D4BF855D152F406C08560CB21951278DCA27EB602F60B819FD2F7D68691E0F158E69EA20C65CD5E8D8A8E3, 1DC533F0E41046DE07F15B53528476DB472D8CCAC8028EEA5869BF60102921644F612DE0A96D8E47B2AACC12868CB24F1A6C89C5C91136DB9E68BE0A4EC7191F875, AF5A59CDADCDD5BDFA872792365E735A3507B76A790F8738C88E62DCF758ED22875CE8A27E3E166A5989316331A91F5BB0112590E6B2179903BEAF3179F2D1DD7B +3080F788D4A1FCE17EA57E3E90173F8DC144190226164BF376A95E77C2208E22284DF78E78393B5A2D40AB3DBE62531681BA89FAA9, 192E4960DFF304595C4F784334AA092C2C944CB31328A05C0224B63A8F0D5EA1753F591E02C35064680DBBFD6B8B8BB514E1E0BC4B66C67512D1080EB4ABB010E44, DBC0284A211FE68D52614ABA9B9BA5847BC114DDB1B2805F84F772BE295B0536520404418E2B3186A2DCAB4C4E1CFACA1D096BA3BEC7F32ED20AF10537A6B6DD30 +9182E69A7DE5F6A47BF07ABBB045BEA943CC4B067242E3DA63FC1B674661AA6678E9E6AB68ABB20E87C201B93B26F943852F9DEFFB, 1A72286CA4510335269C0A7A8528973C9057B408FA9344D1F4064FFFD3280B6897D1F43B3579777800F5C48D9E8555E5C27DC179BF25825CEF9FBD1B5B63B04928, 192FE4551454D55E266A623155D2473AB4DF1F675A453494D3A7E905B4DCA0959C98E865624BE3B84E6036939041D0A737582CB1F8404DB0C3BDF9990290A32547A +1B488B3CF79B1E3ED73D1703310D13BFBCB64E11356C8AB8F2BF45235D324FF336ABDB4023A03162B9746052BB174EBCA8F8ED9CFF1, 13093DAD0548EF1CD3DD104F6F415B4BDAC830442AE1946CC95D4FE385F7D89282360B7581F7851C0A484879E5B3F2799772E6BE515D10C90567D5B6462FABC8A3B, F0A2E650678B0526931C544D24987581E01C60A22DD2D5E32D908AA27B7C0F29632BDF2F0049F721783C472E5F2FA4F8AEE688FF530098B8CDB67968BB3354C271 +51D9A1B6E6D15ABC85B7450993273B3F3622EA33A045A02AD83DCF6A1796EFD9A40391C06AE094282C5D20F83145EC35FAEAC8D6FD3, 16382C2B7F9C282EDF4CC15898744DD404BEFDDD274461CC33BAFB8682B4C02417BB3512B566A0722B40FB7A5B8B3246F46621445FD1ADF186E2B7A9AFF802F4818, 1C7D37BC2A4F2359FD35A2AB14FFEB355C483453FBBCD7A0D0F4AE0B30E1562FA3D315393E5702FC07DEF2356E0DB3BAC1A5F58AF3C5E856E51958A614641CC5402 +F58CE524B47410359125CF1CB975B1BDA268BE9AE0D0E08088B96E3E46C4CF8CEC0AB54140A1BC78851762E893D1C4A1F0C05A84F79, 15162C2DB067EF24A26AFBE769EA5FE69155ABF0C39EEB8E3B898070750A0549B318D5B69519795EC7FB0E8F6A7AC1757973EB6040280C3144B57AC950B2A3DF862, EDFE8D5AA5BAE7C42E4A4DDA5EB3512FF854C02078D19F17AE01DFB6651472432F8F69F9C678ABFE4EB28B6E63138813569042DEBCA32E0D7CF3E8F3BD9CF24B6 +2E0A6AF6E1D5C30A0B3716D562C611538E73A3BD0A272A1819A2C4ABAD44E6EA6C4201FC3C1E535698F4628B9BB754DE5D2410F8EE6B, 1D30D470B2E079FFFBEC501C304666F49A7246B7B4A3932506E0F7521FB935E8AA9EE82627247FC724A329D7A8AD5BB18B953F3F5A0764C959BB0B42755157A21A3, 1051AB08DF58DEDF5E83101A3A8349C7C0F6929BCE9FCA91167FEBC248D88BC6CE46FEC4521A9624EEA4AF30991AA03BA342C85517C39E04D3839542A67331C4595 +8A1F40E4A581491E21A54480285233FAAB5AEB371E757E484CE84E0307CEB4BF44C605F4B45AFA03CADD27A2D325FE9B176C32EACB41, 179648DFC76F49FEA912C21304EEABB3EF2D9D43930DC5213E1F261E31D9A32498B8D97A0FF0E93C08FB7A8B58D0062B3AC983FCBE0D427DDFAA6A5F6270A9F7B61, 54B10D0D94D499FD2E853B61FD6C099E4FBFFA8D42FC273A811031AE8ECA4CF4FAEF3735B11FDA90E571D89EA06B7D75A0B4F85DC5F20A681E03BC4B08A54246F +19E5DC2ADF083DB5A64EFCD8078F69BF00210C1A55B607AD8E6B8EA09176C1E3DCE5211DE1D10EE0B609776E87971FBD1464498C061C3, EAD7064A238176B81C605C4CE0E2EDBB7B5F1246A165A961D5F77CF873041F4A7DE3F37B125C8963F7B8450801F2782FBF133AD4035E6182C9B5F15D1344CA7CFB, 11A8F3CAFFCF2B9E0B4CE967566AAF56687397F9A972612D835299D6952275F6861505D876209DEFC0561414B9527C6A201B3ED62669BF45EB8A707C46C41C34A6D +4DB194809D18B920F2ECF68816AE3D3D0063244F01221708AB42ABE1B46445AB96AF6359A5732CA2221C664B96C55F373D2CDCA412549, 1B8E82141830FE5094583A91383E1C96552C95002A1FF026A60AB5A0A20FFD6A90EB0B1306015EB03946E37ED13CB29CC59D74DB098440F642E963E553C984D26ED, 4CD62F03E4DD7578C64C1046280FCF8C3E54A91E16DCAA6D6B65C59358CC0FCCA9A4B597AE9E13FF58BB5DDA4C7D192507B29AE440526E6395283003127ED3823A +E914BD81D74A2B62D8C6E398440AB7B701296CED0366451A01C803A51D2CD102C40E2A0CF05985E6665532E2C4501DA5B78695EC36FDB, F19EF8D87AF85C3B5321BB3C39AD9CBF60F911B4BB6C73F02D2ECDEF4A1367989115192704B9889CF0EB84013B23DCBB0D38F0FDA0296714B50D6F0EF1AAF4791E, 3B90D68A294B4EA3D33613398EB1A8881ED876F47B54DAF92C3C80A80AC555C8BEE98A9D3025DD03FAC042121BCBE797E39B3880309C0E50ACE24F824DA1D0739B +2BB3E388585DE82288A54AAC8CC202725037C46C70A32CF4E05580AEF578673084C2A7E26D10C91B332FF98A84CF058F12693C1C4A4F91, 1F2CE747EB4B22D5014B69BF3CDECB279446105BDEC7AF21B58C93141D32C8D1B031CC78BE26579A0517B8E16335F7087452963CCB010C52A91A2D4BC507DA3BE8, 1F6161A23C26AD6A1DDD965ABA1C3117C77F818CB3083AF6568F1BB8FC2AC7DFCAB7746676E2199433F7E5D4A663F14EA9AFF3413930CE62A4FA4FA1F000448ABB9 +831BAA990919B86799EFE005A6460756F0A74D4551E986DEA100820CE06935918E47F7A747325B51998FEC9F8E6D10AD373BB454DEEEB3, 156A69E1756107B3310D77907458EAA27FA69DE7C110428618F7CFECE6BDED7051A0E856FC2EB2E7E93B3FD8C185B020AE7AEB680F9A5EFA72D1CA4D046F7D51735, 1EDC17FF76DA34AEB0CFFBAC598F2C287AC06A8F2101514978ACA8127D374EEFF677FF1BC7228276D272ACCB872909FEA1DE6EEA69C121D51CEF2DA0202916D1506 +18952FFCB1B4D2936CDCFA010F2D21604D1F5E7CFF5BC949BE3018626A13BA0B4AAD7E6F5D59711F4CCAFC5DEAB473207A5B31CFE9CCC19, 18E231A2BB0970DC1E6655C8A2B7D8325957D73B7E59A9BB206B638C8CD5439BD295D42BD2C9AACAC391A7513266EDA35379FC12B59D494B4AE60E90BF0818D63FF, 18375B951D26832902650144F76A1CC16E91F6EE5AD76F953E6B61FA754E3CDC764481EC519BC6D4CFE1BF6857258F0AA097B5A724E790A000086E70B24EB73206A +49BF8FF6151E77BA4696EE032D876420E75E1B76FE135BDD3A9049273E3B2E21E0087B4E180C535DE660F519C01D59616F11956FBD6644B, 1975AAA66ADCED2833DE622B01A797EFAE478631A9B455D895F46D40A6901ABF6F6F7C5AF208D2CCB6BE2B81E70BB7FC4C72E88DDF00F1409269A9FE17374B940BB, B605C4E9CDE6E43F254A4FBE3A326F3FF37966BFD5F1FF5BEB0178EEAE932FA78987E6F864443B93BB7B9629E16411B35B680E1B110912A33445E6DFCF4BEBED7 +DD3EAFE23F5B672ED3C4CA0988962C62B61A5264FA3A1397AFB0DB75BAB18A65A01971EA4824FA19B322DF4D40580C244D34C04F3832CE1, 1EB1123F455B677723D14412484CFEBB4DA3950F61F19DF5721F58FD3EFA8A75DA98689B5E7A1EE2C070CD3BB069E55DF84D7DC2CC22582F3F7E56D0C439D2E8325, DA618FD3C5505047AAA8CAE07572462797A26A09D089ACECE3C786408BAA657F6422ED5F7417F5367416E9D764D0F22B9F7EB61E7DFAE97D0CE29C56322B9DC091 +297BC0FA6BE12358C7B4E5E1C99C28528224EF72EEEAE3AC70F12926130149F30E04C55BED86EEE4D19689DE7C108246CE79E40EDA8986A3, 1CC4EA4FCAF6798C560DFE9FE970AD45D754BB2933147A73A81A2DB9ACEFDA4F606398E1597D2C064242A56345959692841FF26D364A5745C3D6597B964F2D987FC, 1E67EE899571AAC18EF4570DF909882D6FC76B1BDE8254A616CE9705A9B55100C322BE863FC12DBDCBFEB4A9D4734477590A2F53F63EE8A3D4EFFF2198F1232C4A2 +7C7342EF43A36A0A571EB1A55CD478F7866ECE58CCC0AB0552D37B723903DDD92A0E5013C894CCAE74C39D9B743186D46B6DAC2C8F9C93E9, 1C5C94EBCF4E441AF961635E852A590638E66AD61ADAFFD38AB95CA9BB0D97ADDA6D45BF2115644D4318D25F357D46CEA9858BE53CD9DE75C6EED05FEE6497A5E8C, 885DAE71332B75E9853931E7A602744D6FB7E30138D8B830955D24A0A83A044979C74D51A59E243F90F480A59BDC38FF79A929562BFC73AD896775CBCDCA12D2C1 +17559C8CDCAEA3E1F055C14F0167D6AE6934C6B0A6642010FF87A7256AB0B998B7E2AF03B59BE660B5E4AD8D25C94947D42490485AED5BBBB, 1B1F5EBABC694721BAEE86B8B527C4EA9703C2F49E191F4E6502DA6C447E0A608E87150FE87AAC675580D30D7A74FA52BCDA80AB8804D18EA902BB4520670EBA8B5, 1843B5C24B62CA20F46E7559F3ACFE2DA8C215FFC6B6B9FDC7EB507D8171B7A7E807465B98077EB5CC60A056C1FA738812C6C1BB49AFD117A6AAF3D1F8380F4B300 +4600D5A6960BEBA5D10143ED0437840B3B9E5411F32C6032FE96F57040122CCA27A80D0B20D3B32221AE08A7715BDBD77C6DB0D910C813331, F709B54B5114543471870692754A841428EFD0770C82A781AECAE63386C327B3C52E992379AA2FBC8514F0A0C9BA2B068CD1C494DB1DFEF4B7827424109323E2A7, 159926BFE544257AC5EAFDAA49A90D4390E578D9A90C2670626317FCD26F384CD65138EA7CA1265E9382F6705158192785D8FB604EF15C540E461F58B17BF21D484 +D20280F3C223C2F17303CBC70CA68C21B2DAFC35D9852098FBC4E050C036865E76F82721627B1966650A19F6541393867549128B325839993, 17C4EF2EDDAC7B6B9C896D936664555798422656BBD4240E7C7F9A447E6EB50B6A1B2A56BDCBB92D4BD10553166815B0127960E767103BDF20CC7E24667AC0ACA57, AD52F42C442B23FCE2650E4B7707D6AA5866F862EBF898F105D6AB42292B3343EA986BFE3BF684F131D0DF349C368860167287B1C2BE5672EC431A7CDA8BA22D3E +2760782DB466B48D4590B635525F3A4651890F4A18C8F61CAF34EA0F240A3931B64E8756427714C332F1E4DE2FC3ABA935FDB37A19708ACCB9, 1329513C937AD4092298CF1593A972B39C33A1A8596632AB6422BE1D1B9DFFD17E272D7C9363210E37E43500C399CF9B14870D231A509FE4386449DC32124F5A6D3, 9B3EB56B122B82035030DF2A6CB05FD0463325B70B5475EC576174FCF58861BC26893555D261A8C7B66B38E2FAF393D1C898FC6F4B339B3FFB48D6208D2C5534E1 +762168891D341DA7D0B2229FF71DAED2F49B2DDE4A5AE2560D9EBE2D6C1EAB9522EB9602C7653E4998D5AE9A8F4B02FBA1F91A6E4C51A0662B, 107D8FE9BA7975F4AD4CA1E8446699B2438621B2C0178900F2F8E2CE179048C984AAD88E794F499258EBFF42DF2B9270DE833EC337BB8BFC1033F7976A49BC9B1FA, 51174AC7A12F0A4D508FF09A0EF48CFA212C36F378AC67929607547544A198DEDA80674FBCFDCB81FA90D98F0960FA7CFD17C2C6945B5D7EED22B701F86469C5B6 +16264399B579C58F7721667DFE5590C78DDD1899ADF10A70228DC3A88445C02BF68C2C208562FBADCCA810BCFADE108F2E5EB4F4AE4F4E13281, 15F1D0395CFFEFA176770CDB66BDBDA07534A481B1F5A2A31991B140FDA835DBFF58429A4845EB501A733F0234698DA9B3C58E23E9BE24E5810F9061AF7F20DBF95, 5FE3F7A9D8213FE65D219E638873F080FE94EFF192711EC237B1098D1F6F3C6AF1DE7E3C727FCDAA1B33D6EFDEB72FD9901049E26C373A7FA37FD8E3B5C2F23679 +4272CACD206D50AE65643379FB00B256A99749CD09D31F5067A94AF98CD14083E3A484619028F30965F83236F09A31AD8B1C1EDE0AEDEA39783, 13BB73C7C0DE9343FD9BF33177CC2C916D2FFA0AABEFFB9F166932845A97212A1259BC6416E1EB584C9ADF7486167CE6E8B642C8AE46FA71434D1B82E514620E4EB, 143266D91BD24A639499B5A0C94641BE2D6434BB8FBAEA6D008F021884E4A5882E50CFCC4A939319AE0AC2733A91B0403BF722EF7382CA0EA696457921845B57597 +C75860676147F20B302C9A6DF1021703FCC5DD671D795DF136FBE0ECA673C18BAAED8D24B07AD91C31E896A4D1CE9508A1545C9A20C9BEAC689, 1A2D288FA87769C9695DD78C70D463392AFFA2BB93EF9D5426518F73FB41ABBFBC1CEBF14271400C54782F8CBA28DC665B3A146B383F1D70E391BAA17669E829CC0, 760C7FCB93FD8D145692C3EB4318EE6F03DAD12F014294CAC35A8481C6020EC71DF14764AD139B9406E77F63A41C7E832F4BDA940EF57A957DE9B4A7F17C1FDA69 +25609213623D7D6219085CF49D306450BF6519835586C19D3A4F3A2C5F35B44A300C8A76E11708B5495B9C3EE756BBF19E3FD15CE625D3C0539B, 127B866890F34CC775044844BC0864B15175DE7A26E51B4F993D1851F605F6D4944703F7D718ECBAEF5C69B806F7AC29604952AD0A0C77154ECBBD3AFE3A9D3652E, 1C8949428A66A1F2D7E54CC8F8C56A421FC0B8A8E2C6B0637671F2BF31AC064E141FD615FBB996C23A4C499189B07BB9DF72F5CFBEB16C25A71F9D4733E7AB3FB83 +7021B63A26B878264B1916DDD7912CF23E2F4C8A009444D7AEEDAE851DA11CDE90259F64A3451A1FDC12D4BCB60433D4DABF7416B2717B40FAD1, 79CD3328A3A58064FB8B90F9FEA4437413F176EE41F6B97E299A538170CB81016CBDDB53C679197505B5723F770D7A4F059ADC86003C634A5630AA114E243E2453, D82A25228F8C3B1407B7EAB67628966010429247A8A4B7B6218D010171EE9C896CC4E817040FAE1FA8A0BCC230399DFD3C961397AF4E8D2FD0BC5E380FCAC4EFE0 +1506522AE74296872E14B449986B386D6BA8DE59E01BCCE870CC90B8F58E3569BB070DE2DE9CF4E5F94387E36220C9B7E903E5C44175471C2F073, 67A20B586960E640C96F6C47EAD9D8C0116AEB8C66345879FCE394A5E94F122A628B56B5B555A2B274B28A4CB8213B594BE94DF210358AE760672771435342CDB7, 161A396F9E6651642A631177DF1A79BD53B1047C0A14A8DF913261343FA40E8C73B108CE4D6E4E509EB14ED597F34FAB0B30BF125C627BC778CE764EAB24D0DE295 +3F12F680B5C7C3958A3E1CDCC941A94842FA9B0DA05366B95265B22AE0AAA03D311529A89BD6DEB1EBCA97AA26625D27BB0BB14CC45FD5548D159, 10A9131226B61979B6A9798D2E2A8448E379A2E558B4E4D817AAA04B0304B59F864A3E85CA1050CE55AC738D8AE14386BEC6C0C311505D55AD8D7CC931AEEBE692C, B6483343D7004A3AD8D5B99094191C7FBE8B8B52D6F564E0A4D60E3D56F9EED4445B301D8372613428FDEF86824EBAE9E4CC29BFD4CA39D2602C915ACA75A53466 +BD38E38221574AC09EBA56965BC4FBD8C8EFD128E0FA342BF7311680A1FFE0B7933F7CF9D3849C15C35FC6FE73271777312313E64D1F7FFDA740B, 9E517DC30559C4CEA55660FE9CC6504D875989DF21629D2C8A83A526A9A186BEED0E8BEFE8999F44086625C32DF45A310E41E18B82210B81A81048D465E762BAD2, 14BAD2DD2D10E324491AE8D29FB0181F16DC0101C47FBDD211897425A410B743028CA405FC074843916801507894C24AC22C2428FDB7053DD07E6D78950F452E0AC +237AAAA866405E041DC2F03C3134EF38A5ACF737AA2EE9C83E5934381E5FFA226B9BE76ED7A8DD4414A1F54FB5975466593693BB2E75E7FF8F5C21, 8C6E1CF957E955181DA548E3DC55EBEC6C3C68BE50F4FBFA0B8AC28F7D4E92FC1F9E5F9D32AC4953F7A6602861575BEE012B9F43771619D1CEF7A8CD492B255268, 14FF248CEADBC92366358C2F3F8046F5DA1A153F8AAB1FF50FD701223209C9B876846D1FAE69EBA7DFE27E6824A101F3E976929EAC9AF070AEA5D53296155AE4868 +6A6FFFF932C11A0C5948D0B4939ECDA9F106E5A6FE8CBD58BB0B9CA85B1FEE6742D3B64C86FA97CC3DE5DFEF20C5FD330BA3BB318B61B7FEAE1463, BBEF569E0CC9A96C7A1C0CC4D3D70620BD5E9D53A58ACD7CD25BF21678DC6EFFAA1F89B1F8F39E7631A9A07D25C19E1C6794958AB2A600B278118F0E25C6223487, 148743E3D98925BEEC533C26B0E3AD101CA28BC7701C54F16A92CE70B2F39B67DBC5984D805C418FE5CB09F4134C2FF58B860A64B9CFD866BAA470EA32DF7DDD68B +13F4FFFEB98434E250BDA721DBADC68FDD314B0F4FBA6380A3122D5F9115FCB35C87B22E594EFC764B9B19FCD6251F79922EB3194A22527FC0A3D29, 1C658E918AD481902FFCB697AF52CEDE3F262449436145B74AD147D2D8E4570FF630D547AAAB4F0ADAC32945E559628A5508C60E3775F0F7B3C62223995CEB56ABB, 7BD861163EFBEC24CCC38A42E1EAA9D2B9BA2D2CD8545876004EA665F0ABD374D38E9A476B291E57DB92DD513D17B93C87CEDEB1A187FBF722416B4CE271384BEE +3BDEFFFC2C8C9EA6F238F565930953AF9793E12DEF2F2A81E936881EB341F61A1597168B0BECF562E2D14DF6826F5E6CB68C194BDE66F77F41EB77B, AF1430CCFB6E96905C60132D711CA0183DC456517413D6B4EA79360EE24DF4C61CEE38D67D57D8F6B97B7996FCEFA4935C2EAE90DC1F7EF6CD93B792EA09CB72CA, 15BBEB0B26DF08BA3BA3DF04DA15DEF333445C9D588166E8F5E7C4333EFEDAAE216228A789DB5E9B76A9F9F8C463C7D028EA38995D37D6755E95769D32B68B93736 +B39CFFF485A5DBF4D6AAE030B91BFB0EC6BBA389CD8D7F85BBA3985C19C5E24E40C543A123C6E028A873E9E3874E1B4623A44BE39B34E67DC5C2671, 11EB2130BCDCE91DFEBF477898E00F46CB475BF5B27E7C5679BD0B167AEFFCE9DA47D499B4A2F13DC4DE9E7223659A6A64D6DE2B246C475F93A4E0AB69374C77CB9, 1D33D47802BD0525A4294A01AAFA1C5BC445EA609D1C91D0A35AB25145951BC9766149EE2190FBFF57350187675CA4F0A2E2F4CDBE21AA58048E538D3082735AF08 +21AD6FFDD90F193DE8400A0922B53F12C5432EA9D68A87E9132EAC9144D51A6EAC24FCAE36B54A079F95BBDAA95EA51D26AECE3AAD19EB3795147353, 1A2F18405BC7A3D509B69C1D05856D4CEF9834E79A256273905DFA6F8B965960B1A7355C8F6365C9D9F4D2540979AE68FE6D4F89F1C462628FDBF2C25F47A9496C5, 14DAA6BB8249897441A6E142244167B9DF06E74D7905910A14AE645A0D23AEC3B4C5A160DE60C9FF1DB0AC4A2AC3D5932D77BBC22D02AC2DC1852F3A9F359D38EEB +65084FF98B2D4BB9B8C01E1B681FBD384FC98BFD839F97BB398C05B3CE7F4F4C046EF60AA41FDE16DEC1338FFC1BEF57740C6AB0074DC1A6BF3D59F9, 1BB9D99F0B34F71683F9629D3ACC1EC0E710861E99FFEC3BFCA03147AFBA4DF250247E2E3AC0C139C54C9DB78F3DE4B6C88D88C435C0253EE30BC55A0F75EC6CFF0, F390B86711EC1DA460FA73AB1C7753428AB592FAA788492718D0ED596A3273914A0BDB4EF43ADD85A9C097F48D7C614E28FCDB14AE62129AA2DD7994C5F51C7D7B +12F18EFECA187E32D2A405A52385F37A8EF5CA3F88ADEC731ACA4111B6B7DEDE40D4CE21FEC5F9A449C439AAFF453CE065C25401015E944F43DB80DEB, AB70771B55DC2406DA2CFDF6AD36BE05F3D6B71391504333C2ADA85367215599B1F75483E32432709AF01E8EF2DC7B393B69D0A66F6BB52749E51A8C855E2B2165, 1C927D230DDEC9908E2202D863E37A9254A9AB0F15B4AD3058D6B508285BF638379DF0513C3DED4C5F003CB486001FB9B5AEA796E8559284FE82113E7BC9EE7184C +38D4ACFC5E497A9877EC10EF6A91DA6FACE15EBE9A09C559505EC33524279C9AC27E6A65FC51ECECDD4CAD00FDCFB6A13146FC03041BBCEDCB92829C1, 1CC9802E3D53A08C1063EF50510241DAAEDF80C1696258F812411A7619D500E3ACAE35D1DC16761E9AB1B667F6A5CFB3DE60C6D0E0626DE429A138FEF3418910622, F45C2CA54B397DB15640C19E2FC5C23A727341A86AA485B95E5E21EF56BDA509239649D4DF7C736DFD5B9423FE2B964941333BA7D63F8AD92E6CFB040992C7F694 +AA7E06F51ADC6FC967C432CE3FB58F4F06A41C3BCE1D500BF11C499F6C76D5D0477B3F31F4F5C6C697E60702F96F23E393D4F4090C5336C962B787D43, 15C7C77A85A087586E3543849614AF7CD373C56AD4D04865A72D9DC8572DEB2E811A75A3FC28C8A1D1D7EC61312E1E81CB02EED003FF3693259DFCD877891BE183C, 6F9499F4D91F936C153285A7C383B8C6058E9E676D1E68AA777896030C86F96022A08CDED4527E2B947D4A27E7D11E942F6EBC0E74E84EC2E2F1CD3ECF59DCC8CF +1FF7A14DF50954F5C374C986ABF20ADED13EC54B36A57F023D354DCDE45648170D671BD95DEE15453C7B21508EC4D6BAABB7EDC1B24F9A45C2826977C9, 542B6B74778AC458886E35A9A1410C3DA9F0F0E77930495B62631ACE17B7A0484C9B014CB1536770BB7B6DFC4913B0F34E63FF33C91481C63F7BC031222BCB53AA, 11D96C405781389CF533F8156A70AAE884D261FF36AD792810CA859A2751B6C14CA1C98E12332DAC28A37671D0693C5E81493A483BCE1BD739333035DDAEAEF5AAF +5FE6E3E9DF1BFEE14A5E5C9403D6209C73BC4FE1A3F07D06B79FE969AD02D8452835538C19CA3FCFB57163F1AC4E84300327C94516EECED147873C675B, 183C05B70F209BE717045ABEA0B91E88645D9210307A45F7887CB5B8E05387801E06A17E34545E4D54B50A61A0AD8619B62A9453D499D4CFA64FC591541D360FA55, 185CA9FFA827C9EA38F9EB0BF24CE36701AE794CF05344AAD469C6B13CC40B1426ECF8DFEB69EA8831612E4A042A883279AE8378F3C28CB54A5B367F41A9CEFA885 +11FB4ABBD9D53FCA3DF1B15BC0B8261D55B34EFA4EBD1771426DFBC3D070888CF789FFAA44D5EBF6F20542BD504EB8C9009775BCF44CC6C73D695B53611, 17E2D3E8289F1A3822316EC45C80A93F113C2CCF92BBAD0616CE4C31F47A6786DE3104B172733C9C349ECB4724C59F90943CE6A87064F36369B4173D402B33B89D4, 14FC14E5BEB0866623400696A2FF439967C7E33A1528F5790D196FAE0CAA5686D38BD795BBBA74712F406E183A92EB79102086229675A2A8B2EBCA9816608596DA0 +35F1E0338D7FBF5EB9D51413422872580119ECEEEC374653C749F34B715199A6E69DFEFECE81C3E4D60FC837F0EC2A5B01C66136DCE65455B83C11FA233, 1673C0F4D6A21EAA5692AC9256C648738BD7252DFD184E9512C3F5F92F8F51E4DCA6FEB75D13FF75EDC8ED728CE24512115B7D66E5A8C7BDD53F148CF7DA70E6CE7, 11AAEC3CE7DF2AD0591949D0BB5F4B5437A7287D3A1CFC06F61FF24D4714631E0471E02782BE823E904AD29FFCE51D17AA838F52E304A157FE0EE06742678A1D22E +A1D5A09AA87F3E1C2D7F3C39C6795708034DC6CCC4A5D2FB55DDD9E253F4CCF4B3D9FCFC6B854BAE822F58A7D2C47F11055323A496B2FD0128B435EE699, DE321BBBF4C54AFCE7D32215A2EEFEB2EE09767FFF04FAA6B2341FAF782CF9A9D07EDBE5936F2B36C585E5D99A29B69E8F08F4A2CFE21641DEB6D041C08B974EBD, 18177025D1E0BE77A67CDEB542C098488503F70360EB2F61C823A7B1BDEBB1A8892A3097D85F49AAABCCA29745C5E7CBF103AC62DADCAA995AD95206EF2411C752D +1E580E1CFF97DBA54887DB4AD536C051809E954664DF178F201998DA6FBDE66DE1B8DF6F5428FE30B868E09F7784D7D330FF96AEDC418F7037A1CA1CB3CB, D8DE2E16D35FADD54628BF94D1EC81611E6D703B7D87B3727F96FBF1326D8EFCEE5469442F6229708D2B9F28D0FF2784C78B44877304A890247ACCCBC16872A3B3, 1FE6EA28DD4B30DF390C567AA15EDEB300863F425A5B1B3CC16BCD861924EAE7834D73C0B13FE1A03BB1DD27ED7424BCC01E7C39AB3A211A8EA92445D13444BE9C9 +5B082A56FEC792EFD99791E07FA440F481DBBFD32E9D46AD604CCA8F4F39B349A52A9E4DFC7AFA92293AA1DE668E877992FEC40C94C4AE50A6E55E561B61, 184ABE3FB0312D282A4E0DF22DAF6408F35D4F08EA171E96DD753DAFB8E334D9CB1F94FDAAE28A52CADAA6196F8EC9FA8C4A1228E5C0FD1C77B69662CFDB90821DB, 188314CA090595942D25D26EE3A71B97DBFD8F3022A799BD61054D6BCD7DD852759102E0B1FD13A4E496B0D03EB499F44F66D803AE7FDDBAABD6B43AD1961CD392F +111187F04FC56B8CF8CC6B5A17EECC2DD85933F798BD7D40820E65FADEDAD19DCEF7FDAE9F570EFB67BAFE59B33AB966CB8FC4C25BE4E0AF1F4B01B025223, 2DF486A3DC35410AAD27C68671278B1DF07EC59A3555AC1F33AC99327743EEEFA50450981D4A63AE1D4791F8576E745B58E21FFB0132BC9F5471CD596C75C9E2D1, CDDF942FAC9EC5A83D34C1E61BFC6DD0432FCF22A03E617B2A76FB432ACCF076EE5538D91019809C257F329D670DD32BC861236C46F8985263556421734E2DB47E +333497D0EF5042A6EA65420E47CC6489890B9BE6CA3877C1862B31F09C9074D96CE7F90BDE052CF23730FB0D19B02C3462AF4E4713AEA20D5DE105106F669, FC47F39D9A9342D32CCD7ED1550B17FC76DBD98E4EC648491EAA3AD81ECCD498E758EF6E68E2942FB5436EC2F18E6E1A59455534D36645AA6CE2EEF7ABEA6A429F, 77B64D0C8442C16071D06AB2F56DC1E454EB37C0046CF9D9A05AF17100789242D6B426A335007936677AA7C82E365E25E6D335C67E5A4C7F22E80AC4F7A915D218 +999DC772CDF0C7F4BF2FC62AD7652D9C9B22D3B45EA96744928195D1D5B15E8C46B7EB239A0F86D6A592F1274D10849D280DEAD53B0BE62819A30F314E33B, 72DF7D29DC382D061D17FA29CDF4F2CA5FE533F44E6C0BB39ACAAA5B535748D155DA215C572A24EFBEB3E08C422CBC7CC389280C764FBB120B37485BE7ED793300, 1379F04E35E19E2823531C0D926889287BC66FEDE617EB1F906294FC5C10D7185AFF09ACAA36484097EEFAD2CB2D9FCD1667FC94A21D7BF27844C157D8EB546769E +1CCD9565869D257DE3D8F5280862F88D5D1687B1D1BFC35CDB784C17581141BA4D427C16ACE2E9483F0B8D375E7318DD77829C07FB123B2784CE92D93EA9B1, 6AF49F5160C72F719C743C516123F45DED177FC979A5257EB459D293CC49C6D6C85FA019A1B25A75D5C5C8EF5AB2D7F471722BAF41D880435CD333F1D35A11A1F9, 17A092F54E224F3F5E370D6188B9735D77BA59A16BF18BDBA27C8622CDB0C4AAADDE676975F36A715B1F5C998E463973C56E5077D81351605DEDCC86E1579E4F45C +5668C03093D77079AB8ADF781928E9A817439715753F4A169268E4460833C52EE7C7744406A8BBD8BD22A7A61B594A986687D417F136B1768E6BB88BBBFD13, 1509FE8354E1C0D49704F7C9E384B44EE122F206A73FD15D5FE5C0893A35BACFC657A2F459B6919C6A59F8B16485DD86901D5FC0334C7F8F56FE2FDD9CD710BAFC3, 1A0FA3E32180226048F38FFE609BC26FD2397A092D6A9CF1EF4F76C682FCA5E0A9BF5B17E87737CC187722AB4DB85E35E6435FBD0B10136F68DABA009D03CD553F1 +1033A4091BB86516D02A09E684B7ABCF845CAC5405FBDDE43B73AACD2189B4F8CB7565CCC13FA338A3767F6F2520BDFC933977C47D3A41463AB4329A333F739, 46DBEFDA4678029137F8D2B537F8B3418FCEB35AD4DE9EFD7016EA10AB8CC83F5DE525A4AF44B85D871880490340C24799CFEC7AEB7DCB8A27F328B78033DA3E3A, 17088E0DA70A4E95C5A05C3C9E7FA1E64803497C8ADD85CC6BE00F1F4730ECC3D83320251BEA6F903C26D518C64D70F0391E40F52394D20D464C4CB1ADDFD17765B +309AEC1B53292F44707E1DB38E27036E8D1604FC11F399ACB25B0067649D1EEA6260316643BEE9A9EA637E4D6F6239F5B9AC674D77AEC3D2B01C97CE99BE5AB, BD1D1172FEA3E457BD8AD5444E23C3185D33B63F90381C7F4ED35DD5ABAD4225EB96C94B2ACA6D6445CD805492FAED155383CB2ADCAF8D2109ED57FFD12DBC60D7, 128187DBD872D2FE96112AD4670661DE2B1E1FF315EC45437DD1D17F22855C64181698EFEA87062EA0B21E9920811A09616DD72A9588D4C2B3C05F2D751554A986F +91D0C451F97B8DCD517A591AAA750A4BA7420EF435DACD06171101362DD75CBF27209432CB3CBCFDBF2A7AE84E26ADE12D0535E8670C4B781055C76BCD3B101, AB657A84D03CBE90E321B0C132C593A87E3229AB6F8526BE212718B4938FB431A10D612146F2FEA097A258CBC3C6490D9010D4BC3C8D449512A8644E32B4B2802F, BE610A0EDA21A8284FE7AF01AE163E93C7AA71ECCDDB50B15D2DE9A13FAAB4362C2A29DDB3BB59ACC8DF9002796B193FB9C686C429F5C8961ECCE946F9051849FA +1B5724CF5EC72A967F46F0B4FFF5F1EE2F5C62CDCA1906712453303A28986163D7561BC9861B636F93D7F70B8EA7409A3870FA1B93524E2683101564367B1303, 16FDBCD87907F7640250E562D5D7EA5FF0C1EEE49A0D63FA7A56D6B848793BF1BCD9755011FFEA81132A9364407F299170A095FE89B9A6A3DF9D79AEE77FD341D62, 12548441A0B629009456EAD09DD05F0DE1FE178D71DB7AB140D32B5D0208268C125BD6C60304F450B4CB684CBE67798C91D4CF70E17D2DBFE6E1C4C3E70BAE03796 +52056E6E1C557FC37DD4D21EFFE1D5CA8E1528695E4B13536CF990AE79C9242B8602535C92522A4EBB87E522ABF5C1CEA952EE52B9F6EA738930402CA3713909, 10470A88DFED45D0F19595E671D53581F51E4A2D3A0DA6533F89632AAB22FCB4BFBB025554F762A32AEAEE6A1101100F9C006A037BC6DBECD79AA761F0E843F395C, 657458DEC44CCAAE706CB552B34BDC57E34F46E7B24B3DB8D3B346E8D3F066DCBC7AF6FFDC52115D76A5551C996FE46037A45279553A8532D4A6288211F966FA64 +F6104B4A55007F4A797E765CFFA5815FAA3F793C1AE139FA46ECB20B6D5B6C829206FA15B6F67EEC3297AF6803E1456BFBF8CAF82DE4BF5A9B90C085EA53AB1B, A9C7B530A8C82ED3DDAC093C679BBA9C10BAE4C6E70A46CE699056782212C251D4659D0174C80EB4A3A9DA5C1309DE8EAB660D182B197CB70984C394B280F2FE51, 1A9AFD356F904DE55B89E664146636D5AA3833C9A8CDC3DB1DE6A40B183F2B658AB79F29024AF382AB6E1E0F5A451C9F54288869F9EB728E3AE80E2F00B786CE883 +2E230E1DEFF017DDF6C7B6316FEF0841EFEBE6BB450A3ADEED4C6162248124587B614EE4124E37CC497C70E380BA3D043F3EA60E889AE3E0FD2B24191BEFB0151, 10BFECB2F86933EF2D3D0F4FC1B8BE4C3C2B6AEA1FAFA4BDC00C5E26457551DFE3FDECB8114596EAD3445FB3F7C2D6807AAA4CF476C0F9E2116EE212848E22F7E64, AA03AF238C228537E1528ADB56243799645ECCCA9AB62D78D4354DA6B06EAB59B7B1A61BE103CF52AEF6FD02E39994B0EDF5B55E5E6835E20729BA6CC3BDFD7B81 +8A692A59CFD04799E45722944FCD18C5CFC3B431CF1EB09CC7E524266D836D097223ECAC36EAA764DC7552AA822EB70CBDBBF22B99D0ABA2F7816C4B53CF103F3, 89C9C81B7863056A04D35A8DA566FED1A583B11A32C139AF5ED52B6B3C84763CD9D16A03FE9F8F76D66D9043A12CBA99E2160163462553A259E7DBB9E39B36BFCA, 1ACA646516FBCDC7419702A53757BA2EE8EEAC0D228F499870BEDF68661F8D56FF9B44F829B6F0DC32D4C7209F81A8A818C83B8DAE23373C5FB482335007B5287FD +19F3B7F0D6F70D6CDAD0567BCEF674A516F4B1C956D5C11D657AF6C73488A471C566BC604A4BFF62E955FF7FF868C25263933D682CD7202E8E68444E1FB6D30BD9, C838E095D259ADC1081183214930E368BC3C68C226983B0808314A7B5C54400F7EE47C093230C367AD46D06616AB864A293C3509732F99C4E4A3BF76277B58CD20, B5A4ACD32FB314B1A0FEDB687CE97FE16CA00A7004D73036E80C6246420D9EA5211DB0ACAD07813C8E74B0370073906EC7AB3B0962DB31A624AC86A03914E52D05 +4DDB27D284E52846907103736CE35DEF44DE155C048143583070E4559D99ED5550343520DEE3FE28BC01FE7FE93A46F72AB9B8388685608BAB38CCEA5F2479238B, 12B7BA8CDCD76630988291EF9B9F414711BECB923207BD1641F63650D2EB79F03D42438B275A2261C69F7DD6FA439794022FFC997C80F12B1255DCAE82A50AEB331, 8B37583CF151BB968D438E17E21480A701261C14963FAE4EF37F9BFA12174D1FB477DAEADAF447DA8188E2D89C052174073ED02CD014CF16A87D2CC77FB0F42F5E +E99177778EAF78D3B1530A5A46AA19CDCE9A40140D83CA089152AD00D8CDC7FFF09C9F629CABFA7A3405FB7FBBAED4E5802D28A9939021A301AA66BF1D6D6B6AA1, 1AA4D99854C554B4BC1106C67B4F4C7471C350068949097410ECC934CE1D8A93521FEE72B32980D51B0C4BEB4CCC4F26661ED17AF49D08A6B6850F01C9811960635, 1E2FDA7EBE4C8581C5342540A22C6AE12D991D5D4AB67CACC38078F0DA280902E90E6A14609E9E404711A048A8FEF8A75DA40957494E1577DAAFED199A66EE97C5F diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/notes/etc/saferp_optimizer.c b/xmhf-64/xmhf/third-party/libtomcrypt/notes/etc/saferp_optimizer.c new file mode 100644 index 0000000000..e73aee7665 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/notes/etc/saferp_optimizer.c @@ -0,0 +1,177 @@ +/* emits an optimized version of LTC_SAFER+ ... only does encrypt so far... */ + +#include +#include + +/* This is the "Armenian" Shuffle. It takes the input from b and stores it in b2 */ +#define SHUF\ + b2[0] = b[8]; b2[1] = b[11]; b2[2] = b[12]; b2[3] = b[15]; \ + b2[4] = b[2]; b2[5] = b[1]; b2[6] = b[6]; b2[7] = b[5]; \ + b2[8] = b[10]; b2[9] = b[9]; b2[10] = b[14]; b2[11] = b[13]; \ + b2[12] = b[0]; b2[13] = b[7]; b2[14] = b[4]; b2[15] = b[3]; memcpy(b, b2, sizeof(b)); + +/* This is the inverse shuffle. It takes from b and gives to b2 */ +#define iSHUF(b, b2) \ + b2[0] = b[12]; b2[1] = b[5]; b2[2] = b[4]; b2[3] = b[15]; \ + b2[4] = b[14]; b2[5] = b[7]; b2[6] = b[6]; b2[7] = b[13]; \ + b2[8] = b[0]; b2[9] = b[9]; b2[10] = b[8]; b2[11] = b[1]; \ + b2[12] = b[2]; b2[13] = b[11]; b2[14] = b[10]; b2[15] = b[3]; memcpy(b, b2, sizeof(b)); + +#define ROUND(b, i) \ + b[0] = (safer_ebox[(b[0] ^ skey->saferp.K[i][0]) & 255] + skey->saferp.K[i+1][0]) & 255; \ + b[1] = safer_lbox[(b[1] + skey->saferp.K[i][1]) & 255] ^ skey->saferp.K[i+1][1]; \ + b[2] = safer_lbox[(b[2] + skey->saferp.K[i][2]) & 255] ^ skey->saferp.K[i+1][2]; \ + b[3] = (safer_ebox[(b[3] ^ skey->saferp.K[i][3]) & 255] + skey->saferp.K[i+1][3]) & 255; \ + b[4] = (safer_ebox[(b[4] ^ skey->saferp.K[i][4]) & 255] + skey->saferp.K[i+1][4]) & 255; \ + b[5] = safer_lbox[(b[5] + skey->saferp.K[i][5]) & 255] ^ skey->saferp.K[i+1][5]; \ + b[6] = safer_lbox[(b[6] + skey->saferp.K[i][6]) & 255] ^ skey->saferp.K[i+1][6]; \ + b[7] = (safer_ebox[(b[7] ^ skey->saferp.K[i][7]) & 255] + skey->saferp.K[i+1][7]) & 255; \ + b[8] = (safer_ebox[(b[8] ^ skey->saferp.K[i][8]) & 255] + skey->saferp.K[i+1][8]) & 255; \ + b[9] = safer_lbox[(b[9] + skey->saferp.K[i][9]) & 255] ^ skey->saferp.K[i+1][9]; \ + b[10] = safer_lbox[(b[10] + skey->saferp.K[i][10]) & 255] ^ skey->saferp.K[i+1][10]; \ + b[11] = (safer_ebox[(b[11] ^ skey->saferp.K[i][11]) & 255] + skey->saferp.K[i+1][11]) & 255; \ + b[12] = (safer_ebox[(b[12] ^ skey->saferp.K[i][12]) & 255] + skey->saferp.K[i+1][12]) & 255; \ + b[13] = safer_lbox[(b[13] + skey->saferp.K[i][13]) & 255] ^ skey->saferp.K[i+1][13]; \ + b[14] = safer_lbox[(b[14] + skey->saferp.K[i][14]) & 255] ^ skey->saferp.K[i+1][14]; \ + b[15] = (safer_ebox[(b[15] ^ skey->saferp.K[i][15]) & 255] + skey->saferp.K[i+1][15]) & 255; + +int main(void) +{ + int b[16], b2[16], x, y, z; + +/* -- ENCRYPT --- */ + for (x = 0; x < 16; x++) b[x] = x; + /* emit encrypt preabmle */ +printf( +"void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)\n" +"{\n" +" int x;\n" +" unsigned char b[16];\n" +"\n" +" LTC_ARGCHK(pt != NULL);\n" +" LTC_ARGCHK(ct != NULL);\n" +" LTC_ARGCHK(skey != NULL);\n" +"\n" +" /* do eight rounds */\n" +" for (x = 0; x < 16; x++) {\n" +" b[x] = pt[x];\n" +" }\n"); + + /* do 8 rounds of ROUND; LT; */ + for (x = 0; x < 8; x++) { + /* ROUND(..., x*2) */ + for (y = 0; y < 16; y++) { +printf("b[%d] = (safer_%cbox[(b[%d] %c skey->saferp.K[%d][%d]) & 255] %c skey->saferp.K[%d][%d]) & 255;\n", + b[y], "elle"[y&3], b[y], "^++^"[y&3], x*2, y, "+^^+"[y&3], x*2+1, y); + } + + /* LT */ + for (y = 0; y < 4; y++) { +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[0], b[0], b[1], b[0], b[1]); +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[2], b[2], b[3], b[3], b[2]); +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[4], b[4], b[5], b[5], b[4]); +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[6], b[6], b[7], b[7], b[6]); +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[8], b[8], b[9], b[9], b[8]); +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[10], b[10], b[11], b[11], b[10]); +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[12], b[12], b[13], b[13], b[12]); +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[14], b[14], b[15], b[15], b[14]); + if (y < 3) { + SHUF; + } + } + } + +printf( +" if (skey->saferp.rounds <= 8) {\n"); +/* finish */ + for (x = 0; x < 16; x++) { + printf( +" ct[%d] = (b[%d] %c skey->saferp.K[skey->saferp.rounds*2][%d]) & 255;\n", + x, b[x], "^++^"[x&3], x); + } + printf(" return;\n }\n"); + + /* 192-bit keys */ +printf( +" /* 192-bit key? */\n" +" if (skey->saferp.rounds > 8) {\n"); + + /* do 4 rounds of ROUND; LT; */ + for (x = 8; x < 12; x++) { + /* ROUND(..., x*2) */ + for (y = 0; y < 16; y++) { +printf("b[%d] = (safer_%cbox[(b[%d] %c skey->saferp.K[%d][%d]) & 255] %c skey->saferp.K[%d][%d]) & 255;\n", + b[y], "elle"[y&3], b[y], "^++^"[y&3], x*2, y, "+^^+"[y&3], x*2+1, y); + } + + /* LT */ + for (y = 0; y < 4; y++) { +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[0], b[0], b[1], b[0], b[1]); +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[2], b[2], b[3], b[3], b[2]); +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[4], b[4], b[5], b[5], b[4]); +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[6], b[6], b[7], b[7], b[6]); +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[8], b[8], b[9], b[9], b[8]); +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[10], b[10], b[11], b[11], b[10]); +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[12], b[12], b[13], b[13], b[12]); +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[14], b[14], b[15], b[15], b[14]); + if (y < 3) { + SHUF; + } + } + } +printf("}\n"); + +printf( +" if (skey->saferp.rounds <= 12) {\n"); +/* finish */ + for (x = 0; x < 16; x++) { + printf( +" ct[%d] = (b[%d] %c skey->saferp.K[skey->saferp.rounds*2][%d]) & 255;\n", + x, b[x], "^++^"[x&3], x); + } + printf(" return;\n }\n"); + + /* 256-bit keys */ +printf( +" /* 256-bit key? */\n" +" if (skey->saferp.rounds > 12) {\n"); + + /* do 4 rounds of ROUND; LT; */ + for (x = 12; x < 16; x++) { + /* ROUND(..., x*2) */ + for (y = 0; y < 16; y++) { +printf("b[%d] = (safer_%cbox[(b[%d] %c skey->saferp.K[%d][%d]) & 255] %c skey->saferp.K[%d][%d]) & 255;\n", + b[y], "elle"[y&3], b[y], "^++^"[y&3], x*2, y, "+^^+"[y&3], x*2+1, y); + } + + /* LT */ + for (y = 0; y < 4; y++) { +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[0], b[0], b[1], b[0], b[1]); +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[2], b[2], b[3], b[3], b[2]); +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[4], b[4], b[5], b[5], b[4]); +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[6], b[6], b[7], b[7], b[6]); +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[8], b[8], b[9], b[9], b[8]); +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[10], b[10], b[11], b[11], b[10]); +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[12], b[12], b[13], b[13], b[12]); +printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[14], b[14], b[15], b[15], b[14]); + if (y < 3) { + SHUF; + } + } + } +/* finish */ + for (x = 0; x < 16; x++) { + printf( +" ct[%d] = (b[%d] %c skey->saferp.K[skey->saferp.rounds*2][%d]) & 255;\n", + x, b[x], "^++^"[x&3], x); + } + printf(" return;\n"); +printf(" }\n}\n\n"); + + return 0; +} + + +/* $Source: /cvs/libtom/libtomcrypt/notes/etc/saferp_optimizer.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2007/05/12 14:20:27 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/notes/etc/whirlgen.c b/xmhf-64/xmhf/third-party/libtomcrypt/notes/etc/whirlgen.c new file mode 100644 index 0000000000..86c7e676b0 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/notes/etc/whirlgen.c @@ -0,0 +1,95 @@ +#include + +unsigned E[16] = { 1, 0xb, 9, 0xc, 0xd, 6, 0xf, 3, 0xe, 8, 7, 4, 0xa, 2, 5, 0 }; +unsigned Ei[16]; +unsigned R[16] = { 7, 0xc, 0xb, 0xd, 0xe, 4, 9, 0xf, 6, 3, 8, 0xa, 2, 5, 1, 0 }; +unsigned cir[8][8] = { + {1, 1, 4, 1, 8, 5, 2, 9 }, +}; + + +unsigned gf_mul(unsigned a, unsigned b) +{ + unsigned r; + + r = 0; + while (a) { + if (a & 1) r ^= b; + a >>= 1; + b = (b << 1) ^ (b & 0x80 ? 0x11d : 0x00); + } + return r; +} + +unsigned sbox(unsigned x) +{ + unsigned a, b, w; + + a = x >> 4; + b = x & 15; + + a = E[a]; b = Ei[b]; + w = a ^ b; w = R[w]; + a = E[a ^ w]; b = Ei[b ^ w]; + + + return (a << 4) | b; +} + +int main(void) +{ + unsigned x, y; + + for (x = 0; x < 16; x++) Ei[E[x]] = x; + +// for (x = 0; x < 16; x++) printf("%2x ", sbox(x)); + for (y = 1; y < 8; y++) { + for (x = 0; x < 8; x++) { + cir[y][x] = cir[y-1][(x-1)&7]; + } + } + +/* + printf("\n"); + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) printf("%2d ", cir[y][x]); + printf("\n"); + } +*/ + + for (y = 0; y < 8; y++) { + printf("static const ulong64 sbox%d[] = {\n", y); + for (x = 0; x < 256; ) { + printf("CONST64(0x%02x%02x%02x%02x%02x%02x%02x%02x)", + gf_mul(sbox(x), cir[y][0]), + gf_mul(sbox(x), cir[y][1]), + gf_mul(sbox(x), cir[y][2]), + gf_mul(sbox(x), cir[y][3]), + gf_mul(sbox(x), cir[y][4]), + gf_mul(sbox(x), cir[y][5]), + gf_mul(sbox(x), cir[y][6]), + gf_mul(sbox(x), cir[y][7])); + if (x < 255) printf(", "); + if (!(++x & 3)) printf("\n"); + } + printf("};\n\n"); + } + + printf("static const ulong64 cont[] = {\n"); + for (y = 0; y <= 10; y++) { + printf("CONST64(0x"); + for (x = 0; x < 8; x++) { + printf("%02x", sbox((8*y + x)&255)); + } + printf("),\n"); + } + printf("};\n\n"); + return 0; + +} + + + +/* $Source: /cvs/libtom/libtomcrypt/notes/etc/whirlgen.c,v $ */ +/* $Revision: 1.2 $ */ +/* $Date: 2005/05/05 14:35:58 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/notes/etc/whirltest.c b/xmhf-64/xmhf/third-party/libtomcrypt/notes/etc/whirltest.c new file mode 100644 index 0000000000..0529d65b53 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/notes/etc/whirltest.c @@ -0,0 +1,19 @@ +#include + +int main(void) +{ + char buf[4096]; + int x; + + while (fgets(buf, sizeof(buf)-2, stdin) != NULL) { + for (x = 0; x < 128; ) { + printf("0x%c%c, ", buf[x], buf[x+1]); + if (!((x += 2) & 31)) printf("\n"); + } + } +} + + +/* $Source: /cvs/libtom/libtomcrypt/notes/etc/whirltest.c,v $ */ +/* $Revision: 1.2 $ */ +/* $Date: 2005/05/05 14:35:58 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/notes/gcm_tv.txt b/xmhf-64/xmhf/third-party/libtomcrypt/notes/gcm_tv.txt new file mode 100644 index 0000000000..79d3b8d673 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/notes/gcm_tv.txt @@ -0,0 +1,214 @@ +GCM Test Vectors. Uses the 00010203...NN-1 pattern for nonce/header/plaintext/key. The outputs +are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous +step repeated sufficiently. The nonce is fixed throughout at 13 bytes 000102... + +GCM-aes (16 byte key) + 0: , C6A13B37878F5B826F4F8162A1C8D879 + 1: F1, 397F649A20F3F89A00F45BF230F26B61 + 2: D6B8, 1653F67C9C716D0FC59F3B14154DECBF + 3: 673456, E82EFC79B30CA5235E2DC8BE4C14265D + 4: 26DD7C26, B8D1F4DB845F7D7079DEB8920949C14D + 5: DA62AD1487, 828A42329320764E5FB74D44A6108F4B + 6: FB79F7D51742, 865415BD049E86F3DA2E0B6E25E1A50C + 7: 9D96D1034166BF, 50669247A5B338E183DE5139831CD6A4 + 8: B466050E1330B20A, CB264FA7853A1FFE86E1A07CFA7C7319 + 9: CF16F0B3D9FC6183DF, 647DD6E1F40F385E1DFE6676FB036242 + 10: 14D90928C7236050096F, 930CAAA5536406218885475CA823A973 + 11: 4F2322D66A7079BD7DF519, 3B3931D47413042FAF1313F1041509A3 + 12: F1497906F1D8F4F9E47E4BE9, 469FB0D62828427C2E9BA04041A1424F + 13: 2FAFA2A3EEA4C000702E58D1D4, C9A484FC4ED8644A06060DAE2C3D1568 + 14: 5D707F8ACF319413D220AA2FC2B2, 0EE9AAF5B1CF622ECF6C4F5E5FF4656A + 15: 2C19DBF966D24B2713F82B69934060, 8676246A2F7795ABD435B3C6B4EA6E7A + 16: B3FED6C2315CE6D98729DBE69270A11E, B8AC739AD154744A33E906C34D91BD4B + 17: B2BC44CE088BC3F654B9703D9C691F17B3, BAD8314A171BC0119942136C5876AACC + 18: C6E958E3E9AC836C9626BD66478974D26B0C, 4E6D61833E9DB839117B665A96DC686C + 19: D40FADD078B474EBCE130FB44DDB4824077988, F43E3CD978A6E328AF039CC70E291E1C + 20: E177B3DF83A117E55F255A6C2CD78AFDAFDA307F, EEF1ABAAB9CBE0EE317CC79E7E5E24B8 + 21: DBB4569B3E305E4525F1F7B3D2AFEF226F397E661D, 65ACFB70132EEE1D47319A550A506DB5 + 22: AC2CAF77718DE59131A6B745DE9F3A9897B17580EC71, D8DB9006A9597F640F2594340D69E551 + 23: 8F62022F72A0D769D2D095A55E28832950870B2B44B0BE, A7E196F869071B7BB713E8A2D15627E9 + 24: 37F5640F820384B35F13F8C8C7DC31BDE1E4F29DCFBDA321, D5765C39DBCA72AC89100CCB8864E1DB + 25: 25059BFC302D0F8DD41BB22CF2391D456630C06F1DAF4DFA86, DC2FFD153C788C28D251B78AB8B7388C + 26: 151F158CC4BA9393FDB153C4C72911C120BAB519FAF64719133D, C61915006038BF15DED603832FD179DE + 27: F5DCF4231482F72D02F8B9BE0A41113D35AEA1CD85021CEC978D9C, 9CBD02C557180FBD0868C87A0BEA25AE + 28: 5D88B5554A2ED73054226473676FAA7159CE12B5357D635DDED35B5A, 5AD11CD6B14C59E64B5B26DFBD00FB5C + 29: 5696C7066EA09A30FC8BCBAD96D48A5E5FBCC8756B770F0A89B8711911, B9EA5F3BEF0599D385A9ACEBE4064498 + 30: 1240FED47B305AC1883F8CF137D58E79052B4E686DCA1423A6A2BECBD5F5, 036A5EA5F4F2D0BF397E8896EB7AB03D + 31: AD9517BF392C1EB56D78EDE1C41F3C73B72304DA47F400C390C86B37A50C2A, EB3E026D518EED47F6C927525746AC54 + 32: 2AE1CEED83C6490A7E5752E91532406EAC6FF4B11AA770EFFF1B255FDB77C528, 74BFBC7F120B58FA2B5E988A41EAF7AC + +GCM-rc6 (16 byte key) + 0: , D595FEDAB06C62D8C5290E76ED84601D + 1: 4D, 47A6EDEF8286F9C144B7B51C9BCCCACF + 2: 0085, 9788DDF89843EC51120B132EB0D0F833 + 3: 463701, 673CB8D248E6BECD5A6A7B0B08465EF6 + 4: F5B3222C, 1C424282D7FB427E55285E20FC2ABFF9 + 5: 3A4A8361B2, BD40E631B054F280C7973E5AB3F06B42 + 6: A475866BF2C5, 2067F42FAAA6274270CF9E65D833FDED + 7: 689D0D407172C8, 3BCCFFC64E56D5B753352E1DDD5CCAA3 + 8: D9CE4B051202A1D3, 79B0CCDA3D0B9C9BCF640BC9E6D9CE0D + 9: 0317D68BE098D276B7, AF35043DB6213DC5D4F3DFB8E29EE537 + 10: 154CEF0C6F37AA0A73C4, 61E598A8C6D17B639F9E27AF55DD00F3 + 11: C3DB1B2B6CCC9170B9C05F, 966871DDD6E110711FB9DD733B6B2B3A + 12: E4F22383C75BC0FB0E59C5E8, 971536AF878F4EED68F59046C928EAC8 + 13: 2FBFB99AABC6209FB8664916DD, 68D0BF2144AD1ADECC4074DAE58540C2 + 14: 5FEEDFD09BF89719A34CDCCD2AAA, 64DEB7D5E6891103AA54C0EB366715D0 + 15: E063A076E0C770FB010D26C3AC3EB5, 0CA321B2A7448FEEF84D4E0AD5BA2DA4 + 16: AFB0DB9959F0906BD346C2D81DC5412C, 425627895E2C4C9546D3227975585459 + 17: 79179C0D4D6C5E0741DD4CA1E8CF28C75C, D0188A344A1CEE52272FE6368DB0FB75 + 18: 8A75521139B0DE3C08C9EAEB77D8018A39FE, 47FCC200D8A384320D2F1A5E803A9991 + 19: 0399381D0A975AE3980A9FB75B991C055AF367, 034915370AF94B96A8A4E50FF9B134CC + 20: 8C189094DB13FBE62EA5C4A53C29A428ED587BA2, 99C58F838423033298897841ED526347 + 21: D91F5144B525AF5D47EF4D5F0AF9915447A55927F9, F6750BF7E089515D35B47BC1C65E2E3A + 22: A4E26B554AA277057A5FE3FA08A6138CEEC6D69BB1D8, 7BBEBF52D8251108C7AA1025E213EC44 + 23: 5C1A8C3A46FCA90D73675706313CADFBB90A535A4B3D5A, E35244A2633478BBDAFCC81161F28B80 + 24: D69F7264FC594057B89181B83582D799AE54E9EE4FE8AD48, D4B29E5C25F9477D9345526DBDE9372A + 25: AFD322D0AC4AF38D5B9CBE0DFE85618C001A7A77CD8FFFCB3E, AD06BB9C59D23D258D6A2AEDD946AA20 + 26: 179CA8395CD8E75B4E5EA07D25C8036AF08B1A1C330492523D36, E3704C4341A834C087500E332B7DEAE9 + 27: B9178EF7774684F43F1FCE99A4319B5A4D167B0A848551F562CD7C, 5D5082FB02B9B494D5883DF49DB3B84B + 28: 830FCD15A09EC61245D7DA258E308E76D3B542F2345DBFC11AE983A3, F50C3332F8D91911BDACCFE228565E5C + 29: 179619B8C7EE9B3121405BBED2AC102A027E6C97EAEDB5ECFEB13792EF, 859EBA3BADCE6E5AB271A261B26DE28C + 30: 14264C7E0A154119BF24B7FCF434E81440D42D54738F0BAE55836849AB85, 0B6C9B9CADB1B6EC71CEA090C8C72834 + 31: 0D7A316F8B873F62CF26CFC569179AB11CBF09D3467936A85ADC265B2C9A8F, 866AE7C51EC2D9DEB32748A1C8B61143 + 32: F8FD1F967CD3632805AD7FA8ECB40F530927DD5C49D31FDBAE49738E2315905D, 9CB1CB84A727C9F42555EB566E0A1DEE + +GCM-safer+ (16 byte key) + 0: , F769B436C7FB7C0C822E24BB2B2555D3 + 1: CA, B156298625F5634FA012B23044437807 + 2: 4960, A64C73E890F3D77B2C3B3C76C2D913C6 + 3: DBBB8D, 686651A017F89A22F9FE96533C85C52C + 4: 150AD99A, 177F7DE9E897DACCAB7EACEE3CDE7601 + 5: 077055065F, 48B4309C76CAC37BDF11842311BA6CD3 + 6: B2F8CE062C06, ED04DF96C06959524956E8AC5C338457 + 7: DCE718211410D8, 3F8D8180BDEAC2F018EA81615177CC8F + 8: 0F71E2772402AC83, 2130481B2CA7B4B4C8F3EE73B3B3C28F + 9: B69030734E5ADF753C, 8CC4B62BFBC3EA56CCDBF0ED318C784D + 10: 6B8A91ABC1BF2F2D0176, 86EAAD80D148A48086987A40A5631DEF + 11: 44AD00799EC8E62E34D6A1, 016830D58F06F75E54531B45D9E785F9 + 12: 0C4B9381D78E0F0A78B3CEAA, 4A79C58DAB131A22F172F9177DC4158B + 13: 2C56D4625876524B4D8D5F079B, 7B407F704225B25F1F136C984E564147 + 14: 36424D69BACC56407D345B3D7B4D, EB126C255A2DCFD32F69DD5CB61876C7 + 15: FDD3E091C0420D1A4D4A848757FCC2, D319C5C07134D67BA42A4BF312CD874D + 16: EFAF6F117EA9A4B4B83052BBF5A07DB9, BB09D473FE82257146E7ABC2EFF6F631 + 17: 19B71383C414BAC3EF252FFF09F5ACD777, 526DC9AE6895ED33A34A9A4ADB07E1B6 + 18: 9AB6DFDB930D26E00B3D98DD5AD014E08756, D70B95B20C106A5A03F9B803D2CAC3A0 + 19: EEB3C236C3031DE4C3F94BD746677AE84B271D, 9483BBCBBFDBA1CC5F6392DABA2ACC19 + 20: 3A0EBC7536F8717E8FDAFEDAC39E8F1F43C0627A, 3DA7DC2475466CEDF01EB543870A74FA + 21: 79D28D2F149E1D97E910342DF383FCEECF5AFD4C6A, 2364F33BCF6F07E381F7E26DAF802D83 + 22: F1D7C319BAFB740332CA19AB0C9B71728D3AE69BFAC2, 3D4AEE9780A5C98CBC69606CDDDB31F8 + 23: 1A0D80381A186673FB7B52C40AB6C46A11AB0889333C20, AF5C17E3D0D9724EDC1FC438A16B4EBB + 24: 5E503440B22DD6AE6401BA4355C8791BACC598C9E0F1412E, 156D8221BD61F5C108FC18FB2F50D159 + 25: 7784EFDC6F0FC56FCADAFF17BB52DEB35B64FA19C3F391BDFD, A291E8238EF158A2379692077F70E8D0 + 26: 184B6E18032D1A70CE5027912E447C357C72EEF7B20EF0FB256C, 0FA0138FB9480E0C4C237BF5D6099777 + 27: 7AC8FCB64F35B71C5ED0CCD776B1FF76CE352EB57244085ED34FE8, D995B3C1350CC777878108640C1CADAE + 28: 86C7A01FB2262A8E37FF38CC99BF3EFAEB8B36166D24913BDD3B91DA, 25EC6D9F69168C5FA32C39631B606B55 + 29: 91F5D3E3FE0B1976E2915B8DA3E785F4D55768FD727AEF19FA1552F506, AF902DED55E386F0FC4210C97DB9446E + 30: 7ABF5BD9CB2EFF8382C6D2B28C1B0B25540E434123AC252046BDDA74DA32, 713259EDDA9B1B63EB68E0283D0259DB + 31: 5634B23ACEF2874BE0591BE3268C4538698FF2D93D59B39BC86D0137DACBAD, C4054796AFD335B43C60E7E634122BAF + 32: F26C68C36B1E56449595EA4E162391E0C6A306592949F69797B6C2327E533ADB, 7B392AF776A94983078814B6B8428BFE + +GCM-twofish (16 byte key) + 0: , 6275E8CA35B36C108AD6D5F84F0CC5A3 + 1: 38, A714210792F9ED12A28F25CAE3B3BC5E + 2: 8E2F, 6357C1F125723F2244DAF344CDFCD47B + 3: 900A4C, ED4E0B318346D5B9B646441E946204E9 + 4: 087EAFF8, B871ED95C873F1EFA24EF8B6915F447D + 5: 63FC9EFBD4, 650D0ED98CBECA07040AB97B97129360 + 6: B6081E94AA19, 6A3BDA8030C5A79B6B9087555A1DA67B + 7: E10A7B9CBB20C2, 59EB55DFD0A37C55A869834E597373AF + 8: 94E947FEE05780EE, 354918527F855264E37DB6892E868050 + 9: 9A80C567AA50220862, 814EE57CC9D51D7D900AB4840C4B072F + 10: A8741BE1E42BE207C416, 2B28AFD8ABE20664D8BAD7535F82F11A + 11: 6AB7E3C68B6682023E8190, 5E48B67541FE83969952394F84D29E93 + 12: 4F66FB634EB258CEE2955D84, F2632C2135B6E1144673B0EF73499818 + 13: B29042F3877C2F5E694953C5F6, 03268A30499D57A06AA873EF00160C3C + 14: DCC7B5D9F58C88F54A9611389B8D, 5515426FF7CF2EEA91BE2B3752371CE0 + 15: B665488BCD75FC02A0DF7994B7CF98, B721531E2A317C254FA2ED306ADCF96C + 16: 9535DC8A72645E34F948B71A5159AA9B, 5CEED93DE128044F0471C65AA8F21D29 + 17: 5CBFC61A23D28562FCA929375E5B585327, 3AA842B21631968D1B58B72FEE090EE1 + 18: 2AC3F780B956A933C0B8565EE527173B8CC8, 16EC4B6D8E2CF3CD0D16E7A5F401C78E + 19: 5067FD65870A4EBF6C7FA811A15270E7F8F17D, 9A7563BEDADFA6B6E48F5C13FCEAED6E + 20: E3A65A188077E5DC171CFF30BE8B27F10F015166, BD5B3D84D0C1DD51A3909F849141B57F + 21: 88D0A65C105823E68BE3987CB205AE0C1A27588FCD, B280221AD0BD83E1D6B37F331F326AB5 + 22: 7C56D987FEF6807EEFAFD4C7EB9D72AA0E037979D91E, 686E1268A8DC9CD0192A383EA6C2D975 + 23: B23CCD0A076CB122750B634B9E6551E0585EDEA18C3245, 6DF30A7F0728E2D549AA411AE375E569 + 24: 767BC3AF206E67C9E27A4D7E814F3B3A65D27BB70BA9DD4D, AB2B16C031FB2C8E85B3B2B38A5CBA4E + 25: 9ABF34ABD43705D62F377449461C5DC239A2A86E5A98AFB159, 3DEDEDA85E6BFB53C6F18726CD561604 + 26: FE756344C05CB12AA0673F1C2069A86556E583FF4B7313A0D395, 21CB0E0BABC3C7E547F5CB207295C0EE + 27: B70F16AD19A6B0AF6D8DBF4E98D7D5ADB944D91BD889D9390C3E21, 2AE67812A22C1C785D3BFC184A1C74EA + 28: A6389032AA9D08BDBAAA5E230E5130665FB4F0CB868F3F20C4C5438B, ECA054EFA3F39400A587839C4F0605C7 + 29: A55A41315EAF3A67A0FD0E14C6E04D03A5E38D0F756719F4A0800B290A, 7A5277809D4B65E663603099B4DFFBD8 + 30: E739633579AA6201A024B9873F28412BB08B08B8616D611BC9D07979BD3A, 390038A93AFD326C5CC1525A24CA91AD + 31: ED3266F8B0DAA7C3DB7814427E8139831CFC0EDE668F0DA83FF7090154410D, DE440EC2C6080048BFF3C5455E1BB33F + 32: 4D0F751B55DA3A2E0B28DE59E9680669FCB5984E9C0DB942DBAACDDEF0879731, 62F96CFE31D3D6AAA0B9F5130ED1B21B + +GCM-noekeon (16 byte key) + 0: , EB5A8E30D5C16311864E2D8D32859ACB + 1: 88, EAB88DE1EB7BC784A706B2D7946798D7 + 2: BA1F, DC3CEC6AA324AC7D053EFF7A99AD3069 + 3: 9A1457, 4AB65831DE378DFF71C20249C7BEC05E + 4: 2F9496D6, 800745CF95EAE3A698EDF9EC949D92B7 + 5: 84153177A2, F6A05B654435ABDF5F696C0E0588CB5C + 6: F80B7865C766, 2334D0061FD488D15A6AC8E44EA1F4B9 + 7: 872EA486B4EA9D, 3A49671DE347F675AD7904DDF4255F3D + 8: A4EE5750507FC831, 956D09F7C5FE812C6FB982E1DDBE864A + 9: B5874AC964FBFC1A97, 90FBC75F45BFF58B3A1100393955D0C2 + 10: 92FF5FCF1EC675E02E71, 983C96A7BD4A0DB5D3B877911CE8A6B3 + 11: F7BCA69A9C7033D84A2BA0, D4ECE5BB9FFCBB331A646D9CE8078634 + 12: 5E1041B4554C8CDD14AAF16D, 1EF777F307CB96788B9120FFF8A8BC2F + 13: 7BB7289FCAD209D7992EB7AEDC, E8AEFB830DBAED2B4A790FFEF940A20B + 14: 12776A7C937A648F0A8628AD8C5C, F070283852AC030819EA67BF82C719AA + 15: 7293476D9E935EAE9DEB66F697F662, D6322603671153A1EC1453CDA5978E15 + 16: DC12A86C85E7358919BABB15A3BF5FD7, BBBFA467EBA8124DFEC82DB0137D56B9 + 17: 0CC1DAD00A987F9C57E3660D9417F226E5, BB8AF5A0B5BC79BD11C5D41CA80CDE2C + 18: D0049115D6EB5495FB391CDC494022AEAA48, 682FF357B2BC059765C29AE6CA668D0C + 19: 48FC54A401B4C06CE8567AD298B672191C7E84, 493A4AF4C2A8828FED8442C4EFF877F6 + 20: 90779795821CB1B7DBD97028E29DC1CE7D0CFAE0, E126F485F73B6F7B3894B4CF7E1C5DDE + 21: 8CA5C246C8B7C04BD7171CAE2D1A892D66302433F8, 5D73149A3635A86B3C34DEA5B95CCBCB + 22: DF082B665F7A952B2604C04554B81393FCC7C0B816C8, D3569ED7D431176B286EF22414E4CBA8 + 23: 761908530C9069E189649ED24B6A68A89B067C31E9868C, A258BCD83D3FBC7AE2AEF7516025AB36 + 24: 717048F5A31F3C89D3704F90069AC5D5174118770C65BDA1, 067EBF18F7E3DF4EA13F9ABAC682C2A2 + 25: 08C6FCC5D3099347C3FEBA3858A6C22C51298CB591DDB77827, B57BFBA40BE99DF5031918A1A4E2CA80 + 26: 2CC53EF7EB954234E64CD4D60FB1D7157A489ABABC10900FFCDB, 236E769611D16EB7F463B7578770F886 + 27: 2556B46F2E831223D632F2691329A874F517687AF81B8322AC55D7, E213A90DBC31DC261A45A9AE41CFEEC3 + 28: 71241792728594D69791B80AD6DBC6417D1D14D222DF5E6F834B82C8, 601F97617708B1945BCDA8A82496EFB1 + 29: 5003DC2EAAA23F9E2221CCBB9E20116692CCC99B3CFBD0DDD3A8491E7C, 3743155B792012845550205C8949B73E + 30: D0589675357E850333F854FBA160688F06D122DEC00CC2620DA0B2770765, 20E085752FC4D37791C22501ED1DB6AD + 31: 645B46D2D114EE7329F14AC1D94E6817EB385EB80C61F014F90530749079EC, 8A18DE86F9555A1070D0BFEDAC15B14F + 32: 068389206D37BF5A41C58075FC98901C3B42E6F2F13C09F4E92524021BB1C1C8, 370B86914D63CFEE8303D538A6BEA0E7 + +GCM-anubis (16 byte key) + 0: , A0061C2F3B2295BFA33BC74C037EA8DA + 1: ED, 9E5648DCE40DE37B56C557D26CB18D83 + 2: 6719, A6605253C59A101FF85C5102CE92BE45 + 3: B8873D, 13F3E3ED3646BB296EE4ED5D6379A21B + 4: 5AA6E2CB, 1812E8385D15B5BAE043E4E860BEF490 + 5: 4F6F4CD8E9, 8A80BC5E08929C42A5A74C5D9ACC0C6D + 6: 2F0D8B483CE4, 316F588F78FC6A9196C97CE59B9B63B6 + 7: 82D885FDE1F948, 7160BF556614511F53738A92B5277056 + 8: E4931462AD41B6DC, 7CE24C4D6B499975FCB72B5E2275ED56 + 9: 503AA70BE698BC5B41, 10EA0C61FDBA8FF7B4E9927BCCEFD911 + 10: 6B2D213D14B5D25EBE36, DC3222AED12EE26D3D14E2E733EDB2A7 + 11: 7D8B0BC1B7443E7267371E, FCACFC73E391865BE86E041F51C45E81 + 12: 9EF3BF8609E133BEB10565AF, D84326D4CAC9D5B74FCFD8CBAFE79E77 + 13: 59AE7B1FDE1178CEE7F63C4894, E1BCFCDCA86CAB9C684F7D21962D580D + 14: 564E7B8BAC5582A3BF1178916569, 54804D8DF4D7577EF65C15487695F840 + 15: 758A6DC437C8821274B0F16F911BAA, 19DD27500915F425F34F67CC2374DC36 + 16: 0468C94A88A27AEEE2B3A973065E53CC, C743996C6F49363B2F4613F24703EF7E + 17: 3B0CABA5EEE44B7BFF0D726ECED54763FF, 14D9D09815BCD91DCCE2F5AE1A9929CF + 18: 5B945D83B98C43B0248F9BC0479E332869AB, 67A275F0313D4245B1965411CFCC8F17 + 19: 97332441CA96DE8553A3C6D898FC6D90C86DBF, 73150EC3D6327E3FC8015A6192652D3B + 20: B9A1778FAF9767160D0D87816ECE1B99AA727087, 0C173D3C4078392CE377313C48D2BAE8 + 21: 5882B73911C7D26EFDCCA3AED2EDC8A8BFFE75B1F8, 8F8C535639A0B59537E590C7FC9D2E53 + 22: 70AEBED8CCFFF6E5CF06F3E841D12387EF8D6C7B4BDE, 4B00C27FCA9BEB82331CC8EB13DCC580 + 23: 345CCB52BC20DC5F1BF5EEDF5D72A6C48F402557FFD342, 1A790A39573B853DBB8E2E73B7331014 + 24: 0637C78A817E91D63CE18CEAF8D65C6107283A90C5A97842, 52786CB81724E12C76A0D23D4680E36B + 25: 59526D1E86A473DFB720FF25E97D6571077845F73C5E8322F1, 369FBA7823FC83D727FFD25D10130987 + 26: 2933BB4E7603C313B62332827601F8189E14C1F08EA547E15AB5, 204520E365DAFF6551B01562A4CEFDFB + 27: A4098CF2A48A1DC2BCCE65CCE8DF825AF51E7E5F94B6186FF85D77, 9833EBB9A1D5CD0356E023E2C3761C2B + 28: 26557B942FD6913D806672EB01526DBD5D6F532F78AB6759DE3415C5, EDAACDD101BC40EE6530D8B5DC031F31 + 29: DB92C3D77DF0C8F4C98845AA9AD43FB800192E57A53E083862B7E3FAF0, 628DEB1E345303A40700289052080FF8 + 30: FC57BFAC2C77781723C2B721886D44ED67A52D9AD827874BC4EEC0A97281, 9A222DBC47B4AB4E520D3CC5850D4DEF + 31: 72DFB9E91A78EAFE758B4542206A4A957B4523A58428398C11BCF2AEAE1938, 307D0B876130E82804C1167E03B69B2F + 32: 7275C6EBDC2680DFCB73326A987D2FBCE83E40A9AEFE6351CFDA7251A6FE10A6, 895E6EEAA9BD88594903325A063CA45F + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/notes/hash_tv.txt b/xmhf-64/xmhf/third-party/libtomcrypt/notes/hash_tv.txt new file mode 100644 index 0000000000..4f2714d30b --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/notes/hash_tv.txt @@ -0,0 +1,1771 @@ +Hash Test Vectors: + +These are the hashes of nn bytes '00 01 02 03 .. (nn-1)' + +Hash: tiger + 0: 3293AC630C13F0245F92BBB1766E16167A4E58492DDE73F3 + 1: 5D9ED00A030E638BDB753A6A24FB900E5A63B8E73E6C25B6 + 2: 65B0E1EA36CA17EDE2F055E67EAD67B1C282A11A5BA3A8E0 + 3: AB7FB8D21CE3D8D9BB5F1AF1F2FA0D3C277906160DB8D226 + 4: FE2E9D43F74B199D91B9291D73CCFCA0BEA5F068FBA244FF + 5: 3DF6D672FE9DAAB21523EB04705D8A8B72B78B00AD465D1C + 6: E05724353FE29957C3E8DEBAA21D0C2DD49CCA22191D5AD3 + 7: 4056DDBF82AE74AB56720DEAF079ACA2F076ED046D044DE5 + 8: 801FB9BE1A9AC7337A81345B3845E4E7C13AF1FBADB73723 + 9: 430156547A82492CA859385304748F65F2D4A7E2664AE2B1 + 10: FC435137CD652D720A11EDF47ABE4680BA4AD5BD810C9835 + 11: 20A8143DF47F5715FA0905FE6F9D1D2B5B2D4E26FA98930B + 12: E4A2063019FBC034DEB01E2A95296042319CBC039DA69A91 + 13: B5F0FA570C4CD69A3C68448BE42C865BDF77ED68B93875E7 + 14: 802BE6EA2CE86A0B371F2354944B19CB3231AF7FB4F00FF8 + 15: D7C08863B5E5E3D69B5404A116315A698E128EBAF8636B70 + 16: 5C5288CB0E4E533056BA5293440D9BE6F3C461233BF1ED51 + 17: 88D3A94F3820E4087DA69D8BBE2CF415466063709C450C4D + 18: C07B4B155F9F75805D9D087087FCDD28D08A9D022192447E + 19: EE473E569FF3E092CF8996B31CE665EA7D61520D42E27395 + 20: E13DAE8098139CFCEA755D2060F107E3C7581EDF9F4B3B85 + 21: B48A9C09F26B379AA28FBC750B50CEF69D0D0EE37FF765F7 + 22: 574A01456373014F4179CDA14541E2E3C5A1CDDA9F9D071C + 23: F2E2831E5BB4AF05914C4BA61BB8D600D1EF071C5DF02269 + 24: B7808A5B6258CBE718EDA938978C69D3FFC45A222E9DBF4C + 25: D8E4E076DDE78950D51EAC9F97D2D1916A0910465D45A55C + 26: 4EDECFAAE1DE98B7E056E64CA24003422BBE6F048129B24C + 27: 0DE283B5A4953EAAEC6F3FDE50D7875C8EE57FA79BDC70FC + 28: ECDD4BA1936DB9E6F83E2BD7F39D23927A1A17B2D52A8649 + 29: BE11893460E49659F7DF3FB3BD5E3E9A319F85FD3496E26C + 30: AEC0DA0F2CC0646325CC03319A0E080F68B46B33F81920D6 + 31: 8824FD39984F6A52FFFF19016E27C594921452086373F2EE + 32: 8B6592AFBB02E227AA451B5CFDC821B84245D34B96BF4F13 + 33: 960DF9C349EC6619FF37E3F0F4832E19CC6A4E4D68962651 + 34: F4E2B7AA72BC7D6E0CF6DA1094BEEFAA9C55610327C62900 + 35: 05FD1B80CA4C7C14FE5BF0ACBD0EA3DAE498DC391DCF2277 + 36: C5E95F953898C68355B591507BB714F0E5DAB9989D083900 + 37: B2D4E286CF7EA8AB6ECD650C9E48CA23497EADE55485DB1E + 38: 9D51657E11C54FFDF205DBB435097A2BC6F93C4BE8D6180B + 39: 3C6AE3911356A343AE3113735F07FCFB5E046ACD47B00FBB + 40: 664342CDECC825ED340A7FFE2E57107DD0B5F24C24B2C3F0 + 41: 4EF7FCA13CE684D81DE4F566D2897CEB407FBB3DDE81FD64 + 42: 54689FECED63F297B13CD494B85E686680F4F78DE7EC81D5 + 43: AF434BDBDC7EF90BE03E40A033F16E8A57B41840E1E8AB59 + 44: A32DB678F44905C18968F5D898CA7992EBE2E4CC3318B96C + 45: DEE9D519A12ACFB8A0935A368D6E6C75EEEEE6F2B0D5D191 + 46: CBC74863472D1C9D23C526F4908BD4D4234E00CBCC99A9E9 + 47: 6C228A1D4871E802E035C9BB16C5187354841FB6BE3C69B6 + 48: CAA755C55AA869E633CB3C6D93A561944AC7418154E2B0F0 + 49: A6835F7C0C6CA8F4A45787BAFA77478AE9ADDBEFBC3052D3 + 50: E406755957EC21BA6A64B5D3AAF31749CF98DF92F1B1FFE0 + 51: 0C2D4A44A803DBA99B7A467553C9293B46A538558BD77DD4 + 52: F04F011B09D275A185528CC040EB719649C8471A87B259B3 + 53: 3DA8B57FF52FCAE7C32636EC6C80708189CED8113C5CDE1E + 54: 6C6C88B8E18DF5CB22EDB61A2D3ED74741A708BC46576FB7 + 55: 2D48EE2BF85DE234754BECF3C6F5B0E62988B5BF24AEA5BB + 56: 0D17702DDCA078ED1CC51B95DF29EA1053CE97F69395C613 + 57: 9D8C2AD327DE43D5782D5F20881F4A8C433BA19AFC8C15AD + 58: 227BA419B760D9D10DBB09585EDD475AC2734FD4539F8275 + 59: 2F5220A828EF94E327BD51D4DF5C58609F8A93B9FE01FFF6 + 60: 0EED9F91E1A33A50B8E913DBA0B5E248D263E1FC72C6A449 + 61: 766B707E999FF3C51EE01168513BA0DCEFEAB222DD1F69F6 + 62: 85E6710694E7C36A2340DA6A371C0560450F3D44D35AD98C + 63: D401F9B13D39C24477C0AE6971C705C63C067F29508C29C9 + 64: 212DF89C57155270344ACCB19027B0B26B104FA0FBBE0FE4 + 65: 3BEDE767AA4A7507DBEFF83D1BC33F67EBA9C64945066227 + 66: 79FED1FB9F17C4980108E8605C10D9E176AC8FE4F6A65064 + 67: 48D9B7622AB7F8968ED926255F78E8CE461E4C9162FFE8B7 + 68: 6638C83837297B3F53B0F824C087D9A0B8D9FC6265683B8F + 69: 174421CF6D331FF51924F8946E8244555C9020D38E31B6DB + 70: 03E42AFB5FFF9B9C3794A3DBEC99FA7E3F7305EF07BD29EF + 71: CCAFC68D4B3ED889DC9F28CB9225808A40AA8E0D5CA343FF + 72: E824F93B4022011886EFC54539D4D5D51863ADA329FB4E22 + 73: 7CF0DC01B326687530F42040BA0D0CE93174455E8A990D14 + 74: 7A8E619479F4F5C418EC041806850E6723CA56AFBC3D32CC + 75: 083C5CA90F4B296C42040559C8296149D4EEBAB5EF2CB82D + 76: 3581B7AC32FA8A0986FD14F277FB106E112B92D18CD689BD + 77: 258E822D9CC1ECA8B55D925BA361BA2D9FC27AF181F138B4 + 78: A86C1E88A64515FA281A462D467458231494F16E835DF873 + 79: 76E7F06FE9B8B388DB012F8B4BE2FB343F95913EDDE47A27 + 80: 00278B4E5690E729EC7118B5BF63C9D1EB1268960893CA75 + 81: 8DE70E64A31BA1AF4F5C23CF774CCA32FE952D76C3FDD1B7 + 82: BBEA72C840749BABAF1415FEAC343411B89515B87848A09A + 83: C6C3CCAC1B338DF117A61ECF9A280E9BA709784C72B76771 + 84: AE9813EF4429EAE73EA9FDB5E23D263AF1BB87928CF5F048 + 85: 68647CD7BFFB8E530D28C86685A8D2F657EE4CD64EDD7E66 + 86: AA8C35B0E746AF56435F6C711AD0423966EA459087409713 + 87: AAD5C0D5E980B29BC88985C544717B81F58CDB923A3468E0 + 88: F60929D14781DE44EA607AAFC0D25FA1B6EF3C6AA0F8B3D7 + 89: C48087DC75EC43A54A593F24E1B359BB75C581A65C3170D0 + 90: 11D1372FBDFD9FF514611AB20D31BA62F18856C8D6AE3AD7 + 91: F2A8076B9017EDADEED41F409C9E32EB3BC090EAE89F855D + 92: 702FA47E5BD35E344B5B87C0082106337206CADD3D4D5014 + 93: B9E03FED752A560C3B0365EDF5BFC4DC7EAC5E4BBB93738D + 94: 3C84C52BF51077A5819F56E5A5C1C06209181579393220C7 + 95: F8ECCA28A525594E138B55C06617A063DF74FE3469D98381 + 96: 1081C3BAEEC0ADF4980C2EA6593B0906DCBEDE4805754774 + 97: B5152E39DE0BFE8982D783FC4F0CB7160EB2D69F6F3B3E5B + 98: 6A6B760BFB1965C72AC793F9C02FA21B0F1C34BD2640BB6B + 99: 1E6DCBFA8BA8D96C29101768A6A39433D5AD5A50E0970730 +100: 733222D3A033351FAFD68C5CE8A4D833BA7420D44103CB6B +101: E4CD7DA59B215F1DEAA8FBBA850F2C1A7F4C3D495FE6804A +102: 7BE78C790713545754D4C78A9318ACA4AA058C5C23540131 +103: B71C3809A504BE2F57AE9E25BDCC3921DC665C65289EA55A +104: 2B8CA39977535EB692EFBF0DECDA8971A8604F7FCBAE75DD +105: 3CC48B51E4C5DE4F0C2ABE0BE6EE4B63CC564A87C01943CD +106: 157ACDF7B59FC25966F9783207554364882840E7251ED6C1 +107: DEA1CFAECF18D3611CCD0517131A16DDBC97A12902DD8BAB +108: 2AD2E990BCF6481284DF44B961632687C2E64DFAE2AE16C2 +109: 838F3A3B28A50A12B5707490A66080DCFA0230E583B6EB14 +110: C8B20315121CDFB3A91BC0EDF11886F283CF6C480F498627 +111: 2B0FB04F100BE9AD51B7D64C76651BAB4B7D31D1D9195711 +112: B6495B6256FF464EC409A4098B622E8BDBB1003411854FD7 +113: 1741A789472E20E1CC89869A2477E4F2807C22182EA5B221 +114: 07ADC82CB3F27389A12B6B9C2B268BDDFD1D9478D9EDA0D7 +115: D9BD6760FB819A8A3CEE75303F8208FCA3E138B517DAB934 +116: 9FCF21A9236C2C12861FD20F1FB15A187CD7EE7821F72BE7 +117: 73D165769B34DA6F151464E61115D0E09A66F8D0FA049726 +118: 74580BFA88EEA03C0EAE722F81997E400D9CC25FA0311DFA +119: E3C6A369820E267C938D276A858928040C7C25A826501DC7 +120: C20AD90DB0B8BEE0335D069259991060969EEC9F939E4CA7 +121: F3746F4CD6A19CC137C5FCC8F60A4C0A7F56D97190B7A9C2 +122: 63A3B79EAF3DF35180960465059C0ADEE06D45179A56284F +123: 606AFD833D082628D58672403EE6DB348E6F68D8CD1947F8 +124: 7567EA8E10CBF312F8478B7C51D87B00B6CF3DE82B03DCE7 +125: DBCDC2B9B8589F6C7616B55B059B3B3E38D97A9E6DF1F29A +126: 15D9909F8D69689E7E78A0DB928194A59623E7253AA9D400 +127: DE39589DCC0C654867943801946B9888B347526279CA15BD +128: 34FA7C74EE67C1F92C0BE1CFD4B2F46A14FFB999604925F6 + +Hash: md2 + 0: 8350E5A3E24C153DF2275C9F80692773 + 1: EE8DBAE3BC62BDC94EA63F69C1BC26C9 + 2: 1EAA4F494D81BC570FED4440EF3AC1C3 + 3: 54CDB6D1BF893171E7814DB84DF63A3A + 4: F71A82F8083CD9ABA3D0D651E2577EDA + 5: 2F708334DBD1FE8F71CEE77E54B470F9 + 6: E014DF2DF43498495056E7A437476A34 + 7: 9C410644446400B0F2C1B4697C443E19 + 8: 0944DEC40367AC855117012204018C9F + 9: CE8A6E797AC79D82D2C6D151F740CB33 + 10: 06DB4C310570268754114F747E1F0946 + 11: 9F323D5FC6DA86307BEBC0371A733787 + 12: 3C1C7E741794D3D4022DE17FCE72B283 + 13: 035D71AA96F782A9EB8D431E431672EE + 14: 7ABE4067ED6CA42C79B542829434559C + 15: 5E8D0D6F6F8E07C226AE9DD32609035A + 16: 2B1632FF487D6C98AA3773B9D3FCD2AB + 17: D3D894482F7541BC0948B19842B479D9 + 18: CFE6B872AC98304524CC6A88B6C45881 + 19: 1573DD015C8629DE9664CA0721473888 + 20: ACFE2D3BB3CCAD8AEF6E37D0D8FBD634 + 21: F5F83499AA172BE8344F7F39BA708AAA + 22: 1D1C71FF6321B685D26F7FA620DA6C22 + 23: 4D7E74B6C8321775A34F7EFF38AAE5DF + 24: 351A988C86AC5A10D0AB8E9071795181 + 25: 970F511C12E9CCD526EFF8574CF1467F + 26: 0A68F53A476F7499EF79278A4EE8DAA3 + 27: D458CF9C8CD0ABA23BD9A8C5ABE495CE + 28: C8002E85C3AD9B8B4AFD23378165C54B + 29: 0B4788B157ED150A34D0E6E96BB4789C + 30: B14F4E31DE09281E07248A17939BE5B9 + 31: 803EEB99231526D6A33C8D4FCA537A6F + 32: 51FE5D6637D2F0F09E48CE2A7F5030EA + +Hash: md4 + 0: 31D6CFE0D16AE931B73C59D7E0C089C0 + 1: 47C61A0FA8738BA77308A8A600F88E4B + 2: 9E7A1DDE4D280E7F389018A5CCC3ABF2 + 3: E9A4DB2923FAF634CBB12CC1F8AC5C66 + 4: DF8FA069C6121801FFC539DADD33FCB9 + 5: 4B3511308F7E71BF6462CF18F1184C61 + 6: 075582A51F87682919E733C84C9FD998 + 7: 20DDA7535A464D13E1763BA61BDC12AC + 8: 66AE1E305BED186780BB60328D3CCBC5 + 9: 503E90BF2375627262E58D90177220F8 + 10: AEC6B48C10659E3D6E18A2CDE8F8D3A0 + 11: 45EFB3704B6684B0750E3DEDBB2BCDA9 + 12: 7C9443DBCD858138E32604E0D288F7B8 + 13: 95E5B93F4EA79C082BA1745D3026D70A + 14: C913D5DE0BBD1C2F2838E46363732D97 + 15: ABE357BDC413C82C8BBAA380C39CB5F9 + 16: 22F840370EBB1DDBEA4FA3A40243391E + 17: 0A289FEC69AF967988FA40C47960060B + 18: B63D3ADF13B509C95C088F909A0B356E + 19: 36E8E07E3202E6F4F7E885853C9735C7 + 20: 1D363AFD1208A7B8BD486D51AEBFAEB8 + 21: 75E36A5445AD72CF5BF47301EBED1FDF + 22: DA7979688F48A6606D86C762DF0D8850 + 23: 6ACB325CE624372873CC01A4AA053F8E + 24: 94F9BFD6503DBDC58C163E33504B7EDB + 25: 3702CB296784290FC46B82445BF7EB17 + 26: 903510251E7A00415EA21B6AC268A92D + 27: 6DF08DB9C33C86CFE8DAF5E5BB865ECE + 28: C29C5223D89A6589DE9253AF050D3449 + 29: 16B935ACC3EC6C016CA1BBF727C272B9 + 30: 644C01B157A24584B02A32119A424C01 + 31: 4A3C6C73634759420C419426F7D43E67 + 32: 7BD627A6B82FF3D797FFF130D8956391 + 33: 811A69D6A8AFE3C4FE5B4EFD73804F6E + 34: 721BE5F4BDDED885BFF842868F62F4ED + 35: 76956871B22D5BECAD3E9A459B4A448B + 36: 4F2CF372771A13B4C0C1A589F0EDCF87 + 37: 084AFBAE8D22DF83CC760A61138E560A + 38: E1CA123EBA05CC4899731A593833F372 + 39: 9D9E277FA61993C018C1C61AE09588BC + 40: 85E0D0316F0B76578948810039EDE2BA + 41: 27736345D0F2B0A1A9576D17C47D0202 + 42: DC9F788BE7C97BB5E0D2DD49B9F1D2DC + 43: 27F1A9A0D166C495493877DF06E9C104 + 44: D1ACA7951866F58773CD4AFA3D2F5C2E + 45: 5204BE3729BD7D318EA8127BED82D5CC + 46: 10258B7939D81F5F8E0EA70EE6500B08 + 47: 4E699952169098ED3084DC2EEE7BC488 + 48: DF6ED8D604512088FCEAFB21808BF7D0 + 49: 904D0667C94C9C981D59BE80DEEEE628 + 50: D83483A47B64D74F9DED5278EE462404 + 51: 490EC8799A9DE3BDE8708DAF68E6888E + 52: 443E4D2D5F800C22D818927A29A38490 + 53: 48E82AA772E111FCBE393177F3123963 + 54: B72685D042162D5F30472281278C42F7 + 55: CC8A7F2BD608E3EEECB7F121D13BEA55 + 56: B8E94B6408BBFA6EC9805BF21BC05CBD + 57: 6AEC85410412FF54078A9FC72A55ACE5 + 58: 3E69F792BE88478883E46E867F3C93EB + 59: 3B057FC41BA700F0E46740B8FF391F52 + 60: 3E3C6DF9500BFF8404486A3AEFC6F16D + 61: F5AD65BA970ACBBB8335F9C0B9D7139F + 62: 75D45F8E48406E32ABF94D07FF9B9C84 + 63: 54BA4472FCD03E99CF28F90EED9F2AE0 + 64: 2DE6578F0E7898FA17ACD84B79685D3A + 65: 3A4F2CA37EEBDF6DC99A6155517B74FC + 66: E19DC463C01E1B712B9415202A2B5505 + 67: 61D8AA0838DEAEEADE2F26156AF58761 + 68: BE294AFF81BFEA3159564B8B61844EFE + 69: BB943319320EE7B3A029D7BCD101F92F + 70: 36239791A7BE33AD46F668B51D724481 + 71: 21DCC9A32031428B7B02F68E1450A0F3 + 72: 95C1B0832575E21982B17CCCCAF54556 + 73: 24939E25985A3B5620B19D7889E5E153 + 74: 3029C8B005386705FE7E4CBAA060E987 + 75: E8BD97C5C1A0CC9AD1F1BEB3913B22FF + 76: 808EBCA0B0E6FD1B30E4BA499C05EF9B + 77: 55BD20AB87DE2E536DDE22286D0922D9 + 78: 2B2E45FA5628F29DA06462378D17DD12 + 79: B90F1709241EF59F78666AEBB3D5607C + 80: 37854275343F079BCE1639C84D74AE1C + 81: 444AB5A4F39B765C5D67BB433D4CF0B1 + 82: 7E30CFA6363F9AC96607783710E151B9 + 83: 9D9252DFFB2D5023CFE34873EA6C43AE + 84: 49A70634AFCED27DC2DF2EB079F7A1E6 + 85: 4C976C9EF13716CCB468D82BD8C56FE2 + 86: 4EB382D16DDC18C31E6DBAC6CA83247D + 87: B16112D0FF3C6A8ADB19C13DF742F5D1 + 88: F703DC6100AE23D194E01EAC433CF28B + 89: A6527B1B907218063BF196AA91C73F47 + 90: 61F1A1E947F3F542FCF85AC758BA5D14 + 91: 12ADDEDCE418E9444AE34A40353ED0EB + 92: D1C35142C475D44A52CEB0A8FAEA7AAB + 93: 1F89912C1FC59AAB53C983B035661269 + 94: 2E7E19A4A6635AB5958DDA70B415EB06 + 95: B700B6739C0AF162D246AF07284A1AE8 + 96: E2B95AC9F876A38D33CCBBD7FA92D67E + 97: AEB4849953750A10BB236BAC8D5AB487 + 98: 82D738AF18FD4B26FFF61377EE921E62 + 99: 0E1451640E59CE0461A46934F174E237 +100: AE06EA64074E8C07116563E8E0893BDC +101: 562DCEB678FBFAB24141E591FFD471B1 +102: 7DD6C3C2884E483E8CA572C471B2D812 +103: 2A4C8E4EC2672C1D54A8DA8F32F04783 +104: 2BFED22E8810A4658060B95B0ADB60BC +105: 214D8F2DD099BAB68EC17189BFF8A8EF +106: 98E4EB29797C8E631CD4317AF422FB05 +107: 241A0F826F359A21CA0E6D9154D1E291 +108: A3398C0118A3605E7A7794B8DF7CA152 +109: 5B0A6FC8721F14EB8A03E9A5D87F173B +110: D93ABEC3EBD5672350C3C36F8FB00E53 +111: 659905751D1F614A78ECBB56D4398D06 +112: 594691B38126E028352DA5B28ADFD416 +113: 7533FBD1FD58C85D54A712EF218A9D53 +114: 654796E7D2F9F2C2D166F23B5AB18812 +115: 5D25B604FB75727AE7EBFF980F54D96A +116: 426A7709CD61EB6ECF4034EC83E073EC +117: 62E21CA2F8E39C03BFF56C8265ACB60A +118: B7C9DAAA89A29F2805DEDE790DCB9575 +119: 9C1067170940CE8F8E4745D362675FAB +120: C5BB35660E3D0A286A96EA3AA4922B3C +121: 8F3B6351623A0E482B57525474DC703A +122: CCC34CC280340681CA5117477DD86AE8 +123: 2F5FB6B41301F87A0490035DE4C1BB99 +124: A16E28DB3F331091E928F9AE3F1ACEB6 +125: 7D2259C98085B9BF7F5E36B29DF8384A +126: BDDA1266FF3E8FFBA1DE1B2759B58BCC +127: 2067886DA4BDE10A94B971CD740B0AAB +128: E1275970EB67D2D996E6E658270AA149 + +Hash: md5 + 0: D41D8CD98F00B204E9800998ECF8427E + 1: 93B885ADFE0DA089CDF634904FD59F71 + 2: 441077CC9E57554DD476BDFB8B8B8102 + 3: B95F67F61EBB03619622D798F45FC2D3 + 4: 37B59AFD592725F9305E484A5D7F5168 + 5: D05374DC381D9B52806446A71C8E79B1 + 6: D15AE53931880FD7B724DD7888B4B4ED + 7: 9AA461E1ECA4086F9230AA49C90B0C61 + 8: 3677509751CCF61539174D2B9635A7BF + 9: A6E7D3B46FDFAF0BDE2A1F832A00D2DE + 10: C56BD5480F6E5413CB62A0AD9666613A + 11: 5B86FA8AD8F4357EA417214182177BE8 + 12: 50A73D7013E9803E3B20888F8FCAFB15 + 13: B20D4797E23EEA3EA5778970D2E226F3 + 14: AA541E601B7B9DDD0504D19866350D4E + 15: 58B7CE493AC99C66058538DACB1E3C94 + 16: 1AC1EF01E96CAF1BE0D329331A4FC2A8 + 17: 1BDD36B0A024C90DB383512607293692 + 18: 633AB81AEA5942052B794524E1A28477 + 19: 2D325313EB5DF436C078435FA0F5EFF1 + 20: 1549D1AAE20214E065AB4B76AAAC89A8 + 21: 7E437C81824D3982E70C88B5DA8EA94B + 22: 2F5F7E7216832AE19C353023618A35A8 + 23: 6535E52506C27EAA1033891FF4F3A74E + 24: 8BD9C8EFBBAC58748951CA5A45CFD386 + 25: D983C63BF41853056787FE1BB764DBFF + 26: B4F24C1219FB00D081C4020C56263451 + 27: B0AE6708C5E1BE10668F57D3916CF423 + 28: BA7BB5AD4DBA5BDE028703007969CB25 + 29: EA880E16EAC1B1488AFF8A25D11D6271 + 30: C7172F0903C4919EB232F18AB7A30C42 + 31: E9E77893BA926E732F483282F416FFAC + 32: B4FFCB23737CEC315A4A4D1AA2A620CE + 33: 5506A276A0A9ACC3093F9169C73CF8C5 + 34: E5A849897D9CC0B25B286C1F0BFB50E3 + 35: F54FA30EA7B26D3E11C54D3C8451BCF0 + 36: 07602FE0229E486957081A49E3F06F83 + 37: 7C4BBA98253CA834BF9ED43FD8B2F959 + 38: CF8DF427548BBFDB1E11143FDF008B85 + 39: 1431A6895A8F435755395F9BA83E76BF + 40: 30DD5E4CAE35BA892CC66D7736723980 + 41: 8EE247A1063931BEDAF4C2FA3E4E261A + 42: C32CEEE2D2245DF8589F94FCDA0C9F2C + 43: F25FA0E071D1F1CDC6632C6B673BCCD5 + 44: 370491B643E97577F4F74BD88576D1EC + 45: B292BF16E3AAFAF41F19C921068214F8 + 46: 52921AAE5CCC9B6E8E45853419D0C80F + 47: F1375BE31969155EF76F04741CD861D7 + 48: 04605CA542B2D82B9886A4B4B9ACFB1C + 49: FA887BA0FA491FAAACBB82BC5FEFCD5B + 50: 06470E932AD7C7CEDF548B5CCB9D4806 + 51: AD130B245E2DD894267CB0DDC532D169 + 52: A9EEB95053682248608E97D79E89CA82 + 53: CC26A3DC608268B98ECD1F3946C4B718 + 54: 33DD62A2DF6538DAF1CF821D9CDE61F9 + 55: 6912EE65FFF2D9F9CE2508CDDF8BCDA0 + 56: 51FDD1ACDA72405DFDFA03FCB85896D7 + 57: 5320EF4C17EF34A0CF2DB763338D25EB + 58: 9F4F41B5CDE885F94CFC0E06E78F929D + 59: E39965BC00ECACD90FD875F77EFF499A + 60: 63ED72093AE09E2C8553EE069E63D702 + 61: 0D08FC14AC5BAA37792377355DBAD0AE + 62: F3CDFFE2E160A061754A06DAFCFD688B + 63: 48A6295221902E8E0938F773A7185E72 + 64: B2D3F56BC197FD985D5965079B5E7148 + 65: 8BD7053801C768420FAF816FADBA971C + 66: E58B3261A467F02BA51B215C013DF4C3 + 67: 73062234B55754C3383480D5EF70DCE5 + 68: F752EBD79A813EF27C35BED69E2EE69F + 69: 10907846EB89EF5DC5D4935A09DAD0E7 + 70: 5F1F5F64B84400FB9AD6D8ECD9C142A0 + 71: 3157D7BB98A202B50CF0C437AA216C39 + 72: 70E7ADE70281B0AFCB1D4ED13EFC2E25 + 73: 0BB96A503B1626C9AB16C1291C663E75 + 74: 5BED4126B3C973F685FCF92A738D4DAB + 75: 7523C240F2A44E86DD22504CA49F098D + 76: 6710949ED8AE17C44FB77496BEDCB2AB + 77: 4A4C43373B9E40035E6E40CBA227CE0B + 78: 91977CBCC32CDEAEC7A0FA24BB948D6A + 79: A6A0F1373CF3DBEE116DF2738D6F544D + 80: 761F6D007F6E5C64C8D161A5CED4E0AA + 81: D44EA4D5A7074B88883A82F2B4CFBE67 + 82: 3097EDA5666E2B2723E8949FCFF2F244 + 83: AB247A3D9BC600F594D5A6C50B80583F + 84: B229430E3DB2DFDD13AA1DA1BAC14D5C + 85: BEFEF62987C6DCDF24FEBD0BB7CD3678 + 86: BFC3E5C7C461500FF085A66548378E0E + 87: A5712194537C75F0DD5A5AB3E9EBAF03 + 88: 8DAAC097E9044B85B75999D6C3BCCD24 + 89: B8124DF21129685597C53A3F606FFD28 + 90: 8FBC4D795C22D958248582A8DF7332ED + 91: 36D217135DB136B2BDF1617D7E9C79CE + 92: 1B3E6271A3A4B663C509A1255027CA99 + 93: A25F596574031FF9C34314C1B1F6BF34 + 94: ACA7017E5BB62BFDD5BBFDED78C8987A + 95: 8129E53A694ADD0560B1534B32FE5912 + 96: DA0E48224106C7535A4CD8DB2AC7B8E3 + 97: CBD4ACE3D766D8E44F63E0DE8F110F04 + 98: BDC17A0EF2777512CB402C90E9D13E31 + 99: 47695AD6AF968D6F1CDD2D8C5C87A466 +100: 7ACEDD1A84A4CFCB6E7A16003242945E +101: 225489D3D073AC705F7B3AD358EABAB2 +102: 301DA87A7B2EC27514C3A2789D5DBE49 +103: 16222C503718F1420958133C330FE3F8 +104: D778CE7F642AA23355948477DA4CC11C +105: E873C37F8977E200A594B815E1A87EF3 +106: E8F8F41528D4F855D8FDF4055BBABE2F +107: CACF3D3D1E7D21C97D265F64D9864B75 +108: 6BF48F161EFF9F7005BD6667F30A5C27 +109: 42E7BB8E780B3B26616ECBCACE81FA1A +110: 225AFD8EC21F86F66211ADF54AFC2E86 +111: 4FAD3AB7D8546851EC1BB63EA7E6F5A8 +112: D1FEC2AC3715E791CA5F489F300381B3 +113: F62807C995735B44699BB8179100CE87 +114: 54050B090344E3284F390806FF716371 +115: 50482241280543B88F7AF3FC13D65C65 +116: 4C36F27D4786FE2FB8CAAC690B6D62F7 +117: 5A0EDF0B97977EE5AFB3D185B64FB610 +118: 4541055C6675B614D27C537C3BB15675 +119: 1C772251899A7FF007400B888D6B2042 +120: B7BA1EFC6022E9ED272F00B8831E26E6 +121: B0B2D719A838DB877B6D6571A39A1CDC +122: 800AA956EC16F603ECDBA66C2DC6E4CF +123: 8827D2778287C58A242ACD4C549BEB31 +124: CFBC5AA0B61103C1A982D8927B26F575 +125: A1F5B691F74F566A2BE1765731084F8A +126: 80749BE03F5724FA4CA0AEF8909379B7 +127: 8402B21E7BC7906493BAE0DAC017F1F9 +128: 37EFF01866BA3F538421B30B7CBEFCAC + +Hash: sha1 + 0: DA39A3EE5E6B4B0D3255BFEF95601890AFD80709 + 1: 5BA93C9DB0CFF93F52B521D7420E43F6EDA2784F + 2: 3F29546453678B855931C174A97D6C0894B8F546 + 3: 0C7A623FD2BBC05B06423BE359E4021D36E721AD + 4: A02A05B025B928C039CF1AE7E8EE04E7C190C0DB + 5: 1CF251472D59F8FADEB3AB258E90999D8491BE19 + 6: 868460D98D09D8BBB93D7B6CDD15CC7FBEC676B9 + 7: 6DC86F11B8CDBE879BF8BA3832499C2F93C729BA + 8: 67423EBFA8454F19AC6F4686D6C0DC731A3DDD6B + 9: 63BF60C7105A07A2B125BBF89E61ABDABC6978C2 + 10: 494179714A6CD627239DFEDEDF2DE9EF994CAF03 + 11: 2C7E7C384F7829694282B1E3A6216DEF8082D055 + 12: CFF9611CB9AA422A16D9BEEE3A75319CE5395912 + 13: E51F9799C4A21BBA255CF473BAF95A89E1B86180 + 14: F741644BA6E1BCF5FEE6D3C1B6177B78468ECE99 + 15: FB1D9241F67827CE6DD7AC55F1E3C4E4F50CAA03 + 16: 56178B86A57FAC22899A9964185C2CC96E7DA589 + 17: 0A0315EC7B1E22A79FC862EDF79BDA2FC01669E3 + 18: 32AF8A619C2566222BB0BA0689DABCC480C381D5 + 19: D35B5AFBC48A696897C084E6E71AAE67C7CD9417 + 20: 602C63D2F3D13CA3206CDF204CDE24E7D8F4266C + 21: A3C6FBE5C13E8B41FADC204C0CF26F3F214189F4 + 22: 25E480E9E0CA2B610105CD1424B8A35F63FB3981 + 23: 45412D51D3CA7BCF452D1612720EE88F9D2427C3 + 24: ED6A95036E3E046931597A457DB7A78B7309C4C0 + 25: B4FE0256D346700783420E08A4A6F7992B1E36C9 + 26: 33E1799E98280E5A9ACE5509477A2048607C5537 + 27: CF193837F6DE43F8E38000ACFCF764FA8D8FDE22 + 28: 7C8DE247DDA83599AF2EC2EE2D29E20583DAC34B + 29: F38A076F70613FC251C4D21E6435AD08341A8A99 + 30: DCD68E6174BD74BA180DA047A7345E8D111F85FD + 31: 43BBACB5F62A0482CBDB564171B04365CA6E27C0 + 32: AE5BD8EFEA5322C4D9986D06680A781392F9A642 + 33: EB90BCE364635C4C23B49F493F0043579BC85C17 + 34: 2942C7AFA65444C43D0592D0DC73CA71DB729205 + 35: ABF726F5FDA729FB7F3F0484D7C94B3107AA02AE + 36: 75DB4F6BCC05A781DDA9D17C46717286DD53654B + 37: A82CB42D89DAF5FBC1D4A48476229C495782F98D + 38: FC1A69683744AF823CD69E8A1E3F460591714028 + 39: DC68DB44B48521B0700A864896A00E17777AEA83 + 40: CC9AD99E917042381B0F99588896CBF236AA8ED3 + 41: EC7A68484A749C7065C6B746F9C465DCB414F370 + 42: C627C449DEFF14AE7ED807293D30846F061DA5B8 + 43: 4782F2A19B6DBB0882D656DE86C3D21A7317F768 + 44: 02D4EED99E7307BEA39AF5330BF7FB388D48B496 + 45: B3D99B9D90A69E50FD4365704F5AB2EAB7BC9763 + 46: 9B1C07176BB227F73E8A4E173071D39302061DE2 + 47: D79097DDAC552A6E02A52CE7AAF494D2D73B2557 + 48: DF7F23B160E75B9BAE5EA1E62B43A5A34A260127 + 49: F598F3780D8C374D97957B9B62D56106E9E0B2D2 + 50: 0BD98598F9AB29C1359EF5460A206DD1370515E3 + 51: E6C320834F69D81689E1ECD5ABC808D49D9C4E07 + 52: FD5EE7588CD129E12B886974621FD29FACC78E19 + 53: 2A9C28EF61EB536D3BBDA64AD95A132554BE3D6B + 54: CFAE6D86A767B9C700B5081A54265FB2FE0F6FD9 + 55: 8AE2D46729CFE68FF927AF5EEC9C7D1B66D65AC2 + 56: 636E2EC698DAC903498E648BD2F3AF641D3C88CB + 57: 7CB1330F35244B57437539253304EA78A6B7C443 + 58: 2E780486F64BC91FBFA2785EC1CA5C9E3CC07939 + 59: 4A7713D44E97D9F09AE1D786199C58AE2BFAF3EB + 60: C98714B16F92C8A770E9FC229DF834D1688E282F + 61: AACE3DD6F54A2A255ABA920F5FFC8CF04B85A69A + 62: CF8563896A3B0A0775985D8289444C4BBC478DA7 + 63: 6D942DA0C4392B123528F2905C713A3CE28364BD + 64: C6138D514FFA2135BFCE0ED0B8FAC65669917EC7 + 65: 69BD728AD6E13CD76FF19751FDE427B00E395746 + 66: CE705B7C60D46E7E36FE073DB8822698579CA410 + 67: C717EBBF6A2BF1BB33DA6257352D5085BEE218B3 + 68: 86151D140AAFC9A4B5877D3FBB49014FE5906E57 + 69: 7446B5A6BBCC58BC9662451A0A747D7D031F9A7D + 70: C24887924F92ADAC5AE367995D12691C662B7362 + 71: 5AF83CFD42D61967778889CA911CFB6C14339BA7 + 72: 587D4F6E6B4E21343423E434679009CBD3D24DCF + 73: AC65DD946C5CC432D4D624CAEB53C7363F96B7AF + 74: FA71E70750674C0F6B4AA19D0BE717B2936C83FD + 75: C9EFE6DD0A019315F73F3962DE38B6C848A1705B + 76: D1D05649B952C8F6EB016BE08FE1544AAC5D5925 + 77: CC3081AC1D695BAE51CFD5B44B9FB3A230733CC3 + 78: EB9DE332558953792687D9A7F598B5D84BF0A46B + 79: 39DE5EFDC92E3D3678F24D2CF545BA4D172D003D + 80: 399DBC9F721E44A992A0DEF42D999B32AF449ADC + 81: 996A2817C8ACBC667E1C4C27B8F4E9952736DD7A + 82: 3EF8189CE1BCC0D65AA182B1A81534635EDFDF2B + 83: D676714C6A6FF4E17A60C0511C25AA8B164FA606 + 84: 4DB6E3381E1B9290267C1539E1053793C8B81FA1 + 85: 3A34D35B0296FE4D83EDA39B742A9D8F4B13A958 + 86: 54F3B45304EF1287F54B877FCCE3285E154F9D6C + 87: B1EA96216E025377AB5AA845238FC8BC65DD60E1 + 88: BC6C7488145485DEDE1AE1D43B594F0046BCDA0F + 89: 3D9A0619ECF88C84CE86213E9AA91D9A252CBC32 + 90: 92CCAA0B4CE89E2BD80A61B9BAFD5AC58AB7B588 + 91: 3EB326B5BF4440FB3A88E3DCB05C1DB5EA01AC5C + 92: 989C63E819B13D4CADFB33F8DEAFBC57C1992A12 + 93: AE944552C20CF16F07A5C357713832C9D72D0C6B + 94: 46723E982569A1E2D9EDCED5498FC1F46F7D63FC + 95: 3BC5DAE7907C83A0693F87FD8372EFDD1DF53E09 + 96: 96D281BA44EB21ECFB1663C8AC5752C48686A927 + 97: FA0EF18178880A72B51C26555C10F5210DAB4390 + 98: 0C7ECAC32B8ED6D9835D381BF069568722A276E1 + 99: 649E44ECBA85C0938EC09229CEE4BB69388EC642 +100: 1E6634BFAEBC0348298105923D0F26E47AA33FF5 +101: AF2AF2734BB2BAA288940CB62109F4849DAA347F +102: 22D14BC045CC9A3794C99BEEE7ABE278BF24D6D8 +103: C3164CCBED75B82ED3F59F4A47FE09B256025549 +104: C27B5BC7CD24DE4913614A769A442E9CC9FB0E08 +105: F44D48D98CAC77522FF6B9E1B9CBB8489E58E588 +106: EA19A71FFBEC9572F6CD65523ACAF865EC05AB52 +107: CDA0EB9D310247BD1E8B3EA10D9B9DEFF6FBABA9 +108: 449DFCE971B9D65D69FBC72940E9A885E8DDE9CE +109: 96EEBB6B95A9DA99C58190CBD77CD6FBCF638A79 +110: 670F7A869E90CE86E0A18232A9D4B1F97C1C77D0 +111: BC544E24573D592290FDAFF8ECF3F7F2B00CD483 +112: E4CE142D09A84A8645338DD6535CBFAAF800D320 +113: 1C26461E26EB697CCC36A98714EE70CAAA87A84E +114: 51C5B1C25A71FF00394A84AB48B5733C8955551E +115: 84803504181C0AE33A511C49AF5015A5B1892BFD +116: 7CC8BCA120C2635ABFEA82DD203112B5C7E165DA +117: 44E2519A529D7261F1BEBEDC8ED95E1182CAE0DC +118: 2A81372DA39C1DF4251539A9922717B7CF5F0334 +119: 41C89D06001BAB4AB78736B44EFE7CE18CE6AE08 +120: D3DBD653BD8597B7475321B60A36891278E6A04A +121: 3723F8AB857804F89F80970E9FC88CF8F890ADC2 +122: D031C9FB7AF0A461241E539E10DB62ED28F7033B +123: E0B550438E794B65D89B9EE5C8F836AE737DECF0 +124: FB3998281C31D1A8EEA2EA737AFFD0B4D6AB6AC2 +125: 7A914D8B86A534581AA71EC61912BA3F5B478698 +126: A271F71547442DEA7B2EDF65CD5FBD5C751710AA +127: 89D7312A903F65CD2B3E34A975E55DBEA9033353 +128: E6434BC401F98603D7EDA504790C98C67385D535 + +Hash: sha224 + 0: D14A028C2A3A2BC9476102BB288234C415A2B01F828EA62AC5B3E42F + 1: FFF9292B4201617BDC4D3053FCE02734166A683D7D858A7F5F59B073 + 2: 00AC60F30E9BD1956F914C8E5125B69DCC31A179734E6A85B3F702BA + 3: E615202185AABE2ACA924BEC29E5A12384F8339EAE4E64C9CBA9F1DA + 4: D70DA0705EAE42A5C596D92F331DDA2421B4E14F8B3035FB73B8B700 + 5: 98029CB458A39A16355963922D32DACD9439F90E9FD106D42A0D123C + 6: 7D92E7F1CAD1818ED1D13AB41F04EBABFE1FEF6BB4CBEEBAC34C29BC + 7: DDD5BABB1B05D8BCCD644ADC393A9E2303C850DA31922C4DA07574F9 + 8: 4C07070802E21052FB0295AC0571CAEDF219143ADAE0627E2850EDAA + 9: 5D3CA3BFE738D33F841069ADF6DD79B987351CE580ACA23326B3A7E7 + 10: 6B5373C535A4FA5D56D6C4953575CE64968031BB019B909F8F2DB904 + 11: 767D0CDC11079BA8DCA276DF5C4B85507DE67DCE47EDA4CD9196D312 + 12: 02C513977B6242D2FAAC094CAE3C247C6E2745F8A71494A60535A2EA + 13: 1F39482310E2209C10A88C7FD7FC1FD567F36789808C37D30045A82B + 14: 55BA81EBA644183AB2460C234BB95ABDA898E980BA976584E2977231 + 15: 2522E2B35A835436C80A122E4676DE64690C81440D42DBDA40EF2151 + 16: 529D656A8BC413FEF58DA82E1BF0308DCFE0429DCD80687E69C94633 + 17: A153F81C68D9FFFD4DE0AB9111C2FA86E8EDCA9B294376083077A135 + 18: 1EC706AEB2227B263A105EDBE2562E0521C96420DA4558012327661B + 19: 4904ADADF19D088911EE0EFD20A9AB511F2786C8FD43F1E5E8BE2AC6 + 20: 6CE245C296289A32F661986FF1C80E893BBD35EB0B182EDC14AB3A7D + 21: 33831C459A43CBF8BEB6DD50039750F1EA3688A7EAEF68CB2F095E16 + 22: EB4BC2EA1F7146E8274A96E874585C401256FB921FFC7E935DDC7FFF + 23: 09A266C98019B6B2A4318FBEDBEA5481AF01F0AD2AD16F09991A3C3A + 24: 7AF2814CD6105473EE530F2B3DAE992ABB6C801428F33430501F09A6 + 25: C5BD6127243049C4D5E9E3B391E12BDA86DC7A9856910A757004486F + 26: FCA06DDE2DCD212E6C1C11BB22B18B4F5582202655DFB9B6C9960C57 + 27: 0851998120F8CE47482DA5B2EB21BADF73C9F145921EEFD33459D49F + 28: ED36A2092538C5D4769917953E7355A13072DDAD8A6E5E2AF1DE96F6 + 29: 2C4A89C05BFD09B7068BAFDA37B0314EFCE02AFAE1B2C25DCE337326 + 30: 1D552A4D06BB8A0827BFE8DA2B6EE56ADBD17CE4810908D572076F6E + 31: 997D180912E0655445B07259278AAAD424633F5FF6BD0AFECD4F15DA + 32: 71446EA93381BA091F94AFCDC5B938323290A1A027C22A75E88A04D0 + 33: F77087D6F4AE34E88C62597CEC06220F4C694D2E0EB704820035AE6A + 34: 64EE78B0A6C116380A4C16F24489C1E94A578E558453537A9819A2E6 + 35: F39C1C862FDC9AB4ACFA50FE283CB7595C608F8C521BB7898CF71D34 + 36: DB482A26C9488A963359D145914612E34B821CC6CDC11113B73BDE2F + 37: C7C45F3AA5EEDE664D6CCD510F628D4DC3C67F93973FE05B0163CA13 + 38: 7F230E3E597845DB9F8D61B44740968FF55F2DF28CA538A68927F130 + 39: EA52362A9C66B6A5FF3B642FCFEBBF54F793B088D29E6840D7A5CF56 + 40: 84B064EF9C13F1ED54AD0B8FC0CC28F9BCE5009500E1CD92CA2BAE04 + 41: A2702281BD63CA745553CB18693DD70AC9A70CD73C01783727707C97 + 42: 89231FCFFC7022DF20B1846285FAACE44AFCC677685DA55EE02D94EA + 43: 4C5B01C50907D097DDBF0923B885A26B58DFF5761C1AEDFB8D5353F5 + 44: 84E0CF33A7E1C0EAA46F37E99CE5C8B292E81AD61318796D1A9A90C3 + 45: 27E59A0B6E7B9125D4CAA658810AE5054CE40A9A0A0FFE6E36435EBC + 46: C7F21E2B4C89B2A6E64D92F93FC4146EB5886503C1231EE6924B4E13 + 47: 653CAFF50E077A855992990F0C5F89C75FA18D1CC147F685AF2EA993 + 48: 6A7BDEA7E456D5339B7D9C244E246AD65B18BA95E0518E201AAA7889 + 49: 837ADE7F298F8159E6E2408751B0C480648CB6FD6D26C551983F3176 + 50: BEEF3F6AC40A9DED345BE41242BB2CF924B457A45CACC68379B1DC4A + 51: 6D2908EB3B6C8952346E0B65B9406D949B5A340123DB83B151DF5F81 + 52: 9E75A1D6B4A4D1A9F5AA6F8A48AFD6F3FD360D2D8723B53DBB63208E + 53: 436E3BFE94A39359CDF47D35395D34C0435018C88B4E96E68C22645A + 54: C209DF2E99E03D679FBA9E14AAF958AC1B0A22076BB3B532A0D7F092 + 55: 8991DFBA74284E04DC7581C7C3E4068FF6CB7A63733361429834BB56 + 56: 2B2CD637C16AD7290BB067AD7D8FD04E204FA43A84366AFC7130F4EF + 57: E87F5BC938C3B981C197D4B163C635A5049FAC81C4C6467E1251BE48 + 58: FD9BDAF5CC288A603D1623651D5BA3B8801D1602B0B9221C0B48435D + 59: 87F207D9D870EDD7DA61753473A51FC386E2792A3861F949BEA05CFE + 60: C9EFF79F4412CE49296C082DC777118F92C9AC4136D4EB32621E942C + 61: DDBC76D25D9819693F3597D6F09044F8D6CCBD12F081156F1090AF7D + 62: 6411AD13AA3654302BAC8E2BFD1CE76F37E3B3394014BBE260062CFC + 63: 049E8DD7EAB3378CE9F823BFB569E5B270235D4B7F9623606971998F + 64: C37B88A3522DBF7AC30D1C68EA397AC11D4773571AED01DDAB73531E + 65: 114B5FD665736A96585C5D5837D35250AED73C725252CBF7F8B121F6 + 66: 7D9B844CAAC9EC93AE2159ED3D336C55396216DAC6AC5DC5DECC11C9 + 67: E1C799109DEEA117F68DD1826B38B514E1D265F11A8B60B24630FF8E + 68: 029A0D024B6C0B63E1586F3D34111727E37D49CA12E7F520FA91A926 + 69: 2EA94F04A72C770A98E2A495D886EE674B7D0FB987B7B5C2217A8773 + 70: FAF445688FFCA34ED783F948B8F74578503D4845836CAF69DBD5EB51 + 71: 91EC59AC7C98F9DFB869E11C80027F8A4D311324597E6FC6135224D3 + 72: 190DFC9C7BDD954E415E543F99B00B5110ED6A12182BFFDCAA77D8B9 + 73: 8C3AA805FA75625476F3267C211B1DDA52E1810B058EF804E34BEE58 + 74: BFD0E517E4A340A4E0EF1AC306EE2C6DD1288C77531EF0FD5ACB73FA + 75: C621A18D7E09976296CBC39761B020E7E346042FC735FDF106148F3F + 76: 27EE5F7E3FE49EAEC0AE0A93FD971EDF0304A4C0513BCF43424C95A2 + 77: BD9D42F293DA572219F08D4A38081D203E44F612EEDEF93CE0DAF6D4 + 78: 374CFB6FB12768717EFED2681718C11B22588C429DB9C71AFB5EB562 + 79: 1CFB1037FC3943559E9F913183DB71392CD4BC68CDFD47D7DEC9C9AD + 80: 2537E015D5945E0541BC48320AE4DFF7FEAB911227AE0D579DA1CD05 + 81: 012B34E1A530B6889E87863A59645EE4FFEB292A33815D2CE11918EA + 82: 5242DD4DFEE389E668D8FF78DA9B2D85AAE12D0C220E8D1BADBBA845 + 83: 4813D70E1D6BB6232CD9257B5132FDBA05E1A4A858E237C303CFA052 + 84: 0530BBA43AE6393655F21F7EEA67F8E8E819BA225AED78CA8BDE075F + 85: 4F7EAF4A9D0000B0E957DFE46DB304EBB2664A32AF4142EC74BE18D8 + 86: 68CF23B9DC4DC3430835B484648CBF126940AF6BAE51431A66D7F0E6 + 87: A093D2119C7076259F194F107077061C61C792DC5326C3A4D3A63BA6 + 88: F4E883F7FD12ACD36E3891986E4D7FF03F3E150F09CD4FB58A023A04 + 89: 0816862C59CE35E0D78834A221D3BABE21987FDAA81F20ED61D9DA84 + 90: F415933677BB364C589722E30B958F2BEF8670A10F1F5082F79FDB4F + 91: E40C5632490BB8DAD2283B6DBDCA870F4B5AB4271C61127DE999BDF0 + 92: B2D4E6CD7AFC35A475620EA1446B9024D767890B8593AB50275F370D + 93: 948616FD7828F09E8A57F986589948085D18EC3550E0ADA8E0127665 + 94: 2B115E930333A355A82F074EF261DE6BB2942D9DD64F98BA12D92DDE + 95: 6EEAB864B5AD618CDB1AE79C7B1DE31020966A02350AEF71088E6876 + 96: 676AD81F213E037F3C9BA2310F49DDDA4D6476C28A8EFC0046D3F55C + 97: 03A28C9068BC10A6FD87A1E53F00415F8CE994C968DD9CFF60D6B0A2 + 98: 01D91D084F400C591EDD750B66EC2482C834CE0E140A37E6E142CFEC + 99: BCAD899E7C771764CB91FF60AD79BFD629F4803A05FCBCC24E8F3E79 +100: 6E08215B5470DDEB67E44A494E52E259A9C2C4FBED4AF5DC6DB3E92A +101: E5C45BED6F8BFC487FF7190B108AF5C5B66F6D55D365B5A1BA156914 +102: 0DB55D83B38D42D229CA42D001B09758B5F3F032109F2F999C553655 +103: AD4DF1AF973A2747568A1B8DEF15E34A350A93F45BA84596580D11F0 +104: D4905849C8C4EA32159A431B52BAAC092F90037093E200A0C46611F9 +105: A936D0AA091B827BAD86644C94603068AB34A5B59E29D1E3BAB13039 +106: 46D214E9FA8C877C2791CC8E6716868713CB5B677CC4D838242C9B18 +107: AE8D3EB227AA3558101D5E5A2BF6C862C9F7297A31A3DF24E4502257 +108: 4462C366B10326D4FEF46E71930BCF93713F7D45FAC9963520FF5FE8 +109: 05EFC35781E413ECBCC763AE13D5A37C159CE5CCEE6EAA1CFF7CA516 +110: CDDBA09D7FE081E7A39C4017B3EDF7A9138D1CB857559BA9AD2C939E +111: 1AEEF583C448A9AE00FBC931B50BC0DA5BB8323E616B11076CEE8B44 +112: 01E5ABF50619B5C2078E754EDDEDCF4DE8D31185A2219313CB91A8C9 +113: B7FF114CA77757CAD67801E6761AF20F4CBB8328AEF290F77EB612C3 +114: 08F43DF4547732424AC7D0390AD8AB3D4978826462446D13B2B468D6 +115: AC3799ED09E3BD9E770FD3A0073E371FE9A3D4E3D464C3A7023CC72D +116: 795F160C275FF6B575031D4053BA1D1C32744D09F005B3BF10BDD1F7 +117: D2EFD4AC8ABA33151D0399E2893769A6D8BBFBA7B128388BFA65B841 +118: F85910F64FEE2B8F91DEC8064F75CB97E1FFC895AEE912DD3945F839 +119: 762F18C0DF65C3D0EA64126C8A6E51DB4425E76D4D969ED0F83899BE +120: D022DEB78772A77E8B91D68F90CA1F636E8FE047AE219434CED18EEF +121: A802D8B618A503352CDBCC1FBEF04EA36499EA72D0E32D314CAF83E5 +122: 6DE1088DD95C9535849294A8635A44084BA36E4EEF81C6D67B98CE90 +123: 6AA11591302A30EFACF874F40AA017F8545D3D9EA68D479965AC0B3E +124: 3288A475A4817D2E42830C709C1DC18A4BBD59DBD903B43CA702F275 +125: CCEEE7F6EFA60B2F2CE1090FB929D6068F7EE301E7A84072FD163F7E +126: A45B0FCFAC3F05279B7E8278AED93E37B225E6A997664F92C7555447 +127: 554C9C3F7E92B80F4121E00CC147535D377EAEB4FB1FA8E25C7F81C1 +128: 67D88DA33FD632D8742424791DFACE672FF59D597FE38B3F2A998386 + +Hash: sha256 + 0: E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 + 1: 6E340B9CFFB37A989CA544E6BB780A2C78901D3FB33738768511A30617AFA01D + 2: B413F47D13EE2FE6C845B2EE141AF81DE858DF4EC549A58B7970BB96645BC8D2 + 3: AE4B3280E56E2FAF83F414A6E3DABE9D5FBE18976544C05FED121ACCB85B53FC + 4: 054EDEC1D0211F624FED0CBCA9D4F9400B0E491C43742AF2C5B0ABEBF0C990D8 + 5: 08BB5E5D6EAAC1049EDE0893D30ED022B1A4D9B5B48DB414871F51C9CB35283D + 6: 17E88DB187AFD62C16E5DEBF3E6527CD006BC012BC90B51A810CD80C2D511F43 + 7: 57355AC3303C148F11AEF7CB179456B9232CDE33A818DFDA2C2FCB9325749A6B + 8: 8A851FF82EE7048AD09EC3847F1DDF44944104D2CBD17EF4E3DB22C6785A0D45 + 9: F8348E0B1DF00833CBBBD08F07ABDECC10C0EFB78829D7828C62A7F36D0CC549 + 10: 1F825AA2F0020EF7CF91DFA30DA4668D791C5D4824FC8E41354B89EC05795AB3 + 11: 78A6273103D17C39A0B6126E226CEC70E33337F4BC6A38067401B54A33E78EAD + 12: FFF3A9BCDD37363D703C1C4F9512533686157868F0D4F16A0F02D0F1DA24F9A2 + 13: 86EBA947D50C2C01570FE1BB5CA552958DABBDBB59B0657F0F26E21FF011E5C7 + 14: AB107F1BD632D3C3F5C724A99D024F7FAA033F33C07696384B604BFE78AC352D + 15: 7071FC3188FDE7E7E500D4768F1784BEDE1A22E991648DCAB9DC3219ACFF1D4C + 16: BE45CB2605BF36BEBDE684841A28F0FD43C69850A3DCE5FEDBA69928EE3A8991 + 17: 3E5718FEA51A8F3F5BACA61C77AFAB473C1810F8B9DB330273B4011CE92C787E + 18: 7A096CC12702BCFA647EE070D4F3BA4C2D1D715B484B55B825D0EDBA6545803B + 19: 5F9A753613D87B8A17302373C4AEE56FAA310D3B24B6AE1862D673AA22E1790F + 20: E7AEBF577F60412F0312D442C70A1FA6148C090BF5BAB404CAEC29482AE779E8 + 21: 75AEE9DCC9FBE7DDC9394F5BC5D38D9F5AD361F0520F7CEAB59616E38F5950B5 + 22: 22CB4DF00CDDD6067AD5CFA2BBA9857F21A06843E1A6E39AD1A68CB9A45AB8B7 + 23: F6A954A68555187D88CD9A026940D15AB2A7E24C7517D21CEEB028E93C96F318 + 24: 1D64ADD2A6388367C9BC2D1F1B384B069A6EF382CDAAA89771DD103E28613A25 + 25: B729CE724D9A48D3884DBFCBEE1D3793D922B29FA9D639E7290AF4978263772B + 26: B858DA80D8A57DC546905FD147612EBDDD3C9188620405D058F9EE5AB1E6BC52 + 27: D78750726155A89C9131D0ECF2704B973B8710865BF9E831845DE4F2DCBC19DA + 28: DC27F8E8EE2D08A2BCCBB2DBD6C8E07FFBA194101FC3458C34DED55F72C0971A + 29: D09BEA65DFF48928A14B79741DE3274B646F55AC898B71A66FA3EAE2D9FACD77 + 30: F2192584B67DA35DFC26F743E5F53BB0376046F899DC6DABD5E7B541AE86C32F + 31: 4F23C2CA8C5C962E50CD31E221BFB6D0ADCA19111DCA8E0C62598FF146DD19C4 + 32: 630DCD2966C4336691125448BBB25B4FF412A49C732DB2C8ABC1B8581BD710DD + 33: 5D8FCFEFA9AEEB711FB8ED1E4B7D5C8A9BAFA46E8E76E68AA18ADCE5A10DF6AB + 34: 14CDBF171499F86BD18B262243D669067EFBDBB5431A48289CF02F2B5448B3D4 + 35: F12DD12340CB84E4D0D9958D62BE7C59BB8F7243A7420FD043177AC542A26AAA + 36: 5D7E2D9B1DCBC85E7C890036A2CF2F9FE7B66554F2DF08CEC6AA9C0A25C99C21 + 37: F4D285F47A1E4959A445EA6528E5DF3EFAB041FA15AAD94DB1E2600B3F395518 + 38: A2FD0E15D72C9D18F383E40016F9DDC706673C54252084285AAA47A812552577 + 39: 4ABA23AEA5E2A91B7807CF3026CDD10A1C38533CE55332683D4CCB88456E0703 + 40: 5FAA4EEC3611556812C2D74B437C8C49ADD3F910F10063D801441F7D75CD5E3B + 41: 753629A6117F5A25D338DFF10F4DD3D07E63EECC2EAF8EABE773F6399706FE67 + 42: 40A1ED73B46030C8D7E88682078C5AB1AE5A2E524E066E8C8743C484DE0E21E5 + 43: C033843682818C475E187D260D5E2EDF0469862DFA3BB0C116F6816A29EDBF60 + 44: 17619EC4250EF65F083E2314EF30AF796B6F1198D0FDDFBB0F272930BF9BB991 + 45: A8E960C769A9508D098451E3D74DD5A2AC6C861EB0341AE94E9FC273597278C9 + 46: 8EBFEB2E3A159E9F39AD7CC040E6678DADE70D4F59A67D529FA76AF301AB2946 + 47: EF8A7781A95C32FA02EBF511EDA3DC6E273BE59CB0F9E20A4F84D54F41427791 + 48: 4DBDC2B2B62CB00749785BC84202236DBC3777D74660611B8E58812F0CFDE6C3 + 49: 7509FE148E2C426ED16C990F22FE8116905C82C561756E723F63223ACE0E147E + 50: A622E13829E488422EE72A5FC92CB11D25C3D0F185A1384B8138DF5074C983BF + 51: 3309847CEE454B4F99DCFE8FDC5511A7BA168CE0B6E5684EF73F9030D009B8B5 + 52: C4C6540A15FC140A784056FE6D9E13566FB614ECB2D9AC0331E264C386442ACD + 53: 90962CC12AE9CDAE32D7C33C4B93194B11FAC835942EE41B98770C6141C66795 + 54: 675F28ACC0B90A72D1C3A570FE83AC565555DB358CF01826DC8EEFB2BF7CA0F3 + 55: 463EB28E72F82E0A96C0A4CC53690C571281131F672AA229E0D45AE59B598B59 + 56: DA2AE4D6B36748F2A318F23E7AB1DFDF45ACDC9D049BD80E59DE82A60895F562 + 57: 2FE741AF801CC238602AC0EC6A7B0C3A8A87C7FC7D7F02A3FE03D1C12EAC4D8F + 58: E03B18640C635B338A92B82CCE4FF072F9F1ABA9AC5261EE1340F592F35C0499 + 59: BD2DE8F5DD15C73F68DFD26A614080C2E323B2B51B1B5ED9D7933E535D223BDA + 60: 0DDDE28E40838EF6F9853E887F597D6ADB5F40EB35D5763C52E1E64D8BA3BFFF + 61: 4B5C2783C91CECCB7C839213BCBB6A902D7FE8C2EC866877A51F433EA17F3E85 + 62: C89DA82CBCD76DDF220E4E9091019B9866FFDA72BEE30DE1EFFE6C99701A2221 + 63: 29AF2686FD53374A36B0846694CC342177E428D1647515F078784D69CDB9E488 + 64: FDEAB9ACF3710362BD2658CDC9A29E8F9C757FCF9811603A8C447CD1D9151108 + 65: 4BFD2C8B6F1EEC7A2AFEB48B934EE4B2694182027E6D0FC075074F2FABB31781 + 66: B6DFD259F6E0D07DEB658A88148F8253F9BBBB74DDD6DB3EDBE159A56BC35073 + 67: 8FA5913B62847D42BB4B464E00A72C612D2AB0DF2AF0B9A96AF8D323FA509077 + 68: 7DED979C0153EBB9EF28A15A314D0B27B41C4F8EED700B54974B48EB3ECAF91C + 69: 1CF3AA651DCF35DBFE296E770AD7EBC4E00BCCCD0224DB296183DC952D0008C9 + 70: 5767D69A906D4860DB9079EB7E90AB4A543E5CB032FCE846554AEF6CEB600E1D + 71: 8189E3D54767D51E8D1942659A9E2905F9EC3AE72860C16A66E75B8CC9BD2087 + 72: 107DE2BC788E11029F7851F8E1B0B5AFB4E34379C709FC840689EBD3D1F51B5B + 73: 169F6F093A9BE82FEBE1A6A4471425697EC25D5040B472C5B1822AEEA2625988 + 74: 2087EBD358AE3EA2A092FC19C2DFEE57C5F0860296BC7B057C14E1227C5CB9D1 + 75: 182AB56F7739E43CEE0B9BA1E92C4B2A81B088705516A5243910159744F21BE9 + 76: 081F6C68899A48A1BE455A55416104921D2FE4BDAE696F4B72F9D9626A47915E + 77: 5CE02376CC256861B78F87E34783814BA1AEC6D09AB500D579ED8EE95C8AFCC8 + 78: B93E407404E3E95F20FD647365E0E7F46AFABE9AF1FF083AF996135E00D54009 + 79: E81FA832B37BE8ED8F79DA29987AA4D61310DCB14B2859DEDF8FB1DAA2541FD3 + 80: C56705FEA5B110B8DC63688533CED21167E628017387C885423B835A55EDD5EF + 81: C2226285D08A245A17058ED2D24AD095B714F608AE364FDDF119E0A7DF890540 + 82: F9C270DA8793221A6809AC685FDD4F5387E0FE1EE6AAF01C74F1E0A719621614 + 83: E69BEFD6EF7F685C36E343AC1702D87AD6A0E4AC8C0D5C521D04AAD4EF0B7458 + 84: 4E3033562AD74A7D43EB5FF5FC2382622C6307CB10E245AD62DA77C4C63CB178 + 85: 2EA17629472564A59E5EB845A2CDD04F442DF2FF26BCC866E400F77158D612A1 + 86: B90223DF74DD49A8A1461F340F2D7A90F96903CCBB5BC3C74EA3658FC8948B20 + 87: E0209F42B927EC9C0F6D6A76007ED540E9BDD6E427B3368A1EA6C5E7565972DD + 88: 10D9BD424114319C0999ADF6288F74060CD8918EF1228827A6269B2BF0F0880C + 89: 7D1978A65AC94DBBCDC62E3D81850299FE157DD9B7BD9E01B170156210D2815A + 90: E052DFF9E1C94AAA49556F86FAD55029A4875839FDA57F5005F4C4403876B256 + 91: 58D29459B2130A2E151252D408B95E6DAC424C564062EB911CC76440CB926CA0 + 92: 4E4530C392316F598E1BD07F32166380A8F712A33A48E9EB4247131EC5DC05D3 + 93: A09C9D3E42342C7DEA44EDB4AEB48CF6727CACD8032A12CF77A25829FC249D32 + 94: EB978D0F1AC03CE5C3510B5F4A16073A7A2BDC15C4AB7777DCF01030CC316667 + 95: 7D1905A3ACE827EA1AC51C4FA08C281ED3BE87E7F4E928D696BFDE35C8F2DC0F + 96: 08359B108FA567F5DCF319FA3434DA6ABBC1D595F426372666447F09CC5A87DC + 97: A7B3830FFAB0F2BBABBEF6DF0B169A7917008BF238880BBF8C20B8E000077312 + 98: B4F5D9B1555994C5EBAEBD82918D560A3BF82962A171A1614E7551939E943366 + 99: 014ECAEA1B378900F1212898C6DDB01565D81AF1D0EF78DF5E28D46E9CAF7CFC +100: BCE0AFF19CF5AA6A7469A30D61D04E4376E4BBF6381052EE9E7F33925C954D52 +101: 4565D7B898CCEA3139AD260F9273115F806B30079D7683218C4E3ECD43AF3B33 +102: DDADEB660FE8902C9FB2DB9B6CF237C9CE5B31753398085C4367EB5910B9CC13 +103: C15A8928131F6687DD10F3C115DDF8D7C8F2DF7E18D12C08C4FD16F666CE60BA +104: AE8E3D799B1353A39815F90ECEEBEFA265CC448FE39FAF2008CB20784CB2DF9F +105: 98545371A3D9981ABE5AB4A32A1D7B2FADD9801D89DA52A94A4F78A42740D21C +106: 6323DCE2F8B3A04DCEA8D205602348C40403CB200C677EB1A1C0FE37EDB6EB2F +107: 8150F7C5DA910D709FF02DDF85DD293C6A2672633DE8CDA30F2E0AA58B14B0C4 +108: 44D21DB70716BD7644CB0D819FA6791805EBC526EA32996A60E41DC753FCFAFC +109: B9B7C375CCA45DB19466EBD0FE7C9E147948CC42C1C90F0579728CFB2651956D +110: A47A551B01E55AAAA015531A4FA26A666F1EBD4BA4573898DE712B8B5E0CA7E9 +111: 60780E9451BDC43CF4530FFC95CBB0C4EB24DAE2C39F55F334D679E076C08065 +112: 09373F127D34E61DBBAA8BC4499C87074F2DDB10E1B465F506D7D70A15011979 +113: 13AAA9B5FB739CDB0E2AF99D9AC0A409390ADC4D1CB9B41F1EF94F8552060E92 +114: 5B0A32F1219524F5D72B00BA1A1B1C09A05FF10C83BB7A86042E42988F2AFC06 +115: 32796A0A246EA67EB785EDA2E045192B9D6E40B9FE2047B21EF0CEE929039651 +116: DA9AB8930992A9F65ECCEC4C310882CAB428A708E6C899181046A8C73AF00855 +117: 9C94557382C966753C8CAB0957EAEDBE1D737B5FCB35C56C220DDD36F8A2D351 +118: D32AB00929CB935B79D44E74C5A745DB460FF794DEA3B79BE40C1CC5CF5388EF +119: DA18797ED7C3A777F0847F429724A2D8CD5138E6ED2895C3FA1A6D39D18F7EC6 +120: F52B23DB1FBB6DED89EF42A23CE0C8922C45F25C50B568A93BF1C075420BBB7C +121: 335A461692B30BBA1D647CC71604E88E676C90E4C22455D0B8C83F4BD7C8AC9B +122: 3D08C4D7BDDA7EC922B0741DF357DE46E7BD102F9AB7A5C67624AB58DA6D9D75 +123: CC63BE92E3A900CD067DA89473B61B40579B54EF54F8305C2FFCC893743792E9 +124: 865447FC4FAE01471F2FC973BFB448DE00217521EF02E3214D5177EA89C3EF31 +125: 3DAA582F9563601E290F3CD6D304BFF7E25A9EE42A34FFBAC5CF2BF40134E0D4 +126: 5DDA7CB7C2282A55676F8AD5C448092F4A9EBD65338B07ED224FCD7B6C73F5EF +127: 92CA0FA6651EE2F97B884B7246A562FA71250FEDEFE5EBF270D31C546BFEA976 +128: 471FB943AA23C511F6F72F8D1652D9C880CFA392AD80503120547703E56A2BE5 + +Hash: sha384 + 0: 38B060A751AC96384CD9327EB1B1E36A21FDB71114BE07434C0CC7BF63F6E1DA274EDEBFE76F65FBD51AD2F14898B95B + 1: BEC021B4F368E3069134E012C2B4307083D3A9BDD206E24E5F0D86E13D6636655933EC2B413465966817A9C208A11717 + 2: 5D13BB39A64C4EE16E0E8D2E1C13EC4731FF1AC69652C072D0CDC355EB9E0EC41B08AEF3DD6FE0541E9FA9E3DCC80F7B + 3: 4F895854C1A4FC5AA2E0456EAF8D0ECAA70C196BD901153861D76B8FA3CD95CEEA29EAB6A279F8B08437703CE0B4B91A + 4: 80AE432E757826025095CA1FA4F89C06C8BA6754B1D883A8E31A1E65FCFB820BD74ACFACA3D939A574EA408A74162D1D + 5: 561C16404A1B592406301780C0C2DF6AA0555F504F35BFBEAC810AE36A343B776858C5E0DE56BB79607A34D2F67108F2 + 6: 79F4738706FCE9650AC60266675C3CD07298B09923850D525604D040E6E448ADC7DC22780D7E1B95BFEAA86A678E4552 + 7: E6CE1896C9783A70AC4C90276CC37B37687D7E30C753975762F961AE37118D9A610242716E8359EFC4975AA98C632DCF + 8: CFB18F81F4BB672B03214F1FEDE456F882A0DE40120212A1FEBA8FDC48F763C86ACBBFB684D34B70F99F4D8D81FE3A28 + 9: D075AE1178210804635AC02C656309311527FC8190835C8AD8196577C3332AF4D87F056023F235DB893C69AA87B0CFB9 + 10: 182E95266ADFF49059E706C61483478FE0688150C8D08B95FAB5CFDE961F12D903AAF44104AF4CE72BA6A4BF20302B2E + 11: 89BFCF569AE4AF718510DA78C67414109F5739BB5C40D51C9C8C50E2B2CEE86F2F80C8B9D68F7C01201A0714572FE602 + 12: B635441A3721CF190B39D23703C5B77018FF1A56C94F8252EE95C217E3477F093E8EC65C6AE767179A7872C8DB9B2141 + 13: 48DEBF56626CC86DFA47AD6FDEC73FD182434621DA8BC6DB23AFF067BC36DC8244D3071B1F57DE4B716F63D9820DFB23 + 14: 58475B7CF93FECCB2C02B588F1552A359E7EE9AC45D9AE50B2D7C22021466677D70EF24EFA5C492515164458E9A24744 + 15: 0AA75534F0F58756A01E3366F78E7611BC7F432364C649C3F50547F7BCA3E5489531B8AB129495FEAC834FF0A0B45DB6 + 16: C81DF98D9E6DE9B858A1E6EBA0F1A3A399D98C441E67E1062601806485BB89125EFD54CC78DF5FBCEABC93CD7C7BA13B + 17: FDD3C4C0F87EEC0CADD73028A06B01E67696C7E04960936B30C73F004CF6B595D644533F8B473C8E63B02D593A64B041 + 18: 445E4CCA1A03480D149F38014C14D28DF8288F2C6CFF047F45D4F2580AE85EFFB3BE009C9D2ACC54B51467F83A09FBE2 + 19: 8305DC56172245B82AEDCE7F9C7DC88C0E62CBF835A2AA133EB579F415FFD15BABBC30BB98E55DFDA0F9E80275C92BC4 + 20: 8A48240E1C85E80651EDDC88599273444839A952CACA2BEF4400576E65B1EB6C19C47A3067B63AF7CDC4238ADB9A8DAD + 21: 8F2F7669C27A7CB1CF7A84A2C4F050D7141852D8B429291956B85E2DB5287741A3104E7E99CA5D23A5EEA59A68A4DDB1 + 22: 32CF04AE2A4A326FDE2FBB887F47FB7A2C486E56088D85B45F0C7587591F44797FE0A67E36F571809695E05F254884B2 + 23: 713A04A3A6BA8D2FD821F1CDF9FACAF42795E4247C9A26F0ADC5E0E6AACBAFFD8F4E02563733C6BDF1A863A787949B35 + 24: 35D8A5AA0DC9AB4C9A4C62B36E0E1013977C198B05CF6B92CEA25C08309DAFD282AA9A4862958593C06BA46919EA8019 + 25: D3FB60C2E981A5C82F1B1BCB3D4D7AF62C9A32A9F0D87E0532C9D3AAC083D70133EFF63A1E2CCB87360BF032C25FE9E1 + 26: B119F9AC74E58BD081E24C0CC1E090012C192996EED67A8ECA33794FE7E1920E26C0EFAEB866EB5AB82FCA3188A3B05A + 27: 5B29543AB0F76F246B7FDE6E8E5D3DF6017A39342BB08351A4EF609AE00A91ACB7C5D0487B3760B34CEF326F63C84572 + 28: F8E1FAA657BF829C9D2E4811805238CCCD11F0C1AB7619058241BA5606E7BD5E4816163E6E8E82E62A43CB4943A41006 + 29: 0855B919786B5E5C87B85A6C17A46C550B2BA81B3724389088E2B54BA89D82B8F9841FF442DA5DB8D54C9B2AC108DC3C + 30: 7DEF8CAB7C80CEF90FB38989ABEF6F1A5EC18379681E484A1B4DB6624818D2E486FB9C245C1F0DDD85A846D4268344B1 + 31: 04AAA180C2CD24F0FB150B1AA360F445344150DCA13E1ABB8117D42E25DF7FE29246D9F00C7473D20CEC32A71E64E1F5 + 32: E7112491FAEEFD57786DA73F367B25A6F5769F5C98FA7B704D8D37747724A647371989E8B0FE8D3CB23F9EEDD528456B + 33: EA27126D0B96E00E428943EA94F4B03FD22D56C4FF4636EED139D027E6D45EF57AB86093A7342B3B3851FD3BFD1DDA23 + 34: B2BD337A4BDD48D25A5E3FCE3E0948EC67829B835A8E3DD0D9F4881D10C766369B079028C6060B7263603288D8FA4BBA + 35: A9E940504AE6B137BB1BC88CE3A9AE53DCB63AFDFE5FA0C652003A921F582C08662425C7FBD5B1E1422E39E645D4A757 + 36: F033150D7464D49A076C7D4BB9E2A5488132786CB4851A4C81DA5B0FCE66D775D3C1766094AD6CA9482DD9539F28ED9A + 37: E64D999E7258ABBB4CFF6F74AF7D6A1E9B044C17E1ACE0FC61B29E7732763755A9C1D3A380B080AD968D2228DB731DE7 + 38: 9030D47B57ABEA93B51162556FF352DA61FDF501132A9FD94E6CB56690E7A805CDB290FB4ADE36BF90A53F20922C9B6E + 39: 4473396BB0461EDB4712880810A3F7252725AD4FD6092021A40559F453A1C63ACFFA8A02C85CC8DB86560323DA0A0FD9 + 40: 095FDD130278B3C8F574D17283611E4D6199EA63A0F1599E01ED070CD0B115296FE353477582BF279D622355C89A23E4 + 41: 7EE600CEE8437531C6A5BEC313D53371F9B56425D5662C104624D83D51111E5C9F4B83000B8A3EF150E04AEDCF67C237 + 42: 676D2BD2500BC527DCB51968FE8742E40D2965047478E69155AAB9201E0C9B0F6BA9BE85C4734B0DD556B5FA7608BE83 + 43: 09F5FE433D1FB8F62A76E5654B54CB6A9EF505D2465A49DCB9669EAC9A30B2532505E4500F842EC9FBE79A382C8C2F4D + 44: 075821CA8C547E66AD94F4C4ADF866A2A7554E08D2B0F0B3576801773EDC85DF76107E6912904E9757EBA753A77CD0FF + 45: 2172C22E7E48BD0B4A73FF02803D6FCE776CECBD95DFC43CA0763A0B375D57030000B12E59F9CDE81DE58E17489B2C41 + 46: B9A15689BA4F41BE46855775B46A5DB9D6826E0CBDBC3B292DA6D57B2A179A3D393A8E1B55DE79438E5221580C604EAD + 47: EBFA57C946831E2E370A6B1BE46E27C95C512297499B8BD15722622178E00599DEEADD48F1B4B08EB649A137805CB786 + 48: 25866C8288F9FA319FA9AA2470B4FC2595DFFA9154E607444EA3247E81D74A2AE0957D6B7E050F8C96AA7577BEDCABB5 + 49: 3D28682B90022C873CEC78C3A47FD45B5124E49ED07E2F0FB41A112A63AACC9E7614ADBB007D129C0673B08C51210839 + 50: F76D9B7ED868085905AE806CFC5C6DE994999E379922AC003D53F00B65467AACEF3929392F1F2F56C621D2F552544A22 + 51: 324951FA2432B63D1765C21F98325BC4AE2FFB25F411047C53ED5A3D550B50E2B8F6E79BBE65F2C686A5132E5B982AC7 + 52: 320CB033AD533AF8EDB3E664E34BB85B2327AFCFC583CE9202C0B11F16425A58FD895D7435E8953F9506A25DE7BE6EF3 + 53: 6065D55530ED8339B09D7A4D9CB1919004F69ED9D6B119E78E1C39C7AD2AAC029A3F266F7E48350966B845C4D7D92A72 + 54: EB6E866BDC0B5089301D89B870B75056ABA6D5FA6C7406A8D6D97CE5175102479647D3F93325A2CB648A3F40CCE38542 + 55: DCEDB6B590EDB4EFA849C801E6B6490657A5C1E64F69269F5F63C9267F6223DE24CEA7AAA6B267D9BCECC15147B6C875 + 56: 7B9132D597B8873AD55BBC30F18ED3F2C9F340E7DE69FB5774056C71A06D9BC2B14137E9E1C68B6B645FED28B188249D + 57: 0901B1E5B13FCE000486BDA64FBE45C79FCE15F38A4DDD9335A521D98829D267ABCCD84284BEF1EA3C2D4E4687C6D3B8 + 58: 4A9375DBAA878E2C1C7BFB977989E6D39CC00F890ADC425F7084AE3761BAEFCB9384C8B9EB3ADD4C3C838A6D560DF788 + 59: 908682C3E0D97A4943063EA9DD0A0F55EFCA203ACA3004010D3D7EF94593592729B523EAAE4160C3EA2241EBA236FD65 + 60: 24586F75A43A08D6CF116B87B86CC43300FC4132523CC4824B7FBB3F54A5B41C7D598B40639B25A99732D575A5CFD355 + 61: 7B4CFB73E247E941570E70C7308ACC5166F123187F003B1CAA9BCD17DDA8ED5535ACAE443C9ADE93C5567090EACE29AA + 62: E97EF4578822DDC79AF60514A188F8C719E4133B58E5EB134261AA7E89C402EA7219129A06B395E5E1D2738AC23FC876 + 63: DD66B519F51A925814407A449C60B34C553D7652D41783EE903A810A4C9F833B8181C91C7F12283EACD6A5F8A2639DDF + 64: 9F2C9EB7116B3D7A4BA84A74A4D4EFF8A5EFCF54B6D7B662693C38577914C73A214766F0A175339BB0895A863824FC0A + 65: 14B0A9FFCE149426BF5045FFC24C057451D2473186DEB4F150117B855911A7641651FB1E15DF406EB373D71151C46F25 + 66: 286505FF7A9EF81224988A8FF1E423A2AD21F6B339E91B89F7F1540F14CC9A603952564539167465CA70FF0B523BECF9 + 67: 8CAB08A79BA16F3D7CBEB942C7D8676F8D0295B5FAA01F3C850DC4B5FE913AF00F2E938BE0B442187B135BEF1A36C34C + 68: 4D12FFBCE2E770ECA1104BD2F29C65FE95534E390A138C30CB0ECB6436A971116D82C6321D2EA2C0A735AF34E5E3E3B2 + 69: F8617A35FE9116A719441F82F21C79B8868E5FFFC2EA737FDC821246DB7610E9868D870575F19B29F2FD259D9242A497 + 70: 932FC435B590B1E1D49C34EB3B627DAD5476216518250B1FBFE772476437872B8DA6CAF6D2F33CE7AF8648D956CF717F + 71: 3F63DF48C2D87CEB2168BEFBF6B857A415D8BFB7062251E8E1AB0487483EEBDE5E8E8B8B0E3AD81ED4AB15E81FD5E448 + 72: 4A71E4E737DE74F78E72ECB9DDB580EA5AC96E5BBD5E52E11D4A41AB3B8303E3AF3458A8AD89B39CD9F4A6D5DB3C9E2A + 73: CAC3A81A98103BBF08C440F6C8F61AC010DF8AC05FDA77E2ED8660AB73A978B9428BA0458A5C64DFCE35D87F0DAA2A6F + 74: 6E5D162C60A451B6257781FA0E36B3BDD9BC42A7BCFEAEB75C18E541A4DE00967E6BF575CB32374C1E9FE7B36D92048B + 75: 04DDFD71893D0F4AD2A0B672A057ED2795D6811AEAFDB7136BC8C20A55DABB3AE4B62B8A2C722C1F53E18FFA5771610F + 76: 555D5B51C2EA17659516A67D31CE2CB302979F80BD7056908C1A152403FD902EAEBABDD066AB3F7834E7213A6CE99EEB + 77: 44797CE4FEC66B26B52A4249C2B267AF891C912E55221EDB6CAFC4E2F022A40E8231931DF0B19321D5CCB2AB8A4F256A + 78: 51D7AC85289FE7E4D9431414B2BF3760BE65FEDD1A0B34BED0E1562A73495EE10971B5141835DB454C865039154BEA15 + 79: 2E31DAE50A484B7E11E2E621D0552803791E07279752E09EDF4C884EF24C79C33D9572AE0DE6E0B6A20271F1F7AB98FF + 80: DDC65ED22CAE4D159D35E129A1602D8FA50D7AA53E209B0D5442BB121DB0D5D102441054B2B321675F3722669FECD06E + 81: 200E0BC495311E2FE524A1579490D843011A592E4E9B927DEB0727E5481898C557CB2941F18AF0F2725A1B19DE045BA5 + 82: 561E1875B31DEAEC4DB2FF5BFA7856A6F0ABE1294CDCCA1DA12CCB1786D9556881A768ABAE50F7243921ACF993AAF18C + 83: F6B88007732D5B9F75209F9FE107B9917010D5960184FD239854AB4611CC788D1455B113A5565A87326B3CE6CA190DB8 + 84: B4E703169169B07AC61E76A75ED4AACEE4115F6A43842BF136B514824A05F5C5ADB68F2E525D8C9E8BDB20D3BCA21155 + 85: F72E2083B296EB7468C97749D3AA1B08F418EBCD9A2E5CB4117C5A034BBEA5E2004EE1E43E26A98E4F25AD4306AF3A57 + 86: B1DE9ED0D5E5F7FDCDF530041D7320CA7376A64590F6679971F84061C42AA03F0B07C7EBCB806EC8380D9FF0E182293F + 87: 30ACC02AECEA9B91F3C6BB0F4CA8EEA1B84A0BA6BBB8F7749FD29C9BE5C5E28AFAE5A33617DFE3FC28CE3A78D1A19CDD + 88: 5B2DABAF662B86DC4B1DF6A2EBDEB5CFF1F63C65ACE5E1237DB507DD3FA2C27FF46517B0FCD6F32F25DCD55ACDC07FA0 + 89: 33BE80B29355AB16AA0F05A45A8DC15A5EF7F9FEE60BCBE05E106BF6FA0F196BFD9CBB8D79298360F760DA7B05135F83 + 90: 048C648A525FAB61CF81E087047044130E407B71DDD27293119689C8516B19DDC4F276E3B4E93E6AB80A79BB2700DE68 + 91: BF18EA9E00E6C2262D802FB66E04FFA21DC5C13640BBF27B2C22592DE4AFE31C18147E6EBD2D45669C36F9432494A000 + 92: 0A1A114981A785C399E2B21871A532B2A747FC67B4DAA287C14F2F449FC6F7C6925DB5E884E6E041D08BF6BC69295124 + 93: AC6705C373300FCC09A291CFF1834401FC30FAD512569848A05171AA02426B7034EA2E4777AAC2DDFF48089226A4884C + 94: B7B08352FF8988C0FFE3FE0E27278F068BDC88AECBA8D7ACD8919850D7400A2C0A0A8519B264F61102290C9AAAD3C2DD + 95: 8F78C56A93B3DC69ECC5827F8D591195FB683A9951175754926A8E19F81FF859DC1904DE12BC8482A760E998552D28E6 + 96: E606004ECDC6878B5EC15F4554017CCF962E92CC6EAEBE4997BA34EC0E53C67D564C8461C013701A401FE347EC0F721E + 97: AB7D7116F436ECB13ED2EC42347DDF902E0FD766EA8978CF93625F56B2164E2E630D6383EB03602A8DF27F28F580E3C7 + 98: D716BE6974E46F19A606486BE576AC6E250AAE6AC2ACE7CA9A924C874790E6B4C94670FD884A6EF770EC5E5F3F264306 + 99: 746EEE51375E6695BC4B66190172DC6E86C18E144267C7B0133D6C2ECE05F75B862E4C4EA5F813DD927D60C46E2C554F +100: 3D20E33BA4D52A8C374878F1A624A907132264D0C831C64FC51ED8E1CDB75D11C3FC78D4C3CFBF99D7F0BEA9829B725C +101: FE6A6EBBE30EEA13CE04B1C8FA4199331B77566D2AF420D4EACEDCF22C23B3D7AD2313175389A0765AD60A79C0AA85C4 +102: 1806469C58C028D7FBE80F219DD45333D440A824032778DEFC0A89CF704D40745F0F449F7DF82D228E1718391C85F318 +103: 20CD15E37F6371020B78579210FFD7756B42BD01EB829C1320C59AC382781AC4224439F1F820E215EE907091EE4F028B +104: 7967636E73E440EF1F8751441ADE0F4D169167AC270949A758FE0FFE0B90C2773435623160E4BEA5F23DBE0678E95ED2 +105: 754F6D73A11693E07A2E5F05FBE13514C52F04F904131E0544202354D30917C333DC649FF7C33557005BB19B64DB777D +106: 358D83F883166A6D2972C63F2A46EF893D2FF0F577A53830B3B8E2CB28D1EFE8405084C145EE4E0BEE5DFA9AEF739263 +107: D74B6FD707BCEC9419F032A9C21A7C79CD38F42D564057CDB956485FC5C2ACAECE9D86BE8E12B9181018EA7871343147 +108: A517359A64226F2D08B65203593F3427DD42852476A7609C7F6423C304FBA6EA83981470B8CF171F71BF02F688BB2448 +109: 62162975F98C8ED1B74ADE5B2325EC3D185F7BF8D9DE6C08BB3AB052E54C28399AABE2BE4295CBE12003A03924D4EE3F +110: 8F1E4237FBB668D2705FA6964FF50014F54AB6346A7DECC8DBAA282B51803DE20F9090E7AF2E6B40FD8A138AFE25E1BC +111: F5F9FE110D809D34029DE262A01B208356CAEC6E054C7F926B2591F6C9780579D4B59F5578C6F531A84F158A33660CEF +112: 33BA080EC0CCB378E4E95FED3B26C23AA1A280476E007519EE47F60CD9C5C8A65D627259A9AA2FD33CA06D3C14EE5548 +113: F14FC73C4192759B70993DC35FBEE193A60A98DBD1F8B2421AFA253DEC63015A0D6B75FB50F9F9A5F7FB8E7241540699 +114: 72B9E34E0E655DCD7D9C288D11839A4FD96292F76F69BFB2E7D4F848E498B842CD4ED6486E77E30C603D218144AEEFB7 +115: D71CBD531B25BA65E319954E5AA670C8055406A595D006F0DCEE11AFAAF735CB1615EBAB4CC98061645FB70F31CDD9AA +116: 1F4398793AE7B2C4975AB102BC054DCEECB238DE4307B5DC54F6D7C20E066F638A782E33441533276DF9DB1AD0EAA75A +117: CCD908195016DC596A78C6C10C92EF6F272C6251F3C40B2E7DAD3A4538BF3FF585D4E44035B49EC397D1476E9DD28D02 +118: A8A26DDB23032BBD4432AC857383A5DE280202B21CE173D864E19C4A52984E159BDD006D95605A4682458137FE6B71BF +119: 0C8D3031D85CEFA23A09E13CE03623F0E648A030E43700C82AA1C8AA7E3EA9CECEF3029A23815AD940CC39ADB7747D2F +120: 0577AD6090B2A39FFA1C4A25436F9E958890C55A5B23CF8CEE8195A5984316D81D6CF0B5916C0AD8B1F512FB39826C6D +121: A5E7C31DCDEC53D8898DCB27D52A5C1774115D8DB163543A330AB502FE31D6017FA4BA4C65ADE0CD911972C5A1B7739D +122: 2785C149B798E41E6ED600DDA5257E2F31484BA4D14D35C8353BA4BB3BFB47F6E2CD9B64C940E3C1F83AA4587DC29CAA +123: 977756EEF1A7C1D4CA31A8E6936E7B8884968A22F2846F20B38F247345B1CCD47405040F727BBE2E0FFCD159206F5E87 +124: 9E4811F182E5D6734EA097FCBC77892EC48F09DBA138AD5A5ABFE67F2E88AB61B0A3ECB29028B5528180191754231765 +125: E964C5CC45E8356DCE9FFFE715D01AEB3935D644DC9C2603ACD175A04E8924DD84A4D88A1384D6BAA8AB3F7F7D52D122 +126: 764EB963850537E57D0969C9914355C5AA67AA9722644569B7F50E20DA8461CC9C6CA5958ABE10F5469E4DC1ED27619F +127: D5FCFE2FCF6B3EF375EDE37C8123D9B78065FECC1D55197E2F7721E6E9A93D0BA4D7FD15F9B96DEA2744DF24141BA2EF +128: CA2385773319124534111A36D0581FC3F00815E907034B90CFF9C3A861E126A741D5DFCFF65A417B6D7296863AC0EC17 +129: EF49AE5B9AD51433D00323528D81EA8D2E4D2B507DBD9F1CB84F952B66249A788B1C89FCDB77A0DB9F1FEB901D47FC73 +130: D9B681BA08EC0D0598DD3A2A37F909D01A231D22DA52216126534402A58A072DB35FDAE555B99159894BC823F9DACFE7 +131: 961E792C94027A091DF880A713ECBCA94E7699FA392CCA3E4B9988CB95DD46C894AB6CFA3DE91236188F7A372B1C60C0 +132: 779C845CED9623B6558577C06C6F22768E4A01CED2A9722CB8788FCCA89E0B5CC6A8925533FD097F635997A9C191D59F +133: F8A6FA1C730483AE488191E5863AB3DAB4BBDA1722710E519A2B2455273E78A382C60DB0D21E3B497EF9EEB2780AB384 +134: 1DAA34486981474A57029F0B1FF5150A144CEC7939A5D0C3D7DDDC4F471225D98E83E8A0DE880036F1A265E24CA1E674 +135: 769694D69D701764BCF81C053E2899B232344506C08A39DEDE3D838F85870818C3A8CD2DBC8695EDAF8FE34B4A5CC35D +136: 97E29E4AE7C7E461196C1D698B5D1186822BB66ACA3B3E062A3AE07DB9DD0FED83A345014D3E5AD89E9046606AD2CEE7 +137: 6B57593EE18186573F92273A9B722F9FD77A4A512164FE3756BC2D9F665768016EB2766C46D473A103D7D7090073271F +138: 35235261C522612958048B7FB8E48F96462D2B8B52AB2455C7C142E442E4CF643B367ED466A30BA97D91C1C8C0070E05 +139: 67004A5E74598981A79984B2662FFF8C8F49F8FD13C8A841F68DBA18DF68015E9C1EF38D6522D44F89DBFEA8AF48D2D0 +140: 8ACD05F9738BBB176E50C7419A05C8200E1BA84B5797032E025ED4B55D7A61CEC4CE3662432A4E0BA938D8C9143D5254 +141: 9963300C0CE5F2D39C2B899E47988BFA914D2EA2DBB972C15B3CBC414E41DF3A2FE793597243D46CFF937F41C0D83136 +142: FBEE0F5E072237D19170999D02BB95F6F8F48FD0596A982A4FA2D1273872226398DF57A63E1ACCCF6343415DF387D89E +143: 32A65099C47EAE3BCD0F68645845C0171417385B15DB5E5F7BB5AD965F66C98CDC39B7534198AF70AD5739C8A2F2B8DA +144: E936DBA2CED7F65DE3450BA7ADBE1030D7AEFAFCCE0CBA94E671422790B45B49918319A90FAA7692780CAB4301D9833A +145: 1E20D13B4D71ACBDBD5D2AA129E98929510C795119EA8A07EC63917114315E2756B45E7AE42E1A44C5E410ECBEFB3661 +146: 02A0571C5C3076CACE7F061BDB108D7CD9C7EA51D0FBF1D00F202A0B5C87F22CE687D1CB15F798ED164CAF1CECF92CF2 +147: EA07C4A1DF1E5CB26DC7A7BC76FE518890FB8C424AF3B1C76B37AB21445D9F7FBAB73C7DB35E85337A8F7A0D55121F34 +148: 7829712876378DF986A63E4616DCA38DBE8833B14760168897AA808B96D8FFA4460CA3C1A9B674A0FC13E0625537C45A +149: A7CBB3CD50AA663BD2C4520CCEEF123F7D314870806291DA26A59C003D041E46E6B563670F27BECC5F838A273D349AFC +150: C14E7F70D28E17D3546EB40EE96D239CA5EF7EBBBD0DE64B964C145A5F2980D408A6AC248D651E4583E25093042EA286 +151: 19F87BFFBFF4B1E195612F41E67E1D4CD0393E73FEDAC1C36550C2B1A7323D3E7D747EAAB9844F45F150F8DF0FB72E80 +152: 6BFA3BC29FFF3A92FEC377AF8508D4823F4E87072D6F2F16370B7DD30789A944EE5721EFDA7ABFD47A512EA2D4984BC0 +153: EE10FDDE70EB0A11462DC00860AC4756B21C83BFF0066C431B17BA57CCBB9ED018E8058CB9EA44CC11952C3C9BD15F09 +154: E6A72B9D2A0FFCA41C3122C767A6FD9CFA04CB5B1D1D94B79A0B2C592A584F731CA0523AEA8F2DBA35FDEF74CAF165EC +155: 59118A53C4479070DC728D94BA36D211F4ED5D35F1B69E4DFC0543F07326F982D2B81DDB020F2CACCAF1E5E9832624E3 +156: 63778B7830A3AB7421912A52B3CE9303A53C2A6655291042F428691A633FB9FF173937A8D8F59B21F72D490F39A9AC06 +157: A702F15D9483BB767FC6BE9C3BFC64732277CE936AEBADE4022B24B4822BD1B0FA1213AACF7B4506BF8F330FB7643955 +158: A3FBEA92041484F7F46B380462C5114B0243A79FEED89ECF8E6D8306D60DBEBDC5FF1578EE7E94B5527EFC5707D2B7D3 +159: 1EAEA2602E0B6B328D008A5325C5D4F9DFF7AB9BB5D36816D3EBFEE733BE664E35170506667BF5A24D00222EBC5DCDCD +160: 92E4D41594E15628BEF06CA61E644D2A686C113BF8E3F9A8CD2CD8261B11D01B081EF2941D5182E565B70C566D461B23 +161: 2F08DAAA98DE6DB4E85B81E32C651D88075DE18B7F9C3F633BE1F29C89F24968525B1B357DE80C6EA8D9570E003C75DE +162: 5DF64E7960C755D40BE78F0BB7C1A185DF8E505F0B421BE23563472843E3B5CFC7DA0F40908BF56C6F3A6244581C1DE6 +163: DABB5DCBC32FE7298C811CE22025E9B1C0B87DA5E7931CC3614E3EE39112206DD8422A5504F11599436B806C9108B01B +164: 31AE27382E330115E009474FB5AC750A278B79EFF63755E323E3478B0761E5E946DA6D2436DC44ADE9F4578A8FBA9896 +165: 6804CF0314E455F499E73BBDF4FAA22CA49020330E74C55B1CF4A2D2F4C57D7149B41916002B2852ECFA0713BA91A094 +166: 7FAD2AB0972D8059D4306F0B63F25D9ACBBD8FD95EC8199CFA89D4E227EEDE6052AF0C53C703C7E319047DC5734C9F4C +167: 4635E654950B173D3EC81A8212C1E65605C85835CFAD8607C829786855636A660D6C3045FF17663DE465BF2B152879E2 +168: B40764D8F066C897C3A8FE54BF21DA294C6B3F1B35255F68C8AB325AB3B94EE8AE2E5173936C17FDC95C9B7C3D3D3A58 +169: EE7E424C550F79BA82043245C3B7D0AC32A41B876988C322B9997D87F0A0A1FB8263726B953B43B4616285A239994936 +170: 627DCEEACB27F39552AB683330A67A316B2F53842BCE8056FCF3988702955E3BA72FDEEAC2CDB53F13627858C1BBC51F +171: DD13F3B3E9C79958B20D1986650A79CEE1343F9957FBEEDE18B2FB5E543E3B8839EDF7A57EFD818129C4F00F505D2112 +172: 0A7061C0FBF1EE8CCB0F4A1D0DCAF2F200291AC06830F0E38D05E1CA2429A2BF57DE5BF8DED5A7CECC3A4748FBCB880E +173: 3635AEA9152337FBFA4C2824C5499B9F3FD32061297C4121FB0A44CDF5D3C8D4C6EFD760A0BF076DBD1801C416949A9C +174: F9C58AF2259C719B0B852FC68299AC9F17A802B49B34CBF5FBEB85DB3C68767CC34DAE2CCB536FF90BAE49FDDEC0CFE4 +175: 3541EB8602A4C84545F4476749EAD54E4542C4358CC78CA5B7C8B6BCD9E9A3E649CCB243FE0B3D02930CF1CB7A507FFD +176: 4AA26C2565531A52811D30A1C59152BDE4C61AE2CEAFEF9642E7076EC44C7EBD50F1D1853761B4097D985DFE6878A701 +177: 32F1DD0B4AF205B4891E2F43D772EB5E4A5EA3658106FDC8B8CEEBD2D502F8048B583610A419E1A60020C8C2A5A02FC8 +178: DA7403FE3C3D3139893522C5DC8E4F615D36A0F7B7B8AAF150D1337C8DFE70311544E54880D1C575D664E9AF979984D9 +179: 39F8450D4A946ABC6FCA804AE11935CDE846D999BCFF3091F1E6944EAEAD504F77139A919F915D34DACC13757CCE0157 +180: 45CC03085CC3278B8337096BEDFE6F1D645994690660F23A358C4EC728EBAFD6966C487B9492DE217C17823B16589852 +181: A2150F3BA3349E3AA0ED97B1A02A58F31EB5731012393EC68846D95465F3B787C272852B6945B1CC0FC2B3BE999E0E46 +182: BF9392B085B3C5FFBDE70A3FB64AAB36E39BDE4816F1C9B2A608269336906303F7DFC15F4701D3FAFA5D7A8BFE316A1B +183: 21BDA179D5B80FA6B9444AB1D1F7E06F89F670DA4A038E7E83E8A63CEDD44AB6C1D069D12C6F538B45022EF3160D396D +184: B4216CDE6BC1C27A5C1EA9AC79E85776740F93440AE438D4D9CF51BE8A83AD44565586FBFB58DD743782724A440218E8 +185: 5C3D5C00381BCCF77FC2103C262F373592FE34C2B2895F54BCFD1F9B3C87026288130822B2B451D716FA9D4D7FCC93F5 +186: B927E3777D4BE05FA85D0CB707FB00F08C576777840634531795CD3D6818F192789977AD6425018025E10F5892FFE708 +187: 9C6976E1EDFAEDC32378C8D2758D1B0C5B287C500442EC5D19560BC87C75FD2A7379A3E64ADC1421B7410D1ADD6456BB +188: 9C20482AB71BBD8E985D7891499DB526BCAAE11D2A42DD72FFED664D7BF7F254C2F8DDA2E340690FB83E1F5C58378B72 +189: 7899D5AF410188A3D0D0B12D52437313D786CE7959FC4D194D6A3ACA85729B60ABBDC58AC40731B9E833505156BEFE24 +190: 4F958FD1841D2B790A199EE3358F4DCEEC64CB34D0886EA91AA5E38F8600FBE13DEE4D6A55AC1273B3730CC62A3611B7 +191: 66572F61FE6C34B440AC00C8D3992B9CDE3FC465FCBB193CB7716B53E8032C743718D4F8245D94A22A9AE125795589E0 +192: E7AD49861960D1460A77F4F363341ADC2207E205302957250612C7E903802AF5C9423414C52F4C1AD55CC1C8B2922EF8 +193: 62BE3AA3A9D08CB41F2CA3ABCCB96E2E91A248E569FF58F58C8BECDDA5B4B25FF46BB30EB37999E6131D944CF3253302 +194: 3E082F7DBDF5BBA5F52CC870F2C6E9C63DFCD5D547B183F3FFBE392BF0A1F8F4970CA21E5B9B4306792C138D6B2056C3 +195: 5CC36277225DA2EDCC6CB603EDE9C629E5DA823E6D233AB7833F70FEA2878B2F8D08F361BD5B4C7609577329784D87DD +196: 9555EEEE1EE60EE981CED3FB6BF74699E5383436ACC283BDA0F9F6FFE20561ECE75ECE2C5A82C0A158C071A3BA59CF58 +197: 0B975D2ABD0551BA987680C4890F80DF93AF2292FDD1E47322560B0AD3BDD38A67D3A78497D78B3C38DA597846C5159D +198: 016CE0B8AD1628C7FBA358EEBB7C3667FA93566086B99F20EA6F87FBACB320E7BCEEBABF0008550A59AC1E6C3B4478DD +199: 3D138114480946A2AA1E2B78948B6BFEA95F53BD8BED81ECCE166062A67FD111933A696E6FFFBFCBDDF71041955C98A0 +200: 7EA4BB2534C67036F49DE7BEB5FE8A2478DF04FF3FEF40A9CD4923999A590E9912DF1297217CE1A021AA2FB1013498B8 +201: 80C399C975ADDAB12FA20B3C3D04F25218DFEB678B5A87F9963A462F5474732C7C5FAFE0EBBBAA94662789CC10C9AACB +202: C27E28A5B6C7BFBC7ED372B5BD2555EF1370FD96043753015B3FB9AF31D41E7189D4FA8860B183703560A298D90B6E75 +203: B792B021B3FA904B5948AFB4E56BD4C40119AC79E57EB24C32A7BF0A1A889313D816997E35F2CA192B34D2FF9B05ED9A +204: 7828C6235E2B8AC46E4BCD7F7C7554EA81B5BFC046133EEFA0C4E64AAAAD7115B04EE09E33CB4EA1FF476960C64D9A36 +205: 06678F9A2F238953A8D6646F859FCC3BB0C29BABA669D7F891142C2C3A0BAC1220200B4EFF8C17F5D79E261128C58248 +206: 0FD4448A47B6620FE90551A9AA06DD991AB13DBD2AF18A4F17AE4A9A24D9A83E7653D5F5A2C54633C42ACCB0E5915A35 +207: AABBB8857DE60BDBB21742DE7ACF7EB8D9180D5D0AED23B7F708F09006C6FC56CE85DB87D9642CB909038E70C15C1574 +208: E1BF933A4F32AF56C929911284F9B05B79F0216EF3A150483D74B2D4DCD78885190EB1601A320150C860168221C6BA49 +209: 9074B187372B0535738D4606AA0478BECB5251EAEC961699C2795FC028D641D60230532C8F6A096FEF419A46B0DB87FC +210: A63532A684A1851050E2861F7AB94296D131F768A94AB0019A941734E13842EBE8AB1F42DB4D0A84E261CB4707C74290 +211: DDFD64103308F0537ABD8D4F2209D8920CB42FA9ECBC93318D438C1493FE11B6134DDFF95DBE3FC6B8AA31F833E305A6 +212: 044ED56EF3129D29243665545A59FDC12412E137E1F55A543AACE511F9F86CD3202E3D24807B0FC878BA76223EDC6F42 +213: 2E470AB58A76690755AE6643D615039E767B84AE9E68480DD937913C44AC2350A27FDB45D6FADC242BD5F84809D59E2A +214: EC0ABAC477B5AD5F6B11DB4B699283FD4668D84C2BA7F8DF90A5BF83C0E1E224623F0D2BB3F2DC6EAAC5E41436035D58 +215: 9FEBB6C1604914837F6D00F9AE23A3459DEDCFD81EF755B96A3CC1F63E4CD2E67F5AC2605E594DCD2610F4962EA6C277 +216: 3873BF1A102F1609A624F1A096E420CC459C02590600808F7DA5E3FD49F5B491269C1116A2AC74185A3105B5E9606126 +217: CD7E8C16B59BCEE5888DC7FFC28E65B72570B26F3A0C85885BBCE81E5A6B63D781F953E497399DCB506E8C4F5E237169 +218: 3D24BC91A4932BF6D631EB7698549B03E7F3930662B8527EC122FC2C7AA41E330862102557F480273864FF9B06628BB2 +219: F0B21BC919A3C6089BE3CB7CE10B55D76E31552E759F0465086A89D1FA435E2671928AC329ED7B3D7C1D7121C158BABE +220: B32F9A1FD8A97E6E8E701371BF1A017078B26C3F4C58E342ED455B2557BDA16EAFAC00AEAC1ED7328C65D7C1E227FB83 +221: 5468F1B9192244C738EC20FA979F746CF6929FC48F69C79F43E46859AA022CC42E65203CE7CF77A039402093A1552EC0 +222: A58151FE3211C27651693B55E67CDE0E886BB0D8F2B6D9066615124CF1DA403DFA014C6F19C1B10DE7D3BBDBD0AB9880 +223: FE73FD3276463D27AE6A9F54877CD9BD3410C4A40381D25F5A915194538CA8C4F4B6154ECB9CE8B1B7E23953DC64F664 +224: 0D4EA680BA7CCBB9D88C09F6DAA6BC655BDB0B2A1C8C3DE0BE895328027794E223A45969AE594C7A21FABD5C92BA6530 +225: E6DC0E64DC804FEF91563B550A83BE7ABD50F51D3BFFA785A428EF9436775DD7E3A589793CB2717DC6BAD8B531CFC922 +226: DE168B8F03C0CE8143FD14BD2D294476FBE8DA85B09BF26C5D846E2D19957F87D6FE150B278EA4B3BCD36AE52D251FE5 +227: F34472A4DF2D3B529CE56E9D2A721A839DB05DB7B66BE8AB7202B024DEFD46ACF493973DD1FE88D8EF6E70673914DAA9 +228: 1F5E8FFB4678B3889E7FEB2288358A5F1377A97F76674A8D3E5EF39D185D02F6A1FB60E43BCC79C31E6974B37E74E50F +229: 190AFF1D363C413BEE16C78C544AFD20678C7B1141D3917B6942E4D1486EDBCEE90EDE8A50E441219ED3B11BEFA09F18 +230: 66BB67FC2BDC1D5E8E4366958804F459AA689E04D5FCAFA8CA222656D568B23E976086E2BBAD979EA0973AAA1FADEB8A +231: 0E14C70C02205AA29303D24D6491CC84B648EEB80AE9CC2A0997B7BB646ED32C69D2AE41C0DC007AFCEC514D7B04BCD6 +232: E38C413F3FC12764415F39A9F3638AA1204D3E818A43CF2EDD9F2CE01936D36C6720CF5BE8ABA362F92AEC81386A4800 +233: C3ED0B3697A84B388AA83DFF8EAA65F5BB12EF00315AD462F1F6D85D410D021BC32E77ADC763A254F7D9F1FB6EEEF1F3 +234: 8DC2C3F8C13C43709AAEBD408A679CEC524DA8C8F4157DA4BE551EFD687A395B33577728EB73EB498ECD0AD2487058E8 +235: 8AE817F2056903661E4EBF37D7293200D8BEE7AE0CADEA671E4987624A43712FD2C392E37C17D8E81EAEEBEE8E96653F +236: 9A622BC18F3A09C8BC1C8603B55260BADF32AE7ABD8DCB6CDD980C5E7A5B8A38C6D287A63FE88567BB9B0481743C06D9 +237: B74C6303DDF9F0AD7CBEE923F7F7F1C7FA52C84EF609F2BBCC07B9911C12F3D1A9BD818A9F36EBB40D4B400AA4D0FDC1 +238: 5B1AD3420ED592FA3D593435CA6EBC700583AC5E3CA2876887E5F190EC2109A1E6DD06AFC6C9D7ED0E8B0272B7F9114E +239: 2556CF077A788C49BB6D600F4A3CEE635C4443832D169F761537AFEE2980742B9F34AFBC87F598DD0AEDC4A826ED6A73 +240: D64769AD58F5A338669B935F3431E5BEF31667D0A2437BFF78F1E5275075F434FFF675F9833EA04AC4E5C2E2C2C99B8C +241: 3264CAD70D24B53CEC95269B980DAB85A30D24CF8BDBD68F0FF8A45C6208F05723A4B3270CD095FB8B2D9A4167FB3D3B +242: 4D564117E87700C69AFE5A4D90FF50DEF8A54A9BF19382E4290290D2BEE101355EBB2DFB2A9D6D044A6D12D6DDF7BDBE +243: 6AAD71FA5D5D7B63FEA64D94E211155B01F8C9E4B3D86C3B9C014CA4BB6C668037C4739A082F37B2EC5FF6D85F0A58FF +244: B36D529E55B5CF0FD3273F204F798E21DF533BE466AD1AF35EF80082132640493FD89A6CF41CA68AED066E93181A9EEA +245: 78814E883A27D6ED3A5B122260059CC00D31B8A0E933F3C377BB99EF33F47B13B6AD825B740784BEBDD9917879C2DAEF +246: A7978D0C79070B208F070241867476AE622EA887D26B0F6703FA8A455F411649D8919E6E12C540C59DF60CA9C05684CC +247: BDC3E02D31DB1EB7F04CD9FB8876AA9C7CB1852BD3BD62F56E062E216BE648A34FD327B84E3B6339F44697470711F661 +248: 9135E6D4B1E2356C3DE16A85E4AF57243CF6861DFB6C53CA13D9481371AEE285B75DCCAFC1A64499F1B2CBE4A3CD82C8 +249: D1F9BAA4007BAD437509DB6F6DCA22086CB786026553244A6F480C3A6488F7E26C416C6AE85874477BB5563BA0AECF2E +250: 49E5B7521794B6C73004BADF3D039F4185BE9BF8499FB08B9C8FDA2186B6C4BCD280AE2D2051C6775C19ECF1C776ACF6 +251: A7534C1716B59AB1C7AF3DF0AE32F22CD02A1823F61B318F36DFB536B8EF4515116A099F8DED19B00EE7B2D243539960 +252: 0F01FB323FADD9380A5E4EE6371E8BDF6FFB1F70C4D4A1B5E8BC9B281582AE0531AB354EA9F58A96568826F6172FC75C +253: 145C9D3926904D8418B75C8D645D43AF651684AE7FAD885AB46141B9EAD2D9727731F44D5AAA0204395E020D1B52DA96 +254: F663682EF7FA3F300DFF0B4D9C0D2D126F2BBC164F3B88C8A2207C3799464ED2086CDD324C1E88DAA6EF2D53CF7C190B +255: 98D7AC796C4CFB5D98A1C323656A4BE8AFAAAD168E5EE72B6B7A3FA3260461A043E27243120D41584B58F1AE4463121A +256: FFDAEBFF65ED05CF400F0221C4CCFB4B2104FB6A51F87E40BE6C4309386BFDEC2892E9179B34632331A59592737DB5C5 + +Hash: sha512 + 0: CF83E1357EEFB8BDF1542850D66D8007D620E4050B5715DC83F4A921D36CE9CE47D0D13C5D85F2B0FF8318D2877EEC2F63B931BD47417A81A538327AF927DA3E + 1: B8244D028981D693AF7B456AF8EFA4CAD63D282E19FF14942C246E50D9351D22704A802A71C3580B6370DE4CEB293C324A8423342557D4E5C38438F0E36910EE + 2: 80536C6170DD8626DC081AF148D39EC2FD5D090CC578A76647E7903FD34BD02E4333ECE57B0E24FF116F43429B6FF541834BD40EF0C8D3563ACEF5ED0FD254B8 + 3: 8081DA5F9C1E3D0E1AA16F604D5E5064543CFF5D7BACE2BB312252461E151B3FE0F034EA8DC1DACFF3361A892D625FBE1B614CDA265F87A473C24B0FA1D91DFD + 4: 4EC54B09E2B209DDB9A678522BB451740C513F488CB27A0883630718571745141920036AEBDB78C0B4CD783A4A6EECC937A40C6104E427512D709A634B412F60 + 5: B7B70A0B14D7FA213C6CCD3CBFFC8BB8F8E11A85F1113B0EB26A00208F2B9B3A1DD4AAF39962861E16AB062274342A1CE1F9DBA3654F36FC338245589F296C28 + 6: 2F3831BCCC94CF061BCFA5F8C23C1429D26E3BC6B76EDAD93D9025CB91C903AF6CF9C935DC37193C04C2C66E7D9DE17C358284418218AFEA2160147AAA912F4C + 7: B7C0B47F42F7202BF7D28D6834BEE365FC01CE3F0C8C8DF24B4D940406C2E9C230BA88854E946EBCD786C18C748969FDF012362B7C96400604B6058950FEAAD4 + 8: 8A414C5860CF1BE7BC8531442F69A65EF2ECF0B7CAD9994BCB407097EB74CCB92E93AABD24BDE60331123B4D900684CA7BE6027099D4946BF537F4D6C6DF3D82 + 9: 8B5E5E7FB6530CCE1BFFFD1B1AA338D3282E8483319BF028BB674BB6AEB8200DA389647E3D8631503DC5C487BBFA7D074584493615B036849E0242610EA4758F + 10: 0F89EE1FCB7B0A4F7809D1267A029719004C5A5E5EC323A7C3523A20974F9A3F202F56FADBA4CD9E8D654AB9F2E96DC5C795EA176FA20EDE8D854C342F903533 + 11: 8FFAEE0CCCC162851FAF051AE38667EEFD423C0164C50055F8ADE00AFC3705E3CDEB9900004B0E426CA66AB63AA3B99B075273F44FD37C22A3555C6FD1F37CCB + 12: BA51B2A9DA2F26FE81FC3EE11524255937EC6BEC48835EB437C598C55674E15AA50F88922DE7584332A5E4D24787090CB14DFC3ABDB39C55AEDF6EE108F95354 + 13: B6E30A4016029486F9205C5D141344F885B3DE2468EDFB0B870545F1775CE82597C2A40462F385C957790C20822D9E920EF1AE230878D6B23F221B0182879CCC + 14: 79D76024A31CDBE54CA951D264C46E78F6F5AC5DCD018BAF89AA586333BE82B2D5CA2BC64B99CA2A99D95A984F2DC0D6C07E7C96059DD346BB3296ADE3AA33C0 + 15: 4236736D08F26244E75B51614091CC2C2907D5DD162F8497B14D58D0D954A777C8397549BEE468F30E480252D9B893175DF7D2BF415A128CCC79407D9D5FA536 + 16: DAA295BEED4E2EE94C24015B56AF626B4F21EF9F44F2B3D40FC41C90900A6BF1B4867C43C57CDA54D1B6FD4869B3F23CED5E0BA3C05D0B1680DF4EC7D0762403 + 17: 7B9AE840AAB8BEE45B038CE398D15A8679DB92D0BA46FA67D1B8177986E41EACDE915C6552FC2AF8678425B8BE81B57E0F7EEADCC93B56C58DFC38B4D33BF25D + 18: 0EF6A8C19E19A466DBA3139E2A401175BEB9EE01FB56A8FC11A3E53B345F2327959F6DAACF0CE6121987D2491251DCF550C95F6026F93A1D96A0F4164CB1C642 + 19: D6221AACC88CE14EB7DE0F15F2260EBF4294D9AC3D75B87465EF7AF9570C959077860EBBC5C8153000507CE1E39AED5D007F2286210EFFD26A118966ED15C143 + 20: C9AC4561A7503FAB9C6B71C843AF6911438550BCDF4881EEC18DDA06E4D8B820CCA9521DFA9EF47298CCF6308FE4C4F2F5E34DFEC2ACB78FBDC04D2EF0A5A09E + 21: 73C5D58B05E1E6FCE4299F8D9294681416BC3785F51E402DCEDC0E30C0671DD48321A0248CCC13389A012B52513F1B5BBF820E91EB4F616928183485B4F1EB22 + 22: AB1725C57427DDF93B34AAC62C26F3FF1E49CAD30DD41AE7B5FCE23894245E7E889E0FCA5EC076F247DC7E929D72FB965B45688E57D8CD54212714A17480BE0E + 23: 456F6757A82F0589040996BF88F28E61317C358135A9AB6E96E22F5CA68E2A6438D13D176B01157ACA1FEEDCE3C1A6D5C3A9B1D5A471691917392FB94D0834F7 + 24: 5330241E6F01A49B21AB0D01A9C76AD662E97A325BF8E24C4EB82C6F3B7D2538ADD98F62307F36F900F3934861B80FC9844B761BE15460A1B102C26CF0410E83 + 25: D8DDA603DC21C20A6DD3C6A4F380C297679F035D27BBA82554D02E1F95ECA2EB20496164F96DC4B84B9BB0942B96A3796AFF6125BB9E8711E2674B440176E91A + 26: 81E5A3AF460DD2881353D006AF37478C58AFFF16022441226FB04439783DA920D09FD03E19F45BC82F82735FBF4F2E5F588F11AFDB87B69DB91123CBF05F7F2F + 27: 25AECF7D241EE54E668DDD345582DB777F9F631B9D2432CE4D32119BEA3968D9FA3E184B135364DF62247AB74BA7B86AC3542F63D9F18653D86B9B47944AB96A + 28: 8A372F722A922E29CF5CB22BDABC6D284364F376DA355CA65BE36DAE2FA6F0335744CEFA9089DE55D331AE64E9B2F1037E73608B03B978758A20A012924AB235 + 29: D57C54ABB87AD2D518790B81230DA336F551A0D89A57D0A3CFE2F4ACC55B4B210261CD1482BC436F62D3FC96D1536B82A2E93E9A3DB5CD0F1822EEACF307460C + 30: 6092F1E76F04A5926F6FCD149B18DC9DBE8581BDE6D2A1468145280463472B636C711FF61F5CCA84FD2F044697BD1DD18340B3ED0A131F4BBA35F839A2DD9E0B + 31: 0674A3CDF5F7C18C1B7524C87C36037F3D0267512D11E052F453DBC097CFD52BC331950880CF904656C70758B2E25E21FE2C7E0462E861112A2DC9D0636BBAFC + 32: 3D94EEA49C580AEF816935762BE049559D6D1440DEDE12E6A125F1841FFF8E6FA9D71862A3E5746B571BE3D187B0041046F52EBD850C7CBD5FDE8EE38473B649 + 33: 301F1CD7B25B097AE4C79A97E92BCE359D1289F6754E76B71E7617A06E7783A3CC30F5290209BDA3E6AF239D0DC0F3D1CD4C5E866F4C5C3209EABBD7AAFB8058 + 34: A8C7114B292CC6F46D73824CB073CAEB23EB1ED5EBB37F064A0A76AD452D936D1DF41433FFA337C3F7CD53F5CC00658ED0633252B69DE192E61D9F002B0F133D + 35: D2F92068E07C9AD0572693CF546FE75070E574807C02F5483A31B8CB2105CA55CC6AADAAFE74977F581CE90F43E2AB48260BD7E273D4A83C442EC4871CD88AAC + 36: 1A4133CDFA6CC518387D392814029744D6FA71122EBDFB70059512B89469CDB9D9B5E45900E99E67DBA54B4708036298A94835751EF583149F06AB272B2BA355 + 37: D30DE790B4905717C956A95F60D9ED5948F9E509BA27607E1C5C8FFE35ACD83F719AE04D63364C0BCB72BA529AC79C321ADDFBF7AECF7CA3CAC840A372E6F6CB + 38: A25F5D4BFFBC5F0E3D5CACC3A91870866D8C2D22573556C9B9FA0D24E1D68C55EB42726B1895DF8E5E870DA33755DDBBAC130AF2D96D84DD0D57761D25FDB64F + 39: F44001A74D0B087AF2A143B778DCDEC1554BCE5992C9672E3D0F6704D022CA1E78F087543569CB99D249B820E683138A2DDC5DC178D585167FDD269D17396A89 + 40: 692F36EB114060FD04CD38555025251DF985DDF681A0636FBD290EFEA6FCAC5226859373F3E10E8CB07AB5343547EB0A543C18420D70527D2BBD90040F8DAA52 + 41: 4B1CEF875A025624398CD06DB876EF9AB34FDB1B6A75A07CCB591D9B20EA66E24BAF323911B5CE8B67904945A36C28630B36129939D23D26218610CB049D7AED + 42: DB3E80F11517AB797265829371F245A7A0A384E36A8D43E72852C8D47F8CE37A178475EEF44CE8BDEE5AB054F47EED502E76D49B9F4A5AA392077ED1E6F43EC1 + 43: BD08551AEA7759911B37E9D45748219B47C4EC17A2D2A306D9B8FDF982A9E3106BDC1ACF3F47D383B6D16E85910BBA08128E35EE578E7C55F2E9B9B59F611298 + 44: 3BD8A709DB9A4E0B874B113564B11EAF8270AD1DA3A9236DBB16F58F43285070344962394C2231B3917401924A3F688150B9A9ED3B410547DE3F56450739592C + 45: D0206C8577202C617592B47AE178DA867AC7DAAE4E65B912C771C5FB09585FBD10C36782064E83ACE749BE27045508D544532B628F67DF00A6B7DBA9775D3E06 + 46: 745083E5994158A0FEE4D849012F43A822D19F068AFB327B372A7A8BFE8347E579DD29424EC95319BF75A24B4DB4280D9C16CEBFF5D930D61D34909061A478AE + 47: 3527A5E1E5E5953EC57F309C6513C34405531603372BA0DFD5725E68B9510E5090CC6B317B2E7359D2ABD5ADD353AE1435B85535EB5B0B8F2E09D4DD1BAF3C8B + 48: 622BE417916F1B0E9CE8C952171B11B6D2E2932D6197CC17431B9FFDF03FD0ADB69B08DEDAEBDD0F94812BC2C670C894D65165B31D2F2879532F2C14453E6A0E + 49: C2EBDADE0368F1DEBE44F8E1B77E66BC1C25E7F0FCED7784D615811E2C01192DBC21253E10709D0BEEE746DE6EF93CF65AA39BA29551E11F602ADDD27B196019 + 50: 5ACE0640F0DCB25871E1925F96BAB48162D692BA134C9C7052A37FDFA4895B90AC56C7FB0E7FAF155D147A467839500D980E9D4ED1CC96661177ACF0BA8D4167 + 51: 5D43600C04E52BF6524CDCB9DAD89B1C7563912E7C7E2CA3D34B27B3C1D07D85D35EBB7A65AF0434155AFA3102A580AD557468CC23EEA1E151BFD4EA817FC5B2 + 52: 38D7538AC3E51DDFB6724F57B29A5E46D15A8C08FB29D15FB0681A4315B03FD6747B85D0EB2B9E5FCEC709F365DE08D61A1EB363094BF292B5154671D15D61DA + 53: 2DCE13E5882A31F7396D970AE72E89FB59270D78BF7B4579D0855C4E8BA231D23E5566B77E79CCDC1146762DAAA74F49D82F9EFC0D4FCA891E78F9FF86C61300 + 54: 6D7644DB575C5C238DA02CC4259996CF163A3A3B5ECCC4FC62442DDF01AA05EF0C4EDBE3E6D220DF189C984AA55726A4922EFE004832F2D8887F0B8A9267DB40 + 55: 6856647F269C2EE3D8128F0B25427659D880641EF343300DD3CD4679168F58D6527FDA70B4EBC854E2065E172B7D58C1536992C0810599259BA84A2B40C65414 + 56: 8B12B2F6FE400A51D29656E2B8C42A1BBFE6FCF3E425DA430DB05D1A2DDA14790DEE20FA8B22D8762AFFFE4988A5C98A4430D22A17E41E23D90FA61AB75671A9 + 57: 92CB9F2E4EEE07C7B32B06CF4917FBE54365F55247CC9B5BC4478D9FADA52B07D1C302B3959D0CA9A75A629653EA7C245A8FBBA2A265CDA4EA70AC5A860A6F3D + 58: 23417F93C499DF9EAAF1BFD6A62AADBC711BFE56682943DE5D94E0DAC32F732B763BE28C32AD5F01CB95E5B322AEFF8494B111D7CD8BAB50E7C602695EA6FE42 + 59: 4ADFA8837BB499605D38716F8305FD50255DEA2EC4BF3EEB07560B3C93B5E3725C5A598277A32502CD5C8AF6C88D55756DEB03B69CFC278FFE2BFB3CA202B0F6 + 60: 981A245B249111B4CDCD565AE60C9DEB69FDB552B10C932E8D0635685904203C37CC65D674292405DF24A589682B8AA69BD0E16F666652290BD79AC10E3A9B37 + 61: 15DDF1E434A88F27DEDB8435ED837FE4F1F3BFC5B6FD387A98E93D1C83493D326467C7C53EFEEF158F6B9CC2081267D9761A32A5094399754C0FD62F4C72371A + 62: E08026874830E0B911F5CC51B81599A4DC21204F5C9381CB5A0DA8F452EE99D9FF7590B798805C2743822572E6D2E47C2C1F2D428EF3C28D05297BEDC5CAC4EF + 63: 9DC9C5598E55DC42955695320839788E353F1D7F6BA74DF74C80A8A52F463C0697F57F68835D1418F4CE9B6530CD79BD0F4C6F7E13C93FEB1218C0B65C2C0561 + 64: EE4320EBAF3FDB4F2C832B137200C08E235E0FA7BBD0EB1740C7063BA8A0D151DA77E003398E1714A955D475B05E3E950B639503B452EC185DE4229BC4873949 + 65: 02856CEF735F9ACEC6B9E33F0FBC8F9804D2AA54187F382B8AE842E5D3696C07459AAD2A5AED25EA5E117EB1C7BA35DA6A7A8ADCE9E6AFE3AD79E9FA42D5BBA8 + 66: 371DDB96ED5BE6521379457AE8ADD707A866732B629EE00074904D73858F3FAE827D84E503F3779073490B274E29D644D76154FAB18945222289BCA798BA6438 + 67: 96A693A22256D39A0596802319CB7AF997DB4BFE311577E38F8423DE81C567A96775D063471438F0982EFAA6B75B4AB173D9D3B3D4762030B522FA70DCF3B27A + 68: 7D8AB6155AB31F29740042D82788A69E880FC642E600BEDFC89098B9D2F4F98BC11141FD420870958810295100DE66F50C96E1E4F6489DE98F9BF2D4A9AA2237 + 69: CE561F8F679B4EEB1DC97DB0F72632B9DA1C5B5C0292CBF0662CAD981374BF8C9A0BE1355657FB18196F980E6685D52FE601DD45C6B0FBDE7AA5C9D52E7E5973 + 70: 10164CFD162CABC44C56D76D369096D759954074B0547FA7310C3388F0FB6BB2AA295FAF1E22C44CF59959A37EFE317698BC29AA718D57EBC831A14144F4E48F + 71: 658B337A8FA873C73AE4D19992BBAAD10E1325AFB4DC8B5733F870761429B4243A7982AB375E529C1FBE6339A48F9FB9E8FD6A568F9CAFE640E102B9F398A330 + 72: 4EBDFA0E60E1A3E7FEFB8DB424A5C3A52365F325EC7F51389A4955EE3453BBFC94692DEAC3FF6A4E94105C27D632DF26250FF37314C882FDEB65D53534F8A961 + 73: DFE9D2A6B0AD5DA802D695B3B91745852C97B0283D9A033F04D79D2CAD4FDE50048AC7D82BCF8C402B109E785D39FC9FA0203F7CFC620EE43577688BCF3E69BF + 74: F21869E1EAC3774F3878570AF0DB9A94F464373C1A92E097D180A331C9028A18A68BF4624D8E620B2216B03709F03FB6CD10004F77433ED605B0F771161145C5 + 75: F1F928D322E6852301AD6FC901E91F2156A3CEEFA204044DDA3B4B76A63692DAAC479FFC6D83EEE3BE028A1F651D3520758DD395A1B251E6C261B7CCE86D0481 + 76: 37954BB11B0AAA67F803973DDD2709A73B947D0A5FF8DC46C2D3C6918C87069AD0DF907589F3026A94B071E0F00230F00CF74AFE8010C24E489CC8AF9B8BD646 + 77: 140DB04BF46A194E44F07F6ACEE8326573AA0591F8370A79DF320093C45764A2ABAE531E5A742F496544657FADFEDB7F04D4BD74C347AAE237B5EE59921BA87D + 78: 6D0D30BE796B6E1039739BF24CE26D8DB954D25813F8D7F7444617816F93FC7488B71C69D96D77C65007EF6A2BA313AE0739302395F3D9EAB0244E372AB96961 + 79: 2B92E0D915BC7D56215651BC9F769544C55E2A27080EE726AB14FAC0A43AC51CD378EEA356DFA70EEC3C9146E08E98358C61FFFA3D477CCAC35FD6724A44C23C + 80: 2CED9E743D84F8EC5664A99C6DE2238464E61129B3C856A7FD2CE08B185F4D447A829F287870AC5428114A7234E41A78801C19EA5C6246FEFF961DC6A9B55835 + 81: 4462303D052C70DE76296234B72BFF1AF173E7B63D1CC0E26C518D103BF3BA78D9AF4BA88013192CBADAD83801B8FC29D0838A144AA3CB721AC859EEABF019C0 + 82: 880FEF79B74C109F030F3FA6FCB82DCA034528CCA68A23ED1EE4133C10B3E443434A37C436F079F3F3A922A8547549A39854120723791519DBC166936C239AA3 + 83: 12DE996C9DCE152C83BE6C0E69C66633FC4244B412066A5FE7CEAE27BD4A109FEC95332C60E87DF08A1C714D9D2ECF28A8A81F1CDF8BB3CD2CEF71011BF5A5DC + 84: 748405D18FC05F0AF7F61E0CCDDEFD8055D86826038C77F2AB230F7D97C89D0EF09CE82C4352A7491729C9FD704B279449D0DD7D86CD2FA52EB3B5A582DC2057 + 85: 746653CDC44B4C86B29DE5B28254BE9198C0271249F0690615B05F23AC0456DD66CDDD13D2F22924DF530C78FDFD3699E38E29A550E2739A803FD1FFBEB29E59 + 86: CED0B3E4011A6DA0415C51E37996EBBC5041861FD1584E3D948E1D4DBD7F8673EF93910A10797490DD5C62245EE7EC03D7CE8B8C38FAE21EFAC1AE6056AED143 + 87: FD4BE7DCAC6984196FABA1D88D0FFA9F33CAA29FBAB3E38CD3DDA7FBD94866C944F91B405B3EC613044E4AF11BE7187B15D5AFB4067C54FA09215C3BAC4FF080 + 88: 46836D5A579D5158B9F49D6EBE9A43C9F4A55C768869C3D542BB615FDBAEC8DD34FFCC40288567F8C5E9363852EFF44FEF0EFC0904BE178D3F78EA1B61B9E98A + 89: C05B8745D68BB9647E411E5AA1F924C2C9B96E7DDE71D190A3B8709ACC2856ABFF3C2DBD7093B25F81C6B9883D377E721968632FA4D566F7F72E1109BDEF2D74 + 90: 647A0E15CC4BB5EB3333919CC828D68C5352F1FCACE6964F23FCEB46D0D2408AE896D3319B202EC687F3F9E55126C05705FDB909CD8CAC88304A61B69ABCF65C + 91: 2DD1C321E3CFB58C2E883F5DC3D87F01936ABAB3F1F27648B6AE563333E3852BCCBBCBF4822230E8F0A0DFE32AB6D8DE92A2B8B2271E17DEBEEBF00D83046B75 + 92: 38122D8324807E25DC8A74012CA9C0292222604303CE8B66D7329FEA394D85B7BFBE0F656895EBFD26BD60A3B553A6E3E4003276157B31B3A47779E1633D89D9 + 93: 27FFBA5DD09485E141B659E218D2924AB0392163CDE296D4109F3AEFCDB02241CF0952F0A38E2680D5CFA35363391A324E12519B58C04E8ADF0E9C7A8B6E1712 + 94: 69DA55F3BDBB1C7397CB382B7E8075F615794F6F8453313C0933D33656A3BAB07C42FF977850625B11CA302494497B0EF3A51F3D2EC2E4AECD24BBBC661C6513 + 95: EE1270F6FE6223C19AD4814F0549B54C11AE7B43A8F3418B0F7BAC42BB5B093024DD4F3AB0C9AF5FD2025D50D5B8DC3505D8F754F98AC3237344A7C14FA50815 + 96: AD8ED48E056378B1AFCDC0B3D5D3936AC825F96ABE0953E9BB85B00EC16084A4F0BF12A2B0B73F0A29ECB9841A1DC7F003456016203E891ABA1BEE13FFD19BF0 + 97: F6EB6972CB5FB156FA20A93D8695AE1D9DA8BBDECCADBA81123E7ECBE917596B51E4A6CF9E1458D882B76B33AEA8F3286CC7CA1085F09EB3DB9B9263095339A5 + 98: 40C54D468FE760A7094726B9EF12A98A1F0FE5E7112137ECFB3A88DB04B0758EC581603EFDE3610B1D76AA879EC31933CB6AAFA2DFC559C59BA31425B091FFB1 + 99: DD0324C4DCFF798F024A32A13063A05AF673CB5F8F03E08A0D931406C868A86B5071BA711F6DA80D7FD2F7D3CEE1B7DC12EA456A1EBE4CBCB25ABFB27492390E +100: AF216A7122D29D6A7DC7B89C8B41C111E7C9A00781D4A867A1D75110B48A5A9C92A15D1DC2AEABB53B83BCFFC50F44CFDCAE29DC9984C8C84FEBD0189322BE25 +101: 1FD96E1905B024D5FA883B3BF76C00A0235EE6386EABAE4D9602B5C5E5EA81FE3A1DD0D81BFB0F904ABD4DA7FC71EF7A2BBD0DC6A766902021CEB03D2578B204 +102: 31B75B047B1214B915EC56983E284D14C214D567F149EB467A1A324080AA0D80264ED771E2F91104B2642E9A8312C0C001652CF4E55308A870A77ACFA088D7C0 +103: 59B8D11078C8B65C5DF4F39D1C532BDB9C6E8F2EF121B97DC5BBC29CAF76774A7DDCDCE0F3BCCFFD4779E57D9B23102EF596B8B940480079355CDCF7EC52D47C +104: 3F1702458BA7F28460E84A032BA160430126221AB5320AE028387B60AC53DEBC42FD169A23714AAC3009D52BF9F9485C0878C06A98BB42D1568E7D038234AD23 +105: C8DA7ABB93D370CE8BA6F2B58F91ABBF1302F96799544CCABF52D5D1EAC3318AD4EC853EDC99CF86DF9341D6D794B57B68CD1FBC5E37C03AA10297F9828D5D0B +106: E1680FAF315911FB7588AA2F02D5F96A3FB02F60DC3C93117B97E4F00E2CE6862DB06117A6627B14B11B9E4C61BBEEF09134E1684599A370C61721A3B086942B +107: BAEE728FD37CBE1DAB3FD5A922E58111BFBA9BB47E107909FBDEECCB1812DE27D2D87003FC6F9F67977ED592EBFC734470CD1E907858F555F21EAFD6E64F060D +108: 891AFA38F3094E487BADAEBA012F11D3109EF19B858394EECA4C7F0C2E8FFBB3B88A7105C7D73E7252E67BBA518ABB6A312A7B8A11742D31BF53267CF3B09E5B +109: 6E6E3BE3956224A97F813DE55B3594EC5E2F4A43BAB873D902025699AE58FB43DB71DE1DC159E83F7A7EFFC19CA5A03C1EFFD27B026EE9AAAD92D1D58104D3DC +110: 51F2BA331C24541EFEC042CC66398D388348C4FEDC3F77A4DDFDA39752AE2880C68E0465C15B07ABFD93E16BA635AE7CA7D7E144018ADE57607DE8643992F50B +111: A1A111449B198D9B1F538BAD7F3FC1022B3A5B1A5E90A0BC860DE8512746CBC31599E6C834DE3A3235327AF0B51FF57BF7ACF1974A73014D9C3953812EDC7C8D +112: C5FBD731D19D2AE1180F001BE72C2C1AABA1D7B094B3748880E24593B8E117A750E11C1BD867CC2F96DACE8C8B74ABD2D5C4F236BE444E77D30D1916174070B9 +113: 61B2E77DB697DFE5571FFF3ED06BD60C41E1E7B7C08A80DE01CB16526D9A9A52D690DFBE792278A60F6E2B4C57A97C729773F26E258D2393890C985D645F6715 +114: C02CCA2EE8BED9B4AC74438D4E8B39619347922DDA5CAD2BC3EB9E4CFD4FAF7CC7EB9F6B21ECCA2C55CB60D11EC450390EBCFBA18312E49598D2BC52020DA9F4 +115: E528ABD6C315EADE09A981E4861F6148C9DD4F2FCE0EA54CD3E9796F17033A3751FE9A223AA23CDE0E051A10C2BC27C0298BE97CB87C7110667A115B6D30657C +116: 1B0BF23602D272A06BEC3E86FC675E16DFB067B2AB662181315C45733D191137454BA22713B51478B096DC51D3FC7E9730504324655AE8B7BDFC184118933D36 +117: 12D5EBC3016C77ADCD01F1DE3F792C4230DE67C0B50102E03FBF3B6B80BF913CB66C3E72530C644719003DB2FCB15196803812D89761E0B781E8AFED7268A35D +118: A3527C4E62349394274FB15B30BD95FAC27472E1E521514775D2E667A5480C5367DA6EE526AAC8D0D1226C33EDA1358091C93EC6B1B8464739D25AC4795EF175 +119: 43E497279C2CE805903A33B54B746EA92D607F7C4807986C849823B81097A9099B5896AC7CC66DF3A93EDC8A91B6F3971D6C7F5688DAF635737760BD080E27B3 +120: 9636708964C5FF6600510319E07BF3FCFCB1F4058FEC278EFB677964BA1E140C1632505452F802E99BCF09DA3D456DC3868D149A0788A730E49D239CE7415145 +121: D5D17F592D401CB111FA7C34CF5035BC08EF6B2E0D3E64DDAB08430DEEFC8B9C09C20EB4E8F98D8EBCAC6F09AA2C1DBB7C1B3B2EFE792377CA6600F703643700 +122: 0EA053BBE2E72264AE4F54512C621C733120F777D3CF8FCD8A7CC1ABCAECFB9BE93EE821A15D19467D249A27961E474ABFC433B8C7132321198789D5C2A50896 +123: C64291C217E37E754F6F57C1316FCD8A7C2AC2426E86786FFB69797C0645848CAC41DE345FF90B72FCDE918B7CFAEA4D661687E6F737A088E9296EEF4C3B4F31 +124: DEF8A3CD4921127815F4D1650FBF8B3EF16EF724A38045133749B7359FA68BDE3EEBC9CB5190FB6720EE3D24473286FC046DE0646C6C0042EA1968B48FB6BFBD +125: 6F3581DF30AF789E44C7459356E1C248749B4A5A389759DFF37826BD278D293BA2264BB808A71C453E22A2962DD33A9C03338AD060B3783713EBA8CC8B43E2C2 +126: 2681BF910DDFA680B7204037294D00D0FCAEE84A3747F6E302A16704B3B08EFBDA0E57DBB8E61E92348C8D5FC5A59EAB74C77949A74C7740C30412A9FC65BF34 +127: EAB89674FEAA34E27AEBEEFF3C0A4D70070BB872D5E9F186CF1DBBDEE517B6E35724D629FF025A5B07185E911ADA7E3C8ACF830AA0E4F71777BD2D44F504F7F0 +128: 1DFFD5E3ADB71D45D2245939665521AE001A317A03720A45732BA1900CA3B8351FC5C9B4CA513EBA6F80BC7B1D1FDAD4ABD13491CB824D61B08D8C0E1561B3F7 +129: 1D9DA57FBBDAB09AFB3506AB2D223D06109D65C1C8AD197F50138F714BC4C3F2FE5787922639C680ACAD1C651F955990425954CE2CBA0C5CC83F2667D878EB0F +130: 90272B89212C81B9700897F611F13AC1D291C33A437000C1423336B4D962DD39CE23413160F023963E12F4CCF90D2762B31BFC6818EF865E8A7CBF918A94C1DB +131: 325638D30C9F63D7CDBAA689B7AF8D23826BFE8593B361C7042D3293926146C65C2D6092F20DB5068262359860B3E3D502B6034B9EC8E7253A1FBE4B2007B77C +132: A3FEEC20C69CDAF1936795AEB9052DC525A26F5559045FE458D4B24697E260BDAA45BE8C940A06AE39FDC1F9365F32BAD7DE824FE7722A444E469C7BC198B7C1 +133: 3F80B7BFBFC9D45073FDC2ED93F7C19F01E4D49CB912BD2568F248561F9C9ED1B6762270033D9F421C977F8BB8B4A73F9A99D580C0245DD4F64AD35D68C9847E +134: C292EF04844CD7C3E477C2C2FDDEF46FCEF97E5DEA7955FD4F418C7B4114BA0CA2CA230D0F73A585EAAAEA9277D72B83DB74AC5E887439A225C105B0BFB5A38D +135: 9F0DDAB7986DA54E65EF6B536BB4F7BFF468E0F310803DE28D3908492343E4CAA855B8CAC7409E3A8928E63B9C5D1CAEA7A408ED061809DBAE1AB1A67BA1B926 +136: C58867D309CA48AF74B4D7E49ECED514C89FD433F9DD842F9B50FFAA6C7810BEF35348D00D26DCBE28122BA1CE33D4CD00D09BA76F982A598B8F65790368AE59 +137: C8B1D6B4778932BC21EDDBBE4E48F7711D7E97ED5354DCF11BE98E3110510FB007948C288FD2F7AA71B2E41C86330DBBCA2ED472D15B444828C6DF4282815879 +138: F1C0C057C974E4C27E497EEF52A02963D5957EA02C7E1CFE06423048799AAF74475732A7352220A914BF32EBA6A0B6FF28C77D25CC3CA1AFBDA89870F4EB55D7 +139: 092E121F2C7A2621AA36AA9B040EFE4435DD649E3F336BA82788D57B9B164184F5B5BA644DB4076B46FF9F3A6B9F58D775CE94FEB648A372D960471A663B74E1 +140: 406A5382E9A563E60FDE5CC47F52C6DB86CEE271BD3974AC6E274A1B8C5A7EB369A9B7CD312C301F891D4E3A601A80B9CA06303C53CABD5D3B7834DBC5108470 +141: B2D3EFC2390CF7A1093B93C52B76D0DD74BC277F3D67A85F41635F89E923AEBC960B2BDF8A13860CF3083AC3FBA13D4FE5E426F144FC988554E89ED7A0324748 +142: F1F7100636AEEEC8AE93A2CAF1F4852F192E1EC1AF13697765CACE58FB40B9D9AFC3BBE7E52EDCE649F53C1BAF653CA20E75D3E4AD549D05EB33A68DD11E1898 +143: DB604416DFD0A7DC509DBD2C83D5FEDE5E31D641EE6C14390CF599CDC7D841660AC700D3DE4BE35E07006B724B7DD1BAA21EFC3CA6D346B3B858384FF691F913 +144: 87AE00E496649511C3BF947A65805ADB5D237AE8486CBFF01EBE52D5D5062A99DB3434EC22A37DFDB4CBA1A59AF1FA5825EE3DB2A8524BDEAE07F3264989B85A +145: F442BB697D498F2026FA2A5FFFF9AC5ACA0052F6D200E10805104D91BDFC71A3764CE0277009229B9E7C945222BD7C9085163987E4CED02ACC7420A96B0F9587 +146: 1061588877909CAABFA37D4915EEBD6E517B8D3EFD5660F872019050B3C1465F11FC9B44E72610219F3F5F21772933F101D9D58B5C5F79FD7457F95749BF11D5 +147: FBB4C9BD6821A04CF154DCC7A7507A2C655739F3636B69E8183418E2C33D951DE6BFDF2C3CA603694C44DE44057665EA4835281A2773CB8A84965BE02DF1F3E2 +148: 08D54B05F901FE95EA5B56BA19DF9120C66AD004F98BF8FCBDA9DA0874E64978EFC34877B8224A024DE12D7B926B5D83068E8A704EEF0F738A5061E5F8462F54 +149: B79F53A5117503B5A0316F801B8D448079F38CB90CC39BAFD4DFE169E3C931D622AF7E26835C9AD4DB25C0D6A684E7DAC4B88B475663E05601A99EE9FC8922EC +150: 2209CF6BA43F61D7E579651EBBA0890686A9CDC1E045255494DB0BC732C9512ACBF72158D5738FF63B500AADCCBA000D25A521D41AB4EE6D92D38E8077B79C07 +151: 8236F7CFFA68B49BE5C38A7A1BB67B745430D1511A08EF347383C32AAE1EF4AB2E7F63A20C9D8E5CF2198B32B7BC79B470D36BDF12E7263D669FA4AB8605B75F +152: 228BEFE5788090066D493CF87F75C666BC3C75E0B7BC63E80D38340CF9176251C6E185992B244D4A5B1CECFA42128DAE6EC3ED535AFF039769E364048C442DCF +153: 59171D498BF80731E2E35D0A32DA356419E69B8BAA5B1195D690CD8A5B11542087A007D8DE3FD000BFB03A0408C08E92A0C7712924373FD67A65218E4A4E0F68 +154: 4F94A8F6A136E49069C88DFDEA9361B34D68FFC25724F836CCB021BDB74E0AEE9DDFE80B938A5C12B01F0F1CC49C500FE7709C2090F809D9E0256FC93D93122F +155: DE5E17A668F75866262BBB2089C9DD86775100C77974161DF46BE02A9578855E7C81C77263105C473FD1A2D55483063970C0F643CB25AA4B4AB45A40888F61FB +156: 3314001C825DFD2CD1CE08C746F0BE5C451027F0FAA401431AC84FAEA51553EFD9E0646FB7E9B94CBC672DC98FE9870467C176AA648EC72BF61334B13E479E4E +157: 3EE80B1422E3572B46F7CE5841998BD2B6DF3B591FB5E46851B4D54BF572A17DB5963A04EC6AB98BA07C943475AC088B4D201AFD684F30F45C8037400A7C9510 +158: 3743FE18BD6AEF36887EAB7BEBCE36D5D3B69DFC306B58B1E8C6241E81A9D38425BA991A29C3B07D4F4B9C5CC762B2563C9E5A05B199CEA5833D9FA0062D161A +159: 7F9F71B086CC6D6B63052767CCD6D0349C076289F63483241CE105076B7549B3187897D45D7B5FB2147E54F056530347A1F9265E6F37953B5941272A29E2FAC6 +160: E09CBBFD3DDBB24755CBE8E51C8BFF1BFF36E571EE72E6C99DDA6D507AFE3C562D437E8612B50859AD5CD608424DBE625E0162E6CB7B838F20E7B2F93F40ED91 +161: 2E2F91BD5FEB5C79E98ED97C513E17D2D97B02A844780A0190264773C3040A2CF07FCB0E6424B7A0E88C221BA3824C1906FC1647AB40DC13E2D0CC507CBB6BCE +162: 8D4E87F66B3418105CD5583A92A2D2EBE8824E1F9150CB872FD3DA9C93D382C08065C818E1AF9B25875B142E70676D9A525D901EA2142E42D813A221D21EAEF5 +163: 0518E420BB5680B74367F8CFCF7DD32F3AAE009A0067FEC22456CEAD0832BDC2A60D8AA7B0A2FDCB9072C0F1171772BB665C0B28CD184609F63AD53F89597F9C +164: 247197FBCBEE77B8EAF6358F71A49D784CB43FB44D99910B0599E69B29E31C4019E830F322D5A7117A996BDB4D91E5CF323DB354E902E4DAEE8057B3F78ED5B7 +165: 35A7D806AF0C8167D1505B25EDB565E931864C453BF60AD7B6695035D7584E7714E21F377B35A5F3A69878835617B951977C209F5F3C5967B7DD9BEAA75A7CAB +166: CA9B60EA8DA2D0BBF46742E31AE882F5355688B071883F690AE775C4D949DED8077170F26E89A18CFC251662EA8D1FF43F5A5F28E3FB41ADD741AD2E28341A79 +167: A861DC64C745B0F5D3EFB2773C51981A836024BC420B1FCC564E03006163B491126AD8633FADB6DFCB25C2EF92FD82823FE2C7F1161A78C7766B5E21F96BACB8 +168: 1EE6CA0866F227B27678326FEDA4CBF59934AB0EA2E874E9EA233AA5C67141A05C1B4C950044BB6C9B9D146520C2E3779AE44187BE0DC1CC41FA7F72500B249E +169: DA1032057A25DA7EF987A2D7CF28B927D3DBD956979679F5A6BF4EA20FE1080BD8AF2DC8B1C7E236E7601BD82CFD64DFCA7D03A03087475ADD57EADFFEC2CA85 +170: 22E41325474C7C7EE980314D7738947E9CE3A970B2D28BCD69D545D5E795ED50A5A1839021645D000CD4779E181A65974171C15B9B08B349205B87C150688839 +171: 5FC5AD1B8B7622C4D17CCE23679FC7E0CCEBA00C1FD7178245206F866A6BB198F26A05A3D429E2C508DAAC6D0F698FAE6C0DE7FF971EACEEE84813110672F3AB +172: 2264F674AFC9743A46180CE4E4AA6A2BB33D6BF2F62AA14648179400806D718DEE8FE57DA48D88DF5D57B42087BB2FA62F833BFF87B6678606C6336CBCF34B3F +173: 65E9D1187801C74FC23C4F19698F6B93405C681B93A80D23D427D9F2CBFE63F7E2959B2AAD6CD7EF6E987A5FFD585E1BE8E314A1D502FAE80215C5331F8FFC2B +174: E0436B17C2BB096B08698F4CB448287D69322C34814776E0B1B21486A2D5B6906889A5B198FDDF699AB285BDF58783DE7913075F86ADA977DD35FD09AF336E21 +175: 857BE6485722B4BE445B72C7A15A1D0BEE6C7FB2AD541C2B4F0035DFA1EEAA10D4F0BA5A124F985DEFA53D0A0554BB258B2832BC2CB5B7787D812E96A55A93DC +176: 7B2298654B95CD00307D8D983A0079CCCFD89E5788180CAF352B6C965B9BB5153C9DE25C4A0CBB5E578859660696C887280EA378A2E02B7C7F9E6CC635509EBD +177: C7ADECC928EF065C263A97A273CE8CB30485BFC035F2FC02C78AE2AC6B7F7ED20E93897C0994CAB8D584EEF9DD475AA1613159A0C862FF179C67120F6B4C72C7 +178: 041A03CCE6696653ED5F367749AE1AF3C2654E8A9C0E70E467261E60023876C7271CAE545D114C32D38DA75389525CF0CF1FC0FA9A481ECF43FA0B1F61B868F7 +179: E652E4A88EC1A9C4678F8CFDBFB1D758774600255165E2B4DC15F61C18B9ADE14C5ACE7E8AE72D3062B7F1787583C55B14B347F642344E71D6E00FD6F4C56808 +180: 903675FD8C70BEBE9FD0DADAB17A638A2DD8089AE63114E36D28F4C75D951D75B0BCAB5247803551862720713AB45A932DBE141E48E9BF3ED9E76201577DDD43 +181: 6E61016D474D2AC2984E4EAD44ED82B7129B0B7FF0B9AAF5F45CA68B0529A736B846626CEBCAB9E7CE374D744E7A09C51BBBC746D989806F1A00703A002542FA +182: 20085D4717A204E896F10C5F7E1FD429C9AF848FFF608A2C46D3738EE4FFB944381880A7A455FEC6A1A21754D9ECCF3F1390EA22EC17FCFECE2B86E361784045 +183: 37216CA069259BA3244DE3933A3AD5F35712F0AB7B9C81D64000F0B91DD4232B53748B704E7ED0DD682A77D84BAC1B943D2FF7A3DBF5FE33DF455DDB10D11632 +184: 1F2467A57006D96FDC75A8BDAF98907AE72AD330C0418B06513C33D86DDB800AB6A51738DBFDF1C44676038C094EB5F309B5B590EAAADA4DB09FE7590FF04888 +185: C45893F92AC3E3AA3BC86A9ED659797A7C7DB949A66552ABD046DA2AA7DA9E52FF8BA2673CB44B2CB0481D599EC70020B6D5079296F2C19DB162DC8CCD64BAFD +186: 9919574ADE9B8640BB0EF45F98D1DB6FB7242C433D86CF6D4BD67AD14FF15D74A13F796429E312BAC581552E6597BAD2792F31B2488ED300C6118891ADEE9FB1 +187: 034A92D00A172A5F0CE717FC38AB8D68019F500493899401B563845EB604ABE0907749AA830F91B53AA7C89DFFF86664F8B123AFF4721D790A58CC22F36A560C +188: 54714E69859C60B07C7FE34859C855A37A82204D723F1A695F78D7765CE906D109FA6144EBA9E7E7A7D8343A99495E72D160DD468BEFB794D97659B8E2D8F1CE +189: D6CA476F7E68095DFCEF4338BD6466FCA90DF78A17DE9E29111D4645B0DAA0C6E98F156C0EBF9134BC28EF9E0EA67E6D839027DD5CB084E9EBA899DD3413E222 +190: 86EB8C026D6BF090636F01F623CD98B960D08E521E44697F364BC1AE1655B9AD6FC3EA38C929AC9A244D18E697342594F3E7DFE605954579AE4042CA69E65AC3 +191: 1F63EE615E9B809E3661C77B5029C78A92DC4BE3CC4DFD8BBE78DC7B7D990BC717238004969A8B854CBA04B4D9B30AA1A1964264C47F23D9BCDF45C74FFFD918 +192: 0351F475C711D068BE7B0395D65343B5E249FEAA3C3F3B6B87100C50306EF0340F60EF36233F0E6287057EF7BE8634BFC4D46B49E4A8F2CC4839F42F486A16FB +193: 16645F9C0ABBDA602B7436DE3B1C55AAFD1E844057D51EF80A96CBC2FAFF6E3B2706B45069C90A52D779E101793EAF4C9AE85CAD0A5A394164F0BF34C189A2A0 +194: 821E46199F4FEBD9C118D49B1CE9FFE953113EB6E4E33DA9E39C676399A0B3F792C2990A9F75D729E58EF750857C07336526631CBAA5EE0643699C8E7B7EEA13 +195: 64CB83ABF2BB0A94451F2B9C3EDD76E4A15F9D1F9EE32C0607F5E0951084377E484A8259B3C64428293396F78E6674CC3C027CED1BE12F5671D328D131740770 +196: CCC1A68114DF54BF467EC49CB15CE381EBA7E6FF06A93EFC88F442F8A35827D5DC6494A4F39E8423167CC1C3269A3EE6AE68825FE3E2E40EAFB75C8D878FF88B +197: 94D38693F1B1A8F1013544419C5B3BA0CD79B72478A91CF3AD325E4C3CDCE092AB667572233A4F8DFF132401968BC74C553AEEE96D530CA4E5F6D427F9D2C422 +198: EB080E256FA9A5D51C3DF577509B877563958704C0F1DB645F75CE24005D3B12503BDC26FD3A66E8F6882D3491428A4932EED6F5F58532FEAF521BA5FE05B70C +199: 9A43D7D0C42D7B5409963339C9D9805BA59ED8A63DB144165A3C759EB9F5D756E6288308DD2FE460CC50DE26E1A1C1747AA165FE6C8A1FD5B0F7CB1373E28CAC +200: 986058E9895E2C2AB8F9E8CBDF801DB12A44842A56A91D5A4E87B1FC98B293722C4664142E42C3C551FF898646268CD92B84ED230B8C94BED7798D4F27CD7465 +201: 9FCCC4EEF7571A2BEEE06981856228CEDAF3BD412E777F4AE8524B81C373FDBC210795C1E788EE7081BA42EC3FAFACCF2F386A9096AC719E6565B4E384E390E2 +202: E4E8BF0BF40249236FB88C442E6668E3067ED6001189053A3A81EB755798911258E25CACF7282811DD5E5147811844C4B5BF52FC24A6862BCAF9407F2E38EF5D +203: 317ECED703044C1BCE944DDA7114DD1E36244DF6A533790FAADBD0B8DDF1AC0D198B593F0479A038198F4B94AA6ED294168FE0EE800C02E769EE78ED45249945 +204: F5FA1EDDE359173067E463107FCDF00EF227CBBA0EC5EA02EBBABE2C79B12E793B98FD3A90A72BC26240D994F53DED65FE22C6FE87EAFD01B8478D1E8569A882 +205: 6323E2A8E380CE86433D5B8FCC5E02FABA4ED7F9CE5BD194F7CBFA36F65844B61A7BDF8F131CB4B28C56ACFDB99CD84830557C571FD369650B4608376BBE4FDC +206: DC6BDB69D1C6111E280F993635BB59CD6E7B189166DE593B71E194C5F218D67B00EBE0D028E944976D6538DE410C4D86A2B6F272BB94FFA590208C644F99240F +207: 2428590D2043634FB10268435EA90ABD082D45317D2C54D065529F15E180438AB18FE4CCC9129584804EB04EA1CFF646FA881878520BC01AFF392B6D7D9C0369 +208: 1A29341BEF679E5351911809DA190BAB8E665A9375BC2D477742176A70A6BE8ACE4A35645BF8DB97AB9BBAF1F0313004AF8B4CF10ADB26AC0198AB1D45D05C46 +209: 0EF4FCF3B2010921C58056B2BA367B4C09F5325E6AE9AD732AB277281D4BA797A847B1C6A74D81523DEA163AB0E556FB5102C14E8CD94AFBAC0AB0A921BF1A25 +210: 73C65AF2A53E8860BEE63AF0BD8A457B0AC8D3C5D243FBB1BC3D67624727CC175F3CA133B26342C3401D75DCDDDAD9A692D9A2B1264E90CFFD4BB9E6E775DE15 +211: 18D3DE049396E2EA541E15C31C0EF0E0BD90CCC6CA35663856B94F6F18160D616667C55F3ADC1B33E749F60BE50514A4F3BE48ABE2E18FCA10F85ED0266972D5 +212: 34DED45ED26FE224E0C5A66A193C11A2CC0786E61D421034B3BB16175019C95453F20BDE865DEEAC5C2BB5C86544641482B51C4E61D9DDACC238D050CFC35776 +213: 025D211B55974BAF086B139D8FA1AEA75B627CE1AB894D52F8769874557BE5944D27FD4BA3606266BC7F50D1734436C53D4555A1D2DE0DD2AC51D7F2FA373867 +214: 08CD521B1F13440D57001F30BDA0029FD8AA17FF26AFECEFA2CB7EE1812FC79A694ACD0BDA98184154B72FB7CE305FF4897F466CBB3972B4863FC88B3DA52C28 +215: BA3BF464071BDF124034CD122451D3374AACFBBC916C858B93E191006235F4D741564BA1DE70372269C122D360121DD3D427853BA76C6B450BB46F4156EA7524 +216: CB0B3250639B4ED947BE0C83EEF67D370DE76AB901F607F68FBF1BF8ADA15984DDA7BECAA4D7FDD55FBFE479EEE3F5ECC9CDA7BAEDC9DB7D35DC227411DCF20E +217: 8AFA4024BD96BD50323AFDCF92A7F3E7BFB4C927108CF81C01FD378F61C55D850020DBEB88C6528B8FC141C37EA4852481C14902878AFDE51A7F1EA1612D0324 +218: 27057269EEB73333A1A8059D6C9D6FD5AC89EC26500F6F9838CACEC20E93F1713CF5569E820BD80969547D77E56AB0CBF57F03182EF45AC8BDDE114470C6DDEA +219: C79C3D4A4608C7CB4A3D0C14B28CBB96364F44DD8651F36D908AE502E547AD7AD5DFC10DA26CA26C6D9E51CD40F6D7F1BEA0A03358967D867A97333DA8ADF3AF +220: 9DC3B1EF11D85FF8A57330FDF91D5B5AB142FB89A72D880DAE476E020755C2F3B4CA58C9ED36239E8807C059BD66F826EC517B7A44187E7216E48B683B567076 +221: D11A97FB7B967E90C2D39EF42EBE49327CD58EA6977C84275B01698E322DD97024A40FC3EEDD96207310708F737E81B79659A6C7202E96BE7AA34D18D4026F63 +222: C9BD62C0FCE47736ADCD9275B46845E4ECA23B73678693FEB8E21909EB8405D4B057AF2AFFD7E667E047A07E6ACCADC2A58D7360C17689769DB009F0A7795560 +223: 7FAFE6ABE7CB8C109B18A14BC4FC2E4FFEADD55A43AE7DFC58D89B9CCEBB4467FE4CC163FF6EB16C8C71B8EFF12E7891D11D3DA2C6DFA8152DEC52B232267B6B +224: AEC37B2A1157708142BDACFE77E5204174F539D86A12730BBEF6386FCA098AFF2A5C31EA1AB21D3B4537531DDEB27CA9DAEA22F5CC8C9956B2F2595F53BB931C +225: 6B005CC923D9AFF56334CFC7A5E3ECD70E97C4247EB372A3180E7DC5BEBE676E72E2FDFACB74277B70E15D871819626F46661285DB04B3F825C49EEF42391B5E +226: 509B5C993CDF61F8F507A84BBD7D6D7AB090970927400043D39E5F47DC23AC289F5BBF9D3246EDB174D9C5D72BA7A066DC13171EC15FF9508911464F8730D395 +227: 00A05302C3A60E58C4C52847F47379212A918060931A72BC660D88E7BF5599DF6C38DE92452B4823B4725BA3EEE866235CCF4D5903E91714CAA230C6D6EEBE45 +228: C4FA5EFAA31CA205A732FCD5DEBED53C09A4F30C5BD9ADF27F8C1DCD4B2730925BB6AF176E2E680B2BE325F7DDEFBC9EE6C1CBC4F0426ADCB5CBF18D1437EE6C +229: D125006B8107FA63C375A79AAA0EBE82017372B7CC65C3157CE078DDBDAEE8C569BB84FD8490F2D66D15FE73C6881245761AB2B1D4F056637ECA70641745CDA4 +230: 01C7D098DCE4E40A69DE14682587FF2A40BAF9833BDCC6413AB54DB0E64262F290D584CD5B21C6558682C50E1E27BF53A18A16D72ABDE878C3522156C9F04DE3 +231: E863DA51CAE09500F589BE05CAAD5788587E2017907444D76F547D6F30632AC658EEB8585733BBB815D2E19EA046369ED3B81AA773FBFFAC316162389E015A71 +232: FD8232F7B79BDF9CC52FF0D5DE1C565E9D659BF19769096895D182A88028C1CDB7387DD240128A7ECFD2708EBA7E9E3C676D6E2A036E1B993940F5CCDF1A736A +233: 3BF8572CDC7B825CE7F3222A3DB87F1C52FBD1A8229B957ACFEF2047C560567483C479603A3C0B0F1B2DD265BEC257D1A32C651508D7A4DF501BC015657DCAC0 +234: 23FC530B031136A17B8B2FCB55046DE7271312EE3E77851FBDB05F78A294815CB2169079168E07647A2BD5D05C1BC2B1EF1B64B929DAA1F9CE723D448C936FEC +235: 83D10057C7FB494FAAD289B4FE5F093DB2A0C7D79A298173DA735CD5063232BF9E5327A7B4AA795C99F323045790B554476F37EB9D04FE3DF40C047E4113A720 +236: 0AA201EDF4124F421D4515554A1A642E3B9D18C70E09E83A886D6F0CAB0750D9BA1FFEB9C587F3ACAB0D8B9C1D83D789102F0E2A6CFF885C50F485929DF4602D +237: B85CC52981751513B917F58305AFFDDC7D901CB3BB1D1BF5DAB058DEC9B8CDCD2DAE543D73EC6AE0889C9D785F9178D207059D994E1C80706EB28AE65AAA100C +238: 068FED72E55444AE108EEFBDD59A96DA4AEA3D81A6642742C38BBD4EAAEDA6EE21FB8702C2F95152F1F997A5F40F06C54619481F2EC343AD33400913D6FDB4FB +239: CB4C7FD522756D5781AD3A4F590A1D862906B960E7720136CB3FB36B563CAA1EA5689134291FA79C80CCC2B4092B41DF32EBDCB36DBE79DB483440228C1622A8 +240: 6C48466C9F6C07E4AB762C696B7EEB35CFE236FCA73683E5FAB873AC3489B4D2EB3D7AFCCE7E8165DBBF37ADED3B5B0C889C0B7E0F1790A8330D8677429D91A5 +241: 4F663484EFCA758D670147758A5D4D9E5933FE22C0A1DC01F954738FF8310A6515B3EC42094449075ED678C55EE001A4FB91B1081DFAE6AB83860B7B4CC7B4AB +242: 81A70404857420638D72672A2DF5A49D52B9F9F38B385D8C5129D6A2B82A682CFEAFE6509266E4B00F6B6A07341C2F64E4D4F2152583ED143E3DCFB14C1C216F +243: 31F655A1334E1A45584F12A22E03B09E3C69ED0E1D0FD573AD0D56F9C86862299E333ABE78590E97EEAA5C2FB14DC9F34FEF6DDAF6E7A9BFBF68CA6631195CE5 +244: B62C5102F97E5C4D7554790A4CF53A58D3EF44C83142D6E009BD1F6FC8F3A19AA1B89DA8DD9BD1310827A5BF662BE7CAC750C48E6ED91313E940D7D9E5EB9C22 +245: 380023C0BAC4C9524FF6778BE80CDF195E36FCF460E8CF1BF04E5C2FE08E38C35F183FBCDC3726FF26423F351C507279F6258F2319EA1403B6C8A3DCB384AC7F +246: 473FC167C7C4BC40B17DA039EE09FF3DE884879557E40C52C1981AC419CE021A090BBAE014822D05714077008988D74FF151C927AA43E88CD63FF2CCD2012AF4 +247: 006086E61959B1D66C72E754427EAD5E1D6C02D8409F5C32B2F5AE448F54682B504A1ABC0346CCF39BF66A8C7B69081E886B47A7D0B02291462391C95351EE40 +248: 3828B2ED548CFD0B74BB34A1FEAE030E267222198D7E387E7FE3ED503905A25D4C3301A9A47E78372F685B05847062476C507708CDD75580ADB579E4CDC79AA0 +249: C26A7D5BB103EDFEAE2F1201BE58AAC127F69AE378DB04156074E991745D4AA5AAB3BA064407DFDA8D34E573B7EC1F9F37CEF01ADC17FAF393C262A09F2C4736 +250: DCF82307195035A668097514FF1A10E0BF0E802B4945A702D2E17AF6DE1D3D9BA49616DFD16D802054B5219CA37884385E87A713B4EF5C7FCB69661C7F56D5E3 +251: 46049EA0DFA5C49429E15626AF4AF2CE0A9DD2F308B99BA6E6E3F3088250A146870FD0B53228D5A1F1BF9859480E1B7A3D3DA180AEF4D5D41BD2951C4E19426C +252: C0A1FB6C0A65A0D1AF46A5FE86C8A88E8A86F83E36317F435542927C98E74833C887CA3AB5E792CE5E3E21CC6C6AF437349F5A66FAFC4DA79742491C643901F9 +253: DCDD20CD47B7C7D011E9DF7855B08336BD5007C4435208BD3B914D7E503B8399164A155697E68A1B88A0600BDCF847A114D98FB773C81FEC817B92057A6998A9 +254: E2DA07644DAA73B66C1B6FBCDAE7FF28E3B9024F0BC5408FE02C18E3744CF9BD6DD54EA7BFA1F6F3A81C8560FB938FDFF9A38A29853A3A819B58D10213A290EC +255: 15025C9D135861FF5A549DF0BFD6C398FD126613496D4E97627651E68B7B1F80407F187D7978464F0F78BFEEA787600FAAEBBE991EDDB60671CD0CE874F0A744 +256: 1E7B80BC8EDC552C8FEEB2780E111477E5BC70465FAC1A77B29B35980C3F0CE4A036A6C9462036824BD56801E62AF7E9FEBA5C22ED8A5AF877BF7DE117DCAC6D + +Hash: rmd128 + 0: CDF26213A150DC3ECB610F18F6B38B46 + 1: F069A435C14A8D4B02A7BBAEE02D0BC3 + 2: 48456EA1CD4C51DD8E1130F625DA4F8D + 3: 6E41F2AE95605779C74CB5ACDFB361CC + 4: 0C7A6C73E99A5C65B12D3EF47ECA9D2B + 5: 3B80361C079D1B67933455D00AB1428E + 6: 0F74C4BFBFC740A027B1D5BB9CAAAFA8 + 7: AA54ED5DA34CE9205B64D138538C0C1F + 8: 08445C3C3E71434DE375CC2071430EBE + 9: 1FE0AE641DEC6F8C172F0E27E9E73B9E + 10: 4E8152B7EA8F7A31D8649A51389260F9 + 11: 0F851C98C2B997C2459B34CCB209E481 + 12: 52D27461FD7E095EE3C6ED43BC24EF23 + 13: E9F3489135F3D90EBBADF9F916C34920 + 14: 36D527B693D6531A5E4E15BDE9E4A670 + 15: 57433A07CC200953B7FD440253D5E476 + 16: 4A91FFF90756026A90A83927066EC911 + 17: 5A247C26BB1BABDF1009B6B4951FD76E + 18: 002DA29AC9F51F065A1E371660BB67BE + 19: CFFED09ACF01DEC9D3891033C0973953 + 20: B78F28AD3460C99D428AF24E2787EFE7 + 21: 5E203157AB6BAC57660F3D25FF615C95 + 22: F128F5DEC3A24AF34AD3E7F3883C8051 + 23: 2E05AF10A6CE9AD1E0C0FBCBF69B1C9E + 24: 67FAFD9A5CEA5D41863D03AF2932C5CF + 25: 5ED7E86651AC4BD0EEA718C773812977 + 26: 6BC74F78256A98761981882C3CF7AAEB + 27: 44CC573B964002D877E79B75E4433E41 + 28: FC02FF53665B52B58DE38784E2C28E92 + 29: BC4D69312DFD24EEA219F29FF2AB2072 + 30: 0355E82F130341EFDD997EBDF4469221 + 31: 453D500D997FC85F6AE16365D83ACC05 + 32: 42DF4C5A3844F00F77ED84E125237113 + 33: E782D7162BB54E735F7B9FDD75A3F14E + 34: 78993013EEEA7B14999DDD3979191D74 + 35: 27BFCEF540F0782E9A28328E8DBEE59B + 36: DCF00356DCD264B7E359F02D7D2CDBB3 + 37: 9EE0BD7F55EBD844A8D114F83B3E8FC3 + 38: 01EF8F3154BA9B9B817AE717FEA00A68 + 39: 4DCBC2AA56D785CE7249761791442BBB + 40: 10282C07B870BCCE0C8DF9E68B4C5DAD + 41: 0757B359AB2D1D121BA01BB345A12A87 + 42: 450AEDEE570A2E9B1A19D5B4747B2AC9 + 43: 2C45713898BD259B10E2352BECFD6DE8 + 44: 3E92731175E510FCD07D28AD47DDA0CE + 45: 6A8E5690AD4AA2180966AC1503A81A18 + 46: 820BE195E2AE85C115BFE3C341567030 + 47: 9C97E1F0E7DA29A0527AC4F59D520100 + 48: E1257842EA15216543BFE84521B9FDC3 + 49: 42BA484CB70A58EB3EB5DA43F1D5D5D1 + 50: 2C674397A81CA35EDF1FE77B442BADD3 + 51: A3E07C012A7C67D2B6557F4A8B4DD031 + 52: F01789A2E0379CE16D87EEDE671171CB + 53: FFF1657EC846507BDECD2DD829DECDA2 + 54: 1673DCE23D430948AB818D47E83BB5CD + 55: 37CEC696967031AB2122155998A07F51 + 56: 320B7D4DE17A731B9BA5CBB48956D605 + 57: 1EB07088E5F563DBC5DD988ACB84B048 + 58: E4DFE704E4C25D06224D2560B4650467 + 59: 6C072AD491BEC80667A6D71D9C8F2FF8 + 60: 53DA8AE3F36FA8F85072A89962F39B76 + 61: 40210D1C7A728A27E1B5F92057DA4765 + 62: A4C4E5F271F3BDD74C560787718E8816 + 63: 4466033447F1E1C9BB107D152BF06051 + 64: 406C6EC2643CCEF38F964864D12C9191 + 65: 19F725CB43B171DFE18EDCB90A9DD900 + 66: EFAC3C9FBF1AB0C0F3601C18FE3F0212 + 67: 9B9BCD32F735EE353D33A657C2292475 + 68: 68F4A4294C640BBE4B1E90FF107E05AC + 69: 3630FD1C9542A56C851140A7D76C0D00 + 70: 21AFDFAACDD8FAB91027A61F8DAB6C91 + 71: 2C7AAC93B6CD1F8E23AAFD49F04C69DF + 72: AE4C5124059CFFB3B823E68FAC8CFB33 + 73: 79E95CB7E752863AA87A7693D0677D89 + 74: 1B491E33A96D9838398A4F624E773DAF + 75: 1F3986FC593D8A8E927C82DFE1F538F8 + 76: CE64F09024A907E76726E29E1364E606 + 77: AC98817981B59789E7C7E9CB9F70FDC3 + 78: 3827B4B077493B289C25EC3E91B36D26 + 79: 75295EED68F750E506C60A780B7F0285 + 80: 4FA47F32992EE6C96C3B96B6A69A6656 + 81: C52E142B7838D731FC036517003FA73E + 82: 3451812871ECD1C09E4A95CDC80369B2 + 83: CB5261A793A55DB33016ED27A35A20F5 + 84: 2D06368ED98E266E81A3C6491BC24890 + 85: 677F6509BDB3D44BCFB088A81BFD96D8 + 86: 6990256193FB0697862AB5A45FFF082E + 87: C88D698EAF83E446C025EA915998EA01 + 88: DB8F672EE8129BF4BCE25704DD57BFA6 + 89: 807F491456D7E28A36AD6E934B053EA8 + 90: BBFD55A483CBD0F9DFE18FEC5070A166 + 91: DF7735106411CC29535664D85ED81603 + 92: 24FE3535DFCC295C2F34F3F88CACDC88 + 93: B80CDE220C4199DE303BC97FEE125048 + 94: 8C252310E9A71C7BC40C3D2011E24EA6 + 95: BBDB705F5660C50C5B0C87CD812B76FD + 96: BD517928591240C7E63C8D9F957F6A4A + 97: 78A534AA0F4250EE83D752F3E6940148 + 98: 3346EDA882F00D6073D133CE609D3B83 + 99: 51EB1D3235CD35A2386E314F815588C1 +100: B4860192E79C1233A08FE595C084315F +101: 79EDBE3E80887B4F741199295347117E +102: A2793EA5F25492D32D315B3923E945D3 +103: E398223EBEFC56D3437AA5FBC5345CA5 +104: D3E6593D69B24069AF0374671E466930 +105: 12D63F5AC48F99BD59EC863B61952C1C +106: CC99A81A22B62A0FCAB4AE889112A8DC +107: CCC82CA5D35A421FFF313F90B9D1A675 +108: 5B4A2912071CC36CEA626F9AAD34F257 +109: D21FC82D78AC98C5DA436388AC9AC6BE +110: C2F22C7C16DD2E1BBFDD2BE7915B869D +111: 2B5AE5D14DC053558A1702959367760B +112: 7A6A3A6553B2C3387BEBE119E80CFB2B +113: 7E2206BCF666B89341CD7615D0291E3E +114: 93D87A658259C7E9FDD0BCDF93A24356 +115: BDBC0B062FA3D743C1B070F2AB43D180 +116: EE0A575AFFC966F58B91BB66CC1E6B6A +117: CC24CF8DF0798ED2CCED077B06AF1BAF +118: CBAE264BB4AE635A15D8FDCF7F9A6852 +119: B879B9BBF61B6F291A8E4645B70EE06D +120: A6F88AD4A16F789A58F178799279B40E +121: 3DCB6B1674608B11F496F45C9828F90C +122: FF34A1C7748C5B5F2F014ADF57241C43 +123: 1A77E2B20ADE5F286705251495AF04BC +124: FD47EE73738626733CC63327D4F5EB7E +125: B9438B50CC80CCE0303244713853A0DA +126: 040BC7876B31E22590F5898068B19859 +127: 16ED82C338495D067BBE1D4AE73345FB +128: FBE1AC0EECF0AA2671A6F25733E9711B + +Hash: rmd160 + 0: 9C1185A5C5E9FC54612808977EE8F548B2258D31 + 1: C81B94933420221A7AC004A90242D8B1D3E5070D + 2: C0C355CA556CFE356ABC0A5595BAB1364BD86444 + 3: 6D8D360567AC2CC8C4EC11DEEDE0ADCACDDA388A + 4: 04DE53FED2BBFA80FA79698B4C5627536FB620A7 + 5: 9538F24F7432E952F030BBA82C9F744365035197 + 6: 817ABE77EBB7EA159AF7BA7DE1EBBF034FE6CAFE + 7: 340835AD791316DE50DDB59838F3EB13F5521228 + 8: 64B7269FA971B162612265C73B9911F53EF43B63 + 9: AFDD1E7F8E39C63DEE7104014AD9EB32B855E0F0 + 10: CD2E472470BE8FD70A306DAEC5C59F485EA43929 + 11: 550844206034AA74E37D813FF29973D3000C1DBF + 12: DC24FD5F309A7BEB9A7CFA7A354F2DB2CBC15AFF + 13: A814B4CBFAD24B7B92AF0E16794A793DC16D10A2 + 14: 6C316617808A930BD29972B1142C0AEC89EF00AC + 15: 3286BABC7C4635FEC52F67CEFF1471E122D50258 + 16: 696C7528A3545E25BEC296E0D39B5F898BEC97F7 + 17: C87DA6F87A65CBCBC4B02BFD6D01E26F8047B5C4 + 18: F1AC2E0951EA5875B71723BA1A2158DB49EE073D + 19: 091A39765126ED406254E7F810F02E0A6124C6A3 + 20: 4002C0305550C5A726705DCF8D3880C54FED0453 + 21: 2B59904E1585334B1298AAE6EAB06526CAE5A232 + 22: 0EF94DF816593728611664F4ED6A0C4DA28C5AA9 + 23: FE7AB8A5B0CA3C86B6524E3333490D0430E9A4A0 + 24: E748023DDA7E4B77DE8A4424744331EBC62A6590 + 25: 96147FE511BC64D9493C795ADE8FC71A78FA8C23 + 26: D81D7D3B46D5BA875EC2604814616230D7A075A1 + 27: E8245E6537FEF146A2CF6AF9BC54472BEE6213F5 + 28: 231CAE27B96A78767A0915A529ADB6B72A8006B6 + 29: 4D6BE5BB6D29A15A259C8B7BD4827EA82F514425 + 30: 3B00599329120E535A5D1A46F35AD03CCA27F9D8 + 31: 2AF4160DADBB84707F7355177A4644E4CF577DFA + 32: E6BABB9619D7A81272711FC546A16B211DD93957 + 33: 1E374AB924A652FA36B395D654D226BF901B6A04 + 34: 67281E2EFADF2EA6211B549426D3A598B5E1F291 + 35: 993464E56DC035716064577245BCE99ED175356B + 36: 298D2CEC0A3887C93501307B51F75BFD5CF0AFEE + 37: 2A0A02BF4D63CC09978EAF3B3B85A4DE8470B025 + 38: 6236F6FE25D5157BA95BF49EEBA8987A6A301D2C + 39: B4DD7121567E8A428F16BBD5A8832FB2EE68BC0A + 40: 5FBE6037F8D8EFAA9A315C070CE3373080244496 + 41: 04D5E112C47EA03BB60CBCEB9FC8ED7D92A68C0A + 42: 658797C7756256C98E04E6718D9F8952F90DA672 + 43: 6A27ECD40BDA4CC81C599DE94D0D2904716FD457 + 44: EF5AC5B8E7A00560E79DB54AAD4B97E996D2745E + 45: E67EE5275910B48F7D248A8B844DBC041257D695 + 46: FFD256BCBBF0F3BB4DF615B4236C147FD09F4F1B + 47: E83A4B18C347F188301DD3AA78265AD3AB3C0311 + 48: 13968583BC017CF0C5043364A42EC0D97E923711 + 49: 39C33EA7C4F393C4DD4B882F73FDDAC2D7FE1EDA + 50: 50B0068D46AA025615053132BB53F88DC062DB2D + 51: 434198200766DB6CF48C993906FEAC2B47224A3F + 52: 004FBC3820002357434D6B8ADCF79BFA6F9E3DD7 + 53: 13F7A8CDDDE021BCA6227EFF1A71DE19AF399B66 + 54: ECAB85CA0C2AABF18F5359F94AAD7578A08AB5EF + 55: 3C86963B3FF646A65AE42996E9664C747CC7E5E6 + 56: EBDD79CFD4FD9949EF8089673D2620427F487CFB + 57: 635B0D05BE254D82503A9E1DB7647DD1B5D5D6BF + 58: BE314B818A657DDEF92DF123FCC17C1DAA851C04 + 59: DCFBF0575A2B3F64B24DC203BDCB46290B21791E + 60: ADA425E87A8DACF9C28B67E8BE4B204A31960004 + 61: 35691DD184E08A80230467ADC6E68599B7295A51 + 62: AD1CAEFC7ABDC90E7877D376957532B7D91D7434 + 63: 6D31D3D634B4A7AA15914C239576EB1956F2D9A4 + 64: 2581F5E9F957B44B0FA24D31996DE47409DD1E0F + 65: 109949B95341EEEA7365E8AC4D0D3883D98F709A + 66: AC745186C82DF8697458326051A6CE7E4E9C1C1A + 67: 5DE50BBB11C62ABE22E7EDC288B7D1B6A1CFCC60 + 68: 7DD54CC4E8C70A4AC55F4C0485A4DFE139253757 + 69: A5E0EFB95E6162F9637D58D3E4836F9661D6A34A + 70: 6C77DE7607A361D22852385E663171148C0499BD + 71: 3467662275B136AF096D84258B17CA5F23BD6397 + 72: 1C56A69A826F95B8971635AA709978A441E75836 + 73: 9094727596F086BA28956A6BB69CCBF3B2B29FA6 + 74: 8C0B6183C33E902C22F17D81D18144ACB7B66FB2 + 75: 24ECF7598894FFBBC7D30FB1EA47092F03C398CA + 76: 6A02FE0041D98AB7AA6916A5245BFBBCF6635C2D + 77: F3021EDB24459533488660512660DDFF7F451C3C + 78: FBB7561C0065C90D7B8182018EAE73A18288E968 + 79: 32784F0E354A20688359B6EE7FD3874714C48677 + 80: 8BFBA0972D36739EA808C37C07F2E320ACB4114D + 81: 74EADA88C8ED0B649FCCC36DE338CB538242FE10 + 82: ED812B77C12856DB371E6F7DDF15A59FEBDD6962 + 83: 27021F491E923CF0B191E13ABCADDAA72586B769 + 84: 47664874218C135C09ED40DFAC26E06733AD02CE + 85: B39E492616FDAF2480F13D6E46CEBECC1FF5CBA5 + 86: DE967F65BF6DF26150AF866FADCA58C45DDC337B + 87: 8F2E2D23CC6A2B52B904032119CE68649406033A + 88: 247FB8B2BD1BDC35D0C07EA10FD9686A19E4723B + 89: 9D1E80D5695569D0DE28587D37103BBB0701E462 + 90: FA5C338E7506AC5418C4FC2C04AA933588892D4A + 91: D6BC93880FEC0163E3F223C8A64BA0879BBB0AED + 92: 8F27EE9C8A923C9698584786B5227CF17F0F557E + 93: 4C10ACF2F404236E2DABED0BB48DDC6D00AC4B16 + 94: D5166CC6B779EB2D45AB3222181064D05FFB5E23 + 95: 13042EB8245A8C5DED69CFCC1F1DB264889CF5CF + 96: 07136FE8CC1A03673891BC614E29BE79EA02D627 + 97: 73C50B2751C502572492C801C28B02C7E9F61B76 + 98: 8BE4B71D50C2D2895B9CA359ECB69F90CDCB1DD5 + 99: 36A669D7C1DA8E23D07B29BD6769DC324EB6D6B3 +100: 8AE5D2E6B1F3A514257F2469B637454931844AEB +101: F16396E005FE5ACC34EB53E6086F477415794BF2 +102: 907CD2922CA5F62F79E17B28AF389A38066E2C9C +103: 62C9351A21A50F2150367F25D4C166C63E771C32 +104: 8809CB529232A0CB22D384B70462B64D93B0EC1A +105: A85E4B4260A836BF0DA50B83BE1080D98CEF8A17 +106: 21D2A0D78435B2590B2C6366439939B9B15246E7 +107: 204FFDFDFCA5D46CCEC5FA96A778BFCBEA70BCE9 +108: 01DC05D6006E12D2F63A8F061B00D18CCA135D41 +109: 30E67D3FC0A0A6D2F257AE24EA8C168A4B0E0F5B +110: 9B9454E2B42908E57403871A64EA5E930F35B70A +111: 9F72DB053BC5370C786E34013FB8DA5958000D5A +112: C1BFA4009BFEAA30ADA4D940FC40F97FFEA3FC39 +113: 26FC30BF64087DC3FA4CA394637D15F73B7687FD +114: 36106E0DF24B7DEF46E9AEAB7CE0D784FE619D9D +115: 0D82262E443C3C56565EE35776F95978E16F1757 +116: B19E6C73E94401020B14ABBF19A15A6F0C9061AF +117: 68ECB5552C7B7B26940A82B6A67B0F4C62EEB871 +118: A834797B79DBB564AE587003EC4B74914A1580C5 +119: AD430B4283203A7B7F338B9D252DFDBF807402BF +120: B89CDC109009F1982C8B34FCA446953584D3F6C4 +121: 8030CC5A4F55566958A5BFCA97CB6F40B9C19279 +122: D0CBD1EA711E2D405DA5ECC2905DD8A3A3E83C37 +123: ACCDC924549D314019C4FD1AAC6AE3CDFB81BC84 +124: 312933643FCAAEBA4DB9BDE6EF7D6EFA70E37399 +125: 47F11AE47E2E693EDC0B06351E935C9B5DA42A35 +126: E4C6AA211767C15E90935DF552E4EEB89F23AD50 +127: 2BE8E565E24A87171F0700ECAFA3C2942C97023E +128: 7C4D36070C1E1176B2960A1B0DD2319D547CF8EB + +Hash: whirlpool + 0: 19FA61D75522A4669B44E39C1D2E1726C530232130D407F89AFEE0964997F7A73E83BE698B288FEBCF88E3E03C4F0757EA8964E59B63D93708B138CC42A66EB3 + 1: 4D9444C212955963D425A410176FCCFB74161E6839692B4C11FDE2ED6EB559EFE0560C39A7B61D5A8BCABD6817A3135AF80F342A4942CCAAE745ABDDFB6AFED0 + 2: 2661D03372ED5C961EE23F42ED9498B451030EED2FD01F29178955529B2F8A758F0444087C82AED85540C8217E959EB8CB43EBBBB77A7E0D2980D6406AA2190B + 3: 7314E8035788304E57E68AC9EA89544ACE6D2379035697D91B98B64B105130DC814B67A4B46B4DF6C103016B8F7C7403E0B943F0291ED6909E2219B6E18E89D8 + 4: A6C01D8CB93A5CEC17A9BDD270B24C8EE78686CAFFC454F253D9B8DAD5398E52304CD57F30F2111BE78FD98338DD3A41FD8A45124C940C4A59F270100DD6CB6F + 5: DB22986F9FECA154CCF0E7DAD914AE8C0851E170D116E9B550C39B373F109FD073395C0711745E40233226F96B5FBF6C8EF1D7F8E2E4AF5375821C897EB18514 + 6: 793498B98970BB3CF187B0A28D353AB2EEC8F6CDA12E6D484CBCCDB96B2BFE6B5278CDB38C9BEDAEB59A8404645DBEDFBE1FE54227947E226EDFD36114067F34 + 7: 052A7C4EC5AD200B6B8131F30E97A9A5DA44899E1C6C31BBE078058630D5E208FD6F2F51A796F814F8AD048D759F8DCE442C405D96D6E1B1A197AD908B366E98 + 8: 219B01987262C597603DBC495792F2423E24A4BCD38825A74CEE8ED91D55935296D80E73DB43A78FDD6119233A31DA5940C6E335EB22600729478A20F61A56DD + 9: 4BBB8746D1D754CE91C27F3A6262ACBBFD4A38D100A65ADADD3174ED6EF8F6AD343F0ED2DF28309A6E979E02B12E732A3E70371EF1E0935E8A30B7C55146D9AC + 10: 81BE2AD26A90BF502C9514F46681276F927E916A630FAC442D823FE4D8EDE0FAE2E8384F3C267B56126F0C009BF8689D475C53425322BF8CD7F6C80CD2C725C6 + 11: FCDEAB03C0FAC7939E8478FD152EEC2408D4A6C0D829B55AFCC5184C50706C253676CF68DA3ABC1C1AEEB5822898C5194AC801881B8CBCC8DB15930EAAEE9373 + 12: F943E5CD2DF74699913B25EEF0B08FCA6BAE9E66BC073DF0BD950CA02FF17276F4A28393BCCCF6E567024CBC6C05C94EA912F1B07034AA375009F594B25D9542 + 13: 1260728E085D172EE82065B3F878FE21F550748598E72A40F4FAC3F54B72A99E6B3CFDA7141C7E5BE123757AE4332C8320786408523DFC8655D7E1F7010792B2 + 14: 67EB4E93961EF18A82152DE2882CC5AF4DD1254732A8FC1959147268441A80EAF0E0B68041F7CF013313ACAD044BD440F1E06D3E449D206433F3B52BE2C9E7B9 + 15: 9AB90A3384DA32A03B31DDA21732B398358DD40D7586E836CFA047961360CEA2F1E3DD0CF2D90CBB57F68C4334110694A6C1BA17B1E9E533E6CF3A3ACCEFF84E + 16: 112C2ED4CE732E21334D7248A30E683246BA602AD3681BAE365E857AA840F1F80FCEF1B9ADA33AC1F9BF6FB75045F9E61449B26F9201E482E7F2ADC8ED9A1D80 + 17: EF574EE7B498AA64F3ACBE1972E42B873C6FADE053A1459AB52D5E5B49C0AFA0C62FE901ADC3FF07A7D0ACC459C3DDB3F6D499C70B63F68B60B02E2784BB9AC4 + 18: C6185B5836DD3B160695E5E27058AB266EDE91A5417DC086988EA5181DF5BA0C51DEB11F6BA14AF2847540BE368B6C561CD976809E2D9982F4D49F96E0AF4F7C + 19: 8510D305A5E1AB3A0832B242ED402BEC2D70C24B41BD840B8D2DE436A6B4DBB7CB5F7F9F1432E694F0CB1239EAB0DDD92E6D0C7E96FDAD5F8E465E286D7588EC + 20: 926800FF566CAFAEABACA9990772EFEC8AC956C3C572A360194F95AAAAE477F98AB7750B2710E262D039D8584BE79D93E9E6405BA25DFF6DCF29C54D748DD655 + 21: 0F0B98CE94E2CC67D36086D153A2DF48F20283413407C3CD0570B619871DAC188AA37BA30BD706AFEF475BDA7AEFAB63055ADE8B792F025D088B51A08E941B01 + 22: E6538F3479D33979F046FBC88D4BA785B072EF58877BFC9D1214FA8374B78DA6895D5A4F4E50E6AC6A237E48A73EB18E4452E7C8AD50C82238FA9B323C96935C + 23: 378E83B88847F234A6A2FF7304ABA759A422E6823334ECF71E9C3C1F8B21B016D9A8A100B6B160772FFF12482A50613BD832EF534DBD1D4D055F3227C7513F11 + 24: ECFC0F6C168962197E181C27FC9AA1975FED01E655B3D4A7857872451D6AF810783184534C401709A63BF6BE6CDB1D1455C382CBAA6F68E8180CBA9E0CDDB9EE + 25: 8523B737250579A3787BD83E5DCC57F7038B393F003223A7BAB98EE4D040441190622290B164F32FB96682730DF62CC366FC33126DE2F7DDE3A38C818C48F680 + 26: C6BE341A28878B733C30F50D67F6933D3A15A0950CAAB96B9F3D7D78C95C61874A400CAB65A100302D9E2DCEADC4A0C043834EB0433D5D684C187AED93B5EC6A + 27: 4AE827A36DA140D2271F74DF1AF4303DF4B1C319428F8BA94EA28BD3765BE4535275053DA49B630E6B754097ADCD7F17DC7C16158F43E2C1851951EC3016CD8B + 28: 6D3F01856A8A28E28EADF60401E84253C3F7CD13F3A9FB8F94D8B07B74F7416817F274903C135BA0DA4509A78D004388CBCCA75B06132C7CFC0156C03803E85B + 29: 07CDC2BDD9CDC49853384FB647736B50D788AB80A0A54A0969B86603B683C22A1C5FD32D3AC92E73D378F379C4BA30A48E7D38FBB867E981271FB3962C745659 + 30: 9DC875BF987C55CE646A709E89CA89E226B0F15666D5174771368FAD768BF3318B8BC7D8CA80AFB5E6BB7FC0090B5559F11DA165DE51B940C9DFE911D4790477 + 31: 58BEE92BE003CCC34F9CE8C0B323C6BAF1297460BAAB4998CB3B52D2BBAA24D1B06CB597EB2E609A008572FF93710E3A7F42AC53E3FF09D4733757EACA41E20C + 32: 888AEB1BE2BECB28598556A128AFEA037D0689C8D13D9894F1416B2C48B2551CB2FDA321A26CC4D7E1C87332D7A3C18FFB455C92C0E7AAF829FA40B8A28BB656 + 33: 19099B4E8ABF225DC7BD1C1DC6D52F54E8FB7E4EAE0AB19293C686E6FD2828221A1153BBA4C143795D1A718585D9255B6DC911C0EDA5E0042A10565AA5D6D8E7 + 34: 22B3ED65F64C8E51257A922FF90DC09447224B9A8C7B5A6A94D68601F3D4C7C1557BB90B91DF318EF9F8BB367E838D36A3CA82FDCB85721AEA20A8A2268D90AF + 35: 0D2B24C6FD5D772704BC17D2FC8C011F1511F92491104F3C22470864882656AA40DD07C0C329C8BAFD90ADEA7F473349038CE475D352DA41E24FF64723070566 + 36: FEB43F7DCDE56A2EE963236C234E5800C011FC54D14396288DE5A7AC7DB2A72D1E8F63F04D1DDB3C55CF3BF19F4E0FBA4B79405A6B45ECB31254C9F1951C632B + 37: B8AE2C8427A750F34647C3529A05D44691B8DE0C79525D9145665BDA5C0C396C00E936BF2493F12945899B6FDAA9F61E6E7B22846023D140F873EE7D48D76BC8 + 38: E80C49D1E29F6FAF0BB5C7B47F5A85B3A0EDDED84418890748724792CC83B53AB044B051722F1ADAAB713E5069E883C1D172CE0EFF6EE6AEBE05B1FD77DB652B + 39: 1FED03FA70436EF45286648ABF39057C33815E6A80A19E22009B89C809DD6F0099C944B882FF9DF3DF08DD51295F3F02FBAB40F606C045BD4395969E27647D24 + 40: 2E3630EB519F6DD115B3E4818DB4429CDDF1C6CC2C8548F8CCA226A24F87A949A27DCBF141803B87B2A2C0F8AF830031DB1FE084E3996D8834F8E7D29EEA4AFB + 41: D54509526805DFC0871CBD6E41ACE395C64373E8F57146A657C28BB3ADBF7E57A152D27BE24B8F30F08329C2E040359B119690D9A1118BC14A3B1883D093466E + 42: 0AB062968EE4D71DCE807EFAF835EE11588854ACA0959B5341DDFD10E70BA9AD427D92168B31B8E6EF81F58615AF9215A8708CE1F144EE29901D1FC282C3F78F + 43: 45862B0D0F0AC5CC1C5769C29D786FD3AC788CFBCDD6CAECFB120D05D71F2575F4174CAD5E5A00D2D740D0714E92822427085F044A72D66631755BC55E5BCC8E + 44: D3A9EFFA759181346D8FE53130F05B2C65F96E1D5908A61DA8FA3A9BC551A7781ED7B1A6CFFCB2F742DDAE8D22B0EC99D82B14EB85719253693FF920FD5071D8 + 45: DB53395A78DDE62A406211955EC56C6F7BEB9EC2275501C35CA955268C3E2D71BA246B4286C76FAFDE012F9E2CAAC8601A74699B466023FE9F8B1BA26F65042B + 46: 9426FFB7B70DEDF1CFBCE6610583CDCD91AB421FE39DDC31F4215CF7604B9050C84A3BA29C4B236F1CC3B09F53D29229132FDDDD9B468CBB6338BBBA6193F84B + 47: 3D74F17DC6FE057703C72452BC7A078EC019424A89783F1FA40003657C323997DF30BBA38CB4B16BAD8FDC43260956090F765C26AB1FC88BF7F87EACA1821B52 + 48: C6EF119085EB17EC1B9F74791D95E366FE916F5397C20857A8966C52512F4EE16E63B53A28F7632A867EFC7FFD8080B173D5E2E33A2063FEC7D1181ACF8C7824 + 49: D878B30402FECA5EC93362105D5E183D658DD2FD38B8173FF609740CC84239C4F8F533AC3451D369001CCD4AC78814058DE0F7E1F93D167A46E85E3002F4F386 + 50: 948C4254AD2C5658A28D42DDC3CB4FE4CF731B4180B8A4A183C23C54CCEA045307422547600598CCFFD3C6229DAA6CDD006D3C782ED91AC61172059D016970DE + 51: B74FDFED0388D5164BEE25E37C6687FA8D5C069D4FB0D42A7F1A270A676F83F24FD1C9048EC0D49F7BE913D893E0015E0A3F724653B3F0AB0017683948712E46 + 52: 497EB803D053D5DF498369BADBF8AAD57ED1B072CF361D3DB2A528D3DB16DD962887916E9D21FFB439DC2C025CDD8C21ADCC98A23C8C5B0245F2D71CF728F10F + 53: 63F4098F650820EDCEA3E7C10B65D3B0F1949A28FEA323702F27C7D311C7E6BFC82D4C01F4FAD06FE0288E410EF325DE192F78B88E04075FA9581AE2B031A68B + 54: 337914B013B8056D7849E42ADB47FA761B5AB05696CB8FDA6B87FFF88B0477902991AD81664727164053E4E47ACDF880DCAD0E0E67F7141123DB494450CF0B61 + 55: A385FE66F8C852638F5BE44503B680298EBBF27DBD9F20B1A0447215C0E2C1078926002113A71C78148D5019FB22C8132DD05356C78A1A8D8E4EEC5A6442DBA9 + 56: 218336585A419E9877CB63387C5E759FC93F0FE1A7BA717B8BE9B2302393E0D14DEF2F749D138692D0A0296F1C792B567F40037DD2B8787F1F47FF363CF34F37 + 57: 7EB842771A61A9AF779C8794CA055518E7F38CD13F61638900EAAEA000B12816D52C593B62B9DAD79DB7397A463AB99A9D0035E7A1369B0556D593DB41EEEB6B + 58: E41D1492D3472FBD42F2460650F9DAF2ECCDEAEF5F4516B452D940DAD516F5168439154B4BA76610461B343BCF1E7DD7DD8C285EC0CC46C17CE3C7E14103042A + 59: 88057C0B8442BC5763283EA17FD1FE1AE011A988E1D7E0F914004CD3AD2E06FEEECDF59E309B9EBDABF19559954C37F71FA98C14BB19F7B91CE5F827C1DDE1B5 + 60: C5DE99AA273D1971272263C740E689739B39725A0B7C48B41577F05738A24F5EE2C0B673F93BD52A083798DDDC6E70A209213B58C95D49ABC5BCBABDD6AE7D22 + 61: 68296AC346BA3B14C038CDC629C5F5700CEB9F5DAFD94F948C6B991C0F91813BFD02660A2A05A02A61D8EB03BC93601F9F6A38196650047E1D7DD1071CC6974D + 62: 1CE0E6793B0ED59C4DB7D5F24FEF75A4ED2F28CE4AA7E5EB25919219C2C04935E4B15841821FA92FC7537DE2A538871E5A043A773CB1ED061333113223248C18 + 63: 37BF321F66ACE827B66ECAA651CCFCAD30AB627E717AA4FE441279C4FA48555CB7784B0AF25A73B86375BE71A1E3FDDEC661E0EB8115E0BB2B9A7FF81DC75DF9 + 64: 5C3C6F524C8AE1E7A4F76B84977B1560E78EB568E2FD8D72699AD79186481BD42B53AB39A0B741D9C098A4ECB01F3ECCF3844CF1B73A9355EE5D496A2A1FB5B3 + 65: 85A19923268414DE6A10A2CDEF7917D7AA01E68DF9D028CBAB5C5236FAEFCED836BDE9CF90D8A214013056202A1BAE5CB73606078C5572D8FE85C36002C92D70 + 66: C2FB9763A6F86225F6C66F55ACC8E7E17C1A2664416B2704D64AAC2CC5B04A626030B5243CA61D62076DDBDF3C6B3765C38D0CFA01D4D45C124EA28DA593F84F + 67: 5083280300FA5A1B172D7B5CCADA5CECE1EE5B7B5D382EB4A430179EB133970B0B89F6BB6DCBB1F38EC9F13F5B7D1559F114DE0EE26178EBC56CBE31BB26A91D + 68: B3571E8C1CBC0C58E23094B39352D554B43F9E7DD0FF981C12A01E0D8BBFF06A39875D90BEDA7F345550E6F67935A49E0183456B9967BB319D74AAD87CCA3695 + 69: D11537B780D458D37279D00621F646EBAD3244A22E4D45DF11AC5D084FDF70E7A32F897DF727E65EDD1019DABCC05DF0B5E015FC5CC1184129C5DDFB14F62154 + 70: C146458EF40E6F1944BFD863B2862A97145BA580D47C7ACA67E797EAC6790841C57D68A74930AEFCD49031819FBED806A0C033DD529A203B4E460F357BA1BBFB + 71: 660F3E1D5CD3B2AFD95DB0D8C258F6AD74DD40DB688A37AB4A24D720766541B1CB928001EF6D67CE5429039C9C1490613DDF90A27E6152BE7D42E1614C590056 + 72: DEC468EF73E98F44B60EB994935921F920DC0CEEB7498655F0FAB7607A77A7A3D9462DD8BAD46CB408EFA81FF08D7E9508BC565C1578C37C2B87D41A0A32A549 + 73: 070D4C36A0934C5C12E6B65FFF385404E49C3871DA8674D93D26E3166A7EF9693D946B419F0E10C9624964B37493DC8A46D26D8AB8942E60143036659CA4C91D + 74: BB8935CC84E08E6B4E7C6233E41D880D70CC018D1668EE64F19906A83730495D01AFCE1A4EA8129A98B7F9E074FD35C0BA6D5667625DB63A867BAA67BDEFC190 + 75: A0A7A0B619643115C582BB6953D2A3EAA942451F631FC56C0933B535313D668FA4CA7D6BEC4DC9FE2AD7528DD6F8DBE68478A040FBFDD2F3DC3AD7035DB67371 + 76: D6C57C3FB08D07A30A622B25985A52A6E552499345244725B1084E41691B11EB31D3B9776940A9A7E6115D2D1A93372D3A7388D87B01D13BCA726E8823E89729 + 77: 413CB26BE2B1BA8ABE930ED1B9978BA4874CF32B38C825CB6DFE9C21A87C0BD115D3357198FDA0A5B7CDEB4235A354E9C2F37D11B33AC6A257DEC67326830E23 + 78: 748E4648FBD009E4848E44A284D0CB2088300F50CD5215A285826E968B9DA59B6322E1987F78447150AF72CE37E516BE9E83B05A9817AB7A924ED8B09557CB5F + 79: 0A8111FEA824D43E0991C22FC3B1368A191D0C73308283494309D0762AB1EE5AF0CE2DB8F0562DECAC636128688540E845D72BEA3852A19CA2ED22D6C1E82CF1 + 80: DB1067879F014EF676471D950A81DA073D676DE52E85F67890C8471FE6144078DAF940CB6F9F097BEDB8FAC94C737C5B8A3B4217CFF4A56DC349B2AE845AB25B + 81: 6165F19F569BAAA3A3ABE6D6108D07E1ECB22092F66227DC27173DAC097118C2D927F2E5F7D20C8CEF0F99C6FE6C7AA46BF18FBC452F6FDD733728030CD0A4A6 + 82: 1D4AA14617A4BB9E48DCC1A7EE5DF65298AE45FB193F077FDB6D1C2B3252E1633AF86A527C29861661CE155A47E5BAC91D9B07715E0FF7E08B39A3128891EC42 + 83: C2C22B53D6BA460954C2D826FD3DEEE60E33AF2EFC87A61CBF2AA021166AFB90967ADE2C564D037518E4141BE9C0D0BC0B4F95498D5AD920BF28CAD4F5FE700C + 84: BB5E9CFE19C6A2D14EA4C1F6BDE51855DF61D650B23330BAC30A5072EAACF86CA02AD31FE4C146176DEC75C56A56C2B868177E0E365414508D2E7606AB9E8921 + 85: 6B40A13C5486396864608BE7285BD4D1205180BC41E10E537042A1CC6CD12FA7737B5E73D768BBC5D687FCCE41880A8D9773C26316ACEA2D78DA26FECCC11E90 + 86: DAD0DC8A7D78E29B12182D36F47B93CAB562C44FD6C5B1718651022CDEEC30133437431D13C43EC1C02DCE776F459A57C29355B3FA0D67C6BF84AD26194A8854 + 87: 8118AEE5DFBD7FD9F94403FFD3C6BEA08706D4C4DC78CDE72F751A6C4027ABEC7786A62732819ADC036B787E25E151AC51B60BD2381A64F05A326800D7514B15 + 88: C64737334A61872EC00C8A3F1B1EA931FEE8D80203CE6DB9F1ABEFEE2CD3E652971615AE4F9A23400B9E31D861BE6B7E0F6DED28ED74B45D6AE90E70AD49508B + 89: F927B571B03B892B46C0A16148F13A2E6B80630CE41BA7DBE311F9ADBB5E8F23923CF0CA527DDD20BB3FE42BBE805066BEAD569F6FED12A2722A8629427ED841 + 90: 2576A445CCD8977F24F50EE30EA7A51F0F3F49D41BAA663BD1C1734E02367A382E3D0E8C07EAED0C6A47CF662FE573BAE5593D9C4BA8FFDB4AF024F6064F7A89 + 91: E85C73AEB638F35565BDD2523AE2A86B573C339B4D5FF8498ADF71BA587CBF146AE63B8C920B2F0A166F802167A04CD0D7F7A842D7D058165894CF9188289032 + 92: E74E2ABDD6AFFF851EF78F8A866DDE9B9F86D906B298DD1E3630E1D4A30B6FCD7FF91943A57367A00E2658A84346F53ABC896EDAA395167E5EBD12C954E0B820 + 93: 6827226985276BA731A9AE2E4DBF2D0187C05D566F06D098E05E3F425DC058958B50F09B4CE0741F1375E9B522F94A61F1ED8A43A8D03A036D2ABFCEDD4F0C1F + 94: 19A71A12DCABA1BA185BA38BCC0D915584A801EA49F975393B25AFBC456571CBF1A6F9121CBAE89A9B438092C65532489A95A0864320102EAD9A2EBD30D41F6F + 95: C70F19BAEA7420A7482C9C54CBB689A9AB93E4F8538EDC2371A1EDB3A103DFB7176E04DF170FF71EF46DFDAC1E8F9CD6FF96115BE1EFC271A56BDCFB67D29E67 + 96: 8BBCCFC8815786ADD9F108F4381A2B084179002AE940ADD4C42AA2550C353CD0351C2F7F1BD544D8F268FA332B0E803838318A39079E9D93269A01EAF9CAC967 + 97: 5266FA966A04B8A2450ECF3826C9E1516FEDC33EE81D4911A601351564D27C8BD4A11BF00E0DE237E50D75421CBE475E38967F28E6A1C5D311A2C95B84898D1E + 98: DF87823E1E02AF34532C5F3A08CF03CB9B2017B835525B3E3C448B1ED15569935D9A1DA19A6B1E8D056FBC868447ABE6226B97F256F6B638B052B4BAB3BD4808 + 99: A1317CAC2364B10EABBD3540B6139D337C0EB3F7A740C050988FF9B3584213DF5833AAD81D36C30CE6CE76962A9E1D45F08667A314036A299454F25F73EB067F +100: B752B6EEB497A8BEBFC1BE1649CA41D57FD1973BFFC2261CA196B5474E0F353762F354C1D743581F61C51F4D86921360BC2E8AD35E830578B68B12E884A50894 +101: B0BB23AED2CFC9C58C8BAB019CD10DBE75717EE8F04AA45FD8D84748E3F05C523FD2F70DCC460F7A18DF7D28A224BCB86CFA4C8164D081D51F3487A7BD0C8109 +102: 0FA46C6A759DA9A3649679780A28FDD51EDFD3F99A4B801C5824247B270A137CF40006609E149C919CDA0A6C856A9A8E855A670A2BB2CD5211FAD42E84F6E365 +103: C4E350267BD335848D00151AF2C380E49A323E63AA264D534EA1BF7A860B764A78993F7FFF34ED93ACB1F5A5AB66758C462B4D2F2F4E14225D29FEC0C102E772 +104: AFA0F1DB8A321FC6C4EF7C65ED2ADC4B094E928E230D27295699DE68FB5C1657FE0E5C4E66C5852ACFC45DA94BEFDAC89CF0D4174B262E6FD51CDC3E7FFFA5CE +105: 9A86A440FF8A33DCD38C69D7564EF827F614629CB699B7F45E7FFF1CFF4AD5E27EFFDD32EF1D0845987A6A273EA34C19374E9FB606BB2E3B909157CC6666D29A +106: 1FAF8C564575D654133B0A452EC43959C9F9E20C044724B74EFC90D2CECE4C49A0512C9F4DA2E999552E3ACC04CE0F0E2FDA9826C2A1FBBACEC4330081D5CA43 +107: 8B35FFFCD91E617C8A49B13CD0FFA2199FA1F20E5633AE6E95881BBCA02B1E047392DC9A4C0F0A4C39D3984E78ECC4DCC1B5C94A26ACDC1F69C7ABABFFB45175 +108: 6C8AB69E946FE86DEF6F14B955B8F1977686EAFF8E384CA45F245CCC0EB1C80AF8E62B0E7387C0DA52BBA31B1A01EBB00CA26CBFDA9D8069A773C3B62F989A2C +109: C3A243B45B7C3C2002CB197BADBD84C4900D504FCD277D2DC6C06D34B1317B41EF098BB980800FA9D011C0363D074308835AEBCF3393B1C925045E97E14831C0 +110: 803E065AFEFC6C48EF9F701233AF512465729E81B0DBFF99A2E7FEFFB542831E1D3B30230BFA2F30343695C060AC8140C37CC8D1E25E95E6A1139C5522F4ED28 +111: 86618429B8720ADCBC8B9FEAED8BD44E0848572CB6137213273563EBFDA859240E17DFDAFF68B09953F1853C9E7EF217875E7BD6959E76DC3A1CE5F548B76CEB +112: 96439A93295B5C479F0310B28377FC10DF81B593AC233556B15897F1FA3886C940639AFF2ECEB29894DA884626B4811254FE2622EC7B4577087D9046C96AA556 +113: 9F7BAE13DB80C72A434BC4704998A73D7E546CC2590E0D0EE511CAFC63C622A8B2A296426E42754606D02B6EA060892E325EA1AC13EF0B523A3551F4D25BE241 +114: E999A862E5C479B7BB21EB52E4BD301571A8A39B712EBFEFAC720F28C515025E98CCC74B950D57CF3C3B34D788D62CDA0339AE0DA02C8A107BCDD797C4751FF1 +115: CD00EC5142CBBCA87BC15D69EBE96B5222F25BE1576B318208178679B13A9A8BA4BBABE9A488BB38C4EEF327C9A4DEA4225DD30C0F70B97C18C5C2FB19FC2134 +116: 1289951D2B62112BA590D8C0CF9EFA38AB77737F994060596738612E6BDC41EC8672F50A027A2C049299FD39E1776BC3EEBFE3E66CCF4009615D63F0A4C43ABE +117: 451A46FBDC954FB76E744AF3DA8429C881197F6BC12D22412438729288AA4540843B9FD4CD1BDBA5E864FEAEF0CD6CFF045A37510B3759FADFEF4697E9BF9240 +118: A267FCDF72D9160DA2A01E781E07701478F95A38C262ADEBFA194EA6D5A50A9CF3E04D32AA4B492580C6E8D8FAE1F813F3C17F82B7F47D8CE0C900F0F3052F98 +119: 3D910AB6579455653EFC939BE1B22D993537408086361008EBB166724FAFE3C8578EF4BE0378BC28ED883FC0FF3DE5A9310CEDE65FAF3AD9590A13B3CA4F81C5 +120: 47386DF4D41775737BC4E52D7CB2EFC11BA335A5D59597B5DEB3DD0A35032461F5DB4779D48BD6F3A10C5503AC563C790235E6F54EA79CEADB6A56AFCCE890DF +121: BA59044EF3A242974F074337CBB6840FA0506C2227A429498F546B2CEBE0644DFF1D442190C48CB54BEE72F960670F71AF1F8402AD5ABE8C1482DEFA881FA903 +122: 89B4F35E5C8C19AD61CF1600BA80C1A1BBCFDC86AD9F8066C967BA10F62827FCEFA1EBD07C90C82B48082A5B7D6A72E0AAFD230DE05955C7E8C081286B0CA96D +123: 0C7F94250F4EA7647F91E7EA8B8612AE8E7BFE4F5BCDD90CDCE564BC9842F6987AFB4C3661D8431440FEE18EB2EC70BCCD34A6B61D209CB72BE782A0808C08E2 +124: 2C8B8B17820085795BC6A2720B5D0BDF5407D9DEE1CAA4270FFAD010AE9555DFD2B74A742512BAFFAA1D5B4F14ECDB2BD4BF37838D5981A317C7287805974019 +125: B464C5A9D040F11DA45D98C4BCA9295D0F589DB11EE5603410C62BDACCC329B9AC14567C3A6F3BBA4B92CD3B95BE58AD4DA435199CE62D8BD61269F8BEA38FE4 +126: 2F64554FD54AA4A04ADE3793AFCC5C968B1C3603F4F71E1BB5342BA4E951D79A4580BF57736E7FC13A43604A057E9C360C099AC5B3403DA8AAFDBBF417FF6ADC +127: 3C9A7F387B7104DF19CF264B0B5821B2E46E44ADC79262546E98FFA113EB3D45799EAC78CCA4643C937FCC3C1D249A212FACB34C63D45EEC81069095D7CDCE7B +128: 803A3B37C89E84FBBEC75BEE3D00DD728FFC4246B5A5E989DC8DC2CD0F7937966AB78C79E1D4648EE6EB40F3D70491CB46B8AB42E155672E2AB8374FCF70DD79 + +Hash: chc_hash + 0: 4047929F1F572643B55F829EB3291D11 + 1: 8898FD04F810507740E7A8DBF44C18E8 + 2: 1445928BB912A6D3C5111923B6C5D48D + 3: D85B2E8854D16A440CF32DDDA741DA52 + 4: 5F3082124472598098B03649EA409CDC + 5: 604A19622A06D0486D559A07C95B297A + 6: A16F89E4DACA6C8174C9D66AA23B15AF + 7: FC6893F79A2D28315FBBEFCAF0280793 + 8: 6A80F04CB93B1CFB947DED28141E877A + 9: D036D0B4DEF1FA138C3181367143D1A9 + 10: F031A2DC2A196B268046F73728EE7831 + 11: 2E05C9B5A43CFB01AD026ABA8AE8201F + 12: 8B49EF0BC936792F905E61AE621E63C3 + 13: 485CF5E83BC66843D446D9922547E43B + 14: 704767A75D1FD6639CE72291AE1F6CD8 + 15: 19F6228C2531747CB20F644F9EC65691 + 16: B78FEC0628D7F47B042A3C15C57750FB + 17: 3EF9AFAAFAE9C80D09CD078E1CC0BD8A + 18: 5E4501C8DD0D49589F4FFA20F278D316 + 19: 00D2D0FDD0E0476C9D40DE5A04508849 + 20: CC7382E78D8DF07F0BAB66203F191745 + 21: 85B841BCCCB4AD2420BCABCFD06A0757 + 22: 7159E38F4D7E4CEBEBF86A65A984BA2A + 23: C8949A9D92601726F77E1AEF0E5F1E0F + 24: 8CE35EF6EC7DDA294134077420159F68 + 25: A0F4E4522832676B49E7CD393E6D9761 + 26: F55C27D180948585819833322D7BC4CA + 27: 0A3975A0113E1FE6A66F8C7D529715B5 + 28: F77135C5D04096181305C0906BAEE789 + 29: 31FF81B49B9003D73F878F810D49C851 + 30: BE1E12BF021D0DB2FC5CE7D5348A1DE7 + 31: CB4AF60D7340EC6849574DF1E5BAA24E + 32: 7C5ABDBA19396D7BE48C2A84F8CC747B + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/notes/hmac_tv.txt b/xmhf-64/xmhf/third-party/libtomcrypt/notes/hmac_tv.txt new file mode 100644 index 0000000000..18edd70a39 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/notes/hmac_tv.txt @@ -0,0 +1,1771 @@ +HMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are HMACed. The initial key is +of the same format (the same length as the HASH output size). The HMAC key in step N+1 is the HMAC output of +step N. + +HMAC-tiger + 0: 2EF793765716EE48A671BDB5F002103C43734304C8717C85 + 1: AE61B56C82BE9FF96DCFBC20DD02B4BEA4FC6B6D5F4EC412 + 2: B54ADBFB404457E6C5AFCCEC27199D1F259EE1994FFFE99F + 3: 08AEEC38E88403BB854935EB6F1464CE95B044F4B4202524 + 4: 4C9DAEDC1929E22128F2A7ED5F3556D8A6D3A8315A7B556A + 5: 764794ED9EE1F94891835CC3A361FE75C600C7951A07F450 + 6: 1A4C447A0FB8826A0881ED2E7BD89499EACA4B6C49F96060 + 7: 1396A21D8B465C6B898511DF94846588EE8E35C0095AD90A + 8: 7552EB03CE26A8F079AC96B42F556FEAEB756014B8FDE622 + 9: 835B7CCA9D9F13BA2A36CBD746E5C92D5B2D123CA2EC848E + 10: 7CF4EA88FF8B9A5A57E5ABB6B35278EE9D8653F624D662FE + 11: D588D953C6F438D077A1E302F84E25EF31AD99B9C5FC9DB4 + 12: 86EC62CF1A08CEA9171AC742E8E615B3F0C7B6FBC95DC3C8 + 13: 6EE7C51E26187F86370A26811C75136E28B0C39A113D80F8 + 14: E1326D54123BC26CF41B30F9F2BA2E732203836AF8A74273 + 15: F211E4C46862E3AC8B8E69976A705582CF6D1B34A6D342B7 + 16: 0C6160FEFE70C81C71B7465F42F070F30808CDAE448D1974 + 17: 492FC6BC091489F926F0F54CBF3E3F6C8CEC6ED14DF2DF8C + 18: FD166027ABD1BD9DBA13E3908D16C403E1691FF173328CA4 + 19: 28D99C64CDFFAC1E6F7B33C8E675E49749CE835A177A1C63 + 20: FD7BD55BC2A684F4875C811143A2997356AA87A300345843 + 21: DB8968E787BF65C00992ED9DDE974EA71BA947395111FFB3 + 22: 4C31B2FA4E6F7F40DECA589F85BB69BFAD1815A73CF9EB23 + 23: B4D8D7FCB314942F171F85EA0953F7816DA9F07D72AF48B5 + 24: 9A6A70BAD76203A7A1F64D1EE34375EC8BCB21810ECE0B68 + 25: D21D7E5EF6F1579C84428AB5D574468933BA037C9B0C34B6 + 26: 3C5292C87B24626241693F0EBE20A96800905691C5945E65 + 27: 350BEEC075258BA7FE0314E6803152B021570F067AE0D4D4 + 28: 6881F892886F9D66E68B937BB3A71FF5CB064611C722996E + 29: 07831F1B2D00108386339F192729687B2F57B9DAB2B1210B + 30: 38DE8DE8398EEC32939A239BC0198B0CFB18D12E4F2A3023 + 31: 5B683578F81867054089AE2E1B20E02B3BD92334CBB01FA9 + 32: E30A80BE07651BA17E2DF0D43A583A9DB268DFF3AB7393ED + 33: 42341B1EC4F61E90571188F5599FBA9ACF884B1E15694921 + 34: 7D98297D65F5FEA85CB967F22AE0707E03F305BF1D2249DD + 35: BC8EE5CE0FA8F9E6694406009EC9358BC420B7E5DE07B6F8 + 36: B8095DE6770CB4CC2127FA672F93F39CA4AF0CCBB9805DDB + 37: 20C0E981DF1B763B6BB47D43F66765AD434127C1FC55F829 + 38: 59795328D40D2CE6CFDED8DD5089F2D5B796C9438E7646CA + 39: 0789CAB229AD54416C82CA5A2E667EC7CE66019FCACF766D + 40: F7C81B1AE705019FF9A9905972AFD72484A70E11FB81B278 + 41: E72F52644BF5EE59BE87DF692EF0070D095115B7664BB53A + 42: B9A5DD984358D0B0F3C2781BA60E9BD3473C1C89C7982F23 + 43: F7BA22269249759F1A87AEA0A125D4DF9B58E93714449008 + 44: 5D2257317F8978576CD7D2CCD346E861A59FE949F74A3D82 + 45: 199D8D5B0B5C5B61E046F50E0E389DA6F19CB3A7A37C8588 + 46: F489CC6CB2D3E9F741D6C9008265CCA97E7E54D62F5EB85F + 47: A5E7CB0787EB7E62A9CFD8486390A6628C9876654B9E85E4 + 48: 22FA78EA17F0D29E16276C70A564D234BC4ECA7302301528 + 49: 4422534FB9EEC601CE7662345D6B6FF932E54BB0483C2F62 + 50: 5D2E2B90B460D393F36BF32B2F491E224EF388FA72A48501 + 51: EA5287BCBB856BF04FC785541079087CE24783E9310F3090 + 52: DEDA3920899FA69F913AE50A4F0D7119C9D3CE8F4E6D5BB2 + 53: B2F55D8EA64C9842BFEA4FADFE616664CD44C57D53998C58 + 54: 3D2C72F26188E1EF5C0F0FC8B541224066C4DF455FEE78FF + 55: 50BB36BD8A8D97E4D6CA78DDCDAD0690FBBC93DC9A66BF18 + 56: 48140E192FF8AB74FC22676AAAA186C1A7E2FA0166E986AC + 57: 40AFD540C40EE7E598D26AE3FE5A47939299B5DD46B0B4FE + 58: CEBBBD763B077342BA16D4B20412C9EDE0F0508ABCE3501B + 59: 0FE4DFE539160F5924C324B8B43DACB4F220195D286C6FA1 + 60: A06D135075F943CEE74AAB1B8DE08B772055551B1E73ED48 + 61: D4E1B5EBBDA5CDA5040DD697BB96DD702C6730CFCC012992 + 62: BD5E77B67B42C507C4912130C8880A9DBD66431DCA0C0038 + 63: D81F583A9B4DD1F48028CA602CC0F131D60561FA34F7B3B4 + 64: A41F0481EE52842CDF676177F8E43BC1F1B00A5682C63E15 + 65: CDB29E274ABEB20EECC8378D5BD806997502E4271AB56708 + 66: B8366ABD45565BB3D26CE46B6F419F74B34851863FF4C336 + 67: 5AD2C193D6D51C9C7E56C5BFF55C1D61E045366B51E7F619 + 68: 9948E3AB7D121B15A6CA8DFDF4EE5377C957F0DE891C3575 + 69: 095676D61096853635128A80570BD1CE803AC7249C0A0F57 + 70: 354F4CCC1E5112770B2AB035AE07200A6CDC0280AD088AFB + 71: A8723395E80BED25DFE8F9ACEDA942A77D225D00440302D2 + 72: 0D2BCE0F8CF396FD8277C8BD9B19D54965308D3ED04D2F27 + 73: 54B1939E9944F499798B3DCE3479AC315F2C42A1EF231984 + 74: 5CFF726EE4B2596240E6CBBC66D7C737A4D12A702B40E81E + 75: 82996D7F3F27B473BDA647BBBA7230DF217288F2D1A38B99 + 76: CB95F63E0E7A2EC4F26E94B81A3C8C757E04EEEAB35A8C2A + 77: 057DEDF45207EA885A0BAC5B64240DD21CB9D99CD8F38FEA + 78: 27DCDD1ABA459506EF98E5C8D567692264C4153F91FDB269 + 79: 911C83660F7EE8CFB5F54890AE98CCA36C4C12B8CC771DF8 + 80: 67CD07209988C517FAEE01E64AC4B5CF261B6035069508FA + 81: D9A40C407E2BA852684770A5EB08D8502DFD264F2DE5A5FC + 82: 9AAC50A2BCFD74BE3DF85237478AAA833484FA3DF912A3AC + 83: 38078488F6183B5A94B655F24212FC9769450D93986C9208 + 84: 2EFFCBFA4CCCAFCA66BF8B368FB1FEFAC280C20416BB90EC + 85: D626FD6D285C49F20E99B88B9F82640D93D9E765CA55B5B0 + 86: B1DD178943B26AA241D34031D3128344C6955F6A942CC5D3 + 87: DA0C850E2067F9FDAE433C1230E0F629700FC8896ADDBDE9 + 88: 58E393E353BD7DF75A591904AA99526E94FA45C98D095E21 + 89: 323D0E04D239BD70192B2ACCB9ACF06E2F8C3B07565893AE + 90: F9C4147C6921640C097534BB08020540B420AD569D03665B + 91: 5171DB964AC815B3A6D058419FD47833DDAED71039966E6D + 92: E7DC7C574AFC2C9A59E46CB8ADBD03330A5321B237DF7899 + 93: 97074CDA9FF8D40B0501E9F632ED7335D6A7926101A34C0C + 94: BDDCD4D007DE39680B80F9AF9803A9F21C836EA971250CD4 + 95: 0DBFF45E3155098D4B4C13815FB461D3C4BE41E9E1A68757 + 96: FC16CB95478E4D23A7AD15CCAE3C24BBB3D0FBDC8A00A144 + 97: 93A7CB506481D6A72EAB14A2BA544F8631542B55903CCAAE + 98: 9CC1FFA19736AB6EB36EB4A2C1624FCB6913B255D2346795 + 99: CE3526A088FFEDEA4345AB221707848823B16DADD19AB487 +100: 1E1D790323586DB8A306EDCCAC8C64A6F29A36F772B8D61D +101: 8C403515F2B9014E9519EC04769ACCF23E522D3E22DE7F41 +102: 6B6A634607634804988301240CA5AB029A9E86E51281D64E +103: C7C3483CC8E6B58520B554259EB08866AA7980B53FFB6B86 +104: 96E429611C9E411321947469E2095CD9B0EF29578030E40F +105: 5C5A7F2B7F1F9BCE730BE2779304A443188FD3B31DD2BF19 +106: 70933F999325353277E0AA1F543B5CBED3F28DAF4FC70A57 +107: 5CD6D136FDDF4AE9CE42F008301FB6647096D5007E79973F +108: 1162BA742AD199AC17FC707285301A82BA9CB12C09BA229D +109: C36615F6D5E29E6CABB7EBC44A6D3F7B024DAFBD338FEFFA +110: C29FEF051D1606CEFCE3417BD571CB9188BBF0FA8AB98679 +111: F925144EDDD27244E19E4B6E433F312C6CDE43EF4F9B84B5 +112: C4230A59E54A34D0709F3F1DB02C18EC8AA270078DE424D5 +113: EB1699CAEC36681CCF8A9144DFB5050566042977D15FD1F9 +114: 9FBF0D9B2DD9A6E87240E538590E9799B76E22604D22AB75 +115: 2657EA06D69A78A5895A9169F849B3DE111B31E5673A8E17 +116: D1F9E1BA4F4E52CDAAFC388FA4C366EF4BD5F440608D86B0 +117: 049196BFFD9F77175FA936066C3119293EAB79D1E0028C8F +118: 9CC1BD2CADDEC1D82FFAFA7031F2E5C9B6765CF1727A0ACB +119: ED00438670D68A70CE2E0729997CC9648947EEA35809B8C7 +120: A520A0089BC16C84CB8E05425B330C6D261108EE3049FACF +121: A55B470483E547D2752EDC3C4FDCF3B4C48A1990AD857941 +122: 46A78E772C533EC8EDA60EB4A127FCEBD35E7D0E7F183241 +123: 5EB9A774124D571FCCC83D1F36C603D9C387390DFB3928B2 +124: E904066FC77F73CA41166297A8FC631FF59634B659F0AED0 +125: B85B66AEF7D9904356F1CAA5583757D1D69EEBB8AB1D1420 +126: 6639F85214BC798D71B757FCD480CB78D325881781A3A073 +127: C5B72BBE80917B55036A9AD6908D59293C49373F0BDD104B +128: C0BD695F6B9B42DAB543C31BA73C9497A6AA6419A007A9F6 + +HMAC-md2 + 0: D39AD9DDE006587A8BE949B11B9288F8 + 1: FCB21B5348C95E8A8DCBEE50A80302CA + 2: 2F26B6ACCD0E03FE9B21A1B0E75FF665 + 3: 17CF85D985D0D85F545897CD42C6EFE5 + 4: 1537A6943B4F5AC1272E4161225D987B + 5: 83E17165D62CA6E4B9ED67DF1E599954 + 6: 7A3195C863DFF86A98968F254E128E61 + 7: BD05057AEBFCB92FA4B07456085EC6C2 + 8: 23AC0D307BFC2E87760F8BDB21851DF8 + 9: 2CD26A2F2994106A375BEB0433575BDE + 10: 1F63BFC44FDBE9A966CD90DF82265EFD + 11: 72735FAADC3819CC24CFCE1D589BA311 + 12: 28B589C3C8078B8FFEF1C8297E33C1E6 + 13: 70A6DC014CAD2752931A47C0879D2371 + 14: 81694317A37FFBA816504974F38B4829 + 15: 72F26208B3051F1B938EA7E03DD8C107 + 16: F945F57FE0696A4C81EC59AE69384FAB + 17: 54D8DFCEE33969486956698495B4BFD0 + 18: 508B82F88A234E753A9E305E15A14D82 + 19: 527D77D2AB25131693B02F653ACBD90E + 20: 4868AC540FCC3A896D5A89F7A0444D36 + 21: 6189807C5FDDDD68D20356ADF3B90DC2 + 22: 0356362F2BC4206F2B930C4282213758 + 23: 2F59956F19B3CAD687C66C4EC3CC916D + 24: E30CEFBDA3FA1A8EDDE3B72614ADDEDF + 25: 33E0E6BFCBC9581BBCDF13F4D3F26724 + 26: B11C6476F9775219A9F18B5E88857790 + 27: 49C7A9D7F56344BD405E53BE927E3A58 + 28: 99A06874B0F0CA45C9F29E05D213195F + 29: D21A60A18F061FC453AD5AC2A519071A + 30: 2F735E82090144C036E3D12DEF2E0030 + 31: F9539EAC81BBCD0069A31E2A3C43769D + 32: EDCAA9C85A614AB6A620B25AF955D66A + +HMAC-md4 + 0: 752E874F35085E497D5032112CC65131 + 1: 6B2CAAEE210F970AB481D6D8EE753114 + 2: 2162A41522C2DB0B8AF1F0C712C19A22 + 3: 7C2106C3CB687F35FE2658BEEFB497A5 + 4: 3715333CA3EB74A15B4B1802A1A78921 + 5: 403D9A691A130AFFFB81A655AAE1D956 + 6: E697C3CB42716CA1973DE0D15486068E + 7: 99676F34E42C61E396F0E76BCB77BEAB + 8: A2B2CE8CF8AC151C5556A36D58894C61 + 9: B8614BFF1DAAEA90BF319F333024976C + 10: B8759E8B97DFCBB2DB94D8CBE2C96B20 + 11: CFFE6119EB0C649831459339C1B0C82A + 12: B2FC0DBA9C4830CA66423728599D3660 + 13: 454749F1DE579F1918FF046FC1CAE7F6 + 14: CC625178FEFD46481B7D02618AF6194E + 15: C26D523EFCC42C4AF7EEC2EA4B45B719 + 16: C352DA2D077FA3F493A5CE0E9A79CB87 + 17: 570DDE9FD220F59867F17484605D2061 + 18: FF5954A163CBA61CD3C8424CC71682C8 + 19: 1240D12E3D6C07F6FE1CD595C847C038 + 20: E87A4D7958C43CA71791B13E16301036 + 21: B2CEDE4A15F8D64C53D243F8C5763C05 + 22: 54A9E9EAE155E7AFA6FC8A7E05D7FA9B + 23: DF0E79F27CE25E56ABCFF5E74D1212CA + 24: D9BE454A95E5D9127990577F7EB7183E + 25: 26F9221A8B854767861BF0281303B89E + 26: 92BD4CC81A673B254A4AB493864BB014 + 27: EBC3851E0AD28BE9876BEFD6B0A88B44 + 28: 1134BC8A40E1D2FB038B67548AC2040B + 29: 954700135C4E7F232337C84130B43360 + 30: 8C3EF2D8F896C8D252851A1543F72493 + 31: 52817E79D2B0B3A37DC08D18D3519F92 + 32: DA661A428B9659DD59545E3B09162F8F + 33: 3FF5BB67B48F87B4B642DACCD2E4001E + 34: C674F95BB622D7B8281FFF34E9EF3E7B + 35: 3A4D25E3BCABAD8CD4918CE650EF00E9 + 36: 2D91248C51837A8B80898E2CE42CBCB4 + 37: C0B3BD2B36493F0EAF9AAFEFDC37064F + 38: 9B4723B091102B480B2B59069317F292 + 39: 0F8EABB489254491FE19AD0E328A483C + 40: 25469BD482E1405E51AA021752394C4C + 41: DF1DF50EF9D95892D08DFEFB79D6552B + 42: 707A546964CB22710482C478E58C2E0F + 43: D1E243DB14E2F946D650C811030ADE9A + 44: 11A1AEA678E98A65420747DD6CF9293F + 45: 66E735F658BD689A9F1BA0B526827CF9 + 46: 98170734E67F576CCC3D01D83965A6C9 + 47: 399D99CB7979E80F6D3B5D5BBA5871CA + 48: C26651C32EABC76289CD0843D3BCDD92 + 49: AE0F50954C90E8897BCF504592D0626C + 50: EA3AB701136862428EC326D2551F8AC8 + 51: 4AE98E5A1E6B1BA8CEAE844E34934039 + 52: 7C9826187053186DDC2760AE6FB56DC7 + 53: FE0F555B851CAD830BAC9FBB40705671 + 54: 221BB509584BCC7E10F3B4FAB2AEB1F3 + 55: DD93EAFE25EE27C6FDC2CCDE7D273267 + 56: 535472E1ECD49FAA75CC6621BE7E6210 + 57: DA4554FF7D5B289A03D195F94154AF47 + 58: F15A3F547B5A3844BFF713CBCEF701A1 + 59: 279DE06FD5644C520BADD3B97D96274D + 60: B933E929073492EC1E2AEB78071C7B83 + 61: D1DA2335654AB4CEBAE5C2E78CF27553 + 62: 06FC50285F4BA5C8B5A478E9C02D6434 + 63: DB66A5D55224DDB50337B7FEF9A808A7 + 64: ECFCD0385FB49553EC89DD94AB084D23 + 65: 4187B0B79E6CB916F747B857AB2F75D3 + 66: E03E14F5E00B2DFC0614308608B929B9 + 67: 5F61FC3005167EB3256DB549DA8BA562 + 68: 21A4D14DF8E934A858569D8BA7F151E8 + 69: 5955DDA4CEF16ABADE2B551841C69B8B + 70: 8E77066A973B60DF64C27DBB93EF204A + 71: 2101EE9DC8221FF17D9D887FC39F41BA + 72: 6574A9DE32B7A673B5BA20FF18EF8C93 + 73: F571B14C9F5C5C1858D48AA944A13050 + 74: 0BA4BE0A5E853D07F79B2D29BCF046B5 + 75: F240C8C38D71131F510369D79FA32208 + 76: 920C294DE37C28803FF3C49A4135CD65 + 77: 38796D25822AD8F2AB4D64E4A65626A0 + 78: 65A203170FDF794397FD1090E318C5DA + 79: 965A767FE4A75BEECE26BAA79D816AD7 + 80: 0F4B30947B790C47924657648FA1D88C + 81: 74B05F7B7D006F7DDAB31DAE251C3BB3 + 82: 61B0366B57A8F46C2F6C16F935DA768F + 83: D4CB13CA922B542980F854C9780A1951 + 84: 039B2F23A1CE410FF4696D9C35C40C08 + 85: 2D734E28F995C2AA2A7AE2412EB99A10 + 86: 1A55FE47703ECDBE446033F492412812 + 87: 6AF4CED86D0181D6E99EE6AE57F295EC + 88: 69C239A875E0352D20BCFBCF8D5CA19F + 89: 62723FBBF0AC6F397438589AF06625A1 + 90: 424EC9353901795251AEF7D7BCFEB8BE + 91: 9BBE4ED6C8BD14F85BA86E553B1B8152 + 92: D7840AA82F788B7D58712E29003D1239 + 93: 4AA55512DCAF770FE4D9428FB318B0B0 + 94: D040BA08BEDFFB20D2C499FEB35EE12A + 95: 0F295EDEFC85546547860B7F7CDFB1AE + 96: 720FCD871B7D8824EE6A7DE9FF1A62BE + 97: 2FE3AD14E24C441C36186673A0D60767 + 98: 943FD502136B66D0313951198680F746 + 99: 4EE6829F3EFFD0A87115512ED28C85BA +100: 6EE1AC28A320246CA5C37F981E22D294 +101: 36BC623D6573C3ADB164F8A6F02315AB +102: 08B3AAED34FB0A0F99C4B22714B9CEAD +103: BDCD10B66096AB992DEC5539773EAF23 +104: 6DA36A53A79FA2C68E5060C0D2D43E13 +105: A3E886199532C025074D4646113F9C23 +106: 00D67A1D2ADCA77A20441CBF593FDEE5 +107: 2E4399F5FB44FF5573B73D01C5B248E2 +108: ED22A18A8824A30B68EE0EF9907B2B91 +109: 36166824634304417BECCC9519899CDD +110: 0757DB01193BEEE90617AA8CAD0360A8 +111: F7691CBEF4ED2E9FE4EB992CB3939970 +112: 09DC2FA975CBE8CE828919957D110EC2 +113: 7DDB74DEC57AE8C318AA5CCFB53872F6 +114: A26B7DD0AA30EAAF1F4F8314AB7DF16A +115: 088855527BEBCDB67A40FEA4FDDCC061 +116: D0F8ECC0C32B7060CB6128279F57FD80 +117: DF5B79D3671CA5E5B44CD395F6FFA551 +118: DA8999EA059C463D5F05D04020EE867D +119: C0EE404DD8447AA70D3725D5634E2B53 +120: D19D1A725F5E9F0DF21871B31900CA73 +121: EC202984BE149C93CC1D440CF6D29E1F +122: 422DB7C21B1348983B75498E270FE6C1 +123: EF136334BC30C92DB9082A9654B391E4 +124: 0B3526430AE734054873B14DD696CB3E +125: 3BEB77C0F85F8C6F21790ADF30EBB812 +126: 4376F8C8EAF5A94871822DBDFBB5F88D +127: F7DEAF52378FF735B2D171B17EF573D8 +128: B4FA8DFD3AD4C88EABC8505D4901B057 + +HMAC-md5 + 0: C91E40247251F39BDFE6A7B72A5857F9 + 1: 00FF2644D0E3699F677F58ECDF57082F + 2: 1B6C2DB6819A4F023FFE21B91E284E93 + 3: 04B0ED3E73FBB9A94444FDFFAA530695 + 4: 1557A22261110DFB31ACE25936BDE45D + 5: 54C5A67A9CB4544CA66BBDA1A2B8479E + 6: F803D9E43C934545AF078FFBB34BC30B + 7: 32F56EA655DF36D845E430D637C85D17 + 8: 14BD2095F4A478C10EEBFF379DE76DD3 + 9: AAF6867B3FA01DD26312B0DFD6371A2A + 10: 0FA2A6FEFEBE7CE3C31A38400F8AB260 + 11: 54C37BE13B7333287D0E74AA9D9227F6 + 12: 385D75A58B0C95E5CDC059DB168BD1D2 + 13: E73003103ED65C08E62D46AE1E1B771A + 14: 278ED4A4EBEA1FFA5EEC874F198C0CC0 + 15: F65CE9EEA7FDB90B9CC603329D3FB9A9 + 16: 8640836944EE0009B2CC6FDC3F5C39E1 + 17: 7819A99F82BABDF060AA51AE109629DB + 18: EF26336668486C76921D1DAB67ED5673 + 19: 13ED7BC140F1496E09AD29C644586957 + 20: 5FDD337CE9C4AC8D910833FCC2BD837E + 21: E9470246ABF7CF4D37FD378738D8F763 + 22: 384A75C33EFFA12EB69187BB80DF843B + 23: 63866A5406B9EA0341032FCFD0244A4B + 24: 8042F8572C8A9B88E135ACB83EF1FD39 + 25: BD1BE6AF2D022F966F612569E191F0E9 + 26: 9F70C839533EE4C7B3CF20C6FB65C94C + 27: 800A5CE92CA4FEE6F1D353F496113873 + 28: C35E93E1E54C84C4389D2DE71E1B9846 + 29: A130EF5F91465F5A56999F450E63F4F9 + 30: 5F16564E05285A099F628245DF9A3C2A + 31: A34F7E3DF06DD84CC67E8A922240D60B + 32: 945E50753B6E6C920183822D5F280F10 + 33: 2DDD269DBCDF5C21A1C3FD540FF4ABA9 + 34: 212FE3E2CEF7DF74FC01CC2CC83119B8 + 35: D98B2930011649F16C08BC8C0178D838 + 36: E39E21026111C1EFB0C491C0FDFA841D + 37: AE46DE06C3B0D2CEC35352C95A1003F0 + 38: 5550EE50BF88C9DE5ADA34567FE044C7 + 39: 6BC486627760373EACFF508F7032BF31 + 40: AE6E0B8DBCFDCCA4B3449B57647D5AE5 + 41: 6BE5A0F140DFC4B75439630E6F9A36EE + 42: E3E4E735BFE79397D4653A6243DF1925 + 43: 68C1D9E8973A3F6B92B588469D68A2A5 + 44: 956132D512118D5F446C8CB912B924D9 + 45: DF5C2AD650B3CA7A89EBF92EE618C845 + 46: 14D375CF7E4294ED99135E4237414F01 + 47: DB966D40B447692E2D13CC0C09C1B495 + 48: 53DADCF1C6B99BD403052A1CE1ED0D14 + 49: DEC4A3C1DB8F6AA4515C512C9299C4DC + 50: 3B3A51DD83AB1DC56A7F0CBE1C71923F + 51: 03C73353B3203EF9CDB95F9DB8750AF1 + 52: ED9E15FD86D66DA2D546D2BFC55041AD + 53: 81B649338F9DB1C6E592427D38221C7C + 54: 92E170E13BF40FF65E3B4C665F222DD5 + 55: 00D5E23F5F829B21D454C4445851AB53 + 56: 39057029AF0B3F4391A7BDC6DDCE4D07 + 57: 2DEACEFA698F9CCAD5198C4E17E69A93 + 58: AD35FD52EA199E26948009DF3546D3A2 + 59: 4C42CF2CFD4D8FD9A06E3F73D02FE818 + 60: 4D7C893E4313FFF72103854463414277 + 61: 3F04E8B32AB56EAF216503E46BD7AEBE + 62: F015DDC3EEF41ECC93E944FA3577DB52 + 63: 31F77A50A2ED96ED8E4A3CE04B9DAA23 + 64: FBF481373481756E0C88978F7E0809A2 + 65: 7D8D793B287C04E7D2896D76EAA5CA15 + 66: DAC74AEBECC2385DD9D0C3147CCA1F78 + 67: F6DDE50D37B460FF5E8B4C03A0854BD5 + 68: 5710D6A54A2124E06A6DADBE9BF76119 + 69: 19DB5D13A53E57184759F33976537AA5 + 70: 848DD8D32130626FBD11B0133C2A29E3 + 71: 4F75BE04BF2F6DD85D048DB82F19C38C + 72: 4AE9436540ED24BCB5EC62977AC90789 + 73: 859D1A9FC2B795AD60F24A37EB9EF890 + 74: CD45865317FD17B652DE9F9EBBBA16B6 + 75: 52313319D395F453BA2C0A0159CF180B + 76: A7B190C0EECACCA4DFC5B45DFB324718 + 77: 23E85CAE85B50F45F7F48EE0F22FDE85 + 78: 6A80DBFF139A5345235EF76586CFCBC7 + 79: 850E638FCE5A2F3B1D1FE9C28F05EF49 + 80: 797CDC3F7E271FC9A3D0566A905D1CFE + 81: 030CE97A9A0B1D5403E253D883FCAF12 + 82: 648FFFF44E416D9DE606BA0DDB751194 + 83: FE15098E0DAC65FA8EE45CAC67121CC9 + 84: 17C90ECD390A8B41046B4C7FA0354E4F + 85: 7D149DFF5F6379B7DBF5C401DB6D2976 + 86: 8D055A4701DD51CB9D1AF8E2AE59BD21 + 87: F3481CB07B034EB4A023D00D4FDA9A86 + 88: FEB22562FFAAA9CCE5CDDA34C29E55C3 + 89: A620AA447216709D8CE5C5F23474ECF8 + 90: F25FCBB2BF7440C5E3C5B53092B8C828 + 91: DBBAE1CF60BBCA0B05EDEA0B362F0A33 + 92: E18E85BCB4633A797FAF7975CEF44B84 + 93: 1BE27EEC72C2EDE151978705C7C7DED2 + 94: A15D36C5C5BED77699838832FC225DD8 + 95: 08F31E68BFBBB420742F80B20B69BE8C + 96: 5E9B4B5B3228F533BA8EFC3C0B9AAD3D + 97: 1239BA6D941D1D8AD2ED561BF517D4B4 + 98: 5233F50218E0D097EFCC68F1536F30AE + 99: 340B47C78B003272EAA4B9D22C3B0542 +100: E7F11759FE8A897364C21767570885BB +101: 054BD6ACBFD5421C0290B0839C0A0ACC +102: CC0748F7B2CC921CF5FA019F955066C9 +103: A4DF167697949B1AEDBBA3226A334BAA +104: 29893B9776BA5E750A9FCEA37B0116AE +105: 2DC25C935F006F7965FAB3256D77004D +106: 24089811FFF2189FB9AF38651F43977D +107: 0E048569D634BF652CD8EBF859C9B69A +108: 00386B569DAB73844A708BA5B48BBAA8 +109: 8033E1AFFBE1218F81C8331343FBE5B5 +110: 9B82008A34F3847C1204ACA89F3D57D1 +111: BE1A529F88AA05A42AFC40F663E97849 +112: 5237637AA645E83B0E56A1361AB80643 +113: 15BC4405E891ADAF48FA56D4356705D5 +114: 0820087438832B63AADC479CFC88BDBF +115: B1E3BA7E96605D5FF614B1BEC1F57AC1 +116: 838A096D64E6C0DDB069DC89E4C3F839 +117: 934BCE159F3959A933C87AB497CA8D42 +118: CA501F1DE619A570DC38FDCB8B3F7722 +119: 033B27D5994A6F5D5F6800539B69E876 +120: B447FC68FEF4E3CF9290B06EB6AECAA3 +121: DD3D3F72F0F1FBCD030D839DCFEE457A +122: EE73C4C996E0150D93B3144F20FB2C1B +123: 5AF9679D2441542391C6A903FD8C1626 +124: 2BD84B87230511DAE7256B62A46AA45E +125: EB159E5694C191F7708951EBC0AAF135 +126: 60F02EFE1DAFAACF65F6664A2321B153 +127: 14E5A0E90D4420E765C4324B68174F46 +128: 09F1503BCD00E3A1B965B66B9609E998 + +HMAC-sha1 + 0: 06E8AD50FC1035823661D979E2968968CECD03D9 + 1: 0CE34DEAAD5CF1131D9528FAB8E46E12F8FE3052 + 2: 23924849643D03BBEAC71755A878A83BD83F5280 + 3: 6119DD9A7024A23F293A3B67EFA2BF1D82EC0220 + 4: 379DC76AC2D322FD8E5117CCA765391BC0E10942 + 5: 7897CC86CFF17A3F95C7AF02CCA03546F5CC2368 + 6: 1FA1EF3980E86B8DF2C8E744309381727ED10E8E + 7: 03B2B726D71DAC6A2BEE63EAA09631DA78F5958B + 8: B8CAC4C104997A547374803B5898057B3F8110A9 + 9: E165E07F8D542FB288C7D367198D0618DE3C9917 + 10: 18125F046C675F434B3C53A28C301FB2D91B5D34 + 11: FAAB993F2FEAE442D28FDBB613D2C768ED13342D + 12: B657E7EE3A65C6484D007E21484813D9AED1264C + 13: EEEC2BB7BAC158742711ED13090FA20462A5E5C0 + 14: 12367F3A4E1501D32D1731B39CD2DB2C5DF5D011 + 15: 57DD9DA36E7A4E567A2C5AE9F6230CF661855D90 + 16: E37110DDD295D93990C4531D95564E74C0EBE264 + 17: B2115C4E923EC640E5B4B507F7BC97FE700E12DD + 18: ED20C67345867AB07E9171B06C9B3B2928F43188 + 19: 6CA7DFC9F8F432DED42E4EFE9F2D70D82507802D + 20: B39EB4D2C190E0CE8FA2C994E92D18CFBCD8F736 + 21: 91BE5ABF1B35F6227772E36337F258420CF51314 + 22: EB957199EF666C6D0EACC64FC4261D11C715BB23 + 23: 2A18D8D4AB1F8C528C9D368BF5A7CFFC2168D067 + 24: D4DC370D482D82932701DF8CEAC9337682C2551B + 25: DB9665A6A26DBDE20238F04E9F1A368D26564E4F + 26: D5AE212C9E543F2656699B59DEED54CAACA9A071 + 27: BE8890F9DEC6A02AE2848D8505B6408E884E6D1A + 28: E8D9DD9FAA3080560B0EDE798B745FEE2A1E5479 + 29: E219219D2CB8C363C2687F578446ADE1C0404287 + 30: E8E7767B35ED8D0965F68272ACE61924CB044262 + 31: 1B26689C1EF55448A61DFAEF98B6E7206A9675EA + 32: FE850390864E98A17FC43C3C871383169741B46D + 33: 3F63068D536A282C53E5C003BCEEC96646CF7455 + 34: 2962C292CE247F11ACB7E1F981447C51E9BBE63C + 35: B28909A2B7B2E0E13FDCB1124B0BDC31D7D2FEDE + 36: 8DA0FC30C8322DABD67D61E82FC92351894789AC + 37: 543DAC6D449FE2DDC3201927D08695F68F832905 + 38: 371540F3092F77867F0CA9DA69318C7673F68388 + 39: 7EAF32204EA5993C87E9A12C67ADA4C85D253281 + 40: FC4994BAA05F592901085ED7DA188EC3A9BF36E3 + 41: EBFE77592EF34E81BDA05305876411484DC0744F + 42: 25F64E8F076305D6F5741EA58232F68B725B8F6E + 43: 5DBA03F7E4B4226666F0D8D5BF49FEE77951D121 + 44: 98E1D56D723DCACF227D2AC67BF2D6E7FD013497 + 45: 53550BC55A367D87416FFA25261362E7D4618DA2 + 46: B18434BCCCC5F08B35397C1A6684D60F4F3A452F + 47: FF2BF38DFC6909B46A01E055D173F67A7E456341 + 48: DAFA445432ED37FEC99059DB8A0BC528E788E95D + 49: 7FF823C570F8B4C0E483165C076AEA7B5E727632 + 50: BC4FC948AB621FE1419CF6006DC04E7D7B32FA23 + 51: 1678AFCC3FBD1063E7C82CACAD5B6A933A93091A + 52: 97DC2F9F56738FDAFFD555BF09274153FC2FD009 + 53: 74F5CB4F0900441B7AFFC278C01A3038DF3D60C8 + 54: 021F66143270C9D58F26AB193DBA81A811917CBC + 55: F486D1C8127813FEEEA8A693C4B8ECB5BB53C3A2 + 56: 8397CAB8EED5B2164FEC6BE688971DFA2138934E + 57: E4477CE9BF8CC5A4CCDE039B4E3000F1A0F4153A + 58: D6D2D1E3EE4D643AC4B38836AE54E846F99B376D + 59: 9545B2C6279371D4D928AEE24328121D43DE1E5E + 60: 947ED38EC087C4E53F417E8216408863A8EBFCB2 + 61: 32518A2326ACDE1E962B3D0D2BF950F318894E83 + 62: 5D21D368FB9D879ADC27B341D608BCF860AB14F4 + 63: E2BEDD94D565A51915B1EC6FA9DE18C62D12533A + 64: 15ABF657DB6473C9E2F017C7A2F4DBA3CE7F33DD + 65: 0C9DAF8D959DAE3B66FF8A21A94BAFC523ABC462 + 66: A36BE72B501D435CB627C4555A426C4ADAF3D666 + 67: 1C171979D67A014A0422D6C3561C817A354CF67D + 68: B75485B08ED052A1F4C3BACCE3C563DF4BA82418 + 69: 17297624219C5955B3AF81E5ED61C6A5D05BD54D + 70: 38A9AC8544F0EF24A623433C05E7F068430DA13E + 71: 1E9EEEAD73E736D7B4F5ABB87BA0FABA623FB2E5 + 72: 4B9D59879EAC80E4DAB3537E9CA9A877F7FAE669 + 73: 7F76F2F875B2674B826C18B118942FBF1E75BE55 + 74: 1716A7804A9A5ABC9E737BDF5189F2784CE4F54B + 75: 168027EDF2A2641F364AF5DF1CB277A6E944EA32 + 76: FBC67DED8C1A1BEBBBC974E4787D2BA3205F2B1B + 77: 33DD26C53F3914FECF26D287E70E85D6971C3C41 + 78: 97906268286CD38E9C7A2FAF68A973143D389B2F + 79: 45C55948D3E062F8612EC98FEE91143AB17BCFC8 + 80: AE1337C129DF65513480E57E2A82B595096BF50F + 81: CEC4B5351F038EBCFDA4787B5DE44ED8DA30CD36 + 82: 6156A6742D90A212A02E3A7D4D7496B11ABCFC3C + 83: 3040F072DF33EBF813DA5760C6EB433270F33E8E + 84: EE1B015C16F91442BAD83E1F5138BD5AF1EB68E7 + 85: A929C6B8FD5599D1E20D6A0865C12793FD4E19E0 + 86: C0BFB5D2D75FB9FE0231EA1FCE7BD1FDAF337EE0 + 87: AB5F421A2210B263154D4DABB8DB51F61F8047DB + 88: 1B8F5346E3F0573E9C0C9294DD55E37B999D9630 + 89: 09DAA959E5A00EDC10121F2453892117DD3963AF + 90: ACB6DA427617B5CD69C5B74599D0503B46FC9E44 + 91: 9E1BB68B50BD441FB4340DA570055BBF056F77A2 + 92: D3E0C8E0C30BCB9017E76F96EEC709BF5F269760 + 93: BE61BB1BC00A6BE1CF7EFE59C1B9467D414CF643 + 94: 19D693B52266A2833ECA2BB929FBF4FCE691A5C9 + 95: B99816886D9FE43313358D6815231E50C3B62B05 + 96: 7A73EE3F1CF18B5E2006A20BB9E098E98B6513CA + 97: DEC620F008EF65A790A7D1139ACE6E8B8EFCCA5E + 98: B6BA0EBD215CF1B35742A41EB81A269ACB67C9A4 + 99: 3A0FAAD14D3B64BE4EDB9D5109DC05DFFA7680E2 +100: 12E62CE53283B5422D3EA5D8D00BC7F0AE8A127C +101: AA36F0CC6B50AB30286BA52BCB9BB5C1BD672D62 +102: 55120C68B419FE5E12DB526D4ABFC84871E5DEC9 +103: 372BF92A9A2507509C3D3932B32444B7BE1C9BAC +104: 7AB4B04EEC091F4ADA0807DDD743609BCD898404 +105: 20CB412425E88482E7D184EFEF79577BE97BAFDA +106: DEB91399A7BFB8323BC8E6A5F4045125277C1335 +107: 6769F41624E553B3092F5E6390E4D983B851C98C +108: 716760E4F99B59E90A4F914E1FB72A6D2C4B607A +109: DA0AA5548B5C0AF0CC494F34CAB662A30372DD11 +110: 17A0E2CA5EF666EB34E2ED9C10EBC5DDCD0D9BBB +111: 1B3614AF749EE359F64F3BE3650210CC3C3498ED +112: 346E604622CF8D6B7D03B9FE74E7A684AECCA999 +113: 629E46882D214F9BD78418C2A97900B2049F1C83 +114: 765F86114E942214E099E684E76E94F95E279568 +115: 002ED578F79094B3D7E28CC3B06CD230163F1586 +116: 52CC9748778AF5C8E8B41F9B948ABCECF446BE91 +117: 9326190BF3A15A060B106B1602C7A159E287FD4C +118: 18A5DFBAE6E7C9418973D18905A8915DCEF7B95B +119: 6D25BF1E8F1244ACB6998AA7B1CB09F36662F733 +120: 5F9806C0C1A82CEA6646503F634A698100A6685D +121: C3362CE612139290492225D96AB33B2ADFF7AF1E +122: 3D42A5C1EAFC725FF0907B600443EEF70E9B827E +123: 7FF97FFC5D4F40650D7A7E857E03C5D76EDD6767 +124: 3A92F2A18E8F593E6A8287921E15E2914DF651EF +125: CDE6F2F58166285390B71640A19BD83CA605C942 +126: 21A227A8DA7A9F5D15C41354196D79FE524DE6F0 +127: EBE93AB44146621BAAB492823A74210D3E9FD35C +128: 6560BD2CDE7403083527E597C60988BB1EB21FF1 + +HMAC-sha224 + 0: 6E99E862E532E8936D78B5F02909B130AB09806B2AF02F7CB9D39D12 + 1: 1D1D08669FC34CDC5FE5621A524E7181CD5B5BAFCA3DA56D2E15FCD9 + 2: 014A21F82D0CAAD15EB74DD892187D7AD93F2BEB549A596DFF2C9AA9 + 3: 5F600F19EDED821AEED09781792F9435458A32A60FFC1B678FE2C905 + 4: 8D933E18052E7FD1F98E5E7D02384DA60F3E743801032256282AE2CA + 5: 21362A65B49C33568251CD1366EB13A4E683359855C00F3AD6710896 + 6: 1E1814B72BFB185265AF94FA622E4A1A70826C06F2BE2EFD96E4E168 + 7: 118F2E1C2F1AB8AF2BD17842FCBFAC966F5B21A81996E3CBADF76442 + 8: 2C6C72703E33A20EA0333629503EBCC41B64DB829064A5C7897C465B + 9: 794046ABC3BD8165D12C2453FFA3FC518D1A6498A48C91053BEA2966 + 10: E6C3B6E2DC215702960633C976B86B8378D7780FF884910454032C7E + 11: DE7CFF6E85D9411FBD58B28FACF72DFDAFA115614BEF3119F6527104 + 12: 11CF7495ADC07EC29EAA7B3464F772D49999A5E1832F71FCE18CF7F1 + 13: A7541E63945FCAD62D2570B015079DF0422E96075986B45772860F38 + 14: AFD3EB7EBFBA79CC68E4F6F6A2D758969B5C5C014FFB53CFF21C2841 + 15: 28D942E37CB92EDE2E6F994E9EEE2BA01077D099F3562FEF97A8CAC6 + 16: 34C7562962548AC9661759B4FC347D6A82CD47991EA06E855571CDE1 + 17: DA76FA12D69D1FDBA5E544495BBE45F620BE147B73D6AA64D3B3C298 + 18: FBF1911FA019CB7ACA20E3F93ECC0D5E8D60DCA0A1A7420C63BA1864 + 19: 565FEDE0EE20842B82D59644929C2A1A426E397B38FAA772781FE018 + 20: 7B9C2BA77B2989904F194021D308089E23F00954275AE9AD87306A31 + 21: 66CBF93ED8071FFA36B61F3AABFDBFE714C3C055B2FBDCD3CF369025 + 22: D96F10ECBFAD7FDDDF60BF1511E94869ED1D992051539E50D5F32831 + 23: 5473F93F0D979D77C3C6B9CEEB2F3DC1058D81401669EF4AEAFA17E7 + 24: 5B5A75A7D99C1B40961533C345B95FBF0AFA916D6E133967FCAA15F2 + 25: 2A1E50E18C37AB7BD928AE14C206FAC9B3E869173CA337FB9374565D + 26: BF2B241659C96007ADC25D9567947BAA740555D066636731EEAE3C97 + 27: 6E1E7B64A70B190BEEBDB9DA82C8E4B160CC73B8FFA224A6B92180B3 + 28: BE36A5F8DAE9294B3995D278CBE9273E66F04D46890B44EC55028C3B + 29: 9983C289CE2F806F41182752A753E0A890217DAF3778B3AD2ED6685E + 30: 8B0F08EDF2CBE25E8F9EE4D2948BA6BF81672BF4F509530328A8BAA2 + 31: B65FB77E6CB86E5F409EAC2F1B5A05E1910213563F816121AFA8CF14 + 32: 5D15E17C8C159EA5DF5F126B12ACE777EAB36A0082C57DF71E4D9609 + 33: DCCB3D17C8756F2546B3E5B24B1678438959D83A56524415666DAE05 + 34: D28DAB7CA715AC86BF4469D743A0005AEE0101F339350661D46A1684 + 35: E7A1CCC4B2B300457DCC64534152119390B69610C7FF9DD3A683439A + 36: 29380148DA403AD5911C7BD52C783EA97EC306F2B32BC426C4D7FD35 + 37: 56DF59CD635F025925A968591E60DF2CBAB22F98B67C78122F3CE868 + 38: C20EF10AE9CD99CBB54C94C971780E0487899D7A810FA51A6553DCF5 + 39: 5B78837F366097CAB6D31624C06B099BDC71286E3AD8873509ABF4CE + 40: 8DA09589C44E710B9F84014FE553074E72E0A86C9418EFBBE420D2C8 + 41: EEE18FA2BB5A5CD16017B4621ACC4211EF7CD60613A8C879B0AFC0D0 + 42: AD9670FCD043E6F91CE986E6F55905337248B72E7B8551AE72ED32BF + 43: 97FA4FBA4815DA49F6127C96C969574AA9543B338F93BF9171D2547E + 44: 838D5AC81EA6BACB827327E8EFE96CC2B14D92C55B40CE58F4DA181E + 45: CA99480DC8480FA07784EF02074453664DBC92257366514060F07C93 + 46: 93B0E493D272470F9F274DFE4B9DDF183B26011090E15861FA21CAF2 + 47: 770CAE487AE5890DC0B931EC17623293EFA5B22EE1ED496A37EB9FCE + 48: 6F1D5CA0446E7B82DA02847ED1761CF02D646E56FB0CAB9B120E5282 + 49: 2A8A1254F6CCC3D656397A5F2D64C266412FC5207866B073B77DBDEF + 50: E8CB788AAA965ED87FF2C7B5F3107684326DCBB0E667217E0EA62C51 + 51: 85BDB6D1486F27827D5870812BEEE2C3976E0DED4BD2F994BBEC12AA + 52: A14E0343FAD6BD78E0A8E3BCD6D0B6C83B1220FE6C89F57F44BC805C + 53: 2C60D71F2D4BEC90CF10804DCEDB9311637B34D62E9CB68B8503162A + 54: 36397D66B434BA744174DA541F080CF6582F10322C7FB1869A100141 + 55: F612E4EA307F56447112CAB5D2EBEA7D12C7C4427D9155D4085687FD + 56: 9798B420980748993BC78E3601B8AEEE2D2CF6E59799C7B07B88435E + 57: 50BED37F1EE78FAE16D178FECEC2EBE4776C8E5FC738F9506E8AF676 + 58: 2755438A9AC457B81999D9E1E479C36DD9AE1F920F5BE6D109ED7431 + 59: F3DC2238B13BA706A048253F86B79045B72EF767CF25DC62F96DAEA0 + 60: 11900A3154C4DFC49B941258A134C9201DFD280728BDB3F8BC7903F8 + 61: FC584202454DD7C9258F72A6258E42F3C2669FD138FD7AEE6200C4CB + 62: 185355C13E146EA89387C332225DF31CF114AEC0BA3A5A5B53667709 + 63: 8194DABD2F7A02DDDD7B752AB5669821519640EE3B0059FD333F3401 + 64: 2CD6946C6DB676ED1EC272AE34735A0546AFB8D996323272C39A814C + 65: B7A344BC5EFFEA97AC49894A85B96F9B570E680DFBB28C76F7F9A180 + 66: 9011B80655A9CC7964CBC4BEE1CC03074003CCCFF5DA553B289ECF6A + 67: 6BDE25371B7EA9ABE31A524E49CAAE40DB220E405463D93FC7F66904 + 68: 35694194E10D0EBCA6758099D09C99C3CAB37AFA52FC4F4361C510F3 + 69: 4E7A79F362D7AE5B1680F30E6770CA46FE6264C9FCA566718C01EF67 + 70: 9DD18D21E413AE12112AFBE16684BFD4FAED7467A2FD5904EF0B493C + 71: 7532D374B66B1E5B17EB49810DC3C04264553E4C36F4550D1E860B70 + 72: 35EB09C82A624B1E3ECD965ED8522E9572EBF26791EFA667B4DB952C + 73: B9C17DF6F2A6506FB1DFCF1A9089974C45760A438330AE7547DFE685 + 74: A7DD0267C15B36D8BD1879F879E894FB9F33F254556B87BFFEDD71A0 + 75: 68A354D120CD63A5D34EEE84B7E5E5BC1E5DF6E021F712BD4270B781 + 76: 441DC4884130D48BA134E2FBA86AF643C8EB79CD1AA4688F82E0D3DC + 77: 17A3F16DEAFDBC1DA00BD14D9C24497BE765F41E2EC79578421ED8B9 + 78: 8756A267D0CAD54BFC848FCC4D6B6C94D39CAF07831EE35324DCD35F + 79: 004EBADA70F19BAB48E6072E2090941DEDB5CC0A7B624E4BBB671382 + 80: B7F8D35CB865977423710FA1E0F939808E68ABB54BD7EB0427DA03DE + 81: F3D0AAA2F912FF95251D3CF51EBF79B940DB56839DEA8BA5872D1FDE + 82: 0835B2DC376BEAE873F1FA337D75C72FD1BF0F72A81669AA891F2722 + 83: 7CF9A7D57CADEC3F013D4BD87C00B420CBFF73670A9CBB072D18EBEB + 84: 68AC0A34930329F5AA40137987208481E34D8B9C08EF7A85AE3AB38B + 85: 00492F706D84B903D5355FDC0B68C2C33B484A95A173FDC4AC945028 + 86: 6F6C509CDCC84CE1C36AB76C9BF30E4422C90C869C164C64696AB5B7 + 87: 4C0A35D512BD0DB15915DE08FEA8E6027063A1780C104F6273CAD5C7 + 88: 27087F6425878D64A56BD5ACCC0E303F803B7208F20AEFEF75501F03 + 89: 4EF78140430EF60F3CA12AAF8132674B0DDB154F495029B4051C2A36 + 90: BCCA3153EF93AAF21CA02D235A23D3013976295E704223CB37E860BA + 91: 20CC8D4C64E09B00ABF23864BD7EDE542F5BE480AFC4B9551B301EBA + 92: ECA3F86DA00098D91F866C58558BB7B00C9E4239CF83C5A3E76291B3 + 93: 7AD9AB198858820D20373C45173D76AF8D68F829D9A250ECADEE0DA1 + 94: 3E1C202F2D589BDAB015306AD063784E5BEA48AE8D1DAF45D571D2FD + 95: 990C44330D56EBC9EDD951F8CB92D5847F4BD3C6442906F57A828FA9 + 96: C92F9FCC6220EDEF52B6F842635A83914B236862F6CCBED16F4899DE + 97: 0E41C85D5C6D625E1884EF7438DD9EBAC818AB50CC265A73165928D0 + 98: AE087D57F9CDBCDF4DD68A3E8D5BDFEC709A532A4A646CB31785506C + 99: 4CB03AEFD24C833B5350996EB261E803F6DB698FB81F37F8A5C3D891 +100: E680BD218AE972999BECDC905F4D39251ECF49B29CF0A13AF5FB09A1 +101: 64326D6B692B0A17045434BFF13282ACB91E7B690339F7FCEBCC9AE6 +102: 20CD91504AB04E2D3CD849808F2362943BECB310F4A0BF6E3BD47751 +103: 80F607E2D79E1EFB0458E47C8E5726CDB8387BC05F42D6EAE3239A20 +104: F83C023D6F539967AB24309DD28321599782ACFCFC76B77186307300 +105: 70164A250799DBE6C5BD3EDCDEDB16D2516A9FC1BBA294C49F753824 +106: 1883397C9C4C9D33FB9E1E03325EDCEA1606D7ABF86C4387DABC449E +107: 1355DFA06822CC1F216C131F2BAA92A10BBF109BA3E648419A35C0F3 +108: 9E35B9B307990B7D664B9EB7F06EFDD23037F859ACB6B96A5287A846 +109: CCCA26C8F8405FF62421558255F2DA06F73F17D1AE1763A0BF8430DB +110: B4FAE909368405206333491674559B9094DA4C48913D9EACA28AD75D +111: 3A5E7D9273F91E10545FE6861D4FC223A5EB0F7B4FBFBC9931634C25 +112: 96553CF0C5C6F6A17FEED04024FCE1D292C392E60B3595FF53007AD9 +113: CA9B79F403412F71FBC10E094B35088576EB3F7F8B5D08757D89F45B +114: CF60CC5B1822E4A12EEB3E1E5F4AA79E345D8C8FCC546D57DCC7C784 +115: 807D65C33E74DA0E2D5E3788084C61AE3E8771FDFE643D1269A7901A +116: A5418DBCA94A1F9692FFDB3F7AEED75806CD9FD47171A6B67921C0A8 +117: C2B880C9E9D78B0C397D72C8B6684276E8C22A7F4D6821DB7C998775 +118: EA447EA731673E5DEAB57012CC9E0D3A7B2443165B665822963FD6B5 +119: 0F6D50C04357DF9240802977779D7F2214FBDBAE95B6D8F59B414964 +120: A3B24B29B29BBF32A01F21FFF13F44FCAA5FED50718803AC3BAAC548 +121: E31E36C38A7F2525ECADECA047533830A9C46D609E297142AB3DACAA +122: 592FF0C399A6CC1606FA3F404DA4BF8618A4DF159CBB7E05DCD30BEB +123: EEDD6A5902091ADB8EF491F820613740DA73A160D825121912613DDB +124: 3A2FCBFCB007F45CB0EEDBDD5A765EA0CB7A142CE3C024114D6D61DC +125: 5D29E1732898854AF468BBFA5B87065BB811AF8F55C91E82E888E842 +126: FD1F646D021EF31F634EF5FB0506620686B9F7D9B5C672734CA10FDF +127: 5E43945BA9DE62C364E34CC1361FFFEE9BE8974D7CF5D2E06428916B +128: 0FF4DA564729A0E9984E15BC69B00FA2E54711573BEE3AD608F511B5 + +HMAC-sha256 + 0: D38B42096D80F45F826B44A9D5607DE72496A415D3F4A1A8C88E3BB9DA8DC1CB + 1: 12B06C3218C858558CAD1DA6FE409898C31014D66CBE4ECD47C910EC975E104D + 2: EDBEF6AA747C951F25AB6AAA0D874648CF18FFECC4C9159F8FC71E971FAC6D21 + 3: 03436338A166E9051599AB268CD74867C6159378069A9FF46FC07CAE375EDA68 + 4: 634758DF0774A587F3AC6AD7988D0965524DE24EBE4DFF07EF622BCB8DA71ACD + 5: 0C08E52C7CFF8B5F70781197069DC8F209552D241687BA0D24661CCCC28D3937 + 6: 749F473E0D934694AB9917569A61591CA50BEF18CABDED51666DF243DE879D53 + 7: B1E12CFE0273F5D27192D1A4B70EEC4DDC714B66C8BB1921C63381F78CEC5219 + 8: 1C60F13A1C539788E989BAC2EBD4F8E126EE6ED82C2E25817C63B2B633FABD33 + 9: 5643F445B2C0656A49BB3DB5088C9E2E4B2082C2B611BBA0DAE5791F2FAA5D43 + 10: C467F47251DAD4694C9C7A6758E54CEBD68FC933C7C57458020774A2A2B4288B + 11: 85C90CF2719BEBF40EF8D501FDA20C342BC406E728551BC0275ADA1747BD981F + 12: 06B72DAC895B008DA249B7B1D8A5133F09D86BF82DE2C4251BFA6C3D8C4CF03F + 13: 49EDB6714A556DF324E41A3CE5B57006E38FD7CA8B90FEEA2ACAB429204747BE + 14: 7411921D759DA0B491D6D4CC372DB79CC163F146C345B4A73D93EEB4C262A1DF + 15: 5C37FFBD1F0512AF443265B2F3E8B6D01AD9B45FF6F373D2CD0A7C6E48D03E26 + 16: 773165FD16D51E51CD8A958E548902B47BBD0A6E156C31B6FEA036F6D8C4A90C + 17: 5B4BE909754EBC8ECBBB8B5DA6298B8341B35D92E17CE7281909EBA1EF568347 + 18: C6EEF2D12F54815561EEED3426D7AA7E671E26D42384B9478D91FC6B14CC76F8 + 19: 4C9FA0575CD96BB1DEF6EA79F5EC7A1F0478E86352812F690C2C2BDB70028BCC + 20: 7F87BA45FC41EC30E76F61E4EADEC013CE2B4C49CA6FE6D2FA525F6BBD45E103 + 21: 9B8CA1D70339A0894E16CE4E76F6655ADDD3EEB598F3DD80FECC5EEEF3F638C3 + 22: E4608AEA430A638799991B748BB858C91AF58F56B226E1901D28336B30498279 + 23: AF4F9C52079B28546FBB44EEBA20C7AF0BF493D34EF6967B07CA32FC4DE25ADB + 24: FE51F3A9313EEDAAA991350AB4D1D7045D42AACF3AC7155DA3AD9A2F1DE3A73E + 25: C1F5AED9D77F85404A4B308A139D33F351B20C91A738E698BD8182F124D96C82 + 26: 3CAC12A252B93B7D724AF9119FD3C18E85E88401F93BFF42AA05711B9833B1F6 + 27: E61D4E94C212324A64B1A0C04B2237A9A1C5CC003D83EA80BCEB45452DCB42F2 + 28: D01BA47DABCE4704B6820EC0ECDBEF137B9C4ACB80DC99B7C9220CFD9F9CE363 + 29: AED502C53A8B2C76F671376CDDBD0596376B3664B917CD9C9ADBC489543D4721 + 30: 3405AFD96584C5E5963362948D112A70155877BE3B5EFD479F226B73351ABAF0 + 31: 5FA0290DC68B72B1FA27DBAF157923C706B3F52CDE9C4EE38CDA31D376B0BC0D + 32: C1391C694C985CCBA707A8C78AD05E2180AF6B4DA5BB877AAC5E2AB33B4890E2 + 33: B018E7B15F92DBEC58F767633BCA3BD0D84B6D5B9443784DC1757166D7AA1C16 + 34: 8D9E2C84967004E3957DF59D502BC11CF8C8959368117EC5DB56AC958A3E791B + 35: B0EAF9C0E869D7A304DDB30061A73C580B0A6F9D49E15442ECFBB3B5A851855B + 36: 0B48B0D8C3ACF7B4F9ECF8E46563C921B1B6720B6C650D72DD1126B6763CD595 + 37: 8879D239EDB09F6606957D96A1F4BF37EAC0F3419881EEA79E8BF1364FB3FF6D + 38: CC663E436DE42E32EA110F9D90EB990D9151C9F06D51243D2076B0CC45361736 + 39: 732DC3B1F809E55C498C53FC75A23966CAEA16BE984F795CB1BC94D026FAB30E + 40: F1F0EEC77D97A0234D0F19B2FB12A96B6E2FF8626F79A74D4AF26CDE1344D838 + 41: 75C9D8C7344668C478D8AE6D9E2C41E336E7A2504CDD43B73CCBF78B4C05EEB1 + 42: 4B149BCA6429408B242E76C52C4D3A0A5F5437EC0AB6D24D71EB1AC5496D75BA + 43: EDB65EBEBC0411B4FDAF186033E306AD500711CCB80E770E99523BB2672A237A + 44: D1BBFF5A48346A0DFD5CFFAA7A2AF08C27F3FC2908D7A5D2F575E07CA9E72474 + 45: E8EFB6373DD3457610E57750738358A50026D2C6704A98148CDD69BFF7B70551 + 46: 8E3733B729CEB97444BCCA405044B98F45FC59BBA86444A3FC0F4DF4854B5C4D + 47: 868F3EE8F4D4DFEDC3FFAEEE1FA069F5FBB2CB818E63C28151C1566634189234 + 48: 3F5396115DC7F17AAB19A3A9779CFFCCA57DE7A7C1A42F748FEC49B7D8C2B82D + 49: DC2A5E3E176A693AD8CAE551A505729B78FBDE778B526E28953BC1A56B54840E + 50: DC91FD745E9A7A9D0B41C79B3B3939B84BDF78BEB007F9AAF8FF82084759223A + 51: E73DCF5413F17D4ECCEC813DC060EF907C2E952AF92DD247A0AE2BE798E6A40B + 52: 696B5EE4C1E1D8B60B0015EEA2389C9A35088022FFF10034D0D09FA722A2A3E6 + 53: F86C07265389512B2CE240A89EA29D61C6C79C2738FACA157B0DE43294485682 + 54: DB31CBBFD28D6F8564219911EFB748A5663E482DBA26E38634E8E27E3CF65707 + 55: 2F9675313AAB7A940AE77CA906D0342A448FDBA3F7589D14B1344D586EA157DE + 56: 7D829FD994258EF2AFDEF22C8CD5CC1D29A9A55B62847B3B6F5DB630421CF999 + 57: A6CDB9BC9AF75EA4680E895E8EDDCE76F536F7CCA571D62781A06DDB3424FA50 + 58: 1B4186A34EB07F5B3127F2BE0F3943610679DB0F6BABC7DA03B416FA577D36E2 + 59: 7B5DFF3459DC10B9B7AA2B2829094F97706DB5B2F133B8BF9F48D90253D68359 + 60: 2ABB68160300028BBF3B5A414970D11DF4FD6F4B4A35029DEF8492ADFB19A480 + 61: B1B13ABF9D20C42E755D63EC63C016126259C8A6C3F9AB3F0F6AC5D0BD44ECA2 + 62: 9ADDD17E5CF407CDBB12E5E52A50CE134F1B48A2A2AF90D7308344FB5A70485F + 63: 6A4C06DF40BA515C56476471D4A94F87A2B91EAFF6C66510892F2F20A342B736 + 64: 555D424206C003BAD0B08BEEA76DFC81B307C79BBB6E4F15325B2ECD37E04423 + 65: 8A58733E0B990D0D82F93F77DF36E30DCFD03B3181B73C544BB097A3A73B6AC9 + 66: 6FCCCCA4172E30A281A702E36E7BCA07370D4B57272385077A44D5F7933DD2FC + 67: 3B1A91E49AF88B1832F8E91109C7CC5DBEE2847D9ACD2A57404DBB565480AC75 + 68: 69584075C278763CB0B09D4C9E15E9300A191BF99907049F14EC8DE24D86C121 + 69: 2EE24340D13E68B10B95C3F77D55027F98BDE6BA5328D0C02CF89965687C062B + 70: C04B37F5932F427D40E21EEAB7C9594B16BFCF4F5FE2BF175CD63C62F2CEEAA2 + 71: 058E1AC8971ADD2617A4BF7D02B46A8B74A4D52B25643DF9729A1E7DF6CCC86F + 72: 18001F246ABC760197482E25F3AC64B14A795E55B41B505D6027261BFDE7C52C + 73: 4AEAAED524B173E08E54A83E2D9A8B8824E6E2F1B89203D698E9BCE7C3242F8F + 74: 7D82CFB1D7427302889CADBA23A99154CBAC0C9ADEC94EAF29EB07DC86B0B7E2 + 75: 18D42E92BA532A409CEDA8E3A07E751B430800827F5A9F14D93E3ED231BA08AF + 76: 8CFBA378D8595372DCE5D9A6E726C23512F84C0C1EC3C66ADF6B6C55DF63936A + 77: DE1A6E280A9054C91B826785928F37A16E1D2A9A3CEC831185B26D2B8EDE158C + 78: 920C40B4204C7F3D4775176BD245BA0276604C568B3C29943C9AEF1A1C93428A + 79: 935BB39E5FBCE5C4A15AC2A854475578CF80308E531CA86818DABE69BED8824A + 80: D608E561471CC09EC0865C826242CA26AA1C90BDF1625E1A38B96E3EE0CC5F04 + 81: EFE2A8D806A1A71596A05A2F5F48D18CFD4A742247B04E8089FAB27291A8DD50 + 82: 80235BE35DDEA5D49F124D8BE3D143F87CCBA7D0608C7E2CABBAAB01BB95E477 + 83: E9410E0DC14F3BE36A49A5CA673C12E18CBE4F0817E0C1CBD2069349F8A09BBB + 84: B2042A81A36F27B4CB96DBB52A61F701A815869FF5AA0CDCAD0327E1ED1C2F22 + 85: E9E5A9501B24952DCFBB9D59CF95A9A9E6A27FB7315EB472D1E2B7F523D06D42 + 86: 99193B4FAFEFFC932B261EF169250B96901ABF877424FF667CC0DA0154C50498 + 87: 1D9C7F7E681D20E1E0324EFE71C8B6913FE8CA87EE52E443335115AB2C458E7F + 88: 7308DB7E2591D2342109C5084B1174F07D289FBE91472FB2D8C06DF39F826B84 + 89: 90F06ADC29070DC50A23D3F093007E273E783491A70A2F0AD6BA40E34F02518D + 90: E676DEEDC972019F10FEC24B4AEAC0A97870E924F7B1D6D3ECF91EF38A2AC544 + 91: B5DA3B40FBF373795E67A6338F9AC3AD742741F34048930D9336D429D02EE78F + 92: 6FDE20988863CE157042EE52065EEDA233BB2E6EC0464B9DCF2AAC1F3A18971F + 93: 428D4CFF477F0F0379F634D1E7C15E4CE6DA067ADC45221A860C9C3AC4235753 + 94: 9EC80B57E921DA3F81D13B65AA851F5971E4074C96E0D8B64E50A7F5089C1FC8 + 95: 9088151BEF766D0896A48EB6DCC8A09D151C3396FBF3A9FE193C5E7BF9030B01 + 96: 86D853024A762536666316F363BB867EFE25FBD03BDD28EA7522973A1A1BD95C + 97: 007104BD935B532BA4702A78C505D67B41358A61DB8069585B91B1445DC346B5 + 98: 5C5709F6202948E805FAC25C454ECFADFAC693955864494E511F0CD1FC9CFDCF + 99: 0B010F71C5323CC96D3B8DF71170968096E44969EA55B4C3DAC632D30D81D529 +100: 54621EC4F31CC7F6273601D81674612B44726B5CC4A76EAD2BBC3D32DBF62A9D +101: 28EFE1AB745BE64E5DD7286C97360FF2D287F862ADBE44380F85E1388008079F +102: 831BFA684C25542676AD52819249A10D9EF9C2505D69CC1397D0D39D08B39E5D +103: EF7922C40CD96A47C5E7AE4D958B495F1D6954EDC20596E303CFBA43190A9EFA +104: 3A0262EBC746A7C044C1DB043951F7EAC645C40F554898D3D7B2B7AAC4EBD396 +105: 1F2CFBA7275639A12DA7CD1986F920C47850DE3FE13C931618C0FAC765820ED5 +106: 7AC8913C0975101E187FDADDAC5B5EC467A25869C4E630EADBB42DD2DFE4958A +107: D386591F326C91D274FE625A667B6F9F6F7D99CF56ACB365A218F1CF8E167A70 +108: 66286CB1B61156B005CBFC94C2CAB1A6694D7F123411B8A123F2ACD821C291F2 +109: 844D1038E710690050DA737D56FD6B17C261C7BE512713E62033384B53C40902 +110: 7EF970C40080F554851277F4E950C6F378B0A3DA3CD1BE250D976162F8A4EE79 +111: 9BC20A2B67566688BCAC77FCF30259F11D9B2FD2277D033E6AAE19E36058A353 +112: 796C72D95BBA1A4341C6B0397E165DD21CFBEF55555B35C717CE33B6C6ADE490 +113: 1E6A9C1F78AFF266EF8FB25C32C1FDFB4A0F64AFFD046D257470BF6DAEF61D6D +114: 0E1AD927AD658C5E0321333AF8AE4ED69903B4F22C5DFF90AC93268507A7C86B +115: 07B7A778E2931704E7FECA284FF3B14071E255A2B824AD0A2272D21448579CEE +116: A8D810DF06368A0E825D6DB4394916E43E217BEE9303AD4096A8E1CAD37B8703 +117: 6A9C7D302CCA1EE170366F355D8F40AE3A20D28BFCB2BA163DCB68E08DACB748 +118: 40C3A8B08FF9F767491E4243D1808572FDAF1D8CD21AB47115849531513D0750 +119: F26EA6760AA80360398371855783815BCD34431E0CCEC58A34A67997ACE43CEF +120: EEA78D68A509988ED6D7E3F27FC22F3EBCD570EF0FE242A0251457EAC4C3C1F4 +121: AF977819B87F2E63C0E131DFA2A31C555AD831ADCA6DE0FC1BE48D21A1E7E666 +122: 846A75DF3691B2BF224FB0E66E360A2E8BB1DA32422190F2B319B73E6900AD42 +123: FFA997FCFABC9FCAD4B58B0EF848890FB23B974CD57FA07223037450C371B116 +124: 0028C776965A0AE5E9E70D9B833BF328BDBCD06C5A12A2F1C510911E60AA304A +125: 7FA234C59957C214A7BE8D1B909C540B48E54414EE5FD1081B4C339FD2204515 +126: A840BEEBF2C2E80AF2E4830BB26F71AEE48A9C65DE4A9425DA9F98FA3A37DD84 +127: A95332415EA29A8CA6FDB0F771E3F2262C6907DC45B0AC8BC229F6009323C3A9 +128: 8B185702392BC1E061414539546904553A62510BC2E9E045892D64DAA6B32A76 + +HMAC-sha384 + 0: 44BE81C415D283AB7A62A45188E5DAFBCB97DA606BD5B16C92C1FC36F198C0B3A714921848D5E03DF1C4849BB8310C66 + 1: C1E1E68D864F758941B87E30C262348B373F167CE4629E4117FBA208773CCC2E6C7797AE5D6BBE2ABE6BAD4DE2E1052E + 2: BB27A0F06A1BAED5AC4FC2267C36EAB663E11EC5F0FCC0BDC09B9B0E803B0ACAA2F39D2AC73DE489FC7C9AD6DE3FC9C5 + 3: 70A273A2E9E5092EF8D4C58E99734A911B7CADD48954FD518305313B0B682CFCE192018D4847375D7E311470D05D97D9 + 4: B4FAF12B325B486B67E38A855D18B45D1BF6CC60E4D00AAA6E58268F524CC1121AD3EDB64D6E0FA524F11C0F139D0BBD + 5: B509A325F561CDDC539A3A4680380759747709D428B77E69C4CFE926F65B147D92D2C83692F526EBB5CF606AD162559E + 6: 9A1E678A743BA285CE154ADBB555CFD097F5839EEB2DE4147986464C1BF032BA0D80473293467ED0A0AC59BEAE736598 + 7: 1DF214529464666002C1AF094BB36F0FB14A4923031B108C21825E8C55BF6A0BB34C9AD7D5030B2FC7C83A2CD4C79C1A + 8: 86D8BEE44CAC35CD3946321796599F20F3A41BE28F161FDA062E4440CCC16E88BC7FFC714D525A6420CDBEBDF6AE9E12 + 9: 92417595F9974B44BB11EB9200B7560FEA3382CDCB8BA4C2CC5CFDD019C2B5956D3E78D5B186633ACB765E822B3D4E90 + 10: 2E87CF886036B7A66AE6581BA0DBB9AC2A39E1C7C7594319184FF3B612A165DC02B3A7133E3AB3D29634B1CD5305A46C + 11: A5CEDD2B54657832F946BFBA14ED5106E8EB5937EAC6C5405BE5CBE7C58053514E784E3F6668C20466A242D25A44462D + 12: 74475D913659C2C304BA49DD2B39B0C7AD7D537BB2240D8611876CF5955B347694525396C43CA73951E711DA38C6976A + 13: B0AEE82D70411F1A79DD7012421BAC1202D7C3BAFFA15B4D8B868A3E6F92B513F6B026E2E8FEE45DB2AE70C15E11D19F + 14: 7D06EA64FF5B9139662FCF9318589E8FF1F783754A9116E090B0B7A981A9EF1D4C1BF582C8EF5E71A49DEA2834447287 + 15: 8F52BB9B0A2B1066AB67603C552C17E983D15114C3B9776C548D747F7E24AC782253812802EC456914444DD67C0CDD46 + 16: 9DE6587211FE4A232F01D6D20554102D24D98EC140A05303C1893F232BAA2C07C81A10C25A95A50B38E87898900BBE1F + 17: E0175EB9DB2649801EC2EEA9DE2C1E950C129CA249C14326614E0BB8C32AEE67DF1DFC6320439DAE4FCDB4B037A53868 + 18: 0606A848086DDA50D031A585103478EED0259A9167959657050F8D7DD21B4D6B62B93AEB0009B1E878EDADEFAE9B2ADB + 19: D4A45DD1A6B613E3D2D72B35E6030E1531D75AF7C3F100934CF27EE9D0E0F0C236581EC8EE74FF759D7A19C5AA6DA9E9 + 20: 3E0FD11AE4933665EF30E10035B0E686DCA837F6D6FE2D5A10B4EC30F183EDDF3558309905F028DB93323D09A3A2F3E9 + 21: DA2A204C7908FD27A29415CAE3BD16A0488FA1D42CCFA2E2F5A1EFD6F99583EC6B3B36762060F547C629B9A332585355 + 22: FFE8FFED47933CC941A8E9233C037080B9465B4F9C25DBAC790825C013545D2344930E953187C77466437BE226962F80 + 23: 69FE734D5C69F34366E5CA6B095DE91CD4DEA29AD70BEF06AFE9BB232162E6BBB1349263087212AE3AE5D74A3B060F50 + 24: EFCF1B825AF87FA5199FB3C76783CCD1769E7DC77BCF145DB76FDC622BFA2425CFFAA40E6376086B2DBF6F5D9D97A534 + 25: 98C3DC50FC08D2A87ABE3FC16871ECB820D530B453C41F83FD304D51660FD29BEC6A7D1C63E3E12B6E80E8C58CB129CC + 26: 945047CD723EF4F25AAAC4A19FDEED463EB04CCB78EA318989143298DFA70D793391BB7FCEA6BE0D79187543426AADFC + 27: 2718D89F835037C94CD6378A3806614B85365A888B48FFD08C09F0B93360C04E43B7E7A19C79BCDC5DB9F5944579AB79 + 28: F714F16238075796DD43960E17AE0EDF9990132D690F44957C3DE9EEC2773683172FDCC44ED2104320726BAA7DBDA1A7 + 29: A87A96ED8FF0E7FD1F235F070CB5F14B41B2C4438A6D7A0A39D038C74008FE9C52497CC506498414835AEA1192439379 + 30: 31B029DFA85DF545B752506E80675E617549A6725A658CA8123D8C837FB71D8C9961BBC2460D7CCE0CABBDEDACB56C37 + 31: 0B1A9DD308E5E6E65E4C60861D42B628FBDB2C2280370EFFAB736A77A8004C5ACD5269D090B652B1D8F146C1D518D288 + 32: 2A160E0B2EC7BC927FFF813A2B56AE61301AA14933C659B3398C7A0B3CA506DD00FA6F1DE9C6D47AB0FB2BF2E7B4B83F + 33: 6893C0205F3F4ACE906F2FACC97E2B1624D40997370419E5981E6041D5CF34C77EF5ABDB1AA0D3C8C3740100C2711555 + 34: 95BC8C72DC8C70ADB7CD38311292ADEB9D7BDEC6A9580EF4E11A18317CB65667D344D8D6603C044454E67F97F4DDFF40 + 35: 3DD892A4E724376814DD5A4CBE96E4317AA8AF72478D53379247E77C35461BB92CF493851FF1FCF57A6704923099DFEE + 36: 3A5DEAF967BFA3EECA3F259307991F7DBFCEC1F354DF385CF0EE8D93291721553EA954E9D6593506E9F3E330E0A02574 + 37: E00A883DCB5460AAD611603614C7214EC4A566E0580FCAB1CA4ECF1386A42DCDA746D3AE1B0D54E0B9AC1FA336FE787B + 38: F437CDEA425E7A70CB4D197C0CA01562532A7C51FFB8462B4796A4FD0A7EC880CB0E5EDDD5F703ADC179374416592256 + 39: CE69E40F5B5F2F25E0B53281BE76ECB0E5B4558292A1C1A5EC56F2CF11B01BEEB1F0BA01E6A9B3D03BEB69AE0511F320 + 40: 41AA84D15342CD0675C8C0312C024352E99914C3E01C98F969AD04CB5705E9184F3821CFC6A22D43A77C928F6DB79D8D + 41: 74001D972353BB45FF3F7F405FC727CB5D0B00431BC76A57EAF17862BD52949AF884403ED6B2A002D618EA33523DE200 + 42: 968BC28223799F1EB92F1432B6AAF5CF6953491C3F959977B065BDB800AA438CC8AA7EE1304C18999CB5ED709431CFFE + 43: D067EC03F14D2D639C4423A311EC86B3DDC3693A2CF43C259BD0358F8D0D68F41950CB705249A59072A2CE7DF155F5C0 + 44: F41EB77179934884DDB56DCF83DC90C606D0226DDF94135FF8E1E0AA56C9A90881C4C380CC0AD3BD0DA45A6352BACC05 + 45: 27BF9A98F9E2732972FE2F35ABC80AE2E5A2BC1D238B9B1D9CE605A89144EE9766987384EBDCD63533E64BEE094E4503 + 46: 166892E106BBD9D16819D9BDD3601D24C0C11860DB13799F0797F204D07DBE914A7BD286B380EFAC34DFE3C940CDD3BE + 47: 2D85DBCFC431A94F8F50132DC8C10B25001EA10AA9DF7C53AEE9E8383EAADFCECC21202EFBCA556BB4E33CC68156B190 + 48: 086007E2874E779A5EDF0E176AC1A11D241F4AD8D02AA99DF2BC1AE3E5CC4775AAA92ADFE772CEEE89D4FDF1B601D05A + 49: 2ECA3144F4F9EA0F37C2CA5943F458590A1D4D19C0ECEA6A55CDCA648C99CD457DC57EAA995042D7FBFAB598B8AFEEDF + 50: 9C1F31F5D3A589631D8B7EF89A507011736BFC328071513D64E5432D24B1BCF47EB10139B6410A3103145AF67B5B6C46 + 51: E0645EDA004D9005399A2C072ED9959E4F8905D15C57992553202A3B53BCFEA0098E6B28BE047A4B29EED7B57602C0E3 + 52: 6CE5CA92F0B1E84D7578DDB86C96A10924601A3680BAFEE5A0B27D8390B59752205EA483832ED3E9343DE7175601C03A + 53: 47F50844C897FD910C5C228DEA1EAF456882C1115AB71DB15E6832D96607CB79C8B7AD1CDDE01966FCDDAA0B0BA9F264 + 54: C0A7EFA24590833E4788BB117D3AB3CE00C84CB4820AD9FD7F03CF1CE1A8983F9906BDD138E1943D75ECD9B98D5AD8D3 + 55: D056E9F831B6DBE97FC751453B1C52C8C6C4D18A00050F5AF2427C1123706375A918656D6755A4C950F4E5B5C318CEBC + 56: 462650CE3981EDD13D0FD2E5FDEA93A9A18CF8FA74CD6142DF4707E604D1F72745D7EE08AB13AFF3A9F8D166EA90CE3E + 57: 2BA5249841412584B161063087AF9F5BAEEFD97989BF8A0455E65C94B0663410F0E1BB22EA6402E59CBC5A23F24ABBFD + 58: C3B1E4B05A7593CC315AE15F63CE8D91C4B30E0D846A97B7D8F01FAA1B6BD7C9234EB153372F6CC7799A035E22A77EF6 + 59: 1E652653B9A3CE862DBBAF2C919E86891C5C03F54ED5970E8028F8D5EFB533B9C111DFD88ACBBDE516F0D4D636F5E821 + 60: DA773D5AAC336B6266D27A03AFDF3A151FAB302E894CC1D09B6E4ECD07C4AF4BE06A2D28D01669C7557FAE8E513D01D5 + 61: 8C8FE648A29D4BA78B3E0B944597E392A31E28F98B15280E1EC0A721C9ED5E3639A6A457744CC5AABFB3600501F5054D + 62: B443DECF40A5693F67B5BF5580A665DF6EB98FA9F14A661CD50D6635E0F78FB2943731AF363839FE6DFC0B4C49F9E849 + 63: B22EC4AFEE3EA69364701E5621E453A0C3988C1E2FDA54FDB99353F285327A534F7162BC54D701652744413B9A5D4CBB + 64: 40A22B7881AE8139941540540FB37C9AF27BCB164B6D1A3BEC709730BBBB413D1F2FD6BA4A7B7EA747FF45F3ED3336C3 + 65: 246E426C57E414575DF312223272819B0F49FF94953DCB94665FFF74FEAB049AF15160706AC5F702AF66478CF2BBA5BD + 66: 184E6E6D5FB55454EEB6DBE323BF28DB8CE60C271DD0ECC8BD4D3F1C2339B7828C1515F030058FF37BD53568FEA81378 + 67: 10B23FE1616AD5609F6F6C1D9266F702C1B5E6F7FA0B3A81406B5A766E2179D082854687701318A7B46E21FA67D2404F + 68: DFCC1280C5206F99A555E291AA1DE6F0A3AE4B49916FEED4337582B91D7EF094159556B01AC87BF7A8E84F9F53595938 + 69: 91BA9A641616449084A57221647369E2E69525A30B274EE5403FE95A43D0A7C2B301B61929D89222A3A03303550521B4 + 70: 94F59A7F5E68B942A5D66D3C642A78685F3BB400F4FF971BA576DECE94A353455277632B70D06EAE38329CC2298ED792 + 71: 21A9F5C4B1290D95A1F3F051A0158F7DD8A879E7861B61CC757FB5C729FE9A8BD46BC6DCE595D20649092B31AD27433D + 72: E4246F7DE67C3A08F18852F6159F5DC9FA4C0129A9F894EB610C10F1FB8B61B1C9947D742A418F03A00A7E11ADF436F3 + 73: 8D2CE8209B8362311D99D68DC2AAE6BE4CC8E52C03A97D99D0C5C15D8E24F1D3B51738BD27BEB6E773472CD22A1225C6 + 74: 7EAAB124A3C900F33DE06B84E7831FE327FD638C4E68DC8648EB619E3C7E5736A26BCDCFD3AA6AF34EB137C6A210746A + 75: 8B60F61A1AC2C6528C8DB07B6874F19B8D474859F98AF03503B115EEB8082E19D53F63D397647BC2D4278B8C2B741D19 + 76: A48D92BA646DAFF7D0F8CBCB1D574E9C19D396A30573A7404F6196FBD7E226731C8AB05138F7B1936986DE6C1F1F7B52 + 77: 2C3ECCA6E7AF0F9587E5A03D462C98F18B8C13C039D02D2D29E06B5309EDC82052EF72C94E0A5EB7FD35827665CA2F92 + 78: C9B659AFAAEAA8778E9E4E3B725F758768963C55151A54BD9DC191E1302ABA1F1F085D5443C46441793682A8047211E1 + 79: 9A76E83A301C14AC6AB8CFB29D2CE39E0E86B335F2B20C3C889651B4E0B94C5218E910B1DAD28474251D06D12D47072A + 80: A526CFAA2EE981A9A4D0EF12A6FA363F562057BB75A218F4645BC5E9BE7CFE7EADFD87386AAE1C607D812772498ABBF6 + 81: B747819B54CDFEAA751FB9F5C22FB269151028BFBC6650BC518692944C5F4195D26AEC45C9B4C987ECF4076B3871C5CF + 82: D45968D452B5349CA43A0FDEFE4A5379381625825A27259AD9BF5A80C46CB07BF1C919FB3ACC250D73238B11C3A07D90 + 83: C0B8AB0F8C497ED9562C65091DF1D80C32C57A018B00957BF53C41DF81A2F6371FCFE82624B2E84859114152B36B6AAD + 84: 30D2BF3DA80C0F37807F042FE7B878851E0BC4093D987438FC2B993F4CC4AF6F704669938B9E30E59BF8999883639F64 + 85: BB782ACEE42930922A98F65F319089E9B4F5D2DD2374DD76035E3178DB4468A3C04F5EF878ECF9ED757DF14DD89BDD49 + 86: 157424F30A10748940BBFAFB6D99B1B06A897E7DAA4F03387E5ED03F02D39AF59F96A20E4E9F3A4C5C07C20A8FADC8D0 + 87: B9ADED711B1E1537A35AF882F1F868D964B5898E85B07F5677DBF183232F36C14AF4D9959C2108D9313F8BFB14830B02 + 88: 7C4563BAC3C05444C3682039EAF9F9EC79B96F0CD36245F584647BC444B81734D7ED4380CC1F0A2BA876020E55660BE0 + 89: 9811A4A45CB28A780C063047EC6CF94328102DEED9971DB99E11C6FBCFC046EE38C1A00F290FF64356B9A304DC0F340F + 90: 09A69D3255EB08E9B3CF7CFA73D86944CCC91DEEEFC04214F8982836726CAF006A3FD83F8FB75600CBD060ECD639C388 + 91: 52D6D0943728CD2EED671736B6B3BE801B811410992E4A3BB50AB4269EB21AB945F6A9F7036DA654A7F2785869335395 + 92: 8C0E1052EF2B06C0C20F67D92E51DFBADF3655FC6475935426AE1C88F3096628EAB9858E5470FB98A546EB11C7B752DD + 93: B21351AF8400B9756F104599BA4BB78C2904959E2B24AC3E15FD0398627E6C8D57A7F9FEED63D8638A206BC1683794A3 + 94: B9F7CFE97C79568D62B07F1EF887C4391B48CAA669AA8495B71A326B120FA49652F02EC0D53441DABA1E104AF091E0E4 + 95: 69D2D1773208CE3BF02B38A7F14910187F3476817ADCC7A1D9830C9F25F112E604AEBB95D0237AC8795DCB23ECF52927 + 96: 57A9FA7CA61FA2FDBF0BC3E3E6463901B3B26E5D9AD79DFC0CC77F79EF3AA1AE3949E7D71CF794E067D2E38E7038EDEC + 97: FEE9196A0A1199DA8697D00AC8084D6CA1F867D105EE928FFEE14E5E36BEBEDE5C79509CA5BA05E36C3F0BAFDC9A755B + 98: 0E8DAF8BA4ED614B38808B4E468CDF88EC9B148017C6BE3FE593410D37D9B50ADF0913B7844FFDCC2F1917A27A58B352 + 99: C7FD40463E26D6A21373EAE14BCB7403B127A1E23E4583B2AC727106B07B849F74C0907804AA799C05D9FF324D04B182 +100: 16E899F4850512FF3DB0FCC58FEA960831364E5FB077CD8DA3F5B3F0F50AC626601917E8355E4847A00E0A5166E786D8 +101: AF2DADB17605DB3CC471C00D63C42F75F815594C1B49D9396BCFE7ED4D4FBB1CF15B542675DE8C9FF50EF81B72FF72CE +102: 1699A1EA2CAC707205A6BFAD8DFDAF09C8D6FCDDF2BC14A9678453463AC80054627F2C39B713861734B0974F442D707D +103: 186DA71D7E913DA49D8D97101882B1282841D41CA12F514C1B2DD61543E330B751E9F97490E18A4A37FF1853EFDD757E +104: D82050038E6DF6EAE9D2D4019827025A25BC8CB15812E0ACF4B676C799A3D80ACAE5706C0FB1FF72B2C4851DC9232B7C +105: 1657C99506EC8B28AFC1684C4A9EE4970F8F426E4BB0C3FC2795CFBA82913B453C87D84AE9B32897A4CE26FF4320CF23 +106: 9834E936482592BAC2373AA64806FE0D5C8FA92143070C61E594004F0D3B8516C2A5B0244F273124E83B20FE9A2CF5D3 +107: 5C4856A82C8E6E49BB81E89C26E355AFB75EF921E579EC4B97868BE2CFB4B1D93195ABA0500D774C5365C2269FF333A7 +108: 67B88FAD5085C8BAB8E194DF73153A5B1D334431227DFC619D5CA5D5605EDC7BC95DE33512B2F5B714F46F54E1E61B0A +109: 90C6A8F36D42C5F21A89417AA04D822A53110DF1D062E0C1A6FD9AE59C6588CC1C78469B94578B6D7C05EFFAF7FEC26A +110: 817C0E7ACD548BD3733792F4F8D845D7E4B3CAA0F0EA943B51235EB82DA7C8B77A733D756E86D57EA303F34BD97BA1CE +111: 7FF397FB43DD909AB80BC381EAA4BD50B7278DBF10F39FE718B421D6C07324F398BA5B1DBAAC64137267DE2C62F19F7F +112: FAC12B732122E18DFBCF8DC7382AB1B55353134F07E07723608825C907DB05B4FDE40FE550878D971F8B0B0953C88C54 +113: 4DB0FA3C105D64A9CAE84C0B5D7AF0955F6F58717F68366935FF9F478E94D3969B1264B1F37F8F5538BF116DE29438AE +114: BA6E693A6C3C5B048FB7F232CC5E12CA71662332EBF689AD75F6F2C54715A689CB1F75525313FB8B2713909EC13EE0D3 +115: 00BA656BEA25DBA36861B92B356C3DEE0DB1C86D4503C7FEB0A88A3541A7018EA456C95224EFC46AA31CB625421BC811 +116: 812622078CA3B4F59141569A0E125B36F7CC471F76B7B65FEAA1F1F656BAB6A3CD61A4D2456E2F5109274B2090C1F4CB +117: DBDAD8926A811DD0295C31D55AE0D41672C7F22B5CAEABFDA2C1505B084AD01440E9B8FFDA4DFCFBE281222AFD547E29 +118: A32EBC13D689B31617D24E6AC03CE6FD7B1AAA2BA78CAE2E24C36A8CA7BC74ED9BD4CF6C74E3C96DEFF048FE3964F0A0 +119: 095D2C8DCF88F69DA4CC49C64B03B2A1D2C6922CE0C6EDA12642480AE0DF35152B4E4A9AB08D6642DDC313C0FA01444C +120: 578A4BFC0CA83F1B38A0D2EABE2C7D3D67436B559624B92E4FBD9241B2CA8C1AB679B503A754D5029314AAC3AF225F38 +121: 25E321E63E4AC8994FA464B3E2B687150007D83ED8D6E1B217E86B0CA0D163B0B9686E4FA2F26C1839F2D778EDCED86D +122: C761BA17FAC3CCCAF2CACE92283DC5E5B8A6571958FC59D0070FB21CABC88A80A40DCD56318988F3AEDF38AEFBB84EB2 +123: 5EDF5D71D2CF85E7ADF9C7E964FD628ACF304C4DE3483F672666A583E3D9B1D86E9E096541ADA237D69A140571F5B3B9 +124: 401702CD847ECA2BC9208F52F27D84D07B37A86CCA5C3A877F24366CDB9719DE63670E850F02CD02C6227B7214D5DDA7 +125: 362C899156DF70FA189A66DAB6DBB3CBF80B629D1E90D9ABEB007C3C5010277EA589C4D73009C81F94AFF3FFACBFCB1F +126: CA43387C71B8245B822D3085CF029004E18CEBDFC9F78C276F3559D962635601957B6D2287089AD43F3179D077F37686 +127: 4CE8504297E21812C901E77C6680529103A017553F095913CFF06AF20E3D6DE7EFE911B636DCB5791B292C60147F6473 +128: 2AC71958C77E39D4DE4DACE92FBB6A093EABD191320A5ADA7114BD201DD026567D2B799EAC78C1F084BA9FAEC2FC8BD4 +129: 87487060C273FE18A2CF1DFF222658E1B50C3BC5A3F1F4575B3A4A6EA2F42238DEB68B3A2EC6A325E3FCA504B2E20E26 +130: 4A79A1C3C798D9F26D54715108279948EAB246086EBFDF0EAC9152216C0BA3A77AADF82A230AA84A7C884063960419AA +131: DB0BA43960FA6B763202B8BDF3FE4ADA0BAD78EBB3E6E8E57C2D5640D1ED4CFB4AC18ADB1B9770DB49A4252CDD25A369 +132: EECE296E258EA3583FBCAD1CDF2B91F4D2AD1FCC1AA339D8F591F89C7ECB5EA2FA644954006F0A58F2F3BEEA1AEAF7F8 +133: 7AFD95C86517BB6050D04BF3BB1448A0608411B612A7C2A939BB44B984E361C40569E5E57AD7DACB018689C2B8E2B3A7 +134: 7FCE7894C8E8D1FB187CC35CF5758269E286427A63A522F4BC45F814B316C1DAEF981917642C50EC693F3EF4DB8E66E3 +135: F67F56C98221892F64E2AE4325CCB80C2846A43E1629D40BB50845184E9C3B66480B3E9F792389983F2FC48FD2508F09 +136: 1CD915561856936AFCC75530DFF151F49A34D0DD0030766FBC1BE47D611F10502BE86C97B91D0E8767D4F38913EEDC1A +137: 80D9CC8B1B2B883C4735B3C0C19AEDAB78A0771753EBB4688A7E584BE7366B3C181C8532FB3A8BFC484C9CB0BBC1B4F1 +138: 8ADE2B8527C994EAB0807A89CABD5B075CACFEF42381DA3CC3D702316842E25151C65A22E80885E5CD5FB5870FCE501C +139: 2B403F2188D086327C92169871FD5A7B432D2EB999FFB0F2369B2B766E799AFDC1463CF4D9941F828FE42591D6B966EE +140: 4A0C18CECC0641C28C4136D42FABD0BC27FEC27C2587FE8A57CE0D279ADAD70F80C1E812E01B26F2BF3ECDC7673C349B +141: 8906762B63651DD5948C98DBB1B39BD6095C1438B2E4CA4B5A581D451AD3EF76C8A0FADEC9C0B0036A833D8F5C13F1C3 +142: A363BF2A479F67F949AFC151C36B052062CC2CE840974BE2F5E79C0BFD7BA29008A6BFDB55B46527D17F61531C953081 +143: 4E2AC5D6EE56567902CC1E02F119E33974762C03885EB7DFF7C58ADE22E56BC384FE74BD491EFDB2E6CF4021E3016E81 +144: BDF0AFDF17F7B014A61ECE257F8C7E0B52384EB7DEF60ADE785F273851D645E5D3B4D9534C0E6097A12C3CFF5C11D42A +145: 0CDC61FF0B3D8510C319020B82C1C5AA12C7B6F257D7D4F118A5EC3CCE03C63FFD38710F8A3C621DD8D66D8BF3790B63 +146: 19E35E1E785C7A41C523F88CDCD919EDC45F63783330D9033768546CF59D10AEBC77F013057C0E41D6FD0FE77DBF914D +147: 8AFA5DF52F6581794FF014A2E1ABCB05781C7F44AE6F37112B363AB13FF01FE1E8074F14466A365374C29FEB048C5B9E +148: BC9ECD12706BE5ADBA04DCE84AD53AE1B324F99C1F5937774DFE19C5EB4D6A20982E97B8F8E4E02EED13B25B8B13E64B +149: 8D02A1E318DA1EBFD1CDDBB7280F3603AF3AFA21B3D4E0727C7CFC576F55640B7A978B179EECDB8FBE896AD38E82F12B +150: 196929CF0849022CCE9CBE4EB2DAF6E5D8014C5A25E119EFF799A82053035BFDB8B05F6C125B1DBDD4E7B393C684FB5D +151: 58808D04067FAD72BBEEE4F6A355E80A2FF76EDBB5366CA43FF358A842FBFA2F9E1AF5FF266BD2E2DAB1D286AF5BBF92 +152: 4A548031093ABA730D8D99A2C1C6EC2A986A94167CF8C1EBE83D52B34BC2068A4C95665988FA93F5246D0FBACDF85FE2 +153: ED949965036F16A0B5856EA4CF69CEDA35C653BB56FD0F0B397E73FF4884B3E679ECCB19B07D6A93504E82A1613CB87C +154: DBA644B20B01E4AC5CD0A325CB063EEF53AD77E5A9E7095C1BE0EB0E6B7CFE60BF25F38CD57F2AC055D327EB6AECC7D6 +155: CEFD6165F70D9019866374AD7AF9C73F3041B932D61A41734E39AE8AA9C7A4FBF1DCBAE9B2A4E979C64352E3CD4E1B95 +156: 732C3B457F78DED89390BC461380760FBEF3CFCB9BF42A6C86ECF120C821CAC79D4D51C71A955309E33724742FE2FA0D +157: 54803568BAE2DB4F143C78FF53B85E6A9D42EC3894FCFB39BED8EE611B36BBCBED834D366A1F797B626DFF3D83CE963C +158: 35A1858E567FC8A11B92737E369069B12502ED3F44DB50434506F2E540FE643655CBF806C06F15CF2428FB408A65C04B +159: D1F9E930418D10043D0E83096CF717B79C1C9234C741C59436F42737AC73BD39B3F4B6D6439375E0D44260131B25FDE9 +160: D5B56A1A70C47A3F88C519668097B54C989E119EE9DD5B8B34F0DBC092FE7108C9D396CFC62C9322563EE72A0E324010 +161: 1578BB76F87DB309A5D3A2229A2B346DE39ADB623836EF0561348ACA7E315C16C6E31328BC70DD0B0D7D9B7ECE076CE6 +162: F8DF4C71F3623ED00EDF8EFC4E0EC154644E21E78B06C9C5ACB980480732E17E92ACFA059BDF299BB6C8351C6CC6AFF2 +163: 090DCE25595D7770753B78C410F10E830140B23D779E0F52FC451582CDE7511A390450F8B65D7BDA77A18CD95EE3DD38 +164: 5D3A56D23BEF1324B1EAE33B8255F904F7DDF131517200A505031D41A2EC3F2AB03912DEFF6BCECBFEDCB8B948CDACA2 +165: EF712AC1E6859F70D0D2CACE7AEE120A666DF9F210512F5C94AA7FB388F1DDD913A12FF92CCD2537675EAEC870203411 +166: A0E6443505B193D89595A51BCBD47A46E1B5AEB239D68B8B18A119E5C9EA1EB8863B373F91B9F22FA944C29365406A79 +167: D97DACBF80BCC76335C187DA29FF33F6D35EA8A8925709322EF3C0F6FE35D128D9D423F911EE31F1C38E1DF36046E507 +168: 67FFCF0A9F88F84B3EE85000B2DE0B7DC12A06160FCBBB57BA291DC04E14B6DBB3CDB81A40C2EE1859956DAD097C1EE1 +169: 7AE82196B46DE3E6948D7FBC7383A6F080903D6BE6E357700A87F82A964581D375006DE35169446B447537B4F11C5702 +170: 502E0A4CF125EC0640DC7E7264D9E47300814B00D4322F2F62BC1D5F1D0D77173B0E7C2874CD59FD8E056B8F38F78D99 +171: 74FDBC4532534DBF24230ED5677A920B12E328E3D073364498D80F0CEAFBEC774EB53F28F0934F787C56AB794B60BE31 +172: 3C9BF5EEC652F40AA0ECB82A834C836E495E841D337E1299AAFC067A2049C540AABE92CAEAE02F099BC4D3A383D541B5 +173: 105AC61F2D4E586E376524C488C33521C4D49D1F95B752D27F49ACD7181E8FBBCA2E0F0B543EFC0CBD32A5EED2CC08A2 +174: 5CA49D8B554D70B3FC467604661DF8FA51D9987F2A77B13DE44D7809FE2956D21485B36F1D17B59F2261B1B40553FBE3 +175: 1DD075C696DB9B07510A0D276F8BAD12225E00515D19E3B85583BF97CF82B5FE3F685502F64D91F4FEEE1848BCD0502B +176: 11A018C4B213BC67C09370C8A3D0B720428BE71C01C6EE9EF6C9C9DA8B2E1FBAEEE42FA44EE54D0F526DCDCD3C2BB2FD +177: E188EC519C6E0B8A89DE68A7648DAC6D9F84FDAA678B431794EB4BFE077901C95FAE25CA3D39D48EA0292F3F6C35FF73 +178: FABEE0B0A02BA622931A5EB82CD63656B47A20D3C0E703D5A69AFDB92C0A7EC5CF6944D9D7A141C1255D60FF9532B089 +179: 3C8E0BB55E099CA9F6E436BB3CA39D511AB9CE5674469DF8BEA4A20193084AF8561D5130FDFFBE62193A712D7C2D4B48 +180: 914BE8F0A58082B877AF0DC077ED146CCD8245339A170B4099B146476B0A580749D01F83FB52834A033A3822D12041B9 +181: A1B31ECBF451571437DE10330A6E9AB4484576AADC4DEE0B31D9C3AFE59FC6DE028275126D7882A2C225EDFE491305E4 +182: E4DD2E805A5BDE3DCD329ED9D35CAEC2D5A97082966186118DC46BCA7AEB1EF52E0C6007CA28131790838DD8C00E96FB +183: 785B81A972DFC6A4982E0BB76F90F26DBB7BCD2D06E872304CCF6AB2D639CAD85FB29124ACE411EA4742468A6663EB2A +184: EEC3CBB5AA129C7206A32A176482C9BA24FE60E71B46F7C3C11FEF8EB57682A3732680E6541D5878CD6A715A48D75F12 +185: 254E279B7C4F17B911712BF7138E2C6933815BAB18661CB47388FEEBDCCDFFFB6AE8B4B88072B90074704EB7EC567843 +186: 9A8CC3FF0D9637220CF2B4AFC9A8A6CBA4D0ABEA6A0BAEBF151380848E92DFED8C0F0E57B6D05095EEAB0A58DFBAED13 +187: 349966E1D59BC9B32E1BEDB050354177868FC07257A3A1800F0E711AD00AE388746DB1E4591E3ABBAD8F418E1AE627DD +188: 84ED950BE54768557475E6B1A256C30F444E12340C29485832439BBB9CBD219050D184624D6282728D4AFBB98CE4BCD6 +189: 2A7CA4EF1A9356E853329D336B6E7E033F2CA13677BEA67CA669EB7C78DBDDE67F9E7D9099C68F34E07B96DE4155AFF2 +190: 7C7020B0528F1B3F76BA258836A89BD27429110F0AB730FD741FE9EA2714AF827E71B731AFD53A293328788292ACFE23 +191: 91400ABC089F8888DCB22880B87A380FEFDAF81F237D424F057E5C4C8E3C8EE4E423930C1D3D9E16199ED82996BE4232 +192: 412979E13B3D143270BB41FEBC12196B981E99BFD6687B780812F409C78A5E2DB7AE828994B60D26CA4A1F7A3A44C64B +193: 02BDD417852D9B03A37338549DFB6D765EC4CFE4C2385002848BA4D46F88053FAD2A39DFF615ECFAE0D41F02E5877251 +194: 77845BA2210971E362DC117B1BB13D7DFBA62F81EEEC7068D3CB9CD093DF535448CC357ADBF0C2394351EFB07C3E7DE7 +195: 0F43AA1739359C14BC5702322F193AF89335887F9175289933B2BB3F00A777D1D1DA74F5D45FC43AA90C9FFBB0CD580E +196: D1D9A7B995B9BFF09252566D2079121AB12B0A5ED06014994464FA1AA18CB1BD8E7D5E07E1C71E2EED9CF081A537F28B +197: 67DFFE8A168B7408B7DDBD10BDF14F4F2244FC904DEC5850F5D8302FE35AD1752BAD2DE50449F9C12182A2AAB8FBC9F6 +198: 030B5E833F6D8703BD0C5E36354387AF833F466AC812D4E1FAB6CDCD3146FFE3B0E56722D671FB85EAB22CA5CB0309BB +199: CB992B3785E51EF3A32DE88073586DB045F356F18A09329E82943E29A12B2D1490B386D8CEBF7D90FB492966989A73BE +200: A1D337D363A0BD8A0F2342351519C62318A120FAF88F9B90330845DA682261C64627B67D2F533FC48D2BE394DF8F4F61 +201: 319DF6326160C7277A3D3C65995BFB729A69B71B40C149DB1241C0B2376B4205837B5770805C86104677917EE5E5912C +202: EBABE3BCAD828A9A3D5EE05C5EBA9605A67E1ACE73AE69F20BF435C3A14AC63E43B61021CDF3FC2245A14FC14A7AB32B +203: 1723D844C0558D58EB3EEE3286C48C133C5F6C1D8CA512F2BAF1FAD7884D4FD5C3000A6756DD1E34E83DD066AD2BEBE2 +204: B048BED188BFFB8FF1B14CAA0BACE82605AEB1C666283FB7A6FDF216742F9F64A89C50B9852B8119B5FAEFE64615C241 +205: 7FC6E8633CB9B16F553ECA3C75C0C0F7B610010853EFC94AC330D36977EA8722B970DC264D5FC4D69F39105E7AA0EE3C +206: BBC6F0E0158B6DD549C5BADE0FDFE415747F1FA2D2A85CC9DB758F34998FBC8C8D99D573CD948EC768540B363D67C4F0 +207: 5073FA9E162BE773AF5BA1CE5E6FC21F2F0F902C80F09BBC3AECAA6CB1867DAE4DC011D1DB987642949E8095909CB984 +208: A641BB0E1D20D5DB0C5CB33D35B73ED83216F2F5DDD5234A0BAA3B209A39E015B7245C40F9F372E618EC73450487B54C +209: 948806B7335EDCC7C4BBE751844DF5717457B223C7A3B81B57AB3A949D0A726BAACFBA228BF6C2CF94E942F9B2F1A7AA +210: 0451CD5EEA206D50A7897F495D648425CA333158C126C4DBA44ADC06447A51D3C7BF2D4D81779535CAE29792C7FE5650 +211: B4227FEE0A32009D60C9C30033C12B7143D4C7A1C25F39F3E4A076BC4943992AD299DEB2C15E27DF867BF948DA27C009 +212: DAAEA18FA433CF3E117F2D43303139D3F1D8C3BB8AE8EFB30B44B9D5D4BD4E553B9B6EB9019CC4E1AE5D0DBB6C23A102 +213: 4434C818BCCFD92189A3A466D2757AE2655BF0D6CD954706C85220A33B95B184EB560FF3CDDCC4DF557E427E60F9FBFC +214: 6AA3B44FA507B6D704A66B4D7F26CBAAB2B400C6BE0A8B61B50EE617A16C2C09CB36E72FC309C6E4DB24961B1785CE3B +215: 63AE9C02B96B4BC456FE5CB9BA35366DD69E78DC9CEEC376C6780703883D609333D45CA577A982A177515674B975B658 +216: 3B5DD4CCBE8CDF32009CE29FEE4F6EC7CCB1471A3F8E9BC9A35E8CC37F6C56957B757DA4C3204F9014977B93F9E30DCB +217: 04A6528CDE6BB9F425132CCD4AEA1EC6CEA482249E5F3782B000FB071A4EB2434597A7FCE2A364A9BC9E0643A8403DDD +218: 69275CA1F9F102925165A568C1F152D25DF8820A6F34595C4359159070052FED260C55FFFAEA2116AEE7A63DDBAA0160 +219: 584697C23C63904709BEA89F055AC592DF48034F908C9F06C706A51C3F6BE5F0F2A5B953AC2119FBC0855B785326C06D +220: 04221F0A6C4799F9CEA3C1D9E65B9F77F77C613FD114135DB019D8C497B8899513AA4B499E720CC11AECADD1AC071DBC +221: C7B878613C2F2ED10C8EA413970B124838F11F0414AEC89A3825DDC588629A8049E82B461A23F25C4F93E5BD11C184AC +222: 1891E7A51768E05BB1D03A1EC1B844C7C8EF77C433F700175998B2D8E2EEEEC4618F00003793C5873655E093048B674E +223: ADD2B81466BC727AC85DBE258B566C4DB56F6F7D81D7A4E43F86C125F2AB2E08C648E628B9CFE440F8BC06FD5D861D3C +224: B3684BEBA86D275745CEAF0922473CA581CEB7371C5747EB87B407468006BA50D69F9BD8BB7F214185CD0D0C548C5432 +225: 0C783882FC826917619C07FD03FFC46DE6CD87BDFA87F1FB872989489C32FE74E8C5660748E1E8E9AE19C68B075B0EBA +226: DF52553B4F7BD148574BB47F61BF8F7B2FDBE5B6963E29CD559F236BAAFC3DFD6A7EB5EC9968E0C2B3A453F982F16AAC +227: 45102671440B04027B1F9966C1013AA351CAA3F3CF42C4D98F5B2D030FF37836E9F5865421D7DC8B037644FE53C6B280 +228: 247396BF60C0FBA27B245CFCA061D1F6EC50CB87CEE54E8C4A7186A07745D255E4EF9457C0A329AC9E3FC913DF86A4CA +229: ACC5998C464A26C1719E9B17E1B8F5E3657FF0364C46FE87154DCD1C95A84734214D2B81CEA8DDBA501975281EF4EA9D +230: 163F5AE385500C1A6EA212D6925E48CE2189DB1DD47F7F2D2D889272D17449A1C33EB3970A5982EF2FE5F1255367C33E +231: E8BBFF2C5CDA88CB60BEADB8D04B88795B0CCD89057CEFF1FF588A169363AD453564FE7528D1FB7148845363C3E17824 +232: 5F8671B7C62A5EE9717FF80EC2AA0A03E557A2840C0FD0B59027AFC834C051CC9B7BEFFDEE3478165DB9CA303E2D874C +233: E0E4DE22993E4A6B4884163C678A23AD6349DCD4C16B9041D01F8B3FAB1E8D8B07DA78BFEB57F8C235C173B2D238C4B7 +234: AD6F58BFA15FD0DF1191171F86F2B4C8729FE407128ADB4FAC3404E15C04752F2A4B5F4BDD488378C56FF8D85A38E583 +235: 90C5A75642A1811D8FC1ECB84AF4904C6D9E613353C1B9ED0FCA37D20974CC2425052E2300738824BECFDB981AFF06FD +236: EF73A9E6D23CE43508400163CE6F3E8F7076CEFB94E549EB6116C2557F740D66A1727AD51CA645A7F9022912058FD262 +237: 99FA424E413A57DB2B1B851098FAB1B6D3337AC7FA85709121F0BBDAFB3EE291F44092EA7EB28E9BF0EA0691AA531BFC +238: A1E0A088A279E750CEC429D0AE320B638ECBF9EE387C65C66D2231C884D844DCD438D4D4E052B8D76998A444E0666629 +239: 0657FBA0E7A73F7525505235120C44AAC6D37CE974FF23F52872D6ADA50DA022D417D8DAE40E80336846E8CE211D5AC5 +240: A72ED7917F0F9D0DD888DAB10AF9091A380F518D5DAFC005D1EBF0013F57A7452AEBA98913F509509A02665F332EE255 +241: 74CC959DC6CFB31CFBBE9CE8ABF32D1629E0F578F9199B9A2E90889A2F032919923142AB32E1DEE0A53ADAFAEFE0EBF2 +242: 9E4D463D2E3DC2B98CBA40EF84B022A76D01926D8DE6AC05F995C07C5F07D01742C5410B240240459280D7D278E8BFEC +243: 0D74C427EE654E4790C7118272998C131337D0D0555B68F488AC7CB8DE3CFB461B0248E78340D74B828C80CA28ADF478 +244: 952F274ECBC66B68EA74CC8534A5D7EDB219B755C91266E5A779EC22F52DD2EFA9C447DD311E71C90E1419B4B2F3DAE0 +245: B845B0A56AFEC2FB399559FA77C4835D2BC4C3F8D62BEB1C45462BAC661D2E553B43D0A86073F0BA5AB85B129ED20B1C +246: E65B931E25101224A6933FAAE7DFCF22FE84759937F5F3BDAA90D9C8E8ECD0BFA1777B99A77E3232E38917F9432CCBFC +247: 4F69FE2CB97E9233BC873D153ED9D61B88C20FA333BD4137A532F4F703A323FAC6F8675D8B44EF5FAD2314894F7D60B6 +248: B36F43A6DD2917A1AA0C6B566599C274701BDF03A5B7DC65E5E9F0ACF882786F07989B106A50D0D89629136EA0E26EB1 +249: 8DB7B80635C53DAEF891B777850487E72B67F57576EB05F708786F7665F1FDC2A78F441636569D1E84058A43F0243A1A +250: 14A43F1882AE0214F56819F4AE9276499D39DB4A4A939275DDDCDDD80CB6B70999E6178C4EF295E69A807EE5FDBF9AFD +251: E5AA44CEA67F0821D4ECBC981F258837A243FD901653D484BE5C24EB7F08E0BF33525EE3DDF9A89E1263A853485B5A02 +252: 0191F0505CE5512FA08500BDC090570F0C430161595894528FE7AE5DAD8726E110B0676181A228A7A90E21B7B055361A +253: 76FA1230972E771661485546D6CE556FCDA23B6DC0FFE94DD3BF7FF13FE9B46DCBC8D8FFC617F35687903B972FA7EA43 +254: FE280E1191D21CAE12EA3B53D77E03EA4D96108D35555CBFA9B156253A011ED91B857B82D644BB94BAC8E4FC4E0142B5 +255: BEDDC3C0E168A4B14B023DFC1AE07BE9A418678494C2399695EA9B17843D373077A708F8C82F37657BDC101950FED664 +256: AA5D7EA1126BF16DA2897AE036E94D1F96875AD306B19910EFE3F17B7A98F9A4163E4032EFD17DDBF78FE3321047509C + +HMAC-sha512 + 0: D29B9E3F87809686F34109FBC718D6ABBB09C278CF05A206ADF21463E1170362122E58272A31679720B254CBD63A7C6D696BF9283F9C6897E7D792483BB0388C + 1: 5EC18FCA20788348244720D58E9532B4B699E78D48CF7D7BDD1A4E5C61CD09C075EA7F112DE379FBE953332C6A7D6273B3F6360BC07203A5175FAE618E4A2F55 + 2: 293D275FDD5021716117D2B85E6D38F8D60D4984BC73E2D8D7EF5942CF1287B65C0675E566794786FEA18AED1192A024FC4B3E0505D91E1F91833B210590BFDF + 3: 8D9E222D6B16C58B3862D6BFA556BDFC2A4A152BB2574C2294D5381F6E38FB681500A6A19D55525B337A467A2FC30DD1684832FFF92AD071EEF05BC4F4399FE9 + 4: 71E7028F8C4CE9C1EAEFE459771528D26993E180E616D68355B9C618153AFF2C0E9620B151C8F733E71180EB87BD773A512B945AA353029A8F807FB2A8FF2264 + 5: 589F462D37095693ED0C1F3E0DCB892BD19086FE033718911931509EF6195AD17C79939A87665889EFA6DC19A69BEC6E7058531552832CCBBC06F1BEC70D1736 + 6: D94FC6BDAB3613271522BA05C998A6D1C57CAF0E6EE929651762F257E7EEBC07F5CC7CD3D4064A2755E408B347939B3927434556B4ED49CA406C21D1024E6D80 + 7: 4D8A886A89E9C60EDA3BF0BC512A295196C3F62018936DDB24BE9F6AEC7AA9511B33CBEC8A22309B6389417F4E7FB0489981CACF03DFECF7D9FE5B91D62BB719 + 8: D0E00955F0FFF98ABE885970EE44F1B5D4C23C205C64B681381FA13C543106B2AB4E762FD71F47008B4C429C39ED3D66B3EAEA946674F08684AC99F957F50416 + 9: 4F623E52B5FA2D556D25754FD00BB8429356FD75FE2EC57EB4BA4E25CE03C5332D3A632179C9FCFFF140E6B443A4285F4A7CE881E6D3EEC4FB0DB26C0E2DCDC1 + 10: 5196EE8D442E5308F9D8911C87050DD3C4842D0CDCF55AC554412CF096EDA94BE1A251743AD5BC5F8AC902A38B66D7D57C90C29200984572D57C04F64166B803 + 11: EF77019B0F93B1598E38D3B1B703B52660192547353E7FCD5A7C8525DBB516970D3A6F2A94729D90A5A34CEA255F310C1F46546C2A08975AF477DA2F3689F17E + 12: 0A77531D7081095AC0D0ADF2B379D3F820DD20CD89610917E287FF57BCA5DEABA750E1E075DAACA9CC4DDC74732E6F7BCCCD3671B6DD27503CA855EACC63FFB1 + 13: F1E04B1F7B09DA270A44B62DBAD2FC0160BA1D144D7721010D77ED250A00986932CB6652D95B4A977494F11AF7E7FC82A70DFDACFA11232D653B1A052820185A + 14: 7BE1855550A49FF66D6D395DA7DEBDEAF674F1AB192DF82D74F6BAE8088F83EF1471F413CE00A404486213E41B42CF6C4F7FF1BFA17A1E28928B7179F0A966EE + 15: DFF2CDE8856D811494F559E9F4159065A50B1E82961628E95F04D595F670249A2B71C2625CC1CC2B1F85829255DA007F0374363EB749E935BB72BDA24B8A3F70 + 16: D2F7FE57D9583EC1AA733403527DFBB118DFE07B2A60C43039FB238A7205A053E0496AD0F3C1896090AEAB3088283C8FAF272D1D53B5F9F88281E0A53FE7F8DB + 17: 963F629ED8F0E7D6D4CA4DC8A8B57C825F726380D0BA9A9857459491BA82F64A929EC4ABFCF79374CA68BA812E3A83A643D05454E146E9F4103D17E20B8350F5 + 18: 1FDAE69CA4A9FAACDDF30A56B23F14768EB7D5616F6666B6F01FE5E216825CD4201A69CE3D2D1D2C3D03246BA7D32ADCAAA4A7D03B9AE6AF4CFBB474E1717BCA + 19: 2532E98B6D91D8D658BC1A1FE41AC719D648D47BACB423C031A8E2E9C25CC6650D3E5DF8046BC3532875F0C8DADB38AA911F216E6741E9FAD700D31269EE5D46 + 20: C81E6E9F4B75A4EB2B903C4DE28CC437CD87BF789F6BE60EF521491CC7E44AF26E9EFAC55961135F79B3591F5F7B92ECDC9917641BDC34943C6759AAD9437498 + 21: C0C2B9478F956800B64FA408BB0E077FEF48DE4B146926B3C577C00688829FFA6540AD7C211A807286C546F7D146F95989E77B62F5E14D62FE0C77C85FCB6CC3 + 22: 980D06C1B27EB2EB15069566BD1BD838FD3DA453751BEC564C05941C9BFB9EE8443EECF84CBF8AA7DECAA294C7D1A3FA4A39C20A4659DF332CAFFCB2863A769B + 23: 70FB10E482AD19447CFAF10EB9FCFEE67F9DF7164B2647F19CB220E7D83BF892AB7B5C5ABB73B779522012BFD464D9D1B18C37C3F6CB70EC4106FA94F8CEFECC + 24: 7AB19BF67380012D3A53B93AC15E353D477FDD1E2E8851CD5AB5F36EA0C8B128D3193934F837D23D232F44009AC60DDD358AFC8D3A201BED3EAEEF74C03617A0 + 25: AAFC1227AC42CC27BBF78FE26B3FACBB7B15360891C8EAA8C737AD42C00971D02B3A07CA751774D02F402F7E76BE08E2C1241EB66242DB5E11B342C22AAB9FEB + 26: D8CC3BE5B48C7BEE8522BD8872419932907B78392B7F2546788477C858D0C7BD772985C0B0D202AB7E69AB5F4E1A0BC848A512FDD79EC29F19BC4BA6D28DEB07 + 27: 6133D836D68C82658F6263F794073CAD9029F20CC11D0A6CF589335B023CFD66D708F09136546C6C08769139363AE5CB4CC2CC86EC6911237ACBFD8B0423E377 + 28: 833DAC9CFFBD62FF0749391A42324E2848670913890754E24ECC29D4738AF00A78134660A20078FE59C66113787F4A3E6C0E783740B2F2B2BC8D36FE4EDE39ED + 29: A2F3BC0DF058506805DCF5CC3006CC4FC4085FD846C7A7A7DD3A06CD6DF635359F4FBE90A676DABD7F9AAF42577C8E3B07B63B9CEC8A9AD05B38D16F56214E8F + 30: A49C3BB487C561E5AADA4FBA2D9F5B42681486AE2DF56087DD65B3D5E03C625F709299C84C64A68D87C92A4CC90246D608E692D1FFCE2C099348CD0A19407C2B + 31: C8D7B7A7FFAEDE88963B09A09ECCCB4CAE77DF9D8D242BA19F6485BC7775308E5D11C78FE9C46E609F3AF070F3DA8ED929C103DA1F25BE7867FD4D3E4F2757C9 + 32: AD4627AFB02DECFF956E612537F011E82CB0C202A5A11AB7AFF55A201016C02CD21EFB4EB197BC2D13D272C6A830FD77F534E800B0AF1E79FCFB626ED6A0D6B8 + 33: 8D4E232D9614EA1194E60748496CFD32A4AC249BB8F08E55A7C9DFDA708DE90D067FC433EB9DA2A6833D43BBA8E8DBF31137A3C9B26903060EF9217471E9F945 + 34: 4CE5E4055F10F1D2182A7892F98206D9A120FBDA3251036B7EFEC835C95B4D1FE0BE3892E2363087D01948AA426AA403ABE1CD79F0AA851E2D1195511C7A85AC + 35: ABD65F8E9A2B39BFEF6EFC9A9EDEF6572489AE82034EF3BF2AE5F380026FF4CC40AF093F0408445735C0E6EBEF5D7E7ECC13C98B59807AE01FFE1BAB040FD14D + 36: E8C687D7AF785B1E547307875682ACD82FB58A8259551D81F309C923C2B1FBAF5935EE059B89070B8420F71EEE3BE7B1E3B55B196872F06DD1FB890F6FED11CA + 37: A344BE73E6585E0CC31525BD6D4EC3345D7780CF180D0D5C2D5FBDEDCBEA050A958FEB13C21924E311F57FD6A498756146AAC58412B98E4D2A3B29D9B77A9F53 + 38: F0A088CC818F76A1FD6B5D707B114BDE24245CD55E48611ACC6AA497A0CEF93768501B5F280AC518CEE48C15373118BE7B72F8ABB2E9FD3526DD1C18D9CB2545 + 39: 4D56D5C9222BB78E04DC9346FA9C4ADC27AE08DA3E34F490A13F674264896E58F9E9839715F633C7195B40DF722441275C84AEF162B513E673809F7874E7A124 + 40: C4B3C9E8140F0D5589E326916462354827E491F3444E0C361512E6E761F5E24AE1873B238B73F32F6BF8F1D1D8FF9437A01DACCB749282E776FF66151A4F7E19 + 41: 7B4E07BAF338DF6479E169EB6CC64CFF88167958D44C5CB6606964B7F9ECF5F3F1B1F695C63F2BD66354722F81EE4BC90B9FCF5345642E264C66F6950CC8C481 + 42: 8571A8F76A1D5DAA0900A03E236FE965D085BE6035B7C0601EAD338106BE7DAFAEC82F7C3D8AD346FF749B6DAFC69901A6072CA089B7A5724C75CB0818640F7D + 43: DF516D84392E571C3FE39F4A0BA5D16D866553644B4C4627D3513F0A1C60D22FC5AA4276A71CB37BD6D6AD05A12BF812A2D5388A606583B78372B84DC567431E + 44: 535AF3C73B479B61B8B70E590E335DC4C1E22DCA656454213E1FDD46D026B6D36133BDD372FBFBB27B6DCA8E487F4A54BDA8C5F67B37C871653C656DDE9524EA + 45: DBFA27964DC6A80FF76112FC6CC02C87811DF1ECA3A8620A5030C600561032FC374A6B060FEBE0ED67421D9217D2719F5A55621736FFFC6F4F26DD4C6049FC09 + 46: 6F69BFD2C60AB1554023A6A2094D30CA78D364501F7813A2CB73DEA94AD4B94A0EDF3A3698D6A30C8A5E764B81F51CD0CAEF0F996B8C685A345AA630CD10570A + 47: 2769DDB3AF3DD650BC381D7B10CBC4353699A2A352E57FA5D5CC4FB610E498767F49104ED0F4E06E2BD563F7F8045212F5B9C49CBE050A1662F2262BAC4053CE + 48: E50169B15772017CD9FF93D1B46AF273B375A39D174E3B8621EAC8EF968BD967E1448DC3B2C72A667EFAEBF2B90D4E6640698CB866075E95817719E0EE61DF30 + 49: 4212648E8F9ACBDC16D48CD7B355884E0817A95DB03BD9B8AC5B28BE6371D8AF83546DC82550B8B23DC77F6D06211E3AF3B25528BE686CCA1672C91117DF9762 + 50: 33C71EECDBE503A6AF72EBA8D2B9AA7AB8FA8DE536C87643ABF1BC3EDA535BBA64A8A7F4BAC90ADB7D8C926DCAB1D7DCE15D356C5074BB3EBC7B17516671EC8F + 51: C8EE9E57EFA859DC5553D03402AE80B84B1E0032CE3F2CAC43F8422A80E3EF59126AE7AB4893735F9C948CD9FA8793571E4582908DA19FC723A93C7C36F79F9C + 52: 7CABE0F83E90CF9A497DCE45F14F9926DC714DEEF05A1A0603F6436E134FC7C8346A19CB92DCDE69D794B38FB22233577BA3905C94A7020841224DA888B9BE1F + 53: FDC20554A15B71BA62F896DDC4F8B354E5D2434B0AF719CCA7DC56FBC9BD280B0F80136C4336D605C7C26208649F38C1DD0004C6E0E787A91FAA6075051FFDCF + 54: 87387F89646B4068038E011D7E02C353BD5649F6DA1C4C46CD9F7D69EB3A2F6EE84DD42D25B67BB81666CE8F92A5B1A0F3EA58D4F0B5B6E59EDEC86B43BA0CA6 + 55: 6D0210417671B66D59B8F28CA0EAFDB493C30A7D7329DF29194C53887F05EDC2C3F35853898ED77394CCC650E8D350F69598E3AEF3DDF540DACCED5BBCBAF6AA + 56: F14085036C69398BC7E0CD8A9D4451A10B080E7CEDA5582ED396E5D54441125EB3EF6EDE4534E788DFE6DD3DAAA204814097987981EC8BD8E39E8E8B35AD8FAA + 57: BA67FB4D7D137531D3F4CD3D91975255FCF8EABBEB97EF0FC7C21C4E25FD034658C63881B0AEBEECD2B7D15357C14542D26EBA3ACCA944EB4C4D7E44E9899D42 + 58: 4546585669E343AD40792308AB456DF623A6A23CCBE64B26B953D6C461460BBA7A3FB444481BDB3F7FC8D5E825F2527D2DFF193356CB3171CFBB56C679AD1BB9 + 59: 210F8AD68FCD10BDB8773194FE57EFF566C7E65BCD82BE6196DECB40BF39774691AC6BA718E4B5FF0DDCF2C0510182B9A114C6F0117A0BB0E1AD585C69D38D0B + 60: 29003A048ECAC0613CFAE8EC8757F5E5CF80E9B0BBF538D7460765FE2D6B56D6251ABCFD42B56D64B56D8F219868DEB42B968E88D3F3BE3A161DCB43EA98349A + 61: A308F9E2B60D0093A7278B0645A471408F58B45B3683531179F34931D06A15F4A502F2F7E1DF8B47830F65387BB9F102646058AB456045267F2DC403A1D9A6DD + 62: AD484DDC270FE74E68620AEC882E86320D0D0753E713D9D5C9C7FEEB894DD3FD5FDF4995DDEF87B1126B36E92618331126F5852AA8C0D44404BF9F77B780595D + 63: B4BA7B2F08BC0FC901188B50493FD165F659D3226227E2E9892BD70B02312C12D195A73AED3A4009618E6E74799DB158D9AC27FCCA9BC682B09ECF53BD368C46 + 64: 0AF65ED93646AE826C79BB6E8CD193D5246BD00B0BABF8425ACE03C845B9AEE428045D5F8267F3EA86C433F1A9DBF4AD1883AF164EAFE02C07CE43079668A248 + 65: 65F899BE2C5E9879F6A3BF7B60E62591B5DC5398283229E4FADB1EE78FFBF962295C427BA0D50BBCB9E2F1DD9694BD36CA598BAE7C2EF1F4D0700DC95BB66C37 + 66: FA9ACC46F0841962D6DDCBF5D47BBEC43A0E1E9B2A8F8B7970E2E73C06612FD95044B8BEB58C71B19AF4169B7E6500500445490F80EA4E305B6BB00C7181810D + 67: E9AEA6E12F881A7AEC3AAF428BBF0DA3138EBF69C6B8E52621609AD340D6537E4A03E2B099B735FA82A3D300F782606EF58598683D4ACB0870D5130B4B3142FB + 68: 3558ADBFD411DB8436A1A8B40420EE9C274FA153AEF891290F79DE5714130A50C70EB87E8A901D540ADCFC37E40EF44592822F6ADBBE8E5CB4EC89909633DD7C + 69: AF3852A0B4E846B59A4EAEB7A7A451311B1E8F554042CEB2D253F10FCB3067F9CA927C7DA3E57BC9C99E4E7997856B35DAB0645C194AE9F1FA0A92BC218CC9BC + 70: 6BD90F0F8FFA39C2A483E8349D2A29A96AA7F3CB4B4C1325FE5162988C9DEE849B8E56BF1423B6905ED3FC6A82A067F850372414E2A4A7E5CA379AB80F1C4F23 + 71: 6433885A8A39F2E4CBB36191A038EC3E3227BDDDAEAE24FD396481332A9AD7BECCC4E9BDEA0C8A7F33180ECB1EC1DB49218D17C4325B661967ADCBA25B341649 + 72: C3235054A1FDFF2C0D218C3B54EE6A58FA5AE99040A64A90B9C8DE601B80A7C130168FE7484CE1FD9FBE22E6E794161826730B63DE794EC4ED1D653E40B27F7A + 73: 89F4DF5AC626665D9791A1E1C30D1F206D89C4B0C59916DA295931539B0A607A1261B4EF022CCDA6ECE02E99449E252EAFC8929F5074866C3FF59CC58268E2B8 + 74: 3F1AC15A90C38AA964518F176016FDC73A85B096EFD1FCDCCF38F3EC692635BD4E610F1B3314E068164D02168F73A307AD549E1E7EF07DD374F9697DB6A17447 + 75: 4FE16A3BF0534DD2E4DACC43E221179C9B61D7D50DAEDA4DA9C45CCFDC76D6FA96EB3CC1C184DD5DDF7DAAA413D05B2FE518117E2C9A880726148C7AE6052160 + 76: 1EA870E13B7E59B97045F662682F29DAEC4413566DA341468CC9F5CAB733D1897BBAD8E9520B85C43DE33B9B70880AB774EA636248CD0A1626C9CDFEC3F1835F + 77: 37AE3A9828B08A055B2E47A613D25A8D43D5A456BF741E7964C0DF4AEC6D8E5F3EF874F2B20606A38AFCBD307C104DFA5BF40BFBB3078771436276E777F645DF + 78: 48CB9B779D37299162D2674CE2C2595B2422071917C28AB48781DED5060E76EDABA56E7C538C3182F9D960DC21928E6B3069D510046608C976D7A113DE54DCEB + 79: A565459CED6C996C04A21FF0DA10A7F24B1DE22EEAD7FA7FD2CEEAF522A42E29395F771140573D684C94F61F19C771DF68FF8EA0FF727C55294C70E701C8E426 + 80: 3A0ADB5479E65BE1F00462E60C8F7F74FF5C996680A2A4CF787B5DF65BB2E82264004E396AD7EAFCF8A201E03AA950D42B9A26EF2D24FD2AD7CF57CBD08AFFAC + 81: 6FFC799781B2E9F3F573651EB2DCB0771073DA1875CCC3D2B4C6C06F43161195610617007CA9A943B1F2B001E62518EBABD4542E73CA131E20A167FA6E8CAE44 + 82: 79C9E349F1216FCB295FFFE5771EF54A024306CED9CA111DA3DC629722DF7FA5F0927152E4401E0358BDC16D9ABFA02C709B1C21F6D86905B0CF0D6EC9FD1952 + 83: 6876CC513300CC83BAFCAAE5DFE4C4A0CB962079523ED475B19568243A63B208301335BDDE10CEC90CA816960013E08271F02111BD18FD03C1B941543FF4A579 + 84: FB5392BCB60C1329D3FBEDB4DE1131E7B89326A34F34BB099A7EBEE42B985682F52412D3F0628AA72A8C2C46BA3FEA08D5765264E48DDDBB96CB598C9C0BA93C + 85: FAE655D7CC2FDB54349870B199FA54CF47BEF2AD98021FA27B968AD4C3AE477C6B2DFA9A10C75FE275D5A32C5E9FA06B03D4C908184F49FCF15ABC409106E951 + 86: 9B15DD192392017E2F4DDFCD30B7AE58546AB71EC44DB94EE66CA3419D580AA05B5F10E5D36D9E60465FB8F56665366824B5B6E9A63A13F6E83A026F5A8E0911 + 87: 1A0EC6F024130D24D9740E8037C78A176D9C5933C4073DE3C6B0536E9F7CD20E0E89705953DAC9CD44C85EA059ADC496A7A0EFC40F187DF676D2BC83F80BE983 + 88: 5E9683BD68FA16BE904FF617510AE99249ED3477276A0B410B269EB2E03A3505EDF653C725811AD9DCD7FCCF6F2411980784F4BE7407D68C02CF6ACD21FA1B52 + 89: 47CE3079037E396A5B5A1A3FFFC3C60A138AA2C6BF4FFF26D846C7E1E84E31A26270AAC5C688DA7A29DED589018BC349E3247B073B765FDBA4C8BB271CC6E233 + 90: 280FE2B5B0B72FEFA48A9B6A1B0A3529CAC9D6338E2083816930B14FEA5B21088B1009DE147D81FC7F29B00BADAB32B57E15322A6180D713411F559658FAC715 + 91: 527C2E33018CE9895C3F84BA5C072055730AAF767DC82AE236F1F7C5511FBF2CFCBE32AAEEFEADE38EED4C0895290D0EAAB38E3A5CF7B2462675D1E6B26CE814 + 92: 8C0E22F5BE099CEE31C816A0F5DCF9A548B0EAB55AE7CC127D172AA5243A5C73B5BD3AFD77C89370D51460CB7E84F1DD15774D1B8442C07AD21A3B128688E1E0 + 93: 6CF00F05A9DD7EBA5F1A755987F5678F80AAAF9B5FC44D6199100C062DB50D2DA89096389DB94A6D68BD8337640BAB60AFC8793E1A909624A4E149AECBE415C5 + 94: 8452FD4AAEB1AF4ACA8192DD59926E7B0D7B295B8FE18DF4DD21E7C7ABE8F4ADE7391753E533EDA2EFA13CBCD96948ACF26B658F1E72390BBCD7C1BDCE8FD650 + 95: C4DBE8DC875D00FFAE2AAEB3E0BF1F01529A364454D56D329FD493D327287F3E34DBDF2AD54C5BAC5E6059F5897D18157C7DC846F15F2CDA1B2F0A6EEAAE58D5 + 96: 6C88BBBAD961E9DD1418E9F8EC69FEB443176108F56FA2B0B686E93B0E5F505E56302994FB190787EBA7CED5EAB69DD24CEC39BD566D18ABE337A31414991735 + 97: 439ACC720E8CD0C4A119B9C318FBC543CB7B35FF12DA190D82A951970248BB47D0DA2171A7BF850A881E8767FBCD542039E483974F18532FDB57DF23CD18B1D3 + 98: D71EF6284984442D05E8B6B1AB636E0BA013A8D70029F9F1B9BA7927A582D5AC6899B9C8EB990CA93B49E460AE140564D40467A1368FB4A9EFFED4A467E174CD + 99: 8B5AD2DDB4F8C044AFE2B0216B7E7D830EBDD285E4D992CA022CA2F59644806D8B7599CEC51DC73786D98B7B6F7C10C3BB7D4CEE3740FA42DB21BB51A1269611 +100: 28CA7AF155E9E7E1F5EB64F211F254D624C6C42935E27A91745F2AF2EECFDCF1DBD5896F60520A527499432DD3D0F3981F0E5BA72EF113231A0319467BF5271A +101: 45B69480A77AEE3D83D39A38717EC1CAE1634D2D50D05FD78F70309DDA566DFC160FDA967EA6ADEA8BF45B74557DBCAE4D6187DE1BB82A053CF84B4217F9CCA6 +102: BF46E03CEAE3211FEAED2147B3F2909D406A767005F9C8A5CE6139133D41C2812D3225123B3BF0792288E4BB5C8B5ECE9BDFE0F8FF097DD64FB2CCB964FC9862 +103: 3CA25AE24E0D847D9552FD74E1D6FAAF91736603DEE98E51922A2923630D7CF35917916A1DB23A758E7F067F26A5DE9135871B3DE508CE4ECFEBCBBA1A958C78 +104: 2C4380BB9F29041388A0F8292D97482E1E96429B79162A19F01918DBC2DF0B36244ED9E7D015A20290877ACC4D2FFB14D236CE7FC92ED16C7C57012B0CF6DF70 +105: A0020193ADA7F57DA648C1474731F145E6A8E9E7F9550ECE1A841E2D735B18769738AEA78E7AABB8ABB51EF08A34C187478B4C5AB5BFF4932E97F4E246C60C6A +106: 60E81090C365DA5E69E2FC12256131F134F561C7A411F51F72B7649727C9D7E99795D18D1AA54D09F6B2DD7FC556512F49D582BA6006D951D474039095F3ED07 +107: B213DA3FB3ABD16B1CF5CA81574D78649382A6CFEBA5A88C0B8DD40B1C6E18520F145968C342DB13A2B4B2659F4F865E8CF50BCF2138A7B09A1FC190676E1895 +108: 6862BF8F73054DEF42EF38C4A362ECC8F13BE7E705573D8E9AC6B347EFE6A218950A5AB5ACAC3607C0C94301E0A085BFAE7DAD5E1863D469C113B790C234A947 +109: 2D7D3040A495F8C089C67FEE236A07C7D3361D35271B4DFEA5F17C7E80B888EA339B936C4475194BBE35DD9AF3BE112201AC21C9F5858E4F4C39A0FCFF0EB31C +110: 1F995515755C98C5EB95818DAF0C55B51192BD8D752FA35EBBF51176F05ADFDC32E2FA845C1821B6110F7EC1F1D1EA963433194BB978285CA4344A5F989113EF +111: 3F5855B07A4288497533924165E7EAD3D91A16F5E832FB341F5373C118D5ED7E0EF8D837FEF594C2039F08A7870EC1C2770B7C4E7185246908976B62A416DE5B +112: 1541B5A9C84B684BBDB543F77CF384473D007992F37498F07709EE68033E41829E29109E7C77E252C241C78AF41C790E40696206D58B2FDEE768E5B321362F4E +113: 6DA9AC8390F4264064947684F53A1ADB49314E0619509298CFFEA1729A944990BE2D4C0988BD6E8BD1062D574879218ED8FC4801877D637ED3B5383C069A29D9 +114: BA0A194D5078019B21910C37AFB81A890C4FECE7B1F4E722CF855A6F2F8B82E4EAD37B7B58C07ACEF1EA2B76B146811732EBE1BC0F76A146207B8213802DFB28 +115: 20631BF1D6555C7BA761B0581BBCDCA5A7B1BAACA1B3D3E5B4D70D0C9B0A279BAF00DE093AB1334ED5994FC17386D0B2BE9E0FB67AC1038704891769AE530BB6 +116: F31F66E176DF632694A6F7E16ED8F15CE88908EF1D1F0067CC8A5C805370B9CACE0BDC78B1CEF06630012B3A35D129C4E2AA4F7302E1A122C7E53C51DA7F795D +117: 18B5417DC4CEE4387338C63156C34BBAFF19A2BB962E4248B1A1AFF1FF145BA47D84C6C8570D072BBC57D912C8048E0ED50060CA33408A00722A65C194178387 +118: 2AE09DC52D7BB9E692822A6FB3D582B805E5ECD2C1C4813F94F555BA2210429B615A2301B3EB7C491153D68AE33AD9D28F2FC11B6C61700D79BC7DDB251BD15F +119: 534390ED2DA55D45402F828D6035819C4528768DBFFAE1039CF0D18F89BEAA867589F78871FBC746E43B59E7886FDF734364DEC4193AABF56E8BEDD801E60D89 +120: 231597B2B71E6BE567C86DFE31ADD7B31332BEDA930C4921C4817B7DEBB0282A12D23B076F4783EA840D890F6C571760E70E143F8565561062877D95BD0FF941 +121: D60A1481686AB8F889EACF2E9F66BC32271E70E3E04B91ACA6CFB90375860E0BFC5AD9A627BA0C763CD7576811CDE2921E9A63C0F0A7A26E763F7EC7902308E7 +122: BA65BE7D1EF697281736B3AFA97FF675CD776C125CB01028EC2894EC2EFB9908835A3882E5E57BD44ACA09DC3B0580145EB2265E1724DA6F01AF5F93022D5774 +123: 0DEE2EBEBAA770891C14346A26834CF40212531EDDD64A21EF9FBD62F4728A16E18C673DC8CE3883156F51854A0ACC341DDEE6A0B71C4CBF797CD5327056AAD9 +124: 0717C9EDCC2FAEE525A684EAAB79653DD83BF46ECB285E6B154DFCB8A0C9F8D4B28FA200A6C224B4620CB0AB5B33B9C8BE77B2B5A04DB1A3EF8A5951EC46607C +125: BADCAAE4F76006290B9090AC81B807E7251EAC041E6CB10A2C5B58C4F4B2386E065E6D55C46CD888396C86606FACC82DE2F3F88904E15D549101AC7FFBA057D3 +126: 751F6366EFC97218AC2E0675E7F375444C8D82AE7A139E78305E14148E07100F5B7EF93B576DCE546A7BAFCE24FE148B248BE072031F89B6AE7BA9CC559E9C9B +127: EC0FCB3E124C482CC8D86BA2CDDE931E521F0B6F3E7F333C4388E7448A7F196D95766CEB8A49A90E46B592958BB85BD7495747E71508877975EB1454A4EBD57E +128: CDEEE6EC4D67DD8698B72C13735657EE9F78BB0E1DD37D0CF06063717DA9DCD617C5F4FF7656AA48CB3F697E36B3904F496136A2B04E19726DEF9D3406F8A84A +129: 81BB692EAF7F5176B6A0E5F2DFC01A045A917649D0B23B22C180BD78672F37F8E562FD006A00AF2D7AF0AFE15C8D191339AE28FF2797E64A3809400E2E73A785 +130: 04A8456D131499586CF7B9FC45C2EC96859F3F4BB8240ECD93E439EFD5DDE1DE7B67B688B583598D7FD50CB179D318D4C05EDE04F6FA318AA1E9DD7D4E279307 +131: E5C9D55B686DD9D7B1819A6144F6272B1FB5BB3B3034AB9D1BF34391283BA614D57894925C3D589A7FAC0CA1B1E98A12E9DFDDC2BCD85D1E7F2980709EF25719 +132: 2C6EF2E1C179BFA8295197371C474081790A63AFAA194E459CDC27AD4453B3A8C0110F9229BBDD4BBA5D6E80F2CEA71059334A97EA34F96810A2EBFCC3B177B8 +133: AAD54FE02E67080851DC84E20F7661E42ADB610D0B105B3EA6EB6654DAF64458B7E0F756392196AE2B40626CC2B0D82E47D74D3C50A607F4402C6C6A62999324 +134: CF210EE9A800943EAAF4EFE15DB7DEB696233A4DD62206D46BD9C84A7EB13B5EA43FF3CE15ADD8FC4BCFF022196197D1D097B7A893A79C6640135929FCEF10F6 +135: C81761EBF3235F4D56697B19F62B4F7445C8FDCE3D7999F3249493D50C19CA57C5FC84CD35CF794F58DDB6AC86E8BD53350BA9676AB63B88214162C8E11C16AF +136: 8E56EB131EFA286A92078F5A3667BC6669D6A7FD9746CA5F208EE38D5265CF27076C1624ED0F98D486C55C28A4FB89C7B667AAC505CA1CFE1E841184615B7602 +137: B6CAF44F87688E9E3651C2C98E840264464DE9DFE1F3E4CE5C1BEAD46C7D9D747DFFE282D775E101591A7254112C2DFD543E44B41E72EFEE30B032E5E015150A +138: 8E7851F56585595ABD2B3EBA5AE713672093A3120798506ADD1ACAA3ADD92D737F9AE155B8A5166C0F047801A93731D4B807DFE15F08D67DEF31A7B808601D6E +139: B36B6689A5F391688DA3A0756A15AF15E6E66701E2132CF6F06326AE9C91A0BBAA35664B28BC5B936D2BF1E6653848C5DB57654685124A08C79FD03ACC0681D1 +140: 24A23CE3A90C8EC3D10330EBDA47763B1B03035F9E4AAE0AD336169A2F464E067B026D94ED4B9723E969C8AAE7F404F7B4481C48EF7545EAAE4E648525A68751 +141: C7ADE61F21133886EE0E0B14438F070DA398B3A5387CABF98B0802662F3BD3AAA8738D36CCC0D3EA25BBE9DD3B59062BDF4BE2740482BF6D4C21D0E0FD7B0679 +142: 17EEAD5930DB3A1F8E123AD2E72C38209824F977674A52F380843442F0A5C82B55F8A362527BF5324124401648BEF5E9E26E08050B1FE80886E3856F98AC1EF8 +143: 9DE4F43CA8F7E528FFF9F4EF5897652323AEB95DF80049AFBA189C3D142CFF55AE340358A71B01797A8B72F478276E6353421E1C0C22EBDEA0C044EA60865784 +144: E259BE34C467B471C94B612EA6BD99A3F7EDE58E237DABA6A6656F7F7EB5466DAF908B7759027C277BD9234ECBB23C5C62DD2C9D248C1AE52865D66B5C256756 +145: E49099FC970994F8293E71467BFB1D241FE99322075795FCACFDBFAB396392E37BA09E66BF492684642FF2A03F8CF92E0ACF4677C21AC1C236DDCA103F0B5A69 +146: 4338E438D419D8694FC40383EB1045FD9DFEBC6F18A9A03B4914687A8639322E3B050F48E872BB7E2AD9013D374D68BDBBDD0B177024C1185320D04598515ADF +147: A36238A5C795B23F42D0833A5152770A4B0094BC19DFA72C935D32D02FAF5D136BF55D92B022D01949FF04B78507FB203302833AA7103729771A112E4FD1584F +148: 47180F9E838B129A7732A8DAD763B8CC5437BAEF77EFD34D3B33C63C09F6314B87B3A1436C6866614C3B3A693BC7926E9AE876C7BDE9D712FB5198D6417FCEF6 +149: A87064FF5DA177F3651488A139E568F6C75722ECF97507316BDAC36393724525291682776843B8563A6B014646F6B19F040B17B62BEE4A0711A7B06A67DF75C3 +150: F358321DC6A376ED500A2DABA60096B817D13B59AA02B56C1F51E2C6804F5D2DE2028409964D5755BFC6424287504994C7605749A5E5D9D802BB42922F444D76 +151: AC4A9999133546B8452047EE31B398F623E01DCACED7BAE4CB0B4DF0DD53B8E4921109308DE53C0924E0006361BC8A480AACF798D6B403F338357E8DB676AFBA +152: 0E73ABBEB68982F163257C1145FA2E465FD6E720EEAF5E532DDD1ACCC690B37A8FAEFF8D7D41564A9C86C2F185E0FBD0FCE75259D34A5E96B8C514EC83CA1382 +153: 094503A1B90D71960F83C91D76754BA6B05D670EC6A8EEE1D3CDC652DA6E52B196E155F3BCB62A9E4EF8C507F377AC1321C4C0D7A03F7D8A5286C0019C358E92 +154: 12803349F15FCBD53F2FE11B67DABCF3F470B8E3AFE8A855D7A918E611A2D5F4DAE8FE847ED1FAF834BB3678C6253111636100A991A80C1EAD0D35E28DB3AC85 +155: F489665F4D8A4AAA679D5E5A1B7C501DECE2E0B228630AEEAA1F5643FC4BCCB9E2F018FC2D7C44ABC4AC0861EBA8B7700A49B42486DD13263D978F8A7C9CA306 +156: D9DFBC3DBF0E3D247C95E16D376E7098A92EC59A54FAB482C330139EC6E06ED514D5C74F9604D1171A127502811A16D1D3039BD03C4DBED20BB765EFD34C5F0F +157: BA56A64D01FCF392A6E2F73D791D6C5A57AB40A376E73388CECBFDB910402043B4DB2F2D2B86E3510986CF1DEC3880E3C739175D5C0AA1DCEA18959135E2CF48 +158: F4B07B0A063AB240E5A64F1C494FCD9839276FD9689AA6720A94B83E579EF1044997F6506C1AD82C2CABB9384CEEA0B77D3970C1B7E13F8DE98AFA869F1F4D2A +159: CB4F232024B2D0C48E415D73193CD83C1A6BB9806CA336AC4F3B8FF7BF992B200504ED5E539CAAE68B1E47D4D8ACFD2E6B4BBC1B518689BBB5BB4311C96FE06A +160: 1E67E36D2EC5D0591C0171E7426A88919EA5A17470DA305CBA7BAEE90002E23043FAE1F4BE003EDDC2520A404E639B03880E3CCC68243C60E243A0E7A02E2CA0 +161: 40E46A8F257265A1E57A09B43890FEEFA57F56BB47551BAB38BE2BA8D143C176749484ADEB2D833EC9D6B70FBE872FA53618E64CF0AED24D51BA982D29E730C8 +162: F399712E5EFBA3FDF6B7D04600C16F69260179AB79545F44EF5849308E6FA589721CF7E6FE384461D05EF02BE51E50FA93C5FEEE9279A953C57EC07CFBE53E1D +163: 58DEEE13BF73ADD8B49EBBA90A8EDCE7030C17D6E6C449726D094F90A35A07759A3BEA031EEAF963C4753522EBBED1482789833D15D6EED7F5214E1AB93C174B +164: 13B2F766E6B796C44429A747CB46D99A9866115C78D2E94DAB52BBC9269B6584D26676CFECC2A9F026AE8E0162B6BB8DCB2242659EDA67CF793BF66963C69021 +165: 992B995865F57633665483C7C3ACD34BD108B5DDF151CED97C0D7AD134A8D9250CA8DC17C5C2A76C1C07989228F8B474814FB116C98D25D8F291D10CE259570E +166: 1C5D5E9C29DD91877E279DB679ACF0EFD8464B0A58EC9A3036EDB2621E8106FCF2A81719FDD1B89F13FCBD20960387754DD0F12876DAA911E793DF8F1991C043 +167: FE7F98A1D7839BB417CFF65A45E2DE806C74ADF2636385FEB16A34C890B524A75452EC096849EF0F905FFB38A0319D31A886DD840FE2FA66E16AC7C68B0D7FCC +168: EC67530458F01366BE95049FCFBF65465CEC9AD7D12332CF898DD72ED4D275F9C9EE96AD02603E8032F9B3B12615329CF0FEA564D278B1DC3B47EF304BF901B7 +169: 77BB3F5E58AF174DED0B31627648A1C7B5B8092C829020A6FE4CFD42CB51143E9DE20E3D827FB070DEDDA94D39BD0D330604DCB190E7252B12B03F48072B7E27 +170: CF33E5358E518807B70D6DCFBFB1CBAFBA7B2BDD20931B2A3B08BF8C6755367AB3BBB2FDCAE305F04812460FAD37E9AF70F1905D2F0D3E7628DD1FA453E5AE63 +171: 0739D32112107994BF3E6EC3A107AE3BDB9E2BBDA1D7C10D9AD6AE32952649007F68D28BA0DDD1F1C45F7128C1D3C42EBFDB1975A143A42949C7D97D9F9D3BA1 +172: A4F0B775988038E50429428C8526793AD8B6EC1F0F3AB7F6B33F716C61B7DFC49E254EAA01FFA422A31D30A8268E1BE99D385907479C7E2E0492681B6851DE1B +173: D2472E93989E1F29BE0DCF991A65BFE0E772CE77850A2F96FC6114EBCD78252DFC17712AF193FC5ECBA371B8FD27B0DAC44AFF6140923885F403904F1664AAD4 +174: 6696E09A153B0077D3586705E4A19FA6B3B2DD8621F5D13D7003017A0C569B7483C8CD9218ED1A252EB160C3620FE96A00E267DA0FA8996B417F64DD4A22153B +175: 2337E38B460CDDB026CB81B59B99572D45BCA4A43949440AA5C9F2502DBD8906453FEE23AC0AE47AB77214E52E7CF06ACE73DD8565BDD315F49A460996E08DE9 +176: 068CAEDFA329C1FB00BA02C80877E0E2B1CB6127FA2224BD14FAE5AD0AAE6FBAE052A145F5A8340B446F54AC9BB2108CF6582AFA0FADE91CD3568B604F68F470 +177: EBD69C96F4F2DB05350B74A475CA8C1FDC671B018A47072A11A8DC082C418EB20466720AF12E113C2D507F02596CB022D2BECC4EF8486CB54260020EB6C36481 +178: DB0770922005DE66FBC2B05B1F863ADA569B76DA9B8CA433C99C2F2B4AD60BD28B19A5B3820C0D8B6B2E443CF54A942B961E5EF1D53BAC4CA379964D701070D3 +179: D435D7240B8C6A6AABCB026EA53BB8DE58C5DB471EDD8173AE30C81BEFA9CCDE8E30758CBD7DED822410576115C2415D9DA7FD8A83CBEAE337E5908A012AE1E7 +180: 838AFEF97BBCFF7692C731D55442140D58CABFBE81BE76D41652106E215AF4E934691DC20F181C2123CF091B6D7552115F59937E165F1645CE0E14DEDB864B11 +181: 771815708A3D7BBE5E00FD677E4EB76B2B9A03A09412284A236401E7FCB19B340782C81D1A49371609DDCD7E38F9448FA657533D53280B3D6B492984E9C9CBC3 +182: 649EAB3244AEDAA18CF0A1FFF6619D63BBB66955C5D58E3A592E53F537FA74C60616B9E4483BCBB08AD7D1F5B6B91ED3176E89C03C224F94E5D3893FB6D01CFB +183: B4B6C653D90EDFEC3BEA0FE1FD766D5736DAFA184C360C8B036B7CC842E8C76BECFBAA7046AF087831E322FFC181073C19360A269851FF4DFFB4712E68560C3A +184: B0C0061EC50BBC67DA4765FEBD4033B8A204260177F9CFD451E97B93F19736D4B0B7478E29FBE76BE17AA6B0DFE9C4CB9C6E4734DCC8AA5EA825F101E5C9B02C +185: 54EB4D2C9B26B8B17818AD702E065407A19A711E22C8E66163E7311D8ECFA54448453890194C3EE892A599125AAFE1CB230C6EA268ED68ACD86DBBD17432352C +186: C049743F49D57D9226AFD26B94BFE9165BE5A8CEA9DCCD101F837F29C63A4201B1D4478EB5C4CE9D8F5D6E91BF89D09E6A0D918EE7A6D58CCD0A46D36963BCAB +187: F11AED8EC2B1C003B8E35F8F2A05861D9DD6B7DED02E28EFA4EDBB0BDA0DAA76EAD810CF1C78F50668D50DBE2AE65009C2E12504DFCE9F9BFA9A14969E1D0622 +188: 1CEB4106BC700F76F4825E6790959CC6EC85AD93D6FBB9783098E367E5C9676AA0D6B8CF9A7DCC67565284E71205551650557D556870B421273772524463245B +189: 9711275100A787D9678CEB38981A2246112C2FB1F0EEC1F844DF1703DE5B0FAD995FAC983526E7E3336B8CDC9DCE56FD66B73811201A2DA6783309AB6B9C0546 +190: 81E9DC0CBF71797104A44E72841FAF7F9CCF35C18EFEEF873450A25AE56564B0E9DA98598C527D5629EEF7F0571D9AD929BAB87A27539CE9898ABF4C57C9EBB5 +191: 28F4214D1C8C5B9291F2E1F7FCE732C3290A691432A65A01F7EAB1A313B83936DC98A3B39B5F7712DDEEB8968001C93A102C7FCFB8AD7D49B29661C9A9867109 +192: 78C7A025ADB85145CA8C6E417C4E68A9DB83FA78A23D0CC3DF20AD1409B936686FF756EB51BD8901157B1D031DE6848D97DC2E0F137BCA1D49EE3FB2D5A5E83F +193: E2C25FC61AFC794F65AA57DCCC4111D4B15331842493F93E9500AF01E2017CB226444E208BA9C841DF6D7ED28955B318511335F842AF3C2C0573227AFD790739 +194: 50D768C744CDD318B950986E305BF74B77396FDABCAF63AB786893B5F4104C2525F2F69905955A35234BD6BD85DB17B94AE7008F2E2C368E9639ABE8BAFEE4CA +195: C4F1BF6C56C494351A880172B9CBB59BB0D1A5955352E10A868D3C33BFEA0484EDF6ADDD009A20C8D7B59B7ABD5115D595B026CCA6442921038D9BE860C44CBE +196: C782CE6A141EF9E6CAA61853588B8C75B3A39CE191C161F43D7C5F88FB77BD5055B21F37D4A49D65CCDBD0E6BFD98193FC0092A34C21D5ED0CAA5F129D462073 +197: 1B2F68D7DC7563C286612B3D708AA725923FC9A2FEDCD4B1F1E2557CC70F3BF65944A2BAD9705303207B00F6DBCCE245C6E653C38EA0896DEF4150DA118A699E +198: C1248D0A6B75BEFFFD70EF17F2D0F3CE3628BCFB6A634C93E8F0ED97BBFDB48F6E5608511AD7091D7B062B795EBEDEC67696679EA092F7B84A64C99BB224D387 +199: 20A3D3F3676947173C7FB824B40069A202ED3A5637DB41C97ABFE9E7036D6C009BDDD5BFFF97FE80EBC40355A535D7D3A4B2FDC09B809D3BAE2DC31803413B27 +200: B85500CB777B14592A4562A26B13AF3F08CE74E03372D9622E29C1FB7988A86B8C00DDB2049C1395B43B17CD5C415A5AEDD71E05CC0980EB9520D4CAABBD6FDC +201: DB553A36A3EAABF7BE6FAF85DB96D3D0F207EA1E5B55DE589A116DB80C21AE5B1826A5FF3BB9D84C26A403A1E5C00BC7D2F6DE3F6A9661899D6D75373ED76B71 +202: 5580422E6393475B7C1F5010FA7F4395B969E190AEA056ECC88783A8B5FAB8ACF130DFF39DC0175E9BA8B63B4FABA7E4A36FC55FA1504468727086B2D26B5818 +203: 1CA3DD194E7BCA2591AD1B95D0CD4CF7938334C95A1EBE2C8C1A9B75E6A85F534C094E652248048923CBAB97CB1581E9A2D1AB8375C506159B724F74447A3201 +204: DC525D0EC1E62EA68C013470D77B61377398EDCA82A91C1C3E4D7E5D910A9D556B3AC810FB1457BDD70A18B063523C39BD806A2227C7E057CC6B018DDABFF73E +205: 2F0B9523725B27245D2A1B635DB5A3A3800099546ABFDD95C8E86C67C378D91E4711AD1927E90CC9B50A1A7BE3D60414E487E72445936FD0FA2BBF541F1394EC +206: AB6EB21BC802EB0854F61346F7BFCFFF738EA39829AB2785976D869830DBAC367D59D50C3873B960AC5185F3DBCEABD4E4E594C5C2916A8DC304207E887473C5 +207: 8E1C160A334D41F08918EC084BE12872DE79D00473D1B6ACADABD67E2A6827FB1DDDACAD9BFCF27430AA84F3F7A0D6CF2FFC91E7758F471F2739D51B60125D46 +208: C135532CFE84849FE9F40799E1F2CA05568868C0D44E6832A05C29ED17C5F6D0FB844485CBAE5E50A67F2319C30526DB444F4B45CDAE01A9D0542427731DC175 +209: B1FBEE68843D42FB558D1D9E0B759C168D6F84D07B2E90B646F45F1708B0D6AFF7BA8959EBB6AE4D5DF9A9951D139C81BBE602671CFDC618AA1EB63288DAD72D +210: DC11C3D993F59473F64F16F87D5F085E834306FC1C40D12CE7D6E44C59C31318C694282B0FE53B4B60E1E5DB546D930AB741A8DAAB8ED67C3D87E8E76B8C025C +211: 85BFAE07EEA80F939D52CB18C970C8ED9D4035B57391739C44D7973223C51344B9BE28C16EA29B35AF74A2F8F7581C766D61525DE5922A83A1BB600D97F7A3F2 +212: 26E52AFEE0F11DD79061EA3E4F97205729E6B61E50B69CC2894CABB08CFD3A10C41662CA6F6FEC9B5B80ACACBF968C5B75BB8CFA31D06C82D9CFE97F6E1F43FD +213: 74F18E92D85D9AE79BD62C4B8FFB2116DA8157E17A6927BE2B2D0D79CA101F7CAD6A25CD623C8756D49B9CBB903477B9CAC67734F84F0915ACA9025A9D5C6DD2 +214: A51B45BC09382F85334EA58CF7E7747457B517118042D53D773C66668CD6D5059B9997DB183B1C0F2900AC9949028D8F76DD8B7259149388FBF340834A3BF4FA +215: 59DC88A518FE44A7FD0F316BC8B5C865D370A8BC82533037C9872B24390F7969ECA530911463520218D00B415409AFA90A63F88EE729A252F1B747C414414091 +216: 146FBF362ACCEB8DF79A761285A0653484C38585817E26A7B8906FBBEAD70031160C7B924D3BD3A9ACE28A5712ED0E6E89CE4E71493B27F87BF73BF592D80600 +217: 74B6738B2F0904FD59F3A680CFBFE4E466FB5094037AA1942DB3A0017260D75AC5916E044CAC6BD0E25D176FDA267542B2C7EA201F7237E18B9D00723E98A239 +218: E821A4033FAF0FEFE525115109D0B836A22C287E3B157EC302768BEF7989AACE853218E5AF7DEE9F6E234AD50ABCC8A9658A0EE4D9FE050235341C94308D7A4D +219: C3EDD652D2F831B1C783CE1B8BB8CEF9453FC71F519A4800EC2362ECDBE9EC142F768185D55E322A32AF421DC84EF84615F7F3DBE6BC6E702B4BC8625CEB5BF3 +220: 6A3CA0B5A43EF42A1D6526C2F1507785248374C7D2602079A923C841F775A652724C29E788695B52387778CF2E2BBE2213B2FE212D729E3718D946238FF0E57E +221: C425148335AF813E36D072DC64C7EF6782D7DB981C5142B5D32D6D4338E06AC64363E86E88DF018968FD659DBF50A4B77BE2A02E71B243D65024B36CD71C1796 +222: B796D1F5AB11389EC7EC8DD4D1D5AAF17262C8522A4AACF454B44A7ED71E20F7028169F3164AABEE4C716B38271D72D7ACA3E54B30B9E05616AC51594995F61D +223: 113A56E96ED6F8613705B5CCA6CC4F2138204D7BC0C8965162597C1FD2F6E8143F57FF1160F4B482F7430536A349D20918064AAD2BB38A9D4403C16977B9616D +224: 9590A3BD7A0613381159E1E26342C150DD9B0A937855BF78FBF625648448B540158196A2855E7FCB967F22F5AE927D60E97D0C1C17A01E8D07284FF985F54B8A +225: 74B11968CC7CD925E21037DF011F1C93B2EC34C34A3224AA281ACE7D6F1B10F2A755DD6DDF33F1A4630123BC1CF875894FBD8D8B70AC05F8C3C1076E346A45B6 +226: 85A08D6993B7E5C014C3CA957D6B53EC1B8A5CEADD5060BBCC350915D3278F28E238425DA3A95AEF725A23B1BBD43E5D8832382BF76603F7E2E4FF711D540980 +227: BEFB08F621281473943AF153124256386570261916E5238FAFE44A72801D7C204A974B38696C102748CD1DF65BE3EA8C45A40021C28C7E4BB143800A3F38A93F +228: AFB97494318F31A4C6813246D125217242247D4EB6CF884B244E59655DF866B2820A8E1A7123DCCDE98ECBDF1F6125EC5B95A0D9F85F05CB09537B3FCFC2CF3D +229: E8C2E1D342E6503D77328A2C1336F95939B0E8855F75CFC61D4B03F4AF2305AB57C7DB383055A51E61AFB75494C222B01967BC74B4574B8208FC337E09E57075 +230: 0B396D0F15F49E60994DF4FB1E7E526A272A5B41FAB67EB8A41547CA6CE5B7F3FCE404B6A46BE79AAE37B4DF2C2EF68EAB71F39D5908760FB2124C7C83B0AAFA +231: FE86580438E8EE3459A62E73AF0E14F00F4F0FAD0447921FAEB2B77A0D8786784659B1F6D3044538300C759EBEF7066F9218F9386FF6C8099E6C71B5EC6B721B +232: C7E45B1737EBCA62C87A8F0C46F661BF7D3FC020C3B4B91988FC36C38BBC8DE05A22D4BF148F96D31115605D7B04D4CC8AB3F8738B652E933D76CD6966604CAE +233: 2C43F84381FB618512EDA0278FD382AABBA41FCF5546312DA565F4503CACB86B8A704B3B49C0C86B2207E4641F71FB5E72654B0AEE705C52ECB2E8FAF109FDF0 +234: ABC4EED8635DDFFD9900F5DF8C6246CAF12D8CD9333F38647255DCC52A20B6DE8D4109957CBCC2F48F52346579E008091628FD7CAFA092F2568828F424EABF26 +235: 14672F19BEEF8896F751B0BCF40FEED78A8093AA4DCB590D7AA588DDEB3170460381FDEF3CFB608D55F9E8A295A36DD64DE058C9EFF30B1D1F1A3671388B0AB8 +236: DB87424F975B03F925D8B99A1DD0967D2283E408B6B0155851DCFD53C0C00B05A42CFE14B10408E0F5985809813D35D7AA7C70C1A7BC852C7F254F0303103628 +237: 095D34066A6E202C896EF29F3481EFACBBFA622676F58E90FCD5A0591124E489BE3804AFA9BD3E4C92A9653EBE878A88B275BF9B5C8EF8EA0F01C89CF40E5FE0 +238: BB5BC80C718B85BB3C3DCE95D186711D5B90827B2097DE63C647E5B6C14B4766BF8EE8ED395103030F72ADF0C8992AE836086571908DB4A6258616EDB4BDA878 +239: 9A18D6DD0F97B7407DB0F17896DB2A2751B76C69B6F91E821A0DD717DFDEF630EEC1427C2D190C095DDB07601DC0EC8687B7411D735A9A6EF0EEB84A60948BAC +240: 60A614BC40A7DE580B6ADD05279A68DDCAE79EC3DDDD2C6FFF7B77BE9DD0260DA5241660982B77BA9C4B904075F39612F514BC86DF6F68E189FAE2C84A32CCE7 +241: 5CFCD44DECBE3D74708C620C70DA807C5AD58072F7558D950F519691FC96F98B760B02897C3A85F68EE37B2735931660106670C4DC7FA98EE2E18B6DED532A9F +242: AFBE6D9871AFFE6D201E2E61435703856424301ADD5152DC745D96D1BAA3ADD4C78F2D7C5057F1AE8B21FB91879562050C84144A2042AB2CD273025FA03839F5 +243: CE9C1B19D0E0FFD3085D28C5B2176A741A3034C1B76C54740AAC3470C1C8C6E77BA765AC4D6D90D4DAB0A89AFB17A8863A2917674F5A189A5CBF721C14F5D637 +244: F2F065927839C22DF56960845E27868BA8F272A464619EFFD9AEBAF1E40A72DDA81CFC67DEE13C351736C407F59DAE8EE6F2BDA17521CF66F10C73566B7DA891 +245: 24CD3AFA2218863437C5518021D1B96E0A80EBD14EBF2FA161A5E7032FD985BF71EA59DC5E35DEDE5EEE3098EAF6A16698F5BD5903C4ED218868D1E96E4B8096 +246: 1C6AC311730640FE427C1F23B60E817C25E1318109643A8AB51DA74995FFC3F156F098AEF97F37CD9746002DAD22FBED1A1F222511B92AB5F39DA9B53BD62AF2 +247: 37609371EB63AEF0CA6EACED8388D187203A88C379F24970434D87950C9B7DF9A68B618E9E83E3EB10376504F8FEE2505830EFE3FFBD23EFBE081325AA171482 +248: F0C06F6A2C7AC3F0EE428D7D1BA893E73D4D2F417999043BEFBB3CED51F95F7EA3CA882B9E8C1C973DD8A7F450CD60BB5A0B30D44A574E43E71D2533EFAEC6B5 +249: 3A9D1BD43CB3B7D3E9364F05987DF4CD99D573C036BF1337988751658EAF2896244DF5E4DD8984DD494709E587A75EA8AFF93681787AD738A95C5E98616115F6 +250: D42E2D57B36095F0CFE8F771A9B198C7B7E0433763341D35033F32D21C638CD948D8DBE75F533391347C440F208D17F20614309DBF1091DCA10801E16F5D03B5 +251: FBB964B7865A889433E99C4B61D3CD069DEB99E44673068771030EB1B8F1FD3B3ECAED1DCE8ADFA44F9A625472CD4D987EC7ED7FDA0DA912C8AFF5B20BED7F04 +252: 13F67CAD96C3304FF3C2E45D71A2D69301695516EA384F6001850A46A7F93CB74C5A4CBC1C56544166ABB6C9BBF90B9559320F5F75ABBBDE34C7B8B45C783BC1 +253: 78A609196BB40EEEBEBC04A8794C840A6F831680864D65FAAB093A499A3CF152EAC96865747ACA28392E9F102962C49247E0EDA424A345C4AC6F4B60CC3D2597 +254: F199515CF806EA25237EB93D658BEDC994E61EF70F5665CC2F230E7A40EADA14BFA00D56C1249F2E5C8920977A6C85017F8663BE9422762CF88487B76EE7EF9B +255: E8702ADD4B9034BCA0590FF897C10022C56D08FC4EEE0A43BA85E9E9C2086616B1BE7B6F928A3C53755506ED2D9D62DF5BA4A1862FBCDBA20683931A2244AFBE +256: 6E6A3CDE12F2CB3A42EC8A5D21B435C4DA4DF6CA7E41537D361D8169158287BF1D2241581DE07F88FE92F5AE4E96EB9C489FC3B258EA3842EA2D511CE883883E + +HMAC-rmd128 + 0: E9BF401EB338AE9ECE9F2DE9CC104A5C + 1: 9536B19B029E60F979B3A6B3052685BE + 2: B52F90B48846959EF56051CB6ED21588 + 3: 0811D2108413D9B64ADFA78B05EDF1C8 + 4: E06414189CCE13B61A2FC3CE9BC11938 + 5: 8BA02647A4914BF4248F6C799055ABA8 + 6: A3D5D44CBE30E23D20643E865F28B7CF + 7: 459DC8A812BBB840CA10A49E10F240E8 + 8: 26131CE4DEA7D66E5B3E6ECB1DDA4329 + 9: 5EB41B6A8F140E49BB4EBCB76EFAA0A4 + 10: C5E076890071C872B071E2D068EAD1E3 + 11: 476474365DEBAFE39DE7830A0BC3ADCE + 12: 3E9E0D4B41D740310572562E5F7F0CFF + 13: 9BA99B782F7B79C9C19D40EB27033941 + 14: 8E9931A75435B113C7E17E94E22D0B7C + 15: 1977BEFFFBF378633AD22D9E489FFB90 + 16: 9CA06536713225F3A5F67CB6510FB165 + 17: F46F54B012982621E33BA13A871F82F8 + 18: 73F925BD50E603A66B17D8D926CAD1FF + 19: AC74EC692DDBEF86570044E1B5F31EF2 + 20: 4F4F95BC7487A8F07B23C11F700F9C4A + 21: 02CE78131B27AB77474CFAE5EEA37055 + 22: 1D66BAD41487BA6C238BDAFC04E9963F + 23: 79058EE7D70C9D19058BE2E1D5383F39 + 24: 773EB9C677055286C84B39D2344C43FE + 25: 414A4816C124BB62DBA3BF65B6276208 + 26: 350DE5DF46801BAF8B12D4516E82EF43 + 27: F31C58CD73A3D8AC050BFFA5FDB6200C + 28: 5D7489AAD6537DB3DC27D43F698F6E79 + 29: EEF7FC37DCF2AB96328E62B8097203B6 + 30: 8FD428368B9B52F25C47E74C0327DA52 + 31: 923B6ECABD0337E39E6D068CC98F71A8 + 32: ECF2239FC767105FC69F46FDA5BA37CB + 33: EAEEFEDEC3B1E74A029683FC21F03B40 + 34: 9620C4913123F3A718D61C956673FB23 + 35: 59283EDEA3804ECD6471EA41EAF89A8E + 36: FB5B60685DC1DAF0C6557325DBBB32C4 + 37: DB71D12AA3B97C421FCBE45F8232F3E7 + 38: B0849EE5F1F9484514F5512BD928148C + 39: C73A777E20CC49AD33DBCBB16DC59A84 + 40: 600BF6FB779EA2F7108D1F7B8FE89F45 + 41: 0BD76F07D4C433E5BB9FC98B7FE49A2C + 42: 209E2124DAAAB3B5C6D2DD9A79A36E4F + 43: 907E4E2540A6794D6526A44FA08CAAC3 + 44: BA1BCEBA60F32ABD0EED0A1A56748248 + 45: 31F8527CCDD022CB9439F8B39ED70D11 + 46: 05F429D6AA9FBB1723D81AB268F95963 + 47: 7B91D5409357FF13F9B92ED2C6D63B66 + 48: 30AA88DDC6D49AEF0D4058616EEFD9D9 + 49: 16C0B4F46936AD501EEB5BEC8C699EB3 + 50: 782DDC3AA9B3E498767AA310D7C32CDB + 51: FABED92C454544588965E4CBBBDCDAC5 + 52: 7B04EC847F160BE26FB4A7C6B111EF91 + 53: C20AC6220BD352F8D53F0DEDBCA97862 + 54: 2EB8A89C854AD2412E5E2DB8638550C1 + 55: 390DC3D1C6EA4CD7A381BDD9F0B505A5 + 56: 1D86B9AAE5246182EF76456E9A8F2CC3 + 57: 1759BE8033CD082D771127CC81435696 + 58: 4F230D4174BBB11231ABD4AB58D6FB80 + 59: 9FA21699DE8CDE39FE4C9DF25271A87C + 60: 7658883C002D62D33EA21AC43E26C355 + 61: ED1CD4C63C40453677804FD66BE3E068 + 62: D715E8E09CF4C5A34793FCFF0A7EF0F9 + 63: 86C450794C4F920138A8CF2DD9221826 + 64: 2AE1A808F63CF7AFF39FE9595BE540EC + 65: C8E550F520B0662100FF767FC0FC38E4 + 66: 1A4CA5249BA8BF8E4AF50BD01B89C13C + 67: 25A3566CEE5E0921857048F4A54BF745 + 68: 4D76448CE2C08EBCF6C21FD304973DB1 + 69: 83BBC6D82633974D76A1B0994DD8891E + 70: 9F322885EB927B8C4F93AAC081C7F378 + 71: 7E0DFB22C9433A0A66A673ABB3E81B4A + 72: FD3DE62829CCF2AC389581D9932E1B94 + 73: CADF66BDE69903E9E3117DFE75EB1C6C + 74: 71DD9BF191A5A1A0311BA19BF0568727 + 75: EEC05781AEED255A8DA730399ABE8929 + 76: 07E7E6E57A239F659A6B17B695161878 + 77: 6E7DC67642EB72C295EC12C009902577 + 78: F6AD3BF571AEC27B2C99AAD4A22B9654 + 79: 0F38A5596BC9BFA1ABB7318A35E5841A + 80: 987BA29276694A84DF6F3448D2FA36B1 + 81: 3661D8F157DCBA761D1292FC2FB332C5 + 82: 81834820599DE6624EC116A651FFA2A4 + 83: 59E556C023829D31F76ECB5D2D5050FC + 84: 9389597634228E243808C1CCCC71627D + 85: FFD30A17850DB17BBDE7C3EBC8482A95 + 86: 0297895965B8C96F95A77E6A1BEB5FA5 + 87: 46185FBA371A282AD8251A8DA93E7A10 + 88: 34940377228A73C2CDA178635B8A4827 + 89: 0737C31BEFDE68780EB3A5504F295809 + 90: 3DEE2B38EAF96BC620785551C926E9AF + 91: 719B32410E625DC65AB4E422E24C8663 + 92: 5B9AEA802EFFE00D19E746E0684993CC + 93: EE96F9B8F8FFC084C0EF8C28ED0EEC4C + 94: C6575E5F4CDEE50C0C2F41ECC33BC9E0 + 95: 000DCE0FA82C1422ABF37EF1971B4B1F + 96: 83D1C6EBEF52D1B9DFA3F439BF8DCE25 + 97: 657AFE5CA6D54F9083F02C257CE7E3DB + 98: 9E65239503BEAB92716D5B504358352A + 99: D8375320E32FAE3BBABD4620B1231315 +100: CC8914472A9B5862287D695AD0A88BE6 +101: B0E0D8EDA1BDBEBCD0A78678AD7D6A64 +102: C8EBE9364129E651BD4FB491FE035433 +103: 2A6DF032E0D615DB3BE890B0B6D3349D +104: 975F0E184517902F1C239684EBC06314 +105: 5A86E403AD3D0B9EE5CF87C32482C6FA +106: D3E986B5231A204C88D7C2FD1ECA40C5 +107: 891ABD274D024F8B04143DE588A02AC7 +108: EA619405003DD17F13ED5BFB29587568 +109: EF5CD5EF1164A2E5BBC2D96360E55B87 +110: 07C74397955571A7E4025BB9EC555846 +111: B5F20FB0AC1C1DAA0DEF8EF78A9BDDB5 +112: 88D91C18A4AD272B4C1E2C76BE217BFA +113: AC548888F0E5E559777568ECE71E2007 +114: 816071E2B807CE6EF526E423BBA252D5 +115: 0585A675BADFDD749ECADE66BFFD0546 +116: 964CA97939664EE55B8B973D044D7695 +117: BB8FAACCE9D3238714C3934E6FEE2386 +118: 2BB26CD61B24CB5CB9E2C5FF40C51A00 +119: F5332DEBA64EB35CE3B5C7134C4C8495 +120: ADE7A5C99757D216D10E1F13E3A91F1F +121: AE98C3C4FD874CE0B8501FE4C428282A +122: 04D7625B67AC3F9D117AA45FEF6C6AC1 +123: A05D3C933DC8C8A1CF48290A5D52644E +124: 078F882264317B0C00383FBA7E079301 +125: 44023F3B109763A53FDEFF1822488855 +126: CA535702BAAB858D5FB5B79895E0E1E0 +127: FE1C2C02B7665895DBD2F4D2C22A7232 +128: 75A182DB4FD99599022F5A03F1427289 + +HMAC-rmd160 + 0: 33528FDB4FD0640B4C4363CEF1DE795719EBC7EE + 1: 514DF566C6204373EEE6020054AE7DDE2B0934DB + 2: CC8A5C8D2EBA02BF4474A4CC05CC2D863F1AA392 + 3: 27D731E218C369A32BE4B2BB29D2F1A0988BA583 + 4: 091245BFADF5C6635298702F233ECB3265E85460 + 5: BD2C07FA2197201DCA309063881F2EAC9D925A21 + 6: 480886856354E6FF34B3AFAF9E63FB794BAC4521 + 7: 258D58532BEB5EAD28E9BCA52AA4C0444CC2467A + 8: DB7513F824B42A9E1FFC1369F22F61054A3EB7F0 + 9: 3A4A258F23675EE02E1AC1F72197D1A11F32DE21 + 10: 9315ACAAAA8DC91A9AAF8DDD4CD000AE04F70E1D + 11: 57D60D77E1D78D23D3F184740D9DE392FC6C3C40 + 12: 950395C815A3D1A4A8BB25322333FECA15445BFB + 13: F8201A01C30F3B569B7497B5191AE16D1705085D + 14: 08DEA1A0CD4BD6C9031C84FD2005F15810FF088B + 15: CF41D88EB3921FA137F0203C2CB8BC5200FDE7BE + 16: A07100AAACF5253501A6643452D07C7DE2EA824E + 17: 19DE22082D1F4535A733F16262A135358D651737 + 18: D50BD92902AE0127AC8DD85E9A81ADB7EF3F1E64 + 19: 3FA34A3C02E06DE451794AB87C4FCE6877458CDA + 20: 5928329E4D830E8B2F7608A4ED46DCCFD5798425 + 21: 2825DBD7989A8978904A654E6AF125608B0BEBC1 + 22: 9C812424417D47ED7C78C7A049D4E6CB906DCF3C + 23: 9518A473A902DB6BB56F7A767ABA13C8DF306D37 + 24: 439C444C7AB4395C4DBA32E4F8CF4F76207E5BB4 + 25: 9021FCB087269457ABAA8105D4DAD8DF8904A2F6 + 26: 8B7B686199BC73A175940686BD57F45B2329D895 + 27: 0F50FB7AA9425975BFBB6AD65CF96284F768BB75 + 28: BAA1B7749A9CCAD7105E9ADEE499058A7BE4BA70 + 29: FBD3413CE89DFFE2F0A869036F5C4265D5B14743 + 30: 7CDB257E051ED0EFB761A5A044ECE5B0C1F12033 + 31: BB1E5D495074594534AD523987D8438CF1632425 + 32: CE6D7BEAD1496190F0F0E99B0B0C9BECFB7D9173 + 33: F8BE617A3256EB1C4BFC04CD386EB7FA46603926 + 34: D1A1F489434C458344239A75DA4241A3A94BEBA2 + 35: BEDD951DC98BD5C4138C1F8531D8288BA3C51B87 + 36: 9C2357E832CE87A227F6919B50A0A9D3A29B7CAF + 37: C9FCBB9A1AC48B71B2AA20AC992821531F1141EF + 38: 0B58D56923F9620BCD072703FBA71EC2172EEAD2 + 39: D97480E09FA6473AF9AAFA14FA9589AF65E62328 + 40: 4D5C56D0EB0BAD64FD0B0FB7F87D05EB551951CE + 41: B7EC2D13EDD3603D1BBC8CD29F32B43AEAF6EB4E + 42: 9BD5300B02C9432F686842E7900F3D2A085C5008 + 43: 7E8787C8780C64009216324802958E1D845332FB + 44: 1A3BC1AE95380D609571B01D8C3458B2566B74A5 + 45: 9672BD12EBBB12F398CEFA089BD3282A2D2892FB + 46: D5D3CAD705E2B0B6E0CBFBB0E8C22CD8EB1DC4C5 + 47: 408D84FE0B28A3B3CF16F60D6207A94B36219F81 + 48: 0B7E3D35C292D295797E3ED1F3D8BD5FD92A71BF + 49: 18AC1EA3406D69CD9E9C801F471AEA3A31C69D51 + 50: 98E40CE293ABE4ACFADE7D81371FA92AFA69248C + 51: D95E38F2D0C5ADB478A9BFF9F8E7B10064455C31 + 52: 6246C69FF502D453950BFEB5DBEF68CE76D70F12 + 53: 9D788F02EEE675F47AB4498B1337C6D83A37F64A + 54: 139387D749674D0E84F3C2BFBAFB3F0CDC4CA273 + 55: 09406CEDC1C37D275EBFE02CC707229244086CA2 + 56: BACA138E6EB6E5BEF150083CE0EFC64FB163EBF4 + 57: 87CF4CC4500A691934C2C6607F3296A0BEC980F6 + 58: F8E4DB4FE6879870E9F47BA29F0DA843342953CE + 59: 52DDF305014F1C68A34ED514B10FAE3B1B91F383 + 60: 0D568164C300BB14A4571A73493C02E4165383E4 + 61: E1DD806961D718F8C085CEA11A140900FE8064A4 + 62: 6470CBC7FE079B684D108550698B7C5D265736D4 + 63: DAF83273B2F16DCC69FD55DC84835931E75FF5D8 + 64: 47F4D7724BF49DE885D23D84D582EA3A00E1C2DE + 65: DBD6BD40F804E38963EBD2E81CE5196F6E69AC48 + 66: BD96E9391148957BE64FE6DA89CBDFF45233FBCE + 67: 20975680C2E31D61D7F303215A25CFAB4479F646 + 68: FFC321ED45ECC1A9FCDBC28ABAE0DA1FD27A628A + 69: 99F90008F139FA442C152706E522CEB349EABB00 + 70: 288C57DAD9D1174F4EBA92F7815B93C0916E8157 + 71: 8380FD083E742776CC32971B9E088B894A6A0071 + 72: B0F44C66552ECE94502597B6B100CC64561E6F1F + 73: AA0465458FA1F285F5A4530035F84F844D545A75 + 74: C90EE3BAC92FA4986C850DED11D728A78BE85543 + 75: 3E525BBEB158B246A3F4918B6D634CE8EBE4503A + 76: 7B42675AAE1D0DA5A84623E47C618744249384E5 + 77: F50AC31B43BC93D1BE2A4D9C40FC4D3593F2551C + 78: A31AE398E0D6668A52DAFE37D019F7571E0F681B + 79: BF10B29B4DC7C848C5192631E59E0EED32B8D81C + 80: 77B214EB3617C372C191D1D284FCED04F5AE17BF + 81: 1B17DC33F5966621F4BFA93961B1A8FFEE1AC820 + 82: 5A07D9861EDA6D8698E12FE5250CCAD882628B44 + 83: 176F46FF2202307828D7F62D39330444D688FDAD + 84: 59E94CFA3AC2BE8DC6098840E888306764308DE2 + 85: 679F243847C647FCC3F4589CF87972558350DC98 + 86: DB97F5EF492C7380472E16E3B055567DAB630153 + 87: 359CF9515F6B2192BF0E85EDBBC81D51232210B7 + 88: 30B59B3CBFFC08DA7D9514AE7627460BBBDED722 + 89: F31D5E2866D9726051B6E5AC9B846DB36EB705FD + 90: 860A58DDB6119261646907E251D60760099CAA07 + 91: 22EA0278EA053175C2F12BA4ED172FB0B518F3BA + 92: EC68297334F421AB3F2EF3518684E8E1B548BF56 + 93: 5C1405CC33D9025DA265FF4F25942853721489E2 + 94: 8AEA8E9EAFBF3BA597B65BBCCEE59013C8E6AC8B + 95: ABF7CCD01374D5DDAD6EFFB19412EE772E663DE2 + 96: F7F28E05FAB93A3D089BBFF56D4E462F0BEDA41A + 97: B6C4199D504E72793EEB49611E28A82DF5CD7905 + 98: 0B0916C89F1D9F1134E9106FEBAF4169DC49F752 + 99: 4F18AA0E88A01ED162D08F35300B1C3FCE1FE8B8 +100: 5D4F3C473D5859C16F70C1566F9800B3DBBBC643 +101: 02C1A5F34232B8900E6C7DF2BED957BCAE529784 +102: CDD46E434331D7869A27EA096CAEBF586D93CC2E +103: 492C04E69F0204F150B63022C7DBD28116458F97 +104: CDDAB90168E934E69E942B1F1EC0D0AD7BFB5B43 +105: F433642FA8091FB2517F3357DD30308B4A2AEF53 +106: 537B2118792B6A419C438E58CBB6C5BA887AE257 +107: 753728CB39813C27498033A07DEC03D1FA720FE9 +108: 119A6C5BF3EA8F7A78DA9ED2DE7ED9AE3942964A +109: A501EB611542A2A2CCC68AE754D2EAC17942BD8D +110: 158FB54E37C7DF54B29928B5DFA53A560DC09A5A +111: 15F5380252E23B5C37EE7E8D1F5963FBF8788577 +112: 735F2C3CF7680C63F33AE2D4F3569FA8EB45EB93 +113: 67AFC501C6582DF2A9DBD713F206041E5F3E1DEB +114: 7CAEFEC1C6E8232BCB90E3FE3523EE06496F36A3 +115: CC90ADFCF3F9AE777B30EAA6206A34EF54F74C02 +116: 974E0E85B47CCB870A511810DDEFE81CB85B28D3 +117: 516D6BA01E0186CB7D796FCD9DD169C45B63A93E +118: A1CE534BDD6591AF4EBF61ED75636C7BFF670658 +119: 1E4B241D6EADD77E046BDCCD25F70AAC969262D3 +120: 7F2F1B4B77C3170A9E015DF4E8C6EDFE736DFFC3 +121: 89A3BF181EF195464DBEF9576873CA2DF7D16268 +122: E1F96A7C9115E3DBF28E10D62F2D6EC89415B6D7 +123: D75C1081B3C2720D030EC5DE13093357A0EE6E51 +124: C11603CDAD8DF271093CACDFB5AA4E113A270EA5 +125: 39A9E659DFFDC2ABC88ADA2B6A7445090C7EFBF7 +126: 4132330C5E3344818AF5C054AD55309FF7B767A2 +127: B107A8B0C7B68581969A0F6DB95DB2F790098F1D +128: AD090CC9A6B381C0B3D87035274FBC056012A4E6 + +HMAC-whirlpool + 0: 5C36BE24B458FD3713761955F28353E433B1B818C8EF90F5B7582E249ED0F8C7C518ECF713410885E3FA2B1987B5DEE0FBAC210A007DA0FE995717F8FEA98995 + 1: 30C66EA7CE95764F4CFCFBBE4C166E80A1F23E8C88D2DB7FAC118BCA9EE28299778610D94CD545C18C114A2A144F9E933CD80238E9F1AC737F7149BA232FB846 + 2: A61FAC4DAAADF3DB746DCDC24CACDD8C2B74429CA812D86091B5E7F8186753B34532047B3263D2E231074CCDFB18188747B657E0B685693901CBBEC524949244 + 3: AC3BBA8D998C234F9BCE9A96643E8EFC342F4772DF5606A812C1C6CFD644E8F2B8F9BD724CBC8D769B74C52669705BD3AD390CA61DBC7EBE4438726A91FB2455 + 4: 59AD4171B4C33E09312A01B97B3BC2B7DA43F8791561E32A9186C9B0C418BBC31DF54D6A9ACA00910C0F3DF5D7C2DD7CF5634B76506646B7D4EE5C60AA7C7950 + 5: EDFD9FB5B7BCB39811D87A890171096AD2237B78862C4921191F8B0B137DE5178BE8DA898B6A895FA6C4F401714D2AAC743F512F8989E39081F02A2A0F9F6137 + 6: 6BBE26824C7582213F89F773C520710AE400F01B99BCE126C5F3ABDE79C8B304139352427A3E25A313A5F753A94B55F1EE9D3A0300E8E987E98004F58707F73F + 7: EB89DDACA2BA68940C4616B3B1BDFC25D94A78B8C3A533F1231A259BAF6A6706E1B90CBC2F21A76210C0322C7E4286E393B167A2455DB24C6B52B0CEF3EB78A5 + 8: E8AF385440589959D67746FCD40E295026E942E44259169780B3954D20CBFE2586D2A8BBE408AC2D707B0FE539DB43B3E9B29A8D26D09A41FA6F191999A45186 + 9: F6B9CF6E0A337906517DB09EFA31E91D57D6B908ED5116C13B49B8F1F3C3A872EF42DED53F939CC4EA4122FD8580D528AD2DA72BE063251CC89FB52741E2AEB2 + 10: 274FEF3E5EF7AD7AFB1161A29492F0DF44BA9E1C30E1E88CD708A5D27F2B35C45085A200E9F42F340B0D9B3A1A354B1F5F6D0D1A754D51DFC39CB2EE213112DF + 11: E2EF7A0A64A3F384F95823201823BC95060707F273E395F46F3C0627E1CD2BCE97DB2984C0EE7A11B22E617F0CF64A3F44BE9FD6B38C3A07A504DDC1D33C73B4 + 12: 681D72B9BCA446200BA7578E038A8FC418225BE5F02D8DA3CF085182628B7BE587DCAD4851863CE1CE8653E4916047F8E92E91A6B0D7FFB065F316DA93C4F44A + 13: 2CC82F237ECC1B9B0B9FB76E6B9651C56AE57CAA072A0C20B968F2A74FCA6A9749FA264331F4F2612AE0DF32810B0CAE95E5861473F4675766459B7380F7B9A7 + 14: 1F3818CFB04AA3882442FDF1F5CB0DB2FA9604228D3CCA1F14DA16B35D9B2071B372996A176AF0592F00175EEA4C16A6E0162DE62DE30E8A80FA669FAE9A33CD + 15: BFE4BF868A8AFED289DED5F6E7B21E6856107EBEFAEAB5CD644FB5634181D52D8DEAA203C468ABD279E9BE73507A690C0B715869F6E722C4512E815FA4EF641C + 16: CCBA3834AC7BF06B16675376ECCD96A0F91E3E3C588C5BEE1711A00C107B35D603B20DA8E5CC5FBA6937A24DA53D8F55C907F3E53F0F255E080396426E7ADF9B + 17: B09F6898640E5CF77B6DD3D5A8A4452F4F1D25C90F7AA55A205EFF2C319EC0BE245CEB4190F11D85C2F7234BEB899BDA465C95A1C59568987C4C020B9A7AFC00 + 18: AA7FEEC56E16AD79990B003AD51626C87C9CCB90EBFD748DC268C0C8C1DEE1BDCA1C8064FE7570A5C624AA0CB6BEC163E63680377A16AD49D1AE166090DC0D80 + 19: F755304A4694DBBEB0E59B978943F3D4E429F8123B3D6CE27AB400D3C4BD81A13A8C3C0BA0FA7E5F13BCB0B48290933A05DCB49A5907C074039427F0EC9004FC + 20: CB8B5804EF0478645400B1655DC6E194C8DC26112EF76C57823A02F39C8ADB42F1225B130FF0D40F580DA8CA95D82C0441E3A82C206D9D8D6DBD63B4BB1BCCE2 + 21: 4EEA4AF294C458BDBA7F49AC0826BC295BAF5B16D16F40D379F6B7C3456EF4145B5EC7F7CFB85638F641CF4D07FE3904DA891E68288FC11C0C72F54430915024 + 22: EC52FC8CC0F849E633E3F7339031DCBCEAB69B6634D3E54E7C153CC63DF7D3D3F93B13C8E751E79290ED4845FAA3D5A79A7DE6B100F538E0FFF470A51CD630E4 + 23: D44419C0A36FBFD0FB441B596E8821D3F543D80FC7EB5A3389037BE0139921027571502B5C53BA30D31D4A053E830E610A394842229E08485A2376CB9766313D + 24: 3F4BDBC8A4C86B3F646CC445E2CD54B4C786BAEDEE9FD91A879640B4085D46FEBEECECC95E819ECF6AA9085C2309E79DE1A988C6B68930ABCB9BBAB90F1C2F85 + 25: E5EBC015269E0E61BBD1717618C15D44953AB6F854D962A04FE88865626DCDDEC5F094AAEDCB708D947A9547A985F0B287CA0FBBE3FF2ECCC4C0C4FEE4FE74CB + 26: 010C622DF84E677805108A2C5FB1E8BF5922D35CFAC2408F2AE174D353AF169A40169709C39BFE90E51B095C8C0D2886B4F10B37BEFF805D384E29CECE89C4C8 + 27: 3E9C7BE96E03C48DEA773204E1EC3721EE817ED2403E3C8F950A4C447949438037E2AF0A030CDB983D3FBE5B82226F510FD91CF8830F59212F8CF26C2B5E4DFE + 28: 8797C9C14CD2DE3CB1D29808DA9F23A5502A7BA579586DE9513B980FC06990DE0E29837ED06E24B15DD0000697666B8D3DDC556D818E87F84D125697D5E2F8FE + 29: 93DFA3DEB3258FC7C4F5362D36C2AE21AC0471AF8B895B5AD1C407E8D50DDCD0111AF76EC500D7BE035E6F9CE932190712A3F52FBA4BB0DFCE74400C82D1BD8F + 30: 5587EF7A31353C0E9C346C837EA645770BC5F5C541B72886844B4B0789FF1D95134F558B29385B35960AFDFEA7E3AA40562C12683CB7DD9A410873565CA10880 + 31: 052CB0FAABB263A49516E39525023E2A02DCDB2D5FC78948E042E59F89363FAAF1869D42EC9D7AFB0DADB7D4E99544BEDA92E3270544900A5641F059571B6238 + 32: 2FAEBF049CC4C9C2770E859739B1774EB6E6AC2EAF1AF7D3EB55774C03ADC4C865A65C82E795959CBC4BF00A64AFD2AE0CCA16D58AEB874E253FB9FB9A266790 + 33: 82FBFD2A46F2102AC27089B6889024FA9172FA691C1E3BA9B44A394D52EBF5A7A8BB2321708ED9AF2776D8BAEA13A5F2E9EA4AAF420A24B6F59E2F583D54A797 + 34: B306D18161C766DBDC734FCEB08D14248EBCC63FCBB5B9CC0AE9D690E20E7152D771B3D623D7ECA1CBD305A31EE10C220FCDDC2CE76B578E2F15DE4741E9C9AE + 35: F527D57F0A5F13D7FC6A30A84BF414712044B56FB8F6C1E1375A09783968A851DBD495D51C693590E7A8BB570A7F1C0C9ADAADB74EF8EC71A0093D8D1A4285EE + 36: 0D9F9DB43A0FB4BDF70487002943A6CD3BF200518500B6934BA518B3B0958095930EF59BAC48C84C1E1ADB815A6569FBBE7E61F039BFD8C2F727EF4636542A5D + 37: 614CFB257400128FBBB7B56550E86198155A5647FC11111FB4D36073BB57AE4D9C0A54BCF0DCDB8B54ADE4FF8AE5645821CF9C83F7FA9468FC2CCB552E30BEDF + 38: 7032724503FA5B0765D610D3FA4609F4537F6EAB75D7CC4E2A15D2B1421293D9411C9E8F38999F7D64D607EFE95224331E47FAD4F9BDB6AC19CD3ADE47C17E7D + 39: A8E4316126475B429E72432073CBF26E94DA450DB553D46667D597F0AACB99325C9EDDB94F8CE33551857827AF3935F2DFFE1EE69A20884D58E095390C04B925 + 40: E7E90B19E76017EE80E4979FE56A488AAEEA011DE9DC068DBE53AF06ED44DA4CA3BF662358F191FE2842B083BC5DF2D4183668F4E7FA9E2750869DECA7302202 + 41: 818D734A02A0AE76A0012D7BFE983B17CACE37D4890214C7C53A81CA9F42EF0A472101D609BE5D3DF4F0A55DAF154C20A1A97D53112E22D136C03004FE09149C + 42: 0B9F5B2D4BC3DF781F55ECEE149470F3BF68FC51D121D021DF0CB8D4A5EDA42EA6840DD735ADF8DED72B325662BCEECC6195AE831D169A891F6663F8D7C6E0D3 + 43: 7A5AE42C635B250598C536E531FDAA1746DE2EC7984DC1BE488DE4766D0CD544AB51AB1E62A8A170D120999A61CC6920DB96935F295817851A4CE285D2755112 + 44: 95093085CFE52D746C54DDF8D2FBE33EC00D71C39BE0865B896C331C7E5682FBC0DD84ED15B3F790166D537A9A68EEE5FEEC63FC761EB854018CEB68245CCB90 + 45: 8BA177C495E9832CA8EB55E67E5D7F34C59C4C59D56D50BF6982B36AC341CBFDFBF5A98BBEBC26A9509FBDFB239312DF3B3D5BCE70386EF0E593E17A621F41F5 + 46: 6DD39D94235D012C89FD030341392AE42BE7702C4D8E725C4229940BC273EBB8EDA7A6893B4FF86D1EF84DFA119058BC6C8CA47675492A0D37C859E6D9BD5471 + 47: 13A2FBE3DBAEFCAC5AB8BBAF91BAFDEF5FE38B7F2EBA8BFF0F44B4BBB236613B8BB122BECAD9852BF7638E48F0FC656F9C432D9A66C1188DF3FD1D2A88161139 + 48: 33B9B7EF63B302C1C79E0A43D77487C55D38C53F29C800B4CC287A99A440435121C7ED78BE7406349E65AAF991EA0EF19D06C1AFBB814FE4E0BD68613AF0C760 + 49: 720E1005ACE28903D9C2B6EDE02A52F89860788AFB35208B4B7C147E43BAB3D06445DA138606F334624C606DFF288B0C70B487679685D1DDD26F1DA0A5F6839F + 50: 2A742F1E8CE6CDB501E8AD9BD256786A42E7F1888D9803AA8D5750817B3EA101331D7266298962FA28AF2232BF956FAC7C1C0B1C3DE4C5B3FDDF8E63BEB02185 + 51: 05CF6361A4A238091A1FD011336F7F53B9ACF78BA1B96997EE49B99FE36F0F1163E04B446EEFC117B377593EE078B85BB9588918C76612E2A6F9515E0CA244B2 + 52: F510C877546FD2D022051364A09F2051523F8E7FDCD3E9D2AC5158205FB36CF25A9E0FC394ED2FACA7CB4F0639B33B706FD4D072D62F6EB229E4D7879DFB45CD + 53: 2664476D94776DB52BAAF3B2DE05A36D3E35EF44ABB6F09670F37EEE00C2C54B38F70D06359B20F7E40E22B42901863864EF89EA473A1F3C834D22176E87E617 + 54: 62620CBDA92EC8241DD3A6A0EFB28254B0CEBF3E2351B10CF93029244A6A3D1DCE10D9A895EB6E8A33108DDBAA897DFF2703757DA3706209A7871F4274901E3F + 55: 51282A90B63998F7AE7ADE4787D957992A81D3009D6AC5BF824DD1507B53F6918E9AB6AA1F36373D5E5D3EF8D01AF9D05FBC224781C62C1DCB4A2089BFF5496F + 56: FE1C4394AE26E4B85752045DB14E0AD378726BC1C985C8805222B614C62721E40B2A0D21983FF40AACE8E5F9CD57BA62C37C8F0968EE12FAE14267D6AE906A7A + 57: E570E1183CC6AD7A2C73D7D0E96D3AE0605039603B6F6467FA5CA62E4C1424BC14B17E9614F0ACACCAFC2B1B39D8C081B05DFE2B9796F32C0C742FB09DC7B8DD + 58: E690D667A94344E267A6EA7F3F7A6A5385C961BB6139800CD5257BFD6C4A672DB576B52335D22160A372987D652741EC3AA9439B35D8975AEA49698F8D5528E8 + 59: 59FE977EC1D9927FB09389E3D31272E625F089AA75401D1B541DDCE8C6983A363622CA4F2AA9741F0D1484195CA31D6D315DF6B66E74888D111FEFD249FA0174 + 60: 2CAA990D06814CA73ACEFE0D9A815589958398999707BD52C3773F61B2DC2F20EE7AB7F66D643BD9686C4C460AF45D58BE9F8DFC1B5CFE3A5C2DC2C93D9491A3 + 61: F198E9238E9592A97DDFE1B0B56DE5DC05D358940672D84F15E1CE71ECFD3854CDD38762DF11E1871EE615EB6080E329495B37B23710DCA9F4179F5F95F3E2A3 + 62: 3D7C45603510C6916226B192C81B90EC213D30C11AA21C8520437CA5639D00EAB529A4C443C9A39C5E40DFEEA0F685B3D0E1277BEBDDBF80C3D5F9C8326765D9 + 63: BA081CA12FFBE3CA8F1E2703C96587634F8EB3BA140F93D997B6D0FAD1C1915ECF7D77CC0421E639B083451EDA605571D68DE81E7A4BFC183D7A53A07122168E + 64: CEFE2203F6428D267CD2E284C3B8C31E1946558A56A33291508093DCBF64FD5FA4D33FB723ED49CBA02D97743312138FA77AE960EDF5910E3ADBD02B1203FD97 + 65: DE0379336B1C7421AB4A7F5708BAA3D4E15CE75CEEB8C7349265E71942A963216559FD628C52F71356134AC328D0315ACB63A06382D4251A28127380CCEB08FA + 66: 95FD3399270415A80C2F295957C0BD8E33E35C679C31B2118DFABD542EF02F6E2E432559ED4066954AFBF90C982F60D73DA8BCC94DD48BEDBB00A8E458CCB6B8 + 67: DE49AD8262EACF733B567D8F7752711ECB5D0FF5CB18E5A99C6C35442E652643149A51C820E6D4481AFE63F5B6955105F8173DA57DEFA392E43F7285799A32B9 + 68: BED41AF0733EED85BB26E8A06949AFA1CBCA9BA87C085BDE29FD38F94709F4AC20360F7C7958457D2C49BC5A38FBA06D6A6AF77ACC883783B357032FBA9F93CD + 69: CE72D475D983EB5E528C4D71EEE48EF337E1723DEFDF142598E4CEB3B2978B1B4E36A69EAB6CEE8F3DB2EB353CBD27BF7D41F73FB184CC8785DDCE8EC22E9741 + 70: 24A8A7C759F59CD3DE2E3BA953EA975B60079D9B331AEC4D1F4586FFAD190EF53C2EC6BAB566660EB5D652D7D54265B8584C6BBF986537F54F9D8E4068C01F67 + 71: A7CBE72C99EEEACB387D4532BDB651EB46B8D30A9D5DB8095C9B3422D9D5C9480AA820CFAFE4047AA0546C03DBF07424FCF7B812274B3CDFDC76B9FBBBF08190 + 72: 16D536D1D673F74D9E298B16AE65C65E467131FDE5B4356FE16E3FC36624E19FA7B55727240C51C20491F3122A1AB073B98E095A24F4B3260EBE5211EA2DCB0F + 73: 692189C1FF6DA5862657623BC862F5041D63A2A1EC8986139CCBCAB114427B1A2500B152CC611C5D5599E9792F014A640FBF7C6D944EDA811CD92374326B2C52 + 74: 273E18F4B94E624988C47CC45820E4552DCC53BB40A9A24F744A14E56FB1DADD3EA4087A785AEDB5400A65971709DA1AAB9C18EF534087EA73A1FC8FDC865170 + 75: 8F048230B202743FF1DEBAFEF8CC93244687A58A8E5E3E6F7D85237ADBC724641431783E63FC8EF2FBEF9DE9CD50C9FB294341654706DBEFE6B05CA8588E1A3C + 76: 7AEF7701439F9DB556AD3B166B0B25A51795638A83E0EE25E5244BBE9D2E8CB6A8242D81E78E4906AC9CA0AD4FECD1006D89C5A8582D1BF51C278EE7A357232D + 77: 55CE718F7686A0692B3727BB5C24B16FCB87D8E8EC943A80236CF3E9B37A4A20194243E461B453CF03AD846A0B3287A2005D6603D5E080D700ED2FA25F0FCA87 + 78: 3378B07E0563CA7BCB91F29C8ECA876AD748760748AD07DE0208BAC227E0EED4A4834B8879F3DFE51FFA27B70AAD1F3E9FE1586B1D6B2B9757D545D9CC5DFBB2 + 79: 040E1EC767CDD85FEED2AC6767F0B3C17CE4579FD9525213A682A9B49ED03979144CCE2B94026AAF7D401355B90B25259954163E0C9739CB9E756177ABA053CE + 80: D1CAE0E4FB245C1AC27659C2EE86BADCE26228CF8EA24AA62B69995FF02F9A59B1ACC1C959EF91A7B6EC90EA9D57F49CD0E7621D09E4016676953A3F9B9D40E9 + 81: B41EAC0850797959C62DA2750F2BCAECCDFBAB843D56C034E4E0DC15C961FA611C50F22BBC135E5D99DC4E4B7634A8DF4B0262829593A8A86EF6C265DB9AE907 + 82: 66BE82FD1582736D0DE7861D9DF74715658CF3CD2BCED12868EC4D92F4B015B7BACBB331ACA8D58386AE6B0642C3740BF5F3CB26E76551541AD57E1C303D4527 + 83: C38BC2639AFEC1964C89CB92DE5ECB78E0B2994EF37F839D0A61EA688CCEB068B1A590D6CCC929EFF1145F5A5925A17BF2FC0AD352801CB92651F08352A992D5 + 84: B699ADFC29C54F178B3EFFBF8FE8BFBCD722F2997AC30754A8FC5CC6D51352AFFF7F31D7F71FD9D136E78D1C1E040B05E25CCB75C7AEEF714018F51663C7AD91 + 85: FDC4207E97D12B7A8D05F5073D47EF32BA32961568599ED34CA160F2EDC87726C53087711A63F6BB7E840F305477B931D1CBC1939A8B80205565D453675FCFD7 + 86: 07E1DDE64790A279B69873C6887FBFCA69B87C97BC25B969E2B16040CDD2051BCF43637F490EF1B051CD882B64E22DA55C253A5E796528526EC62A305FB05621 + 87: 3ABE353A4291A3A0ECF204994D49443C1FCC60C80BF6096026551048533E02C475B905046C7708F4852645168C88125221504E174A8B7E67AE424C0077163E0D + 88: 33793697140180A04DA72C0F74E1F845139937CD6F05AF74E3F3C5031D1D2DE571BD72916CBE67859FE501C0E56354C1360E3EBC36EBC11D11C1EE08D158247C + 89: 9E5A386AA9C4C5A2419B902D239E49ED84E542A6F949895C88129DFC2844FC77FB132592C7C1474E619C55FC2835F0810F227799984777CE99D586C158C8F9ED + 90: 6E0D9841C04BB47DEE30F6AB430E53FA1637421E460BBBD7BC8EA167B9A341DDC5E933B6983A025226B1FB3CC663EDC3477F8F0C8FA109A8B97B4B17AF3C2774 + 91: AA0218FD54533314F62390B8C02219D26801C249D394E33981E3B853C5735E331826FA02697DF54C9268B891592DBD876E25C8D985DE8752ADAA0CBE55AE7FFB + 92: 23905B9273CA17D80D9C877DD78150B5382744896B073DC636618C540876B9BA51EC60F5E45DD53BE210B6076554238A3B5EA95DCE3481F0FCF2825B852BDE3E + 93: 1815D1AA4018626EAFF051AFBB92E91F6D6D136F58E8DB160C9E85BEC027B6CC92F0F0760DFD722BE12A97F7D29EEC341BD309F230B55B81D146B409EAEEB7D0 + 94: A2358789A04795BB20D2EDBF95D5DA28A1FBAB329F99DFD0B103304F868CE5AA2DC1F52FE98CC84EB095B9C5ACBD6DC05FD03CFBB3F1D26675D0A8F652D38236 + 95: 2C4DEF028098A0680DF15DEBFE6A7FA42C7A7D75CF410340ADD5257037F0B2F98FB5A068361DF33010FD48A4B41E0E40A2730FF2148C45FA568FAA182589A543 + 96: 360F3B6819EAFD9B3D6BC469F4272F9458C0791759EC1136FAD500F3FCB4FA0598204669E865D7D5F8C289043A2A1CCB47F55CEEFAEAD98C7FDEF38FB22D3A29 + 97: 1CB2E98EE8795761EDB7579583EF86E7223A2109267E5234663BCAAF9FBF28EAE35FE362AE9AD075023C1D36672002E08CB36189A603C174D73BB9489E13355F + 98: 9B3F2D2B2E3D0401229F11E6DED451A1289C631122684BB32B8C0450043ED2267AAEA20E950F52B44EA5941C507F38D23CA76E212593B65BAB347841179BED1D + 99: 2E27C53324017626F7EE7EE26BB0C88450B3D882C2D8823647ECA7650CADDFF3E4201D7DFA2A07A51B9372FCB04C1A79A264DCD3D260DE135D08DBABD2C5869A +100: 0B3D7FFC5DC1CB18B867D995E3D02FB2FBA0DE27BCC85E49A3B01C5581EB3B14C19254C87D92D2EEF952C98E4E6F51C9662CDB982BC95B88C11CB2EECF032576 +101: 85C0B9C8AB8C670C01E179F495DE26F818EE772AAF6FCE4ECBDB4FFADEB1CFD8EA86E42020B47894301920B86082DE52A7E7CDC6DB4904F8F0D383D9CDA312E7 +102: 0C6637D399CFE2734AF7B63F81B7493158B7842E3C5B72E6CEA4388A5C6DB7222D46727B92FB82D88551A227703B8BB6A1AAF47247661E074CF6AE4277D586DB +103: DC54B4ABBB7942C502BF3275E37570947FF7162B6831AA430566E69AA80658C6E792B78EA081611256C64552A9E15A66000632116AC83769B7C58B809FD96021 +104: 532372848D0F525884E5ACED9A727E96A8D92B484DC2D4089206B001CF9EC52902E49E6FD9FDE634941BDF5AA2B45B0787D0B183B895470BF1E79B57DC976EE0 +105: 4B6CEB5AA2174E6486ECB185044629BE6C280807F102CE52D2CE2DCCCFE96E5586A6888DF7500614896C9FE70CF7BC83FE755E88170B3D39EF9B218BE809E495 +106: 6D506B4BD3F079EF4818FCFDA519E7E2AB6A03293525711142C3CDC5236A7CD82A880D9CEDCBC089F7A3D5D3E48BD75DCCA7ADC53B13A2FC9CAC80C037F2CE5D +107: B8ABE308840CC901C6C5FD908E2680886AAA0BDF7085C1A6ABC257186AFC52C522528BD7BF4E82553D9E64CBEE09B9318995E13715AB1F7809EF185E8473D70E +108: 9790A198DA7616F4D8ACDE68DE19635A555874EAE77AD4ECFEF7207DC305D475FD250F308F466B189425AB6A9722D744AEF14541FEB83698943E87E8A39DF838 +109: 816678F1D7484660F4701CE77F4C5E13E5DFADEE6622411BE86DBA4EB71A110DD1087AF7D3F37B8ECB1B9C44A3BD5EA73901C21AAB51E569E61EFF25B5E955F9 +110: 51881FF4B150EDC3542CA12CE6554A40415AFFAA1197FE7CA4B8B065A4FB1DC3B924A444CA31776CED52514C525261269895EBD8584C29747F8D527213534E49 +111: 6D8902F285029EE683CE1803B2D9C6BF6E4B7B59C0ADBFBCED3346782A35652DE3F304ABBDE9F22E4960DF6049431139EC6AA023EE2B013A426DB9A816D92699 +112: 06E5847A060BBC4FCE1375DCC15AEAFBF514EE1ADCDF42AFF932AA277DC09EF614651255E35C499D6BA1BB875EA3E80F80AABF8B7710AA5696B058BE91B99B01 +113: CB1859580DCA13556FAB791572E523C2E888115C18C043B0E33F2268DD0056F9A60EDBB65DD9C8B552CE2299E847ED4617BEF3A453ED2AC3B5366B4D9A651B61 +114: 39778F80D346E53D1B0E60FF7B36A92639D9E7F11548C9326A59D9311D57BF09F33BFD6AC5352F2F041BD07A6D26A181419F5FCD1D5FF8AD38E485DA7DBD5419 +115: E508C9A77F53E36F76F0E477DFF076DE810F9F1599A16A3EFF1840332B26D6C7CC40E03CA8CC212FDA776F4DF968FCF92CE492AEBAABD65F069D1AEBECD11B7B +116: 4659D0E1F9E5318D7B92FCF7700C467429B63F27188C0BA168F0D5696DC764FBFE2C5EFFCF6DF11EA77A17B0565CADC04F95FFB0485CE6900161B82608B1647B +117: B3DB7FF2F08F57F0CBF2195BB9600E9AE5D86A15921EB164A98D25D559BAF5FD740D68430653DE73F3277425DD77CC3FB0CB44ACC5FDE693D59D5FA6DED84597 +118: CA4559843946A7583F944D51E31FDF32BBDBBFC049724454C090A6DB9C356739F2B7E254CF9746521D965593FBBCFB26092069FBFB0D17A1593416D69681B687 +119: 27CB8A2143D1073AC17009C31B28DB95DC195E20AD7D245D8AD880789898F043F0565FE41485EDC239C7129E4B7FB693D9044B2C3D34C5648E4FD8447E85FD71 +120: 99811490C7FC83A10AAD197E95D3618ABF5018E9AF7EA0AA2CC0C771FC11FCEF9FD6070A0962A563D260E8CCFDB77B48745C8C27018F9140870F146F124FF14B +121: A1537FDAD7E18F732181CD9EC9BFD3993FAF5F994A8809A106B59D13BB70FD8D7D4E6A4BEDFA806A9D434AAB0368DE840FD64395B4A9A874DB39405707AE3AE3 +122: FB0D6D962055B47D3A72371BDAF77BE7BF965EA7D53018CAE086E3536804AC748E706E89772DB60896EB8FE2ED8F580866BAF3108CA0C97938B69830FFBC14E3 +123: 3C947F4136D9E780A7572CA4D5D7998DD82D3890CC3F1BCB59A7FE230E31DE322DBA7CF7C1DACB33A3EB1F7E75297C056570D2846EDF756D36C1AE92F8DF6954 +124: BC1BDEFFC6AB779A7ACFE53A3F9DD588CD3C77C740F944C69E331C38F162607E0D4A0CA874AC3D1D74965468843133AA9F961FBFCBF59B58818577132B863181 +125: 51143DA8F5D6E68EC97CE22A4961EF43B3AB658711280587D9ACEE701CA65CAE90D34B66DB52D779A8E2BB6204FFCBCA945C6B98B2C17C8375551FAAFE4C8A44 +126: 2550FCF54872616ED31C60FB3FD97B9AEC7A27B3CEC07D774FCE694ED9D60C43A968251C5F3C5B50E6214426B00C55D7DB1DB31CFC4BC07F6ACEA222052AB796 +127: 1D8B2525E519A3FF8BDAAF31E80EE695F5914B78E7DAB801729B5D84C3A7A2B36A33803F5E0723981CF8A9586EC1BEABC58154EFD919AFF08935FBD756327AAB +128: 4AABF1C3F24C20FFAA61D6106E32EF1BB7CDEB607354BD4B6251893941730054244E198EECD4943C77082CC9B406A2E12271BCA455DF15D3613336615C36B22E + +HMAC-chc_hash + 0: 0607F24D43AA98A86FCC45B53DA04F9D + 1: BE4FB5E0BC4BD8132DB14BCBD7E4CD10 + 2: A3246C609FE39D7C9F7CFCF16185FB48 + 3: 3C7EA951205937240F0756BC0F2F4D1B + 4: 7F69A5DD411DFE6BB99D1B8391B31272 + 5: DCB4D4D7F3B9AF6F51F30DCF733068CC + 6: 1363B27E6B28BCD8AE3DCD0F55B387D7 + 7: BB525342845B1253CFE98F00237A85F3 + 8: 89FB247A36A9926FDA10F2013119151B + 9: 54EB023EF9CE37EDC986373E23A9ED16 + 10: 2358D8884471CB1D9E233107C7A7A4A0 + 11: 94BAB092B00574C5FBEB1D7E54B684C4 + 12: DF1819707621B8A66D9709397E92DC2F + 13: 3044DFFC7947787FDB12F62141B9E4FB + 14: 9EA9943FC2635AD852D1C5699234915D + 15: 1CC75C985BE6EDD3AD5907ED72ECE05E + 16: 1A826C4817FF59E686A59B0B96C9A619 + 17: 44DB2A64264B125DE535A182CB7B2B2C + 18: 4741D46F73F2A860F95751E7E14CC244 + 19: 13FDD4463084FEEB24F713DD9858E7F4 + 20: D3308382E65E588D576D970A792BAC61 + 21: 38E04BD5885FEA9E140F065F37DD09FC + 22: 5C309499657F24C1812FD8B926A419E2 + 23: D1FDB9E8AC245737DA836D68FA507736 + 24: F6924085988770FCC3BC9EEA8F72604E + 25: C72B261A79411F74D707C6B6F45823BD + 26: 2ED2333EBAC77F291FC6E844F2A7E42D + 27: CE0D3EF674917CEA5171F1A52EA62AAE + 28: 55EDEAC9F935ABEAF2956C8E83F3E447 + 29: 820B799CB66DC9763FFD9AB634D971EC + 30: E14B18AB25025BF5DF2C1A73C235AD8B + 31: DE9F394575B9F525A734F302F0DB0A42 + 32: 625ED3B09144ADFF57B6659BB2044FBE + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/notes/lrw_tv.txt b/xmhf-64/xmhf/third-party/libtomcrypt/notes/lrw_tv.txt new file mode 100644 index 0000000000..24532502a1 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/notes/lrw_tv.txt @@ -0,0 +1,126 @@ +16:931b40b97cd1d1338d4a4abdf96d1f45 +16:000102030405060708090a0b0c0d0e0f +32:85e82fe5e8b426cf04bd96d9aed318fb5dae89a1dfb854a09f556b61c5ac918b +32:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +48:dd7aad6c6d10176e25eb97e165ba612a2b6275d97667102f20af20ec2630c7ccb4f5772a3e009948f1ea91f3bbaf7e04 +48:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f +64:338509ed021eecd249cb15cdd440a84ff9d6704b99e8e52e9d057f152b742a5e3b9c314574026c76fc887fb404a12d669eea9460c1fa08e1867c2c0274408b9e +64:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +80:8a9cbff36874de7da3e20e9a26691eef944ff78a72341515ae20c2199688ff92f039a19dc6d517e017ef36647834debee90bf80ba20a7caf24964bcb0bb3a621f8203ce5428461d3ee72ead7aeb201a9 +80:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f +96:06eb66a88b9667296b8644cda3464a27e3e2d8b6b3d0a9ffbebfd48f3967952ce161d8867900b0a7a44638a6e41b9a9dc53bf183a85a4ee33bb6f6c2d64b8cb54bfbb8625ff5cd3965aa08b460737b575da0b8f4123751cf8f0ae801c5856712 +96:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f +112:7af5a2b1381a8bc5aa2bdd4370b88d680c34ba9332d1d9f6e203c4d9fdbf5ece39fe5afb5871490a180c4b102665823dabe1079656f24969bf84267d3264f92cbbc610f26203536d387333938d1a52f4076df1aa0a114f3b0182da12c3a5d87bdc8eff54f80b0d56f7044ba372ee6366 +112:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f +128:814fe82674b98d54671869e3fd705f76e353761bf61cfc635fbb23037d8a0e0dfc13c6c0e34f8c79d4444ac314d4918773265b3fb5866a997e270d5ea8891f0217ec6749df281d790dfbbec8adc504404cc0a6f11e91d0ee6c19abdc67b0c22ea4d9fa218320a694dca53cf522c761e426e0cd57e49b73a5d765cb4bc571e888 +128:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f +144:9fab9584b0dd87df42f07513edad3b5e3a35b8871323eed63a48ded1efe4308a9883579f3a7ab830277bda59b1f1c2614a2cabe11cdd87689c0bae80ebad02b76d9300703d0268e0eb052d9956c5648912843b16be988134cfaf65fa87013ab960b190afea879897f1fdd00b360b6bfc6cc3531285682894b707af5914d2d1a136407f869ae6672e096ad7e95f380d53 +144:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f +160:95aa16e637f1449d9012237f5fd95a57c5a9e203ca0a9393975e5991cc568f7ad2af3266ab605915af277f4395aa312586fb28a18f22d1644963233e1121472980229a3941c2f24758a51c48aa22b61fa4310ed2e6175a71bd4058cdb070f2b8289a46a39636dbe259eeff3c87f96fc8d46961aac54d7a8491b5d713e6cc0d6551b9e90911947d9fd15051badf67420188c450f9916c2edae245f1f6a67e4f5c +160:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f +176:5cb782dd9e2391ab54378121d0766afe6d35ecef7a2cbd85ab04ea82b06b56ddabd311917093ff16bc1857480f84049d89ec6694414617b1cf3a11778c1ccbf22b81be5f07ed6f978df5089e54561fec53de95205ffa7d573092688fce92cae228f342f77c50df87404d502a9b274bbf3cfcaf4e94a1e8401630e18b79d048a5f3901abe82493d911d385890405bcaf4d5981def670955e95c546da8939aa68aefda56b37abd3bdcd466605f9bcc5931 +176:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf +192:e9a7781c750910f265e72edf0659d76a0db2dab863f43ca313b9e67e8f9f97a1ad8ced641c6d8d889ed2d38caa7887ec2eb9242093b39d4633702731b96e11da52b1a9a584d2367e6a0e759baf902eb908b4432ffecd367ff1fde454d4af844e9a10cb260ae222446c179dcc82b5f767b941f75196e8c4b210315d01b006fa6b5f1faf931549044b17b33f567b729ddea115c7b11c90982e1480101e98aab23da6533b40777971b4afc3815d063ef175419dd72bddcdc6bb187b3512c3bff56e +192:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf +208:8fd33ac16f8d9bd2ab24d1d26b267f67222b9309d697502bd001bb48b8c3206bd5c98cc1cff788633cda4edb5aaed2055435c2c092a7c655455d1d01a6d7a449df870dd559e9bae1e0fb0d6e5a98679402c288b87cbda569c3503b4aa9403f80c835c995e3b47e33c1c5b8321e8db1b72955ccbdf640c78aac376ec449396b163b8d16b51b0749fab6ba71d0b563fef6e94702f35ff2ed180f0de1f86679d8f2a26b2b9d8adffc7ad11c5944118e30025c9be26431f130aa2bc238e4b0104ddf9f82630ab7eea590bd7eabb2da745ffa +208:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecf +224:ac2daa6b330224b6f146ad67edebacd98cd2269d0cb313fde49d85ad60f9b21c9926d411fd435be8bd073d294e905acfccea2708f98e05cc9ded3c77e684b671bdc59deff3b43fb931381b12133ce386a0314a939d6c4855bbb7765adf955f4e587bebaf6d3b8cf547b2feda60c326e3409833665f61d91a2451ca2693bad6779094e010a3804993d6078c1ac3c2d26d589a8b3376dd06241b3139d2ae603ae5c4829c297f09a5c535c37998f571b0e96855e7a708d7b2ac42659050547c7bd447bbebad92e98b203ce6e83bab8e94f232417152ac6bfe8f9982012c8f83c674 +224:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf +240:5c4d34448cf5b5b385a8aa9e504d724e6e689a35ff36143c20fa16df16f74347df6b65ef354c094732fe1b31e454e319a7be20dc6df4b900dd6527feb5b7c81a7a40df73d513cd40a5e1acfda4ba9e4fed784bb26b2719899c60a54bd8c772f17c95e6100c6def216c9c612a10db62a576cf45392c68736466305f6cb86f218f57b033c3773d0cdd9827f822cd480b60f94d32b28f536e6f0464e63e84294f0c3ab088dbf0efcf95b020f4c2ddc72c5823c2182025cfda510e1a944ac9316f0ceaba7dbd116cef95e051ca9143eebd575ce53c26cab9aa897167d500fcbe229560a85c98e83385ca6befa90726e768b4 +240:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeef +256:46d31a1a6fccbff0435e1811a4851746df2af5772dd0408fbca2b3603cc4f92f778dec8f14daaa6f081500de55d036b3680a8a9b6c50bc20eebf09e35036bdef9b3751167e807cd1aa70385ea9f4be42ef4de6211079eb0cd6c3810404a60f09dd4e98cccb09c356e6b4c4cc1da036bc82023b075011cad2d01bf95fc45829c7af484f92562c2579bd3b4dba3967d5c6bfdb3e2236c2b43655e6393cdce8a2cca0affb8e45e8545aaf04049c2789108ac5bc6bceba18bcb9d4944ed81a64ab43e28e28207268464b99dad7328db0059defa25a722cbfaf89e93a20768bbce91b64f395a379ba5580a2ca4ab2d978c6ed3aedc9f53896bdc28aa5f1300473a3df +256:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff +272:96a46190ac8c56cb272488d1db3a6153a4be7a298f200eecd42b0657e7110e879ddaf12a782d3f946a283f23fd5fd98ddce5874ea645e6581284d94c5437a4737921fd1504fded721d9a12c9bac8d8feda0b1a32a5a04e3602dd3befaebb161af6df1590d280ce09fd99e551ab39351dff8cd85dc084920a21f49e726bafdfc75e1cd2c42fc8789edf52adcb8b8f87b0b7c89c7e80fb8a14807c96912fa125395d71f631cc3181cccbf435da014e47c4dd25640cf7953787c3fa2e9de4a867d61cc398724a94b584ed336715ec92a562215bf36c193cf2356973e60b858d3f97a944d12a40173218f0bd2e565833581e51bee580e3b3430b3d41d6d6788b73ebb45a22a548456f393f24999c40136688 +272:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f +288:4ea9644990536525105792b735e1a9adaabf7542f8d30f41553f756b33fa90051352939fe2693be9e5e482f9a2fd0ea00ec85abb01a56780b61609ac1364b22b2a1f7b061317995c1d2a8bdd280a7735d1191aa6c546516713577093f17b5696c9f2a2b94b766b5a9d2551891a5c17530bf953aa1dbec6a9560054534163c26973399b128156af6a257e0c591b279ff376d0e2464b06a464bc5e5f3d4ca309ddb9fc96d8c59efe0027389e25aca9106b4a6c0e8e3726e26470f0aa59ecbb1022953312bf5a09db75728ce455f63bd328437622bc61dc5f703e7e0d49a27ccc1fa25439848a1349c7790d1920f465151318c3d27855bd953231981eb903bde19906667d26900e2c233330fa0b6c157db37d5b7c76fdfa7a7e1606045e9a18a0b9 +288:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +304:53ef1d7350ca9c52f3d53b1f3097919a4e49bc48d2e63c571abac2f19f16084b16308dd8cf96f374fafbd1ac7b3f9cf3b9c62af25563ff09f419c94f0530d43ddda8396d99010c861c92d59b3d03bb8423eea55044053b06be07fdab392cff5f85be8119ce3e3783cd03923d28bd6cbecd5620fc2465a9f2b1a0850e4a6f35c1893819b689387e5bd2449aaf8b1497a598a48595030a00b92ce357509f259690823c0d1b710edb36cae8b7653afc183f54b1955a56db65929df6b29880e99eb68581f1e41141ee697c1fa565f0d674a2b9f1e88c3f370d1d5c564547370e73e2f475f52eda167bccbcc19405e1cdd24c13ac25bcfa3f7dd65e233e059b18fb420bdb52969816548bca83ae9d392b8ba1eece0faea2a4d965e46e38c3acdb00466892c1be69ed0e73ad80beee0cbe6d2b +304:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f +320:577d305d82d993adb3fbf1e91bbfcd6d9fd9b7872420dc418825ff0bc791b12dcc5fb56f0a4396131f989cebb7b07b67f6365bf120b15cdf7c856e4ffdecff571bc8b04a10328811401ced98c14b92d667d89ef0f413d2472d039931c33570bef3db3485b4f018bdc771ecad8cdca1ace0ec948591e98ce1e037d33ce00326452fddfc70a340c73b0886b43dd0e9203c11c025af0aa2ef3e3538893d6716574f242657cf1bfdf6d8ca3fabb982866d04554d74a9495f178b5bb68d2c2d026b82a1d65a2a63a5527710c305d6b54e830baa18f692dc0f29815b7eeb717c08d49b696af80db2c05481aa077e52420cbd1ec47c99aa82a0bb730a85bff1a8000c1735af09ac45ad3d0088eaf52f5d42ba1337dfe3ae956d6d7899ac949028ec0f5884ae58d949099505dc9576d204702d9b25a172f81a041fea4e8744605ff0dcb5 +320:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +336:cf3c36fbf2b8d72b6e9e8e9ec871117b2d4dc814e3204a5aa223136f8fb8218245dcf03cd81de80a4d35fc5d0a4f8a31a2872d3c1acdab0846c89bbc8db6f31436741f6e3f21cc1f783bf4eeea9b29415eab9c1d6ed94dbd391a13ba98a851ee0646a378a8d1b25d56de83049fa5ffb33ed2c5f60c6588eaf8e6b374c43cf1aac153dd63951aab2ef10923889af3192bf2adf9eaad048eb8ee3f81916eb589974b5152226c5d1e6f516a82e8acfccbb46ab14d5b901a4b9ad23c3310b0a2d30f0d88d0852e67fd7391c64b9e57800d62d81695d9450e135c9d193fc0efcc8f774e0fab020dff5d0a28390dd4d629f5492a544fcf04811f2b0e3a64d33c5eabc43a22a97c698390d53789935aab90808b091211609a5834ee60da7af6cce5cfe9dcdb438b9e8bf60706696d0a95c5e6bfd25921dee98c47de5d7e4cf5101fc994b062fd2dd01a176358113bafa404bbc8 +336:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f +352:7dfc531b8d9b4f8a084ef0f6bca81ccedb88d13f899c64ddae54611d76a0f77ca27d3745860c79bc944eb854738a1c5a1d23491d19a20f7fef3ac6391798360eb210874cec1cedeef549726e533b223a3f3b14d4bdad059920910279ceb49e70c87a84f1901125327a9929f238f5361099425afa5d826c82253d94d83cd291947a7d54dde88aac734d1df8de1f125fa02b6b0983cd8674bf529c97929b56a5ba681c7279461575a7568c7b9518d95e6ea8faa6ab6b4dca7874dda2c8d2cc72577dd67744873da145bce25593511d0bc3d67bf5cb61f9ac53e04701a1a448e80d692fb46651e45b65dae90994c91b83ba4c1ec9f7945187b9e7c31e870401f5ec8322d0a686fc2f9559279de992171957719004de602a7da9ab63a902fad8313b60fd883781aeb1c8d5b99c73e417c821f75859bbaafad40ab85098dae356c996f4274b198536262b2d26b22216e79ff3fc707fd197e1f39bdfb9acb6214d9196 +352:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f +368:100e6e817ed865757039f75eb6d15c16c5478784eb9dc70f60e3b900f60fa925404e09e2cfc0450bc89bce115fef62de782a2d7725970e7fe8226122c1ff9ccf142275d4f37d011ca3aad5700e2e8a8d27c7553e59f8173c8117d813e4d237bf906e3499306fd5bee0fbae137a372807caae0619caee51039049a09066b62953fc5bf1213dac7da86b4418cf3bbfe046c1b9fedb6045ccbf25617ea52e2b6fe2cf9a52ed371f864197fbb3ccd27ff2d0e2e7285e29b21632111d2ebea0c8f1a216779aaef98346b84f54fafe46ee3128020434d0fb1291e07c53bdb236e3f476199647bd7366a72dcdb5484e2439257ddc5b2d77b3c033e068c32288d94a72f2c6562c7e1727e4f60fa41a75f5561c4c15d5997db99471ff68b085b39d5107003927dce0060b1926ed8e9144a6ba6d907ecf037f8006936ba536513fb8122b82214162b7735a16f72ffc4773c32c9d694827c3c2ecddf742766d2b742ffba674a04c3700ea52988f6e265925cdcf4ef5 +368:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f +384:0e2a132eca216076665bab6f3d1f222a9b502a4830e7a67be3330fb4a4cbc1f2ba2c3891ffd67cca8514739848cd90354e99e489235f380b3727e74467b5579ab2c3661054eac7f9413fe1f5f9b8b54f25b9eec5f693025d300bc70c607f074b640764d91230a6a9753bc403a17009e201cb96b57020b527d48943436e4fb717a5c5ab027e239cb508115244f1ba975861c0beebbfa6a7ff1e47ae135eb2cefdd8976c48ad71ff19549164d22df54044abb8cf86c7281035c00f471514762b6224b2c06cd496e149fe43262c554ba04735df40ae8946a59d87d7bfc4573e5a1cc4bee53a4d33d301503955e405c47cce974a8844ad1990c568dd07dcc1a240dd1dba5f4ce864321967870acf941535926e5d3b511a97924350c9019313a56816a1abc5c51aa96bbfdd2c7837a43320ba964d047fe5d2db2800471679663dbc8afd4fb8ca4d39c5735281b9a668b9dcc46c4f45881a2c9f841dc52f354d706cd32ef5dcb4a9f2cb5c1c7b4fc9e2b56e14fe10a8492f7137e580b6f117d1cae58c +384:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f +400:0195b4bd24e6a6295a3a6ea05ee7717ec07eb6eab50bbac751f66f6a79fc564f7aa1bce8b62b87dc25e7b45d52ff34f4f9d30afd0eb33eedac4eb19241fd80dc05ed8265974d1ed3df48c2e027b77866dbc235536b48ab50f628635a95c4430f8c237d647fd588e0318a5370ee6342eb802c6e584983ec6aace4f486aa05e4ae68da28307cd64f1b9572ba59c0c59ecd198dcae3d6d36e09c80d10c877a88b8779b934c6e39dfe0123c922be796a5d962586b54f6e9fbb467f72534be73c4374a7ec7c34cc1eb3e3934505d9edde91c210697b2e550569bf6a3e1adfc2db5d364336c19ac4dc17e3270601ac88f996a5efbcb2d241a1c7acc8ab4a354533f912c9e51ba898bd41f43486290fa32b36a760de5df0c25d5914f3d56004920c6dc2e1724a95eab88f61cfd154dd47fc8b62702e7780522938fb9c035b494a0ace5a21c09f0cd465a834a61c4c979b093a5d780141cca82324f3dde77f45efbe46d3772831cfa93869d144740bc4d0948bd60df373ea24e4be876b6dc8a338e1853cce36b9415ee9aa9077c4cf9b2d482f70 +400:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f +416:5c3985f375cf6cca081dfc118d4460208446d21d3f3d100e883222cabddda538115ccfc37f68739fb6a1649c55fd36412579ad1c66908b87f252cde8ab32386ef68c6205c8994bb7d0f9e0fa5e1e6d8aef7064b0432b1a03b3dd4fea645aea15216c03f58658df21ca8792fd2253a2a889d1b223efbd60e10890676291fedbdc91aff403cb98fcd96de1d1481bb8103f157780ca09ab5490c79fc9c60fe91d5325103441b986af5e9a0e323bdc98150e45a2e7cd20997c58a561c8698a64e7734ada60ad1669160f92c07e56360113adf699c25990d0172cf67fa8e0e4a3687ac23801badd498c7a1a411ffb1f96bdfa5de99d5a4d6faa8feff99f624c396029c5605927ae0b7315dda77d092d6e37ff885669e7e60a823fd06a457785be0a151786fb0a7a3a8b67a4cf47788ff8768e24b38df7338c87c2fe3919e74e923cc8a4a3ab7a21db18ff4672a25d3652be23b4ef02e958a77d7df0254d7d54f6ce0f3a4572ef675782d0a9083c6549304cb302a03b5692137a2fd65f0b5a21eeae19c6535836844445afbbe2a236ec3fe26b7d7615a4171a6900620376bf27db1479 +416:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f +432:de81559812d2938cba8075ee1cfb7313173305486f59e53abc00efa276653d6cf200828615a9f51a045ee94017723aa431e0d4252205f8b45afce15d3654fc638bc32744488e97f4f7b9958694d40403bec42a1ca97011cc166580737b6fdd71843b8e9e876793858d5b7a06da8cd7bcaad4ab2db8a5635f3643263c9881a9157e1ad82c2832e5894630dd36cb9c65dd7faf147b57e230b5b94417aa962a3f63bf1594a99adbbedb9c03bb9d1a728614032946ad9743c514948b3e01ba8099954dd5e3a0c157eee3e0038c8254fbedb10c685d89cb0555ea7d3f7bd5bce22431bb274ca8421af1fd9842cc9d8094f2289b6e0f4eaa183f316a203b1aa4e6f8008d8576b5936f715ccc584e4ccf1ae81ba5954ee4f5d78ed17135cb13af0484f3664a6f9639a7440ceffd5ea60cc5f391b7cd7201b0059e3391eab6cee0e9ae0ab7c4b7e6480ce7f315b84d8321ec4d1a33cce3ff8dfcf9b1299cbbfee9a5874ce5a1c1dd89710a3119c1d73bd9795d85ff3a01d88066a7b2377738a2247f3cc02072f0f3ea2e3adf463c157e9d662167422db3824df31c592891474fd4d0268e0c64ee9117f6fa02acbbec532d4f9801 +432:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf +448:957c2adc952b9187cc7da773714fcb6fe574a07684c3d5d1e2d633354cfe248406b95f0e9714f276f156d97014cfb35991c359e07464b55ebf67f745168b386bda72f0c2df5a7f830a5e4629303443181cd43cd8d30a415cbce0f503d10a0f63a34eaa3a7ae962111caff5fc33d012549eac997290ee78f4c9cf95c148138b60734cef0612983eb27a160bcf5434bb1e3e6a6c100dd55dff25b04d738bfcedb84ae2a168f3be9711bf74c0c61925b61b321f90bed4018f0798b6aeb99975d26244606e1b5632ad1c1019d0ed0f254273cb6a48494b92e516dd1c90b6e48b407179fb20426ee46a8a0771f1bd67b153bd7625e76ebe052d33137ed1cb8b0574eb7c93176d6ad88c5e4bc47c8c9ef4bd54a46fa8ff32ed284339982a1aafe3752648c55f01f5ea80c419aee39b0590de39f0e34f382e3463bad7b42aa17b5eeb2e5a4ca06e9dc3c254cceb5567acc56fd6848d5d6b259e79452423d1a541c6cbaff928039186f51bf1800d859ed932977df30fe28e00117c1e6e8e77a0bf7ca69e264fcc96c1f75ca677554e9aefd06ce97ce5f0edacd50ef8af9653ec3650dc78693a483cb9686015565ea96fd0c36c13d51af320fb8ca900802ae94fdbcd560e +448:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf +464:1b30a6f0f8275f186d7dc2686794411242cd55389a35c2a8f0d276138b9c1bbd2e12c152def0bcbdc323bd3e3b43fab29cbb67f5ffdf7450acbd8c4844e17b196d68f0ca6c0075bf06b1561432435687a998658d62d2f9945ab9d2a2b9cfd7d4f67bbf4c536ea589faa7a438e3cb0c006a2bbf2f90c139793c6cb41be18b4948841a2d31cff96b25ad0f1377563a4acb28f64efa006834c3335e604d94873e7b8eab583f87c5f4e096bb27f1c1af45eb906953acfd7558c978032624355fb2421a636ac6433e7459b61b0706dac2f4bbcaf18727dea1f6100d34eeed31d2ea2672f9dfc853e408736b1cc03a6485496b6cfccc6f3481b2cd05f5569bb36456970d0289aee8c0442cb85b0659efe9872d5e7eee0218d9da684ed0f11c489b49f5b974d1a397bb31e15a9556dc1447018a4cb40f1e13db643a8769e4be78e22f354390563a7a7334445adc5e70ad26623d248721a0e3b8354e526f573f8a292e7d568e63fa38b48e0a4ce7431e890ed19b3f824cedc84a050d4d2a7818ee26b8ea804700ac840eb4bd3a4c1cc9655380d13a86a69f03f642e7b2337d21116aa7510761704098bde0cd6136cf47858a26e4a11649920fc2cb21a51f2f9330095d9de06b5d72b93a67a59ae3fbaa4652b82c +464:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecf +480:8140b529f455d70afc9ee6018a2e59a1ae060ccc18908f3b0ee9e8efcbd3f0124123252c5a62401b3c30ae2843f4565f19d6f4af186dc35ce11fc8d0d23bde67ac133dea138a5c27712381f148f1756228e0ae06a0795e8fa3e8437f87a6f34db3edd5a679d8b93442e9129ccb3bbd2e79d4e01d57caeeb085b5cf24200150bfa76047b850e96818faabd768ac5e2dfe210846008bd76d956352bcc5600fa77c044ec582c17b8bacbef9075e9f99a2f58fbf8f102825786b6785428f4ac15756c7190ba822ce5c0c571940bf77a22474f8eb6692469a3faf69694301d5c14d92d9995d20afe38b9e58aa6c0bb59dfabdb2aebb0e7b11bd2eba1cfa05ded46cf1dd1cb174dc76ff6784d06f6062fb58a7760284e051cc1ce1144643d902881f1a435130d3a5d7b2442fc03db9896d6d552afc14be38263c63b24659fff6e115b795aa1e1d6415e67637b0bc095de9dc4d464b9cc00dc47cbb55b3b73f3ac03a8ab933be81986e9739c79169e51bb90b1664320193df2368697afc9e02b9d9ca09d7e8710535f512c17ff24e3bfafec233f799999d8be0bc8f460fea79d8459ba17d4efef64cfd90624864fb5b220bc3b77d21a3db10fb626cd8539245398b008c93205254a60c73f9c19f0ed4f4152311ab1743762d859b29af7807fafa815fe9 +480:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf +496:569e7fa1c3fb86f2f88b26de0fbbe7332900ef284696d3b04800b0d81d09eaffece090063c472a180f237b2d4e51b2be3f29c361fad95789ef5f1fbb07059133ed74c3cc544032021d98894be3202af6c77e43f55755afe31ac5b9e5d73d1aa8ad059a4efb9fa10f76d88ad0bd792c96f804254566d4c86949027fff96a5d05c673eecb52436737d329298922ebd45d77789104c6b0885e742e45c4d2fd283768377c09a9925b3984828d1a4fc9bc2bc256b28a2aff31a1ead319897441fccc4b8f3f2c82e5c64cd82111de146cdf7652a8147076d828f1c50b67e2d060deecb9bd2b84a8ba13f0a65fea79a0f47af74d3f03207a191e3a5c9087994846cf176063c196b77271c7e8560ab28084fd1e394d9c43b07deab40c48c05eecfc5ba42ec6d36724eb30ffa5e9904318c1242b0b113cf0c7a168da9197abc2a083f371c526b4afdfe1f1424b290fb2bccf48a426c8f321663c767e3708f37fda56968f0b5e787b67d366828a3cc16266268d92c8afdced356463dcaff0ef568c87653a308c12b69649235f7b2eb391f6c54df1e96451419bf412d2ca0f6d34ec92e04b7bc618ccbff4433e687dd147c5b3fdcf4705078adf5d7e370ee992e021329bed281d0c086930a3661541d67d4af188d882ddd020cdb7bd0c65743ff41b6fc7fd75237e02e7d6dd8083afb544080620c41 +496:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeef +512:9821b3449869f2cb0ef0a24ecbff9b33a73b3cd54bde63d343c426a36c68d1d166c13d02ca4d65cf78e953361a4d2a4035fcade9f3d35d0ae1cff5b85f1fe5c9f3a9db9dab6c10b8ee7542944c84815ca990bf4bcd7062a8013bf852ff3b781f60e29eb9196f31b0e9cd566b7c906b8d930c4d4f410793c1fdf7c8c8ed913469c2506ccfa1c029f383a9eee5a95f18ffeb1f25084c62d6c9fab1d67213efc1ff08f2a33a20eabb520d6997803ffe382ec2f1879465c8b166b045e8ef6fc27c8182d8969419291fa5641afb45ba1600f512a612e7dfca4f71cd63c5fae50a53fb305650e3805428bfb6689813e342425ac6d5d13c9575b629b9430cbb21bfc41c026fa3f8fcd9677bf9bb7cc14c447706a455e2d5fc90a80ee635fbaa589e2f50d35d1a1d5ded77bd970a1fe32f92fccae831c8e540c5cfbad2162dd0683160f0d614fef933207b4ecb51465ec0063ab31243c9a23a07cf0952b81eb02e628b9e53ed0c27d720f65be8f38b960c0286b8dc58aa11905f3d3c694d364ac0997e6b2e3886a1a11b357ef0b75cadbf77acf015b4cf6bce508f4c27f01048d2f4d811e39ee8501d4fb6d69fbb6159a6ba56629e54e798e872be33c191750168af7a47dfefd989c65f6b2ef8064aef83e2e902f68aa9e10a7d6ac4a2680dd0913aad62b5dbbe2f51b46bf64c950caee3b66f6e7857a64d9ccd4518d955f24a23819615 +512:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff +528:f02604963d9dc47382d2b835494b8591deeee437c38d4d23e643ef3d3d3d3d87a6ac3475667a749ee84cac055aa47b531eb22d58cfdcdb395fccd9e34e88ec8dd6d4bdff940e321899b700572badb5e44675f7b425a9c1c1969df684a25ee0974c8a9d5e801b5cd70976a6c5af27937c784f4f8d1c86ae1c265c5cb38ea1ee18bca93ff6019f1927ebe203514bf20548c7efc13cd91fc292e2c9ab9fc014d8371d85a2efae108b2afb8bbafab75e7361c99925a19d83f3d7fa51c0274a7a9796aee7451e783976e679db97baadc4aecbc9d120e01719592e007195dcb7b42439c5403ccdde0ed0ad21a7c5a2798919abe81ff72a2baa033002fe25070e14f3417e7076847e90d21ca9a7fa82b45f62d2340bc2aa729616c83bbbf2a6505f860ceca837c479eead3b18f50f88a63f9582e517b4bf51703e42c3f473f901702d3eb4dc25097169a2fa95729f295200e13d05567e5132268b3939250b8bec170a90bf842c8f2b680fb7dd6bb63bcc1ade151944030c0a58b278d700e3460e9d9a7453f0698de6fe4b3104f048d0d3c2bfd6d71c86d8460b95568df8a493f6e77e1d64b158329bec6ec126a24a1d3cec3beb2749c0d2f2d1c9d03708d0f0a4faf81ab0cc31e31dadba6e7f453f35978d49bd026c145188b042da98795d884256fb7b25f5d6e8ef42c927bb39c921d1e634bc94539076986afc5973e98bbd0e466b2b7e4cfc7831fb0d4da70ab31dd9e1584d +528:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f +544:ab5530701149690a9f3157b9718fb392d2d2c38e57b588c652a9af8580750ef2da9ac7f28442a1a3acc2ddc06e0cca15a6ad8c5a253c0cbb307e7d89ecd6a9d5e72c76f2589e11706713bd0cc4bf524fb5ef3c410eb88e52ec0e52d822f6fe14d744a09ec110171af24ce27a8f116688092d7a7123c2ae144fef01f277876e85bf0bf774350c92c7bfee5977d71f52a0d395003adecddcd92ce6e3a6c73b07786db829396479b10b92938c7b788b897695f74b61bec738526c02865b15ddb8d6a927840fabac0fc2ccbca815ab58689eb73adfb08d6148d9a98e8a5388aa6502458ebf02592178527681a12afacb0e0e1b861347dca374eb38f31d86761b5d933f182cfb3aa48cdcf17f08cb9563ab8928e6472fdf43143454f66b626d4e69b1ea0698a4571387e99fd4ee16faf826c3a5c1110522236345948c594c20e3a61e530dee291b79b7cd0e2b0fe7d0180ba1162bc4b3b1b3280dca81fd5a9ca8a227f77cef89896e5c664a75b787f45e9693147776ca8ec8ed99ced39920b813ae9e1e93214d8cfe5c168ec5f07fca092f6368fd952d0d48a49600fc0b3905486140be1fdbf142d0cc8da446d2ed4b1b42f09f09d3cccb95b50ebbfeff60a1f5bc44a9161ec3bebb94504b70fef1c36035a89a866fb96b12f122d2e5ee5fe85b371223f95664b7737784c0cecea980fa711cc263446be48c07e6da223c4ec856004f99b0b195180187aa73ad3318b7b23c9002590d6b42fc57e9b0891e70406387ed +544:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +560:dee4d7750f0870bcd16faff4d65a5593f5d86f32a6ad7a519d6b2333e522dccadfab7890d02a6499d6487302aeddf9c52c929486ffb44b9ea9409a940d4486a379b0ed04e00421f6e43e7393f75963e68422ebcb2b87eca211f671dd713d59a6034576a4feb356eff67f33081f7889c684f971a22be68adaceb35d24d1947d7f5a5c03f66f3152dc3bd70f59e172879f50da9038a115986ada1277014958b2b19d8a158c097c3212eab6c6c0e97948ae15f146a245bda2495a5a860da0dea32b7794f77aa4bc91268076649255fb138a4ed831e659a1ab9761e37bc13839d1f419d7cecbb12bfa67c53fde957ef5f5cdf43157517f8021e89eb46df4762cdb992a9285c36b6361561dc469c2e9b5bbf79fdc8779627971e6d6a74e40fb1961933f182a1b270910d7604a680d5bfc2e5f66b6e4098a0b13d4c9b923bb56713012bb63b7a5cd1f9f1a7b42a4e28278e5766a3e484da08a7538fb1b27a15f7eefdb5fe28cf6297d81ce7c464b6f7373783c7d344334beed713e325e1429bd7bfdd1610efa551f0c16a6eee5b787f973a0110754bb681de8d17830996e993a360e1585b12ea8720fdb3227f193a1963f0afa7d59e303c27c70d37392fcdaefd5b85d52c2bbb7f19b3146c2165e35bda3b6c23f16e469281e10bd351a533edc370388a07e63f02b07db8569b8760b7c091529907893133685aec1cabbb8e06752f90490ed49fe4cf5d580c0007ea7e902a71923029237fbcf965859abb2d14f6c89548017eeed6d0d5614d131b6512c74b407 +560:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f +576:a1d36653fed5f5d40d1dd0873a07b82e673c63f30f6d7c895ec6eec7fb1e9fce1f3ecc41032c94b3fefa4fe98f66baa353939c796be30cc1668d195eaf5c8556c1a00c4dc0d6ab65919a1d72950231c8969c5b02b7f22b70cc03fceaa39a5adca0c9ba1cfd9bfbbef5d4dbe74d3596659658cc5aa1709e4d60469600324514517e90d203aa7eb44612e58870e3acec3b8c969f47f90c2142128a2a47ac3d3247c67fcb051c82f3bcfc98dc5fdf5bef407e369d02f23d690f62cc5e41aeb2298bf2c971a66744bdaeb9832650edc25d09fbd1314a5d84477d7e552b81b3c5731b420eab4d679bb84e765ffc5bf9b4d19df96b22342ec09d808d509fe8c4d0d40c3ab9b1d40040b4443555d9ce9aa04e216567f05ee286c811c9daa6c1dab198bce81e03d171305f1423626132210f0143a514daa926edbfce9a234b3100590196c424fffe738d0137fba0532a7b9b4dc162b9b406fa06840e49b0b9cad3ef7d71aa767b8b2fbf9780f1369d6c5b34361f403a3516ceb2fa0a89bf1821574439dcf42fb1328415e363d9a306a3f720e23eb5041199edcfa10b865a9f5a32009906512202bb4ed532616b956d0308a0d713c6adf20dc03da7c9b29c9d409b2fbe3c7f30376bace8a3156fcb384a62b93c50561776fc6cf16ded8e968b27391af2b767ac890b57fdbb7d3a3fcdee5467badc7c0d8ce59a17129a3672c37259874b85202902b11a3261ce7a16b3f830d36a173a8dd3623db5f45c233c6456b8a2d0fdadb16356e5c37afeb7f473cb4a55f39b9ffb0e4fd96952b75edb5c7f4648250e +576:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +592:4231efb1fe07daf9ef1a69137769cce0731aac9aef27cfae5b60094e8e8550cc5b83c31efee907f5aa9fc51fbffe785d7d70ed0b93e918b4d771c7b22dd72b3d78e7eedaba9689eafd5d440897a339a2fd814651166f74636518affd53d96ce9b6b2727cf3b87c1a7e5ad7cf839b244bb2561fb3955d848131efa937cc8f61fa8820496b779498ecb3a3ea1cb573d55c11bcfe1f21ca95110012be5f35ee2d224cc284062b27b5ef85abe933f8bc5f1acb40b2f42b24db4dddaaae33b67653145a2c20ec0b308cb7f2e1a4110033776cdca32115a2022b3427d73d1e3895c9b6f337c6ba7efffc63bfde50b2c43cb6741650a4ec6a742019c65581a6d45f8d62f62d3da161211e414eb6af9894383615b4df3d1ac5d5d878ba72087ae03530013b21d56130782acfe0a9605466085a8c8b8db96827ea4039a77b1d7b95aca25167d37e6d6ca8880da08588ec7c613f06d24f69c3e8bc1f0b9b8bf589b7010671a9737f57eb59e76523b9df0a94edbb85a5ad91a7bc58ac0df86e6fa68b36eac485b497a170bfdd798e1032376906d0b77dfe9335fe47ae4142dfe9da9b3d946af220715dfa7adcb0c7789e4566fb9acad513c054d859ef309cec2a196a5407902ae929aab826cdd056f70a8957e7e001a63522e579986f542297fe07226c946e832554cb4d8a0f579891abd54b7ed12247ed880574eb62f823b42cca3418fd03b9efbd6e490e92dcca2409c1e5530b9a02529fef02114f96bc0ee7739507b22e48510221e218c0bad525dec6a2da81b834134ebf0bbad4638d6e3d781db3335883256d1964bcfd37391e84d128c5c7fd +592:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f +608:7cff31eeaa23800d7147e8746ad4e2b2e041a68804786f51539d19c040c4529d2c8f3a9eb917505eaf9fa09c8ae6e0d8d8f5c341e4f35f0b0f9b4ad99d7996c140abe8adcb81b6c96459f62b7e24e580614f6320b9d9a2f791b7c2aa9de02f0450819411e80cd62d67ab56f207441f823e8a40bb89f41fbbe95e26359f738ec2c7e418acd5c054c18631d573aec346915979d8eda7ef287b96053e6b9ad1ea683624fd02b3ae6ecf0db342a7e5c46b4b39f5fb16a52237689977c1f2d310fa7e940b9a7c6e20beb9e7a8c0727f0c7461dcb6fee73b4444822776345d7db060c7ff761e2246250b2d7a48e4ebd1f084fae6906c3120f59b740ac6bfda70ac6e1168d4572ca2912f6891d33a128e439bda816691e519bef01660a80df5d6e7108b7789950ee523b9b2ac8d998dcd276ad09c479265fc9679008174cac18ab8ba38f0ea3384f3e623daf1fa7081d042203a4777e5a245540bfb1cda88445f056d4668256e719352a4cd9d02cc3f0a3bf24153aeca33ed0df4ba73d5453a40e79a4a1ff462b6c9b3f3a129be2d27f1ee31b5675ad4d9c1a4567c57d039badc19676a6a029881c6c30616a8d32b6af83c6a3fa412a6a383af1f6cd38366c1475670dc15a9406a22e33ca2e149bb7141b8e39f1e437a13cb0ea27a9f73f7f01a02ceb8ef6a70de8a33e68c6f5495058a0b5af933bbcda9451e93f6e8877938ec67728d48fce408e803351928ea05f2d0d53ead088eaa84c2ec158ac9c036ba602399d542b687e8e0c80f7ea642b09abb61798e54c54886c88eeca627a8012254bdecd763c906e4dc7c31249830278dc4ac6a08cb22eb2aca2cc1bd54da06376e741149 +608:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f +624:d49acd3a39ebf5002de6a7e435cddbc5df1ee700d41c4f8ae145882f005aa149edbb81506056755bc660208b79ce20927d17f8246689174e22c9e5dc225d86924de4ab1073d6f9762931ecf002c9149d05c715b05d7b56dd0c2d715aef361084073d55b126a9e34390f49cf66fa1deabe9c1191478659be5509462b2bf5c0c6490c4a97aa9343403b5056de209afe24ad277e68bfe19c11e4b99d70bd7f1f0abcdd80ec552392b4e5b385c25e9703c992a340927fe1271dcae11fc44a1060b77bbb42fe8fbe92cee73fb6231e0c66747c5dcd0e407958707745d7a969605c5308ca858641863c8546039bbf78e54178dc3445285f6c4cfa1264ec44e76946b16c7d1fb40370bb7681cc5bd08f1f325517c076b83a0fbc9dd82cc6b4a5fe145df1d206934333f04940bf403f6a0ae6bf2dacd9d240f73d20ae6aa24bf6b8ae918bdaff2615eb6fe2de197420e085ded829a2bcd194043d2c7f4da31acb04a84123ee75cdb611618667b6adcc3677f0c5203cfb9b18d6994e1a3b05b01f97471c374facd2a380c8770f1baeb09a0d9b45ab4e32ded8ae5292c307a8f83352757dbb797c8a7dbac6d2f2c54bf86055e08cc59db82c083d2a4ee16c57127d335dc07a895ceeccc8a8c268873cad5b3b3f9318e5e1b46f1e603596abed2332e79cc8d9835e0d67b9bc9c3192671a812bb80d3d09a95110dd4191bbf76c0eb6665326c753dfa9047dedfb91bf6258e575c0305a46b8f27847f74020fd5cb6306b32f526286d2f69d3c1f7c77071ce622b809ff9706eec156ac3c6b31dc3fc112c6fbfee7e40a86a1bb634dd2f62cf3e7b9885fe6a24db8204e1424bcb996f53ca5a5fb823263e564cc08d0194ef39500c81568 +624:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f +640:34aa7620dd642155a71ef5f64dbb6e226780c86774d9892d7cfc2f11876d05a4e51cf71d01479119ee35ba690debba287a0a8a2a5f984eacf6623db41cc5f8f8028cabbb1377d010effcb8cdfad1a9f583e2b8357760ebe68e4d8727844ff55277713d27e1c98290b4d83cdf71a577de138daec9dbe03fa7637e5a42c39fce6540f921c2248c28cea6787f23fc8046fb6efd9b3a1ffc3fc335f130bc0b4cca337dcd8ba050d8d87bc8da7c0e286503526e46385c85a6c8bd36ea803f3bff5d37dc29dd39429a84c6f35e83a3192db15a3bece1fa7648002ebf8feb5a158859831f10946c94a834ebe3922a71bb424e681a18fbd7feb27cbf889443f6ad1a94a0e48ef3ce6378f123acd41abf79621663a75e5f14dacd0e590fd9cb9f50daff9f9f109959474c9841d9fbfc538947dc98221df050732084f672daf8ae517fc9b59617c5667c946f3837a21a1c60707c8f086d27e856df624bd7972aa9149d2d588dcf4cdb66b78b257387d28985e9e518631aa1b4c9e272eec70ee9b2b58e98983aa14461bb6a468c6976620ff76855570ac7a7894199de1240ebabc8d5dd6aa261bfe09d8bf711f2175977d241e5a32bb99f4486a7e023e5c587eb952ae908bf48125a74ed8a675e801151bef8b226d10cd1cb0981697b67fda8064385b3867232071123128619c05f64fdab86fa6903c2651674fc225855317f7bc47a0018db70dad91b08164bef0a2de82e62d6592b42d8e303aea2974ddacec20efa9cebf99ed23a93582388bb75ea7bb93d2447079b8968644747ab32b3ac10f6445d585eb3011e1dc12fa65863e616c0e44fb36a978852a10e913aba4239ce369ea1358f32130aac17be13af5ccb31e404fbb916a2ca902b6c84c2b7b369747454db4844 +640:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f +656:f7ed0e6e0ef7d5fa1d23f895db539ad14e024902f30d899dd592a64a4a044b191f545c72734b2ecc70a1a752d7e55acb2f28503e3e9e06569faeb1bec2b6e7f4b9064aeaef41bcfa097ba3cc416505dee7e2840128cb1abef3e4106be9add513c3d22646211de6dd6fa7c7e2a40a2ac70b3724d1e5875c59ad004d82c2d3fda06d9f5dada4345d2f945f0a7c3036ba290b4dfed691688140b9af1b82274ba844a3d03b86556b67babd856e6c812a4c2521ce629596f28267e7d3cb7fe30bd1d693927b4c85fd50445a1c4753ecce75035996f38684685211e5b43ea5d32e54c5db286a70c573681d386480a499488502be1f51bf205ab3ffbc61a86765835d748e6e2a81410389ec98eeeb2bcb2c16cd9d3514e542021ed1bd9a41b3775cee0af410c6e3a29db39ab9a8913d7b72ceedee6f06bcd17178974d93a037ff303ac8a58b50787067ace9ed15d12417964230712cf154d881968ace0cec64721370864714739670441fc421185c2fa57a2a0bf9bc43a1e4cb78c0964ae06789af36cca8f7f85364c6d4be28fd7f275050b0e3b88b3a46739cb5ab2bd6d301c03dfae838b3137d085ff8bcdc593b8f790d6c3b56c8c4901ab23e5fe4f5fbe9b6cceb4beb06e8bdf1d6e8df98b6e4b3c96f2555431f1e634e8b7cd7919d489188c792b89b538e4fd8334fa28bd45bfcfa9dd9796ce0849f99b4c1c915f73ec0e0d59859f3100892f9c9f5793e5d0e908546eaaeb8bf4a8629386b1b28eb94d4b03dedff7b101a22f219a989285cd657fcfd3b5eeea8151e31ab11e38bad33bc40e519a8450b5929779aa90fb0c28ffd45df929c962faa2a342c5d6c7170af7213019e92d84758e41a4545dced705a21b6c857e4a2aa6176e21933626f363ac758b566278016e7088741cb3776ebe0530e26fda6 +656:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f +672:c324cc370a3ac69bcd8312a091b00dea07de0b5f3d4335ef68b596926fad005df403820803a80934f87d0ae02bc5ef9c25caf162d5b0638d0ce61b79bc0e0105d3c2df29015dee30fa123be4c5ca9e4ed4f9388bab22e2b7602a7a76206a311d5bb1f609ef60b777227326efe17a648f3b6febe3c64e8160070d5b8f5f81a5820af7b69486051e65779481e7edd4a0326b72d9292bfa5c553384f66c18ac573e848e1e69d9288cb52ab7bba98cadc6be8a71f5cb6ef23baafca64e91e0b451f2fb32479653a4f54e790dd7ba625713a2d3fc8d0c54d2dada99bd4e78e819ea0dab2586fad553dc4d87e8f45c85d1efb0f9d7a8da57184a2daaaad2d174c912e79997269f5e5a1a9c10f644e2280956f4836e8feea9b39557f7a928bbc6641fc61b613afefe04d35feb60fe33d03ed772fda778fa8c6fbc568a3ce516d1d7a731bb4cd3428caaeb2fb72fbd3e320b868dffc0794a0749c7ff42699c07dbc576d6e52105ceb16478683818e6207bbd02b268c45496e7841df2bb49faca2e45aa6cc5f50e8c845fe19faf6e4d79ca84d1437529be69ab32ee97c21e0002426098b9ab6c043f3fca03379d3d047701c43127ffc5d49543435c3c21fc9bcf798dde20b764040061f89293d9f2cf793e6e2afe443b423168a8fa9bc0484bdec7949e6a4be68a7f1afe8e6256b55a49827f18054a3c09dd3bc8c7676e86b1786e04d279ee61faa805d9e574e17d8a0d366f127784cad553fd038e237f6c5e8fb2c94817bb76cf954eb5195ede1ff597690239be6e0f6ceac8107ac4b5c843e4c2edadc7754a55ec64a59c7d88122a8a353bf8b75c56ed1aecb6d3454bc352088ce570bd066afd2402e8da33d4ec1d670a06030165fbd1f25407eee55b554848d0923f77b9a263af75f83b5bf702dc733686d9cdcd977da36d321844ec1e5fbd38c3db11 +672:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f +688:d4f095f98c6f6d5e536668ef67014b1cfaae8410377f67505c1fbac8f1d5a9b08e117348803c9dc1a06faa05527d6c9962611aa80a027ba9ab90f4bda65f4ca70dfc0008b18229b4c7e5b8970feac4f5f0b2012f7acde2dd835dcc94175ed97ca691f66ba1e86e86db2e1b546d24b44166061327e5e872829e1693671c42fead9921bfc9a10eb16dac02ab725ed48b34c153716c897ba91e1d55d53e6954bdcb2653f49a5bdd6f25b2ba109ee0f9ccffdde38e7bb5b6bb23ee4aa062e3148ff5e11fca8a484be29849aafc41dd8d23c6d051f58a998717a96c32aef897f80f5143a8d9140965544926540f6a9f33762a97ace2a127839c193aa643d9e7277854f362e4149b39688af16767f20cb3340df8a61a1c850d1c79d5408762985341fa62f2863ff650cbf1676f6e247987e317691dc8b77647db6d26e9ddd53923508343f1404e16e2e13da4dc1bf51c9c2ad2e604d6843f2a506ab32dc893c9f6e392917d04b4b3f18e7cd0e60d170987a2a479570bdfc4a933579a19daea628e3966df59285775da8ed1ef1c60888c7f65f8ccaa21fe4196d638ff5ab9e0948b2b7d6ecbe98f38a22bf9cfac14d5a277c16b6c4b43999c092d0fcd0b6f4d4bd0b7cbe05d03ddac0e2e8cc70d8627a97e2ffe0f7d7d5e82a1a59fa190bf798531de3c130a92cfe737f3d41ae67ff9040ea86bae64f0035765577326e595d08fa90b6490a8960cf636be26f21cf15f9628554e0c55132274a7acf6cb738ad535e872e591daa602b17c64f296950b2f6978f5edb11063d5d838418e6aa960fd09f713426ac4d522fc3ebe1a440c04de7398e9d787a5209d5720e17946543a0251921d1e61cd51a1b71d83cd40a4b190ff58668a90d264576ee675110e17aadb765d4e8bdea5d6f8bb87d558ceaec33f81facfe0b2cc78b37335b91aa6cb7f4d749302df73ee9e01a936c78b2b1a8a3d2e949b48 +688:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf +704:52aa88885c8189072ed6fba7972b92b32544c1ffae641cd7704987d5661338d5a86f45540abd8fa9b36df2a74ac0e7fde18a9b863e689ac6c50ec81cdea4ff74ebba9b4a5bf401479e3c7b4c444616f1b385e0b335c26b9ec89ef10fa2f5e6e7b13c7c4ef9b88bb9ba10a8715886d6b0e598dd5a2e8b5ab98f6f5a6855bda241beeb0fbf53869254a39c250395b75ee8c6cde6e911f9d110c19759ee93e90f741b4620b008c9c54cbaf10d9cd39855f6493a612e9fdaf8709552c4f36eae6831edba0bbdec5cde5193e0ca24c7afdcd66ec6d3d94ff2fb1d0a9b71da4f0d6638fa924f780b3cd6c271685d23d6018bd7e87a565ac9cfda02c5d0fda60b2c076ffae6aa94f73a58526c6b7e1c08384cb0aa660c6a8b939f7d7ac7ca57b7c18b9be7e496fa0b94771a8918a57a3fa5dc03ca5b3f47b8cd99ce97d9d01c27cd97050602238ec7fac872c1e9b280dd551ae59734ee935f4c1257e067f5de2b6f2ff532cb5f45e228a6a961d2107835874aa307d7d9e495eefc7cc1039745a478a61eff60083689828f225304bc3a22524a6ff3849ef260c84458884c9b011b5660988de0e8ef47ced9cb5ce31b684c22156ca0ec1c60c2b09d487e5672e5a7ba98a1a4c8d0390420190bf2a3d4d5191f164b248297bec98e656742770849e9abc22156a8a214c464ebcdcc0db0a6b77ad29987b6ffa23cf1281a5316c2db1e8a712ace87d6023f1252ccdda51722dbd47b758dd12c44c4c356cd005d42e1a7f1bbfa5b4b57a0fedbbdce6e0ce0fc69d92417aecb8e7d7c593a1d1e74e58273072da7e4bce4f4bd94a03f1dd87d3a7089079ae6caa80a835109d984b19aa30f3e50db4fc91ea93182418ab500a44f521f8ebf7e202388da49472e7442fa407bc6604b8c0954a40f9c543a55a436a2eac98dd454755137602021130a9e13cc5107a9f23fbf9d1d1448a60d09fbaeb7472ff3d227df70964cbbf9bb0a35780cf7917e54 +704:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf +720:17d8ac181eb03a99368dc6cb4a8e3b6ed3b8ebfa2ac6e0f988243b96066031261827c3964295c33a20e45ec4529509e8dfb754c69e5988e7b67a737365980184e935fc8fe51b8e5b9514e2b61283872320e75a43aaf92bb9ac44dc0774068d3be4a1497616d5867321e03ad9e440545b82a48bf5a185701f9683ce291757e398e9f4dec98182493d977dbf57529c88e6c88ba9c92cd6c5af668d9d37c99d85cd11e58dcd6b159dcd1c699c302df95fc9e60b651bed0e571ee6db8e711d0bc7c69e52706be5a181fe213b28c70d2ec92d45056e29ff2314367c1695737e73e75b7be408cb3287cdca8b592f83fb03870ea88343331c3b02f0d91552d673d41c2957be143bd9dae64eed6c71ac8d4a8f627112720b1c5b95c2555bcc4fe8727fdb650f3db80a9c18bb8fdf885efa2cfeb4b56a1f1e78bc670c44fbcf49f84daaa1b9b1c943de2068364674b51a389dced863c8b4950bbf1e706b9d5132319697da0f5714e0380d8d7411e650df78f2e875c2178105f86dd0b7ff49f98bc61115e6231f01954c3c73957d8f26469b9b12232aeec1a592fb1fee638e02c1ac8c795a986734e896e79ebb510d9956e6fdc2421dd304c7fa11db82dc05f053d7fb0b9b77c368379245c2ebc3ff9573548985eead364f65d7737c84444b020b6875b0c845caf9e521500143f732cf13dd493a7fcad33299cec6ef50a088a1ba6aa42b9fa1bcbae6068debf5a0751785ff646bf79454242f784b70b6b36f8c7fa12469faea65dcf2fb8ab7548893c725c139514c0a317dcc6aa76241cb76230e9daeba2853d3aeebd02901038c53c08769abf5d3738750c6f2854071713ea513838d4efdea23f13ce194ab3e3adcb5e66504714ca084198c4fac1ed59e0e112030142aae46f89772a2440555990d659bac5c05c4bd6f7be52de389cb581f7a381759749e103fc184ef880bf6d170beeb5c931ac02ecfa92321013da446d89d6ab564da6d7865cda50677ce5d352ca93bdf702736 +720:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecf +736:7d25eb22236666c1574748f0fd631c8694d573df66e16bde87491efaba83b36d389ff10fedf3a8fe4689d57826f47c5e0eb47119f8f6e61c589602762a6c3a7c3be980b9a271f721483ada30887e5dd6d75d906511b6cf422d41aa7adf1d1254fe299aa5faa1be4b95e63f235e26fe10dcb60a189ae415016c5484989a7d32f51494d9ac28c81822eb2760ea734da2320f083d3c2a708b4a68569073b11e634977b2aaa053b08c4ef1c11bf92d4cd9dac7ecd913bdc4ce70a5c9f0d559cfd98cca12c43c8102a9c89349702c173defef8222b486c2fb63e2b0ea9b1a103550cad8719883f349c9b21c135df1cb84d3f5ece4f153dbb661abaed30574c53eb7922a72737a92d4baba008bdf983a56bd58789242f4176e3c65031dc2a418b32a7ff53f4557cda34583b70710c6feec420938087728f9692c21edf00c6a8cb6487d8f51dede758835cb716b383dbe90fdd90478687b1da45905f0ce5f0cc2765c0737da9810c7ebc698bd2f00d0e905fd86bdf9bac5ac7ce4af90cf87242356fdbf3ba0cf19e82daf21d2261363e8b30187edd9b1339f8f48afc8880f71c06bd59ff7906e2847c5129ac20d2e68622b34eb29657fe949ab4953232efac5eb83efc010aada059a5073d8dad10037fd586ac93dc5417c916073765d7e1eacb3dd076f22809d06dd6b0c90bd776015a8d769ee82e9963c6153030a845131c9ce8f8642dee4fc878c7d727ab3982c8c3394482124a32ff12684991fb2114f7256eb3421273129905abc87de9b27a34009440f8d4537c8e6df11209b7289b84ace6f5d63677fda318c8f55f6535c270bc0a39b9a1d05f459db316415021cd90a476e10a342499b88181c2e5985902f761654380c59cafa90c0ca056c058daada2de18fe6860a4a5bd860bb50b348418f668266d73551d38c771266edf1466dd52989f3551f45e3075d9bbb8c95d8c8bd0f062534bca370c0ddafeb08c51781126b785a176e9410b054f66b584c4da0777970a141598adb1826d6f5038da6f25f013fbfa7 +736:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf +752:0c2ace6d4227b0314c8c9b39c2090541759f40f9d5d0523b25f081436b9982bd8b2fd7db50b6e6e8cf5ed828854f549c6d6f7b768372e73dbf7c834759b0f01d3a1ecfbb6d19b3ace85cb643e7d69a9af7d591608f266cb347298eb3756da5b92188c6d9e1dab31cee666b5dd06b3077a21bbd14479a35701bb5a21f80417a49cf36333b4da1a7a1871424cf6c3b90a0530c9746d75977b585d6a621d08161a3695e56b569184f8bc7b26519505422f220a4f2e20d5b5dafbe24a0811b675d0d5c85e2180ba194490f9ac758006f23886abce9e06d42b8b7519eb2c77f2a0545fd7b36ff0f15544b15ce100ac7a96ccda5b0a9d7b657f93407c86a9c58e08aa9ad13fec40601d9f7c79225ef8b8b4029f4d470d606b3e30acd463dcdb45c50a8b1dca6063d56fdbd05326a75e6a16e8b6fb41c3030b8b0e613694e8b877662a3361c95f0534599fbfc9a623fae8a119e98cb8068a911cca7c4edc105d65b5395d9ec3b75cf73fa4b371e3319f241f060b84c9760403395913abdd74bb75fbe4693232a853ace148248f218e5e0c175ba82196fd26f4c478014ec08e5bc47b599b6f42483668925d7e45eeb59026a2589d76dd2a6bdc23c292162355938f4f7440ff5eba65c946adb900f1dde05a85b0d82a84a2ae9585695cbcce85a88d99c5f4fff8e153d947b973766c9120b5d1fe2d6e3ea9fad4cd732e3aa869d0a721c188fdead76d98d37a4696bd968e23f069506c525f46362acd222e845cf4c0665e6369c4ca0822eb89d3711b070172485d8447d203f80cc82a174945c094f5e9659fc7e3069c8848efebef09dd3495b06d10a659abbb363b78a79bd8bc2de1beecee979d2b3b504a054c66a98393ab0549311337fc121f3728e6e8821be49820755ff578b3763643dd7f3b54b4ba694609017849c0bda642a49e4a85b8eed67cd9daff10c980869d8e1edf95476e79c5475110d16cad3c271b42d4809c658c2a0cbbc5394fc83dc416d255f814301b8711b91605e73b744db9edcb87fc6b14cca8ffe14d00719b00c4f8f53b4e825acd6b9 +752:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeef +768:a96c69c3bf2a4bfe67bc553c6028bb5f42ee4178f87aee7535aada824b72716a40af3bb5bf039f6cee5e4524c424b15dccd1ae02981ab382a6070fc739d8fd5666e097ddf40b0142a9ffcf069445cf50db8c08087d5a78421f526922e7e79bc2a149e585075720c51be341d083e9dcd51aaa6aeb69fb08346e58269cd895ac0bc2fb3291f74a6d71155150b5bbcee52ada0d08fe6e4afd2d7e5bc7c4e18846edf2be939bc46815b68ced4532136bffdd890a83393f75653bd983f1ce52ab699b75d0b7c3293e398c38048e778f42aa988b51fba10b6aa379cc1abd12291eb11a910f927d13b7a74b725c27db8c9f4499f3d3b0d25f2d8738280b73ebb29790ada6e95ff7933a189e34532e3124027e9fccabf23ec6469b425c62ba4e0cd68177c555af0e49bc3d48f4b8c43328b57bdd47cc2c1a87df7764e25d49395c6f353a66b42f41e3bd1bc9f6ba84724990d1978b34d740e0bb84a8dd46edb245259cea37aa1f46cb8fe54802b65c98986fe9dc61a03aec493ecc2b263682d585cbf4162d6a9a7da7660fbe37a2e89cf1d4dac38211cf3cdc0554676e18c1a43e93e90c969da7c1e5265238d55c9cbb1563b07a77535ae14b895c5b020f3bdd7cbea272f79e5a42e23025cb25aef30a7e0cd43d01d93f6dae36c5ccc52d16e9abbbb65928e0eb97d83c184a8e181c9d8430f3d198dc024d757ebca4dd2f011863af893d4b25a434e304f6db5b5d46e193fd83404bd97216c314b9cdf59b68eb3272789472f0e0f077e98fcf53a9979fd08ae339598d57a0e59c0bfb7c6898c042634ee7e32f889eb07f5b17b568c007ba55d05cb33f554bec6f7dfdf165f49b659d3e3af859fcb3024f6610b5db6b176f250e838fe4ba8c21cc5ea2472851853702cba5ba99b17df0a47ae3fa0ecb36099c22df6782f8d45d910ebb2aa701c60af0d55da51659da3bd6054afe5413036532741aeb808932d10a4e5af32ee9b28b6c39a5c91371a58de8c4220f8c65b0458e764dea847b07be78c41610e02588f604733701255b26a5e9ca572c16f32bb92115c078bd76cf270aca1a56b283fb9a67f2f8 +768:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff +784:21278770ac93e98b0d7a4a5a2fc7014e8cebba97b575c45dc3beb9edd7e8a07448639bc285c9e7a98014d2b40c2cd33ac6f14d18ad1ffa5d12dae454527ca8d4a832e27e0c94d6b870f77e3c11cf54bcd8a8e49a2edc6ce8e19bea61c7bb5ef4f75342d3f2dc5e694df575ca778c0246da3669553eb58c7da006e4faa9f58d530da166a051cc4bb1ca70092bc58a07fc0cf668558e28471f6f83bb2667e6b131a4ec76c291a027b7a563dcb373ae1de152c17865e254699f5a88662621cbbfae892309cc2f06eca8c2a6275c7a65277b63266b36a8eaeb31a3b76e0cac01b155eb0e7998c30f3c7cb9556cdf1496108fbc6592c2ef7a3bd57a559ce9d9f8dd30e39e223a8090919c302a6d703600ec053f505178e83af97259a5eff1b222ceacc74ba6ac3e46097bb62cdf8ced6b027c68e60f76c222a6957284912ebcbbdb74585c03e8867bea69de6bdd68566873e743eae0857448b03b191890e791529e4e2149f88130ab912bbeba27ecd75ae44d6554e33bcca80e9161b285329694dd246d0b146d8a8918ef68ba5dd49aea22adea00b4dd0167b9a4a4b5f18fa684bec7c7f628ea7832ee6fea16b20ac303fec7a8df1bb39dd8448d192c19e686f90fbc7493898a801f0f231603592caa5fc5e562b737f82b89de49ee5f2cf7ec5be61ad8b145da0f9dd2fa0e6bc6a0dc17613c48f5e1ca260d35fb9c807e244dda3372d61f0f5988b4f2cdf703fe507cd932ea0d0833481d2bca2dfdbad4ab50efd08e2e63a29eaf1e4155d6bc80f1a665c4237cf40d331ac1d52f29667c9581d5a66b7b6c629956553aed47dde70ef3492be6b4a9728f57469db1d3e830a6719533d757f69b6f400c7f6636ee699f0dc06273d70b40335792aabdf8101952f9eaccd40ded5cb911bd3e55d698b7ae4937a619dbb67c7b02fdf67a97253d0e0e3ab0a9e24bde2046ba82a69b7e1bf32bab2fbbbc2b02680e1c2b08c1099b661f5bdb2ebc58fd39e82c5d4ba199efcd73f8a1843fea9c84c083aee456aa811c9d6072aac9868d61f3bccc40c7b1a3aa470296c4ee7525ff29854484a05485c327186394dcab0a9b6fea8a00bdfc5ad667b85c66 +784:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f +800:09a0113a78cf09a4a7e8ca519b63004d62f50d84c9570e7431e4a9dc1e7f9b2943374fc3a83961efd9b43c6967d9d3655dad2a1edc70b948c3ff10621aa60d6739da0bb75d434f46e251963be90121c802eb02b78560a0fa57eb0f8b7592caf2a91928c874573da9b859c85c3b82b93bd427a2e1a98ea8fd5337da73f456041a01f824bc3d1042f3dcf73f9c8809aedfabcc982087efa1953bc95d3b33a4627695839badb2ef5b70353e1ec2992b07089c747dd4614de1b1f273e8a22a5002b87d7dd2b92f7c9c5fa3b2c33e4e027e6bd93ca5072de8f918bd49ef3a8191030e83f104ddbdcc0e4f98783397c4e1d2c6fe009c4f2b0042e1c16dbdbb35f689dff9e793496ac33f6c96f70740a2bdb18688fd9b9b2865cbd4344c2a54ddc033a83ef3d134d5c8ee785f9697dbe28de6fa034caff78919b32af62e7cae90cb5b709e07a6ca844959fd5e015daed3d8cee560c1dc95dd5a4e1b30c03569fe3d9262078cbc48c294ac0603325bde7cbb9def6a4d828eaaf68059eaa27b50edfe83545fc7d2e008c046b912719fc7d72622fd73b0744ea4e023206f54797e7b36bee14a4f669226349d6cc2b5550f4543bbbe76e43b1746f52cec2cd735723538a34c9ab54db2edd22e6b163a4c5dbe7cea900b6f1cdb8be7ff25d3f18f2eec7929a4dd3d475d6e526c8644430106d02ffeb300d4dbb19f1f806c750f1838663ba70def27ed20f16515308ce942fa1ad2e8516f5df37751339f6a9a5835e8e848c257d25f806c5d5e0562ef2c96a541a8cda5950d107c23fbfd6947d68256fcba0098591b6b57418919c23d0ba37b2368669fe2701c4d58b629be2661b5f27d2b3de75fbd274c2d626350ee6da7861e5d033fd1905da0c1c72ddfebe92af2e6a6c7881f6a98c4b62057478d4173c6ac8d31a50ef01fed21177bea97cbf382bfd0ad1e5fb5b4a931f62dd2948c3a2b94ea5b4ff55e80187ad453c5b8c430494651f09acb764b8c44d47305ee22dc1289377481cdfd2a8664cc764b0982ac2923a485db4e8f7ad35cd08820f5bf854dc5089a077aa92a2f175c3f1771b14102c52bb2720619ffa98ebd94ff15ed62b8d24f9e02dd8b8f454e0d8c74f133df512cdbbae7 +800:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +816:3563439e39e10a74a84b204c7e3aa88695514c2c2b4575058999b0b2acf7221ebc0efafca23fee6dfec9640a6711d1c5fc903c99df596f43c8ddb919116c3a301a8f526d87b94b41c674093527db68aeb63d1705015d4c5f14099e258791ceea5bbd1369ae632cfa42f5c6d85520a5b8e3bf9691ac41bbb7569d44ab7af84eff60f633fc2be1601778ddb4f8481f940ddd8432d1aa898d2841aeea92dd4ae3b83a2e736454a8e779ee7b27778fc80b35a2c23d87e4b9e3db21cd549fb46fd8d37a883d4d210cc4336dd2aba0501db3c7ec53c5fce208b67b236ce3a446c036872ffe4251d455a444c00c62672b100de3e40118115b82ad2c516c30e49ebf2c3e8b16e1ed575e1c6c200c95a1482d89f769f14a2ad11877cadb3cd8d8ac0e26de638295a4d19d900d0ec6f24d97035e61dc8f4a5026269e205ba1b3bde1c431d56de4dfe0dcb979018ebb0e075fc712bf0114e3788a7cdc7ba93ade53a0e08dee265ae8ed1d6345cc2d5fa931c53e14dfcf3bc61c4803b3e86b702cda53efe0f6f0c9c2e1dc6e754736a276dabd46217b98ba1063a7b041d8d2685d9b36fdb441d3a23c60af648ad504e8c00301eda5b65696cde206d549fcd9822745aab3079d116905652052993e28b89e01a53db7ad3ab4756b33a024930a2b8e4fd39dfff919e8a3ff69d1f09453e0e9662b9a86e9956b65cc1e0ad33ebfddf19d13cc9e2aaf8e6d2c416975ab56f6b2e38c3bc00b31643e9062dd18a39888ebacc284ae73b6b9aac6e6b41e4fc4aa2f0a3c8a5c89e40278ec0649187e8a27b6240f8b68b67c84dc085cbdeaaa0e98b18c97785e8924d6b15899496c1079368dfce78b4e1321cb5b223ebf963231dda79a9c3b2c6f4c84c8b8f6420f474eeac754eaddd8c2b403b5ec2ba9bf133da6319e2a9a33813b94db2d4dadce0c2843a32ea06f75fa9e73752c179d8014def50b102e2018f3e46d00373660a2beb7abbc1c73d352d8e163a0f6cfdbbbeb82634bea3992efc2bc402a8383df91f7fb2ff0b7e5b87ba90ae76f920c7028cbd77fbfbcb6feb1cbb8656e0271223034edcc711a37a5e3d0ea3fb4383a5c2654bac15ce4fd97caa0552673a7b7409ed209ea47e13995467573dd8da2245a5d53223cbf3a1645a0de +816:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f +832:5d06971e1b3999c61b8c2ad2f6c69cdc1c07f5dc736daa78838c68127564bc8925ba600e892c04045667448c9be6101dbcc99b28d8fd809d31c2c0f2a0ce9ee430754588703eb7ed65dfd24f316710267885dd6cbace7d6636d3ac7e4d654b7fba954f2b4dc5164f21e6ccc3cffb9f430e3b673a7c64088adc8e841ee3d1d83b475808992588660e8756f438065f9a93b3de2e3ee0a5229df17c830d4c1a1e3d72e829eb8d77fca6b4cabdf16d0dd00862a08d899062b9e201b38dc0f755f08658a85ad83cd5dcfb289cd2ed3e2c5e4f2fc1097d5748e6e5be88df37f58696d69673408b21b8ee1fabbc63332053c206e54209aeff02bf2c7aa39634791c5d44b9ef2fe117dc9835dd0fef1e18dddfb03ba8f1819983fc7bbd9176e663bfe291c0b655b64d6d520901806a44c670e16bdb551bde314212ea306f440cc3c1ae5fe18dff4d58c595fbcf2abee582344f334eaf7c0d06faa39c6ff9219677675c857254644060f3117cdc9e9574c4af13d2b91103f92fe8aa66874680be0e31f52f7df722523068e5120c6061b50a84599c29fa33403c1853e393b7f971cd94633b9808e9b2b487d2f818dab80399d74dc40d6a5a9f9f0ae86e6b3a404010755b6d91b283bf96eddaac4f6cd918d37e13813b1b9d5fc56d9f6c6b704e845e443f2c7ff15197bf3ad8780a53a45dfd434cec61d6fdb148d3001f6d4d1da11b2440cda7cfc4ecb8a4dda37647b638eed69d15292d4af489bc7207fc562627a2bc47f30a1723a19b956a6747bbe5fef13fb83980730599adf1c8c79f3eb8f8bd16f8872e3d011d24967d5b4df53058bf6d850ea352823cad19a0b1e60c0c2430b899530a593d02721b1015cd334356291ac48bb34b840c8eb2eaa8490e31f0fbb40c405cad0a4a7abb1969a4781d45b39ddf470719909cf853ce0854e4ea742bee2434c49c82cbec4f4ffd6d417751acf04c7aa3cf806a33dbfdbd4b622945eb65eaa698e2ed6e648e068bb6ee917d72f7e1f0c50a96b9f139925ecacf07d5823772f79ef5a0bbe3ea5030b48a6d45a96cce9112ca45632c58629dc7765402d180b7ad3b88e72e59398e0256ed406b5ae58fb91d7263064b78667e37f1bae38d4565d90005d29c2dda4d8421f46671a83e6d457f4843b1c3a40468fb92271f1b085629 +832:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +848:7425c506e34c1f7f41351e6a836d712e308fee8e9b07b0ea43fe7c91aff8b9d2ff367a0e7427d06ca131e396ad7d8bee4d92849deb3fbed9d3b4c69553a85b537b10f671fb5bb18e2c0b81cf3d8c42511db6f70cf8339462d19e0f17872ba0264ebf4ca34e87ab2e633e63f88f8fc69be8bed9638f5e8a33b4ff4b50408c5b640505069e862d3f43ef3ed5fc691b9e2076c378c32a3d92668d169aa44be6ad4259601528fbcea5fa5d48fba49f830f6084481b920e9b9c60bfb1d36c92f8bfba1cd03f75d77c1e20af32457d64a148bd0509fc25b9e50739183346a1e7012d9dec8e9f7f83a48a745e483889c20fc88974cb2cfea5a271a3a48155e23d2f27ff0b9cf92df0bfe67af2e0948355206f2a28b6e984a211d6e2d9d4b4dc1dbecceb26cfb8d61bdd439fa7908c8377e75e3ef38caae86b49978d287463d139459da625f80e5f90b4b210095b29ef9eb54744f9c0e1b409d3105b5583c0774af8a1a496559527b0d6181fb539a1ea5799e5e7b36264024983803fa1c22d5f9fb69ddaabe3b86b67f1a1e28ac4f54bce5095c62c34cf44eb9b4c7dace34efbf79bc064fae5cac01a3f2ff0f175aa44b0207b29e4404f058b633f994d6fa2d87302b0454deed9305b9c6a5dca4413deed61b3d0c13c23b69c291a5197842dce0b787361440b9b8f687284cc923fd3c50c1be290927386b757f9aaeb318a878296c95a243affecf5387b6d2bcf7f68f407dcb2b775262acc0460e516d84f3a46fac4f3a2b6f413d57a9e865a01d9cfb1395742d05cd9932169de4ca1d242e6a1cf5c6b230031ceb0a1bfc09fd3520528f11109bed15ff9fb011b13d956b34c06e7ce5f28693f8a4ab93df6f11e6945b56d32bea6ab4754be8c951abf74833c91e362b50efd26a0787b09c5ccd9386d79c7c2c6eb2da20e873108c16a7658f8b765fcdb6480071a0b8624fb0ca5ee081bc2407586aa6bf5b285da6c10070a068e1daed4502fade3ee5aef733fff590d906cb0aee09061fc8033dfbb6f8e52d98223320c17ae6ac86e1ebfac3beb758b80d0818a02d335544c372f70fb7a602668ab163ec0b9ec5d00cf637ed1aa4e6d8e76668d7ca75a418a71f57c90679af483758cbf5940272a901eaf1ca9aa7335c6ccc1399c8d7f829eb7bc9011c9bc71920d5d80efbea91a2f8d94b3389478a81293e7193b +848:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f +864:764b92fd61e99249b6fb085b02c3b204dca2858aac1b419d9ae16dc7e927aa5ba4971a1a4ebbc54236a86f4372043162ddc4b9c35f4ee43a1cba3f090470e80f5dd1aaad578c518da3fa5fec78d464e74b2acde84e5641b1074868356cf1afed14271eaf705ebdb94234e4c9b00b4f88fcb409b2066ec82f954def23a153b95231d03bb4a1c8fde19187b997555026e19542427f757fd7283716bc0e8d0a4e78c8861e7f49733e89d28179508bb5bf1d03d8ccec34225fe5bf26803456f5210b4a009570d5683a83c0f8ff480b4a4f454edcc2cce8abc112fda27595eba8f3a101597dd2c2d53b073816aff654c35de769b6396429bb9a1b4395d08229968e57666832356f43d61b9132d752e9839659d286dd75667eb320e90b0e6352e0834fb7b18c658ca5472ac0909e018f7f4953affd3529154ad883d2e91d56c41ef85ab7a49a49aac116d0051d8e0f4e091ad6f5ac4273e5e56d8dcb3ee0e6e759eb2a7f54d71f20b7d0250056c6eb02b8a05d812f449cf47ed191196156b2e061098205a9eab3fe510c3691b439835dbb62705553f0edd6fe643fb54a273ab3b7bcb37b9a46a6d5b508f0a42679cf11ed4057c87928018d72222b14a38a1d1e1744eb79ba7d7271403b1fe3ee39d76d94665a313f5932795cf66fa08a5b0e61cd6b32648c628ec0ef0079ca74cb84ba96627e349892636f0783976d16e1aeaa21bd20b8b0c642fc73caa1e5d92fa1b412f94ed3e08e21755d608f5e62e38726785daf73306c082a5ac13690a82465babdf8f154f0096736780136856c86c5c63d95172dbac86476275387658e28f612acbf0ac9d44dbb015d339cc05517f5a0c0bc7c7e7748b91df87b6f8d48b8a8921a7d8737da324767390846b70ef4f5aa81a1df8e16c1effbfd8610fd5f815ae42aae521181b716f42a24e601ebb9b95358a77a80ed2e7da8b54ab9359f9f15c9628eec00b38cc2134a671f11ae7bc96da59da73ef278338716dd85a67bbb507b0600f26186dec8c6ab4e5a68b31c0d0501c69a4964644dc0e4f611b603b4accc295c7be7d6372871a5bcc5be78e6f53689c50a20f0cc1b4cade5c3c3f465337fe7ca320eab9f2e6b4fb81897f2fbdd79f2af5641c41f8efb1c6bd7829c2959946a7671ad4e62916378ee220c9356d54205d88d0f32f128bb80824f2f88506c590eb4faf8fcc9cf28afbd391ecce6bc538a5b66 +864:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f +880:29c2f3b2c6bdd1209c76fb6b483a0fea5b269ddce36ca90008cf2cc52cc1e3b382f3fe445523997c1318f50014ce000de365dbaab930c4a8ad0743ba4f8c9fb4540c5ba1296cff579a64b964efd3f62e481944a5c475af35c51394383c80fd5cf37eb969e97f53afcdb4a2914473523a61e8239fd8e441cbb028c23b9a837fd05824972fd9e2cf92876d2dc93641e3500f52be33ca5f646c8013c04a256a71bbb4ca3e4c8ffba6113e34ff2423ee5c623902b47f2a1d8f51bf5f0b33d3c8d948859c9a0787101e126dc8e5e2b5bab6f125605f7b1a3ed85e1484bb6380bb01b44d3b18db78d904fb9f239222926893314d85591c5970f2c287dc78827c3895385c306a6dfe05000f7f01bcabc0e7ea14edf019f20c01f3732e4bebef395834d069582f685157f93e7924fcb0fa4898662fd67144f5b5bd07f8ae60d820a4305151a29e9306762914b579a52ea1b8d6b06e50e039a6b2148dd063c3781db0ce2c0e46f054f41329b57c07e5f571356a29587905be947cea7cb38a1a190a2cdf443514e09fb429a5e8c56a8774ec2344edfebc4aa4088725e7083b9d0908f5b0fbb71876dfd8fa69a0c1ea5cac706c6063c7ec9a2ce986e8ebe5f3cfab9a7bc636666b627d5338d48bae45016c6c98748f852554fff47b0b46f4d2951df9422f839ada5b10aa5c471f359ae1e462a839bad79af26322893533ba119fe5fad16d2cabbbc07210d2cb6eab815a4a74e8aa60332da45a8eeb37916365cf4435aa5b5df3686b299c846bd33412b7f8535e470074a9440702d9f98bf9dfcbaec7c356d8c61077235dfdb66e3493724e93be78c5c114c9e7996733f1c6c618d960b779263c1473b7c0eb6831bdbccccae88a287ab9096f5003a28f9d9026366554177954ab34ac940e33d14e2c61c74628fd617dbb4bd037c5763edfc5243f1c7cd98bed9718e8560c1ede47c5b3201fc47a2ed5507697633fe34bfcb9e40827989378a85f3e4c476f2b1c210cd0940703637ab728614e98f603a46cf5e830ac644c848a5e233349c5d5178c67f51261d1d7ca4aa36e293ef771b61bb81303b4546f1d6c7b84d9e1d47121990c3a7b819d53195b7ece7bc6bb517948cc44778200a7a53b083b1de133e8fbf1e51da9cf49cfbd04773654149bdbd679ed72acab26f301d895b1bd8c045fec96768ba49021fe380ec68ad1d143f26b8d2e873fc8295bba799c953d8b9e0857df2fea790f0d753432 +880:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f +896:b3807844dbb30365e6f40f56e7b1f075d50762f12c64d7a7afdaa7da9b9eb80e90bd263a5977f9ce2fc761627fe447780f59fd6f452c0688f5ace451c9d583111523558b007e17db611961a6956e7d778c74384f427eb54ac2321041e1baa70119c81978a751392b4f49704f14c9fdd7f423b7c0c9b6f8e89c25999d7ef008f5397968e26a769bc172b50974f6988d6d92cf783634c79cf804d59c8e9225a17e7c6fe42179f52239ccb1b865c8d4ed5ec8bd7bd63f8cc1a05d6d652f26841937f794b2c0c8c4903e0b8935b1868363798da983541807debf9996bb6cd5f61974e06953c3b72ec70c6b5c69181e2745033b3d7aabf40d84845aa6a33bdedcd6383f7a19506e65ca18a38777768b1e229a13da5c054a585d1ed83d7a7839b780db663b634132d90fd1c3941f095282c760b21889438acb47ae02b9c2f3058f13186b16cf9c374545c804807ce2ddf590e038633619b50bf2b78a55f6c08483563d267ae84924f8b1b6a94572e782c4f86605446d0650556ec5ffcdcb92b33a9c983b2e4360f9887db8312ff2eface3fd92a2b8bf034bc720ec832252a5eb9d81732ca31a926955ba01e2f28699913a4961a26aceee382e3ca742f1b9fe3f53f71ff12f3bf12d9ee7e0f0de6ee089568da0511562813edaef60f429beb76626814d40854dc91fdf6c27831407113074c1661feed01c7a222c2c468c6f4207f625d0a09e5a4ad07f12388cfce72c4b05ba1d6c07c3c60c7c744509777b7e6feb085a33bad2df5538b4683976d3208be57c217eb5de4a5b5844e4ee877381ebf08f975b47ed1d17ba2c541146802658a14641376c13459764e018d7e6320f52c6cd2c7804d78d1b74e860e134b36628b423bc0ab8e45b7db1cd1f4609ab93878c05ea070cf2d5998cdbb8dbd87f1226b24029b53471f68439601e04b658f4269ffe58b070251b2864298adfc6be0a3df6d1c94ad25ac27aefa0cedd1473e9a3808877e1fa65f6411f82c67f42c94c655f3e2e9215ccb082d171feccc6ea0688d29051d6a80ebd36382131933d5d9f9538c35a489446fc8bb2748dfaf232d51bd4986c3dd5df2427696fde8761c695c12d0d291099e38c7abf0cf2e25fd9523f8dd0ef226d23cf69f23db15e46bbc30cc652ab7140f3ed4caf39d26df35d6628cd39bfd4493d535533a61bfe210dc929e8a6f50db5f0222355ed2ba3f6e945ec86c740648bcef4c9576c327f9cb3ca52612c5b72d8f4b152805e6cbf83593153ea0f0b +896:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f +912:b690948e6fbb6d5065e1f143bd8413a18f1762ae4301c9467f31bb75fc73cad9ef44a6f5d22d9813d068b555bb4949faa007568c86f63663a14df9d36c40e329435ac5baa656796e9b92ba26247a266a9d6cef4618ec1fafb730fdb5e417503a1bd061ccda2f93bcab6c8d0b1e11d9f29781c2ae361774b82b0b097be4a6c0494dfdee31d97591c22422a09418082d1c3689fd8b72828ea1730531665ca7264e75aed3b4f22845cb813bc525d877dfe616278e2041505c8bcc0b3d52bc8ef7335ef655733f263413f5493cd65d233c3f0e276881dcb13b27760b2694375502d9de447501dcbdb380e8fb3d554fa2cc771a38ef927cfd4cc3879e497e86006f4aa3b0e9ba3de6844cbdb0e63e04d83bb124ccbeb91aabb4c6df567ff4c4302a9e8ed13c5932e1c8ab03d3d0d6c6e4715a641e82d15f08de55a818b82c437ac039616499da2c3afc9c50e85e7af23801516961d2f4460ff425b10228c42594e78e05a68f238be3957d15e2ba3a227499ff30564f7c2a11ba00fe05505d0664462e301738f37b59bbb43bf44e3afc41e789211b97005898f8edb18231afc26ef98965df9e38a2306c14b82bd995184bcc1078b36cdcba476980a50252447a4f2a5925e311a2f21067b80b35031d677bf3560d5d5435c1131d0eb9863eedc06095c0ae8a4e6b13e9fefad3a9c9b35bd6adbc4db04ada77e3af55181cb17aff5aef861bd05d7ead1f42554a5bac36cd5b2b89cc10cf2b09072d13e517411235ff0a348894df3dc8d37a1828a5ff5dd31c9d04205ba0cb98a51394359e202dbdfda332185ccced81f451e7a7b79576be0bd5ab571c82c5763fca0ca66527dd9f524c85dd06f522d85de846c111ece570d1072dece75853d72d8d2b76677b53877b9586473795ce9d7b59e612023fd08a163d2897b35480b4f3e2d4daa092daf321031878e5432197133ae6a763e336e570f6e0428ea6a2501aee160b3b9ea2e0caa101927b93edc6dcf92cc38c4688989ede312fba3ae35ccb8056eef57668dd46f2f0ed9ba2d35ad450caa945baf34b8f254a3e0afbc3bdd37869f13745622f30c35f380d62990bb5c40a0dcbf6e13ec0cfb569c2581ee68e16d1cdcadf77a15d166c59b7f154aaaea4bd4287c31f2683013facb53bfc69998d5d35a58c4cd90a3aa3a049e06cc63a6d7181a2c38817be9c4721e346667557bd8d076c1224392d039ae243724dc495fe2ec3f2be06107bb91475f23bdd70b91f86c5f42711509222f29783ff066ea43cfb2933ff327ba83918 +912:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f +928:bc5df364add8c8b84b3cd442f0cc09d2ac092ab25a81c6c57a5a13f62d9fea43c0fbf314d71e05c4eb01158aea19309efb4a5f32de5f311db43f568b6ec9d54383738ce402eb66a16129c4ab14f01ba81bba99ceae83b1e126f89125dbca89be178c23a5a1a8cdb287369321b95986aeec02c74a63fc32d7364e2e49382d440156be2428a3082c14dd482374a8ede2b3756a49725ae7e3148e8cdff15e8f2c8287d3fd7933e88b1c2439c6b8a0147d14c4bcf39a718ce38f2d42108282fe6ff236957fe5396362eb0e0dfd53e25d7b38e14de45ff451f1b56ec05e5d1a74d3aef5f2c0acd4662b5010af266fd653f3d99ea6e0a538655f1709e221392a7c450cdda6adebbd0f13fd3eb85520a7b8b5ed07926a09b763c6075fe6343d2fda48805d9345a3bff442b607e7d1417ef044d82f32e4fc2f8370fc36eee84854c63d4b4869a5b14874f03bad28b1fd9228f2eb648ae562763582dfe198d1a817ba42e2d9e7785cd54cc934045ac9985c9ae3d5b54dc61ffe99646a7f041a5a424ef909d68b1d8c042952f70533d8ae85e677d20554566dff1097d70780da80f5e6061ca27cfed9365c51a2db775be2e145fef14b2cf9bf671110be653f0781ee8d2b77f40e7d52f6928aa6e3f6dbb4462b0707afb354b2d88f1f6e0a9a687c63e2b0275e9309930956e310e37935c8b142af786bfaef99ef4786b0347c2238d8c468a77724b963b9bd04b85766bf358b44835a765ef105a4f71352f00d53aead6b98799c36dba4f73f6ffff880ffeabbb4c7bc97b61d3c8cdb757459f70a800e68980f120c1c5e9c4fd87d6b8d797bf3474744e42d5075a903d7ec24841b6d317d0e266e96b7fe40c1c65e90b65ae6476fbf4db5afa20d930ea00a5ff117766f300497b64edff10fbfcdb2a5b389c6ad4f1a4dc7338b6aab66f3b1c914b64c980572fb858eeb2364001271f7b3d9230faef634455753123766f14bcd0567905a121009dfdd6648b37a4012c5c534fa097f9e5e043a4dc18e924131cba32cbe91beeee1dbe8be95a91e3dbcb3eacdac1c6ae914cf50df6913f8dec3b17b6536df1fcf276b241f8e3ca34ee37f9182ec7beb3965f809780226c19da869a42aeb0ca0f75d6c8e61cc5241b48d1d0896db21ff6dc242604ecb003d6dfd3d04ff9b3ef1262c5c8a39ee525e642577019d69c5c2d0be5872b85fdab68769bc55658a553d1448918124284ee1a32961f0c6e4ef97ad1c19a5f7e75e254f837560b3c25c31c774248d1e48a5f7effcf96abf9774dcec13e732bfbe0a812ce2a4a9b4a08bf80fc0 +928:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f +944:62e7a2ef1ec0ee486b1de8c2d10232ebc0615252f48dc33b7700b64c262849098660a89d87747d7970a029c15fbfc980dc2f780ccf1f3c35283ecdc690412debb3466da444dcc5658b025bbc34fdee1bdd6058064b42ae92fa228f576337e2cb01bd062e5f8a353b027881e5b95aa153128a3a3092a4dcaa6395c59cadfcfc44fcb368c1809cd8f18817c8920e02f18ca7bdd9bd441f4d7a5ba3e3801ca1ab16b16742a77d459055b7fc755e74e525e8d21a1bdc6105c726d5aec9595cbc3b2ec95643739c49678e177165c15a5f7252020e48225bd5b61c0a3021e4811ee6d14a5a3cba357f429d5593a55a58e6b13cb105c9434049b1e86432926efddecfca063e1502ecf33915e00e7e4a03dddfd64ddeec5aeb18a4c6dd054495fe05e0bf83d4d8fddbaf11799fff54fdafd5562d0f0abf1f3bfd67813425b9568c05cb70bae4c1bbd888d3d5d79322127deae89003f857b66d2e623eaa7ca28e75012c669d28a438f1b47d71dc03539f273969017f033cb4037bed293e227fc3d745b26727bffdb313713ad08de751bd9135e8f2e463a1d8b8b8b2ffdb023cc5af4497b0e8dfd19ecb29684a15e5167d9bbc0bcf674a0c9bb454c6e31c81605776af4b640ff35d7a011ed5658df6b7157acd8f87fa505195b5524f3283f4c4e8bffeb7af66cdc233f1af1d9b81c63601eb5863de6d2d7ca892207c20ae6078dd347f9c1464d92f39f55b7a62caa2913bea8e8893f76e92fc1408b4f76412ff5baf04d62766282c23588eae49908c856ed4eece4ede57dca9e745cf4838fd3c7aef6a857a9d9826db5b571928ca1d614467225deb510f4aa24955a00755c64e49d3183715a34f7ab2069e6fa864e5cefcc706633d4543d448ec7a18779cda8e6116bdd4120c0a1f653161adba4c1abca388ae6f40c96d853793e5aef469ca3c57f57f19c09f2eecad6ac0bb687fbb0c71a932fdd80483b85759ba661d3a9747c5131cdfcd7c1b46ab719a0fd2f0a7c1b41fa043177d5187f1cfe9f870a36d7e71f080a286aec0a2c6771e629944551f3692fe91beb59c3fff95470dc42ad077260f0f20912c394e2e04baac2363d3e056d589d763b5963642decd3ff5e345377574e24b87405ca7179e2d6a278089cf89dfe726a3639e4820ba48cf264717343dfa7e0b82a3928fcca98f3e1129837f2bfbd732664583354e71ac115009f3e8a9499694af02edef9d25c95291f206bd931a5d43227e1d0fa1de8ce06f88fc33e70ecbe1b17c5b43a716211f6a26b1fb28a431f3c2ed6b106ada51add23e4eb690a23a91d2db355c880c441390d06a9de6022e499c +944:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf +960:b8616d0a83c9aae9f1ac8ba538c43eae3f5861843787aec8b1189d7c32e072d79fe1f08fe0291740ef058d53e52c08f41cfca7b8d8eed4404a24dab6816003828c083f57152cbcefa411d213211e828efef1669cbec96fbff2f691ae78aebb5ddccf87684cf08d1c243ea7b3c6bac1b11ebe02ff7e1c342e825670ae7b88bcf31c3850f94dc540e6bb9be4ed8fd08113799c539eb97c1342a23448cea9d81a188974d47b6bca7c37dd19b413746f7feb2e49e1f7a61a3e6516b4bd49a2b02a73c27bbcd95b262e57986905eea78a7579b0a01a98269264a5fd2f1297cff5d109c4014c07bb3a98de6ba4490dbaf81ed8c62a6942d7295815f97fac618b3533e8c3d1ffb7f047004ad18cf0278d3d0cc046f67e64914eae29589381ab9b14781c4cf801579d01c5d5472816a6826982d5a626ca4d4404a10bb882b34083b4d2a1be756ded346c2300705c27d517cd2bb607a7e2c2f1b209a3c0ae4dffff1de98f7e64848ad865354919ec5efa517cab15b5f109d2264fe98b019b01665d5e4a73e98afa189699cece78b2ec97925ce99e2a2e195858f7487a199d55eb8ff9a69b11cf958b5d522a23c0bd30e6092e191ca4ae702d21ca3fb0823c57de653a93d7942c7731ae7a530c74fcc18f064f53fa507cc13608625d723ce39bf937a969c68f20c4b8aaba3869e12dfe4fe887d7cdec7d0c6efa9bfa11a949ceea5e16c353ea4f3c834161d3cf991a73d750e32ea75cbf15674a488028c4967569534cf17f587b5cde13d0e39614c46150d48572522fbd1dc4f4e7671b40b9a9c2bffa40084791211dd9e4fda25aa547ca27d6f68569e1cee1333b6fa3ebf7937aa6765a3421a3bfafbb605f95eb5bac77df9530a6a75f87c8463ef1733167316b4339ab8e41d3fd7dd518ae7c28c043fa802924b854ad01e6b2e7166e3f1966bd352943a794b6f4752beb8122103913a0f1a88d2f3cd8a210a54a81b991b3f566b912fc03d133c4fc55537bd0c9095678f7558b400500060f01c179bb9e998361a6c4c140be88070bdad79d40984579cf663db9e5de3d29274f1897d4d576ac3b593343e6d618e0747664429e7c087ce1eeac4e5aab827e24f21ec8a1bea9c0da9c41859ad2b09e9cfbdb88f426c66bb5dcfac33aae44976b8c567fecd0ec0549612d74f1932a571649198c736a602abf02bdf48bdd1fb7677e9aba0dab07b8afa973e1bd50eb9977f6d4779c24ae085ece616dcac3a0c8d6923aed9dc256e48a08dd33369e6bb9d619a3410ca5766b6cacb1cce1fe5dd2119beca4af02889721b0e28b3ce2c14a746a84155cd66408bcdc9d62fc7999eed86d1138aa4bdb5e8639ac2492 +960:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf +976:fe8a924f6b473e4252e8306238646b383cb6cc6adeb6c472314b1c21b0d651e2864e875d4f5c47b9c8b74493b153f6795fd0265e9022f93ed363e9e4439e233f4298d859620eb269663a3094ef87a65b8568e8f646bb7a94a9bfb666c416486492bc14783cc1d32a6def86aacd4fb3e808785f796cdb3c67333d14dc611b043ad8d5dbd9ebad1b18f3f243bc67d4578077872de81f660d01a9a0d289d24d224ee33852ba898da68b74612f7140d3151f6d1dcc4304b1677a46f623589d3a1ccf61434dfc23d0fc2e31cb118ba4d02550b0057a261e736d8cdfac1f33373d2ee932bb6c07d3420f5c1791faab4e61ae17f857d716b93ff583883a834e6d878db98fb9f2abd0b1641a8f3904406d536c480f1c6be78083b745f1d8cb103700911a4c8d5b9b8f5a1dc5dcf5cbb021ed9f035ffba62f2bb1ea524e4fd999aa226980633853ff20b4b7094f3e8fe5913b7bd36259bb531ec1a4a41336a855cd8d8712480b380af3e66f8eae13b964fca9b1e1593ecb904cd6b8e1daff2296c268954bb6baf1211e35280c3d0115374055e0dda8a48486f45d1236c04d3e3d24f4aed948bd5467df2468929840ba0af1487e96f8883846fb02a6a20cdb3ffdd280a534c0f4d88743694b8abd71b24ad4dcb7ca7563f01971815b785b4d29c91994776b8a4fac9da0f9fc76488d8016bcb77d927125bd86f2127b85dbae52b0712358908a75f545c83ef81ce34a5f931504ab75b0d1aa12814f176ecec759e9cc8e21b2e92a3e2e6fcca56f8e0c6423e1a93e4c856316d7a6a2cb9ac4400538cecaa9ac7868ce99de9a50dc7b5bb7707c959ab0291708e83395bd142225261ea222b9ef58614f5208848dee2c97baa86ab3e390658803e0483968d6f2a067fbaeba311983066b9032f99cdbfb4d767729bf7d9148345724462fb868297e6b325f289f00bc151110f89d5ea758e9484eb26ba3eaeab7156308740ac499414b5d75d07fdec78843ba261a8c58d03609668fbf55d4ad2eed5b0ea4eca805d633541bcd6e93020003c6ad2cf360b03c71c32673cb34130f7634f8eaa459fa8bcb56f4476738b49aa9c7569672f0a7e58874e8d2b78373150faea04648c08873afd27530b04f9882f9921306fddea77a186605390f40de81efe5cdb48d6a25efbac6f6badfe7e2a7eea7d204151febdad5687c228f22ca4fed8b456cd5a7eeadb750ff29cff75016d8e5a439b735aa9586244300f6f78164b10f27cf311e46ce86e4a387ccf72e277ec6eff71ea62e783bbdf20a4f234d54c0e3d8c24d1fc3c9f27bb5c160d92cfd4b5e789a0f54335f7b16b7226877ff142e7a396f087422c41ea1424c7b89f7b05ac5f16b15ebf37ae8718b511b72 +976:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecf +992:af755a7fd216598bcfec0d1398921f87ad8f9a4aa4418a5bfccf00bc9a710a0669ea2cb17cae99ad9a87b731236847bd642a3598c7e590e0135d0aae144d288fa1426ab6c50bbe70a27b72c793dcfddd118373e22ae8f680b0e8b10a3cda8a334a0faa389f56b7807c05d6cefa9560b0467c1ad10d29f83a5c07d6c69e8917a4aa4520cf42c7156ccf114781ee80bf2f1558fd9efdc9f9ef369b219ca8106408d24b6bbf851816e8e0c989615fb2d4c0854072ab3758ffa22c69185d5ff6920cb62fbf786b054353940081a55fd81979b73f5808a9cd29b8d3e4c75a622561375e95d50c2ffd61bc967b1295c70d8c8163c80cea6d6982f9a72db09495414a99247b24bbb64511ddaddb8fae455816d7c12880442001e8d0588180ed69a9a84e975b93659389c986653e8bbee4332b748ee40d8e1b556d05da8a3aa1348972036fb2657f29d044ca0ed4d8ea4030a1b23d0e973958806d8dc806430deabb64d5bd75dbcf2641a6d2ce92f297a8598c7aab436c1485074f244b609aca470151e8f3d54102f0d4290ba5b7722758a363c873fbc88e43afb2437f79ebd38990f72238bb865261bd434f9da58c0a54048494f0746b9690a69510361a02d934b14ff0589353828d375741236f1b45497d8afc1b479779e4f724edae20e2609764fb9613305d370f16afe452be289f595941981b451b4180c7b4b65843c2d99a75e4332f1ab83f8ef22827f94c6ecff6b3ec136033d4839e3518e1f76d734910556bccc0394bf619e209d92275862ebcc19d8be4a68ba52b6ef05db9ce497853bdb31764a351d2d6b91e0f1680b84d154e7f3404b97a0e9643188e27268e73f0740e9ac3c4461c9be061970a7b4a77db5bab38450b4fd0af274fa8c4283b2e95776c63d023991c8b02da1aff122eb9e661bcb1239d67e516500ce626e2000ef9767e75843c5e90679beee9aac3328defc89dcc5da2b7dbb76ab1dd6d84ac22f7e05d9e515b827824482c115d7180cc1b9378fe0eafbe34b545fa52b3fb9a9bdce1e41a80b2f911747f6bdb279b140cf12507fd33ef9eadcafc7ea5dc107a3ff6745a30c12d8ded824580aaa274e49495f017435979940c3a0035be77f29e099f44e1ee82b00a13729b2b90addc549d6799c388630ce7c42691b888380ccdf5cf7a701ccdc3f3422a677dc7f7891140c7fbb5093626349066a7720a4c696ec590fb74a5ca7f6b6774811af33eed78198d5b8de2371a9aa768b789cc0ca1c381cf4b70104204fba70b140a87e6093f15b02625c7b90ac215c3b318c2efc85c5e9baa06b52e426e2d3207b638f28af2814d8bc6dd29204e1d45823e6bca114acc39bae9293bb4b292bdddc457502b6dca9a7a80ba45f528a2234a166924d62b09cbbab14f +992:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf +1008:425b0a3543b047574d63f3513c2fc330437067ea9e14c24487e0fed0a5e5ca8c1e92d8c5015e4d25fb6bb9e7a16b6f0fd54782f84499ea944ef01b05053c004c730c5e229523bd7e017dabb49487f4aa6d93e580d7d5d6f05316f39a2f3fbaed95b615a83b39a4106dbf127e9d1a134cd65780cd9507723e876ff82a63d96c16a50ec0412f977b038e0efae2fcc1203da3ea4feb029a5be2bfd502e58d1f753fefd49bd3c67ed0d79d99618efbafadef0b47327803ea099247f8fb17f7ac8cc7ca37a32f5d1ee27f637db36d3c171af5549f554b4b9422f8bfad644ef9dbd47fc868ce4ba9342888ebc8c69728902565f1b520528fc73dc2bcd7d516d0a4ff9eee95069f487c810efc38bda54933f41ef69b3a39f28a19afaf758a5abf173f7544dea90596ac9eaf6194f26f444ad6f0feaf9c6cf1827a35eab9e4a44f7bcfa085dafd83f5a2ff66b73f58e7415d906312749427ac5625bc70f7b58dc78f2b0153c83f2d2503d670b9da82df1ae7ff567f80464f1a7a7ffc2e69ccbd507fdce91714691582800a07694969536d86f1acaa4bf4517fcfb631f08732a9234e17154ad807d0308aca397fdb648dc49164cfaec222f6a911c4deefa790738aaa7a5c94f1668441c20bfbf7e1a72f9f45b7e62e87214194c9b4e9a4e68702f91d797076c9268dff2fb1bd84b4bfab3af92bc7fbf21610be8819bdee42cb40515676c4d82561a41d930b34790a6f744d05c599256bbc94adeca9be462ee24fce633eac239ff0d1423a51c475f4a51ca51c570293988113c64b921b7496e5a9f0013578bb206819574ee4fc80067ce33df536a8a7fb6b54b16b719c547257cfabeed00c18eb120e019c09e7d275feae4076a1957035e05f9649dd93bec3e56a9aabdaebbe9bc53af637004f35f029e75b44a40989885c7913574fbe040ba059524044f00da3f29d0f6eab71b8508c5693a8401fd0bd0d4312d018b9b26cd2633ee477585affb5a2be73f156285bd93905a227f6794138e18ecc0fedc9814ba806c0bb2087653e02295aa13807908d968d6966c7ec21c936c877b8ba6a76f2dc367dd1b538c0045d211ea81d286a8afa147eabea42802fe01891012a1766551abcdbffdab8191b630c6a98ba91cd9dee647091838cf31454fa7c877418fb10b19ef905408c47ba1115394fbd5af5ce362b1f888124043a5fd3fc78a041fd7240396d61d2fe3fceea37488065b23d9b7745cc46b1769aad936ded16a4fb73b982d24959ea0ec38f6d0673b1e4272f0da01512cca7d2e14bf2481c5fcb37cbae35a95fa417b18b1173413a0d6ca1e548bcdc09b070656b98b0d6a05fac98c986ccad9c6bbd17881412adcef7d041550c753f26320a6e296ac0059ba1b91015bce4a73a7749a3dc02efab9668503d20f492d78be481 +1008:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeef diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/notes/ocb_tv.txt b/xmhf-64/xmhf/third-party/libtomcrypt/notes/ocb_tv.txt new file mode 100644 index 0000000000..6429228f96 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/notes/ocb_tv.txt @@ -0,0 +1,461 @@ +OCB Test Vectors. Uses the 00010203...NN-1 pattern for nonce/plaintext/key. The outputs +are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous +step repeated sufficiently. The nonce is fixed throughout. + +OCB-aes (16 byte key) + 0: , 04ADA45E947BC5B6E00F4C8B8053902D + 1: 07, 987354C062CD6251CAA6D93280EFE9BE + 2: 1CB7, B9F1620EA8374E1C2D05110878D93069 + 3: B98C59, 3793FB737C2DFB29E73DD1AD8B8F71C7 + 4: 8978F240, 5E25316ED13D3300F2EC12D718A0BA8E + 5: CB4D261594, EDA252A1A5C7D0A4AB4620F771446DD3 + 6: 30D6B6688D59, 684037DE07832C6FC38CA42BDF2A7D53 + 7: D0583F9741BFA4, 3DF53DFF73431C0245982F4EEEAD432F + 8: EE3B9596CBEFF520, D283D1B9D990739EA05F4BAE2E96BE4E + 9: 6570FC25E6103AC125, 90D3F1FA6595B775749FAE7B00A8E5B1 + 10: F56750C98C370DFDC4A0, 19389A6875FAB432B72D64BCDD6BD26C + 11: 3344AE6D9528603CC1E4E1, 87AB6FBC7F919125A7DB0D17D19056B8 + 12: F3D9D816A727D3E67330C779, 07AC0F3841DFCFEC58A5AAC22270538C + 13: 976651E63ABC3B276799BC1FE4, EE603A8C66099AD6FF8667B3F34ABF29 + 14: A48E3ABC31336C6B717A96170A9B, A9D1B973D84D3125F5F9D7923BA0A8FF + 15: F60E9B2A911FAFB0080FAA3ECDEE42, 4902F8AEB7685F7B255ECC45B5B7D3D4 + 16: 0855DE488940144AF18C65A9966DDB66, A66B3E7A75D394273AC196FFD062F9DD + 17: 172DC1740F75AB2A27B2B80895961A69AB, D6986BB95F7E4137430CAC67F773623B + 18: A414234DCCC61B65A79B7C618A6B91ACA410, 6CE32E55E158BC3E51E94116A615F3A2 + 19: 16A1B16BC0F63D63179901F1CBC772D612C102, 54007EF9822E0E4A4F953838577C76FA + 20: 539788EBF85C15B3A638017B4054D71315BFF25F, 9B2511322E16CECD53E3241F3D51EB97 + 21: 7E74595A3DCFE1EA2C91B67738765463D50A22924A, AC9C9B526251C16F112E769F9FBE74E4 + 22: A2B61792102B2E44F1DC0E48B40472CE883730504FEB, 76452A49C2524404C8A4B098D6390F98 + 23: F58174BC06A022AB7D81991E9346F5E4B0AEC535D93473, 47F96374BC094BB2C1A5D1D291806912 + 24: A3A7713895D178A85D9092EA6138323DC2FF9090D7F01AC5, 3814208FA7009A2934F9A172D029667D + 25: 385525DAF9949DCDEB22F7518AF96438E40F7D94933706A9F2, 1249F3DF50084A6D1A76AA350FD85B0B + 26: 6838E207D98A5BF8D8E41454CF51663D8F8B76FD26092D45D1D9, 301723D0F49BF8CF37828340B894689C + 27: 736413C025A549CB2550E93139DFD5DC3CE241C296C9FE641FF520, BE07259963F251743A85DF51EB1B47FB + 28: 7F2CD26367A885BD9E2B515D4E871272AC1BEA1C650B530E5616B2D3, EEB37E8451597E5A53CB49072EDA9346 + 29: 68F23DCDEF223B60B46E3D724A93BEEF8B110D4394C990AC3D0E34E1B6, 9A60344982F852EFE02CBE9CBBAB60F1 + 30: 66C5DE3EB27139983D48BED81D0E5FCE6BA1AB402C357062FE989D31C69C, BAFA0A7997A529039F0CE8528E670415 + 31: D3B9009C1A930EE288C61B0B15C7E92CB73484C345594DC5A3F377147981DB, 1EDAACF7F1F3AC7EA613F94DA4DEF930 + 32: F7818DF15FE6FBC42A28FDE1D55A2C07EC8D82AA0E7A680DBD3CF26C13448F9B, 67FEB344108008A88067E92B210766D5 + +OCB-blowfish (8 byte key) + 0: , 07B7752047F9E0AE + 1: CE, 7D69017C42B06204 + 2: 1D6F, 4DFD4BD58439062F + 3: 30A011, DB49D988798F8842 + 4: B71C8951, AA3261584B0C20FD + 5: 06F89957DA, 88BFA80D36427F64 + 6: 45BC4CE5FABD, 4CAF71136ED166A7 + 7: A7405F124D0296, 5D8993CE64FFF0E7 + 8: ECABEFD9E6574E4D, B69349673CF86E41 + 9: F7D26A7E82A34ACC71, AFFDEE843ABEA68A + 10: E225C5F0FA1D649F81A3, 03AC1D5DF1323EF8 + 11: 58722FBFB86C2697061217, CE731D80E6355710 + 12: E577EB8FA70225C5A18D31DC, 2F08B140F0D3A255 + 13: 92154A94CD7D42EBADB6CFEE14, DC949170E84D3CA2 + 14: 5A3C08744FD85CA262D51AC6CD25, E83CE45547403BAD + 15: 8B2E4980ABA10A20573A402D89AD12, E3D978611DD831D0 + 16: 3EDC4A0FA95BD8F944BCE4F252B6470C, 87B54BBEA86A5B5C + +OCB-xtea (16 byte key) + 0: , 56722ECFE6ED1300 + 1: CA, DF53479333DB86AA + 2: 9529, D0B5A859106FCC9B + 3: DDBAB2, 3B31FFDA57CF51C8 + 4: 22EB7DD4, 2BB34D04FFF810CB + 5: 108693761A, 7AFF6F52574A019A + 6: 391FB7C61E76, 616C5E66297F2CCE + 7: 3E22E4A4A0BD13, E84C385ABE25C8D8 + 8: 94FA11D5243EE34F, 8F017DE96049D0F9 + 9: DADB6B5D27049240A7, CA69E14047C6BBA7 + 10: F79C8EA83C69DE914DAC, 1EF042DA68106C64 + 11: C5B6E04AB8B9491E6A99F8, 143515779A55C972 + 12: 33F493AB7AE62DADA38C5B24, 531BF7799A778620 + 13: 6DAA66BF02E66DF8C0B6C1CC24, 6CDF72786C5EC761 + 14: 4940E22F083A0F3EC01B3D468928, 185EE9CD2D7521AB + 15: 5D100BF55708147A9537C7DB6E42A6, 78984C682124E904 + 16: 744033532DDB372BA4AFADEA1959251E, 438EB9F6B939844C + +OCB-rc5 (8 byte key) + 0: , E7462C3C0C95A73E + 1: C5, 83CB00E780937259 + 2: 1533, 022FF70566E0BA87 + 3: 57543B, AC4EF15FC83BDF2D + 4: 01E4474B, BD817C06AC2141E0 + 5: 4CD7E850EE, 7BB6B3BDA5373422 + 6: 489C0CD1502A, 23DD4406F87EB164 + 7: 0CBAAE08E07EFF, 92569C958B722413 + 8: 073612F283F8A6E4, 1DD978D01CE8D1DF + 9: CDE676B1A3AC98B00E, C033F099E2620668 + 10: AD3BC88EEEDA40A83685, 36DA44E13C0C8A4D + 11: CA60E8B918F73E99986021, 45634CA0E43E4B13 + 12: 3B3CF82157ECEACAD8658EF5, E681F57616146CC7 + 13: EBC1A7068346EC1B7EB815A7DC, 2C806D2A909CCAF1 + 14: 97CDB3EF8276F1E7D6B6677DA2DB, 53F00B9A2E43DE08 + 15: 44169B3EDAD9506C51A6DA055EF9C2, 5BB6DD996130896B + 16: 35EC29065B1FC640015B0F779E7A358A, 867EBD0E86823F09 + +OCB-rc6 (16 byte key) + 0: , 27B9E3F544B8F567EEBF98ED5FD55C76 + 1: 92, 219FD2D74D7E3F21AA6C2A507C0A546B + 2: BECF, 96A656A16FB3C4579E6955D592AECAE1 + 3: 4DDE09, 7D1882879B5D6FD8C151502BD8AB220A + 4: 0D6B4FCC, E01FBD1ECA2A6A8DC6697A06AB12BDB0 + 5: E5E19C973B, E5A86AADF2F333D5DEDCE410688CC6A4 + 6: 90BA7D2A6965, 80523A2CAB2A7BB2E90B121DE80F46A9 + 7: 6FE258148EC8D0, B7254B11276A77C5F99FE5EC91D81F57 + 8: D887080095DF8817, F3FB938068A01EF89DE0F1226C544362 + 9: D9823313289D597614, A547764EF20BD4B4B303882B64FAF2C5 + 10: FF68942112CF01701E86, 94F3860D4438428EE296CEACB3EB67F5 + 11: FFD390D3E0B64F64D3192F, 99D2E424C67EBACCD4E2EB9A0CDB8CDD + 12: 3162235748BDDECC84FC8C94, BDD400A58AF59100A731DD5B4386444E + 13: D2A0EC8B1F20672289F7236C56, B245CF42644BDAC5F077143AF2A57BA7 + 14: 830929B2850E22F6C1BA2027248C, B6B522F7D6BA3CFFA92D093B383542FE + 15: 2A5FCCCCF43F845AA77750D3BC6B1E, 53A0A0882C7844636900509921661FCA + 16: 8480234796F9EAC313140CE014B0265C, 0656CA8D851B53FD5C1AAC303B264E43 + 17: F011A67C22F16A42CEA5E493CB766964AA, 830B8158B7A96224A53FB7F3A08CD128 + 18: F76274A730A608C2AB37497A049C3699882E, 4DC4DD4DF39D0E68D6169F9DC7F4A6D5 + 19: 7B38DD237DE552A72E4369A81C30AFEA5E5063, 01A62CBD30153702A5B29FB2A1683899 + 20: 58EB866F1FCB060ACC821D776AAC4AD9E87C326A, 25AFB8FC48605E1396EA8471F55C1294 + 21: A25F2C0FAD66B3580627498EC66C994B49C5445911, 0182A951D9A3DA53675612DE8EED1FB9 + 22: 8813977F092F07F251A1497C898967F3F98F5CB878CB, 80BC353E310880A83DD4DE4FE96AB6F0 + 23: 52DC8B76F5A6F78D51FB7DB51048E2663563335EC876A5, DC3689AA079C04C19D83646B272F9DEC + 24: 965437D3FDF91784B63C73C8CD001BD9372167963DF36B89, 9FF84E2845E3C1E3E6711D1646B18F21 + 25: ADD40F674BD56FFC8F9B4047FAAD2471F0A48F4544C894F806, 9D684F74F9734F1C497E33D96A27E00C + 26: 7B049B688839BC62785082397DEC7AA94B837D094AECA4B14571, EE711DF1C15B5C9E36B6E38B6F7152D2 + 27: DD4681F9C498A3CF69A9AC876E02BD9CDC4FB1F6798F772013B62D, C5A50676EFAA2A56CBDBE55CFED3050D + 28: 471B5E89A1337E75E88AFBAACA1C011790F1657425483229E55C34EE, 20F73F2AC452FFEA423BE2EBDF33CFA1 + 29: 71812C83DE34DB329C8DCD98890AFB1F7719E890DAE5CEB7AC9668CAD0, 6FAA03E10C6FB67D425C683C6D85FD76 + 30: 4BC2DB33786CFD29B5CA5B804454169906138E90E29E7BE9197971027AF7, 75053C433EF5572A70C58EEC96F56C53 + 31: 5E3A0AB41264AB65365458ED3B7E6A25827E50075A9E347F1622ED0723E229, C8F1ECD19AD5FC970CF0D31BF46B0F2B + 32: 2E48DEE4B379CD59F5367D17DC397C1BFD53B8C4CE46A8202518614076174EB6, EFCE758ECCB6BE875D16B7E03A498D31 + +OCB-safer+ (16 byte key) + 0: , 88618DEF98FE588E23107E9A5D89C26B + 1: 39, 2B01B202E751F957E331ECD1CEDE3456 + 2: 13CB, 17071E5AFD5D8CE953A73F49412BE8C4 + 3: DC4428, 4B0B1881C2540FF92E7DE63C479A7750 + 4: 120382B0, 0BB11D57B5BD9D846CF31033CD4CCB92 + 5: 97F332F95B, 335E0424D0A820F60DBB968B8B5AA057 + 6: 3C7AAE72037B, C8034C2C76C1CCD7C1B3F36DD8907E1D + 7: 8A99E4A1B89B6D, 06A8165DFADF1EA5ABD89E574422DF7F + 8: 676587065F0342B8, 93ADE63994DF2189079234DC204BF92B + 9: 8EC394CBC6877B245A, 1A89F0AB0B44BC708EBD9DE489E2EEB8 + 10: 5FB5366E5CAE4DB72411, 5CA5881A5805D53ACA4904A5EEC01550 + 11: 72A1994028F09ED6A4E45C, 0FFC0052996CE45DF4A28F7A6E9CFEA6 + 12: 1D5EF20F52A9B72386D1A601, A697DF1179628DE1120D5E8D9F39DA6E + 13: 79BD002AA59D74F125AD9E32DE, 2F02CB6F70BF57BBA0DF100DE503F633 + 14: 442C6F9016DF4C090056258756A9, 58C6FD3180B9B74459D70B5684BE3F4C + 15: 4FC5543D9A892B44ED04EE8B25E232, B8B858B3D3EB4B26E867E429F88A56B4 + 16: F06E7503167C2210AB332259BAFD6AB4, 73CE2589D1DF34CA3DC2B14CC9FA6276 + 17: BCCC260BD4823B64090FB33E6816F9C330, 81ABBDC83B2544907840FEB5AF4479EC + 18: 450C1105B76F960D1A5F33D7F9D37DAE20C3, C41DDC8980E88E3986D9C84857BBE1E7 + 19: C9F36EF3A990E0554EDB59E6788F8E9BF1DBC7, 90DD543E148D9A0B79A8B376C5509E09 + 20: 3666FEEA98A4FC434EDB7517E7FCEE2320C69BCB, 99F11B360DDB3A15C42110831CCBF21C + 21: 126F39C19D1E0B87F1180F6589A75712B66209E2CE, B4D268FB8EF5C048CA9A35337D57828A + 22: C1B6D14EE8B6D0A653BFCC295D5F94E6BCA09E181D8A, 4B4883B614D5CC412B53ED4203EA93B7 + 23: D1F2A10F1A9DAB738C61CD0EF66FE5F6D1DA95DC671128, 3F1EFDA55EFEF1A0B24708E132BC4D25 + 24: 9D457216C584F43DBA1DD55C54822A8B6A86D22DBFFA14D4, 53402970B128E98A5F0D62476A38F959 + 25: 012828614B5D67C9A1EE24A1EBCD322FE9C8BE0C3F20A53714, 2BFF288D90DBDC638084F80F3F7AADF3 + 26: B1904AECF599F6C74557475E409E75E646271DEDEC7A830260DB, BF119BDBDA27773E038B7067D2B0EECD + 27: ED831771C4346FC19435354AE29F7A9436D6E8D4D42CFF26207DBD, C3F029FC8AE690E84FBD0EF806B801F3 + 28: E051B958601223FECEADF932A277BCF18C25025AE4DA791155B85035, EB75E56BE7856F1B5ED3D125C092D38A + 29: AB3449537C5E22125BC32D483F74C3A3DBDBD5232839A85D300F65B4FD, 851B0FBABD080F783BDE4F47ADCD6D76 + 30: 4E68550837130652795A8C9D68530717D2B0AA5A17F3AEF92FFB502E46AC, 10E222706527A64E757EDE4B9EFC09DD + 31: C2D7033DA7A1857D79497EA6C64779EB969046CCEE6C74E6592FEE6E7C94C4, 2015674ECA80AC9B67AE854E18A7D56E + 32: 2F3F0374DDC24AE21F02D4DA74D46C71F0CD2269A68F32F7FAA0BAB64AA8E9BC, 737C8BA1677A8CE97D42FBB07530EE99 + +OCB-twofish (16 byte key) + 0: , 2CD8EF22E5457C7FE4016B0FB82FD204 + 1: 64, EB7BB60E4932C0E97A7A5906BD044ACF + 2: 3A59, E3D2024241666369BB542ED096F20C71 + 3: 67C038, 7E6F1EB3F2088F6416BB675DCAC0D484 + 4: BB36BF02, BDEEEF07EBB7A50A5201C8A2D72C0036 + 5: 6F06C0E293, C63557681D84ACCFFBFEE87D82EF1D3C + 6: 2015F94CC5AA, EF1DEAD4134D2A1A47A20F26FAA3554D + 7: A5F8CDD07964B0, 672B74D88C8AA7567C6AC4A896E0F6D1 + 8: 5EFC9D8C3B9E7F3F, DB9160C53AD429D4C22BC0E2E6C509C5 + 9: B62CB80F75594BC54F, 20020A798FF59F0472E750C796B5CC94 + 10: 970983B0F889760EEEF0, 360AE43CEBCC27755548D4984CEEA10C + 11: 75C3A8CCB30A94CD57D1F8, 79820F3B1625E216B5BC1D1A22B198F9 + 12: 033DA41CCBFE3C6897230FCE, CFE3EDD11627270CD63916508B058B7A + 13: 15358032F30043A66F49D3F76A, 98B8056A7991D5EF498E7C09DAC7B25D + 14: 71FBA7D6C2C8DC4A0E2773766F26, 22BA0ECEF19532554335D8F1A1C7DEFC + 15: BD761CD92C6F9FB651B38555CDFDC7, 8E3C7E1D8C4702B85C6FCD04184739E4 + 16: EB6D310E2B7F84C24872EC48BFAA6BD7, 12DE548D982A122716CEDF5B5D2176D9 + 17: 8DDF6CE25A67B409D3FB42A25C3AA7A842, 3E9FA2C6C65341A8E1101C15E1BBD936 + 18: 5563DFC29B750FBC647E427C5480B65846DB, 90881C6820901BD41F7B3C2DF529B8A9 + 19: 93343C1E9624321C2A0A155BA8B4E66FD92BE2, 71A641DDCD49825E10880D54BEF30E91 + 20: C256BCA0CF0ACCEEC1AA4B9372AF27D2C3C65AFC, 91D45C4DA49BBAD1809A11F4041C7D09 + 21: 3DE69FDB72C93518A3E317F7B26C425EE3DD42DA7E, 85E37B3E8EC3AF476DB7819D739D07D5 + 22: 676AC7885C7C8FBE9862242FCCC46C181440EE49AE59, BCDB42B53AC4FDDF9C3BF8849AB96EEC + 23: D71B98B88F46CC47D90BB931564CDF0157F0ABCB5E6954, 289CD5799D9E49F36D70F67726A59610 + 24: 669C16DB9DC175200C08476832155DAA52F1F8969DF3B79A, 835B210EBBE5C9D34C2E052E1843C1F8 + 25: 2F39346E14A34BBED0491929CD9F1FB3CEC412C25AB703372A, DC4B42E8BA676BA100B87BEE328C5229 + 26: 1FD0F8BD0AC95E91881635EB0CF0E4FB099CBB214CE556422E2D, 898CEB3CA8FCA565CE5B01EF932FD391 + 27: 7FBD32B3D88B7E002BA6055585B5D0E1CC648315A81CFECA363CC8, 804820B1E3813D244164F778B9C2A8C8 + 28: 877A5F336A1D33AB94751A33E285C21666F0D8F103AC1187FC205372, AF9F0AC165EAFCEE8C2A831608F166B4 + 29: ECCA297705B0395E71B9E4263343D486B29207DA188C2F1BA626EDBF46, A05DC873406B236E4DDBC038DC4D2627 + 30: FF3BD8D4E1108E98FBAE2E28BC12819CD7956BC491C0B3A291FBEE739599, 68DFE58473BA2818A23095D1D6EC065C + 31: F175230606040ADACEBAFE4D58BBD140B2D45E8BF7E5C904510B58E4B53D3F, DAF579E1A12481D39F4DCFB7C28794B1 + 32: 261388D491EF1CB92C261FD9B91CAD5B95440DE0A747144EB8697699F600801D, 749056EBEAF4F20CD8746AA8C8846C47 + +OCB-safer-k64 (8 byte key) + 0: , 0EDD2A1AB692AA7A + 1: 3E, 306F814F3C2C109E + 2: 0593, 063D19B734C34715 + 3: CA72C6, DF6DAAFAD91BE697 + 4: 08924AEE, 15095FA49E789483 + 5: 359908A6CD, 16CB7F0741BA4091 + 6: 97F3BD820CF4, A59DB15B67B95EE8 + 7: 0A267201AC039E, B4FFC31DBCD8284A + 8: 9F6ACD9705C9ECC5, 6B41A938F0B1CAEB + 9: F355D5A937DD1582C2, 9D1F932E521CB955 + 10: ED39758CAF89E7932E48, 398EF517015F118F + 11: D8ACF19363A0E0ADC9321B, F98B2A30217766AA + 12: F8F54A8202B0F281ED610F33, 36EF7FA4A20E04B7 + 13: 0F8677DF64B5982DB6E2299140, 4DED2DA806834C81 + 14: 0C357A9DC321C93B3872881503B0, 7814D1C0C6A8900A + 15: 10B6B1A261C3015A18110AD200A7B6, 9A814D6D2BAD850C + 16: AA9EA9D1BA7818C0D2EBF23781A5467D, 236A24FC98826702 + +OCB-safer-sk64 (8 byte key) + 0: , 76F16BDCE55B3E23 + 1: 63, F34B0B471F6F8F75 + 2: 8651, D7EFE17943D35193 + 3: D45504, 263224E50E7E9E75 + 4: 57B414C3, A553D6CABCA0F285 + 5: 4976E3B303, AC5E9969F739EBD9 + 6: F10AB8EB94E0, 8301FFE68848D46D + 7: 6E954593AC427D, C1CF93BBC0F92644 + 8: F48F44441B898C0F, 698FFAED1A95E8E4 + 9: 1DC60156D62782E3D0, 6AFF0DCC65D4C933 + 10: 71920ADC8997CB8B3A72, 1C101C6A27CFBBBD + 11: 890ED7492ED914AC20391B, F66DCD6205D945C6 + 12: 1B9FAB84A8748BAC187C7393, B450757FCAFAAD52 + 13: B4C89E1BB280DBC265E43ACE15, AE6BB3D2E6A371FF + 14: 24B0C28944BDF22048E2E86644F5, 84E93E2191CEF17A + 15: 8F2D5694D55EE235168AAA735943AF, 514252AEF2F2A2D9 + 16: 568B7E31FFDA726718E40397CFC8DCC6, 3C80BA7FCA9E419E + +OCB-safer-k128 (16 byte key) + 0: , 4919F68F6BC44ABC + 1: 65, C6785F7BE4DE54D3 + 2: E1B0, C197C93B63F58355 + 3: BB7247, DFE092EF8184443B + 4: 38C2D022, 943FD999227C5596 + 5: D71E4FD0ED, 51040FE9A01EA901 + 6: C4B211EADC2A, 329429BE3366F22F + 7: 426DEB3FC3A4BC, CF1C976F6A19CE88 + 8: A6F813C09CE84800, 98D9FF427B3BD571 + 9: 4D1A9948FD157814B4, 5A389FAEEB85B8C6 + 10: EC3EA142C3F07F5A9EEB, 31E26E13F032A48F + 11: A75FB14365D1533CD3FBE7, 8EF01ACC568C0591 + 12: 891582B5853DD546FF3EA071, E013CFFE43219C21 + 13: 54CA848C49DCDEE076780F21F4, 298EFC7B4D6B6CFE + 14: EA7611C69A60F1A2EF71D6A7762D, 7D9AA51CFCEC8101 + 15: B2D1A211BC524B965A084BB4B21710, 7B2AC0EEB5216892 + 16: 5E81F1BFA270E804A488C9BFAB75811D, A67F627CE1E37851 + +OCB-safer-sk128 (16 byte key) + 0: , E523C6DBB3CA178D + 1: 5E, B1CB7EBE5780DF98 + 2: F4D8, 8036235F2BE7A817 + 3: 4FE268, 123320394EAC24F6 + 4: A5BA02B4, B8276B5E027D45DA + 5: 1571859CCC, 29406C5F2DF2CFC4 + 6: CA1E47447B95, 5D4FAF8FD5341791 + 7: 8710DB37022D96, E10040FEA9AEA9C2 + 8: 205990DC9A34DA3C, AE25CB49AA7A697B + 9: 757AFCB3191DC811C3, AA8CADA8638D6118 + 10: 6994F8C153522361BB92, 1BCEE09E928EB18B + 11: A86FA0CDD051BB60AF5AA8, 50A38F8E9889354D + 12: 8D3FD3EB7FF2269AACFD24BA, CB51CF84CEFC45F0 + 13: 03D2A313925D9490FC5547F95F, A1FF9D72E11C420B + 14: D77C0F0F600FE92F14F479FA457C, 1EBE1B4B9685EDFA + 15: 0CAF0A8BEB864E26058C7DF8EBA0EB, 1B153DDAE807561F + 16: 113D12716DFE0596A2F30C875EC6BA0E, C61F5AC0245154A6 + +OCB-rc2 (8 byte key) + 0: , 1A073F25FF5690BE + 1: F4, 3D3221E92E40F634 + 2: 2C76, C22C20B7231A0DB9 + 3: C647CB, 3E6348D996399629 + 4: 2021891A, 8EF76B24E9D55FDA + 5: 1966CBCBBF, 310D24024D573E8D + 6: 42C15AC9AAF0, 217E83C0CDE4F077 + 7: AB70F3F73DF0B6, 16AB2679D96A591B + 8: B7C7DD845D7E76DD, F33065EA531545CA + 9: 468CC16A37CF63EA73, 88879733F70AE3D3 + 10: 4F769E25A7346E22A932, 26E1A92FEDEE0597 + 11: 304A8B53B1CD24C6C27C17, 48B46E9F091B0B2E + 12: 4E3DF867FEFF0B8E06D5FA70, 53BB48BFB8AB4750 + 13: 2BAB3F0A8C38A3BD3C49DBBA5A, 52303CADCBB6D312 + 14: 3D04A29924589AAEF93A29003EE7, 120EF9364B83748F + 15: 486127A80E4EC599C461451CF1D79B, 2245D51599CAD629 + 16: AF8FB3FD2DB343F1AFF564FCBEA58785, 805BF441E660B0B0 + +OCB-des (8 byte key) + 0: , 8A65BD7DE54082AD + 1: A8, 3A83897CC8EC7CF6 + 2: 9256, DC66C39C7DD87D93 + 3: C145A0, 45967F3764F62F48 + 4: CD314BAB, EF38B0213259C3D4 + 5: 7074014741, 6748F4BAF06DD7BD + 6: 9A874CAE01F1, E382DB7235624104 + 7: DFA0D86DC4CA84, 627ABB432E50455E + 8: 685C2B2CBDD8D144, D166082E085063BA + 9: 53515DAAC7F7B8CE1D, 6680B6C26E1B0994 + 10: 2B3967812BF4155A8D36, AFED7F38AFEFC543 + 11: F4E5AC3CC5913B8A7F35FB, 6181DD3C46A6C24F + 12: F3EC89AD4235287D53715A81, 12CC354833FE5BD8 + 13: 66D554AC2CA85C079F051B8459, 097F31088CFBA239 + 14: 8746061C26D72771A7586949A3E4, 6CEF3565D0E45C6B + 15: FB3BCC650B29F418930A467EA4FB73, 64D12723E100F08B + 16: DE1C27E9B3C391AF5DF403291F2C084A, 6BADE4638AE46BE2 + +OCB-3des (24 byte key) + 0: , 9CB7074F93CD37DD + 1: 4D, 51541A838A154E0B + 2: 5C77, 60E86F2F1F4C6F96 + 3: B3D2F0, 7D74A9E6A061457D + 4: B3556075, EAF7A89A07453460 + 5: 1B61CE7230, F90D18620E1AB877 + 6: 3987FEC8D0D7, B5EF04DEE2E528F9 + 7: EBD0A7EBEEFF3B, A72CA24DD77A5DDA + 8: 429FB38DDABF76D4, D0578484C37227C8 + 9: F8DF28BF5C4CD28B1B, 5E7C4DC8E694E3B4 + 10: 2BF436BBE063F7E830C2, 8D919637C973C71B + 11: ED21656C8878319F1B7D29, 8813280C1277DF26 + 12: F45F90980D38EDF5D0FEC926, F9619341E273A31F + 13: 52F2D3CACC294B141B35D73BBF, 7BBC3F1A0D38F61F + 14: 2E6DA0FB55962F79B8E890E8DD8D, 8060799DCAB802E4 + 15: D6F9A6B2420174C499F9FE91178784, D3AAF969ED2F7215 + 16: 4F1CF285B8748C4F8F4D201C06B343CA, 203A2692C077F1B5 + +OCB-cast5 (8 byte key) + 0: , 77E8002236021687 + 1: 52, D57DF1037B6A799D + 2: 31C9, 7E781759B057D695 + 3: 5C8324, 56965D6CB2C97C0C + 4: 17D99099, 7C52B5D09475F5D3 + 5: 400082C475, 3CA5CDB9B4A0FAE9 + 6: 4DF0E4000C24, DCFEE2C3384F9731 + 7: 10004C3CE32255, 0A6832F985F61658 + 8: FFA6EA76B346893C, 6202693B153254D6 + 9: E96378C94D246AB51C, 5B259FEB715B9159 + 10: A9BED2D59A92D3D9418A, 1E7E066C098A023D + 11: 4EF144B7D4622BAD4DC840, 5DAB2C1D0DF56B08 + 12: 6DBCDF56E57CE47DD3D0CF44, 2A24F2A224368F55 + 13: 43241A0AD933635D7C8EAD47DC, 86B4B5AC22177F19 + 14: 920D6BDBE073F3C75052420C883D, 10943DBB23BD894D + 15: B2C75DF024269833B039CAB19EC865, 84B7DBB425E45855 + 16: 6A9424B6A873BB7155C01DC87E23EC52, 82C5047655952B01 + +OCB-noekeon (16 byte key) + 0: , 72751E743D0B7A07EFB23444F1492DDC + 1: 61, 41BDE9478A47B2B612A23752B5A42915 + 2: F4EB, 90EF542D89F867CDFB1A0807F8AA3CC6 + 3: F5A59B, 1BED873B613096546D4C201347CC3858 + 4: F454610B, FB4035F28AA75221F599668ABBE21782 + 5: 382FC932F1, B40270E2084E8DCEB14C6603D080D7C2 + 6: 18F921441119, 47F1F889B307298150750E81E94AB360 + 7: EF01C70C9D1810, AE0439DBB3825F27CF846B43E4C3AA80 + 8: 89863EDCAD471C3A, F4E8AF73BFC4CB79AECBBB3774DAF8C2 + 9: A6F494092E066A70F6, F73D3B04752B7D913420C17E656C7F86 + 10: 342459682E0A8D53AF4F, 61E7CF14E9878E0726C64B1E8CA08BFF + 11: 65E520D5A99825DE2441D1, 7A2AA740D786EB7015C61B31959E55D9 + 12: 2F96D0BB72E37DA202410302, 1A313242527FB522289094B9AFDB5F7B + 13: 3E8F8A1FCEE3F866EC29128BA0, B8065DA2DABF04129E5AE28ECC11A15B + 14: C2C15976D3C2499ACB9454878131, 372CAD486E104098EB1AA78A2922A1BE + 15: 1F12CADABAEE80E448B7EDCB42F8FE, 86A38DE5363787F55B16462C684E08DC + 16: 3B9ABB3304E75BF5B63E7F5B5A3F3980, 1FBD6B93E457B9779E2D12D78301EFA9 + 17: DC0CD805E43675A4317452E378AD48AC4C, 40AE4AFA4B3E580EFDB4AD0AF5BC4E4A + 18: E9DD52EA7264C6C7BBA39B761B6E87B65687, 4061DD65D5E7FFFE8D3D4261494D4F8C + 19: 80A9735CA1175072823828123413CCE772D521, D3378A12E79C49A37378DF527A460AB2 + 20: 09AD495AFFBF7CB8841262E7E5E8952878D4391A, C25D7A98C6F260B5FBCA3B8B5F7F33C1 + 21: 3925615707CC40C351D4A49794778545BC1F683175, 97622437A7208383A4A8D276D5551876 + 22: 5BB0D41ECD7BD2CF0B12A933255D95A3FE35E4C896BB, 4B8AD84EEA3156765A46AC19C68B6F88 + 23: 1EE71FE23CBFD5683AB1B391FC12B4E5952E4E6AA3D189, B0FD75996F28E071EB6C86BD7102BAA5 + 24: 0AA3D8C98AADEEE1867B13B017DD263BD16E960DA64FD071, 5204780963A62C2F4F7B3555BFF73836 + 25: 3A88B6F2AE321B226DA90B98E04A6A1589411BEDBE994632D5, 5638AF04EACF1EB986AC0702B4373A22 + 26: C2731661AC634A4DC0345F040DA7AEE507A3B9D019B5958543BA, 4C67D3FE37ABEE928B3BB812E7346823 + 27: D3E7651AA6DA035D05D599EFB806E8FD45177224593B5974758419, 5814E84258E1B9BD56A188AAE6F25138 + 28: 17818E7102B8C123230C5D64F18BE94C3159B85C8F7B64A7D4712CDA, FAA905B587A93DCF600BA8589A985432 + 29: BCA4335C6C29D978032C216114D39C01C6F161BF69D5A1CE55FBA8C575, BE24424A162E43A19755E2EFD274DBED + 30: 24C33CEE022F8A633DE9DFD009F535B52BCF64F390D2375E5BED65B70D08, 138F21D54B6B7E34628397DCDE0D33BF + 31: 838FE950C8165ADBBD6B61E9732F9A727CA7AE74376981382F0C531C331915, 0742E769CCBA2D1CAC7CAD4E0F012810 + 32: 57CD778DAD477271794FBF763662D97F8A10B17D70A69FDCB974FFE67E558519, 942C7D1C200C3845748F8131DF71AE26 + +OCB-skipjack (10 byte key) + 0: , 90EAAB5131AEB43B + 1: 2F, 6274B82063314006 + 2: DAF6, 6A6BCCE84FD4EF02 + 3: 5C2A88, C83D54C562A62852 + 4: B6E8FB5E, C44459EF41C8F296 + 5: 6C0888C119, 269DD7657BD0225F + 6: 1FD9AD7ECCC3, 3CA090F46B107839 + 7: 1EDBFF8AE458A3, 440380BF9745132B + 8: 04DBECC1F31F9F96, 2653620A4877B0E6 + 9: 908AE5648AF988A896, 00180FF33C1DD249 + 10: 53E63E0C297C1FC7859B, 36616209504C4230 + 11: 407BE16144187B4BEBD3A3, 4754B7DD4DB2927B + 12: 9961D87CFEDDF9CC22F2C806, 5947FC41E6B9CEC9 + 13: 9F5254962E4D210ED8AC301252, 97A392BEAF9B3B04 + 14: 379FDA76ECCFDAAC10F67FBF624C, 1D895ABD932BD5EC + 15: 1D5A7AD556FF3078284BB21A536DAA, 01FAE2F4936ED9D2 + 16: 4B8B71396924880CB33EA6EC6593F969, A0F4B1BE3B9B4CCE + +OCB-anubis (16 byte key) + 0: , D22ACF880B297DB0513DFAF0D2DF57D9 + 1: 59, 210A179469D6568AB9470C760415574E + 2: AFA5, 1223F9CD160ABE2F257164C6E5533C87 + 3: 969BEC, A57EC767543CA2ADBA4F5A7423ECA78A + 4: CF8B31F1, 13B5BF9CD87CE15CE696F3AF1B082650 + 5: 9B22DF3852, 4937FDDA0AFDDA04CCD53CCBB0A82745 + 6: E11719B2F0F8, 6847931DBF0223F5CEF66AE3F4DFCF9B + 7: 5A85E0F6DD2266, A1A0AF45A68A681CC396615FE1E1DFB5 + 8: 7F2DFCC65ED86976, 13614A3C6E0E08611D8DF8EE5B7D788F + 9: 1DAF10DFA3F1D53E50, 673632B6DD553BAE90E9E6CC8CDE0FA5 + 10: AF74FD9671F9C0A9879C, B8B4DD448FE967207227B84E42126D90 + 11: 49421CED1167A882E26297, 21C8951A1761E4BD13BC85CBD14D30BD + 12: BC0BC779B83F07D30CB340DA, FAABD25E14FFD8D468AD6616021F604C + 13: 843D7E00F94E61AE950B9AA191, 08933ED5FBDCAF72F788393CD5422D0F + 14: 296F15C383C511C36258F528E331, 8BFFADF5655C1864057D69A6706D1739 + 15: E31D2E80B2DBA4FBFAF52DB0513838, C4CD36821EC631CCBF1F258EE9931288 + 16: 87F319FE9A48E2D087EDF95563896EE5, 517960488E5A118D150A1573E76C290A + 17: 9632B7DC1740BBE0A7AEEFD0F535B5AE8A, 0C24D0950873621D319A928862D3A6AC + 18: 359431ED4B3AC537238CAC2F86126972D403, 4A0CED2F4BFA3355C17D6C5DF9FABFAA + 19: E15B50172EE8DA9C552D448A5A48BEEAA2F11D, 8166B2A2D3A0745D1055F9F503FD6C03 + 20: 75842DDC0D5E3BD80225E4BFBD1298421244D7EF, BB957BB2582B67B63978BCFD7A949EDD + 21: 3DD69162716D5F3E096E614991CAD7ED8E01F926B8, 40A954F31F5B0A2C5DD220ACED8D2B3E + 22: 8A49AC14F59593D5399A10F9346E2FD36F47F64ED419, 4324D408CE7F86370495AF14FBD1A859 + 23: 6AA8FA353BCAAB4262211D75F13D27BE173526B8BC3CFC, BA3A27D79EC8ECBC5A78CB9FD095B766 + 24: B918192BB72CFEF980298EEE570460356A4BA1755576FEAA, EB341ECE0A070E769F498600EE4EBF77 + 25: BEFAE0B77E42A2FD18958D9E43202E8A338562AFF8317461B0, 444C1D6BDC026A01012BB2CEEAD89C2C + 26: 07E86D49CFFE6FB08FDF44584033AF321447003D8AD3862C00C9, DA9355A79B224EF662DA65F19BE494A7 + 27: 911BB223AC6F6E54082FBFEDEC300D73FCAF715CCA35949212B372, 3496160A46A21DCDB5A4C179F159D860 + 28: ABB563FC803715F59AA35460E98470E2E94E4270455ACEBF4297641B, 899CFE1946A060DE620879B8A7464718 + 29: 47D98E83B5849CDE19B14ABCF9EA6CA9684AB49A3AB36BD14F328D808C, 6D76CD5EFF6D4AD3B67A56DF1EB42E05 + 30: C8BF0B71A95884FFB93D64C57E327A4754EC5A1EE26632CF8E0B6B26CBDE, 2B3BE785263B1A400E5893273AFD09AE + 31: 9804D668CF2D75CA58C9671F65630E33909269B9511AF9119BE88EBB35F00C, 3DDA028B1A2339CA817DC8D9371E0FF8 + 32: F6E038A82A09BCD20BAAC7926B2296B78F9CBA9DD12C497C47EA08DBCD8CEA3A, A203FC1E68E21A52E72224891AC10EE2 + +OCB-khazad (16 byte key) + 0: , BDEDFF7AA0070063 + 1: 00, 67E951582D66ED93 + 2: 5FED, 09DC8AEAD70673DE + 3: 26A7CC, CE1436CE1E37D4B0 + 4: 3D2BD063, 574C24395F31511A + 5: 597F1AFCB1, 6FBBE820C6F26CDB + 6: 202DAE442DF6, 58CA6E5706C9852D + 7: 7C20EDA18E9444, AABF0DA252A1BAAD + 8: DEC02BF76DFD5B77, A0A97446B80EACB6 + 9: 5D7A42F73843F9200E, A1DD603372D124CB + 10: 0D4710E454C19B68369E, CC78E9D7EAA6A39F + 11: 126694191BF09A29DCF40E, 76C9B84FA3E8913F + 12: A94EBB86BD325B4FA1942FA5, 613DE312DB1666F7 + 13: 4F9462386469EA0EFDC1BFAFE9, 5247244FD4BBAA6F + 14: 4EB794DFCF3823BDC38FA5EF3B23, 0C12017B5E058398 + 15: D870479780CC5B3B13A7A39029A56F, 003D3FCD31D497B5 + 16: A47BF1218AC86A60F6002CE004AF5E50, B4EC27091D5DCD58 + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/notes/omac_tv.txt b/xmhf-64/xmhf/third-party/libtomcrypt/notes/omac_tv.txt new file mode 100644 index 0000000000..56d8da6fb1 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/notes/omac_tv.txt @@ -0,0 +1,461 @@ +OMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are OMAC'ed. The initial key is +of the same format (length specified per cipher). The OMAC key in step N+1 is the OMAC output of +step N (repeated as required to fill the array). + +OMAC-aes (16 byte key) + 0: 97DD6E5A882CBD564C39AE7D1C5A31AA + 1: F69346EEB9A76553172FC20E9DB18C63 + 2: 996B17202E2EDEBD63F414DD5E84F3AF + 3: D00D7DA967A2873589A7496503B3DBAB + 4: B43C24C0A82DAA12D328395C2ABD7CAE + 5: 9B902B6663B5FEDC6F9DCE74B35B91F2 + 6: 06A9678C65D7CE225E082ECA31788335 + 7: 7D67866CDB313DF65DED113DB02D6362 + 8: 259E28CF3E578AC47A21A77BA9EA8261 + 9: 32F23C8F93EA301C6D3FE0840CA8DB4B + 10: C2B06388AD6F8C43D19FE4F6A8ED21AE + 11: FA8622485DB2F62F84FF46E532A1A141 + 12: F312D9B2E6272578F406B66C79F30A0E + 13: 7A5DE06B2BFB75ADA665E96F680AC098 + 14: C3B00380F0BD8E2F5C9DD9945E0F36EE + 15: DDD87974A5FB2E7A4514241E94526B5B + 16: AD24FC47A0FEA84C54696DE997A94F4B + 17: 7538713D8AA2AE3726307EFF087BBF5E + 18: 7619A52B4C34A98440812F5F28F8DC4F + 19: 7E797B8846554888622CC5E400B2FA44 + 20: 61E8DD3E09145F5657DB4B8F7BD2D7D8 + 21: FDAE2A3FE60DDF1871C2613A293AB6F1 + 22: A186D6EFD10DFFD2C088480B0A784185 + 23: 3119D337865618CDA55C06FB992427CF + 24: 413E3EAD7E3F169A37C49F9CA92E235E + 25: 37A55AF22373B9A1E2F8368B2FB992CA + 26: 4941F604C40EEEE1A16CFE073C12D1FE + 27: 3E8F4A0876BF12A2DCA87157F15DC884 + 28: 5DFAE292D8EEB13D8FE5725E5D169742 + 29: 59160455E0C0B35D950BA67C77F9FB05 + 30: 5AC0D736A06A7DD146B137ADEE78EE06 + 31: 0CA1178F28B953045EE76E2E760036CA + 32: 025616215F870D1EF838AD1D2AE0C649 + +OMAC-blowfish (8 byte key) + 0: 2CFB5DE451FFE8CC + 1: A5AC339DB44D020C + 2: A3CE0CF62249444D + 3: 3076B7129CE3F6A1 + 4: 9E091A637DDF70E3 + 5: 275199AB20A5F09C + 6: CDEDA8D16A401E62 + 7: FC980516CF5C9E30 + 8: 659D0B31D21B622B + 9: 8306847B5E72E018 + 10: 7AD029BBF1D2919F + 11: 133181425C6808C9 + 12: FC5AC60E367F413A + 13: E0DF8BCCF0AD01D9 + 14: AC5015398FA64A85 + 15: 1F068F22AFFECEE1 + 16: 8E6831D5370678EF + +OMAC-xtea (16 byte key) + 0: 4A0B6160602E6C69 + 1: 1B797D5E14237F21 + 2: 938300C83B99D0AC + 3: F989B99B3DE563C6 + 4: F65DEA2A6AD45D1E + 5: 1DB329F0239E162E + 6: C0C148C4EE8B4E1F + 7: D82B387D5DFFE1FB + 8: 1D027A4493898DF2 + 9: 196369F6B0AF971A + 10: 2A37A2655191D10A + 11: BD514BE32718EB4A + 12: B4DBC978F8EE74ED + 13: 8ACCAD35C3D436AE + 14: 73ABDC1956630C9B + 15: 73410D3D169373CE + 16: 23D797B3C7919374 + +OMAC-rc5 (8 byte key) + 0: E374E40562C3CB23 + 1: B46D83F69233E236 + 2: 7CB72B1D335F04B0 + 3: 94457CBC97B31328 + 4: 543D0EDFCDCD7C76 + 5: 5164EFA8412EAA5D + 6: 13CA0717EF95F9A7 + 7: 2AA49A7AA7719700 + 8: C9E7C56125C3D90F + 9: 2BE3E15FE58648AA + 10: 77D0B90372D6D0FD + 11: 17408F62ECD62F57 + 12: 7864EFFA59DC059B + 13: 3212E76E25E5DEA8 + 14: E2424C083CDE5A6A + 15: DE86FFDBDA65D138 + 16: 85482C24D61B8950 + +OMAC-rc6 (16 byte key) + 0: E103BD8BA47B7C1C010E1561712E6722 + 1: E51AEECFED3AF40443B3A1C011407736 + 2: FA6506C5ABE03381B045D28D1D828966 + 3: FAC4237FFE7772E2299D3D983BB130DD + 4: 3A7E24D41121A5D4F96FCECF0C2A4A10 + 5: AA44291E5500C1C8E1A14CB56E4F979A + 6: 4B8FDA6DA6B3266E39111F403C31754E + 7: 4DF5F1A1C8EBC7F56D0D12EEB63FF585 + 8: 46A6DDE419355EDE14D31045FCA1BA35 + 9: 71756D4D3DF59578B7F93FD4B5C08187 + 10: ADA292A19F8636A03A8BC58C26D65B0D + 11: 703190DAF17F8D08A67A11FDF0C2A622 + 12: D2B94CAD1AFC5CD012575964D1425BE6 + 13: 45FD0069FCA6F72E23E4DB41AA543091 + 14: 36F652600F5C9F226721400A7199E2BA + 15: E8CC6389ECF8EF1DBB90A0FD051B7570 + 16: 8125446B975DBDA742A903340D6B96C7 + 17: 00B55E4399EB930E592F507F896BF3DC + 18: 33E58F42A47C9543A851D6CA9324FEE0 + 19: 9F28FDEA3EC7F515128F5D0C0EB684C5 + 20: AC1DAF6C01AA28BCC0A819189FA949D7 + 21: D0532B5F54A179444D052A4D2AD6E4F9 + 22: 58B80A66549404C7B9F64D5AE3F798AB + 23: D0D6D586477F92311DDF667E0749D338 + 24: 0DFC0FAA67FF114398CE94D0688AE146 + 25: E163B8C00CF5CC9FA23ACACD62B53D64 + 26: ACE9270456AF9BD388BA72E98825CFE8 + 27: 4302EED9BAA19C7A296585E23A066A44 + 28: B3EEABEFAB25C7478419265564715387 + 29: 9F0630ADE9C74AB2981D63F3B69E85BF + 30: 1215A9446A275CCE2714F94F3C213BB7 + 31: AF43D7F748DE0E3458DB970BAC37E98D + 32: BF871AC9E892CE0DCD7C8C7ADDD854C6 + +OMAC-safer+ (16 byte key) + 0: A2C8C7FEA5529D01C3FF4E9359EF74F4 + 1: EAB87021118FF24FE79B69ABCCB14A8F + 2: 789566F467BAA68F4CC3C4B61901D6D4 + 3: 369F41EEAF7D628F9E0D77BE43BFC1D2 + 4: DC46A20E1F36F45006ED5B43BEC20DA6 + 5: 8F150CE34F57BBA2E6CE3431B78E4ACD + 6: 61CD154478BE20F33B26CD8FC58091A5 + 7: 4E6DAA575CF28F1F48B256262B7D558C + 8: D21FA4F1859571DB91E92767C5487AA2 + 9: E3D009DC7E71FBBB030B8FF0B544A2C9 + 10: 094C236EA48ABF7DBAE5A88AA3DE07D7 + 11: 00C401996F8224359566660AC1CEDAA1 + 12: D580EC60F712558D875F01643D96653F + 13: 8482298027C7B4D5969787A1DB1B1F2F + 14: AB726AE3DA95CB242E63EF876A4BC446 + 15: D668ED4919003F5E45590663FAED41DA + 16: E4CFFD7E0E7B176867C386001849FD6F + 17: 37B3C6DEFC5573879006D15F982A397C + 18: 0AB8847EE6A41A0E960080EF0D1BF1C5 + 19: 2C94FCA2A685F276A65ED286AE12FD9F + 20: 23383032032D7B5165A31ECA156DBD23 + 21: E1EECFB3D671DF694FFB05AE4305AD4C + 22: A0F6CA99B96CD1EDD04C52828C8A4D74 + 23: 12D6B7053417AF3E407EFD6EE1CC38FE + 24: A566D1C39AE7A1A0A77D5A1F56C5FAAB + 25: 81C9FAECEAEA326140AFCD569668F669 + 26: 6A00BF1D0DC893868378E4347CB4A1B9 + 27: 98842956DBE7AFB1BF49C46497BD54C7 + 28: 88EFCD5A1644B75BB0B3F5DD338849CE + 29: 77EC62C278C61163B1BEC595A11F047A + 30: 147424E817DC69413CC657E0CB292F7F + 31: A2946CBB910743EF62D8A3C7391B9B9B + 32: 00EEDA55520B8A5B88B76487E80EB6E1 + +OMAC-twofish (16 byte key) + 0: 0158EB365FCCFDD94EBA6BE42B6659C4 + 1: 17DA580917D147D10CB73DB6800B0E59 + 2: 3F185CC15EF3328D3E075665308C07C8 + 3: 5712A97ACC9D08FE9D2087D0CA16B0AD + 4: 90425A8CC1C026DDD896FC2131AF654B + 5: 30A43D4FEAE71F5396308C16DA081B4A + 6: 6839FEF605704D49F1A379A9E9595E6F + 7: 56A8F06DFEE543971B351B07430E2026 + 8: 36DD0E4B55C5314F9F2753D7EB6F0849 + 9: 8E319249A3CD456460F410F518F8CEDB + 10: 463978BE2A063C22E71DC71520723517 + 11: 1B735E45FD3DF636E0A6104D4A2E9CB8 + 12: 628A82213148AD9791153D5AAFBDDFDC + 13: 21AFDF08A36ADB6659B656C8EA0800E5 + 14: E5C3E58803DDBE174E0D4C2B8171AEF0 + 15: FC6981F2B4359BA05988D61822C0FA88 + 16: 7B03498FAFB04A6542248852225F9DAE + 17: 9B173E91E59A940186E57BB867B8307B + 18: 470BF2EE614C8423AA3FDF323F1C103E + 19: 6E664AFDFD8306547BBEDA036D267B79 + 20: F61AEC1144C3DD646169E16073700AC6 + 21: AE503B139707AFA494F7F2DE933EE81A + 22: A0A8BDD4ED0DCAE4A8E1DCEE56368FF0 + 23: 460B8207930DA434AE6AFECC305D9A26 + 24: 7F03F8C7BA5365CC65F7864A42693BC8 + 25: 31448849D6190484192F29A221700011 + 26: BDA941019C75551D858F70FB1362EB23 + 27: 2880CB3E62447AE8EACA76C17971BB18 + 28: FC8D710FA3990B56357E61C2A302EB84 + 29: 793CD15348D7DFF301C47BC6E6235E22 + 30: 6FB0CE69A15A3B6A933324A480077D35 + 31: C24FCA5DD4AE0DF2BFF17364D17D6743 + 32: DC6738080478AF9AF7CA833295031E06 + +OMAC-safer-k64 (8 byte key) + 0: 726FE2DD40A43924 + 1: 2A138B65EB352621 + 2: 9588A1B53E29616C + 3: C025DEFDE1A59850 + 4: 73D062F1B6D8E003 + 5: 944598A2FC8A2D76 + 6: B176C25D8CAFFC98 + 7: 14F05014DE6A090A + 8: A7B9847B2CE22D0F + 9: FCD71310CBAA3A62 + 10: BFF00CE5D4A20331 + 11: BEE12A2171333ED5 + 12: 333FD849BEB4A64A + 13: D048EC7E93B90435 + 14: F04960356689CFEF + 15: 9E63D9744BF1B61A + 16: 7C744982F32F8889 + +OMAC-safer-sk64 (8 byte key) + 0: E96711BA37D53743 + 1: 7DCFF26A03509FE1 + 2: 0A20EF19C8EE9BF2 + 3: FE2883748A6963CF + 4: 557060195B820A18 + 5: 771A7931FBBE5C0F + 6: 6BDBCE5F96CF91D8 + 7: F3B924CCE8724595 + 8: EC7191286D83C2C3 + 9: 94F55B19BB7A8AC1 + 10: 2189F4F2B06A8CA4 + 11: 99853DAEBCA33A46 + 12: 66EAC37A033802D7 + 13: 845D7AA866F8A8AD + 14: 33A874DFECAC22AC + 15: 63DD9F7A7F3683DF + 16: EAC277D951676C44 + +OMAC-safer-k128 (16 byte key) + 0: 8037B89AF193F129 + 1: FF2314E87BA6AFE1 + 2: C3243DF896B61D85 + 3: 0F61C715CE821AB8 + 4: EBFDC6A9CFD2F5A4 + 5: AB6497D7AF2C7FFF + 6: C920CEEB7C1819C2 + 7: 3E186951B545A7E5 + 8: 5EA36A93C94AF4AC + 9: 6A2C59FAE33709BE + 10: BF1BAFAF9FC39C19 + 11: 69EB6EF046677B7C + 12: CDDCEE6B20453094 + 13: A3833BD3FED6895C + 14: B6C05E51F01E049B + 15: 90A2D0EAB739D39B + 16: 07BF607A161D0A66 + +OMAC-safer-sk128 (16 byte key) + 0: 5E8B137A3946A557 + 1: 0228FA66B13F3C7E + 2: A6F9BBAFF050DCDD + 3: F75880F684A796CE + 4: E0AEFB8E32040EBD + 5: 9F65D658B86D310F + 6: 3FA52804FB46CCAA + 7: 2F6D12D199FCD2FB + 8: CB56AF60AFB4D2BB + 9: 8E6F0FF6FDD262FD + 10: 490245BE3CCCEDE2 + 11: EFD319AE46C73005 + 12: 43E00E545C848995 + 13: 10444B41ECA15EBE + 14: 521775C389D5BE71 + 15: 9B683EF8B097FEBA + 16: 3C5D746EED09530A + +OMAC-rc2 (8 byte key) + 0: F001FE9BBC3A97B0 + 1: 8F8DC9C952897FBD + 2: EC82EAD195AAC38C + 3: 53DD52269B19E9A4 + 4: 9B86F64BF72A0647 + 5: 664A88A29F2898C6 + 6: AFEC3F71C1415666 + 7: 9BA1F2C1A2E765F9 + 8: 402A12120908B436 + 9: 03ECCD4C6AF44144 + 10: E8CA3529B5D9D6FC + 11: 951EE10779CC585D + 12: B9083CA88E7E819B + 13: AFFB9E884DACC5B7 + 14: E942E8BC241343D6 + 15: 9B190489091344FB + 16: 9330A9E05554A15A + +OMAC-des (8 byte key) + 0: C9085E99D74DF01D + 1: FAC84F0EFBEF8630 + 2: C37C5FECE671CF16 + 3: 45B2CBEE8701A5B1 + 4: 53665E1F024EB001 + 5: 357123CEDFC9FF61 + 6: BD2CFD33FB1F832B + 7: 1AAA9D8C9120BDBF + 8: EB9F589AE9D4E78F + 9: C8F9D2ACE691922D + 10: 81ED6F3611DDC0FD + 11: 2965ABEAC46839EE + 12: 2208B1E095F7AE2E + 13: C0414FE41800113E + 14: 653A24119CF43D97 + 15: 7FB7CE0862958B37 + 16: 55097816B10C549B + +OMAC-3des (24 byte key) + 0: 7F07A9EA8ECEDF9E + 1: 4E2A652EB5FBF5F8 + 2: 4F84E3779ACCB9F5 + 3: 7134AB3463115DC6 + 4: 82327BE8EA2D7E0B + 5: 24950B9C14D87CD9 + 6: B25A097BB7E0E18A + 7: ED51BAE55ED925E7 + 8: 56B79E7644556975 + 9: A65BD98E4D4E31E2 + 10: 11145BB51514482D + 11: 397486787E676BA6 + 12: BD1F6DEBAF6D9AEF + 13: 5CC3921F7DB815CF + 14: B0C0E60DA5F727F3 + 15: F8637AEEFF10F470 + 16: 0EA19531D42706EA + +OMAC-cast5 (8 byte key) + 0: 7413DCDB9F0C3100 + 1: 423799EDF1472B79 + 2: 03856F0CB4F11606 + 3: F152AE6360813DE0 + 4: 853998BD980AD146 + 5: AE6C3D667DB8B414 + 6: B5A4986A34BDE20F + 7: E5ABE5B979798942 + 8: BEE8DFED4555F405 + 9: 6B5339E952AF61BE + 10: 5E867CF34D9C1149 + 11: F9C55CB3BC655E08 + 12: EA09A2929AC7D915 + 13: CE8EB0E4370E1933 + 14: 749A424B2AA91B98 + 15: 8DDA93C2B814D5D1 + 16: E8B0B219D4CB699B + +OMAC-noekeon (16 byte key) + 0: EC61647B281C47C1B43F9815064BF953 + 1: B100B1B6CD96DCED8F47A77E70670A92 + 2: A96CDE3C48831A6B0A5ADFECA6399BDB + 3: 14E75E7CAD840208834918B29A5D4430 + 4: 9577083713AE6E44EEC987C77C93C072 + 5: 2A738C02841E461238C02F5CFC8E66A6 + 6: A901327E451BE0D2D9DEC83DEEA9A022 + 7: 5ED7EE1BE04A64A689D15F6970A821A6 + 8: BA053E24FCFD02C731A8CFCA19EE66A0 + 9: 57139CA8C91072555B29F85A19E2C84D + 10: 4585EAC7EFB84869FD96EE7A5FDD350B + 11: 62AF6C415CA73E54E82EA306254C1BDE + 12: 75304F9724BD364F84371EE154F5210E + 13: 7FE5DBCEE826760434745D417453182B + 14: EC98DA2A580E9131218D1CDE835423D4 + 15: 631BD9EAFD1AE445F2C1C35E2B4416ED + 16: CA2D902A1D83388FE35BAB7C29F359BA + 17: 0DBF0AF7FCBEEE21FB6159C0A2FFCD4C + 18: BD7CD2C49241032DA33B1975EE2EE982 + 19: B30B090EE8626D77D310EDB957552D46 + 20: 64F608AC5707C381AC6878AA38345144 + 21: 28513CA7795B23A02B37DC3732413D23 + 22: 9F440700094517847E9E013C8915C433 + 23: 8CA483F313D20BFE7E0C089DAA4145BD + 24: FA44872743E20E5E0A069B3C4578DB50 + 25: F6DE8FFBECD52CC1F213CD9E406DF3BC + 26: B9702B7E846735A3DCC0724255F88FEC + 27: A1DDAFED2B1732C7BA89C2F194AF039E + 28: 2549C5F0E30F8F4002431D2C098805B8 + 29: 52E3836181BF5C9B09A507D5330CD14F + 30: 01C55DCBCCFD9D7A4D27BDE2A89AA8EF + 31: 3CF721A0CF006702CDA91F2FF3E4D5E3 + 32: 6D264B9065BE98C170E68E9D2A4DE86E + +OMAC-skipjack (10 byte key) + 0: 84EDFA769040603C + 1: 7DA58A4CBD642627 + 2: 118F60115CFC8229 + 3: A7F7346D34DB2F0E + 4: 35615CCD526CD57F + 5: DE471601A3660844 + 6: 15FCCE6D6D883D1F + 7: C6F694861233151B + 8: 3B762B397F16E807 + 9: 976C6AB59FB3AB12 + 10: 6810791F2C595961 + 11: 7FA3478286917F17 + 12: 73DEE44A51C6B610 + 13: 89EE8B253B1ACE81 + 14: CDF2586A56C8A0B5 + 15: ED91F98DA98F42C4 + 16: D8D0FA5CE96B08BF + +OMAC-anubis (16 byte key) + 0: E672617CAA1E641C0E7B4B4CC4787455 + 1: C0C16E8FD63907C08A8ABBB7B73376D3 + 2: 23F97CED54939361830396224A7BDD91 + 3: 7FD87DEA9F05E07212DDF61292D9E13D + 4: 929A11A4D0991A6446B1051926A6048D + 5: 4EB74F1CC0150D86126BC6FE1FC8253D + 6: 33C2C3C072D05BB6D54F87579C23B116 + 7: DE350181C9E90A79879813A609BE77E2 + 8: DB519EB9EF0E154D9D248734FD3D3724 + 9: 4F7F2E6D3FC72BA94FE24EC0ABBF4E66 + 10: D646389DBCEEDD59EBB6E8F09C422930 + 11: 8547658AE1CE6A8B8D010A1E1FEA7AF4 + 12: C9BE2B7F3630EFDFBD3AEA6A108C86EA + 13: 290417C57096B8B9A1BA3C20FD91285B + 14: 9AF60E99692C5F911CBF969A6E11DC14 + 15: CDA433BE58C98E49EBA8A7108E50DE2B + 16: 7430D0EE631A4659351B8A4489A78D46 + 17: DCC74C0FD0415768FE00225CA14B7DC2 + 18: 0CF2432B1B465F2A8C5FACAAF2FEF619 + 19: DA020680C64E93AE5FCA3D71466D01C1 + 20: B9C33A86E6ED9FCCDCD973382DD1B6A3 + 21: 6631236B9F2F810DD4D97E6046F41AF2 + 22: 0312C322F4D634CF4FBC0C2624E3E9F2 + 23: 111E3E9F8FBDC1E4364622723F1CB524 + 24: 6D2608D7AAF243D5219E14513895BFF6 + 25: 683BD01B43CBC0430A007ACBAB357DC9 + 26: 01B8FC65C56B0F1A5BFEBEDCCF6748D9 + 27: 4D6298D63A80D55491697A6DD8E3694C + 28: 6F0205E4E083CAB00747D723300510DF + 29: 5183BAEEF05E9402A935EB9AFF0AA2A9 + 30: 1E673BFAD4944643A740C59D96A5925C + 31: 940FB4000E34EEE78E8DB402E4A76502 + 32: 87B0C48F3D155AD85D0502D94A4572DE + +OMAC-khazad (16 byte key) + 0: 4EBEFA460499424F + 1: 97AEEAD51E541D16 + 2: 29A35212910C9595 + 3: ABD1577D622074EA + 4: 70A537DE14DD765C + 5: 240A19016DE99C51 + 6: 4D42C10A9F803177 + 7: F464BC3E0DB5A909 + 8: 1C65A01A7C08DAC7 + 9: E49A1428C230C209 + 10: 16DD0FEB7A6505B8 + 11: 2DDDB3E35A05C220 + 12: EC88910C799AC6CC + 13: B2A65C9EF39BEC8A + 14: F0D2366BA91DFFD5 + 15: BCAB623CAB7AAA23 + 16: 9BCEAB857596E478 + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/notes/pmac_tv.txt b/xmhf-64/xmhf/third-party/libtomcrypt/notes/pmac_tv.txt new file mode 100644 index 0000000000..e0a19006e2 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/notes/pmac_tv.txt @@ -0,0 +1,461 @@ +PMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are OMAC'ed. The initial key is +of the same format (length specified per cipher). The OMAC key in step N+1 is the OMAC output of +step N (repeated as required to fill the array). + +PMAC-aes (16 byte key) + 0: 4399572CD6EA5341B8D35876A7098AF7 + 1: 580F7AA4AA45857C79BA2FB892228893 + 2: 24D2D1DBABDB25F9F2D391BB61F4204A + 3: 083BF95E310B42A89751BC8E65ABA8B5 + 4: 69BEB9268CD7FD3D7AB820BD7E226955 + 5: FD71B0E647ADB4BB3F587E82B8B3401A + 6: 07EA46271081840737CEB1AC9E5E22E3 + 7: FFA12AD9A9FDB5EE126084F82B381B10 + 8: 8A11AF301AAFEAC8A75984ED16BB3292 + 9: 368BDC3F4220E89B54C5F9D09FFB8F34 + 10: 8B6DBFF776FD526147D1C4655626374F + 11: C538C09FC10DF38217CD8E799D8D1DC9 + 12: FC1264A2051DEF73339432EA39443CFD + 13: 8AF37ED2FB2E8E30E9C4B75C1F1363E1 + 14: 4295541FC62F6774068B8194CC9D9A46 + 15: CFAF4D8EA09BB342F07131344DB0AA52 + 16: B6CBD6E95959B2A8E22DE07E38B64D8D + 17: 3124E42DE3273B0F4806FB72A50F3E54 + 18: 252D49403509B618AB3A6A1D99F9E9FA + 19: 9CDA75594CB696EB19C022DDA7324C10 + 20: 33BB8AE43B7BC179E85F157FA19607D0 + 21: 12FE91BCF2F2875379DC671C6F1B403E + 22: 416A3E519D1E406C92F8BB0DDBBBB6BF + 23: 6F98DCCD5A8D60DEAF612ACCEDD7E465 + 24: FFCE7604609B2C3C050921854C638B7E + 25: DD2BB10AA07A5EC8D326BB7BF8D407F4 + 26: 468BFE669FCDF354E4F9768FE1EAF8F6 + 27: 01724D2F2C61EB4F380852218212E892 + 28: 2D90EC658F57138505598C659C539A3E + 29: 6301EAA0E1500FFEB86752744EFFF23D + 30: 3CCB177486377616056D835F6F857F7C + 31: BFB3C7755C1F4543B516EB8610CB219F + 32: D5C505847D7CFFD8CED848F6CB613105 + +PMAC-blowfish (8 byte key) + 0: 3B7E4EFE92FA46AF + 1: 746840017C38C892 + 2: 3B6A92C731465B64 + 3: D89D3B05143B6704 + 4: 43F70D54B808B7CE + 5: 84E4063AB32F046C + 6: A7E78CD5CCD23805 + 7: A78FB083475FEF10 + 8: D4F6C26B5386BA25 + 9: 184768A079853C90 + 10: 0702E6C8140C5D3B + 11: 786D94565AA0DF4B + 12: F6D36D3A2F4FB2C1 + 13: 7BB3A0592E02B391 + 14: 5B575C77A470946B + 15: 686DAD633B5A8CC3 + 16: BDFE0C7F0254BAD5 + +PMAC-xtea (16 byte key) + 0: A7EF6BB667216DDA + 1: B039E53812C4ABDC + 2: 87D2F8EA5FB6864D + 3: F85E3F4C1D9F5EFC + 4: 4EB749D982FB5FE2 + 5: 0BFA0F172027441A + 6: FF82D01F36A6EC91 + 7: 3BC2AA2028EBBD7A + 8: 15AA03A97A971E2A + 9: C974691F5D66B835 + 10: 4FC7AA8F399A79ED + 11: 2633DA9E94673BAE + 12: 82A9FD48C5B60902 + 13: 31BF6DA9EE0CE7E4 + 14: 26B2538601B7620E + 15: D103F3C0B4579BE5 + 16: 031346BA20CD87BC + +PMAC-rc5 (8 byte key) + 0: C6B48F8DEC631F7C + 1: F7AA62C39972C358 + 2: 0E26EC105D99F417 + 3: 7D3C942798F20B8C + 4: 415CDA53E1DE3888 + 5: A314BA5BCA9A67AC + 6: 02A5D00A3E371326 + 7: E210F0A597A639E5 + 8: D4A15EED872B78A2 + 9: AC5F99886123F7DC + 10: 69AEB2478B58FFDF + 11: 8AB167DFC9EF7854 + 12: 945786A136B98E07 + 13: F3822AB46627CAB5 + 14: 23833793C3A83DA9 + 15: 70E6AB9E6734E5A6 + 16: 0705C312A4BB6EDE + +PMAC-rc6 (16 byte key) + 0: C7715A17012401DE248DC944DEEBD551 + 1: 5B804C6CCDF97BB28811C9ED24FE6157 + 2: 7528378C052F4346253CB0DFA3D251C7 + 3: 6DA86EE0B28606861B1A954D7429A93C + 4: B4DFF84C25937FB50EE79D4037323160 + 5: A60FD9BE5E1FF67EC9734776C8781096 + 6: 81D3F8EDC0A197DD3739EAE648F38580 + 7: 8BAF47F02120E898916D678DBD0C1641 + 8: 7A9EEC96F10B7CF557B61EF35BB55B08 + 9: B88C11221014F8AE048E56C427DF4A46 + 10: 4BBA8EED89F357861A265006816D9B04 + 11: 8497C1D55010A65ED8C3688B75A7CABF + 12: 95E1720C06A373CAD1A22F432F26BCCA + 13: A175FB732692831E96AFB587BC49E18C + 14: 54EBC04FCFD90302907BF77C4D8AC77C + 15: EA9F13EE5548CDF771C354527CDDA09B + 16: 4EDBCFD0E2E6B321530EB31B3E8C2FE4 + 17: F412304C1A5B9005CC3B7900A597DFB5 + 18: 3B9247C12BB25DF048BF5541E91E1A78 + 19: 39626488635D0A6224CD23C13B25AE8E + 20: 40305F5C2FCEF34E764E33EF635A3DC5 + 21: F84499804086033E85633A1EF9908617 + 22: C4D263CDC7E0969B8AC6FA9AD9D65CB8 + 23: 6137DC840E61EA6A288D017EFB9646FC + 24: 8619960428EB29B1D5390F40173C152F + 25: F0464509D0FBDBECEC9DFC57A820016D + 26: 630EED23E87059051E564194831BAEF6 + 27: 4B792B412458DC9411F281D5DD3A8DF6 + 28: F2349FA4418BC89853706B35A9F887BA + 29: FEAC41D48AEAB0955745DC2BE1E024D5 + 30: A67A135B4E6043CB7C9CAFBFA25D1828 + 31: EC12C9574BDE5B0001EE3895B53716E2 + 32: 44903C5737EE6B08FD7D7A3937CC840D + +PMAC-safer+ (16 byte key) + 0: E8603C78F9324E9D294DA13C1C6E6E9B + 1: 3F1178DFC2A10567D4BCC817D35D1E16 + 2: 27FE01F90E09237B4B888746199908EE + 3: 4F5172E3D8A58CD775CD480D85E70835 + 4: 74BED75EFAAB3E8AA0027D6730318521 + 5: 54B003AB0BE29B7C69F7C7494E4E9623 + 6: 8A2DAD967747AEA24670141B52494E2F + 7: 69EB054A24EE814E1FB7E78395339781 + 8: E59C2D16B76B700DC62093F0A7F716CC + 9: AB227D6303007FD2001D0B6A9E2BFEB7 + 10: AE107117D9457A1166C6DFD27A819B44 + 11: F84DE551B480CED350458851BAE20541 + 12: B0EB5103E7559B967D06A081665421E0 + 13: CDB14F3AD1170CE8C6091947BE89DE7B + 14: 24FA2F476407094152D528FCF124E438 + 15: 440144B31EC09BD8791BFE02E24EA170 + 16: 697D268A46E8B33CEC0BAB8CAF43F52D + 17: 587CBDE7608449BD162184020FBFCC8D + 18: 3EA999C2169CC65735737F50FCD7956B + 19: C6D692698CD8BEEBF2387C6A35A261B0 + 20: 46DAB3AD3C4E2EF712FAC38F846C63E1 + 21: 7261E68B530D10DDC9AD4C9AB5D95693 + 22: 4D0BA5773E988C2B7B2302BBA0A9D368 + 23: 8617154626362736698613151D1FD03A + 24: 23CF25F68B281E21777DC409FE3B774A + 25: CA626956C97DC4207D968A8CC85940B8 + 26: 24C39BE160BDBB753513F949C238014E + 27: 83CD65C010FB69A77EEDEA022A650530 + 28: 1A72DC8438B927464125C0DFEACDE75D + 29: 546054936A2CB5BFBB5E25FFD07C9B51 + 30: 0EB81A268F1BB91997CB9809D7F9F2AD + 31: 7D08B4DE960CADC483D55745BB4B2C17 + 32: FD45061D378A31D0186598B088F6261B + +PMAC-twofish (16 byte key) + 0: D2D40F078CEDC1A330279CB71B0FF12B + 1: D1C1E80FD5F38212C3527DA3797DA71D + 2: 071118A5A87F637D627E27CB581AD58C + 3: C8CFA166A9B300F720590382CE503B94 + 4: 3965342C5A6AC5F7B0A40DC3B89ED4EB + 5: 6830AB8969796682C3705E368B2BDF74 + 6: FF4DCC4D16B71AFEEA405D0097AD6B89 + 7: ADB77760B079C010889F79AA02190D70 + 8: 5F2FCD6AA2A22CEECAA4671EE0403B88 + 9: 70DD6D396330904A0A03E19046F4C0BF + 10: 8A2C9D88FA0303123275C704445A7F47 + 11: BA0B2F6D029DCD72566821AB884A8427 + 12: C8DF45FF13D7A2E4CFE1546279172300 + 13: 512659AD40DC2B9D31D299A1B00B3DAD + 14: A8A0E99D2E231180949FC4DFB4B79ED4 + 15: CA161AFB2BC7D891AAE268D167897EF2 + 16: D6C19BBDFFC5822663B604B1F836D8BD + 17: 4BF115F409A41A26E89C8D758BBF5F68 + 18: 02E3196D888D5A8DE818DBCBAD6E6DC7 + 19: 995C9DD698EC711A73BD41CAAE8EB633 + 20: A031857FADC8C8AFEABF14EF663A712D + 21: 124695C9A8132618B10E9800A4EFACC5 + 22: 997E5E41798648B8CE0C398EF9135A2C + 23: 42C92154B71FB4E133F8F5B2A2007AB2 + 24: 945DC568188D036AC91051A11AC92BBF + 25: D5A860CC4C3087E9F4988B25D1F7FAAE + 26: 6CD6ABF8EDF3102659AFFBE476E2CBE8 + 27: 45ECD0C37091414E28153AA5AFA3E0B2 + 28: CBA6FE296DDE36FE689C65667F67A038 + 29: C4022281633F2FC438625540B2EE4EB8 + 30: 864E27045F9CC79B5377FDF80A6199CF + 31: 0D06F2FAEC5AA404A4087AAEBC4DBB36 + 32: 0F396FE9E3D9D74D17EB7A0BF603AB51 + +PMAC-safer-k64 (8 byte key) + 0: 2E49792C78C1DA52 + 1: 7A5136F4FE617C57 + 2: 6FC8575F6F3D78EC + 3: 7C0373CAEAAA640B + 4: 9D469E7FF6C35D31 + 5: 7755D62DD7D88112 + 6: ADD9E7855A958C9F + 7: 752D29BA8150F18E + 8: 0954649A99596104 + 9: 05D4D75A9FAE233D + 10: 1AADAFD7B4B250DA + 11: E7A8F31ED74DA32B + 12: 1A74DF61BDB9DF94 + 13: C38A67B1955C4E0D + 14: EBADAA44746ADF16 + 15: C0BFBB092CE81D8E + 16: 984975657F3FF2B0 + +PMAC-safer-sk64 (8 byte key) + 0: E8917E1629E7403E + 1: AE8061A5E412A647 + 2: C969771CE5A9B0C6 + 3: 78159C01D0A3A5CB + 4: 1DD4382A8FC81921 + 5: 4086880FD863C048 + 6: A520B45600A3FA1D + 7: 0F0AB5118D7506C4 + 8: 22E315F2DD03BCC6 + 9: 5ECB5561EE372016 + 10: 446A9B2BCB367AD6 + 11: B2107FE2EB411AE9 + 12: 5A539B62FB5893DF + 13: F44EE1EB3278C2BA + 14: 293FEA56D1F6EA81 + 15: F38F614D2B5F81C4 + 16: AB23F7F8F4C12A7E + +PMAC-safer-k128 (16 byte key) + 0: 7E0BDE11EC82FDE6 + 1: 8942FB017A135520 + 2: 0B073E6D0F037A02 + 3: DBF88439D671ED4F + 4: B89427ED1121069A + 5: AA8573DAC66D2315 + 6: 12DA3144BEF13FF2 + 7: EF80413CBA281B3A + 8: DFA7114D8505EEBD + 9: AE53607F3E6F4A54 + 10: 3F2C9395CFB9F78F + 11: 67EB7C5F02760AED + 12: 3EF4CBB4AB5B8D1F + 13: 83B63AFA78795A92 + 14: 5DE400951766992A + 15: AA8791A45237CF83 + 16: 7743B18704B037CF + +PMAC-safer-sk128 (16 byte key) + 0: 8F1597FFCF6FB7C1 + 1: AFF8BD8FF9F3888A + 2: 65F89D82869D8B42 + 3: CBE1F06476B2D5BD + 4: 4878D47FDFECE23E + 5: 4751A9E6D61AB2A2 + 6: 003AC162AED4DED8 + 7: 1F617A5555092C22 + 8: 088EE0C35B607153 + 9: F840B485086F9908 + 10: BA99E0FB5D7D0976 + 11: F04AF6DC4BAF6887 + 12: 5DBBE40AF2F67E4E + 13: 7F52A93E87E29C9D + 14: 7B26A14A4BD5B709 + 15: C34F26E08C64F26B + 16: 291A41D479EC1D2A + +PMAC-rc2 (8 byte key) + 0: E5AF80FAC4580444 + 1: 6A15D6211EB4FF99 + 2: DDB95E9486C4B034 + 3: 9764761DC2AAD5C0 + 4: 1B1CD2E799D44B4F + 5: 4F80FE32256CF2EC + 6: 7B70CF31C81CD384 + 7: 9BC10DD9332CF3BB + 8: 628189801879FDD8 + 9: 5FC17C555E2AE28B + 10: E20E68327ABEAC32 + 11: 5D375CA59E7E2A7C + 12: A9F4CFC684113161 + 13: 3A0E069940DDD13C + 14: EAC25B6351941674 + 15: CB8B5CF885D838CF + 16: DCBCDDFC06D3DB9A + +PMAC-des (8 byte key) + 0: 086A2A7CFC08E28E + 1: F66A1FB75AF18EC9 + 2: B58561DE2BEB96DF + 3: 9C50856F571B3167 + 4: 6CC645BF3FB00754 + 5: 0E4BEE62B2972C5A + 6: D2215E451649F11F + 7: E83DDC61D12F3995 + 8: 155B20BDA899D2CF + 9: 2567071973052B1D + 10: DB9C20237A2D8575 + 11: DAF4041E5674A48C + 12: 552DB7A627E8ECC4 + 13: 1E8B7F823488DEC0 + 14: 84AA15713793B25D + 15: FCE22E6CAD528B49 + 16: 993884FB9B3FB620 + +PMAC-3des (24 byte key) + 0: E42CCBC9C9457DF6 + 1: FE766F7930557708 + 2: B9011E8AF7CD1E16 + 3: 5AE38B037BEA850B + 4: A6B2C586E1875116 + 5: BF8BA4F1D53A4473 + 6: 3EB4A079E4E39AD5 + 7: 80293018AC36EDBF + 8: CC3F5F62C2CEE93C + 9: EE6AA24CE39BE821 + 10: 487A6EAF915966EA + 11: D94AD6393DF44F00 + 12: F4BFCCC818B4E20D + 13: 2BE9BC57412591AA + 14: 7F7CC8D87F2CDAB7 + 15: B13BFD07E7A202CB + 16: 58A6931335B4B2C2 + +PMAC-cast5 (8 byte key) + 0: 0654F2F4BC1F7470 + 1: 3F725B162A1C8E6B + 2: BCFBDC680A20F379 + 3: 027922705BCACDEE + 4: 44E2F4BE59774BA4 + 5: 3ABD1AFC8EE291F7 + 6: D96347E717921E96 + 7: 96257299FCE55BC6 + 8: C2C1DA176EE98170 + 9: FD415C122E604589 + 10: DCBCA228D45AEDA4 + 11: 7801FBCFAAB9DF75 + 12: D38CB38574474B7F + 13: F5C5A23FF3E80F37 + 14: 83FA4DAD55D092F5 + 15: BDC0A27EE0CB1657 + 16: 87D907CACA80A138 + +PMAC-noekeon (16 byte key) + 0: A1E4C84B5958726557DF0855B37AA551 + 1: 5DE20299CA919D3365B493D3D4895F92 + 2: AF7E70C336571A857F62A18649EDB197 + 3: C5F55CFE1AA119C352B64252AD246CBD + 4: FEF68A0CE08E8BA315B73B62F861824F + 5: 8321C2958DE4903DC12C42A8845ECC20 + 6: 370466D1324AECF1F5B42E0E01381613 + 7: 5CB900190F5CACBACFE5EAB0CC289D87 + 8: A13C043E6CAAA1E34601A93C497446A4 + 9: 865E11622A4CC8A9E1408E00F56C4543 + 10: 9DC42C26868374649BD17D69D025CA1B + 11: 37D33C11B433C91DA09925CA9E86757A + 12: 1373D769C270E7137C953AC0F8F37941 + 13: 7E81DEC583348B1E2F6267ECF82CB994 + 14: 505B6329338556518FF364CAA730F5E8 + 15: 0C085AEEB315968B0BDE904E8BBC6FD0 + 16: 5FED63259364BE7E5133FF0507DD2D4C + 17: F7EE5C80A99AAEADB49E7CC69BFFF679 + 18: 4388FA5E763A641130940EB705BEFD08 + 19: 1BC31CA79EBE1674CEBE01BC9988267B + 20: BE88961637EFFE2D6905D104FEDD51A4 + 21: 9C341004FB22AFCC496094E3207CA761 + 22: B9DAA3620E38FFC7C5D5E7D2D8FE3DE4 + 23: A38D2E571F037061B4400F1131FDBDEA + 24: 61DB71AE77A6EB47F2E9E14E8CBF2F4B + 25: 9903A072274CC048EF2C51493266D9ED + 26: 1EBEA421DD08859C17DDF39B20A82102 + 27: F425858618E1A86F4912E4714EFB9E75 + 28: 3B3D4EA07F7FE6DDFDD02D624ACDFC9F + 29: CEEE256591D701514EB17DF73B08A970 + 30: 5CC56D5D46120C530A23B6C511C685FC + 31: 68E484CE18BE28EADD0BBF23291B8237 + 32: ABD58A9CDF8AA68168A1A402074CF520 + +PMAC-skipjack (10 byte key) + 0: 9CD94B75BC43B647 + 1: B069ACB82B12BC7B + 2: 6DD40E71EB03E311 + 3: 74CBED61D77DBA7D + 4: DD1B7E0D181537FE + 5: ACB5B96FA0AD1786 + 6: B34E01EB2567D381 + 7: 9623DAADE57B9549 + 8: 8BA384BABB798344 + 9: B147AA9D5C5C67CF + 10: 0033C520F4C67523 + 11: 42DAC184BEABC3E5 + 12: 428029311004AEBB + 13: AC2BB1C0F0ED649B + 14: F7CAA9A3BF749C1A + 15: 2C5BD475AAC44C77 + 16: FEB892DA66D31A84 + +PMAC-anubis (16 byte key) + 0: DF33EE541FFEE6A97FE3A1F72F7A38FC + 1: 0AB28675AC3923C6DD9F5A8E1E2928D0 + 2: 2DABF75D6403E1E1CFAB3E6869FB1088 + 3: 95835D49E09740180B79E394FC2AA744 + 4: F364D6DC2C2078A519E5BAEFE858AFCA + 5: DA4C66A4805FC91FABAECC0D3AEAD850 + 6: 487660FADCAC7B326C492AA051A1DF49 + 7: BF07835AA1A548FA7312509AF35CE3F3 + 8: 3CE8A8B1F324A700923AC0B830D53D99 + 9: 3C54D99AACFAB26E34FC1B0B6BB9EB22 + 10: 0A559F9D107ED76FD19227FDD0752B8A + 11: BFD9E74ADC40B9C7446FDD09558FA584 + 12: F1130F663BC0FA3B1066129E0D1910E9 + 13: 535EAD786F0D211DE7AA78F3CB480803 + 14: CDF5855F00A4C310D95B26751B01A28B + 15: EF6686E999D5A9C35A96D25BB9DBBF57 + 16: E795733AA0AAF16D8F7AB1A8E9C55E54 + 17: E03CA85727D5CF06F56BB6465BB3E5C5 + 18: 6EDDDB6D2292EFF584E382E1BACD1A49 + 19: 7B7FE0D8821836C1AA95578071FF2FD2 + 20: 5F8CC568338400746B61A9286B7CF262 + 21: 32DEE5A11E9EDB04BDF911837CE0FA4D + 22: F1A99914F13B17ABF383F36157FEB170 + 23: 99F541647F382390043CAE5332E3114D + 24: 34C5EBB85693A1979F8CFDF8B431A5BB + 25: 1BA7266568F1E7B4A77A869D3021AC0F + 26: 0FC675C99C24E859F8CE714E86BF5289 + 27: CBFAB21F5ABC47356A43BED806D873C0 + 28: 9659AB1A4D334B622629721F98EECE3A + 29: 644C8BEE41F03BDE7652B03CAEA31E37 + 30: 5B3447AFAD934B4D1E4910A8DFD588E7 + 31: BFF403342E8D50D0447627AEA2F56B23 + 32: 19F468F0FB05184D00FABD40A18DB7B2 + +PMAC-khazad (16 byte key) + 0: F40CEF2E392BEAEB + 1: C6E086BD1CFA0992 + 2: 513F2851583AD69A + 3: 07279D57695D78FF + 4: 051E94FE4CC847B6 + 5: 5E9AAA5989D5C951 + 6: 310D5D740143369A + 7: 9BB1EA8ECD4AF34B + 8: CF886800AF0526C8 + 9: 0B03E2C94729E643 + 10: 42815B308A900EC7 + 11: 9A38A58C438D26DD + 12: 044BFF68FD2BFF76 + 13: 7F5ABBDC29852729 + 14: F81A7D6F7B788A5D + 15: 93098DA8A180AA35 + 16: BACE2F4DA8A89E32 + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/notes/tech0001.txt b/xmhf-64/xmhf/third-party/libtomcrypt/notes/tech0001.txt new file mode 100644 index 0000000000..daf7e57a0d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/notes/tech0001.txt @@ -0,0 +1,73 @@ +Tech Note 0001 +How to Gather Entropy on Embedded Systems +Tom St Denis + +Introduction +------------ + +This tech note explains a relatively simple way to gather entropy for a PRNG (Yarrow in this case) in embedded systems +where there are few sources of entropy or physical sources. + +When trying to setup a secure random number generator a fresh source of random data (entropy) is required to ensure the +deterministic state of the PRNG is not known or predetermined with respect to an attacker. + +At the very least the system requires one timer and one source of un-timed interrupts. by "un-timed" I mean interrupts +that do not occur at regular intervals [e.g. joypad/keypad input, network packets, etc...]. + +First we shall begin by taking an overview of how the Yarrow PRNG works within libtomcrypt. At the heart of all +PRNGs is the "prng_state" data type. This is a union of structures that hold the PRNG state for the various prngs. The +first thing we require is a state... + + prng_state myPrng; + +Next we must initialize the state once to get the ball rolling + + if (yarrow_start(&myPrng) != CRYPT_OK) { + // error should never happen! + } + +At this point the PRNG is ready to accept fresh entropy which is added with + + int yarrow_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng) + +This function is **NOT** thread safe which will come under consideration later. To add entropy to our PRNG we must +call this function with fresh data as its sampled. Lets say we have a timer counter called "uTimer" which is a 32-bit +long and say a 32-bit joyPad state called "uPad". An example interrupt handler would look like + + void joypad_interrupt(...) { + unsigned char buf[8]; + + STORE32L(uTimer, buf); + STORE32L(uPad, buf+4) + if (yarrow_add_entropy(buf, 8, &myPrng) != CRYPT_OK) { + // this should never occur either unless you didn't call yarrow_start + } + + // handle interrupt + } + +In this snippet the timer count and state of the joypad are added together into the entropy pool. The timer is important +because with respect to the joypad it is a good source of entropy (on its own its not). For example, the probability of +the user pushing the up arrow is fairly high, but at a specific time is not. + +This method doesn't gather alot of entropy and has to be used to for quite a while. One way to speed it up is to tap +multiple sources. If you have a network adapter and other sources of events (keyboard, mouse, etc...) trapping their +data is ideal as well. Its important to gather the timer along with the event data. + +As mentioned the "yarrow_add_entropy()" function is not thread safe. If your system allows interrupt handlers to be +interrupted themselves then you could have trouble. One simple way is to detect when an interrupt is in progress and +simply not add entropy during the call (jump over the yarrow_add_entropy() call) + +Once you feel that there has been enough entropy added to the pool then within a single thread you can call + + int yarrow_ready(prng_state *prng) + +Now the PRNG is ready to read via the + + unsigned long yarrow_read(unsigned char *buf, unsigned long len, prng_state *prng) + +It is a very good idea that once you call the yarrow_ready() function that you stop harvesting entropy in your interrupt +functions. This will free up alot of CPU time. Also one more final note. The yarrow_read() function is not thread +safe either. This means if you have multiple threads or processes that read from it you will have to add your own semaphores +around calls to it. + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/notes/tech0002.txt b/xmhf-64/xmhf/third-party/libtomcrypt/notes/tech0002.txt new file mode 100644 index 0000000000..b9990e02e4 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/notes/tech0002.txt @@ -0,0 +1,52 @@ +Tech Note 0002 +How to avoid non-intrusive timing attacks with online computations +Tom St Denis + +Introduction +------------ + +A timing attack is when an attacker can observe a side channel of the device (in this case time). In this tech note +we consider only non-intrusive timing attacks with respect to online computations. That is an attacker can +determine when a computation (such as a public key encryption) begins and ends but cannot observe the device +directly. This is specifically important for applications which transmit data via a public network. + +Consider a Diffie-Hellman encryption which requires the sender to make up a public key "y = g^x mod p". Libtomcrypt +uses the MPI bignum library to perform the operation. The time it takes to compute y is controlled by the number +of 1 bits in the exponent 'x'. To a large extent there will be the same number of squaring operations. "1" bits in +the exponent require the sender to perform a multiplication. This means to a certain extent an attacker can +determine not only the magnitude of 'x' but the number of one bits. With this information the attacker cannot directly +learn the key used. However, good cryptography mandates the close scrutiny of any practical side channel. + +Similar logic applies to the other various routines. Fortunately for this case there is a simple solution. First, +determine the maximum time the particular operation can require. For instance, on an Athlon 1.53Ghz XP processor a +DH-768 encryption requires roughly 50 milliseconds. Take that time and round it up. Now place a delay after the call. + +For example, + +void demo(void) { + clock_t t1; + + // get initial clock + t1 = clock(); + + // some PK function + + // now delay + while (clock() < (t1 + 100)); + + // transmit data... + +} + +This code has the effect of taking at least 100 ms always. In effect someone analyzing the traffic will see that the +operations always take a fixed amount of time. Since no two platforms are the same this type of fix has not been +incorporated into libtomcrypt (nor is it desired for many platforms). This requires on the developers part to profile +the code to determine the delays required. + +Note that this "quick" fix has no effect against an intrusive attacker. For example, power consumption will drop +significantly in the loop after the operation. However, this type of fix is more important to secure the user of the +application/device. For example, a user placing an order online won't try to cheat themselves by cracking open their +device and performing side-channel cryptanalysis. An attacker over a network might try to use the timing information +against the user. + + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/notes/tech0003.txt b/xmhf-64/xmhf/third-party/libtomcrypt/notes/tech0003.txt new file mode 100644 index 0000000000..1a21867c9c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/notes/tech0003.txt @@ -0,0 +1,52 @@ +Tech Note 0003 +Minimizing Memory Usage +Tom St Denis + +Introduction +------------ + +For the most part the library can get by with around 20KB of stack and about 32KB of heap even if you use the +public key functions. If all you plan on using are the hashes and ciphers than only about 1KB of stack is required +and no heap. + +To save space all of the symmetric key scheduled keys are stored in a union called "symmetric_key". This means the +size of a symmetric_key is the size of the largest scheduled key. By removing the ciphers you don't use from +the build you can minimize the size of this structure. For instance, by removing both Twofish and Blowfish the +size reduces to 768 bytes from the 4,256 bytes it would have been (on a 32-bit platform). Or if you remove +Blowfish and use Twofish with TWOFISH_SMALL defined its still 768 bytes. Even at its largest the structure is only +4KB which is normally not a problem for any platform. + + +Cipher Name | Size of scheduled key (bytes) | +------------+-------------------------------| +Twofish | 4,256 | +Blowfish | 4,168 | +3DES | 768 | +SAFER+ | 532 | +Serpent | 528 | +Rijndael | 516 | +XTEA | 256 | +RC2 | 256 | +DES | 256 | +SAFER [#] | 217 | +RC5 | 204 | +Twofish [*] | 193 | +RC6 | 176 | +CAST5 | 132 | +Noekeon | 32 | +Skipjack | 10 | +------------+-------------------------------/ +Memory used per cipher on a 32-bit platform. + +[*] For Twofish with TWOFISH_SMALL defined +[#] For all 64-bit SAFER ciphers. + +Noekeon is a fairly fast cipher and uses very little memory. Ideally in low-ram platforms all other ciphers should be +left undefined and Noekeon should remain. While Noekeon is generally considered a secure block cipher (it is insecure +as a hash) CAST5 is perhaps a "runner-up" choice. CAST5 has been around longer (it is also known as CAST-128) and is +fairly fast as well. + +You can easily accomplish this via the "config.pl" script. Simply answer "n" to all of the ciphers except the one you want +and then rebuild the library. [or you can hand edit mycrypt_custom.h] + + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/notes/tech0004.txt b/xmhf-64/xmhf/third-party/libtomcrypt/notes/tech0004.txt new file mode 100644 index 0000000000..2acd3782ff --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/notes/tech0004.txt @@ -0,0 +1,91 @@ +Tech Note 0004 +Using Yarrow, Fortuna and SOBER-128 +Tom St Denis + +Introduction +------------ + +This tech note explains how to use three of the more useful pseudo random number generators and their +own little "issues". While all of the PRNGs have the same API and are roughly used in the same +manner their effectiveness really depends on the user knowing how they work. + + +Yarrow +------ + +Yarrow is by far the simplest of the PRNGs. It gathers bits of entropy by hashing the pool state +plus the additional bits storing the message digest back in the pool. E.g. + +pool = hash(pool || newbits) + +Simply dump bits into the PRNG via yarrow_add_entropy() and call yarrow_ready() when you want to +put them to use. This PRNG while simple is not entirely safe. An attacker who learns the state +of the pool and can control future events can control the PRNG. This requires an active attacker but +isn't entire impossible. + +The pool is then used as a key for a cipher that is used in CTR mode. + +Yarrow is mostly meant for short-term programs [e.g. like file utils]. This particular implementation +is not meant for long-term usage. + +Fortuna +------- + +Fortuna was designed by Niels Fergusson and Bruce Schneier [Bruce is also the guy who invented Yarrow]. It +operates on a more defensive level than Yarrow. Instead of 1 entropy pool it has 32 and the new entropy +is spread [round robin] in all of the pools. + +That is, each call to fortuna_add_entropy() puts the bits in the next [in the sequenece] pool of entropy. +Effective bits are added to the pool by sending them through a hash [but not terminating the hash]. + +Here's the main catch though. When the PRNG must be reseeded [so that you can extract bits from it] only +certain pools are used. More precisely the i'th pool is used every 2**i'th reseeding. For example, pool[0] +is always used. pool[1] is used every second reseeding, pool[2] every fourth. + +The pools are hashed together along with the current key and the result is the new key for a cipher which +operates in CTR mode [more about that in a sec]. + +Now this may seem odd at first however there is a good reason behind it. An attacker who learns pool[0] won't +strictly know the other pools. So the recovery rate of is not 0. In fact pool[0] can be completely +compromised and the PRNG will still eventually recover. The value FORTUNA_WD is the "WatchDog" counter. +Every FORTUNA_WD calls to fortuna_read will invoke the reseed operation. By default this is set to 10 which +means after 10 calls the PRNG will reseed itself. + +The pools are combined with the running cipher key [256 bits] so that a cipher in CTR mode can produce +the stream. Unlike Yarrow the cipher is re-keyed after every call to fortuna_read() [so one big call +would be faster than many smaller calls]. This prevents too much data being encrypted under the same +key [and mitigates a flaw in CTR mode that the same block can't be emitted twice under the same key]. + +Fortuna is really meant for a kernel-level PRNG. The more sources [and often] you feed into it the +healthier it will be. It's also meant to be used for long term purposes. Since it can recover from +compromises it is harder to control it. + +SOBER-128 +------ + +SOBER-128 is actually a stream cipher but like most ciphers can easily be modelled in the context of a PRNG. +This PRNG is extremely fast [4 cycles/byte on a P4] and was designed by a well known cryptographer [Greg Rose]. + +SOBER-128 doesn't really "act" like the other two PRNGs. It's meant to be seeded once and then read as +required. In such a sense it isn't a "system PRNG" but useful short term purposes. In particular +the sober128_read() function actually XORs against the input buffer you specify. This allows the +read() function to be used as an "encrypt" function as well. + +You can only key SOBER-128 once [by calling sober128_add_entropy()]. Once it it is keyed subsequent +calls to add_entropy() will be considered a "re-IV" operation. Changing the IV allows you to use same +initial key and not produce the same output stream. It also lets you differentiate packets. E.g. each +packet has it's own IV. + +All inputs to sober128_add_entropy() must have a length that is a multiple of four. + +Overall +------- + +Since SOBER-128 is *much* faster than the other two PRNGs a good setup would be to use Fortuna as your +system-wide PRNG and use SOBER-128 [key'ed from Fortuna] for encrypting streams or as a PRNG for +simulations. + +Yarrow is still a good candidate but only for "short lived" programs. However, since Fortuna is faster +[by about 10 cycles/byte on a P4] I'd use Fortuna anyways... + +Tom \ No newline at end of file diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/notes/tech0005.txt b/xmhf-64/xmhf/third-party/libtomcrypt/notes/tech0005.txt new file mode 100644 index 0000000000..c2502208cf --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/notes/tech0005.txt @@ -0,0 +1,20 @@ +Tech Note 0005 +Minimizing Code Space +Tom St Denis + +Introduction +------------ + +Tweaking... + +You can disable whole classes of algorithms on the command line with the LTC_NO_* defines. From there you can manually turn on what you want to enable. + +The following build with GCC 3.4.4 on an AMD64 box gets you AES, CTR mode, SHA-256, HMAC, Yarrow, full RSA PKCS #1, PKCS #5 and ASN.1 DER in +roughly 40KB of code (49KB on the ARMv4) (both excluding the math library). + +CFLAGS="-DLTC_NO_CIPHERS -DLTC_NO_HASHES -DLTC_NO_PRNGS -DLTC_NO_MACS -DLTC_NO_MODES -DLTC_NO_PK -DLTC_RIJNDAEL -DLTC_CTR_MODE -DSHA256 \ +-DLTC_HMAC -DYARROW -DMRSA -DMPI -DTFM_DESC -DARGTYPE=3 -Os -DLTC_SMALL_CODE -fomit-frame-pointer" make IGNORE_SPEED=1 + +Obviously this won't get you performance but if you need to pack a crypto lib in a device with limited means it's more than enough... + +Neato eh? diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/notes/tech0006.txt b/xmhf-64/xmhf/third-party/libtomcrypt/notes/tech0006.txt new file mode 100644 index 0000000000..ecbe8b0809 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/notes/tech0006.txt @@ -0,0 +1,91 @@ +Tech Note 0006 +PK Standards Compliance +Tom St Denis + +RSA +---- + +PKCS #1 compliance. + +Key Format: RSAPublicKey and RSAPrivateKey as per PKCS #1 v2.1 +Encryption: OAEP as per PKCS #1 +Signature : PSS as per PKCS #1 + +DSA +---- + +The NIST DSA algorithm + +Key Format: HomeBrew [see below] +Signature : ANSI X9.62 format [see below]. + +Keys are stored as + +DSAPublicKey ::= SEQUENCE { + publicFlags BIT STRING(1), -- must be 0 + g INTEGER , -- base generator, check that g^q mod p == 1 + -- and that 1 < g < p - 1 + p INTEGER , -- prime modulus + q INTEGER , -- order of sub-group (must be prime) + y INTEGER , -- public key, specifically, g^x mod p, + -- check that y^q mod p == 1 + -- and that 1 < y < p - 1 +} + +DSAPrivateKey ::= SEQUENCE { + publicFlags BIT STRING(1), -- must be 1 + g INTEGER , -- base generator, check that g^q mod p == 1 + -- and that 1 < g < p - 1 + p INTEGER , -- prime modulus + q INTEGER , -- order of sub-group (must be prime) + y INTEGER , -- public key, specifically, g^x mod p, + -- check that y^q mod p == 1 + -- and that 1 < y < p - 1 + x INTEGER -- private key +} + +Signatures are stored as + +DSASignature ::= SEQUENCE { + r, s INTEGER -- signature parameters +} + +ECC +---- + +The ANSI X9.62 and X9.63 algorithms [partial]. Supports all NIST GF(p) curves. + +Key Format : Homebrew [see below, only GF(p) NIST curves supported] +Signature : X9.62 compliant +Encryption : Homebrew [based on X9.63, differs in that the public point is stored as an ECCPublicKey] +Shared Secret: X9.63 compliant + +ECCPublicKey ::= SEQUENCE { + flags BIT STRING(1), -- public/private flag (always zero), + keySize INTEGER, -- Curve size (in bits) divided by eight + -- and rounded down, e.g. 521 => 65 + pubkey.x INTEGER, -- The X co-ordinate of the public key point + pubkey.y INTEGER, -- The Y co-ordinate of the public key point +} + +ECCPrivateKey ::= SEQUENCE { + flags BIT STRING(1), -- public/private flag (always one), + keySize INTEGER, -- Curve size (in bits) divided by eight + -- and rounded down, e.g. 521 => 65 + pubkey.x INTEGER, -- The X co-ordinate of the public key point + pubkey.y INTEGER, -- The Y co-ordinate of the public key point + secret.k INTEGER, -- The secret key scalar +} + +The encryption works by finding the X9.63 shared secret and hashing it. The hash is then simply XOR'ed against the message [which must be at most the size +of the hash digest]. The format of the encrypted text is as follows + +ECCEncrypted ::= SEQUENCE { + hashOID OBJECT IDENTIFIER, -- The OID of the hash used + pubkey OCTET STRING , -- Encapsulation of a random ECCPublicKey + skey OCTET STRING -- The encrypted text (which the hash was XOR'ed against) +} + +% $Source: /cvs/libtom/libtomcrypt/notes/tech0006.txt,v $ +% $Revision: 1.2 $ +% $Date: 2005/06/18 02:26:27 $ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/notes/tech0007.txt b/xmhf-64/xmhf/third-party/libtomcrypt/notes/tech0007.txt new file mode 100644 index 0000000000..149bd49df9 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/notes/tech0007.txt @@ -0,0 +1,5 @@ +Tech Note #7 +Quick building for testing with LTM + +EXTRALIBS=-ltommath CFLAGS="-g3 -DLTC_NO_ASM -DUSE_LTM -DLTM_DESC" make -j3 IGNORE_SPEED=1 test + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/parsenames.pl b/xmhf-64/xmhf/third-party/libtomcrypt/parsenames.pl new file mode 100644 index 0000000000..761f036229 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/parsenames.pl @@ -0,0 +1,26 @@ +#!/usr/bin/perl +# +# Splits the list of files and outputs for makefile type files +# wrapped at 80 chars +# +# Tom St Denis +@a = split(" ", $ARGV[1]); +$b = "$ARGV[0]="; +$len = length($b); +print $b; +foreach my $obj (@a) { + $len = $len + length($obj); + $obj =~ s/\*/\$/; + if ($len > 100) { + printf "\\\n"; + $len = length($obj); + } + print "$obj "; +} +if ($ARGV[0] eq "HEADERS") { print "testprof/tomcrypt_test.h"; } + +print "\n\n"; + +# $Source: /cvs/libtom/libtomcrypt/parsenames.pl,v $ +# $Revision: 1.3 $ +# $Date: 2005/05/05 14:49:27 $ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/run.sh b/xmhf-64/xmhf/third-party/libtomcrypt/run.sh new file mode 100644 index 0000000000..dd982e9874 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/run.sh @@ -0,0 +1,35 @@ +#!/bin/bash +bash build.sh " $1" "$2 -O2" "$3 IGNORE_SPEED=1" "$4" "$5" +if [ -a testok.txt ] && [ -f testok.txt ]; then + echo +else + echo + echo "Test failed" + exit 1 +fi + +rm -f testok.txt +bash build.sh " $1" "$2 -Os" " $3 IGNORE_SPEED=1 LTC_SMALL=1" "$4" "$5" +if [ -a testok.txt ] && [ -f testok.txt ]; then + echo +else + echo + echo "Test failed" + exit 1 +fi + +rm -f testok.txt +bash build.sh " $1" " $2" " $3 " "$4" "$5" +if [ -a testok.txt ] && [ -f testok.txt ]; then + echo +else + echo + echo "Test failed" + exit 1 +fi + +exit 0 + +# $Source: /cvs/libtom/libtomcrypt/run.sh,v $ +# $Revision: 1.15 $ +# $Date: 2005/07/23 14:18:31 $ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/aes/aes.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/aes/aes.c new file mode 100644 index 0000000000..31cec093ce --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/aes/aes.c @@ -0,0 +1,760 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* AES implementation by Tom St Denis + * + * Derived from the Public Domain source code by + +--- + * rijndael-alg-fst.c + * + * @version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen + * @author Antoon Bosselaers + * @author Paulo Barreto +--- + */ +/** + @file aes.c + Implementation of AES +*/ + +#include "tomcrypt.h" + +#ifdef LTC_RIJNDAEL + +#ifndef ENCRYPT_ONLY + +#define SETUP rijndael_setup +#define ECB_ENC rijndael_ecb_encrypt +#define ECB_DEC rijndael_ecb_decrypt +#define ECB_DONE rijndael_done +#define ECB_TEST rijndael_test +#define ECB_KS rijndael_keysize + +const struct ltc_cipher_descriptor rijndael_desc = +{ + "rijndael", + 6, + 16, 32, 16, 10, + SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +const struct ltc_cipher_descriptor aes_desc = +{ + "aes", + 6, + 16, 32, 16, 10, + SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +#else + +#define SETUP rijndael_enc_setup +#define ECB_ENC rijndael_enc_ecb_encrypt +#define ECB_KS rijndael_enc_keysize +#define ECB_DONE rijndael_enc_done + +const struct ltc_cipher_descriptor rijndael_enc_desc = +{ + "rijndael", + 6, + 16, 32, 16, 10, + SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +const struct ltc_cipher_descriptor aes_enc_desc = +{ + "aes", + 6, + 16, 32, 16, 10, + SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +#endif + +#include "aes_tab.c" + +static ulong32 setup_mix(ulong32 temp) +{ + return (Te4_3[byte(temp, 2)]) ^ + (Te4_2[byte(temp, 1)]) ^ + (Te4_1[byte(temp, 0)]) ^ + (Te4_0[byte(temp, 3)]); +} + +#ifndef ENCRYPT_ONLY +#ifdef LTC_SMALL_CODE +static ulong32 setup_mix2(ulong32 temp) +{ + return Td0(255 & Te4[byte(temp, 3)]) ^ + Td1(255 & Te4[byte(temp, 2)]) ^ + Td2(255 & Te4[byte(temp, 1)]) ^ + Td3(255 & Te4[byte(temp, 0)]); +} +#endif +#endif + + /** + Initialize the AES (Rijndael) block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int i, j; + ulong32 temp, *rk; +#ifndef ENCRYPT_ONLY + ulong32 *rrk; +#endif + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (keylen != 16 && keylen != 24 && keylen != 32) { + return CRYPT_INVALID_KEYSIZE; + } + + if (num_rounds != 0 && num_rounds != (10 + ((keylen/8)-2)*2)) { + return CRYPT_INVALID_ROUNDS; + } + + skey->rijndael.Nr = 10 + ((keylen/8)-2)*2; + + /* setup the forward key */ + i = 0; + rk = skey->rijndael.eK; + LOAD32H(rk[0], key ); + LOAD32H(rk[1], key + 4); + LOAD32H(rk[2], key + 8); + LOAD32H(rk[3], key + 12); + if (keylen == 16) { + j = 44; + for (;;) { + temp = rk[3]; + rk[4] = rk[0] ^ setup_mix(temp) ^ rcon[i]; + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + if (++i == 10) { + break; + } + rk += 4; + } + } else if (keylen == 24) { + j = 52; + LOAD32H(rk[4], key + 16); + LOAD32H(rk[5], key + 20); + for (;;) { + #ifdef _MSC_VER + temp = skey->rijndael.eK[rk - skey->rijndael.eK + 5]; + #else + temp = rk[5]; + #endif + rk[ 6] = rk[ 0] ^ setup_mix(temp) ^ rcon[i]; + rk[ 7] = rk[ 1] ^ rk[ 6]; + rk[ 8] = rk[ 2] ^ rk[ 7]; + rk[ 9] = rk[ 3] ^ rk[ 8]; + if (++i == 8) { + break; + } + rk[10] = rk[ 4] ^ rk[ 9]; + rk[11] = rk[ 5] ^ rk[10]; + rk += 6; + } + } else if (keylen == 32) { + j = 60; + LOAD32H(rk[4], key + 16); + LOAD32H(rk[5], key + 20); + LOAD32H(rk[6], key + 24); + LOAD32H(rk[7], key + 28); + for (;;) { + #ifdef _MSC_VER + temp = skey->rijndael.eK[rk - skey->rijndael.eK + 7]; + #else + temp = rk[7]; + #endif + rk[ 8] = rk[ 0] ^ setup_mix(temp) ^ rcon[i]; + rk[ 9] = rk[ 1] ^ rk[ 8]; + rk[10] = rk[ 2] ^ rk[ 9]; + rk[11] = rk[ 3] ^ rk[10]; + if (++i == 7) { + break; + } + temp = rk[11]; + rk[12] = rk[ 4] ^ setup_mix(RORc(temp, 8)); + rk[13] = rk[ 5] ^ rk[12]; + rk[14] = rk[ 6] ^ rk[13]; + rk[15] = rk[ 7] ^ rk[14]; + rk += 8; + } + } else { + /* this can't happen */ + return CRYPT_ERROR; + } + +#ifndef ENCRYPT_ONLY + /* setup the inverse key now */ + rk = skey->rijndael.dK; + rrk = skey->rijndael.eK + j - 4; + + /* apply the inverse MixColumn transform to all round keys but the first and the last: */ + /* copy first */ + *rk++ = *rrk++; + *rk++ = *rrk++; + *rk++ = *rrk++; + *rk = *rrk; + rk -= 3; rrk -= 3; + + for (i = 1; i < skey->rijndael.Nr; i++) { + rrk -= 4; + rk += 4; + #ifdef LTC_SMALL_CODE + temp = rrk[0]; + rk[0] = setup_mix2(temp); + temp = rrk[1]; + rk[1] = setup_mix2(temp); + temp = rrk[2]; + rk[2] = setup_mix2(temp); + temp = rrk[3]; + rk[3] = setup_mix2(temp); + #else + temp = rrk[0]; + rk[0] = + Tks0[byte(temp, 3)] ^ + Tks1[byte(temp, 2)] ^ + Tks2[byte(temp, 1)] ^ + Tks3[byte(temp, 0)]; + temp = rrk[1]; + rk[1] = + Tks0[byte(temp, 3)] ^ + Tks1[byte(temp, 2)] ^ + Tks2[byte(temp, 1)] ^ + Tks3[byte(temp, 0)]; + temp = rrk[2]; + rk[2] = + Tks0[byte(temp, 3)] ^ + Tks1[byte(temp, 2)] ^ + Tks2[byte(temp, 1)] ^ + Tks3[byte(temp, 0)]; + temp = rrk[3]; + rk[3] = + Tks0[byte(temp, 3)] ^ + Tks1[byte(temp, 2)] ^ + Tks2[byte(temp, 1)] ^ + Tks3[byte(temp, 0)]; + #endif + + } + + /* copy last */ + rrk -= 4; + rk += 4; + *rk++ = *rrk++; + *rk++ = *rrk++; + *rk++ = *rrk++; + *rk = *rrk; +#endif /* ENCRYPT_ONLY */ + + return CRYPT_OK; +} + +/** + Encrypts a block of text with AES + @param pt The input plaintext (16 bytes) + @param ct The output ciphertext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#else +int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#endif +{ + ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk; + int Nr, r; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + Nr = skey->rijndael.Nr; + rk = skey->rijndael.eK; + + /* + * map byte array block to cipher state + * and add initial round key: + */ + LOAD32H(s0, pt ); s0 ^= rk[0]; + LOAD32H(s1, pt + 4); s1 ^= rk[1]; + LOAD32H(s2, pt + 8); s2 ^= rk[2]; + LOAD32H(s3, pt + 12); s3 ^= rk[3]; + +#ifdef LTC_SMALL_CODE + + for (r = 0; ; r++) { + rk += 4; + t0 = + Te0(byte(s0, 3)) ^ + Te1(byte(s1, 2)) ^ + Te2(byte(s2, 1)) ^ + Te3(byte(s3, 0)) ^ + rk[0]; + t1 = + Te0(byte(s1, 3)) ^ + Te1(byte(s2, 2)) ^ + Te2(byte(s3, 1)) ^ + Te3(byte(s0, 0)) ^ + rk[1]; + t2 = + Te0(byte(s2, 3)) ^ + Te1(byte(s3, 2)) ^ + Te2(byte(s0, 1)) ^ + Te3(byte(s1, 0)) ^ + rk[2]; + t3 = + Te0(byte(s3, 3)) ^ + Te1(byte(s0, 2)) ^ + Te2(byte(s1, 1)) ^ + Te3(byte(s2, 0)) ^ + rk[3]; + if (r == Nr-2) { + break; + } + s0 = t0; s1 = t1; s2 = t2; s3 = t3; + } + rk += 4; + +#else + + /* + * Nr - 1 full rounds: + */ + r = Nr >> 1; + for (;;) { + t0 = + Te0(byte(s0, 3)) ^ + Te1(byte(s1, 2)) ^ + Te2(byte(s2, 1)) ^ + Te3(byte(s3, 0)) ^ + rk[4]; + t1 = + Te0(byte(s1, 3)) ^ + Te1(byte(s2, 2)) ^ + Te2(byte(s3, 1)) ^ + Te3(byte(s0, 0)) ^ + rk[5]; + t2 = + Te0(byte(s2, 3)) ^ + Te1(byte(s3, 2)) ^ + Te2(byte(s0, 1)) ^ + Te3(byte(s1, 0)) ^ + rk[6]; + t3 = + Te0(byte(s3, 3)) ^ + Te1(byte(s0, 2)) ^ + Te2(byte(s1, 1)) ^ + Te3(byte(s2, 0)) ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + s0 = + Te0(byte(t0, 3)) ^ + Te1(byte(t1, 2)) ^ + Te2(byte(t2, 1)) ^ + Te3(byte(t3, 0)) ^ + rk[0]; + s1 = + Te0(byte(t1, 3)) ^ + Te1(byte(t2, 2)) ^ + Te2(byte(t3, 1)) ^ + Te3(byte(t0, 0)) ^ + rk[1]; + s2 = + Te0(byte(t2, 3)) ^ + Te1(byte(t3, 2)) ^ + Te2(byte(t0, 1)) ^ + Te3(byte(t1, 0)) ^ + rk[2]; + s3 = + Te0(byte(t3, 3)) ^ + Te1(byte(t0, 2)) ^ + Te2(byte(t1, 1)) ^ + Te3(byte(t2, 0)) ^ + rk[3]; + } + +#endif + + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = + (Te4_3[byte(t0, 3)]) ^ + (Te4_2[byte(t1, 2)]) ^ + (Te4_1[byte(t2, 1)]) ^ + (Te4_0[byte(t3, 0)]) ^ + rk[0]; + STORE32H(s0, ct); + s1 = + (Te4_3[byte(t1, 3)]) ^ + (Te4_2[byte(t2, 2)]) ^ + (Te4_1[byte(t3, 1)]) ^ + (Te4_0[byte(t0, 0)]) ^ + rk[1]; + STORE32H(s1, ct+4); + s2 = + (Te4_3[byte(t2, 3)]) ^ + (Te4_2[byte(t3, 2)]) ^ + (Te4_1[byte(t0, 1)]) ^ + (Te4_0[byte(t1, 0)]) ^ + rk[2]; + STORE32H(s2, ct+8); + s3 = + (Te4_3[byte(t3, 3)]) ^ + (Te4_2[byte(t0, 2)]) ^ + (Te4_1[byte(t1, 1)]) ^ + (Te4_0[byte(t2, 0)]) ^ + rk[3]; + STORE32H(s3, ct+12); + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + int err = _rijndael_ecb_encrypt(pt, ct, skey); + burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2); + return err; +} +#endif + +#ifndef ENCRYPT_ONLY + +/** + Decrypts a block of text with AES + @param ct The input ciphertext (16 bytes) + @param pt The output plaintext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#else +int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#endif +{ + ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk; + int Nr, r; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + Nr = skey->rijndael.Nr; + rk = skey->rijndael.dK; + + /* + * map byte array block to cipher state + * and add initial round key: + */ + LOAD32H(s0, ct ); s0 ^= rk[0]; + LOAD32H(s1, ct + 4); s1 ^= rk[1]; + LOAD32H(s2, ct + 8); s2 ^= rk[2]; + LOAD32H(s3, ct + 12); s3 ^= rk[3]; + +#ifdef LTC_SMALL_CODE + for (r = 0; ; r++) { + rk += 4; + t0 = + Td0(byte(s0, 3)) ^ + Td1(byte(s3, 2)) ^ + Td2(byte(s2, 1)) ^ + Td3(byte(s1, 0)) ^ + rk[0]; + t1 = + Td0(byte(s1, 3)) ^ + Td1(byte(s0, 2)) ^ + Td2(byte(s3, 1)) ^ + Td3(byte(s2, 0)) ^ + rk[1]; + t2 = + Td0(byte(s2, 3)) ^ + Td1(byte(s1, 2)) ^ + Td2(byte(s0, 1)) ^ + Td3(byte(s3, 0)) ^ + rk[2]; + t3 = + Td0(byte(s3, 3)) ^ + Td1(byte(s2, 2)) ^ + Td2(byte(s1, 1)) ^ + Td3(byte(s0, 0)) ^ + rk[3]; + if (r == Nr-2) { + break; + } + s0 = t0; s1 = t1; s2 = t2; s3 = t3; + } + rk += 4; + +#else + + /* + * Nr - 1 full rounds: + */ + r = Nr >> 1; + for (;;) { + + t0 = + Td0(byte(s0, 3)) ^ + Td1(byte(s3, 2)) ^ + Td2(byte(s2, 1)) ^ + Td3(byte(s1, 0)) ^ + rk[4]; + t1 = + Td0(byte(s1, 3)) ^ + Td1(byte(s0, 2)) ^ + Td2(byte(s3, 1)) ^ + Td3(byte(s2, 0)) ^ + rk[5]; + t2 = + Td0(byte(s2, 3)) ^ + Td1(byte(s1, 2)) ^ + Td2(byte(s0, 1)) ^ + Td3(byte(s3, 0)) ^ + rk[6]; + t3 = + Td0(byte(s3, 3)) ^ + Td1(byte(s2, 2)) ^ + Td2(byte(s1, 1)) ^ + Td3(byte(s0, 0)) ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + + s0 = + Td0(byte(t0, 3)) ^ + Td1(byte(t3, 2)) ^ + Td2(byte(t2, 1)) ^ + Td3(byte(t1, 0)) ^ + rk[0]; + s1 = + Td0(byte(t1, 3)) ^ + Td1(byte(t0, 2)) ^ + Td2(byte(t3, 1)) ^ + Td3(byte(t2, 0)) ^ + rk[1]; + s2 = + Td0(byte(t2, 3)) ^ + Td1(byte(t1, 2)) ^ + Td2(byte(t0, 1)) ^ + Td3(byte(t3, 0)) ^ + rk[2]; + s3 = + Td0(byte(t3, 3)) ^ + Td1(byte(t2, 2)) ^ + Td2(byte(t1, 1)) ^ + Td3(byte(t0, 0)) ^ + rk[3]; + } +#endif + + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = + (Td4[byte(t0, 3)] & 0xff000000) ^ + (Td4[byte(t3, 2)] & 0x00ff0000) ^ + (Td4[byte(t2, 1)] & 0x0000ff00) ^ + (Td4[byte(t1, 0)] & 0x000000ff) ^ + rk[0]; + STORE32H(s0, pt); + s1 = + (Td4[byte(t1, 3)] & 0xff000000) ^ + (Td4[byte(t0, 2)] & 0x00ff0000) ^ + (Td4[byte(t3, 1)] & 0x0000ff00) ^ + (Td4[byte(t2, 0)] & 0x000000ff) ^ + rk[1]; + STORE32H(s1, pt+4); + s2 = + (Td4[byte(t2, 3)] & 0xff000000) ^ + (Td4[byte(t1, 2)] & 0x00ff0000) ^ + (Td4[byte(t0, 1)] & 0x0000ff00) ^ + (Td4[byte(t3, 0)] & 0x000000ff) ^ + rk[2]; + STORE32H(s2, pt+8); + s3 = + (Td4[byte(t3, 3)] & 0xff000000) ^ + (Td4[byte(t2, 2)] & 0x00ff0000) ^ + (Td4[byte(t1, 1)] & 0x0000ff00) ^ + (Td4[byte(t0, 0)] & 0x000000ff) ^ + rk[3]; + STORE32H(s3, pt+12); + + return CRYPT_OK; +} + + +#ifdef LTC_CLEAN_STACK +int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + int err = _rijndael_ecb_decrypt(ct, pt, skey); + burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2); + return err; +} +#endif + +/** + Performs a self-test of the AES block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int ECB_TEST(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + int err; + static const struct { + int keylen; + unsigned char key[32], pt[16], ct[16]; + } tests[] = { + { 16, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, + 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a } + }, { + 24, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 }, + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, + 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 } + }, { + 32, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, + 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 } + } + }; + + symmetric_key key; + unsigned char tmp[2][16]; + int i, y; + + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { + zeromem(&key, sizeof(key)); + if ((err = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { + return err; + } + + rijndael_ecb_encrypt(tests[i].pt, tmp[0], &key); + rijndael_ecb_decrypt(tmp[0], tmp[1], &key); + if (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) { +#if 0 + printf("\n\nTest %d failed\n", i); + if (XMEMCMP(tmp[0], tests[i].ct, 16)) { + printf("CT: "); + for (i = 0; i < 16; i++) { + printf("%02x ", tmp[0][i]); + } + printf("\n"); + } else { + printf("PT: "); + for (i = 0; i < 16; i++) { + printf("%02x ", tmp[1][i]); + } + printf("\n"); + } +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 16; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) rijndael_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) rijndael_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +#endif /* ENCRYPT_ONLY */ + + +/** Terminate the context + @param skey The scheduled key +*/ +void ECB_DONE(symmetric_key *skey) +{ +} + + +/** + Gets suitable key size + @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. + @return CRYPT_OK if the input key size is acceptable. +*/ +int ECB_KS(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + + if (*keysize < 16) + return CRYPT_INVALID_KEYSIZE; + if (*keysize < 24) { + *keysize = 16; + return CRYPT_OK; + } else if (*keysize < 32) { + *keysize = 24; + return CRYPT_OK; + } else { + *keysize = 32; + return CRYPT_OK; + } +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/aes/aes.c,v $ */ +/* $Revision: 1.16 $ */ +/* $Date: 2007/05/12 14:13:00 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/aes/aes_tab.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/aes/aes_tab.c new file mode 100644 index 0000000000..99bac9a83b --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/aes/aes_tab.c @@ -0,0 +1,1028 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +/* The precomputed tables for AES */ +/* +Te0[x] = S [x].[02, 01, 01, 03]; +Te1[x] = S [x].[03, 02, 01, 01]; +Te2[x] = S [x].[01, 03, 02, 01]; +Te3[x] = S [x].[01, 01, 03, 02]; +Te4[x] = S [x].[01, 01, 01, 01]; + +Td0[x] = Si[x].[0e, 09, 0d, 0b]; +Td1[x] = Si[x].[0b, 0e, 09, 0d]; +Td2[x] = Si[x].[0d, 0b, 0e, 09]; +Td3[x] = Si[x].[09, 0d, 0b, 0e]; +Td4[x] = Si[x].[01, 01, 01, 01]; +*/ + +/** + @file aes_tab.c + AES tables +*/ +static const ulong32 TE0[256] = { + 0xc66363a5UL, 0xf87c7c84UL, 0xee777799UL, 0xf67b7b8dUL, + 0xfff2f20dUL, 0xd66b6bbdUL, 0xde6f6fb1UL, 0x91c5c554UL, + 0x60303050UL, 0x02010103UL, 0xce6767a9UL, 0x562b2b7dUL, + 0xe7fefe19UL, 0xb5d7d762UL, 0x4dababe6UL, 0xec76769aUL, + 0x8fcaca45UL, 0x1f82829dUL, 0x89c9c940UL, 0xfa7d7d87UL, + 0xeffafa15UL, 0xb25959ebUL, 0x8e4747c9UL, 0xfbf0f00bUL, + 0x41adadecUL, 0xb3d4d467UL, 0x5fa2a2fdUL, 0x45afafeaUL, + 0x239c9cbfUL, 0x53a4a4f7UL, 0xe4727296UL, 0x9bc0c05bUL, + 0x75b7b7c2UL, 0xe1fdfd1cUL, 0x3d9393aeUL, 0x4c26266aUL, + 0x6c36365aUL, 0x7e3f3f41UL, 0xf5f7f702UL, 0x83cccc4fUL, + 0x6834345cUL, 0x51a5a5f4UL, 0xd1e5e534UL, 0xf9f1f108UL, + 0xe2717193UL, 0xabd8d873UL, 0x62313153UL, 0x2a15153fUL, + 0x0804040cUL, 0x95c7c752UL, 0x46232365UL, 0x9dc3c35eUL, + 0x30181828UL, 0x379696a1UL, 0x0a05050fUL, 0x2f9a9ab5UL, + 0x0e070709UL, 0x24121236UL, 0x1b80809bUL, 0xdfe2e23dUL, + 0xcdebeb26UL, 0x4e272769UL, 0x7fb2b2cdUL, 0xea75759fUL, + 0x1209091bUL, 0x1d83839eUL, 0x582c2c74UL, 0x341a1a2eUL, + 0x361b1b2dUL, 0xdc6e6eb2UL, 0xb45a5aeeUL, 0x5ba0a0fbUL, + 0xa45252f6UL, 0x763b3b4dUL, 0xb7d6d661UL, 0x7db3b3ceUL, + 0x5229297bUL, 0xdde3e33eUL, 0x5e2f2f71UL, 0x13848497UL, + 0xa65353f5UL, 0xb9d1d168UL, 0x00000000UL, 0xc1eded2cUL, + 0x40202060UL, 0xe3fcfc1fUL, 0x79b1b1c8UL, 0xb65b5bedUL, + 0xd46a6abeUL, 0x8dcbcb46UL, 0x67bebed9UL, 0x7239394bUL, + 0x944a4adeUL, 0x984c4cd4UL, 0xb05858e8UL, 0x85cfcf4aUL, + 0xbbd0d06bUL, 0xc5efef2aUL, 0x4faaaae5UL, 0xedfbfb16UL, + 0x864343c5UL, 0x9a4d4dd7UL, 0x66333355UL, 0x11858594UL, + 0x8a4545cfUL, 0xe9f9f910UL, 0x04020206UL, 0xfe7f7f81UL, + 0xa05050f0UL, 0x783c3c44UL, 0x259f9fbaUL, 0x4ba8a8e3UL, + 0xa25151f3UL, 0x5da3a3feUL, 0x804040c0UL, 0x058f8f8aUL, + 0x3f9292adUL, 0x219d9dbcUL, 0x70383848UL, 0xf1f5f504UL, + 0x63bcbcdfUL, 0x77b6b6c1UL, 0xafdada75UL, 0x42212163UL, + 0x20101030UL, 0xe5ffff1aUL, 0xfdf3f30eUL, 0xbfd2d26dUL, + 0x81cdcd4cUL, 0x180c0c14UL, 0x26131335UL, 0xc3ecec2fUL, + 0xbe5f5fe1UL, 0x359797a2UL, 0x884444ccUL, 0x2e171739UL, + 0x93c4c457UL, 0x55a7a7f2UL, 0xfc7e7e82UL, 0x7a3d3d47UL, + 0xc86464acUL, 0xba5d5de7UL, 0x3219192bUL, 0xe6737395UL, + 0xc06060a0UL, 0x19818198UL, 0x9e4f4fd1UL, 0xa3dcdc7fUL, + 0x44222266UL, 0x542a2a7eUL, 0x3b9090abUL, 0x0b888883UL, + 0x8c4646caUL, 0xc7eeee29UL, 0x6bb8b8d3UL, 0x2814143cUL, + 0xa7dede79UL, 0xbc5e5ee2UL, 0x160b0b1dUL, 0xaddbdb76UL, + 0xdbe0e03bUL, 0x64323256UL, 0x743a3a4eUL, 0x140a0a1eUL, + 0x924949dbUL, 0x0c06060aUL, 0x4824246cUL, 0xb85c5ce4UL, + 0x9fc2c25dUL, 0xbdd3d36eUL, 0x43acacefUL, 0xc46262a6UL, + 0x399191a8UL, 0x319595a4UL, 0xd3e4e437UL, 0xf279798bUL, + 0xd5e7e732UL, 0x8bc8c843UL, 0x6e373759UL, 0xda6d6db7UL, + 0x018d8d8cUL, 0xb1d5d564UL, 0x9c4e4ed2UL, 0x49a9a9e0UL, + 0xd86c6cb4UL, 0xac5656faUL, 0xf3f4f407UL, 0xcfeaea25UL, + 0xca6565afUL, 0xf47a7a8eUL, 0x47aeaee9UL, 0x10080818UL, + 0x6fbabad5UL, 0xf0787888UL, 0x4a25256fUL, 0x5c2e2e72UL, + 0x381c1c24UL, 0x57a6a6f1UL, 0x73b4b4c7UL, 0x97c6c651UL, + 0xcbe8e823UL, 0xa1dddd7cUL, 0xe874749cUL, 0x3e1f1f21UL, + 0x964b4bddUL, 0x61bdbddcUL, 0x0d8b8b86UL, 0x0f8a8a85UL, + 0xe0707090UL, 0x7c3e3e42UL, 0x71b5b5c4UL, 0xcc6666aaUL, + 0x904848d8UL, 0x06030305UL, 0xf7f6f601UL, 0x1c0e0e12UL, + 0xc26161a3UL, 0x6a35355fUL, 0xae5757f9UL, 0x69b9b9d0UL, + 0x17868691UL, 0x99c1c158UL, 0x3a1d1d27UL, 0x279e9eb9UL, + 0xd9e1e138UL, 0xebf8f813UL, 0x2b9898b3UL, 0x22111133UL, + 0xd26969bbUL, 0xa9d9d970UL, 0x078e8e89UL, 0x339494a7UL, + 0x2d9b9bb6UL, 0x3c1e1e22UL, 0x15878792UL, 0xc9e9e920UL, + 0x87cece49UL, 0xaa5555ffUL, 0x50282878UL, 0xa5dfdf7aUL, + 0x038c8c8fUL, 0x59a1a1f8UL, 0x09898980UL, 0x1a0d0d17UL, + 0x65bfbfdaUL, 0xd7e6e631UL, 0x844242c6UL, 0xd06868b8UL, + 0x824141c3UL, 0x299999b0UL, 0x5a2d2d77UL, 0x1e0f0f11UL, + 0x7bb0b0cbUL, 0xa85454fcUL, 0x6dbbbbd6UL, 0x2c16163aUL, +}; + +#ifndef PELI_TAB +static const ulong32 Te4[256] = { + 0x63636363UL, 0x7c7c7c7cUL, 0x77777777UL, 0x7b7b7b7bUL, + 0xf2f2f2f2UL, 0x6b6b6b6bUL, 0x6f6f6f6fUL, 0xc5c5c5c5UL, + 0x30303030UL, 0x01010101UL, 0x67676767UL, 0x2b2b2b2bUL, + 0xfefefefeUL, 0xd7d7d7d7UL, 0xababababUL, 0x76767676UL, + 0xcacacacaUL, 0x82828282UL, 0xc9c9c9c9UL, 0x7d7d7d7dUL, + 0xfafafafaUL, 0x59595959UL, 0x47474747UL, 0xf0f0f0f0UL, + 0xadadadadUL, 0xd4d4d4d4UL, 0xa2a2a2a2UL, 0xafafafafUL, + 0x9c9c9c9cUL, 0xa4a4a4a4UL, 0x72727272UL, 0xc0c0c0c0UL, + 0xb7b7b7b7UL, 0xfdfdfdfdUL, 0x93939393UL, 0x26262626UL, + 0x36363636UL, 0x3f3f3f3fUL, 0xf7f7f7f7UL, 0xccccccccUL, + 0x34343434UL, 0xa5a5a5a5UL, 0xe5e5e5e5UL, 0xf1f1f1f1UL, + 0x71717171UL, 0xd8d8d8d8UL, 0x31313131UL, 0x15151515UL, + 0x04040404UL, 0xc7c7c7c7UL, 0x23232323UL, 0xc3c3c3c3UL, + 0x18181818UL, 0x96969696UL, 0x05050505UL, 0x9a9a9a9aUL, + 0x07070707UL, 0x12121212UL, 0x80808080UL, 0xe2e2e2e2UL, + 0xebebebebUL, 0x27272727UL, 0xb2b2b2b2UL, 0x75757575UL, + 0x09090909UL, 0x83838383UL, 0x2c2c2c2cUL, 0x1a1a1a1aUL, + 0x1b1b1b1bUL, 0x6e6e6e6eUL, 0x5a5a5a5aUL, 0xa0a0a0a0UL, + 0x52525252UL, 0x3b3b3b3bUL, 0xd6d6d6d6UL, 0xb3b3b3b3UL, + 0x29292929UL, 0xe3e3e3e3UL, 0x2f2f2f2fUL, 0x84848484UL, + 0x53535353UL, 0xd1d1d1d1UL, 0x00000000UL, 0xededededUL, + 0x20202020UL, 0xfcfcfcfcUL, 0xb1b1b1b1UL, 0x5b5b5b5bUL, + 0x6a6a6a6aUL, 0xcbcbcbcbUL, 0xbebebebeUL, 0x39393939UL, + 0x4a4a4a4aUL, 0x4c4c4c4cUL, 0x58585858UL, 0xcfcfcfcfUL, + 0xd0d0d0d0UL, 0xefefefefUL, 0xaaaaaaaaUL, 0xfbfbfbfbUL, + 0x43434343UL, 0x4d4d4d4dUL, 0x33333333UL, 0x85858585UL, + 0x45454545UL, 0xf9f9f9f9UL, 0x02020202UL, 0x7f7f7f7fUL, + 0x50505050UL, 0x3c3c3c3cUL, 0x9f9f9f9fUL, 0xa8a8a8a8UL, + 0x51515151UL, 0xa3a3a3a3UL, 0x40404040UL, 0x8f8f8f8fUL, + 0x92929292UL, 0x9d9d9d9dUL, 0x38383838UL, 0xf5f5f5f5UL, + 0xbcbcbcbcUL, 0xb6b6b6b6UL, 0xdadadadaUL, 0x21212121UL, + 0x10101010UL, 0xffffffffUL, 0xf3f3f3f3UL, 0xd2d2d2d2UL, + 0xcdcdcdcdUL, 0x0c0c0c0cUL, 0x13131313UL, 0xececececUL, + 0x5f5f5f5fUL, 0x97979797UL, 0x44444444UL, 0x17171717UL, + 0xc4c4c4c4UL, 0xa7a7a7a7UL, 0x7e7e7e7eUL, 0x3d3d3d3dUL, + 0x64646464UL, 0x5d5d5d5dUL, 0x19191919UL, 0x73737373UL, + 0x60606060UL, 0x81818181UL, 0x4f4f4f4fUL, 0xdcdcdcdcUL, + 0x22222222UL, 0x2a2a2a2aUL, 0x90909090UL, 0x88888888UL, + 0x46464646UL, 0xeeeeeeeeUL, 0xb8b8b8b8UL, 0x14141414UL, + 0xdedededeUL, 0x5e5e5e5eUL, 0x0b0b0b0bUL, 0xdbdbdbdbUL, + 0xe0e0e0e0UL, 0x32323232UL, 0x3a3a3a3aUL, 0x0a0a0a0aUL, + 0x49494949UL, 0x06060606UL, 0x24242424UL, 0x5c5c5c5cUL, + 0xc2c2c2c2UL, 0xd3d3d3d3UL, 0xacacacacUL, 0x62626262UL, + 0x91919191UL, 0x95959595UL, 0xe4e4e4e4UL, 0x79797979UL, + 0xe7e7e7e7UL, 0xc8c8c8c8UL, 0x37373737UL, 0x6d6d6d6dUL, + 0x8d8d8d8dUL, 0xd5d5d5d5UL, 0x4e4e4e4eUL, 0xa9a9a9a9UL, + 0x6c6c6c6cUL, 0x56565656UL, 0xf4f4f4f4UL, 0xeaeaeaeaUL, + 0x65656565UL, 0x7a7a7a7aUL, 0xaeaeaeaeUL, 0x08080808UL, + 0xbabababaUL, 0x78787878UL, 0x25252525UL, 0x2e2e2e2eUL, + 0x1c1c1c1cUL, 0xa6a6a6a6UL, 0xb4b4b4b4UL, 0xc6c6c6c6UL, + 0xe8e8e8e8UL, 0xddddddddUL, 0x74747474UL, 0x1f1f1f1fUL, + 0x4b4b4b4bUL, 0xbdbdbdbdUL, 0x8b8b8b8bUL, 0x8a8a8a8aUL, + 0x70707070UL, 0x3e3e3e3eUL, 0xb5b5b5b5UL, 0x66666666UL, + 0x48484848UL, 0x03030303UL, 0xf6f6f6f6UL, 0x0e0e0e0eUL, + 0x61616161UL, 0x35353535UL, 0x57575757UL, 0xb9b9b9b9UL, + 0x86868686UL, 0xc1c1c1c1UL, 0x1d1d1d1dUL, 0x9e9e9e9eUL, + 0xe1e1e1e1UL, 0xf8f8f8f8UL, 0x98989898UL, 0x11111111UL, + 0x69696969UL, 0xd9d9d9d9UL, 0x8e8e8e8eUL, 0x94949494UL, + 0x9b9b9b9bUL, 0x1e1e1e1eUL, 0x87878787UL, 0xe9e9e9e9UL, + 0xcecececeUL, 0x55555555UL, 0x28282828UL, 0xdfdfdfdfUL, + 0x8c8c8c8cUL, 0xa1a1a1a1UL, 0x89898989UL, 0x0d0d0d0dUL, + 0xbfbfbfbfUL, 0xe6e6e6e6UL, 0x42424242UL, 0x68686868UL, + 0x41414141UL, 0x99999999UL, 0x2d2d2d2dUL, 0x0f0f0f0fUL, + 0xb0b0b0b0UL, 0x54545454UL, 0xbbbbbbbbUL, 0x16161616UL, +}; +#endif + +#ifndef ENCRYPT_ONLY + +static const ulong32 TD0[256] = { + 0x51f4a750UL, 0x7e416553UL, 0x1a17a4c3UL, 0x3a275e96UL, + 0x3bab6bcbUL, 0x1f9d45f1UL, 0xacfa58abUL, 0x4be30393UL, + 0x2030fa55UL, 0xad766df6UL, 0x88cc7691UL, 0xf5024c25UL, + 0x4fe5d7fcUL, 0xc52acbd7UL, 0x26354480UL, 0xb562a38fUL, + 0xdeb15a49UL, 0x25ba1b67UL, 0x45ea0e98UL, 0x5dfec0e1UL, + 0xc32f7502UL, 0x814cf012UL, 0x8d4697a3UL, 0x6bd3f9c6UL, + 0x038f5fe7UL, 0x15929c95UL, 0xbf6d7aebUL, 0x955259daUL, + 0xd4be832dUL, 0x587421d3UL, 0x49e06929UL, 0x8ec9c844UL, + 0x75c2896aUL, 0xf48e7978UL, 0x99583e6bUL, 0x27b971ddUL, + 0xbee14fb6UL, 0xf088ad17UL, 0xc920ac66UL, 0x7dce3ab4UL, + 0x63df4a18UL, 0xe51a3182UL, 0x97513360UL, 0x62537f45UL, + 0xb16477e0UL, 0xbb6bae84UL, 0xfe81a01cUL, 0xf9082b94UL, + 0x70486858UL, 0x8f45fd19UL, 0x94de6c87UL, 0x527bf8b7UL, + 0xab73d323UL, 0x724b02e2UL, 0xe31f8f57UL, 0x6655ab2aUL, + 0xb2eb2807UL, 0x2fb5c203UL, 0x86c57b9aUL, 0xd33708a5UL, + 0x302887f2UL, 0x23bfa5b2UL, 0x02036abaUL, 0xed16825cUL, + 0x8acf1c2bUL, 0xa779b492UL, 0xf307f2f0UL, 0x4e69e2a1UL, + 0x65daf4cdUL, 0x0605bed5UL, 0xd134621fUL, 0xc4a6fe8aUL, + 0x342e539dUL, 0xa2f355a0UL, 0x058ae132UL, 0xa4f6eb75UL, + 0x0b83ec39UL, 0x4060efaaUL, 0x5e719f06UL, 0xbd6e1051UL, + 0x3e218af9UL, 0x96dd063dUL, 0xdd3e05aeUL, 0x4de6bd46UL, + 0x91548db5UL, 0x71c45d05UL, 0x0406d46fUL, 0x605015ffUL, + 0x1998fb24UL, 0xd6bde997UL, 0x894043ccUL, 0x67d99e77UL, + 0xb0e842bdUL, 0x07898b88UL, 0xe7195b38UL, 0x79c8eedbUL, + 0xa17c0a47UL, 0x7c420fe9UL, 0xf8841ec9UL, 0x00000000UL, + 0x09808683UL, 0x322bed48UL, 0x1e1170acUL, 0x6c5a724eUL, + 0xfd0efffbUL, 0x0f853856UL, 0x3daed51eUL, 0x362d3927UL, + 0x0a0fd964UL, 0x685ca621UL, 0x9b5b54d1UL, 0x24362e3aUL, + 0x0c0a67b1UL, 0x9357e70fUL, 0xb4ee96d2UL, 0x1b9b919eUL, + 0x80c0c54fUL, 0x61dc20a2UL, 0x5a774b69UL, 0x1c121a16UL, + 0xe293ba0aUL, 0xc0a02ae5UL, 0x3c22e043UL, 0x121b171dUL, + 0x0e090d0bUL, 0xf28bc7adUL, 0x2db6a8b9UL, 0x141ea9c8UL, + 0x57f11985UL, 0xaf75074cUL, 0xee99ddbbUL, 0xa37f60fdUL, + 0xf701269fUL, 0x5c72f5bcUL, 0x44663bc5UL, 0x5bfb7e34UL, + 0x8b432976UL, 0xcb23c6dcUL, 0xb6edfc68UL, 0xb8e4f163UL, + 0xd731dccaUL, 0x42638510UL, 0x13972240UL, 0x84c61120UL, + 0x854a247dUL, 0xd2bb3df8UL, 0xaef93211UL, 0xc729a16dUL, + 0x1d9e2f4bUL, 0xdcb230f3UL, 0x0d8652ecUL, 0x77c1e3d0UL, + 0x2bb3166cUL, 0xa970b999UL, 0x119448faUL, 0x47e96422UL, + 0xa8fc8cc4UL, 0xa0f03f1aUL, 0x567d2cd8UL, 0x223390efUL, + 0x87494ec7UL, 0xd938d1c1UL, 0x8ccaa2feUL, 0x98d40b36UL, + 0xa6f581cfUL, 0xa57ade28UL, 0xdab78e26UL, 0x3fadbfa4UL, + 0x2c3a9de4UL, 0x5078920dUL, 0x6a5fcc9bUL, 0x547e4662UL, + 0xf68d13c2UL, 0x90d8b8e8UL, 0x2e39f75eUL, 0x82c3aff5UL, + 0x9f5d80beUL, 0x69d0937cUL, 0x6fd52da9UL, 0xcf2512b3UL, + 0xc8ac993bUL, 0x10187da7UL, 0xe89c636eUL, 0xdb3bbb7bUL, + 0xcd267809UL, 0x6e5918f4UL, 0xec9ab701UL, 0x834f9aa8UL, + 0xe6956e65UL, 0xaaffe67eUL, 0x21bccf08UL, 0xef15e8e6UL, + 0xbae79bd9UL, 0x4a6f36ceUL, 0xea9f09d4UL, 0x29b07cd6UL, + 0x31a4b2afUL, 0x2a3f2331UL, 0xc6a59430UL, 0x35a266c0UL, + 0x744ebc37UL, 0xfc82caa6UL, 0xe090d0b0UL, 0x33a7d815UL, + 0xf104984aUL, 0x41ecdaf7UL, 0x7fcd500eUL, 0x1791f62fUL, + 0x764dd68dUL, 0x43efb04dUL, 0xccaa4d54UL, 0xe49604dfUL, + 0x9ed1b5e3UL, 0x4c6a881bUL, 0xc12c1fb8UL, 0x4665517fUL, + 0x9d5eea04UL, 0x018c355dUL, 0xfa877473UL, 0xfb0b412eUL, + 0xb3671d5aUL, 0x92dbd252UL, 0xe9105633UL, 0x6dd64713UL, + 0x9ad7618cUL, 0x37a10c7aUL, 0x59f8148eUL, 0xeb133c89UL, + 0xcea927eeUL, 0xb761c935UL, 0xe11ce5edUL, 0x7a47b13cUL, + 0x9cd2df59UL, 0x55f2733fUL, 0x1814ce79UL, 0x73c737bfUL, + 0x53f7cdeaUL, 0x5ffdaa5bUL, 0xdf3d6f14UL, 0x7844db86UL, + 0xcaaff381UL, 0xb968c43eUL, 0x3824342cUL, 0xc2a3405fUL, + 0x161dc372UL, 0xbce2250cUL, 0x283c498bUL, 0xff0d9541UL, + 0x39a80171UL, 0x080cb3deUL, 0xd8b4e49cUL, 0x6456c190UL, + 0x7bcb8461UL, 0xd532b670UL, 0x486c5c74UL, 0xd0b85742UL, +}; + +static const ulong32 Td4[256] = { + 0x52525252UL, 0x09090909UL, 0x6a6a6a6aUL, 0xd5d5d5d5UL, + 0x30303030UL, 0x36363636UL, 0xa5a5a5a5UL, 0x38383838UL, + 0xbfbfbfbfUL, 0x40404040UL, 0xa3a3a3a3UL, 0x9e9e9e9eUL, + 0x81818181UL, 0xf3f3f3f3UL, 0xd7d7d7d7UL, 0xfbfbfbfbUL, + 0x7c7c7c7cUL, 0xe3e3e3e3UL, 0x39393939UL, 0x82828282UL, + 0x9b9b9b9bUL, 0x2f2f2f2fUL, 0xffffffffUL, 0x87878787UL, + 0x34343434UL, 0x8e8e8e8eUL, 0x43434343UL, 0x44444444UL, + 0xc4c4c4c4UL, 0xdedededeUL, 0xe9e9e9e9UL, 0xcbcbcbcbUL, + 0x54545454UL, 0x7b7b7b7bUL, 0x94949494UL, 0x32323232UL, + 0xa6a6a6a6UL, 0xc2c2c2c2UL, 0x23232323UL, 0x3d3d3d3dUL, + 0xeeeeeeeeUL, 0x4c4c4c4cUL, 0x95959595UL, 0x0b0b0b0bUL, + 0x42424242UL, 0xfafafafaUL, 0xc3c3c3c3UL, 0x4e4e4e4eUL, + 0x08080808UL, 0x2e2e2e2eUL, 0xa1a1a1a1UL, 0x66666666UL, + 0x28282828UL, 0xd9d9d9d9UL, 0x24242424UL, 0xb2b2b2b2UL, + 0x76767676UL, 0x5b5b5b5bUL, 0xa2a2a2a2UL, 0x49494949UL, + 0x6d6d6d6dUL, 0x8b8b8b8bUL, 0xd1d1d1d1UL, 0x25252525UL, + 0x72727272UL, 0xf8f8f8f8UL, 0xf6f6f6f6UL, 0x64646464UL, + 0x86868686UL, 0x68686868UL, 0x98989898UL, 0x16161616UL, + 0xd4d4d4d4UL, 0xa4a4a4a4UL, 0x5c5c5c5cUL, 0xccccccccUL, + 0x5d5d5d5dUL, 0x65656565UL, 0xb6b6b6b6UL, 0x92929292UL, + 0x6c6c6c6cUL, 0x70707070UL, 0x48484848UL, 0x50505050UL, + 0xfdfdfdfdUL, 0xededededUL, 0xb9b9b9b9UL, 0xdadadadaUL, + 0x5e5e5e5eUL, 0x15151515UL, 0x46464646UL, 0x57575757UL, + 0xa7a7a7a7UL, 0x8d8d8d8dUL, 0x9d9d9d9dUL, 0x84848484UL, + 0x90909090UL, 0xd8d8d8d8UL, 0xababababUL, 0x00000000UL, + 0x8c8c8c8cUL, 0xbcbcbcbcUL, 0xd3d3d3d3UL, 0x0a0a0a0aUL, + 0xf7f7f7f7UL, 0xe4e4e4e4UL, 0x58585858UL, 0x05050505UL, + 0xb8b8b8b8UL, 0xb3b3b3b3UL, 0x45454545UL, 0x06060606UL, + 0xd0d0d0d0UL, 0x2c2c2c2cUL, 0x1e1e1e1eUL, 0x8f8f8f8fUL, + 0xcacacacaUL, 0x3f3f3f3fUL, 0x0f0f0f0fUL, 0x02020202UL, + 0xc1c1c1c1UL, 0xafafafafUL, 0xbdbdbdbdUL, 0x03030303UL, + 0x01010101UL, 0x13131313UL, 0x8a8a8a8aUL, 0x6b6b6b6bUL, + 0x3a3a3a3aUL, 0x91919191UL, 0x11111111UL, 0x41414141UL, + 0x4f4f4f4fUL, 0x67676767UL, 0xdcdcdcdcUL, 0xeaeaeaeaUL, + 0x97979797UL, 0xf2f2f2f2UL, 0xcfcfcfcfUL, 0xcecececeUL, + 0xf0f0f0f0UL, 0xb4b4b4b4UL, 0xe6e6e6e6UL, 0x73737373UL, + 0x96969696UL, 0xacacacacUL, 0x74747474UL, 0x22222222UL, + 0xe7e7e7e7UL, 0xadadadadUL, 0x35353535UL, 0x85858585UL, + 0xe2e2e2e2UL, 0xf9f9f9f9UL, 0x37373737UL, 0xe8e8e8e8UL, + 0x1c1c1c1cUL, 0x75757575UL, 0xdfdfdfdfUL, 0x6e6e6e6eUL, + 0x47474747UL, 0xf1f1f1f1UL, 0x1a1a1a1aUL, 0x71717171UL, + 0x1d1d1d1dUL, 0x29292929UL, 0xc5c5c5c5UL, 0x89898989UL, + 0x6f6f6f6fUL, 0xb7b7b7b7UL, 0x62626262UL, 0x0e0e0e0eUL, + 0xaaaaaaaaUL, 0x18181818UL, 0xbebebebeUL, 0x1b1b1b1bUL, + 0xfcfcfcfcUL, 0x56565656UL, 0x3e3e3e3eUL, 0x4b4b4b4bUL, + 0xc6c6c6c6UL, 0xd2d2d2d2UL, 0x79797979UL, 0x20202020UL, + 0x9a9a9a9aUL, 0xdbdbdbdbUL, 0xc0c0c0c0UL, 0xfefefefeUL, + 0x78787878UL, 0xcdcdcdcdUL, 0x5a5a5a5aUL, 0xf4f4f4f4UL, + 0x1f1f1f1fUL, 0xddddddddUL, 0xa8a8a8a8UL, 0x33333333UL, + 0x88888888UL, 0x07070707UL, 0xc7c7c7c7UL, 0x31313131UL, + 0xb1b1b1b1UL, 0x12121212UL, 0x10101010UL, 0x59595959UL, + 0x27272727UL, 0x80808080UL, 0xececececUL, 0x5f5f5f5fUL, + 0x60606060UL, 0x51515151UL, 0x7f7f7f7fUL, 0xa9a9a9a9UL, + 0x19191919UL, 0xb5b5b5b5UL, 0x4a4a4a4aUL, 0x0d0d0d0dUL, + 0x2d2d2d2dUL, 0xe5e5e5e5UL, 0x7a7a7a7aUL, 0x9f9f9f9fUL, + 0x93939393UL, 0xc9c9c9c9UL, 0x9c9c9c9cUL, 0xefefefefUL, + 0xa0a0a0a0UL, 0xe0e0e0e0UL, 0x3b3b3b3bUL, 0x4d4d4d4dUL, + 0xaeaeaeaeUL, 0x2a2a2a2aUL, 0xf5f5f5f5UL, 0xb0b0b0b0UL, + 0xc8c8c8c8UL, 0xebebebebUL, 0xbbbbbbbbUL, 0x3c3c3c3cUL, + 0x83838383UL, 0x53535353UL, 0x99999999UL, 0x61616161UL, + 0x17171717UL, 0x2b2b2b2bUL, 0x04040404UL, 0x7e7e7e7eUL, + 0xbabababaUL, 0x77777777UL, 0xd6d6d6d6UL, 0x26262626UL, + 0xe1e1e1e1UL, 0x69696969UL, 0x14141414UL, 0x63636363UL, + 0x55555555UL, 0x21212121UL, 0x0c0c0c0cUL, 0x7d7d7d7dUL, +}; + +#endif /* ENCRYPT_ONLY */ + +#ifdef LTC_SMALL_CODE + +#define Te0(x) TE0[x] +#define Te1(x) RORc(TE0[x], 8) +#define Te2(x) RORc(TE0[x], 16) +#define Te3(x) RORc(TE0[x], 24) + +#define Td0(x) TD0[x] +#define Td1(x) RORc(TD0[x], 8) +#define Td2(x) RORc(TD0[x], 16) +#define Td3(x) RORc(TD0[x], 24) + +#define Te4_0 0x000000FF & Te4 +#define Te4_1 0x0000FF00 & Te4 +#define Te4_2 0x00FF0000 & Te4 +#define Te4_3 0xFF000000 & Te4 + +#else + +#define Te0(x) TE0[x] +#define Te1(x) TE1[x] +#define Te2(x) TE2[x] +#define Te3(x) TE3[x] + +#define Td0(x) TD0[x] +#define Td1(x) TD1[x] +#define Td2(x) TD2[x] +#define Td3(x) TD3[x] + +static const ulong32 TE1[256] = { + 0xa5c66363UL, 0x84f87c7cUL, 0x99ee7777UL, 0x8df67b7bUL, + 0x0dfff2f2UL, 0xbdd66b6bUL, 0xb1de6f6fUL, 0x5491c5c5UL, + 0x50603030UL, 0x03020101UL, 0xa9ce6767UL, 0x7d562b2bUL, + 0x19e7fefeUL, 0x62b5d7d7UL, 0xe64dababUL, 0x9aec7676UL, + 0x458fcacaUL, 0x9d1f8282UL, 0x4089c9c9UL, 0x87fa7d7dUL, + 0x15effafaUL, 0xebb25959UL, 0xc98e4747UL, 0x0bfbf0f0UL, + 0xec41adadUL, 0x67b3d4d4UL, 0xfd5fa2a2UL, 0xea45afafUL, + 0xbf239c9cUL, 0xf753a4a4UL, 0x96e47272UL, 0x5b9bc0c0UL, + 0xc275b7b7UL, 0x1ce1fdfdUL, 0xae3d9393UL, 0x6a4c2626UL, + 0x5a6c3636UL, 0x417e3f3fUL, 0x02f5f7f7UL, 0x4f83ccccUL, + 0x5c683434UL, 0xf451a5a5UL, 0x34d1e5e5UL, 0x08f9f1f1UL, + 0x93e27171UL, 0x73abd8d8UL, 0x53623131UL, 0x3f2a1515UL, + 0x0c080404UL, 0x5295c7c7UL, 0x65462323UL, 0x5e9dc3c3UL, + 0x28301818UL, 0xa1379696UL, 0x0f0a0505UL, 0xb52f9a9aUL, + 0x090e0707UL, 0x36241212UL, 0x9b1b8080UL, 0x3ddfe2e2UL, + 0x26cdebebUL, 0x694e2727UL, 0xcd7fb2b2UL, 0x9fea7575UL, + 0x1b120909UL, 0x9e1d8383UL, 0x74582c2cUL, 0x2e341a1aUL, + 0x2d361b1bUL, 0xb2dc6e6eUL, 0xeeb45a5aUL, 0xfb5ba0a0UL, + 0xf6a45252UL, 0x4d763b3bUL, 0x61b7d6d6UL, 0xce7db3b3UL, + 0x7b522929UL, 0x3edde3e3UL, 0x715e2f2fUL, 0x97138484UL, + 0xf5a65353UL, 0x68b9d1d1UL, 0x00000000UL, 0x2cc1ededUL, + 0x60402020UL, 0x1fe3fcfcUL, 0xc879b1b1UL, 0xedb65b5bUL, + 0xbed46a6aUL, 0x468dcbcbUL, 0xd967bebeUL, 0x4b723939UL, + 0xde944a4aUL, 0xd4984c4cUL, 0xe8b05858UL, 0x4a85cfcfUL, + 0x6bbbd0d0UL, 0x2ac5efefUL, 0xe54faaaaUL, 0x16edfbfbUL, + 0xc5864343UL, 0xd79a4d4dUL, 0x55663333UL, 0x94118585UL, + 0xcf8a4545UL, 0x10e9f9f9UL, 0x06040202UL, 0x81fe7f7fUL, + 0xf0a05050UL, 0x44783c3cUL, 0xba259f9fUL, 0xe34ba8a8UL, + 0xf3a25151UL, 0xfe5da3a3UL, 0xc0804040UL, 0x8a058f8fUL, + 0xad3f9292UL, 0xbc219d9dUL, 0x48703838UL, 0x04f1f5f5UL, + 0xdf63bcbcUL, 0xc177b6b6UL, 0x75afdadaUL, 0x63422121UL, + 0x30201010UL, 0x1ae5ffffUL, 0x0efdf3f3UL, 0x6dbfd2d2UL, + 0x4c81cdcdUL, 0x14180c0cUL, 0x35261313UL, 0x2fc3ececUL, + 0xe1be5f5fUL, 0xa2359797UL, 0xcc884444UL, 0x392e1717UL, + 0x5793c4c4UL, 0xf255a7a7UL, 0x82fc7e7eUL, 0x477a3d3dUL, + 0xacc86464UL, 0xe7ba5d5dUL, 0x2b321919UL, 0x95e67373UL, + 0xa0c06060UL, 0x98198181UL, 0xd19e4f4fUL, 0x7fa3dcdcUL, + 0x66442222UL, 0x7e542a2aUL, 0xab3b9090UL, 0x830b8888UL, + 0xca8c4646UL, 0x29c7eeeeUL, 0xd36bb8b8UL, 0x3c281414UL, + 0x79a7dedeUL, 0xe2bc5e5eUL, 0x1d160b0bUL, 0x76addbdbUL, + 0x3bdbe0e0UL, 0x56643232UL, 0x4e743a3aUL, 0x1e140a0aUL, + 0xdb924949UL, 0x0a0c0606UL, 0x6c482424UL, 0xe4b85c5cUL, + 0x5d9fc2c2UL, 0x6ebdd3d3UL, 0xef43acacUL, 0xa6c46262UL, + 0xa8399191UL, 0xa4319595UL, 0x37d3e4e4UL, 0x8bf27979UL, + 0x32d5e7e7UL, 0x438bc8c8UL, 0x596e3737UL, 0xb7da6d6dUL, + 0x8c018d8dUL, 0x64b1d5d5UL, 0xd29c4e4eUL, 0xe049a9a9UL, + 0xb4d86c6cUL, 0xfaac5656UL, 0x07f3f4f4UL, 0x25cfeaeaUL, + 0xafca6565UL, 0x8ef47a7aUL, 0xe947aeaeUL, 0x18100808UL, + 0xd56fbabaUL, 0x88f07878UL, 0x6f4a2525UL, 0x725c2e2eUL, + 0x24381c1cUL, 0xf157a6a6UL, 0xc773b4b4UL, 0x5197c6c6UL, + 0x23cbe8e8UL, 0x7ca1ddddUL, 0x9ce87474UL, 0x213e1f1fUL, + 0xdd964b4bUL, 0xdc61bdbdUL, 0x860d8b8bUL, 0x850f8a8aUL, + 0x90e07070UL, 0x427c3e3eUL, 0xc471b5b5UL, 0xaacc6666UL, + 0xd8904848UL, 0x05060303UL, 0x01f7f6f6UL, 0x121c0e0eUL, + 0xa3c26161UL, 0x5f6a3535UL, 0xf9ae5757UL, 0xd069b9b9UL, + 0x91178686UL, 0x5899c1c1UL, 0x273a1d1dUL, 0xb9279e9eUL, + 0x38d9e1e1UL, 0x13ebf8f8UL, 0xb32b9898UL, 0x33221111UL, + 0xbbd26969UL, 0x70a9d9d9UL, 0x89078e8eUL, 0xa7339494UL, + 0xb62d9b9bUL, 0x223c1e1eUL, 0x92158787UL, 0x20c9e9e9UL, + 0x4987ceceUL, 0xffaa5555UL, 0x78502828UL, 0x7aa5dfdfUL, + 0x8f038c8cUL, 0xf859a1a1UL, 0x80098989UL, 0x171a0d0dUL, + 0xda65bfbfUL, 0x31d7e6e6UL, 0xc6844242UL, 0xb8d06868UL, + 0xc3824141UL, 0xb0299999UL, 0x775a2d2dUL, 0x111e0f0fUL, + 0xcb7bb0b0UL, 0xfca85454UL, 0xd66dbbbbUL, 0x3a2c1616UL, +}; +static const ulong32 TE2[256] = { + 0x63a5c663UL, 0x7c84f87cUL, 0x7799ee77UL, 0x7b8df67bUL, + 0xf20dfff2UL, 0x6bbdd66bUL, 0x6fb1de6fUL, 0xc55491c5UL, + 0x30506030UL, 0x01030201UL, 0x67a9ce67UL, 0x2b7d562bUL, + 0xfe19e7feUL, 0xd762b5d7UL, 0xabe64dabUL, 0x769aec76UL, + 0xca458fcaUL, 0x829d1f82UL, 0xc94089c9UL, 0x7d87fa7dUL, + 0xfa15effaUL, 0x59ebb259UL, 0x47c98e47UL, 0xf00bfbf0UL, + 0xadec41adUL, 0xd467b3d4UL, 0xa2fd5fa2UL, 0xafea45afUL, + 0x9cbf239cUL, 0xa4f753a4UL, 0x7296e472UL, 0xc05b9bc0UL, + 0xb7c275b7UL, 0xfd1ce1fdUL, 0x93ae3d93UL, 0x266a4c26UL, + 0x365a6c36UL, 0x3f417e3fUL, 0xf702f5f7UL, 0xcc4f83ccUL, + 0x345c6834UL, 0xa5f451a5UL, 0xe534d1e5UL, 0xf108f9f1UL, + 0x7193e271UL, 0xd873abd8UL, 0x31536231UL, 0x153f2a15UL, + 0x040c0804UL, 0xc75295c7UL, 0x23654623UL, 0xc35e9dc3UL, + 0x18283018UL, 0x96a13796UL, 0x050f0a05UL, 0x9ab52f9aUL, + 0x07090e07UL, 0x12362412UL, 0x809b1b80UL, 0xe23ddfe2UL, + 0xeb26cdebUL, 0x27694e27UL, 0xb2cd7fb2UL, 0x759fea75UL, + 0x091b1209UL, 0x839e1d83UL, 0x2c74582cUL, 0x1a2e341aUL, + 0x1b2d361bUL, 0x6eb2dc6eUL, 0x5aeeb45aUL, 0xa0fb5ba0UL, + 0x52f6a452UL, 0x3b4d763bUL, 0xd661b7d6UL, 0xb3ce7db3UL, + 0x297b5229UL, 0xe33edde3UL, 0x2f715e2fUL, 0x84971384UL, + 0x53f5a653UL, 0xd168b9d1UL, 0x00000000UL, 0xed2cc1edUL, + 0x20604020UL, 0xfc1fe3fcUL, 0xb1c879b1UL, 0x5bedb65bUL, + 0x6abed46aUL, 0xcb468dcbUL, 0xbed967beUL, 0x394b7239UL, + 0x4ade944aUL, 0x4cd4984cUL, 0x58e8b058UL, 0xcf4a85cfUL, + 0xd06bbbd0UL, 0xef2ac5efUL, 0xaae54faaUL, 0xfb16edfbUL, + 0x43c58643UL, 0x4dd79a4dUL, 0x33556633UL, 0x85941185UL, + 0x45cf8a45UL, 0xf910e9f9UL, 0x02060402UL, 0x7f81fe7fUL, + 0x50f0a050UL, 0x3c44783cUL, 0x9fba259fUL, 0xa8e34ba8UL, + 0x51f3a251UL, 0xa3fe5da3UL, 0x40c08040UL, 0x8f8a058fUL, + 0x92ad3f92UL, 0x9dbc219dUL, 0x38487038UL, 0xf504f1f5UL, + 0xbcdf63bcUL, 0xb6c177b6UL, 0xda75afdaUL, 0x21634221UL, + 0x10302010UL, 0xff1ae5ffUL, 0xf30efdf3UL, 0xd26dbfd2UL, + 0xcd4c81cdUL, 0x0c14180cUL, 0x13352613UL, 0xec2fc3ecUL, + 0x5fe1be5fUL, 0x97a23597UL, 0x44cc8844UL, 0x17392e17UL, + 0xc45793c4UL, 0xa7f255a7UL, 0x7e82fc7eUL, 0x3d477a3dUL, + 0x64acc864UL, 0x5de7ba5dUL, 0x192b3219UL, 0x7395e673UL, + 0x60a0c060UL, 0x81981981UL, 0x4fd19e4fUL, 0xdc7fa3dcUL, + 0x22664422UL, 0x2a7e542aUL, 0x90ab3b90UL, 0x88830b88UL, + 0x46ca8c46UL, 0xee29c7eeUL, 0xb8d36bb8UL, 0x143c2814UL, + 0xde79a7deUL, 0x5ee2bc5eUL, 0x0b1d160bUL, 0xdb76addbUL, + 0xe03bdbe0UL, 0x32566432UL, 0x3a4e743aUL, 0x0a1e140aUL, + 0x49db9249UL, 0x060a0c06UL, 0x246c4824UL, 0x5ce4b85cUL, + 0xc25d9fc2UL, 0xd36ebdd3UL, 0xacef43acUL, 0x62a6c462UL, + 0x91a83991UL, 0x95a43195UL, 0xe437d3e4UL, 0x798bf279UL, + 0xe732d5e7UL, 0xc8438bc8UL, 0x37596e37UL, 0x6db7da6dUL, + 0x8d8c018dUL, 0xd564b1d5UL, 0x4ed29c4eUL, 0xa9e049a9UL, + 0x6cb4d86cUL, 0x56faac56UL, 0xf407f3f4UL, 0xea25cfeaUL, + 0x65afca65UL, 0x7a8ef47aUL, 0xaee947aeUL, 0x08181008UL, + 0xbad56fbaUL, 0x7888f078UL, 0x256f4a25UL, 0x2e725c2eUL, + 0x1c24381cUL, 0xa6f157a6UL, 0xb4c773b4UL, 0xc65197c6UL, + 0xe823cbe8UL, 0xdd7ca1ddUL, 0x749ce874UL, 0x1f213e1fUL, + 0x4bdd964bUL, 0xbddc61bdUL, 0x8b860d8bUL, 0x8a850f8aUL, + 0x7090e070UL, 0x3e427c3eUL, 0xb5c471b5UL, 0x66aacc66UL, + 0x48d89048UL, 0x03050603UL, 0xf601f7f6UL, 0x0e121c0eUL, + 0x61a3c261UL, 0x355f6a35UL, 0x57f9ae57UL, 0xb9d069b9UL, + 0x86911786UL, 0xc15899c1UL, 0x1d273a1dUL, 0x9eb9279eUL, + 0xe138d9e1UL, 0xf813ebf8UL, 0x98b32b98UL, 0x11332211UL, + 0x69bbd269UL, 0xd970a9d9UL, 0x8e89078eUL, 0x94a73394UL, + 0x9bb62d9bUL, 0x1e223c1eUL, 0x87921587UL, 0xe920c9e9UL, + 0xce4987ceUL, 0x55ffaa55UL, 0x28785028UL, 0xdf7aa5dfUL, + 0x8c8f038cUL, 0xa1f859a1UL, 0x89800989UL, 0x0d171a0dUL, + 0xbfda65bfUL, 0xe631d7e6UL, 0x42c68442UL, 0x68b8d068UL, + 0x41c38241UL, 0x99b02999UL, 0x2d775a2dUL, 0x0f111e0fUL, + 0xb0cb7bb0UL, 0x54fca854UL, 0xbbd66dbbUL, 0x163a2c16UL, +}; +static const ulong32 TE3[256] = { + + 0x6363a5c6UL, 0x7c7c84f8UL, 0x777799eeUL, 0x7b7b8df6UL, + 0xf2f20dffUL, 0x6b6bbdd6UL, 0x6f6fb1deUL, 0xc5c55491UL, + 0x30305060UL, 0x01010302UL, 0x6767a9ceUL, 0x2b2b7d56UL, + 0xfefe19e7UL, 0xd7d762b5UL, 0xababe64dUL, 0x76769aecUL, + 0xcaca458fUL, 0x82829d1fUL, 0xc9c94089UL, 0x7d7d87faUL, + 0xfafa15efUL, 0x5959ebb2UL, 0x4747c98eUL, 0xf0f00bfbUL, + 0xadadec41UL, 0xd4d467b3UL, 0xa2a2fd5fUL, 0xafafea45UL, + 0x9c9cbf23UL, 0xa4a4f753UL, 0x727296e4UL, 0xc0c05b9bUL, + 0xb7b7c275UL, 0xfdfd1ce1UL, 0x9393ae3dUL, 0x26266a4cUL, + 0x36365a6cUL, 0x3f3f417eUL, 0xf7f702f5UL, 0xcccc4f83UL, + 0x34345c68UL, 0xa5a5f451UL, 0xe5e534d1UL, 0xf1f108f9UL, + 0x717193e2UL, 0xd8d873abUL, 0x31315362UL, 0x15153f2aUL, + 0x04040c08UL, 0xc7c75295UL, 0x23236546UL, 0xc3c35e9dUL, + 0x18182830UL, 0x9696a137UL, 0x05050f0aUL, 0x9a9ab52fUL, + 0x0707090eUL, 0x12123624UL, 0x80809b1bUL, 0xe2e23ddfUL, + 0xebeb26cdUL, 0x2727694eUL, 0xb2b2cd7fUL, 0x75759feaUL, + 0x09091b12UL, 0x83839e1dUL, 0x2c2c7458UL, 0x1a1a2e34UL, + 0x1b1b2d36UL, 0x6e6eb2dcUL, 0x5a5aeeb4UL, 0xa0a0fb5bUL, + 0x5252f6a4UL, 0x3b3b4d76UL, 0xd6d661b7UL, 0xb3b3ce7dUL, + 0x29297b52UL, 0xe3e33eddUL, 0x2f2f715eUL, 0x84849713UL, + 0x5353f5a6UL, 0xd1d168b9UL, 0x00000000UL, 0xeded2cc1UL, + 0x20206040UL, 0xfcfc1fe3UL, 0xb1b1c879UL, 0x5b5bedb6UL, + 0x6a6abed4UL, 0xcbcb468dUL, 0xbebed967UL, 0x39394b72UL, + 0x4a4ade94UL, 0x4c4cd498UL, 0x5858e8b0UL, 0xcfcf4a85UL, + 0xd0d06bbbUL, 0xefef2ac5UL, 0xaaaae54fUL, 0xfbfb16edUL, + 0x4343c586UL, 0x4d4dd79aUL, 0x33335566UL, 0x85859411UL, + 0x4545cf8aUL, 0xf9f910e9UL, 0x02020604UL, 0x7f7f81feUL, + 0x5050f0a0UL, 0x3c3c4478UL, 0x9f9fba25UL, 0xa8a8e34bUL, + 0x5151f3a2UL, 0xa3a3fe5dUL, 0x4040c080UL, 0x8f8f8a05UL, + 0x9292ad3fUL, 0x9d9dbc21UL, 0x38384870UL, 0xf5f504f1UL, + 0xbcbcdf63UL, 0xb6b6c177UL, 0xdada75afUL, 0x21216342UL, + 0x10103020UL, 0xffff1ae5UL, 0xf3f30efdUL, 0xd2d26dbfUL, + 0xcdcd4c81UL, 0x0c0c1418UL, 0x13133526UL, 0xecec2fc3UL, + 0x5f5fe1beUL, 0x9797a235UL, 0x4444cc88UL, 0x1717392eUL, + 0xc4c45793UL, 0xa7a7f255UL, 0x7e7e82fcUL, 0x3d3d477aUL, + 0x6464acc8UL, 0x5d5de7baUL, 0x19192b32UL, 0x737395e6UL, + 0x6060a0c0UL, 0x81819819UL, 0x4f4fd19eUL, 0xdcdc7fa3UL, + 0x22226644UL, 0x2a2a7e54UL, 0x9090ab3bUL, 0x8888830bUL, + 0x4646ca8cUL, 0xeeee29c7UL, 0xb8b8d36bUL, 0x14143c28UL, + 0xdede79a7UL, 0x5e5ee2bcUL, 0x0b0b1d16UL, 0xdbdb76adUL, + 0xe0e03bdbUL, 0x32325664UL, 0x3a3a4e74UL, 0x0a0a1e14UL, + 0x4949db92UL, 0x06060a0cUL, 0x24246c48UL, 0x5c5ce4b8UL, + 0xc2c25d9fUL, 0xd3d36ebdUL, 0xacacef43UL, 0x6262a6c4UL, + 0x9191a839UL, 0x9595a431UL, 0xe4e437d3UL, 0x79798bf2UL, + 0xe7e732d5UL, 0xc8c8438bUL, 0x3737596eUL, 0x6d6db7daUL, + 0x8d8d8c01UL, 0xd5d564b1UL, 0x4e4ed29cUL, 0xa9a9e049UL, + 0x6c6cb4d8UL, 0x5656faacUL, 0xf4f407f3UL, 0xeaea25cfUL, + 0x6565afcaUL, 0x7a7a8ef4UL, 0xaeaee947UL, 0x08081810UL, + 0xbabad56fUL, 0x787888f0UL, 0x25256f4aUL, 0x2e2e725cUL, + 0x1c1c2438UL, 0xa6a6f157UL, 0xb4b4c773UL, 0xc6c65197UL, + 0xe8e823cbUL, 0xdddd7ca1UL, 0x74749ce8UL, 0x1f1f213eUL, + 0x4b4bdd96UL, 0xbdbddc61UL, 0x8b8b860dUL, 0x8a8a850fUL, + 0x707090e0UL, 0x3e3e427cUL, 0xb5b5c471UL, 0x6666aaccUL, + 0x4848d890UL, 0x03030506UL, 0xf6f601f7UL, 0x0e0e121cUL, + 0x6161a3c2UL, 0x35355f6aUL, 0x5757f9aeUL, 0xb9b9d069UL, + 0x86869117UL, 0xc1c15899UL, 0x1d1d273aUL, 0x9e9eb927UL, + 0xe1e138d9UL, 0xf8f813ebUL, 0x9898b32bUL, 0x11113322UL, + 0x6969bbd2UL, 0xd9d970a9UL, 0x8e8e8907UL, 0x9494a733UL, + 0x9b9bb62dUL, 0x1e1e223cUL, 0x87879215UL, 0xe9e920c9UL, + 0xcece4987UL, 0x5555ffaaUL, 0x28287850UL, 0xdfdf7aa5UL, + 0x8c8c8f03UL, 0xa1a1f859UL, 0x89898009UL, 0x0d0d171aUL, + 0xbfbfda65UL, 0xe6e631d7UL, 0x4242c684UL, 0x6868b8d0UL, + 0x4141c382UL, 0x9999b029UL, 0x2d2d775aUL, 0x0f0f111eUL, + 0xb0b0cb7bUL, 0x5454fca8UL, 0xbbbbd66dUL, 0x16163a2cUL, +}; + +#ifndef PELI_TAB +static const ulong32 Te4_0[] = { +0x00000063UL, 0x0000007cUL, 0x00000077UL, 0x0000007bUL, 0x000000f2UL, 0x0000006bUL, 0x0000006fUL, 0x000000c5UL, +0x00000030UL, 0x00000001UL, 0x00000067UL, 0x0000002bUL, 0x000000feUL, 0x000000d7UL, 0x000000abUL, 0x00000076UL, +0x000000caUL, 0x00000082UL, 0x000000c9UL, 0x0000007dUL, 0x000000faUL, 0x00000059UL, 0x00000047UL, 0x000000f0UL, +0x000000adUL, 0x000000d4UL, 0x000000a2UL, 0x000000afUL, 0x0000009cUL, 0x000000a4UL, 0x00000072UL, 0x000000c0UL, +0x000000b7UL, 0x000000fdUL, 0x00000093UL, 0x00000026UL, 0x00000036UL, 0x0000003fUL, 0x000000f7UL, 0x000000ccUL, +0x00000034UL, 0x000000a5UL, 0x000000e5UL, 0x000000f1UL, 0x00000071UL, 0x000000d8UL, 0x00000031UL, 0x00000015UL, +0x00000004UL, 0x000000c7UL, 0x00000023UL, 0x000000c3UL, 0x00000018UL, 0x00000096UL, 0x00000005UL, 0x0000009aUL, +0x00000007UL, 0x00000012UL, 0x00000080UL, 0x000000e2UL, 0x000000ebUL, 0x00000027UL, 0x000000b2UL, 0x00000075UL, +0x00000009UL, 0x00000083UL, 0x0000002cUL, 0x0000001aUL, 0x0000001bUL, 0x0000006eUL, 0x0000005aUL, 0x000000a0UL, +0x00000052UL, 0x0000003bUL, 0x000000d6UL, 0x000000b3UL, 0x00000029UL, 0x000000e3UL, 0x0000002fUL, 0x00000084UL, +0x00000053UL, 0x000000d1UL, 0x00000000UL, 0x000000edUL, 0x00000020UL, 0x000000fcUL, 0x000000b1UL, 0x0000005bUL, +0x0000006aUL, 0x000000cbUL, 0x000000beUL, 0x00000039UL, 0x0000004aUL, 0x0000004cUL, 0x00000058UL, 0x000000cfUL, +0x000000d0UL, 0x000000efUL, 0x000000aaUL, 0x000000fbUL, 0x00000043UL, 0x0000004dUL, 0x00000033UL, 0x00000085UL, +0x00000045UL, 0x000000f9UL, 0x00000002UL, 0x0000007fUL, 0x00000050UL, 0x0000003cUL, 0x0000009fUL, 0x000000a8UL, +0x00000051UL, 0x000000a3UL, 0x00000040UL, 0x0000008fUL, 0x00000092UL, 0x0000009dUL, 0x00000038UL, 0x000000f5UL, +0x000000bcUL, 0x000000b6UL, 0x000000daUL, 0x00000021UL, 0x00000010UL, 0x000000ffUL, 0x000000f3UL, 0x000000d2UL, +0x000000cdUL, 0x0000000cUL, 0x00000013UL, 0x000000ecUL, 0x0000005fUL, 0x00000097UL, 0x00000044UL, 0x00000017UL, +0x000000c4UL, 0x000000a7UL, 0x0000007eUL, 0x0000003dUL, 0x00000064UL, 0x0000005dUL, 0x00000019UL, 0x00000073UL, +0x00000060UL, 0x00000081UL, 0x0000004fUL, 0x000000dcUL, 0x00000022UL, 0x0000002aUL, 0x00000090UL, 0x00000088UL, +0x00000046UL, 0x000000eeUL, 0x000000b8UL, 0x00000014UL, 0x000000deUL, 0x0000005eUL, 0x0000000bUL, 0x000000dbUL, +0x000000e0UL, 0x00000032UL, 0x0000003aUL, 0x0000000aUL, 0x00000049UL, 0x00000006UL, 0x00000024UL, 0x0000005cUL, +0x000000c2UL, 0x000000d3UL, 0x000000acUL, 0x00000062UL, 0x00000091UL, 0x00000095UL, 0x000000e4UL, 0x00000079UL, +0x000000e7UL, 0x000000c8UL, 0x00000037UL, 0x0000006dUL, 0x0000008dUL, 0x000000d5UL, 0x0000004eUL, 0x000000a9UL, +0x0000006cUL, 0x00000056UL, 0x000000f4UL, 0x000000eaUL, 0x00000065UL, 0x0000007aUL, 0x000000aeUL, 0x00000008UL, +0x000000baUL, 0x00000078UL, 0x00000025UL, 0x0000002eUL, 0x0000001cUL, 0x000000a6UL, 0x000000b4UL, 0x000000c6UL, +0x000000e8UL, 0x000000ddUL, 0x00000074UL, 0x0000001fUL, 0x0000004bUL, 0x000000bdUL, 0x0000008bUL, 0x0000008aUL, +0x00000070UL, 0x0000003eUL, 0x000000b5UL, 0x00000066UL, 0x00000048UL, 0x00000003UL, 0x000000f6UL, 0x0000000eUL, +0x00000061UL, 0x00000035UL, 0x00000057UL, 0x000000b9UL, 0x00000086UL, 0x000000c1UL, 0x0000001dUL, 0x0000009eUL, +0x000000e1UL, 0x000000f8UL, 0x00000098UL, 0x00000011UL, 0x00000069UL, 0x000000d9UL, 0x0000008eUL, 0x00000094UL, +0x0000009bUL, 0x0000001eUL, 0x00000087UL, 0x000000e9UL, 0x000000ceUL, 0x00000055UL, 0x00000028UL, 0x000000dfUL, +0x0000008cUL, 0x000000a1UL, 0x00000089UL, 0x0000000dUL, 0x000000bfUL, 0x000000e6UL, 0x00000042UL, 0x00000068UL, +0x00000041UL, 0x00000099UL, 0x0000002dUL, 0x0000000fUL, 0x000000b0UL, 0x00000054UL, 0x000000bbUL, 0x00000016UL +}; + +static const ulong32 Te4_1[] = { +0x00006300UL, 0x00007c00UL, 0x00007700UL, 0x00007b00UL, 0x0000f200UL, 0x00006b00UL, 0x00006f00UL, 0x0000c500UL, +0x00003000UL, 0x00000100UL, 0x00006700UL, 0x00002b00UL, 0x0000fe00UL, 0x0000d700UL, 0x0000ab00UL, 0x00007600UL, +0x0000ca00UL, 0x00008200UL, 0x0000c900UL, 0x00007d00UL, 0x0000fa00UL, 0x00005900UL, 0x00004700UL, 0x0000f000UL, +0x0000ad00UL, 0x0000d400UL, 0x0000a200UL, 0x0000af00UL, 0x00009c00UL, 0x0000a400UL, 0x00007200UL, 0x0000c000UL, +0x0000b700UL, 0x0000fd00UL, 0x00009300UL, 0x00002600UL, 0x00003600UL, 0x00003f00UL, 0x0000f700UL, 0x0000cc00UL, +0x00003400UL, 0x0000a500UL, 0x0000e500UL, 0x0000f100UL, 0x00007100UL, 0x0000d800UL, 0x00003100UL, 0x00001500UL, +0x00000400UL, 0x0000c700UL, 0x00002300UL, 0x0000c300UL, 0x00001800UL, 0x00009600UL, 0x00000500UL, 0x00009a00UL, +0x00000700UL, 0x00001200UL, 0x00008000UL, 0x0000e200UL, 0x0000eb00UL, 0x00002700UL, 0x0000b200UL, 0x00007500UL, +0x00000900UL, 0x00008300UL, 0x00002c00UL, 0x00001a00UL, 0x00001b00UL, 0x00006e00UL, 0x00005a00UL, 0x0000a000UL, +0x00005200UL, 0x00003b00UL, 0x0000d600UL, 0x0000b300UL, 0x00002900UL, 0x0000e300UL, 0x00002f00UL, 0x00008400UL, +0x00005300UL, 0x0000d100UL, 0x00000000UL, 0x0000ed00UL, 0x00002000UL, 0x0000fc00UL, 0x0000b100UL, 0x00005b00UL, +0x00006a00UL, 0x0000cb00UL, 0x0000be00UL, 0x00003900UL, 0x00004a00UL, 0x00004c00UL, 0x00005800UL, 0x0000cf00UL, +0x0000d000UL, 0x0000ef00UL, 0x0000aa00UL, 0x0000fb00UL, 0x00004300UL, 0x00004d00UL, 0x00003300UL, 0x00008500UL, +0x00004500UL, 0x0000f900UL, 0x00000200UL, 0x00007f00UL, 0x00005000UL, 0x00003c00UL, 0x00009f00UL, 0x0000a800UL, +0x00005100UL, 0x0000a300UL, 0x00004000UL, 0x00008f00UL, 0x00009200UL, 0x00009d00UL, 0x00003800UL, 0x0000f500UL, +0x0000bc00UL, 0x0000b600UL, 0x0000da00UL, 0x00002100UL, 0x00001000UL, 0x0000ff00UL, 0x0000f300UL, 0x0000d200UL, +0x0000cd00UL, 0x00000c00UL, 0x00001300UL, 0x0000ec00UL, 0x00005f00UL, 0x00009700UL, 0x00004400UL, 0x00001700UL, +0x0000c400UL, 0x0000a700UL, 0x00007e00UL, 0x00003d00UL, 0x00006400UL, 0x00005d00UL, 0x00001900UL, 0x00007300UL, +0x00006000UL, 0x00008100UL, 0x00004f00UL, 0x0000dc00UL, 0x00002200UL, 0x00002a00UL, 0x00009000UL, 0x00008800UL, +0x00004600UL, 0x0000ee00UL, 0x0000b800UL, 0x00001400UL, 0x0000de00UL, 0x00005e00UL, 0x00000b00UL, 0x0000db00UL, +0x0000e000UL, 0x00003200UL, 0x00003a00UL, 0x00000a00UL, 0x00004900UL, 0x00000600UL, 0x00002400UL, 0x00005c00UL, +0x0000c200UL, 0x0000d300UL, 0x0000ac00UL, 0x00006200UL, 0x00009100UL, 0x00009500UL, 0x0000e400UL, 0x00007900UL, +0x0000e700UL, 0x0000c800UL, 0x00003700UL, 0x00006d00UL, 0x00008d00UL, 0x0000d500UL, 0x00004e00UL, 0x0000a900UL, +0x00006c00UL, 0x00005600UL, 0x0000f400UL, 0x0000ea00UL, 0x00006500UL, 0x00007a00UL, 0x0000ae00UL, 0x00000800UL, +0x0000ba00UL, 0x00007800UL, 0x00002500UL, 0x00002e00UL, 0x00001c00UL, 0x0000a600UL, 0x0000b400UL, 0x0000c600UL, +0x0000e800UL, 0x0000dd00UL, 0x00007400UL, 0x00001f00UL, 0x00004b00UL, 0x0000bd00UL, 0x00008b00UL, 0x00008a00UL, +0x00007000UL, 0x00003e00UL, 0x0000b500UL, 0x00006600UL, 0x00004800UL, 0x00000300UL, 0x0000f600UL, 0x00000e00UL, +0x00006100UL, 0x00003500UL, 0x00005700UL, 0x0000b900UL, 0x00008600UL, 0x0000c100UL, 0x00001d00UL, 0x00009e00UL, +0x0000e100UL, 0x0000f800UL, 0x00009800UL, 0x00001100UL, 0x00006900UL, 0x0000d900UL, 0x00008e00UL, 0x00009400UL, +0x00009b00UL, 0x00001e00UL, 0x00008700UL, 0x0000e900UL, 0x0000ce00UL, 0x00005500UL, 0x00002800UL, 0x0000df00UL, +0x00008c00UL, 0x0000a100UL, 0x00008900UL, 0x00000d00UL, 0x0000bf00UL, 0x0000e600UL, 0x00004200UL, 0x00006800UL, +0x00004100UL, 0x00009900UL, 0x00002d00UL, 0x00000f00UL, 0x0000b000UL, 0x00005400UL, 0x0000bb00UL, 0x00001600UL +}; + +static const ulong32 Te4_2[] = { +0x00630000UL, 0x007c0000UL, 0x00770000UL, 0x007b0000UL, 0x00f20000UL, 0x006b0000UL, 0x006f0000UL, 0x00c50000UL, +0x00300000UL, 0x00010000UL, 0x00670000UL, 0x002b0000UL, 0x00fe0000UL, 0x00d70000UL, 0x00ab0000UL, 0x00760000UL, +0x00ca0000UL, 0x00820000UL, 0x00c90000UL, 0x007d0000UL, 0x00fa0000UL, 0x00590000UL, 0x00470000UL, 0x00f00000UL, +0x00ad0000UL, 0x00d40000UL, 0x00a20000UL, 0x00af0000UL, 0x009c0000UL, 0x00a40000UL, 0x00720000UL, 0x00c00000UL, +0x00b70000UL, 0x00fd0000UL, 0x00930000UL, 0x00260000UL, 0x00360000UL, 0x003f0000UL, 0x00f70000UL, 0x00cc0000UL, +0x00340000UL, 0x00a50000UL, 0x00e50000UL, 0x00f10000UL, 0x00710000UL, 0x00d80000UL, 0x00310000UL, 0x00150000UL, +0x00040000UL, 0x00c70000UL, 0x00230000UL, 0x00c30000UL, 0x00180000UL, 0x00960000UL, 0x00050000UL, 0x009a0000UL, +0x00070000UL, 0x00120000UL, 0x00800000UL, 0x00e20000UL, 0x00eb0000UL, 0x00270000UL, 0x00b20000UL, 0x00750000UL, +0x00090000UL, 0x00830000UL, 0x002c0000UL, 0x001a0000UL, 0x001b0000UL, 0x006e0000UL, 0x005a0000UL, 0x00a00000UL, +0x00520000UL, 0x003b0000UL, 0x00d60000UL, 0x00b30000UL, 0x00290000UL, 0x00e30000UL, 0x002f0000UL, 0x00840000UL, +0x00530000UL, 0x00d10000UL, 0x00000000UL, 0x00ed0000UL, 0x00200000UL, 0x00fc0000UL, 0x00b10000UL, 0x005b0000UL, +0x006a0000UL, 0x00cb0000UL, 0x00be0000UL, 0x00390000UL, 0x004a0000UL, 0x004c0000UL, 0x00580000UL, 0x00cf0000UL, +0x00d00000UL, 0x00ef0000UL, 0x00aa0000UL, 0x00fb0000UL, 0x00430000UL, 0x004d0000UL, 0x00330000UL, 0x00850000UL, +0x00450000UL, 0x00f90000UL, 0x00020000UL, 0x007f0000UL, 0x00500000UL, 0x003c0000UL, 0x009f0000UL, 0x00a80000UL, +0x00510000UL, 0x00a30000UL, 0x00400000UL, 0x008f0000UL, 0x00920000UL, 0x009d0000UL, 0x00380000UL, 0x00f50000UL, +0x00bc0000UL, 0x00b60000UL, 0x00da0000UL, 0x00210000UL, 0x00100000UL, 0x00ff0000UL, 0x00f30000UL, 0x00d20000UL, +0x00cd0000UL, 0x000c0000UL, 0x00130000UL, 0x00ec0000UL, 0x005f0000UL, 0x00970000UL, 0x00440000UL, 0x00170000UL, +0x00c40000UL, 0x00a70000UL, 0x007e0000UL, 0x003d0000UL, 0x00640000UL, 0x005d0000UL, 0x00190000UL, 0x00730000UL, +0x00600000UL, 0x00810000UL, 0x004f0000UL, 0x00dc0000UL, 0x00220000UL, 0x002a0000UL, 0x00900000UL, 0x00880000UL, +0x00460000UL, 0x00ee0000UL, 0x00b80000UL, 0x00140000UL, 0x00de0000UL, 0x005e0000UL, 0x000b0000UL, 0x00db0000UL, +0x00e00000UL, 0x00320000UL, 0x003a0000UL, 0x000a0000UL, 0x00490000UL, 0x00060000UL, 0x00240000UL, 0x005c0000UL, +0x00c20000UL, 0x00d30000UL, 0x00ac0000UL, 0x00620000UL, 0x00910000UL, 0x00950000UL, 0x00e40000UL, 0x00790000UL, +0x00e70000UL, 0x00c80000UL, 0x00370000UL, 0x006d0000UL, 0x008d0000UL, 0x00d50000UL, 0x004e0000UL, 0x00a90000UL, +0x006c0000UL, 0x00560000UL, 0x00f40000UL, 0x00ea0000UL, 0x00650000UL, 0x007a0000UL, 0x00ae0000UL, 0x00080000UL, +0x00ba0000UL, 0x00780000UL, 0x00250000UL, 0x002e0000UL, 0x001c0000UL, 0x00a60000UL, 0x00b40000UL, 0x00c60000UL, +0x00e80000UL, 0x00dd0000UL, 0x00740000UL, 0x001f0000UL, 0x004b0000UL, 0x00bd0000UL, 0x008b0000UL, 0x008a0000UL, +0x00700000UL, 0x003e0000UL, 0x00b50000UL, 0x00660000UL, 0x00480000UL, 0x00030000UL, 0x00f60000UL, 0x000e0000UL, +0x00610000UL, 0x00350000UL, 0x00570000UL, 0x00b90000UL, 0x00860000UL, 0x00c10000UL, 0x001d0000UL, 0x009e0000UL, +0x00e10000UL, 0x00f80000UL, 0x00980000UL, 0x00110000UL, 0x00690000UL, 0x00d90000UL, 0x008e0000UL, 0x00940000UL, +0x009b0000UL, 0x001e0000UL, 0x00870000UL, 0x00e90000UL, 0x00ce0000UL, 0x00550000UL, 0x00280000UL, 0x00df0000UL, +0x008c0000UL, 0x00a10000UL, 0x00890000UL, 0x000d0000UL, 0x00bf0000UL, 0x00e60000UL, 0x00420000UL, 0x00680000UL, +0x00410000UL, 0x00990000UL, 0x002d0000UL, 0x000f0000UL, 0x00b00000UL, 0x00540000UL, 0x00bb0000UL, 0x00160000UL +}; + +static const ulong32 Te4_3[] = { +0x63000000UL, 0x7c000000UL, 0x77000000UL, 0x7b000000UL, 0xf2000000UL, 0x6b000000UL, 0x6f000000UL, 0xc5000000UL, +0x30000000UL, 0x01000000UL, 0x67000000UL, 0x2b000000UL, 0xfe000000UL, 0xd7000000UL, 0xab000000UL, 0x76000000UL, +0xca000000UL, 0x82000000UL, 0xc9000000UL, 0x7d000000UL, 0xfa000000UL, 0x59000000UL, 0x47000000UL, 0xf0000000UL, +0xad000000UL, 0xd4000000UL, 0xa2000000UL, 0xaf000000UL, 0x9c000000UL, 0xa4000000UL, 0x72000000UL, 0xc0000000UL, +0xb7000000UL, 0xfd000000UL, 0x93000000UL, 0x26000000UL, 0x36000000UL, 0x3f000000UL, 0xf7000000UL, 0xcc000000UL, +0x34000000UL, 0xa5000000UL, 0xe5000000UL, 0xf1000000UL, 0x71000000UL, 0xd8000000UL, 0x31000000UL, 0x15000000UL, +0x04000000UL, 0xc7000000UL, 0x23000000UL, 0xc3000000UL, 0x18000000UL, 0x96000000UL, 0x05000000UL, 0x9a000000UL, +0x07000000UL, 0x12000000UL, 0x80000000UL, 0xe2000000UL, 0xeb000000UL, 0x27000000UL, 0xb2000000UL, 0x75000000UL, +0x09000000UL, 0x83000000UL, 0x2c000000UL, 0x1a000000UL, 0x1b000000UL, 0x6e000000UL, 0x5a000000UL, 0xa0000000UL, +0x52000000UL, 0x3b000000UL, 0xd6000000UL, 0xb3000000UL, 0x29000000UL, 0xe3000000UL, 0x2f000000UL, 0x84000000UL, +0x53000000UL, 0xd1000000UL, 0x00000000UL, 0xed000000UL, 0x20000000UL, 0xfc000000UL, 0xb1000000UL, 0x5b000000UL, +0x6a000000UL, 0xcb000000UL, 0xbe000000UL, 0x39000000UL, 0x4a000000UL, 0x4c000000UL, 0x58000000UL, 0xcf000000UL, +0xd0000000UL, 0xef000000UL, 0xaa000000UL, 0xfb000000UL, 0x43000000UL, 0x4d000000UL, 0x33000000UL, 0x85000000UL, +0x45000000UL, 0xf9000000UL, 0x02000000UL, 0x7f000000UL, 0x50000000UL, 0x3c000000UL, 0x9f000000UL, 0xa8000000UL, +0x51000000UL, 0xa3000000UL, 0x40000000UL, 0x8f000000UL, 0x92000000UL, 0x9d000000UL, 0x38000000UL, 0xf5000000UL, +0xbc000000UL, 0xb6000000UL, 0xda000000UL, 0x21000000UL, 0x10000000UL, 0xff000000UL, 0xf3000000UL, 0xd2000000UL, +0xcd000000UL, 0x0c000000UL, 0x13000000UL, 0xec000000UL, 0x5f000000UL, 0x97000000UL, 0x44000000UL, 0x17000000UL, +0xc4000000UL, 0xa7000000UL, 0x7e000000UL, 0x3d000000UL, 0x64000000UL, 0x5d000000UL, 0x19000000UL, 0x73000000UL, +0x60000000UL, 0x81000000UL, 0x4f000000UL, 0xdc000000UL, 0x22000000UL, 0x2a000000UL, 0x90000000UL, 0x88000000UL, +0x46000000UL, 0xee000000UL, 0xb8000000UL, 0x14000000UL, 0xde000000UL, 0x5e000000UL, 0x0b000000UL, 0xdb000000UL, +0xe0000000UL, 0x32000000UL, 0x3a000000UL, 0x0a000000UL, 0x49000000UL, 0x06000000UL, 0x24000000UL, 0x5c000000UL, +0xc2000000UL, 0xd3000000UL, 0xac000000UL, 0x62000000UL, 0x91000000UL, 0x95000000UL, 0xe4000000UL, 0x79000000UL, +0xe7000000UL, 0xc8000000UL, 0x37000000UL, 0x6d000000UL, 0x8d000000UL, 0xd5000000UL, 0x4e000000UL, 0xa9000000UL, +0x6c000000UL, 0x56000000UL, 0xf4000000UL, 0xea000000UL, 0x65000000UL, 0x7a000000UL, 0xae000000UL, 0x08000000UL, +0xba000000UL, 0x78000000UL, 0x25000000UL, 0x2e000000UL, 0x1c000000UL, 0xa6000000UL, 0xb4000000UL, 0xc6000000UL, +0xe8000000UL, 0xdd000000UL, 0x74000000UL, 0x1f000000UL, 0x4b000000UL, 0xbd000000UL, 0x8b000000UL, 0x8a000000UL, +0x70000000UL, 0x3e000000UL, 0xb5000000UL, 0x66000000UL, 0x48000000UL, 0x03000000UL, 0xf6000000UL, 0x0e000000UL, +0x61000000UL, 0x35000000UL, 0x57000000UL, 0xb9000000UL, 0x86000000UL, 0xc1000000UL, 0x1d000000UL, 0x9e000000UL, +0xe1000000UL, 0xf8000000UL, 0x98000000UL, 0x11000000UL, 0x69000000UL, 0xd9000000UL, 0x8e000000UL, 0x94000000UL, +0x9b000000UL, 0x1e000000UL, 0x87000000UL, 0xe9000000UL, 0xce000000UL, 0x55000000UL, 0x28000000UL, 0xdf000000UL, +0x8c000000UL, 0xa1000000UL, 0x89000000UL, 0x0d000000UL, 0xbf000000UL, 0xe6000000UL, 0x42000000UL, 0x68000000UL, +0x41000000UL, 0x99000000UL, 0x2d000000UL, 0x0f000000UL, 0xb0000000UL, 0x54000000UL, 0xbb000000UL, 0x16000000UL +}; +#endif /* pelimac */ + +#ifndef ENCRYPT_ONLY + +static const ulong32 TD1[256] = { + 0x5051f4a7UL, 0x537e4165UL, 0xc31a17a4UL, 0x963a275eUL, + 0xcb3bab6bUL, 0xf11f9d45UL, 0xabacfa58UL, 0x934be303UL, + 0x552030faUL, 0xf6ad766dUL, 0x9188cc76UL, 0x25f5024cUL, + 0xfc4fe5d7UL, 0xd7c52acbUL, 0x80263544UL, 0x8fb562a3UL, + 0x49deb15aUL, 0x6725ba1bUL, 0x9845ea0eUL, 0xe15dfec0UL, + 0x02c32f75UL, 0x12814cf0UL, 0xa38d4697UL, 0xc66bd3f9UL, + 0xe7038f5fUL, 0x9515929cUL, 0xebbf6d7aUL, 0xda955259UL, + 0x2dd4be83UL, 0xd3587421UL, 0x2949e069UL, 0x448ec9c8UL, + 0x6a75c289UL, 0x78f48e79UL, 0x6b99583eUL, 0xdd27b971UL, + 0xb6bee14fUL, 0x17f088adUL, 0x66c920acUL, 0xb47dce3aUL, + 0x1863df4aUL, 0x82e51a31UL, 0x60975133UL, 0x4562537fUL, + 0xe0b16477UL, 0x84bb6baeUL, 0x1cfe81a0UL, 0x94f9082bUL, + 0x58704868UL, 0x198f45fdUL, 0x8794de6cUL, 0xb7527bf8UL, + 0x23ab73d3UL, 0xe2724b02UL, 0x57e31f8fUL, 0x2a6655abUL, + 0x07b2eb28UL, 0x032fb5c2UL, 0x9a86c57bUL, 0xa5d33708UL, + 0xf2302887UL, 0xb223bfa5UL, 0xba02036aUL, 0x5ced1682UL, + 0x2b8acf1cUL, 0x92a779b4UL, 0xf0f307f2UL, 0xa14e69e2UL, + 0xcd65daf4UL, 0xd50605beUL, 0x1fd13462UL, 0x8ac4a6feUL, + 0x9d342e53UL, 0xa0a2f355UL, 0x32058ae1UL, 0x75a4f6ebUL, + 0x390b83ecUL, 0xaa4060efUL, 0x065e719fUL, 0x51bd6e10UL, + 0xf93e218aUL, 0x3d96dd06UL, 0xaedd3e05UL, 0x464de6bdUL, + 0xb591548dUL, 0x0571c45dUL, 0x6f0406d4UL, 0xff605015UL, + 0x241998fbUL, 0x97d6bde9UL, 0xcc894043UL, 0x7767d99eUL, + 0xbdb0e842UL, 0x8807898bUL, 0x38e7195bUL, 0xdb79c8eeUL, + 0x47a17c0aUL, 0xe97c420fUL, 0xc9f8841eUL, 0x00000000UL, + 0x83098086UL, 0x48322bedUL, 0xac1e1170UL, 0x4e6c5a72UL, + 0xfbfd0effUL, 0x560f8538UL, 0x1e3daed5UL, 0x27362d39UL, + 0x640a0fd9UL, 0x21685ca6UL, 0xd19b5b54UL, 0x3a24362eUL, + 0xb10c0a67UL, 0x0f9357e7UL, 0xd2b4ee96UL, 0x9e1b9b91UL, + 0x4f80c0c5UL, 0xa261dc20UL, 0x695a774bUL, 0x161c121aUL, + 0x0ae293baUL, 0xe5c0a02aUL, 0x433c22e0UL, 0x1d121b17UL, + 0x0b0e090dUL, 0xadf28bc7UL, 0xb92db6a8UL, 0xc8141ea9UL, + 0x8557f119UL, 0x4caf7507UL, 0xbbee99ddUL, 0xfda37f60UL, + 0x9ff70126UL, 0xbc5c72f5UL, 0xc544663bUL, 0x345bfb7eUL, + 0x768b4329UL, 0xdccb23c6UL, 0x68b6edfcUL, 0x63b8e4f1UL, + 0xcad731dcUL, 0x10426385UL, 0x40139722UL, 0x2084c611UL, + 0x7d854a24UL, 0xf8d2bb3dUL, 0x11aef932UL, 0x6dc729a1UL, + 0x4b1d9e2fUL, 0xf3dcb230UL, 0xec0d8652UL, 0xd077c1e3UL, + 0x6c2bb316UL, 0x99a970b9UL, 0xfa119448UL, 0x2247e964UL, + 0xc4a8fc8cUL, 0x1aa0f03fUL, 0xd8567d2cUL, 0xef223390UL, + 0xc787494eUL, 0xc1d938d1UL, 0xfe8ccaa2UL, 0x3698d40bUL, + 0xcfa6f581UL, 0x28a57adeUL, 0x26dab78eUL, 0xa43fadbfUL, + 0xe42c3a9dUL, 0x0d507892UL, 0x9b6a5fccUL, 0x62547e46UL, + 0xc2f68d13UL, 0xe890d8b8UL, 0x5e2e39f7UL, 0xf582c3afUL, + 0xbe9f5d80UL, 0x7c69d093UL, 0xa96fd52dUL, 0xb3cf2512UL, + 0x3bc8ac99UL, 0xa710187dUL, 0x6ee89c63UL, 0x7bdb3bbbUL, + 0x09cd2678UL, 0xf46e5918UL, 0x01ec9ab7UL, 0xa8834f9aUL, + 0x65e6956eUL, 0x7eaaffe6UL, 0x0821bccfUL, 0xe6ef15e8UL, + 0xd9bae79bUL, 0xce4a6f36UL, 0xd4ea9f09UL, 0xd629b07cUL, + 0xaf31a4b2UL, 0x312a3f23UL, 0x30c6a594UL, 0xc035a266UL, + 0x37744ebcUL, 0xa6fc82caUL, 0xb0e090d0UL, 0x1533a7d8UL, + 0x4af10498UL, 0xf741ecdaUL, 0x0e7fcd50UL, 0x2f1791f6UL, + 0x8d764dd6UL, 0x4d43efb0UL, 0x54ccaa4dUL, 0xdfe49604UL, + 0xe39ed1b5UL, 0x1b4c6a88UL, 0xb8c12c1fUL, 0x7f466551UL, + 0x049d5eeaUL, 0x5d018c35UL, 0x73fa8774UL, 0x2efb0b41UL, + 0x5ab3671dUL, 0x5292dbd2UL, 0x33e91056UL, 0x136dd647UL, + 0x8c9ad761UL, 0x7a37a10cUL, 0x8e59f814UL, 0x89eb133cUL, + 0xeecea927UL, 0x35b761c9UL, 0xede11ce5UL, 0x3c7a47b1UL, + 0x599cd2dfUL, 0x3f55f273UL, 0x791814ceUL, 0xbf73c737UL, + 0xea53f7cdUL, 0x5b5ffdaaUL, 0x14df3d6fUL, 0x867844dbUL, + 0x81caaff3UL, 0x3eb968c4UL, 0x2c382434UL, 0x5fc2a340UL, + 0x72161dc3UL, 0x0cbce225UL, 0x8b283c49UL, 0x41ff0d95UL, + 0x7139a801UL, 0xde080cb3UL, 0x9cd8b4e4UL, 0x906456c1UL, + 0x617bcb84UL, 0x70d532b6UL, 0x74486c5cUL, 0x42d0b857UL, +}; +static const ulong32 TD2[256] = { + 0xa75051f4UL, 0x65537e41UL, 0xa4c31a17UL, 0x5e963a27UL, + 0x6bcb3babUL, 0x45f11f9dUL, 0x58abacfaUL, 0x03934be3UL, + 0xfa552030UL, 0x6df6ad76UL, 0x769188ccUL, 0x4c25f502UL, + 0xd7fc4fe5UL, 0xcbd7c52aUL, 0x44802635UL, 0xa38fb562UL, + 0x5a49deb1UL, 0x1b6725baUL, 0x0e9845eaUL, 0xc0e15dfeUL, + 0x7502c32fUL, 0xf012814cUL, 0x97a38d46UL, 0xf9c66bd3UL, + 0x5fe7038fUL, 0x9c951592UL, 0x7aebbf6dUL, 0x59da9552UL, + 0x832dd4beUL, 0x21d35874UL, 0x692949e0UL, 0xc8448ec9UL, + 0x896a75c2UL, 0x7978f48eUL, 0x3e6b9958UL, 0x71dd27b9UL, + 0x4fb6bee1UL, 0xad17f088UL, 0xac66c920UL, 0x3ab47dceUL, + 0x4a1863dfUL, 0x3182e51aUL, 0x33609751UL, 0x7f456253UL, + 0x77e0b164UL, 0xae84bb6bUL, 0xa01cfe81UL, 0x2b94f908UL, + 0x68587048UL, 0xfd198f45UL, 0x6c8794deUL, 0xf8b7527bUL, + 0xd323ab73UL, 0x02e2724bUL, 0x8f57e31fUL, 0xab2a6655UL, + 0x2807b2ebUL, 0xc2032fb5UL, 0x7b9a86c5UL, 0x08a5d337UL, + 0x87f23028UL, 0xa5b223bfUL, 0x6aba0203UL, 0x825ced16UL, + 0x1c2b8acfUL, 0xb492a779UL, 0xf2f0f307UL, 0xe2a14e69UL, + 0xf4cd65daUL, 0xbed50605UL, 0x621fd134UL, 0xfe8ac4a6UL, + 0x539d342eUL, 0x55a0a2f3UL, 0xe132058aUL, 0xeb75a4f6UL, + 0xec390b83UL, 0xefaa4060UL, 0x9f065e71UL, 0x1051bd6eUL, + 0x8af93e21UL, 0x063d96ddUL, 0x05aedd3eUL, 0xbd464de6UL, + 0x8db59154UL, 0x5d0571c4UL, 0xd46f0406UL, 0x15ff6050UL, + 0xfb241998UL, 0xe997d6bdUL, 0x43cc8940UL, 0x9e7767d9UL, + 0x42bdb0e8UL, 0x8b880789UL, 0x5b38e719UL, 0xeedb79c8UL, + 0x0a47a17cUL, 0x0fe97c42UL, 0x1ec9f884UL, 0x00000000UL, + 0x86830980UL, 0xed48322bUL, 0x70ac1e11UL, 0x724e6c5aUL, + 0xfffbfd0eUL, 0x38560f85UL, 0xd51e3daeUL, 0x3927362dUL, + 0xd9640a0fUL, 0xa621685cUL, 0x54d19b5bUL, 0x2e3a2436UL, + 0x67b10c0aUL, 0xe70f9357UL, 0x96d2b4eeUL, 0x919e1b9bUL, + 0xc54f80c0UL, 0x20a261dcUL, 0x4b695a77UL, 0x1a161c12UL, + 0xba0ae293UL, 0x2ae5c0a0UL, 0xe0433c22UL, 0x171d121bUL, + 0x0d0b0e09UL, 0xc7adf28bUL, 0xa8b92db6UL, 0xa9c8141eUL, + 0x198557f1UL, 0x074caf75UL, 0xddbbee99UL, 0x60fda37fUL, + 0x269ff701UL, 0xf5bc5c72UL, 0x3bc54466UL, 0x7e345bfbUL, + 0x29768b43UL, 0xc6dccb23UL, 0xfc68b6edUL, 0xf163b8e4UL, + 0xdccad731UL, 0x85104263UL, 0x22401397UL, 0x112084c6UL, + 0x247d854aUL, 0x3df8d2bbUL, 0x3211aef9UL, 0xa16dc729UL, + 0x2f4b1d9eUL, 0x30f3dcb2UL, 0x52ec0d86UL, 0xe3d077c1UL, + 0x166c2bb3UL, 0xb999a970UL, 0x48fa1194UL, 0x642247e9UL, + 0x8cc4a8fcUL, 0x3f1aa0f0UL, 0x2cd8567dUL, 0x90ef2233UL, + 0x4ec78749UL, 0xd1c1d938UL, 0xa2fe8ccaUL, 0x0b3698d4UL, + 0x81cfa6f5UL, 0xde28a57aUL, 0x8e26dab7UL, 0xbfa43fadUL, + 0x9de42c3aUL, 0x920d5078UL, 0xcc9b6a5fUL, 0x4662547eUL, + 0x13c2f68dUL, 0xb8e890d8UL, 0xf75e2e39UL, 0xaff582c3UL, + 0x80be9f5dUL, 0x937c69d0UL, 0x2da96fd5UL, 0x12b3cf25UL, + 0x993bc8acUL, 0x7da71018UL, 0x636ee89cUL, 0xbb7bdb3bUL, + 0x7809cd26UL, 0x18f46e59UL, 0xb701ec9aUL, 0x9aa8834fUL, + 0x6e65e695UL, 0xe67eaaffUL, 0xcf0821bcUL, 0xe8e6ef15UL, + 0x9bd9bae7UL, 0x36ce4a6fUL, 0x09d4ea9fUL, 0x7cd629b0UL, + 0xb2af31a4UL, 0x23312a3fUL, 0x9430c6a5UL, 0x66c035a2UL, + 0xbc37744eUL, 0xcaa6fc82UL, 0xd0b0e090UL, 0xd81533a7UL, + 0x984af104UL, 0xdaf741ecUL, 0x500e7fcdUL, 0xf62f1791UL, + 0xd68d764dUL, 0xb04d43efUL, 0x4d54ccaaUL, 0x04dfe496UL, + 0xb5e39ed1UL, 0x881b4c6aUL, 0x1fb8c12cUL, 0x517f4665UL, + 0xea049d5eUL, 0x355d018cUL, 0x7473fa87UL, 0x412efb0bUL, + 0x1d5ab367UL, 0xd25292dbUL, 0x5633e910UL, 0x47136dd6UL, + 0x618c9ad7UL, 0x0c7a37a1UL, 0x148e59f8UL, 0x3c89eb13UL, + 0x27eecea9UL, 0xc935b761UL, 0xe5ede11cUL, 0xb13c7a47UL, + 0xdf599cd2UL, 0x733f55f2UL, 0xce791814UL, 0x37bf73c7UL, + 0xcdea53f7UL, 0xaa5b5ffdUL, 0x6f14df3dUL, 0xdb867844UL, + 0xf381caafUL, 0xc43eb968UL, 0x342c3824UL, 0x405fc2a3UL, + 0xc372161dUL, 0x250cbce2UL, 0x498b283cUL, 0x9541ff0dUL, + 0x017139a8UL, 0xb3de080cUL, 0xe49cd8b4UL, 0xc1906456UL, + 0x84617bcbUL, 0xb670d532UL, 0x5c74486cUL, 0x5742d0b8UL, +}; +static const ulong32 TD3[256] = { + 0xf4a75051UL, 0x4165537eUL, 0x17a4c31aUL, 0x275e963aUL, + 0xab6bcb3bUL, 0x9d45f11fUL, 0xfa58abacUL, 0xe303934bUL, + 0x30fa5520UL, 0x766df6adUL, 0xcc769188UL, 0x024c25f5UL, + 0xe5d7fc4fUL, 0x2acbd7c5UL, 0x35448026UL, 0x62a38fb5UL, + 0xb15a49deUL, 0xba1b6725UL, 0xea0e9845UL, 0xfec0e15dUL, + 0x2f7502c3UL, 0x4cf01281UL, 0x4697a38dUL, 0xd3f9c66bUL, + 0x8f5fe703UL, 0x929c9515UL, 0x6d7aebbfUL, 0x5259da95UL, + 0xbe832dd4UL, 0x7421d358UL, 0xe0692949UL, 0xc9c8448eUL, + 0xc2896a75UL, 0x8e7978f4UL, 0x583e6b99UL, 0xb971dd27UL, + 0xe14fb6beUL, 0x88ad17f0UL, 0x20ac66c9UL, 0xce3ab47dUL, + 0xdf4a1863UL, 0x1a3182e5UL, 0x51336097UL, 0x537f4562UL, + 0x6477e0b1UL, 0x6bae84bbUL, 0x81a01cfeUL, 0x082b94f9UL, + 0x48685870UL, 0x45fd198fUL, 0xde6c8794UL, 0x7bf8b752UL, + 0x73d323abUL, 0x4b02e272UL, 0x1f8f57e3UL, 0x55ab2a66UL, + 0xeb2807b2UL, 0xb5c2032fUL, 0xc57b9a86UL, 0x3708a5d3UL, + 0x2887f230UL, 0xbfa5b223UL, 0x036aba02UL, 0x16825cedUL, + 0xcf1c2b8aUL, 0x79b492a7UL, 0x07f2f0f3UL, 0x69e2a14eUL, + 0xdaf4cd65UL, 0x05bed506UL, 0x34621fd1UL, 0xa6fe8ac4UL, + 0x2e539d34UL, 0xf355a0a2UL, 0x8ae13205UL, 0xf6eb75a4UL, + 0x83ec390bUL, 0x60efaa40UL, 0x719f065eUL, 0x6e1051bdUL, + 0x218af93eUL, 0xdd063d96UL, 0x3e05aeddUL, 0xe6bd464dUL, + 0x548db591UL, 0xc45d0571UL, 0x06d46f04UL, 0x5015ff60UL, + 0x98fb2419UL, 0xbde997d6UL, 0x4043cc89UL, 0xd99e7767UL, + 0xe842bdb0UL, 0x898b8807UL, 0x195b38e7UL, 0xc8eedb79UL, + 0x7c0a47a1UL, 0x420fe97cUL, 0x841ec9f8UL, 0x00000000UL, + 0x80868309UL, 0x2bed4832UL, 0x1170ac1eUL, 0x5a724e6cUL, + 0x0efffbfdUL, 0x8538560fUL, 0xaed51e3dUL, 0x2d392736UL, + 0x0fd9640aUL, 0x5ca62168UL, 0x5b54d19bUL, 0x362e3a24UL, + 0x0a67b10cUL, 0x57e70f93UL, 0xee96d2b4UL, 0x9b919e1bUL, + 0xc0c54f80UL, 0xdc20a261UL, 0x774b695aUL, 0x121a161cUL, + 0x93ba0ae2UL, 0xa02ae5c0UL, 0x22e0433cUL, 0x1b171d12UL, + 0x090d0b0eUL, 0x8bc7adf2UL, 0xb6a8b92dUL, 0x1ea9c814UL, + 0xf1198557UL, 0x75074cafUL, 0x99ddbbeeUL, 0x7f60fda3UL, + 0x01269ff7UL, 0x72f5bc5cUL, 0x663bc544UL, 0xfb7e345bUL, + 0x4329768bUL, 0x23c6dccbUL, 0xedfc68b6UL, 0xe4f163b8UL, + 0x31dccad7UL, 0x63851042UL, 0x97224013UL, 0xc6112084UL, + 0x4a247d85UL, 0xbb3df8d2UL, 0xf93211aeUL, 0x29a16dc7UL, + 0x9e2f4b1dUL, 0xb230f3dcUL, 0x8652ec0dUL, 0xc1e3d077UL, + 0xb3166c2bUL, 0x70b999a9UL, 0x9448fa11UL, 0xe9642247UL, + 0xfc8cc4a8UL, 0xf03f1aa0UL, 0x7d2cd856UL, 0x3390ef22UL, + 0x494ec787UL, 0x38d1c1d9UL, 0xcaa2fe8cUL, 0xd40b3698UL, + 0xf581cfa6UL, 0x7ade28a5UL, 0xb78e26daUL, 0xadbfa43fUL, + 0x3a9de42cUL, 0x78920d50UL, 0x5fcc9b6aUL, 0x7e466254UL, + 0x8d13c2f6UL, 0xd8b8e890UL, 0x39f75e2eUL, 0xc3aff582UL, + 0x5d80be9fUL, 0xd0937c69UL, 0xd52da96fUL, 0x2512b3cfUL, + 0xac993bc8UL, 0x187da710UL, 0x9c636ee8UL, 0x3bbb7bdbUL, + 0x267809cdUL, 0x5918f46eUL, 0x9ab701ecUL, 0x4f9aa883UL, + 0x956e65e6UL, 0xffe67eaaUL, 0xbccf0821UL, 0x15e8e6efUL, + 0xe79bd9baUL, 0x6f36ce4aUL, 0x9f09d4eaUL, 0xb07cd629UL, + 0xa4b2af31UL, 0x3f23312aUL, 0xa59430c6UL, 0xa266c035UL, + 0x4ebc3774UL, 0x82caa6fcUL, 0x90d0b0e0UL, 0xa7d81533UL, + 0x04984af1UL, 0xecdaf741UL, 0xcd500e7fUL, 0x91f62f17UL, + 0x4dd68d76UL, 0xefb04d43UL, 0xaa4d54ccUL, 0x9604dfe4UL, + 0xd1b5e39eUL, 0x6a881b4cUL, 0x2c1fb8c1UL, 0x65517f46UL, + 0x5eea049dUL, 0x8c355d01UL, 0x877473faUL, 0x0b412efbUL, + 0x671d5ab3UL, 0xdbd25292UL, 0x105633e9UL, 0xd647136dUL, + 0xd7618c9aUL, 0xa10c7a37UL, 0xf8148e59UL, 0x133c89ebUL, + 0xa927eeceUL, 0x61c935b7UL, 0x1ce5ede1UL, 0x47b13c7aUL, + 0xd2df599cUL, 0xf2733f55UL, 0x14ce7918UL, 0xc737bf73UL, + 0xf7cdea53UL, 0xfdaa5b5fUL, 0x3d6f14dfUL, 0x44db8678UL, + 0xaff381caUL, 0x68c43eb9UL, 0x24342c38UL, 0xa3405fc2UL, + 0x1dc37216UL, 0xe2250cbcUL, 0x3c498b28UL, 0x0d9541ffUL, + 0xa8017139UL, 0x0cb3de08UL, 0xb4e49cd8UL, 0x56c19064UL, + 0xcb84617bUL, 0x32b670d5UL, 0x6c5c7448UL, 0xb85742d0UL, +}; + +static const ulong32 Tks0[] = { +0x00000000UL, 0x0e090d0bUL, 0x1c121a16UL, 0x121b171dUL, 0x3824342cUL, 0x362d3927UL, 0x24362e3aUL, 0x2a3f2331UL, +0x70486858UL, 0x7e416553UL, 0x6c5a724eUL, 0x62537f45UL, 0x486c5c74UL, 0x4665517fUL, 0x547e4662UL, 0x5a774b69UL, +0xe090d0b0UL, 0xee99ddbbUL, 0xfc82caa6UL, 0xf28bc7adUL, 0xd8b4e49cUL, 0xd6bde997UL, 0xc4a6fe8aUL, 0xcaaff381UL, +0x90d8b8e8UL, 0x9ed1b5e3UL, 0x8ccaa2feUL, 0x82c3aff5UL, 0xa8fc8cc4UL, 0xa6f581cfUL, 0xb4ee96d2UL, 0xbae79bd9UL, +0xdb3bbb7bUL, 0xd532b670UL, 0xc729a16dUL, 0xc920ac66UL, 0xe31f8f57UL, 0xed16825cUL, 0xff0d9541UL, 0xf104984aUL, +0xab73d323UL, 0xa57ade28UL, 0xb761c935UL, 0xb968c43eUL, 0x9357e70fUL, 0x9d5eea04UL, 0x8f45fd19UL, 0x814cf012UL, +0x3bab6bcbUL, 0x35a266c0UL, 0x27b971ddUL, 0x29b07cd6UL, 0x038f5fe7UL, 0x0d8652ecUL, 0x1f9d45f1UL, 0x119448faUL, +0x4be30393UL, 0x45ea0e98UL, 0x57f11985UL, 0x59f8148eUL, 0x73c737bfUL, 0x7dce3ab4UL, 0x6fd52da9UL, 0x61dc20a2UL, +0xad766df6UL, 0xa37f60fdUL, 0xb16477e0UL, 0xbf6d7aebUL, 0x955259daUL, 0x9b5b54d1UL, 0x894043ccUL, 0x87494ec7UL, +0xdd3e05aeUL, 0xd33708a5UL, 0xc12c1fb8UL, 0xcf2512b3UL, 0xe51a3182UL, 0xeb133c89UL, 0xf9082b94UL, 0xf701269fUL, +0x4de6bd46UL, 0x43efb04dUL, 0x51f4a750UL, 0x5ffdaa5bUL, 0x75c2896aUL, 0x7bcb8461UL, 0x69d0937cUL, 0x67d99e77UL, +0x3daed51eUL, 0x33a7d815UL, 0x21bccf08UL, 0x2fb5c203UL, 0x058ae132UL, 0x0b83ec39UL, 0x1998fb24UL, 0x1791f62fUL, +0x764dd68dUL, 0x7844db86UL, 0x6a5fcc9bUL, 0x6456c190UL, 0x4e69e2a1UL, 0x4060efaaUL, 0x527bf8b7UL, 0x5c72f5bcUL, +0x0605bed5UL, 0x080cb3deUL, 0x1a17a4c3UL, 0x141ea9c8UL, 0x3e218af9UL, 0x302887f2UL, 0x223390efUL, 0x2c3a9de4UL, +0x96dd063dUL, 0x98d40b36UL, 0x8acf1c2bUL, 0x84c61120UL, 0xaef93211UL, 0xa0f03f1aUL, 0xb2eb2807UL, 0xbce2250cUL, +0xe6956e65UL, 0xe89c636eUL, 0xfa877473UL, 0xf48e7978UL, 0xdeb15a49UL, 0xd0b85742UL, 0xc2a3405fUL, 0xccaa4d54UL, +0x41ecdaf7UL, 0x4fe5d7fcUL, 0x5dfec0e1UL, 0x53f7cdeaUL, 0x79c8eedbUL, 0x77c1e3d0UL, 0x65daf4cdUL, 0x6bd3f9c6UL, +0x31a4b2afUL, 0x3fadbfa4UL, 0x2db6a8b9UL, 0x23bfa5b2UL, 0x09808683UL, 0x07898b88UL, 0x15929c95UL, 0x1b9b919eUL, +0xa17c0a47UL, 0xaf75074cUL, 0xbd6e1051UL, 0xb3671d5aUL, 0x99583e6bUL, 0x97513360UL, 0x854a247dUL, 0x8b432976UL, +0xd134621fUL, 0xdf3d6f14UL, 0xcd267809UL, 0xc32f7502UL, 0xe9105633UL, 0xe7195b38UL, 0xf5024c25UL, 0xfb0b412eUL, +0x9ad7618cUL, 0x94de6c87UL, 0x86c57b9aUL, 0x88cc7691UL, 0xa2f355a0UL, 0xacfa58abUL, 0xbee14fb6UL, 0xb0e842bdUL, +0xea9f09d4UL, 0xe49604dfUL, 0xf68d13c2UL, 0xf8841ec9UL, 0xd2bb3df8UL, 0xdcb230f3UL, 0xcea927eeUL, 0xc0a02ae5UL, +0x7a47b13cUL, 0x744ebc37UL, 0x6655ab2aUL, 0x685ca621UL, 0x42638510UL, 0x4c6a881bUL, 0x5e719f06UL, 0x5078920dUL, +0x0a0fd964UL, 0x0406d46fUL, 0x161dc372UL, 0x1814ce79UL, 0x322bed48UL, 0x3c22e043UL, 0x2e39f75eUL, 0x2030fa55UL, +0xec9ab701UL, 0xe293ba0aUL, 0xf088ad17UL, 0xfe81a01cUL, 0xd4be832dUL, 0xdab78e26UL, 0xc8ac993bUL, 0xc6a59430UL, +0x9cd2df59UL, 0x92dbd252UL, 0x80c0c54fUL, 0x8ec9c844UL, 0xa4f6eb75UL, 0xaaffe67eUL, 0xb8e4f163UL, 0xb6edfc68UL, +0x0c0a67b1UL, 0x02036abaUL, 0x10187da7UL, 0x1e1170acUL, 0x342e539dUL, 0x3a275e96UL, 0x283c498bUL, 0x26354480UL, +0x7c420fe9UL, 0x724b02e2UL, 0x605015ffUL, 0x6e5918f4UL, 0x44663bc5UL, 0x4a6f36ceUL, 0x587421d3UL, 0x567d2cd8UL, +0x37a10c7aUL, 0x39a80171UL, 0x2bb3166cUL, 0x25ba1b67UL, 0x0f853856UL, 0x018c355dUL, 0x13972240UL, 0x1d9e2f4bUL, +0x47e96422UL, 0x49e06929UL, 0x5bfb7e34UL, 0x55f2733fUL, 0x7fcd500eUL, 0x71c45d05UL, 0x63df4a18UL, 0x6dd64713UL, +0xd731dccaUL, 0xd938d1c1UL, 0xcb23c6dcUL, 0xc52acbd7UL, 0xef15e8e6UL, 0xe11ce5edUL, 0xf307f2f0UL, 0xfd0efffbUL, +0xa779b492UL, 0xa970b999UL, 0xbb6bae84UL, 0xb562a38fUL, 0x9f5d80beUL, 0x91548db5UL, 0x834f9aa8UL, 0x8d4697a3UL +}; + +static const ulong32 Tks1[] = { +0x00000000UL, 0x0b0e090dUL, 0x161c121aUL, 0x1d121b17UL, 0x2c382434UL, 0x27362d39UL, 0x3a24362eUL, 0x312a3f23UL, +0x58704868UL, 0x537e4165UL, 0x4e6c5a72UL, 0x4562537fUL, 0x74486c5cUL, 0x7f466551UL, 0x62547e46UL, 0x695a774bUL, +0xb0e090d0UL, 0xbbee99ddUL, 0xa6fc82caUL, 0xadf28bc7UL, 0x9cd8b4e4UL, 0x97d6bde9UL, 0x8ac4a6feUL, 0x81caaff3UL, +0xe890d8b8UL, 0xe39ed1b5UL, 0xfe8ccaa2UL, 0xf582c3afUL, 0xc4a8fc8cUL, 0xcfa6f581UL, 0xd2b4ee96UL, 0xd9bae79bUL, +0x7bdb3bbbUL, 0x70d532b6UL, 0x6dc729a1UL, 0x66c920acUL, 0x57e31f8fUL, 0x5ced1682UL, 0x41ff0d95UL, 0x4af10498UL, +0x23ab73d3UL, 0x28a57adeUL, 0x35b761c9UL, 0x3eb968c4UL, 0x0f9357e7UL, 0x049d5eeaUL, 0x198f45fdUL, 0x12814cf0UL, +0xcb3bab6bUL, 0xc035a266UL, 0xdd27b971UL, 0xd629b07cUL, 0xe7038f5fUL, 0xec0d8652UL, 0xf11f9d45UL, 0xfa119448UL, +0x934be303UL, 0x9845ea0eUL, 0x8557f119UL, 0x8e59f814UL, 0xbf73c737UL, 0xb47dce3aUL, 0xa96fd52dUL, 0xa261dc20UL, +0xf6ad766dUL, 0xfda37f60UL, 0xe0b16477UL, 0xebbf6d7aUL, 0xda955259UL, 0xd19b5b54UL, 0xcc894043UL, 0xc787494eUL, +0xaedd3e05UL, 0xa5d33708UL, 0xb8c12c1fUL, 0xb3cf2512UL, 0x82e51a31UL, 0x89eb133cUL, 0x94f9082bUL, 0x9ff70126UL, +0x464de6bdUL, 0x4d43efb0UL, 0x5051f4a7UL, 0x5b5ffdaaUL, 0x6a75c289UL, 0x617bcb84UL, 0x7c69d093UL, 0x7767d99eUL, +0x1e3daed5UL, 0x1533a7d8UL, 0x0821bccfUL, 0x032fb5c2UL, 0x32058ae1UL, 0x390b83ecUL, 0x241998fbUL, 0x2f1791f6UL, +0x8d764dd6UL, 0x867844dbUL, 0x9b6a5fccUL, 0x906456c1UL, 0xa14e69e2UL, 0xaa4060efUL, 0xb7527bf8UL, 0xbc5c72f5UL, +0xd50605beUL, 0xde080cb3UL, 0xc31a17a4UL, 0xc8141ea9UL, 0xf93e218aUL, 0xf2302887UL, 0xef223390UL, 0xe42c3a9dUL, +0x3d96dd06UL, 0x3698d40bUL, 0x2b8acf1cUL, 0x2084c611UL, 0x11aef932UL, 0x1aa0f03fUL, 0x07b2eb28UL, 0x0cbce225UL, +0x65e6956eUL, 0x6ee89c63UL, 0x73fa8774UL, 0x78f48e79UL, 0x49deb15aUL, 0x42d0b857UL, 0x5fc2a340UL, 0x54ccaa4dUL, +0xf741ecdaUL, 0xfc4fe5d7UL, 0xe15dfec0UL, 0xea53f7cdUL, 0xdb79c8eeUL, 0xd077c1e3UL, 0xcd65daf4UL, 0xc66bd3f9UL, +0xaf31a4b2UL, 0xa43fadbfUL, 0xb92db6a8UL, 0xb223bfa5UL, 0x83098086UL, 0x8807898bUL, 0x9515929cUL, 0x9e1b9b91UL, +0x47a17c0aUL, 0x4caf7507UL, 0x51bd6e10UL, 0x5ab3671dUL, 0x6b99583eUL, 0x60975133UL, 0x7d854a24UL, 0x768b4329UL, +0x1fd13462UL, 0x14df3d6fUL, 0x09cd2678UL, 0x02c32f75UL, 0x33e91056UL, 0x38e7195bUL, 0x25f5024cUL, 0x2efb0b41UL, +0x8c9ad761UL, 0x8794de6cUL, 0x9a86c57bUL, 0x9188cc76UL, 0xa0a2f355UL, 0xabacfa58UL, 0xb6bee14fUL, 0xbdb0e842UL, +0xd4ea9f09UL, 0xdfe49604UL, 0xc2f68d13UL, 0xc9f8841eUL, 0xf8d2bb3dUL, 0xf3dcb230UL, 0xeecea927UL, 0xe5c0a02aUL, +0x3c7a47b1UL, 0x37744ebcUL, 0x2a6655abUL, 0x21685ca6UL, 0x10426385UL, 0x1b4c6a88UL, 0x065e719fUL, 0x0d507892UL, +0x640a0fd9UL, 0x6f0406d4UL, 0x72161dc3UL, 0x791814ceUL, 0x48322bedUL, 0x433c22e0UL, 0x5e2e39f7UL, 0x552030faUL, +0x01ec9ab7UL, 0x0ae293baUL, 0x17f088adUL, 0x1cfe81a0UL, 0x2dd4be83UL, 0x26dab78eUL, 0x3bc8ac99UL, 0x30c6a594UL, +0x599cd2dfUL, 0x5292dbd2UL, 0x4f80c0c5UL, 0x448ec9c8UL, 0x75a4f6ebUL, 0x7eaaffe6UL, 0x63b8e4f1UL, 0x68b6edfcUL, +0xb10c0a67UL, 0xba02036aUL, 0xa710187dUL, 0xac1e1170UL, 0x9d342e53UL, 0x963a275eUL, 0x8b283c49UL, 0x80263544UL, +0xe97c420fUL, 0xe2724b02UL, 0xff605015UL, 0xf46e5918UL, 0xc544663bUL, 0xce4a6f36UL, 0xd3587421UL, 0xd8567d2cUL, +0x7a37a10cUL, 0x7139a801UL, 0x6c2bb316UL, 0x6725ba1bUL, 0x560f8538UL, 0x5d018c35UL, 0x40139722UL, 0x4b1d9e2fUL, +0x2247e964UL, 0x2949e069UL, 0x345bfb7eUL, 0x3f55f273UL, 0x0e7fcd50UL, 0x0571c45dUL, 0x1863df4aUL, 0x136dd647UL, +0xcad731dcUL, 0xc1d938d1UL, 0xdccb23c6UL, 0xd7c52acbUL, 0xe6ef15e8UL, 0xede11ce5UL, 0xf0f307f2UL, 0xfbfd0effUL, +0x92a779b4UL, 0x99a970b9UL, 0x84bb6baeUL, 0x8fb562a3UL, 0xbe9f5d80UL, 0xb591548dUL, 0xa8834f9aUL, 0xa38d4697UL +}; + +static const ulong32 Tks2[] = { +0x00000000UL, 0x0d0b0e09UL, 0x1a161c12UL, 0x171d121bUL, 0x342c3824UL, 0x3927362dUL, 0x2e3a2436UL, 0x23312a3fUL, +0x68587048UL, 0x65537e41UL, 0x724e6c5aUL, 0x7f456253UL, 0x5c74486cUL, 0x517f4665UL, 0x4662547eUL, 0x4b695a77UL, +0xd0b0e090UL, 0xddbbee99UL, 0xcaa6fc82UL, 0xc7adf28bUL, 0xe49cd8b4UL, 0xe997d6bdUL, 0xfe8ac4a6UL, 0xf381caafUL, +0xb8e890d8UL, 0xb5e39ed1UL, 0xa2fe8ccaUL, 0xaff582c3UL, 0x8cc4a8fcUL, 0x81cfa6f5UL, 0x96d2b4eeUL, 0x9bd9bae7UL, +0xbb7bdb3bUL, 0xb670d532UL, 0xa16dc729UL, 0xac66c920UL, 0x8f57e31fUL, 0x825ced16UL, 0x9541ff0dUL, 0x984af104UL, +0xd323ab73UL, 0xde28a57aUL, 0xc935b761UL, 0xc43eb968UL, 0xe70f9357UL, 0xea049d5eUL, 0xfd198f45UL, 0xf012814cUL, +0x6bcb3babUL, 0x66c035a2UL, 0x71dd27b9UL, 0x7cd629b0UL, 0x5fe7038fUL, 0x52ec0d86UL, 0x45f11f9dUL, 0x48fa1194UL, +0x03934be3UL, 0x0e9845eaUL, 0x198557f1UL, 0x148e59f8UL, 0x37bf73c7UL, 0x3ab47dceUL, 0x2da96fd5UL, 0x20a261dcUL, +0x6df6ad76UL, 0x60fda37fUL, 0x77e0b164UL, 0x7aebbf6dUL, 0x59da9552UL, 0x54d19b5bUL, 0x43cc8940UL, 0x4ec78749UL, +0x05aedd3eUL, 0x08a5d337UL, 0x1fb8c12cUL, 0x12b3cf25UL, 0x3182e51aUL, 0x3c89eb13UL, 0x2b94f908UL, 0x269ff701UL, +0xbd464de6UL, 0xb04d43efUL, 0xa75051f4UL, 0xaa5b5ffdUL, 0x896a75c2UL, 0x84617bcbUL, 0x937c69d0UL, 0x9e7767d9UL, +0xd51e3daeUL, 0xd81533a7UL, 0xcf0821bcUL, 0xc2032fb5UL, 0xe132058aUL, 0xec390b83UL, 0xfb241998UL, 0xf62f1791UL, +0xd68d764dUL, 0xdb867844UL, 0xcc9b6a5fUL, 0xc1906456UL, 0xe2a14e69UL, 0xefaa4060UL, 0xf8b7527bUL, 0xf5bc5c72UL, +0xbed50605UL, 0xb3de080cUL, 0xa4c31a17UL, 0xa9c8141eUL, 0x8af93e21UL, 0x87f23028UL, 0x90ef2233UL, 0x9de42c3aUL, +0x063d96ddUL, 0x0b3698d4UL, 0x1c2b8acfUL, 0x112084c6UL, 0x3211aef9UL, 0x3f1aa0f0UL, 0x2807b2ebUL, 0x250cbce2UL, +0x6e65e695UL, 0x636ee89cUL, 0x7473fa87UL, 0x7978f48eUL, 0x5a49deb1UL, 0x5742d0b8UL, 0x405fc2a3UL, 0x4d54ccaaUL, +0xdaf741ecUL, 0xd7fc4fe5UL, 0xc0e15dfeUL, 0xcdea53f7UL, 0xeedb79c8UL, 0xe3d077c1UL, 0xf4cd65daUL, 0xf9c66bd3UL, +0xb2af31a4UL, 0xbfa43fadUL, 0xa8b92db6UL, 0xa5b223bfUL, 0x86830980UL, 0x8b880789UL, 0x9c951592UL, 0x919e1b9bUL, +0x0a47a17cUL, 0x074caf75UL, 0x1051bd6eUL, 0x1d5ab367UL, 0x3e6b9958UL, 0x33609751UL, 0x247d854aUL, 0x29768b43UL, +0x621fd134UL, 0x6f14df3dUL, 0x7809cd26UL, 0x7502c32fUL, 0x5633e910UL, 0x5b38e719UL, 0x4c25f502UL, 0x412efb0bUL, +0x618c9ad7UL, 0x6c8794deUL, 0x7b9a86c5UL, 0x769188ccUL, 0x55a0a2f3UL, 0x58abacfaUL, 0x4fb6bee1UL, 0x42bdb0e8UL, +0x09d4ea9fUL, 0x04dfe496UL, 0x13c2f68dUL, 0x1ec9f884UL, 0x3df8d2bbUL, 0x30f3dcb2UL, 0x27eecea9UL, 0x2ae5c0a0UL, +0xb13c7a47UL, 0xbc37744eUL, 0xab2a6655UL, 0xa621685cUL, 0x85104263UL, 0x881b4c6aUL, 0x9f065e71UL, 0x920d5078UL, +0xd9640a0fUL, 0xd46f0406UL, 0xc372161dUL, 0xce791814UL, 0xed48322bUL, 0xe0433c22UL, 0xf75e2e39UL, 0xfa552030UL, +0xb701ec9aUL, 0xba0ae293UL, 0xad17f088UL, 0xa01cfe81UL, 0x832dd4beUL, 0x8e26dab7UL, 0x993bc8acUL, 0x9430c6a5UL, +0xdf599cd2UL, 0xd25292dbUL, 0xc54f80c0UL, 0xc8448ec9UL, 0xeb75a4f6UL, 0xe67eaaffUL, 0xf163b8e4UL, 0xfc68b6edUL, +0x67b10c0aUL, 0x6aba0203UL, 0x7da71018UL, 0x70ac1e11UL, 0x539d342eUL, 0x5e963a27UL, 0x498b283cUL, 0x44802635UL, +0x0fe97c42UL, 0x02e2724bUL, 0x15ff6050UL, 0x18f46e59UL, 0x3bc54466UL, 0x36ce4a6fUL, 0x21d35874UL, 0x2cd8567dUL, +0x0c7a37a1UL, 0x017139a8UL, 0x166c2bb3UL, 0x1b6725baUL, 0x38560f85UL, 0x355d018cUL, 0x22401397UL, 0x2f4b1d9eUL, +0x642247e9UL, 0x692949e0UL, 0x7e345bfbUL, 0x733f55f2UL, 0x500e7fcdUL, 0x5d0571c4UL, 0x4a1863dfUL, 0x47136dd6UL, +0xdccad731UL, 0xd1c1d938UL, 0xc6dccb23UL, 0xcbd7c52aUL, 0xe8e6ef15UL, 0xe5ede11cUL, 0xf2f0f307UL, 0xfffbfd0eUL, +0xb492a779UL, 0xb999a970UL, 0xae84bb6bUL, 0xa38fb562UL, 0x80be9f5dUL, 0x8db59154UL, 0x9aa8834fUL, 0x97a38d46UL +}; + +static const ulong32 Tks3[] = { +0x00000000UL, 0x090d0b0eUL, 0x121a161cUL, 0x1b171d12UL, 0x24342c38UL, 0x2d392736UL, 0x362e3a24UL, 0x3f23312aUL, +0x48685870UL, 0x4165537eUL, 0x5a724e6cUL, 0x537f4562UL, 0x6c5c7448UL, 0x65517f46UL, 0x7e466254UL, 0x774b695aUL, +0x90d0b0e0UL, 0x99ddbbeeUL, 0x82caa6fcUL, 0x8bc7adf2UL, 0xb4e49cd8UL, 0xbde997d6UL, 0xa6fe8ac4UL, 0xaff381caUL, +0xd8b8e890UL, 0xd1b5e39eUL, 0xcaa2fe8cUL, 0xc3aff582UL, 0xfc8cc4a8UL, 0xf581cfa6UL, 0xee96d2b4UL, 0xe79bd9baUL, +0x3bbb7bdbUL, 0x32b670d5UL, 0x29a16dc7UL, 0x20ac66c9UL, 0x1f8f57e3UL, 0x16825cedUL, 0x0d9541ffUL, 0x04984af1UL, +0x73d323abUL, 0x7ade28a5UL, 0x61c935b7UL, 0x68c43eb9UL, 0x57e70f93UL, 0x5eea049dUL, 0x45fd198fUL, 0x4cf01281UL, +0xab6bcb3bUL, 0xa266c035UL, 0xb971dd27UL, 0xb07cd629UL, 0x8f5fe703UL, 0x8652ec0dUL, 0x9d45f11fUL, 0x9448fa11UL, +0xe303934bUL, 0xea0e9845UL, 0xf1198557UL, 0xf8148e59UL, 0xc737bf73UL, 0xce3ab47dUL, 0xd52da96fUL, 0xdc20a261UL, +0x766df6adUL, 0x7f60fda3UL, 0x6477e0b1UL, 0x6d7aebbfUL, 0x5259da95UL, 0x5b54d19bUL, 0x4043cc89UL, 0x494ec787UL, +0x3e05aeddUL, 0x3708a5d3UL, 0x2c1fb8c1UL, 0x2512b3cfUL, 0x1a3182e5UL, 0x133c89ebUL, 0x082b94f9UL, 0x01269ff7UL, +0xe6bd464dUL, 0xefb04d43UL, 0xf4a75051UL, 0xfdaa5b5fUL, 0xc2896a75UL, 0xcb84617bUL, 0xd0937c69UL, 0xd99e7767UL, +0xaed51e3dUL, 0xa7d81533UL, 0xbccf0821UL, 0xb5c2032fUL, 0x8ae13205UL, 0x83ec390bUL, 0x98fb2419UL, 0x91f62f17UL, +0x4dd68d76UL, 0x44db8678UL, 0x5fcc9b6aUL, 0x56c19064UL, 0x69e2a14eUL, 0x60efaa40UL, 0x7bf8b752UL, 0x72f5bc5cUL, +0x05bed506UL, 0x0cb3de08UL, 0x17a4c31aUL, 0x1ea9c814UL, 0x218af93eUL, 0x2887f230UL, 0x3390ef22UL, 0x3a9de42cUL, +0xdd063d96UL, 0xd40b3698UL, 0xcf1c2b8aUL, 0xc6112084UL, 0xf93211aeUL, 0xf03f1aa0UL, 0xeb2807b2UL, 0xe2250cbcUL, +0x956e65e6UL, 0x9c636ee8UL, 0x877473faUL, 0x8e7978f4UL, 0xb15a49deUL, 0xb85742d0UL, 0xa3405fc2UL, 0xaa4d54ccUL, +0xecdaf741UL, 0xe5d7fc4fUL, 0xfec0e15dUL, 0xf7cdea53UL, 0xc8eedb79UL, 0xc1e3d077UL, 0xdaf4cd65UL, 0xd3f9c66bUL, +0xa4b2af31UL, 0xadbfa43fUL, 0xb6a8b92dUL, 0xbfa5b223UL, 0x80868309UL, 0x898b8807UL, 0x929c9515UL, 0x9b919e1bUL, +0x7c0a47a1UL, 0x75074cafUL, 0x6e1051bdUL, 0x671d5ab3UL, 0x583e6b99UL, 0x51336097UL, 0x4a247d85UL, 0x4329768bUL, +0x34621fd1UL, 0x3d6f14dfUL, 0x267809cdUL, 0x2f7502c3UL, 0x105633e9UL, 0x195b38e7UL, 0x024c25f5UL, 0x0b412efbUL, +0xd7618c9aUL, 0xde6c8794UL, 0xc57b9a86UL, 0xcc769188UL, 0xf355a0a2UL, 0xfa58abacUL, 0xe14fb6beUL, 0xe842bdb0UL, +0x9f09d4eaUL, 0x9604dfe4UL, 0x8d13c2f6UL, 0x841ec9f8UL, 0xbb3df8d2UL, 0xb230f3dcUL, 0xa927eeceUL, 0xa02ae5c0UL, +0x47b13c7aUL, 0x4ebc3774UL, 0x55ab2a66UL, 0x5ca62168UL, 0x63851042UL, 0x6a881b4cUL, 0x719f065eUL, 0x78920d50UL, +0x0fd9640aUL, 0x06d46f04UL, 0x1dc37216UL, 0x14ce7918UL, 0x2bed4832UL, 0x22e0433cUL, 0x39f75e2eUL, 0x30fa5520UL, +0x9ab701ecUL, 0x93ba0ae2UL, 0x88ad17f0UL, 0x81a01cfeUL, 0xbe832dd4UL, 0xb78e26daUL, 0xac993bc8UL, 0xa59430c6UL, +0xd2df599cUL, 0xdbd25292UL, 0xc0c54f80UL, 0xc9c8448eUL, 0xf6eb75a4UL, 0xffe67eaaUL, 0xe4f163b8UL, 0xedfc68b6UL, +0x0a67b10cUL, 0x036aba02UL, 0x187da710UL, 0x1170ac1eUL, 0x2e539d34UL, 0x275e963aUL, 0x3c498b28UL, 0x35448026UL, +0x420fe97cUL, 0x4b02e272UL, 0x5015ff60UL, 0x5918f46eUL, 0x663bc544UL, 0x6f36ce4aUL, 0x7421d358UL, 0x7d2cd856UL, +0xa10c7a37UL, 0xa8017139UL, 0xb3166c2bUL, 0xba1b6725UL, 0x8538560fUL, 0x8c355d01UL, 0x97224013UL, 0x9e2f4b1dUL, +0xe9642247UL, 0xe0692949UL, 0xfb7e345bUL, 0xf2733f55UL, 0xcd500e7fUL, 0xc45d0571UL, 0xdf4a1863UL, 0xd647136dUL, +0x31dccad7UL, 0x38d1c1d9UL, 0x23c6dccbUL, 0x2acbd7c5UL, 0x15e8e6efUL, 0x1ce5ede1UL, 0x07f2f0f3UL, 0x0efffbfdUL, +0x79b492a7UL, 0x70b999a9UL, 0x6bae84bbUL, 0x62a38fb5UL, 0x5d80be9fUL, 0x548db591UL, 0x4f9aa883UL, 0x4697a38dUL +}; + +#endif /* ENCRYPT_ONLY */ + +#endif /* SMALL CODE */ + +static const ulong32 rcon[] = { + 0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL, + 0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL, + 0x1B000000UL, 0x36000000UL, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; + +/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/aes/aes_tab.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/anubis.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/anubis.c new file mode 100644 index 0000000000..ab1ebf6a8d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/anubis.c @@ -0,0 +1,1558 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file anubis.c + Anubis implementation derived from public domain source + Authors: Paulo S.L.M. Barreto and Vincent Rijmen. +*/ + +#include "tomcrypt.h" + +#ifdef LTC_ANUBIS + +const struct ltc_cipher_descriptor anubis_desc = { + "anubis", + 19, + 16, 40, 16, 12, + &anubis_setup, + &anubis_ecb_encrypt, + &anubis_ecb_decrypt, + &anubis_test, + &anubis_done, + &anubis_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +#define MIN_N 4 +#define MAX_N 10 +#define MIN_ROUNDS (8 + MIN_N) +#define MAX_ROUNDS (8 + MAX_N) +#define MIN_KEYSIZEB (4*MIN_N) +#define MAX_KEYSIZEB (4*MAX_N) +#define BLOCKSIZE 128 +#define BLOCKSIZEB (BLOCKSIZE/8) + + +/* + * Though Anubis is endianness-neutral, the encryption tables are listed + * in BIG-ENDIAN format, which is adopted throughout this implementation + * (but little-endian notation would be equally suitable if consistently + * employed). + */ +#if defined(LTC_ANUBIS_TWEAK) + +static const ulong32 T0[256] = { + 0xba69d2bbU, 0x54a84de5U, 0x2f5ebce2U, 0x74e8cd25U, + 0x53a651f7U, 0xd3bb6bd0U, 0xd2b96fd6U, 0x4d9a29b3U, + 0x50a05dfdU, 0xac458acfU, 0x8d070e09U, 0xbf63c6a5U, + 0x70e0dd3dU, 0x52a455f1U, 0x9a29527bU, 0x4c982db5U, + 0xeac98f46U, 0xd5b773c4U, 0x97336655U, 0xd1bf63dcU, + 0x3366ccaaU, 0x51a259fbU, 0x5bb671c7U, 0xa651a2f3U, + 0xdea15ffeU, 0x48903dadU, 0xa84d9ad7U, 0x992f5e71U, + 0xdbab4be0U, 0x3264c8acU, 0xb773e695U, 0xfce5d732U, + 0xe3dbab70U, 0x9e214263U, 0x913f7e41U, 0x9b2b567dU, + 0xe2d9af76U, 0xbb6bd6bdU, 0x4182199bU, 0x6edca579U, + 0xa557aef9U, 0xcb8b0b80U, 0x6bd6b167U, 0x95376e59U, + 0xa15fbee1U, 0xf3fbeb10U, 0xb17ffe81U, 0x0204080cU, + 0xcc851792U, 0xc49537a2U, 0x1d3a744eU, 0x14285078U, + 0xc39b2bb0U, 0x63c69157U, 0xdaa94fe6U, 0x5dba69d3U, + 0x5fbe61dfU, 0xdca557f2U, 0x7dfae913U, 0xcd871394U, + 0x7ffee11fU, 0x5ab475c1U, 0x6cd8ad75U, 0x5cb86dd5U, + 0xf7f3fb08U, 0x264c98d4U, 0xffe3db38U, 0xedc79354U, + 0xe8cd874aU, 0x9d274e69U, 0x6fdea17fU, 0x8e010203U, + 0x19326456U, 0xa05dbae7U, 0xf0fde71aU, 0x890f1e11U, + 0x0f1e3c22U, 0x070e1c12U, 0xaf4386c5U, 0xfbebcb20U, + 0x08102030U, 0x152a547eU, 0x0d1a342eU, 0x04081018U, + 0x01020406U, 0x64c88d45U, 0xdfa35bf8U, 0x76ecc529U, + 0x79f2f90bU, 0xdda753f4U, 0x3d7af48eU, 0x162c5874U, + 0x3f7efc82U, 0x376edcb2U, 0x6ddaa973U, 0x3870e090U, + 0xb96fdeb1U, 0x73e6d137U, 0xe9cf834cU, 0x356ad4beU, + 0x55aa49e3U, 0x71e2d93bU, 0x7bf6f107U, 0x8c050a0fU, + 0x72e4d531U, 0x880d1a17U, 0xf6f1ff0eU, 0x2a54a8fcU, + 0x3e7cf884U, 0x5ebc65d9U, 0x274e9cd2U, 0x468c0589U, + 0x0c183028U, 0x65ca8943U, 0x68d0bd6dU, 0x61c2995bU, + 0x03060c0aU, 0xc19f23bcU, 0x57ae41efU, 0xd6b17fceU, + 0xd9af43ecU, 0x58b07dcdU, 0xd8ad47eaU, 0x66cc8549U, + 0xd7b37bc8U, 0x3a74e89cU, 0xc88d078aU, 0x3c78f088U, + 0xfae9cf26U, 0x96316253U, 0xa753a6f5U, 0x982d5a77U, + 0xecc59752U, 0xb86ddab7U, 0xc7933ba8U, 0xae4182c3U, + 0x69d2b96bU, 0x4b9631a7U, 0xab4b96ddU, 0xa94f9ed1U, + 0x67ce814fU, 0x0a14283cU, 0x478e018fU, 0xf2f9ef16U, + 0xb577ee99U, 0x224488ccU, 0xe5d7b364U, 0xeec19f5eU, + 0xbe61c2a3U, 0x2b56acfaU, 0x811f3e21U, 0x1224486cU, + 0x831b362dU, 0x1b366c5aU, 0x0e1c3824U, 0x23468ccaU, + 0xf5f7f304U, 0x458a0983U, 0x214284c6U, 0xce811f9eU, + 0x499239abU, 0x2c58b0e8U, 0xf9efc32cU, 0xe6d1bf6eU, + 0xb671e293U, 0x2850a0f0U, 0x172e5c72U, 0x8219322bU, + 0x1a34685cU, 0x8b0b161dU, 0xfee1df3eU, 0x8a09121bU, + 0x09122436U, 0xc98f038cU, 0x87132635U, 0x4e9c25b9U, + 0xe1dfa37cU, 0x2e5cb8e4U, 0xe4d5b762U, 0xe0dda77aU, + 0xebcb8b40U, 0x903d7a47U, 0xa455aaffU, 0x1e3c7844U, + 0x85172e39U, 0x60c09d5dU, 0x00000000U, 0x254a94deU, + 0xf4f5f702U, 0xf1ffe31cU, 0x94356a5fU, 0x0b162c3aU, + 0xe7d3bb68U, 0x75eac923U, 0xefc39b58U, 0x3468d0b8U, + 0x3162c4a6U, 0xd4b577c2U, 0xd0bd67daU, 0x86112233U, + 0x7efce519U, 0xad478ec9U, 0xfde7d334U, 0x2952a4f6U, + 0x3060c0a0U, 0x3b76ec9aU, 0x9f234665U, 0xf8edc72aU, + 0xc6913faeU, 0x13264c6aU, 0x060c1814U, 0x050a141eU, + 0xc59733a4U, 0x11224466U, 0x77eec12fU, 0x7cf8ed15U, + 0x7af4f501U, 0x78f0fd0dU, 0x366cd8b4U, 0x1c387048U, + 0x3972e496U, 0x59b279cbU, 0x18306050U, 0x56ac45e9U, + 0xb37bf68dU, 0xb07dfa87U, 0x244890d8U, 0x204080c0U, + 0xb279f28bU, 0x9239724bU, 0xa35bb6edU, 0xc09d27baU, + 0x44880d85U, 0x62c49551U, 0x10204060U, 0xb475ea9fU, + 0x84152a3fU, 0x43861197U, 0x933b764dU, 0xc2992fb6U, + 0x4a9435a1U, 0xbd67cea9U, 0x8f030605U, 0x2d5ab4eeU, + 0xbc65caafU, 0x9c254a6fU, 0x6ad4b561U, 0x40801d9dU, + 0xcf831b98U, 0xa259b2ebU, 0x801d3a27U, 0x4f9e21bfU, + 0x1f3e7c42U, 0xca890f86U, 0xaa4992dbU, 0x42841591U, +}; + +static const ulong32 T1[256] = { + 0x69babbd2U, 0xa854e54dU, 0x5e2fe2bcU, 0xe87425cdU, + 0xa653f751U, 0xbbd3d06bU, 0xb9d2d66fU, 0x9a4db329U, + 0xa050fd5dU, 0x45accf8aU, 0x078d090eU, 0x63bfa5c6U, + 0xe0703dddU, 0xa452f155U, 0x299a7b52U, 0x984cb52dU, + 0xc9ea468fU, 0xb7d5c473U, 0x33975566U, 0xbfd1dc63U, + 0x6633aaccU, 0xa251fb59U, 0xb65bc771U, 0x51a6f3a2U, + 0xa1defe5fU, 0x9048ad3dU, 0x4da8d79aU, 0x2f99715eU, + 0xabdbe04bU, 0x6432acc8U, 0x73b795e6U, 0xe5fc32d7U, + 0xdbe370abU, 0x219e6342U, 0x3f91417eU, 0x2b9b7d56U, + 0xd9e276afU, 0x6bbbbdd6U, 0x82419b19U, 0xdc6e79a5U, + 0x57a5f9aeU, 0x8bcb800bU, 0xd66b67b1U, 0x3795596eU, + 0x5fa1e1beU, 0xfbf310ebU, 0x7fb181feU, 0x04020c08U, + 0x85cc9217U, 0x95c4a237U, 0x3a1d4e74U, 0x28147850U, + 0x9bc3b02bU, 0xc6635791U, 0xa9dae64fU, 0xba5dd369U, + 0xbe5fdf61U, 0xa5dcf257U, 0xfa7d13e9U, 0x87cd9413U, + 0xfe7f1fe1U, 0xb45ac175U, 0xd86c75adU, 0xb85cd56dU, + 0xf3f708fbU, 0x4c26d498U, 0xe3ff38dbU, 0xc7ed5493U, + 0xcde84a87U, 0x279d694eU, 0xde6f7fa1U, 0x018e0302U, + 0x32195664U, 0x5da0e7baU, 0xfdf01ae7U, 0x0f89111eU, + 0x1e0f223cU, 0x0e07121cU, 0x43afc586U, 0xebfb20cbU, + 0x10083020U, 0x2a157e54U, 0x1a0d2e34U, 0x08041810U, + 0x02010604U, 0xc864458dU, 0xa3dff85bU, 0xec7629c5U, + 0xf2790bf9U, 0xa7ddf453U, 0x7a3d8ef4U, 0x2c167458U, + 0x7e3f82fcU, 0x6e37b2dcU, 0xda6d73a9U, 0x703890e0U, + 0x6fb9b1deU, 0xe67337d1U, 0xcfe94c83U, 0x6a35bed4U, + 0xaa55e349U, 0xe2713bd9U, 0xf67b07f1U, 0x058c0f0aU, + 0xe47231d5U, 0x0d88171aU, 0xf1f60effU, 0x542afca8U, + 0x7c3e84f8U, 0xbc5ed965U, 0x4e27d29cU, 0x8c468905U, + 0x180c2830U, 0xca654389U, 0xd0686dbdU, 0xc2615b99U, + 0x06030a0cU, 0x9fc1bc23U, 0xae57ef41U, 0xb1d6ce7fU, + 0xafd9ec43U, 0xb058cd7dU, 0xadd8ea47U, 0xcc664985U, + 0xb3d7c87bU, 0x743a9ce8U, 0x8dc88a07U, 0x783c88f0U, + 0xe9fa26cfU, 0x31965362U, 0x53a7f5a6U, 0x2d98775aU, + 0xc5ec5297U, 0x6db8b7daU, 0x93c7a83bU, 0x41aec382U, + 0xd2696bb9U, 0x964ba731U, 0x4babdd96U, 0x4fa9d19eU, + 0xce674f81U, 0x140a3c28U, 0x8e478f01U, 0xf9f216efU, + 0x77b599eeU, 0x4422cc88U, 0xd7e564b3U, 0xc1ee5e9fU, + 0x61bea3c2U, 0x562bfaacU, 0x1f81213eU, 0x24126c48U, + 0x1b832d36U, 0x361b5a6cU, 0x1c0e2438U, 0x4623ca8cU, + 0xf7f504f3U, 0x8a458309U, 0x4221c684U, 0x81ce9e1fU, + 0x9249ab39U, 0x582ce8b0U, 0xeff92cc3U, 0xd1e66ebfU, + 0x71b693e2U, 0x5028f0a0U, 0x2e17725cU, 0x19822b32U, + 0x341a5c68U, 0x0b8b1d16U, 0xe1fe3edfU, 0x098a1b12U, + 0x12093624U, 0x8fc98c03U, 0x13873526U, 0x9c4eb925U, + 0xdfe17ca3U, 0x5c2ee4b8U, 0xd5e462b7U, 0xdde07aa7U, + 0xcbeb408bU, 0x3d90477aU, 0x55a4ffaaU, 0x3c1e4478U, + 0x1785392eU, 0xc0605d9dU, 0x00000000U, 0x4a25de94U, + 0xf5f402f7U, 0xfff11ce3U, 0x35945f6aU, 0x160b3a2cU, + 0xd3e768bbU, 0xea7523c9U, 0xc3ef589bU, 0x6834b8d0U, + 0x6231a6c4U, 0xb5d4c277U, 0xbdd0da67U, 0x11863322U, + 0xfc7e19e5U, 0x47adc98eU, 0xe7fd34d3U, 0x5229f6a4U, + 0x6030a0c0U, 0x763b9aecU, 0x239f6546U, 0xedf82ac7U, + 0x91c6ae3fU, 0x26136a4cU, 0x0c061418U, 0x0a051e14U, + 0x97c5a433U, 0x22116644U, 0xee772fc1U, 0xf87c15edU, + 0xf47a01f5U, 0xf0780dfdU, 0x6c36b4d8U, 0x381c4870U, + 0x723996e4U, 0xb259cb79U, 0x30185060U, 0xac56e945U, + 0x7bb38df6U, 0x7db087faU, 0x4824d890U, 0x4020c080U, + 0x79b28bf2U, 0x39924b72U, 0x5ba3edb6U, 0x9dc0ba27U, + 0x8844850dU, 0xc4625195U, 0x20106040U, 0x75b49feaU, + 0x15843f2aU, 0x86439711U, 0x3b934d76U, 0x99c2b62fU, + 0x944aa135U, 0x67bda9ceU, 0x038f0506U, 0x5a2deeb4U, + 0x65bcafcaU, 0x259c6f4aU, 0xd46a61b5U, 0x80409d1dU, + 0x83cf981bU, 0x59a2ebb2U, 0x1d80273aU, 0x9e4fbf21U, + 0x3e1f427cU, 0x89ca860fU, 0x49aadb92U, 0x84429115U, +}; + +static const ulong32 T2[256] = { + 0xd2bbba69U, 0x4de554a8U, 0xbce22f5eU, 0xcd2574e8U, + 0x51f753a6U, 0x6bd0d3bbU, 0x6fd6d2b9U, 0x29b34d9aU, + 0x5dfd50a0U, 0x8acfac45U, 0x0e098d07U, 0xc6a5bf63U, + 0xdd3d70e0U, 0x55f152a4U, 0x527b9a29U, 0x2db54c98U, + 0x8f46eac9U, 0x73c4d5b7U, 0x66559733U, 0x63dcd1bfU, + 0xccaa3366U, 0x59fb51a2U, 0x71c75bb6U, 0xa2f3a651U, + 0x5ffedea1U, 0x3dad4890U, 0x9ad7a84dU, 0x5e71992fU, + 0x4be0dbabU, 0xc8ac3264U, 0xe695b773U, 0xd732fce5U, + 0xab70e3dbU, 0x42639e21U, 0x7e41913fU, 0x567d9b2bU, + 0xaf76e2d9U, 0xd6bdbb6bU, 0x199b4182U, 0xa5796edcU, + 0xaef9a557U, 0x0b80cb8bU, 0xb1676bd6U, 0x6e599537U, + 0xbee1a15fU, 0xeb10f3fbU, 0xfe81b17fU, 0x080c0204U, + 0x1792cc85U, 0x37a2c495U, 0x744e1d3aU, 0x50781428U, + 0x2bb0c39bU, 0x915763c6U, 0x4fe6daa9U, 0x69d35dbaU, + 0x61df5fbeU, 0x57f2dca5U, 0xe9137dfaU, 0x1394cd87U, + 0xe11f7ffeU, 0x75c15ab4U, 0xad756cd8U, 0x6dd55cb8U, + 0xfb08f7f3U, 0x98d4264cU, 0xdb38ffe3U, 0x9354edc7U, + 0x874ae8cdU, 0x4e699d27U, 0xa17f6fdeU, 0x02038e01U, + 0x64561932U, 0xbae7a05dU, 0xe71af0fdU, 0x1e11890fU, + 0x3c220f1eU, 0x1c12070eU, 0x86c5af43U, 0xcb20fbebU, + 0x20300810U, 0x547e152aU, 0x342e0d1aU, 0x10180408U, + 0x04060102U, 0x8d4564c8U, 0x5bf8dfa3U, 0xc52976ecU, + 0xf90b79f2U, 0x53f4dda7U, 0xf48e3d7aU, 0x5874162cU, + 0xfc823f7eU, 0xdcb2376eU, 0xa9736ddaU, 0xe0903870U, + 0xdeb1b96fU, 0xd13773e6U, 0x834ce9cfU, 0xd4be356aU, + 0x49e355aaU, 0xd93b71e2U, 0xf1077bf6U, 0x0a0f8c05U, + 0xd53172e4U, 0x1a17880dU, 0xff0ef6f1U, 0xa8fc2a54U, + 0xf8843e7cU, 0x65d95ebcU, 0x9cd2274eU, 0x0589468cU, + 0x30280c18U, 0x894365caU, 0xbd6d68d0U, 0x995b61c2U, + 0x0c0a0306U, 0x23bcc19fU, 0x41ef57aeU, 0x7fced6b1U, + 0x43ecd9afU, 0x7dcd58b0U, 0x47ead8adU, 0x854966ccU, + 0x7bc8d7b3U, 0xe89c3a74U, 0x078ac88dU, 0xf0883c78U, + 0xcf26fae9U, 0x62539631U, 0xa6f5a753U, 0x5a77982dU, + 0x9752ecc5U, 0xdab7b86dU, 0x3ba8c793U, 0x82c3ae41U, + 0xb96b69d2U, 0x31a74b96U, 0x96ddab4bU, 0x9ed1a94fU, + 0x814f67ceU, 0x283c0a14U, 0x018f478eU, 0xef16f2f9U, + 0xee99b577U, 0x88cc2244U, 0xb364e5d7U, 0x9f5eeec1U, + 0xc2a3be61U, 0xacfa2b56U, 0x3e21811fU, 0x486c1224U, + 0x362d831bU, 0x6c5a1b36U, 0x38240e1cU, 0x8cca2346U, + 0xf304f5f7U, 0x0983458aU, 0x84c62142U, 0x1f9ece81U, + 0x39ab4992U, 0xb0e82c58U, 0xc32cf9efU, 0xbf6ee6d1U, + 0xe293b671U, 0xa0f02850U, 0x5c72172eU, 0x322b8219U, + 0x685c1a34U, 0x161d8b0bU, 0xdf3efee1U, 0x121b8a09U, + 0x24360912U, 0x038cc98fU, 0x26358713U, 0x25b94e9cU, + 0xa37ce1dfU, 0xb8e42e5cU, 0xb762e4d5U, 0xa77ae0ddU, + 0x8b40ebcbU, 0x7a47903dU, 0xaaffa455U, 0x78441e3cU, + 0x2e398517U, 0x9d5d60c0U, 0x00000000U, 0x94de254aU, + 0xf702f4f5U, 0xe31cf1ffU, 0x6a5f9435U, 0x2c3a0b16U, + 0xbb68e7d3U, 0xc92375eaU, 0x9b58efc3U, 0xd0b83468U, + 0xc4a63162U, 0x77c2d4b5U, 0x67dad0bdU, 0x22338611U, + 0xe5197efcU, 0x8ec9ad47U, 0xd334fde7U, 0xa4f62952U, + 0xc0a03060U, 0xec9a3b76U, 0x46659f23U, 0xc72af8edU, + 0x3faec691U, 0x4c6a1326U, 0x1814060cU, 0x141e050aU, + 0x33a4c597U, 0x44661122U, 0xc12f77eeU, 0xed157cf8U, + 0xf5017af4U, 0xfd0d78f0U, 0xd8b4366cU, 0x70481c38U, + 0xe4963972U, 0x79cb59b2U, 0x60501830U, 0x45e956acU, + 0xf68db37bU, 0xfa87b07dU, 0x90d82448U, 0x80c02040U, + 0xf28bb279U, 0x724b9239U, 0xb6eda35bU, 0x27bac09dU, + 0x0d854488U, 0x955162c4U, 0x40601020U, 0xea9fb475U, + 0x2a3f8415U, 0x11974386U, 0x764d933bU, 0x2fb6c299U, + 0x35a14a94U, 0xcea9bd67U, 0x06058f03U, 0xb4ee2d5aU, + 0xcaafbc65U, 0x4a6f9c25U, 0xb5616ad4U, 0x1d9d4080U, + 0x1b98cf83U, 0xb2eba259U, 0x3a27801dU, 0x21bf4f9eU, + 0x7c421f3eU, 0x0f86ca89U, 0x92dbaa49U, 0x15914284U, +}; + +static const ulong32 T3[256] = { + 0xbbd269baU, 0xe54da854U, 0xe2bc5e2fU, 0x25cde874U, + 0xf751a653U, 0xd06bbbd3U, 0xd66fb9d2U, 0xb3299a4dU, + 0xfd5da050U, 0xcf8a45acU, 0x090e078dU, 0xa5c663bfU, + 0x3ddde070U, 0xf155a452U, 0x7b52299aU, 0xb52d984cU, + 0x468fc9eaU, 0xc473b7d5U, 0x55663397U, 0xdc63bfd1U, + 0xaacc6633U, 0xfb59a251U, 0xc771b65bU, 0xf3a251a6U, + 0xfe5fa1deU, 0xad3d9048U, 0xd79a4da8U, 0x715e2f99U, + 0xe04babdbU, 0xacc86432U, 0x95e673b7U, 0x32d7e5fcU, + 0x70abdbe3U, 0x6342219eU, 0x417e3f91U, 0x7d562b9bU, + 0x76afd9e2U, 0xbdd66bbbU, 0x9b198241U, 0x79a5dc6eU, + 0xf9ae57a5U, 0x800b8bcbU, 0x67b1d66bU, 0x596e3795U, + 0xe1be5fa1U, 0x10ebfbf3U, 0x81fe7fb1U, 0x0c080402U, + 0x921785ccU, 0xa23795c4U, 0x4e743a1dU, 0x78502814U, + 0xb02b9bc3U, 0x5791c663U, 0xe64fa9daU, 0xd369ba5dU, + 0xdf61be5fU, 0xf257a5dcU, 0x13e9fa7dU, 0x941387cdU, + 0x1fe1fe7fU, 0xc175b45aU, 0x75add86cU, 0xd56db85cU, + 0x08fbf3f7U, 0xd4984c26U, 0x38dbe3ffU, 0x5493c7edU, + 0x4a87cde8U, 0x694e279dU, 0x7fa1de6fU, 0x0302018eU, + 0x56643219U, 0xe7ba5da0U, 0x1ae7fdf0U, 0x111e0f89U, + 0x223c1e0fU, 0x121c0e07U, 0xc58643afU, 0x20cbebfbU, + 0x30201008U, 0x7e542a15U, 0x2e341a0dU, 0x18100804U, + 0x06040201U, 0x458dc864U, 0xf85ba3dfU, 0x29c5ec76U, + 0x0bf9f279U, 0xf453a7ddU, 0x8ef47a3dU, 0x74582c16U, + 0x82fc7e3fU, 0xb2dc6e37U, 0x73a9da6dU, 0x90e07038U, + 0xb1de6fb9U, 0x37d1e673U, 0x4c83cfe9U, 0xbed46a35U, + 0xe349aa55U, 0x3bd9e271U, 0x07f1f67bU, 0x0f0a058cU, + 0x31d5e472U, 0x171a0d88U, 0x0efff1f6U, 0xfca8542aU, + 0x84f87c3eU, 0xd965bc5eU, 0xd29c4e27U, 0x89058c46U, + 0x2830180cU, 0x4389ca65U, 0x6dbdd068U, 0x5b99c261U, + 0x0a0c0603U, 0xbc239fc1U, 0xef41ae57U, 0xce7fb1d6U, + 0xec43afd9U, 0xcd7db058U, 0xea47add8U, 0x4985cc66U, + 0xc87bb3d7U, 0x9ce8743aU, 0x8a078dc8U, 0x88f0783cU, + 0x26cfe9faU, 0x53623196U, 0xf5a653a7U, 0x775a2d98U, + 0x5297c5ecU, 0xb7da6db8U, 0xa83b93c7U, 0xc38241aeU, + 0x6bb9d269U, 0xa731964bU, 0xdd964babU, 0xd19e4fa9U, + 0x4f81ce67U, 0x3c28140aU, 0x8f018e47U, 0x16eff9f2U, + 0x99ee77b5U, 0xcc884422U, 0x64b3d7e5U, 0x5e9fc1eeU, + 0xa3c261beU, 0xfaac562bU, 0x213e1f81U, 0x6c482412U, + 0x2d361b83U, 0x5a6c361bU, 0x24381c0eU, 0xca8c4623U, + 0x04f3f7f5U, 0x83098a45U, 0xc6844221U, 0x9e1f81ceU, + 0xab399249U, 0xe8b0582cU, 0x2cc3eff9U, 0x6ebfd1e6U, + 0x93e271b6U, 0xf0a05028U, 0x725c2e17U, 0x2b321982U, + 0x5c68341aU, 0x1d160b8bU, 0x3edfe1feU, 0x1b12098aU, + 0x36241209U, 0x8c038fc9U, 0x35261387U, 0xb9259c4eU, + 0x7ca3dfe1U, 0xe4b85c2eU, 0x62b7d5e4U, 0x7aa7dde0U, + 0x408bcbebU, 0x477a3d90U, 0xffaa55a4U, 0x44783c1eU, + 0x392e1785U, 0x5d9dc060U, 0x00000000U, 0xde944a25U, + 0x02f7f5f4U, 0x1ce3fff1U, 0x5f6a3594U, 0x3a2c160bU, + 0x68bbd3e7U, 0x23c9ea75U, 0x589bc3efU, 0xb8d06834U, + 0xa6c46231U, 0xc277b5d4U, 0xda67bdd0U, 0x33221186U, + 0x19e5fc7eU, 0xc98e47adU, 0x34d3e7fdU, 0xf6a45229U, + 0xa0c06030U, 0x9aec763bU, 0x6546239fU, 0x2ac7edf8U, + 0xae3f91c6U, 0x6a4c2613U, 0x14180c06U, 0x1e140a05U, + 0xa43397c5U, 0x66442211U, 0x2fc1ee77U, 0x15edf87cU, + 0x01f5f47aU, 0x0dfdf078U, 0xb4d86c36U, 0x4870381cU, + 0x96e47239U, 0xcb79b259U, 0x50603018U, 0xe945ac56U, + 0x8df67bb3U, 0x87fa7db0U, 0xd8904824U, 0xc0804020U, + 0x8bf279b2U, 0x4b723992U, 0xedb65ba3U, 0xba279dc0U, + 0x850d8844U, 0x5195c462U, 0x60402010U, 0x9fea75b4U, + 0x3f2a1584U, 0x97118643U, 0x4d763b93U, 0xb62f99c2U, + 0xa135944aU, 0xa9ce67bdU, 0x0506038fU, 0xeeb45a2dU, + 0xafca65bcU, 0x6f4a259cU, 0x61b5d46aU, 0x9d1d8040U, + 0x981b83cfU, 0xebb259a2U, 0x273a1d80U, 0xbf219e4fU, + 0x427c3e1fU, 0x860f89caU, 0xdb9249aaU, 0x91158442U, +}; + +static const ulong32 T4[256] = { + 0xbabababaU, 0x54545454U, 0x2f2f2f2fU, 0x74747474U, + 0x53535353U, 0xd3d3d3d3U, 0xd2d2d2d2U, 0x4d4d4d4dU, + 0x50505050U, 0xacacacacU, 0x8d8d8d8dU, 0xbfbfbfbfU, + 0x70707070U, 0x52525252U, 0x9a9a9a9aU, 0x4c4c4c4cU, + 0xeaeaeaeaU, 0xd5d5d5d5U, 0x97979797U, 0xd1d1d1d1U, + 0x33333333U, 0x51515151U, 0x5b5b5b5bU, 0xa6a6a6a6U, + 0xdedededeU, 0x48484848U, 0xa8a8a8a8U, 0x99999999U, + 0xdbdbdbdbU, 0x32323232U, 0xb7b7b7b7U, 0xfcfcfcfcU, + 0xe3e3e3e3U, 0x9e9e9e9eU, 0x91919191U, 0x9b9b9b9bU, + 0xe2e2e2e2U, 0xbbbbbbbbU, 0x41414141U, 0x6e6e6e6eU, + 0xa5a5a5a5U, 0xcbcbcbcbU, 0x6b6b6b6bU, 0x95959595U, + 0xa1a1a1a1U, 0xf3f3f3f3U, 0xb1b1b1b1U, 0x02020202U, + 0xccccccccU, 0xc4c4c4c4U, 0x1d1d1d1dU, 0x14141414U, + 0xc3c3c3c3U, 0x63636363U, 0xdadadadaU, 0x5d5d5d5dU, + 0x5f5f5f5fU, 0xdcdcdcdcU, 0x7d7d7d7dU, 0xcdcdcdcdU, + 0x7f7f7f7fU, 0x5a5a5a5aU, 0x6c6c6c6cU, 0x5c5c5c5cU, + 0xf7f7f7f7U, 0x26262626U, 0xffffffffU, 0xededededU, + 0xe8e8e8e8U, 0x9d9d9d9dU, 0x6f6f6f6fU, 0x8e8e8e8eU, + 0x19191919U, 0xa0a0a0a0U, 0xf0f0f0f0U, 0x89898989U, + 0x0f0f0f0fU, 0x07070707U, 0xafafafafU, 0xfbfbfbfbU, + 0x08080808U, 0x15151515U, 0x0d0d0d0dU, 0x04040404U, + 0x01010101U, 0x64646464U, 0xdfdfdfdfU, 0x76767676U, + 0x79797979U, 0xddddddddU, 0x3d3d3d3dU, 0x16161616U, + 0x3f3f3f3fU, 0x37373737U, 0x6d6d6d6dU, 0x38383838U, + 0xb9b9b9b9U, 0x73737373U, 0xe9e9e9e9U, 0x35353535U, + 0x55555555U, 0x71717171U, 0x7b7b7b7bU, 0x8c8c8c8cU, + 0x72727272U, 0x88888888U, 0xf6f6f6f6U, 0x2a2a2a2aU, + 0x3e3e3e3eU, 0x5e5e5e5eU, 0x27272727U, 0x46464646U, + 0x0c0c0c0cU, 0x65656565U, 0x68686868U, 0x61616161U, + 0x03030303U, 0xc1c1c1c1U, 0x57575757U, 0xd6d6d6d6U, + 0xd9d9d9d9U, 0x58585858U, 0xd8d8d8d8U, 0x66666666U, + 0xd7d7d7d7U, 0x3a3a3a3aU, 0xc8c8c8c8U, 0x3c3c3c3cU, + 0xfafafafaU, 0x96969696U, 0xa7a7a7a7U, 0x98989898U, + 0xececececU, 0xb8b8b8b8U, 0xc7c7c7c7U, 0xaeaeaeaeU, + 0x69696969U, 0x4b4b4b4bU, 0xababababU, 0xa9a9a9a9U, + 0x67676767U, 0x0a0a0a0aU, 0x47474747U, 0xf2f2f2f2U, + 0xb5b5b5b5U, 0x22222222U, 0xe5e5e5e5U, 0xeeeeeeeeU, + 0xbebebebeU, 0x2b2b2b2bU, 0x81818181U, 0x12121212U, + 0x83838383U, 0x1b1b1b1bU, 0x0e0e0e0eU, 0x23232323U, + 0xf5f5f5f5U, 0x45454545U, 0x21212121U, 0xcecececeU, + 0x49494949U, 0x2c2c2c2cU, 0xf9f9f9f9U, 0xe6e6e6e6U, + 0xb6b6b6b6U, 0x28282828U, 0x17171717U, 0x82828282U, + 0x1a1a1a1aU, 0x8b8b8b8bU, 0xfefefefeU, 0x8a8a8a8aU, + 0x09090909U, 0xc9c9c9c9U, 0x87878787U, 0x4e4e4e4eU, + 0xe1e1e1e1U, 0x2e2e2e2eU, 0xe4e4e4e4U, 0xe0e0e0e0U, + 0xebebebebU, 0x90909090U, 0xa4a4a4a4U, 0x1e1e1e1eU, + 0x85858585U, 0x60606060U, 0x00000000U, 0x25252525U, + 0xf4f4f4f4U, 0xf1f1f1f1U, 0x94949494U, 0x0b0b0b0bU, + 0xe7e7e7e7U, 0x75757575U, 0xefefefefU, 0x34343434U, + 0x31313131U, 0xd4d4d4d4U, 0xd0d0d0d0U, 0x86868686U, + 0x7e7e7e7eU, 0xadadadadU, 0xfdfdfdfdU, 0x29292929U, + 0x30303030U, 0x3b3b3b3bU, 0x9f9f9f9fU, 0xf8f8f8f8U, + 0xc6c6c6c6U, 0x13131313U, 0x06060606U, 0x05050505U, + 0xc5c5c5c5U, 0x11111111U, 0x77777777U, 0x7c7c7c7cU, + 0x7a7a7a7aU, 0x78787878U, 0x36363636U, 0x1c1c1c1cU, + 0x39393939U, 0x59595959U, 0x18181818U, 0x56565656U, + 0xb3b3b3b3U, 0xb0b0b0b0U, 0x24242424U, 0x20202020U, + 0xb2b2b2b2U, 0x92929292U, 0xa3a3a3a3U, 0xc0c0c0c0U, + 0x44444444U, 0x62626262U, 0x10101010U, 0xb4b4b4b4U, + 0x84848484U, 0x43434343U, 0x93939393U, 0xc2c2c2c2U, + 0x4a4a4a4aU, 0xbdbdbdbdU, 0x8f8f8f8fU, 0x2d2d2d2dU, + 0xbcbcbcbcU, 0x9c9c9c9cU, 0x6a6a6a6aU, 0x40404040U, + 0xcfcfcfcfU, 0xa2a2a2a2U, 0x80808080U, 0x4f4f4f4fU, + 0x1f1f1f1fU, 0xcacacacaU, 0xaaaaaaaaU, 0x42424242U, +}; + +static const ulong32 T5[256] = { + 0x00000000U, 0x01020608U, 0x02040c10U, 0x03060a18U, + 0x04081820U, 0x050a1e28U, 0x060c1430U, 0x070e1238U, + 0x08103040U, 0x09123648U, 0x0a143c50U, 0x0b163a58U, + 0x0c182860U, 0x0d1a2e68U, 0x0e1c2470U, 0x0f1e2278U, + 0x10206080U, 0x11226688U, 0x12246c90U, 0x13266a98U, + 0x142878a0U, 0x152a7ea8U, 0x162c74b0U, 0x172e72b8U, + 0x183050c0U, 0x193256c8U, 0x1a345cd0U, 0x1b365ad8U, + 0x1c3848e0U, 0x1d3a4ee8U, 0x1e3c44f0U, 0x1f3e42f8U, + 0x2040c01dU, 0x2142c615U, 0x2244cc0dU, 0x2346ca05U, + 0x2448d83dU, 0x254ade35U, 0x264cd42dU, 0x274ed225U, + 0x2850f05dU, 0x2952f655U, 0x2a54fc4dU, 0x2b56fa45U, + 0x2c58e87dU, 0x2d5aee75U, 0x2e5ce46dU, 0x2f5ee265U, + 0x3060a09dU, 0x3162a695U, 0x3264ac8dU, 0x3366aa85U, + 0x3468b8bdU, 0x356abeb5U, 0x366cb4adU, 0x376eb2a5U, + 0x387090ddU, 0x397296d5U, 0x3a749ccdU, 0x3b769ac5U, + 0x3c7888fdU, 0x3d7a8ef5U, 0x3e7c84edU, 0x3f7e82e5U, + 0x40809d3aU, 0x41829b32U, 0x4284912aU, 0x43869722U, + 0x4488851aU, 0x458a8312U, 0x468c890aU, 0x478e8f02U, + 0x4890ad7aU, 0x4992ab72U, 0x4a94a16aU, 0x4b96a762U, + 0x4c98b55aU, 0x4d9ab352U, 0x4e9cb94aU, 0x4f9ebf42U, + 0x50a0fdbaU, 0x51a2fbb2U, 0x52a4f1aaU, 0x53a6f7a2U, + 0x54a8e59aU, 0x55aae392U, 0x56ace98aU, 0x57aeef82U, + 0x58b0cdfaU, 0x59b2cbf2U, 0x5ab4c1eaU, 0x5bb6c7e2U, + 0x5cb8d5daU, 0x5dbad3d2U, 0x5ebcd9caU, 0x5fbedfc2U, + 0x60c05d27U, 0x61c25b2fU, 0x62c45137U, 0x63c6573fU, + 0x64c84507U, 0x65ca430fU, 0x66cc4917U, 0x67ce4f1fU, + 0x68d06d67U, 0x69d26b6fU, 0x6ad46177U, 0x6bd6677fU, + 0x6cd87547U, 0x6dda734fU, 0x6edc7957U, 0x6fde7f5fU, + 0x70e03da7U, 0x71e23bafU, 0x72e431b7U, 0x73e637bfU, + 0x74e82587U, 0x75ea238fU, 0x76ec2997U, 0x77ee2f9fU, + 0x78f00de7U, 0x79f20befU, 0x7af401f7U, 0x7bf607ffU, + 0x7cf815c7U, 0x7dfa13cfU, 0x7efc19d7U, 0x7ffe1fdfU, + 0x801d2774U, 0x811f217cU, 0x82192b64U, 0x831b2d6cU, + 0x84153f54U, 0x8517395cU, 0x86113344U, 0x8713354cU, + 0x880d1734U, 0x890f113cU, 0x8a091b24U, 0x8b0b1d2cU, + 0x8c050f14U, 0x8d07091cU, 0x8e010304U, 0x8f03050cU, + 0x903d47f4U, 0x913f41fcU, 0x92394be4U, 0x933b4decU, + 0x94355fd4U, 0x953759dcU, 0x963153c4U, 0x973355ccU, + 0x982d77b4U, 0x992f71bcU, 0x9a297ba4U, 0x9b2b7dacU, + 0x9c256f94U, 0x9d27699cU, 0x9e216384U, 0x9f23658cU, + 0xa05de769U, 0xa15fe161U, 0xa259eb79U, 0xa35bed71U, + 0xa455ff49U, 0xa557f941U, 0xa651f359U, 0xa753f551U, + 0xa84dd729U, 0xa94fd121U, 0xaa49db39U, 0xab4bdd31U, + 0xac45cf09U, 0xad47c901U, 0xae41c319U, 0xaf43c511U, + 0xb07d87e9U, 0xb17f81e1U, 0xb2798bf9U, 0xb37b8df1U, + 0xb4759fc9U, 0xb57799c1U, 0xb67193d9U, 0xb77395d1U, + 0xb86db7a9U, 0xb96fb1a1U, 0xba69bbb9U, 0xbb6bbdb1U, + 0xbc65af89U, 0xbd67a981U, 0xbe61a399U, 0xbf63a591U, + 0xc09dba4eU, 0xc19fbc46U, 0xc299b65eU, 0xc39bb056U, + 0xc495a26eU, 0xc597a466U, 0xc691ae7eU, 0xc793a876U, + 0xc88d8a0eU, 0xc98f8c06U, 0xca89861eU, 0xcb8b8016U, + 0xcc85922eU, 0xcd879426U, 0xce819e3eU, 0xcf839836U, + 0xd0bddaceU, 0xd1bfdcc6U, 0xd2b9d6deU, 0xd3bbd0d6U, + 0xd4b5c2eeU, 0xd5b7c4e6U, 0xd6b1cefeU, 0xd7b3c8f6U, + 0xd8adea8eU, 0xd9afec86U, 0xdaa9e69eU, 0xdbabe096U, + 0xdca5f2aeU, 0xdda7f4a6U, 0xdea1febeU, 0xdfa3f8b6U, + 0xe0dd7a53U, 0xe1df7c5bU, 0xe2d97643U, 0xe3db704bU, + 0xe4d56273U, 0xe5d7647bU, 0xe6d16e63U, 0xe7d3686bU, + 0xe8cd4a13U, 0xe9cf4c1bU, 0xeac94603U, 0xebcb400bU, + 0xecc55233U, 0xedc7543bU, 0xeec15e23U, 0xefc3582bU, + 0xf0fd1ad3U, 0xf1ff1cdbU, 0xf2f916c3U, 0xf3fb10cbU, + 0xf4f502f3U, 0xf5f704fbU, 0xf6f10ee3U, 0xf7f308ebU, + 0xf8ed2a93U, 0xf9ef2c9bU, 0xfae92683U, 0xfbeb208bU, + 0xfce532b3U, 0xfde734bbU, 0xfee13ea3U, 0xffe338abU, +}; + +/** + * The round constants. + */ +static const ulong32 rc[] = { + 0xba542f74U, 0x53d3d24dU, 0x50ac8dbfU, 0x70529a4cU, + 0xead597d1U, 0x33515ba6U, 0xde48a899U, 0xdb32b7fcU, + 0xe39e919bU, 0xe2bb416eU, 0xa5cb6b95U, 0xa1f3b102U, + 0xccc41d14U, 0xc363da5dU, 0x5fdc7dcdU, 0x7f5a6c5cU, + 0xf726ffedU, 0xe89d6f8eU, 0x19a0f089U, +}; + + + +#else + + +static const ulong32 T0[256] = { + 0xa753a6f5U, 0xd3bb6bd0U, 0xe6d1bf6eU, 0x71e2d93bU, + 0xd0bd67daU, 0xac458acfU, 0x4d9a29b3U, 0x79f2f90bU, + 0x3a74e89cU, 0xc98f038cU, 0x913f7e41U, 0xfce5d732U, + 0x1e3c7844U, 0x478e018fU, 0x54a84de5U, 0xbd67cea9U, + 0x8c050a0fU, 0xa557aef9U, 0x7af4f501U, 0xfbebcb20U, + 0x63c69157U, 0xb86ddab7U, 0xdda753f4U, 0xd4b577c2U, + 0xe5d7b364U, 0xb37bf68dU, 0xc59733a4U, 0xbe61c2a3U, + 0xa94f9ed1U, 0x880d1a17U, 0x0c183028U, 0xa259b2ebU, + 0x3972e496U, 0xdfa35bf8U, 0x2952a4f6U, 0xdaa94fe6U, + 0x2b56acfaU, 0xa84d9ad7U, 0xcb8b0b80U, 0x4c982db5U, + 0x4b9631a7U, 0x224488ccU, 0xaa4992dbU, 0x244890d8U, + 0x4182199bU, 0x70e0dd3dU, 0xa651a2f3U, 0xf9efc32cU, + 0x5ab475c1U, 0xe2d9af76U, 0xb07dfa87U, 0x366cd8b4U, + 0x7dfae913U, 0xe4d5b762U, 0x3366ccaaU, 0xffe3db38U, + 0x60c09d5dU, 0x204080c0U, 0x08102030U, 0x8b0b161dU, + 0x5ebc65d9U, 0xab4b96ddU, 0x7ffee11fU, 0x78f0fd0dU, + 0x7cf8ed15U, 0x2c58b0e8U, 0x57ae41efU, 0xd2b96fd6U, + 0xdca557f2U, 0x6ddaa973U, 0x7efce519U, 0x0d1a342eU, + 0x53a651f7U, 0x94356a5fU, 0xc39b2bb0U, 0x2850a0f0U, + 0x274e9cd2U, 0x060c1814U, 0x5fbe61dfU, 0xad478ec9U, + 0x67ce814fU, 0x5cb86dd5U, 0x55aa49e3U, 0x48903dadU, + 0x0e1c3824U, 0x52a455f1U, 0xeac98f46U, 0x42841591U, + 0x5bb671c7U, 0x5dba69d3U, 0x3060c0a0U, 0x58b07dcdU, + 0x51a259fbU, 0x59b279cbU, 0x3c78f088U, 0x4e9c25b9U, + 0x3870e090U, 0x8a09121bU, 0x72e4d531U, 0x14285078U, + 0xe7d3bb68U, 0xc6913faeU, 0xdea15ffeU, 0x50a05dfdU, + 0x8e010203U, 0x9239724bU, 0xd1bf63dcU, 0x77eec12fU, + 0x933b764dU, 0x458a0983U, 0x9a29527bU, 0xce811f9eU, + 0x2d5ab4eeU, 0x03060c0aU, 0x62c49551U, 0xb671e293U, + 0xb96fdeb1U, 0xbf63c6a5U, 0x96316253U, 0x6bd6b167U, + 0x3f7efc82U, 0x070e1c12U, 0x1224486cU, 0xae4182c3U, + 0x40801d9dU, 0x3468d0b8U, 0x468c0589U, 0x3e7cf884U, + 0xdbab4be0U, 0xcf831b98U, 0xecc59752U, 0xcc851792U, + 0xc19f23bcU, 0xa15fbee1U, 0xc09d27baU, 0xd6b17fceU, + 0x1d3a744eU, 0xf4f5f702U, 0x61c2995bU, 0x3b76ec9aU, + 0x10204060U, 0xd8ad47eaU, 0x68d0bd6dU, 0xa05dbae7U, + 0xb17ffe81U, 0x0a14283cU, 0x69d2b96bU, 0x6cd8ad75U, + 0x499239abU, 0xfae9cf26U, 0x76ecc529U, 0xc49537a2U, + 0x9e214263U, 0x9b2b567dU, 0x6edca579U, 0x992f5e71U, + 0xc2992fb6U, 0xb773e695U, 0x982d5a77U, 0xbc65caafU, + 0x8f030605U, 0x85172e39U, 0x1f3e7c42U, 0xb475ea9fU, + 0xf8edc72aU, 0x11224466U, 0x2e5cb8e4U, 0x00000000U, + 0x254a94deU, 0x1c387048U, 0x2a54a8fcU, 0x3d7af48eU, + 0x050a141eU, 0x4f9e21bfU, 0x7bf6f107U, 0xb279f28bU, + 0x3264c8acU, 0x903d7a47U, 0xaf4386c5U, 0x19326456U, + 0xa35bb6edU, 0xf7f3fb08U, 0x73e6d137U, 0x9d274e69U, + 0x152a547eU, 0x74e8cd25U, 0xeec19f5eU, 0xca890f86U, + 0x9f234665U, 0x0f1e3c22U, 0x1b366c5aU, 0x75eac923U, + 0x86112233U, 0x84152a3fU, 0x9c254a6fU, 0x4a9435a1U, + 0x97336655U, 0x1a34685cU, 0x65ca8943U, 0xf6f1ff0eU, + 0xedc79354U, 0x09122436U, 0xbb6bd6bdU, 0x264c98d4U, + 0x831b362dU, 0xebcb8b40U, 0x6fdea17fU, 0x811f3e21U, + 0x04081018U, 0x6ad4b561U, 0x43861197U, 0x01020406U, + 0x172e5c72U, 0xe1dfa37cU, 0x87132635U, 0xf5f7f304U, + 0x8d070e09U, 0xe3dbab70U, 0x23468ccaU, 0x801d3a27U, + 0x44880d85U, 0x162c5874U, 0x66cc8549U, 0x214284c6U, + 0xfee1df3eU, 0xd5b773c4U, 0x3162c4a6U, 0xd9af43ecU, + 0x356ad4beU, 0x18306050U, 0x0204080cU, 0x64c88d45U, + 0xf2f9ef16U, 0xf1ffe31cU, 0x56ac45e9U, 0xcd871394U, + 0x8219322bU, 0xc88d078aU, 0xba69d2bbU, 0xf0fde71aU, + 0xefc39b58U, 0xe9cf834cU, 0xe8cd874aU, 0xfde7d334U, + 0x890f1e11U, 0xd7b37bc8U, 0xc7933ba8U, 0xb577ee99U, + 0xa455aaffU, 0x2f5ebce2U, 0x95376e59U, 0x13264c6aU, + 0x0b162c3aU, 0xf3fbeb10U, 0xe0dda77aU, 0x376edcb2U, +}; + +static const ulong32 T1[256] = { + 0x53a7f5a6U, 0xbbd3d06bU, 0xd1e66ebfU, 0xe2713bd9U, + 0xbdd0da67U, 0x45accf8aU, 0x9a4db329U, 0xf2790bf9U, + 0x743a9ce8U, 0x8fc98c03U, 0x3f91417eU, 0xe5fc32d7U, + 0x3c1e4478U, 0x8e478f01U, 0xa854e54dU, 0x67bda9ceU, + 0x058c0f0aU, 0x57a5f9aeU, 0xf47a01f5U, 0xebfb20cbU, + 0xc6635791U, 0x6db8b7daU, 0xa7ddf453U, 0xb5d4c277U, + 0xd7e564b3U, 0x7bb38df6U, 0x97c5a433U, 0x61bea3c2U, + 0x4fa9d19eU, 0x0d88171aU, 0x180c2830U, 0x59a2ebb2U, + 0x723996e4U, 0xa3dff85bU, 0x5229f6a4U, 0xa9dae64fU, + 0x562bfaacU, 0x4da8d79aU, 0x8bcb800bU, 0x984cb52dU, + 0x964ba731U, 0x4422cc88U, 0x49aadb92U, 0x4824d890U, + 0x82419b19U, 0xe0703dddU, 0x51a6f3a2U, 0xeff92cc3U, + 0xb45ac175U, 0xd9e276afU, 0x7db087faU, 0x6c36b4d8U, + 0xfa7d13e9U, 0xd5e462b7U, 0x6633aaccU, 0xe3ff38dbU, + 0xc0605d9dU, 0x4020c080U, 0x10083020U, 0x0b8b1d16U, + 0xbc5ed965U, 0x4babdd96U, 0xfe7f1fe1U, 0xf0780dfdU, + 0xf87c15edU, 0x582ce8b0U, 0xae57ef41U, 0xb9d2d66fU, + 0xa5dcf257U, 0xda6d73a9U, 0xfc7e19e5U, 0x1a0d2e34U, + 0xa653f751U, 0x35945f6aU, 0x9bc3b02bU, 0x5028f0a0U, + 0x4e27d29cU, 0x0c061418U, 0xbe5fdf61U, 0x47adc98eU, + 0xce674f81U, 0xb85cd56dU, 0xaa55e349U, 0x9048ad3dU, + 0x1c0e2438U, 0xa452f155U, 0xc9ea468fU, 0x84429115U, + 0xb65bc771U, 0xba5dd369U, 0x6030a0c0U, 0xb058cd7dU, + 0xa251fb59U, 0xb259cb79U, 0x783c88f0U, 0x9c4eb925U, + 0x703890e0U, 0x098a1b12U, 0xe47231d5U, 0x28147850U, + 0xd3e768bbU, 0x91c6ae3fU, 0xa1defe5fU, 0xa050fd5dU, + 0x018e0302U, 0x39924b72U, 0xbfd1dc63U, 0xee772fc1U, + 0x3b934d76U, 0x8a458309U, 0x299a7b52U, 0x81ce9e1fU, + 0x5a2deeb4U, 0x06030a0cU, 0xc4625195U, 0x71b693e2U, + 0x6fb9b1deU, 0x63bfa5c6U, 0x31965362U, 0xd66b67b1U, + 0x7e3f82fcU, 0x0e07121cU, 0x24126c48U, 0x41aec382U, + 0x80409d1dU, 0x6834b8d0U, 0x8c468905U, 0x7c3e84f8U, + 0xabdbe04bU, 0x83cf981bU, 0xc5ec5297U, 0x85cc9217U, + 0x9fc1bc23U, 0x5fa1e1beU, 0x9dc0ba27U, 0xb1d6ce7fU, + 0x3a1d4e74U, 0xf5f402f7U, 0xc2615b99U, 0x763b9aecU, + 0x20106040U, 0xadd8ea47U, 0xd0686dbdU, 0x5da0e7baU, + 0x7fb181feU, 0x140a3c28U, 0xd2696bb9U, 0xd86c75adU, + 0x9249ab39U, 0xe9fa26cfU, 0xec7629c5U, 0x95c4a237U, + 0x219e6342U, 0x2b9b7d56U, 0xdc6e79a5U, 0x2f99715eU, + 0x99c2b62fU, 0x73b795e6U, 0x2d98775aU, 0x65bcafcaU, + 0x038f0506U, 0x1785392eU, 0x3e1f427cU, 0x75b49feaU, + 0xedf82ac7U, 0x22116644U, 0x5c2ee4b8U, 0x00000000U, + 0x4a25de94U, 0x381c4870U, 0x542afca8U, 0x7a3d8ef4U, + 0x0a051e14U, 0x9e4fbf21U, 0xf67b07f1U, 0x79b28bf2U, + 0x6432acc8U, 0x3d90477aU, 0x43afc586U, 0x32195664U, + 0x5ba3edb6U, 0xf3f708fbU, 0xe67337d1U, 0x279d694eU, + 0x2a157e54U, 0xe87425cdU, 0xc1ee5e9fU, 0x89ca860fU, + 0x239f6546U, 0x1e0f223cU, 0x361b5a6cU, 0xea7523c9U, + 0x11863322U, 0x15843f2aU, 0x259c6f4aU, 0x944aa135U, + 0x33975566U, 0x341a5c68U, 0xca654389U, 0xf1f60effU, + 0xc7ed5493U, 0x12093624U, 0x6bbbbdd6U, 0x4c26d498U, + 0x1b832d36U, 0xcbeb408bU, 0xde6f7fa1U, 0x1f81213eU, + 0x08041810U, 0xd46a61b5U, 0x86439711U, 0x02010604U, + 0x2e17725cU, 0xdfe17ca3U, 0x13873526U, 0xf7f504f3U, + 0x078d090eU, 0xdbe370abU, 0x4623ca8cU, 0x1d80273aU, + 0x8844850dU, 0x2c167458U, 0xcc664985U, 0x4221c684U, + 0xe1fe3edfU, 0xb7d5c473U, 0x6231a6c4U, 0xafd9ec43U, + 0x6a35bed4U, 0x30185060U, 0x04020c08U, 0xc864458dU, + 0xf9f216efU, 0xfff11ce3U, 0xac56e945U, 0x87cd9413U, + 0x19822b32U, 0x8dc88a07U, 0x69babbd2U, 0xfdf01ae7U, + 0xc3ef589bU, 0xcfe94c83U, 0xcde84a87U, 0xe7fd34d3U, + 0x0f89111eU, 0xb3d7c87bU, 0x93c7a83bU, 0x77b599eeU, + 0x55a4ffaaU, 0x5e2fe2bcU, 0x3795596eU, 0x26136a4cU, + 0x160b3a2cU, 0xfbf310ebU, 0xdde07aa7U, 0x6e37b2dcU, +}; + +static const ulong32 T2[256] = { + 0xa6f5a753U, 0x6bd0d3bbU, 0xbf6ee6d1U, 0xd93b71e2U, + 0x67dad0bdU, 0x8acfac45U, 0x29b34d9aU, 0xf90b79f2U, + 0xe89c3a74U, 0x038cc98fU, 0x7e41913fU, 0xd732fce5U, + 0x78441e3cU, 0x018f478eU, 0x4de554a8U, 0xcea9bd67U, + 0x0a0f8c05U, 0xaef9a557U, 0xf5017af4U, 0xcb20fbebU, + 0x915763c6U, 0xdab7b86dU, 0x53f4dda7U, 0x77c2d4b5U, + 0xb364e5d7U, 0xf68db37bU, 0x33a4c597U, 0xc2a3be61U, + 0x9ed1a94fU, 0x1a17880dU, 0x30280c18U, 0xb2eba259U, + 0xe4963972U, 0x5bf8dfa3U, 0xa4f62952U, 0x4fe6daa9U, + 0xacfa2b56U, 0x9ad7a84dU, 0x0b80cb8bU, 0x2db54c98U, + 0x31a74b96U, 0x88cc2244U, 0x92dbaa49U, 0x90d82448U, + 0x199b4182U, 0xdd3d70e0U, 0xa2f3a651U, 0xc32cf9efU, + 0x75c15ab4U, 0xaf76e2d9U, 0xfa87b07dU, 0xd8b4366cU, + 0xe9137dfaU, 0xb762e4d5U, 0xccaa3366U, 0xdb38ffe3U, + 0x9d5d60c0U, 0x80c02040U, 0x20300810U, 0x161d8b0bU, + 0x65d95ebcU, 0x96ddab4bU, 0xe11f7ffeU, 0xfd0d78f0U, + 0xed157cf8U, 0xb0e82c58U, 0x41ef57aeU, 0x6fd6d2b9U, + 0x57f2dca5U, 0xa9736ddaU, 0xe5197efcU, 0x342e0d1aU, + 0x51f753a6U, 0x6a5f9435U, 0x2bb0c39bU, 0xa0f02850U, + 0x9cd2274eU, 0x1814060cU, 0x61df5fbeU, 0x8ec9ad47U, + 0x814f67ceU, 0x6dd55cb8U, 0x49e355aaU, 0x3dad4890U, + 0x38240e1cU, 0x55f152a4U, 0x8f46eac9U, 0x15914284U, + 0x71c75bb6U, 0x69d35dbaU, 0xc0a03060U, 0x7dcd58b0U, + 0x59fb51a2U, 0x79cb59b2U, 0xf0883c78U, 0x25b94e9cU, + 0xe0903870U, 0x121b8a09U, 0xd53172e4U, 0x50781428U, + 0xbb68e7d3U, 0x3faec691U, 0x5ffedea1U, 0x5dfd50a0U, + 0x02038e01U, 0x724b9239U, 0x63dcd1bfU, 0xc12f77eeU, + 0x764d933bU, 0x0983458aU, 0x527b9a29U, 0x1f9ece81U, + 0xb4ee2d5aU, 0x0c0a0306U, 0x955162c4U, 0xe293b671U, + 0xdeb1b96fU, 0xc6a5bf63U, 0x62539631U, 0xb1676bd6U, + 0xfc823f7eU, 0x1c12070eU, 0x486c1224U, 0x82c3ae41U, + 0x1d9d4080U, 0xd0b83468U, 0x0589468cU, 0xf8843e7cU, + 0x4be0dbabU, 0x1b98cf83U, 0x9752ecc5U, 0x1792cc85U, + 0x23bcc19fU, 0xbee1a15fU, 0x27bac09dU, 0x7fced6b1U, + 0x744e1d3aU, 0xf702f4f5U, 0x995b61c2U, 0xec9a3b76U, + 0x40601020U, 0x47ead8adU, 0xbd6d68d0U, 0xbae7a05dU, + 0xfe81b17fU, 0x283c0a14U, 0xb96b69d2U, 0xad756cd8U, + 0x39ab4992U, 0xcf26fae9U, 0xc52976ecU, 0x37a2c495U, + 0x42639e21U, 0x567d9b2bU, 0xa5796edcU, 0x5e71992fU, + 0x2fb6c299U, 0xe695b773U, 0x5a77982dU, 0xcaafbc65U, + 0x06058f03U, 0x2e398517U, 0x7c421f3eU, 0xea9fb475U, + 0xc72af8edU, 0x44661122U, 0xb8e42e5cU, 0x00000000U, + 0x94de254aU, 0x70481c38U, 0xa8fc2a54U, 0xf48e3d7aU, + 0x141e050aU, 0x21bf4f9eU, 0xf1077bf6U, 0xf28bb279U, + 0xc8ac3264U, 0x7a47903dU, 0x86c5af43U, 0x64561932U, + 0xb6eda35bU, 0xfb08f7f3U, 0xd13773e6U, 0x4e699d27U, + 0x547e152aU, 0xcd2574e8U, 0x9f5eeec1U, 0x0f86ca89U, + 0x46659f23U, 0x3c220f1eU, 0x6c5a1b36U, 0xc92375eaU, + 0x22338611U, 0x2a3f8415U, 0x4a6f9c25U, 0x35a14a94U, + 0x66559733U, 0x685c1a34U, 0x894365caU, 0xff0ef6f1U, + 0x9354edc7U, 0x24360912U, 0xd6bdbb6bU, 0x98d4264cU, + 0x362d831bU, 0x8b40ebcbU, 0xa17f6fdeU, 0x3e21811fU, + 0x10180408U, 0xb5616ad4U, 0x11974386U, 0x04060102U, + 0x5c72172eU, 0xa37ce1dfU, 0x26358713U, 0xf304f5f7U, + 0x0e098d07U, 0xab70e3dbU, 0x8cca2346U, 0x3a27801dU, + 0x0d854488U, 0x5874162cU, 0x854966ccU, 0x84c62142U, + 0xdf3efee1U, 0x73c4d5b7U, 0xc4a63162U, 0x43ecd9afU, + 0xd4be356aU, 0x60501830U, 0x080c0204U, 0x8d4564c8U, + 0xef16f2f9U, 0xe31cf1ffU, 0x45e956acU, 0x1394cd87U, + 0x322b8219U, 0x078ac88dU, 0xd2bbba69U, 0xe71af0fdU, + 0x9b58efc3U, 0x834ce9cfU, 0x874ae8cdU, 0xd334fde7U, + 0x1e11890fU, 0x7bc8d7b3U, 0x3ba8c793U, 0xee99b577U, + 0xaaffa455U, 0xbce22f5eU, 0x6e599537U, 0x4c6a1326U, + 0x2c3a0b16U, 0xeb10f3fbU, 0xa77ae0ddU, 0xdcb2376eU, +}; + +static const ulong32 T3[256] = { + 0xf5a653a7U, 0xd06bbbd3U, 0x6ebfd1e6U, 0x3bd9e271U, + 0xda67bdd0U, 0xcf8a45acU, 0xb3299a4dU, 0x0bf9f279U, + 0x9ce8743aU, 0x8c038fc9U, 0x417e3f91U, 0x32d7e5fcU, + 0x44783c1eU, 0x8f018e47U, 0xe54da854U, 0xa9ce67bdU, + 0x0f0a058cU, 0xf9ae57a5U, 0x01f5f47aU, 0x20cbebfbU, + 0x5791c663U, 0xb7da6db8U, 0xf453a7ddU, 0xc277b5d4U, + 0x64b3d7e5U, 0x8df67bb3U, 0xa43397c5U, 0xa3c261beU, + 0xd19e4fa9U, 0x171a0d88U, 0x2830180cU, 0xebb259a2U, + 0x96e47239U, 0xf85ba3dfU, 0xf6a45229U, 0xe64fa9daU, + 0xfaac562bU, 0xd79a4da8U, 0x800b8bcbU, 0xb52d984cU, + 0xa731964bU, 0xcc884422U, 0xdb9249aaU, 0xd8904824U, + 0x9b198241U, 0x3ddde070U, 0xf3a251a6U, 0x2cc3eff9U, + 0xc175b45aU, 0x76afd9e2U, 0x87fa7db0U, 0xb4d86c36U, + 0x13e9fa7dU, 0x62b7d5e4U, 0xaacc6633U, 0x38dbe3ffU, + 0x5d9dc060U, 0xc0804020U, 0x30201008U, 0x1d160b8bU, + 0xd965bc5eU, 0xdd964babU, 0x1fe1fe7fU, 0x0dfdf078U, + 0x15edf87cU, 0xe8b0582cU, 0xef41ae57U, 0xd66fb9d2U, + 0xf257a5dcU, 0x73a9da6dU, 0x19e5fc7eU, 0x2e341a0dU, + 0xf751a653U, 0x5f6a3594U, 0xb02b9bc3U, 0xf0a05028U, + 0xd29c4e27U, 0x14180c06U, 0xdf61be5fU, 0xc98e47adU, + 0x4f81ce67U, 0xd56db85cU, 0xe349aa55U, 0xad3d9048U, + 0x24381c0eU, 0xf155a452U, 0x468fc9eaU, 0x91158442U, + 0xc771b65bU, 0xd369ba5dU, 0xa0c06030U, 0xcd7db058U, + 0xfb59a251U, 0xcb79b259U, 0x88f0783cU, 0xb9259c4eU, + 0x90e07038U, 0x1b12098aU, 0x31d5e472U, 0x78502814U, + 0x68bbd3e7U, 0xae3f91c6U, 0xfe5fa1deU, 0xfd5da050U, + 0x0302018eU, 0x4b723992U, 0xdc63bfd1U, 0x2fc1ee77U, + 0x4d763b93U, 0x83098a45U, 0x7b52299aU, 0x9e1f81ceU, + 0xeeb45a2dU, 0x0a0c0603U, 0x5195c462U, 0x93e271b6U, + 0xb1de6fb9U, 0xa5c663bfU, 0x53623196U, 0x67b1d66bU, + 0x82fc7e3fU, 0x121c0e07U, 0x6c482412U, 0xc38241aeU, + 0x9d1d8040U, 0xb8d06834U, 0x89058c46U, 0x84f87c3eU, + 0xe04babdbU, 0x981b83cfU, 0x5297c5ecU, 0x921785ccU, + 0xbc239fc1U, 0xe1be5fa1U, 0xba279dc0U, 0xce7fb1d6U, + 0x4e743a1dU, 0x02f7f5f4U, 0x5b99c261U, 0x9aec763bU, + 0x60402010U, 0xea47add8U, 0x6dbdd068U, 0xe7ba5da0U, + 0x81fe7fb1U, 0x3c28140aU, 0x6bb9d269U, 0x75add86cU, + 0xab399249U, 0x26cfe9faU, 0x29c5ec76U, 0xa23795c4U, + 0x6342219eU, 0x7d562b9bU, 0x79a5dc6eU, 0x715e2f99U, + 0xb62f99c2U, 0x95e673b7U, 0x775a2d98U, 0xafca65bcU, + 0x0506038fU, 0x392e1785U, 0x427c3e1fU, 0x9fea75b4U, + 0x2ac7edf8U, 0x66442211U, 0xe4b85c2eU, 0x00000000U, + 0xde944a25U, 0x4870381cU, 0xfca8542aU, 0x8ef47a3dU, + 0x1e140a05U, 0xbf219e4fU, 0x07f1f67bU, 0x8bf279b2U, + 0xacc86432U, 0x477a3d90U, 0xc58643afU, 0x56643219U, + 0xedb65ba3U, 0x08fbf3f7U, 0x37d1e673U, 0x694e279dU, + 0x7e542a15U, 0x25cde874U, 0x5e9fc1eeU, 0x860f89caU, + 0x6546239fU, 0x223c1e0fU, 0x5a6c361bU, 0x23c9ea75U, + 0x33221186U, 0x3f2a1584U, 0x6f4a259cU, 0xa135944aU, + 0x55663397U, 0x5c68341aU, 0x4389ca65U, 0x0efff1f6U, + 0x5493c7edU, 0x36241209U, 0xbdd66bbbU, 0xd4984c26U, + 0x2d361b83U, 0x408bcbebU, 0x7fa1de6fU, 0x213e1f81U, + 0x18100804U, 0x61b5d46aU, 0x97118643U, 0x06040201U, + 0x725c2e17U, 0x7ca3dfe1U, 0x35261387U, 0x04f3f7f5U, + 0x090e078dU, 0x70abdbe3U, 0xca8c4623U, 0x273a1d80U, + 0x850d8844U, 0x74582c16U, 0x4985cc66U, 0xc6844221U, + 0x3edfe1feU, 0xc473b7d5U, 0xa6c46231U, 0xec43afd9U, + 0xbed46a35U, 0x50603018U, 0x0c080402U, 0x458dc864U, + 0x16eff9f2U, 0x1ce3fff1U, 0xe945ac56U, 0x941387cdU, + 0x2b321982U, 0x8a078dc8U, 0xbbd269baU, 0x1ae7fdf0U, + 0x589bc3efU, 0x4c83cfe9U, 0x4a87cde8U, 0x34d3e7fdU, + 0x111e0f89U, 0xc87bb3d7U, 0xa83b93c7U, 0x99ee77b5U, + 0xffaa55a4U, 0xe2bc5e2fU, 0x596e3795U, 0x6a4c2613U, + 0x3a2c160bU, 0x10ebfbf3U, 0x7aa7dde0U, 0xb2dc6e37U, +}; + +static const ulong32 T4[256] = { + 0xa7a7a7a7U, 0xd3d3d3d3U, 0xe6e6e6e6U, 0x71717171U, + 0xd0d0d0d0U, 0xacacacacU, 0x4d4d4d4dU, 0x79797979U, + 0x3a3a3a3aU, 0xc9c9c9c9U, 0x91919191U, 0xfcfcfcfcU, + 0x1e1e1e1eU, 0x47474747U, 0x54545454U, 0xbdbdbdbdU, + 0x8c8c8c8cU, 0xa5a5a5a5U, 0x7a7a7a7aU, 0xfbfbfbfbU, + 0x63636363U, 0xb8b8b8b8U, 0xddddddddU, 0xd4d4d4d4U, + 0xe5e5e5e5U, 0xb3b3b3b3U, 0xc5c5c5c5U, 0xbebebebeU, + 0xa9a9a9a9U, 0x88888888U, 0x0c0c0c0cU, 0xa2a2a2a2U, + 0x39393939U, 0xdfdfdfdfU, 0x29292929U, 0xdadadadaU, + 0x2b2b2b2bU, 0xa8a8a8a8U, 0xcbcbcbcbU, 0x4c4c4c4cU, + 0x4b4b4b4bU, 0x22222222U, 0xaaaaaaaaU, 0x24242424U, + 0x41414141U, 0x70707070U, 0xa6a6a6a6U, 0xf9f9f9f9U, + 0x5a5a5a5aU, 0xe2e2e2e2U, 0xb0b0b0b0U, 0x36363636U, + 0x7d7d7d7dU, 0xe4e4e4e4U, 0x33333333U, 0xffffffffU, + 0x60606060U, 0x20202020U, 0x08080808U, 0x8b8b8b8bU, + 0x5e5e5e5eU, 0xababababU, 0x7f7f7f7fU, 0x78787878U, + 0x7c7c7c7cU, 0x2c2c2c2cU, 0x57575757U, 0xd2d2d2d2U, + 0xdcdcdcdcU, 0x6d6d6d6dU, 0x7e7e7e7eU, 0x0d0d0d0dU, + 0x53535353U, 0x94949494U, 0xc3c3c3c3U, 0x28282828U, + 0x27272727U, 0x06060606U, 0x5f5f5f5fU, 0xadadadadU, + 0x67676767U, 0x5c5c5c5cU, 0x55555555U, 0x48484848U, + 0x0e0e0e0eU, 0x52525252U, 0xeaeaeaeaU, 0x42424242U, + 0x5b5b5b5bU, 0x5d5d5d5dU, 0x30303030U, 0x58585858U, + 0x51515151U, 0x59595959U, 0x3c3c3c3cU, 0x4e4e4e4eU, + 0x38383838U, 0x8a8a8a8aU, 0x72727272U, 0x14141414U, + 0xe7e7e7e7U, 0xc6c6c6c6U, 0xdedededeU, 0x50505050U, + 0x8e8e8e8eU, 0x92929292U, 0xd1d1d1d1U, 0x77777777U, + 0x93939393U, 0x45454545U, 0x9a9a9a9aU, 0xcecececeU, + 0x2d2d2d2dU, 0x03030303U, 0x62626262U, 0xb6b6b6b6U, + 0xb9b9b9b9U, 0xbfbfbfbfU, 0x96969696U, 0x6b6b6b6bU, + 0x3f3f3f3fU, 0x07070707U, 0x12121212U, 0xaeaeaeaeU, + 0x40404040U, 0x34343434U, 0x46464646U, 0x3e3e3e3eU, + 0xdbdbdbdbU, 0xcfcfcfcfU, 0xececececU, 0xccccccccU, + 0xc1c1c1c1U, 0xa1a1a1a1U, 0xc0c0c0c0U, 0xd6d6d6d6U, + 0x1d1d1d1dU, 0xf4f4f4f4U, 0x61616161U, 0x3b3b3b3bU, + 0x10101010U, 0xd8d8d8d8U, 0x68686868U, 0xa0a0a0a0U, + 0xb1b1b1b1U, 0x0a0a0a0aU, 0x69696969U, 0x6c6c6c6cU, + 0x49494949U, 0xfafafafaU, 0x76767676U, 0xc4c4c4c4U, + 0x9e9e9e9eU, 0x9b9b9b9bU, 0x6e6e6e6eU, 0x99999999U, + 0xc2c2c2c2U, 0xb7b7b7b7U, 0x98989898U, 0xbcbcbcbcU, + 0x8f8f8f8fU, 0x85858585U, 0x1f1f1f1fU, 0xb4b4b4b4U, + 0xf8f8f8f8U, 0x11111111U, 0x2e2e2e2eU, 0x00000000U, + 0x25252525U, 0x1c1c1c1cU, 0x2a2a2a2aU, 0x3d3d3d3dU, + 0x05050505U, 0x4f4f4f4fU, 0x7b7b7b7bU, 0xb2b2b2b2U, + 0x32323232U, 0x90909090U, 0xafafafafU, 0x19191919U, + 0xa3a3a3a3U, 0xf7f7f7f7U, 0x73737373U, 0x9d9d9d9dU, + 0x15151515U, 0x74747474U, 0xeeeeeeeeU, 0xcacacacaU, + 0x9f9f9f9fU, 0x0f0f0f0fU, 0x1b1b1b1bU, 0x75757575U, + 0x86868686U, 0x84848484U, 0x9c9c9c9cU, 0x4a4a4a4aU, + 0x97979797U, 0x1a1a1a1aU, 0x65656565U, 0xf6f6f6f6U, + 0xededededU, 0x09090909U, 0xbbbbbbbbU, 0x26262626U, + 0x83838383U, 0xebebebebU, 0x6f6f6f6fU, 0x81818181U, + 0x04040404U, 0x6a6a6a6aU, 0x43434343U, 0x01010101U, + 0x17171717U, 0xe1e1e1e1U, 0x87878787U, 0xf5f5f5f5U, + 0x8d8d8d8dU, 0xe3e3e3e3U, 0x23232323U, 0x80808080U, + 0x44444444U, 0x16161616U, 0x66666666U, 0x21212121U, + 0xfefefefeU, 0xd5d5d5d5U, 0x31313131U, 0xd9d9d9d9U, + 0x35353535U, 0x18181818U, 0x02020202U, 0x64646464U, + 0xf2f2f2f2U, 0xf1f1f1f1U, 0x56565656U, 0xcdcdcdcdU, + 0x82828282U, 0xc8c8c8c8U, 0xbabababaU, 0xf0f0f0f0U, + 0xefefefefU, 0xe9e9e9e9U, 0xe8e8e8e8U, 0xfdfdfdfdU, + 0x89898989U, 0xd7d7d7d7U, 0xc7c7c7c7U, 0xb5b5b5b5U, + 0xa4a4a4a4U, 0x2f2f2f2fU, 0x95959595U, 0x13131313U, + 0x0b0b0b0bU, 0xf3f3f3f3U, 0xe0e0e0e0U, 0x37373737U, +}; + +static const ulong32 T5[256] = { + 0x00000000U, 0x01020608U, 0x02040c10U, 0x03060a18U, + 0x04081820U, 0x050a1e28U, 0x060c1430U, 0x070e1238U, + 0x08103040U, 0x09123648U, 0x0a143c50U, 0x0b163a58U, + 0x0c182860U, 0x0d1a2e68U, 0x0e1c2470U, 0x0f1e2278U, + 0x10206080U, 0x11226688U, 0x12246c90U, 0x13266a98U, + 0x142878a0U, 0x152a7ea8U, 0x162c74b0U, 0x172e72b8U, + 0x183050c0U, 0x193256c8U, 0x1a345cd0U, 0x1b365ad8U, + 0x1c3848e0U, 0x1d3a4ee8U, 0x1e3c44f0U, 0x1f3e42f8U, + 0x2040c01dU, 0x2142c615U, 0x2244cc0dU, 0x2346ca05U, + 0x2448d83dU, 0x254ade35U, 0x264cd42dU, 0x274ed225U, + 0x2850f05dU, 0x2952f655U, 0x2a54fc4dU, 0x2b56fa45U, + 0x2c58e87dU, 0x2d5aee75U, 0x2e5ce46dU, 0x2f5ee265U, + 0x3060a09dU, 0x3162a695U, 0x3264ac8dU, 0x3366aa85U, + 0x3468b8bdU, 0x356abeb5U, 0x366cb4adU, 0x376eb2a5U, + 0x387090ddU, 0x397296d5U, 0x3a749ccdU, 0x3b769ac5U, + 0x3c7888fdU, 0x3d7a8ef5U, 0x3e7c84edU, 0x3f7e82e5U, + 0x40809d3aU, 0x41829b32U, 0x4284912aU, 0x43869722U, + 0x4488851aU, 0x458a8312U, 0x468c890aU, 0x478e8f02U, + 0x4890ad7aU, 0x4992ab72U, 0x4a94a16aU, 0x4b96a762U, + 0x4c98b55aU, 0x4d9ab352U, 0x4e9cb94aU, 0x4f9ebf42U, + 0x50a0fdbaU, 0x51a2fbb2U, 0x52a4f1aaU, 0x53a6f7a2U, + 0x54a8e59aU, 0x55aae392U, 0x56ace98aU, 0x57aeef82U, + 0x58b0cdfaU, 0x59b2cbf2U, 0x5ab4c1eaU, 0x5bb6c7e2U, + 0x5cb8d5daU, 0x5dbad3d2U, 0x5ebcd9caU, 0x5fbedfc2U, + 0x60c05d27U, 0x61c25b2fU, 0x62c45137U, 0x63c6573fU, + 0x64c84507U, 0x65ca430fU, 0x66cc4917U, 0x67ce4f1fU, + 0x68d06d67U, 0x69d26b6fU, 0x6ad46177U, 0x6bd6677fU, + 0x6cd87547U, 0x6dda734fU, 0x6edc7957U, 0x6fde7f5fU, + 0x70e03da7U, 0x71e23bafU, 0x72e431b7U, 0x73e637bfU, + 0x74e82587U, 0x75ea238fU, 0x76ec2997U, 0x77ee2f9fU, + 0x78f00de7U, 0x79f20befU, 0x7af401f7U, 0x7bf607ffU, + 0x7cf815c7U, 0x7dfa13cfU, 0x7efc19d7U, 0x7ffe1fdfU, + 0x801d2774U, 0x811f217cU, 0x82192b64U, 0x831b2d6cU, + 0x84153f54U, 0x8517395cU, 0x86113344U, 0x8713354cU, + 0x880d1734U, 0x890f113cU, 0x8a091b24U, 0x8b0b1d2cU, + 0x8c050f14U, 0x8d07091cU, 0x8e010304U, 0x8f03050cU, + 0x903d47f4U, 0x913f41fcU, 0x92394be4U, 0x933b4decU, + 0x94355fd4U, 0x953759dcU, 0x963153c4U, 0x973355ccU, + 0x982d77b4U, 0x992f71bcU, 0x9a297ba4U, 0x9b2b7dacU, + 0x9c256f94U, 0x9d27699cU, 0x9e216384U, 0x9f23658cU, + 0xa05de769U, 0xa15fe161U, 0xa259eb79U, 0xa35bed71U, + 0xa455ff49U, 0xa557f941U, 0xa651f359U, 0xa753f551U, + 0xa84dd729U, 0xa94fd121U, 0xaa49db39U, 0xab4bdd31U, + 0xac45cf09U, 0xad47c901U, 0xae41c319U, 0xaf43c511U, + 0xb07d87e9U, 0xb17f81e1U, 0xb2798bf9U, 0xb37b8df1U, + 0xb4759fc9U, 0xb57799c1U, 0xb67193d9U, 0xb77395d1U, + 0xb86db7a9U, 0xb96fb1a1U, 0xba69bbb9U, 0xbb6bbdb1U, + 0xbc65af89U, 0xbd67a981U, 0xbe61a399U, 0xbf63a591U, + 0xc09dba4eU, 0xc19fbc46U, 0xc299b65eU, 0xc39bb056U, + 0xc495a26eU, 0xc597a466U, 0xc691ae7eU, 0xc793a876U, + 0xc88d8a0eU, 0xc98f8c06U, 0xca89861eU, 0xcb8b8016U, + 0xcc85922eU, 0xcd879426U, 0xce819e3eU, 0xcf839836U, + 0xd0bddaceU, 0xd1bfdcc6U, 0xd2b9d6deU, 0xd3bbd0d6U, + 0xd4b5c2eeU, 0xd5b7c4e6U, 0xd6b1cefeU, 0xd7b3c8f6U, + 0xd8adea8eU, 0xd9afec86U, 0xdaa9e69eU, 0xdbabe096U, + 0xdca5f2aeU, 0xdda7f4a6U, 0xdea1febeU, 0xdfa3f8b6U, + 0xe0dd7a53U, 0xe1df7c5bU, 0xe2d97643U, 0xe3db704bU, + 0xe4d56273U, 0xe5d7647bU, 0xe6d16e63U, 0xe7d3686bU, + 0xe8cd4a13U, 0xe9cf4c1bU, 0xeac94603U, 0xebcb400bU, + 0xecc55233U, 0xedc7543bU, 0xeec15e23U, 0xefc3582bU, + 0xf0fd1ad3U, 0xf1ff1cdbU, 0xf2f916c3U, 0xf3fb10cbU, + 0xf4f502f3U, 0xf5f704fbU, 0xf6f10ee3U, 0xf7f308ebU, + 0xf8ed2a93U, 0xf9ef2c9bU, 0xfae92683U, 0xfbeb208bU, + 0xfce532b3U, 0xfde734bbU, 0xfee13ea3U, 0xffe338abU, +}; + +/** + * The round constants. + */ +static const ulong32 rc[] = { + 0xa7d3e671U, 0xd0ac4d79U, 0x3ac991fcU, 0x1e4754bdU, + 0x8ca57afbU, 0x63b8ddd4U, 0xe5b3c5beU, 0xa9880ca2U, + 0x39df29daU, 0x2ba8cb4cU, 0x4b22aa24U, 0x4170a6f9U, + 0x5ae2b036U, 0x7de433ffU, 0x6020088bU, 0x5eab7f78U, + 0x7c2c57d2U, 0xdc6d7e0dU, 0x5394c328U, +}; + +#endif + + /** + Initialize the Anubis block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +#ifdef LTC_CLEAN_STACK +static int _anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#else +int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#endif +{ + int N, R, i, pos, r; + ulong32 kappa[MAX_N]; + ulong32 inter[MAX_N]; + ulong32 v, K0, K1, K2, K3; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + /* Valid sizes (in bytes) are 16, 20, 24, 28, 32, 36, and 40. */ + if ((keylen & 3) || (keylen < 16) || (keylen > 40)) { + return CRYPT_INVALID_KEYSIZE; + } + skey->anubis.keyBits = keylen*8; + + /* + * determine the N length parameter: + * (N.B. it is assumed that the key length is valid!) + */ + N = skey->anubis.keyBits >> 5; + + /* + * determine number of rounds from key size: + */ + skey->anubis.R = R = 8 + N; + + if (num_rounds != 0 && num_rounds != skey->anubis.R) { + return CRYPT_INVALID_ROUNDS; + } + + /* + * map cipher key to initial key state (mu): + */ + for (i = 0, pos = 0; i < N; i++, pos += 4) { + kappa[i] = + (key[pos ] << 24) ^ + (key[pos + 1] << 16) ^ + (key[pos + 2] << 8) ^ + (key[pos + 3] ); + } + + /* + * generate R + 1 round keys: + */ + for (r = 0; r <= R; r++) { + /* + * generate r-th round key K^r: + */ + K0 = T4[(kappa[N - 1] >> 24) & 0xff]; + K1 = T4[(kappa[N - 1] >> 16) & 0xff]; + K2 = T4[(kappa[N - 1] >> 8) & 0xff]; + K3 = T4[(kappa[N - 1] ) & 0xff]; + for (i = N - 2; i >= 0; i--) { + K0 = T4[(kappa[i] >> 24) & 0xff] ^ + (T5[(K0 >> 24) & 0xff] & 0xff000000U) ^ + (T5[(K0 >> 16) & 0xff] & 0x00ff0000U) ^ + (T5[(K0 >> 8) & 0xff] & 0x0000ff00U) ^ + (T5[(K0 ) & 0xff] & 0x000000ffU); + K1 = T4[(kappa[i] >> 16) & 0xff] ^ + (T5[(K1 >> 24) & 0xff] & 0xff000000U) ^ + (T5[(K1 >> 16) & 0xff] & 0x00ff0000U) ^ + (T5[(K1 >> 8) & 0xff] & 0x0000ff00U) ^ + (T5[(K1 ) & 0xff] & 0x000000ffU); + K2 = T4[(kappa[i] >> 8) & 0xff] ^ + (T5[(K2 >> 24) & 0xff] & 0xff000000U) ^ + (T5[(K2 >> 16) & 0xff] & 0x00ff0000U) ^ + (T5[(K2 >> 8) & 0xff] & 0x0000ff00U) ^ + (T5[(K2 ) & 0xff] & 0x000000ffU); + K3 = T4[(kappa[i] ) & 0xff] ^ + (T5[(K3 >> 24) & 0xff] & 0xff000000U) ^ + (T5[(K3 >> 16) & 0xff] & 0x00ff0000U) ^ + (T5[(K3 >> 8) & 0xff] & 0x0000ff00U) ^ + (T5[(K3 ) & 0xff] & 0x000000ffU); + } + /* + -- this is the code to use with the large U tables: + K0 = K1 = K2 = K3 = 0; + for (i = 0; i < N; i++) { + K0 ^= U[i][(kappa[i] >> 24) & 0xff]; + K1 ^= U[i][(kappa[i] >> 16) & 0xff]; + K2 ^= U[i][(kappa[i] >> 8) & 0xff]; + K3 ^= U[i][(kappa[i] ) & 0xff]; + } + */ + skey->anubis.roundKeyEnc[r][0] = K0; + skey->anubis.roundKeyEnc[r][1] = K1; + skey->anubis.roundKeyEnc[r][2] = K2; + skey->anubis.roundKeyEnc[r][3] = K3; + + /* + * compute kappa^{r+1} from kappa^r: + */ + if (r == R) { + break; + } + for (i = 0; i < N; i++) { + int j = i; + inter[i] = T0[(kappa[j--] >> 24) & 0xff]; if (j < 0) j = N - 1; + inter[i] ^= T1[(kappa[j--] >> 16) & 0xff]; if (j < 0) j = N - 1; + inter[i] ^= T2[(kappa[j--] >> 8) & 0xff]; if (j < 0) j = N - 1; + inter[i] ^= T3[(kappa[j ] ) & 0xff]; + } + kappa[0] = inter[0] ^ rc[r]; + for (i = 1; i < N; i++) { + kappa[i] = inter[i]; + } + } + + /* + * generate inverse key schedule: K'^0 = K^R, K'^R = K^0, K'^r = theta(K^{R-r}): + */ + for (i = 0; i < 4; i++) { + skey->anubis.roundKeyDec[0][i] = skey->anubis.roundKeyEnc[R][i]; + skey->anubis.roundKeyDec[R][i] = skey->anubis.roundKeyEnc[0][i]; + } + for (r = 1; r < R; r++) { + for (i = 0; i < 4; i++) { + v = skey->anubis.roundKeyEnc[R - r][i]; + skey->anubis.roundKeyDec[r][i] = + T0[T4[(v >> 24) & 0xff] & 0xff] ^ + T1[T4[(v >> 16) & 0xff] & 0xff] ^ + T2[T4[(v >> 8) & 0xff] & 0xff] ^ + T3[T4[(v ) & 0xff] & 0xff]; + } + } + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int err; + err = _anubis_setup(key, keylen, num_rounds, skey); + burn_stack(sizeof(int) * 5 + sizeof(ulong32) * (MAX_N + MAX_N + 5)); + return err; +} +#endif + + +static void anubis_crypt(const unsigned char *plaintext, unsigned char *ciphertext, + ulong32 roundKey[18 + 1][4], int R) { + int i, pos, r; + ulong32 state[4]; + ulong32 inter[4]; + + /* + * map plaintext block to cipher state (mu) + * and add initial round key (sigma[K^0]): + */ + for (i = 0, pos = 0; i < 4; i++, pos += 4) { + state[i] = + (plaintext[pos ] << 24) ^ + (plaintext[pos + 1] << 16) ^ + (plaintext[pos + 2] << 8) ^ + (plaintext[pos + 3] ) ^ + roundKey[0][i]; + } + + /* + * R - 1 full rounds: + */ + for (r = 1; r < R; r++) { + inter[0] = + T0[(state[0] >> 24) & 0xff] ^ + T1[(state[1] >> 24) & 0xff] ^ + T2[(state[2] >> 24) & 0xff] ^ + T3[(state[3] >> 24) & 0xff] ^ + roundKey[r][0]; + inter[1] = + T0[(state[0] >> 16) & 0xff] ^ + T1[(state[1] >> 16) & 0xff] ^ + T2[(state[2] >> 16) & 0xff] ^ + T3[(state[3] >> 16) & 0xff] ^ + roundKey[r][1]; + inter[2] = + T0[(state[0] >> 8) & 0xff] ^ + T1[(state[1] >> 8) & 0xff] ^ + T2[(state[2] >> 8) & 0xff] ^ + T3[(state[3] >> 8) & 0xff] ^ + roundKey[r][2]; + inter[3] = + T0[(state[0] ) & 0xff] ^ + T1[(state[1] ) & 0xff] ^ + T2[(state[2] ) & 0xff] ^ + T3[(state[3] ) & 0xff] ^ + roundKey[r][3]; + state[0] = inter[0]; + state[1] = inter[1]; + state[2] = inter[2]; + state[3] = inter[3]; + } + + /* + * last round: + */ + inter[0] = + (T0[(state[0] >> 24) & 0xff] & 0xff000000U) ^ + (T1[(state[1] >> 24) & 0xff] & 0x00ff0000U) ^ + (T2[(state[2] >> 24) & 0xff] & 0x0000ff00U) ^ + (T3[(state[3] >> 24) & 0xff] & 0x000000ffU) ^ + roundKey[R][0]; + inter[1] = + (T0[(state[0] >> 16) & 0xff] & 0xff000000U) ^ + (T1[(state[1] >> 16) & 0xff] & 0x00ff0000U) ^ + (T2[(state[2] >> 16) & 0xff] & 0x0000ff00U) ^ + (T3[(state[3] >> 16) & 0xff] & 0x000000ffU) ^ + roundKey[R][1]; + inter[2] = + (T0[(state[0] >> 8) & 0xff] & 0xff000000U) ^ + (T1[(state[1] >> 8) & 0xff] & 0x00ff0000U) ^ + (T2[(state[2] >> 8) & 0xff] & 0x0000ff00U) ^ + (T3[(state[3] >> 8) & 0xff] & 0x000000ffU) ^ + roundKey[R][2]; + inter[3] = + (T0[(state[0] ) & 0xff] & 0xff000000U) ^ + (T1[(state[1] ) & 0xff] & 0x00ff0000U) ^ + (T2[(state[2] ) & 0xff] & 0x0000ff00U) ^ + (T3[(state[3] ) & 0xff] & 0x000000ffU) ^ + roundKey[R][3]; + + /* + * map cipher state to ciphertext block (mu^{-1}): + */ + for (i = 0, pos = 0; i < 4; i++, pos += 4) { + ulong32 w = inter[i]; + ciphertext[pos ] = (unsigned char)(w >> 24); + ciphertext[pos + 1] = (unsigned char)(w >> 16); + ciphertext[pos + 2] = (unsigned char)(w >> 8); + ciphertext[pos + 3] = (unsigned char)(w ); + } +} + +/** + Encrypts a block of text with Anubis + @param pt The input plaintext (16 bytes) + @param ct The output ciphertext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + anubis_crypt(pt, ct, skey->anubis.roundKeyEnc, skey->anubis.R); + return CRYPT_OK; +} + +/** + Decrypts a block of text with Anubis + @param ct The input ciphertext (16 bytes) + @param pt The output plaintext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + anubis_crypt(ct, pt, skey->anubis.roundKeyDec, skey->anubis.R); + return CRYPT_OK; +} + +/** + Performs a self-test of the Anubis block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int anubis_test(void) +{ +#if !defined(LTC_TEST) + return CRYPT_NOP; +#else + static const struct test { + int keylen; + unsigned char pt[16], ct[16], key[40]; + } tests[] = { +#ifndef LTC_ANUBIS_TWEAK + /**** ORIGINAL LTC_ANUBIS ****/ + /* 128 bit keys */ +{ + 16, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xF0, 0x68, 0x60, 0xFC, 0x67, 0x30, 0xE8, 0x18, + 0xF1, 0x32, 0xC7, 0x8A, 0xF4, 0x13, 0x2A, 0xFE }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}, { + 16, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xA8, 0x66, 0x84, 0x80, 0x07, 0x74, 0x5C, 0x89, + 0xFC, 0x5E, 0xB5, 0xBA, 0xD4, 0xFE, 0x32, 0x6D }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } +}, + + /* 160-bit keys */ +{ + 20, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xBD, 0x5E, 0x32, 0xBE, 0x51, 0x67, 0xA8, 0xE2, + 0x72, 0xD7, 0x95, 0x0F, 0x83, 0xC6, 0x8C, 0x31 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 } +}, { + 20, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x4C, 0x1F, 0x86, 0x2E, 0x11, 0xEB, 0xCE, 0xEB, + 0xFE, 0xB9, 0x73, 0xC9, 0xDF, 0xEF, 0x7A, 0xDB }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01 } +}, + + /* 192-bit keys */ +{ + 24, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x17, 0xAC, 0x57, 0x44, 0x9D, 0x59, 0x61, 0x66, + 0xD0, 0xC7, 0x9E, 0x04, 0x7C, 0xC7, 0x58, 0xF0 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}, { + 24, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x71, 0x52, 0xB4, 0xEB, 0x1D, 0xAA, 0x36, 0xFD, + 0x57, 0x14, 0x5F, 0x57, 0x04, 0x9F, 0x70, 0x74 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } +}, + + /* 224-bit keys */ +{ + 28, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xA2, 0xF0, 0xA6, 0xB9, 0x17, 0x93, 0x2A, 0x3B, + 0xEF, 0x08, 0xE8, 0x7A, 0x58, 0xD6, 0xF8, 0x53 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 } +}, { + 28, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xF0, 0xCA, 0xFC, 0x78, 0x8B, 0x4B, 0x4E, 0x53, + 0x8B, 0xC4, 0x32, 0x6A, 0xF5, 0xB9, 0x1B, 0x5F }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01 } +}, + + /* 256-bit keys */ +{ + 32, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xE0, 0x86, 0xAC, 0x45, 0x6B, 0x3C, 0xE5, 0x13, + 0xED, 0xF5, 0xDF, 0xDD, 0xD6, 0x3B, 0x71, 0x93 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}, { + 32, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x50, 0x01, 0xB9, 0xF5, 0x21, 0xC1, 0xC1, 0x29, + 0x00, 0xD5, 0xEC, 0x98, 0x2B, 0x9E, 0xE8, 0x21 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } +}, + + /* 288-bit keys */ +{ + 36, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xE8, 0xF4, 0xAF, 0x2B, 0x21, 0xA0, 0x87, 0x9B, + 0x41, 0x95, 0xB9, 0x71, 0x75, 0x79, 0x04, 0x7C }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 } +}, { + 36, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xE6, 0xA6, 0xA5, 0xBC, 0x8B, 0x63, 0x6F, 0xE2, + 0xBD, 0xA7, 0xA7, 0x53, 0xAB, 0x40, 0x22, 0xE0 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01 } +}, + + /* 320-bit keys */ +{ + 40, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x17, 0x04, 0xD7, 0x2C, 0xC6, 0x85, 0x76, 0x02, + 0x4B, 0xCC, 0x39, 0x80, 0xD8, 0x22, 0xEA, 0xA4 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}, { + 40, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x7A, 0x41, 0xE6, 0x7D, 0x4F, 0xD8, 0x64, 0xF0, + 0x44, 0xA8, 0x3C, 0x73, 0x81, 0x7E, 0x53, 0xD8 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } +} +#else + /**** Tweaked LTC_ANUBIS ****/ + /* 128 bit keys */ +{ + 16, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xB8, 0x35, 0xBD, 0xC3, 0x34, 0x82, 0x9D, 0x83, + 0x71, 0xBF, 0xA3, 0x71, 0xE4, 0xB3, 0xC4, 0xFD }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}, { + 16, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xE6, 0x14, 0x1E, 0xAF, 0xEB, 0xE0, 0x59, 0x3C, + 0x48, 0xE1, 0xCD, 0xF2, 0x1B, 0xBA, 0xA1, 0x89 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } +}, + + /* 160-bit keys */ +{ + 20, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x97, 0x59, 0x79, 0x4B, 0x5C, 0xA0, 0x70, 0x73, + 0x24, 0xEF, 0xB3, 0x58, 0x67, 0xCA, 0xD4, 0xB3 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 } +}, { + 20, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xB8, 0x0D, 0xFB, 0x9B, 0xE4, 0xA1, 0x58, 0x87, + 0xB3, 0x76, 0xD5, 0x02, 0x18, 0x95, 0xC1, 0x2E }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01 } +}, + + /* 192-bit keys */ +{ + 24, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x7D, 0x62, 0x3B, 0x52, 0xC7, 0x4C, 0x64, 0xD8, + 0xEB, 0xC7, 0x2D, 0x57, 0x97, 0x85, 0x43, 0x8F }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}, { + 24, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xB1, 0x0A, 0x59, 0xDD, 0x5D, 0x5D, 0x8D, 0x67, + 0xEC, 0xEE, 0x4A, 0xC4, 0xBE, 0x4F, 0xA8, 0x4F }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } +}, + + /* 224-bit keys */ +{ + 28, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x68, 0x9E, 0x05, 0x94, 0x6A, 0x94, 0x43, 0x8F, + 0xE7, 0x8E, 0x37, 0x3D, 0x24, 0x97, 0x92, 0xF5 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 } +}, { + 28, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xDD, 0xB7, 0xB0, 0xB4, 0xE9, 0xB4, 0x9B, 0x9C, + 0x38, 0x20, 0x25, 0x0B, 0x47, 0xC2, 0x1F, 0x89 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01 } +}, + + /* 256-bit keys */ +{ + 32, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x96, 0x00, 0xF0, 0x76, 0x91, 0x69, 0x29, 0x87, + 0xF5, 0xE5, 0x97, 0xDB, 0xDB, 0xAF, 0x1B, 0x0A }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}, { + 32, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x69, 0x9C, 0xAF, 0xDD, 0x94, 0xC7, 0xBC, 0x60, + 0x44, 0xFE, 0x02, 0x05, 0x8A, 0x6E, 0xEF, 0xBD }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } +}, + + /* 288-bit keys */ +{ + 36, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x0F, 0xC7, 0xA2, 0xC0, 0x11, 0x17, 0xAC, 0x43, + 0x52, 0x5E, 0xDF, 0x6C, 0xF3, 0x96, 0x33, 0x6C }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 } +}, { + 36, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xAD, 0x08, 0x4F, 0xED, 0x55, 0xA6, 0x94, 0x3E, + 0x7E, 0x5E, 0xED, 0x05, 0xA1, 0x9D, 0x41, 0xB4 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01 } +}, + + /* 320-bit keys */ +{ + 40, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xFE, 0xE2, 0x0E, 0x2A, 0x9D, 0xC5, 0x83, 0xBA, + 0xA3, 0xA6, 0xD6, 0xA6, 0xF2, 0xE8, 0x06, 0xA5 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}, { + 40, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x86, 0x3D, 0xCC, 0x4A, 0x60, 0x34, 0x9C, 0x28, + 0xA7, 0xDA, 0xA4, 0x3B, 0x0A, 0xD7, 0xFD, 0xC7 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } +} +#endif +}; + int x, y; + unsigned char buf[2][16]; + symmetric_key skey; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + anubis_setup(tests[x].key, tests[x].keylen, 0, &skey); + anubis_ecb_encrypt(tests[x].pt, buf[0], &skey); + anubis_ecb_decrypt(buf[0], buf[1], &skey); + if (XMEMCMP(buf[0], tests[x].ct, 16) || XMEMCMP(buf[1], tests[x].pt, 16)) { + return CRYPT_FAIL_TESTVECTOR; + } + + for (y = 0; y < 1000; y++) anubis_ecb_encrypt(buf[0], buf[0], &skey); + for (y = 0; y < 1000; y++) anubis_ecb_decrypt(buf[0], buf[0], &skey); + if (XMEMCMP(buf[0], tests[x].ct, 16)) { + return CRYPT_FAIL_TESTVECTOR; + } + + } + return CRYPT_OK; +#endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void anubis_done(symmetric_key *skey) +{ +} + +/** + Gets suitable key size + @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. + @return CRYPT_OK if the input key size is acceptable. +*/ +int anubis_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize >= 40) { + *keysize = 40; + } else if (*keysize >= 36) { + *keysize = 36; + } else if (*keysize >= 32) { + *keysize = 32; + } else if (*keysize >= 28) { + *keysize = 28; + } else if (*keysize >= 24) { + *keysize = 24; + } else if (*keysize >= 20) { + *keysize = 20; + } else if (*keysize >= 16) { + *keysize = 16; + } else { + return CRYPT_INVALID_KEYSIZE; + } + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/anubis.c,v $ */ +/* $Revision: 1.17 $ */ +/* $Date: 2007/05/12 14:21:44 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/blowfish.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/blowfish.c new file mode 100644 index 0000000000..4e9a2fcf8e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/blowfish.c @@ -0,0 +1,594 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +/** + @file blowfish.c + Implementation of the Blowfish block cipher, Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_BLOWFISH + +const struct ltc_cipher_descriptor blowfish_desc = +{ + "blowfish", + 0, + 8, 56, 8, 16, + &blowfish_setup, + &blowfish_ecb_encrypt, + &blowfish_ecb_decrypt, + &blowfish_test, + &blowfish_done, + &blowfish_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +static const ulong32 ORIG_P[16 + 2] = { + 0x243F6A88UL, 0x85A308D3UL, 0x13198A2EUL, 0x03707344UL, + 0xA4093822UL, 0x299F31D0UL, 0x082EFA98UL, 0xEC4E6C89UL, + 0x452821E6UL, 0x38D01377UL, 0xBE5466CFUL, 0x34E90C6CUL, + 0xC0AC29B7UL, 0xC97C50DDUL, 0x3F84D5B5UL, 0xB5470917UL, + 0x9216D5D9UL, 0x8979FB1BUL +}; + +static const ulong32 ORIG_S[4][256] = { + { 0xD1310BA6UL, 0x98DFB5ACUL, 0x2FFD72DBUL, 0xD01ADFB7UL, + 0xB8E1AFEDUL, 0x6A267E96UL, 0xBA7C9045UL, 0xF12C7F99UL, + 0x24A19947UL, 0xB3916CF7UL, 0x0801F2E2UL, 0x858EFC16UL, + 0x636920D8UL, 0x71574E69UL, 0xA458FEA3UL, 0xF4933D7EUL, + 0x0D95748FUL, 0x728EB658UL, 0x718BCD58UL, 0x82154AEEUL, + 0x7B54A41DUL, 0xC25A59B5UL, 0x9C30D539UL, 0x2AF26013UL, + 0xC5D1B023UL, 0x286085F0UL, 0xCA417918UL, 0xB8DB38EFUL, + 0x8E79DCB0UL, 0x603A180EUL, 0x6C9E0E8BUL, 0xB01E8A3EUL, + 0xD71577C1UL, 0xBD314B27UL, 0x78AF2FDAUL, 0x55605C60UL, + 0xE65525F3UL, 0xAA55AB94UL, 0x57489862UL, 0x63E81440UL, + 0x55CA396AUL, 0x2AAB10B6UL, 0xB4CC5C34UL, 0x1141E8CEUL, + 0xA15486AFUL, 0x7C72E993UL, 0xB3EE1411UL, 0x636FBC2AUL, + 0x2BA9C55DUL, 0x741831F6UL, 0xCE5C3E16UL, 0x9B87931EUL, + 0xAFD6BA33UL, 0x6C24CF5CUL, 0x7A325381UL, 0x28958677UL, + 0x3B8F4898UL, 0x6B4BB9AFUL, 0xC4BFE81BUL, 0x66282193UL, + 0x61D809CCUL, 0xFB21A991UL, 0x487CAC60UL, 0x5DEC8032UL, + 0xEF845D5DUL, 0xE98575B1UL, 0xDC262302UL, 0xEB651B88UL, + 0x23893E81UL, 0xD396ACC5UL, 0x0F6D6FF3UL, 0x83F44239UL, + 0x2E0B4482UL, 0xA4842004UL, 0x69C8F04AUL, 0x9E1F9B5EUL, + 0x21C66842UL, 0xF6E96C9AUL, 0x670C9C61UL, 0xABD388F0UL, + 0x6A51A0D2UL, 0xD8542F68UL, 0x960FA728UL, 0xAB5133A3UL, + 0x6EEF0B6CUL, 0x137A3BE4UL, 0xBA3BF050UL, 0x7EFB2A98UL, + 0xA1F1651DUL, 0x39AF0176UL, 0x66CA593EUL, 0x82430E88UL, + 0x8CEE8619UL, 0x456F9FB4UL, 0x7D84A5C3UL, 0x3B8B5EBEUL, + 0xE06F75D8UL, 0x85C12073UL, 0x401A449FUL, 0x56C16AA6UL, + 0x4ED3AA62UL, 0x363F7706UL, 0x1BFEDF72UL, 0x429B023DUL, + 0x37D0D724UL, 0xD00A1248UL, 0xDB0FEAD3UL, 0x49F1C09BUL, + 0x075372C9UL, 0x80991B7BUL, 0x25D479D8UL, 0xF6E8DEF7UL, + 0xE3FE501AUL, 0xB6794C3BUL, 0x976CE0BDUL, 0x04C006BAUL, + 0xC1A94FB6UL, 0x409F60C4UL, 0x5E5C9EC2UL, 0x196A2463UL, + 0x68FB6FAFUL, 0x3E6C53B5UL, 0x1339B2EBUL, 0x3B52EC6FUL, + 0x6DFC511FUL, 0x9B30952CUL, 0xCC814544UL, 0xAF5EBD09UL, + 0xBEE3D004UL, 0xDE334AFDUL, 0x660F2807UL, 0x192E4BB3UL, + 0xC0CBA857UL, 0x45C8740FUL, 0xD20B5F39UL, 0xB9D3FBDBUL, + 0x5579C0BDUL, 0x1A60320AUL, 0xD6A100C6UL, 0x402C7279UL, + 0x679F25FEUL, 0xFB1FA3CCUL, 0x8EA5E9F8UL, 0xDB3222F8UL, + 0x3C7516DFUL, 0xFD616B15UL, 0x2F501EC8UL, 0xAD0552ABUL, + 0x323DB5FAUL, 0xFD238760UL, 0x53317B48UL, 0x3E00DF82UL, + 0x9E5C57BBUL, 0xCA6F8CA0UL, 0x1A87562EUL, 0xDF1769DBUL, + 0xD542A8F6UL, 0x287EFFC3UL, 0xAC6732C6UL, 0x8C4F5573UL, + 0x695B27B0UL, 0xBBCA58C8UL, 0xE1FFA35DUL, 0xB8F011A0UL, + 0x10FA3D98UL, 0xFD2183B8UL, 0x4AFCB56CUL, 0x2DD1D35BUL, + 0x9A53E479UL, 0xB6F84565UL, 0xD28E49BCUL, 0x4BFB9790UL, + 0xE1DDF2DAUL, 0xA4CB7E33UL, 0x62FB1341UL, 0xCEE4C6E8UL, + 0xEF20CADAUL, 0x36774C01UL, 0xD07E9EFEUL, 0x2BF11FB4UL, + 0x95DBDA4DUL, 0xAE909198UL, 0xEAAD8E71UL, 0x6B93D5A0UL, + 0xD08ED1D0UL, 0xAFC725E0UL, 0x8E3C5B2FUL, 0x8E7594B7UL, + 0x8FF6E2FBUL, 0xF2122B64UL, 0x8888B812UL, 0x900DF01CUL, + 0x4FAD5EA0UL, 0x688FC31CUL, 0xD1CFF191UL, 0xB3A8C1ADUL, + 0x2F2F2218UL, 0xBE0E1777UL, 0xEA752DFEUL, 0x8B021FA1UL, + 0xE5A0CC0FUL, 0xB56F74E8UL, 0x18ACF3D6UL, 0xCE89E299UL, + 0xB4A84FE0UL, 0xFD13E0B7UL, 0x7CC43B81UL, 0xD2ADA8D9UL, + 0x165FA266UL, 0x80957705UL, 0x93CC7314UL, 0x211A1477UL, + 0xE6AD2065UL, 0x77B5FA86UL, 0xC75442F5UL, 0xFB9D35CFUL, + 0xEBCDAF0CUL, 0x7B3E89A0UL, 0xD6411BD3UL, 0xAE1E7E49UL, + 0x00250E2DUL, 0x2071B35EUL, 0x226800BBUL, 0x57B8E0AFUL, + 0x2464369BUL, 0xF009B91EUL, 0x5563911DUL, 0x59DFA6AAUL, + 0x78C14389UL, 0xD95A537FUL, 0x207D5BA2UL, 0x02E5B9C5UL, + 0x83260376UL, 0x6295CFA9UL, 0x11C81968UL, 0x4E734A41UL, + 0xB3472DCAUL, 0x7B14A94AUL, 0x1B510052UL, 0x9A532915UL, + 0xD60F573FUL, 0xBC9BC6E4UL, 0x2B60A476UL, 0x81E67400UL, + 0x08BA6FB5UL, 0x571BE91FUL, 0xF296EC6BUL, 0x2A0DD915UL, + 0xB6636521UL, 0xE7B9F9B6UL, 0xFF34052EUL, 0xC5855664UL, + 0x53B02D5DUL, 0xA99F8FA1UL, 0x08BA4799UL, 0x6E85076AUL }, + { 0x4B7A70E9UL, 0xB5B32944UL, 0xDB75092EUL, 0xC4192623UL, + 0xAD6EA6B0UL, 0x49A7DF7DUL, 0x9CEE60B8UL, 0x8FEDB266UL, + 0xECAA8C71UL, 0x699A17FFUL, 0x5664526CUL, 0xC2B19EE1UL, + 0x193602A5UL, 0x75094C29UL, 0xA0591340UL, 0xE4183A3EUL, + 0x3F54989AUL, 0x5B429D65UL, 0x6B8FE4D6UL, 0x99F73FD6UL, + 0xA1D29C07UL, 0xEFE830F5UL, 0x4D2D38E6UL, 0xF0255DC1UL, + 0x4CDD2086UL, 0x8470EB26UL, 0x6382E9C6UL, 0x021ECC5EUL, + 0x09686B3FUL, 0x3EBAEFC9UL, 0x3C971814UL, 0x6B6A70A1UL, + 0x687F3584UL, 0x52A0E286UL, 0xB79C5305UL, 0xAA500737UL, + 0x3E07841CUL, 0x7FDEAE5CUL, 0x8E7D44ECUL, 0x5716F2B8UL, + 0xB03ADA37UL, 0xF0500C0DUL, 0xF01C1F04UL, 0x0200B3FFUL, + 0xAE0CF51AUL, 0x3CB574B2UL, 0x25837A58UL, 0xDC0921BDUL, + 0xD19113F9UL, 0x7CA92FF6UL, 0x94324773UL, 0x22F54701UL, + 0x3AE5E581UL, 0x37C2DADCUL, 0xC8B57634UL, 0x9AF3DDA7UL, + 0xA9446146UL, 0x0FD0030EUL, 0xECC8C73EUL, 0xA4751E41UL, + 0xE238CD99UL, 0x3BEA0E2FUL, 0x3280BBA1UL, 0x183EB331UL, + 0x4E548B38UL, 0x4F6DB908UL, 0x6F420D03UL, 0xF60A04BFUL, + 0x2CB81290UL, 0x24977C79UL, 0x5679B072UL, 0xBCAF89AFUL, + 0xDE9A771FUL, 0xD9930810UL, 0xB38BAE12UL, 0xDCCF3F2EUL, + 0x5512721FUL, 0x2E6B7124UL, 0x501ADDE6UL, 0x9F84CD87UL, + 0x7A584718UL, 0x7408DA17UL, 0xBC9F9ABCUL, 0xE94B7D8CUL, + 0xEC7AEC3AUL, 0xDB851DFAUL, 0x63094366UL, 0xC464C3D2UL, + 0xEF1C1847UL, 0x3215D908UL, 0xDD433B37UL, 0x24C2BA16UL, + 0x12A14D43UL, 0x2A65C451UL, 0x50940002UL, 0x133AE4DDUL, + 0x71DFF89EUL, 0x10314E55UL, 0x81AC77D6UL, 0x5F11199BUL, + 0x043556F1UL, 0xD7A3C76BUL, 0x3C11183BUL, 0x5924A509UL, + 0xF28FE6EDUL, 0x97F1FBFAUL, 0x9EBABF2CUL, 0x1E153C6EUL, + 0x86E34570UL, 0xEAE96FB1UL, 0x860E5E0AUL, 0x5A3E2AB3UL, + 0x771FE71CUL, 0x4E3D06FAUL, 0x2965DCB9UL, 0x99E71D0FUL, + 0x803E89D6UL, 0x5266C825UL, 0x2E4CC978UL, 0x9C10B36AUL, + 0xC6150EBAUL, 0x94E2EA78UL, 0xA5FC3C53UL, 0x1E0A2DF4UL, + 0xF2F74EA7UL, 0x361D2B3DUL, 0x1939260FUL, 0x19C27960UL, + 0x5223A708UL, 0xF71312B6UL, 0xEBADFE6EUL, 0xEAC31F66UL, + 0xE3BC4595UL, 0xA67BC883UL, 0xB17F37D1UL, 0x018CFF28UL, + 0xC332DDEFUL, 0xBE6C5AA5UL, 0x65582185UL, 0x68AB9802UL, + 0xEECEA50FUL, 0xDB2F953BUL, 0x2AEF7DADUL, 0x5B6E2F84UL, + 0x1521B628UL, 0x29076170UL, 0xECDD4775UL, 0x619F1510UL, + 0x13CCA830UL, 0xEB61BD96UL, 0x0334FE1EUL, 0xAA0363CFUL, + 0xB5735C90UL, 0x4C70A239UL, 0xD59E9E0BUL, 0xCBAADE14UL, + 0xEECC86BCUL, 0x60622CA7UL, 0x9CAB5CABUL, 0xB2F3846EUL, + 0x648B1EAFUL, 0x19BDF0CAUL, 0xA02369B9UL, 0x655ABB50UL, + 0x40685A32UL, 0x3C2AB4B3UL, 0x319EE9D5UL, 0xC021B8F7UL, + 0x9B540B19UL, 0x875FA099UL, 0x95F7997EUL, 0x623D7DA8UL, + 0xF837889AUL, 0x97E32D77UL, 0x11ED935FUL, 0x16681281UL, + 0x0E358829UL, 0xC7E61FD6UL, 0x96DEDFA1UL, 0x7858BA99UL, + 0x57F584A5UL, 0x1B227263UL, 0x9B83C3FFUL, 0x1AC24696UL, + 0xCDB30AEBUL, 0x532E3054UL, 0x8FD948E4UL, 0x6DBC3128UL, + 0x58EBF2EFUL, 0x34C6FFEAUL, 0xFE28ED61UL, 0xEE7C3C73UL, + 0x5D4A14D9UL, 0xE864B7E3UL, 0x42105D14UL, 0x203E13E0UL, + 0x45EEE2B6UL, 0xA3AAABEAUL, 0xDB6C4F15UL, 0xFACB4FD0UL, + 0xC742F442UL, 0xEF6ABBB5UL, 0x654F3B1DUL, 0x41CD2105UL, + 0xD81E799EUL, 0x86854DC7UL, 0xE44B476AUL, 0x3D816250UL, + 0xCF62A1F2UL, 0x5B8D2646UL, 0xFC8883A0UL, 0xC1C7B6A3UL, + 0x7F1524C3UL, 0x69CB7492UL, 0x47848A0BUL, 0x5692B285UL, + 0x095BBF00UL, 0xAD19489DUL, 0x1462B174UL, 0x23820E00UL, + 0x58428D2AUL, 0x0C55F5EAUL, 0x1DADF43EUL, 0x233F7061UL, + 0x3372F092UL, 0x8D937E41UL, 0xD65FECF1UL, 0x6C223BDBUL, + 0x7CDE3759UL, 0xCBEE7460UL, 0x4085F2A7UL, 0xCE77326EUL, + 0xA6078084UL, 0x19F8509EUL, 0xE8EFD855UL, 0x61D99735UL, + 0xA969A7AAUL, 0xC50C06C2UL, 0x5A04ABFCUL, 0x800BCADCUL, + 0x9E447A2EUL, 0xC3453484UL, 0xFDD56705UL, 0x0E1E9EC9UL, + 0xDB73DBD3UL, 0x105588CDUL, 0x675FDA79UL, 0xE3674340UL, + 0xC5C43465UL, 0x713E38D8UL, 0x3D28F89EUL, 0xF16DFF20UL, + 0x153E21E7UL, 0x8FB03D4AUL, 0xE6E39F2BUL, 0xDB83ADF7UL }, + { 0xE93D5A68UL, 0x948140F7UL, 0xF64C261CUL, 0x94692934UL, + 0x411520F7UL, 0x7602D4F7UL, 0xBCF46B2EUL, 0xD4A20068UL, + 0xD4082471UL, 0x3320F46AUL, 0x43B7D4B7UL, 0x500061AFUL, + 0x1E39F62EUL, 0x97244546UL, 0x14214F74UL, 0xBF8B8840UL, + 0x4D95FC1DUL, 0x96B591AFUL, 0x70F4DDD3UL, 0x66A02F45UL, + 0xBFBC09ECUL, 0x03BD9785UL, 0x7FAC6DD0UL, 0x31CB8504UL, + 0x96EB27B3UL, 0x55FD3941UL, 0xDA2547E6UL, 0xABCA0A9AUL, + 0x28507825UL, 0x530429F4UL, 0x0A2C86DAUL, 0xE9B66DFBUL, + 0x68DC1462UL, 0xD7486900UL, 0x680EC0A4UL, 0x27A18DEEUL, + 0x4F3FFEA2UL, 0xE887AD8CUL, 0xB58CE006UL, 0x7AF4D6B6UL, + 0xAACE1E7CUL, 0xD3375FECUL, 0xCE78A399UL, 0x406B2A42UL, + 0x20FE9E35UL, 0xD9F385B9UL, 0xEE39D7ABUL, 0x3B124E8BUL, + 0x1DC9FAF7UL, 0x4B6D1856UL, 0x26A36631UL, 0xEAE397B2UL, + 0x3A6EFA74UL, 0xDD5B4332UL, 0x6841E7F7UL, 0xCA7820FBUL, + 0xFB0AF54EUL, 0xD8FEB397UL, 0x454056ACUL, 0xBA489527UL, + 0x55533A3AUL, 0x20838D87UL, 0xFE6BA9B7UL, 0xD096954BUL, + 0x55A867BCUL, 0xA1159A58UL, 0xCCA92963UL, 0x99E1DB33UL, + 0xA62A4A56UL, 0x3F3125F9UL, 0x5EF47E1CUL, 0x9029317CUL, + 0xFDF8E802UL, 0x04272F70UL, 0x80BB155CUL, 0x05282CE3UL, + 0x95C11548UL, 0xE4C66D22UL, 0x48C1133FUL, 0xC70F86DCUL, + 0x07F9C9EEUL, 0x41041F0FUL, 0x404779A4UL, 0x5D886E17UL, + 0x325F51EBUL, 0xD59BC0D1UL, 0xF2BCC18FUL, 0x41113564UL, + 0x257B7834UL, 0x602A9C60UL, 0xDFF8E8A3UL, 0x1F636C1BUL, + 0x0E12B4C2UL, 0x02E1329EUL, 0xAF664FD1UL, 0xCAD18115UL, + 0x6B2395E0UL, 0x333E92E1UL, 0x3B240B62UL, 0xEEBEB922UL, + 0x85B2A20EUL, 0xE6BA0D99UL, 0xDE720C8CUL, 0x2DA2F728UL, + 0xD0127845UL, 0x95B794FDUL, 0x647D0862UL, 0xE7CCF5F0UL, + 0x5449A36FUL, 0x877D48FAUL, 0xC39DFD27UL, 0xF33E8D1EUL, + 0x0A476341UL, 0x992EFF74UL, 0x3A6F6EABUL, 0xF4F8FD37UL, + 0xA812DC60UL, 0xA1EBDDF8UL, 0x991BE14CUL, 0xDB6E6B0DUL, + 0xC67B5510UL, 0x6D672C37UL, 0x2765D43BUL, 0xDCD0E804UL, + 0xF1290DC7UL, 0xCC00FFA3UL, 0xB5390F92UL, 0x690FED0BUL, + 0x667B9FFBUL, 0xCEDB7D9CUL, 0xA091CF0BUL, 0xD9155EA3UL, + 0xBB132F88UL, 0x515BAD24UL, 0x7B9479BFUL, 0x763BD6EBUL, + 0x37392EB3UL, 0xCC115979UL, 0x8026E297UL, 0xF42E312DUL, + 0x6842ADA7UL, 0xC66A2B3BUL, 0x12754CCCUL, 0x782EF11CUL, + 0x6A124237UL, 0xB79251E7UL, 0x06A1BBE6UL, 0x4BFB6350UL, + 0x1A6B1018UL, 0x11CAEDFAUL, 0x3D25BDD8UL, 0xE2E1C3C9UL, + 0x44421659UL, 0x0A121386UL, 0xD90CEC6EUL, 0xD5ABEA2AUL, + 0x64AF674EUL, 0xDA86A85FUL, 0xBEBFE988UL, 0x64E4C3FEUL, + 0x9DBC8057UL, 0xF0F7C086UL, 0x60787BF8UL, 0x6003604DUL, + 0xD1FD8346UL, 0xF6381FB0UL, 0x7745AE04UL, 0xD736FCCCUL, + 0x83426B33UL, 0xF01EAB71UL, 0xB0804187UL, 0x3C005E5FUL, + 0x77A057BEUL, 0xBDE8AE24UL, 0x55464299UL, 0xBF582E61UL, + 0x4E58F48FUL, 0xF2DDFDA2UL, 0xF474EF38UL, 0x8789BDC2UL, + 0x5366F9C3UL, 0xC8B38E74UL, 0xB475F255UL, 0x46FCD9B9UL, + 0x7AEB2661UL, 0x8B1DDF84UL, 0x846A0E79UL, 0x915F95E2UL, + 0x466E598EUL, 0x20B45770UL, 0x8CD55591UL, 0xC902DE4CUL, + 0xB90BACE1UL, 0xBB8205D0UL, 0x11A86248UL, 0x7574A99EUL, + 0xB77F19B6UL, 0xE0A9DC09UL, 0x662D09A1UL, 0xC4324633UL, + 0xE85A1F02UL, 0x09F0BE8CUL, 0x4A99A025UL, 0x1D6EFE10UL, + 0x1AB93D1DUL, 0x0BA5A4DFUL, 0xA186F20FUL, 0x2868F169UL, + 0xDCB7DA83UL, 0x573906FEUL, 0xA1E2CE9BUL, 0x4FCD7F52UL, + 0x50115E01UL, 0xA70683FAUL, 0xA002B5C4UL, 0x0DE6D027UL, + 0x9AF88C27UL, 0x773F8641UL, 0xC3604C06UL, 0x61A806B5UL, + 0xF0177A28UL, 0xC0F586E0UL, 0x006058AAUL, 0x30DC7D62UL, + 0x11E69ED7UL, 0x2338EA63UL, 0x53C2DD94UL, 0xC2C21634UL, + 0xBBCBEE56UL, 0x90BCB6DEUL, 0xEBFC7DA1UL, 0xCE591D76UL, + 0x6F05E409UL, 0x4B7C0188UL, 0x39720A3DUL, 0x7C927C24UL, + 0x86E3725FUL, 0x724D9DB9UL, 0x1AC15BB4UL, 0xD39EB8FCUL, + 0xED545578UL, 0x08FCA5B5UL, 0xD83D7CD3UL, 0x4DAD0FC4UL, + 0x1E50EF5EUL, 0xB161E6F8UL, 0xA28514D9UL, 0x6C51133CUL, + 0x6FD5C7E7UL, 0x56E14EC4UL, 0x362ABFCEUL, 0xDDC6C837UL, + 0xD79A3234UL, 0x92638212UL, 0x670EFA8EUL, 0x406000E0UL }, + { 0x3A39CE37UL, 0xD3FAF5CFUL, 0xABC27737UL, 0x5AC52D1BUL, + 0x5CB0679EUL, 0x4FA33742UL, 0xD3822740UL, 0x99BC9BBEUL, + 0xD5118E9DUL, 0xBF0F7315UL, 0xD62D1C7EUL, 0xC700C47BUL, + 0xB78C1B6BUL, 0x21A19045UL, 0xB26EB1BEUL, 0x6A366EB4UL, + 0x5748AB2FUL, 0xBC946E79UL, 0xC6A376D2UL, 0x6549C2C8UL, + 0x530FF8EEUL, 0x468DDE7DUL, 0xD5730A1DUL, 0x4CD04DC6UL, + 0x2939BBDBUL, 0xA9BA4650UL, 0xAC9526E8UL, 0xBE5EE304UL, + 0xA1FAD5F0UL, 0x6A2D519AUL, 0x63EF8CE2UL, 0x9A86EE22UL, + 0xC089C2B8UL, 0x43242EF6UL, 0xA51E03AAUL, 0x9CF2D0A4UL, + 0x83C061BAUL, 0x9BE96A4DUL, 0x8FE51550UL, 0xBA645BD6UL, + 0x2826A2F9UL, 0xA73A3AE1UL, 0x4BA99586UL, 0xEF5562E9UL, + 0xC72FEFD3UL, 0xF752F7DAUL, 0x3F046F69UL, 0x77FA0A59UL, + 0x80E4A915UL, 0x87B08601UL, 0x9B09E6ADUL, 0x3B3EE593UL, + 0xE990FD5AUL, 0x9E34D797UL, 0x2CF0B7D9UL, 0x022B8B51UL, + 0x96D5AC3AUL, 0x017DA67DUL, 0xD1CF3ED6UL, 0x7C7D2D28UL, + 0x1F9F25CFUL, 0xADF2B89BUL, 0x5AD6B472UL, 0x5A88F54CUL, + 0xE029AC71UL, 0xE019A5E6UL, 0x47B0ACFDUL, 0xED93FA9BUL, + 0xE8D3C48DUL, 0x283B57CCUL, 0xF8D56629UL, 0x79132E28UL, + 0x785F0191UL, 0xED756055UL, 0xF7960E44UL, 0xE3D35E8CUL, + 0x15056DD4UL, 0x88F46DBAUL, 0x03A16125UL, 0x0564F0BDUL, + 0xC3EB9E15UL, 0x3C9057A2UL, 0x97271AECUL, 0xA93A072AUL, + 0x1B3F6D9BUL, 0x1E6321F5UL, 0xF59C66FBUL, 0x26DCF319UL, + 0x7533D928UL, 0xB155FDF5UL, 0x03563482UL, 0x8ABA3CBBUL, + 0x28517711UL, 0xC20AD9F8UL, 0xABCC5167UL, 0xCCAD925FUL, + 0x4DE81751UL, 0x3830DC8EUL, 0x379D5862UL, 0x9320F991UL, + 0xEA7A90C2UL, 0xFB3E7BCEUL, 0x5121CE64UL, 0x774FBE32UL, + 0xA8B6E37EUL, 0xC3293D46UL, 0x48DE5369UL, 0x6413E680UL, + 0xA2AE0810UL, 0xDD6DB224UL, 0x69852DFDUL, 0x09072166UL, + 0xB39A460AUL, 0x6445C0DDUL, 0x586CDECFUL, 0x1C20C8AEUL, + 0x5BBEF7DDUL, 0x1B588D40UL, 0xCCD2017FUL, 0x6BB4E3BBUL, + 0xDDA26A7EUL, 0x3A59FF45UL, 0x3E350A44UL, 0xBCB4CDD5UL, + 0x72EACEA8UL, 0xFA6484BBUL, 0x8D6612AEUL, 0xBF3C6F47UL, + 0xD29BE463UL, 0x542F5D9EUL, 0xAEC2771BUL, 0xF64E6370UL, + 0x740E0D8DUL, 0xE75B1357UL, 0xF8721671UL, 0xAF537D5DUL, + 0x4040CB08UL, 0x4EB4E2CCUL, 0x34D2466AUL, 0x0115AF84UL, + 0xE1B00428UL, 0x95983A1DUL, 0x06B89FB4UL, 0xCE6EA048UL, + 0x6F3F3B82UL, 0x3520AB82UL, 0x011A1D4BUL, 0x277227F8UL, + 0x611560B1UL, 0xE7933FDCUL, 0xBB3A792BUL, 0x344525BDUL, + 0xA08839E1UL, 0x51CE794BUL, 0x2F32C9B7UL, 0xA01FBAC9UL, + 0xE01CC87EUL, 0xBCC7D1F6UL, 0xCF0111C3UL, 0xA1E8AAC7UL, + 0x1A908749UL, 0xD44FBD9AUL, 0xD0DADECBUL, 0xD50ADA38UL, + 0x0339C32AUL, 0xC6913667UL, 0x8DF9317CUL, 0xE0B12B4FUL, + 0xF79E59B7UL, 0x43F5BB3AUL, 0xF2D519FFUL, 0x27D9459CUL, + 0xBF97222CUL, 0x15E6FC2AUL, 0x0F91FC71UL, 0x9B941525UL, + 0xFAE59361UL, 0xCEB69CEBUL, 0xC2A86459UL, 0x12BAA8D1UL, + 0xB6C1075EUL, 0xE3056A0CUL, 0x10D25065UL, 0xCB03A442UL, + 0xE0EC6E0EUL, 0x1698DB3BUL, 0x4C98A0BEUL, 0x3278E964UL, + 0x9F1F9532UL, 0xE0D392DFUL, 0xD3A0342BUL, 0x8971F21EUL, + 0x1B0A7441UL, 0x4BA3348CUL, 0xC5BE7120UL, 0xC37632D8UL, + 0xDF359F8DUL, 0x9B992F2EUL, 0xE60B6F47UL, 0x0FE3F11DUL, + 0xE54CDA54UL, 0x1EDAD891UL, 0xCE6279CFUL, 0xCD3E7E6FUL, + 0x1618B166UL, 0xFD2C1D05UL, 0x848FD2C5UL, 0xF6FB2299UL, + 0xF523F357UL, 0xA6327623UL, 0x93A83531UL, 0x56CCCD02UL, + 0xACF08162UL, 0x5A75EBB5UL, 0x6E163697UL, 0x88D273CCUL, + 0xDE966292UL, 0x81B949D0UL, 0x4C50901BUL, 0x71C65614UL, + 0xE6C6C7BDUL, 0x327A140AUL, 0x45E1D006UL, 0xC3F27B9AUL, + 0xC9AA53FDUL, 0x62A80F00UL, 0xBB25BFE2UL, 0x35BDD2F6UL, + 0x71126905UL, 0xB2040222UL, 0xB6CBCF7CUL, 0xCD769C2BUL, + 0x53113EC0UL, 0x1640E3D3UL, 0x38ABBD60UL, 0x2547ADF0UL, + 0xBA38209CUL, 0xF746CE76UL, 0x77AFA1C5UL, 0x20756060UL, + 0x85CBFE4EUL, 0x8AE88DD8UL, 0x7AAAF9B0UL, 0x4CF9AA7EUL, + 0x1948C25CUL, 0x02FB8A8CUL, 0x01C36AE4UL, 0xD6EBE1F9UL, + 0x90D4F869UL, 0xA65CDEA0UL, 0x3F09252DUL, 0xC208E69FUL, + 0xB74E6132UL, 0xCE77E25BUL, 0x578FDFE3UL, 0x3AC372E6UL } +}; + + /** + Initialize the Blowfish block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, + symmetric_key *skey) +{ + ulong32 x, y, z, A; + unsigned char B[8]; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + /* check key length */ + if (keylen < 8 || keylen > 56) { + return CRYPT_INVALID_KEYSIZE; + } + + /* check rounds */ + if (num_rounds != 0 && num_rounds != 16) { + return CRYPT_INVALID_ROUNDS; + } + + /* load in key bytes (Supplied by David Hopwood) */ + for (x = y = 0; x < 18; x++) { + A = 0; + for (z = 0; z < 4; z++) { + A = (A << 8) | ((ulong32)key[y++] & 255); + if (y == (ulong32)keylen) { + y = 0; + } + } + skey->blowfish.K[x] = ORIG_P[x] ^ A; + } + + /* copy sboxes */ + for (x = 0; x < 4; x++) { + for (y = 0; y < 256; y++) { + skey->blowfish.S[x][y] = ORIG_S[x][y]; + } + } + + /* encrypt K array */ + for (x = 0; x < 8; x++) { + B[x] = 0; + } + + for (x = 0; x < 18; x += 2) { + /* encrypt it */ + blowfish_ecb_encrypt(B, B, skey); + /* copy it */ + LOAD32H(skey->blowfish.K[x], &B[0]); + LOAD32H(skey->blowfish.K[x+1], &B[4]); + } + + /* encrypt S array */ + for (x = 0; x < 4; x++) { + for (y = 0; y < 256; y += 2) { + /* encrypt it */ + blowfish_ecb_encrypt(B, B, skey); + /* copy it */ + LOAD32H(skey->blowfish.S[x][y], &B[0]); + LOAD32H(skey->blowfish.S[x][y+1], &B[4]); + } + } + +#ifdef LTC_CLEAN_STACK + zeromem(B, sizeof(B)); +#endif + + return CRYPT_OK; +} + +#ifndef __GNUC__ +#define F(x) ((S1[byte(x,3)] + S2[byte(x,2)]) ^ S3[byte(x,1)]) + S4[byte(x,0)] +#else +#define F(x) ((skey->blowfish.S[0][byte(x,3)] + skey->blowfish.S[1][byte(x,2)]) ^ skey->blowfish.S[2][byte(x,1)]) + skey->blowfish.S[3][byte(x,0)] +#endif + +/** + Encrypts a block of text with Blowfish + @param pt The input plaintext (8 bytes) + @param ct The output ciphertext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#else +int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#endif +{ + ulong32 L, R; + int r; +#ifndef __GNUC__ + ulong32 *S1, *S2, *S3, *S4; +#endif + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + +#ifndef __GNUC__ + S1 = skey->blowfish.S[0]; + S2 = skey->blowfish.S[1]; + S3 = skey->blowfish.S[2]; + S4 = skey->blowfish.S[3]; +#endif + + /* load it */ + LOAD32H(L, &pt[0]); + LOAD32H(R, &pt[4]); + + /* do 16 rounds */ + for (r = 0; r < 16; ) { + L ^= skey->blowfish.K[r++]; R ^= F(L); + R ^= skey->blowfish.K[r++]; L ^= F(R); + L ^= skey->blowfish.K[r++]; R ^= F(L); + R ^= skey->blowfish.K[r++]; L ^= F(R); + } + + /* last keying */ + R ^= skey->blowfish.K[17]; + L ^= skey->blowfish.K[16]; + + /* store */ + STORE32H(R, &ct[0]); + STORE32H(L, &ct[4]); + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + int err = _blowfish_ecb_encrypt(pt, ct, skey); + burn_stack(sizeof(ulong32) * 2 + sizeof(int)); + return err; +} +#endif + +/** + Decrypts a block of text with Blowfish + @param ct The input ciphertext (8 bytes) + @param pt The output plaintext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#else +int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#endif +{ + ulong32 L, R; + int r; +#ifndef __GNUC__ + ulong32 *S1, *S2, *S3, *S4; +#endif + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + +#ifndef __GNUC__ + S1 = skey->blowfish.S[0]; + S2 = skey->blowfish.S[1]; + S3 = skey->blowfish.S[2]; + S4 = skey->blowfish.S[3]; +#endif + + /* load it */ + LOAD32H(R, &ct[0]); + LOAD32H(L, &ct[4]); + + /* undo last keying */ + R ^= skey->blowfish.K[17]; + L ^= skey->blowfish.K[16]; + + /* do 16 rounds */ + for (r = 15; r > 0; ) { + L ^= F(R); R ^= skey->blowfish.K[r--]; + R ^= F(L); L ^= skey->blowfish.K[r--]; + L ^= F(R); R ^= skey->blowfish.K[r--]; + R ^= F(L); L ^= skey->blowfish.K[r--]; + } + + /* store */ + STORE32H(L, &pt[0]); + STORE32H(R, &pt[4]); + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + int err = _blowfish_ecb_decrypt(ct, pt, skey); + burn_stack(sizeof(ulong32) * 2 + sizeof(int)); + return err; +} +#endif + + +/** + Performs a self-test of the Blowfish block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int blowfish_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + int err; + symmetric_key key; + static const struct { + unsigned char key[8], pt[8], ct[8]; + } tests[] = { + { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + { 0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78} + }, + { + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + { 0x51, 0x86, 0x6F, 0xD5, 0xB8, 0x5E, 0xCB, 0x8A} + }, + { + { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + { 0x7D, 0x85, 0x6F, 0x9A, 0x61, 0x30, 0x63, 0xF2} + } + }; + unsigned char tmp[2][8]; + int x, y; + + for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { + /* setup key */ + if ((err = blowfish_setup(tests[x].key, 8, 16, &key)) != CRYPT_OK) { + return err; + } + + /* encrypt and decrypt */ + blowfish_ecb_encrypt(tests[x].pt, tmp[0], &key); + blowfish_ecb_decrypt(tmp[0], tmp[1], &key); + + /* compare */ + if ((XMEMCMP(tmp[0], tests[x].ct, 8) != 0) || (XMEMCMP(tmp[1], tests[x].pt, 8) != 0)) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) blowfish_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) blowfish_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void blowfish_done(symmetric_key *skey) +{ +} + +/** + Gets suitable key size + @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. + @return CRYPT_OK if the input key size is acceptable. +*/ +int blowfish_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + + if (*keysize < 8) { + return CRYPT_INVALID_KEYSIZE; + } else if (*keysize > 56) { + *keysize = 56; + } + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/blowfish.c,v $ */ +/* $Revision: 1.14 $ */ +/* $Date: 2007/05/12 14:20:27 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/cast5.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/cast5.c new file mode 100644 index 0000000000..a977b2ce26 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/cast5.c @@ -0,0 +1,720 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + + /** + @file cast5.c + Implementation of LTC_CAST5 (RFC 2144) by Tom St Denis + */ +#include "tomcrypt.h" + +#ifdef LTC_CAST5 + +const struct ltc_cipher_descriptor cast5_desc = { + "cast5", + 15, + 5, 16, 8, 16, + &cast5_setup, + &cast5_ecb_encrypt, + &cast5_ecb_decrypt, + &cast5_test, + &cast5_done, + &cast5_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +static const ulong32 S1[256] = { +0x30fb40d4UL, 0x9fa0ff0bUL, 0x6beccd2fUL, 0x3f258c7aUL, 0x1e213f2fUL, 0x9c004dd3UL, +0x6003e540UL, 0xcf9fc949UL, 0xbfd4af27UL, 0x88bbbdb5UL, 0xe2034090UL, 0x98d09675UL, +0x6e63a0e0UL, 0x15c361d2UL, 0xc2e7661dUL, 0x22d4ff8eUL, 0x28683b6fUL, 0xc07fd059UL, +0xff2379c8UL, 0x775f50e2UL, 0x43c340d3UL, 0xdf2f8656UL, 0x887ca41aUL, 0xa2d2bd2dUL, +0xa1c9e0d6UL, 0x346c4819UL, 0x61b76d87UL, 0x22540f2fUL, 0x2abe32e1UL, 0xaa54166bUL, +0x22568e3aUL, 0xa2d341d0UL, 0x66db40c8UL, 0xa784392fUL, 0x004dff2fUL, 0x2db9d2deUL, +0x97943facUL, 0x4a97c1d8UL, 0x527644b7UL, 0xb5f437a7UL, 0xb82cbaefUL, 0xd751d159UL, +0x6ff7f0edUL, 0x5a097a1fUL, 0x827b68d0UL, 0x90ecf52eUL, 0x22b0c054UL, 0xbc8e5935UL, +0x4b6d2f7fUL, 0x50bb64a2UL, 0xd2664910UL, 0xbee5812dUL, 0xb7332290UL, 0xe93b159fUL, +0xb48ee411UL, 0x4bff345dUL, 0xfd45c240UL, 0xad31973fUL, 0xc4f6d02eUL, 0x55fc8165UL, +0xd5b1caadUL, 0xa1ac2daeUL, 0xa2d4b76dUL, 0xc19b0c50UL, 0x882240f2UL, 0x0c6e4f38UL, +0xa4e4bfd7UL, 0x4f5ba272UL, 0x564c1d2fUL, 0xc59c5319UL, 0xb949e354UL, 0xb04669feUL, +0xb1b6ab8aUL, 0xc71358ddUL, 0x6385c545UL, 0x110f935dUL, 0x57538ad5UL, 0x6a390493UL, +0xe63d37e0UL, 0x2a54f6b3UL, 0x3a787d5fUL, 0x6276a0b5UL, 0x19a6fcdfUL, 0x7a42206aUL, +0x29f9d4d5UL, 0xf61b1891UL, 0xbb72275eUL, 0xaa508167UL, 0x38901091UL, 0xc6b505ebUL, +0x84c7cb8cUL, 0x2ad75a0fUL, 0x874a1427UL, 0xa2d1936bUL, 0x2ad286afUL, 0xaa56d291UL, +0xd7894360UL, 0x425c750dUL, 0x93b39e26UL, 0x187184c9UL, 0x6c00b32dUL, 0x73e2bb14UL, +0xa0bebc3cUL, 0x54623779UL, 0x64459eabUL, 0x3f328b82UL, 0x7718cf82UL, 0x59a2cea6UL, +0x04ee002eUL, 0x89fe78e6UL, 0x3fab0950UL, 0x325ff6c2UL, 0x81383f05UL, 0x6963c5c8UL, +0x76cb5ad6UL, 0xd49974c9UL, 0xca180dcfUL, 0x380782d5UL, 0xc7fa5cf6UL, 0x8ac31511UL, +0x35e79e13UL, 0x47da91d0UL, 0xf40f9086UL, 0xa7e2419eUL, 0x31366241UL, 0x051ef495UL, +0xaa573b04UL, 0x4a805d8dUL, 0x548300d0UL, 0x00322a3cUL, 0xbf64cddfUL, 0xba57a68eUL, +0x75c6372bUL, 0x50afd341UL, 0xa7c13275UL, 0x915a0bf5UL, 0x6b54bfabUL, 0x2b0b1426UL, +0xab4cc9d7UL, 0x449ccd82UL, 0xf7fbf265UL, 0xab85c5f3UL, 0x1b55db94UL, 0xaad4e324UL, +0xcfa4bd3fUL, 0x2deaa3e2UL, 0x9e204d02UL, 0xc8bd25acUL, 0xeadf55b3UL, 0xd5bd9e98UL, +0xe31231b2UL, 0x2ad5ad6cUL, 0x954329deUL, 0xadbe4528UL, 0xd8710f69UL, 0xaa51c90fUL, +0xaa786bf6UL, 0x22513f1eUL, 0xaa51a79bUL, 0x2ad344ccUL, 0x7b5a41f0UL, 0xd37cfbadUL, +0x1b069505UL, 0x41ece491UL, 0xb4c332e6UL, 0x032268d4UL, 0xc9600accUL, 0xce387e6dUL, +0xbf6bb16cUL, 0x6a70fb78UL, 0x0d03d9c9UL, 0xd4df39deUL, 0xe01063daUL, 0x4736f464UL, +0x5ad328d8UL, 0xb347cc96UL, 0x75bb0fc3UL, 0x98511bfbUL, 0x4ffbcc35UL, 0xb58bcf6aUL, +0xe11f0abcUL, 0xbfc5fe4aUL, 0xa70aec10UL, 0xac39570aUL, 0x3f04442fUL, 0x6188b153UL, +0xe0397a2eUL, 0x5727cb79UL, 0x9ceb418fUL, 0x1cacd68dUL, 0x2ad37c96UL, 0x0175cb9dUL, +0xc69dff09UL, 0xc75b65f0UL, 0xd9db40d8UL, 0xec0e7779UL, 0x4744ead4UL, 0xb11c3274UL, +0xdd24cb9eUL, 0x7e1c54bdUL, 0xf01144f9UL, 0xd2240eb1UL, 0x9675b3fdUL, 0xa3ac3755UL, +0xd47c27afUL, 0x51c85f4dUL, 0x56907596UL, 0xa5bb15e6UL, 0x580304f0UL, 0xca042cf1UL, +0x011a37eaUL, 0x8dbfaadbUL, 0x35ba3e4aUL, 0x3526ffa0UL, 0xc37b4d09UL, 0xbc306ed9UL, +0x98a52666UL, 0x5648f725UL, 0xff5e569dUL, 0x0ced63d0UL, 0x7c63b2cfUL, 0x700b45e1UL, +0xd5ea50f1UL, 0x85a92872UL, 0xaf1fbda7UL, 0xd4234870UL, 0xa7870bf3UL, 0x2d3b4d79UL, +0x42e04198UL, 0x0cd0ede7UL, 0x26470db8UL, 0xf881814cUL, 0x474d6ad7UL, 0x7c0c5e5cUL, +0xd1231959UL, 0x381b7298UL, 0xf5d2f4dbUL, 0xab838653UL, 0x6e2f1e23UL, 0x83719c9eUL, +0xbd91e046UL, 0x9a56456eUL, 0xdc39200cUL, 0x20c8c571UL, 0x962bda1cUL, 0xe1e696ffUL, +0xb141ab08UL, 0x7cca89b9UL, 0x1a69e783UL, 0x02cc4843UL, 0xa2f7c579UL, 0x429ef47dUL, +0x427b169cUL, 0x5ac9f049UL, 0xdd8f0f00UL, 0x5c8165bfUL}; + +static const ulong32 S2[256] = { +0x1f201094UL, 0xef0ba75bUL, 0x69e3cf7eUL, 0x393f4380UL, 0xfe61cf7aUL, 0xeec5207aUL, +0x55889c94UL, 0x72fc0651UL, 0xada7ef79UL, 0x4e1d7235UL, 0xd55a63ceUL, 0xde0436baUL, +0x99c430efUL, 0x5f0c0794UL, 0x18dcdb7dUL, 0xa1d6eff3UL, 0xa0b52f7bUL, 0x59e83605UL, +0xee15b094UL, 0xe9ffd909UL, 0xdc440086UL, 0xef944459UL, 0xba83ccb3UL, 0xe0c3cdfbUL, +0xd1da4181UL, 0x3b092ab1UL, 0xf997f1c1UL, 0xa5e6cf7bUL, 0x01420ddbUL, 0xe4e7ef5bUL, +0x25a1ff41UL, 0xe180f806UL, 0x1fc41080UL, 0x179bee7aUL, 0xd37ac6a9UL, 0xfe5830a4UL, +0x98de8b7fUL, 0x77e83f4eUL, 0x79929269UL, 0x24fa9f7bUL, 0xe113c85bUL, 0xacc40083UL, +0xd7503525UL, 0xf7ea615fUL, 0x62143154UL, 0x0d554b63UL, 0x5d681121UL, 0xc866c359UL, +0x3d63cf73UL, 0xcee234c0UL, 0xd4d87e87UL, 0x5c672b21UL, 0x071f6181UL, 0x39f7627fUL, +0x361e3084UL, 0xe4eb573bUL, 0x602f64a4UL, 0xd63acd9cUL, 0x1bbc4635UL, 0x9e81032dUL, +0x2701f50cUL, 0x99847ab4UL, 0xa0e3df79UL, 0xba6cf38cUL, 0x10843094UL, 0x2537a95eUL, +0xf46f6ffeUL, 0xa1ff3b1fUL, 0x208cfb6aUL, 0x8f458c74UL, 0xd9e0a227UL, 0x4ec73a34UL, +0xfc884f69UL, 0x3e4de8dfUL, 0xef0e0088UL, 0x3559648dUL, 0x8a45388cUL, 0x1d804366UL, +0x721d9bfdUL, 0xa58684bbUL, 0xe8256333UL, 0x844e8212UL, 0x128d8098UL, 0xfed33fb4UL, +0xce280ae1UL, 0x27e19ba5UL, 0xd5a6c252UL, 0xe49754bdUL, 0xc5d655ddUL, 0xeb667064UL, +0x77840b4dUL, 0xa1b6a801UL, 0x84db26a9UL, 0xe0b56714UL, 0x21f043b7UL, 0xe5d05860UL, +0x54f03084UL, 0x066ff472UL, 0xa31aa153UL, 0xdadc4755UL, 0xb5625dbfUL, 0x68561be6UL, +0x83ca6b94UL, 0x2d6ed23bUL, 0xeccf01dbUL, 0xa6d3d0baUL, 0xb6803d5cUL, 0xaf77a709UL, +0x33b4a34cUL, 0x397bc8d6UL, 0x5ee22b95UL, 0x5f0e5304UL, 0x81ed6f61UL, 0x20e74364UL, +0xb45e1378UL, 0xde18639bUL, 0x881ca122UL, 0xb96726d1UL, 0x8049a7e8UL, 0x22b7da7bUL, +0x5e552d25UL, 0x5272d237UL, 0x79d2951cUL, 0xc60d894cUL, 0x488cb402UL, 0x1ba4fe5bUL, +0xa4b09f6bUL, 0x1ca815cfUL, 0xa20c3005UL, 0x8871df63UL, 0xb9de2fcbUL, 0x0cc6c9e9UL, +0x0beeff53UL, 0xe3214517UL, 0xb4542835UL, 0x9f63293cUL, 0xee41e729UL, 0x6e1d2d7cUL, +0x50045286UL, 0x1e6685f3UL, 0xf33401c6UL, 0x30a22c95UL, 0x31a70850UL, 0x60930f13UL, +0x73f98417UL, 0xa1269859UL, 0xec645c44UL, 0x52c877a9UL, 0xcdff33a6UL, 0xa02b1741UL, +0x7cbad9a2UL, 0x2180036fUL, 0x50d99c08UL, 0xcb3f4861UL, 0xc26bd765UL, 0x64a3f6abUL, +0x80342676UL, 0x25a75e7bUL, 0xe4e6d1fcUL, 0x20c710e6UL, 0xcdf0b680UL, 0x17844d3bUL, +0x31eef84dUL, 0x7e0824e4UL, 0x2ccb49ebUL, 0x846a3baeUL, 0x8ff77888UL, 0xee5d60f6UL, +0x7af75673UL, 0x2fdd5cdbUL, 0xa11631c1UL, 0x30f66f43UL, 0xb3faec54UL, 0x157fd7faUL, +0xef8579ccUL, 0xd152de58UL, 0xdb2ffd5eUL, 0x8f32ce19UL, 0x306af97aUL, 0x02f03ef8UL, +0x99319ad5UL, 0xc242fa0fUL, 0xa7e3ebb0UL, 0xc68e4906UL, 0xb8da230cUL, 0x80823028UL, +0xdcdef3c8UL, 0xd35fb171UL, 0x088a1bc8UL, 0xbec0c560UL, 0x61a3c9e8UL, 0xbca8f54dUL, +0xc72feffaUL, 0x22822e99UL, 0x82c570b4UL, 0xd8d94e89UL, 0x8b1c34bcUL, 0x301e16e6UL, +0x273be979UL, 0xb0ffeaa6UL, 0x61d9b8c6UL, 0x00b24869UL, 0xb7ffce3fUL, 0x08dc283bUL, +0x43daf65aUL, 0xf7e19798UL, 0x7619b72fUL, 0x8f1c9ba4UL, 0xdc8637a0UL, 0x16a7d3b1UL, +0x9fc393b7UL, 0xa7136eebUL, 0xc6bcc63eUL, 0x1a513742UL, 0xef6828bcUL, 0x520365d6UL, +0x2d6a77abUL, 0x3527ed4bUL, 0x821fd216UL, 0x095c6e2eUL, 0xdb92f2fbUL, 0x5eea29cbUL, +0x145892f5UL, 0x91584f7fUL, 0x5483697bUL, 0x2667a8ccUL, 0x85196048UL, 0x8c4baceaUL, +0x833860d4UL, 0x0d23e0f9UL, 0x6c387e8aUL, 0x0ae6d249UL, 0xb284600cUL, 0xd835731dUL, +0xdcb1c647UL, 0xac4c56eaUL, 0x3ebd81b3UL, 0x230eabb0UL, 0x6438bc87UL, 0xf0b5b1faUL, +0x8f5ea2b3UL, 0xfc184642UL, 0x0a036b7aUL, 0x4fb089bdUL, 0x649da589UL, 0xa345415eUL, +0x5c038323UL, 0x3e5d3bb9UL, 0x43d79572UL, 0x7e6dd07cUL, 0x06dfdf1eUL, 0x6c6cc4efUL, +0x7160a539UL, 0x73bfbe70UL, 0x83877605UL, 0x4523ecf1UL}; + +static const ulong32 S3[256] = { +0x8defc240UL, 0x25fa5d9fUL, 0xeb903dbfUL, 0xe810c907UL, 0x47607fffUL, 0x369fe44bUL, +0x8c1fc644UL, 0xaececa90UL, 0xbeb1f9bfUL, 0xeefbcaeaUL, 0xe8cf1950UL, 0x51df07aeUL, +0x920e8806UL, 0xf0ad0548UL, 0xe13c8d83UL, 0x927010d5UL, 0x11107d9fUL, 0x07647db9UL, +0xb2e3e4d4UL, 0x3d4f285eUL, 0xb9afa820UL, 0xfade82e0UL, 0xa067268bUL, 0x8272792eUL, +0x553fb2c0UL, 0x489ae22bUL, 0xd4ef9794UL, 0x125e3fbcUL, 0x21fffceeUL, 0x825b1bfdUL, +0x9255c5edUL, 0x1257a240UL, 0x4e1a8302UL, 0xbae07fffUL, 0x528246e7UL, 0x8e57140eUL, +0x3373f7bfUL, 0x8c9f8188UL, 0xa6fc4ee8UL, 0xc982b5a5UL, 0xa8c01db7UL, 0x579fc264UL, +0x67094f31UL, 0xf2bd3f5fUL, 0x40fff7c1UL, 0x1fb78dfcUL, 0x8e6bd2c1UL, 0x437be59bUL, +0x99b03dbfUL, 0xb5dbc64bUL, 0x638dc0e6UL, 0x55819d99UL, 0xa197c81cUL, 0x4a012d6eUL, +0xc5884a28UL, 0xccc36f71UL, 0xb843c213UL, 0x6c0743f1UL, 0x8309893cUL, 0x0feddd5fUL, +0x2f7fe850UL, 0xd7c07f7eUL, 0x02507fbfUL, 0x5afb9a04UL, 0xa747d2d0UL, 0x1651192eUL, +0xaf70bf3eUL, 0x58c31380UL, 0x5f98302eUL, 0x727cc3c4UL, 0x0a0fb402UL, 0x0f7fef82UL, +0x8c96fdadUL, 0x5d2c2aaeUL, 0x8ee99a49UL, 0x50da88b8UL, 0x8427f4a0UL, 0x1eac5790UL, +0x796fb449UL, 0x8252dc15UL, 0xefbd7d9bUL, 0xa672597dUL, 0xada840d8UL, 0x45f54504UL, +0xfa5d7403UL, 0xe83ec305UL, 0x4f91751aUL, 0x925669c2UL, 0x23efe941UL, 0xa903f12eUL, +0x60270df2UL, 0x0276e4b6UL, 0x94fd6574UL, 0x927985b2UL, 0x8276dbcbUL, 0x02778176UL, +0xf8af918dUL, 0x4e48f79eUL, 0x8f616ddfUL, 0xe29d840eUL, 0x842f7d83UL, 0x340ce5c8UL, +0x96bbb682UL, 0x93b4b148UL, 0xef303cabUL, 0x984faf28UL, 0x779faf9bUL, 0x92dc560dUL, +0x224d1e20UL, 0x8437aa88UL, 0x7d29dc96UL, 0x2756d3dcUL, 0x8b907ceeUL, 0xb51fd240UL, +0xe7c07ce3UL, 0xe566b4a1UL, 0xc3e9615eUL, 0x3cf8209dUL, 0x6094d1e3UL, 0xcd9ca341UL, +0x5c76460eUL, 0x00ea983bUL, 0xd4d67881UL, 0xfd47572cUL, 0xf76cedd9UL, 0xbda8229cUL, +0x127dadaaUL, 0x438a074eUL, 0x1f97c090UL, 0x081bdb8aUL, 0x93a07ebeUL, 0xb938ca15UL, +0x97b03cffUL, 0x3dc2c0f8UL, 0x8d1ab2ecUL, 0x64380e51UL, 0x68cc7bfbUL, 0xd90f2788UL, +0x12490181UL, 0x5de5ffd4UL, 0xdd7ef86aUL, 0x76a2e214UL, 0xb9a40368UL, 0x925d958fUL, +0x4b39fffaUL, 0xba39aee9UL, 0xa4ffd30bUL, 0xfaf7933bUL, 0x6d498623UL, 0x193cbcfaUL, +0x27627545UL, 0x825cf47aUL, 0x61bd8ba0UL, 0xd11e42d1UL, 0xcead04f4UL, 0x127ea392UL, +0x10428db7UL, 0x8272a972UL, 0x9270c4a8UL, 0x127de50bUL, 0x285ba1c8UL, 0x3c62f44fUL, +0x35c0eaa5UL, 0xe805d231UL, 0x428929fbUL, 0xb4fcdf82UL, 0x4fb66a53UL, 0x0e7dc15bUL, +0x1f081fabUL, 0x108618aeUL, 0xfcfd086dUL, 0xf9ff2889UL, 0x694bcc11UL, 0x236a5caeUL, +0x12deca4dUL, 0x2c3f8cc5UL, 0xd2d02dfeUL, 0xf8ef5896UL, 0xe4cf52daUL, 0x95155b67UL, +0x494a488cUL, 0xb9b6a80cUL, 0x5c8f82bcUL, 0x89d36b45UL, 0x3a609437UL, 0xec00c9a9UL, +0x44715253UL, 0x0a874b49UL, 0xd773bc40UL, 0x7c34671cUL, 0x02717ef6UL, 0x4feb5536UL, +0xa2d02fffUL, 0xd2bf60c4UL, 0xd43f03c0UL, 0x50b4ef6dUL, 0x07478cd1UL, 0x006e1888UL, +0xa2e53f55UL, 0xb9e6d4bcUL, 0xa2048016UL, 0x97573833UL, 0xd7207d67UL, 0xde0f8f3dUL, +0x72f87b33UL, 0xabcc4f33UL, 0x7688c55dUL, 0x7b00a6b0UL, 0x947b0001UL, 0x570075d2UL, +0xf9bb88f8UL, 0x8942019eUL, 0x4264a5ffUL, 0x856302e0UL, 0x72dbd92bUL, 0xee971b69UL, +0x6ea22fdeUL, 0x5f08ae2bUL, 0xaf7a616dUL, 0xe5c98767UL, 0xcf1febd2UL, 0x61efc8c2UL, +0xf1ac2571UL, 0xcc8239c2UL, 0x67214cb8UL, 0xb1e583d1UL, 0xb7dc3e62UL, 0x7f10bdceUL, +0xf90a5c38UL, 0x0ff0443dUL, 0x606e6dc6UL, 0x60543a49UL, 0x5727c148UL, 0x2be98a1dUL, +0x8ab41738UL, 0x20e1be24UL, 0xaf96da0fUL, 0x68458425UL, 0x99833be5UL, 0x600d457dUL, +0x282f9350UL, 0x8334b362UL, 0xd91d1120UL, 0x2b6d8da0UL, 0x642b1e31UL, 0x9c305a00UL, +0x52bce688UL, 0x1b03588aUL, 0xf7baefd5UL, 0x4142ed9cUL, 0xa4315c11UL, 0x83323ec5UL, +0xdfef4636UL, 0xa133c501UL, 0xe9d3531cUL, 0xee353783UL}; + +static const ulong32 S4[256] = { +0x9db30420UL, 0x1fb6e9deUL, 0xa7be7befUL, 0xd273a298UL, 0x4a4f7bdbUL, 0x64ad8c57UL, +0x85510443UL, 0xfa020ed1UL, 0x7e287affUL, 0xe60fb663UL, 0x095f35a1UL, 0x79ebf120UL, +0xfd059d43UL, 0x6497b7b1UL, 0xf3641f63UL, 0x241e4adfUL, 0x28147f5fUL, 0x4fa2b8cdUL, +0xc9430040UL, 0x0cc32220UL, 0xfdd30b30UL, 0xc0a5374fUL, 0x1d2d00d9UL, 0x24147b15UL, +0xee4d111aUL, 0x0fca5167UL, 0x71ff904cUL, 0x2d195ffeUL, 0x1a05645fUL, 0x0c13fefeUL, +0x081b08caUL, 0x05170121UL, 0x80530100UL, 0xe83e5efeUL, 0xac9af4f8UL, 0x7fe72701UL, +0xd2b8ee5fUL, 0x06df4261UL, 0xbb9e9b8aUL, 0x7293ea25UL, 0xce84ffdfUL, 0xf5718801UL, +0x3dd64b04UL, 0xa26f263bUL, 0x7ed48400UL, 0x547eebe6UL, 0x446d4ca0UL, 0x6cf3d6f5UL, +0x2649abdfUL, 0xaea0c7f5UL, 0x36338cc1UL, 0x503f7e93UL, 0xd3772061UL, 0x11b638e1UL, +0x72500e03UL, 0xf80eb2bbUL, 0xabe0502eUL, 0xec8d77deUL, 0x57971e81UL, 0xe14f6746UL, +0xc9335400UL, 0x6920318fUL, 0x081dbb99UL, 0xffc304a5UL, 0x4d351805UL, 0x7f3d5ce3UL, +0xa6c866c6UL, 0x5d5bcca9UL, 0xdaec6feaUL, 0x9f926f91UL, 0x9f46222fUL, 0x3991467dUL, +0xa5bf6d8eUL, 0x1143c44fUL, 0x43958302UL, 0xd0214eebUL, 0x022083b8UL, 0x3fb6180cUL, +0x18f8931eUL, 0x281658e6UL, 0x26486e3eUL, 0x8bd78a70UL, 0x7477e4c1UL, 0xb506e07cUL, +0xf32d0a25UL, 0x79098b02UL, 0xe4eabb81UL, 0x28123b23UL, 0x69dead38UL, 0x1574ca16UL, +0xdf871b62UL, 0x211c40b7UL, 0xa51a9ef9UL, 0x0014377bUL, 0x041e8ac8UL, 0x09114003UL, +0xbd59e4d2UL, 0xe3d156d5UL, 0x4fe876d5UL, 0x2f91a340UL, 0x557be8deUL, 0x00eae4a7UL, +0x0ce5c2ecUL, 0x4db4bba6UL, 0xe756bdffUL, 0xdd3369acUL, 0xec17b035UL, 0x06572327UL, +0x99afc8b0UL, 0x56c8c391UL, 0x6b65811cUL, 0x5e146119UL, 0x6e85cb75UL, 0xbe07c002UL, +0xc2325577UL, 0x893ff4ecUL, 0x5bbfc92dUL, 0xd0ec3b25UL, 0xb7801ab7UL, 0x8d6d3b24UL, +0x20c763efUL, 0xc366a5fcUL, 0x9c382880UL, 0x0ace3205UL, 0xaac9548aUL, 0xeca1d7c7UL, +0x041afa32UL, 0x1d16625aUL, 0x6701902cUL, 0x9b757a54UL, 0x31d477f7UL, 0x9126b031UL, +0x36cc6fdbUL, 0xc70b8b46UL, 0xd9e66a48UL, 0x56e55a79UL, 0x026a4cebUL, 0x52437effUL, +0x2f8f76b4UL, 0x0df980a5UL, 0x8674cde3UL, 0xedda04ebUL, 0x17a9be04UL, 0x2c18f4dfUL, +0xb7747f9dUL, 0xab2af7b4UL, 0xefc34d20UL, 0x2e096b7cUL, 0x1741a254UL, 0xe5b6a035UL, +0x213d42f6UL, 0x2c1c7c26UL, 0x61c2f50fUL, 0x6552daf9UL, 0xd2c231f8UL, 0x25130f69UL, +0xd8167fa2UL, 0x0418f2c8UL, 0x001a96a6UL, 0x0d1526abUL, 0x63315c21UL, 0x5e0a72ecUL, +0x49bafefdUL, 0x187908d9UL, 0x8d0dbd86UL, 0x311170a7UL, 0x3e9b640cUL, 0xcc3e10d7UL, +0xd5cad3b6UL, 0x0caec388UL, 0xf73001e1UL, 0x6c728affUL, 0x71eae2a1UL, 0x1f9af36eUL, +0xcfcbd12fUL, 0xc1de8417UL, 0xac07be6bUL, 0xcb44a1d8UL, 0x8b9b0f56UL, 0x013988c3UL, +0xb1c52fcaUL, 0xb4be31cdUL, 0xd8782806UL, 0x12a3a4e2UL, 0x6f7de532UL, 0x58fd7eb6UL, +0xd01ee900UL, 0x24adffc2UL, 0xf4990fc5UL, 0x9711aac5UL, 0x001d7b95UL, 0x82e5e7d2UL, +0x109873f6UL, 0x00613096UL, 0xc32d9521UL, 0xada121ffUL, 0x29908415UL, 0x7fbb977fUL, +0xaf9eb3dbUL, 0x29c9ed2aUL, 0x5ce2a465UL, 0xa730f32cUL, 0xd0aa3fe8UL, 0x8a5cc091UL, +0xd49e2ce7UL, 0x0ce454a9UL, 0xd60acd86UL, 0x015f1919UL, 0x77079103UL, 0xdea03af6UL, +0x78a8565eUL, 0xdee356dfUL, 0x21f05cbeUL, 0x8b75e387UL, 0xb3c50651UL, 0xb8a5c3efUL, +0xd8eeb6d2UL, 0xe523be77UL, 0xc2154529UL, 0x2f69efdfUL, 0xafe67afbUL, 0xf470c4b2UL, +0xf3e0eb5bUL, 0xd6cc9876UL, 0x39e4460cUL, 0x1fda8538UL, 0x1987832fUL, 0xca007367UL, +0xa99144f8UL, 0x296b299eUL, 0x492fc295UL, 0x9266beabUL, 0xb5676e69UL, 0x9bd3dddaUL, +0xdf7e052fUL, 0xdb25701cUL, 0x1b5e51eeUL, 0xf65324e6UL, 0x6afce36cUL, 0x0316cc04UL, +0x8644213eUL, 0xb7dc59d0UL, 0x7965291fUL, 0xccd6fd43UL, 0x41823979UL, 0x932bcdf6UL, +0xb657c34dUL, 0x4edfd282UL, 0x7ae5290cUL, 0x3cb9536bUL, 0x851e20feUL, 0x9833557eUL, +0x13ecf0b0UL, 0xd3ffb372UL, 0x3f85c5c1UL, 0x0aef7ed2UL}; + +static const ulong32 S5[256] = { +0x7ec90c04UL, 0x2c6e74b9UL, 0x9b0e66dfUL, 0xa6337911UL, 0xb86a7fffUL, 0x1dd358f5UL, +0x44dd9d44UL, 0x1731167fUL, 0x08fbf1faUL, 0xe7f511ccUL, 0xd2051b00UL, 0x735aba00UL, +0x2ab722d8UL, 0x386381cbUL, 0xacf6243aUL, 0x69befd7aUL, 0xe6a2e77fUL, 0xf0c720cdUL, +0xc4494816UL, 0xccf5c180UL, 0x38851640UL, 0x15b0a848UL, 0xe68b18cbUL, 0x4caadeffUL, +0x5f480a01UL, 0x0412b2aaUL, 0x259814fcUL, 0x41d0efe2UL, 0x4e40b48dUL, 0x248eb6fbUL, +0x8dba1cfeUL, 0x41a99b02UL, 0x1a550a04UL, 0xba8f65cbUL, 0x7251f4e7UL, 0x95a51725UL, +0xc106ecd7UL, 0x97a5980aUL, 0xc539b9aaUL, 0x4d79fe6aUL, 0xf2f3f763UL, 0x68af8040UL, +0xed0c9e56UL, 0x11b4958bUL, 0xe1eb5a88UL, 0x8709e6b0UL, 0xd7e07156UL, 0x4e29fea7UL, +0x6366e52dUL, 0x02d1c000UL, 0xc4ac8e05UL, 0x9377f571UL, 0x0c05372aUL, 0x578535f2UL, +0x2261be02UL, 0xd642a0c9UL, 0xdf13a280UL, 0x74b55bd2UL, 0x682199c0UL, 0xd421e5ecUL, +0x53fb3ce8UL, 0xc8adedb3UL, 0x28a87fc9UL, 0x3d959981UL, 0x5c1ff900UL, 0xfe38d399UL, +0x0c4eff0bUL, 0x062407eaUL, 0xaa2f4fb1UL, 0x4fb96976UL, 0x90c79505UL, 0xb0a8a774UL, +0xef55a1ffUL, 0xe59ca2c2UL, 0xa6b62d27UL, 0xe66a4263UL, 0xdf65001fUL, 0x0ec50966UL, +0xdfdd55bcUL, 0x29de0655UL, 0x911e739aUL, 0x17af8975UL, 0x32c7911cUL, 0x89f89468UL, +0x0d01e980UL, 0x524755f4UL, 0x03b63cc9UL, 0x0cc844b2UL, 0xbcf3f0aaUL, 0x87ac36e9UL, +0xe53a7426UL, 0x01b3d82bUL, 0x1a9e7449UL, 0x64ee2d7eUL, 0xcddbb1daUL, 0x01c94910UL, +0xb868bf80UL, 0x0d26f3fdUL, 0x9342ede7UL, 0x04a5c284UL, 0x636737b6UL, 0x50f5b616UL, +0xf24766e3UL, 0x8eca36c1UL, 0x136e05dbUL, 0xfef18391UL, 0xfb887a37UL, 0xd6e7f7d4UL, +0xc7fb7dc9UL, 0x3063fcdfUL, 0xb6f589deUL, 0xec2941daUL, 0x26e46695UL, 0xb7566419UL, +0xf654efc5UL, 0xd08d58b7UL, 0x48925401UL, 0xc1bacb7fUL, 0xe5ff550fUL, 0xb6083049UL, +0x5bb5d0e8UL, 0x87d72e5aUL, 0xab6a6ee1UL, 0x223a66ceUL, 0xc62bf3cdUL, 0x9e0885f9UL, +0x68cb3e47UL, 0x086c010fUL, 0xa21de820UL, 0xd18b69deUL, 0xf3f65777UL, 0xfa02c3f6UL, +0x407edac3UL, 0xcbb3d550UL, 0x1793084dUL, 0xb0d70ebaUL, 0x0ab378d5UL, 0xd951fb0cUL, +0xded7da56UL, 0x4124bbe4UL, 0x94ca0b56UL, 0x0f5755d1UL, 0xe0e1e56eUL, 0x6184b5beUL, +0x580a249fUL, 0x94f74bc0UL, 0xe327888eUL, 0x9f7b5561UL, 0xc3dc0280UL, 0x05687715UL, +0x646c6bd7UL, 0x44904db3UL, 0x66b4f0a3UL, 0xc0f1648aUL, 0x697ed5afUL, 0x49e92ff6UL, +0x309e374fUL, 0x2cb6356aUL, 0x85808573UL, 0x4991f840UL, 0x76f0ae02UL, 0x083be84dUL, +0x28421c9aUL, 0x44489406UL, 0x736e4cb8UL, 0xc1092910UL, 0x8bc95fc6UL, 0x7d869cf4UL, +0x134f616fUL, 0x2e77118dUL, 0xb31b2be1UL, 0xaa90b472UL, 0x3ca5d717UL, 0x7d161bbaUL, +0x9cad9010UL, 0xaf462ba2UL, 0x9fe459d2UL, 0x45d34559UL, 0xd9f2da13UL, 0xdbc65487UL, +0xf3e4f94eUL, 0x176d486fUL, 0x097c13eaUL, 0x631da5c7UL, 0x445f7382UL, 0x175683f4UL, +0xcdc66a97UL, 0x70be0288UL, 0xb3cdcf72UL, 0x6e5dd2f3UL, 0x20936079UL, 0x459b80a5UL, +0xbe60e2dbUL, 0xa9c23101UL, 0xeba5315cUL, 0x224e42f2UL, 0x1c5c1572UL, 0xf6721b2cUL, +0x1ad2fff3UL, 0x8c25404eUL, 0x324ed72fUL, 0x4067b7fdUL, 0x0523138eUL, 0x5ca3bc78UL, +0xdc0fd66eUL, 0x75922283UL, 0x784d6b17UL, 0x58ebb16eUL, 0x44094f85UL, 0x3f481d87UL, +0xfcfeae7bUL, 0x77b5ff76UL, 0x8c2302bfUL, 0xaaf47556UL, 0x5f46b02aUL, 0x2b092801UL, +0x3d38f5f7UL, 0x0ca81f36UL, 0x52af4a8aUL, 0x66d5e7c0UL, 0xdf3b0874UL, 0x95055110UL, +0x1b5ad7a8UL, 0xf61ed5adUL, 0x6cf6e479UL, 0x20758184UL, 0xd0cefa65UL, 0x88f7be58UL, +0x4a046826UL, 0x0ff6f8f3UL, 0xa09c7f70UL, 0x5346aba0UL, 0x5ce96c28UL, 0xe176eda3UL, +0x6bac307fUL, 0x376829d2UL, 0x85360fa9UL, 0x17e3fe2aUL, 0x24b79767UL, 0xf5a96b20UL, +0xd6cd2595UL, 0x68ff1ebfUL, 0x7555442cUL, 0xf19f06beUL, 0xf9e0659aUL, 0xeeb9491dUL, +0x34010718UL, 0xbb30cab8UL, 0xe822fe15UL, 0x88570983UL, 0x750e6249UL, 0xda627e55UL, +0x5e76ffa8UL, 0xb1534546UL, 0x6d47de08UL, 0xefe9e7d4UL}; + +static const ulong32 S6[256] = { +0xf6fa8f9dUL, 0x2cac6ce1UL, 0x4ca34867UL, 0xe2337f7cUL, 0x95db08e7UL, 0x016843b4UL, +0xeced5cbcUL, 0x325553acUL, 0xbf9f0960UL, 0xdfa1e2edUL, 0x83f0579dUL, 0x63ed86b9UL, +0x1ab6a6b8UL, 0xde5ebe39UL, 0xf38ff732UL, 0x8989b138UL, 0x33f14961UL, 0xc01937bdUL, +0xf506c6daUL, 0xe4625e7eUL, 0xa308ea99UL, 0x4e23e33cUL, 0x79cbd7ccUL, 0x48a14367UL, +0xa3149619UL, 0xfec94bd5UL, 0xa114174aUL, 0xeaa01866UL, 0xa084db2dUL, 0x09a8486fUL, +0xa888614aUL, 0x2900af98UL, 0x01665991UL, 0xe1992863UL, 0xc8f30c60UL, 0x2e78ef3cUL, +0xd0d51932UL, 0xcf0fec14UL, 0xf7ca07d2UL, 0xd0a82072UL, 0xfd41197eUL, 0x9305a6b0UL, +0xe86be3daUL, 0x74bed3cdUL, 0x372da53cUL, 0x4c7f4448UL, 0xdab5d440UL, 0x6dba0ec3UL, +0x083919a7UL, 0x9fbaeed9UL, 0x49dbcfb0UL, 0x4e670c53UL, 0x5c3d9c01UL, 0x64bdb941UL, +0x2c0e636aUL, 0xba7dd9cdUL, 0xea6f7388UL, 0xe70bc762UL, 0x35f29adbUL, 0x5c4cdd8dUL, +0xf0d48d8cUL, 0xb88153e2UL, 0x08a19866UL, 0x1ae2eac8UL, 0x284caf89UL, 0xaa928223UL, +0x9334be53UL, 0x3b3a21bfUL, 0x16434be3UL, 0x9aea3906UL, 0xefe8c36eUL, 0xf890cdd9UL, +0x80226daeUL, 0xc340a4a3UL, 0xdf7e9c09UL, 0xa694a807UL, 0x5b7c5eccUL, 0x221db3a6UL, +0x9a69a02fUL, 0x68818a54UL, 0xceb2296fUL, 0x53c0843aUL, 0xfe893655UL, 0x25bfe68aUL, +0xb4628abcUL, 0xcf222ebfUL, 0x25ac6f48UL, 0xa9a99387UL, 0x53bddb65UL, 0xe76ffbe7UL, +0xe967fd78UL, 0x0ba93563UL, 0x8e342bc1UL, 0xe8a11be9UL, 0x4980740dUL, 0xc8087dfcUL, +0x8de4bf99UL, 0xa11101a0UL, 0x7fd37975UL, 0xda5a26c0UL, 0xe81f994fUL, 0x9528cd89UL, +0xfd339fedUL, 0xb87834bfUL, 0x5f04456dUL, 0x22258698UL, 0xc9c4c83bUL, 0x2dc156beUL, +0x4f628daaUL, 0x57f55ec5UL, 0xe2220abeUL, 0xd2916ebfUL, 0x4ec75b95UL, 0x24f2c3c0UL, +0x42d15d99UL, 0xcd0d7fa0UL, 0x7b6e27ffUL, 0xa8dc8af0UL, 0x7345c106UL, 0xf41e232fUL, +0x35162386UL, 0xe6ea8926UL, 0x3333b094UL, 0x157ec6f2UL, 0x372b74afUL, 0x692573e4UL, +0xe9a9d848UL, 0xf3160289UL, 0x3a62ef1dUL, 0xa787e238UL, 0xf3a5f676UL, 0x74364853UL, +0x20951063UL, 0x4576698dUL, 0xb6fad407UL, 0x592af950UL, 0x36f73523UL, 0x4cfb6e87UL, +0x7da4cec0UL, 0x6c152daaUL, 0xcb0396a8UL, 0xc50dfe5dUL, 0xfcd707abUL, 0x0921c42fUL, +0x89dff0bbUL, 0x5fe2be78UL, 0x448f4f33UL, 0x754613c9UL, 0x2b05d08dUL, 0x48b9d585UL, +0xdc049441UL, 0xc8098f9bUL, 0x7dede786UL, 0xc39a3373UL, 0x42410005UL, 0x6a091751UL, +0x0ef3c8a6UL, 0x890072d6UL, 0x28207682UL, 0xa9a9f7beUL, 0xbf32679dUL, 0xd45b5b75UL, +0xb353fd00UL, 0xcbb0e358UL, 0x830f220aUL, 0x1f8fb214UL, 0xd372cf08UL, 0xcc3c4a13UL, +0x8cf63166UL, 0x061c87beUL, 0x88c98f88UL, 0x6062e397UL, 0x47cf8e7aUL, 0xb6c85283UL, +0x3cc2acfbUL, 0x3fc06976UL, 0x4e8f0252UL, 0x64d8314dUL, 0xda3870e3UL, 0x1e665459UL, +0xc10908f0UL, 0x513021a5UL, 0x6c5b68b7UL, 0x822f8aa0UL, 0x3007cd3eUL, 0x74719eefUL, +0xdc872681UL, 0x073340d4UL, 0x7e432fd9UL, 0x0c5ec241UL, 0x8809286cUL, 0xf592d891UL, +0x08a930f6UL, 0x957ef305UL, 0xb7fbffbdUL, 0xc266e96fUL, 0x6fe4ac98UL, 0xb173ecc0UL, +0xbc60b42aUL, 0x953498daUL, 0xfba1ae12UL, 0x2d4bd736UL, 0x0f25faabUL, 0xa4f3fcebUL, +0xe2969123UL, 0x257f0c3dUL, 0x9348af49UL, 0x361400bcUL, 0xe8816f4aUL, 0x3814f200UL, +0xa3f94043UL, 0x9c7a54c2UL, 0xbc704f57UL, 0xda41e7f9UL, 0xc25ad33aUL, 0x54f4a084UL, +0xb17f5505UL, 0x59357cbeUL, 0xedbd15c8UL, 0x7f97c5abUL, 0xba5ac7b5UL, 0xb6f6deafUL, +0x3a479c3aUL, 0x5302da25UL, 0x653d7e6aUL, 0x54268d49UL, 0x51a477eaUL, 0x5017d55bUL, +0xd7d25d88UL, 0x44136c76UL, 0x0404a8c8UL, 0xb8e5a121UL, 0xb81a928aUL, 0x60ed5869UL, +0x97c55b96UL, 0xeaec991bUL, 0x29935913UL, 0x01fdb7f1UL, 0x088e8dfaUL, 0x9ab6f6f5UL, +0x3b4cbf9fUL, 0x4a5de3abUL, 0xe6051d35UL, 0xa0e1d855UL, 0xd36b4cf1UL, 0xf544edebUL, +0xb0e93524UL, 0xbebb8fbdUL, 0xa2d762cfUL, 0x49c92f54UL, 0x38b5f331UL, 0x7128a454UL, +0x48392905UL, 0xa65b1db8UL, 0x851c97bdUL, 0xd675cf2fUL}; + +static const ulong32 S7[256] = { +0x85e04019UL, 0x332bf567UL, 0x662dbfffUL, 0xcfc65693UL, 0x2a8d7f6fUL, 0xab9bc912UL, +0xde6008a1UL, 0x2028da1fUL, 0x0227bce7UL, 0x4d642916UL, 0x18fac300UL, 0x50f18b82UL, +0x2cb2cb11UL, 0xb232e75cUL, 0x4b3695f2UL, 0xb28707deUL, 0xa05fbcf6UL, 0xcd4181e9UL, +0xe150210cUL, 0xe24ef1bdUL, 0xb168c381UL, 0xfde4e789UL, 0x5c79b0d8UL, 0x1e8bfd43UL, +0x4d495001UL, 0x38be4341UL, 0x913cee1dUL, 0x92a79c3fUL, 0x089766beUL, 0xbaeeadf4UL, +0x1286becfUL, 0xb6eacb19UL, 0x2660c200UL, 0x7565bde4UL, 0x64241f7aUL, 0x8248dca9UL, +0xc3b3ad66UL, 0x28136086UL, 0x0bd8dfa8UL, 0x356d1cf2UL, 0x107789beUL, 0xb3b2e9ceUL, +0x0502aa8fUL, 0x0bc0351eUL, 0x166bf52aUL, 0xeb12ff82UL, 0xe3486911UL, 0xd34d7516UL, +0x4e7b3affUL, 0x5f43671bUL, 0x9cf6e037UL, 0x4981ac83UL, 0x334266ceUL, 0x8c9341b7UL, +0xd0d854c0UL, 0xcb3a6c88UL, 0x47bc2829UL, 0x4725ba37UL, 0xa66ad22bUL, 0x7ad61f1eUL, +0x0c5cbafaUL, 0x4437f107UL, 0xb6e79962UL, 0x42d2d816UL, 0x0a961288UL, 0xe1a5c06eUL, +0x13749e67UL, 0x72fc081aUL, 0xb1d139f7UL, 0xf9583745UL, 0xcf19df58UL, 0xbec3f756UL, +0xc06eba30UL, 0x07211b24UL, 0x45c28829UL, 0xc95e317fUL, 0xbc8ec511UL, 0x38bc46e9UL, +0xc6e6fa14UL, 0xbae8584aUL, 0xad4ebc46UL, 0x468f508bUL, 0x7829435fUL, 0xf124183bUL, +0x821dba9fUL, 0xaff60ff4UL, 0xea2c4e6dUL, 0x16e39264UL, 0x92544a8bUL, 0x009b4fc3UL, +0xaba68cedUL, 0x9ac96f78UL, 0x06a5b79aUL, 0xb2856e6eUL, 0x1aec3ca9UL, 0xbe838688UL, +0x0e0804e9UL, 0x55f1be56UL, 0xe7e5363bUL, 0xb3a1f25dUL, 0xf7debb85UL, 0x61fe033cUL, +0x16746233UL, 0x3c034c28UL, 0xda6d0c74UL, 0x79aac56cUL, 0x3ce4e1adUL, 0x51f0c802UL, +0x98f8f35aUL, 0x1626a49fUL, 0xeed82b29UL, 0x1d382fe3UL, 0x0c4fb99aUL, 0xbb325778UL, +0x3ec6d97bUL, 0x6e77a6a9UL, 0xcb658b5cUL, 0xd45230c7UL, 0x2bd1408bUL, 0x60c03eb7UL, +0xb9068d78UL, 0xa33754f4UL, 0xf430c87dUL, 0xc8a71302UL, 0xb96d8c32UL, 0xebd4e7beUL, +0xbe8b9d2dUL, 0x7979fb06UL, 0xe7225308UL, 0x8b75cf77UL, 0x11ef8da4UL, 0xe083c858UL, +0x8d6b786fUL, 0x5a6317a6UL, 0xfa5cf7a0UL, 0x5dda0033UL, 0xf28ebfb0UL, 0xf5b9c310UL, +0xa0eac280UL, 0x08b9767aUL, 0xa3d9d2b0UL, 0x79d34217UL, 0x021a718dUL, 0x9ac6336aUL, +0x2711fd60UL, 0x438050e3UL, 0x069908a8UL, 0x3d7fedc4UL, 0x826d2befUL, 0x4eeb8476UL, +0x488dcf25UL, 0x36c9d566UL, 0x28e74e41UL, 0xc2610acaUL, 0x3d49a9cfUL, 0xbae3b9dfUL, +0xb65f8de6UL, 0x92aeaf64UL, 0x3ac7d5e6UL, 0x9ea80509UL, 0xf22b017dUL, 0xa4173f70UL, +0xdd1e16c3UL, 0x15e0d7f9UL, 0x50b1b887UL, 0x2b9f4fd5UL, 0x625aba82UL, 0x6a017962UL, +0x2ec01b9cUL, 0x15488aa9UL, 0xd716e740UL, 0x40055a2cUL, 0x93d29a22UL, 0xe32dbf9aUL, +0x058745b9UL, 0x3453dc1eUL, 0xd699296eUL, 0x496cff6fUL, 0x1c9f4986UL, 0xdfe2ed07UL, +0xb87242d1UL, 0x19de7eaeUL, 0x053e561aUL, 0x15ad6f8cUL, 0x66626c1cUL, 0x7154c24cUL, +0xea082b2aUL, 0x93eb2939UL, 0x17dcb0f0UL, 0x58d4f2aeUL, 0x9ea294fbUL, 0x52cf564cUL, +0x9883fe66UL, 0x2ec40581UL, 0x763953c3UL, 0x01d6692eUL, 0xd3a0c108UL, 0xa1e7160eUL, +0xe4f2dfa6UL, 0x693ed285UL, 0x74904698UL, 0x4c2b0eddUL, 0x4f757656UL, 0x5d393378UL, +0xa132234fUL, 0x3d321c5dUL, 0xc3f5e194UL, 0x4b269301UL, 0xc79f022fUL, 0x3c997e7eUL, +0x5e4f9504UL, 0x3ffafbbdUL, 0x76f7ad0eUL, 0x296693f4UL, 0x3d1fce6fUL, 0xc61e45beUL, +0xd3b5ab34UL, 0xf72bf9b7UL, 0x1b0434c0UL, 0x4e72b567UL, 0x5592a33dUL, 0xb5229301UL, +0xcfd2a87fUL, 0x60aeb767UL, 0x1814386bUL, 0x30bcc33dUL, 0x38a0c07dUL, 0xfd1606f2UL, +0xc363519bUL, 0x589dd390UL, 0x5479f8e6UL, 0x1cb8d647UL, 0x97fd61a9UL, 0xea7759f4UL, +0x2d57539dUL, 0x569a58cfUL, 0xe84e63adUL, 0x462e1b78UL, 0x6580f87eUL, 0xf3817914UL, +0x91da55f4UL, 0x40a230f3UL, 0xd1988f35UL, 0xb6e318d2UL, 0x3ffa50bcUL, 0x3d40f021UL, +0xc3c0bdaeUL, 0x4958c24cUL, 0x518f36b2UL, 0x84b1d370UL, 0x0fedce83UL, 0x878ddadaUL, +0xf2a279c7UL, 0x94e01be8UL, 0x90716f4bUL, 0x954b8aa3UL}; + +static const ulong32 S8[256] = { +0xe216300dUL, 0xbbddfffcUL, 0xa7ebdabdUL, 0x35648095UL, 0x7789f8b7UL, 0xe6c1121bUL, +0x0e241600UL, 0x052ce8b5UL, 0x11a9cfb0UL, 0xe5952f11UL, 0xece7990aUL, 0x9386d174UL, +0x2a42931cUL, 0x76e38111UL, 0xb12def3aUL, 0x37ddddfcUL, 0xde9adeb1UL, 0x0a0cc32cUL, +0xbe197029UL, 0x84a00940UL, 0xbb243a0fUL, 0xb4d137cfUL, 0xb44e79f0UL, 0x049eedfdUL, +0x0b15a15dUL, 0x480d3168UL, 0x8bbbde5aUL, 0x669ded42UL, 0xc7ece831UL, 0x3f8f95e7UL, +0x72df191bUL, 0x7580330dUL, 0x94074251UL, 0x5c7dcdfaUL, 0xabbe6d63UL, 0xaa402164UL, +0xb301d40aUL, 0x02e7d1caUL, 0x53571daeUL, 0x7a3182a2UL, 0x12a8ddecUL, 0xfdaa335dUL, +0x176f43e8UL, 0x71fb46d4UL, 0x38129022UL, 0xce949ad4UL, 0xb84769adUL, 0x965bd862UL, +0x82f3d055UL, 0x66fb9767UL, 0x15b80b4eUL, 0x1d5b47a0UL, 0x4cfde06fUL, 0xc28ec4b8UL, +0x57e8726eUL, 0x647a78fcUL, 0x99865d44UL, 0x608bd593UL, 0x6c200e03UL, 0x39dc5ff6UL, +0x5d0b00a3UL, 0xae63aff2UL, 0x7e8bd632UL, 0x70108c0cUL, 0xbbd35049UL, 0x2998df04UL, +0x980cf42aUL, 0x9b6df491UL, 0x9e7edd53UL, 0x06918548UL, 0x58cb7e07UL, 0x3b74ef2eUL, +0x522fffb1UL, 0xd24708ccUL, 0x1c7e27cdUL, 0xa4eb215bUL, 0x3cf1d2e2UL, 0x19b47a38UL, +0x424f7618UL, 0x35856039UL, 0x9d17dee7UL, 0x27eb35e6UL, 0xc9aff67bUL, 0x36baf5b8UL, +0x09c467cdUL, 0xc18910b1UL, 0xe11dbf7bUL, 0x06cd1af8UL, 0x7170c608UL, 0x2d5e3354UL, +0xd4de495aUL, 0x64c6d006UL, 0xbcc0c62cUL, 0x3dd00db3UL, 0x708f8f34UL, 0x77d51b42UL, +0x264f620fUL, 0x24b8d2bfUL, 0x15c1b79eUL, 0x46a52564UL, 0xf8d7e54eUL, 0x3e378160UL, +0x7895cda5UL, 0x859c15a5UL, 0xe6459788UL, 0xc37bc75fUL, 0xdb07ba0cUL, 0x0676a3abUL, +0x7f229b1eUL, 0x31842e7bUL, 0x24259fd7UL, 0xf8bef472UL, 0x835ffcb8UL, 0x6df4c1f2UL, +0x96f5b195UL, 0xfd0af0fcUL, 0xb0fe134cUL, 0xe2506d3dUL, 0x4f9b12eaUL, 0xf215f225UL, +0xa223736fUL, 0x9fb4c428UL, 0x25d04979UL, 0x34c713f8UL, 0xc4618187UL, 0xea7a6e98UL, +0x7cd16efcUL, 0x1436876cUL, 0xf1544107UL, 0xbedeee14UL, 0x56e9af27UL, 0xa04aa441UL, +0x3cf7c899UL, 0x92ecbae6UL, 0xdd67016dUL, 0x151682ebUL, 0xa842eedfUL, 0xfdba60b4UL, +0xf1907b75UL, 0x20e3030fUL, 0x24d8c29eUL, 0xe139673bUL, 0xefa63fb8UL, 0x71873054UL, +0xb6f2cf3bUL, 0x9f326442UL, 0xcb15a4ccUL, 0xb01a4504UL, 0xf1e47d8dUL, 0x844a1be5UL, +0xbae7dfdcUL, 0x42cbda70UL, 0xcd7dae0aUL, 0x57e85b7aUL, 0xd53f5af6UL, 0x20cf4d8cUL, +0xcea4d428UL, 0x79d130a4UL, 0x3486ebfbUL, 0x33d3cddcUL, 0x77853b53UL, 0x37effcb5UL, +0xc5068778UL, 0xe580b3e6UL, 0x4e68b8f4UL, 0xc5c8b37eUL, 0x0d809ea2UL, 0x398feb7cUL, +0x132a4f94UL, 0x43b7950eUL, 0x2fee7d1cUL, 0x223613bdUL, 0xdd06caa2UL, 0x37df932bUL, +0xc4248289UL, 0xacf3ebc3UL, 0x5715f6b7UL, 0xef3478ddUL, 0xf267616fUL, 0xc148cbe4UL, +0x9052815eUL, 0x5e410fabUL, 0xb48a2465UL, 0x2eda7fa4UL, 0xe87b40e4UL, 0xe98ea084UL, +0x5889e9e1UL, 0xefd390fcUL, 0xdd07d35bUL, 0xdb485694UL, 0x38d7e5b2UL, 0x57720101UL, +0x730edebcUL, 0x5b643113UL, 0x94917e4fUL, 0x503c2fbaUL, 0x646f1282UL, 0x7523d24aUL, +0xe0779695UL, 0xf9c17a8fUL, 0x7a5b2121UL, 0xd187b896UL, 0x29263a4dUL, 0xba510cdfUL, +0x81f47c9fUL, 0xad1163edUL, 0xea7b5965UL, 0x1a00726eUL, 0x11403092UL, 0x00da6d77UL, +0x4a0cdd61UL, 0xad1f4603UL, 0x605bdfb0UL, 0x9eedc364UL, 0x22ebe6a8UL, 0xcee7d28aUL, +0xa0e736a0UL, 0x5564a6b9UL, 0x10853209UL, 0xc7eb8f37UL, 0x2de705caUL, 0x8951570fUL, +0xdf09822bUL, 0xbd691a6cUL, 0xaa12e4f2UL, 0x87451c0fUL, 0xe0f6a27aUL, 0x3ada4819UL, +0x4cf1764fUL, 0x0d771c2bUL, 0x67cdb156UL, 0x350d8384UL, 0x5938fa0fUL, 0x42399ef3UL, +0x36997b07UL, 0x0e84093dUL, 0x4aa93e61UL, 0x8360d87bUL, 0x1fa98b0cUL, 0x1149382cUL, +0xe97625a5UL, 0x0614d1b7UL, 0x0e25244bUL, 0x0c768347UL, 0x589e8d82UL, 0x0d2059d1UL, +0xa466bb1eUL, 0xf8da0a82UL, 0x04f19130UL, 0xba6e4ec0UL, 0x99265164UL, 0x1ee7230dUL, +0x50b2ad80UL, 0xeaee6801UL, 0x8db2a283UL, 0xea8bf59eUL}; + +/* returns the i'th byte of a variable */ +#ifdef _MSC_VER + #define GB(x, i) ((unsigned char)((x[(15-i)>>2])>>(unsigned)(8*((15-i)&3)))) +#else + #define GB(x, i) (((x[(15-i)>>2])>>(unsigned)(8*((15-i)&3)))&255) +#endif + + /** + Initialize the LTC_CAST5 block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +#ifdef LTC_CLEAN_STACK +static int _cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#else +int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#endif +{ + ulong32 x[4], z[4]; + unsigned char buf[16]; + int y, i; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (num_rounds != 12 && num_rounds != 16 && num_rounds != 0) { + return CRYPT_INVALID_ROUNDS; + } + + if (num_rounds == 12 && keylen > 10) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen < 5 || keylen > 16) { + return CRYPT_INVALID_KEYSIZE; + } + + /* extend the key as required */ + zeromem(buf, sizeof(buf)); + XMEMCPY(buf, key, (size_t)keylen); + + /* load and start the awful looking network */ + for (y = 0; y < 4; y++) { + LOAD32H(x[3-y],buf+4*y); + } + + for (i = y = 0; y < 2; y++) { + z[3] = x[3] ^ S5[GB(x, 0xD)] ^ S6[GB(x, 0xF)] ^ S7[GB(x, 0xC)] ^ S8[GB(x, 0xE)] ^ S7[GB(x, 0x8)]; + z[2] = x[1] ^ S5[GB(z, 0x0)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x3)] ^ S8[GB(x, 0xA)]; + z[1] = x[0] ^ S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S5[GB(x, 0x9)]; + z[0] = x[2] ^ S5[GB(z, 0xA)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0xb)] ^ S8[GB(z, 0x8)] ^ S6[GB(x, 0xB)]; + skey->cast5.K[i++] = S5[GB(z, 0x8)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0x7)] ^ S8[GB(z, 0x6)] ^ S5[GB(z, 0x2)]; + skey->cast5.K[i++] = S5[GB(z, 0xA)] ^ S6[GB(z, 0xB)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S6[GB(z, 0x6)]; + skey->cast5.K[i++] = S5[GB(z, 0xC)] ^ S6[GB(z, 0xd)] ^ S7[GB(z, 0x3)] ^ S8[GB(z, 0x2)] ^ S7[GB(z, 0x9)]; + skey->cast5.K[i++] = S5[GB(z, 0xE)] ^ S6[GB(z, 0xF)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x0)] ^ S8[GB(z, 0xc)]; + + x[3] = z[1] ^ S5[GB(z, 0x5)] ^ S6[GB(z, 0x7)] ^ S7[GB(z, 0x4)] ^ S8[GB(z, 0x6)] ^ S7[GB(z, 0x0)]; + x[2] = z[3] ^ S5[GB(x, 0x0)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x3)] ^ S8[GB(z, 0x2)]; + x[1] = z[2] ^ S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S5[GB(z, 0x1)]; + x[0] = z[0] ^ S5[GB(x, 0xA)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0xb)] ^ S8[GB(x, 0x8)] ^ S6[GB(z, 0x3)]; + skey->cast5.K[i++] = S5[GB(x, 0x3)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0xc)] ^ S8[GB(x, 0xd)] ^ S5[GB(x, 0x8)]; + skey->cast5.K[i++] = S5[GB(x, 0x1)] ^ S6[GB(x, 0x0)] ^ S7[GB(x, 0xe)] ^ S8[GB(x, 0xf)] ^ S6[GB(x, 0xd)]; + skey->cast5.K[i++] = S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x8)] ^ S8[GB(x, 0x9)] ^ S7[GB(x, 0x3)]; + skey->cast5.K[i++] = S5[GB(x, 0x5)] ^ S6[GB(x, 0x4)] ^ S7[GB(x, 0xa)] ^ S8[GB(x, 0xb)] ^ S8[GB(x, 0x7)]; + + /* second half */ + z[3] = x[3] ^ S5[GB(x, 0xD)] ^ S6[GB(x, 0xF)] ^ S7[GB(x, 0xC)] ^ S8[GB(x, 0xE)] ^ S7[GB(x, 0x8)]; + z[2] = x[1] ^ S5[GB(z, 0x0)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x3)] ^ S8[GB(x, 0xA)]; + z[1] = x[0] ^ S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S5[GB(x, 0x9)]; + z[0] = x[2] ^ S5[GB(z, 0xA)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0xb)] ^ S8[GB(z, 0x8)] ^ S6[GB(x, 0xB)]; + skey->cast5.K[i++] = S5[GB(z, 0x3)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0xc)] ^ S8[GB(z, 0xd)] ^ S5[GB(z, 0x9)]; + skey->cast5.K[i++] = S5[GB(z, 0x1)] ^ S6[GB(z, 0x0)] ^ S7[GB(z, 0xe)] ^ S8[GB(z, 0xf)] ^ S6[GB(z, 0xc)]; + skey->cast5.K[i++] = S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x8)] ^ S8[GB(z, 0x9)] ^ S7[GB(z, 0x2)]; + skey->cast5.K[i++] = S5[GB(z, 0x5)] ^ S6[GB(z, 0x4)] ^ S7[GB(z, 0xa)] ^ S8[GB(z, 0xb)] ^ S8[GB(z, 0x6)]; + + x[3] = z[1] ^ S5[GB(z, 0x5)] ^ S6[GB(z, 0x7)] ^ S7[GB(z, 0x4)] ^ S8[GB(z, 0x6)] ^ S7[GB(z, 0x0)]; + x[2] = z[3] ^ S5[GB(x, 0x0)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x3)] ^ S8[GB(z, 0x2)]; + x[1] = z[2] ^ S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S5[GB(z, 0x1)]; + x[0] = z[0] ^ S5[GB(x, 0xA)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0xb)] ^ S8[GB(x, 0x8)] ^ S6[GB(z, 0x3)]; + skey->cast5.K[i++] = S5[GB(x, 0x8)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0x7)] ^ S8[GB(x, 0x6)] ^ S5[GB(x, 0x3)]; + skey->cast5.K[i++] = S5[GB(x, 0xa)] ^ S6[GB(x, 0xb)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S6[GB(x, 0x7)]; + skey->cast5.K[i++] = S5[GB(x, 0xc)] ^ S6[GB(x, 0xd)] ^ S7[GB(x, 0x3)] ^ S8[GB(x, 0x2)] ^ S7[GB(x, 0x8)]; + skey->cast5.K[i++] = S5[GB(x, 0xe)] ^ S6[GB(x, 0xf)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x0)] ^ S8[GB(x, 0xd)]; + } + + skey->cast5.keylen = keylen; + +#ifdef LTC_CLEAN_STACK + zeromem(buf, sizeof(buf)); + zeromem(x, sizeof(x)); + zeromem(z, sizeof(z)); +#endif + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int z; + z = _cast5_setup(key, keylen, num_rounds, skey); + burn_stack(sizeof(ulong32)*8 + 16 + sizeof(int)*2); + return z; +} +#endif + +#ifdef _MSC_VER + #define INLINE __inline +#else + #define INLINE +#endif + +INLINE static ulong32 FI(ulong32 R, ulong32 Km, ulong32 Kr) +{ + ulong32 I; + I = (Km + R); + I = ROL(I, Kr); + return ((S1[byte(I, 3)] ^ S2[byte(I,2)]) - S3[byte(I,1)]) + S4[byte(I,0)]; +} + +INLINE static ulong32 FII(ulong32 R, ulong32 Km, ulong32 Kr) +{ + ulong32 I; + I = (Km ^ R); + I = ROL(I, Kr); + return ((S1[byte(I, 3)] - S2[byte(I,2)]) + S3[byte(I,1)]) ^ S4[byte(I,0)]; +} + +INLINE static ulong32 FIII(ulong32 R, ulong32 Km, ulong32 Kr) +{ + ulong32 I; + I = (Km - R); + I = ROL(I, Kr); + return ((S1[byte(I, 3)] + S2[byte(I,2)]) ^ S3[byte(I,1)]) - S4[byte(I,0)]; +} + +/** + Encrypts a block of text with LTC_CAST5 + @param pt The input plaintext (8 bytes) + @param ct The output ciphertext (8 bytes) + @param skey The key as scheduled +*/ +#ifdef LTC_CLEAN_STACK +static int _cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#else +int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#endif +{ + ulong32 R, L; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + LOAD32H(L,&pt[0]); + LOAD32H(R,&pt[4]); + L ^= FI(R, skey->cast5.K[0], skey->cast5.K[16]); + R ^= FII(L, skey->cast5.K[1], skey->cast5.K[17]); + L ^= FIII(R, skey->cast5.K[2], skey->cast5.K[18]); + R ^= FI(L, skey->cast5.K[3], skey->cast5.K[19]); + L ^= FII(R, skey->cast5.K[4], skey->cast5.K[20]); + R ^= FIII(L, skey->cast5.K[5], skey->cast5.K[21]); + L ^= FI(R, skey->cast5.K[6], skey->cast5.K[22]); + R ^= FII(L, skey->cast5.K[7], skey->cast5.K[23]); + L ^= FIII(R, skey->cast5.K[8], skey->cast5.K[24]); + R ^= FI(L, skey->cast5.K[9], skey->cast5.K[25]); + L ^= FII(R, skey->cast5.K[10], skey->cast5.K[26]); + R ^= FIII(L, skey->cast5.K[11], skey->cast5.K[27]); + if (skey->cast5.keylen > 10) { + L ^= FI(R, skey->cast5.K[12], skey->cast5.K[28]); + R ^= FII(L, skey->cast5.K[13], skey->cast5.K[29]); + L ^= FIII(R, skey->cast5.K[14], skey->cast5.K[30]); + R ^= FI(L, skey->cast5.K[15], skey->cast5.K[31]); + } + STORE32H(R,&ct[0]); + STORE32H(L,&ct[4]); + return CRYPT_OK; +} + + +#ifdef LTC_CLEAN_STACK +int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + int err =_cast5_ecb_encrypt(pt,ct,skey); + burn_stack(sizeof(ulong32)*3); + return err; +} +#endif + +/** + Decrypts a block of text with LTC_CAST5 + @param ct The input ciphertext (8 bytes) + @param pt The output plaintext (8 bytes) + @param skey The key as scheduled +*/ +#ifdef LTC_CLEAN_STACK +static int _cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#else +int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#endif +{ + ulong32 R, L; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + LOAD32H(R,&ct[0]); + LOAD32H(L,&ct[4]); + if (skey->cast5.keylen > 10) { + R ^= FI(L, skey->cast5.K[15], skey->cast5.K[31]); + L ^= FIII(R, skey->cast5.K[14], skey->cast5.K[30]); + R ^= FII(L, skey->cast5.K[13], skey->cast5.K[29]); + L ^= FI(R, skey->cast5.K[12], skey->cast5.K[28]); + } + R ^= FIII(L, skey->cast5.K[11], skey->cast5.K[27]); + L ^= FII(R, skey->cast5.K[10], skey->cast5.K[26]); + R ^= FI(L, skey->cast5.K[9], skey->cast5.K[25]); + L ^= FIII(R, skey->cast5.K[8], skey->cast5.K[24]); + R ^= FII(L, skey->cast5.K[7], skey->cast5.K[23]); + L ^= FI(R, skey->cast5.K[6], skey->cast5.K[22]); + R ^= FIII(L, skey->cast5.K[5], skey->cast5.K[21]); + L ^= FII(R, skey->cast5.K[4], skey->cast5.K[20]); + R ^= FI(L, skey->cast5.K[3], skey->cast5.K[19]); + L ^= FIII(R, skey->cast5.K[2], skey->cast5.K[18]); + R ^= FII(L, skey->cast5.K[1], skey->cast5.K[17]); + L ^= FI(R, skey->cast5.K[0], skey->cast5.K[16]); + STORE32H(L,&pt[0]); + STORE32H(R,&pt[4]); + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + int err = _cast5_ecb_decrypt(ct,pt,skey); + burn_stack(sizeof(ulong32)*3); + return err; +} +#endif + +/** + Performs a self-test of the LTC_CAST5 block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int cast5_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen; + unsigned char key[16]; + unsigned char pt[8]; + unsigned char ct[8]; + } tests[] = { + { 16, + {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2} + }, + { 10, + {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0xEB, 0x6A, 0x71, 0x1A, 0x2C, 0x02, 0x27, 0x1B}, + }, + { 5, + {0x01, 0x23, 0x45, 0x67, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x7A, 0xC8, 0x16, 0xD1, 0x6E, 0x9B, 0x30, 0x2E} + } + }; + int i, y, err; + symmetric_key key; + unsigned char tmp[2][8]; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + if ((err = cast5_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { + return err; + } + cast5_ecb_encrypt(tests[i].pt, tmp[0], &key); + cast5_ecb_decrypt(tmp[0], tmp[1], &key); + if ((XMEMCMP(tmp[0], tests[i].ct, 8) != 0) || (XMEMCMP(tmp[1], tests[i].pt, 8) != 0)) { + return CRYPT_FAIL_TESTVECTOR; + } + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) cast5_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) cast5_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + + } + return CRYPT_OK; + #endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void cast5_done(symmetric_key *skey) +{ +} + +/** + Gets suitable key size + @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. + @return CRYPT_OK if the input key size is acceptable. +*/ +int cast5_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize < 5) { + return CRYPT_INVALID_KEYSIZE; + } else if (*keysize > 16) { + *keysize = 16; + } + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/cast5.c,v $ */ +/* $Revision: 1.14 $ */ +/* $Date: 2007/05/12 14:13:00 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/des.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/des.c new file mode 100644 index 0000000000..6c8eef95e4 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/des.c @@ -0,0 +1,1902 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file des.c + LTC_DES code submitted by Dobes Vandermeer +*/ + +#ifdef LTC_DES + +#define EN0 0 +#define DE1 1 + +const struct ltc_cipher_descriptor des_desc = +{ + "des", + 13, + 8, 8, 8, 16, + &des_setup, + &des_ecb_encrypt, + &des_ecb_decrypt, + &des_test, + &des_done, + &des_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +const struct ltc_cipher_descriptor des3_desc = +{ + "3des", + 14, + 24, 24, 8, 16, + &des3_setup, + &des3_ecb_encrypt, + &des3_ecb_decrypt, + &des3_test, + &des3_done, + &des3_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +static const ulong32 bytebit[8] = +{ + 0200, 0100, 040, 020, 010, 04, 02, 01 +}; + +static const ulong32 bigbyte[24] = +{ + 0x800000UL, 0x400000UL, 0x200000UL, 0x100000UL, + 0x80000UL, 0x40000UL, 0x20000UL, 0x10000UL, + 0x8000UL, 0x4000UL, 0x2000UL, 0x1000UL, + 0x800UL, 0x400UL, 0x200UL, 0x100UL, + 0x80UL, 0x40UL, 0x20UL, 0x10UL, + 0x8UL, 0x4UL, 0x2UL, 0x1L +}; + +/* Use the key schedule specific in the standard (ANSI X3.92-1981) */ + +static const unsigned char pc1[56] = { + 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, + 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, + 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, + 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 +}; + +static const unsigned char totrot[16] = { + 1, 2, 4, 6, + 8, 10, 12, 14, + 15, 17, 19, 21, + 23, 25, 27, 28 +}; + +static const unsigned char pc2[48] = { + 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, + 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, + 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, + 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 +}; + + +static const ulong32 SP1[64] = +{ + 0x01010400UL, 0x00000000UL, 0x00010000UL, 0x01010404UL, + 0x01010004UL, 0x00010404UL, 0x00000004UL, 0x00010000UL, + 0x00000400UL, 0x01010400UL, 0x01010404UL, 0x00000400UL, + 0x01000404UL, 0x01010004UL, 0x01000000UL, 0x00000004UL, + 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00010400UL, + 0x00010400UL, 0x01010000UL, 0x01010000UL, 0x01000404UL, + 0x00010004UL, 0x01000004UL, 0x01000004UL, 0x00010004UL, + 0x00000000UL, 0x00000404UL, 0x00010404UL, 0x01000000UL, + 0x00010000UL, 0x01010404UL, 0x00000004UL, 0x01010000UL, + 0x01010400UL, 0x01000000UL, 0x01000000UL, 0x00000400UL, + 0x01010004UL, 0x00010000UL, 0x00010400UL, 0x01000004UL, + 0x00000400UL, 0x00000004UL, 0x01000404UL, 0x00010404UL, + 0x01010404UL, 0x00010004UL, 0x01010000UL, 0x01000404UL, + 0x01000004UL, 0x00000404UL, 0x00010404UL, 0x01010400UL, + 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00000000UL, + 0x00010004UL, 0x00010400UL, 0x00000000UL, 0x01010004UL +}; + +static const ulong32 SP2[64] = +{ + 0x80108020UL, 0x80008000UL, 0x00008000UL, 0x00108020UL, + 0x00100000UL, 0x00000020UL, 0x80100020UL, 0x80008020UL, + 0x80000020UL, 0x80108020UL, 0x80108000UL, 0x80000000UL, + 0x80008000UL, 0x00100000UL, 0x00000020UL, 0x80100020UL, + 0x00108000UL, 0x00100020UL, 0x80008020UL, 0x00000000UL, + 0x80000000UL, 0x00008000UL, 0x00108020UL, 0x80100000UL, + 0x00100020UL, 0x80000020UL, 0x00000000UL, 0x00108000UL, + 0x00008020UL, 0x80108000UL, 0x80100000UL, 0x00008020UL, + 0x00000000UL, 0x00108020UL, 0x80100020UL, 0x00100000UL, + 0x80008020UL, 0x80100000UL, 0x80108000UL, 0x00008000UL, + 0x80100000UL, 0x80008000UL, 0x00000020UL, 0x80108020UL, + 0x00108020UL, 0x00000020UL, 0x00008000UL, 0x80000000UL, + 0x00008020UL, 0x80108000UL, 0x00100000UL, 0x80000020UL, + 0x00100020UL, 0x80008020UL, 0x80000020UL, 0x00100020UL, + 0x00108000UL, 0x00000000UL, 0x80008000UL, 0x00008020UL, + 0x80000000UL, 0x80100020UL, 0x80108020UL, 0x00108000UL +}; + +static const ulong32 SP3[64] = +{ + 0x00000208UL, 0x08020200UL, 0x00000000UL, 0x08020008UL, + 0x08000200UL, 0x00000000UL, 0x00020208UL, 0x08000200UL, + 0x00020008UL, 0x08000008UL, 0x08000008UL, 0x00020000UL, + 0x08020208UL, 0x00020008UL, 0x08020000UL, 0x00000208UL, + 0x08000000UL, 0x00000008UL, 0x08020200UL, 0x00000200UL, + 0x00020200UL, 0x08020000UL, 0x08020008UL, 0x00020208UL, + 0x08000208UL, 0x00020200UL, 0x00020000UL, 0x08000208UL, + 0x00000008UL, 0x08020208UL, 0x00000200UL, 0x08000000UL, + 0x08020200UL, 0x08000000UL, 0x00020008UL, 0x00000208UL, + 0x00020000UL, 0x08020200UL, 0x08000200UL, 0x00000000UL, + 0x00000200UL, 0x00020008UL, 0x08020208UL, 0x08000200UL, + 0x08000008UL, 0x00000200UL, 0x00000000UL, 0x08020008UL, + 0x08000208UL, 0x00020000UL, 0x08000000UL, 0x08020208UL, + 0x00000008UL, 0x00020208UL, 0x00020200UL, 0x08000008UL, + 0x08020000UL, 0x08000208UL, 0x00000208UL, 0x08020000UL, + 0x00020208UL, 0x00000008UL, 0x08020008UL, 0x00020200UL +}; + +static const ulong32 SP4[64] = +{ + 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL, + 0x00802080UL, 0x00800081UL, 0x00800001UL, 0x00002001UL, + 0x00000000UL, 0x00802000UL, 0x00802000UL, 0x00802081UL, + 0x00000081UL, 0x00000000UL, 0x00800080UL, 0x00800001UL, + 0x00000001UL, 0x00002000UL, 0x00800000UL, 0x00802001UL, + 0x00000080UL, 0x00800000UL, 0x00002001UL, 0x00002080UL, + 0x00800081UL, 0x00000001UL, 0x00002080UL, 0x00800080UL, + 0x00002000UL, 0x00802080UL, 0x00802081UL, 0x00000081UL, + 0x00800080UL, 0x00800001UL, 0x00802000UL, 0x00802081UL, + 0x00000081UL, 0x00000000UL, 0x00000000UL, 0x00802000UL, + 0x00002080UL, 0x00800080UL, 0x00800081UL, 0x00000001UL, + 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL, + 0x00802081UL, 0x00000081UL, 0x00000001UL, 0x00002000UL, + 0x00800001UL, 0x00002001UL, 0x00802080UL, 0x00800081UL, + 0x00002001UL, 0x00002080UL, 0x00800000UL, 0x00802001UL, + 0x00000080UL, 0x00800000UL, 0x00002000UL, 0x00802080UL +}; + +static const ulong32 SP5[64] = +{ + 0x00000100UL, 0x02080100UL, 0x02080000UL, 0x42000100UL, + 0x00080000UL, 0x00000100UL, 0x40000000UL, 0x02080000UL, + 0x40080100UL, 0x00080000UL, 0x02000100UL, 0x40080100UL, + 0x42000100UL, 0x42080000UL, 0x00080100UL, 0x40000000UL, + 0x02000000UL, 0x40080000UL, 0x40080000UL, 0x00000000UL, + 0x40000100UL, 0x42080100UL, 0x42080100UL, 0x02000100UL, + 0x42080000UL, 0x40000100UL, 0x00000000UL, 0x42000000UL, + 0x02080100UL, 0x02000000UL, 0x42000000UL, 0x00080100UL, + 0x00080000UL, 0x42000100UL, 0x00000100UL, 0x02000000UL, + 0x40000000UL, 0x02080000UL, 0x42000100UL, 0x40080100UL, + 0x02000100UL, 0x40000000UL, 0x42080000UL, 0x02080100UL, + 0x40080100UL, 0x00000100UL, 0x02000000UL, 0x42080000UL, + 0x42080100UL, 0x00080100UL, 0x42000000UL, 0x42080100UL, + 0x02080000UL, 0x00000000UL, 0x40080000UL, 0x42000000UL, + 0x00080100UL, 0x02000100UL, 0x40000100UL, 0x00080000UL, + 0x00000000UL, 0x40080000UL, 0x02080100UL, 0x40000100UL +}; + +static const ulong32 SP6[64] = +{ + 0x20000010UL, 0x20400000UL, 0x00004000UL, 0x20404010UL, + 0x20400000UL, 0x00000010UL, 0x20404010UL, 0x00400000UL, + 0x20004000UL, 0x00404010UL, 0x00400000UL, 0x20000010UL, + 0x00400010UL, 0x20004000UL, 0x20000000UL, 0x00004010UL, + 0x00000000UL, 0x00400010UL, 0x20004010UL, 0x00004000UL, + 0x00404000UL, 0x20004010UL, 0x00000010UL, 0x20400010UL, + 0x20400010UL, 0x00000000UL, 0x00404010UL, 0x20404000UL, + 0x00004010UL, 0x00404000UL, 0x20404000UL, 0x20000000UL, + 0x20004000UL, 0x00000010UL, 0x20400010UL, 0x00404000UL, + 0x20404010UL, 0x00400000UL, 0x00004010UL, 0x20000010UL, + 0x00400000UL, 0x20004000UL, 0x20000000UL, 0x00004010UL, + 0x20000010UL, 0x20404010UL, 0x00404000UL, 0x20400000UL, + 0x00404010UL, 0x20404000UL, 0x00000000UL, 0x20400010UL, + 0x00000010UL, 0x00004000UL, 0x20400000UL, 0x00404010UL, + 0x00004000UL, 0x00400010UL, 0x20004010UL, 0x00000000UL, + 0x20404000UL, 0x20000000UL, 0x00400010UL, 0x20004010UL +}; + +static const ulong32 SP7[64] = +{ + 0x00200000UL, 0x04200002UL, 0x04000802UL, 0x00000000UL, + 0x00000800UL, 0x04000802UL, 0x00200802UL, 0x04200800UL, + 0x04200802UL, 0x00200000UL, 0x00000000UL, 0x04000002UL, + 0x00000002UL, 0x04000000UL, 0x04200002UL, 0x00000802UL, + 0x04000800UL, 0x00200802UL, 0x00200002UL, 0x04000800UL, + 0x04000002UL, 0x04200000UL, 0x04200800UL, 0x00200002UL, + 0x04200000UL, 0x00000800UL, 0x00000802UL, 0x04200802UL, + 0x00200800UL, 0x00000002UL, 0x04000000UL, 0x00200800UL, + 0x04000000UL, 0x00200800UL, 0x00200000UL, 0x04000802UL, + 0x04000802UL, 0x04200002UL, 0x04200002UL, 0x00000002UL, + 0x00200002UL, 0x04000000UL, 0x04000800UL, 0x00200000UL, + 0x04200800UL, 0x00000802UL, 0x00200802UL, 0x04200800UL, + 0x00000802UL, 0x04000002UL, 0x04200802UL, 0x04200000UL, + 0x00200800UL, 0x00000000UL, 0x00000002UL, 0x04200802UL, + 0x00000000UL, 0x00200802UL, 0x04200000UL, 0x00000800UL, + 0x04000002UL, 0x04000800UL, 0x00000800UL, 0x00200002UL +}; + +static const ulong32 SP8[64] = +{ + 0x10001040UL, 0x00001000UL, 0x00040000UL, 0x10041040UL, + 0x10000000UL, 0x10001040UL, 0x00000040UL, 0x10000000UL, + 0x00040040UL, 0x10040000UL, 0x10041040UL, 0x00041000UL, + 0x10041000UL, 0x00041040UL, 0x00001000UL, 0x00000040UL, + 0x10040000UL, 0x10000040UL, 0x10001000UL, 0x00001040UL, + 0x00041000UL, 0x00040040UL, 0x10040040UL, 0x10041000UL, + 0x00001040UL, 0x00000000UL, 0x00000000UL, 0x10040040UL, + 0x10000040UL, 0x10001000UL, 0x00041040UL, 0x00040000UL, + 0x00041040UL, 0x00040000UL, 0x10041000UL, 0x00001000UL, + 0x00000040UL, 0x10040040UL, 0x00001000UL, 0x00041040UL, + 0x10001000UL, 0x00000040UL, 0x10000040UL, 0x10040000UL, + 0x10040040UL, 0x10000000UL, 0x00040000UL, 0x10001040UL, + 0x00000000UL, 0x10041040UL, 0x00040040UL, 0x10000040UL, + 0x10040000UL, 0x10001000UL, 0x10001040UL, 0x00000000UL, + 0x10041040UL, 0x00041000UL, 0x00041000UL, 0x00001040UL, + 0x00001040UL, 0x00040040UL, 0x10000000UL, 0x10041000UL +}; + +#ifndef LTC_SMALL_CODE + +static const ulong64 des_ip[8][256] = { + +{ CONST64(0x0000000000000000), CONST64(0x0000001000000000), CONST64(0x0000000000000010), CONST64(0x0000001000000010), + CONST64(0x0000100000000000), CONST64(0x0000101000000000), CONST64(0x0000100000000010), CONST64(0x0000101000000010), + CONST64(0x0000000000001000), CONST64(0x0000001000001000), CONST64(0x0000000000001010), CONST64(0x0000001000001010), + CONST64(0x0000100000001000), CONST64(0x0000101000001000), CONST64(0x0000100000001010), CONST64(0x0000101000001010), + CONST64(0x0010000000000000), CONST64(0x0010001000000000), CONST64(0x0010000000000010), CONST64(0x0010001000000010), + CONST64(0x0010100000000000), CONST64(0x0010101000000000), CONST64(0x0010100000000010), CONST64(0x0010101000000010), + CONST64(0x0010000000001000), CONST64(0x0010001000001000), CONST64(0x0010000000001010), CONST64(0x0010001000001010), + CONST64(0x0010100000001000), CONST64(0x0010101000001000), CONST64(0x0010100000001010), CONST64(0x0010101000001010), + CONST64(0x0000000000100000), CONST64(0x0000001000100000), CONST64(0x0000000000100010), CONST64(0x0000001000100010), + CONST64(0x0000100000100000), CONST64(0x0000101000100000), CONST64(0x0000100000100010), CONST64(0x0000101000100010), + CONST64(0x0000000000101000), CONST64(0x0000001000101000), CONST64(0x0000000000101010), CONST64(0x0000001000101010), + CONST64(0x0000100000101000), CONST64(0x0000101000101000), CONST64(0x0000100000101010), CONST64(0x0000101000101010), + CONST64(0x0010000000100000), CONST64(0x0010001000100000), CONST64(0x0010000000100010), CONST64(0x0010001000100010), + CONST64(0x0010100000100000), CONST64(0x0010101000100000), CONST64(0x0010100000100010), CONST64(0x0010101000100010), + CONST64(0x0010000000101000), CONST64(0x0010001000101000), CONST64(0x0010000000101010), CONST64(0x0010001000101010), + CONST64(0x0010100000101000), CONST64(0x0010101000101000), CONST64(0x0010100000101010), CONST64(0x0010101000101010), + CONST64(0x1000000000000000), CONST64(0x1000001000000000), CONST64(0x1000000000000010), CONST64(0x1000001000000010), + CONST64(0x1000100000000000), CONST64(0x1000101000000000), CONST64(0x1000100000000010), CONST64(0x1000101000000010), + CONST64(0x1000000000001000), CONST64(0x1000001000001000), CONST64(0x1000000000001010), CONST64(0x1000001000001010), + CONST64(0x1000100000001000), CONST64(0x1000101000001000), CONST64(0x1000100000001010), CONST64(0x1000101000001010), + CONST64(0x1010000000000000), CONST64(0x1010001000000000), CONST64(0x1010000000000010), CONST64(0x1010001000000010), + CONST64(0x1010100000000000), CONST64(0x1010101000000000), CONST64(0x1010100000000010), CONST64(0x1010101000000010), + CONST64(0x1010000000001000), CONST64(0x1010001000001000), CONST64(0x1010000000001010), CONST64(0x1010001000001010), + CONST64(0x1010100000001000), CONST64(0x1010101000001000), CONST64(0x1010100000001010), CONST64(0x1010101000001010), + CONST64(0x1000000000100000), CONST64(0x1000001000100000), CONST64(0x1000000000100010), CONST64(0x1000001000100010), + CONST64(0x1000100000100000), CONST64(0x1000101000100000), CONST64(0x1000100000100010), CONST64(0x1000101000100010), + CONST64(0x1000000000101000), CONST64(0x1000001000101000), CONST64(0x1000000000101010), CONST64(0x1000001000101010), + CONST64(0x1000100000101000), CONST64(0x1000101000101000), CONST64(0x1000100000101010), CONST64(0x1000101000101010), + CONST64(0x1010000000100000), CONST64(0x1010001000100000), CONST64(0x1010000000100010), CONST64(0x1010001000100010), + CONST64(0x1010100000100000), CONST64(0x1010101000100000), CONST64(0x1010100000100010), CONST64(0x1010101000100010), + CONST64(0x1010000000101000), CONST64(0x1010001000101000), CONST64(0x1010000000101010), CONST64(0x1010001000101010), + CONST64(0x1010100000101000), CONST64(0x1010101000101000), CONST64(0x1010100000101010), CONST64(0x1010101000101010), + CONST64(0x0000000010000000), CONST64(0x0000001010000000), CONST64(0x0000000010000010), CONST64(0x0000001010000010), + CONST64(0x0000100010000000), CONST64(0x0000101010000000), CONST64(0x0000100010000010), CONST64(0x0000101010000010), + CONST64(0x0000000010001000), CONST64(0x0000001010001000), CONST64(0x0000000010001010), CONST64(0x0000001010001010), + CONST64(0x0000100010001000), CONST64(0x0000101010001000), CONST64(0x0000100010001010), CONST64(0x0000101010001010), + CONST64(0x0010000010000000), CONST64(0x0010001010000000), CONST64(0x0010000010000010), CONST64(0x0010001010000010), + CONST64(0x0010100010000000), CONST64(0x0010101010000000), CONST64(0x0010100010000010), CONST64(0x0010101010000010), + CONST64(0x0010000010001000), CONST64(0x0010001010001000), CONST64(0x0010000010001010), CONST64(0x0010001010001010), + CONST64(0x0010100010001000), CONST64(0x0010101010001000), CONST64(0x0010100010001010), CONST64(0x0010101010001010), + CONST64(0x0000000010100000), CONST64(0x0000001010100000), CONST64(0x0000000010100010), CONST64(0x0000001010100010), + CONST64(0x0000100010100000), CONST64(0x0000101010100000), CONST64(0x0000100010100010), CONST64(0x0000101010100010), + CONST64(0x0000000010101000), CONST64(0x0000001010101000), CONST64(0x0000000010101010), CONST64(0x0000001010101010), + CONST64(0x0000100010101000), CONST64(0x0000101010101000), CONST64(0x0000100010101010), CONST64(0x0000101010101010), + CONST64(0x0010000010100000), CONST64(0x0010001010100000), CONST64(0x0010000010100010), CONST64(0x0010001010100010), + CONST64(0x0010100010100000), CONST64(0x0010101010100000), CONST64(0x0010100010100010), CONST64(0x0010101010100010), + CONST64(0x0010000010101000), CONST64(0x0010001010101000), CONST64(0x0010000010101010), CONST64(0x0010001010101010), + CONST64(0x0010100010101000), CONST64(0x0010101010101000), CONST64(0x0010100010101010), CONST64(0x0010101010101010), + CONST64(0x1000000010000000), CONST64(0x1000001010000000), CONST64(0x1000000010000010), CONST64(0x1000001010000010), + CONST64(0x1000100010000000), CONST64(0x1000101010000000), CONST64(0x1000100010000010), CONST64(0x1000101010000010), + CONST64(0x1000000010001000), CONST64(0x1000001010001000), CONST64(0x1000000010001010), CONST64(0x1000001010001010), + CONST64(0x1000100010001000), CONST64(0x1000101010001000), CONST64(0x1000100010001010), CONST64(0x1000101010001010), + CONST64(0x1010000010000000), CONST64(0x1010001010000000), CONST64(0x1010000010000010), CONST64(0x1010001010000010), + CONST64(0x1010100010000000), CONST64(0x1010101010000000), CONST64(0x1010100010000010), CONST64(0x1010101010000010), + CONST64(0x1010000010001000), CONST64(0x1010001010001000), CONST64(0x1010000010001010), CONST64(0x1010001010001010), + CONST64(0x1010100010001000), CONST64(0x1010101010001000), CONST64(0x1010100010001010), CONST64(0x1010101010001010), + CONST64(0x1000000010100000), CONST64(0x1000001010100000), CONST64(0x1000000010100010), CONST64(0x1000001010100010), + CONST64(0x1000100010100000), CONST64(0x1000101010100000), CONST64(0x1000100010100010), CONST64(0x1000101010100010), + CONST64(0x1000000010101000), CONST64(0x1000001010101000), CONST64(0x1000000010101010), CONST64(0x1000001010101010), + CONST64(0x1000100010101000), CONST64(0x1000101010101000), CONST64(0x1000100010101010), CONST64(0x1000101010101010), + CONST64(0x1010000010100000), CONST64(0x1010001010100000), CONST64(0x1010000010100010), CONST64(0x1010001010100010), + CONST64(0x1010100010100000), CONST64(0x1010101010100000), CONST64(0x1010100010100010), CONST64(0x1010101010100010), + CONST64(0x1010000010101000), CONST64(0x1010001010101000), CONST64(0x1010000010101010), CONST64(0x1010001010101010), + CONST64(0x1010100010101000), CONST64(0x1010101010101000), CONST64(0x1010100010101010), CONST64(0x1010101010101010) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000800000000), CONST64(0x0000000000000008), CONST64(0x0000000800000008), + CONST64(0x0000080000000000), CONST64(0x0000080800000000), CONST64(0x0000080000000008), CONST64(0x0000080800000008), + CONST64(0x0000000000000800), CONST64(0x0000000800000800), CONST64(0x0000000000000808), CONST64(0x0000000800000808), + CONST64(0x0000080000000800), CONST64(0x0000080800000800), CONST64(0x0000080000000808), CONST64(0x0000080800000808), + CONST64(0x0008000000000000), CONST64(0x0008000800000000), CONST64(0x0008000000000008), CONST64(0x0008000800000008), + CONST64(0x0008080000000000), CONST64(0x0008080800000000), CONST64(0x0008080000000008), CONST64(0x0008080800000008), + CONST64(0x0008000000000800), CONST64(0x0008000800000800), CONST64(0x0008000000000808), CONST64(0x0008000800000808), + CONST64(0x0008080000000800), CONST64(0x0008080800000800), CONST64(0x0008080000000808), CONST64(0x0008080800000808), + CONST64(0x0000000000080000), CONST64(0x0000000800080000), CONST64(0x0000000000080008), CONST64(0x0000000800080008), + CONST64(0x0000080000080000), CONST64(0x0000080800080000), CONST64(0x0000080000080008), CONST64(0x0000080800080008), + CONST64(0x0000000000080800), CONST64(0x0000000800080800), CONST64(0x0000000000080808), CONST64(0x0000000800080808), + CONST64(0x0000080000080800), CONST64(0x0000080800080800), CONST64(0x0000080000080808), CONST64(0x0000080800080808), + CONST64(0x0008000000080000), CONST64(0x0008000800080000), CONST64(0x0008000000080008), CONST64(0x0008000800080008), + CONST64(0x0008080000080000), CONST64(0x0008080800080000), CONST64(0x0008080000080008), CONST64(0x0008080800080008), + CONST64(0x0008000000080800), CONST64(0x0008000800080800), CONST64(0x0008000000080808), CONST64(0x0008000800080808), + CONST64(0x0008080000080800), CONST64(0x0008080800080800), CONST64(0x0008080000080808), CONST64(0x0008080800080808), + CONST64(0x0800000000000000), CONST64(0x0800000800000000), CONST64(0x0800000000000008), CONST64(0x0800000800000008), + CONST64(0x0800080000000000), CONST64(0x0800080800000000), CONST64(0x0800080000000008), CONST64(0x0800080800000008), + CONST64(0x0800000000000800), CONST64(0x0800000800000800), CONST64(0x0800000000000808), CONST64(0x0800000800000808), + CONST64(0x0800080000000800), CONST64(0x0800080800000800), CONST64(0x0800080000000808), CONST64(0x0800080800000808), + CONST64(0x0808000000000000), CONST64(0x0808000800000000), CONST64(0x0808000000000008), CONST64(0x0808000800000008), + CONST64(0x0808080000000000), CONST64(0x0808080800000000), CONST64(0x0808080000000008), CONST64(0x0808080800000008), + CONST64(0x0808000000000800), CONST64(0x0808000800000800), CONST64(0x0808000000000808), CONST64(0x0808000800000808), + CONST64(0x0808080000000800), CONST64(0x0808080800000800), CONST64(0x0808080000000808), CONST64(0x0808080800000808), + CONST64(0x0800000000080000), CONST64(0x0800000800080000), CONST64(0x0800000000080008), CONST64(0x0800000800080008), + CONST64(0x0800080000080000), CONST64(0x0800080800080000), CONST64(0x0800080000080008), CONST64(0x0800080800080008), + CONST64(0x0800000000080800), CONST64(0x0800000800080800), CONST64(0x0800000000080808), CONST64(0x0800000800080808), + CONST64(0x0800080000080800), CONST64(0x0800080800080800), CONST64(0x0800080000080808), CONST64(0x0800080800080808), + CONST64(0x0808000000080000), CONST64(0x0808000800080000), CONST64(0x0808000000080008), CONST64(0x0808000800080008), + CONST64(0x0808080000080000), CONST64(0x0808080800080000), CONST64(0x0808080000080008), CONST64(0x0808080800080008), + CONST64(0x0808000000080800), CONST64(0x0808000800080800), CONST64(0x0808000000080808), CONST64(0x0808000800080808), + CONST64(0x0808080000080800), CONST64(0x0808080800080800), CONST64(0x0808080000080808), CONST64(0x0808080800080808), + CONST64(0x0000000008000000), CONST64(0x0000000808000000), CONST64(0x0000000008000008), CONST64(0x0000000808000008), + CONST64(0x0000080008000000), CONST64(0x0000080808000000), CONST64(0x0000080008000008), CONST64(0x0000080808000008), + CONST64(0x0000000008000800), CONST64(0x0000000808000800), CONST64(0x0000000008000808), CONST64(0x0000000808000808), + CONST64(0x0000080008000800), CONST64(0x0000080808000800), CONST64(0x0000080008000808), CONST64(0x0000080808000808), + CONST64(0x0008000008000000), CONST64(0x0008000808000000), CONST64(0x0008000008000008), CONST64(0x0008000808000008), + CONST64(0x0008080008000000), CONST64(0x0008080808000000), CONST64(0x0008080008000008), CONST64(0x0008080808000008), + CONST64(0x0008000008000800), CONST64(0x0008000808000800), CONST64(0x0008000008000808), CONST64(0x0008000808000808), + CONST64(0x0008080008000800), CONST64(0x0008080808000800), CONST64(0x0008080008000808), CONST64(0x0008080808000808), + CONST64(0x0000000008080000), CONST64(0x0000000808080000), CONST64(0x0000000008080008), CONST64(0x0000000808080008), + CONST64(0x0000080008080000), CONST64(0x0000080808080000), CONST64(0x0000080008080008), CONST64(0x0000080808080008), + CONST64(0x0000000008080800), CONST64(0x0000000808080800), CONST64(0x0000000008080808), CONST64(0x0000000808080808), + CONST64(0x0000080008080800), CONST64(0x0000080808080800), CONST64(0x0000080008080808), CONST64(0x0000080808080808), + CONST64(0x0008000008080000), CONST64(0x0008000808080000), CONST64(0x0008000008080008), CONST64(0x0008000808080008), + CONST64(0x0008080008080000), CONST64(0x0008080808080000), CONST64(0x0008080008080008), CONST64(0x0008080808080008), + CONST64(0x0008000008080800), CONST64(0x0008000808080800), CONST64(0x0008000008080808), CONST64(0x0008000808080808), + CONST64(0x0008080008080800), CONST64(0x0008080808080800), CONST64(0x0008080008080808), CONST64(0x0008080808080808), + CONST64(0x0800000008000000), CONST64(0x0800000808000000), CONST64(0x0800000008000008), CONST64(0x0800000808000008), + CONST64(0x0800080008000000), CONST64(0x0800080808000000), CONST64(0x0800080008000008), CONST64(0x0800080808000008), + CONST64(0x0800000008000800), CONST64(0x0800000808000800), CONST64(0x0800000008000808), CONST64(0x0800000808000808), + CONST64(0x0800080008000800), CONST64(0x0800080808000800), CONST64(0x0800080008000808), CONST64(0x0800080808000808), + CONST64(0x0808000008000000), CONST64(0x0808000808000000), CONST64(0x0808000008000008), CONST64(0x0808000808000008), + CONST64(0x0808080008000000), CONST64(0x0808080808000000), CONST64(0x0808080008000008), CONST64(0x0808080808000008), + CONST64(0x0808000008000800), CONST64(0x0808000808000800), CONST64(0x0808000008000808), CONST64(0x0808000808000808), + CONST64(0x0808080008000800), CONST64(0x0808080808000800), CONST64(0x0808080008000808), CONST64(0x0808080808000808), + CONST64(0x0800000008080000), CONST64(0x0800000808080000), CONST64(0x0800000008080008), CONST64(0x0800000808080008), + CONST64(0x0800080008080000), CONST64(0x0800080808080000), CONST64(0x0800080008080008), CONST64(0x0800080808080008), + CONST64(0x0800000008080800), CONST64(0x0800000808080800), CONST64(0x0800000008080808), CONST64(0x0800000808080808), + CONST64(0x0800080008080800), CONST64(0x0800080808080800), CONST64(0x0800080008080808), CONST64(0x0800080808080808), + CONST64(0x0808000008080000), CONST64(0x0808000808080000), CONST64(0x0808000008080008), CONST64(0x0808000808080008), + CONST64(0x0808080008080000), CONST64(0x0808080808080000), CONST64(0x0808080008080008), CONST64(0x0808080808080008), + CONST64(0x0808000008080800), CONST64(0x0808000808080800), CONST64(0x0808000008080808), CONST64(0x0808000808080808), + CONST64(0x0808080008080800), CONST64(0x0808080808080800), CONST64(0x0808080008080808), CONST64(0x0808080808080808) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000400000000), CONST64(0x0000000000000004), CONST64(0x0000000400000004), + CONST64(0x0000040000000000), CONST64(0x0000040400000000), CONST64(0x0000040000000004), CONST64(0x0000040400000004), + CONST64(0x0000000000000400), CONST64(0x0000000400000400), CONST64(0x0000000000000404), CONST64(0x0000000400000404), + CONST64(0x0000040000000400), CONST64(0x0000040400000400), CONST64(0x0000040000000404), CONST64(0x0000040400000404), + CONST64(0x0004000000000000), CONST64(0x0004000400000000), CONST64(0x0004000000000004), CONST64(0x0004000400000004), + CONST64(0x0004040000000000), CONST64(0x0004040400000000), CONST64(0x0004040000000004), CONST64(0x0004040400000004), + CONST64(0x0004000000000400), CONST64(0x0004000400000400), CONST64(0x0004000000000404), CONST64(0x0004000400000404), + CONST64(0x0004040000000400), CONST64(0x0004040400000400), CONST64(0x0004040000000404), CONST64(0x0004040400000404), + CONST64(0x0000000000040000), CONST64(0x0000000400040000), CONST64(0x0000000000040004), CONST64(0x0000000400040004), + CONST64(0x0000040000040000), CONST64(0x0000040400040000), CONST64(0x0000040000040004), CONST64(0x0000040400040004), + CONST64(0x0000000000040400), CONST64(0x0000000400040400), CONST64(0x0000000000040404), CONST64(0x0000000400040404), + CONST64(0x0000040000040400), CONST64(0x0000040400040400), CONST64(0x0000040000040404), CONST64(0x0000040400040404), + CONST64(0x0004000000040000), CONST64(0x0004000400040000), CONST64(0x0004000000040004), CONST64(0x0004000400040004), + CONST64(0x0004040000040000), CONST64(0x0004040400040000), CONST64(0x0004040000040004), CONST64(0x0004040400040004), + CONST64(0x0004000000040400), CONST64(0x0004000400040400), CONST64(0x0004000000040404), CONST64(0x0004000400040404), + CONST64(0x0004040000040400), CONST64(0x0004040400040400), CONST64(0x0004040000040404), CONST64(0x0004040400040404), + CONST64(0x0400000000000000), CONST64(0x0400000400000000), CONST64(0x0400000000000004), CONST64(0x0400000400000004), + CONST64(0x0400040000000000), CONST64(0x0400040400000000), CONST64(0x0400040000000004), CONST64(0x0400040400000004), + CONST64(0x0400000000000400), CONST64(0x0400000400000400), CONST64(0x0400000000000404), CONST64(0x0400000400000404), + CONST64(0x0400040000000400), CONST64(0x0400040400000400), CONST64(0x0400040000000404), CONST64(0x0400040400000404), + CONST64(0x0404000000000000), CONST64(0x0404000400000000), CONST64(0x0404000000000004), CONST64(0x0404000400000004), + CONST64(0x0404040000000000), CONST64(0x0404040400000000), CONST64(0x0404040000000004), CONST64(0x0404040400000004), + CONST64(0x0404000000000400), CONST64(0x0404000400000400), CONST64(0x0404000000000404), CONST64(0x0404000400000404), + CONST64(0x0404040000000400), CONST64(0x0404040400000400), CONST64(0x0404040000000404), CONST64(0x0404040400000404), + CONST64(0x0400000000040000), CONST64(0x0400000400040000), CONST64(0x0400000000040004), CONST64(0x0400000400040004), + CONST64(0x0400040000040000), CONST64(0x0400040400040000), CONST64(0x0400040000040004), CONST64(0x0400040400040004), + CONST64(0x0400000000040400), CONST64(0x0400000400040400), CONST64(0x0400000000040404), CONST64(0x0400000400040404), + CONST64(0x0400040000040400), CONST64(0x0400040400040400), CONST64(0x0400040000040404), CONST64(0x0400040400040404), + CONST64(0x0404000000040000), CONST64(0x0404000400040000), CONST64(0x0404000000040004), CONST64(0x0404000400040004), + CONST64(0x0404040000040000), CONST64(0x0404040400040000), CONST64(0x0404040000040004), CONST64(0x0404040400040004), + CONST64(0x0404000000040400), CONST64(0x0404000400040400), CONST64(0x0404000000040404), CONST64(0x0404000400040404), + CONST64(0x0404040000040400), CONST64(0x0404040400040400), CONST64(0x0404040000040404), CONST64(0x0404040400040404), + CONST64(0x0000000004000000), CONST64(0x0000000404000000), CONST64(0x0000000004000004), CONST64(0x0000000404000004), + CONST64(0x0000040004000000), CONST64(0x0000040404000000), CONST64(0x0000040004000004), CONST64(0x0000040404000004), + CONST64(0x0000000004000400), CONST64(0x0000000404000400), CONST64(0x0000000004000404), CONST64(0x0000000404000404), + CONST64(0x0000040004000400), CONST64(0x0000040404000400), CONST64(0x0000040004000404), CONST64(0x0000040404000404), + CONST64(0x0004000004000000), CONST64(0x0004000404000000), CONST64(0x0004000004000004), CONST64(0x0004000404000004), + CONST64(0x0004040004000000), CONST64(0x0004040404000000), CONST64(0x0004040004000004), CONST64(0x0004040404000004), + CONST64(0x0004000004000400), CONST64(0x0004000404000400), CONST64(0x0004000004000404), CONST64(0x0004000404000404), + CONST64(0x0004040004000400), CONST64(0x0004040404000400), CONST64(0x0004040004000404), CONST64(0x0004040404000404), + CONST64(0x0000000004040000), CONST64(0x0000000404040000), CONST64(0x0000000004040004), CONST64(0x0000000404040004), + CONST64(0x0000040004040000), CONST64(0x0000040404040000), CONST64(0x0000040004040004), CONST64(0x0000040404040004), + CONST64(0x0000000004040400), CONST64(0x0000000404040400), CONST64(0x0000000004040404), CONST64(0x0000000404040404), + CONST64(0x0000040004040400), CONST64(0x0000040404040400), CONST64(0x0000040004040404), CONST64(0x0000040404040404), + CONST64(0x0004000004040000), CONST64(0x0004000404040000), CONST64(0x0004000004040004), CONST64(0x0004000404040004), + CONST64(0x0004040004040000), CONST64(0x0004040404040000), CONST64(0x0004040004040004), CONST64(0x0004040404040004), + CONST64(0x0004000004040400), CONST64(0x0004000404040400), CONST64(0x0004000004040404), CONST64(0x0004000404040404), + CONST64(0x0004040004040400), CONST64(0x0004040404040400), CONST64(0x0004040004040404), CONST64(0x0004040404040404), + CONST64(0x0400000004000000), CONST64(0x0400000404000000), CONST64(0x0400000004000004), CONST64(0x0400000404000004), + CONST64(0x0400040004000000), CONST64(0x0400040404000000), CONST64(0x0400040004000004), CONST64(0x0400040404000004), + CONST64(0x0400000004000400), CONST64(0x0400000404000400), CONST64(0x0400000004000404), CONST64(0x0400000404000404), + CONST64(0x0400040004000400), CONST64(0x0400040404000400), CONST64(0x0400040004000404), CONST64(0x0400040404000404), + CONST64(0x0404000004000000), CONST64(0x0404000404000000), CONST64(0x0404000004000004), CONST64(0x0404000404000004), + CONST64(0x0404040004000000), CONST64(0x0404040404000000), CONST64(0x0404040004000004), CONST64(0x0404040404000004), + CONST64(0x0404000004000400), CONST64(0x0404000404000400), CONST64(0x0404000004000404), CONST64(0x0404000404000404), + CONST64(0x0404040004000400), CONST64(0x0404040404000400), CONST64(0x0404040004000404), CONST64(0x0404040404000404), + CONST64(0x0400000004040000), CONST64(0x0400000404040000), CONST64(0x0400000004040004), CONST64(0x0400000404040004), + CONST64(0x0400040004040000), CONST64(0x0400040404040000), CONST64(0x0400040004040004), CONST64(0x0400040404040004), + CONST64(0x0400000004040400), CONST64(0x0400000404040400), CONST64(0x0400000004040404), CONST64(0x0400000404040404), + CONST64(0x0400040004040400), CONST64(0x0400040404040400), CONST64(0x0400040004040404), CONST64(0x0400040404040404), + CONST64(0x0404000004040000), CONST64(0x0404000404040000), CONST64(0x0404000004040004), CONST64(0x0404000404040004), + CONST64(0x0404040004040000), CONST64(0x0404040404040000), CONST64(0x0404040004040004), CONST64(0x0404040404040004), + CONST64(0x0404000004040400), CONST64(0x0404000404040400), CONST64(0x0404000004040404), CONST64(0x0404000404040404), + CONST64(0x0404040004040400), CONST64(0x0404040404040400), CONST64(0x0404040004040404), CONST64(0x0404040404040404) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000200000000), CONST64(0x0000000000000002), CONST64(0x0000000200000002), + CONST64(0x0000020000000000), CONST64(0x0000020200000000), CONST64(0x0000020000000002), CONST64(0x0000020200000002), + CONST64(0x0000000000000200), CONST64(0x0000000200000200), CONST64(0x0000000000000202), CONST64(0x0000000200000202), + CONST64(0x0000020000000200), CONST64(0x0000020200000200), CONST64(0x0000020000000202), CONST64(0x0000020200000202), + CONST64(0x0002000000000000), CONST64(0x0002000200000000), CONST64(0x0002000000000002), CONST64(0x0002000200000002), + CONST64(0x0002020000000000), CONST64(0x0002020200000000), CONST64(0x0002020000000002), CONST64(0x0002020200000002), + CONST64(0x0002000000000200), CONST64(0x0002000200000200), CONST64(0x0002000000000202), CONST64(0x0002000200000202), + CONST64(0x0002020000000200), CONST64(0x0002020200000200), CONST64(0x0002020000000202), CONST64(0x0002020200000202), + CONST64(0x0000000000020000), CONST64(0x0000000200020000), CONST64(0x0000000000020002), CONST64(0x0000000200020002), + CONST64(0x0000020000020000), CONST64(0x0000020200020000), CONST64(0x0000020000020002), CONST64(0x0000020200020002), + CONST64(0x0000000000020200), CONST64(0x0000000200020200), CONST64(0x0000000000020202), CONST64(0x0000000200020202), + CONST64(0x0000020000020200), CONST64(0x0000020200020200), CONST64(0x0000020000020202), CONST64(0x0000020200020202), + CONST64(0x0002000000020000), CONST64(0x0002000200020000), CONST64(0x0002000000020002), CONST64(0x0002000200020002), + CONST64(0x0002020000020000), CONST64(0x0002020200020000), CONST64(0x0002020000020002), CONST64(0x0002020200020002), + CONST64(0x0002000000020200), CONST64(0x0002000200020200), CONST64(0x0002000000020202), CONST64(0x0002000200020202), + CONST64(0x0002020000020200), CONST64(0x0002020200020200), CONST64(0x0002020000020202), CONST64(0x0002020200020202), + CONST64(0x0200000000000000), CONST64(0x0200000200000000), CONST64(0x0200000000000002), CONST64(0x0200000200000002), + CONST64(0x0200020000000000), CONST64(0x0200020200000000), CONST64(0x0200020000000002), CONST64(0x0200020200000002), + CONST64(0x0200000000000200), CONST64(0x0200000200000200), CONST64(0x0200000000000202), CONST64(0x0200000200000202), + CONST64(0x0200020000000200), CONST64(0x0200020200000200), CONST64(0x0200020000000202), CONST64(0x0200020200000202), + CONST64(0x0202000000000000), CONST64(0x0202000200000000), CONST64(0x0202000000000002), CONST64(0x0202000200000002), + CONST64(0x0202020000000000), CONST64(0x0202020200000000), CONST64(0x0202020000000002), CONST64(0x0202020200000002), + CONST64(0x0202000000000200), CONST64(0x0202000200000200), CONST64(0x0202000000000202), CONST64(0x0202000200000202), + CONST64(0x0202020000000200), CONST64(0x0202020200000200), CONST64(0x0202020000000202), CONST64(0x0202020200000202), + CONST64(0x0200000000020000), CONST64(0x0200000200020000), CONST64(0x0200000000020002), CONST64(0x0200000200020002), + CONST64(0x0200020000020000), CONST64(0x0200020200020000), CONST64(0x0200020000020002), CONST64(0x0200020200020002), + CONST64(0x0200000000020200), CONST64(0x0200000200020200), CONST64(0x0200000000020202), CONST64(0x0200000200020202), + CONST64(0x0200020000020200), CONST64(0x0200020200020200), CONST64(0x0200020000020202), CONST64(0x0200020200020202), + CONST64(0x0202000000020000), CONST64(0x0202000200020000), CONST64(0x0202000000020002), CONST64(0x0202000200020002), + CONST64(0x0202020000020000), CONST64(0x0202020200020000), CONST64(0x0202020000020002), CONST64(0x0202020200020002), + CONST64(0x0202000000020200), CONST64(0x0202000200020200), CONST64(0x0202000000020202), CONST64(0x0202000200020202), + CONST64(0x0202020000020200), CONST64(0x0202020200020200), CONST64(0x0202020000020202), CONST64(0x0202020200020202), + CONST64(0x0000000002000000), CONST64(0x0000000202000000), CONST64(0x0000000002000002), CONST64(0x0000000202000002), + CONST64(0x0000020002000000), CONST64(0x0000020202000000), CONST64(0x0000020002000002), CONST64(0x0000020202000002), + CONST64(0x0000000002000200), CONST64(0x0000000202000200), CONST64(0x0000000002000202), CONST64(0x0000000202000202), + CONST64(0x0000020002000200), CONST64(0x0000020202000200), CONST64(0x0000020002000202), CONST64(0x0000020202000202), + CONST64(0x0002000002000000), CONST64(0x0002000202000000), CONST64(0x0002000002000002), CONST64(0x0002000202000002), + CONST64(0x0002020002000000), CONST64(0x0002020202000000), CONST64(0x0002020002000002), CONST64(0x0002020202000002), + CONST64(0x0002000002000200), CONST64(0x0002000202000200), CONST64(0x0002000002000202), CONST64(0x0002000202000202), + CONST64(0x0002020002000200), CONST64(0x0002020202000200), CONST64(0x0002020002000202), CONST64(0x0002020202000202), + CONST64(0x0000000002020000), CONST64(0x0000000202020000), CONST64(0x0000000002020002), CONST64(0x0000000202020002), + CONST64(0x0000020002020000), CONST64(0x0000020202020000), CONST64(0x0000020002020002), CONST64(0x0000020202020002), + CONST64(0x0000000002020200), CONST64(0x0000000202020200), CONST64(0x0000000002020202), CONST64(0x0000000202020202), + CONST64(0x0000020002020200), CONST64(0x0000020202020200), CONST64(0x0000020002020202), CONST64(0x0000020202020202), + CONST64(0x0002000002020000), CONST64(0x0002000202020000), CONST64(0x0002000002020002), CONST64(0x0002000202020002), + CONST64(0x0002020002020000), CONST64(0x0002020202020000), CONST64(0x0002020002020002), CONST64(0x0002020202020002), + CONST64(0x0002000002020200), CONST64(0x0002000202020200), CONST64(0x0002000002020202), CONST64(0x0002000202020202), + CONST64(0x0002020002020200), CONST64(0x0002020202020200), CONST64(0x0002020002020202), CONST64(0x0002020202020202), + CONST64(0x0200000002000000), CONST64(0x0200000202000000), CONST64(0x0200000002000002), CONST64(0x0200000202000002), + CONST64(0x0200020002000000), CONST64(0x0200020202000000), CONST64(0x0200020002000002), CONST64(0x0200020202000002), + CONST64(0x0200000002000200), CONST64(0x0200000202000200), CONST64(0x0200000002000202), CONST64(0x0200000202000202), + CONST64(0x0200020002000200), CONST64(0x0200020202000200), CONST64(0x0200020002000202), CONST64(0x0200020202000202), + CONST64(0x0202000002000000), CONST64(0x0202000202000000), CONST64(0x0202000002000002), CONST64(0x0202000202000002), + CONST64(0x0202020002000000), CONST64(0x0202020202000000), CONST64(0x0202020002000002), CONST64(0x0202020202000002), + CONST64(0x0202000002000200), CONST64(0x0202000202000200), CONST64(0x0202000002000202), CONST64(0x0202000202000202), + CONST64(0x0202020002000200), CONST64(0x0202020202000200), CONST64(0x0202020002000202), CONST64(0x0202020202000202), + CONST64(0x0200000002020000), CONST64(0x0200000202020000), CONST64(0x0200000002020002), CONST64(0x0200000202020002), + CONST64(0x0200020002020000), CONST64(0x0200020202020000), CONST64(0x0200020002020002), CONST64(0x0200020202020002), + CONST64(0x0200000002020200), CONST64(0x0200000202020200), CONST64(0x0200000002020202), CONST64(0x0200000202020202), + CONST64(0x0200020002020200), CONST64(0x0200020202020200), CONST64(0x0200020002020202), CONST64(0x0200020202020202), + CONST64(0x0202000002020000), CONST64(0x0202000202020000), CONST64(0x0202000002020002), CONST64(0x0202000202020002), + CONST64(0x0202020002020000), CONST64(0x0202020202020000), CONST64(0x0202020002020002), CONST64(0x0202020202020002), + CONST64(0x0202000002020200), CONST64(0x0202000202020200), CONST64(0x0202000002020202), CONST64(0x0202000202020202), + CONST64(0x0202020002020200), CONST64(0x0202020202020200), CONST64(0x0202020002020202), CONST64(0x0202020202020202) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000010000000000), CONST64(0x0000000000000100), CONST64(0x0000010000000100), + CONST64(0x0001000000000000), CONST64(0x0001010000000000), CONST64(0x0001000000000100), CONST64(0x0001010000000100), + CONST64(0x0000000000010000), CONST64(0x0000010000010000), CONST64(0x0000000000010100), CONST64(0x0000010000010100), + CONST64(0x0001000000010000), CONST64(0x0001010000010000), CONST64(0x0001000000010100), CONST64(0x0001010000010100), + CONST64(0x0100000000000000), CONST64(0x0100010000000000), CONST64(0x0100000000000100), CONST64(0x0100010000000100), + CONST64(0x0101000000000000), CONST64(0x0101010000000000), CONST64(0x0101000000000100), CONST64(0x0101010000000100), + CONST64(0x0100000000010000), CONST64(0x0100010000010000), CONST64(0x0100000000010100), CONST64(0x0100010000010100), + CONST64(0x0101000000010000), CONST64(0x0101010000010000), CONST64(0x0101000000010100), CONST64(0x0101010000010100), + CONST64(0x0000000001000000), CONST64(0x0000010001000000), CONST64(0x0000000001000100), CONST64(0x0000010001000100), + CONST64(0x0001000001000000), CONST64(0x0001010001000000), CONST64(0x0001000001000100), CONST64(0x0001010001000100), + CONST64(0x0000000001010000), CONST64(0x0000010001010000), CONST64(0x0000000001010100), CONST64(0x0000010001010100), + CONST64(0x0001000001010000), CONST64(0x0001010001010000), CONST64(0x0001000001010100), CONST64(0x0001010001010100), + CONST64(0x0100000001000000), CONST64(0x0100010001000000), CONST64(0x0100000001000100), CONST64(0x0100010001000100), + CONST64(0x0101000001000000), CONST64(0x0101010001000000), CONST64(0x0101000001000100), CONST64(0x0101010001000100), + CONST64(0x0100000001010000), CONST64(0x0100010001010000), CONST64(0x0100000001010100), CONST64(0x0100010001010100), + CONST64(0x0101000001010000), CONST64(0x0101010001010000), CONST64(0x0101000001010100), CONST64(0x0101010001010100), + CONST64(0x0000000100000000), CONST64(0x0000010100000000), CONST64(0x0000000100000100), CONST64(0x0000010100000100), + CONST64(0x0001000100000000), CONST64(0x0001010100000000), CONST64(0x0001000100000100), CONST64(0x0001010100000100), + CONST64(0x0000000100010000), CONST64(0x0000010100010000), CONST64(0x0000000100010100), CONST64(0x0000010100010100), + CONST64(0x0001000100010000), CONST64(0x0001010100010000), CONST64(0x0001000100010100), CONST64(0x0001010100010100), + CONST64(0x0100000100000000), CONST64(0x0100010100000000), CONST64(0x0100000100000100), CONST64(0x0100010100000100), + CONST64(0x0101000100000000), CONST64(0x0101010100000000), CONST64(0x0101000100000100), CONST64(0x0101010100000100), + CONST64(0x0100000100010000), CONST64(0x0100010100010000), CONST64(0x0100000100010100), CONST64(0x0100010100010100), + CONST64(0x0101000100010000), CONST64(0x0101010100010000), CONST64(0x0101000100010100), CONST64(0x0101010100010100), + CONST64(0x0000000101000000), CONST64(0x0000010101000000), CONST64(0x0000000101000100), CONST64(0x0000010101000100), + CONST64(0x0001000101000000), CONST64(0x0001010101000000), CONST64(0x0001000101000100), CONST64(0x0001010101000100), + CONST64(0x0000000101010000), CONST64(0x0000010101010000), CONST64(0x0000000101010100), CONST64(0x0000010101010100), + CONST64(0x0001000101010000), CONST64(0x0001010101010000), CONST64(0x0001000101010100), CONST64(0x0001010101010100), + CONST64(0x0100000101000000), CONST64(0x0100010101000000), CONST64(0x0100000101000100), CONST64(0x0100010101000100), + CONST64(0x0101000101000000), CONST64(0x0101010101000000), CONST64(0x0101000101000100), CONST64(0x0101010101000100), + CONST64(0x0100000101010000), CONST64(0x0100010101010000), CONST64(0x0100000101010100), CONST64(0x0100010101010100), + CONST64(0x0101000101010000), CONST64(0x0101010101010000), CONST64(0x0101000101010100), CONST64(0x0101010101010100), + CONST64(0x0000000000000001), CONST64(0x0000010000000001), CONST64(0x0000000000000101), CONST64(0x0000010000000101), + CONST64(0x0001000000000001), CONST64(0x0001010000000001), CONST64(0x0001000000000101), CONST64(0x0001010000000101), + CONST64(0x0000000000010001), CONST64(0x0000010000010001), CONST64(0x0000000000010101), CONST64(0x0000010000010101), + CONST64(0x0001000000010001), CONST64(0x0001010000010001), CONST64(0x0001000000010101), CONST64(0x0001010000010101), + CONST64(0x0100000000000001), CONST64(0x0100010000000001), CONST64(0x0100000000000101), CONST64(0x0100010000000101), + CONST64(0x0101000000000001), CONST64(0x0101010000000001), CONST64(0x0101000000000101), CONST64(0x0101010000000101), + CONST64(0x0100000000010001), CONST64(0x0100010000010001), CONST64(0x0100000000010101), CONST64(0x0100010000010101), + CONST64(0x0101000000010001), CONST64(0x0101010000010001), CONST64(0x0101000000010101), CONST64(0x0101010000010101), + CONST64(0x0000000001000001), CONST64(0x0000010001000001), CONST64(0x0000000001000101), CONST64(0x0000010001000101), + CONST64(0x0001000001000001), CONST64(0x0001010001000001), CONST64(0x0001000001000101), CONST64(0x0001010001000101), + CONST64(0x0000000001010001), CONST64(0x0000010001010001), CONST64(0x0000000001010101), CONST64(0x0000010001010101), + CONST64(0x0001000001010001), CONST64(0x0001010001010001), CONST64(0x0001000001010101), CONST64(0x0001010001010101), + CONST64(0x0100000001000001), CONST64(0x0100010001000001), CONST64(0x0100000001000101), CONST64(0x0100010001000101), + CONST64(0x0101000001000001), CONST64(0x0101010001000001), CONST64(0x0101000001000101), CONST64(0x0101010001000101), + CONST64(0x0100000001010001), CONST64(0x0100010001010001), CONST64(0x0100000001010101), CONST64(0x0100010001010101), + CONST64(0x0101000001010001), CONST64(0x0101010001010001), CONST64(0x0101000001010101), CONST64(0x0101010001010101), + CONST64(0x0000000100000001), CONST64(0x0000010100000001), CONST64(0x0000000100000101), CONST64(0x0000010100000101), + CONST64(0x0001000100000001), CONST64(0x0001010100000001), CONST64(0x0001000100000101), CONST64(0x0001010100000101), + CONST64(0x0000000100010001), CONST64(0x0000010100010001), CONST64(0x0000000100010101), CONST64(0x0000010100010101), + CONST64(0x0001000100010001), CONST64(0x0001010100010001), CONST64(0x0001000100010101), CONST64(0x0001010100010101), + CONST64(0x0100000100000001), CONST64(0x0100010100000001), CONST64(0x0100000100000101), CONST64(0x0100010100000101), + CONST64(0x0101000100000001), CONST64(0x0101010100000001), CONST64(0x0101000100000101), CONST64(0x0101010100000101), + CONST64(0x0100000100010001), CONST64(0x0100010100010001), CONST64(0x0100000100010101), CONST64(0x0100010100010101), + CONST64(0x0101000100010001), CONST64(0x0101010100010001), CONST64(0x0101000100010101), CONST64(0x0101010100010101), + CONST64(0x0000000101000001), CONST64(0x0000010101000001), CONST64(0x0000000101000101), CONST64(0x0000010101000101), + CONST64(0x0001000101000001), CONST64(0x0001010101000001), CONST64(0x0001000101000101), CONST64(0x0001010101000101), + CONST64(0x0000000101010001), CONST64(0x0000010101010001), CONST64(0x0000000101010101), CONST64(0x0000010101010101), + CONST64(0x0001000101010001), CONST64(0x0001010101010001), CONST64(0x0001000101010101), CONST64(0x0001010101010101), + CONST64(0x0100000101000001), CONST64(0x0100010101000001), CONST64(0x0100000101000101), CONST64(0x0100010101000101), + CONST64(0x0101000101000001), CONST64(0x0101010101000001), CONST64(0x0101000101000101), CONST64(0x0101010101000101), + CONST64(0x0100000101010001), CONST64(0x0100010101010001), CONST64(0x0100000101010101), CONST64(0x0100010101010101), + CONST64(0x0101000101010001), CONST64(0x0101010101010001), CONST64(0x0101000101010101), CONST64(0x0101010101010101) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000008000000000), CONST64(0x0000000000000080), CONST64(0x0000008000000080), + CONST64(0x0000800000000000), CONST64(0x0000808000000000), CONST64(0x0000800000000080), CONST64(0x0000808000000080), + CONST64(0x0000000000008000), CONST64(0x0000008000008000), CONST64(0x0000000000008080), CONST64(0x0000008000008080), + CONST64(0x0000800000008000), CONST64(0x0000808000008000), CONST64(0x0000800000008080), CONST64(0x0000808000008080), + CONST64(0x0080000000000000), CONST64(0x0080008000000000), CONST64(0x0080000000000080), CONST64(0x0080008000000080), + CONST64(0x0080800000000000), CONST64(0x0080808000000000), CONST64(0x0080800000000080), CONST64(0x0080808000000080), + CONST64(0x0080000000008000), CONST64(0x0080008000008000), CONST64(0x0080000000008080), CONST64(0x0080008000008080), + CONST64(0x0080800000008000), CONST64(0x0080808000008000), CONST64(0x0080800000008080), CONST64(0x0080808000008080), + CONST64(0x0000000000800000), CONST64(0x0000008000800000), CONST64(0x0000000000800080), CONST64(0x0000008000800080), + CONST64(0x0000800000800000), CONST64(0x0000808000800000), CONST64(0x0000800000800080), CONST64(0x0000808000800080), + CONST64(0x0000000000808000), CONST64(0x0000008000808000), CONST64(0x0000000000808080), CONST64(0x0000008000808080), + CONST64(0x0000800000808000), CONST64(0x0000808000808000), CONST64(0x0000800000808080), CONST64(0x0000808000808080), + CONST64(0x0080000000800000), CONST64(0x0080008000800000), CONST64(0x0080000000800080), CONST64(0x0080008000800080), + CONST64(0x0080800000800000), CONST64(0x0080808000800000), CONST64(0x0080800000800080), CONST64(0x0080808000800080), + CONST64(0x0080000000808000), CONST64(0x0080008000808000), CONST64(0x0080000000808080), CONST64(0x0080008000808080), + CONST64(0x0080800000808000), CONST64(0x0080808000808000), CONST64(0x0080800000808080), CONST64(0x0080808000808080), + CONST64(0x8000000000000000), CONST64(0x8000008000000000), CONST64(0x8000000000000080), CONST64(0x8000008000000080), + CONST64(0x8000800000000000), CONST64(0x8000808000000000), CONST64(0x8000800000000080), CONST64(0x8000808000000080), + CONST64(0x8000000000008000), CONST64(0x8000008000008000), CONST64(0x8000000000008080), CONST64(0x8000008000008080), + CONST64(0x8000800000008000), CONST64(0x8000808000008000), CONST64(0x8000800000008080), CONST64(0x8000808000008080), + CONST64(0x8080000000000000), CONST64(0x8080008000000000), CONST64(0x8080000000000080), CONST64(0x8080008000000080), + CONST64(0x8080800000000000), CONST64(0x8080808000000000), CONST64(0x8080800000000080), CONST64(0x8080808000000080), + CONST64(0x8080000000008000), CONST64(0x8080008000008000), CONST64(0x8080000000008080), CONST64(0x8080008000008080), + CONST64(0x8080800000008000), CONST64(0x8080808000008000), CONST64(0x8080800000008080), CONST64(0x8080808000008080), + CONST64(0x8000000000800000), CONST64(0x8000008000800000), CONST64(0x8000000000800080), CONST64(0x8000008000800080), + CONST64(0x8000800000800000), CONST64(0x8000808000800000), CONST64(0x8000800000800080), CONST64(0x8000808000800080), + CONST64(0x8000000000808000), CONST64(0x8000008000808000), CONST64(0x8000000000808080), CONST64(0x8000008000808080), + CONST64(0x8000800000808000), CONST64(0x8000808000808000), CONST64(0x8000800000808080), CONST64(0x8000808000808080), + CONST64(0x8080000000800000), CONST64(0x8080008000800000), CONST64(0x8080000000800080), CONST64(0x8080008000800080), + CONST64(0x8080800000800000), CONST64(0x8080808000800000), CONST64(0x8080800000800080), CONST64(0x8080808000800080), + CONST64(0x8080000000808000), CONST64(0x8080008000808000), CONST64(0x8080000000808080), CONST64(0x8080008000808080), + CONST64(0x8080800000808000), CONST64(0x8080808000808000), CONST64(0x8080800000808080), CONST64(0x8080808000808080), + CONST64(0x0000000080000000), CONST64(0x0000008080000000), CONST64(0x0000000080000080), CONST64(0x0000008080000080), + CONST64(0x0000800080000000), CONST64(0x0000808080000000), CONST64(0x0000800080000080), CONST64(0x0000808080000080), + CONST64(0x0000000080008000), CONST64(0x0000008080008000), CONST64(0x0000000080008080), CONST64(0x0000008080008080), + CONST64(0x0000800080008000), CONST64(0x0000808080008000), CONST64(0x0000800080008080), CONST64(0x0000808080008080), + CONST64(0x0080000080000000), CONST64(0x0080008080000000), CONST64(0x0080000080000080), CONST64(0x0080008080000080), + CONST64(0x0080800080000000), CONST64(0x0080808080000000), CONST64(0x0080800080000080), CONST64(0x0080808080000080), + CONST64(0x0080000080008000), CONST64(0x0080008080008000), CONST64(0x0080000080008080), CONST64(0x0080008080008080), + CONST64(0x0080800080008000), CONST64(0x0080808080008000), CONST64(0x0080800080008080), CONST64(0x0080808080008080), + CONST64(0x0000000080800000), CONST64(0x0000008080800000), CONST64(0x0000000080800080), CONST64(0x0000008080800080), + CONST64(0x0000800080800000), CONST64(0x0000808080800000), CONST64(0x0000800080800080), CONST64(0x0000808080800080), + CONST64(0x0000000080808000), CONST64(0x0000008080808000), CONST64(0x0000000080808080), CONST64(0x0000008080808080), + CONST64(0x0000800080808000), CONST64(0x0000808080808000), CONST64(0x0000800080808080), CONST64(0x0000808080808080), + CONST64(0x0080000080800000), CONST64(0x0080008080800000), CONST64(0x0080000080800080), CONST64(0x0080008080800080), + CONST64(0x0080800080800000), CONST64(0x0080808080800000), CONST64(0x0080800080800080), CONST64(0x0080808080800080), + CONST64(0x0080000080808000), CONST64(0x0080008080808000), CONST64(0x0080000080808080), CONST64(0x0080008080808080), + CONST64(0x0080800080808000), CONST64(0x0080808080808000), CONST64(0x0080800080808080), CONST64(0x0080808080808080), + CONST64(0x8000000080000000), CONST64(0x8000008080000000), CONST64(0x8000000080000080), CONST64(0x8000008080000080), + CONST64(0x8000800080000000), CONST64(0x8000808080000000), CONST64(0x8000800080000080), CONST64(0x8000808080000080), + CONST64(0x8000000080008000), CONST64(0x8000008080008000), CONST64(0x8000000080008080), CONST64(0x8000008080008080), + CONST64(0x8000800080008000), CONST64(0x8000808080008000), CONST64(0x8000800080008080), CONST64(0x8000808080008080), + CONST64(0x8080000080000000), CONST64(0x8080008080000000), CONST64(0x8080000080000080), CONST64(0x8080008080000080), + CONST64(0x8080800080000000), CONST64(0x8080808080000000), CONST64(0x8080800080000080), CONST64(0x8080808080000080), + CONST64(0x8080000080008000), CONST64(0x8080008080008000), CONST64(0x8080000080008080), CONST64(0x8080008080008080), + CONST64(0x8080800080008000), CONST64(0x8080808080008000), CONST64(0x8080800080008080), CONST64(0x8080808080008080), + CONST64(0x8000000080800000), CONST64(0x8000008080800000), CONST64(0x8000000080800080), CONST64(0x8000008080800080), + CONST64(0x8000800080800000), CONST64(0x8000808080800000), CONST64(0x8000800080800080), CONST64(0x8000808080800080), + CONST64(0x8000000080808000), CONST64(0x8000008080808000), CONST64(0x8000000080808080), CONST64(0x8000008080808080), + CONST64(0x8000800080808000), CONST64(0x8000808080808000), CONST64(0x8000800080808080), CONST64(0x8000808080808080), + CONST64(0x8080000080800000), CONST64(0x8080008080800000), CONST64(0x8080000080800080), CONST64(0x8080008080800080), + CONST64(0x8080800080800000), CONST64(0x8080808080800000), CONST64(0x8080800080800080), CONST64(0x8080808080800080), + CONST64(0x8080000080808000), CONST64(0x8080008080808000), CONST64(0x8080000080808080), CONST64(0x8080008080808080), + CONST64(0x8080800080808000), CONST64(0x8080808080808000), CONST64(0x8080800080808080), CONST64(0x8080808080808080) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000004000000000), CONST64(0x0000000000000040), CONST64(0x0000004000000040), + CONST64(0x0000400000000000), CONST64(0x0000404000000000), CONST64(0x0000400000000040), CONST64(0x0000404000000040), + CONST64(0x0000000000004000), CONST64(0x0000004000004000), CONST64(0x0000000000004040), CONST64(0x0000004000004040), + CONST64(0x0000400000004000), CONST64(0x0000404000004000), CONST64(0x0000400000004040), CONST64(0x0000404000004040), + CONST64(0x0040000000000000), CONST64(0x0040004000000000), CONST64(0x0040000000000040), CONST64(0x0040004000000040), + CONST64(0x0040400000000000), CONST64(0x0040404000000000), CONST64(0x0040400000000040), CONST64(0x0040404000000040), + CONST64(0x0040000000004000), CONST64(0x0040004000004000), CONST64(0x0040000000004040), CONST64(0x0040004000004040), + CONST64(0x0040400000004000), CONST64(0x0040404000004000), CONST64(0x0040400000004040), CONST64(0x0040404000004040), + CONST64(0x0000000000400000), CONST64(0x0000004000400000), CONST64(0x0000000000400040), CONST64(0x0000004000400040), + CONST64(0x0000400000400000), CONST64(0x0000404000400000), CONST64(0x0000400000400040), CONST64(0x0000404000400040), + CONST64(0x0000000000404000), CONST64(0x0000004000404000), CONST64(0x0000000000404040), CONST64(0x0000004000404040), + CONST64(0x0000400000404000), CONST64(0x0000404000404000), CONST64(0x0000400000404040), CONST64(0x0000404000404040), + CONST64(0x0040000000400000), CONST64(0x0040004000400000), CONST64(0x0040000000400040), CONST64(0x0040004000400040), + CONST64(0x0040400000400000), CONST64(0x0040404000400000), CONST64(0x0040400000400040), CONST64(0x0040404000400040), + CONST64(0x0040000000404000), CONST64(0x0040004000404000), CONST64(0x0040000000404040), CONST64(0x0040004000404040), + CONST64(0x0040400000404000), CONST64(0x0040404000404000), CONST64(0x0040400000404040), CONST64(0x0040404000404040), + CONST64(0x4000000000000000), CONST64(0x4000004000000000), CONST64(0x4000000000000040), CONST64(0x4000004000000040), + CONST64(0x4000400000000000), CONST64(0x4000404000000000), CONST64(0x4000400000000040), CONST64(0x4000404000000040), + CONST64(0x4000000000004000), CONST64(0x4000004000004000), CONST64(0x4000000000004040), CONST64(0x4000004000004040), + CONST64(0x4000400000004000), CONST64(0x4000404000004000), CONST64(0x4000400000004040), CONST64(0x4000404000004040), + CONST64(0x4040000000000000), CONST64(0x4040004000000000), CONST64(0x4040000000000040), CONST64(0x4040004000000040), + CONST64(0x4040400000000000), CONST64(0x4040404000000000), CONST64(0x4040400000000040), CONST64(0x4040404000000040), + CONST64(0x4040000000004000), CONST64(0x4040004000004000), CONST64(0x4040000000004040), CONST64(0x4040004000004040), + CONST64(0x4040400000004000), CONST64(0x4040404000004000), CONST64(0x4040400000004040), CONST64(0x4040404000004040), + CONST64(0x4000000000400000), CONST64(0x4000004000400000), CONST64(0x4000000000400040), CONST64(0x4000004000400040), + CONST64(0x4000400000400000), CONST64(0x4000404000400000), CONST64(0x4000400000400040), CONST64(0x4000404000400040), + CONST64(0x4000000000404000), CONST64(0x4000004000404000), CONST64(0x4000000000404040), CONST64(0x4000004000404040), + CONST64(0x4000400000404000), CONST64(0x4000404000404000), CONST64(0x4000400000404040), CONST64(0x4000404000404040), + CONST64(0x4040000000400000), CONST64(0x4040004000400000), CONST64(0x4040000000400040), CONST64(0x4040004000400040), + CONST64(0x4040400000400000), CONST64(0x4040404000400000), CONST64(0x4040400000400040), CONST64(0x4040404000400040), + CONST64(0x4040000000404000), CONST64(0x4040004000404000), CONST64(0x4040000000404040), CONST64(0x4040004000404040), + CONST64(0x4040400000404000), CONST64(0x4040404000404000), CONST64(0x4040400000404040), CONST64(0x4040404000404040), + CONST64(0x0000000040000000), CONST64(0x0000004040000000), CONST64(0x0000000040000040), CONST64(0x0000004040000040), + CONST64(0x0000400040000000), CONST64(0x0000404040000000), CONST64(0x0000400040000040), CONST64(0x0000404040000040), + CONST64(0x0000000040004000), CONST64(0x0000004040004000), CONST64(0x0000000040004040), CONST64(0x0000004040004040), + CONST64(0x0000400040004000), CONST64(0x0000404040004000), CONST64(0x0000400040004040), CONST64(0x0000404040004040), + CONST64(0x0040000040000000), CONST64(0x0040004040000000), CONST64(0x0040000040000040), CONST64(0x0040004040000040), + CONST64(0x0040400040000000), CONST64(0x0040404040000000), CONST64(0x0040400040000040), CONST64(0x0040404040000040), + CONST64(0x0040000040004000), CONST64(0x0040004040004000), CONST64(0x0040000040004040), CONST64(0x0040004040004040), + CONST64(0x0040400040004000), CONST64(0x0040404040004000), CONST64(0x0040400040004040), CONST64(0x0040404040004040), + CONST64(0x0000000040400000), CONST64(0x0000004040400000), CONST64(0x0000000040400040), CONST64(0x0000004040400040), + CONST64(0x0000400040400000), CONST64(0x0000404040400000), CONST64(0x0000400040400040), CONST64(0x0000404040400040), + CONST64(0x0000000040404000), CONST64(0x0000004040404000), CONST64(0x0000000040404040), CONST64(0x0000004040404040), + CONST64(0x0000400040404000), CONST64(0x0000404040404000), CONST64(0x0000400040404040), CONST64(0x0000404040404040), + CONST64(0x0040000040400000), CONST64(0x0040004040400000), CONST64(0x0040000040400040), CONST64(0x0040004040400040), + CONST64(0x0040400040400000), CONST64(0x0040404040400000), CONST64(0x0040400040400040), CONST64(0x0040404040400040), + CONST64(0x0040000040404000), CONST64(0x0040004040404000), CONST64(0x0040000040404040), CONST64(0x0040004040404040), + CONST64(0x0040400040404000), CONST64(0x0040404040404000), CONST64(0x0040400040404040), CONST64(0x0040404040404040), + CONST64(0x4000000040000000), CONST64(0x4000004040000000), CONST64(0x4000000040000040), CONST64(0x4000004040000040), + CONST64(0x4000400040000000), CONST64(0x4000404040000000), CONST64(0x4000400040000040), CONST64(0x4000404040000040), + CONST64(0x4000000040004000), CONST64(0x4000004040004000), CONST64(0x4000000040004040), CONST64(0x4000004040004040), + CONST64(0x4000400040004000), CONST64(0x4000404040004000), CONST64(0x4000400040004040), CONST64(0x4000404040004040), + CONST64(0x4040000040000000), CONST64(0x4040004040000000), CONST64(0x4040000040000040), CONST64(0x4040004040000040), + CONST64(0x4040400040000000), CONST64(0x4040404040000000), CONST64(0x4040400040000040), CONST64(0x4040404040000040), + CONST64(0x4040000040004000), CONST64(0x4040004040004000), CONST64(0x4040000040004040), CONST64(0x4040004040004040), + CONST64(0x4040400040004000), CONST64(0x4040404040004000), CONST64(0x4040400040004040), CONST64(0x4040404040004040), + CONST64(0x4000000040400000), CONST64(0x4000004040400000), CONST64(0x4000000040400040), CONST64(0x4000004040400040), + CONST64(0x4000400040400000), CONST64(0x4000404040400000), CONST64(0x4000400040400040), CONST64(0x4000404040400040), + CONST64(0x4000000040404000), CONST64(0x4000004040404000), CONST64(0x4000000040404040), CONST64(0x4000004040404040), + CONST64(0x4000400040404000), CONST64(0x4000404040404000), CONST64(0x4000400040404040), CONST64(0x4000404040404040), + CONST64(0x4040000040400000), CONST64(0x4040004040400000), CONST64(0x4040000040400040), CONST64(0x4040004040400040), + CONST64(0x4040400040400000), CONST64(0x4040404040400000), CONST64(0x4040400040400040), CONST64(0x4040404040400040), + CONST64(0x4040000040404000), CONST64(0x4040004040404000), CONST64(0x4040000040404040), CONST64(0x4040004040404040), + CONST64(0x4040400040404000), CONST64(0x4040404040404000), CONST64(0x4040400040404040), CONST64(0x4040404040404040) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000002000000000), CONST64(0x0000000000000020), CONST64(0x0000002000000020), + CONST64(0x0000200000000000), CONST64(0x0000202000000000), CONST64(0x0000200000000020), CONST64(0x0000202000000020), + CONST64(0x0000000000002000), CONST64(0x0000002000002000), CONST64(0x0000000000002020), CONST64(0x0000002000002020), + CONST64(0x0000200000002000), CONST64(0x0000202000002000), CONST64(0x0000200000002020), CONST64(0x0000202000002020), + CONST64(0x0020000000000000), CONST64(0x0020002000000000), CONST64(0x0020000000000020), CONST64(0x0020002000000020), + CONST64(0x0020200000000000), CONST64(0x0020202000000000), CONST64(0x0020200000000020), CONST64(0x0020202000000020), + CONST64(0x0020000000002000), CONST64(0x0020002000002000), CONST64(0x0020000000002020), CONST64(0x0020002000002020), + CONST64(0x0020200000002000), CONST64(0x0020202000002000), CONST64(0x0020200000002020), CONST64(0x0020202000002020), + CONST64(0x0000000000200000), CONST64(0x0000002000200000), CONST64(0x0000000000200020), CONST64(0x0000002000200020), + CONST64(0x0000200000200000), CONST64(0x0000202000200000), CONST64(0x0000200000200020), CONST64(0x0000202000200020), + CONST64(0x0000000000202000), CONST64(0x0000002000202000), CONST64(0x0000000000202020), CONST64(0x0000002000202020), + CONST64(0x0000200000202000), CONST64(0x0000202000202000), CONST64(0x0000200000202020), CONST64(0x0000202000202020), + CONST64(0x0020000000200000), CONST64(0x0020002000200000), CONST64(0x0020000000200020), CONST64(0x0020002000200020), + CONST64(0x0020200000200000), CONST64(0x0020202000200000), CONST64(0x0020200000200020), CONST64(0x0020202000200020), + CONST64(0x0020000000202000), CONST64(0x0020002000202000), CONST64(0x0020000000202020), CONST64(0x0020002000202020), + CONST64(0x0020200000202000), CONST64(0x0020202000202000), CONST64(0x0020200000202020), CONST64(0x0020202000202020), + CONST64(0x2000000000000000), CONST64(0x2000002000000000), CONST64(0x2000000000000020), CONST64(0x2000002000000020), + CONST64(0x2000200000000000), CONST64(0x2000202000000000), CONST64(0x2000200000000020), CONST64(0x2000202000000020), + CONST64(0x2000000000002000), CONST64(0x2000002000002000), CONST64(0x2000000000002020), CONST64(0x2000002000002020), + CONST64(0x2000200000002000), CONST64(0x2000202000002000), CONST64(0x2000200000002020), CONST64(0x2000202000002020), + CONST64(0x2020000000000000), CONST64(0x2020002000000000), CONST64(0x2020000000000020), CONST64(0x2020002000000020), + CONST64(0x2020200000000000), CONST64(0x2020202000000000), CONST64(0x2020200000000020), CONST64(0x2020202000000020), + CONST64(0x2020000000002000), CONST64(0x2020002000002000), CONST64(0x2020000000002020), CONST64(0x2020002000002020), + CONST64(0x2020200000002000), CONST64(0x2020202000002000), CONST64(0x2020200000002020), CONST64(0x2020202000002020), + CONST64(0x2000000000200000), CONST64(0x2000002000200000), CONST64(0x2000000000200020), CONST64(0x2000002000200020), + CONST64(0x2000200000200000), CONST64(0x2000202000200000), CONST64(0x2000200000200020), CONST64(0x2000202000200020), + CONST64(0x2000000000202000), CONST64(0x2000002000202000), CONST64(0x2000000000202020), CONST64(0x2000002000202020), + CONST64(0x2000200000202000), CONST64(0x2000202000202000), CONST64(0x2000200000202020), CONST64(0x2000202000202020), + CONST64(0x2020000000200000), CONST64(0x2020002000200000), CONST64(0x2020000000200020), CONST64(0x2020002000200020), + CONST64(0x2020200000200000), CONST64(0x2020202000200000), CONST64(0x2020200000200020), CONST64(0x2020202000200020), + CONST64(0x2020000000202000), CONST64(0x2020002000202000), CONST64(0x2020000000202020), CONST64(0x2020002000202020), + CONST64(0x2020200000202000), CONST64(0x2020202000202000), CONST64(0x2020200000202020), CONST64(0x2020202000202020), + CONST64(0x0000000020000000), CONST64(0x0000002020000000), CONST64(0x0000000020000020), CONST64(0x0000002020000020), + CONST64(0x0000200020000000), CONST64(0x0000202020000000), CONST64(0x0000200020000020), CONST64(0x0000202020000020), + CONST64(0x0000000020002000), CONST64(0x0000002020002000), CONST64(0x0000000020002020), CONST64(0x0000002020002020), + CONST64(0x0000200020002000), CONST64(0x0000202020002000), CONST64(0x0000200020002020), CONST64(0x0000202020002020), + CONST64(0x0020000020000000), CONST64(0x0020002020000000), CONST64(0x0020000020000020), CONST64(0x0020002020000020), + CONST64(0x0020200020000000), CONST64(0x0020202020000000), CONST64(0x0020200020000020), CONST64(0x0020202020000020), + CONST64(0x0020000020002000), CONST64(0x0020002020002000), CONST64(0x0020000020002020), CONST64(0x0020002020002020), + CONST64(0x0020200020002000), CONST64(0x0020202020002000), CONST64(0x0020200020002020), CONST64(0x0020202020002020), + CONST64(0x0000000020200000), CONST64(0x0000002020200000), CONST64(0x0000000020200020), CONST64(0x0000002020200020), + CONST64(0x0000200020200000), CONST64(0x0000202020200000), CONST64(0x0000200020200020), CONST64(0x0000202020200020), + CONST64(0x0000000020202000), CONST64(0x0000002020202000), CONST64(0x0000000020202020), CONST64(0x0000002020202020), + CONST64(0x0000200020202000), CONST64(0x0000202020202000), CONST64(0x0000200020202020), CONST64(0x0000202020202020), + CONST64(0x0020000020200000), CONST64(0x0020002020200000), CONST64(0x0020000020200020), CONST64(0x0020002020200020), + CONST64(0x0020200020200000), CONST64(0x0020202020200000), CONST64(0x0020200020200020), CONST64(0x0020202020200020), + CONST64(0x0020000020202000), CONST64(0x0020002020202000), CONST64(0x0020000020202020), CONST64(0x0020002020202020), + CONST64(0x0020200020202000), CONST64(0x0020202020202000), CONST64(0x0020200020202020), CONST64(0x0020202020202020), + CONST64(0x2000000020000000), CONST64(0x2000002020000000), CONST64(0x2000000020000020), CONST64(0x2000002020000020), + CONST64(0x2000200020000000), CONST64(0x2000202020000000), CONST64(0x2000200020000020), CONST64(0x2000202020000020), + CONST64(0x2000000020002000), CONST64(0x2000002020002000), CONST64(0x2000000020002020), CONST64(0x2000002020002020), + CONST64(0x2000200020002000), CONST64(0x2000202020002000), CONST64(0x2000200020002020), CONST64(0x2000202020002020), + CONST64(0x2020000020000000), CONST64(0x2020002020000000), CONST64(0x2020000020000020), CONST64(0x2020002020000020), + CONST64(0x2020200020000000), CONST64(0x2020202020000000), CONST64(0x2020200020000020), CONST64(0x2020202020000020), + CONST64(0x2020000020002000), CONST64(0x2020002020002000), CONST64(0x2020000020002020), CONST64(0x2020002020002020), + CONST64(0x2020200020002000), CONST64(0x2020202020002000), CONST64(0x2020200020002020), CONST64(0x2020202020002020), + CONST64(0x2000000020200000), CONST64(0x2000002020200000), CONST64(0x2000000020200020), CONST64(0x2000002020200020), + CONST64(0x2000200020200000), CONST64(0x2000202020200000), CONST64(0x2000200020200020), CONST64(0x2000202020200020), + CONST64(0x2000000020202000), CONST64(0x2000002020202000), CONST64(0x2000000020202020), CONST64(0x2000002020202020), + CONST64(0x2000200020202000), CONST64(0x2000202020202000), CONST64(0x2000200020202020), CONST64(0x2000202020202020), + CONST64(0x2020000020200000), CONST64(0x2020002020200000), CONST64(0x2020000020200020), CONST64(0x2020002020200020), + CONST64(0x2020200020200000), CONST64(0x2020202020200000), CONST64(0x2020200020200020), CONST64(0x2020202020200020), + CONST64(0x2020000020202000), CONST64(0x2020002020202000), CONST64(0x2020000020202020), CONST64(0x2020002020202020), + CONST64(0x2020200020202000), CONST64(0x2020202020202000), CONST64(0x2020200020202020), CONST64(0x2020202020202020) + }}; + +static const ulong64 des_fp[8][256] = { + +{ CONST64(0x0000000000000000), CONST64(0x0000008000000000), CONST64(0x0000000002000000), CONST64(0x0000008002000000), + CONST64(0x0000000000020000), CONST64(0x0000008000020000), CONST64(0x0000000002020000), CONST64(0x0000008002020000), + CONST64(0x0000000000000200), CONST64(0x0000008000000200), CONST64(0x0000000002000200), CONST64(0x0000008002000200), + CONST64(0x0000000000020200), CONST64(0x0000008000020200), CONST64(0x0000000002020200), CONST64(0x0000008002020200), + CONST64(0x0000000000000002), CONST64(0x0000008000000002), CONST64(0x0000000002000002), CONST64(0x0000008002000002), + CONST64(0x0000000000020002), CONST64(0x0000008000020002), CONST64(0x0000000002020002), CONST64(0x0000008002020002), + CONST64(0x0000000000000202), CONST64(0x0000008000000202), CONST64(0x0000000002000202), CONST64(0x0000008002000202), + CONST64(0x0000000000020202), CONST64(0x0000008000020202), CONST64(0x0000000002020202), CONST64(0x0000008002020202), + CONST64(0x0200000000000000), CONST64(0x0200008000000000), CONST64(0x0200000002000000), CONST64(0x0200008002000000), + CONST64(0x0200000000020000), CONST64(0x0200008000020000), CONST64(0x0200000002020000), CONST64(0x0200008002020000), + CONST64(0x0200000000000200), CONST64(0x0200008000000200), CONST64(0x0200000002000200), CONST64(0x0200008002000200), + CONST64(0x0200000000020200), CONST64(0x0200008000020200), CONST64(0x0200000002020200), CONST64(0x0200008002020200), + CONST64(0x0200000000000002), CONST64(0x0200008000000002), CONST64(0x0200000002000002), CONST64(0x0200008002000002), + CONST64(0x0200000000020002), CONST64(0x0200008000020002), CONST64(0x0200000002020002), CONST64(0x0200008002020002), + CONST64(0x0200000000000202), CONST64(0x0200008000000202), CONST64(0x0200000002000202), CONST64(0x0200008002000202), + CONST64(0x0200000000020202), CONST64(0x0200008000020202), CONST64(0x0200000002020202), CONST64(0x0200008002020202), + CONST64(0x0002000000000000), CONST64(0x0002008000000000), CONST64(0x0002000002000000), CONST64(0x0002008002000000), + CONST64(0x0002000000020000), CONST64(0x0002008000020000), CONST64(0x0002000002020000), CONST64(0x0002008002020000), + CONST64(0x0002000000000200), CONST64(0x0002008000000200), CONST64(0x0002000002000200), CONST64(0x0002008002000200), + CONST64(0x0002000000020200), CONST64(0x0002008000020200), CONST64(0x0002000002020200), CONST64(0x0002008002020200), + CONST64(0x0002000000000002), CONST64(0x0002008000000002), CONST64(0x0002000002000002), CONST64(0x0002008002000002), + CONST64(0x0002000000020002), CONST64(0x0002008000020002), CONST64(0x0002000002020002), CONST64(0x0002008002020002), + CONST64(0x0002000000000202), CONST64(0x0002008000000202), CONST64(0x0002000002000202), CONST64(0x0002008002000202), + CONST64(0x0002000000020202), CONST64(0x0002008000020202), CONST64(0x0002000002020202), CONST64(0x0002008002020202), + CONST64(0x0202000000000000), CONST64(0x0202008000000000), CONST64(0x0202000002000000), CONST64(0x0202008002000000), + CONST64(0x0202000000020000), CONST64(0x0202008000020000), CONST64(0x0202000002020000), CONST64(0x0202008002020000), + CONST64(0x0202000000000200), CONST64(0x0202008000000200), CONST64(0x0202000002000200), CONST64(0x0202008002000200), + CONST64(0x0202000000020200), CONST64(0x0202008000020200), CONST64(0x0202000002020200), CONST64(0x0202008002020200), + CONST64(0x0202000000000002), CONST64(0x0202008000000002), CONST64(0x0202000002000002), CONST64(0x0202008002000002), + CONST64(0x0202000000020002), CONST64(0x0202008000020002), CONST64(0x0202000002020002), CONST64(0x0202008002020002), + CONST64(0x0202000000000202), CONST64(0x0202008000000202), CONST64(0x0202000002000202), CONST64(0x0202008002000202), + CONST64(0x0202000000020202), CONST64(0x0202008000020202), CONST64(0x0202000002020202), CONST64(0x0202008002020202), + CONST64(0x0000020000000000), CONST64(0x0000028000000000), CONST64(0x0000020002000000), CONST64(0x0000028002000000), + CONST64(0x0000020000020000), CONST64(0x0000028000020000), CONST64(0x0000020002020000), CONST64(0x0000028002020000), + CONST64(0x0000020000000200), CONST64(0x0000028000000200), CONST64(0x0000020002000200), CONST64(0x0000028002000200), + CONST64(0x0000020000020200), CONST64(0x0000028000020200), CONST64(0x0000020002020200), CONST64(0x0000028002020200), + CONST64(0x0000020000000002), CONST64(0x0000028000000002), CONST64(0x0000020002000002), CONST64(0x0000028002000002), + CONST64(0x0000020000020002), CONST64(0x0000028000020002), CONST64(0x0000020002020002), CONST64(0x0000028002020002), + CONST64(0x0000020000000202), CONST64(0x0000028000000202), CONST64(0x0000020002000202), CONST64(0x0000028002000202), + CONST64(0x0000020000020202), CONST64(0x0000028000020202), CONST64(0x0000020002020202), CONST64(0x0000028002020202), + CONST64(0x0200020000000000), CONST64(0x0200028000000000), CONST64(0x0200020002000000), CONST64(0x0200028002000000), + CONST64(0x0200020000020000), CONST64(0x0200028000020000), CONST64(0x0200020002020000), CONST64(0x0200028002020000), + CONST64(0x0200020000000200), CONST64(0x0200028000000200), CONST64(0x0200020002000200), CONST64(0x0200028002000200), + CONST64(0x0200020000020200), CONST64(0x0200028000020200), CONST64(0x0200020002020200), CONST64(0x0200028002020200), + CONST64(0x0200020000000002), CONST64(0x0200028000000002), CONST64(0x0200020002000002), CONST64(0x0200028002000002), + CONST64(0x0200020000020002), CONST64(0x0200028000020002), CONST64(0x0200020002020002), CONST64(0x0200028002020002), + CONST64(0x0200020000000202), CONST64(0x0200028000000202), CONST64(0x0200020002000202), CONST64(0x0200028002000202), + CONST64(0x0200020000020202), CONST64(0x0200028000020202), CONST64(0x0200020002020202), CONST64(0x0200028002020202), + CONST64(0x0002020000000000), CONST64(0x0002028000000000), CONST64(0x0002020002000000), CONST64(0x0002028002000000), + CONST64(0x0002020000020000), CONST64(0x0002028000020000), CONST64(0x0002020002020000), CONST64(0x0002028002020000), + CONST64(0x0002020000000200), CONST64(0x0002028000000200), CONST64(0x0002020002000200), CONST64(0x0002028002000200), + CONST64(0x0002020000020200), CONST64(0x0002028000020200), CONST64(0x0002020002020200), CONST64(0x0002028002020200), + CONST64(0x0002020000000002), CONST64(0x0002028000000002), CONST64(0x0002020002000002), CONST64(0x0002028002000002), + CONST64(0x0002020000020002), CONST64(0x0002028000020002), CONST64(0x0002020002020002), CONST64(0x0002028002020002), + CONST64(0x0002020000000202), CONST64(0x0002028000000202), CONST64(0x0002020002000202), CONST64(0x0002028002000202), + CONST64(0x0002020000020202), CONST64(0x0002028000020202), CONST64(0x0002020002020202), CONST64(0x0002028002020202), + CONST64(0x0202020000000000), CONST64(0x0202028000000000), CONST64(0x0202020002000000), CONST64(0x0202028002000000), + CONST64(0x0202020000020000), CONST64(0x0202028000020000), CONST64(0x0202020002020000), CONST64(0x0202028002020000), + CONST64(0x0202020000000200), CONST64(0x0202028000000200), CONST64(0x0202020002000200), CONST64(0x0202028002000200), + CONST64(0x0202020000020200), CONST64(0x0202028000020200), CONST64(0x0202020002020200), CONST64(0x0202028002020200), + CONST64(0x0202020000000002), CONST64(0x0202028000000002), CONST64(0x0202020002000002), CONST64(0x0202028002000002), + CONST64(0x0202020000020002), CONST64(0x0202028000020002), CONST64(0x0202020002020002), CONST64(0x0202028002020002), + CONST64(0x0202020000000202), CONST64(0x0202028000000202), CONST64(0x0202020002000202), CONST64(0x0202028002000202), + CONST64(0x0202020000020202), CONST64(0x0202028000020202), CONST64(0x0202020002020202), CONST64(0x0202028002020202) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000200000000), CONST64(0x0000000008000000), CONST64(0x0000000208000000), + CONST64(0x0000000000080000), CONST64(0x0000000200080000), CONST64(0x0000000008080000), CONST64(0x0000000208080000), + CONST64(0x0000000000000800), CONST64(0x0000000200000800), CONST64(0x0000000008000800), CONST64(0x0000000208000800), + CONST64(0x0000000000080800), CONST64(0x0000000200080800), CONST64(0x0000000008080800), CONST64(0x0000000208080800), + CONST64(0x0000000000000008), CONST64(0x0000000200000008), CONST64(0x0000000008000008), CONST64(0x0000000208000008), + CONST64(0x0000000000080008), CONST64(0x0000000200080008), CONST64(0x0000000008080008), CONST64(0x0000000208080008), + CONST64(0x0000000000000808), CONST64(0x0000000200000808), CONST64(0x0000000008000808), CONST64(0x0000000208000808), + CONST64(0x0000000000080808), CONST64(0x0000000200080808), CONST64(0x0000000008080808), CONST64(0x0000000208080808), + CONST64(0x0800000000000000), CONST64(0x0800000200000000), CONST64(0x0800000008000000), CONST64(0x0800000208000000), + CONST64(0x0800000000080000), CONST64(0x0800000200080000), CONST64(0x0800000008080000), CONST64(0x0800000208080000), + CONST64(0x0800000000000800), CONST64(0x0800000200000800), CONST64(0x0800000008000800), CONST64(0x0800000208000800), + CONST64(0x0800000000080800), CONST64(0x0800000200080800), CONST64(0x0800000008080800), CONST64(0x0800000208080800), + CONST64(0x0800000000000008), CONST64(0x0800000200000008), CONST64(0x0800000008000008), CONST64(0x0800000208000008), + CONST64(0x0800000000080008), CONST64(0x0800000200080008), CONST64(0x0800000008080008), CONST64(0x0800000208080008), + CONST64(0x0800000000000808), CONST64(0x0800000200000808), CONST64(0x0800000008000808), CONST64(0x0800000208000808), + CONST64(0x0800000000080808), CONST64(0x0800000200080808), CONST64(0x0800000008080808), CONST64(0x0800000208080808), + CONST64(0x0008000000000000), CONST64(0x0008000200000000), CONST64(0x0008000008000000), CONST64(0x0008000208000000), + CONST64(0x0008000000080000), CONST64(0x0008000200080000), CONST64(0x0008000008080000), CONST64(0x0008000208080000), + CONST64(0x0008000000000800), CONST64(0x0008000200000800), CONST64(0x0008000008000800), CONST64(0x0008000208000800), + CONST64(0x0008000000080800), CONST64(0x0008000200080800), CONST64(0x0008000008080800), CONST64(0x0008000208080800), + CONST64(0x0008000000000008), CONST64(0x0008000200000008), CONST64(0x0008000008000008), CONST64(0x0008000208000008), + CONST64(0x0008000000080008), CONST64(0x0008000200080008), CONST64(0x0008000008080008), CONST64(0x0008000208080008), + CONST64(0x0008000000000808), CONST64(0x0008000200000808), CONST64(0x0008000008000808), CONST64(0x0008000208000808), + CONST64(0x0008000000080808), CONST64(0x0008000200080808), CONST64(0x0008000008080808), CONST64(0x0008000208080808), + CONST64(0x0808000000000000), CONST64(0x0808000200000000), CONST64(0x0808000008000000), CONST64(0x0808000208000000), + CONST64(0x0808000000080000), CONST64(0x0808000200080000), CONST64(0x0808000008080000), CONST64(0x0808000208080000), + CONST64(0x0808000000000800), CONST64(0x0808000200000800), CONST64(0x0808000008000800), CONST64(0x0808000208000800), + CONST64(0x0808000000080800), CONST64(0x0808000200080800), CONST64(0x0808000008080800), CONST64(0x0808000208080800), + CONST64(0x0808000000000008), CONST64(0x0808000200000008), CONST64(0x0808000008000008), CONST64(0x0808000208000008), + CONST64(0x0808000000080008), CONST64(0x0808000200080008), CONST64(0x0808000008080008), CONST64(0x0808000208080008), + CONST64(0x0808000000000808), CONST64(0x0808000200000808), CONST64(0x0808000008000808), CONST64(0x0808000208000808), + CONST64(0x0808000000080808), CONST64(0x0808000200080808), CONST64(0x0808000008080808), CONST64(0x0808000208080808), + CONST64(0x0000080000000000), CONST64(0x0000080200000000), CONST64(0x0000080008000000), CONST64(0x0000080208000000), + CONST64(0x0000080000080000), CONST64(0x0000080200080000), CONST64(0x0000080008080000), CONST64(0x0000080208080000), + CONST64(0x0000080000000800), CONST64(0x0000080200000800), CONST64(0x0000080008000800), CONST64(0x0000080208000800), + CONST64(0x0000080000080800), CONST64(0x0000080200080800), CONST64(0x0000080008080800), CONST64(0x0000080208080800), + CONST64(0x0000080000000008), CONST64(0x0000080200000008), CONST64(0x0000080008000008), CONST64(0x0000080208000008), + CONST64(0x0000080000080008), CONST64(0x0000080200080008), CONST64(0x0000080008080008), CONST64(0x0000080208080008), + CONST64(0x0000080000000808), CONST64(0x0000080200000808), CONST64(0x0000080008000808), CONST64(0x0000080208000808), + CONST64(0x0000080000080808), CONST64(0x0000080200080808), CONST64(0x0000080008080808), CONST64(0x0000080208080808), + CONST64(0x0800080000000000), CONST64(0x0800080200000000), CONST64(0x0800080008000000), CONST64(0x0800080208000000), + CONST64(0x0800080000080000), CONST64(0x0800080200080000), CONST64(0x0800080008080000), CONST64(0x0800080208080000), + CONST64(0x0800080000000800), CONST64(0x0800080200000800), CONST64(0x0800080008000800), CONST64(0x0800080208000800), + CONST64(0x0800080000080800), CONST64(0x0800080200080800), CONST64(0x0800080008080800), CONST64(0x0800080208080800), + CONST64(0x0800080000000008), CONST64(0x0800080200000008), CONST64(0x0800080008000008), CONST64(0x0800080208000008), + CONST64(0x0800080000080008), CONST64(0x0800080200080008), CONST64(0x0800080008080008), CONST64(0x0800080208080008), + CONST64(0x0800080000000808), CONST64(0x0800080200000808), CONST64(0x0800080008000808), CONST64(0x0800080208000808), + CONST64(0x0800080000080808), CONST64(0x0800080200080808), CONST64(0x0800080008080808), CONST64(0x0800080208080808), + CONST64(0x0008080000000000), CONST64(0x0008080200000000), CONST64(0x0008080008000000), CONST64(0x0008080208000000), + CONST64(0x0008080000080000), CONST64(0x0008080200080000), CONST64(0x0008080008080000), CONST64(0x0008080208080000), + CONST64(0x0008080000000800), CONST64(0x0008080200000800), CONST64(0x0008080008000800), CONST64(0x0008080208000800), + CONST64(0x0008080000080800), CONST64(0x0008080200080800), CONST64(0x0008080008080800), CONST64(0x0008080208080800), + CONST64(0x0008080000000008), CONST64(0x0008080200000008), CONST64(0x0008080008000008), CONST64(0x0008080208000008), + CONST64(0x0008080000080008), CONST64(0x0008080200080008), CONST64(0x0008080008080008), CONST64(0x0008080208080008), + CONST64(0x0008080000000808), CONST64(0x0008080200000808), CONST64(0x0008080008000808), CONST64(0x0008080208000808), + CONST64(0x0008080000080808), CONST64(0x0008080200080808), CONST64(0x0008080008080808), CONST64(0x0008080208080808), + CONST64(0x0808080000000000), CONST64(0x0808080200000000), CONST64(0x0808080008000000), CONST64(0x0808080208000000), + CONST64(0x0808080000080000), CONST64(0x0808080200080000), CONST64(0x0808080008080000), CONST64(0x0808080208080000), + CONST64(0x0808080000000800), CONST64(0x0808080200000800), CONST64(0x0808080008000800), CONST64(0x0808080208000800), + CONST64(0x0808080000080800), CONST64(0x0808080200080800), CONST64(0x0808080008080800), CONST64(0x0808080208080800), + CONST64(0x0808080000000008), CONST64(0x0808080200000008), CONST64(0x0808080008000008), CONST64(0x0808080208000008), + CONST64(0x0808080000080008), CONST64(0x0808080200080008), CONST64(0x0808080008080008), CONST64(0x0808080208080008), + CONST64(0x0808080000000808), CONST64(0x0808080200000808), CONST64(0x0808080008000808), CONST64(0x0808080208000808), + CONST64(0x0808080000080808), CONST64(0x0808080200080808), CONST64(0x0808080008080808), CONST64(0x0808080208080808) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000800000000), CONST64(0x0000000020000000), CONST64(0x0000000820000000), + CONST64(0x0000000000200000), CONST64(0x0000000800200000), CONST64(0x0000000020200000), CONST64(0x0000000820200000), + CONST64(0x0000000000002000), CONST64(0x0000000800002000), CONST64(0x0000000020002000), CONST64(0x0000000820002000), + CONST64(0x0000000000202000), CONST64(0x0000000800202000), CONST64(0x0000000020202000), CONST64(0x0000000820202000), + CONST64(0x0000000000000020), CONST64(0x0000000800000020), CONST64(0x0000000020000020), CONST64(0x0000000820000020), + CONST64(0x0000000000200020), CONST64(0x0000000800200020), CONST64(0x0000000020200020), CONST64(0x0000000820200020), + CONST64(0x0000000000002020), CONST64(0x0000000800002020), CONST64(0x0000000020002020), CONST64(0x0000000820002020), + CONST64(0x0000000000202020), CONST64(0x0000000800202020), CONST64(0x0000000020202020), CONST64(0x0000000820202020), + CONST64(0x2000000000000000), CONST64(0x2000000800000000), CONST64(0x2000000020000000), CONST64(0x2000000820000000), + CONST64(0x2000000000200000), CONST64(0x2000000800200000), CONST64(0x2000000020200000), CONST64(0x2000000820200000), + CONST64(0x2000000000002000), CONST64(0x2000000800002000), CONST64(0x2000000020002000), CONST64(0x2000000820002000), + CONST64(0x2000000000202000), CONST64(0x2000000800202000), CONST64(0x2000000020202000), CONST64(0x2000000820202000), + CONST64(0x2000000000000020), CONST64(0x2000000800000020), CONST64(0x2000000020000020), CONST64(0x2000000820000020), + CONST64(0x2000000000200020), CONST64(0x2000000800200020), CONST64(0x2000000020200020), CONST64(0x2000000820200020), + CONST64(0x2000000000002020), CONST64(0x2000000800002020), CONST64(0x2000000020002020), CONST64(0x2000000820002020), + CONST64(0x2000000000202020), CONST64(0x2000000800202020), CONST64(0x2000000020202020), CONST64(0x2000000820202020), + CONST64(0x0020000000000000), CONST64(0x0020000800000000), CONST64(0x0020000020000000), CONST64(0x0020000820000000), + CONST64(0x0020000000200000), CONST64(0x0020000800200000), CONST64(0x0020000020200000), CONST64(0x0020000820200000), + CONST64(0x0020000000002000), CONST64(0x0020000800002000), CONST64(0x0020000020002000), CONST64(0x0020000820002000), + CONST64(0x0020000000202000), CONST64(0x0020000800202000), CONST64(0x0020000020202000), CONST64(0x0020000820202000), + CONST64(0x0020000000000020), CONST64(0x0020000800000020), CONST64(0x0020000020000020), CONST64(0x0020000820000020), + CONST64(0x0020000000200020), CONST64(0x0020000800200020), CONST64(0x0020000020200020), CONST64(0x0020000820200020), + CONST64(0x0020000000002020), CONST64(0x0020000800002020), CONST64(0x0020000020002020), CONST64(0x0020000820002020), + CONST64(0x0020000000202020), CONST64(0x0020000800202020), CONST64(0x0020000020202020), CONST64(0x0020000820202020), + CONST64(0x2020000000000000), CONST64(0x2020000800000000), CONST64(0x2020000020000000), CONST64(0x2020000820000000), + CONST64(0x2020000000200000), CONST64(0x2020000800200000), CONST64(0x2020000020200000), CONST64(0x2020000820200000), + CONST64(0x2020000000002000), CONST64(0x2020000800002000), CONST64(0x2020000020002000), CONST64(0x2020000820002000), + CONST64(0x2020000000202000), CONST64(0x2020000800202000), CONST64(0x2020000020202000), CONST64(0x2020000820202000), + CONST64(0x2020000000000020), CONST64(0x2020000800000020), CONST64(0x2020000020000020), CONST64(0x2020000820000020), + CONST64(0x2020000000200020), CONST64(0x2020000800200020), CONST64(0x2020000020200020), CONST64(0x2020000820200020), + CONST64(0x2020000000002020), CONST64(0x2020000800002020), CONST64(0x2020000020002020), CONST64(0x2020000820002020), + CONST64(0x2020000000202020), CONST64(0x2020000800202020), CONST64(0x2020000020202020), CONST64(0x2020000820202020), + CONST64(0x0000200000000000), CONST64(0x0000200800000000), CONST64(0x0000200020000000), CONST64(0x0000200820000000), + CONST64(0x0000200000200000), CONST64(0x0000200800200000), CONST64(0x0000200020200000), CONST64(0x0000200820200000), + CONST64(0x0000200000002000), CONST64(0x0000200800002000), CONST64(0x0000200020002000), CONST64(0x0000200820002000), + CONST64(0x0000200000202000), CONST64(0x0000200800202000), CONST64(0x0000200020202000), CONST64(0x0000200820202000), + CONST64(0x0000200000000020), CONST64(0x0000200800000020), CONST64(0x0000200020000020), CONST64(0x0000200820000020), + CONST64(0x0000200000200020), CONST64(0x0000200800200020), CONST64(0x0000200020200020), CONST64(0x0000200820200020), + CONST64(0x0000200000002020), CONST64(0x0000200800002020), CONST64(0x0000200020002020), CONST64(0x0000200820002020), + CONST64(0x0000200000202020), CONST64(0x0000200800202020), CONST64(0x0000200020202020), CONST64(0x0000200820202020), + CONST64(0x2000200000000000), CONST64(0x2000200800000000), CONST64(0x2000200020000000), CONST64(0x2000200820000000), + CONST64(0x2000200000200000), CONST64(0x2000200800200000), CONST64(0x2000200020200000), CONST64(0x2000200820200000), + CONST64(0x2000200000002000), CONST64(0x2000200800002000), CONST64(0x2000200020002000), CONST64(0x2000200820002000), + CONST64(0x2000200000202000), CONST64(0x2000200800202000), CONST64(0x2000200020202000), CONST64(0x2000200820202000), + CONST64(0x2000200000000020), CONST64(0x2000200800000020), CONST64(0x2000200020000020), CONST64(0x2000200820000020), + CONST64(0x2000200000200020), CONST64(0x2000200800200020), CONST64(0x2000200020200020), CONST64(0x2000200820200020), + CONST64(0x2000200000002020), CONST64(0x2000200800002020), CONST64(0x2000200020002020), CONST64(0x2000200820002020), + CONST64(0x2000200000202020), CONST64(0x2000200800202020), CONST64(0x2000200020202020), CONST64(0x2000200820202020), + CONST64(0x0020200000000000), CONST64(0x0020200800000000), CONST64(0x0020200020000000), CONST64(0x0020200820000000), + CONST64(0x0020200000200000), CONST64(0x0020200800200000), CONST64(0x0020200020200000), CONST64(0x0020200820200000), + CONST64(0x0020200000002000), CONST64(0x0020200800002000), CONST64(0x0020200020002000), CONST64(0x0020200820002000), + CONST64(0x0020200000202000), CONST64(0x0020200800202000), CONST64(0x0020200020202000), CONST64(0x0020200820202000), + CONST64(0x0020200000000020), CONST64(0x0020200800000020), CONST64(0x0020200020000020), CONST64(0x0020200820000020), + CONST64(0x0020200000200020), CONST64(0x0020200800200020), CONST64(0x0020200020200020), CONST64(0x0020200820200020), + CONST64(0x0020200000002020), CONST64(0x0020200800002020), CONST64(0x0020200020002020), CONST64(0x0020200820002020), + CONST64(0x0020200000202020), CONST64(0x0020200800202020), CONST64(0x0020200020202020), CONST64(0x0020200820202020), + CONST64(0x2020200000000000), CONST64(0x2020200800000000), CONST64(0x2020200020000000), CONST64(0x2020200820000000), + CONST64(0x2020200000200000), CONST64(0x2020200800200000), CONST64(0x2020200020200000), CONST64(0x2020200820200000), + CONST64(0x2020200000002000), CONST64(0x2020200800002000), CONST64(0x2020200020002000), CONST64(0x2020200820002000), + CONST64(0x2020200000202000), CONST64(0x2020200800202000), CONST64(0x2020200020202000), CONST64(0x2020200820202000), + CONST64(0x2020200000000020), CONST64(0x2020200800000020), CONST64(0x2020200020000020), CONST64(0x2020200820000020), + CONST64(0x2020200000200020), CONST64(0x2020200800200020), CONST64(0x2020200020200020), CONST64(0x2020200820200020), + CONST64(0x2020200000002020), CONST64(0x2020200800002020), CONST64(0x2020200020002020), CONST64(0x2020200820002020), + CONST64(0x2020200000202020), CONST64(0x2020200800202020), CONST64(0x2020200020202020), CONST64(0x2020200820202020) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000002000000000), CONST64(0x0000000080000000), CONST64(0x0000002080000000), + CONST64(0x0000000000800000), CONST64(0x0000002000800000), CONST64(0x0000000080800000), CONST64(0x0000002080800000), + CONST64(0x0000000000008000), CONST64(0x0000002000008000), CONST64(0x0000000080008000), CONST64(0x0000002080008000), + CONST64(0x0000000000808000), CONST64(0x0000002000808000), CONST64(0x0000000080808000), CONST64(0x0000002080808000), + CONST64(0x0000000000000080), CONST64(0x0000002000000080), CONST64(0x0000000080000080), CONST64(0x0000002080000080), + CONST64(0x0000000000800080), CONST64(0x0000002000800080), CONST64(0x0000000080800080), CONST64(0x0000002080800080), + CONST64(0x0000000000008080), CONST64(0x0000002000008080), CONST64(0x0000000080008080), CONST64(0x0000002080008080), + CONST64(0x0000000000808080), CONST64(0x0000002000808080), CONST64(0x0000000080808080), CONST64(0x0000002080808080), + CONST64(0x8000000000000000), CONST64(0x8000002000000000), CONST64(0x8000000080000000), CONST64(0x8000002080000000), + CONST64(0x8000000000800000), CONST64(0x8000002000800000), CONST64(0x8000000080800000), CONST64(0x8000002080800000), + CONST64(0x8000000000008000), CONST64(0x8000002000008000), CONST64(0x8000000080008000), CONST64(0x8000002080008000), + CONST64(0x8000000000808000), CONST64(0x8000002000808000), CONST64(0x8000000080808000), CONST64(0x8000002080808000), + CONST64(0x8000000000000080), CONST64(0x8000002000000080), CONST64(0x8000000080000080), CONST64(0x8000002080000080), + CONST64(0x8000000000800080), CONST64(0x8000002000800080), CONST64(0x8000000080800080), CONST64(0x8000002080800080), + CONST64(0x8000000000008080), CONST64(0x8000002000008080), CONST64(0x8000000080008080), CONST64(0x8000002080008080), + CONST64(0x8000000000808080), CONST64(0x8000002000808080), CONST64(0x8000000080808080), CONST64(0x8000002080808080), + CONST64(0x0080000000000000), CONST64(0x0080002000000000), CONST64(0x0080000080000000), CONST64(0x0080002080000000), + CONST64(0x0080000000800000), CONST64(0x0080002000800000), CONST64(0x0080000080800000), CONST64(0x0080002080800000), + CONST64(0x0080000000008000), CONST64(0x0080002000008000), CONST64(0x0080000080008000), CONST64(0x0080002080008000), + CONST64(0x0080000000808000), CONST64(0x0080002000808000), CONST64(0x0080000080808000), CONST64(0x0080002080808000), + CONST64(0x0080000000000080), CONST64(0x0080002000000080), CONST64(0x0080000080000080), CONST64(0x0080002080000080), + CONST64(0x0080000000800080), CONST64(0x0080002000800080), CONST64(0x0080000080800080), CONST64(0x0080002080800080), + CONST64(0x0080000000008080), CONST64(0x0080002000008080), CONST64(0x0080000080008080), CONST64(0x0080002080008080), + CONST64(0x0080000000808080), CONST64(0x0080002000808080), CONST64(0x0080000080808080), CONST64(0x0080002080808080), + CONST64(0x8080000000000000), CONST64(0x8080002000000000), CONST64(0x8080000080000000), CONST64(0x8080002080000000), + CONST64(0x8080000000800000), CONST64(0x8080002000800000), CONST64(0x8080000080800000), CONST64(0x8080002080800000), + CONST64(0x8080000000008000), CONST64(0x8080002000008000), CONST64(0x8080000080008000), CONST64(0x8080002080008000), + CONST64(0x8080000000808000), CONST64(0x8080002000808000), CONST64(0x8080000080808000), CONST64(0x8080002080808000), + CONST64(0x8080000000000080), CONST64(0x8080002000000080), CONST64(0x8080000080000080), CONST64(0x8080002080000080), + CONST64(0x8080000000800080), CONST64(0x8080002000800080), CONST64(0x8080000080800080), CONST64(0x8080002080800080), + CONST64(0x8080000000008080), CONST64(0x8080002000008080), CONST64(0x8080000080008080), CONST64(0x8080002080008080), + CONST64(0x8080000000808080), CONST64(0x8080002000808080), CONST64(0x8080000080808080), CONST64(0x8080002080808080), + CONST64(0x0000800000000000), CONST64(0x0000802000000000), CONST64(0x0000800080000000), CONST64(0x0000802080000000), + CONST64(0x0000800000800000), CONST64(0x0000802000800000), CONST64(0x0000800080800000), CONST64(0x0000802080800000), + CONST64(0x0000800000008000), CONST64(0x0000802000008000), CONST64(0x0000800080008000), CONST64(0x0000802080008000), + CONST64(0x0000800000808000), CONST64(0x0000802000808000), CONST64(0x0000800080808000), CONST64(0x0000802080808000), + CONST64(0x0000800000000080), CONST64(0x0000802000000080), CONST64(0x0000800080000080), CONST64(0x0000802080000080), + CONST64(0x0000800000800080), CONST64(0x0000802000800080), CONST64(0x0000800080800080), CONST64(0x0000802080800080), + CONST64(0x0000800000008080), CONST64(0x0000802000008080), CONST64(0x0000800080008080), CONST64(0x0000802080008080), + CONST64(0x0000800000808080), CONST64(0x0000802000808080), CONST64(0x0000800080808080), CONST64(0x0000802080808080), + CONST64(0x8000800000000000), CONST64(0x8000802000000000), CONST64(0x8000800080000000), CONST64(0x8000802080000000), + CONST64(0x8000800000800000), CONST64(0x8000802000800000), CONST64(0x8000800080800000), CONST64(0x8000802080800000), + CONST64(0x8000800000008000), CONST64(0x8000802000008000), CONST64(0x8000800080008000), CONST64(0x8000802080008000), + CONST64(0x8000800000808000), CONST64(0x8000802000808000), CONST64(0x8000800080808000), CONST64(0x8000802080808000), + CONST64(0x8000800000000080), CONST64(0x8000802000000080), CONST64(0x8000800080000080), CONST64(0x8000802080000080), + CONST64(0x8000800000800080), CONST64(0x8000802000800080), CONST64(0x8000800080800080), CONST64(0x8000802080800080), + CONST64(0x8000800000008080), CONST64(0x8000802000008080), CONST64(0x8000800080008080), CONST64(0x8000802080008080), + CONST64(0x8000800000808080), CONST64(0x8000802000808080), CONST64(0x8000800080808080), CONST64(0x8000802080808080), + CONST64(0x0080800000000000), CONST64(0x0080802000000000), CONST64(0x0080800080000000), CONST64(0x0080802080000000), + CONST64(0x0080800000800000), CONST64(0x0080802000800000), CONST64(0x0080800080800000), CONST64(0x0080802080800000), + CONST64(0x0080800000008000), CONST64(0x0080802000008000), CONST64(0x0080800080008000), CONST64(0x0080802080008000), + CONST64(0x0080800000808000), CONST64(0x0080802000808000), CONST64(0x0080800080808000), CONST64(0x0080802080808000), + CONST64(0x0080800000000080), CONST64(0x0080802000000080), CONST64(0x0080800080000080), CONST64(0x0080802080000080), + CONST64(0x0080800000800080), CONST64(0x0080802000800080), CONST64(0x0080800080800080), CONST64(0x0080802080800080), + CONST64(0x0080800000008080), CONST64(0x0080802000008080), CONST64(0x0080800080008080), CONST64(0x0080802080008080), + CONST64(0x0080800000808080), CONST64(0x0080802000808080), CONST64(0x0080800080808080), CONST64(0x0080802080808080), + CONST64(0x8080800000000000), CONST64(0x8080802000000000), CONST64(0x8080800080000000), CONST64(0x8080802080000000), + CONST64(0x8080800000800000), CONST64(0x8080802000800000), CONST64(0x8080800080800000), CONST64(0x8080802080800000), + CONST64(0x8080800000008000), CONST64(0x8080802000008000), CONST64(0x8080800080008000), CONST64(0x8080802080008000), + CONST64(0x8080800000808000), CONST64(0x8080802000808000), CONST64(0x8080800080808000), CONST64(0x8080802080808000), + CONST64(0x8080800000000080), CONST64(0x8080802000000080), CONST64(0x8080800080000080), CONST64(0x8080802080000080), + CONST64(0x8080800000800080), CONST64(0x8080802000800080), CONST64(0x8080800080800080), CONST64(0x8080802080800080), + CONST64(0x8080800000008080), CONST64(0x8080802000008080), CONST64(0x8080800080008080), CONST64(0x8080802080008080), + CONST64(0x8080800000808080), CONST64(0x8080802000808080), CONST64(0x8080800080808080), CONST64(0x8080802080808080) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000004000000000), CONST64(0x0000000001000000), CONST64(0x0000004001000000), + CONST64(0x0000000000010000), CONST64(0x0000004000010000), CONST64(0x0000000001010000), CONST64(0x0000004001010000), + CONST64(0x0000000000000100), CONST64(0x0000004000000100), CONST64(0x0000000001000100), CONST64(0x0000004001000100), + CONST64(0x0000000000010100), CONST64(0x0000004000010100), CONST64(0x0000000001010100), CONST64(0x0000004001010100), + CONST64(0x0000000000000001), CONST64(0x0000004000000001), CONST64(0x0000000001000001), CONST64(0x0000004001000001), + CONST64(0x0000000000010001), CONST64(0x0000004000010001), CONST64(0x0000000001010001), CONST64(0x0000004001010001), + CONST64(0x0000000000000101), CONST64(0x0000004000000101), CONST64(0x0000000001000101), CONST64(0x0000004001000101), + CONST64(0x0000000000010101), CONST64(0x0000004000010101), CONST64(0x0000000001010101), CONST64(0x0000004001010101), + CONST64(0x0100000000000000), CONST64(0x0100004000000000), CONST64(0x0100000001000000), CONST64(0x0100004001000000), + CONST64(0x0100000000010000), CONST64(0x0100004000010000), CONST64(0x0100000001010000), CONST64(0x0100004001010000), + CONST64(0x0100000000000100), CONST64(0x0100004000000100), CONST64(0x0100000001000100), CONST64(0x0100004001000100), + CONST64(0x0100000000010100), CONST64(0x0100004000010100), CONST64(0x0100000001010100), CONST64(0x0100004001010100), + CONST64(0x0100000000000001), CONST64(0x0100004000000001), CONST64(0x0100000001000001), CONST64(0x0100004001000001), + CONST64(0x0100000000010001), CONST64(0x0100004000010001), CONST64(0x0100000001010001), CONST64(0x0100004001010001), + CONST64(0x0100000000000101), CONST64(0x0100004000000101), CONST64(0x0100000001000101), CONST64(0x0100004001000101), + CONST64(0x0100000000010101), CONST64(0x0100004000010101), CONST64(0x0100000001010101), CONST64(0x0100004001010101), + CONST64(0x0001000000000000), CONST64(0x0001004000000000), CONST64(0x0001000001000000), CONST64(0x0001004001000000), + CONST64(0x0001000000010000), CONST64(0x0001004000010000), CONST64(0x0001000001010000), CONST64(0x0001004001010000), + CONST64(0x0001000000000100), CONST64(0x0001004000000100), CONST64(0x0001000001000100), CONST64(0x0001004001000100), + CONST64(0x0001000000010100), CONST64(0x0001004000010100), CONST64(0x0001000001010100), CONST64(0x0001004001010100), + CONST64(0x0001000000000001), CONST64(0x0001004000000001), CONST64(0x0001000001000001), CONST64(0x0001004001000001), + CONST64(0x0001000000010001), CONST64(0x0001004000010001), CONST64(0x0001000001010001), CONST64(0x0001004001010001), + CONST64(0x0001000000000101), CONST64(0x0001004000000101), CONST64(0x0001000001000101), CONST64(0x0001004001000101), + CONST64(0x0001000000010101), CONST64(0x0001004000010101), CONST64(0x0001000001010101), CONST64(0x0001004001010101), + CONST64(0x0101000000000000), CONST64(0x0101004000000000), CONST64(0x0101000001000000), CONST64(0x0101004001000000), + CONST64(0x0101000000010000), CONST64(0x0101004000010000), CONST64(0x0101000001010000), CONST64(0x0101004001010000), + CONST64(0x0101000000000100), CONST64(0x0101004000000100), CONST64(0x0101000001000100), CONST64(0x0101004001000100), + CONST64(0x0101000000010100), CONST64(0x0101004000010100), CONST64(0x0101000001010100), CONST64(0x0101004001010100), + CONST64(0x0101000000000001), CONST64(0x0101004000000001), CONST64(0x0101000001000001), CONST64(0x0101004001000001), + CONST64(0x0101000000010001), CONST64(0x0101004000010001), CONST64(0x0101000001010001), CONST64(0x0101004001010001), + CONST64(0x0101000000000101), CONST64(0x0101004000000101), CONST64(0x0101000001000101), CONST64(0x0101004001000101), + CONST64(0x0101000000010101), CONST64(0x0101004000010101), CONST64(0x0101000001010101), CONST64(0x0101004001010101), + CONST64(0x0000010000000000), CONST64(0x0000014000000000), CONST64(0x0000010001000000), CONST64(0x0000014001000000), + CONST64(0x0000010000010000), CONST64(0x0000014000010000), CONST64(0x0000010001010000), CONST64(0x0000014001010000), + CONST64(0x0000010000000100), CONST64(0x0000014000000100), CONST64(0x0000010001000100), CONST64(0x0000014001000100), + CONST64(0x0000010000010100), CONST64(0x0000014000010100), CONST64(0x0000010001010100), CONST64(0x0000014001010100), + CONST64(0x0000010000000001), CONST64(0x0000014000000001), CONST64(0x0000010001000001), CONST64(0x0000014001000001), + CONST64(0x0000010000010001), CONST64(0x0000014000010001), CONST64(0x0000010001010001), CONST64(0x0000014001010001), + CONST64(0x0000010000000101), CONST64(0x0000014000000101), CONST64(0x0000010001000101), CONST64(0x0000014001000101), + CONST64(0x0000010000010101), CONST64(0x0000014000010101), CONST64(0x0000010001010101), CONST64(0x0000014001010101), + CONST64(0x0100010000000000), CONST64(0x0100014000000000), CONST64(0x0100010001000000), CONST64(0x0100014001000000), + CONST64(0x0100010000010000), CONST64(0x0100014000010000), CONST64(0x0100010001010000), CONST64(0x0100014001010000), + CONST64(0x0100010000000100), CONST64(0x0100014000000100), CONST64(0x0100010001000100), CONST64(0x0100014001000100), + CONST64(0x0100010000010100), CONST64(0x0100014000010100), CONST64(0x0100010001010100), CONST64(0x0100014001010100), + CONST64(0x0100010000000001), CONST64(0x0100014000000001), CONST64(0x0100010001000001), CONST64(0x0100014001000001), + CONST64(0x0100010000010001), CONST64(0x0100014000010001), CONST64(0x0100010001010001), CONST64(0x0100014001010001), + CONST64(0x0100010000000101), CONST64(0x0100014000000101), CONST64(0x0100010001000101), CONST64(0x0100014001000101), + CONST64(0x0100010000010101), CONST64(0x0100014000010101), CONST64(0x0100010001010101), CONST64(0x0100014001010101), + CONST64(0x0001010000000000), CONST64(0x0001014000000000), CONST64(0x0001010001000000), CONST64(0x0001014001000000), + CONST64(0x0001010000010000), CONST64(0x0001014000010000), CONST64(0x0001010001010000), CONST64(0x0001014001010000), + CONST64(0x0001010000000100), CONST64(0x0001014000000100), CONST64(0x0001010001000100), CONST64(0x0001014001000100), + CONST64(0x0001010000010100), CONST64(0x0001014000010100), CONST64(0x0001010001010100), CONST64(0x0001014001010100), + CONST64(0x0001010000000001), CONST64(0x0001014000000001), CONST64(0x0001010001000001), CONST64(0x0001014001000001), + CONST64(0x0001010000010001), CONST64(0x0001014000010001), CONST64(0x0001010001010001), CONST64(0x0001014001010001), + CONST64(0x0001010000000101), CONST64(0x0001014000000101), CONST64(0x0001010001000101), CONST64(0x0001014001000101), + CONST64(0x0001010000010101), CONST64(0x0001014000010101), CONST64(0x0001010001010101), CONST64(0x0001014001010101), + CONST64(0x0101010000000000), CONST64(0x0101014000000000), CONST64(0x0101010001000000), CONST64(0x0101014001000000), + CONST64(0x0101010000010000), CONST64(0x0101014000010000), CONST64(0x0101010001010000), CONST64(0x0101014001010000), + CONST64(0x0101010000000100), CONST64(0x0101014000000100), CONST64(0x0101010001000100), CONST64(0x0101014001000100), + CONST64(0x0101010000010100), CONST64(0x0101014000010100), CONST64(0x0101010001010100), CONST64(0x0101014001010100), + CONST64(0x0101010000000001), CONST64(0x0101014000000001), CONST64(0x0101010001000001), CONST64(0x0101014001000001), + CONST64(0x0101010000010001), CONST64(0x0101014000010001), CONST64(0x0101010001010001), CONST64(0x0101014001010001), + CONST64(0x0101010000000101), CONST64(0x0101014000000101), CONST64(0x0101010001000101), CONST64(0x0101014001000101), + CONST64(0x0101010000010101), CONST64(0x0101014000010101), CONST64(0x0101010001010101), CONST64(0x0101014001010101) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000100000000), CONST64(0x0000000004000000), CONST64(0x0000000104000000), + CONST64(0x0000000000040000), CONST64(0x0000000100040000), CONST64(0x0000000004040000), CONST64(0x0000000104040000), + CONST64(0x0000000000000400), CONST64(0x0000000100000400), CONST64(0x0000000004000400), CONST64(0x0000000104000400), + CONST64(0x0000000000040400), CONST64(0x0000000100040400), CONST64(0x0000000004040400), CONST64(0x0000000104040400), + CONST64(0x0000000000000004), CONST64(0x0000000100000004), CONST64(0x0000000004000004), CONST64(0x0000000104000004), + CONST64(0x0000000000040004), CONST64(0x0000000100040004), CONST64(0x0000000004040004), CONST64(0x0000000104040004), + CONST64(0x0000000000000404), CONST64(0x0000000100000404), CONST64(0x0000000004000404), CONST64(0x0000000104000404), + CONST64(0x0000000000040404), CONST64(0x0000000100040404), CONST64(0x0000000004040404), CONST64(0x0000000104040404), + CONST64(0x0400000000000000), CONST64(0x0400000100000000), CONST64(0x0400000004000000), CONST64(0x0400000104000000), + CONST64(0x0400000000040000), CONST64(0x0400000100040000), CONST64(0x0400000004040000), CONST64(0x0400000104040000), + CONST64(0x0400000000000400), CONST64(0x0400000100000400), CONST64(0x0400000004000400), CONST64(0x0400000104000400), + CONST64(0x0400000000040400), CONST64(0x0400000100040400), CONST64(0x0400000004040400), CONST64(0x0400000104040400), + CONST64(0x0400000000000004), CONST64(0x0400000100000004), CONST64(0x0400000004000004), CONST64(0x0400000104000004), + CONST64(0x0400000000040004), CONST64(0x0400000100040004), CONST64(0x0400000004040004), CONST64(0x0400000104040004), + CONST64(0x0400000000000404), CONST64(0x0400000100000404), CONST64(0x0400000004000404), CONST64(0x0400000104000404), + CONST64(0x0400000000040404), CONST64(0x0400000100040404), CONST64(0x0400000004040404), CONST64(0x0400000104040404), + CONST64(0x0004000000000000), CONST64(0x0004000100000000), CONST64(0x0004000004000000), CONST64(0x0004000104000000), + CONST64(0x0004000000040000), CONST64(0x0004000100040000), CONST64(0x0004000004040000), CONST64(0x0004000104040000), + CONST64(0x0004000000000400), CONST64(0x0004000100000400), CONST64(0x0004000004000400), CONST64(0x0004000104000400), + CONST64(0x0004000000040400), CONST64(0x0004000100040400), CONST64(0x0004000004040400), CONST64(0x0004000104040400), + CONST64(0x0004000000000004), CONST64(0x0004000100000004), CONST64(0x0004000004000004), CONST64(0x0004000104000004), + CONST64(0x0004000000040004), CONST64(0x0004000100040004), CONST64(0x0004000004040004), CONST64(0x0004000104040004), + CONST64(0x0004000000000404), CONST64(0x0004000100000404), CONST64(0x0004000004000404), CONST64(0x0004000104000404), + CONST64(0x0004000000040404), CONST64(0x0004000100040404), CONST64(0x0004000004040404), CONST64(0x0004000104040404), + CONST64(0x0404000000000000), CONST64(0x0404000100000000), CONST64(0x0404000004000000), CONST64(0x0404000104000000), + CONST64(0x0404000000040000), CONST64(0x0404000100040000), CONST64(0x0404000004040000), CONST64(0x0404000104040000), + CONST64(0x0404000000000400), CONST64(0x0404000100000400), CONST64(0x0404000004000400), CONST64(0x0404000104000400), + CONST64(0x0404000000040400), CONST64(0x0404000100040400), CONST64(0x0404000004040400), CONST64(0x0404000104040400), + CONST64(0x0404000000000004), CONST64(0x0404000100000004), CONST64(0x0404000004000004), CONST64(0x0404000104000004), + CONST64(0x0404000000040004), CONST64(0x0404000100040004), CONST64(0x0404000004040004), CONST64(0x0404000104040004), + CONST64(0x0404000000000404), CONST64(0x0404000100000404), CONST64(0x0404000004000404), CONST64(0x0404000104000404), + CONST64(0x0404000000040404), CONST64(0x0404000100040404), CONST64(0x0404000004040404), CONST64(0x0404000104040404), + CONST64(0x0000040000000000), CONST64(0x0000040100000000), CONST64(0x0000040004000000), CONST64(0x0000040104000000), + CONST64(0x0000040000040000), CONST64(0x0000040100040000), CONST64(0x0000040004040000), CONST64(0x0000040104040000), + CONST64(0x0000040000000400), CONST64(0x0000040100000400), CONST64(0x0000040004000400), CONST64(0x0000040104000400), + CONST64(0x0000040000040400), CONST64(0x0000040100040400), CONST64(0x0000040004040400), CONST64(0x0000040104040400), + CONST64(0x0000040000000004), CONST64(0x0000040100000004), CONST64(0x0000040004000004), CONST64(0x0000040104000004), + CONST64(0x0000040000040004), CONST64(0x0000040100040004), CONST64(0x0000040004040004), CONST64(0x0000040104040004), + CONST64(0x0000040000000404), CONST64(0x0000040100000404), CONST64(0x0000040004000404), CONST64(0x0000040104000404), + CONST64(0x0000040000040404), CONST64(0x0000040100040404), CONST64(0x0000040004040404), CONST64(0x0000040104040404), + CONST64(0x0400040000000000), CONST64(0x0400040100000000), CONST64(0x0400040004000000), CONST64(0x0400040104000000), + CONST64(0x0400040000040000), CONST64(0x0400040100040000), CONST64(0x0400040004040000), CONST64(0x0400040104040000), + CONST64(0x0400040000000400), CONST64(0x0400040100000400), CONST64(0x0400040004000400), CONST64(0x0400040104000400), + CONST64(0x0400040000040400), CONST64(0x0400040100040400), CONST64(0x0400040004040400), CONST64(0x0400040104040400), + CONST64(0x0400040000000004), CONST64(0x0400040100000004), CONST64(0x0400040004000004), CONST64(0x0400040104000004), + CONST64(0x0400040000040004), CONST64(0x0400040100040004), CONST64(0x0400040004040004), CONST64(0x0400040104040004), + CONST64(0x0400040000000404), CONST64(0x0400040100000404), CONST64(0x0400040004000404), CONST64(0x0400040104000404), + CONST64(0x0400040000040404), CONST64(0x0400040100040404), CONST64(0x0400040004040404), CONST64(0x0400040104040404), + CONST64(0x0004040000000000), CONST64(0x0004040100000000), CONST64(0x0004040004000000), CONST64(0x0004040104000000), + CONST64(0x0004040000040000), CONST64(0x0004040100040000), CONST64(0x0004040004040000), CONST64(0x0004040104040000), + CONST64(0x0004040000000400), CONST64(0x0004040100000400), CONST64(0x0004040004000400), CONST64(0x0004040104000400), + CONST64(0x0004040000040400), CONST64(0x0004040100040400), CONST64(0x0004040004040400), CONST64(0x0004040104040400), + CONST64(0x0004040000000004), CONST64(0x0004040100000004), CONST64(0x0004040004000004), CONST64(0x0004040104000004), + CONST64(0x0004040000040004), CONST64(0x0004040100040004), CONST64(0x0004040004040004), CONST64(0x0004040104040004), + CONST64(0x0004040000000404), CONST64(0x0004040100000404), CONST64(0x0004040004000404), CONST64(0x0004040104000404), + CONST64(0x0004040000040404), CONST64(0x0004040100040404), CONST64(0x0004040004040404), CONST64(0x0004040104040404), + CONST64(0x0404040000000000), CONST64(0x0404040100000000), CONST64(0x0404040004000000), CONST64(0x0404040104000000), + CONST64(0x0404040000040000), CONST64(0x0404040100040000), CONST64(0x0404040004040000), CONST64(0x0404040104040000), + CONST64(0x0404040000000400), CONST64(0x0404040100000400), CONST64(0x0404040004000400), CONST64(0x0404040104000400), + CONST64(0x0404040000040400), CONST64(0x0404040100040400), CONST64(0x0404040004040400), CONST64(0x0404040104040400), + CONST64(0x0404040000000004), CONST64(0x0404040100000004), CONST64(0x0404040004000004), CONST64(0x0404040104000004), + CONST64(0x0404040000040004), CONST64(0x0404040100040004), CONST64(0x0404040004040004), CONST64(0x0404040104040004), + CONST64(0x0404040000000404), CONST64(0x0404040100000404), CONST64(0x0404040004000404), CONST64(0x0404040104000404), + CONST64(0x0404040000040404), CONST64(0x0404040100040404), CONST64(0x0404040004040404), CONST64(0x0404040104040404) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000400000000), CONST64(0x0000000010000000), CONST64(0x0000000410000000), + CONST64(0x0000000000100000), CONST64(0x0000000400100000), CONST64(0x0000000010100000), CONST64(0x0000000410100000), + CONST64(0x0000000000001000), CONST64(0x0000000400001000), CONST64(0x0000000010001000), CONST64(0x0000000410001000), + CONST64(0x0000000000101000), CONST64(0x0000000400101000), CONST64(0x0000000010101000), CONST64(0x0000000410101000), + CONST64(0x0000000000000010), CONST64(0x0000000400000010), CONST64(0x0000000010000010), CONST64(0x0000000410000010), + CONST64(0x0000000000100010), CONST64(0x0000000400100010), CONST64(0x0000000010100010), CONST64(0x0000000410100010), + CONST64(0x0000000000001010), CONST64(0x0000000400001010), CONST64(0x0000000010001010), CONST64(0x0000000410001010), + CONST64(0x0000000000101010), CONST64(0x0000000400101010), CONST64(0x0000000010101010), CONST64(0x0000000410101010), + CONST64(0x1000000000000000), CONST64(0x1000000400000000), CONST64(0x1000000010000000), CONST64(0x1000000410000000), + CONST64(0x1000000000100000), CONST64(0x1000000400100000), CONST64(0x1000000010100000), CONST64(0x1000000410100000), + CONST64(0x1000000000001000), CONST64(0x1000000400001000), CONST64(0x1000000010001000), CONST64(0x1000000410001000), + CONST64(0x1000000000101000), CONST64(0x1000000400101000), CONST64(0x1000000010101000), CONST64(0x1000000410101000), + CONST64(0x1000000000000010), CONST64(0x1000000400000010), CONST64(0x1000000010000010), CONST64(0x1000000410000010), + CONST64(0x1000000000100010), CONST64(0x1000000400100010), CONST64(0x1000000010100010), CONST64(0x1000000410100010), + CONST64(0x1000000000001010), CONST64(0x1000000400001010), CONST64(0x1000000010001010), CONST64(0x1000000410001010), + CONST64(0x1000000000101010), CONST64(0x1000000400101010), CONST64(0x1000000010101010), CONST64(0x1000000410101010), + CONST64(0x0010000000000000), CONST64(0x0010000400000000), CONST64(0x0010000010000000), CONST64(0x0010000410000000), + CONST64(0x0010000000100000), CONST64(0x0010000400100000), CONST64(0x0010000010100000), CONST64(0x0010000410100000), + CONST64(0x0010000000001000), CONST64(0x0010000400001000), CONST64(0x0010000010001000), CONST64(0x0010000410001000), + CONST64(0x0010000000101000), CONST64(0x0010000400101000), CONST64(0x0010000010101000), CONST64(0x0010000410101000), + CONST64(0x0010000000000010), CONST64(0x0010000400000010), CONST64(0x0010000010000010), CONST64(0x0010000410000010), + CONST64(0x0010000000100010), CONST64(0x0010000400100010), CONST64(0x0010000010100010), CONST64(0x0010000410100010), + CONST64(0x0010000000001010), CONST64(0x0010000400001010), CONST64(0x0010000010001010), CONST64(0x0010000410001010), + CONST64(0x0010000000101010), CONST64(0x0010000400101010), CONST64(0x0010000010101010), CONST64(0x0010000410101010), + CONST64(0x1010000000000000), CONST64(0x1010000400000000), CONST64(0x1010000010000000), CONST64(0x1010000410000000), + CONST64(0x1010000000100000), CONST64(0x1010000400100000), CONST64(0x1010000010100000), CONST64(0x1010000410100000), + CONST64(0x1010000000001000), CONST64(0x1010000400001000), CONST64(0x1010000010001000), CONST64(0x1010000410001000), + CONST64(0x1010000000101000), CONST64(0x1010000400101000), CONST64(0x1010000010101000), CONST64(0x1010000410101000), + CONST64(0x1010000000000010), CONST64(0x1010000400000010), CONST64(0x1010000010000010), CONST64(0x1010000410000010), + CONST64(0x1010000000100010), CONST64(0x1010000400100010), CONST64(0x1010000010100010), CONST64(0x1010000410100010), + CONST64(0x1010000000001010), CONST64(0x1010000400001010), CONST64(0x1010000010001010), CONST64(0x1010000410001010), + CONST64(0x1010000000101010), CONST64(0x1010000400101010), CONST64(0x1010000010101010), CONST64(0x1010000410101010), + CONST64(0x0000100000000000), CONST64(0x0000100400000000), CONST64(0x0000100010000000), CONST64(0x0000100410000000), + CONST64(0x0000100000100000), CONST64(0x0000100400100000), CONST64(0x0000100010100000), CONST64(0x0000100410100000), + CONST64(0x0000100000001000), CONST64(0x0000100400001000), CONST64(0x0000100010001000), CONST64(0x0000100410001000), + CONST64(0x0000100000101000), CONST64(0x0000100400101000), CONST64(0x0000100010101000), CONST64(0x0000100410101000), + CONST64(0x0000100000000010), CONST64(0x0000100400000010), CONST64(0x0000100010000010), CONST64(0x0000100410000010), + CONST64(0x0000100000100010), CONST64(0x0000100400100010), CONST64(0x0000100010100010), CONST64(0x0000100410100010), + CONST64(0x0000100000001010), CONST64(0x0000100400001010), CONST64(0x0000100010001010), CONST64(0x0000100410001010), + CONST64(0x0000100000101010), CONST64(0x0000100400101010), CONST64(0x0000100010101010), CONST64(0x0000100410101010), + CONST64(0x1000100000000000), CONST64(0x1000100400000000), CONST64(0x1000100010000000), CONST64(0x1000100410000000), + CONST64(0x1000100000100000), CONST64(0x1000100400100000), CONST64(0x1000100010100000), CONST64(0x1000100410100000), + CONST64(0x1000100000001000), CONST64(0x1000100400001000), CONST64(0x1000100010001000), CONST64(0x1000100410001000), + CONST64(0x1000100000101000), CONST64(0x1000100400101000), CONST64(0x1000100010101000), CONST64(0x1000100410101000), + CONST64(0x1000100000000010), CONST64(0x1000100400000010), CONST64(0x1000100010000010), CONST64(0x1000100410000010), + CONST64(0x1000100000100010), CONST64(0x1000100400100010), CONST64(0x1000100010100010), CONST64(0x1000100410100010), + CONST64(0x1000100000001010), CONST64(0x1000100400001010), CONST64(0x1000100010001010), CONST64(0x1000100410001010), + CONST64(0x1000100000101010), CONST64(0x1000100400101010), CONST64(0x1000100010101010), CONST64(0x1000100410101010), + CONST64(0x0010100000000000), CONST64(0x0010100400000000), CONST64(0x0010100010000000), CONST64(0x0010100410000000), + CONST64(0x0010100000100000), CONST64(0x0010100400100000), CONST64(0x0010100010100000), CONST64(0x0010100410100000), + CONST64(0x0010100000001000), CONST64(0x0010100400001000), CONST64(0x0010100010001000), CONST64(0x0010100410001000), + CONST64(0x0010100000101000), CONST64(0x0010100400101000), CONST64(0x0010100010101000), CONST64(0x0010100410101000), + CONST64(0x0010100000000010), CONST64(0x0010100400000010), CONST64(0x0010100010000010), CONST64(0x0010100410000010), + CONST64(0x0010100000100010), CONST64(0x0010100400100010), CONST64(0x0010100010100010), CONST64(0x0010100410100010), + CONST64(0x0010100000001010), CONST64(0x0010100400001010), CONST64(0x0010100010001010), CONST64(0x0010100410001010), + CONST64(0x0010100000101010), CONST64(0x0010100400101010), CONST64(0x0010100010101010), CONST64(0x0010100410101010), + CONST64(0x1010100000000000), CONST64(0x1010100400000000), CONST64(0x1010100010000000), CONST64(0x1010100410000000), + CONST64(0x1010100000100000), CONST64(0x1010100400100000), CONST64(0x1010100010100000), CONST64(0x1010100410100000), + CONST64(0x1010100000001000), CONST64(0x1010100400001000), CONST64(0x1010100010001000), CONST64(0x1010100410001000), + CONST64(0x1010100000101000), CONST64(0x1010100400101000), CONST64(0x1010100010101000), CONST64(0x1010100410101000), + CONST64(0x1010100000000010), CONST64(0x1010100400000010), CONST64(0x1010100010000010), CONST64(0x1010100410000010), + CONST64(0x1010100000100010), CONST64(0x1010100400100010), CONST64(0x1010100010100010), CONST64(0x1010100410100010), + CONST64(0x1010100000001010), CONST64(0x1010100400001010), CONST64(0x1010100010001010), CONST64(0x1010100410001010), + CONST64(0x1010100000101010), CONST64(0x1010100400101010), CONST64(0x1010100010101010), CONST64(0x1010100410101010) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000001000000000), CONST64(0x0000000040000000), CONST64(0x0000001040000000), + CONST64(0x0000000000400000), CONST64(0x0000001000400000), CONST64(0x0000000040400000), CONST64(0x0000001040400000), + CONST64(0x0000000000004000), CONST64(0x0000001000004000), CONST64(0x0000000040004000), CONST64(0x0000001040004000), + CONST64(0x0000000000404000), CONST64(0x0000001000404000), CONST64(0x0000000040404000), CONST64(0x0000001040404000), + CONST64(0x0000000000000040), CONST64(0x0000001000000040), CONST64(0x0000000040000040), CONST64(0x0000001040000040), + CONST64(0x0000000000400040), CONST64(0x0000001000400040), CONST64(0x0000000040400040), CONST64(0x0000001040400040), + CONST64(0x0000000000004040), CONST64(0x0000001000004040), CONST64(0x0000000040004040), CONST64(0x0000001040004040), + CONST64(0x0000000000404040), CONST64(0x0000001000404040), CONST64(0x0000000040404040), CONST64(0x0000001040404040), + CONST64(0x4000000000000000), CONST64(0x4000001000000000), CONST64(0x4000000040000000), CONST64(0x4000001040000000), + CONST64(0x4000000000400000), CONST64(0x4000001000400000), CONST64(0x4000000040400000), CONST64(0x4000001040400000), + CONST64(0x4000000000004000), CONST64(0x4000001000004000), CONST64(0x4000000040004000), CONST64(0x4000001040004000), + CONST64(0x4000000000404000), CONST64(0x4000001000404000), CONST64(0x4000000040404000), CONST64(0x4000001040404000), + CONST64(0x4000000000000040), CONST64(0x4000001000000040), CONST64(0x4000000040000040), CONST64(0x4000001040000040), + CONST64(0x4000000000400040), CONST64(0x4000001000400040), CONST64(0x4000000040400040), CONST64(0x4000001040400040), + CONST64(0x4000000000004040), CONST64(0x4000001000004040), CONST64(0x4000000040004040), CONST64(0x4000001040004040), + CONST64(0x4000000000404040), CONST64(0x4000001000404040), CONST64(0x4000000040404040), CONST64(0x4000001040404040), + CONST64(0x0040000000000000), CONST64(0x0040001000000000), CONST64(0x0040000040000000), CONST64(0x0040001040000000), + CONST64(0x0040000000400000), CONST64(0x0040001000400000), CONST64(0x0040000040400000), CONST64(0x0040001040400000), + CONST64(0x0040000000004000), CONST64(0x0040001000004000), CONST64(0x0040000040004000), CONST64(0x0040001040004000), + CONST64(0x0040000000404000), CONST64(0x0040001000404000), CONST64(0x0040000040404000), CONST64(0x0040001040404000), + CONST64(0x0040000000000040), CONST64(0x0040001000000040), CONST64(0x0040000040000040), CONST64(0x0040001040000040), + CONST64(0x0040000000400040), CONST64(0x0040001000400040), CONST64(0x0040000040400040), CONST64(0x0040001040400040), + CONST64(0x0040000000004040), CONST64(0x0040001000004040), CONST64(0x0040000040004040), CONST64(0x0040001040004040), + CONST64(0x0040000000404040), CONST64(0x0040001000404040), CONST64(0x0040000040404040), CONST64(0x0040001040404040), + CONST64(0x4040000000000000), CONST64(0x4040001000000000), CONST64(0x4040000040000000), CONST64(0x4040001040000000), + CONST64(0x4040000000400000), CONST64(0x4040001000400000), CONST64(0x4040000040400000), CONST64(0x4040001040400000), + CONST64(0x4040000000004000), CONST64(0x4040001000004000), CONST64(0x4040000040004000), CONST64(0x4040001040004000), + CONST64(0x4040000000404000), CONST64(0x4040001000404000), CONST64(0x4040000040404000), CONST64(0x4040001040404000), + CONST64(0x4040000000000040), CONST64(0x4040001000000040), CONST64(0x4040000040000040), CONST64(0x4040001040000040), + CONST64(0x4040000000400040), CONST64(0x4040001000400040), CONST64(0x4040000040400040), CONST64(0x4040001040400040), + CONST64(0x4040000000004040), CONST64(0x4040001000004040), CONST64(0x4040000040004040), CONST64(0x4040001040004040), + CONST64(0x4040000000404040), CONST64(0x4040001000404040), CONST64(0x4040000040404040), CONST64(0x4040001040404040), + CONST64(0x0000400000000000), CONST64(0x0000401000000000), CONST64(0x0000400040000000), CONST64(0x0000401040000000), + CONST64(0x0000400000400000), CONST64(0x0000401000400000), CONST64(0x0000400040400000), CONST64(0x0000401040400000), + CONST64(0x0000400000004000), CONST64(0x0000401000004000), CONST64(0x0000400040004000), CONST64(0x0000401040004000), + CONST64(0x0000400000404000), CONST64(0x0000401000404000), CONST64(0x0000400040404000), CONST64(0x0000401040404000), + CONST64(0x0000400000000040), CONST64(0x0000401000000040), CONST64(0x0000400040000040), CONST64(0x0000401040000040), + CONST64(0x0000400000400040), CONST64(0x0000401000400040), CONST64(0x0000400040400040), CONST64(0x0000401040400040), + CONST64(0x0000400000004040), CONST64(0x0000401000004040), CONST64(0x0000400040004040), CONST64(0x0000401040004040), + CONST64(0x0000400000404040), CONST64(0x0000401000404040), CONST64(0x0000400040404040), CONST64(0x0000401040404040), + CONST64(0x4000400000000000), CONST64(0x4000401000000000), CONST64(0x4000400040000000), CONST64(0x4000401040000000), + CONST64(0x4000400000400000), CONST64(0x4000401000400000), CONST64(0x4000400040400000), CONST64(0x4000401040400000), + CONST64(0x4000400000004000), CONST64(0x4000401000004000), CONST64(0x4000400040004000), CONST64(0x4000401040004000), + CONST64(0x4000400000404000), CONST64(0x4000401000404000), CONST64(0x4000400040404000), CONST64(0x4000401040404000), + CONST64(0x4000400000000040), CONST64(0x4000401000000040), CONST64(0x4000400040000040), CONST64(0x4000401040000040), + CONST64(0x4000400000400040), CONST64(0x4000401000400040), CONST64(0x4000400040400040), CONST64(0x4000401040400040), + CONST64(0x4000400000004040), CONST64(0x4000401000004040), CONST64(0x4000400040004040), CONST64(0x4000401040004040), + CONST64(0x4000400000404040), CONST64(0x4000401000404040), CONST64(0x4000400040404040), CONST64(0x4000401040404040), + CONST64(0x0040400000000000), CONST64(0x0040401000000000), CONST64(0x0040400040000000), CONST64(0x0040401040000000), + CONST64(0x0040400000400000), CONST64(0x0040401000400000), CONST64(0x0040400040400000), CONST64(0x0040401040400000), + CONST64(0x0040400000004000), CONST64(0x0040401000004000), CONST64(0x0040400040004000), CONST64(0x0040401040004000), + CONST64(0x0040400000404000), CONST64(0x0040401000404000), CONST64(0x0040400040404000), CONST64(0x0040401040404000), + CONST64(0x0040400000000040), CONST64(0x0040401000000040), CONST64(0x0040400040000040), CONST64(0x0040401040000040), + CONST64(0x0040400000400040), CONST64(0x0040401000400040), CONST64(0x0040400040400040), CONST64(0x0040401040400040), + CONST64(0x0040400000004040), CONST64(0x0040401000004040), CONST64(0x0040400040004040), CONST64(0x0040401040004040), + CONST64(0x0040400000404040), CONST64(0x0040401000404040), CONST64(0x0040400040404040), CONST64(0x0040401040404040), + CONST64(0x4040400000000000), CONST64(0x4040401000000000), CONST64(0x4040400040000000), CONST64(0x4040401040000000), + CONST64(0x4040400000400000), CONST64(0x4040401000400000), CONST64(0x4040400040400000), CONST64(0x4040401040400000), + CONST64(0x4040400000004000), CONST64(0x4040401000004000), CONST64(0x4040400040004000), CONST64(0x4040401040004000), + CONST64(0x4040400000404000), CONST64(0x4040401000404000), CONST64(0x4040400040404000), CONST64(0x4040401040404000), + CONST64(0x4040400000000040), CONST64(0x4040401000000040), CONST64(0x4040400040000040), CONST64(0x4040401040000040), + CONST64(0x4040400000400040), CONST64(0x4040401000400040), CONST64(0x4040400040400040), CONST64(0x4040401040400040), + CONST64(0x4040400000004040), CONST64(0x4040401000004040), CONST64(0x4040400040004040), CONST64(0x4040401040004040), + CONST64(0x4040400000404040), CONST64(0x4040401000404040), CONST64(0x4040400040404040), CONST64(0x4040401040404040) + }}; + +#endif + + +static void cookey(const ulong32 *raw1, ulong32 *keyout); + +#ifdef LTC_CLEAN_STACK +static void _deskey(const unsigned char *key, short edf, ulong32 *keyout) +#else +static void deskey(const unsigned char *key, short edf, ulong32 *keyout) +#endif +{ + ulong32 i, j, l, m, n, kn[32]; + unsigned char pc1m[56], pcr[56]; + + for (j=0; j < 56; j++) { + l = (ulong32)pc1[j]; + m = l & 7; + pc1m[j] = (unsigned char)((key[l >> 3U] & bytebit[m]) == bytebit[m] ? 1 : 0); + } + + for (i=0; i < 16; i++) { + if (edf == DE1) { + m = (15 - i) << 1; + } else { + m = i << 1; + } + n = m + 1; + kn[m] = kn[n] = 0L; + for (j=0; j < 28; j++) { + l = j + (ulong32)totrot[i]; + if (l < 28) { + pcr[j] = pc1m[l]; + } else { + pcr[j] = pc1m[l - 28]; + } + } + for (/*j = 28*/; j < 56; j++) { + l = j + (ulong32)totrot[i]; + if (l < 56) { + pcr[j] = pc1m[l]; + } else { + pcr[j] = pc1m[l - 28]; + } + } + for (j=0; j < 24; j++) { + if ((int)pcr[(int)pc2[j]] != 0) { + kn[m] |= bigbyte[j]; + } + if ((int)pcr[(int)pc2[j+24]] != 0) { + kn[n] |= bigbyte[j]; + } + } + } + + cookey(kn, keyout); +} + +#ifdef LTC_CLEAN_STACK +static void deskey(const unsigned char *key, short edf, ulong32 *keyout) +{ + _deskey(key, edf, keyout); + burn_stack(sizeof(int)*5 + sizeof(ulong32)*32 + sizeof(unsigned char)*112); +} +#endif + +#ifdef LTC_CLEAN_STACK +static void _cookey(const ulong32 *raw1, ulong32 *keyout) +#else +static void cookey(const ulong32 *raw1, ulong32 *keyout) +#endif +{ + ulong32 *cook; + const ulong32 *raw0; + ulong32 dough[32]; + int i; + + cook = dough; + for(i=0; i < 16; i++, raw1++) + { + raw0 = raw1++; + *cook = (*raw0 & 0x00fc0000L) << 6; + *cook |= (*raw0 & 0x00000fc0L) << 10; + *cook |= (*raw1 & 0x00fc0000L) >> 10; + *cook++ |= (*raw1 & 0x00000fc0L) >> 6; + *cook = (*raw0 & 0x0003f000L) << 12; + *cook |= (*raw0 & 0x0000003fL) << 16; + *cook |= (*raw1 & 0x0003f000L) >> 4; + *cook++ |= (*raw1 & 0x0000003fL); + } + + XMEMCPY(keyout, dough, sizeof dough); +} + +#ifdef LTC_CLEAN_STACK +static void cookey(const ulong32 *raw1, ulong32 *keyout) +{ + _cookey(raw1, keyout); + burn_stack(sizeof(ulong32 *) * 2 + sizeof(ulong32)*32 + sizeof(int)); +} +#endif + +#ifndef LTC_CLEAN_STACK +static void desfunc(ulong32 *block, const ulong32 *keys) +#else +static void _desfunc(ulong32 *block, const ulong32 *keys) +#endif +{ + ulong32 work, right, leftt; + int cur_round; + + leftt = block[0]; + right = block[1]; + +#ifdef LTC_SMALL_CODE + work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; + right ^= work; + leftt ^= (work << 4); + + work = ((leftt >> 16) ^ right) & 0x0000ffffL; + right ^= work; + leftt ^= (work << 16); + + work = ((right >> 2) ^ leftt) & 0x33333333L; + leftt ^= work; + right ^= (work << 2); + + work = ((right >> 8) ^ leftt) & 0x00ff00ffL; + leftt ^= work; + right ^= (work << 8); + + right = ROLc(right, 1); + work = (leftt ^ right) & 0xaaaaaaaaL; + + leftt ^= work; + right ^= work; + leftt = ROLc(leftt, 1); +#else + { + ulong64 tmp; + tmp = des_ip[0][byte(leftt, 0)] ^ + des_ip[1][byte(leftt, 1)] ^ + des_ip[2][byte(leftt, 2)] ^ + des_ip[3][byte(leftt, 3)] ^ + des_ip[4][byte(right, 0)] ^ + des_ip[5][byte(right, 1)] ^ + des_ip[6][byte(right, 2)] ^ + des_ip[7][byte(right, 3)]; + leftt = (ulong32)(tmp >> 32); + right = (ulong32)(tmp & 0xFFFFFFFFUL); + } +#endif + + for (cur_round = 0; cur_round < 8; cur_round++) { + work = RORc(right, 4) ^ *keys++; + leftt ^= SP7[work & 0x3fL] + ^ SP5[(work >> 8) & 0x3fL] + ^ SP3[(work >> 16) & 0x3fL] + ^ SP1[(work >> 24) & 0x3fL]; + work = right ^ *keys++; + leftt ^= SP8[ work & 0x3fL] + ^ SP6[(work >> 8) & 0x3fL] + ^ SP4[(work >> 16) & 0x3fL] + ^ SP2[(work >> 24) & 0x3fL]; + + work = RORc(leftt, 4) ^ *keys++; + right ^= SP7[ work & 0x3fL] + ^ SP5[(work >> 8) & 0x3fL] + ^ SP3[(work >> 16) & 0x3fL] + ^ SP1[(work >> 24) & 0x3fL]; + work = leftt ^ *keys++; + right ^= SP8[ work & 0x3fL] + ^ SP6[(work >> 8) & 0x3fL] + ^ SP4[(work >> 16) & 0x3fL] + ^ SP2[(work >> 24) & 0x3fL]; + } + +#ifdef LTC_SMALL_CODE + right = RORc(right, 1); + work = (leftt ^ right) & 0xaaaaaaaaL; + leftt ^= work; + right ^= work; + leftt = RORc(leftt, 1); + work = ((leftt >> 8) ^ right) & 0x00ff00ffL; + right ^= work; + leftt ^= (work << 8); + /* -- */ + work = ((leftt >> 2) ^ right) & 0x33333333L; + right ^= work; + leftt ^= (work << 2); + work = ((right >> 16) ^ leftt) & 0x0000ffffL; + leftt ^= work; + right ^= (work << 16); + work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; + leftt ^= work; + right ^= (work << 4); +#else + { + ulong64 tmp; + tmp = des_fp[0][byte(leftt, 0)] ^ + des_fp[1][byte(leftt, 1)] ^ + des_fp[2][byte(leftt, 2)] ^ + des_fp[3][byte(leftt, 3)] ^ + des_fp[4][byte(right, 0)] ^ + des_fp[5][byte(right, 1)] ^ + des_fp[6][byte(right, 2)] ^ + des_fp[7][byte(right, 3)]; + leftt = (ulong32)(tmp >> 32); + right = (ulong32)(tmp & 0xFFFFFFFFUL); + } +#endif + + block[0] = right; + block[1] = leftt; +} + +#ifdef LTC_CLEAN_STACK +static void desfunc(ulong32 *block, const ulong32 *keys) +{ + _desfunc(block, keys); + burn_stack(sizeof(ulong32) * 4 + sizeof(int)); +} +#endif + + /** + Initialize the LTC_DES block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (num_rounds != 0 && num_rounds != 16) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 8) { + return CRYPT_INVALID_KEYSIZE; + } + + deskey(key, EN0, skey->des.ek); + deskey(key, DE1, skey->des.dk); + + return CRYPT_OK; +} + + /** + Initialize the 3LTC_DES-EDE block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if(num_rounds != 0 && num_rounds != 16) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 24) { + return CRYPT_INVALID_KEYSIZE; + } + + deskey(key, EN0, skey->des3.ek[0]); + deskey(key+8, DE1, skey->des3.ek[1]); + deskey(key+16, EN0, skey->des3.ek[2]); + + deskey(key, DE1, skey->des3.dk[2]); + deskey(key+8, EN0, skey->des3.dk[1]); + deskey(key+16, DE1, skey->des3.dk[0]); + + return CRYPT_OK; +} + +/** + Encrypts a block of text with LTC_DES + @param pt The input plaintext (8 bytes) + @param ct The output ciphertext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + ulong32 work[2]; + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + LOAD32H(work[0], pt+0); + LOAD32H(work[1], pt+4); + desfunc(work, skey->des.ek); + STORE32H(work[0],ct+0); + STORE32H(work[1],ct+4); + return CRYPT_OK; +} + +/** + Decrypts a block of text with LTC_DES + @param ct The input ciphertext (8 bytes) + @param pt The output plaintext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + ulong32 work[2]; + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + LOAD32H(work[0], ct+0); + LOAD32H(work[1], ct+4); + desfunc(work, skey->des.dk); + STORE32H(work[0],pt+0); + STORE32H(work[1],pt+4); + return CRYPT_OK; +} + +/** + Encrypts a block of text with 3LTC_DES-EDE + @param pt The input plaintext (8 bytes) + @param ct The output ciphertext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + ulong32 work[2]; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + LOAD32H(work[0], pt+0); + LOAD32H(work[1], pt+4); + desfunc(work, skey->des3.ek[0]); + desfunc(work, skey->des3.ek[1]); + desfunc(work, skey->des3.ek[2]); + STORE32H(work[0],ct+0); + STORE32H(work[1],ct+4); + return CRYPT_OK; +} + +/** + Decrypts a block of text with 3LTC_DES-EDE + @param ct The input ciphertext (8 bytes) + @param pt The output plaintext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + ulong32 work[2]; + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + LOAD32H(work[0], ct+0); + LOAD32H(work[1], ct+4); + desfunc(work, skey->des3.dk[0]); + desfunc(work, skey->des3.dk[1]); + desfunc(work, skey->des3.dk[2]); + STORE32H(work[0],pt+0); + STORE32H(work[1],pt+4); + return CRYPT_OK; +} + +/** + Performs a self-test of the LTC_DES block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int des_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + int err; + static const struct des_test_case { + int num, mode; /* mode 1 = encrypt */ + unsigned char key[8], txt[8], out[8]; + } cases[] = { + { 1, 1, { 0x10, 0x31, 0x6E, 0x02, 0x8C, 0x8F, 0x3B, 0x4A }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x82, 0xDC, 0xBA, 0xFB, 0xDE, 0xAB, 0x66, 0x02 } }, + { 2, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 3, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0xDD, 0x7F, 0x12, 0x1C, 0xA5, 0x01, 0x56, 0x19 }, + { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 4, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x2E, 0x86, 0x53, 0x10, 0x4F, 0x38, 0x34, 0xEA }, + { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 5, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x4B, 0xD3, 0x88, 0xFF, 0x6C, 0xD8, 0x1D, 0x4F }, + { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 6, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x20, 0xB9, 0xE7, 0x67, 0xB2, 0xFB, 0x14, 0x56 }, + { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 7, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x55, 0x57, 0x93, 0x80, 0xD7, 0x71, 0x38, 0xEF }, + { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 8, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x6C, 0xC5, 0xDE, 0xFA, 0xAF, 0x04, 0x51, 0x2F }, + { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 9, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 }, + { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + {10, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0xD9, 0x03, 0x1B, 0x02, 0x71, 0xBD, 0x5A, 0x0A }, + { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + + { 1, 0, { 0x10, 0x31, 0x6E, 0x02, 0x8C, 0x8F, 0x3B, 0x4A }, + { 0x82, 0xDC, 0xBA, 0xFB, 0xDE, 0xAB, 0x66, 0x02 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 2, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00 } }, + { 3, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xDD, 0x7F, 0x12, 0x1C, 0xA5, 0x01, 0x56, 0x19 } }, + { 4, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x2E, 0x86, 0x53, 0x10, 0x4F, 0x38, 0x34, 0xEA } }, + { 5, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x4B, 0xD3, 0x88, 0xFF, 0x6C, 0xD8, 0x1D, 0x4F } }, + { 6, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x20, 0xB9, 0xE7, 0x67, 0xB2, 0xFB, 0x14, 0x56 } }, + { 7, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x55, 0x57, 0x93, 0x80, 0xD7, 0x71, 0x38, 0xEF } }, + { 8, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x6C, 0xC5, 0xDE, 0xFA, 0xAF, 0x04, 0x51, 0x2F } }, + { 9, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 } }, + {10, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xD9, 0x03, 0x1B, 0x02, 0x71, 0xBD, 0x5A, 0x0A } } + + /*** more test cases you could add if you are not convinced (the above test cases aren't really too good): + + key plaintext ciphertext + 0000000000000000 0000000000000000 8CA64DE9C1B123A7 + FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF 7359B2163E4EDC58 + 3000000000000000 1000000000000001 958E6E627A05557B + 1111111111111111 1111111111111111 F40379AB9E0EC533 + 0123456789ABCDEF 1111111111111111 17668DFC7292532D + 1111111111111111 0123456789ABCDEF 8A5AE1F81AB8F2DD + 0000000000000000 0000000000000000 8CA64DE9C1B123A7 + FEDCBA9876543210 0123456789ABCDEF ED39D950FA74BCC4 + 7CA110454A1A6E57 01A1D6D039776742 690F5B0D9A26939B + 0131D9619DC1376E 5CD54CA83DEF57DA 7A389D10354BD271 + 07A1133E4A0B2686 0248D43806F67172 868EBB51CAB4599A + 3849674C2602319E 51454B582DDF440A 7178876E01F19B2A + 04B915BA43FEB5B6 42FD443059577FA2 AF37FB421F8C4095 + 0113B970FD34F2CE 059B5E0851CF143A 86A560F10EC6D85B + 0170F175468FB5E6 0756D8E0774761D2 0CD3DA020021DC09 + 43297FAD38E373FE 762514B829BF486A EA676B2CB7DB2B7A + 07A7137045DA2A16 3BDD119049372802 DFD64A815CAF1A0F + 04689104C2FD3B2F 26955F6835AF609A 5C513C9C4886C088 + 37D06BB516CB7546 164D5E404F275232 0A2AEEAE3FF4AB77 + 1F08260D1AC2465E 6B056E18759F5CCA EF1BF03E5DFA575A + 584023641ABA6176 004BD6EF09176062 88BF0DB6D70DEE56 + 025816164629B007 480D39006EE762F2 A1F9915541020B56 + 49793EBC79B3258F 437540C8698F3CFA 6FBF1CAFCFFD0556 + 4FB05E1515AB73A7 072D43A077075292 2F22E49BAB7CA1AC + 49E95D6D4CA229BF 02FE55778117F12A 5A6B612CC26CCE4A + 018310DC409B26D6 1D9D5C5018F728C2 5F4C038ED12B2E41 + 1C587F1C13924FEF 305532286D6F295A 63FAC0D034D9F793 + 0101010101010101 0123456789ABCDEF 617B3A0CE8F07100 + 1F1F1F1F0E0E0E0E 0123456789ABCDEF DB958605F8C8C606 + E0FEE0FEF1FEF1FE 0123456789ABCDEF EDBFD1C66C29CCC7 + 0000000000000000 FFFFFFFFFFFFFFFF 355550B2150E2451 + FFFFFFFFFFFFFFFF 0000000000000000 CAAAAF4DEAF1DBAE + 0123456789ABCDEF 0000000000000000 D5D44FF720683D0D + FEDCBA9876543210 FFFFFFFFFFFFFFFF 2A2BB008DF97C2F2 + + http://www.ecs.soton.ac.uk/~prw99r/ez438/vectors.txt + ***/ + }; + int i, y; + unsigned char tmp[8]; + symmetric_key des; + + for(i=0; i < (int)(sizeof(cases)/sizeof(cases[0])); i++) + { + if ((err = des_setup(cases[i].key, 8, 0, &des)) != CRYPT_OK) { + return err; + } + if (cases[i].mode != 0) { + des_ecb_encrypt(cases[i].txt, tmp, &des); + } else { + des_ecb_decrypt(cases[i].txt, tmp, &des); + } + + if (XMEMCMP(cases[i].out, tmp, sizeof(tmp)) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[y] = 0; + for (y = 0; y < 1000; y++) des_ecb_encrypt(tmp, tmp, &des); + for (y = 0; y < 1000; y++) des_ecb_decrypt(tmp, tmp, &des); + for (y = 0; y < 8; y++) if (tmp[y] != 0) return CRYPT_FAIL_TESTVECTOR; +} + + return CRYPT_OK; + #endif +} + +int des3_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + unsigned char key[24], pt[8], ct[8], tmp[8]; + symmetric_key skey; + int x, err; + + if ((err = des_test()) != CRYPT_OK) { + return err; + } + + for (x = 0; x < 8; x++) { + pt[x] = x; + } + + for (x = 0; x < 24; x++) { + key[x] = x; + } + + if ((err = des3_setup(key, 24, 0, &skey)) != CRYPT_OK) { + return err; + } + + des3_ecb_encrypt(pt, ct, &skey); + des3_ecb_decrypt(ct, tmp, &skey); + + if (XMEMCMP(pt, tmp, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; + #endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void des_done(symmetric_key *skey) +{ +} + +/** Terminate the context + @param skey The scheduled key +*/ +void des3_done(symmetric_key *skey) +{ +} + + +/** + Gets suitable key size + @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. + @return CRYPT_OK if the input key size is acceptable. +*/ +int des_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if(*keysize < 8) { + return CRYPT_INVALID_KEYSIZE; + } + *keysize = 8; + return CRYPT_OK; +} + +/** + Gets suitable key size + @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. + @return CRYPT_OK if the input key size is acceptable. +*/ +int des3_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if(*keysize < 24) { + return CRYPT_INVALID_KEYSIZE; + } + *keysize = 24; + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/des.c,v $ */ +/* $Revision: 1.15 $ */ +/* $Date: 2007/05/12 14:20:27 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/kasumi.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/kasumi.c new file mode 100644 index 0000000000..86f285c994 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/kasumi.c @@ -0,0 +1,319 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file kasumi.c + Implementation of the 3GPP Kasumi block cipher + Derived from the 3GPP standard source code +*/ + +#include "tomcrypt.h" + +#ifdef LTC_KASUMI + +#include +/* typedef unsigned u16; */ + +#define ROL16(x, y) ((((x)<<(y)) | ((x)>>(16-(y)))) & 0xFFFF) + +const struct ltc_cipher_descriptor kasumi_desc = { + "kasumi", + 21, + 16, 16, 8, 8, + &kasumi_setup, + &kasumi_ecb_encrypt, + &kasumi_ecb_decrypt, + &kasumi_test, + &kasumi_done, + &kasumi_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +static uint16_t FI( uint16_t in, uint16_t subkey ) +{ + uint16_t nine, seven; + static const uint16_t S7[128] = { + 54, 50, 62, 56, 22, 34, 94, 96, 38, 6, 63, 93, 2, 18,123, 33, + 55,113, 39,114, 21, 67, 65, 12, 47, 73, 46, 27, 25,111,124, 81, + 53, 9,121, 79, 52, 60, 58, 48,101,127, 40,120,104, 70, 71, 43, + 20,122, 72, 61, 23,109, 13,100, 77, 1, 16, 7, 82, 10,105, 98, + 117,116, 76, 11, 89,106, 0,125,118, 99, 86, 69, 30, 57,126, 87, + 112, 51, 17, 5, 95, 14, 90, 84, 91, 8, 35,103, 32, 97, 28, 66, + 102, 31, 26, 45, 75, 4, 85, 92, 37, 74, 80, 49, 68, 29,115, 44, + 64,107,108, 24,110, 83, 36, 78, 42, 19, 15, 41, 88,119, 59, 3 }; + static const uint16_t S9[512] = { + 167,239,161,379,391,334, 9,338, 38,226, 48,358,452,385, 90,397, + 183,253,147,331,415,340, 51,362,306,500,262, 82,216,159,356,177, + 175,241,489, 37,206, 17, 0,333, 44,254,378, 58,143,220, 81,400, + 95, 3,315,245, 54,235,218,405,472,264,172,494,371,290,399, 76, + 165,197,395,121,257,480,423,212,240, 28,462,176,406,507,288,223, + 501,407,249,265, 89,186,221,428,164, 74,440,196,458,421,350,163, + 232,158,134,354, 13,250,491,142,191, 69,193,425,152,227,366,135, + 344,300,276,242,437,320,113,278, 11,243, 87,317, 36, 93,496, 27, + 487,446,482, 41, 68,156,457,131,326,403,339, 20, 39,115,442,124, + 475,384,508, 53,112,170,479,151,126,169, 73,268,279,321,168,364, + 363,292, 46,499,393,327,324, 24,456,267,157,460,488,426,309,229, + 439,506,208,271,349,401,434,236, 16,209,359, 52, 56,120,199,277, + 465,416,252,287,246, 6, 83,305,420,345,153,502, 65, 61,244,282, + 173,222,418, 67,386,368,261,101,476,291,195,430, 49, 79,166,330, + 280,383,373,128,382,408,155,495,367,388,274,107,459,417, 62,454, + 132,225,203,316,234, 14,301, 91,503,286,424,211,347,307,140,374, + 35,103,125,427, 19,214,453,146,498,314,444,230,256,329,198,285, + 50,116, 78,410, 10,205,510,171,231, 45,139,467, 29, 86,505, 32, + 72, 26,342,150,313,490,431,238,411,325,149,473, 40,119,174,355, + 185,233,389, 71,448,273,372, 55,110,178,322, 12,469,392,369,190, + 1,109,375,137,181, 88, 75,308,260,484, 98,272,370,275,412,111, + 336,318, 4,504,492,259,304, 77,337,435, 21,357,303,332,483, 18, + 47, 85, 25,497,474,289,100,269,296,478,270,106, 31,104,433, 84, + 414,486,394, 96, 99,154,511,148,413,361,409,255,162,215,302,201, + 266,351,343,144,441,365,108,298,251, 34,182,509,138,210,335,133, + 311,352,328,141,396,346,123,319,450,281,429,228,443,481, 92,404, + 485,422,248,297, 23,213,130,466, 22,217,283, 70,294,360,419,127, + 312,377, 7,468,194, 2,117,295,463,258,224,447,247,187, 80,398, + 284,353,105,390,299,471,470,184, 57,200,348, 63,204,188, 33,451, + 97, 30,310,219, 94,160,129,493, 64,179,263,102,189,207,114,402, + 438,477,387,122,192, 42,381, 5,145,118,180,449,293,323,136,380, + 43, 66, 60,455,341,445,202,432, 8,237, 15,376,436,464, 59,461}; + + /* The sixteen bit input is split into two unequal halves, * + * nine bits and seven bits - as is the subkey */ + + nine = (uint16_t)(in>>7)&0x1FF; + seven = (uint16_t)(in&0x7F); + + /* Now run the various operations */ + nine = (uint16_t)(S9[nine] ^ seven); + seven = (uint16_t)(S7[seven] ^ (nine & 0x7F)); + seven ^= (subkey>>9); + nine ^= (subkey&0x1FF); + nine = (uint16_t)(S9[nine] ^ seven); + seven = (uint16_t)(S7[seven] ^ (nine & 0x7F)); + return (uint16_t)(seven<<9) + nine; +} + +static ulong32 FO( ulong32 in, int round_no, symmetric_key *key) +{ + uint16_t left, right; + + /* Split the input into two 16-bit words */ + left = (uint16_t)(in>>16); + right = (uint16_t) in&0xFFFF; + + /* Now apply the same basic transformation three times */ + left ^= key->kasumi.KOi1[round_no]; + left = FI( left, key->kasumi.KIi1[round_no] ); + left ^= right; + + right ^= key->kasumi.KOi2[round_no]; + right = FI( right, key->kasumi.KIi2[round_no] ); + right ^= left; + + left ^= key->kasumi.KOi3[round_no]; + left = FI( left, key->kasumi.KIi3[round_no] ); + left ^= right; + + return (((ulong32)right)<<16)+left; +} + +static ulong32 FL( ulong32 in, int round_no, symmetric_key *key ) +{ + uint16_t l, r, a, b; + /* split out the left and right halves */ + l = (uint16_t)(in>>16); + r = (uint16_t)(in)&0xFFFF; + /* do the FL() operations */ + a = (uint16_t) (l & key->kasumi.KLi1[round_no]); + r ^= ROL16(a,1); + b = (uint16_t)(r | key->kasumi.KLi2[round_no]); + l ^= ROL16(b,1); + /* put the two halves back together */ + + return (((ulong32)l)<<16) + r; +} + +int kasumi_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + ulong32 left, right, temp; + int n; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + LOAD32H(left, pt); + LOAD32H(right, pt+4); + + for (n = 0; n <= 7; ) { + temp = FL(left, n, skey); + temp = FO(temp, n++, skey); + right ^= temp; + temp = FO(right, n, skey); + temp = FL(temp, n++, skey); + left ^= temp; + } + + STORE32H(left, ct); + STORE32H(right, ct+4); + + return CRYPT_OK; +} + +int kasumi_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + ulong32 left, right, temp; + int n; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + LOAD32H(left, ct); + LOAD32H(right, ct+4); + + for (n = 7; n >= 0; ) { + temp = FO(right, n, skey); + temp = FL(temp, n--, skey); + left ^= temp; + temp = FL(left, n, skey); + temp = FO(temp, n--, skey); + right ^= temp; + } + + STORE32H(left, pt); + STORE32H(right, pt+4); + + return CRYPT_OK; +} + +int kasumi_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + static const uint16_t C[8] = { 0x0123,0x4567,0x89AB,0xCDEF, 0xFEDC,0xBA98,0x7654,0x3210 }; + uint16_t ukey[8], Kprime[8]; + int n; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (keylen != 16) { + return CRYPT_INVALID_KEYSIZE; + } + + if (num_rounds != 0 && num_rounds != 8) { + return CRYPT_INVALID_ROUNDS; + } + + /* Start by ensuring the subkeys are endian correct on a 16-bit basis */ + for (n = 0; n < 8; n++ ) { + ukey[n] = (((uint16_t)key[2*n]) << 8) | key[2*n+1]; + } + + /* Now build the K'[] keys */ + for (n = 0; n < 8; n++) { + Kprime[n] = ukey[n] ^ C[n]; + } + + /* Finally construct the various sub keys */ + for(n = 0; n < 8; n++) { + skey->kasumi.KLi1[n] = ROL16(ukey[n],1); + skey->kasumi.KLi2[n] = Kprime[(n+2)&0x7]; + skey->kasumi.KOi1[n] = ROL16(ukey[(n+1)&0x7],5); + skey->kasumi.KOi2[n] = ROL16(ukey[(n+5)&0x7],8); + skey->kasumi.KOi3[n] = ROL16(ukey[(n+6)&0x7],13); + skey->kasumi.KIi1[n] = Kprime[(n+4)&0x7]; + skey->kasumi.KIi2[n] = Kprime[(n+3)&0x7]; + skey->kasumi.KIi3[n] = Kprime[(n+7)&0x7]; + } + + return CRYPT_OK; +} + +void kasumi_done(symmetric_key *skey) +{ +} + +int kasumi_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize >= 16) { + *keysize = 16; + return CRYPT_OK; + } else { + return CRYPT_INVALID_KEYSIZE; + } +} + +int kasumi_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + unsigned char key[16], pt[8], ct[8]; + } tests[] = { + +{ + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x4B, 0x58, 0xA7, 0x71, 0xAF, 0xC7, 0xE5, 0xE8 } +}, + +{ + { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x7E, 0xEF, 0x11, 0x3C, 0x95, 0xBB, 0x5A, 0x77 } +}, + +{ + { 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x5F, 0x14, 0x06, 0x86, 0xD7, 0xAD, 0x5A, 0x39 }, +}, + +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x2E, 0x14, 0x91, 0xCF, 0x70, 0xAA, 0x46, 0x5D } +}, + +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xB5, 0x45, 0x86, 0xF4, 0xAB, 0x9A, 0xE5, 0x46 } +}, + +}; + unsigned char buf[2][8]; + symmetric_key key; + int err, x; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + if ((err = kasumi_setup(tests[x].key, 16, 0, &key)) != CRYPT_OK) { + return err; + } + if ((err = kasumi_ecb_encrypt(tests[x].pt, buf[0], &key)) != CRYPT_OK) { + return err; + } + if ((err = kasumi_ecb_decrypt(tests[x].ct, buf[1], &key)) != CRYPT_OK) { + return err; + } + if (XMEMCMP(tests[x].pt, buf[1], 8) || XMEMCMP(tests[x].ct, buf[0], 8)) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/kasumi.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/khazad.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/khazad.c new file mode 100644 index 0000000000..d2c0f6b08c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/khazad.c @@ -0,0 +1,855 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file khazad.c + Khazad implementation derived from public domain source + Authors: Paulo S.L.M. Barreto and Vincent Rijmen. +*/ + +#ifdef LTC_KHAZAD + +const struct ltc_cipher_descriptor khazad_desc = { + "khazad", + 18, + 16, 16, 8, 8, + &khazad_setup, + &khazad_ecb_encrypt, + &khazad_ecb_decrypt, + &khazad_test, + &khazad_done, + &khazad_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +#define R 8 +#define KEYSIZE 128 +#define KEYSIZEB (KEYSIZE/8) +#define BLOCKSIZE 64 +#define BLOCKSIZEB (BLOCKSIZE/8) + +static const ulong64 T0[256] = { + CONST64(0xbad3d268bbb96a01), CONST64(0x54fc4d19e59a66b1), CONST64(0x2f71bc93e26514cd), CONST64(0x749ccdb925871b51), + CONST64(0x53f55102f7a257a4), CONST64(0xd3686bb8d0d6be03), CONST64(0xd26b6fbdd6deb504), CONST64(0x4dd72964b35285fe), + CONST64(0x50f05d0dfdba4aad), CONST64(0xace98a26cf09e063), CONST64(0x8d8a0e83091c9684), CONST64(0xbfdcc679a5914d1a), + CONST64(0x7090ddad3da7374d), CONST64(0x52f65507f1aa5ca3), CONST64(0x9ab352c87ba417e1), CONST64(0x4cd42d61b55a8ef9), + CONST64(0xea238f65460320ac), CONST64(0xd56273a6c4e68411), CONST64(0x97a466f155cc68c2), CONST64(0xd16e63b2dcc6a80d), + CONST64(0x3355ccffaa85d099), CONST64(0x51f35908fbb241aa), CONST64(0x5bed712ac7e20f9c), CONST64(0xa6f7a204f359ae55), + CONST64(0xde7f5f81febec120), CONST64(0x48d83d75ad7aa2e5), CONST64(0xa8e59a32d729cc7f), CONST64(0x99b65ec771bc0ae8), + CONST64(0xdb704b90e096e63b), CONST64(0x3256c8faac8ddb9e), CONST64(0xb7c4e65195d11522), CONST64(0xfc19d72b32b3aace), + CONST64(0xe338ab48704b7393), CONST64(0x9ebf42dc63843bfd), CONST64(0x91ae7eef41fc52d0), CONST64(0x9bb056cd7dac1ce6), + CONST64(0xe23baf4d76437894), CONST64(0xbbd0d66dbdb16106), CONST64(0x41c319589b32f1da), CONST64(0x6eb2a5cb7957e517), + CONST64(0xa5f2ae0bf941b35c), CONST64(0xcb400bc08016564b), CONST64(0x6bbdb1da677fc20c), CONST64(0x95a26efb59dc7ecc), + CONST64(0xa1febe1fe1619f40), CONST64(0xf308eb1810cbc3e3), CONST64(0xb1cefe4f81e12f30), CONST64(0x0206080a0c10160e), + CONST64(0xcc4917db922e675e), CONST64(0xc45137f3a26e3f66), CONST64(0x1d2774694ee8cf53), CONST64(0x143c504478a09c6c), + CONST64(0xc3582be8b0560e73), CONST64(0x63a591f2573f9a34), CONST64(0xda734f95e69eed3c), CONST64(0x5de76934d3d2358e), + CONST64(0x5fe1613edfc22380), CONST64(0xdc79578bf2aed72e), CONST64(0x7d87e99413cf486e), CONST64(0xcd4a13de94266c59), + CONST64(0x7f81e19e1fdf5e60), CONST64(0x5aee752fc1ea049b), CONST64(0x6cb4adc17547f319), CONST64(0x5ce46d31d5da3e89), + CONST64(0xf704fb0c08ebefff), CONST64(0x266a98bed42d47f2), CONST64(0xff1cdb2438abb7c7), CONST64(0xed2a937e543b11b9), + CONST64(0xe825876f4a1336a2), CONST64(0x9dba4ed3699c26f4), CONST64(0x6fb1a1ce7f5fee10), CONST64(0x8e8f028c03048b8d), + CONST64(0x192b647d56c8e34f), CONST64(0xa0fdba1ae7699447), CONST64(0xf00de7171ad3deea), CONST64(0x89861e97113cba98), + CONST64(0x0f113c332278692d), CONST64(0x07091c1b12383115), CONST64(0xafec8629c511fd6a), CONST64(0xfb10cb30208b9bdb), + CONST64(0x0818202830405838), CONST64(0x153f54417ea8976b), CONST64(0x0d1734392e687f23), CONST64(0x040c101418202c1c), + CONST64(0x0103040506080b07), CONST64(0x64ac8de94507ab21), CONST64(0xdf7c5b84f8b6ca27), CONST64(0x769ac5b329970d5f), + CONST64(0x798bf9800bef6472), CONST64(0xdd7a538ef4a6dc29), CONST64(0x3d47f4c98ef5b2b3), CONST64(0x163a584e74b08a62), + CONST64(0x3f41fcc382e5a4bd), CONST64(0x3759dcebb2a5fc85), CONST64(0x6db7a9c4734ff81e), CONST64(0x3848e0d890dd95a8), + CONST64(0xb9d6de67b1a17708), CONST64(0x7395d1a237bf2a44), CONST64(0xe926836a4c1b3da5), CONST64(0x355fd4e1beb5ea8b), + CONST64(0x55ff491ce3926db6), CONST64(0x7193d9a83baf3c4a), CONST64(0x7b8df18a07ff727c), CONST64(0x8c890a860f149d83), + CONST64(0x7296d5a731b72143), CONST64(0x88851a921734b19f), CONST64(0xf607ff090ee3e4f8), CONST64(0x2a7ea882fc4d33d6), + CONST64(0x3e42f8c684edafba), CONST64(0x5ee2653bd9ca2887), CONST64(0x27699cbbd2254cf5), CONST64(0x46ca0543890ac0cf), + CONST64(0x0c14303c28607424), CONST64(0x65af89ec430fa026), CONST64(0x68b8bdd56d67df05), CONST64(0x61a399f85b2f8c3a), + CONST64(0x03050c0f0a181d09), CONST64(0xc15e23e2bc46187d), CONST64(0x57f94116ef827bb8), CONST64(0xd6677fa9cefe9918), + CONST64(0xd976439aec86f035), CONST64(0x58e87d25cdfa1295), CONST64(0xd875479fea8efb32), CONST64(0x66aa85e34917bd2f), + CONST64(0xd7647bacc8f6921f), CONST64(0x3a4ee8d29ccd83a6), CONST64(0xc84507cf8a0e4b42), CONST64(0x3c44f0cc88fdb9b4), + CONST64(0xfa13cf35268390dc), CONST64(0x96a762f453c463c5), CONST64(0xa7f4a601f551a552), CONST64(0x98b55ac277b401ef), + CONST64(0xec29977b52331abe), CONST64(0xb8d5da62b7a97c0f), CONST64(0xc7543bfca876226f), CONST64(0xaeef822cc319f66d), + CONST64(0x69bbb9d06b6fd402), CONST64(0x4bdd317aa762bfec), CONST64(0xabe0963ddd31d176), CONST64(0xa9e69e37d121c778), + CONST64(0x67a981e64f1fb628), CONST64(0x0a1e28223c504e36), CONST64(0x47c901468f02cbc8), CONST64(0xf20bef1d16c3c8e4), + CONST64(0xb5c2ee5b99c1032c), CONST64(0x226688aacc0d6bee), CONST64(0xe532b356647b4981), CONST64(0xee2f9f715e230cb0), + CONST64(0xbedfc27ca399461d), CONST64(0x2b7dac87fa4538d1), CONST64(0x819e3ebf217ce2a0), CONST64(0x1236485a6c90a67e), + CONST64(0x839836b52d6cf4ae), CONST64(0x1b2d6c775ad8f541), CONST64(0x0e1238362470622a), CONST64(0x23658cafca0560e9), + CONST64(0xf502f30604fbf9f1), CONST64(0x45cf094c8312ddc6), CONST64(0x216384a5c61576e7), CONST64(0xce4f1fd19e3e7150), + CONST64(0x49db3970ab72a9e2), CONST64(0x2c74b09ce87d09c4), CONST64(0xf916c33a2c9b8dd5), CONST64(0xe637bf596e635488), + CONST64(0xb6c7e25493d91e25), CONST64(0x2878a088f05d25d8), CONST64(0x17395c4b72b88165), CONST64(0x829b32b02b64ffa9), + CONST64(0x1a2e68725cd0fe46), CONST64(0x8b80169d1d2cac96), CONST64(0xfe1fdf213ea3bcc0), CONST64(0x8a8312981b24a791), + CONST64(0x091b242d3648533f), CONST64(0xc94603ca8c064045), CONST64(0x879426a1354cd8b2), CONST64(0x4ed2256bb94a98f7), + CONST64(0xe13ea3427c5b659d), CONST64(0x2e72b896e46d1fca), CONST64(0xe431b75362734286), CONST64(0xe03da7477a536e9a), + CONST64(0xeb208b60400b2bab), CONST64(0x90ad7aea47f459d7), CONST64(0xa4f1aa0eff49b85b), CONST64(0x1e22786644f0d25a), + CONST64(0x85922eab395ccebc), CONST64(0x60a09dfd5d27873d), CONST64(0x0000000000000000), CONST64(0x256f94b1de355afb), + CONST64(0xf401f70302f3f2f6), CONST64(0xf10ee3121cdbd5ed), CONST64(0x94a16afe5fd475cb), CONST64(0x0b1d2c273a584531), + CONST64(0xe734bb5c686b5f8f), CONST64(0x759fc9bc238f1056), CONST64(0xef2c9b74582b07b7), CONST64(0x345cd0e4b8bde18c), + CONST64(0x3153c4f5a695c697), CONST64(0xd46177a3c2ee8f16), CONST64(0xd06d67b7dacea30a), CONST64(0x869722a43344d3b5), + CONST64(0x7e82e59b19d75567), CONST64(0xadea8e23c901eb64), CONST64(0xfd1ad32e34bba1c9), CONST64(0x297ba48df6552edf), + CONST64(0x3050c0f0a09dcd90), CONST64(0x3b4decd79ac588a1), CONST64(0x9fbc46d9658c30fa), CONST64(0xf815c73f2a9386d2), + CONST64(0xc6573ff9ae7e2968), CONST64(0x13354c5f6a98ad79), CONST64(0x060a181e14303a12), CONST64(0x050f14111e28271b), + CONST64(0xc55233f6a4663461), CONST64(0x113344556688bb77), CONST64(0x7799c1b62f9f0658), CONST64(0x7c84ed9115c74369), + CONST64(0x7a8ef58f01f7797b), CONST64(0x7888fd850de76f75), CONST64(0x365ad8eeb4adf782), CONST64(0x1c24706c48e0c454), + CONST64(0x394be4dd96d59eaf), CONST64(0x59eb7920cbf21992), CONST64(0x1828607850c0e848), CONST64(0x56fa4513e98a70bf), + CONST64(0xb3c8f6458df1393e), CONST64(0xb0cdfa4a87e92437), CONST64(0x246c90b4d83d51fc), CONST64(0x206080a0c01d7de0), + CONST64(0xb2cbf2408bf93239), CONST64(0x92ab72e04be44fd9), CONST64(0xa3f8b615ed71894e), CONST64(0xc05d27e7ba4e137a), + CONST64(0x44cc0d49851ad6c1), CONST64(0x62a695f751379133), CONST64(0x103040506080b070), CONST64(0xb4c1ea5e9fc9082b), + CONST64(0x84912aae3f54c5bb), CONST64(0x43c511529722e7d4), CONST64(0x93a876e54dec44de), CONST64(0xc25b2fedb65e0574), + CONST64(0x4ade357fa16ab4eb), CONST64(0xbddace73a9815b14), CONST64(0x8f8c0689050c808a), CONST64(0x2d77b499ee7502c3), + CONST64(0xbcd9ca76af895013), CONST64(0x9cb94ad66f942df3), CONST64(0x6abeb5df6177c90b), CONST64(0x40c01d5d9d3afadd), + CONST64(0xcf4c1bd498367a57), CONST64(0xa2fbb210eb798249), CONST64(0x809d3aba2774e9a7), CONST64(0x4fd1216ebf4293f0), + CONST64(0x1f217c6342f8d95d), CONST64(0xca430fc5861e5d4c), CONST64(0xaae39238db39da71), CONST64(0x42c61557912aecd3), +}; + +static const ulong64 T1[256] = { + CONST64(0xd3ba68d2b9bb016a), CONST64(0xfc54194d9ae5b166), CONST64(0x712f93bc65e2cd14), CONST64(0x9c74b9cd8725511b), + CONST64(0xf5530251a2f7a457), CONST64(0x68d3b86bd6d003be), CONST64(0x6bd2bd6fded604b5), CONST64(0xd74d642952b3fe85), + CONST64(0xf0500d5dbafdad4a), CONST64(0xe9ac268a09cf63e0), CONST64(0x8a8d830e1c098496), CONST64(0xdcbf79c691a51a4d), + CONST64(0x9070addda73d4d37), CONST64(0xf6520755aaf1a35c), CONST64(0xb39ac852a47be117), CONST64(0xd44c612d5ab5f98e), + CONST64(0x23ea658f0346ac20), CONST64(0x62d5a673e6c41184), CONST64(0xa497f166cc55c268), CONST64(0x6ed1b263c6dc0da8), + CONST64(0x5533ffcc85aa99d0), CONST64(0xf3510859b2fbaa41), CONST64(0xed5b2a71e2c79c0f), CONST64(0xf7a604a259f355ae), + CONST64(0x7fde815fbefe20c1), CONST64(0xd848753d7aade5a2), CONST64(0xe5a8329a29d77fcc), CONST64(0xb699c75ebc71e80a), + CONST64(0x70db904b96e03be6), CONST64(0x5632fac88dac9edb), CONST64(0xc4b751e6d1952215), CONST64(0x19fc2bd7b332ceaa), + CONST64(0x38e348ab4b709373), CONST64(0xbf9edc428463fd3b), CONST64(0xae91ef7efc41d052), CONST64(0xb09bcd56ac7de61c), + CONST64(0x3be24daf43769478), CONST64(0xd0bb6dd6b1bd0661), CONST64(0xc3415819329bdaf1), CONST64(0xb26ecba5577917e5), + CONST64(0xf2a50bae41f95cb3), CONST64(0x40cbc00b16804b56), CONST64(0xbd6bdab17f670cc2), CONST64(0xa295fb6edc59cc7e), + CONST64(0xfea11fbe61e1409f), CONST64(0x08f318ebcb10e3c3), CONST64(0xceb14ffee181302f), CONST64(0x06020a08100c0e16), + CONST64(0x49ccdb172e925e67), CONST64(0x51c4f3376ea2663f), CONST64(0x271d6974e84e53cf), CONST64(0x3c144450a0786c9c), + CONST64(0x58c3e82b56b0730e), CONST64(0xa563f2913f57349a), CONST64(0x73da954f9ee63ced), CONST64(0xe75d3469d2d38e35), + CONST64(0xe15f3e61c2df8023), CONST64(0x79dc8b57aef22ed7), CONST64(0x877d94e9cf136e48), CONST64(0x4acdde132694596c), + CONST64(0x817f9ee1df1f605e), CONST64(0xee5a2f75eac19b04), CONST64(0xb46cc1ad477519f3), CONST64(0xe45c316ddad5893e), + CONST64(0x04f70cfbeb08ffef), CONST64(0x6a26be982dd4f247), CONST64(0x1cff24dbab38c7b7), CONST64(0x2aed7e933b54b911), + CONST64(0x25e86f87134aa236), CONST64(0xba9dd34e9c69f426), CONST64(0xb16fcea15f7f10ee), CONST64(0x8f8e8c0204038d8b), + CONST64(0x2b197d64c8564fe3), CONST64(0xfda01aba69e74794), CONST64(0x0df017e7d31aeade), CONST64(0x8689971e3c1198ba), + CONST64(0x110f333c78222d69), CONST64(0x09071b1c38121531), CONST64(0xecaf298611c56afd), CONST64(0x10fb30cb8b20db9b), + CONST64(0x1808282040303858), CONST64(0x3f154154a87e6b97), CONST64(0x170d3934682e237f), CONST64(0x0c04141020181c2c), + CONST64(0x030105040806070b), CONST64(0xac64e98d074521ab), CONST64(0x7cdf845bb6f827ca), CONST64(0x9a76b3c597295f0d), + CONST64(0x8b7980f9ef0b7264), CONST64(0x7add8e53a6f429dc), CONST64(0x473dc9f4f58eb3b2), CONST64(0x3a164e58b074628a), + CONST64(0x413fc3fce582bda4), CONST64(0x5937ebdca5b285fc), CONST64(0xb76dc4a94f731ef8), CONST64(0x4838d8e0dd90a895), + CONST64(0xd6b967dea1b10877), CONST64(0x9573a2d1bf37442a), CONST64(0x26e96a831b4ca53d), CONST64(0x5f35e1d4b5be8bea), + CONST64(0xff551c4992e3b66d), CONST64(0x9371a8d9af3b4a3c), CONST64(0x8d7b8af1ff077c72), CONST64(0x898c860a140f839d), + CONST64(0x9672a7d5b7314321), CONST64(0x8588921a34179fb1), CONST64(0x07f609ffe30ef8e4), CONST64(0x7e2a82a84dfcd633), + CONST64(0x423ec6f8ed84baaf), CONST64(0xe25e3b65cad98728), CONST64(0x6927bb9c25d2f54c), CONST64(0xca4643050a89cfc0), + CONST64(0x140c3c3060282474), CONST64(0xaf65ec890f4326a0), CONST64(0xb868d5bd676d05df), CONST64(0xa361f8992f5b3a8c), + CONST64(0x05030f0c180a091d), CONST64(0x5ec1e22346bc7d18), CONST64(0xf957164182efb87b), CONST64(0x67d6a97ffece1899), + CONST64(0x76d99a4386ec35f0), CONST64(0xe858257dfacd9512), CONST64(0x75d89f478eea32fb), CONST64(0xaa66e38517492fbd), + CONST64(0x64d7ac7bf6c81f92), CONST64(0x4e3ad2e8cd9ca683), CONST64(0x45c8cf070e8a424b), CONST64(0x443cccf0fd88b4b9), + CONST64(0x13fa35cf8326dc90), CONST64(0xa796f462c453c563), CONST64(0xf4a701a651f552a5), CONST64(0xb598c25ab477ef01), + CONST64(0x29ec7b973352be1a), CONST64(0xd5b862daa9b70f7c), CONST64(0x54c7fc3b76a86f22), CONST64(0xefae2c8219c36df6), + CONST64(0xbb69d0b96f6b02d4), CONST64(0xdd4b7a3162a7ecbf), CONST64(0xe0ab3d9631dd76d1), CONST64(0xe6a9379e21d178c7), + CONST64(0xa967e6811f4f28b6), CONST64(0x1e0a2228503c364e), CONST64(0xc9474601028fc8cb), CONST64(0x0bf21defc316e4c8), + CONST64(0xc2b55beec1992c03), CONST64(0x6622aa880dccee6b), CONST64(0x32e556b37b648149), CONST64(0x2fee719f235eb00c), + CONST64(0xdfbe7cc299a31d46), CONST64(0x7d2b87ac45fad138), CONST64(0x9e81bf3e7c21a0e2), CONST64(0x36125a48906c7ea6), + CONST64(0x9883b5366c2daef4), CONST64(0x2d1b776cd85a41f5), CONST64(0x120e363870242a62), CONST64(0x6523af8c05cae960), + CONST64(0x02f506f3fb04f1f9), CONST64(0xcf454c091283c6dd), CONST64(0x6321a58415c6e776), CONST64(0x4fced11f3e9e5071), + CONST64(0xdb49703972abe2a9), CONST64(0x742c9cb07de8c409), CONST64(0x16f93ac39b2cd58d), CONST64(0x37e659bf636e8854), + CONST64(0xc7b654e2d993251e), CONST64(0x782888a05df0d825), CONST64(0x39174b5cb8726581), CONST64(0x9b82b032642ba9ff), + CONST64(0x2e1a7268d05c46fe), CONST64(0x808b9d162c1d96ac), CONST64(0x1ffe21dfa33ec0bc), CONST64(0x838a9812241b91a7), + CONST64(0x1b092d2448363f53), CONST64(0x46c9ca03068c4540), CONST64(0x9487a1264c35b2d8), CONST64(0xd24e6b254ab9f798), + CONST64(0x3ee142a35b7c9d65), CONST64(0x722e96b86de4ca1f), CONST64(0x31e453b773628642), CONST64(0x3de047a7537a9a6e), + CONST64(0x20eb608b0b40ab2b), CONST64(0xad90ea7af447d759), CONST64(0xf1a40eaa49ff5bb8), CONST64(0x221e6678f0445ad2), + CONST64(0x9285ab2e5c39bcce), CONST64(0xa060fd9d275d3d87), CONST64(0x0000000000000000), CONST64(0x6f25b19435defb5a), + CONST64(0x01f403f7f302f6f2), CONST64(0x0ef112e3db1cedd5), CONST64(0xa194fe6ad45fcb75), CONST64(0x1d0b272c583a3145), + CONST64(0x34e75cbb6b688f5f), CONST64(0x9f75bcc98f235610), CONST64(0x2cef749b2b58b707), CONST64(0x5c34e4d0bdb88ce1), + CONST64(0x5331f5c495a697c6), CONST64(0x61d4a377eec2168f), CONST64(0x6dd0b767ceda0aa3), CONST64(0x9786a4224433b5d3), + CONST64(0x827e9be5d7196755), CONST64(0xeaad238e01c964eb), CONST64(0x1afd2ed3bb34c9a1), CONST64(0x7b298da455f6df2e), + CONST64(0x5030f0c09da090cd), CONST64(0x4d3bd7ecc59aa188), CONST64(0xbc9fd9468c65fa30), CONST64(0x15f83fc7932ad286), + CONST64(0x57c6f93f7eae6829), CONST64(0x35135f4c986a79ad), CONST64(0x0a061e183014123a), CONST64(0x0f051114281e1b27), + CONST64(0x52c5f63366a46134), CONST64(0x33115544886677bb), CONST64(0x9977b6c19f2f5806), CONST64(0x847c91edc7156943), + CONST64(0x8e7a8ff5f7017b79), CONST64(0x887885fde70d756f), CONST64(0x5a36eed8adb482f7), CONST64(0x241c6c70e04854c4), + CONST64(0x4b39dde4d596af9e), CONST64(0xeb592079f2cb9219), CONST64(0x28187860c05048e8), CONST64(0xfa5613458ae9bf70), + CONST64(0xc8b345f6f18d3e39), CONST64(0xcdb04afae9873724), CONST64(0x6c24b4903dd8fc51), CONST64(0x6020a0801dc0e07d), + CONST64(0xcbb240f2f98b3932), CONST64(0xab92e072e44bd94f), CONST64(0xf8a315b671ed4e89), CONST64(0x5dc0e7274eba7a13), + CONST64(0xcc44490d1a85c1d6), CONST64(0xa662f79537513391), CONST64(0x30105040806070b0), CONST64(0xc1b45eeac99f2b08), + CONST64(0x9184ae2a543fbbc5), CONST64(0xc54352112297d4e7), CONST64(0xa893e576ec4dde44), CONST64(0x5bc2ed2f5eb67405), + CONST64(0xde4a7f356aa1ebb4), CONST64(0xdabd73ce81a9145b), CONST64(0x8c8f89060c058a80), CONST64(0x772d99b475eec302), + CONST64(0xd9bc76ca89af1350), CONST64(0xb99cd64a946ff32d), CONST64(0xbe6adfb577610bc9), CONST64(0xc0405d1d3a9dddfa), + CONST64(0x4ccfd41b3698577a), CONST64(0xfba210b279eb4982), CONST64(0x9d80ba3a7427a7e9), CONST64(0xd14f6e2142bff093), + CONST64(0x211f637cf8425dd9), CONST64(0x43cac50f1e864c5d), CONST64(0xe3aa389239db71da), CONST64(0xc64257152a91d3ec), +}; + +static const ulong64 T2[256] = { + CONST64(0xd268bad36a01bbb9), CONST64(0x4d1954fc66b1e59a), CONST64(0xbc932f7114cde265), CONST64(0xcdb9749c1b512587), + CONST64(0x510253f557a4f7a2), CONST64(0x6bb8d368be03d0d6), CONST64(0x6fbdd26bb504d6de), CONST64(0x29644dd785feb352), + CONST64(0x5d0d50f04aadfdba), CONST64(0x8a26ace9e063cf09), CONST64(0x0e838d8a9684091c), CONST64(0xc679bfdc4d1aa591), + CONST64(0xddad7090374d3da7), CONST64(0x550752f65ca3f1aa), CONST64(0x52c89ab317e17ba4), CONST64(0x2d614cd48ef9b55a), + CONST64(0x8f65ea2320ac4603), CONST64(0x73a6d5628411c4e6), CONST64(0x66f197a468c255cc), CONST64(0x63b2d16ea80ddcc6), + CONST64(0xccff3355d099aa85), CONST64(0x590851f341aafbb2), CONST64(0x712a5bed0f9cc7e2), CONST64(0xa204a6f7ae55f359), + CONST64(0x5f81de7fc120febe), CONST64(0x3d7548d8a2e5ad7a), CONST64(0x9a32a8e5cc7fd729), CONST64(0x5ec799b60ae871bc), + CONST64(0x4b90db70e63be096), CONST64(0xc8fa3256db9eac8d), CONST64(0xe651b7c4152295d1), CONST64(0xd72bfc19aace32b3), + CONST64(0xab48e3387393704b), CONST64(0x42dc9ebf3bfd6384), CONST64(0x7eef91ae52d041fc), CONST64(0x56cd9bb01ce67dac), + CONST64(0xaf4de23b78947643), CONST64(0xd66dbbd06106bdb1), CONST64(0x195841c3f1da9b32), CONST64(0xa5cb6eb2e5177957), + CONST64(0xae0ba5f2b35cf941), CONST64(0x0bc0cb40564b8016), CONST64(0xb1da6bbdc20c677f), CONST64(0x6efb95a27ecc59dc), + CONST64(0xbe1fa1fe9f40e161), CONST64(0xeb18f308c3e310cb), CONST64(0xfe4fb1ce2f3081e1), CONST64(0x080a0206160e0c10), + CONST64(0x17dbcc49675e922e), CONST64(0x37f3c4513f66a26e), CONST64(0x74691d27cf534ee8), CONST64(0x5044143c9c6c78a0), + CONST64(0x2be8c3580e73b056), CONST64(0x91f263a59a34573f), CONST64(0x4f95da73ed3ce69e), CONST64(0x69345de7358ed3d2), + CONST64(0x613e5fe12380dfc2), CONST64(0x578bdc79d72ef2ae), CONST64(0xe9947d87486e13cf), CONST64(0x13decd4a6c599426), + CONST64(0xe19e7f815e601fdf), CONST64(0x752f5aee049bc1ea), CONST64(0xadc16cb4f3197547), CONST64(0x6d315ce43e89d5da), + CONST64(0xfb0cf704efff08eb), CONST64(0x98be266a47f2d42d), CONST64(0xdb24ff1cb7c738ab), CONST64(0x937eed2a11b9543b), + CONST64(0x876fe82536a24a13), CONST64(0x4ed39dba26f4699c), CONST64(0xa1ce6fb1ee107f5f), CONST64(0x028c8e8f8b8d0304), + CONST64(0x647d192be34f56c8), CONST64(0xba1aa0fd9447e769), CONST64(0xe717f00ddeea1ad3), CONST64(0x1e978986ba98113c), + CONST64(0x3c330f11692d2278), CONST64(0x1c1b070931151238), CONST64(0x8629afecfd6ac511), CONST64(0xcb30fb109bdb208b), + CONST64(0x2028081858383040), CONST64(0x5441153f976b7ea8), CONST64(0x34390d177f232e68), CONST64(0x1014040c2c1c1820), + CONST64(0x040501030b070608), CONST64(0x8de964acab214507), CONST64(0x5b84df7cca27f8b6), CONST64(0xc5b3769a0d5f2997), + CONST64(0xf980798b64720bef), CONST64(0x538edd7adc29f4a6), CONST64(0xf4c93d47b2b38ef5), CONST64(0x584e163a8a6274b0), + CONST64(0xfcc33f41a4bd82e5), CONST64(0xdceb3759fc85b2a5), CONST64(0xa9c46db7f81e734f), CONST64(0xe0d8384895a890dd), + CONST64(0xde67b9d67708b1a1), CONST64(0xd1a273952a4437bf), CONST64(0x836ae9263da54c1b), CONST64(0xd4e1355fea8bbeb5), + CONST64(0x491c55ff6db6e392), CONST64(0xd9a871933c4a3baf), CONST64(0xf18a7b8d727c07ff), CONST64(0x0a868c899d830f14), + CONST64(0xd5a77296214331b7), CONST64(0x1a928885b19f1734), CONST64(0xff09f607e4f80ee3), CONST64(0xa8822a7e33d6fc4d), + CONST64(0xf8c63e42afba84ed), CONST64(0x653b5ee22887d9ca), CONST64(0x9cbb27694cf5d225), CONST64(0x054346cac0cf890a), + CONST64(0x303c0c1474242860), CONST64(0x89ec65afa026430f), CONST64(0xbdd568b8df056d67), CONST64(0x99f861a38c3a5b2f), + CONST64(0x0c0f03051d090a18), CONST64(0x23e2c15e187dbc46), CONST64(0x411657f97bb8ef82), CONST64(0x7fa9d6679918cefe), + CONST64(0x439ad976f035ec86), CONST64(0x7d2558e81295cdfa), CONST64(0x479fd875fb32ea8e), CONST64(0x85e366aabd2f4917), + CONST64(0x7bacd764921fc8f6), CONST64(0xe8d23a4e83a69ccd), CONST64(0x07cfc8454b428a0e), CONST64(0xf0cc3c44b9b488fd), + CONST64(0xcf35fa1390dc2683), CONST64(0x62f496a763c553c4), CONST64(0xa601a7f4a552f551), CONST64(0x5ac298b501ef77b4), + CONST64(0x977bec291abe5233), CONST64(0xda62b8d57c0fb7a9), CONST64(0x3bfcc754226fa876), CONST64(0x822caeeff66dc319), + CONST64(0xb9d069bbd4026b6f), CONST64(0x317a4bddbfeca762), CONST64(0x963dabe0d176dd31), CONST64(0x9e37a9e6c778d121), + CONST64(0x81e667a9b6284f1f), CONST64(0x28220a1e4e363c50), CONST64(0x014647c9cbc88f02), CONST64(0xef1df20bc8e416c3), + CONST64(0xee5bb5c2032c99c1), CONST64(0x88aa22666beecc0d), CONST64(0xb356e5324981647b), CONST64(0x9f71ee2f0cb05e23), + CONST64(0xc27cbedf461da399), CONST64(0xac872b7d38d1fa45), CONST64(0x3ebf819ee2a0217c), CONST64(0x485a1236a67e6c90), + CONST64(0x36b58398f4ae2d6c), CONST64(0x6c771b2df5415ad8), CONST64(0x38360e12622a2470), CONST64(0x8caf236560e9ca05), + CONST64(0xf306f502f9f104fb), CONST64(0x094c45cfddc68312), CONST64(0x84a5216376e7c615), CONST64(0x1fd1ce4f71509e3e), + CONST64(0x397049dba9e2ab72), CONST64(0xb09c2c7409c4e87d), CONST64(0xc33af9168dd52c9b), CONST64(0xbf59e63754886e63), + CONST64(0xe254b6c71e2593d9), CONST64(0xa088287825d8f05d), CONST64(0x5c4b1739816572b8), CONST64(0x32b0829bffa92b64), + CONST64(0x68721a2efe465cd0), CONST64(0x169d8b80ac961d2c), CONST64(0xdf21fe1fbcc03ea3), CONST64(0x12988a83a7911b24), + CONST64(0x242d091b533f3648), CONST64(0x03cac94640458c06), CONST64(0x26a18794d8b2354c), CONST64(0x256b4ed298f7b94a), + CONST64(0xa342e13e659d7c5b), CONST64(0xb8962e721fcae46d), CONST64(0xb753e43142866273), CONST64(0xa747e03d6e9a7a53), + CONST64(0x8b60eb202bab400b), CONST64(0x7aea90ad59d747f4), CONST64(0xaa0ea4f1b85bff49), CONST64(0x78661e22d25a44f0), + CONST64(0x2eab8592cebc395c), CONST64(0x9dfd60a0873d5d27), CONST64(0x0000000000000000), CONST64(0x94b1256f5afbde35), + CONST64(0xf703f401f2f602f3), CONST64(0xe312f10ed5ed1cdb), CONST64(0x6afe94a175cb5fd4), CONST64(0x2c270b1d45313a58), + CONST64(0xbb5ce7345f8f686b), CONST64(0xc9bc759f1056238f), CONST64(0x9b74ef2c07b7582b), CONST64(0xd0e4345ce18cb8bd), + CONST64(0xc4f53153c697a695), CONST64(0x77a3d4618f16c2ee), CONST64(0x67b7d06da30adace), CONST64(0x22a48697d3b53344), + CONST64(0xe59b7e82556719d7), CONST64(0x8e23adeaeb64c901), CONST64(0xd32efd1aa1c934bb), CONST64(0xa48d297b2edff655), + CONST64(0xc0f03050cd90a09d), CONST64(0xecd73b4d88a19ac5), CONST64(0x46d99fbc30fa658c), CONST64(0xc73ff81586d22a93), + CONST64(0x3ff9c6572968ae7e), CONST64(0x4c5f1335ad796a98), CONST64(0x181e060a3a121430), CONST64(0x1411050f271b1e28), + CONST64(0x33f6c5523461a466), CONST64(0x44551133bb776688), CONST64(0xc1b6779906582f9f), CONST64(0xed917c84436915c7), + CONST64(0xf58f7a8e797b01f7), CONST64(0xfd8578886f750de7), CONST64(0xd8ee365af782b4ad), CONST64(0x706c1c24c45448e0), + CONST64(0xe4dd394b9eaf96d5), CONST64(0x792059eb1992cbf2), CONST64(0x60781828e84850c0), CONST64(0x451356fa70bfe98a), + CONST64(0xf645b3c8393e8df1), CONST64(0xfa4ab0cd243787e9), CONST64(0x90b4246c51fcd83d), CONST64(0x80a020607de0c01d), + CONST64(0xf240b2cb32398bf9), CONST64(0x72e092ab4fd94be4), CONST64(0xb615a3f8894eed71), CONST64(0x27e7c05d137aba4e), + CONST64(0x0d4944ccd6c1851a), CONST64(0x95f762a691335137), CONST64(0x40501030b0706080), CONST64(0xea5eb4c1082b9fc9), + CONST64(0x2aae8491c5bb3f54), CONST64(0x115243c5e7d49722), CONST64(0x76e593a844de4dec), CONST64(0x2fedc25b0574b65e), + CONST64(0x357f4adeb4eba16a), CONST64(0xce73bdda5b14a981), CONST64(0x06898f8c808a050c), CONST64(0xb4992d7702c3ee75), + CONST64(0xca76bcd95013af89), CONST64(0x4ad69cb92df36f94), CONST64(0xb5df6abec90b6177), CONST64(0x1d5d40c0fadd9d3a), + CONST64(0x1bd4cf4c7a579836), CONST64(0xb210a2fb8249eb79), CONST64(0x3aba809de9a72774), CONST64(0x216e4fd193f0bf42), + CONST64(0x7c631f21d95d42f8), CONST64(0x0fc5ca435d4c861e), CONST64(0x9238aae3da71db39), CONST64(0x155742c6ecd3912a), +}; + +static const ulong64 T3[256] = { + CONST64(0x68d2d3ba016ab9bb), CONST64(0x194dfc54b1669ae5), CONST64(0x93bc712fcd1465e2), CONST64(0xb9cd9c74511b8725), + CONST64(0x0251f553a457a2f7), CONST64(0xb86b68d303bed6d0), CONST64(0xbd6f6bd204b5ded6), CONST64(0x6429d74dfe8552b3), + CONST64(0x0d5df050ad4abafd), CONST64(0x268ae9ac63e009cf), CONST64(0x830e8a8d84961c09), CONST64(0x79c6dcbf1a4d91a5), + CONST64(0xaddd90704d37a73d), CONST64(0x0755f652a35caaf1), CONST64(0xc852b39ae117a47b), CONST64(0x612dd44cf98e5ab5), + CONST64(0x658f23eaac200346), CONST64(0xa67362d51184e6c4), CONST64(0xf166a497c268cc55), CONST64(0xb2636ed10da8c6dc), + CONST64(0xffcc553399d085aa), CONST64(0x0859f351aa41b2fb), CONST64(0x2a71ed5b9c0fe2c7), CONST64(0x04a2f7a655ae59f3), + CONST64(0x815f7fde20c1befe), CONST64(0x753dd848e5a27aad), CONST64(0x329ae5a87fcc29d7), CONST64(0xc75eb699e80abc71), + CONST64(0x904b70db3be696e0), CONST64(0xfac856329edb8dac), CONST64(0x51e6c4b72215d195), CONST64(0x2bd719fcceaab332), + CONST64(0x48ab38e393734b70), CONST64(0xdc42bf9efd3b8463), CONST64(0xef7eae91d052fc41), CONST64(0xcd56b09be61cac7d), + CONST64(0x4daf3be294784376), CONST64(0x6dd6d0bb0661b1bd), CONST64(0x5819c341daf1329b), CONST64(0xcba5b26e17e55779), + CONST64(0x0baef2a55cb341f9), CONST64(0xc00b40cb4b561680), CONST64(0xdab1bd6b0cc27f67), CONST64(0xfb6ea295cc7edc59), + CONST64(0x1fbefea1409f61e1), CONST64(0x18eb08f3e3c3cb10), CONST64(0x4ffeceb1302fe181), CONST64(0x0a0806020e16100c), + CONST64(0xdb1749cc5e672e92), CONST64(0xf33751c4663f6ea2), CONST64(0x6974271d53cfe84e), CONST64(0x44503c146c9ca078), + CONST64(0xe82b58c3730e56b0), CONST64(0xf291a563349a3f57), CONST64(0x954f73da3ced9ee6), CONST64(0x3469e75d8e35d2d3), + CONST64(0x3e61e15f8023c2df), CONST64(0x8b5779dc2ed7aef2), CONST64(0x94e9877d6e48cf13), CONST64(0xde134acd596c2694), + CONST64(0x9ee1817f605edf1f), CONST64(0x2f75ee5a9b04eac1), CONST64(0xc1adb46c19f34775), CONST64(0x316de45c893edad5), + CONST64(0x0cfb04f7ffefeb08), CONST64(0xbe986a26f2472dd4), CONST64(0x24db1cffc7b7ab38), CONST64(0x7e932aedb9113b54), + CONST64(0x6f8725e8a236134a), CONST64(0xd34eba9df4269c69), CONST64(0xcea1b16f10ee5f7f), CONST64(0x8c028f8e8d8b0403), + CONST64(0x7d642b194fe3c856), CONST64(0x1abafda0479469e7), CONST64(0x17e70df0eaded31a), CONST64(0x971e868998ba3c11), + CONST64(0x333c110f2d697822), CONST64(0x1b1c090715313812), CONST64(0x2986ecaf6afd11c5), CONST64(0x30cb10fbdb9b8b20), + CONST64(0x2820180838584030), CONST64(0x41543f156b97a87e), CONST64(0x3934170d237f682e), CONST64(0x14100c041c2c2018), + CONST64(0x05040301070b0806), CONST64(0xe98dac6421ab0745), CONST64(0x845b7cdf27cab6f8), CONST64(0xb3c59a765f0d9729), + CONST64(0x80f98b797264ef0b), CONST64(0x8e537add29dca6f4), CONST64(0xc9f4473db3b2f58e), CONST64(0x4e583a16628ab074), + CONST64(0xc3fc413fbda4e582), CONST64(0xebdc593785fca5b2), CONST64(0xc4a9b76d1ef84f73), CONST64(0xd8e04838a895dd90), + CONST64(0x67ded6b90877a1b1), CONST64(0xa2d19573442abf37), CONST64(0x6a8326e9a53d1b4c), CONST64(0xe1d45f358beab5be), + CONST64(0x1c49ff55b66d92e3), CONST64(0xa8d993714a3caf3b), CONST64(0x8af18d7b7c72ff07), CONST64(0x860a898c839d140f), + CONST64(0xa7d596724321b731), CONST64(0x921a85889fb13417), CONST64(0x09ff07f6f8e4e30e), CONST64(0x82a87e2ad6334dfc), + CONST64(0xc6f8423ebaafed84), CONST64(0x3b65e25e8728cad9), CONST64(0xbb9c6927f54c25d2), CONST64(0x4305ca46cfc00a89), + CONST64(0x3c30140c24746028), CONST64(0xec89af6526a00f43), CONST64(0xd5bdb86805df676d), CONST64(0xf899a3613a8c2f5b), + CONST64(0x0f0c0503091d180a), CONST64(0xe2235ec17d1846bc), CONST64(0x1641f957b87b82ef), CONST64(0xa97f67d61899fece), + CONST64(0x9a4376d935f086ec), CONST64(0x257de8589512facd), CONST64(0x9f4775d832fb8eea), CONST64(0xe385aa662fbd1749), + CONST64(0xac7b64d71f92f6c8), CONST64(0xd2e84e3aa683cd9c), CONST64(0xcf0745c8424b0e8a), CONST64(0xccf0443cb4b9fd88), + CONST64(0x35cf13fadc908326), CONST64(0xf462a796c563c453), CONST64(0x01a6f4a752a551f5), CONST64(0xc25ab598ef01b477), + CONST64(0x7b9729ecbe1a3352), CONST64(0x62dad5b80f7ca9b7), CONST64(0xfc3b54c76f2276a8), CONST64(0x2c82efae6df619c3), + CONST64(0xd0b9bb6902d46f6b), CONST64(0x7a31dd4becbf62a7), CONST64(0x3d96e0ab76d131dd), CONST64(0x379ee6a978c721d1), + CONST64(0xe681a96728b61f4f), CONST64(0x22281e0a364e503c), CONST64(0x4601c947c8cb028f), CONST64(0x1def0bf2e4c8c316), + CONST64(0x5beec2b52c03c199), CONST64(0xaa886622ee6b0dcc), CONST64(0x56b332e581497b64), CONST64(0x719f2feeb00c235e), + CONST64(0x7cc2dfbe1d4699a3), CONST64(0x87ac7d2bd13845fa), CONST64(0xbf3e9e81a0e27c21), CONST64(0x5a4836127ea6906c), + CONST64(0xb5369883aef46c2d), CONST64(0x776c2d1b41f5d85a), CONST64(0x3638120e2a627024), CONST64(0xaf8c6523e96005ca), + CONST64(0x06f302f5f1f9fb04), CONST64(0x4c09cf45c6dd1283), CONST64(0xa5846321e77615c6), CONST64(0xd11f4fce50713e9e), + CONST64(0x7039db49e2a972ab), CONST64(0x9cb0742cc4097de8), CONST64(0x3ac316f9d58d9b2c), CONST64(0x59bf37e68854636e), + CONST64(0x54e2c7b6251ed993), CONST64(0x88a07828d8255df0), CONST64(0x4b5c39176581b872), CONST64(0xb0329b82a9ff642b), + CONST64(0x72682e1a46fed05c), CONST64(0x9d16808b96ac2c1d), CONST64(0x21df1ffec0bca33e), CONST64(0x9812838a91a7241b), + CONST64(0x2d241b093f534836), CONST64(0xca0346c94540068c), CONST64(0xa1269487b2d84c35), CONST64(0x6b25d24ef7984ab9), + CONST64(0x42a33ee19d655b7c), CONST64(0x96b8722eca1f6de4), CONST64(0x53b731e486427362), CONST64(0x47a73de09a6e537a), + CONST64(0x608b20ebab2b0b40), CONST64(0xea7aad90d759f447), CONST64(0x0eaaf1a45bb849ff), CONST64(0x6678221e5ad2f044), + CONST64(0xab2e9285bcce5c39), CONST64(0xfd9da0603d87275d), CONST64(0x0000000000000000), CONST64(0xb1946f25fb5a35de), + CONST64(0x03f701f4f6f2f302), CONST64(0x12e30ef1edd5db1c), CONST64(0xfe6aa194cb75d45f), CONST64(0x272c1d0b3145583a), + CONST64(0x5cbb34e78f5f6b68), CONST64(0xbcc99f7556108f23), CONST64(0x749b2cefb7072b58), CONST64(0xe4d05c348ce1bdb8), + CONST64(0xf5c4533197c695a6), CONST64(0xa37761d4168feec2), CONST64(0xb7676dd00aa3ceda), CONST64(0xa4229786b5d34433), + CONST64(0x9be5827e6755d719), CONST64(0x238eeaad64eb01c9), CONST64(0x2ed31afdc9a1bb34), CONST64(0x8da47b29df2e55f6), + CONST64(0xf0c0503090cd9da0), CONST64(0xd7ec4d3ba188c59a), CONST64(0xd946bc9ffa308c65), CONST64(0x3fc715f8d286932a), + CONST64(0xf93f57c668297eae), CONST64(0x5f4c351379ad986a), CONST64(0x1e180a06123a3014), CONST64(0x11140f051b27281e), + CONST64(0xf63352c5613466a4), CONST64(0x5544331177bb8866), CONST64(0xb6c1997758069f2f), CONST64(0x91ed847c6943c715), + CONST64(0x8ff58e7a7b79f701), CONST64(0x85fd8878756fe70d), CONST64(0xeed85a3682f7adb4), CONST64(0x6c70241c54c4e048), + CONST64(0xdde44b39af9ed596), CONST64(0x2079eb599219f2cb), CONST64(0x7860281848e8c050), CONST64(0x1345fa56bf708ae9), + CONST64(0x45f6c8b33e39f18d), CONST64(0x4afacdb03724e987), CONST64(0xb4906c24fc513dd8), CONST64(0xa0806020e07d1dc0), + CONST64(0x40f2cbb23932f98b), CONST64(0xe072ab92d94fe44b), CONST64(0x15b6f8a34e8971ed), CONST64(0xe7275dc07a134eba), + CONST64(0x490dcc44c1d61a85), CONST64(0xf795a66233913751), CONST64(0x5040301070b08060), CONST64(0x5eeac1b42b08c99f), + CONST64(0xae2a9184bbc5543f), CONST64(0x5211c543d4e72297), CONST64(0xe576a893de44ec4d), CONST64(0xed2f5bc274055eb6), + CONST64(0x7f35de4aebb46aa1), CONST64(0x73cedabd145b81a9), CONST64(0x89068c8f8a800c05), CONST64(0x99b4772dc30275ee), + CONST64(0x76cad9bc135089af), CONST64(0xd64ab99cf32d946f), CONST64(0xdfb5be6a0bc97761), CONST64(0x5d1dc040ddfa3a9d), + CONST64(0xd41b4ccf577a3698), CONST64(0x10b2fba2498279eb), CONST64(0xba3a9d80a7e97427), CONST64(0x6e21d14ff09342bf), + CONST64(0x637c211f5dd9f842), CONST64(0xc50f43ca4c5d1e86), CONST64(0x3892e3aa71da39db), CONST64(0x5715c642d3ec2a91), +}; + +static const ulong64 T4[256] = { + CONST64(0xbbb96a01bad3d268), CONST64(0xe59a66b154fc4d19), CONST64(0xe26514cd2f71bc93), CONST64(0x25871b51749ccdb9), + CONST64(0xf7a257a453f55102), CONST64(0xd0d6be03d3686bb8), CONST64(0xd6deb504d26b6fbd), CONST64(0xb35285fe4dd72964), + CONST64(0xfdba4aad50f05d0d), CONST64(0xcf09e063ace98a26), CONST64(0x091c96848d8a0e83), CONST64(0xa5914d1abfdcc679), + CONST64(0x3da7374d7090ddad), CONST64(0xf1aa5ca352f65507), CONST64(0x7ba417e19ab352c8), CONST64(0xb55a8ef94cd42d61), + CONST64(0x460320acea238f65), CONST64(0xc4e68411d56273a6), CONST64(0x55cc68c297a466f1), CONST64(0xdcc6a80dd16e63b2), + CONST64(0xaa85d0993355ccff), CONST64(0xfbb241aa51f35908), CONST64(0xc7e20f9c5bed712a), CONST64(0xf359ae55a6f7a204), + CONST64(0xfebec120de7f5f81), CONST64(0xad7aa2e548d83d75), CONST64(0xd729cc7fa8e59a32), CONST64(0x71bc0ae899b65ec7), + CONST64(0xe096e63bdb704b90), CONST64(0xac8ddb9e3256c8fa), CONST64(0x95d11522b7c4e651), CONST64(0x32b3aacefc19d72b), + CONST64(0x704b7393e338ab48), CONST64(0x63843bfd9ebf42dc), CONST64(0x41fc52d091ae7eef), CONST64(0x7dac1ce69bb056cd), + CONST64(0x76437894e23baf4d), CONST64(0xbdb16106bbd0d66d), CONST64(0x9b32f1da41c31958), CONST64(0x7957e5176eb2a5cb), + CONST64(0xf941b35ca5f2ae0b), CONST64(0x8016564bcb400bc0), CONST64(0x677fc20c6bbdb1da), CONST64(0x59dc7ecc95a26efb), + CONST64(0xe1619f40a1febe1f), CONST64(0x10cbc3e3f308eb18), CONST64(0x81e12f30b1cefe4f), CONST64(0x0c10160e0206080a), + CONST64(0x922e675ecc4917db), CONST64(0xa26e3f66c45137f3), CONST64(0x4ee8cf531d277469), CONST64(0x78a09c6c143c5044), + CONST64(0xb0560e73c3582be8), CONST64(0x573f9a3463a591f2), CONST64(0xe69eed3cda734f95), CONST64(0xd3d2358e5de76934), + CONST64(0xdfc223805fe1613e), CONST64(0xf2aed72edc79578b), CONST64(0x13cf486e7d87e994), CONST64(0x94266c59cd4a13de), + CONST64(0x1fdf5e607f81e19e), CONST64(0xc1ea049b5aee752f), CONST64(0x7547f3196cb4adc1), CONST64(0xd5da3e895ce46d31), + CONST64(0x08ebeffff704fb0c), CONST64(0xd42d47f2266a98be), CONST64(0x38abb7c7ff1cdb24), CONST64(0x543b11b9ed2a937e), + CONST64(0x4a1336a2e825876f), CONST64(0x699c26f49dba4ed3), CONST64(0x7f5fee106fb1a1ce), CONST64(0x03048b8d8e8f028c), + CONST64(0x56c8e34f192b647d), CONST64(0xe7699447a0fdba1a), CONST64(0x1ad3deeaf00de717), CONST64(0x113cba9889861e97), + CONST64(0x2278692d0f113c33), CONST64(0x1238311507091c1b), CONST64(0xc511fd6aafec8629), CONST64(0x208b9bdbfb10cb30), + CONST64(0x3040583808182028), CONST64(0x7ea8976b153f5441), CONST64(0x2e687f230d173439), CONST64(0x18202c1c040c1014), + CONST64(0x06080b0701030405), CONST64(0x4507ab2164ac8de9), CONST64(0xf8b6ca27df7c5b84), CONST64(0x29970d5f769ac5b3), + CONST64(0x0bef6472798bf980), CONST64(0xf4a6dc29dd7a538e), CONST64(0x8ef5b2b33d47f4c9), CONST64(0x74b08a62163a584e), + CONST64(0x82e5a4bd3f41fcc3), CONST64(0xb2a5fc853759dceb), CONST64(0x734ff81e6db7a9c4), CONST64(0x90dd95a83848e0d8), + CONST64(0xb1a17708b9d6de67), CONST64(0x37bf2a447395d1a2), CONST64(0x4c1b3da5e926836a), CONST64(0xbeb5ea8b355fd4e1), + CONST64(0xe3926db655ff491c), CONST64(0x3baf3c4a7193d9a8), CONST64(0x07ff727c7b8df18a), CONST64(0x0f149d838c890a86), + CONST64(0x31b721437296d5a7), CONST64(0x1734b19f88851a92), CONST64(0x0ee3e4f8f607ff09), CONST64(0xfc4d33d62a7ea882), + CONST64(0x84edafba3e42f8c6), CONST64(0xd9ca28875ee2653b), CONST64(0xd2254cf527699cbb), CONST64(0x890ac0cf46ca0543), + CONST64(0x286074240c14303c), CONST64(0x430fa02665af89ec), CONST64(0x6d67df0568b8bdd5), CONST64(0x5b2f8c3a61a399f8), + CONST64(0x0a181d0903050c0f), CONST64(0xbc46187dc15e23e2), CONST64(0xef827bb857f94116), CONST64(0xcefe9918d6677fa9), + CONST64(0xec86f035d976439a), CONST64(0xcdfa129558e87d25), CONST64(0xea8efb32d875479f), CONST64(0x4917bd2f66aa85e3), + CONST64(0xc8f6921fd7647bac), CONST64(0x9ccd83a63a4ee8d2), CONST64(0x8a0e4b42c84507cf), CONST64(0x88fdb9b43c44f0cc), + CONST64(0x268390dcfa13cf35), CONST64(0x53c463c596a762f4), CONST64(0xf551a552a7f4a601), CONST64(0x77b401ef98b55ac2), + CONST64(0x52331abeec29977b), CONST64(0xb7a97c0fb8d5da62), CONST64(0xa876226fc7543bfc), CONST64(0xc319f66daeef822c), + CONST64(0x6b6fd40269bbb9d0), CONST64(0xa762bfec4bdd317a), CONST64(0xdd31d176abe0963d), CONST64(0xd121c778a9e69e37), + CONST64(0x4f1fb62867a981e6), CONST64(0x3c504e360a1e2822), CONST64(0x8f02cbc847c90146), CONST64(0x16c3c8e4f20bef1d), + CONST64(0x99c1032cb5c2ee5b), CONST64(0xcc0d6bee226688aa), CONST64(0x647b4981e532b356), CONST64(0x5e230cb0ee2f9f71), + CONST64(0xa399461dbedfc27c), CONST64(0xfa4538d12b7dac87), CONST64(0x217ce2a0819e3ebf), CONST64(0x6c90a67e1236485a), + CONST64(0x2d6cf4ae839836b5), CONST64(0x5ad8f5411b2d6c77), CONST64(0x2470622a0e123836), CONST64(0xca0560e923658caf), + CONST64(0x04fbf9f1f502f306), CONST64(0x8312ddc645cf094c), CONST64(0xc61576e7216384a5), CONST64(0x9e3e7150ce4f1fd1), + CONST64(0xab72a9e249db3970), CONST64(0xe87d09c42c74b09c), CONST64(0x2c9b8dd5f916c33a), CONST64(0x6e635488e637bf59), + CONST64(0x93d91e25b6c7e254), CONST64(0xf05d25d82878a088), CONST64(0x72b8816517395c4b), CONST64(0x2b64ffa9829b32b0), + CONST64(0x5cd0fe461a2e6872), CONST64(0x1d2cac968b80169d), CONST64(0x3ea3bcc0fe1fdf21), CONST64(0x1b24a7918a831298), + CONST64(0x3648533f091b242d), CONST64(0x8c064045c94603ca), CONST64(0x354cd8b2879426a1), CONST64(0xb94a98f74ed2256b), + CONST64(0x7c5b659de13ea342), CONST64(0xe46d1fca2e72b896), CONST64(0x62734286e431b753), CONST64(0x7a536e9ae03da747), + CONST64(0x400b2babeb208b60), CONST64(0x47f459d790ad7aea), CONST64(0xff49b85ba4f1aa0e), CONST64(0x44f0d25a1e227866), + CONST64(0x395ccebc85922eab), CONST64(0x5d27873d60a09dfd), CONST64(0x0000000000000000), CONST64(0xde355afb256f94b1), + CONST64(0x02f3f2f6f401f703), CONST64(0x1cdbd5edf10ee312), CONST64(0x5fd475cb94a16afe), CONST64(0x3a5845310b1d2c27), + CONST64(0x686b5f8fe734bb5c), CONST64(0x238f1056759fc9bc), CONST64(0x582b07b7ef2c9b74), CONST64(0xb8bde18c345cd0e4), + CONST64(0xa695c6973153c4f5), CONST64(0xc2ee8f16d46177a3), CONST64(0xdacea30ad06d67b7), CONST64(0x3344d3b5869722a4), + CONST64(0x19d755677e82e59b), CONST64(0xc901eb64adea8e23), CONST64(0x34bba1c9fd1ad32e), CONST64(0xf6552edf297ba48d), + CONST64(0xa09dcd903050c0f0), CONST64(0x9ac588a13b4decd7), CONST64(0x658c30fa9fbc46d9), CONST64(0x2a9386d2f815c73f), + CONST64(0xae7e2968c6573ff9), CONST64(0x6a98ad7913354c5f), CONST64(0x14303a12060a181e), CONST64(0x1e28271b050f1411), + CONST64(0xa4663461c55233f6), CONST64(0x6688bb7711334455), CONST64(0x2f9f06587799c1b6), CONST64(0x15c743697c84ed91), + CONST64(0x01f7797b7a8ef58f), CONST64(0x0de76f757888fd85), CONST64(0xb4adf782365ad8ee), CONST64(0x48e0c4541c24706c), + CONST64(0x96d59eaf394be4dd), CONST64(0xcbf2199259eb7920), CONST64(0x50c0e84818286078), CONST64(0xe98a70bf56fa4513), + CONST64(0x8df1393eb3c8f645), CONST64(0x87e92437b0cdfa4a), CONST64(0xd83d51fc246c90b4), CONST64(0xc01d7de0206080a0), + CONST64(0x8bf93239b2cbf240), CONST64(0x4be44fd992ab72e0), CONST64(0xed71894ea3f8b615), CONST64(0xba4e137ac05d27e7), + CONST64(0x851ad6c144cc0d49), CONST64(0x5137913362a695f7), CONST64(0x6080b07010304050), CONST64(0x9fc9082bb4c1ea5e), + CONST64(0x3f54c5bb84912aae), CONST64(0x9722e7d443c51152), CONST64(0x4dec44de93a876e5), CONST64(0xb65e0574c25b2fed), + CONST64(0xa16ab4eb4ade357f), CONST64(0xa9815b14bddace73), CONST64(0x050c808a8f8c0689), CONST64(0xee7502c32d77b499), + CONST64(0xaf895013bcd9ca76), CONST64(0x6f942df39cb94ad6), CONST64(0x6177c90b6abeb5df), CONST64(0x9d3afadd40c01d5d), + CONST64(0x98367a57cf4c1bd4), CONST64(0xeb798249a2fbb210), CONST64(0x2774e9a7809d3aba), CONST64(0xbf4293f04fd1216e), + CONST64(0x42f8d95d1f217c63), CONST64(0x861e5d4cca430fc5), CONST64(0xdb39da71aae39238), CONST64(0x912aecd342c61557), +}; + +static const ulong64 T5[256] = { + CONST64(0xb9bb016ad3ba68d2), CONST64(0x9ae5b166fc54194d), CONST64(0x65e2cd14712f93bc), CONST64(0x8725511b9c74b9cd), + CONST64(0xa2f7a457f5530251), CONST64(0xd6d003be68d3b86b), CONST64(0xded604b56bd2bd6f), CONST64(0x52b3fe85d74d6429), + CONST64(0xbafdad4af0500d5d), CONST64(0x09cf63e0e9ac268a), CONST64(0x1c0984968a8d830e), CONST64(0x91a51a4ddcbf79c6), + CONST64(0xa73d4d379070addd), CONST64(0xaaf1a35cf6520755), CONST64(0xa47be117b39ac852), CONST64(0x5ab5f98ed44c612d), + CONST64(0x0346ac2023ea658f), CONST64(0xe6c4118462d5a673), CONST64(0xcc55c268a497f166), CONST64(0xc6dc0da86ed1b263), + CONST64(0x85aa99d05533ffcc), CONST64(0xb2fbaa41f3510859), CONST64(0xe2c79c0fed5b2a71), CONST64(0x59f355aef7a604a2), + CONST64(0xbefe20c17fde815f), CONST64(0x7aade5a2d848753d), CONST64(0x29d77fcce5a8329a), CONST64(0xbc71e80ab699c75e), + CONST64(0x96e03be670db904b), CONST64(0x8dac9edb5632fac8), CONST64(0xd1952215c4b751e6), CONST64(0xb332ceaa19fc2bd7), + CONST64(0x4b70937338e348ab), CONST64(0x8463fd3bbf9edc42), CONST64(0xfc41d052ae91ef7e), CONST64(0xac7de61cb09bcd56), + CONST64(0x437694783be24daf), CONST64(0xb1bd0661d0bb6dd6), CONST64(0x329bdaf1c3415819), CONST64(0x577917e5b26ecba5), + CONST64(0x41f95cb3f2a50bae), CONST64(0x16804b5640cbc00b), CONST64(0x7f670cc2bd6bdab1), CONST64(0xdc59cc7ea295fb6e), + CONST64(0x61e1409ffea11fbe), CONST64(0xcb10e3c308f318eb), CONST64(0xe181302fceb14ffe), CONST64(0x100c0e1606020a08), + CONST64(0x2e925e6749ccdb17), CONST64(0x6ea2663f51c4f337), CONST64(0xe84e53cf271d6974), CONST64(0xa0786c9c3c144450), + CONST64(0x56b0730e58c3e82b), CONST64(0x3f57349aa563f291), CONST64(0x9ee63ced73da954f), CONST64(0xd2d38e35e75d3469), + CONST64(0xc2df8023e15f3e61), CONST64(0xaef22ed779dc8b57), CONST64(0xcf136e48877d94e9), CONST64(0x2694596c4acdde13), + CONST64(0xdf1f605e817f9ee1), CONST64(0xeac19b04ee5a2f75), CONST64(0x477519f3b46cc1ad), CONST64(0xdad5893ee45c316d), + CONST64(0xeb08ffef04f70cfb), CONST64(0x2dd4f2476a26be98), CONST64(0xab38c7b71cff24db), CONST64(0x3b54b9112aed7e93), + CONST64(0x134aa23625e86f87), CONST64(0x9c69f426ba9dd34e), CONST64(0x5f7f10eeb16fcea1), CONST64(0x04038d8b8f8e8c02), + CONST64(0xc8564fe32b197d64), CONST64(0x69e74794fda01aba), CONST64(0xd31aeade0df017e7), CONST64(0x3c1198ba8689971e), + CONST64(0x78222d69110f333c), CONST64(0x3812153109071b1c), CONST64(0x11c56afdecaf2986), CONST64(0x8b20db9b10fb30cb), + CONST64(0x4030385818082820), CONST64(0xa87e6b973f154154), CONST64(0x682e237f170d3934), CONST64(0x20181c2c0c041410), + CONST64(0x0806070b03010504), CONST64(0x074521abac64e98d), CONST64(0xb6f827ca7cdf845b), CONST64(0x97295f0d9a76b3c5), + CONST64(0xef0b72648b7980f9), CONST64(0xa6f429dc7add8e53), CONST64(0xf58eb3b2473dc9f4), CONST64(0xb074628a3a164e58), + CONST64(0xe582bda4413fc3fc), CONST64(0xa5b285fc5937ebdc), CONST64(0x4f731ef8b76dc4a9), CONST64(0xdd90a8954838d8e0), + CONST64(0xa1b10877d6b967de), CONST64(0xbf37442a9573a2d1), CONST64(0x1b4ca53d26e96a83), CONST64(0xb5be8bea5f35e1d4), + CONST64(0x92e3b66dff551c49), CONST64(0xaf3b4a3c9371a8d9), CONST64(0xff077c728d7b8af1), CONST64(0x140f839d898c860a), + CONST64(0xb73143219672a7d5), CONST64(0x34179fb18588921a), CONST64(0xe30ef8e407f609ff), CONST64(0x4dfcd6337e2a82a8), + CONST64(0xed84baaf423ec6f8), CONST64(0xcad98728e25e3b65), CONST64(0x25d2f54c6927bb9c), CONST64(0x0a89cfc0ca464305), + CONST64(0x60282474140c3c30), CONST64(0x0f4326a0af65ec89), CONST64(0x676d05dfb868d5bd), CONST64(0x2f5b3a8ca361f899), + CONST64(0x180a091d05030f0c), CONST64(0x46bc7d185ec1e223), CONST64(0x82efb87bf9571641), CONST64(0xfece189967d6a97f), + CONST64(0x86ec35f076d99a43), CONST64(0xfacd9512e858257d), CONST64(0x8eea32fb75d89f47), CONST64(0x17492fbdaa66e385), + CONST64(0xf6c81f9264d7ac7b), CONST64(0xcd9ca6834e3ad2e8), CONST64(0x0e8a424b45c8cf07), CONST64(0xfd88b4b9443cccf0), + CONST64(0x8326dc9013fa35cf), CONST64(0xc453c563a796f462), CONST64(0x51f552a5f4a701a6), CONST64(0xb477ef01b598c25a), + CONST64(0x3352be1a29ec7b97), CONST64(0xa9b70f7cd5b862da), CONST64(0x76a86f2254c7fc3b), CONST64(0x19c36df6efae2c82), + CONST64(0x6f6b02d4bb69d0b9), CONST64(0x62a7ecbfdd4b7a31), CONST64(0x31dd76d1e0ab3d96), CONST64(0x21d178c7e6a9379e), + CONST64(0x1f4f28b6a967e681), CONST64(0x503c364e1e0a2228), CONST64(0x028fc8cbc9474601), CONST64(0xc316e4c80bf21def), + CONST64(0xc1992c03c2b55bee), CONST64(0x0dccee6b6622aa88), CONST64(0x7b64814932e556b3), CONST64(0x235eb00c2fee719f), + CONST64(0x99a31d46dfbe7cc2), CONST64(0x45fad1387d2b87ac), CONST64(0x7c21a0e29e81bf3e), CONST64(0x906c7ea636125a48), + CONST64(0x6c2daef49883b536), CONST64(0xd85a41f52d1b776c), CONST64(0x70242a62120e3638), CONST64(0x05cae9606523af8c), + CONST64(0xfb04f1f902f506f3), CONST64(0x1283c6ddcf454c09), CONST64(0x15c6e7766321a584), CONST64(0x3e9e50714fced11f), + CONST64(0x72abe2a9db497039), CONST64(0x7de8c409742c9cb0), CONST64(0x9b2cd58d16f93ac3), CONST64(0x636e885437e659bf), + CONST64(0xd993251ec7b654e2), CONST64(0x5df0d825782888a0), CONST64(0xb872658139174b5c), CONST64(0x642ba9ff9b82b032), + CONST64(0xd05c46fe2e1a7268), CONST64(0x2c1d96ac808b9d16), CONST64(0xa33ec0bc1ffe21df), CONST64(0x241b91a7838a9812), + CONST64(0x48363f531b092d24), CONST64(0x068c454046c9ca03), CONST64(0x4c35b2d89487a126), CONST64(0x4ab9f798d24e6b25), + CONST64(0x5b7c9d653ee142a3), CONST64(0x6de4ca1f722e96b8), CONST64(0x7362864231e453b7), CONST64(0x537a9a6e3de047a7), + CONST64(0x0b40ab2b20eb608b), CONST64(0xf447d759ad90ea7a), CONST64(0x49ff5bb8f1a40eaa), CONST64(0xf0445ad2221e6678), + CONST64(0x5c39bcce9285ab2e), CONST64(0x275d3d87a060fd9d), CONST64(0x0000000000000000), CONST64(0x35defb5a6f25b194), + CONST64(0xf302f6f201f403f7), CONST64(0xdb1cedd50ef112e3), CONST64(0xd45fcb75a194fe6a), CONST64(0x583a31451d0b272c), + CONST64(0x6b688f5f34e75cbb), CONST64(0x8f2356109f75bcc9), CONST64(0x2b58b7072cef749b), CONST64(0xbdb88ce15c34e4d0), + CONST64(0x95a697c65331f5c4), CONST64(0xeec2168f61d4a377), CONST64(0xceda0aa36dd0b767), CONST64(0x4433b5d39786a422), + CONST64(0xd7196755827e9be5), CONST64(0x01c964ebeaad238e), CONST64(0xbb34c9a11afd2ed3), CONST64(0x55f6df2e7b298da4), + CONST64(0x9da090cd5030f0c0), CONST64(0xc59aa1884d3bd7ec), CONST64(0x8c65fa30bc9fd946), CONST64(0x932ad28615f83fc7), + CONST64(0x7eae682957c6f93f), CONST64(0x986a79ad35135f4c), CONST64(0x3014123a0a061e18), CONST64(0x281e1b270f051114), + CONST64(0x66a4613452c5f633), CONST64(0x886677bb33115544), CONST64(0x9f2f58069977b6c1), CONST64(0xc7156943847c91ed), + CONST64(0xf7017b798e7a8ff5), CONST64(0xe70d756f887885fd), CONST64(0xadb482f75a36eed8), CONST64(0xe04854c4241c6c70), + CONST64(0xd596af9e4b39dde4), CONST64(0xf2cb9219eb592079), CONST64(0xc05048e828187860), CONST64(0x8ae9bf70fa561345), + CONST64(0xf18d3e39c8b345f6), CONST64(0xe9873724cdb04afa), CONST64(0x3dd8fc516c24b490), CONST64(0x1dc0e07d6020a080), + CONST64(0xf98b3932cbb240f2), CONST64(0xe44bd94fab92e072), CONST64(0x71ed4e89f8a315b6), CONST64(0x4eba7a135dc0e727), + CONST64(0x1a85c1d6cc44490d), CONST64(0x37513391a662f795), CONST64(0x806070b030105040), CONST64(0xc99f2b08c1b45eea), + CONST64(0x543fbbc59184ae2a), CONST64(0x2297d4e7c5435211), CONST64(0xec4dde44a893e576), CONST64(0x5eb674055bc2ed2f), + CONST64(0x6aa1ebb4de4a7f35), CONST64(0x81a9145bdabd73ce), CONST64(0x0c058a808c8f8906), CONST64(0x75eec302772d99b4), + CONST64(0x89af1350d9bc76ca), CONST64(0x946ff32db99cd64a), CONST64(0x77610bc9be6adfb5), CONST64(0x3a9dddfac0405d1d), + CONST64(0x3698577a4ccfd41b), CONST64(0x79eb4982fba210b2), CONST64(0x7427a7e99d80ba3a), CONST64(0x42bff093d14f6e21), + CONST64(0xf8425dd9211f637c), CONST64(0x1e864c5d43cac50f), CONST64(0x39db71dae3aa3892), CONST64(0x2a91d3ecc6425715), +}; + +static const ulong64 T6[256] = { + CONST64(0x6a01bbb9d268bad3), CONST64(0x66b1e59a4d1954fc), CONST64(0x14cde265bc932f71), CONST64(0x1b512587cdb9749c), + CONST64(0x57a4f7a2510253f5), CONST64(0xbe03d0d66bb8d368), CONST64(0xb504d6de6fbdd26b), CONST64(0x85feb35229644dd7), + CONST64(0x4aadfdba5d0d50f0), CONST64(0xe063cf098a26ace9), CONST64(0x9684091c0e838d8a), CONST64(0x4d1aa591c679bfdc), + CONST64(0x374d3da7ddad7090), CONST64(0x5ca3f1aa550752f6), CONST64(0x17e17ba452c89ab3), CONST64(0x8ef9b55a2d614cd4), + CONST64(0x20ac46038f65ea23), CONST64(0x8411c4e673a6d562), CONST64(0x68c255cc66f197a4), CONST64(0xa80ddcc663b2d16e), + CONST64(0xd099aa85ccff3355), CONST64(0x41aafbb2590851f3), CONST64(0x0f9cc7e2712a5bed), CONST64(0xae55f359a204a6f7), + CONST64(0xc120febe5f81de7f), CONST64(0xa2e5ad7a3d7548d8), CONST64(0xcc7fd7299a32a8e5), CONST64(0x0ae871bc5ec799b6), + CONST64(0xe63be0964b90db70), CONST64(0xdb9eac8dc8fa3256), CONST64(0x152295d1e651b7c4), CONST64(0xaace32b3d72bfc19), + CONST64(0x7393704bab48e338), CONST64(0x3bfd638442dc9ebf), CONST64(0x52d041fc7eef91ae), CONST64(0x1ce67dac56cd9bb0), + CONST64(0x78947643af4de23b), CONST64(0x6106bdb1d66dbbd0), CONST64(0xf1da9b32195841c3), CONST64(0xe5177957a5cb6eb2), + CONST64(0xb35cf941ae0ba5f2), CONST64(0x564b80160bc0cb40), CONST64(0xc20c677fb1da6bbd), CONST64(0x7ecc59dc6efb95a2), + CONST64(0x9f40e161be1fa1fe), CONST64(0xc3e310cbeb18f308), CONST64(0x2f3081e1fe4fb1ce), CONST64(0x160e0c10080a0206), + CONST64(0x675e922e17dbcc49), CONST64(0x3f66a26e37f3c451), CONST64(0xcf534ee874691d27), CONST64(0x9c6c78a05044143c), + CONST64(0x0e73b0562be8c358), CONST64(0x9a34573f91f263a5), CONST64(0xed3ce69e4f95da73), CONST64(0x358ed3d269345de7), + CONST64(0x2380dfc2613e5fe1), CONST64(0xd72ef2ae578bdc79), CONST64(0x486e13cfe9947d87), CONST64(0x6c59942613decd4a), + CONST64(0x5e601fdfe19e7f81), CONST64(0x049bc1ea752f5aee), CONST64(0xf3197547adc16cb4), CONST64(0x3e89d5da6d315ce4), + CONST64(0xefff08ebfb0cf704), CONST64(0x47f2d42d98be266a), CONST64(0xb7c738abdb24ff1c), CONST64(0x11b9543b937eed2a), + CONST64(0x36a24a13876fe825), CONST64(0x26f4699c4ed39dba), CONST64(0xee107f5fa1ce6fb1), CONST64(0x8b8d0304028c8e8f), + CONST64(0xe34f56c8647d192b), CONST64(0x9447e769ba1aa0fd), CONST64(0xdeea1ad3e717f00d), CONST64(0xba98113c1e978986), + CONST64(0x692d22783c330f11), CONST64(0x311512381c1b0709), CONST64(0xfd6ac5118629afec), CONST64(0x9bdb208bcb30fb10), + CONST64(0x5838304020280818), CONST64(0x976b7ea85441153f), CONST64(0x7f232e6834390d17), CONST64(0x2c1c18201014040c), + CONST64(0x0b07060804050103), CONST64(0xab2145078de964ac), CONST64(0xca27f8b65b84df7c), CONST64(0x0d5f2997c5b3769a), + CONST64(0x64720beff980798b), CONST64(0xdc29f4a6538edd7a), CONST64(0xb2b38ef5f4c93d47), CONST64(0x8a6274b0584e163a), + CONST64(0xa4bd82e5fcc33f41), CONST64(0xfc85b2a5dceb3759), CONST64(0xf81e734fa9c46db7), CONST64(0x95a890dde0d83848), + CONST64(0x7708b1a1de67b9d6), CONST64(0x2a4437bfd1a27395), CONST64(0x3da54c1b836ae926), CONST64(0xea8bbeb5d4e1355f), + CONST64(0x6db6e392491c55ff), CONST64(0x3c4a3bafd9a87193), CONST64(0x727c07fff18a7b8d), CONST64(0x9d830f140a868c89), + CONST64(0x214331b7d5a77296), CONST64(0xb19f17341a928885), CONST64(0xe4f80ee3ff09f607), CONST64(0x33d6fc4da8822a7e), + CONST64(0xafba84edf8c63e42), CONST64(0x2887d9ca653b5ee2), CONST64(0x4cf5d2259cbb2769), CONST64(0xc0cf890a054346ca), + CONST64(0x74242860303c0c14), CONST64(0xa026430f89ec65af), CONST64(0xdf056d67bdd568b8), CONST64(0x8c3a5b2f99f861a3), + CONST64(0x1d090a180c0f0305), CONST64(0x187dbc4623e2c15e), CONST64(0x7bb8ef82411657f9), CONST64(0x9918cefe7fa9d667), + CONST64(0xf035ec86439ad976), CONST64(0x1295cdfa7d2558e8), CONST64(0xfb32ea8e479fd875), CONST64(0xbd2f491785e366aa), + CONST64(0x921fc8f67bacd764), CONST64(0x83a69ccde8d23a4e), CONST64(0x4b428a0e07cfc845), CONST64(0xb9b488fdf0cc3c44), + CONST64(0x90dc2683cf35fa13), CONST64(0x63c553c462f496a7), CONST64(0xa552f551a601a7f4), CONST64(0x01ef77b45ac298b5), + CONST64(0x1abe5233977bec29), CONST64(0x7c0fb7a9da62b8d5), CONST64(0x226fa8763bfcc754), CONST64(0xf66dc319822caeef), + CONST64(0xd4026b6fb9d069bb), CONST64(0xbfeca762317a4bdd), CONST64(0xd176dd31963dabe0), CONST64(0xc778d1219e37a9e6), + CONST64(0xb6284f1f81e667a9), CONST64(0x4e363c5028220a1e), CONST64(0xcbc88f02014647c9), CONST64(0xc8e416c3ef1df20b), + CONST64(0x032c99c1ee5bb5c2), CONST64(0x6beecc0d88aa2266), CONST64(0x4981647bb356e532), CONST64(0x0cb05e239f71ee2f), + CONST64(0x461da399c27cbedf), CONST64(0x38d1fa45ac872b7d), CONST64(0xe2a0217c3ebf819e), CONST64(0xa67e6c90485a1236), + CONST64(0xf4ae2d6c36b58398), CONST64(0xf5415ad86c771b2d), CONST64(0x622a247038360e12), CONST64(0x60e9ca058caf2365), + CONST64(0xf9f104fbf306f502), CONST64(0xddc68312094c45cf), CONST64(0x76e7c61584a52163), CONST64(0x71509e3e1fd1ce4f), + CONST64(0xa9e2ab72397049db), CONST64(0x09c4e87db09c2c74), CONST64(0x8dd52c9bc33af916), CONST64(0x54886e63bf59e637), + CONST64(0x1e2593d9e254b6c7), CONST64(0x25d8f05da0882878), CONST64(0x816572b85c4b1739), CONST64(0xffa92b6432b0829b), + CONST64(0xfe465cd068721a2e), CONST64(0xac961d2c169d8b80), CONST64(0xbcc03ea3df21fe1f), CONST64(0xa7911b2412988a83), + CONST64(0x533f3648242d091b), CONST64(0x40458c0603cac946), CONST64(0xd8b2354c26a18794), CONST64(0x98f7b94a256b4ed2), + CONST64(0x659d7c5ba342e13e), CONST64(0x1fcae46db8962e72), CONST64(0x42866273b753e431), CONST64(0x6e9a7a53a747e03d), + CONST64(0x2bab400b8b60eb20), CONST64(0x59d747f47aea90ad), CONST64(0xb85bff49aa0ea4f1), CONST64(0xd25a44f078661e22), + CONST64(0xcebc395c2eab8592), CONST64(0x873d5d279dfd60a0), CONST64(0x0000000000000000), CONST64(0x5afbde3594b1256f), + CONST64(0xf2f602f3f703f401), CONST64(0xd5ed1cdbe312f10e), CONST64(0x75cb5fd46afe94a1), CONST64(0x45313a582c270b1d), + CONST64(0x5f8f686bbb5ce734), CONST64(0x1056238fc9bc759f), CONST64(0x07b7582b9b74ef2c), CONST64(0xe18cb8bdd0e4345c), + CONST64(0xc697a695c4f53153), CONST64(0x8f16c2ee77a3d461), CONST64(0xa30adace67b7d06d), CONST64(0xd3b5334422a48697), + CONST64(0x556719d7e59b7e82), CONST64(0xeb64c9018e23adea), CONST64(0xa1c934bbd32efd1a), CONST64(0x2edff655a48d297b), + CONST64(0xcd90a09dc0f03050), CONST64(0x88a19ac5ecd73b4d), CONST64(0x30fa658c46d99fbc), CONST64(0x86d22a93c73ff815), + CONST64(0x2968ae7e3ff9c657), CONST64(0xad796a984c5f1335), CONST64(0x3a121430181e060a), CONST64(0x271b1e281411050f), + CONST64(0x3461a46633f6c552), CONST64(0xbb77668844551133), CONST64(0x06582f9fc1b67799), CONST64(0x436915c7ed917c84), + CONST64(0x797b01f7f58f7a8e), CONST64(0x6f750de7fd857888), CONST64(0xf782b4add8ee365a), CONST64(0xc45448e0706c1c24), + CONST64(0x9eaf96d5e4dd394b), CONST64(0x1992cbf2792059eb), CONST64(0xe84850c060781828), CONST64(0x70bfe98a451356fa), + CONST64(0x393e8df1f645b3c8), CONST64(0x243787e9fa4ab0cd), CONST64(0x51fcd83d90b4246c), CONST64(0x7de0c01d80a02060), + CONST64(0x32398bf9f240b2cb), CONST64(0x4fd94be472e092ab), CONST64(0x894eed71b615a3f8), CONST64(0x137aba4e27e7c05d), + CONST64(0xd6c1851a0d4944cc), CONST64(0x9133513795f762a6), CONST64(0xb070608040501030), CONST64(0x082b9fc9ea5eb4c1), + CONST64(0xc5bb3f542aae8491), CONST64(0xe7d49722115243c5), CONST64(0x44de4dec76e593a8), CONST64(0x0574b65e2fedc25b), + CONST64(0xb4eba16a357f4ade), CONST64(0x5b14a981ce73bdda), CONST64(0x808a050c06898f8c), CONST64(0x02c3ee75b4992d77), + CONST64(0x5013af89ca76bcd9), CONST64(0x2df36f944ad69cb9), CONST64(0xc90b6177b5df6abe), CONST64(0xfadd9d3a1d5d40c0), + CONST64(0x7a5798361bd4cf4c), CONST64(0x8249eb79b210a2fb), CONST64(0xe9a727743aba809d), CONST64(0x93f0bf42216e4fd1), + CONST64(0xd95d42f87c631f21), CONST64(0x5d4c861e0fc5ca43), CONST64(0xda71db399238aae3), CONST64(0xecd3912a155742c6), +}; + +static const ulong64 T7[256] = { + CONST64(0x016ab9bb68d2d3ba), CONST64(0xb1669ae5194dfc54), CONST64(0xcd1465e293bc712f), CONST64(0x511b8725b9cd9c74), + CONST64(0xa457a2f70251f553), CONST64(0x03bed6d0b86b68d3), CONST64(0x04b5ded6bd6f6bd2), CONST64(0xfe8552b36429d74d), + CONST64(0xad4abafd0d5df050), CONST64(0x63e009cf268ae9ac), CONST64(0x84961c09830e8a8d), CONST64(0x1a4d91a579c6dcbf), + CONST64(0x4d37a73daddd9070), CONST64(0xa35caaf10755f652), CONST64(0xe117a47bc852b39a), CONST64(0xf98e5ab5612dd44c), + CONST64(0xac200346658f23ea), CONST64(0x1184e6c4a67362d5), CONST64(0xc268cc55f166a497), CONST64(0x0da8c6dcb2636ed1), + CONST64(0x99d085aaffcc5533), CONST64(0xaa41b2fb0859f351), CONST64(0x9c0fe2c72a71ed5b), CONST64(0x55ae59f304a2f7a6), + CONST64(0x20c1befe815f7fde), CONST64(0xe5a27aad753dd848), CONST64(0x7fcc29d7329ae5a8), CONST64(0xe80abc71c75eb699), + CONST64(0x3be696e0904b70db), CONST64(0x9edb8dacfac85632), CONST64(0x2215d19551e6c4b7), CONST64(0xceaab3322bd719fc), + CONST64(0x93734b7048ab38e3), CONST64(0xfd3b8463dc42bf9e), CONST64(0xd052fc41ef7eae91), CONST64(0xe61cac7dcd56b09b), + CONST64(0x947843764daf3be2), CONST64(0x0661b1bd6dd6d0bb), CONST64(0xdaf1329b5819c341), CONST64(0x17e55779cba5b26e), + CONST64(0x5cb341f90baef2a5), CONST64(0x4b561680c00b40cb), CONST64(0x0cc27f67dab1bd6b), CONST64(0xcc7edc59fb6ea295), + CONST64(0x409f61e11fbefea1), CONST64(0xe3c3cb1018eb08f3), CONST64(0x302fe1814ffeceb1), CONST64(0x0e16100c0a080602), + CONST64(0x5e672e92db1749cc), CONST64(0x663f6ea2f33751c4), CONST64(0x53cfe84e6974271d), CONST64(0x6c9ca07844503c14), + CONST64(0x730e56b0e82b58c3), CONST64(0x349a3f57f291a563), CONST64(0x3ced9ee6954f73da), CONST64(0x8e35d2d33469e75d), + CONST64(0x8023c2df3e61e15f), CONST64(0x2ed7aef28b5779dc), CONST64(0x6e48cf1394e9877d), CONST64(0x596c2694de134acd), + CONST64(0x605edf1f9ee1817f), CONST64(0x9b04eac12f75ee5a), CONST64(0x19f34775c1adb46c), CONST64(0x893edad5316de45c), + CONST64(0xffefeb080cfb04f7), CONST64(0xf2472dd4be986a26), CONST64(0xc7b7ab3824db1cff), CONST64(0xb9113b547e932aed), + CONST64(0xa236134a6f8725e8), CONST64(0xf4269c69d34eba9d), CONST64(0x10ee5f7fcea1b16f), CONST64(0x8d8b04038c028f8e), + CONST64(0x4fe3c8567d642b19), CONST64(0x479469e71abafda0), CONST64(0xeaded31a17e70df0), CONST64(0x98ba3c11971e8689), + CONST64(0x2d697822333c110f), CONST64(0x153138121b1c0907), CONST64(0x6afd11c52986ecaf), CONST64(0xdb9b8b2030cb10fb), + CONST64(0x3858403028201808), CONST64(0x6b97a87e41543f15), CONST64(0x237f682e3934170d), CONST64(0x1c2c201814100c04), + CONST64(0x070b080605040301), CONST64(0x21ab0745e98dac64), CONST64(0x27cab6f8845b7cdf), CONST64(0x5f0d9729b3c59a76), + CONST64(0x7264ef0b80f98b79), CONST64(0x29dca6f48e537add), CONST64(0xb3b2f58ec9f4473d), CONST64(0x628ab0744e583a16), + CONST64(0xbda4e582c3fc413f), CONST64(0x85fca5b2ebdc5937), CONST64(0x1ef84f73c4a9b76d), CONST64(0xa895dd90d8e04838), + CONST64(0x0877a1b167ded6b9), CONST64(0x442abf37a2d19573), CONST64(0xa53d1b4c6a8326e9), CONST64(0x8beab5bee1d45f35), + CONST64(0xb66d92e31c49ff55), CONST64(0x4a3caf3ba8d99371), CONST64(0x7c72ff078af18d7b), CONST64(0x839d140f860a898c), + CONST64(0x4321b731a7d59672), CONST64(0x9fb13417921a8588), CONST64(0xf8e4e30e09ff07f6), CONST64(0xd6334dfc82a87e2a), + CONST64(0xbaafed84c6f8423e), CONST64(0x8728cad93b65e25e), CONST64(0xf54c25d2bb9c6927), CONST64(0xcfc00a894305ca46), + CONST64(0x247460283c30140c), CONST64(0x26a00f43ec89af65), CONST64(0x05df676dd5bdb868), CONST64(0x3a8c2f5bf899a361), + CONST64(0x091d180a0f0c0503), CONST64(0x7d1846bce2235ec1), CONST64(0xb87b82ef1641f957), CONST64(0x1899fecea97f67d6), + CONST64(0x35f086ec9a4376d9), CONST64(0x9512facd257de858), CONST64(0x32fb8eea9f4775d8), CONST64(0x2fbd1749e385aa66), + CONST64(0x1f92f6c8ac7b64d7), CONST64(0xa683cd9cd2e84e3a), CONST64(0x424b0e8acf0745c8), CONST64(0xb4b9fd88ccf0443c), + CONST64(0xdc90832635cf13fa), CONST64(0xc563c453f462a796), CONST64(0x52a551f501a6f4a7), CONST64(0xef01b477c25ab598), + CONST64(0xbe1a33527b9729ec), CONST64(0x0f7ca9b762dad5b8), CONST64(0x6f2276a8fc3b54c7), CONST64(0x6df619c32c82efae), + CONST64(0x02d46f6bd0b9bb69), CONST64(0xecbf62a77a31dd4b), CONST64(0x76d131dd3d96e0ab), CONST64(0x78c721d1379ee6a9), + CONST64(0x28b61f4fe681a967), CONST64(0x364e503c22281e0a), CONST64(0xc8cb028f4601c947), CONST64(0xe4c8c3161def0bf2), + CONST64(0x2c03c1995beec2b5), CONST64(0xee6b0dccaa886622), CONST64(0x81497b6456b332e5), CONST64(0xb00c235e719f2fee), + CONST64(0x1d4699a37cc2dfbe), CONST64(0xd13845fa87ac7d2b), CONST64(0xa0e27c21bf3e9e81), CONST64(0x7ea6906c5a483612), + CONST64(0xaef46c2db5369883), CONST64(0x41f5d85a776c2d1b), CONST64(0x2a6270243638120e), CONST64(0xe96005caaf8c6523), + CONST64(0xf1f9fb0406f302f5), CONST64(0xc6dd12834c09cf45), CONST64(0xe77615c6a5846321), CONST64(0x50713e9ed11f4fce), + CONST64(0xe2a972ab7039db49), CONST64(0xc4097de89cb0742c), CONST64(0xd58d9b2c3ac316f9), CONST64(0x8854636e59bf37e6), + CONST64(0x251ed99354e2c7b6), CONST64(0xd8255df088a07828), CONST64(0x6581b8724b5c3917), CONST64(0xa9ff642bb0329b82), + CONST64(0x46fed05c72682e1a), CONST64(0x96ac2c1d9d16808b), CONST64(0xc0bca33e21df1ffe), CONST64(0x91a7241b9812838a), + CONST64(0x3f5348362d241b09), CONST64(0x4540068cca0346c9), CONST64(0xb2d84c35a1269487), CONST64(0xf7984ab96b25d24e), + CONST64(0x9d655b7c42a33ee1), CONST64(0xca1f6de496b8722e), CONST64(0x8642736253b731e4), CONST64(0x9a6e537a47a73de0), + CONST64(0xab2b0b40608b20eb), CONST64(0xd759f447ea7aad90), CONST64(0x5bb849ff0eaaf1a4), CONST64(0x5ad2f0446678221e), + CONST64(0xbcce5c39ab2e9285), CONST64(0x3d87275dfd9da060), CONST64(0x0000000000000000), CONST64(0xfb5a35deb1946f25), + CONST64(0xf6f2f30203f701f4), CONST64(0xedd5db1c12e30ef1), CONST64(0xcb75d45ffe6aa194), CONST64(0x3145583a272c1d0b), + CONST64(0x8f5f6b685cbb34e7), CONST64(0x56108f23bcc99f75), CONST64(0xb7072b58749b2cef), CONST64(0x8ce1bdb8e4d05c34), + CONST64(0x97c695a6f5c45331), CONST64(0x168feec2a37761d4), CONST64(0x0aa3cedab7676dd0), CONST64(0xb5d34433a4229786), + CONST64(0x6755d7199be5827e), CONST64(0x64eb01c9238eeaad), CONST64(0xc9a1bb342ed31afd), CONST64(0xdf2e55f68da47b29), + CONST64(0x90cd9da0f0c05030), CONST64(0xa188c59ad7ec4d3b), CONST64(0xfa308c65d946bc9f), CONST64(0xd286932a3fc715f8), + CONST64(0x68297eaef93f57c6), CONST64(0x79ad986a5f4c3513), CONST64(0x123a30141e180a06), CONST64(0x1b27281e11140f05), + CONST64(0x613466a4f63352c5), CONST64(0x77bb886655443311), CONST64(0x58069f2fb6c19977), CONST64(0x6943c71591ed847c), + CONST64(0x7b79f7018ff58e7a), CONST64(0x756fe70d85fd8878), CONST64(0x82f7adb4eed85a36), CONST64(0x54c4e0486c70241c), + CONST64(0xaf9ed596dde44b39), CONST64(0x9219f2cb2079eb59), CONST64(0x48e8c05078602818), CONST64(0xbf708ae91345fa56), + CONST64(0x3e39f18d45f6c8b3), CONST64(0x3724e9874afacdb0), CONST64(0xfc513dd8b4906c24), CONST64(0xe07d1dc0a0806020), + CONST64(0x3932f98b40f2cbb2), CONST64(0xd94fe44be072ab92), CONST64(0x4e8971ed15b6f8a3), CONST64(0x7a134ebae7275dc0), + CONST64(0xc1d61a85490dcc44), CONST64(0x33913751f795a662), CONST64(0x70b0806050403010), CONST64(0x2b08c99f5eeac1b4), + CONST64(0xbbc5543fae2a9184), CONST64(0xd4e722975211c543), CONST64(0xde44ec4de576a893), CONST64(0x74055eb6ed2f5bc2), + CONST64(0xebb46aa17f35de4a), CONST64(0x145b81a973cedabd), CONST64(0x8a800c0589068c8f), CONST64(0xc30275ee99b4772d), + CONST64(0x135089af76cad9bc), CONST64(0xf32d946fd64ab99c), CONST64(0x0bc97761dfb5be6a), CONST64(0xddfa3a9d5d1dc040), + CONST64(0x577a3698d41b4ccf), CONST64(0x498279eb10b2fba2), CONST64(0xa7e97427ba3a9d80), CONST64(0xf09342bf6e21d14f), + CONST64(0x5dd9f842637c211f), CONST64(0x4c5d1e86c50f43ca), CONST64(0x71da39db3892e3aa), CONST64(0xd3ec2a915715c642), +}; + +static const ulong64 c[R + 1] = { + CONST64(0xba542f7453d3d24d), + CONST64(0x50ac8dbf70529a4c), + CONST64(0xead597d133515ba6), + CONST64(0xde48a899db32b7fc), + CONST64(0xe39e919be2bb416e), + CONST64(0xa5cb6b95a1f3b102), + CONST64(0xccc41d14c363da5d), + CONST64(0x5fdc7dcd7f5a6c5c), + CONST64(0xf726ffede89d6f8e), +}; + + /** + Initialize the Khazad block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int r; + const ulong64 *S; + ulong64 K2, K1; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + if (keylen != 16) { + return CRYPT_INVALID_KEYSIZE; + } + if (num_rounds != 8 && num_rounds != 0) { + return CRYPT_INVALID_ROUNDS; + } + + /* use 7th table */ + S = T7; + + /* + * map unsigned char array cipher key to initial key state (mu): + */ + K2 = + ((ulong64)key[ 0] << 56) ^ + ((ulong64)key[ 1] << 48) ^ + ((ulong64)key[ 2] << 40) ^ + ((ulong64)key[ 3] << 32) ^ + ((ulong64)key[ 4] << 24) ^ + ((ulong64)key[ 5] << 16) ^ + ((ulong64)key[ 6] << 8) ^ + ((ulong64)key[ 7] ); + K1 = + ((ulong64)key[ 8] << 56) ^ + ((ulong64)key[ 9] << 48) ^ + ((ulong64)key[10] << 40) ^ + ((ulong64)key[11] << 32) ^ + ((ulong64)key[12] << 24) ^ + ((ulong64)key[13] << 16) ^ + ((ulong64)key[14] << 8) ^ + ((ulong64)key[15] ); + + /* + * compute the round keys: + */ + for (r = 0; r <= R; r++) { + /* + * K[r] = rho(c[r], K1) ^ K2; + */ + skey->khazad.roundKeyEnc[r] = + T0[(int)(K1 >> 56) ] ^ + T1[(int)(K1 >> 48) & 0xff] ^ + T2[(int)(K1 >> 40) & 0xff] ^ + T3[(int)(K1 >> 32) & 0xff] ^ + T4[(int)(K1 >> 24) & 0xff] ^ + T5[(int)(K1 >> 16) & 0xff] ^ + T6[(int)(K1 >> 8) & 0xff] ^ + T7[(int)(K1 ) & 0xff] ^ + c[r] ^ K2; + K2 = K1; K1 = skey->khazad.roundKeyEnc[r]; + } + /* + * compute the inverse key schedule: + * K'^0 = K^R, K'^R = K^0, K'^r = theta(K^{R-r}) + */ + skey->khazad.roundKeyDec[0] = skey->khazad.roundKeyEnc[R]; + for (r = 1; r < R; r++) { + K1 = skey->khazad.roundKeyEnc[R - r]; + skey->khazad.roundKeyDec[r] = + T0[(int)S[(int)(K1 >> 56) ] & 0xff] ^ + T1[(int)S[(int)(K1 >> 48) & 0xff] & 0xff] ^ + T2[(int)S[(int)(K1 >> 40) & 0xff] & 0xff] ^ + T3[(int)S[(int)(K1 >> 32) & 0xff] & 0xff] ^ + T4[(int)S[(int)(K1 >> 24) & 0xff] & 0xff] ^ + T5[(int)S[(int)(K1 >> 16) & 0xff] & 0xff] ^ + T6[(int)S[(int)(K1 >> 8) & 0xff] & 0xff] ^ + T7[(int)S[(int)(K1 ) & 0xff] & 0xff]; + } + skey->khazad.roundKeyDec[R] = skey->khazad.roundKeyEnc[0]; + + return CRYPT_OK; +} + +static void khazad_crypt(const unsigned char *plaintext, unsigned char *ciphertext, + const ulong64 *roundKey) { + int r; + ulong64 state; + /* + * map plaintext block to cipher state (mu) + * and add initial round key (sigma[K^0]): + */ + state = + ((ulong64)plaintext[0] << 56) ^ + ((ulong64)plaintext[1] << 48) ^ + ((ulong64)plaintext[2] << 40) ^ + ((ulong64)plaintext[3] << 32) ^ + ((ulong64)plaintext[4] << 24) ^ + ((ulong64)plaintext[5] << 16) ^ + ((ulong64)plaintext[6] << 8) ^ + ((ulong64)plaintext[7] ) ^ + roundKey[0]; + + /* + * R - 1 full rounds: + */ + for (r = 1; r < R; r++) { + state = + T0[(int)(state >> 56) ] ^ + T1[(int)(state >> 48) & 0xff] ^ + T2[(int)(state >> 40) & 0xff] ^ + T3[(int)(state >> 32) & 0xff] ^ + T4[(int)(state >> 24) & 0xff] ^ + T5[(int)(state >> 16) & 0xff] ^ + T6[(int)(state >> 8) & 0xff] ^ + T7[(int)(state ) & 0xff] ^ + roundKey[r]; + } + + /* + * last round: + */ + state = + (T0[(int)(state >> 56) ] & CONST64(0xff00000000000000)) ^ + (T1[(int)(state >> 48) & 0xff] & CONST64(0x00ff000000000000)) ^ + (T2[(int)(state >> 40) & 0xff] & CONST64(0x0000ff0000000000)) ^ + (T3[(int)(state >> 32) & 0xff] & CONST64(0x000000ff00000000)) ^ + (T4[(int)(state >> 24) & 0xff] & CONST64(0x00000000ff000000)) ^ + (T5[(int)(state >> 16) & 0xff] & CONST64(0x0000000000ff0000)) ^ + (T6[(int)(state >> 8) & 0xff] & CONST64(0x000000000000ff00)) ^ + (T7[(int)(state ) & 0xff] & CONST64(0x00000000000000ff)) ^ + roundKey[R]; + + /* + * map cipher state to ciphertext block (mu^{-1}): + */ + ciphertext[0] = (unsigned char)(state >> 56); + ciphertext[1] = (unsigned char)(state >> 48); + ciphertext[2] = (unsigned char)(state >> 40); + ciphertext[3] = (unsigned char)(state >> 32); + ciphertext[4] = (unsigned char)(state >> 24); + ciphertext[5] = (unsigned char)(state >> 16); + ciphertext[6] = (unsigned char)(state >> 8); + ciphertext[7] = (unsigned char)(state ); +} + +/** + Encrypts a block of text with Khazad + @param pt The input plaintext (8 bytes) + @param ct The output ciphertext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + khazad_crypt(pt, ct, skey->khazad.roundKeyEnc); + return CRYPT_OK; +} + +/** + Decrypts a block of text with Khazad + @param ct The input ciphertext (8 bytes) + @param pt The output plaintext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + khazad_crypt(ct, pt, skey->khazad.roundKeyDec); + return CRYPT_OK; +} + +/** + Performs a self-test of the Khazad block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int khazad_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct test { + unsigned char pt[8], ct[8], key[16]; + } tests[] = { +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x49, 0xA4, 0xCE, 0x32, 0xAC, 0x19, 0x0E, 0x3F }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}, { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x64, 0x5D, 0x77, 0x3E, 0x40, 0xAB, 0xDD, 0x53 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } +}, { + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x9E, 0x39, 0x98, 0x64, 0xF7, 0x8E, 0xCA, 0x02 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}, { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + { 0xA9, 0xDF, 0x3D, 0x2C, 0x64, 0xD3, 0xEA, 0x28 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +} +}; + int x, y; + unsigned char buf[2][8]; + symmetric_key skey; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + khazad_setup(tests[x].key, 16, 0, &skey); + khazad_ecb_encrypt(tests[x].pt, buf[0], &skey); + khazad_ecb_decrypt(buf[0], buf[1], &skey); + if (XMEMCMP(buf[0], tests[x].ct, 8) || XMEMCMP(buf[1], tests[x].pt, 8)) { + return CRYPT_FAIL_TESTVECTOR; + } + + for (y = 0; y < 1000; y++) khazad_ecb_encrypt(buf[0], buf[0], &skey); + for (y = 0; y < 1000; y++) khazad_ecb_decrypt(buf[0], buf[0], &skey); + if (XMEMCMP(buf[0], tests[x].ct, 8)) { + return CRYPT_FAIL_TESTVECTOR; + } + + } + return CRYPT_OK; +#endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void khazad_done(symmetric_key *skey) +{ +} + +/** + Gets suitable key size + @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. + @return CRYPT_OK if the input key size is acceptable. +*/ +int khazad_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize >= 16) { + *keysize = 16; + return CRYPT_OK; + } else { + return CRYPT_INVALID_KEYSIZE; + } +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/khazad.c,v $ */ +/* $Revision: 1.14 $ */ +/* $Date: 2007/05/12 14:20:27 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/kseed.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/kseed.c new file mode 100644 index 0000000000..6727b5f4bb --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/kseed.c @@ -0,0 +1,376 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file kseed.c + seed implementation of SEED derived from RFC4269 + Tom St Denis +*/ + +#include "tomcrypt.h" + +#ifdef LTC_KSEED + +const struct ltc_cipher_descriptor kseed_desc = { + "seed", + 20, + 16, 16, 16, 16, + &kseed_setup, + &kseed_ecb_encrypt, + &kseed_ecb_decrypt, + &kseed_test, + &kseed_done, + &kseed_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +static const ulong32 SS0[256] = { +0x2989A1A8UL,0x05858184UL,0x16C6D2D4UL,0x13C3D3D0UL,0x14445054UL,0x1D0D111CUL,0x2C8CA0ACUL,0x25052124UL, +0x1D4D515CUL,0x03434340UL,0x18081018UL,0x1E0E121CUL,0x11415150UL,0x3CCCF0FCUL,0x0ACAC2C8UL,0x23436360UL, +0x28082028UL,0x04444044UL,0x20002020UL,0x1D8D919CUL,0x20C0E0E0UL,0x22C2E2E0UL,0x08C8C0C8UL,0x17071314UL, +0x2585A1A4UL,0x0F8F838CUL,0x03030300UL,0x3B4B7378UL,0x3B8BB3B8UL,0x13031310UL,0x12C2D2D0UL,0x2ECEE2ECUL, +0x30407070UL,0x0C8C808CUL,0x3F0F333CUL,0x2888A0A8UL,0x32023230UL,0x1DCDD1DCUL,0x36C6F2F4UL,0x34447074UL, +0x2CCCE0ECUL,0x15859194UL,0x0B0B0308UL,0x17475354UL,0x1C4C505CUL,0x1B4B5358UL,0x3D8DB1BCUL,0x01010100UL, +0x24042024UL,0x1C0C101CUL,0x33437370UL,0x18889098UL,0x10001010UL,0x0CCCC0CCUL,0x32C2F2F0UL,0x19C9D1D8UL, +0x2C0C202CUL,0x27C7E3E4UL,0x32427270UL,0x03838380UL,0x1B8B9398UL,0x11C1D1D0UL,0x06868284UL,0x09C9C1C8UL, +0x20406060UL,0x10405050UL,0x2383A3A0UL,0x2BCBE3E8UL,0x0D0D010CUL,0x3686B2B4UL,0x1E8E929CUL,0x0F4F434CUL, +0x3787B3B4UL,0x1A4A5258UL,0x06C6C2C4UL,0x38487078UL,0x2686A2A4UL,0x12021210UL,0x2F8FA3ACUL,0x15C5D1D4UL, +0x21416160UL,0x03C3C3C0UL,0x3484B0B4UL,0x01414140UL,0x12425250UL,0x3D4D717CUL,0x0D8D818CUL,0x08080008UL, +0x1F0F131CUL,0x19899198UL,0x00000000UL,0x19091118UL,0x04040004UL,0x13435350UL,0x37C7F3F4UL,0x21C1E1E0UL, +0x3DCDF1FCUL,0x36467274UL,0x2F0F232CUL,0x27072324UL,0x3080B0B0UL,0x0B8B8388UL,0x0E0E020CUL,0x2B8BA3A8UL, +0x2282A2A0UL,0x2E4E626CUL,0x13839390UL,0x0D4D414CUL,0x29496168UL,0x3C4C707CUL,0x09090108UL,0x0A0A0208UL, +0x3F8FB3BCUL,0x2FCFE3ECUL,0x33C3F3F0UL,0x05C5C1C4UL,0x07878384UL,0x14041014UL,0x3ECEF2FCUL,0x24446064UL, +0x1ECED2DCUL,0x2E0E222CUL,0x0B4B4348UL,0x1A0A1218UL,0x06060204UL,0x21012120UL,0x2B4B6368UL,0x26466264UL, +0x02020200UL,0x35C5F1F4UL,0x12829290UL,0x0A8A8288UL,0x0C0C000CUL,0x3383B3B0UL,0x3E4E727CUL,0x10C0D0D0UL, +0x3A4A7278UL,0x07474344UL,0x16869294UL,0x25C5E1E4UL,0x26062224UL,0x00808080UL,0x2D8DA1ACUL,0x1FCFD3DCUL, +0x2181A1A0UL,0x30003030UL,0x37073334UL,0x2E8EA2ACUL,0x36063234UL,0x15051114UL,0x22022220UL,0x38083038UL, +0x34C4F0F4UL,0x2787A3A4UL,0x05454144UL,0x0C4C404CUL,0x01818180UL,0x29C9E1E8UL,0x04848084UL,0x17879394UL, +0x35053134UL,0x0BCBC3C8UL,0x0ECEC2CCUL,0x3C0C303CUL,0x31417170UL,0x11011110UL,0x07C7C3C4UL,0x09898188UL, +0x35457174UL,0x3BCBF3F8UL,0x1ACAD2D8UL,0x38C8F0F8UL,0x14849094UL,0x19495158UL,0x02828280UL,0x04C4C0C4UL, +0x3FCFF3FCUL,0x09494148UL,0x39093138UL,0x27476364UL,0x00C0C0C0UL,0x0FCFC3CCUL,0x17C7D3D4UL,0x3888B0B8UL, +0x0F0F030CUL,0x0E8E828CUL,0x02424240UL,0x23032320UL,0x11819190UL,0x2C4C606CUL,0x1BCBD3D8UL,0x2484A0A4UL, +0x34043034UL,0x31C1F1F0UL,0x08484048UL,0x02C2C2C0UL,0x2F4F636CUL,0x3D0D313CUL,0x2D0D212CUL,0x00404040UL, +0x3E8EB2BCUL,0x3E0E323CUL,0x3C8CB0BCUL,0x01C1C1C0UL,0x2A8AA2A8UL,0x3A8AB2B8UL,0x0E4E424CUL,0x15455154UL, +0x3B0B3338UL,0x1CCCD0DCUL,0x28486068UL,0x3F4F737CUL,0x1C8C909CUL,0x18C8D0D8UL,0x0A4A4248UL,0x16465254UL, +0x37477374UL,0x2080A0A0UL,0x2DCDE1ECUL,0x06464244UL,0x3585B1B4UL,0x2B0B2328UL,0x25456164UL,0x3ACAF2F8UL, +0x23C3E3E0UL,0x3989B1B8UL,0x3181B1B0UL,0x1F8F939CUL,0x1E4E525CUL,0x39C9F1F8UL,0x26C6E2E4UL,0x3282B2B0UL, +0x31013130UL,0x2ACAE2E8UL,0x2D4D616CUL,0x1F4F535CUL,0x24C4E0E4UL,0x30C0F0F0UL,0x0DCDC1CCUL,0x08888088UL, +0x16061214UL,0x3A0A3238UL,0x18485058UL,0x14C4D0D4UL,0x22426260UL,0x29092128UL,0x07070304UL,0x33033330UL, +0x28C8E0E8UL,0x1B0B1318UL,0x05050104UL,0x39497178UL,0x10809090UL,0x2A4A6268UL,0x2A0A2228UL,0x1A8A9298UL +}; + +static const ulong32 SS1[256] = { +0x38380830UL,0xE828C8E0UL,0x2C2D0D21UL,0xA42686A2UL,0xCC0FCFC3UL,0xDC1ECED2UL,0xB03383B3UL,0xB83888B0UL, +0xAC2F8FA3UL,0x60204060UL,0x54154551UL,0xC407C7C3UL,0x44044440UL,0x6C2F4F63UL,0x682B4B63UL,0x581B4B53UL, +0xC003C3C3UL,0x60224262UL,0x30330333UL,0xB43585B1UL,0x28290921UL,0xA02080A0UL,0xE022C2E2UL,0xA42787A3UL, +0xD013C3D3UL,0x90118191UL,0x10110111UL,0x04060602UL,0x1C1C0C10UL,0xBC3C8CB0UL,0x34360632UL,0x480B4B43UL, +0xEC2FCFE3UL,0x88088880UL,0x6C2C4C60UL,0xA82888A0UL,0x14170713UL,0xC404C4C0UL,0x14160612UL,0xF434C4F0UL, +0xC002C2C2UL,0x44054541UL,0xE021C1E1UL,0xD416C6D2UL,0x3C3F0F33UL,0x3C3D0D31UL,0x8C0E8E82UL,0x98188890UL, +0x28280820UL,0x4C0E4E42UL,0xF436C6F2UL,0x3C3E0E32UL,0xA42585A1UL,0xF839C9F1UL,0x0C0D0D01UL,0xDC1FCFD3UL, +0xD818C8D0UL,0x282B0B23UL,0x64264662UL,0x783A4A72UL,0x24270723UL,0x2C2F0F23UL,0xF031C1F1UL,0x70324272UL, +0x40024242UL,0xD414C4D0UL,0x40014141UL,0xC000C0C0UL,0x70334373UL,0x64274763UL,0xAC2C8CA0UL,0x880B8B83UL, +0xF437C7F3UL,0xAC2D8DA1UL,0x80008080UL,0x1C1F0F13UL,0xC80ACAC2UL,0x2C2C0C20UL,0xA82A8AA2UL,0x34340430UL, +0xD012C2D2UL,0x080B0B03UL,0xEC2ECEE2UL,0xE829C9E1UL,0x5C1D4D51UL,0x94148490UL,0x18180810UL,0xF838C8F0UL, +0x54174753UL,0xAC2E8EA2UL,0x08080800UL,0xC405C5C1UL,0x10130313UL,0xCC0DCDC1UL,0x84068682UL,0xB83989B1UL, +0xFC3FCFF3UL,0x7C3D4D71UL,0xC001C1C1UL,0x30310131UL,0xF435C5F1UL,0x880A8A82UL,0x682A4A62UL,0xB03181B1UL, +0xD011C1D1UL,0x20200020UL,0xD417C7D3UL,0x00020202UL,0x20220222UL,0x04040400UL,0x68284860UL,0x70314171UL, +0x04070703UL,0xD81BCBD3UL,0x9C1D8D91UL,0x98198991UL,0x60214161UL,0xBC3E8EB2UL,0xE426C6E2UL,0x58194951UL, +0xDC1DCDD1UL,0x50114151UL,0x90108090UL,0xDC1CCCD0UL,0x981A8A92UL,0xA02383A3UL,0xA82B8BA3UL,0xD010C0D0UL, +0x80018181UL,0x0C0F0F03UL,0x44074743UL,0x181A0A12UL,0xE023C3E3UL,0xEC2CCCE0UL,0x8C0D8D81UL,0xBC3F8FB3UL, +0x94168692UL,0x783B4B73UL,0x5C1C4C50UL,0xA02282A2UL,0xA02181A1UL,0x60234363UL,0x20230323UL,0x4C0D4D41UL, +0xC808C8C0UL,0x9C1E8E92UL,0x9C1C8C90UL,0x383A0A32UL,0x0C0C0C00UL,0x2C2E0E22UL,0xB83A8AB2UL,0x6C2E4E62UL, +0x9C1F8F93UL,0x581A4A52UL,0xF032C2F2UL,0x90128292UL,0xF033C3F3UL,0x48094941UL,0x78384870UL,0xCC0CCCC0UL, +0x14150511UL,0xF83BCBF3UL,0x70304070UL,0x74354571UL,0x7C3F4F73UL,0x34350531UL,0x10100010UL,0x00030303UL, +0x64244460UL,0x6C2D4D61UL,0xC406C6C2UL,0x74344470UL,0xD415C5D1UL,0xB43484B0UL,0xE82ACAE2UL,0x08090901UL, +0x74364672UL,0x18190911UL,0xFC3ECEF2UL,0x40004040UL,0x10120212UL,0xE020C0E0UL,0xBC3D8DB1UL,0x04050501UL, +0xF83ACAF2UL,0x00010101UL,0xF030C0F0UL,0x282A0A22UL,0x5C1E4E52UL,0xA82989A1UL,0x54164652UL,0x40034343UL, +0x84058581UL,0x14140410UL,0x88098981UL,0x981B8B93UL,0xB03080B0UL,0xE425C5E1UL,0x48084840UL,0x78394971UL, +0x94178793UL,0xFC3CCCF0UL,0x1C1E0E12UL,0x80028282UL,0x20210121UL,0x8C0C8C80UL,0x181B0B13UL,0x5C1F4F53UL, +0x74374773UL,0x54144450UL,0xB03282B2UL,0x1C1D0D11UL,0x24250521UL,0x4C0F4F43UL,0x00000000UL,0x44064642UL, +0xEC2DCDE1UL,0x58184850UL,0x50124252UL,0xE82BCBE3UL,0x7C3E4E72UL,0xD81ACAD2UL,0xC809C9C1UL,0xFC3DCDF1UL, +0x30300030UL,0x94158591UL,0x64254561UL,0x3C3C0C30UL,0xB43686B2UL,0xE424C4E0UL,0xB83B8BB3UL,0x7C3C4C70UL, +0x0C0E0E02UL,0x50104050UL,0x38390931UL,0x24260622UL,0x30320232UL,0x84048480UL,0x68294961UL,0x90138393UL, +0x34370733UL,0xE427C7E3UL,0x24240420UL,0xA42484A0UL,0xC80BCBC3UL,0x50134353UL,0x080A0A02UL,0x84078783UL, +0xD819C9D1UL,0x4C0C4C40UL,0x80038383UL,0x8C0F8F83UL,0xCC0ECEC2UL,0x383B0B33UL,0x480A4A42UL,0xB43787B3UL +}; + +static const ulong32 SS2[256] = { +0xA1A82989UL,0x81840585UL,0xD2D416C6UL,0xD3D013C3UL,0x50541444UL,0x111C1D0DUL,0xA0AC2C8CUL,0x21242505UL, +0x515C1D4DUL,0x43400343UL,0x10181808UL,0x121C1E0EUL,0x51501141UL,0xF0FC3CCCUL,0xC2C80ACAUL,0x63602343UL, +0x20282808UL,0x40440444UL,0x20202000UL,0x919C1D8DUL,0xE0E020C0UL,0xE2E022C2UL,0xC0C808C8UL,0x13141707UL, +0xA1A42585UL,0x838C0F8FUL,0x03000303UL,0x73783B4BUL,0xB3B83B8BUL,0x13101303UL,0xD2D012C2UL,0xE2EC2ECEUL, +0x70703040UL,0x808C0C8CUL,0x333C3F0FUL,0xA0A82888UL,0x32303202UL,0xD1DC1DCDUL,0xF2F436C6UL,0x70743444UL, +0xE0EC2CCCUL,0x91941585UL,0x03080B0BUL,0x53541747UL,0x505C1C4CUL,0x53581B4BUL,0xB1BC3D8DUL,0x01000101UL, +0x20242404UL,0x101C1C0CUL,0x73703343UL,0x90981888UL,0x10101000UL,0xC0CC0CCCUL,0xF2F032C2UL,0xD1D819C9UL, +0x202C2C0CUL,0xE3E427C7UL,0x72703242UL,0x83800383UL,0x93981B8BUL,0xD1D011C1UL,0x82840686UL,0xC1C809C9UL, +0x60602040UL,0x50501040UL,0xA3A02383UL,0xE3E82BCBUL,0x010C0D0DUL,0xB2B43686UL,0x929C1E8EUL,0x434C0F4FUL, +0xB3B43787UL,0x52581A4AUL,0xC2C406C6UL,0x70783848UL,0xA2A42686UL,0x12101202UL,0xA3AC2F8FUL,0xD1D415C5UL, +0x61602141UL,0xC3C003C3UL,0xB0B43484UL,0x41400141UL,0x52501242UL,0x717C3D4DUL,0x818C0D8DUL,0x00080808UL, +0x131C1F0FUL,0x91981989UL,0x00000000UL,0x11181909UL,0x00040404UL,0x53501343UL,0xF3F437C7UL,0xE1E021C1UL, +0xF1FC3DCDUL,0x72743646UL,0x232C2F0FUL,0x23242707UL,0xB0B03080UL,0x83880B8BUL,0x020C0E0EUL,0xA3A82B8BUL, +0xA2A02282UL,0x626C2E4EUL,0x93901383UL,0x414C0D4DUL,0x61682949UL,0x707C3C4CUL,0x01080909UL,0x02080A0AUL, +0xB3BC3F8FUL,0xE3EC2FCFUL,0xF3F033C3UL,0xC1C405C5UL,0x83840787UL,0x10141404UL,0xF2FC3ECEUL,0x60642444UL, +0xD2DC1ECEUL,0x222C2E0EUL,0x43480B4BUL,0x12181A0AUL,0x02040606UL,0x21202101UL,0x63682B4BUL,0x62642646UL, +0x02000202UL,0xF1F435C5UL,0x92901282UL,0x82880A8AUL,0x000C0C0CUL,0xB3B03383UL,0x727C3E4EUL,0xD0D010C0UL, +0x72783A4AUL,0x43440747UL,0x92941686UL,0xE1E425C5UL,0x22242606UL,0x80800080UL,0xA1AC2D8DUL,0xD3DC1FCFUL, +0xA1A02181UL,0x30303000UL,0x33343707UL,0xA2AC2E8EUL,0x32343606UL,0x11141505UL,0x22202202UL,0x30383808UL, +0xF0F434C4UL,0xA3A42787UL,0x41440545UL,0x404C0C4CUL,0x81800181UL,0xE1E829C9UL,0x80840484UL,0x93941787UL, +0x31343505UL,0xC3C80BCBUL,0xC2CC0ECEUL,0x303C3C0CUL,0x71703141UL,0x11101101UL,0xC3C407C7UL,0x81880989UL, +0x71743545UL,0xF3F83BCBUL,0xD2D81ACAUL,0xF0F838C8UL,0x90941484UL,0x51581949UL,0x82800282UL,0xC0C404C4UL, +0xF3FC3FCFUL,0x41480949UL,0x31383909UL,0x63642747UL,0xC0C000C0UL,0xC3CC0FCFUL,0xD3D417C7UL,0xB0B83888UL, +0x030C0F0FUL,0x828C0E8EUL,0x42400242UL,0x23202303UL,0x91901181UL,0x606C2C4CUL,0xD3D81BCBUL,0xA0A42484UL, +0x30343404UL,0xF1F031C1UL,0x40480848UL,0xC2C002C2UL,0x636C2F4FUL,0x313C3D0DUL,0x212C2D0DUL,0x40400040UL, +0xB2BC3E8EUL,0x323C3E0EUL,0xB0BC3C8CUL,0xC1C001C1UL,0xA2A82A8AUL,0xB2B83A8AUL,0x424C0E4EUL,0x51541545UL, +0x33383B0BUL,0xD0DC1CCCUL,0x60682848UL,0x737C3F4FUL,0x909C1C8CUL,0xD0D818C8UL,0x42480A4AUL,0x52541646UL, +0x73743747UL,0xA0A02080UL,0xE1EC2DCDUL,0x42440646UL,0xB1B43585UL,0x23282B0BUL,0x61642545UL,0xF2F83ACAUL, +0xE3E023C3UL,0xB1B83989UL,0xB1B03181UL,0x939C1F8FUL,0x525C1E4EUL,0xF1F839C9UL,0xE2E426C6UL,0xB2B03282UL, +0x31303101UL,0xE2E82ACAUL,0x616C2D4DUL,0x535C1F4FUL,0xE0E424C4UL,0xF0F030C0UL,0xC1CC0DCDUL,0x80880888UL, +0x12141606UL,0x32383A0AUL,0x50581848UL,0xD0D414C4UL,0x62602242UL,0x21282909UL,0x03040707UL,0x33303303UL, +0xE0E828C8UL,0x13181B0BUL,0x01040505UL,0x71783949UL,0x90901080UL,0x62682A4AUL,0x22282A0AUL,0x92981A8AUL +}; + +static const ulong32 SS3[256] = { +0x08303838UL,0xC8E0E828UL,0x0D212C2DUL,0x86A2A426UL,0xCFC3CC0FUL,0xCED2DC1EUL,0x83B3B033UL,0x88B0B838UL, +0x8FA3AC2FUL,0x40606020UL,0x45515415UL,0xC7C3C407UL,0x44404404UL,0x4F636C2FUL,0x4B63682BUL,0x4B53581BUL, +0xC3C3C003UL,0x42626022UL,0x03333033UL,0x85B1B435UL,0x09212829UL,0x80A0A020UL,0xC2E2E022UL,0x87A3A427UL, +0xC3D3D013UL,0x81919011UL,0x01111011UL,0x06020406UL,0x0C101C1CUL,0x8CB0BC3CUL,0x06323436UL,0x4B43480BUL, +0xCFE3EC2FUL,0x88808808UL,0x4C606C2CUL,0x88A0A828UL,0x07131417UL,0xC4C0C404UL,0x06121416UL,0xC4F0F434UL, +0xC2C2C002UL,0x45414405UL,0xC1E1E021UL,0xC6D2D416UL,0x0F333C3FUL,0x0D313C3DUL,0x8E828C0EUL,0x88909818UL, +0x08202828UL,0x4E424C0EUL,0xC6F2F436UL,0x0E323C3EUL,0x85A1A425UL,0xC9F1F839UL,0x0D010C0DUL,0xCFD3DC1FUL, +0xC8D0D818UL,0x0B23282BUL,0x46626426UL,0x4A72783AUL,0x07232427UL,0x0F232C2FUL,0xC1F1F031UL,0x42727032UL, +0x42424002UL,0xC4D0D414UL,0x41414001UL,0xC0C0C000UL,0x43737033UL,0x47636427UL,0x8CA0AC2CUL,0x8B83880BUL, +0xC7F3F437UL,0x8DA1AC2DUL,0x80808000UL,0x0F131C1FUL,0xCAC2C80AUL,0x0C202C2CUL,0x8AA2A82AUL,0x04303434UL, +0xC2D2D012UL,0x0B03080BUL,0xCEE2EC2EUL,0xC9E1E829UL,0x4D515C1DUL,0x84909414UL,0x08101818UL,0xC8F0F838UL, +0x47535417UL,0x8EA2AC2EUL,0x08000808UL,0xC5C1C405UL,0x03131013UL,0xCDC1CC0DUL,0x86828406UL,0x89B1B839UL, +0xCFF3FC3FUL,0x4D717C3DUL,0xC1C1C001UL,0x01313031UL,0xC5F1F435UL,0x8A82880AUL,0x4A62682AUL,0x81B1B031UL, +0xC1D1D011UL,0x00202020UL,0xC7D3D417UL,0x02020002UL,0x02222022UL,0x04000404UL,0x48606828UL,0x41717031UL, +0x07030407UL,0xCBD3D81BUL,0x8D919C1DUL,0x89919819UL,0x41616021UL,0x8EB2BC3EUL,0xC6E2E426UL,0x49515819UL, +0xCDD1DC1DUL,0x41515011UL,0x80909010UL,0xCCD0DC1CUL,0x8A92981AUL,0x83A3A023UL,0x8BA3A82BUL,0xC0D0D010UL, +0x81818001UL,0x0F030C0FUL,0x47434407UL,0x0A12181AUL,0xC3E3E023UL,0xCCE0EC2CUL,0x8D818C0DUL,0x8FB3BC3FUL, +0x86929416UL,0x4B73783BUL,0x4C505C1CUL,0x82A2A022UL,0x81A1A021UL,0x43636023UL,0x03232023UL,0x4D414C0DUL, +0xC8C0C808UL,0x8E929C1EUL,0x8C909C1CUL,0x0A32383AUL,0x0C000C0CUL,0x0E222C2EUL,0x8AB2B83AUL,0x4E626C2EUL, +0x8F939C1FUL,0x4A52581AUL,0xC2F2F032UL,0x82929012UL,0xC3F3F033UL,0x49414809UL,0x48707838UL,0xCCC0CC0CUL, +0x05111415UL,0xCBF3F83BUL,0x40707030UL,0x45717435UL,0x4F737C3FUL,0x05313435UL,0x00101010UL,0x03030003UL, +0x44606424UL,0x4D616C2DUL,0xC6C2C406UL,0x44707434UL,0xC5D1D415UL,0x84B0B434UL,0xCAE2E82AUL,0x09010809UL, +0x46727436UL,0x09111819UL,0xCEF2FC3EUL,0x40404000UL,0x02121012UL,0xC0E0E020UL,0x8DB1BC3DUL,0x05010405UL, +0xCAF2F83AUL,0x01010001UL,0xC0F0F030UL,0x0A22282AUL,0x4E525C1EUL,0x89A1A829UL,0x46525416UL,0x43434003UL, +0x85818405UL,0x04101414UL,0x89818809UL,0x8B93981BUL,0x80B0B030UL,0xC5E1E425UL,0x48404808UL,0x49717839UL, +0x87939417UL,0xCCF0FC3CUL,0x0E121C1EUL,0x82828002UL,0x01212021UL,0x8C808C0CUL,0x0B13181BUL,0x4F535C1FUL, +0x47737437UL,0x44505414UL,0x82B2B032UL,0x0D111C1DUL,0x05212425UL,0x4F434C0FUL,0x00000000UL,0x46424406UL, +0xCDE1EC2DUL,0x48505818UL,0x42525012UL,0xCBE3E82BUL,0x4E727C3EUL,0xCAD2D81AUL,0xC9C1C809UL,0xCDF1FC3DUL, +0x00303030UL,0x85919415UL,0x45616425UL,0x0C303C3CUL,0x86B2B436UL,0xC4E0E424UL,0x8BB3B83BUL,0x4C707C3CUL, +0x0E020C0EUL,0x40505010UL,0x09313839UL,0x06222426UL,0x02323032UL,0x84808404UL,0x49616829UL,0x83939013UL, +0x07333437UL,0xC7E3E427UL,0x04202424UL,0x84A0A424UL,0xCBC3C80BUL,0x43535013UL,0x0A02080AUL,0x87838407UL, +0xC9D1D819UL,0x4C404C0CUL,0x83838003UL,0x8F838C0FUL,0xCEC2CC0EUL,0x0B33383BUL,0x4A42480AUL,0x87B3B437UL +}; + +static const ulong32 KCi[16] = { +0x9E3779B9,0x3C6EF373, +0x78DDE6E6,0xF1BBCDCC, +0xE3779B99,0xC6EF3733, +0x8DDE6E67,0x1BBCDCCF, +0x3779B99E,0x6EF3733C, +0xDDE6E678,0xBBCDCCF1, +0x779B99E3,0xEF3733C6, +0xDE6E678D,0xBCDCCF1B +}; + +#define G(x) (SS3[((x)>>24)&255] ^ SS2[((x)>>16)&255] ^ SS1[((x)>>8)&255] ^ SS0[(x)&255]) + +#define F(L1, L2, R1, R2, K1, K2) \ + T2 = G((R1 ^ K1) ^ (R2 ^ K2)); \ + T = G( G(T2 + (R1 ^ K1)) + T2); \ + L2 ^= T; \ + L1 ^= (T + G(T2 + (R1 ^ K1))); \ + + /** + Initialize the SEED block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +int kseed_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int i; + ulong32 tmp, k1, k2, k3, k4; + + if (keylen != 16) { + return CRYPT_INVALID_KEYSIZE; + } + + if (num_rounds != 16 && num_rounds != 0) { + return CRYPT_INVALID_ROUNDS; + } + + /* load key */ + LOAD32H(k1, key); + LOAD32H(k2, key+4); + LOAD32H(k3, key+8); + LOAD32H(k4, key+12); + + for (i = 0; i < 16; i++) { + skey->kseed.K[2*i+0] = G(k1 + k3 - KCi[i]); + skey->kseed.K[2*i+1] = G(k2 - k4 + KCi[i]); + if (i&1) { + tmp = k3; + k3 = ((k3 << 8) | (k4 >> 24)) & 0xFFFFFFFF; + k4 = ((k4 << 8) | (tmp >> 24)) & 0xFFFFFFFF; + } else { + tmp = k1; + k1 = ((k1 >> 8) | (k2 << 24)) & 0xFFFFFFFF; + k2 = ((k2 >> 8) | (tmp << 24)) & 0xFFFFFFFF; + } + /* reverse keys for decrypt */ + skey->kseed.dK[2*(15-i)+0] = skey->kseed.K[2*i+0]; + skey->kseed.dK[2*(15-i)+1] = skey->kseed.K[2*i+1]; + } + + return CRYPT_OK; +} + +static void rounds(ulong32 *P, ulong32 *K) +{ + ulong32 T, T2; + int i; + for (i = 0; i < 16; i += 2) { + F(P[0], P[1], P[2], P[3], K[0], K[1]); + F(P[2], P[3], P[0], P[1], K[2], K[3]); + K += 4; + } +} + +/** + Encrypts a block of text with SEED + @param pt The input plaintext (16 bytes) + @param ct The output ciphertext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int kseed_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + ulong32 P[4]; + LOAD32H(P[0], pt); + LOAD32H(P[1], pt+4); + LOAD32H(P[2], pt+8); + LOAD32H(P[3], pt+12); + rounds(P, skey->kseed.K); + STORE32H(P[2], ct); + STORE32H(P[3], ct+4); + STORE32H(P[0], ct+8); + STORE32H(P[1], ct+12); + return CRYPT_OK; +} + +/** + Decrypts a block of text with SEED + @param ct The input ciphertext (16 bytes) + @param pt The output plaintext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int kseed_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + ulong32 P[4]; + LOAD32H(P[0], ct); + LOAD32H(P[1], ct+4); + LOAD32H(P[2], ct+8); + LOAD32H(P[3], ct+12); + rounds(P, skey->kseed.dK); + STORE32H(P[2], pt); + STORE32H(P[3], pt+4); + STORE32H(P[0], pt+8); + STORE32H(P[1], pt+12); + return CRYPT_OK; +} + +/** Terminate the context + @param skey The scheduled key +*/ +void kseed_done(symmetric_key *skey) +{ +} + +/** + Performs a self-test of the SEED block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int kseed_test(void) +{ +#if !defined(LTC_TEST) + return CRYPT_NOP; +#else + static const struct test { + unsigned char pt[16], ct[16], key[16]; + } tests[] = { + +{ + { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F }, + { 0x5E,0xBA,0xC6,0xE0,0x05,0x4E,0x16,0x68,0x19,0xAF,0xF1,0xCC,0x6D,0x34,0x6C,0xDB }, + { 0 }, +}, + +{ + { 0 }, + { 0xC1,0x1F,0x22,0xF2,0x01,0x40,0x50,0x50,0x84,0x48,0x35,0x97,0xE4,0x37,0x0F,0x43 }, + { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F }, +}, + +{ + { 0x83,0xA2,0xF8,0xA2,0x88,0x64,0x1F,0xB9,0xA4,0xE9,0xA5,0xCC,0x2F,0x13,0x1C,0x7D }, + { 0xEE,0x54,0xD1,0x3E,0xBC,0xAE,0x70,0x6D,0x22,0x6B,0xC3,0x14,0x2C,0xD4,0x0D,0x4A }, + { 0x47,0x06,0x48,0x08,0x51,0xE6,0x1B,0xE8,0x5D,0x74,0xBF,0xB3,0xFD,0x95,0x61,0x85 }, +}, + +{ + { 0xB4,0x1E,0x6B,0xE2,0xEB,0xA8,0x4A,0x14,0x8E,0x2E,0xED,0x84,0x59,0x3C,0x5E,0xC7 }, + { 0x9B,0x9B,0x7B,0xFC,0xD1,0x81,0x3C,0xB9,0x5D,0x0B,0x36,0x18,0xF4,0x0F,0x51,0x22 }, + { 0x28,0xDB,0xC3,0xBC,0x49,0xFF,0xD8,0x7D,0xCF,0xA5,0x09,0xB1,0x1D,0x42,0x2B,0xE7 }, +} +}; + int x; + unsigned char buf[2][16]; + symmetric_key skey; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + kseed_setup(tests[x].key, 16, 0, &skey); + kseed_ecb_encrypt(tests[x].pt, buf[0], &skey); + kseed_ecb_decrypt(buf[0], buf[1], &skey); + if (XMEMCMP(buf[0], tests[x].ct, 16) || XMEMCMP(buf[1], tests[x].pt, 16)) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + +/** + Gets suitable key size + @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. + @return CRYPT_OK if the input key size is acceptable. +*/ +int kseed_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize >= 16) { + *keysize = 16; + } else { + return CRYPT_INVALID_KEYSIZE; + } + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/kseed.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:21:44 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/multi2.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/multi2.c new file mode 100644 index 0000000000..7820810281 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/multi2.c @@ -0,0 +1,303 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file multi2.c + Multi-2 implementation (not public domain, hence the default disable) +*/ +#include "tomcrypt.h" + +#ifdef LTC_MULTI2 + +static void pi1(ulong32 *p) +{ + p[1] ^= p[0]; +} + +static void pi2(ulong32 *p, ulong32 *k) +{ + ulong32 t; + t = (p[1] + k[0]) & 0xFFFFFFFFUL; + t = (ROL(t, 1) + t - 1) & 0xFFFFFFFFUL; + t = (ROL(t, 4) ^ t) & 0xFFFFFFFFUL; + p[0] ^= t; +} + +static void pi3(ulong32 *p, ulong32 *k) +{ + ulong32 t; + t = p[0] + k[1]; + t = (ROL(t, 2) + t + 1) & 0xFFFFFFFFUL; + t = (ROL(t, 8) ^ t) & 0xFFFFFFFFUL; + t = (t + k[2]) & 0xFFFFFFFFUL; + t = (ROL(t, 1) - t) & 0xFFFFFFFFUL; + t = ROL(t, 16) ^ (p[0] | t); + p[1] ^= t; +} + +static void pi4(ulong32 *p, ulong32 *k) +{ + ulong32 t; + t = (p[1] + k[3]) & 0xFFFFFFFFUL; + t = (ROL(t, 2) + t + 1) & 0xFFFFFFFFUL; + p[0] ^= t; +} + +static void setup(ulong32 *dk, ulong32 *k, ulong32 *uk) +{ + int n, t; + ulong32 p[2]; + + p[0] = dk[0]; p[1] = dk[1]; + + t = 4; + n = 0; + pi1(p); + pi2(p, k); + uk[n++] = p[0]; + pi3(p, k); + uk[n++] = p[1]; + pi4(p, k); + uk[n++] = p[0]; + pi1(p); + uk[n++] = p[1]; + pi2(p, k+t); + uk[n++] = p[0]; + pi3(p, k+t); + uk[n++] = p[1]; + pi4(p, k+t); + uk[n++] = p[0]; + pi1(p); + uk[n++] = p[1]; +} + +static void encrypt(ulong32 *p, int N, ulong32 *uk) +{ + int n, t; + for (t = n = 0; ; ) { + pi1(p); if (++n == N) break; + pi2(p, uk+t); if (++n == N) break; + pi3(p, uk+t); if (++n == N) break; + pi4(p, uk+t); if (++n == N) break; + t ^= 4; + } +} + +static void decrypt(ulong32 *p, int N, ulong32 *uk) +{ + int n, t; + for (t = 4*((N&1)^1), n = N; ; ) { + switch (n >= 4 ? 4 : 0) { + case 4: pi4(p, uk+t); --n; + case 3: pi3(p, uk+t); --n; + case 2: pi2(p, uk+t); --n; + case 1: pi1(p); --n; break; + case 0: return; + } + t ^= 4; + } +} + +const struct ltc_cipher_descriptor multi2_desc = { + "multi2", + 22, + 40, 40, 8, 128, + &multi2_setup, + &multi2_ecb_encrypt, + &multi2_ecb_decrypt, + &multi2_test, + &multi2_done, + &multi2_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +int multi2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + ulong32 sk[8], dk[2]; + int x; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (keylen != 40) return CRYPT_INVALID_KEYSIZE; + if (num_rounds == 0) num_rounds = 128; + + skey->multi2.N = num_rounds; + for (x = 0; x < 8; x++) { + LOAD32H(sk[x], key + x*4); + } + LOAD32H(dk[0], key + 32); + LOAD32H(dk[1], key + 36); + setup(dk, sk, skey->multi2.uk); + + zeromem(sk, sizeof(sk)); + zeromem(dk, sizeof(dk)); + return CRYPT_OK; +} + +/** + Encrypts a block of text with multi2 + @param pt The input plaintext (8 bytes) + @param ct The output ciphertext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int multi2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + ulong32 p[2]; + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + LOAD32H(p[0], pt); + LOAD32H(p[1], pt+4); + encrypt(p, skey->multi2.N, skey->multi2.uk); + STORE32H(p[0], ct); + STORE32H(p[1], ct+4); + return CRYPT_OK; +} + +/** + Decrypts a block of text with multi2 + @param ct The input ciphertext (8 bytes) + @param pt The output plaintext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int multi2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + ulong32 p[2]; + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + LOAD32H(p[0], ct); + LOAD32H(p[1], ct+4); + decrypt(p, skey->multi2.N, skey->multi2.uk); + STORE32H(p[0], pt); + STORE32H(p[1], pt+4); + return CRYPT_OK; +} + +/** + Performs a self-test of the multi2 block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int multi2_test(void) +{ + static const struct { + unsigned char key[40]; + unsigned char pt[8], ct[8]; + int rounds; + } tests[] = { +{ + { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x01, 0x23, 0x45, 0x67, + 0x89, 0xAB, 0xCD, 0xEF + }, + { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + }, + { + 0xf8, 0x94, 0x40, 0x84, + 0x5e, 0x11, 0xcf, 0x89 + }, + 128, +}, +{ + { + 0x35, 0x91, 0x9d, 0x96, + 0x07, 0x02, 0xe2, 0xce, + 0x8d, 0x0b, 0x58, 0x3c, + 0xc9, 0xc8, 0x9d, 0x59, + 0xa2, 0xae, 0x96, 0x4e, + 0x87, 0x82, 0x45, 0xed, + 0x3f, 0x2e, 0x62, 0xd6, + 0x36, 0x35, 0xd0, 0x67, + + 0xb1, 0x27, 0xb9, 0x06, + 0xe7, 0x56, 0x22, 0x38, + }, + { + 0x1f, 0xb4, 0x60, 0x60, + 0xd0, 0xb3, 0x4f, 0xa5 + }, + { + 0xca, 0x84, 0xa9, 0x34, + 0x75, 0xc8, 0x60, 0xe5 + }, + 216, +} +}; + unsigned char buf[8]; + symmetric_key skey; + int err, x; + + for (x = 1; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + if ((err = multi2_setup(tests[x].key, 40, tests[x].rounds, &skey)) != CRYPT_OK) { + return err; + } + if ((err = multi2_ecb_encrypt(tests[x].pt, buf, &skey)) != CRYPT_OK) { + return err; + } + + if (XMEMCMP(buf, tests[x].ct, 8)) { + return CRYPT_FAIL_TESTVECTOR; + } + + if ((err = multi2_ecb_decrypt(buf, buf, &skey)) != CRYPT_OK) { + return err; + } + if (XMEMCMP(buf, tests[x].pt, 8)) { + return CRYPT_FAIL_TESTVECTOR; + } + } + + return CRYPT_OK; +} + +/** Terminate the context + @param skey The scheduled key +*/ +void multi2_done(symmetric_key *skey) +{ +} + +/** + Gets suitable key size + @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. + @return CRYPT_OK if the input key size is acceptable. +*/ +int multi2_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize >= 40) { + *keysize = 40; + } else { + return CRYPT_INVALID_KEYSIZE; + } + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/multi2.c,v $ */ +/* $Revision: 1.1 $ */ +/* $Date: 2007/01/05 16:01:25 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/noekeon.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/noekeon.c new file mode 100644 index 0000000000..8b92a46059 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/noekeon.c @@ -0,0 +1,303 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +/** + @file noekeon.c + Implementation of the Noekeon block cipher by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_NOEKEON + +const struct ltc_cipher_descriptor noekeon_desc = +{ + "noekeon", + 16, + 16, 16, 16, 16, + &noekeon_setup, + &noekeon_ecb_encrypt, + &noekeon_ecb_decrypt, + &noekeon_test, + &noekeon_done, + &noekeon_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +static const ulong32 RC[] = { + 0x00000080UL, 0x0000001bUL, 0x00000036UL, 0x0000006cUL, + 0x000000d8UL, 0x000000abUL, 0x0000004dUL, 0x0000009aUL, + 0x0000002fUL, 0x0000005eUL, 0x000000bcUL, 0x00000063UL, + 0x000000c6UL, 0x00000097UL, 0x00000035UL, 0x0000006aUL, + 0x000000d4UL +}; + +#define kTHETA(a, b, c, d) \ + temp = a^c; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \ + b ^= temp; d ^= temp; \ + temp = b^d; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \ + a ^= temp; c ^= temp; + +#define THETA(k, a, b, c, d) \ + temp = a^c; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \ + b ^= temp ^ k[1]; d ^= temp ^ k[3]; \ + temp = b^d; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \ + a ^= temp ^ k[0]; c ^= temp ^ k[2]; + +#define GAMMA(a, b, c, d) \ + b ^= ~(d|c); \ + a ^= c&b; \ + temp = d; d = a; a = temp;\ + c ^= a ^ b ^ d; \ + b ^= ~(d|c); \ + a ^= c&b; + +#define PI1(a, b, c, d) \ + a = ROLc(a, 1); c = ROLc(c, 5); d = ROLc(d, 2); + +#define PI2(a, b, c, d) \ + a = RORc(a, 1); c = RORc(c, 5); d = RORc(d, 2); + + /** + Initialize the Noekeon block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + ulong32 temp; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (keylen != 16) { + return CRYPT_INVALID_KEYSIZE; + } + + if (num_rounds != 16 && num_rounds != 0) { + return CRYPT_INVALID_ROUNDS; + } + + LOAD32H(skey->noekeon.K[0],&key[0]); + LOAD32H(skey->noekeon.K[1],&key[4]); + LOAD32H(skey->noekeon.K[2],&key[8]); + LOAD32H(skey->noekeon.K[3],&key[12]); + + LOAD32H(skey->noekeon.dK[0],&key[0]); + LOAD32H(skey->noekeon.dK[1],&key[4]); + LOAD32H(skey->noekeon.dK[2],&key[8]); + LOAD32H(skey->noekeon.dK[3],&key[12]); + + kTHETA(skey->noekeon.dK[0], skey->noekeon.dK[1], skey->noekeon.dK[2], skey->noekeon.dK[3]); + + return CRYPT_OK; +} + +/** + Encrypts a block of text with Noekeon + @param pt The input plaintext (16 bytes) + @param ct The output ciphertext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#else +int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#endif +{ + ulong32 a,b,c,d,temp; + int r; + + LTC_ARGCHK(skey != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + + LOAD32H(a,&pt[0]); LOAD32H(b,&pt[4]); + LOAD32H(c,&pt[8]); LOAD32H(d,&pt[12]); + +#define ROUND(i) \ + a ^= RC[i]; \ + THETA(skey->noekeon.K, a,b,c,d); \ + PI1(a,b,c,d); \ + GAMMA(a,b,c,d); \ + PI2(a,b,c,d); + + for (r = 0; r < 16; ++r) { + ROUND(r); + } + +#undef ROUND + + a ^= RC[16]; + THETA(skey->noekeon.K, a, b, c, d); + + STORE32H(a,&ct[0]); STORE32H(b,&ct[4]); + STORE32H(c,&ct[8]); STORE32H(d,&ct[12]); + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + int err = _noekeon_ecb_encrypt(pt, ct, skey); + burn_stack(sizeof(ulong32) * 5 + sizeof(int)); + return CRYPT_OK; +} +#endif + +/** + Decrypts a block of text with Noekeon + @param ct The input ciphertext (16 bytes) + @param pt The output plaintext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#else +int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#endif +{ + ulong32 a,b,c,d, temp; + int r; + + LTC_ARGCHK(skey != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + + LOAD32H(a,&ct[0]); LOAD32H(b,&ct[4]); + LOAD32H(c,&ct[8]); LOAD32H(d,&ct[12]); + + +#define ROUND(i) \ + THETA(skey->noekeon.dK, a,b,c,d); \ + a ^= RC[i]; \ + PI1(a,b,c,d); \ + GAMMA(a,b,c,d); \ + PI2(a,b,c,d); + + for (r = 16; r > 0; --r) { + ROUND(r); + } + +#undef ROUND + + THETA(skey->noekeon.dK, a,b,c,d); + a ^= RC[0]; + STORE32H(a,&pt[0]); STORE32H(b, &pt[4]); + STORE32H(c,&pt[8]); STORE32H(d, &pt[12]); + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + int err = _noekeon_ecb_decrypt(ct, pt, skey); + burn_stack(sizeof(ulong32) * 5 + sizeof(int)); + return err; +} +#endif + +/** + Performs a self-test of the Noekeon block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int noekeon_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen; + unsigned char key[16], pt[16], ct[16]; + } tests[] = { + { + 16, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 0x18, 0xa6, 0xec, 0xe5, 0x28, 0xaa, 0x79, 0x73, + 0x28, 0xb2, 0xc0, 0x91, 0xa0, 0x2f, 0x54, 0xc5} + } + }; + symmetric_key key; + unsigned char tmp[2][16]; + int err, i, y; + + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { + zeromem(&key, sizeof(key)); + if ((err = noekeon_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { + return err; + } + + noekeon_ecb_encrypt(tests[i].pt, tmp[0], &key); + noekeon_ecb_decrypt(tmp[0], tmp[1], &key); + if (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) { +#if 0 + printf("\n\nTest %d failed\n", i); + if (XMEMCMP(tmp[0], tests[i].ct, 16)) { + printf("CT: "); + for (i = 0; i < 16; i++) { + printf("%02x ", tmp[0][i]); + } + printf("\n"); + } else { + printf("PT: "); + for (i = 0; i < 16; i++) { + printf("%02x ", tmp[1][i]); + } + printf("\n"); + } +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 16; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) noekeon_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) noekeon_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void noekeon_done(symmetric_key *skey) +{ +} + +/** + Gets suitable key size + @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. + @return CRYPT_OK if the input key size is acceptable. +*/ +int noekeon_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize < 16) { + return CRYPT_INVALID_KEYSIZE; + } else { + *keysize = 16; + return CRYPT_OK; + } +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/noekeon.c,v $ */ +/* $Revision: 1.14 $ */ +/* $Date: 2007/05/12 14:20:27 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/rc2.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/rc2.c new file mode 100644 index 0000000000..3849fe06c3 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/rc2.c @@ -0,0 +1,362 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +/**********************************************************************\ +* To commemorate the 1996 RSA Data Security Conference, the following * +* code is released into the public domain by its author. Prost! * +* * +* This cipher uses 16-bit words and little-endian byte ordering. * +* I wonder which processor it was optimized for? * +* * +* Thanks to CodeView, SoftIce, and D86 for helping bring this code to * +* the public. * +\**********************************************************************/ +#include + +/** + @file rc2.c + Implementation of LTC_RC2 +*/ + +#ifdef LTC_RC2 + +const struct ltc_cipher_descriptor rc2_desc = { + "rc2", + 12, 8, 128, 8, 16, + &rc2_setup, + &rc2_ecb_encrypt, + &rc2_ecb_decrypt, + &rc2_test, + &rc2_done, + &rc2_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +/* 256-entry permutation table, probably derived somehow from pi */ +static const unsigned char permute[256] = { + 217,120,249,196, 25,221,181,237, 40,233,253,121, 74,160,216,157, + 198,126, 55,131, 43,118, 83,142, 98, 76,100,136, 68,139,251,162, + 23,154, 89,245,135,179, 79, 19, 97, 69,109,141, 9,129,125, 50, + 189,143, 64,235,134,183,123, 11,240,149, 33, 34, 92,107, 78,130, + 84,214,101,147,206, 96,178, 28,115, 86,192, 20,167,140,241,220, + 18,117,202, 31, 59,190,228,209, 66, 61,212, 48,163, 60,182, 38, + 111,191, 14,218, 70,105, 7, 87, 39,242, 29,155,188,148, 67, 3, + 248, 17,199,246,144,239, 62,231, 6,195,213, 47,200,102, 30,215, + 8,232,234,222,128, 82,238,247,132,170,114,172, 53, 77,106, 42, + 150, 26,210,113, 90, 21, 73,116, 75,159,208, 94, 4, 24,164,236, + 194,224, 65,110, 15, 81,203,204, 36,145,175, 80,161,244,112, 57, + 153,124, 58,133, 35,184,180,122,252, 2, 54, 91, 37, 85,151, 49, + 45, 93,250,152,227,138,146,174, 5,223, 41, 16,103,108,186,201, + 211, 0,230,207,225,158,168, 44, 99, 22, 1, 63, 88,226,137,169, + 13, 56, 52, 27,171, 51,255,176,187, 72, 12, 95,185,177,205, 46, + 197,243,219, 71,229,165,156,119, 10,166, 32,104,254,127,193,173 +}; + + /** + Initialize the LTC_RC2 block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + unsigned *xkey = skey->rc2.xkey; + unsigned char tmp[128]; + unsigned T8, TM; + int i, bits; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (keylen < 8 || keylen > 128) { + return CRYPT_INVALID_KEYSIZE; + } + + if (num_rounds != 0 && num_rounds != 16) { + return CRYPT_INVALID_ROUNDS; + } + + for (i = 0; i < keylen; i++) { + tmp[i] = key[i] & 255; + } + + /* Phase 1: Expand input key to 128 bytes */ + if (keylen < 128) { + for (i = keylen; i < 128; i++) { + tmp[i] = permute[(tmp[i - 1] + tmp[i - keylen]) & 255]; + } + } + + /* Phase 2 - reduce effective key size to "bits" */ + bits = keylen<<3; + T8 = (unsigned)(bits+7)>>3; + TM = (255 >> (unsigned)(7 & -bits)); + tmp[128 - T8] = permute[tmp[128 - T8] & TM]; + for (i = 127 - T8; i >= 0; i--) { + tmp[i] = permute[tmp[i + 1] ^ tmp[i + T8]]; + } + + /* Phase 3 - copy to xkey in little-endian order */ + for (i = 0; i < 64; i++) { + xkey[i] = (unsigned)tmp[2*i] + ((unsigned)tmp[2*i+1] << 8); + } + +#ifdef LTC_CLEAN_STACK + zeromem(tmp, sizeof(tmp)); +#endif + + return CRYPT_OK; +} + +/**********************************************************************\ +* Encrypt an 8-byte block of plaintext using the given key. * +\**********************************************************************/ +/** + Encrypts a block of text with LTC_RC2 + @param pt The input plaintext (8 bytes) + @param ct The output ciphertext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _rc2_ecb_encrypt( const unsigned char *pt, + unsigned char *ct, + symmetric_key *skey) +#else +int rc2_ecb_encrypt( const unsigned char *pt, + unsigned char *ct, + symmetric_key *skey) +#endif +{ + unsigned *xkey; + unsigned x76, x54, x32, x10, i; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + xkey = skey->rc2.xkey; + + x76 = ((unsigned)pt[7] << 8) + (unsigned)pt[6]; + x54 = ((unsigned)pt[5] << 8) + (unsigned)pt[4]; + x32 = ((unsigned)pt[3] << 8) + (unsigned)pt[2]; + x10 = ((unsigned)pt[1] << 8) + (unsigned)pt[0]; + + for (i = 0; i < 16; i++) { + x10 = (x10 + (x32 & ~x76) + (x54 & x76) + xkey[4*i+0]) & 0xFFFF; + x10 = ((x10 << 1) | (x10 >> 15)); + + x32 = (x32 + (x54 & ~x10) + (x76 & x10) + xkey[4*i+1]) & 0xFFFF; + x32 = ((x32 << 2) | (x32 >> 14)); + + x54 = (x54 + (x76 & ~x32) + (x10 & x32) + xkey[4*i+2]) & 0xFFFF; + x54 = ((x54 << 3) | (x54 >> 13)); + + x76 = (x76 + (x10 & ~x54) + (x32 & x54) + xkey[4*i+3]) & 0xFFFF; + x76 = ((x76 << 5) | (x76 >> 11)); + + if (i == 4 || i == 10) { + x10 = (x10 + xkey[x76 & 63]) & 0xFFFF; + x32 = (x32 + xkey[x10 & 63]) & 0xFFFF; + x54 = (x54 + xkey[x32 & 63]) & 0xFFFF; + x76 = (x76 + xkey[x54 & 63]) & 0xFFFF; + } + } + + ct[0] = (unsigned char)x10; + ct[1] = (unsigned char)(x10 >> 8); + ct[2] = (unsigned char)x32; + ct[3] = (unsigned char)(x32 >> 8); + ct[4] = (unsigned char)x54; + ct[5] = (unsigned char)(x54 >> 8); + ct[6] = (unsigned char)x76; + ct[7] = (unsigned char)(x76 >> 8); + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int rc2_ecb_encrypt( const unsigned char *pt, + unsigned char *ct, + symmetric_key *skey) +{ + int err = _rc2_ecb_encrypt(pt, ct, skey); + burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 5); + return err; +} +#endif + +/**********************************************************************\ +* Decrypt an 8-byte block of ciphertext using the given key. * +\**********************************************************************/ +/** + Decrypts a block of text with LTC_RC2 + @param ct The input ciphertext (8 bytes) + @param pt The output plaintext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _rc2_ecb_decrypt( const unsigned char *ct, + unsigned char *pt, + symmetric_key *skey) +#else +int rc2_ecb_decrypt( const unsigned char *ct, + unsigned char *pt, + symmetric_key *skey) +#endif +{ + unsigned x76, x54, x32, x10; + unsigned *xkey; + int i; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + xkey = skey->rc2.xkey; + + x76 = ((unsigned)ct[7] << 8) + (unsigned)ct[6]; + x54 = ((unsigned)ct[5] << 8) + (unsigned)ct[4]; + x32 = ((unsigned)ct[3] << 8) + (unsigned)ct[2]; + x10 = ((unsigned)ct[1] << 8) + (unsigned)ct[0]; + + for (i = 15; i >= 0; i--) { + if (i == 4 || i == 10) { + x76 = (x76 - xkey[x54 & 63]) & 0xFFFF; + x54 = (x54 - xkey[x32 & 63]) & 0xFFFF; + x32 = (x32 - xkey[x10 & 63]) & 0xFFFF; + x10 = (x10 - xkey[x76 & 63]) & 0xFFFF; + } + + x76 = ((x76 << 11) | (x76 >> 5)); + x76 = (x76 - ((x10 & ~x54) + (x32 & x54) + xkey[4*i+3])) & 0xFFFF; + + x54 = ((x54 << 13) | (x54 >> 3)); + x54 = (x54 - ((x76 & ~x32) + (x10 & x32) + xkey[4*i+2])) & 0xFFFF; + + x32 = ((x32 << 14) | (x32 >> 2)); + x32 = (x32 - ((x54 & ~x10) + (x76 & x10) + xkey[4*i+1])) & 0xFFFF; + + x10 = ((x10 << 15) | (x10 >> 1)); + x10 = (x10 - ((x32 & ~x76) + (x54 & x76) + xkey[4*i+0])) & 0xFFFF; + } + + pt[0] = (unsigned char)x10; + pt[1] = (unsigned char)(x10 >> 8); + pt[2] = (unsigned char)x32; + pt[3] = (unsigned char)(x32 >> 8); + pt[4] = (unsigned char)x54; + pt[5] = (unsigned char)(x54 >> 8); + pt[6] = (unsigned char)x76; + pt[7] = (unsigned char)(x76 >> 8); + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int rc2_ecb_decrypt( const unsigned char *ct, + unsigned char *pt, + symmetric_key *skey) +{ + int err = _rc2_ecb_decrypt(ct, pt, skey); + burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 4 + sizeof(int)); + return err; +} +#endif + +/** + Performs a self-test of the LTC_RC2 block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int rc2_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen; + unsigned char key[16], pt[8], ct[8]; + } tests[] = { + + { 8, + { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + { 0x30, 0x64, 0x9e, 0xdf, 0x9b, 0xe7, 0xd2, 0xc2 } + + }, + { 16, + { 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f, + 0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x22, 0x69, 0x55, 0x2a, 0xb0, 0xf8, 0x5c, 0xa6 } + } + }; + int x, y, err; + symmetric_key skey; + unsigned char tmp[2][8]; + + for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { + zeromem(tmp, sizeof(tmp)); + if ((err = rc2_setup(tests[x].key, tests[x].keylen, 0, &skey)) != CRYPT_OK) { + return err; + } + + rc2_ecb_encrypt(tests[x].pt, tmp[0], &skey); + rc2_ecb_decrypt(tmp[0], tmp[1], &skey); + + if (XMEMCMP(tmp[0], tests[x].ct, 8) != 0 || XMEMCMP(tmp[1], tests[x].pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) rc2_ecb_encrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 1000; y++) rc2_ecb_decrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void rc2_done(symmetric_key *skey) +{ +} + +/** + Gets suitable key size + @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. + @return CRYPT_OK if the input key size is acceptable. +*/ +int rc2_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize < 8) { + return CRYPT_INVALID_KEYSIZE; + } else if (*keysize > 128) { + *keysize = 128; + } + return CRYPT_OK; +} + +#endif + + + + +/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/rc2.c,v $ */ +/* $Revision: 1.14 $ */ +/* $Date: 2007/05/12 14:13:00 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/rc5.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/rc5.c new file mode 100644 index 0000000000..d22f8c7701 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/rc5.c @@ -0,0 +1,322 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file rc5.c + LTC_RC5 code by Tom St Denis +*/ + +#include "tomcrypt.h" + +#ifdef LTC_RC5 + +const struct ltc_cipher_descriptor rc5_desc = +{ + "rc5", + 2, + 8, 128, 8, 12, + &rc5_setup, + &rc5_ecb_encrypt, + &rc5_ecb_decrypt, + &rc5_test, + &rc5_done, + &rc5_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +static const ulong32 stab[50] = { +0xb7e15163UL, 0x5618cb1cUL, 0xf45044d5UL, 0x9287be8eUL, 0x30bf3847UL, 0xcef6b200UL, 0x6d2e2bb9UL, 0x0b65a572UL, +0xa99d1f2bUL, 0x47d498e4UL, 0xe60c129dUL, 0x84438c56UL, 0x227b060fUL, 0xc0b27fc8UL, 0x5ee9f981UL, 0xfd21733aUL, +0x9b58ecf3UL, 0x399066acUL, 0xd7c7e065UL, 0x75ff5a1eUL, 0x1436d3d7UL, 0xb26e4d90UL, 0x50a5c749UL, 0xeedd4102UL, +0x8d14babbUL, 0x2b4c3474UL, 0xc983ae2dUL, 0x67bb27e6UL, 0x05f2a19fUL, 0xa42a1b58UL, 0x42619511UL, 0xe0990ecaUL, +0x7ed08883UL, 0x1d08023cUL, 0xbb3f7bf5UL, 0x5976f5aeUL, 0xf7ae6f67UL, 0x95e5e920UL, 0x341d62d9UL, 0xd254dc92UL, +0x708c564bUL, 0x0ec3d004UL, 0xacfb49bdUL, 0x4b32c376UL, 0xe96a3d2fUL, 0x87a1b6e8UL, 0x25d930a1UL, 0xc410aa5aUL, +0x62482413UL, 0x007f9dccUL +}; + + /** + Initialize the LTC_RC5 block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +#ifdef LTC_CLEAN_STACK +static int _rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#else +int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#endif +{ + ulong32 L[64], *S, A, B, i, j, v, s, t, l; + + LTC_ARGCHK(skey != NULL); + LTC_ARGCHK(key != NULL); + + /* test parameters */ + if (num_rounds == 0) { + num_rounds = rc5_desc.default_rounds; + } + + if (num_rounds < 12 || num_rounds > 24) { + return CRYPT_INVALID_ROUNDS; + } + + /* key must be between 64 and 1024 bits */ + if (keylen < 8 || keylen > 128) { + return CRYPT_INVALID_KEYSIZE; + } + + skey->rc5.rounds = num_rounds; + S = skey->rc5.K; + + /* copy the key into the L array */ + for (A = i = j = 0; i < (ulong32)keylen; ) { + A = (A << 8) | ((ulong32)(key[i++] & 255)); + if ((i & 3) == 0) { + L[j++] = BSWAP(A); + A = 0; + } + } + + if ((keylen & 3) != 0) { + A <<= (ulong32)((8 * (4 - (keylen&3)))); + L[j++] = BSWAP(A); + } + + /* setup the S array */ + t = (ulong32)(2 * (num_rounds + 1)); + XMEMCPY(S, stab, t * sizeof(*S)); + + /* mix buffer */ + s = 3 * MAX(t, j); + l = j; + for (A = B = i = j = v = 0; v < s; v++) { + A = S[i] = ROLc(S[i] + A + B, 3); + B = L[j] = ROL(L[j] + A + B, (A+B)); + if (++i == t) { i = 0; } + if (++j == l) { j = 0; } + } + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int x; + x = _rc5_setup(key, keylen, num_rounds, skey); + burn_stack(sizeof(ulong32) * 122 + sizeof(int)); + return x; +} +#endif + +/** + Encrypts a block of text with LTC_RC5 + @param pt The input plaintext (8 bytes) + @param ct The output ciphertext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#else +int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#endif +{ + ulong32 A, B, *K; + int r; + LTC_ARGCHK(skey != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + + LOAD32L(A, &pt[0]); + LOAD32L(B, &pt[4]); + A += skey->rc5.K[0]; + B += skey->rc5.K[1]; + K = skey->rc5.K + 2; + + if ((skey->rc5.rounds & 1) == 0) { + for (r = 0; r < skey->rc5.rounds; r += 2) { + A = ROL(A ^ B, B) + K[0]; + B = ROL(B ^ A, A) + K[1]; + A = ROL(A ^ B, B) + K[2]; + B = ROL(B ^ A, A) + K[3]; + K += 4; + } + } else { + for (r = 0; r < skey->rc5.rounds; r++) { + A = ROL(A ^ B, B) + K[0]; + B = ROL(B ^ A, A) + K[1]; + K += 2; + } + } + STORE32L(A, &ct[0]); + STORE32L(B, &ct[4]); + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + int err = _rc5_ecb_encrypt(pt, ct, skey); + burn_stack(sizeof(ulong32) * 2 + sizeof(int)); + return err; +} +#endif + +/** + Decrypts a block of text with LTC_RC5 + @param ct The input ciphertext (8 bytes) + @param pt The output plaintext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#else +int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#endif +{ + ulong32 A, B, *K; + int r; + LTC_ARGCHK(skey != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + + LOAD32L(A, &ct[0]); + LOAD32L(B, &ct[4]); + K = skey->rc5.K + (skey->rc5.rounds << 1); + + if ((skey->rc5.rounds & 1) == 0) { + K -= 2; + for (r = skey->rc5.rounds - 1; r >= 0; r -= 2) { + B = ROR(B - K[3], A) ^ A; + A = ROR(A - K[2], B) ^ B; + B = ROR(B - K[1], A) ^ A; + A = ROR(A - K[0], B) ^ B; + K -= 4; + } + } else { + for (r = skey->rc5.rounds - 1; r >= 0; r--) { + B = ROR(B - K[1], A) ^ A; + A = ROR(A - K[0], B) ^ B; + K -= 2; + } + } + A -= skey->rc5.K[0]; + B -= skey->rc5.K[1]; + STORE32L(A, &pt[0]); + STORE32L(B, &pt[4]); + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + int err = _rc5_ecb_decrypt(ct, pt, skey); + burn_stack(sizeof(ulong32) * 2 + sizeof(int)); + return err; +} +#endif + +/** + Performs a self-test of the LTC_RC5 block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int rc5_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + unsigned char key[16], pt[8], ct[8]; + } tests[] = { + { + { 0x91, 0x5f, 0x46, 0x19, 0xbe, 0x41, 0xb2, 0x51, + 0x63, 0x55, 0xa5, 0x01, 0x10, 0xa9, 0xce, 0x91 }, + { 0x21, 0xa5, 0xdb, 0xee, 0x15, 0x4b, 0x8f, 0x6d }, + { 0xf7, 0xc0, 0x13, 0xac, 0x5b, 0x2b, 0x89, 0x52 } + }, + { + { 0x78, 0x33, 0x48, 0xe7, 0x5a, 0xeb, 0x0f, 0x2f, + 0xd7, 0xb1, 0x69, 0xbb, 0x8d, 0xc1, 0x67, 0x87 }, + { 0xF7, 0xC0, 0x13, 0xAC, 0x5B, 0x2B, 0x89, 0x52 }, + { 0x2F, 0x42, 0xB3, 0xB7, 0x03, 0x69, 0xFC, 0x92 } + }, + { + { 0xDC, 0x49, 0xdb, 0x13, 0x75, 0xa5, 0x58, 0x4f, + 0x64, 0x85, 0xb4, 0x13, 0xb5, 0xf1, 0x2b, 0xaf }, + { 0x2F, 0x42, 0xB3, 0xB7, 0x03, 0x69, 0xFC, 0x92 }, + { 0x65, 0xc1, 0x78, 0xb2, 0x84, 0xd1, 0x97, 0xcc } + } + }; + unsigned char tmp[2][8]; + int x, y, err; + symmetric_key key; + + for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { + /* setup key */ + if ((err = rc5_setup(tests[x].key, 16, 12, &key)) != CRYPT_OK) { + return err; + } + + /* encrypt and decrypt */ + rc5_ecb_encrypt(tests[x].pt, tmp[0], &key); + rc5_ecb_decrypt(tmp[0], tmp[1], &key); + + /* compare */ + if (XMEMCMP(tmp[0], tests[x].ct, 8) != 0 || XMEMCMP(tmp[1], tests[x].pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) rc5_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) rc5_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void rc5_done(symmetric_key *skey) +{ +} + +/** + Gets suitable key size + @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. + @return CRYPT_OK if the input key size is acceptable. +*/ +int rc5_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize < 8) { + return CRYPT_INVALID_KEYSIZE; + } else if (*keysize > 128) { + *keysize = 128; + } + return CRYPT_OK; +} + +#endif + + + + +/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/rc5.c,v $ */ +/* $Revision: 1.14 $ */ +/* $Date: 2007/05/12 14:13:00 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/rc6.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/rc6.c new file mode 100644 index 0000000000..5879ee4777 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/rc6.c @@ -0,0 +1,348 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file rc6.c + LTC_RC6 code by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_RC6 + +const struct ltc_cipher_descriptor rc6_desc = +{ + "rc6", + 3, + 8, 128, 16, 20, + &rc6_setup, + &rc6_ecb_encrypt, + &rc6_ecb_decrypt, + &rc6_test, + &rc6_done, + &rc6_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +static const ulong32 stab[44] = { +0xb7e15163UL, 0x5618cb1cUL, 0xf45044d5UL, 0x9287be8eUL, 0x30bf3847UL, 0xcef6b200UL, 0x6d2e2bb9UL, 0x0b65a572UL, +0xa99d1f2bUL, 0x47d498e4UL, 0xe60c129dUL, 0x84438c56UL, 0x227b060fUL, 0xc0b27fc8UL, 0x5ee9f981UL, 0xfd21733aUL, +0x9b58ecf3UL, 0x399066acUL, 0xd7c7e065UL, 0x75ff5a1eUL, 0x1436d3d7UL, 0xb26e4d90UL, 0x50a5c749UL, 0xeedd4102UL, +0x8d14babbUL, 0x2b4c3474UL, 0xc983ae2dUL, 0x67bb27e6UL, 0x05f2a19fUL, 0xa42a1b58UL, 0x42619511UL, 0xe0990ecaUL, +0x7ed08883UL, 0x1d08023cUL, 0xbb3f7bf5UL, 0x5976f5aeUL, 0xf7ae6f67UL, 0x95e5e920UL, 0x341d62d9UL, 0xd254dc92UL, +0x708c564bUL, 0x0ec3d004UL, 0xacfb49bdUL, 0x4b32c376UL }; + + /** + Initialize the LTC_RC6 block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +#ifdef LTC_CLEAN_STACK +static int _rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#else +int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#endif +{ + ulong32 L[64], S[50], A, B, i, j, v, s, l; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + /* test parameters */ + if (num_rounds != 0 && num_rounds != 20) { + return CRYPT_INVALID_ROUNDS; + } + + /* key must be between 64 and 1024 bits */ + if (keylen < 8 || keylen > 128) { + return CRYPT_INVALID_KEYSIZE; + } + + /* copy the key into the L array */ + for (A = i = j = 0; i < (ulong32)keylen; ) { + A = (A << 8) | ((ulong32)(key[i++] & 255)); + if (!(i & 3)) { + L[j++] = BSWAP(A); + A = 0; + } + } + + /* handle odd sized keys */ + if (keylen & 3) { + A <<= (8 * (4 - (keylen&3))); + L[j++] = BSWAP(A); + } + + /* setup the S array */ + XMEMCPY(S, stab, 44 * sizeof(stab[0])); + + /* mix buffer */ + s = 3 * MAX(44, j); + l = j; + for (A = B = i = j = v = 0; v < s; v++) { + A = S[i] = ROLc(S[i] + A + B, 3); + B = L[j] = ROL(L[j] + A + B, (A+B)); + if (++i == 44) { i = 0; } + if (++j == l) { j = 0; } + } + + /* copy to key */ + for (i = 0; i < 44; i++) { + skey->rc6.K[i] = S[i]; + } + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int x; + x = _rc6_setup(key, keylen, num_rounds, skey); + burn_stack(sizeof(ulong32) * 122); + return x; +} +#endif + +/** + Encrypts a block of text with LTC_RC6 + @param pt The input plaintext (16 bytes) + @param ct The output ciphertext (16 bytes) + @param skey The key as scheduled +*/ +#ifdef LTC_CLEAN_STACK +static int _rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#else +int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#endif +{ + ulong32 a,b,c,d,t,u, *K; + int r; + + LTC_ARGCHK(skey != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LOAD32L(a,&pt[0]);LOAD32L(b,&pt[4]);LOAD32L(c,&pt[8]);LOAD32L(d,&pt[12]); + + b += skey->rc6.K[0]; + d += skey->rc6.K[1]; + +#define RND(a,b,c,d) \ + t = (b * (b + b + 1)); t = ROLc(t, 5); \ + u = (d * (d + d + 1)); u = ROLc(u, 5); \ + a = ROL(a^t,u) + K[0]; \ + c = ROL(c^u,t) + K[1]; K += 2; + + K = skey->rc6.K + 2; + for (r = 0; r < 20; r += 4) { + RND(a,b,c,d); + RND(b,c,d,a); + RND(c,d,a,b); + RND(d,a,b,c); + } + +#undef RND + + a += skey->rc6.K[42]; + c += skey->rc6.K[43]; + STORE32L(a,&ct[0]);STORE32L(b,&ct[4]);STORE32L(c,&ct[8]);STORE32L(d,&ct[12]); + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + int err = _rc6_ecb_encrypt(pt, ct, skey); + burn_stack(sizeof(ulong32) * 6 + sizeof(int)); + return err; +} +#endif + +/** + Decrypts a block of text with LTC_RC6 + @param ct The input ciphertext (16 bytes) + @param pt The output plaintext (16 bytes) + @param skey The key as scheduled +*/ +#ifdef LTC_CLEAN_STACK +static int _rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#else +int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#endif +{ + ulong32 a,b,c,d,t,u, *K; + int r; + + LTC_ARGCHK(skey != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + + LOAD32L(a,&ct[0]);LOAD32L(b,&ct[4]);LOAD32L(c,&ct[8]);LOAD32L(d,&ct[12]); + a -= skey->rc6.K[42]; + c -= skey->rc6.K[43]; + +#define RND(a,b,c,d) \ + t = (b * (b + b + 1)); t = ROLc(t, 5); \ + u = (d * (d + d + 1)); u = ROLc(u, 5); \ + c = ROR(c - K[1], t) ^ u; \ + a = ROR(a - K[0], u) ^ t; K -= 2; + + K = skey->rc6.K + 40; + + for (r = 0; r < 20; r += 4) { + RND(d,a,b,c); + RND(c,d,a,b); + RND(b,c,d,a); + RND(a,b,c,d); + } + +#undef RND + + b -= skey->rc6.K[0]; + d -= skey->rc6.K[1]; + STORE32L(a,&pt[0]);STORE32L(b,&pt[4]);STORE32L(c,&pt[8]);STORE32L(d,&pt[12]); + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + int err = _rc6_ecb_decrypt(ct, pt, skey); + burn_stack(sizeof(ulong32) * 6 + sizeof(int)); + return err; +} +#endif + +/** + Performs a self-test of the LTC_RC6 block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int rc6_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen; + unsigned char key[32], pt[16], ct[16]; + } tests[] = { + { + 16, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79, + 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 }, + { 0x52, 0x4e, 0x19, 0x2f, 0x47, 0x15, 0xc6, 0x23, + 0x1f, 0x51, 0xf6, 0x36, 0x7e, 0xa4, 0x3f, 0x18 } + }, + { + 24, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, + 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79, + 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 }, + { 0x68, 0x83, 0x29, 0xd0, 0x19, 0xe5, 0x05, 0x04, + 0x1e, 0x52, 0xe9, 0x2a, 0xf9, 0x52, 0x91, 0xd4 } + }, + { + 32, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, + 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0, + 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe }, + { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79, + 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 }, + { 0xc8, 0x24, 0x18, 0x16, 0xf0, 0xd7, 0xe4, 0x89, + 0x20, 0xad, 0x16, 0xa1, 0x67, 0x4e, 0x5d, 0x48 } + } + }; + unsigned char tmp[2][16]; + int x, y, err; + symmetric_key key; + + for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { + /* setup key */ + if ((err = rc6_setup(tests[x].key, tests[x].keylen, 0, &key)) != CRYPT_OK) { + return err; + } + + /* encrypt and decrypt */ + rc6_ecb_encrypt(tests[x].pt, tmp[0], &key); + rc6_ecb_decrypt(tmp[0], tmp[1], &key); + + /* compare */ + if (XMEMCMP(tmp[0], tests[x].ct, 16) || XMEMCMP(tmp[1], tests[x].pt, 16)) { +#if 0 + printf("\n\nFailed test %d\n", x); + if (XMEMCMP(tmp[0], tests[x].ct, 16)) { + printf("Ciphertext: "); + for (y = 0; y < 16; y++) printf("%02x ", tmp[0][y]); + printf("\nExpected : "); + for (y = 0; y < 16; y++) printf("%02x ", tests[x].ct[y]); + printf("\n"); + } + if (XMEMCMP(tmp[1], tests[x].pt, 16)) { + printf("Plaintext: "); + for (y = 0; y < 16; y++) printf("%02x ", tmp[0][y]); + printf("\nExpected : "); + for (y = 0; y < 16; y++) printf("%02x ", tests[x].pt[y]); + printf("\n"); + } +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 16; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) rc6_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) rc6_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void rc6_done(symmetric_key *skey) +{ +} + +/** + Gets suitable key size + @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. + @return CRYPT_OK if the input key size is acceptable. +*/ +int rc6_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize < 8) { + return CRYPT_INVALID_KEYSIZE; + } else if (*keysize > 128) { + *keysize = 128; + } + return CRYPT_OK; +} + +#endif /*LTC_RC6*/ + + + +/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/rc6.c,v $ */ +/* $Revision: 1.14 $ */ +/* $Date: 2007/05/12 14:13:00 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/safer/safer.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/safer/safer.c new file mode 100644 index 0000000000..21435876b1 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/safer/safer.c @@ -0,0 +1,491 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/******************************************************************************* +* +* FILE: safer.c +* +* LTC_DESCRIPTION: block-cipher algorithm LTC_SAFER (Secure And Fast Encryption +* Routine) in its four versions: LTC_SAFER K-64, LTC_SAFER K-128, +* LTC_SAFER SK-64 and LTC_SAFER SK-128. +* +* AUTHOR: Richard De Moliner (demoliner@isi.ee.ethz.ch) +* Signal and Information Processing Laboratory +* Swiss Federal Institute of Technology +* CH-8092 Zuerich, Switzerland +* +* DATE: September 9, 1995 +* +* CHANGE HISTORY: +* +*******************************************************************************/ + +#include + +#ifdef LTC_SAFER + +const struct ltc_cipher_descriptor + safer_k64_desc = { + "safer-k64", + 8, 8, 8, 8, LTC_SAFER_K64_DEFAULT_NOF_ROUNDS, + &safer_k64_setup, + &safer_ecb_encrypt, + &safer_ecb_decrypt, + &safer_k64_test, + &safer_done, + &safer_64_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + }, + + safer_sk64_desc = { + "safer-sk64", + 9, 8, 8, 8, LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS, + &safer_sk64_setup, + &safer_ecb_encrypt, + &safer_ecb_decrypt, + &safer_sk64_test, + &safer_done, + &safer_64_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + }, + + safer_k128_desc = { + "safer-k128", + 10, 16, 16, 8, LTC_SAFER_K128_DEFAULT_NOF_ROUNDS, + &safer_k128_setup, + &safer_ecb_encrypt, + &safer_ecb_decrypt, + &safer_sk128_test, + &safer_done, + &safer_128_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + }, + + safer_sk128_desc = { + "safer-sk128", + 11, 16, 16, 8, LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS, + &safer_sk128_setup, + &safer_ecb_encrypt, + &safer_ecb_decrypt, + &safer_sk128_test, + &safer_done, + &safer_128_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + }; + +/******************* Constants ************************************************/ +/* #define TAB_LEN 256 */ + +/******************* Assertions ***********************************************/ + +/******************* Macros ***************************************************/ +#define ROL8(x, n) ((unsigned char)((unsigned int)(x) << (n)\ + |(unsigned int)((x) & 0xFF) >> (8 - (n)))) +#define EXP(x) safer_ebox[(x) & 0xFF] +#define LOG(x) safer_lbox[(x) & 0xFF] +#define PHT(x, y) { y += x; x += y; } +#define IPHT(x, y) { x -= y; y -= x; } + +/******************* Types ****************************************************/ +extern const unsigned char safer_ebox[], safer_lbox[]; + +#ifdef LTC_CLEAN_STACK +static void _Safer_Expand_Userkey(const unsigned char *userkey_1, + const unsigned char *userkey_2, + unsigned int nof_rounds, + int strengthened, + safer_key_t key) +#else +static void Safer_Expand_Userkey(const unsigned char *userkey_1, + const unsigned char *userkey_2, + unsigned int nof_rounds, + int strengthened, + safer_key_t key) +#endif +{ unsigned int i, j, k; + unsigned char ka[LTC_SAFER_BLOCK_LEN + 1]; + unsigned char kb[LTC_SAFER_BLOCK_LEN + 1]; + + if (LTC_SAFER_MAX_NOF_ROUNDS < nof_rounds) + nof_rounds = LTC_SAFER_MAX_NOF_ROUNDS; + *key++ = (unsigned char)nof_rounds; + ka[LTC_SAFER_BLOCK_LEN] = (unsigned char)0; + kb[LTC_SAFER_BLOCK_LEN] = (unsigned char)0; + k = 0; + for (j = 0; j < LTC_SAFER_BLOCK_LEN; j++) { + ka[j] = ROL8(userkey_1[j], 5); + ka[LTC_SAFER_BLOCK_LEN] ^= ka[j]; + kb[j] = *key++ = userkey_2[j]; + kb[LTC_SAFER_BLOCK_LEN] ^= kb[j]; + } + for (i = 1; i <= nof_rounds; i++) { + for (j = 0; j < LTC_SAFER_BLOCK_LEN + 1; j++) { + ka[j] = ROL8(ka[j], 6); + kb[j] = ROL8(kb[j], 6); + } + if (strengthened) { + k = 2 * i - 1; + while (k >= (LTC_SAFER_BLOCK_LEN + 1)) { k -= LTC_SAFER_BLOCK_LEN + 1; } + } + for (j = 0; j < LTC_SAFER_BLOCK_LEN; j++) { + if (strengthened) { + *key++ = (ka[k] + + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 1)&0xFF)]]) & 0xFF; + if (++k == (LTC_SAFER_BLOCK_LEN + 1)) { k = 0; } + } else { + *key++ = (ka[j] + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 1)&0xFF)]]) & 0xFF; + } + } + if (strengthened) { + k = 2 * i; + while (k >= (LTC_SAFER_BLOCK_LEN + 1)) { k -= LTC_SAFER_BLOCK_LEN + 1; } + } + for (j = 0; j < LTC_SAFER_BLOCK_LEN; j++) { + if (strengthened) { + *key++ = (kb[k] + + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 10)&0xFF)]]) & 0xFF; + if (++k == (LTC_SAFER_BLOCK_LEN + 1)) { k = 0; } + } else { + *key++ = (kb[j] + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 10)&0xFF)]]) & 0xFF; + } + } + } + +#ifdef LTC_CLEAN_STACK + zeromem(ka, sizeof(ka)); + zeromem(kb, sizeof(kb)); +#endif +} + +#ifdef LTC_CLEAN_STACK +static void Safer_Expand_Userkey(const unsigned char *userkey_1, + const unsigned char *userkey_2, + unsigned int nof_rounds, + int strengthened, + safer_key_t key) +{ + _Safer_Expand_Userkey(userkey_1, userkey_2, nof_rounds, strengthened, key); + burn_stack(sizeof(unsigned char) * (2 * (LTC_SAFER_BLOCK_LEN + 1)) + sizeof(unsigned int)*2); +} +#endif + +int safer_k64_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) +{ + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 8) { + return CRYPT_INVALID_KEYSIZE; + } + + Safer_Expand_Userkey(key, key, (unsigned int)(numrounds != 0 ?numrounds:LTC_SAFER_K64_DEFAULT_NOF_ROUNDS), 0, skey->safer.key); + return CRYPT_OK; +} + +int safer_sk64_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) +{ + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 8) { + return CRYPT_INVALID_KEYSIZE; + } + + Safer_Expand_Userkey(key, key, (unsigned int)(numrounds != 0 ?numrounds:LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS), 1, skey->safer.key); + return CRYPT_OK; +} + +int safer_k128_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) +{ + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 16) { + return CRYPT_INVALID_KEYSIZE; + } + + Safer_Expand_Userkey(key, key+8, (unsigned int)(numrounds != 0 ?numrounds:LTC_SAFER_K128_DEFAULT_NOF_ROUNDS), 0, skey->safer.key); + return CRYPT_OK; +} + +int safer_sk128_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) +{ + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 16) { + return CRYPT_INVALID_KEYSIZE; + } + + Safer_Expand_Userkey(key, key+8, (unsigned int)(numrounds != 0?numrounds:LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS), 1, skey->safer.key); + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +static int _safer_ecb_encrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +#else +int safer_ecb_encrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +#endif +{ unsigned char a, b, c, d, e, f, g, h, t; + unsigned int round; + unsigned char *key; + + LTC_ARGCHK(block_in != NULL); + LTC_ARGCHK(block_out != NULL); + LTC_ARGCHK(skey != NULL); + + key = skey->safer.key; + a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3]; + e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7]; + if (LTC_SAFER_MAX_NOF_ROUNDS < (round = *key)) round = LTC_SAFER_MAX_NOF_ROUNDS; + while(round-- > 0) + { + a ^= *++key; b += *++key; c += *++key; d ^= *++key; + e ^= *++key; f += *++key; g += *++key; h ^= *++key; + a = EXP(a) + *++key; b = LOG(b) ^ *++key; + c = LOG(c) ^ *++key; d = EXP(d) + *++key; + e = EXP(e) + *++key; f = LOG(f) ^ *++key; + g = LOG(g) ^ *++key; h = EXP(h) + *++key; + PHT(a, b); PHT(c, d); PHT(e, f); PHT(g, h); + PHT(a, c); PHT(e, g); PHT(b, d); PHT(f, h); + PHT(a, e); PHT(b, f); PHT(c, g); PHT(d, h); + t = b; b = e; e = c; c = t; t = d; d = f; f = g; g = t; + } + a ^= *++key; b += *++key; c += *++key; d ^= *++key; + e ^= *++key; f += *++key; g += *++key; h ^= *++key; + block_out[0] = a & 0xFF; block_out[1] = b & 0xFF; + block_out[2] = c & 0xFF; block_out[3] = d & 0xFF; + block_out[4] = e & 0xFF; block_out[5] = f & 0xFF; + block_out[6] = g & 0xFF; block_out[7] = h & 0xFF; + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int safer_ecb_encrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +{ + int err = _safer_ecb_encrypt(block_in, block_out, skey); + burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *)); + return err; +} +#endif + +#ifdef LTC_CLEAN_STACK +static int _safer_ecb_decrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +#else +int safer_ecb_decrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +#endif +{ unsigned char a, b, c, d, e, f, g, h, t; + unsigned int round; + unsigned char *key; + + LTC_ARGCHK(block_in != NULL); + LTC_ARGCHK(block_out != NULL); + LTC_ARGCHK(skey != NULL); + + key = skey->safer.key; + a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3]; + e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7]; + if (LTC_SAFER_MAX_NOF_ROUNDS < (round = *key)) round = LTC_SAFER_MAX_NOF_ROUNDS; + key += LTC_SAFER_BLOCK_LEN * (1 + 2 * round); + h ^= *key; g -= *--key; f -= *--key; e ^= *--key; + d ^= *--key; c -= *--key; b -= *--key; a ^= *--key; + while (round--) + { + t = e; e = b; b = c; c = t; t = f; f = d; d = g; g = t; + IPHT(a, e); IPHT(b, f); IPHT(c, g); IPHT(d, h); + IPHT(a, c); IPHT(e, g); IPHT(b, d); IPHT(f, h); + IPHT(a, b); IPHT(c, d); IPHT(e, f); IPHT(g, h); + h -= *--key; g ^= *--key; f ^= *--key; e -= *--key; + d -= *--key; c ^= *--key; b ^= *--key; a -= *--key; + h = LOG(h) ^ *--key; g = EXP(g) - *--key; + f = EXP(f) - *--key; e = LOG(e) ^ *--key; + d = LOG(d) ^ *--key; c = EXP(c) - *--key; + b = EXP(b) - *--key; a = LOG(a) ^ *--key; + } + block_out[0] = a & 0xFF; block_out[1] = b & 0xFF; + block_out[2] = c & 0xFF; block_out[3] = d & 0xFF; + block_out[4] = e & 0xFF; block_out[5] = f & 0xFF; + block_out[6] = g & 0xFF; block_out[7] = h & 0xFF; + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int safer_ecb_decrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +{ + int err = _safer_ecb_decrypt(block_in, block_out, skey); + burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *)); + return err; +} +#endif + +int safer_64_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize < 8) { + return CRYPT_INVALID_KEYSIZE; + } else { + *keysize = 8; + return CRYPT_OK; + } +} + +int safer_128_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize < 16) { + return CRYPT_INVALID_KEYSIZE; + } else { + *keysize = 16; + return CRYPT_OK; + } +} + +int safer_k64_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const unsigned char k64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, + k64_key[] = { 8, 7, 6, 5, 4, 3, 2, 1 }, + k64_ct[] = { 200, 242, 156, 221, 135, 120, 62, 217 }; + + symmetric_key skey; + unsigned char buf[2][8]; + int err; + + /* test K64 */ + if ((err = safer_k64_setup(k64_key, 8, 6, &skey)) != CRYPT_OK) { + return err; + } + safer_ecb_encrypt(k64_pt, buf[0], &skey); + safer_ecb_decrypt(buf[0], buf[1], &skey); + + if (XMEMCMP(buf[0], k64_ct, 8) != 0 || XMEMCMP(buf[1], k64_pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; + #endif +} + + +int safer_sk64_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const unsigned char sk64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, + sk64_key[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, + sk64_ct[] = { 95, 206, 155, 162, 5, 132, 56, 199 }; + + symmetric_key skey; + unsigned char buf[2][8]; + int err, y; + + /* test SK64 */ + if ((err = safer_sk64_setup(sk64_key, 8, 6, &skey)) != CRYPT_OK) { + return err; + } + + safer_ecb_encrypt(sk64_pt, buf[0], &skey); + safer_ecb_decrypt(buf[0], buf[1], &skey); + + if (XMEMCMP(buf[0], sk64_ct, 8) != 0 || XMEMCMP(buf[1], sk64_pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) buf[0][y] = 0; + for (y = 0; y < 1000; y++) safer_ecb_encrypt(buf[0], buf[0], &skey); + for (y = 0; y < 1000; y++) safer_ecb_decrypt(buf[0], buf[0], &skey); + for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + + return CRYPT_OK; + #endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void safer_done(symmetric_key *skey) +{ +} + +int safer_sk128_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const unsigned char sk128_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, + sk128_key[] = { 1, 2, 3, 4, 5, 6, 7, 8, + 0, 0, 0, 0, 0, 0, 0, 0 }, + sk128_ct[] = { 255, 120, 17, 228, 179, 167, 46, 113 }; + + symmetric_key skey; + unsigned char buf[2][8]; + int err, y; + + /* test SK128 */ + if ((err = safer_sk128_setup(sk128_key, 16, 0, &skey)) != CRYPT_OK) { + return err; + } + safer_ecb_encrypt(sk128_pt, buf[0], &skey); + safer_ecb_decrypt(buf[0], buf[1], &skey); + + if (XMEMCMP(buf[0], sk128_ct, 8) != 0 || XMEMCMP(buf[1], sk128_pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) buf[0][y] = 0; + for (y = 0; y < 1000; y++) safer_ecb_encrypt(buf[0], buf[0], &skey); + for (y = 0; y < 1000; y++) safer_ecb_decrypt(buf[0], buf[0], &skey); + for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + return CRYPT_OK; + #endif +} + +#endif + + + + +/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/safer/safer.c,v $ */ +/* $Revision: 1.15 $ */ +/* $Date: 2007/05/12 14:20:27 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/safer/safer_tab.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/safer/safer_tab.c new file mode 100644 index 0000000000..60408d5f23 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/safer/safer_tab.c @@ -0,0 +1,68 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file safer_tab.c + Tables for LTC_SAFER block ciphers +*/ + +#include "tomcrypt.h" + +#if defined(LTC_SAFERP) || defined(LTC_SAFER) + +/* This is the box defined by ebox[x] = 45^x mod 257. + * Its assumed that the value "256" corresponds to zero. */ +const unsigned char safer_ebox[256] = { + 1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207, 63, + 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247, + 64, 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, +255, 167, 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, +241, 51, 239, 218, 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, +129, 151, 113, 202, 95, 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, + 4, 180, 133, 74, 246, 19, 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, + 32, 155, 36, 78, 169, 152, 158, 171, 242, 96, 208, 108, 234, 250, 199, 217, + 0, 212, 31, 110, 67, 188, 236, 83, 137, 254, 122, 93, 73, 201, 50, 194, +249, 154, 248, 109, 22, 219, 89, 150, 68, 233, 205, 230, 70, 66, 143, 10, +193, 204, 185, 101, 176, 210, 198, 172, 30, 65, 98, 41, 46, 14, 116, 80, + 2, 90, 195, 37, 123, 138, 42, 91, 240, 6, 13, 71, 111, 112, 157, 126, + 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104, 54, 117, 125, 228, 237, +128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175, 165, 229, 25, 97, +253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35, 33, 200, 5, +225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7, 58, 40 +}; + +/* This is the inverse of ebox or the base 45 logarithm */ +const unsigned char safer_lbox[256] = { +128, 0, 176, 9, 96, 239, 185, 253, 16, 18, 159, 228, 105, 186, 173, 248, +192, 56, 194, 101, 79, 6, 148, 252, 25, 222, 106, 27, 93, 78, 168, 130, +112, 237, 232, 236, 114, 179, 21, 195, 255, 171, 182, 71, 68, 1, 172, 37, +201, 250, 142, 65, 26, 33, 203, 211, 13, 110, 254, 38, 88, 218, 50, 15, + 32, 169, 157, 132, 152, 5, 156, 187, 34, 140, 99, 231, 197, 225, 115, 198, +175, 36, 91, 135, 102, 39, 247, 87, 244, 150, 177, 183, 92, 139, 213, 84, +121, 223, 170, 246, 62, 163, 241, 17, 202, 245, 209, 23, 123, 147, 131, 188, +189, 82, 30, 235, 174, 204, 214, 53, 8, 200, 138, 180, 226, 205, 191, 217, +208, 80, 89, 63, 77, 98, 52, 10, 72, 136, 181, 86, 76, 46, 107, 158, +210, 61, 60, 3, 19, 251, 151, 81, 117, 74, 145, 113, 35, 190, 118, 42, + 95, 249, 212, 85, 11, 220, 55, 49, 22, 116, 215, 119, 167, 230, 7, 219, +164, 47, 70, 243, 97, 69, 103, 227, 12, 162, 59, 28, 133, 24, 4, 29, + 41, 160, 143, 178, 90, 216, 166, 126, 238, 141, 83, 75, 161, 154, 193, 14, +122, 73, 165, 44, 129, 196, 199, 54, 43, 127, 67, 149, 51, 242, 108, 104, +109, 240, 2, 40, 206, 221, 155, 234, 94, 153, 124, 20, 134, 207, 229, 66, +184, 64, 120, 45, 58, 233, 100, 31, 146, 144, 125, 57, 111, 224, 137, 48 +}; + +#endif + + + +/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/safer/safer_tab.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:20:27 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/safer/saferp.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/safer/saferp.c new file mode 100644 index 0000000000..b436385b46 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/safer/saferp.c @@ -0,0 +1,559 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file saferp.c + LTC_SAFER+ Implementation by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_SAFERP + +const struct ltc_cipher_descriptor saferp_desc = +{ + "safer+", + 4, + 16, 32, 16, 8, + &saferp_setup, + &saferp_ecb_encrypt, + &saferp_ecb_decrypt, + &saferp_test, + &saferp_done, + &saferp_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +/* ROUND(b,i) + * + * This is one forward key application. Note the basic form is + * key addition, substitution, key addition. The safer_ebox and safer_lbox + * are the exponentiation box and logarithm boxes respectively. + * The value of 'i' is the current round number which allows this + * function to be unrolled massively. Most of LTC_SAFER+'s speed + * comes from not having to compute indirect accesses into the + * array of 16 bytes b[0..15] which is the block of data +*/ + +extern const unsigned char safer_ebox[], safer_lbox[]; + +#define ROUND(b, i) \ + b[0] = (safer_ebox[(b[0] ^ skey->saferp.K[i][0]) & 255] + skey->saferp.K[i+1][0]) & 255; \ + b[1] = safer_lbox[(b[1] + skey->saferp.K[i][1]) & 255] ^ skey->saferp.K[i+1][1]; \ + b[2] = safer_lbox[(b[2] + skey->saferp.K[i][2]) & 255] ^ skey->saferp.K[i+1][2]; \ + b[3] = (safer_ebox[(b[3] ^ skey->saferp.K[i][3]) & 255] + skey->saferp.K[i+1][3]) & 255; \ + b[4] = (safer_ebox[(b[4] ^ skey->saferp.K[i][4]) & 255] + skey->saferp.K[i+1][4]) & 255; \ + b[5] = safer_lbox[(b[5] + skey->saferp.K[i][5]) & 255] ^ skey->saferp.K[i+1][5]; \ + b[6] = safer_lbox[(b[6] + skey->saferp.K[i][6]) & 255] ^ skey->saferp.K[i+1][6]; \ + b[7] = (safer_ebox[(b[7] ^ skey->saferp.K[i][7]) & 255] + skey->saferp.K[i+1][7]) & 255; \ + b[8] = (safer_ebox[(b[8] ^ skey->saferp.K[i][8]) & 255] + skey->saferp.K[i+1][8]) & 255; \ + b[9] = safer_lbox[(b[9] + skey->saferp.K[i][9]) & 255] ^ skey->saferp.K[i+1][9]; \ + b[10] = safer_lbox[(b[10] + skey->saferp.K[i][10]) & 255] ^ skey->saferp.K[i+1][10]; \ + b[11] = (safer_ebox[(b[11] ^ skey->saferp.K[i][11]) & 255] + skey->saferp.K[i+1][11]) & 255; \ + b[12] = (safer_ebox[(b[12] ^ skey->saferp.K[i][12]) & 255] + skey->saferp.K[i+1][12]) & 255; \ + b[13] = safer_lbox[(b[13] + skey->saferp.K[i][13]) & 255] ^ skey->saferp.K[i+1][13]; \ + b[14] = safer_lbox[(b[14] + skey->saferp.K[i][14]) & 255] ^ skey->saferp.K[i+1][14]; \ + b[15] = (safer_ebox[(b[15] ^ skey->saferp.K[i][15]) & 255] + skey->saferp.K[i+1][15]) & 255; + +/* This is one inverse key application */ +#define iROUND(b, i) \ + b[0] = safer_lbox[(b[0] - skey->saferp.K[i+1][0]) & 255] ^ skey->saferp.K[i][0]; \ + b[1] = (safer_ebox[(b[1] ^ skey->saferp.K[i+1][1]) & 255] - skey->saferp.K[i][1]) & 255; \ + b[2] = (safer_ebox[(b[2] ^ skey->saferp.K[i+1][2]) & 255] - skey->saferp.K[i][2]) & 255; \ + b[3] = safer_lbox[(b[3] - skey->saferp.K[i+1][3]) & 255] ^ skey->saferp.K[i][3]; \ + b[4] = safer_lbox[(b[4] - skey->saferp.K[i+1][4]) & 255] ^ skey->saferp.K[i][4]; \ + b[5] = (safer_ebox[(b[5] ^ skey->saferp.K[i+1][5]) & 255] - skey->saferp.K[i][5]) & 255; \ + b[6] = (safer_ebox[(b[6] ^ skey->saferp.K[i+1][6]) & 255] - skey->saferp.K[i][6]) & 255; \ + b[7] = safer_lbox[(b[7] - skey->saferp.K[i+1][7]) & 255] ^ skey->saferp.K[i][7]; \ + b[8] = safer_lbox[(b[8] - skey->saferp.K[i+1][8]) & 255] ^ skey->saferp.K[i][8]; \ + b[9] = (safer_ebox[(b[9] ^ skey->saferp.K[i+1][9]) & 255] - skey->saferp.K[i][9]) & 255; \ + b[10] = (safer_ebox[(b[10] ^ skey->saferp.K[i+1][10]) & 255] - skey->saferp.K[i][10]) & 255; \ + b[11] = safer_lbox[(b[11] - skey->saferp.K[i+1][11]) & 255] ^ skey->saferp.K[i][11]; \ + b[12] = safer_lbox[(b[12] - skey->saferp.K[i+1][12]) & 255] ^ skey->saferp.K[i][12]; \ + b[13] = (safer_ebox[(b[13] ^ skey->saferp.K[i+1][13]) & 255] - skey->saferp.K[i][13]) & 255; \ + b[14] = (safer_ebox[(b[14] ^ skey->saferp.K[i+1][14]) & 255] - skey->saferp.K[i][14]) & 255; \ + b[15] = safer_lbox[(b[15] - skey->saferp.K[i+1][15]) & 255] ^ skey->saferp.K[i][15]; + +/* This is a forward single layer PHT transform. */ +#define PHT(b) \ + b[0] = (b[0] + (b[1] = (b[0] + b[1]) & 255)) & 255; \ + b[2] = (b[2] + (b[3] = (b[3] + b[2]) & 255)) & 255; \ + b[4] = (b[4] + (b[5] = (b[5] + b[4]) & 255)) & 255; \ + b[6] = (b[6] + (b[7] = (b[7] + b[6]) & 255)) & 255; \ + b[8] = (b[8] + (b[9] = (b[9] + b[8]) & 255)) & 255; \ + b[10] = (b[10] + (b[11] = (b[11] + b[10]) & 255)) & 255; \ + b[12] = (b[12] + (b[13] = (b[13] + b[12]) & 255)) & 255; \ + b[14] = (b[14] + (b[15] = (b[15] + b[14]) & 255)) & 255; + +/* This is an inverse single layer PHT transform */ +#define iPHT(b) \ + b[15] = (b[15] - (b[14] = (b[14] - b[15]) & 255)) & 255; \ + b[13] = (b[13] - (b[12] = (b[12] - b[13]) & 255)) & 255; \ + b[11] = (b[11] - (b[10] = (b[10] - b[11]) & 255)) & 255; \ + b[9] = (b[9] - (b[8] = (b[8] - b[9]) & 255)) & 255; \ + b[7] = (b[7] - (b[6] = (b[6] - b[7]) & 255)) & 255; \ + b[5] = (b[5] - (b[4] = (b[4] - b[5]) & 255)) & 255; \ + b[3] = (b[3] - (b[2] = (b[2] - b[3]) & 255)) & 255; \ + b[1] = (b[1] - (b[0] = (b[0] - b[1]) & 255)) & 255; \ + +/* This is the "Armenian" Shuffle. It takes the input from b and stores it in b2 */ +#define SHUF(b, b2) \ + b2[0] = b[8]; b2[1] = b[11]; b2[2] = b[12]; b2[3] = b[15]; \ + b2[4] = b[2]; b2[5] = b[1]; b2[6] = b[6]; b2[7] = b[5]; \ + b2[8] = b[10]; b2[9] = b[9]; b2[10] = b[14]; b2[11] = b[13]; \ + b2[12] = b[0]; b2[13] = b[7]; b2[14] = b[4]; b2[15] = b[3]; + +/* This is the inverse shuffle. It takes from b and gives to b2 */ +#define iSHUF(b, b2) \ + b2[0] = b[12]; b2[1] = b[5]; b2[2] = b[4]; b2[3] = b[15]; \ + b2[4] = b[14]; b2[5] = b[7]; b2[6] = b[6]; b2[7] = b[13]; \ + b2[8] = b[0]; b2[9] = b[9]; b2[10] = b[8]; b2[11] = b[1]; \ + b2[12] = b[2]; b2[13] = b[11]; b2[14] = b[10]; b2[15] = b[3]; + +/* The complete forward Linear Transform layer. + * Note that alternating usage of b and b2. + * Each round of LT starts in 'b' and ends in 'b2'. + */ +#define LT(b, b2) \ + PHT(b); SHUF(b, b2); \ + PHT(b2); SHUF(b2, b); \ + PHT(b); SHUF(b, b2); \ + PHT(b2); + +/* This is the inverse linear transform layer. */ +#define iLT(b, b2) \ + iPHT(b); \ + iSHUF(b, b2); iPHT(b2); \ + iSHUF(b2, b); iPHT(b); \ + iSHUF(b, b2); iPHT(b2); + +#ifdef LTC_SMALL_CODE + +static void _round(unsigned char *b, int i, symmetric_key *skey) +{ + ROUND(b, i); +} + +static void _iround(unsigned char *b, int i, symmetric_key *skey) +{ + iROUND(b, i); +} + +static void _lt(unsigned char *b, unsigned char *b2) +{ + LT(b, b2); +} + +static void _ilt(unsigned char *b, unsigned char *b2) +{ + iLT(b, b2); +} + +#undef ROUND +#define ROUND(b, i) _round(b, i, skey) + +#undef iROUND +#define iROUND(b, i) _iround(b, i, skey) + +#undef LT +#define LT(b, b2) _lt(b, b2) + +#undef iLT +#define iLT(b, b2) _ilt(b, b2) + +#endif + +/* These are the 33, 128-bit bias words for the key schedule */ +static const unsigned char safer_bias[33][16] = { +{ 70, 151, 177, 186, 163, 183, 16, 10, 197, 55, 179, 201, 90, 40, 172, 100}, +{ 236, 171, 170, 198, 103, 149, 88, 13, 248, 154, 246, 110, 102, 220, 5, 61}, +{ 138, 195, 216, 137, 106, 233, 54, 73, 67, 191, 235, 212, 150, 155, 104, 160}, +{ 93, 87, 146, 31, 213, 113, 92, 187, 34, 193, 190, 123, 188, 153, 99, 148}, +{ 42, 97, 184, 52, 50, 25, 253, 251, 23, 64, 230, 81, 29, 65, 68, 143}, +{ 221, 4, 128, 222, 231, 49, 214, 127, 1, 162, 247, 57, 218, 111, 35, 202}, +{ 58, 208, 28, 209, 48, 62, 18, 161, 205, 15, 224, 168, 175, 130, 89, 44}, +{ 125, 173, 178, 239, 194, 135, 206, 117, 6, 19, 2, 144, 79, 46, 114, 51}, +{ 192, 141, 207, 169, 129, 226, 196, 39, 47, 108, 122, 159, 82, 225, 21, 56}, +{ 252, 32, 66, 199, 8, 228, 9, 85, 94, 140, 20, 118, 96, 255, 223, 215}, +{ 250, 11, 33, 0, 26, 249, 166, 185, 232, 158, 98, 76, 217, 145, 80, 210}, +{ 24, 180, 7, 132, 234, 91, 164, 200, 14, 203, 72, 105, 75, 78, 156, 53}, +{ 69, 77, 84, 229, 37, 60, 12, 74, 139, 63, 204, 167, 219, 107, 174, 244}, +{ 45, 243, 124, 109, 157, 181, 38, 116, 242, 147, 83, 176, 240, 17, 237, 131}, +{ 182, 3, 22, 115, 59, 30, 142, 112, 189, 134, 27, 71, 126, 36, 86, 241}, +{ 136, 70, 151, 177, 186, 163, 183, 16, 10, 197, 55, 179, 201, 90, 40, 172}, +{ 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51, 239}, +{ 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, 129, 151, 113, 202}, +{ 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, 4, 180, 133, 74, 246}, +{ 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, 32, 155, 36, 78, 169, 152}, +{ 171, 242, 96, 208, 108, 234, 250, 199, 217, 0, 212, 31, 110, 67, 188, 236}, +{ 137, 254, 122, 93, 73, 201, 50, 194, 249, 154, 248, 109, 22, 219, 89, 150}, +{ 233, 205, 230, 70, 66, 143, 10, 193, 204, 185, 101, 176, 210, 198, 172, 30}, +{ 98, 41, 46, 14, 116, 80, 2, 90, 195, 37, 123, 138, 42, 91, 240, 6}, +{ 71, 111, 112, 157, 126, 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104}, +{ 117, 125, 228, 237, 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175}, +{ 229, 25, 97, 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35}, +{ 200, 5, 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7}, +{ 40, 1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207}, +{ 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247}, +{ 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, 255}, +{ 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51}}; + + /** + Initialize the LTC_SAFER+ block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + unsigned x, y, z; + unsigned char t[33]; + static const int rounds[3] = { 8, 12, 16 }; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + /* check arguments */ + if (keylen != 16 && keylen != 24 && keylen != 32) { + return CRYPT_INVALID_KEYSIZE; + } + + /* Is the number of rounds valid? Either use zero for default or + * 8,12,16 rounds for 16,24,32 byte keys + */ + if (num_rounds != 0 && num_rounds != rounds[(keylen/8)-2]) { + return CRYPT_INVALID_ROUNDS; + } + + /* 128 bit key version */ + if (keylen == 16) { + /* copy key into t */ + for (x = y = 0; x < 16; x++) { + t[x] = key[x]; + y ^= key[x]; + } + t[16] = y; + + /* make round keys */ + for (x = 0; x < 16; x++) { + skey->saferp.K[0][x] = t[x]; + } + + /* make the 16 other keys as a transformation of the first key */ + for (x = 1; x < 17; x++) { + /* rotate 3 bits each */ + for (y = 0; y < 17; y++) { + t[y] = ((t[y]<<3)|(t[y]>>5)) & 255; + } + + /* select and add */ + z = x; + for (y = 0; y < 16; y++) { + skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255; + if (++z == 17) { z = 0; } + } + } + skey->saferp.rounds = 8; + } else if (keylen == 24) { + /* copy key into t */ + for (x = y = 0; x < 24; x++) { + t[x] = key[x]; + y ^= key[x]; + } + t[24] = y; + + /* make round keys */ + for (x = 0; x < 16; x++) { + skey->saferp.K[0][x] = t[x]; + } + + for (x = 1; x < 25; x++) { + /* rotate 3 bits each */ + for (y = 0; y < 25; y++) { + t[y] = ((t[y]<<3)|(t[y]>>5)) & 255; + } + + /* select and add */ + z = x; + for (y = 0; y < 16; y++) { + skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255; + if (++z == 25) { z = 0; } + } + } + skey->saferp.rounds = 12; + } else { + /* copy key into t */ + for (x = y = 0; x < 32; x++) { + t[x] = key[x]; + y ^= key[x]; + } + t[32] = y; + + /* make round keys */ + for (x = 0; x < 16; x++) { + skey->saferp.K[0][x] = t[x]; + } + + for (x = 1; x < 33; x++) { + /* rotate 3 bits each */ + for (y = 0; y < 33; y++) { + t[y] = ((t[y]<<3)|(t[y]>>5)) & 255; + } + + /* select and add */ + z = x; + for (y = 0; y < 16; y++) { + skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255; + if (++z == 33) { z = 0; } + } + } + skey->saferp.rounds = 16; + } +#ifdef LTC_CLEAN_STACK + zeromem(t, sizeof(t)); +#endif + return CRYPT_OK; +} + +/** + Encrypts a block of text with LTC_SAFER+ + @param pt The input plaintext (16 bytes) + @param ct The output ciphertext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + unsigned char b[16]; + int x; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + /* do eight rounds */ + for (x = 0; x < 16; x++) { + b[x] = pt[x]; + } + ROUND(b, 0); LT(b, ct); + ROUND(ct, 2); LT(ct, b); + ROUND(b, 4); LT(b, ct); + ROUND(ct, 6); LT(ct, b); + ROUND(b, 8); LT(b, ct); + ROUND(ct, 10); LT(ct, b); + ROUND(b, 12); LT(b, ct); + ROUND(ct, 14); LT(ct, b); + /* 192-bit key? */ + if (skey->saferp.rounds > 8) { + ROUND(b, 16); LT(b, ct); + ROUND(ct, 18); LT(ct, b); + ROUND(b, 20); LT(b, ct); + ROUND(ct, 22); LT(ct, b); + } + /* 256-bit key? */ + if (skey->saferp.rounds > 12) { + ROUND(b, 24); LT(b, ct); + ROUND(ct, 26); LT(ct, b); + ROUND(b, 28); LT(b, ct); + ROUND(ct, 30); LT(ct, b); + } + ct[0] = b[0] ^ skey->saferp.K[skey->saferp.rounds*2][0]; + ct[1] = (b[1] + skey->saferp.K[skey->saferp.rounds*2][1]) & 255; + ct[2] = (b[2] + skey->saferp.K[skey->saferp.rounds*2][2]) & 255; + ct[3] = b[3] ^ skey->saferp.K[skey->saferp.rounds*2][3]; + ct[4] = b[4] ^ skey->saferp.K[skey->saferp.rounds*2][4]; + ct[5] = (b[5] + skey->saferp.K[skey->saferp.rounds*2][5]) & 255; + ct[6] = (b[6] + skey->saferp.K[skey->saferp.rounds*2][6]) & 255; + ct[7] = b[7] ^ skey->saferp.K[skey->saferp.rounds*2][7]; + ct[8] = b[8] ^ skey->saferp.K[skey->saferp.rounds*2][8]; + ct[9] = (b[9] + skey->saferp.K[skey->saferp.rounds*2][9]) & 255; + ct[10] = (b[10] + skey->saferp.K[skey->saferp.rounds*2][10]) & 255; + ct[11] = b[11] ^ skey->saferp.K[skey->saferp.rounds*2][11]; + ct[12] = b[12] ^ skey->saferp.K[skey->saferp.rounds*2][12]; + ct[13] = (b[13] + skey->saferp.K[skey->saferp.rounds*2][13]) & 255; + ct[14] = (b[14] + skey->saferp.K[skey->saferp.rounds*2][14]) & 255; + ct[15] = b[15] ^ skey->saferp.K[skey->saferp.rounds*2][15]; +#ifdef LTC_CLEAN_STACK + zeromem(b, sizeof(b)); +#endif + return CRYPT_OK; +} + +/** + Decrypts a block of text with LTC_SAFER+ + @param ct The input ciphertext (16 bytes) + @param pt The output plaintext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + unsigned char b[16]; + int x; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + /* do eight rounds */ + b[0] = ct[0] ^ skey->saferp.K[skey->saferp.rounds*2][0]; + b[1] = (ct[1] - skey->saferp.K[skey->saferp.rounds*2][1]) & 255; + b[2] = (ct[2] - skey->saferp.K[skey->saferp.rounds*2][2]) & 255; + b[3] = ct[3] ^ skey->saferp.K[skey->saferp.rounds*2][3]; + b[4] = ct[4] ^ skey->saferp.K[skey->saferp.rounds*2][4]; + b[5] = (ct[5] - skey->saferp.K[skey->saferp.rounds*2][5]) & 255; + b[6] = (ct[6] - skey->saferp.K[skey->saferp.rounds*2][6]) & 255; + b[7] = ct[7] ^ skey->saferp.K[skey->saferp.rounds*2][7]; + b[8] = ct[8] ^ skey->saferp.K[skey->saferp.rounds*2][8]; + b[9] = (ct[9] - skey->saferp.K[skey->saferp.rounds*2][9]) & 255; + b[10] = (ct[10] - skey->saferp.K[skey->saferp.rounds*2][10]) & 255; + b[11] = ct[11] ^ skey->saferp.K[skey->saferp.rounds*2][11]; + b[12] = ct[12] ^ skey->saferp.K[skey->saferp.rounds*2][12]; + b[13] = (ct[13] - skey->saferp.K[skey->saferp.rounds*2][13]) & 255; + b[14] = (ct[14] - skey->saferp.K[skey->saferp.rounds*2][14]) & 255; + b[15] = ct[15] ^ skey->saferp.K[skey->saferp.rounds*2][15]; + /* 256-bit key? */ + if (skey->saferp.rounds > 12) { + iLT(b, pt); iROUND(pt, 30); + iLT(pt, b); iROUND(b, 28); + iLT(b, pt); iROUND(pt, 26); + iLT(pt, b); iROUND(b, 24); + } + /* 192-bit key? */ + if (skey->saferp.rounds > 8) { + iLT(b, pt); iROUND(pt, 22); + iLT(pt, b); iROUND(b, 20); + iLT(b, pt); iROUND(pt, 18); + iLT(pt, b); iROUND(b, 16); + } + iLT(b, pt); iROUND(pt, 14); + iLT(pt, b); iROUND(b, 12); + iLT(b, pt); iROUND(pt,10); + iLT(pt, b); iROUND(b, 8); + iLT(b, pt); iROUND(pt,6); + iLT(pt, b); iROUND(b, 4); + iLT(b, pt); iROUND(pt,2); + iLT(pt, b); iROUND(b, 0); + for (x = 0; x < 16; x++) { + pt[x] = b[x]; + } +#ifdef LTC_CLEAN_STACK + zeromem(b, sizeof(b)); +#endif + return CRYPT_OK; +} + +/** + Performs a self-test of the LTC_SAFER+ block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int saferp_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen; + unsigned char key[32], pt[16], ct[16]; + } tests[] = { + { + 16, + { 41, 35, 190, 132, 225, 108, 214, 174, + 82, 144, 73, 241, 241, 187, 233, 235 }, + { 179, 166, 219, 60, 135, 12, 62, 153, + 36, 94, 13, 28, 6, 183, 71, 222 }, + { 224, 31, 182, 10, 12, 255, 84, 70, + 127, 13, 89, 249, 9, 57, 165, 220 } + }, { + 24, + { 72, 211, 143, 117, 230, 217, 29, 42, + 229, 192, 247, 43, 120, 129, 135, 68, + 14, 95, 80, 0, 212, 97, 141, 190 }, + { 123, 5, 21, 7, 59, 51, 130, 31, + 24, 112, 146, 218, 100, 84, 206, 177 }, + { 92, 136, 4, 63, 57, 95, 100, 0, + 150, 130, 130, 16, 193, 111, 219, 133 } + }, { + 32, + { 243, 168, 141, 254, 190, 242, 235, 113, + 255, 160, 208, 59, 117, 6, 140, 126, + 135, 120, 115, 77, 208, 190, 130, 190, + 219, 194, 70, 65, 43, 140, 250, 48 }, + { 127, 112, 240, 167, 84, 134, 50, 149, + 170, 91, 104, 19, 11, 230, 252, 245 }, + { 88, 11, 25, 36, 172, 229, 202, 213, + 170, 65, 105, 153, 220, 104, 153, 138 } + } + }; + + unsigned char tmp[2][16]; + symmetric_key skey; + int err, i, y; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + if ((err = saferp_setup(tests[i].key, tests[i].keylen, 0, &skey)) != CRYPT_OK) { + return err; + } + saferp_ecb_encrypt(tests[i].pt, tmp[0], &skey); + saferp_ecb_decrypt(tmp[0], tmp[1], &skey); + + /* compare */ + if (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 16; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) saferp_ecb_encrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 1000; y++) saferp_ecb_decrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; + #endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void saferp_done(symmetric_key *skey) +{ +} + +/** + Gets suitable key size + @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. + @return CRYPT_OK if the input key size is acceptable. +*/ +int saferp_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + + if (*keysize < 16) + return CRYPT_INVALID_KEYSIZE; + if (*keysize < 24) { + *keysize = 16; + } else if (*keysize < 32) { + *keysize = 24; + } else { + *keysize = 32; + } + return CRYPT_OK; +} + +#endif + + + +/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/safer/saferp.c,v $ */ +/* $Revision: 1.14 $ */ +/* $Date: 2007/05/12 14:20:27 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/skipjack.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/skipjack.c new file mode 100644 index 0000000000..2d87fb23b4 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/skipjack.c @@ -0,0 +1,343 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file skipjack.c + Skipjack Implementation by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_SKIPJACK + +const struct ltc_cipher_descriptor skipjack_desc = +{ + "skipjack", + 17, + 10, 10, 8, 32, + &skipjack_setup, + &skipjack_ecb_encrypt, + &skipjack_ecb_decrypt, + &skipjack_test, + &skipjack_done, + &skipjack_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +static const unsigned char sbox[256] = { + 0xa3,0xd7,0x09,0x83,0xf8,0x48,0xf6,0xf4,0xb3,0x21,0x15,0x78,0x99,0xb1,0xaf,0xf9, + 0xe7,0x2d,0x4d,0x8a,0xce,0x4c,0xca,0x2e,0x52,0x95,0xd9,0x1e,0x4e,0x38,0x44,0x28, + 0x0a,0xdf,0x02,0xa0,0x17,0xf1,0x60,0x68,0x12,0xb7,0x7a,0xc3,0xe9,0xfa,0x3d,0x53, + 0x96,0x84,0x6b,0xba,0xf2,0x63,0x9a,0x19,0x7c,0xae,0xe5,0xf5,0xf7,0x16,0x6a,0xa2, + 0x39,0xb6,0x7b,0x0f,0xc1,0x93,0x81,0x1b,0xee,0xb4,0x1a,0xea,0xd0,0x91,0x2f,0xb8, + 0x55,0xb9,0xda,0x85,0x3f,0x41,0xbf,0xe0,0x5a,0x58,0x80,0x5f,0x66,0x0b,0xd8,0x90, + 0x35,0xd5,0xc0,0xa7,0x33,0x06,0x65,0x69,0x45,0x00,0x94,0x56,0x6d,0x98,0x9b,0x76, + 0x97,0xfc,0xb2,0xc2,0xb0,0xfe,0xdb,0x20,0xe1,0xeb,0xd6,0xe4,0xdd,0x47,0x4a,0x1d, + 0x42,0xed,0x9e,0x6e,0x49,0x3c,0xcd,0x43,0x27,0xd2,0x07,0xd4,0xde,0xc7,0x67,0x18, + 0x89,0xcb,0x30,0x1f,0x8d,0xc6,0x8f,0xaa,0xc8,0x74,0xdc,0xc9,0x5d,0x5c,0x31,0xa4, + 0x70,0x88,0x61,0x2c,0x9f,0x0d,0x2b,0x87,0x50,0x82,0x54,0x64,0x26,0x7d,0x03,0x40, + 0x34,0x4b,0x1c,0x73,0xd1,0xc4,0xfd,0x3b,0xcc,0xfb,0x7f,0xab,0xe6,0x3e,0x5b,0xa5, + 0xad,0x04,0x23,0x9c,0x14,0x51,0x22,0xf0,0x29,0x79,0x71,0x7e,0xff,0x8c,0x0e,0xe2, + 0x0c,0xef,0xbc,0x72,0x75,0x6f,0x37,0xa1,0xec,0xd3,0x8e,0x62,0x8b,0x86,0x10,0xe8, + 0x08,0x77,0x11,0xbe,0x92,0x4f,0x24,0xc5,0x32,0x36,0x9d,0xcf,0xf3,0xa6,0xbb,0xac, + 0x5e,0x6c,0xa9,0x13,0x57,0x25,0xb5,0xe3,0xbd,0xa8,0x3a,0x01,0x05,0x59,0x2a,0x46 +}; + +/* simple x + 1 (mod 10) in one step. */ +static const int keystep[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; + +/* simple x - 1 (mod 10) in one step */ +static const int ikeystep[] = { 9, 0, 1, 2, 3, 4, 5, 6, 7, 8 }; + + /** + Initialize the Skipjack block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int x; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (keylen != 10) { + return CRYPT_INVALID_KEYSIZE; + } + + if (num_rounds != 32 && num_rounds != 0) { + return CRYPT_INVALID_ROUNDS; + } + + /* make sure the key is in range for platforms where CHAR_BIT != 8 */ + for (x = 0; x < 10; x++) { + skey->skipjack.key[x] = key[x] & 255; + } + + return CRYPT_OK; +} + +#define RULE_A \ + tmp = g_func(w1, &kp, skey->skipjack.key); \ + w1 = tmp ^ w4 ^ x; \ + w4 = w3; w3 = w2; \ + w2 = tmp; + +#define RULE_B \ + tmp = g_func(w1, &kp, skey->skipjack.key); \ + tmp1 = w4; w4 = w3; \ + w3 = w1 ^ w2 ^ x; \ + w1 = tmp1; w2 = tmp; + +#define RULE_A1 \ + tmp = w1 ^ w2 ^ x; \ + w1 = ig_func(w2, &kp, skey->skipjack.key); \ + w2 = w3; w3 = w4; w4 = tmp; + +#define RULE_B1 \ + tmp = ig_func(w2, &kp, skey->skipjack.key); \ + w2 = tmp ^ w3 ^ x; \ + w3 = w4; w4 = w1; w1 = tmp; + +static unsigned g_func(unsigned w, int *kp, unsigned char *key) +{ + unsigned char g1,g2; + + g1 = (w >> 8) & 255; g2 = w & 255; + g1 ^= sbox[g2^key[*kp]]; *kp = keystep[*kp]; + g2 ^= sbox[g1^key[*kp]]; *kp = keystep[*kp]; + g1 ^= sbox[g2^key[*kp]]; *kp = keystep[*kp]; + g2 ^= sbox[g1^key[*kp]]; *kp = keystep[*kp]; + return ((unsigned)g1<<8)|(unsigned)g2; +} + +static unsigned ig_func(unsigned w, int *kp, unsigned char *key) +{ + unsigned char g1,g2; + + g1 = (w >> 8) & 255; g2 = w & 255; + *kp = ikeystep[*kp]; g2 ^= sbox[g1^key[*kp]]; + *kp = ikeystep[*kp]; g1 ^= sbox[g2^key[*kp]]; + *kp = ikeystep[*kp]; g2 ^= sbox[g1^key[*kp]]; + *kp = ikeystep[*kp]; g1 ^= sbox[g2^key[*kp]]; + return ((unsigned)g1<<8)|(unsigned)g2; +} + +/** + Encrypts a block of text with Skipjack + @param pt The input plaintext (8 bytes) + @param ct The output ciphertext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#else +int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#endif +{ + unsigned w1,w2,w3,w4,tmp,tmp1; + int x, kp; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + /* load block */ + w1 = ((unsigned)pt[0]<<8)|pt[1]; + w2 = ((unsigned)pt[2]<<8)|pt[3]; + w3 = ((unsigned)pt[4]<<8)|pt[5]; + w4 = ((unsigned)pt[6]<<8)|pt[7]; + + /* 8 rounds of RULE A */ + for (x = 1, kp = 0; x < 9; x++) { + RULE_A; + } + + /* 8 rounds of RULE B */ + for (; x < 17; x++) { + RULE_B; + } + + /* 8 rounds of RULE A */ + for (; x < 25; x++) { + RULE_A; + } + + /* 8 rounds of RULE B */ + for (; x < 33; x++) { + RULE_B; + } + + /* store block */ + ct[0] = (w1>>8)&255; ct[1] = w1&255; + ct[2] = (w2>>8)&255; ct[3] = w2&255; + ct[4] = (w3>>8)&255; ct[5] = w3&255; + ct[6] = (w4>>8)&255; ct[7] = w4&255; + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + int err = _skipjack_ecb_encrypt(pt, ct, skey); + burn_stack(sizeof(unsigned) * 8 + sizeof(int) * 2); + return err; +} +#endif + +/** + Decrypts a block of text with Skipjack + @param ct The input ciphertext (8 bytes) + @param pt The output plaintext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#else +int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#endif +{ + unsigned w1,w2,w3,w4,tmp; + int x, kp; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + /* load block */ + w1 = ((unsigned)ct[0]<<8)|ct[1]; + w2 = ((unsigned)ct[2]<<8)|ct[3]; + w3 = ((unsigned)ct[4]<<8)|ct[5]; + w4 = ((unsigned)ct[6]<<8)|ct[7]; + + /* 8 rounds of RULE B^-1 + + Note the value "kp = 8" comes from "kp = (32 * 4) mod 10" where 32*4 is 128 which mod 10 is 8 + */ + for (x = 32, kp = 8; x > 24; x--) { + RULE_B1; + } + + /* 8 rounds of RULE A^-1 */ + for (; x > 16; x--) { + RULE_A1; + } + + + /* 8 rounds of RULE B^-1 */ + for (; x > 8; x--) { + RULE_B1; + } + + /* 8 rounds of RULE A^-1 */ + for (; x > 0; x--) { + RULE_A1; + } + + /* store block */ + pt[0] = (w1>>8)&255; pt[1] = w1&255; + pt[2] = (w2>>8)&255; pt[3] = w2&255; + pt[4] = (w3>>8)&255; pt[5] = w3&255; + pt[6] = (w4>>8)&255; pt[7] = w4&255; + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + int err = _skipjack_ecb_decrypt(ct, pt, skey); + burn_stack(sizeof(unsigned) * 7 + sizeof(int) * 2); + return err; +} +#endif + +/** + Performs a self-test of the Skipjack block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int skipjack_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + unsigned char key[10], pt[8], ct[8]; + } tests[] = { + { + { 0x00, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }, + { 0x33, 0x22, 0x11, 0x00, 0xdd, 0xcc, 0xbb, 0xaa }, + { 0x25, 0x87, 0xca, 0xe2, 0x7a, 0x12, 0xd3, 0x00 } + } + }; + unsigned char buf[2][8]; + int x, y, err; + symmetric_key key; + + for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { + /* setup key */ + if ((err = skipjack_setup(tests[x].key, 10, 0, &key)) != CRYPT_OK) { + return err; + } + + /* encrypt and decrypt */ + skipjack_ecb_encrypt(tests[x].pt, buf[0], &key); + skipjack_ecb_decrypt(buf[0], buf[1], &key); + + /* compare */ + if (XMEMCMP(buf[0], tests[x].ct, 8) != 0 || XMEMCMP(buf[1], tests[x].pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) buf[0][y] = 0; + for (y = 0; y < 1000; y++) skipjack_ecb_encrypt(buf[0], buf[0], &key); + for (y = 0; y < 1000; y++) skipjack_ecb_decrypt(buf[0], buf[0], &key); + for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; + #endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void skipjack_done(symmetric_key *skey) +{ +} + +/** + Gets suitable key size + @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. + @return CRYPT_OK if the input key size is acceptable. +*/ +int skipjack_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize < 10) { + return CRYPT_INVALID_KEYSIZE; + } else if (*keysize > 10) { + *keysize = 10; + } + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/skipjack.c,v $ */ +/* $Revision: 1.14 $ */ +/* $Date: 2007/05/12 14:20:27 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/twofish/twofish.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/twofish/twofish.c new file mode 100644 index 0000000000..0118e63533 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/twofish/twofish.c @@ -0,0 +1,716 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + + /** + @file twofish.c + Implementation of Twofish by Tom St Denis + */ +#include "tomcrypt.h" + +#ifdef LTC_TWOFISH + +/* first LTC_TWOFISH_ALL_TABLES must ensure LTC_TWOFISH_TABLES is defined */ +#ifdef LTC_TWOFISH_ALL_TABLES +#ifndef LTC_TWOFISH_TABLES +#define LTC_TWOFISH_TABLES +#endif +#endif + +const struct ltc_cipher_descriptor twofish_desc = +{ + "twofish", + 7, + 16, 32, 16, 16, + &twofish_setup, + &twofish_ecb_encrypt, + &twofish_ecb_decrypt, + &twofish_test, + &twofish_done, + &twofish_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +/* the two polynomials */ +#define MDS_POLY 0x169 +#define RS_POLY 0x14D + +/* The 4x4 MDS Linear Transform */ +static const unsigned char MDS[4][4] = { + { 0x01, 0xEF, 0x5B, 0x5B }, + { 0x5B, 0xEF, 0xEF, 0x01 }, + { 0xEF, 0x5B, 0x01, 0xEF }, + { 0xEF, 0x01, 0xEF, 0x5B } +}; + +/* The 4x8 RS Linear Transform */ +static const unsigned char RS[4][8] = { + { 0x01, 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E }, + { 0xA4, 0x56, 0x82, 0xF3, 0X1E, 0XC6, 0X68, 0XE5 }, + { 0X02, 0XA1, 0XFC, 0XC1, 0X47, 0XAE, 0X3D, 0X19 }, + { 0XA4, 0X55, 0X87, 0X5A, 0X58, 0XDB, 0X9E, 0X03 } +}; + +/* sbox usage orderings */ +static const unsigned char qord[4][5] = { + { 1, 1, 0, 0, 1 }, + { 0, 1, 1, 0, 0 }, + { 0, 0, 0, 1, 1 }, + { 1, 0, 1, 1, 0 } +}; + +#ifdef LTC_TWOFISH_TABLES + +#include "twofish_tab.c" + +#define sbox(i, x) ((ulong32)SBOX[i][(x)&255]) + +#else + +/* The Q-box tables */ +static const unsigned char qbox[2][4][16] = { +{ + { 0x8, 0x1, 0x7, 0xD, 0x6, 0xF, 0x3, 0x2, 0x0, 0xB, 0x5, 0x9, 0xE, 0xC, 0xA, 0x4 }, + { 0xE, 0XC, 0XB, 0X8, 0X1, 0X2, 0X3, 0X5, 0XF, 0X4, 0XA, 0X6, 0X7, 0X0, 0X9, 0XD }, + { 0XB, 0XA, 0X5, 0XE, 0X6, 0XD, 0X9, 0X0, 0XC, 0X8, 0XF, 0X3, 0X2, 0X4, 0X7, 0X1 }, + { 0XD, 0X7, 0XF, 0X4, 0X1, 0X2, 0X6, 0XE, 0X9, 0XB, 0X3, 0X0, 0X8, 0X5, 0XC, 0XA } +}, +{ + { 0X2, 0X8, 0XB, 0XD, 0XF, 0X7, 0X6, 0XE, 0X3, 0X1, 0X9, 0X4, 0X0, 0XA, 0XC, 0X5 }, + { 0X1, 0XE, 0X2, 0XB, 0X4, 0XC, 0X3, 0X7, 0X6, 0XD, 0XA, 0X5, 0XF, 0X9, 0X0, 0X8 }, + { 0X4, 0XC, 0X7, 0X5, 0X1, 0X6, 0X9, 0XA, 0X0, 0XE, 0XD, 0X8, 0X2, 0XB, 0X3, 0XF }, + { 0xB, 0X9, 0X5, 0X1, 0XC, 0X3, 0XD, 0XE, 0X6, 0X4, 0X7, 0XF, 0X2, 0X0, 0X8, 0XA } +} +}; + +/* computes S_i[x] */ +#ifdef LTC_CLEAN_STACK +static ulong32 _sbox(int i, ulong32 x) +#else +static ulong32 sbox(int i, ulong32 x) +#endif +{ + unsigned char a0,b0,a1,b1,a2,b2,a3,b3,a4,b4,y; + + /* a0,b0 = [x/16], x mod 16 */ + a0 = (unsigned char)((x>>4)&15); + b0 = (unsigned char)((x)&15); + + /* a1 = a0 ^ b0 */ + a1 = a0 ^ b0; + + /* b1 = a0 ^ ROR(b0, 1) ^ 8a0 */ + b1 = (a0 ^ ((b0<<3)|(b0>>1)) ^ (a0<<3)) & 15; + + /* a2,b2 = t0[a1], t1[b1] */ + a2 = qbox[i][0][(int)a1]; + b2 = qbox[i][1][(int)b1]; + + /* a3 = a2 ^ b2 */ + a3 = a2 ^ b2; + + /* b3 = a2 ^ ROR(b2, 1) ^ 8a2 */ + b3 = (a2 ^ ((b2<<3)|(b2>>1)) ^ (a2<<3)) & 15; + + /* a4,b4 = t2[a3], t3[b3] */ + a4 = qbox[i][2][(int)a3]; + b4 = qbox[i][3][(int)b3]; + + /* y = 16b4 + a4 */ + y = (b4 << 4) + a4; + + /* return result */ + return (ulong32)y; +} + +#ifdef LTC_CLEAN_STACK +static ulong32 sbox(int i, ulong32 x) +{ + ulong32 y; + y = _sbox(i, x); + burn_stack(sizeof(unsigned char) * 11); + return y; +} +#endif /* LTC_CLEAN_STACK */ + +#endif /* LTC_TWOFISH_TABLES */ + +/* computes ab mod p */ +static ulong32 gf_mult(ulong32 a, ulong32 b, ulong32 p) +{ + ulong32 result, B[2], P[2]; + + P[1] = p; + B[1] = b; + result = P[0] = B[0] = 0; + + /* unrolled branchless GF multiplier */ + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; + + return result; +} + +/* computes [y0 y1 y2 y3] = MDS . [x0] */ +#ifndef LTC_TWOFISH_TABLES +static ulong32 mds_column_mult(unsigned char in, int col) +{ + ulong32 x01, x5B, xEF; + + x01 = in; + x5B = gf_mult(in, 0x5B, MDS_POLY); + xEF = gf_mult(in, 0xEF, MDS_POLY); + + switch (col) { + case 0: + return (x01 << 0 ) | + (x5B << 8 ) | + (xEF << 16) | + (xEF << 24); + case 1: + return (xEF << 0 ) | + (xEF << 8 ) | + (x5B << 16) | + (x01 << 24); + case 2: + return (x5B << 0 ) | + (xEF << 8 ) | + (x01 << 16) | + (xEF << 24); + case 3: + return (x5B << 0 ) | + (x01 << 8 ) | + (xEF << 16) | + (x5B << 24); + } + /* avoid warnings, we'd never get here normally but just to calm compiler warnings... */ + return 0; +} + +#else /* !LTC_TWOFISH_TABLES */ + +#define mds_column_mult(x, i) mds_tab[i][x] + +#endif /* LTC_TWOFISH_TABLES */ + +/* Computes [y0 y1 y2 y3] = MDS . [x0 x1 x2 x3] */ +static void mds_mult(const unsigned char *in, unsigned char *out) +{ + int x; + ulong32 tmp; + for (tmp = x = 0; x < 4; x++) { + tmp ^= mds_column_mult(in[x], x); + } + STORE32L(tmp, out); +} + +#ifdef LTC_TWOFISH_ALL_TABLES +/* computes [y0 y1 y2 y3] = RS . [x0 x1 x2 x3 x4 x5 x6 x7] */ +static void rs_mult(const unsigned char *in, unsigned char *out) +{ + ulong32 tmp; + tmp = rs_tab0[in[0]] ^ rs_tab1[in[1]] ^ rs_tab2[in[2]] ^ rs_tab3[in[3]] ^ + rs_tab4[in[4]] ^ rs_tab5[in[5]] ^ rs_tab6[in[6]] ^ rs_tab7[in[7]]; + STORE32L(tmp, out); +} + +#else /* !LTC_TWOFISH_ALL_TABLES */ + +/* computes [y0 y1 y2 y3] = RS . [x0 x1 x2 x3 x4 x5 x6 x7] */ +static void rs_mult(const unsigned char *in, unsigned char *out) +{ + int x, y; + for (x = 0; x < 4; x++) { + out[x] = 0; + for (y = 0; y < 8; y++) { + out[x] ^= gf_mult(in[y], RS[x][y], RS_POLY); + } + } +} + +#endif + +/* computes h(x) */ +static void h_func(const unsigned char *in, unsigned char *out, unsigned char *M, int k, int offset) +{ + int x; + unsigned char y[4]; + for (x = 0; x < 4; x++) { + y[x] = in[x]; + } + switch (k) { + case 4: + y[0] = (unsigned char)(sbox(1, (ulong32)y[0]) ^ M[4 * (6 + offset) + 0]); + y[1] = (unsigned char)(sbox(0, (ulong32)y[1]) ^ M[4 * (6 + offset) + 1]); + y[2] = (unsigned char)(sbox(0, (ulong32)y[2]) ^ M[4 * (6 + offset) + 2]); + y[3] = (unsigned char)(sbox(1, (ulong32)y[3]) ^ M[4 * (6 + offset) + 3]); + case 3: + y[0] = (unsigned char)(sbox(1, (ulong32)y[0]) ^ M[4 * (4 + offset) + 0]); + y[1] = (unsigned char)(sbox(1, (ulong32)y[1]) ^ M[4 * (4 + offset) + 1]); + y[2] = (unsigned char)(sbox(0, (ulong32)y[2]) ^ M[4 * (4 + offset) + 2]); + y[3] = (unsigned char)(sbox(0, (ulong32)y[3]) ^ M[4 * (4 + offset) + 3]); + case 2: + y[0] = (unsigned char)(sbox(1, sbox(0, sbox(0, (ulong32)y[0]) ^ M[4 * (2 + offset) + 0]) ^ M[4 * (0 + offset) + 0])); + y[1] = (unsigned char)(sbox(0, sbox(0, sbox(1, (ulong32)y[1]) ^ M[4 * (2 + offset) + 1]) ^ M[4 * (0 + offset) + 1])); + y[2] = (unsigned char)(sbox(1, sbox(1, sbox(0, (ulong32)y[2]) ^ M[4 * (2 + offset) + 2]) ^ M[4 * (0 + offset) + 2])); + y[3] = (unsigned char)(sbox(0, sbox(1, sbox(1, (ulong32)y[3]) ^ M[4 * (2 + offset) + 3]) ^ M[4 * (0 + offset) + 3])); + } + mds_mult(y, out); +} + +#ifndef LTC_TWOFISH_SMALL + +/* for GCC we don't use pointer aliases */ +#if defined(__GNUC__) + #define S1 skey->twofish.S[0] + #define S2 skey->twofish.S[1] + #define S3 skey->twofish.S[2] + #define S4 skey->twofish.S[3] +#endif + +/* the G function */ +#define g_func(x, dum) (S1[byte(x,0)] ^ S2[byte(x,1)] ^ S3[byte(x,2)] ^ S4[byte(x,3)]) +#define g1_func(x, dum) (S2[byte(x,0)] ^ S3[byte(x,1)] ^ S4[byte(x,2)] ^ S1[byte(x,3)]) + +#else + +#ifdef LTC_CLEAN_STACK +static ulong32 _g_func(ulong32 x, symmetric_key *key) +#else +static ulong32 g_func(ulong32 x, symmetric_key *key) +#endif +{ + unsigned char g, i, y, z; + ulong32 res; + + res = 0; + for (y = 0; y < 4; y++) { + z = key->twofish.start; + + /* do unkeyed substitution */ + g = sbox(qord[y][z++], (x >> (8*y)) & 255); + + /* first subkey */ + i = 0; + + /* do key mixing+sbox until z==5 */ + while (z != 5) { + g = g ^ key->twofish.S[4*i++ + y]; + g = sbox(qord[y][z++], g); + } + + /* multiply g by a column of the MDS */ + res ^= mds_column_mult(g, y); + } + return res; +} + +#define g1_func(x, key) g_func(ROLc(x, 8), key) + +#ifdef LTC_CLEAN_STACK +static ulong32 g_func(ulong32 x, symmetric_key *key) +{ + ulong32 y; + y = _g_func(x, key); + burn_stack(sizeof(unsigned char) * 4 + sizeof(ulong32)); + return y; +} +#endif /* LTC_CLEAN_STACK */ + +#endif /* LTC_TWOFISH_SMALL */ + + /** + Initialize the Twofish block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +#ifdef LTC_CLEAN_STACK +static int _twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#else +int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#endif +{ +#ifndef LTC_TWOFISH_SMALL + unsigned char S[4*4], tmpx0, tmpx1; +#endif + int k, x, y; + unsigned char tmp[4], tmp2[4], M[8*4]; + ulong32 A, B; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + /* invalid arguments? */ + if (num_rounds != 16 && num_rounds != 0) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 16 && keylen != 24 && keylen != 32) { + return CRYPT_INVALID_KEYSIZE; + } + + /* k = keysize/64 [but since our keysize is in bytes...] */ + k = keylen / 8; + + /* copy the key into M */ + for (x = 0; x < keylen; x++) { + M[x] = key[x] & 255; + } + + /* create the S[..] words */ +#ifndef LTC_TWOFISH_SMALL + for (x = 0; x < k; x++) { + rs_mult(M+(x*8), S+(x*4)); + } +#else + for (x = 0; x < k; x++) { + rs_mult(M+(x*8), skey->twofish.S+(x*4)); + } +#endif + + /* make subkeys */ + for (x = 0; x < 20; x++) { + /* A = h(p * 2x, Me) */ + for (y = 0; y < 4; y++) { + tmp[y] = x+x; + } + h_func(tmp, tmp2, M, k, 0); + LOAD32L(A, tmp2); + + /* B = ROL(h(p * (2x + 1), Mo), 8) */ + for (y = 0; y < 4; y++) { + tmp[y] = (unsigned char)(x+x+1); + } + h_func(tmp, tmp2, M, k, 1); + LOAD32L(B, tmp2); + B = ROLc(B, 8); + + /* K[2i] = A + B */ + skey->twofish.K[x+x] = (A + B) & 0xFFFFFFFFUL; + + /* K[2i+1] = (A + 2B) <<< 9 */ + skey->twofish.K[x+x+1] = ROLc(B + B + A, 9); + } + +#ifndef LTC_TWOFISH_SMALL + /* make the sboxes (large ram variant) */ + if (k == 2) { + for (x = 0; x < 256; x++) { + tmpx0 = (unsigned char)sbox(0, x); + tmpx1 = (unsigned char)sbox(1, x); + skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, tmpx0 ^ S[0]) ^ S[4])),0); + skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, tmpx1 ^ S[1]) ^ S[5])),1); + skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, tmpx0 ^ S[2]) ^ S[6])),2); + skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, tmpx1 ^ S[3]) ^ S[7])),3); + } + } else if (k == 3) { + for (x = 0; x < 256; x++) { + tmpx0 = (unsigned char)sbox(0, x); + tmpx1 = (unsigned char)sbox(1, x); + skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, tmpx1 ^ S[0]) ^ S[4]) ^ S[8])),0); + skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, tmpx1 ^ S[1]) ^ S[5]) ^ S[9])),1); + skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10])),2); + skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, tmpx0 ^ S[3]) ^ S[7]) ^ S[11])),3); + } + } else { + for (x = 0; x < 256; x++) { + tmpx0 = (unsigned char)sbox(0, x); + tmpx1 = (unsigned char)sbox(1, x); + skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, sbox(1, tmpx1 ^ S[0]) ^ S[4]) ^ S[8]) ^ S[12])),0); + skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, sbox(1, tmpx0 ^ S[1]) ^ S[5]) ^ S[9]) ^ S[13])),1); + skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10]) ^ S[14])),2); + skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, sbox(0, tmpx1 ^ S[3]) ^ S[7]) ^ S[11]) ^ S[15])),3); + } + } +#else + /* where to start in the sbox layers */ + /* small ram variant */ + switch (k) { + case 4 : skey->twofish.start = 0; break; + case 3 : skey->twofish.start = 1; break; + default: skey->twofish.start = 2; break; + } +#endif + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int x; + x = _twofish_setup(key, keylen, num_rounds, skey); + burn_stack(sizeof(int) * 7 + sizeof(unsigned char) * 56 + sizeof(ulong32) * 2); + return x; +} +#endif + +/** + Encrypts a block of text with Twofish + @param pt The input plaintext (16 bytes) + @param ct The output ciphertext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#else +int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#endif +{ + ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; + int r; +#if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__) + ulong32 *S1, *S2, *S3, *S4; +#endif + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + +#if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__) + S1 = skey->twofish.S[0]; + S2 = skey->twofish.S[1]; + S3 = skey->twofish.S[2]; + S4 = skey->twofish.S[3]; +#endif + + LOAD32L(a,&pt[0]); LOAD32L(b,&pt[4]); + LOAD32L(c,&pt[8]); LOAD32L(d,&pt[12]); + a ^= skey->twofish.K[0]; + b ^= skey->twofish.K[1]; + c ^= skey->twofish.K[2]; + d ^= skey->twofish.K[3]; + + k = skey->twofish.K + 8; + for (r = 8; r != 0; --r) { + t2 = g1_func(b, skey); + t1 = g_func(a, skey) + t2; + c = RORc(c ^ (t1 + k[0]), 1); + d = ROLc(d, 1) ^ (t2 + t1 + k[1]); + + t2 = g1_func(d, skey); + t1 = g_func(c, skey) + t2; + a = RORc(a ^ (t1 + k[2]), 1); + b = ROLc(b, 1) ^ (t2 + t1 + k[3]); + k += 4; + } + + /* output with "undo last swap" */ + ta = c ^ skey->twofish.K[4]; + tb = d ^ skey->twofish.K[5]; + tc = a ^ skey->twofish.K[6]; + td = b ^ skey->twofish.K[7]; + + /* store output */ + STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]); + STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]); + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + int err = _twofish_ecb_encrypt(pt, ct, skey); + burn_stack(sizeof(ulong32) * 10 + sizeof(int)); + return err; +} +#endif + +/** + Decrypts a block of text with Twofish + @param ct The input ciphertext (16 bytes) + @param pt The output plaintext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#else +int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#endif +{ + ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; + int r; +#if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__) + ulong32 *S1, *S2, *S3, *S4; +#endif + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + +#if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__) + S1 = skey->twofish.S[0]; + S2 = skey->twofish.S[1]; + S3 = skey->twofish.S[2]; + S4 = skey->twofish.S[3]; +#endif + + /* load input */ + LOAD32L(ta,&ct[0]); LOAD32L(tb,&ct[4]); + LOAD32L(tc,&ct[8]); LOAD32L(td,&ct[12]); + + /* undo undo final swap */ + a = tc ^ skey->twofish.K[6]; + b = td ^ skey->twofish.K[7]; + c = ta ^ skey->twofish.K[4]; + d = tb ^ skey->twofish.K[5]; + + k = skey->twofish.K + 36; + for (r = 8; r != 0; --r) { + t2 = g1_func(d, skey); + t1 = g_func(c, skey) + t2; + a = ROLc(a, 1) ^ (t1 + k[2]); + b = RORc(b ^ (t2 + t1 + k[3]), 1); + + t2 = g1_func(b, skey); + t1 = g_func(a, skey) + t2; + c = ROLc(c, 1) ^ (t1 + k[0]); + d = RORc(d ^ (t2 + t1 + k[1]), 1); + k -= 4; + } + + /* pre-white */ + a ^= skey->twofish.K[0]; + b ^= skey->twofish.K[1]; + c ^= skey->twofish.K[2]; + d ^= skey->twofish.K[3]; + + /* store */ + STORE32L(a, &pt[0]); STORE32L(b, &pt[4]); + STORE32L(c, &pt[8]); STORE32L(d, &pt[12]); + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + int err =_twofish_ecb_decrypt(ct, pt, skey); + burn_stack(sizeof(ulong32) * 10 + sizeof(int)); + return err; +} +#endif + +/** + Performs a self-test of the Twofish block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int twofish_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen; + unsigned char key[32], pt[16], ct[16]; + } tests[] = { + { 16, + { 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32, + 0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A }, + { 0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E, + 0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19 }, + { 0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85, + 0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3 } + }, { + 24, + { 0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36, + 0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88, + 0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44 }, + { 0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5, + 0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2 }, + { 0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45, + 0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65 } + }, { + 32, + { 0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46, + 0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D, + 0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B, + 0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F }, + { 0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F, + 0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6 }, + { 0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97, + 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA } + } +}; + + + symmetric_key key; + unsigned char tmp[2][16]; + int err, i, y; + + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { + if ((err = twofish_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { + return err; + } + twofish_ecb_encrypt(tests[i].pt, tmp[0], &key); + twofish_ecb_decrypt(tmp[0], tmp[1], &key); + if (XMEMCMP(tmp[0], tests[i].ct, 16) != 0 || XMEMCMP(tmp[1], tests[i].pt, 16) != 0) { +#if 0 + printf("Twofish failed test %d, %d, %d\n", i, XMEMCMP(tmp[0], tests[i].ct, 16), XMEMCMP(tmp[1], tests[i].pt, 16)); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 16; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) twofish_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) twofish_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; +#endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void twofish_done(symmetric_key *skey) +{ +} + +/** + Gets suitable key size + @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. + @return CRYPT_OK if the input key size is acceptable. +*/ +int twofish_keysize(int *keysize) +{ + LTC_ARGCHK(keysize); + if (*keysize < 16) + return CRYPT_INVALID_KEYSIZE; + if (*keysize < 24) { + *keysize = 16; + return CRYPT_OK; + } else if (*keysize < 32) { + *keysize = 24; + return CRYPT_OK; + } else { + *keysize = 32; + return CRYPT_OK; + } +} + +#endif + + + + +/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/twofish/twofish.c,v $ */ +/* $Revision: 1.16 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/twofish/twofish_tab.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/twofish/twofish_tab.c new file mode 100644 index 0000000000..1d801910b5 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/twofish/twofish_tab.c @@ -0,0 +1,496 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + + /** + @file twofish_tab.c + Twofish tables, Tom St Denis + */ +#ifdef LTC_TWOFISH_TABLES + +/* pre generated 8x8 tables from the four 4x4s */ +static const unsigned char SBOX[2][256] = { +{ + 0xa9, 0x67, 0xb3, 0xe8, 0x04, 0xfd, 0xa3, 0x76, 0x9a, 0x92, + 0x80, 0x78, 0xe4, 0xdd, 0xd1, 0x38, 0x0d, 0xc6, 0x35, 0x98, + 0x18, 0xf7, 0xec, 0x6c, 0x43, 0x75, 0x37, 0x26, 0xfa, 0x13, + 0x94, 0x48, 0xf2, 0xd0, 0x8b, 0x30, 0x84, 0x54, 0xdf, 0x23, + 0x19, 0x5b, 0x3d, 0x59, 0xf3, 0xae, 0xa2, 0x82, 0x63, 0x01, + 0x83, 0x2e, 0xd9, 0x51, 0x9b, 0x7c, 0xa6, 0xeb, 0xa5, 0xbe, + 0x16, 0x0c, 0xe3, 0x61, 0xc0, 0x8c, 0x3a, 0xf5, 0x73, 0x2c, + 0x25, 0x0b, 0xbb, 0x4e, 0x89, 0x6b, 0x53, 0x6a, 0xb4, 0xf1, + 0xe1, 0xe6, 0xbd, 0x45, 0xe2, 0xf4, 0xb6, 0x66, 0xcc, 0x95, + 0x03, 0x56, 0xd4, 0x1c, 0x1e, 0xd7, 0xfb, 0xc3, 0x8e, 0xb5, + 0xe9, 0xcf, 0xbf, 0xba, 0xea, 0x77, 0x39, 0xaf, 0x33, 0xc9, + 0x62, 0x71, 0x81, 0x79, 0x09, 0xad, 0x24, 0xcd, 0xf9, 0xd8, + 0xe5, 0xc5, 0xb9, 0x4d, 0x44, 0x08, 0x86, 0xe7, 0xa1, 0x1d, + 0xaa, 0xed, 0x06, 0x70, 0xb2, 0xd2, 0x41, 0x7b, 0xa0, 0x11, + 0x31, 0xc2, 0x27, 0x90, 0x20, 0xf6, 0x60, 0xff, 0x96, 0x5c, + 0xb1, 0xab, 0x9e, 0x9c, 0x52, 0x1b, 0x5f, 0x93, 0x0a, 0xef, + 0x91, 0x85, 0x49, 0xee, 0x2d, 0x4f, 0x8f, 0x3b, 0x47, 0x87, + 0x6d, 0x46, 0xd6, 0x3e, 0x69, 0x64, 0x2a, 0xce, 0xcb, 0x2f, + 0xfc, 0x97, 0x05, 0x7a, 0xac, 0x7f, 0xd5, 0x1a, 0x4b, 0x0e, + 0xa7, 0x5a, 0x28, 0x14, 0x3f, 0x29, 0x88, 0x3c, 0x4c, 0x02, + 0xb8, 0xda, 0xb0, 0x17, 0x55, 0x1f, 0x8a, 0x7d, 0x57, 0xc7, + 0x8d, 0x74, 0xb7, 0xc4, 0x9f, 0x72, 0x7e, 0x15, 0x22, 0x12, + 0x58, 0x07, 0x99, 0x34, 0x6e, 0x50, 0xde, 0x68, 0x65, 0xbc, + 0xdb, 0xf8, 0xc8, 0xa8, 0x2b, 0x40, 0xdc, 0xfe, 0x32, 0xa4, + 0xca, 0x10, 0x21, 0xf0, 0xd3, 0x5d, 0x0f, 0x00, 0x6f, 0x9d, + 0x36, 0x42, 0x4a, 0x5e, 0xc1, 0xe0}, +{ + 0x75, 0xf3, 0xc6, 0xf4, 0xdb, 0x7b, 0xfb, 0xc8, 0x4a, 0xd3, + 0xe6, 0x6b, 0x45, 0x7d, 0xe8, 0x4b, 0xd6, 0x32, 0xd8, 0xfd, + 0x37, 0x71, 0xf1, 0xe1, 0x30, 0x0f, 0xf8, 0x1b, 0x87, 0xfa, + 0x06, 0x3f, 0x5e, 0xba, 0xae, 0x5b, 0x8a, 0x00, 0xbc, 0x9d, + 0x6d, 0xc1, 0xb1, 0x0e, 0x80, 0x5d, 0xd2, 0xd5, 0xa0, 0x84, + 0x07, 0x14, 0xb5, 0x90, 0x2c, 0xa3, 0xb2, 0x73, 0x4c, 0x54, + 0x92, 0x74, 0x36, 0x51, 0x38, 0xb0, 0xbd, 0x5a, 0xfc, 0x60, + 0x62, 0x96, 0x6c, 0x42, 0xf7, 0x10, 0x7c, 0x28, 0x27, 0x8c, + 0x13, 0x95, 0x9c, 0xc7, 0x24, 0x46, 0x3b, 0x70, 0xca, 0xe3, + 0x85, 0xcb, 0x11, 0xd0, 0x93, 0xb8, 0xa6, 0x83, 0x20, 0xff, + 0x9f, 0x77, 0xc3, 0xcc, 0x03, 0x6f, 0x08, 0xbf, 0x40, 0xe7, + 0x2b, 0xe2, 0x79, 0x0c, 0xaa, 0x82, 0x41, 0x3a, 0xea, 0xb9, + 0xe4, 0x9a, 0xa4, 0x97, 0x7e, 0xda, 0x7a, 0x17, 0x66, 0x94, + 0xa1, 0x1d, 0x3d, 0xf0, 0xde, 0xb3, 0x0b, 0x72, 0xa7, 0x1c, + 0xef, 0xd1, 0x53, 0x3e, 0x8f, 0x33, 0x26, 0x5f, 0xec, 0x76, + 0x2a, 0x49, 0x81, 0x88, 0xee, 0x21, 0xc4, 0x1a, 0xeb, 0xd9, + 0xc5, 0x39, 0x99, 0xcd, 0xad, 0x31, 0x8b, 0x01, 0x18, 0x23, + 0xdd, 0x1f, 0x4e, 0x2d, 0xf9, 0x48, 0x4f, 0xf2, 0x65, 0x8e, + 0x78, 0x5c, 0x58, 0x19, 0x8d, 0xe5, 0x98, 0x57, 0x67, 0x7f, + 0x05, 0x64, 0xaf, 0x63, 0xb6, 0xfe, 0xf5, 0xb7, 0x3c, 0xa5, + 0xce, 0xe9, 0x68, 0x44, 0xe0, 0x4d, 0x43, 0x69, 0x29, 0x2e, + 0xac, 0x15, 0x59, 0xa8, 0x0a, 0x9e, 0x6e, 0x47, 0xdf, 0x34, + 0x35, 0x6a, 0xcf, 0xdc, 0x22, 0xc9, 0xc0, 0x9b, 0x89, 0xd4, + 0xed, 0xab, 0x12, 0xa2, 0x0d, 0x52, 0xbb, 0x02, 0x2f, 0xa9, + 0xd7, 0x61, 0x1e, 0xb4, 0x50, 0x04, 0xf6, 0xc2, 0x16, 0x25, + 0x86, 0x56, 0x55, 0x09, 0xbe, 0x91} +}; + +/* the 4x4 MDS in a nicer format */ +static const ulong32 mds_tab[4][256] = { +{ +0x00000000UL, 0xefef5b01UL, 0xb7b7b602UL, 0x5858ed03UL, 0x07070504UL, 0xe8e85e05UL, 0xb0b0b306UL, 0x5f5fe807UL, +0x0e0e0a08UL, 0xe1e15109UL, 0xb9b9bc0aUL, 0x5656e70bUL, 0x09090f0cUL, 0xe6e6540dUL, 0xbebeb90eUL, 0x5151e20fUL, +0x1c1c1410UL, 0xf3f34f11UL, 0xababa212UL, 0x4444f913UL, 0x1b1b1114UL, 0xf4f44a15UL, 0xacaca716UL, 0x4343fc17UL, +0x12121e18UL, 0xfdfd4519UL, 0xa5a5a81aUL, 0x4a4af31bUL, 0x15151b1cUL, 0xfafa401dUL, 0xa2a2ad1eUL, 0x4d4df61fUL, +0x38382820UL, 0xd7d77321UL, 0x8f8f9e22UL, 0x6060c523UL, 0x3f3f2d24UL, 0xd0d07625UL, 0x88889b26UL, 0x6767c027UL, +0x36362228UL, 0xd9d97929UL, 0x8181942aUL, 0x6e6ecf2bUL, 0x3131272cUL, 0xdede7c2dUL, 0x8686912eUL, 0x6969ca2fUL, +0x24243c30UL, 0xcbcb6731UL, 0x93938a32UL, 0x7c7cd133UL, 0x23233934UL, 0xcccc6235UL, 0x94948f36UL, 0x7b7bd437UL, +0x2a2a3638UL, 0xc5c56d39UL, 0x9d9d803aUL, 0x7272db3bUL, 0x2d2d333cUL, 0xc2c2683dUL, 0x9a9a853eUL, 0x7575de3fUL, +0x70705040UL, 0x9f9f0b41UL, 0xc7c7e642UL, 0x2828bd43UL, 0x77775544UL, 0x98980e45UL, 0xc0c0e346UL, 0x2f2fb847UL, +0x7e7e5a48UL, 0x91910149UL, 0xc9c9ec4aUL, 0x2626b74bUL, 0x79795f4cUL, 0x9696044dUL, 0xcecee94eUL, 0x2121b24fUL, +0x6c6c4450UL, 0x83831f51UL, 0xdbdbf252UL, 0x3434a953UL, 0x6b6b4154UL, 0x84841a55UL, 0xdcdcf756UL, 0x3333ac57UL, +0x62624e58UL, 0x8d8d1559UL, 0xd5d5f85aUL, 0x3a3aa35bUL, 0x65654b5cUL, 0x8a8a105dUL, 0xd2d2fd5eUL, 0x3d3da65fUL, +0x48487860UL, 0xa7a72361UL, 0xffffce62UL, 0x10109563UL, 0x4f4f7d64UL, 0xa0a02665UL, 0xf8f8cb66UL, 0x17179067UL, +0x46467268UL, 0xa9a92969UL, 0xf1f1c46aUL, 0x1e1e9f6bUL, 0x4141776cUL, 0xaeae2c6dUL, 0xf6f6c16eUL, 0x19199a6fUL, +0x54546c70UL, 0xbbbb3771UL, 0xe3e3da72UL, 0x0c0c8173UL, 0x53536974UL, 0xbcbc3275UL, 0xe4e4df76UL, 0x0b0b8477UL, +0x5a5a6678UL, 0xb5b53d79UL, 0xededd07aUL, 0x02028b7bUL, 0x5d5d637cUL, 0xb2b2387dUL, 0xeaead57eUL, 0x05058e7fUL, +0xe0e0a080UL, 0x0f0ffb81UL, 0x57571682UL, 0xb8b84d83UL, 0xe7e7a584UL, 0x0808fe85UL, 0x50501386UL, 0xbfbf4887UL, +0xeeeeaa88UL, 0x0101f189UL, 0x59591c8aUL, 0xb6b6478bUL, 0xe9e9af8cUL, 0x0606f48dUL, 0x5e5e198eUL, 0xb1b1428fUL, +0xfcfcb490UL, 0x1313ef91UL, 0x4b4b0292UL, 0xa4a45993UL, 0xfbfbb194UL, 0x1414ea95UL, 0x4c4c0796UL, 0xa3a35c97UL, +0xf2f2be98UL, 0x1d1de599UL, 0x4545089aUL, 0xaaaa539bUL, 0xf5f5bb9cUL, 0x1a1ae09dUL, 0x42420d9eUL, 0xadad569fUL, +0xd8d888a0UL, 0x3737d3a1UL, 0x6f6f3ea2UL, 0x808065a3UL, 0xdfdf8da4UL, 0x3030d6a5UL, 0x68683ba6UL, 0x878760a7UL, +0xd6d682a8UL, 0x3939d9a9UL, 0x616134aaUL, 0x8e8e6fabUL, 0xd1d187acUL, 0x3e3edcadUL, 0x666631aeUL, 0x89896aafUL, +0xc4c49cb0UL, 0x2b2bc7b1UL, 0x73732ab2UL, 0x9c9c71b3UL, 0xc3c399b4UL, 0x2c2cc2b5UL, 0x74742fb6UL, 0x9b9b74b7UL, +0xcaca96b8UL, 0x2525cdb9UL, 0x7d7d20baUL, 0x92927bbbUL, 0xcdcd93bcUL, 0x2222c8bdUL, 0x7a7a25beUL, 0x95957ebfUL, +0x9090f0c0UL, 0x7f7fabc1UL, 0x272746c2UL, 0xc8c81dc3UL, 0x9797f5c4UL, 0x7878aec5UL, 0x202043c6UL, 0xcfcf18c7UL, +0x9e9efac8UL, 0x7171a1c9UL, 0x29294ccaUL, 0xc6c617cbUL, 0x9999ffccUL, 0x7676a4cdUL, 0x2e2e49ceUL, 0xc1c112cfUL, +0x8c8ce4d0UL, 0x6363bfd1UL, 0x3b3b52d2UL, 0xd4d409d3UL, 0x8b8be1d4UL, 0x6464bad5UL, 0x3c3c57d6UL, 0xd3d30cd7UL, +0x8282eed8UL, 0x6d6db5d9UL, 0x353558daUL, 0xdada03dbUL, 0x8585ebdcUL, 0x6a6ab0ddUL, 0x32325ddeUL, 0xdddd06dfUL, +0xa8a8d8e0UL, 0x474783e1UL, 0x1f1f6ee2UL, 0xf0f035e3UL, 0xafafdde4UL, 0x404086e5UL, 0x18186be6UL, 0xf7f730e7UL, +0xa6a6d2e8UL, 0x494989e9UL, 0x111164eaUL, 0xfefe3febUL, 0xa1a1d7ecUL, 0x4e4e8cedUL, 0x161661eeUL, 0xf9f93aefUL, +0xb4b4ccf0UL, 0x5b5b97f1UL, 0x03037af2UL, 0xecec21f3UL, 0xb3b3c9f4UL, 0x5c5c92f5UL, 0x04047ff6UL, 0xebeb24f7UL, +0xbabac6f8UL, 0x55559df9UL, 0x0d0d70faUL, 0xe2e22bfbUL, 0xbdbdc3fcUL, 0x525298fdUL, 0x0a0a75feUL, 0xe5e52effUL +}, +{ +0x00000000UL, 0x015befefUL, 0x02b6b7b7UL, 0x03ed5858UL, 0x04050707UL, 0x055ee8e8UL, 0x06b3b0b0UL, 0x07e85f5fUL, +0x080a0e0eUL, 0x0951e1e1UL, 0x0abcb9b9UL, 0x0be75656UL, 0x0c0f0909UL, 0x0d54e6e6UL, 0x0eb9bebeUL, 0x0fe25151UL, +0x10141c1cUL, 0x114ff3f3UL, 0x12a2ababUL, 0x13f94444UL, 0x14111b1bUL, 0x154af4f4UL, 0x16a7acacUL, 0x17fc4343UL, +0x181e1212UL, 0x1945fdfdUL, 0x1aa8a5a5UL, 0x1bf34a4aUL, 0x1c1b1515UL, 0x1d40fafaUL, 0x1eada2a2UL, 0x1ff64d4dUL, +0x20283838UL, 0x2173d7d7UL, 0x229e8f8fUL, 0x23c56060UL, 0x242d3f3fUL, 0x2576d0d0UL, 0x269b8888UL, 0x27c06767UL, +0x28223636UL, 0x2979d9d9UL, 0x2a948181UL, 0x2bcf6e6eUL, 0x2c273131UL, 0x2d7cdedeUL, 0x2e918686UL, 0x2fca6969UL, +0x303c2424UL, 0x3167cbcbUL, 0x328a9393UL, 0x33d17c7cUL, 0x34392323UL, 0x3562ccccUL, 0x368f9494UL, 0x37d47b7bUL, +0x38362a2aUL, 0x396dc5c5UL, 0x3a809d9dUL, 0x3bdb7272UL, 0x3c332d2dUL, 0x3d68c2c2UL, 0x3e859a9aUL, 0x3fde7575UL, +0x40507070UL, 0x410b9f9fUL, 0x42e6c7c7UL, 0x43bd2828UL, 0x44557777UL, 0x450e9898UL, 0x46e3c0c0UL, 0x47b82f2fUL, +0x485a7e7eUL, 0x49019191UL, 0x4aecc9c9UL, 0x4bb72626UL, 0x4c5f7979UL, 0x4d049696UL, 0x4ee9ceceUL, 0x4fb22121UL, +0x50446c6cUL, 0x511f8383UL, 0x52f2dbdbUL, 0x53a93434UL, 0x54416b6bUL, 0x551a8484UL, 0x56f7dcdcUL, 0x57ac3333UL, +0x584e6262UL, 0x59158d8dUL, 0x5af8d5d5UL, 0x5ba33a3aUL, 0x5c4b6565UL, 0x5d108a8aUL, 0x5efdd2d2UL, 0x5fa63d3dUL, +0x60784848UL, 0x6123a7a7UL, 0x62ceffffUL, 0x63951010UL, 0x647d4f4fUL, 0x6526a0a0UL, 0x66cbf8f8UL, 0x67901717UL, +0x68724646UL, 0x6929a9a9UL, 0x6ac4f1f1UL, 0x6b9f1e1eUL, 0x6c774141UL, 0x6d2caeaeUL, 0x6ec1f6f6UL, 0x6f9a1919UL, +0x706c5454UL, 0x7137bbbbUL, 0x72dae3e3UL, 0x73810c0cUL, 0x74695353UL, 0x7532bcbcUL, 0x76dfe4e4UL, 0x77840b0bUL, +0x78665a5aUL, 0x793db5b5UL, 0x7ad0ededUL, 0x7b8b0202UL, 0x7c635d5dUL, 0x7d38b2b2UL, 0x7ed5eaeaUL, 0x7f8e0505UL, +0x80a0e0e0UL, 0x81fb0f0fUL, 0x82165757UL, 0x834db8b8UL, 0x84a5e7e7UL, 0x85fe0808UL, 0x86135050UL, 0x8748bfbfUL, +0x88aaeeeeUL, 0x89f10101UL, 0x8a1c5959UL, 0x8b47b6b6UL, 0x8cafe9e9UL, 0x8df40606UL, 0x8e195e5eUL, 0x8f42b1b1UL, +0x90b4fcfcUL, 0x91ef1313UL, 0x92024b4bUL, 0x9359a4a4UL, 0x94b1fbfbUL, 0x95ea1414UL, 0x96074c4cUL, 0x975ca3a3UL, +0x98bef2f2UL, 0x99e51d1dUL, 0x9a084545UL, 0x9b53aaaaUL, 0x9cbbf5f5UL, 0x9de01a1aUL, 0x9e0d4242UL, 0x9f56adadUL, +0xa088d8d8UL, 0xa1d33737UL, 0xa23e6f6fUL, 0xa3658080UL, 0xa48ddfdfUL, 0xa5d63030UL, 0xa63b6868UL, 0xa7608787UL, +0xa882d6d6UL, 0xa9d93939UL, 0xaa346161UL, 0xab6f8e8eUL, 0xac87d1d1UL, 0xaddc3e3eUL, 0xae316666UL, 0xaf6a8989UL, +0xb09cc4c4UL, 0xb1c72b2bUL, 0xb22a7373UL, 0xb3719c9cUL, 0xb499c3c3UL, 0xb5c22c2cUL, 0xb62f7474UL, 0xb7749b9bUL, +0xb896cacaUL, 0xb9cd2525UL, 0xba207d7dUL, 0xbb7b9292UL, 0xbc93cdcdUL, 0xbdc82222UL, 0xbe257a7aUL, 0xbf7e9595UL, +0xc0f09090UL, 0xc1ab7f7fUL, 0xc2462727UL, 0xc31dc8c8UL, 0xc4f59797UL, 0xc5ae7878UL, 0xc6432020UL, 0xc718cfcfUL, +0xc8fa9e9eUL, 0xc9a17171UL, 0xca4c2929UL, 0xcb17c6c6UL, 0xccff9999UL, 0xcda47676UL, 0xce492e2eUL, 0xcf12c1c1UL, +0xd0e48c8cUL, 0xd1bf6363UL, 0xd2523b3bUL, 0xd309d4d4UL, 0xd4e18b8bUL, 0xd5ba6464UL, 0xd6573c3cUL, 0xd70cd3d3UL, +0xd8ee8282UL, 0xd9b56d6dUL, 0xda583535UL, 0xdb03dadaUL, 0xdceb8585UL, 0xddb06a6aUL, 0xde5d3232UL, 0xdf06ddddUL, +0xe0d8a8a8UL, 0xe1834747UL, 0xe26e1f1fUL, 0xe335f0f0UL, 0xe4ddafafUL, 0xe5864040UL, 0xe66b1818UL, 0xe730f7f7UL, +0xe8d2a6a6UL, 0xe9894949UL, 0xea641111UL, 0xeb3ffefeUL, 0xecd7a1a1UL, 0xed8c4e4eUL, 0xee611616UL, 0xef3af9f9UL, +0xf0ccb4b4UL, 0xf1975b5bUL, 0xf27a0303UL, 0xf321ececUL, 0xf4c9b3b3UL, 0xf5925c5cUL, 0xf67f0404UL, 0xf724ebebUL, +0xf8c6babaUL, 0xf99d5555UL, 0xfa700d0dUL, 0xfb2be2e2UL, 0xfcc3bdbdUL, 0xfd985252UL, 0xfe750a0aUL, 0xff2ee5e5UL +}, +{ +0x00000000UL, 0xef01ef5bUL, 0xb702b7b6UL, 0x580358edUL, 0x07040705UL, 0xe805e85eUL, 0xb006b0b3UL, 0x5f075fe8UL, +0x0e080e0aUL, 0xe109e151UL, 0xb90ab9bcUL, 0x560b56e7UL, 0x090c090fUL, 0xe60de654UL, 0xbe0ebeb9UL, 0x510f51e2UL, +0x1c101c14UL, 0xf311f34fUL, 0xab12aba2UL, 0x441344f9UL, 0x1b141b11UL, 0xf415f44aUL, 0xac16aca7UL, 0x431743fcUL, +0x1218121eUL, 0xfd19fd45UL, 0xa51aa5a8UL, 0x4a1b4af3UL, 0x151c151bUL, 0xfa1dfa40UL, 0xa21ea2adUL, 0x4d1f4df6UL, +0x38203828UL, 0xd721d773UL, 0x8f228f9eUL, 0x602360c5UL, 0x3f243f2dUL, 0xd025d076UL, 0x8826889bUL, 0x672767c0UL, +0x36283622UL, 0xd929d979UL, 0x812a8194UL, 0x6e2b6ecfUL, 0x312c3127UL, 0xde2dde7cUL, 0x862e8691UL, 0x692f69caUL, +0x2430243cUL, 0xcb31cb67UL, 0x9332938aUL, 0x7c337cd1UL, 0x23342339UL, 0xcc35cc62UL, 0x9436948fUL, 0x7b377bd4UL, +0x2a382a36UL, 0xc539c56dUL, 0x9d3a9d80UL, 0x723b72dbUL, 0x2d3c2d33UL, 0xc23dc268UL, 0x9a3e9a85UL, 0x753f75deUL, +0x70407050UL, 0x9f419f0bUL, 0xc742c7e6UL, 0x284328bdUL, 0x77447755UL, 0x9845980eUL, 0xc046c0e3UL, 0x2f472fb8UL, +0x7e487e5aUL, 0x91499101UL, 0xc94ac9ecUL, 0x264b26b7UL, 0x794c795fUL, 0x964d9604UL, 0xce4ecee9UL, 0x214f21b2UL, +0x6c506c44UL, 0x8351831fUL, 0xdb52dbf2UL, 0x345334a9UL, 0x6b546b41UL, 0x8455841aUL, 0xdc56dcf7UL, 0x335733acUL, +0x6258624eUL, 0x8d598d15UL, 0xd55ad5f8UL, 0x3a5b3aa3UL, 0x655c654bUL, 0x8a5d8a10UL, 0xd25ed2fdUL, 0x3d5f3da6UL, +0x48604878UL, 0xa761a723UL, 0xff62ffceUL, 0x10631095UL, 0x4f644f7dUL, 0xa065a026UL, 0xf866f8cbUL, 0x17671790UL, +0x46684672UL, 0xa969a929UL, 0xf16af1c4UL, 0x1e6b1e9fUL, 0x416c4177UL, 0xae6dae2cUL, 0xf66ef6c1UL, 0x196f199aUL, +0x5470546cUL, 0xbb71bb37UL, 0xe372e3daUL, 0x0c730c81UL, 0x53745369UL, 0xbc75bc32UL, 0xe476e4dfUL, 0x0b770b84UL, +0x5a785a66UL, 0xb579b53dUL, 0xed7aedd0UL, 0x027b028bUL, 0x5d7c5d63UL, 0xb27db238UL, 0xea7eead5UL, 0x057f058eUL, +0xe080e0a0UL, 0x0f810ffbUL, 0x57825716UL, 0xb883b84dUL, 0xe784e7a5UL, 0x088508feUL, 0x50865013UL, 0xbf87bf48UL, +0xee88eeaaUL, 0x018901f1UL, 0x598a591cUL, 0xb68bb647UL, 0xe98ce9afUL, 0x068d06f4UL, 0x5e8e5e19UL, 0xb18fb142UL, +0xfc90fcb4UL, 0x139113efUL, 0x4b924b02UL, 0xa493a459UL, 0xfb94fbb1UL, 0x149514eaUL, 0x4c964c07UL, 0xa397a35cUL, +0xf298f2beUL, 0x1d991de5UL, 0x459a4508UL, 0xaa9baa53UL, 0xf59cf5bbUL, 0x1a9d1ae0UL, 0x429e420dUL, 0xad9fad56UL, +0xd8a0d888UL, 0x37a137d3UL, 0x6fa26f3eUL, 0x80a38065UL, 0xdfa4df8dUL, 0x30a530d6UL, 0x68a6683bUL, 0x87a78760UL, +0xd6a8d682UL, 0x39a939d9UL, 0x61aa6134UL, 0x8eab8e6fUL, 0xd1acd187UL, 0x3ead3edcUL, 0x66ae6631UL, 0x89af896aUL, +0xc4b0c49cUL, 0x2bb12bc7UL, 0x73b2732aUL, 0x9cb39c71UL, 0xc3b4c399UL, 0x2cb52cc2UL, 0x74b6742fUL, 0x9bb79b74UL, +0xcab8ca96UL, 0x25b925cdUL, 0x7dba7d20UL, 0x92bb927bUL, 0xcdbccd93UL, 0x22bd22c8UL, 0x7abe7a25UL, 0x95bf957eUL, +0x90c090f0UL, 0x7fc17fabUL, 0x27c22746UL, 0xc8c3c81dUL, 0x97c497f5UL, 0x78c578aeUL, 0x20c62043UL, 0xcfc7cf18UL, +0x9ec89efaUL, 0x71c971a1UL, 0x29ca294cUL, 0xc6cbc617UL, 0x99cc99ffUL, 0x76cd76a4UL, 0x2ece2e49UL, 0xc1cfc112UL, +0x8cd08ce4UL, 0x63d163bfUL, 0x3bd23b52UL, 0xd4d3d409UL, 0x8bd48be1UL, 0x64d564baUL, 0x3cd63c57UL, 0xd3d7d30cUL, +0x82d882eeUL, 0x6dd96db5UL, 0x35da3558UL, 0xdadbda03UL, 0x85dc85ebUL, 0x6add6ab0UL, 0x32de325dUL, 0xdddfdd06UL, +0xa8e0a8d8UL, 0x47e14783UL, 0x1fe21f6eUL, 0xf0e3f035UL, 0xafe4afddUL, 0x40e54086UL, 0x18e6186bUL, 0xf7e7f730UL, +0xa6e8a6d2UL, 0x49e94989UL, 0x11ea1164UL, 0xfeebfe3fUL, 0xa1eca1d7UL, 0x4eed4e8cUL, 0x16ee1661UL, 0xf9eff93aUL, +0xb4f0b4ccUL, 0x5bf15b97UL, 0x03f2037aUL, 0xecf3ec21UL, 0xb3f4b3c9UL, 0x5cf55c92UL, 0x04f6047fUL, 0xebf7eb24UL, +0xbaf8bac6UL, 0x55f9559dUL, 0x0dfa0d70UL, 0xe2fbe22bUL, 0xbdfcbdc3UL, 0x52fd5298UL, 0x0afe0a75UL, 0xe5ffe52eUL +}, +{ +0x00000000UL, 0x5bef015bUL, 0xb6b702b6UL, 0xed5803edUL, 0x05070405UL, 0x5ee8055eUL, 0xb3b006b3UL, 0xe85f07e8UL, +0x0a0e080aUL, 0x51e10951UL, 0xbcb90abcUL, 0xe7560be7UL, 0x0f090c0fUL, 0x54e60d54UL, 0xb9be0eb9UL, 0xe2510fe2UL, +0x141c1014UL, 0x4ff3114fUL, 0xa2ab12a2UL, 0xf94413f9UL, 0x111b1411UL, 0x4af4154aUL, 0xa7ac16a7UL, 0xfc4317fcUL, +0x1e12181eUL, 0x45fd1945UL, 0xa8a51aa8UL, 0xf34a1bf3UL, 0x1b151c1bUL, 0x40fa1d40UL, 0xada21eadUL, 0xf64d1ff6UL, +0x28382028UL, 0x73d72173UL, 0x9e8f229eUL, 0xc56023c5UL, 0x2d3f242dUL, 0x76d02576UL, 0x9b88269bUL, 0xc06727c0UL, +0x22362822UL, 0x79d92979UL, 0x94812a94UL, 0xcf6e2bcfUL, 0x27312c27UL, 0x7cde2d7cUL, 0x91862e91UL, 0xca692fcaUL, +0x3c24303cUL, 0x67cb3167UL, 0x8a93328aUL, 0xd17c33d1UL, 0x39233439UL, 0x62cc3562UL, 0x8f94368fUL, 0xd47b37d4UL, +0x362a3836UL, 0x6dc5396dUL, 0x809d3a80UL, 0xdb723bdbUL, 0x332d3c33UL, 0x68c23d68UL, 0x859a3e85UL, 0xde753fdeUL, +0x50704050UL, 0x0b9f410bUL, 0xe6c742e6UL, 0xbd2843bdUL, 0x55774455UL, 0x0e98450eUL, 0xe3c046e3UL, 0xb82f47b8UL, +0x5a7e485aUL, 0x01914901UL, 0xecc94aecUL, 0xb7264bb7UL, 0x5f794c5fUL, 0x04964d04UL, 0xe9ce4ee9UL, 0xb2214fb2UL, +0x446c5044UL, 0x1f83511fUL, 0xf2db52f2UL, 0xa93453a9UL, 0x416b5441UL, 0x1a84551aUL, 0xf7dc56f7UL, 0xac3357acUL, +0x4e62584eUL, 0x158d5915UL, 0xf8d55af8UL, 0xa33a5ba3UL, 0x4b655c4bUL, 0x108a5d10UL, 0xfdd25efdUL, 0xa63d5fa6UL, +0x78486078UL, 0x23a76123UL, 0xceff62ceUL, 0x95106395UL, 0x7d4f647dUL, 0x26a06526UL, 0xcbf866cbUL, 0x90176790UL, +0x72466872UL, 0x29a96929UL, 0xc4f16ac4UL, 0x9f1e6b9fUL, 0x77416c77UL, 0x2cae6d2cUL, 0xc1f66ec1UL, 0x9a196f9aUL, +0x6c54706cUL, 0x37bb7137UL, 0xdae372daUL, 0x810c7381UL, 0x69537469UL, 0x32bc7532UL, 0xdfe476dfUL, 0x840b7784UL, +0x665a7866UL, 0x3db5793dUL, 0xd0ed7ad0UL, 0x8b027b8bUL, 0x635d7c63UL, 0x38b27d38UL, 0xd5ea7ed5UL, 0x8e057f8eUL, +0xa0e080a0UL, 0xfb0f81fbUL, 0x16578216UL, 0x4db8834dUL, 0xa5e784a5UL, 0xfe0885feUL, 0x13508613UL, 0x48bf8748UL, +0xaaee88aaUL, 0xf10189f1UL, 0x1c598a1cUL, 0x47b68b47UL, 0xafe98cafUL, 0xf4068df4UL, 0x195e8e19UL, 0x42b18f42UL, +0xb4fc90b4UL, 0xef1391efUL, 0x024b9202UL, 0x59a49359UL, 0xb1fb94b1UL, 0xea1495eaUL, 0x074c9607UL, 0x5ca3975cUL, +0xbef298beUL, 0xe51d99e5UL, 0x08459a08UL, 0x53aa9b53UL, 0xbbf59cbbUL, 0xe01a9de0UL, 0x0d429e0dUL, 0x56ad9f56UL, +0x88d8a088UL, 0xd337a1d3UL, 0x3e6fa23eUL, 0x6580a365UL, 0x8ddfa48dUL, 0xd630a5d6UL, 0x3b68a63bUL, 0x6087a760UL, +0x82d6a882UL, 0xd939a9d9UL, 0x3461aa34UL, 0x6f8eab6fUL, 0x87d1ac87UL, 0xdc3eaddcUL, 0x3166ae31UL, 0x6a89af6aUL, +0x9cc4b09cUL, 0xc72bb1c7UL, 0x2a73b22aUL, 0x719cb371UL, 0x99c3b499UL, 0xc22cb5c2UL, 0x2f74b62fUL, 0x749bb774UL, +0x96cab896UL, 0xcd25b9cdUL, 0x207dba20UL, 0x7b92bb7bUL, 0x93cdbc93UL, 0xc822bdc8UL, 0x257abe25UL, 0x7e95bf7eUL, +0xf090c0f0UL, 0xab7fc1abUL, 0x4627c246UL, 0x1dc8c31dUL, 0xf597c4f5UL, 0xae78c5aeUL, 0x4320c643UL, 0x18cfc718UL, +0xfa9ec8faUL, 0xa171c9a1UL, 0x4c29ca4cUL, 0x17c6cb17UL, 0xff99ccffUL, 0xa476cda4UL, 0x492ece49UL, 0x12c1cf12UL, +0xe48cd0e4UL, 0xbf63d1bfUL, 0x523bd252UL, 0x09d4d309UL, 0xe18bd4e1UL, 0xba64d5baUL, 0x573cd657UL, 0x0cd3d70cUL, +0xee82d8eeUL, 0xb56dd9b5UL, 0x5835da58UL, 0x03dadb03UL, 0xeb85dcebUL, 0xb06addb0UL, 0x5d32de5dUL, 0x06dddf06UL, +0xd8a8e0d8UL, 0x8347e183UL, 0x6e1fe26eUL, 0x35f0e335UL, 0xddafe4ddUL, 0x8640e586UL, 0x6b18e66bUL, 0x30f7e730UL, +0xd2a6e8d2UL, 0x8949e989UL, 0x6411ea64UL, 0x3ffeeb3fUL, 0xd7a1ecd7UL, 0x8c4eed8cUL, 0x6116ee61UL, 0x3af9ef3aUL, +0xccb4f0ccUL, 0x975bf197UL, 0x7a03f27aUL, 0x21ecf321UL, 0xc9b3f4c9UL, 0x925cf592UL, 0x7f04f67fUL, 0x24ebf724UL, +0xc6baf8c6UL, 0x9d55f99dUL, 0x700dfa70UL, 0x2be2fb2bUL, 0xc3bdfcc3UL, 0x9852fd98UL, 0x750afe75UL, 0x2ee5ff2eUL +}}; + +#ifdef LTC_TWOFISH_ALL_TABLES + +/* the 4x8 RS transform */ +static const ulong32 rs_tab0[256] = { +0x00000000LU, 0xa402a401LU, 0x05040502LU, 0xa106a103LU, 0x0a080a04LU, 0xae0aae05LU, 0x0f0c0f06LU, 0xab0eab07LU, +0x14101408LU, 0xb012b009LU, 0x1114110aLU, 0xb516b50bLU, 0x1e181e0cLU, 0xba1aba0dLU, 0x1b1c1b0eLU, 0xbf1ebf0fLU, +0x28202810LU, 0x8c228c11LU, 0x2d242d12LU, 0x89268913LU, 0x22282214LU, 0x862a8615LU, 0x272c2716LU, 0x832e8317LU, +0x3c303c18LU, 0x98329819LU, 0x3934391aLU, 0x9d369d1bLU, 0x3638361cLU, 0x923a921dLU, 0x333c331eLU, 0x973e971fLU, +0x50405020LU, 0xf442f421LU, 0x55445522LU, 0xf146f123LU, 0x5a485a24LU, 0xfe4afe25LU, 0x5f4c5f26LU, 0xfb4efb27LU, +0x44504428LU, 0xe052e029LU, 0x4154412aLU, 0xe556e52bLU, 0x4e584e2cLU, 0xea5aea2dLU, 0x4b5c4b2eLU, 0xef5eef2fLU, +0x78607830LU, 0xdc62dc31LU, 0x7d647d32LU, 0xd966d933LU, 0x72687234LU, 0xd66ad635LU, 0x776c7736LU, 0xd36ed337LU, +0x6c706c38LU, 0xc872c839LU, 0x6974693aLU, 0xcd76cd3bLU, 0x6678663cLU, 0xc27ac23dLU, 0x637c633eLU, 0xc77ec73fLU, +0xa080a040LU, 0x04820441LU, 0xa584a542LU, 0x01860143LU, 0xaa88aa44LU, 0x0e8a0e45LU, 0xaf8caf46LU, 0x0b8e0b47LU, +0xb490b448LU, 0x10921049LU, 0xb194b14aLU, 0x1596154bLU, 0xbe98be4cLU, 0x1a9a1a4dLU, 0xbb9cbb4eLU, 0x1f9e1f4fLU, +0x88a08850LU, 0x2ca22c51LU, 0x8da48d52LU, 0x29a62953LU, 0x82a88254LU, 0x26aa2655LU, 0x87ac8756LU, 0x23ae2357LU, +0x9cb09c58LU, 0x38b23859LU, 0x99b4995aLU, 0x3db63d5bLU, 0x96b8965cLU, 0x32ba325dLU, 0x93bc935eLU, 0x37be375fLU, +0xf0c0f060LU, 0x54c25461LU, 0xf5c4f562LU, 0x51c65163LU, 0xfac8fa64LU, 0x5eca5e65LU, 0xffccff66LU, 0x5bce5b67LU, +0xe4d0e468LU, 0x40d24069LU, 0xe1d4e16aLU, 0x45d6456bLU, 0xeed8ee6cLU, 0x4ada4a6dLU, 0xebdceb6eLU, 0x4fde4f6fLU, +0xd8e0d870LU, 0x7ce27c71LU, 0xdde4dd72LU, 0x79e67973LU, 0xd2e8d274LU, 0x76ea7675LU, 0xd7ecd776LU, 0x73ee7377LU, +0xccf0cc78LU, 0x68f26879LU, 0xc9f4c97aLU, 0x6df66d7bLU, 0xc6f8c67cLU, 0x62fa627dLU, 0xc3fcc37eLU, 0x67fe677fLU, +0x0d4d0d80LU, 0xa94fa981LU, 0x08490882LU, 0xac4bac83LU, 0x07450784LU, 0xa347a385LU, 0x02410286LU, 0xa643a687LU, +0x195d1988LU, 0xbd5fbd89LU, 0x1c591c8aLU, 0xb85bb88bLU, 0x1355138cLU, 0xb757b78dLU, 0x1651168eLU, 0xb253b28fLU, +0x256d2590LU, 0x816f8191LU, 0x20692092LU, 0x846b8493LU, 0x2f652f94LU, 0x8b678b95LU, 0x2a612a96LU, 0x8e638e97LU, +0x317d3198LU, 0x957f9599LU, 0x3479349aLU, 0x907b909bLU, 0x3b753b9cLU, 0x9f779f9dLU, 0x3e713e9eLU, 0x9a739a9fLU, +0x5d0d5da0LU, 0xf90ff9a1LU, 0x580958a2LU, 0xfc0bfca3LU, 0x570557a4LU, 0xf307f3a5LU, 0x520152a6LU, 0xf603f6a7LU, +0x491d49a8LU, 0xed1feda9LU, 0x4c194caaLU, 0xe81be8abLU, 0x431543acLU, 0xe717e7adLU, 0x461146aeLU, 0xe213e2afLU, +0x752d75b0LU, 0xd12fd1b1LU, 0x702970b2LU, 0xd42bd4b3LU, 0x7f257fb4LU, 0xdb27dbb5LU, 0x7a217ab6LU, 0xde23deb7LU, +0x613d61b8LU, 0xc53fc5b9LU, 0x643964baLU, 0xc03bc0bbLU, 0x6b356bbcLU, 0xcf37cfbdLU, 0x6e316ebeLU, 0xca33cabfLU, +0xadcdadc0LU, 0x09cf09c1LU, 0xa8c9a8c2LU, 0x0ccb0cc3LU, 0xa7c5a7c4LU, 0x03c703c5LU, 0xa2c1a2c6LU, 0x06c306c7LU, +0xb9ddb9c8LU, 0x1ddf1dc9LU, 0xbcd9bccaLU, 0x18db18cbLU, 0xb3d5b3ccLU, 0x17d717cdLU, 0xb6d1b6ceLU, 0x12d312cfLU, +0x85ed85d0LU, 0x21ef21d1LU, 0x80e980d2LU, 0x24eb24d3LU, 0x8fe58fd4LU, 0x2be72bd5LU, 0x8ae18ad6LU, 0x2ee32ed7LU, +0x91fd91d8LU, 0x35ff35d9LU, 0x94f994daLU, 0x30fb30dbLU, 0x9bf59bdcLU, 0x3ff73fddLU, 0x9ef19edeLU, 0x3af33adfLU, +0xfd8dfde0LU, 0x598f59e1LU, 0xf889f8e2LU, 0x5c8b5ce3LU, 0xf785f7e4LU, 0x538753e5LU, 0xf281f2e6LU, 0x568356e7LU, +0xe99de9e8LU, 0x4d9f4de9LU, 0xec99eceaLU, 0x489b48ebLU, 0xe395e3ecLU, 0x479747edLU, 0xe691e6eeLU, 0x429342efLU, +0xd5add5f0LU, 0x71af71f1LU, 0xd0a9d0f2LU, 0x74ab74f3LU, 0xdfa5dff4LU, 0x7ba77bf5LU, 0xdaa1daf6LU, 0x7ea37ef7LU, +0xc1bdc1f8LU, 0x65bf65f9LU, 0xc4b9c4faLU, 0x60bb60fbLU, 0xcbb5cbfcLU, 0x6fb76ffdLU, 0xceb1cefeLU, 0x6ab36affLU }; + +static const ulong32 rs_tab1[256] = { +0x00000000LU, 0x55a156a4LU, 0xaa0fac05LU, 0xffaefaa1LU, 0x191e150aLU, 0x4cbf43aeLU, 0xb311b90fLU, 0xe6b0efabLU, +0x323c2a14LU, 0x679d7cb0LU, 0x98338611LU, 0xcd92d0b5LU, 0x2b223f1eLU, 0x7e8369baLU, 0x812d931bLU, 0xd48cc5bfLU, +0x64785428LU, 0x31d9028cLU, 0xce77f82dLU, 0x9bd6ae89LU, 0x7d664122LU, 0x28c71786LU, 0xd769ed27LU, 0x82c8bb83LU, +0x56447e3cLU, 0x03e52898LU, 0xfc4bd239LU, 0xa9ea849dLU, 0x4f5a6b36LU, 0x1afb3d92LU, 0xe555c733LU, 0xb0f49197LU, +0xc8f0a850LU, 0x9d51fef4LU, 0x62ff0455LU, 0x375e52f1LU, 0xd1eebd5aLU, 0x844febfeLU, 0x7be1115fLU, 0x2e4047fbLU, +0xfacc8244LU, 0xaf6dd4e0LU, 0x50c32e41LU, 0x056278e5LU, 0xe3d2974eLU, 0xb673c1eaLU, 0x49dd3b4bLU, 0x1c7c6defLU, +0xac88fc78LU, 0xf929aadcLU, 0x0687507dLU, 0x532606d9LU, 0xb596e972LU, 0xe037bfd6LU, 0x1f994577LU, 0x4a3813d3LU, +0x9eb4d66cLU, 0xcb1580c8LU, 0x34bb7a69LU, 0x611a2ccdLU, 0x87aac366LU, 0xd20b95c2LU, 0x2da56f63LU, 0x780439c7LU, +0xddad1da0LU, 0x880c4b04LU, 0x77a2b1a5LU, 0x2203e701LU, 0xc4b308aaLU, 0x91125e0eLU, 0x6ebca4afLU, 0x3b1df20bLU, +0xef9137b4LU, 0xba306110LU, 0x459e9bb1LU, 0x103fcd15LU, 0xf68f22beLU, 0xa32e741aLU, 0x5c808ebbLU, 0x0921d81fLU, +0xb9d54988LU, 0xec741f2cLU, 0x13dae58dLU, 0x467bb329LU, 0xa0cb5c82LU, 0xf56a0a26LU, 0x0ac4f087LU, 0x5f65a623LU, +0x8be9639cLU, 0xde483538LU, 0x21e6cf99LU, 0x7447993dLU, 0x92f77696LU, 0xc7562032LU, 0x38f8da93LU, 0x6d598c37LU, +0x155db5f0LU, 0x40fce354LU, 0xbf5219f5LU, 0xeaf34f51LU, 0x0c43a0faLU, 0x59e2f65eLU, 0xa64c0cffLU, 0xf3ed5a5bLU, +0x27619fe4LU, 0x72c0c940LU, 0x8d6e33e1LU, 0xd8cf6545LU, 0x3e7f8aeeLU, 0x6bdedc4aLU, 0x947026ebLU, 0xc1d1704fLU, +0x7125e1d8LU, 0x2484b77cLU, 0xdb2a4dddLU, 0x8e8b1b79LU, 0x683bf4d2LU, 0x3d9aa276LU, 0xc23458d7LU, 0x97950e73LU, +0x4319cbccLU, 0x16b89d68LU, 0xe91667c9LU, 0xbcb7316dLU, 0x5a07dec6LU, 0x0fa68862LU, 0xf00872c3LU, 0xa5a92467LU, +0xf7173a0dLU, 0xa2b66ca9LU, 0x5d189608LU, 0x08b9c0acLU, 0xee092f07LU, 0xbba879a3LU, 0x44068302LU, 0x11a7d5a6LU, +0xc52b1019LU, 0x908a46bdLU, 0x6f24bc1cLU, 0x3a85eab8LU, 0xdc350513LU, 0x899453b7LU, 0x763aa916LU, 0x239bffb2LU, +0x936f6e25LU, 0xc6ce3881LU, 0x3960c220LU, 0x6cc19484LU, 0x8a717b2fLU, 0xdfd02d8bLU, 0x207ed72aLU, 0x75df818eLU, +0xa1534431LU, 0xf4f21295LU, 0x0b5ce834LU, 0x5efdbe90LU, 0xb84d513bLU, 0xedec079fLU, 0x1242fd3eLU, 0x47e3ab9aLU, +0x3fe7925dLU, 0x6a46c4f9LU, 0x95e83e58LU, 0xc04968fcLU, 0x26f98757LU, 0x7358d1f3LU, 0x8cf62b52LU, 0xd9577df6LU, +0x0ddbb849LU, 0x587aeeedLU, 0xa7d4144cLU, 0xf27542e8LU, 0x14c5ad43LU, 0x4164fbe7LU, 0xbeca0146LU, 0xeb6b57e2LU, +0x5b9fc675LU, 0x0e3e90d1LU, 0xf1906a70LU, 0xa4313cd4LU, 0x4281d37fLU, 0x172085dbLU, 0xe88e7f7aLU, 0xbd2f29deLU, +0x69a3ec61LU, 0x3c02bac5LU, 0xc3ac4064LU, 0x960d16c0LU, 0x70bdf96bLU, 0x251cafcfLU, 0xdab2556eLU, 0x8f1303caLU, +0x2aba27adLU, 0x7f1b7109LU, 0x80b58ba8LU, 0xd514dd0cLU, 0x33a432a7LU, 0x66056403LU, 0x99ab9ea2LU, 0xcc0ac806LU, +0x18860db9LU, 0x4d275b1dLU, 0xb289a1bcLU, 0xe728f718LU, 0x019818b3LU, 0x54394e17LU, 0xab97b4b6LU, 0xfe36e212LU, +0x4ec27385LU, 0x1b632521LU, 0xe4cddf80LU, 0xb16c8924LU, 0x57dc668fLU, 0x027d302bLU, 0xfdd3ca8aLU, 0xa8729c2eLU, +0x7cfe5991LU, 0x295f0f35LU, 0xd6f1f594LU, 0x8350a330LU, 0x65e04c9bLU, 0x30411a3fLU, 0xcfefe09eLU, 0x9a4eb63aLU, +0xe24a8ffdLU, 0xb7ebd959LU, 0x484523f8LU, 0x1de4755cLU, 0xfb549af7LU, 0xaef5cc53LU, 0x515b36f2LU, 0x04fa6056LU, +0xd076a5e9LU, 0x85d7f34dLU, 0x7a7909ecLU, 0x2fd85f48LU, 0xc968b0e3LU, 0x9cc9e647LU, 0x63671ce6LU, 0x36c64a42LU, +0x8632dbd5LU, 0xd3938d71LU, 0x2c3d77d0LU, 0x799c2174LU, 0x9f2ccedfLU, 0xca8d987bLU, 0x352362daLU, 0x6082347eLU, +0xb40ef1c1LU, 0xe1afa765LU, 0x1e015dc4LU, 0x4ba00b60LU, 0xad10e4cbLU, 0xf8b1b26fLU, 0x071f48ceLU, 0x52be1e6aLU }; + +static const ulong32 rs_tab2[256] = { +0x00000000LU, 0x87fc8255LU, 0x43b549aaLU, 0xc449cbffLU, 0x86279219LU, 0x01db104cLU, 0xc592dbb3LU, 0x426e59e6LU, +0x414e6932LU, 0xc6b2eb67LU, 0x02fb2098LU, 0x8507a2cdLU, 0xc769fb2bLU, 0x4095797eLU, 0x84dcb281LU, 0x032030d4LU, +0x829cd264LU, 0x05605031LU, 0xc1299bceLU, 0x46d5199bLU, 0x04bb407dLU, 0x8347c228LU, 0x470e09d7LU, 0xc0f28b82LU, +0xc3d2bb56LU, 0x442e3903LU, 0x8067f2fcLU, 0x079b70a9LU, 0x45f5294fLU, 0xc209ab1aLU, 0x064060e5LU, 0x81bce2b0LU, +0x4975e9c8LU, 0xce896b9dLU, 0x0ac0a062LU, 0x8d3c2237LU, 0xcf527bd1LU, 0x48aef984LU, 0x8ce7327bLU, 0x0b1bb02eLU, +0x083b80faLU, 0x8fc702afLU, 0x4b8ec950LU, 0xcc724b05LU, 0x8e1c12e3LU, 0x09e090b6LU, 0xcda95b49LU, 0x4a55d91cLU, +0xcbe93bacLU, 0x4c15b9f9LU, 0x885c7206LU, 0x0fa0f053LU, 0x4dcea9b5LU, 0xca322be0LU, 0x0e7be01fLU, 0x8987624aLU, +0x8aa7529eLU, 0x0d5bd0cbLU, 0xc9121b34LU, 0x4eee9961LU, 0x0c80c087LU, 0x8b7c42d2LU, 0x4f35892dLU, 0xc8c90b78LU, +0x92ea9fddLU, 0x15161d88LU, 0xd15fd677LU, 0x56a35422LU, 0x14cd0dc4LU, 0x93318f91LU, 0x5778446eLU, 0xd084c63bLU, +0xd3a4f6efLU, 0x545874baLU, 0x9011bf45LU, 0x17ed3d10LU, 0x558364f6LU, 0xd27fe6a3LU, 0x16362d5cLU, 0x91caaf09LU, +0x10764db9LU, 0x978acfecLU, 0x53c30413LU, 0xd43f8646LU, 0x9651dfa0LU, 0x11ad5df5LU, 0xd5e4960aLU, 0x5218145fLU, +0x5138248bLU, 0xd6c4a6deLU, 0x128d6d21LU, 0x9571ef74LU, 0xd71fb692LU, 0x50e334c7LU, 0x94aaff38LU, 0x13567d6dLU, +0xdb9f7615LU, 0x5c63f440LU, 0x982a3fbfLU, 0x1fd6bdeaLU, 0x5db8e40cLU, 0xda446659LU, 0x1e0dada6LU, 0x99f12ff3LU, +0x9ad11f27LU, 0x1d2d9d72LU, 0xd964568dLU, 0x5e98d4d8LU, 0x1cf68d3eLU, 0x9b0a0f6bLU, 0x5f43c494LU, 0xd8bf46c1LU, +0x5903a471LU, 0xdeff2624LU, 0x1ab6eddbLU, 0x9d4a6f8eLU, 0xdf243668LU, 0x58d8b43dLU, 0x9c917fc2LU, 0x1b6dfd97LU, +0x184dcd43LU, 0x9fb14f16LU, 0x5bf884e9LU, 0xdc0406bcLU, 0x9e6a5f5aLU, 0x1996dd0fLU, 0xdddf16f0LU, 0x5a2394a5LU, +0x699973f7LU, 0xee65f1a2LU, 0x2a2c3a5dLU, 0xadd0b808LU, 0xefbee1eeLU, 0x684263bbLU, 0xac0ba844LU, 0x2bf72a11LU, +0x28d71ac5LU, 0xaf2b9890LU, 0x6b62536fLU, 0xec9ed13aLU, 0xaef088dcLU, 0x290c0a89LU, 0xed45c176LU, 0x6ab94323LU, +0xeb05a193LU, 0x6cf923c6LU, 0xa8b0e839LU, 0x2f4c6a6cLU, 0x6d22338aLU, 0xeadeb1dfLU, 0x2e977a20LU, 0xa96bf875LU, +0xaa4bc8a1LU, 0x2db74af4LU, 0xe9fe810bLU, 0x6e02035eLU, 0x2c6c5ab8LU, 0xab90d8edLU, 0x6fd91312LU, 0xe8259147LU, +0x20ec9a3fLU, 0xa710186aLU, 0x6359d395LU, 0xe4a551c0LU, 0xa6cb0826LU, 0x21378a73LU, 0xe57e418cLU, 0x6282c3d9LU, +0x61a2f30dLU, 0xe65e7158LU, 0x2217baa7LU, 0xa5eb38f2LU, 0xe7856114LU, 0x6079e341LU, 0xa43028beLU, 0x23ccaaebLU, +0xa270485bLU, 0x258cca0eLU, 0xe1c501f1LU, 0x663983a4LU, 0x2457da42LU, 0xa3ab5817LU, 0x67e293e8LU, 0xe01e11bdLU, +0xe33e2169LU, 0x64c2a33cLU, 0xa08b68c3LU, 0x2777ea96LU, 0x6519b370LU, 0xe2e53125LU, 0x26acfadaLU, 0xa150788fLU, +0xfb73ec2aLU, 0x7c8f6e7fLU, 0xb8c6a580LU, 0x3f3a27d5LU, 0x7d547e33LU, 0xfaa8fc66LU, 0x3ee13799LU, 0xb91db5ccLU, +0xba3d8518LU, 0x3dc1074dLU, 0xf988ccb2LU, 0x7e744ee7LU, 0x3c1a1701LU, 0xbbe69554LU, 0x7faf5eabLU, 0xf853dcfeLU, +0x79ef3e4eLU, 0xfe13bc1bLU, 0x3a5a77e4LU, 0xbda6f5b1LU, 0xffc8ac57LU, 0x78342e02LU, 0xbc7de5fdLU, 0x3b8167a8LU, +0x38a1577cLU, 0xbf5dd529LU, 0x7b141ed6LU, 0xfce89c83LU, 0xbe86c565LU, 0x397a4730LU, 0xfd338ccfLU, 0x7acf0e9aLU, +0xb20605e2LU, 0x35fa87b7LU, 0xf1b34c48LU, 0x764fce1dLU, 0x342197fbLU, 0xb3dd15aeLU, 0x7794de51LU, 0xf0685c04LU, +0xf3486cd0LU, 0x74b4ee85LU, 0xb0fd257aLU, 0x3701a72fLU, 0x756ffec9LU, 0xf2937c9cLU, 0x36dab763LU, 0xb1263536LU, +0x309ad786LU, 0xb76655d3LU, 0x732f9e2cLU, 0xf4d31c79LU, 0xb6bd459fLU, 0x3141c7caLU, 0xf5080c35LU, 0x72f48e60LU, +0x71d4beb4LU, 0xf6283ce1LU, 0x3261f71eLU, 0xb59d754bLU, 0xf7f32cadLU, 0x700faef8LU, 0xb4466507LU, 0x33bae752LU }; + +static const ulong32 rs_tab3[256] = { +0x00000000LU, 0x5ac1f387LU, 0xb4cfab43LU, 0xee0e58c4LU, 0x25d31b86LU, 0x7f12e801LU, 0x911cb0c5LU, 0xcbdd4342LU, +0x4aeb3641LU, 0x102ac5c6LU, 0xfe249d02LU, 0xa4e56e85LU, 0x6f382dc7LU, 0x35f9de40LU, 0xdbf78684LU, 0x81367503LU, +0x949b6c82LU, 0xce5a9f05LU, 0x2054c7c1LU, 0x7a953446LU, 0xb1487704LU, 0xeb898483LU, 0x0587dc47LU, 0x5f462fc0LU, +0xde705ac3LU, 0x84b1a944LU, 0x6abff180LU, 0x307e0207LU, 0xfba34145LU, 0xa162b2c2LU, 0x4f6cea06LU, 0x15ad1981LU, +0x657bd849LU, 0x3fba2bceLU, 0xd1b4730aLU, 0x8b75808dLU, 0x40a8c3cfLU, 0x1a693048LU, 0xf467688cLU, 0xaea69b0bLU, +0x2f90ee08LU, 0x75511d8fLU, 0x9b5f454bLU, 0xc19eb6ccLU, 0x0a43f58eLU, 0x50820609LU, 0xbe8c5ecdLU, 0xe44dad4aLU, +0xf1e0b4cbLU, 0xab21474cLU, 0x452f1f88LU, 0x1feeec0fLU, 0xd433af4dLU, 0x8ef25ccaLU, 0x60fc040eLU, 0x3a3df789LU, +0xbb0b828aLU, 0xe1ca710dLU, 0x0fc429c9LU, 0x5505da4eLU, 0x9ed8990cLU, 0xc4196a8bLU, 0x2a17324fLU, 0x70d6c1c8LU, +0xcaf6fd92LU, 0x90370e15LU, 0x7e3956d1LU, 0x24f8a556LU, 0xef25e614LU, 0xb5e41593LU, 0x5bea4d57LU, 0x012bbed0LU, +0x801dcbd3LU, 0xdadc3854LU, 0x34d26090LU, 0x6e139317LU, 0xa5ced055LU, 0xff0f23d2LU, 0x11017b16LU, 0x4bc08891LU, +0x5e6d9110LU, 0x04ac6297LU, 0xeaa23a53LU, 0xb063c9d4LU, 0x7bbe8a96LU, 0x217f7911LU, 0xcf7121d5LU, 0x95b0d252LU, +0x1486a751LU, 0x4e4754d6LU, 0xa0490c12LU, 0xfa88ff95LU, 0x3155bcd7LU, 0x6b944f50LU, 0x859a1794LU, 0xdf5be413LU, +0xaf8d25dbLU, 0xf54cd65cLU, 0x1b428e98LU, 0x41837d1fLU, 0x8a5e3e5dLU, 0xd09fcddaLU, 0x3e91951eLU, 0x64506699LU, +0xe566139aLU, 0xbfa7e01dLU, 0x51a9b8d9LU, 0x0b684b5eLU, 0xc0b5081cLU, 0x9a74fb9bLU, 0x747aa35fLU, 0x2ebb50d8LU, +0x3b164959LU, 0x61d7badeLU, 0x8fd9e21aLU, 0xd518119dLU, 0x1ec552dfLU, 0x4404a158LU, 0xaa0af99cLU, 0xf0cb0a1bLU, +0x71fd7f18LU, 0x2b3c8c9fLU, 0xc532d45bLU, 0x9ff327dcLU, 0x542e649eLU, 0x0eef9719LU, 0xe0e1cfddLU, 0xba203c5aLU, +0xd9a1b769LU, 0x836044eeLU, 0x6d6e1c2aLU, 0x37afefadLU, 0xfc72acefLU, 0xa6b35f68LU, 0x48bd07acLU, 0x127cf42bLU, +0x934a8128LU, 0xc98b72afLU, 0x27852a6bLU, 0x7d44d9ecLU, 0xb6999aaeLU, 0xec586929LU, 0x025631edLU, 0x5897c26aLU, +0x4d3adbebLU, 0x17fb286cLU, 0xf9f570a8LU, 0xa334832fLU, 0x68e9c06dLU, 0x322833eaLU, 0xdc266b2eLU, 0x86e798a9LU, +0x07d1edaaLU, 0x5d101e2dLU, 0xb31e46e9LU, 0xe9dfb56eLU, 0x2202f62cLU, 0x78c305abLU, 0x96cd5d6fLU, 0xcc0caee8LU, +0xbcda6f20LU, 0xe61b9ca7LU, 0x0815c463LU, 0x52d437e4LU, 0x990974a6LU, 0xc3c88721LU, 0x2dc6dfe5LU, 0x77072c62LU, +0xf6315961LU, 0xacf0aae6LU, 0x42fef222LU, 0x183f01a5LU, 0xd3e242e7LU, 0x8923b160LU, 0x672de9a4LU, 0x3dec1a23LU, +0x284103a2LU, 0x7280f025LU, 0x9c8ea8e1LU, 0xc64f5b66LU, 0x0d921824LU, 0x5753eba3LU, 0xb95db367LU, 0xe39c40e0LU, +0x62aa35e3LU, 0x386bc664LU, 0xd6659ea0LU, 0x8ca46d27LU, 0x47792e65LU, 0x1db8dde2LU, 0xf3b68526LU, 0xa97776a1LU, +0x13574afbLU, 0x4996b97cLU, 0xa798e1b8LU, 0xfd59123fLU, 0x3684517dLU, 0x6c45a2faLU, 0x824bfa3eLU, 0xd88a09b9LU, +0x59bc7cbaLU, 0x037d8f3dLU, 0xed73d7f9LU, 0xb7b2247eLU, 0x7c6f673cLU, 0x26ae94bbLU, 0xc8a0cc7fLU, 0x92613ff8LU, +0x87cc2679LU, 0xdd0dd5feLU, 0x33038d3aLU, 0x69c27ebdLU, 0xa21f3dffLU, 0xf8dece78LU, 0x16d096bcLU, 0x4c11653bLU, +0xcd271038LU, 0x97e6e3bfLU, 0x79e8bb7bLU, 0x232948fcLU, 0xe8f40bbeLU, 0xb235f839LU, 0x5c3ba0fdLU, 0x06fa537aLU, +0x762c92b2LU, 0x2ced6135LU, 0xc2e339f1LU, 0x9822ca76LU, 0x53ff8934LU, 0x093e7ab3LU, 0xe7302277LU, 0xbdf1d1f0LU, +0x3cc7a4f3LU, 0x66065774LU, 0x88080fb0LU, 0xd2c9fc37LU, 0x1914bf75LU, 0x43d54cf2LU, 0xaddb1436LU, 0xf71ae7b1LU, +0xe2b7fe30LU, 0xb8760db7LU, 0x56785573LU, 0x0cb9a6f4LU, 0xc764e5b6LU, 0x9da51631LU, 0x73ab4ef5LU, 0x296abd72LU, +0xa85cc871LU, 0xf29d3bf6LU, 0x1c936332LU, 0x465290b5LU, 0x8d8fd3f7LU, 0xd74e2070LU, 0x394078b4LU, 0x63818b33LU }; + +static const ulong32 rs_tab4[256] = { +0x00000000LU, 0x58471e5aLU, 0xb08e3cb4LU, 0xe8c922eeLU, 0x2d517825LU, 0x7516667fLU, 0x9ddf4491LU, 0xc5985acbLU, +0x5aa2f04aLU, 0x02e5ee10LU, 0xea2cccfeLU, 0xb26bd2a4LU, 0x77f3886fLU, 0x2fb49635LU, 0xc77db4dbLU, 0x9f3aaa81LU, +0xb409ad94LU, 0xec4eb3ceLU, 0x04879120LU, 0x5cc08f7aLU, 0x9958d5b1LU, 0xc11fcbebLU, 0x29d6e905LU, 0x7191f75fLU, +0xeeab5ddeLU, 0xb6ec4384LU, 0x5e25616aLU, 0x06627f30LU, 0xc3fa25fbLU, 0x9bbd3ba1LU, 0x7374194fLU, 0x2b330715LU, +0x25121765LU, 0x7d55093fLU, 0x959c2bd1LU, 0xcddb358bLU, 0x08436f40LU, 0x5004711aLU, 0xb8cd53f4LU, 0xe08a4daeLU, +0x7fb0e72fLU, 0x27f7f975LU, 0xcf3edb9bLU, 0x9779c5c1LU, 0x52e19f0aLU, 0x0aa68150LU, 0xe26fa3beLU, 0xba28bde4LU, +0x911bbaf1LU, 0xc95ca4abLU, 0x21958645LU, 0x79d2981fLU, 0xbc4ac2d4LU, 0xe40ddc8eLU, 0x0cc4fe60LU, 0x5483e03aLU, +0xcbb94abbLU, 0x93fe54e1LU, 0x7b37760fLU, 0x23706855LU, 0xe6e8329eLU, 0xbeaf2cc4LU, 0x56660e2aLU, 0x0e211070LU, +0x4a242ecaLU, 0x12633090LU, 0xfaaa127eLU, 0xa2ed0c24LU, 0x677556efLU, 0x3f3248b5LU, 0xd7fb6a5bLU, 0x8fbc7401LU, +0x1086de80LU, 0x48c1c0daLU, 0xa008e234LU, 0xf84ffc6eLU, 0x3dd7a6a5LU, 0x6590b8ffLU, 0x8d599a11LU, 0xd51e844bLU, +0xfe2d835eLU, 0xa66a9d04LU, 0x4ea3bfeaLU, 0x16e4a1b0LU, 0xd37cfb7bLU, 0x8b3be521LU, 0x63f2c7cfLU, 0x3bb5d995LU, +0xa48f7314LU, 0xfcc86d4eLU, 0x14014fa0LU, 0x4c4651faLU, 0x89de0b31LU, 0xd199156bLU, 0x39503785LU, 0x611729dfLU, +0x6f3639afLU, 0x377127f5LU, 0xdfb8051bLU, 0x87ff1b41LU, 0x4267418aLU, 0x1a205fd0LU, 0xf2e97d3eLU, 0xaaae6364LU, +0x3594c9e5LU, 0x6dd3d7bfLU, 0x851af551LU, 0xdd5deb0bLU, 0x18c5b1c0LU, 0x4082af9aLU, 0xa84b8d74LU, 0xf00c932eLU, +0xdb3f943bLU, 0x83788a61LU, 0x6bb1a88fLU, 0x33f6b6d5LU, 0xf66eec1eLU, 0xae29f244LU, 0x46e0d0aaLU, 0x1ea7cef0LU, +0x819d6471LU, 0xd9da7a2bLU, 0x311358c5LU, 0x6954469fLU, 0xaccc1c54LU, 0xf48b020eLU, 0x1c4220e0LU, 0x44053ebaLU, +0x94485cd9LU, 0xcc0f4283LU, 0x24c6606dLU, 0x7c817e37LU, 0xb91924fcLU, 0xe15e3aa6LU, 0x09971848LU, 0x51d00612LU, +0xceeaac93LU, 0x96adb2c9LU, 0x7e649027LU, 0x26238e7dLU, 0xe3bbd4b6LU, 0xbbfccaecLU, 0x5335e802LU, 0x0b72f658LU, +0x2041f14dLU, 0x7806ef17LU, 0x90cfcdf9LU, 0xc888d3a3LU, 0x0d108968LU, 0x55579732LU, 0xbd9eb5dcLU, 0xe5d9ab86LU, +0x7ae30107LU, 0x22a41f5dLU, 0xca6d3db3LU, 0x922a23e9LU, 0x57b27922LU, 0x0ff56778LU, 0xe73c4596LU, 0xbf7b5bccLU, +0xb15a4bbcLU, 0xe91d55e6LU, 0x01d47708LU, 0x59936952LU, 0x9c0b3399LU, 0xc44c2dc3LU, 0x2c850f2dLU, 0x74c21177LU, +0xebf8bbf6LU, 0xb3bfa5acLU, 0x5b768742LU, 0x03319918LU, 0xc6a9c3d3LU, 0x9eeedd89LU, 0x7627ff67LU, 0x2e60e13dLU, +0x0553e628LU, 0x5d14f872LU, 0xb5ddda9cLU, 0xed9ac4c6LU, 0x28029e0dLU, 0x70458057LU, 0x988ca2b9LU, 0xc0cbbce3LU, +0x5ff11662LU, 0x07b60838LU, 0xef7f2ad6LU, 0xb738348cLU, 0x72a06e47LU, 0x2ae7701dLU, 0xc22e52f3LU, 0x9a694ca9LU, +0xde6c7213LU, 0x862b6c49LU, 0x6ee24ea7LU, 0x36a550fdLU, 0xf33d0a36LU, 0xab7a146cLU, 0x43b33682LU, 0x1bf428d8LU, +0x84ce8259LU, 0xdc899c03LU, 0x3440beedLU, 0x6c07a0b7LU, 0xa99ffa7cLU, 0xf1d8e426LU, 0x1911c6c8LU, 0x4156d892LU, +0x6a65df87LU, 0x3222c1ddLU, 0xdaebe333LU, 0x82acfd69LU, 0x4734a7a2LU, 0x1f73b9f8LU, 0xf7ba9b16LU, 0xaffd854cLU, +0x30c72fcdLU, 0x68803197LU, 0x80491379LU, 0xd80e0d23LU, 0x1d9657e8LU, 0x45d149b2LU, 0xad186b5cLU, 0xf55f7506LU, +0xfb7e6576LU, 0xa3397b2cLU, 0x4bf059c2LU, 0x13b74798LU, 0xd62f1d53LU, 0x8e680309LU, 0x66a121e7LU, 0x3ee63fbdLU, +0xa1dc953cLU, 0xf99b8b66LU, 0x1152a988LU, 0x4915b7d2LU, 0x8c8ded19LU, 0xd4caf343LU, 0x3c03d1adLU, 0x6444cff7LU, +0x4f77c8e2LU, 0x1730d6b8LU, 0xfff9f456LU, 0xa7beea0cLU, 0x6226b0c7LU, 0x3a61ae9dLU, 0xd2a88c73LU, 0x8aef9229LU, +0x15d538a8LU, 0x4d9226f2LU, 0xa55b041cLU, 0xfd1c1a46LU, 0x3884408dLU, 0x60c35ed7LU, 0x880a7c39LU, 0xd04d6263LU }; + +static const ulong32 rs_tab5[256] = { +0x00000000LU, 0xdbaec658LU, 0xfb11c1b0LU, 0x20bf07e8LU, 0xbb22cf2dLU, 0x608c0975LU, 0x40330e9dLU, 0x9b9dc8c5LU, +0x3b44d35aLU, 0xe0ea1502LU, 0xc05512eaLU, 0x1bfbd4b2LU, 0x80661c77LU, 0x5bc8da2fLU, 0x7b77ddc7LU, 0xa0d91b9fLU, +0x7688ebb4LU, 0xad262decLU, 0x8d992a04LU, 0x5637ec5cLU, 0xcdaa2499LU, 0x1604e2c1LU, 0x36bbe529LU, 0xed152371LU, +0x4dcc38eeLU, 0x9662feb6LU, 0xb6ddf95eLU, 0x6d733f06LU, 0xf6eef7c3LU, 0x2d40319bLU, 0x0dff3673LU, 0xd651f02bLU, +0xec5d9b25LU, 0x37f35d7dLU, 0x174c5a95LU, 0xcce29ccdLU, 0x577f5408LU, 0x8cd19250LU, 0xac6e95b8LU, 0x77c053e0LU, +0xd719487fLU, 0x0cb78e27LU, 0x2c0889cfLU, 0xf7a64f97LU, 0x6c3b8752LU, 0xb795410aLU, 0x972a46e2LU, 0x4c8480baLU, +0x9ad57091LU, 0x417bb6c9LU, 0x61c4b121LU, 0xba6a7779LU, 0x21f7bfbcLU, 0xfa5979e4LU, 0xdae67e0cLU, 0x0148b854LU, +0xa191a3cbLU, 0x7a3f6593LU, 0x5a80627bLU, 0x812ea423LU, 0x1ab36ce6LU, 0xc11daabeLU, 0xe1a2ad56LU, 0x3a0c6b0eLU, +0x95ba7b4aLU, 0x4e14bd12LU, 0x6eabbafaLU, 0xb5057ca2LU, 0x2e98b467LU, 0xf536723fLU, 0xd58975d7LU, 0x0e27b38fLU, +0xaefea810LU, 0x75506e48LU, 0x55ef69a0LU, 0x8e41aff8LU, 0x15dc673dLU, 0xce72a165LU, 0xeecda68dLU, 0x356360d5LU, +0xe33290feLU, 0x389c56a6LU, 0x1823514eLU, 0xc38d9716LU, 0x58105fd3LU, 0x83be998bLU, 0xa3019e63LU, 0x78af583bLU, +0xd87643a4LU, 0x03d885fcLU, 0x23678214LU, 0xf8c9444cLU, 0x63548c89LU, 0xb8fa4ad1LU, 0x98454d39LU, 0x43eb8b61LU, +0x79e7e06fLU, 0xa2492637LU, 0x82f621dfLU, 0x5958e787LU, 0xc2c52f42LU, 0x196be91aLU, 0x39d4eef2LU, 0xe27a28aaLU, +0x42a33335LU, 0x990df56dLU, 0xb9b2f285LU, 0x621c34ddLU, 0xf981fc18LU, 0x222f3a40LU, 0x02903da8LU, 0xd93efbf0LU, +0x0f6f0bdbLU, 0xd4c1cd83LU, 0xf47eca6bLU, 0x2fd00c33LU, 0xb44dc4f6LU, 0x6fe302aeLU, 0x4f5c0546LU, 0x94f2c31eLU, +0x342bd881LU, 0xef851ed9LU, 0xcf3a1931LU, 0x1494df69LU, 0x8f0917acLU, 0x54a7d1f4LU, 0x7418d61cLU, 0xafb61044LU, +0x6739f694LU, 0xbc9730ccLU, 0x9c283724LU, 0x4786f17cLU, 0xdc1b39b9LU, 0x07b5ffe1LU, 0x270af809LU, 0xfca43e51LU, +0x5c7d25ceLU, 0x87d3e396LU, 0xa76ce47eLU, 0x7cc22226LU, 0xe75feae3LU, 0x3cf12cbbLU, 0x1c4e2b53LU, 0xc7e0ed0bLU, +0x11b11d20LU, 0xca1fdb78LU, 0xeaa0dc90LU, 0x310e1ac8LU, 0xaa93d20dLU, 0x713d1455LU, 0x518213bdLU, 0x8a2cd5e5LU, +0x2af5ce7aLU, 0xf15b0822LU, 0xd1e40fcaLU, 0x0a4ac992LU, 0x91d70157LU, 0x4a79c70fLU, 0x6ac6c0e7LU, 0xb16806bfLU, +0x8b646db1LU, 0x50caabe9LU, 0x7075ac01LU, 0xabdb6a59LU, 0x3046a29cLU, 0xebe864c4LU, 0xcb57632cLU, 0x10f9a574LU, +0xb020beebLU, 0x6b8e78b3LU, 0x4b317f5bLU, 0x909fb903LU, 0x0b0271c6LU, 0xd0acb79eLU, 0xf013b076LU, 0x2bbd762eLU, +0xfdec8605LU, 0x2642405dLU, 0x06fd47b5LU, 0xdd5381edLU, 0x46ce4928LU, 0x9d608f70LU, 0xbddf8898LU, 0x66714ec0LU, +0xc6a8555fLU, 0x1d069307LU, 0x3db994efLU, 0xe61752b7LU, 0x7d8a9a72LU, 0xa6245c2aLU, 0x869b5bc2LU, 0x5d359d9aLU, +0xf2838ddeLU, 0x292d4b86LU, 0x09924c6eLU, 0xd23c8a36LU, 0x49a142f3LU, 0x920f84abLU, 0xb2b08343LU, 0x691e451bLU, +0xc9c75e84LU, 0x126998dcLU, 0x32d69f34LU, 0xe978596cLU, 0x72e591a9LU, 0xa94b57f1LU, 0x89f45019LU, 0x525a9641LU, +0x840b666aLU, 0x5fa5a032LU, 0x7f1aa7daLU, 0xa4b46182LU, 0x3f29a947LU, 0xe4876f1fLU, 0xc43868f7LU, 0x1f96aeafLU, +0xbf4fb530LU, 0x64e17368LU, 0x445e7480LU, 0x9ff0b2d8LU, 0x046d7a1dLU, 0xdfc3bc45LU, 0xff7cbbadLU, 0x24d27df5LU, +0x1ede16fbLU, 0xc570d0a3LU, 0xe5cfd74bLU, 0x3e611113LU, 0xa5fcd9d6LU, 0x7e521f8eLU, 0x5eed1866LU, 0x8543de3eLU, +0x259ac5a1LU, 0xfe3403f9LU, 0xde8b0411LU, 0x0525c249LU, 0x9eb80a8cLU, 0x4516ccd4LU, 0x65a9cb3cLU, 0xbe070d64LU, +0x6856fd4fLU, 0xb3f83b17LU, 0x93473cffLU, 0x48e9faa7LU, 0xd3743262LU, 0x08daf43aLU, 0x2865f3d2LU, 0xf3cb358aLU, +0x53122e15LU, 0x88bce84dLU, 0xa803efa5LU, 0x73ad29fdLU, 0xe830e138LU, 0x339e2760LU, 0x13212088LU, 0xc88fe6d0LU }; + +static const ulong32 rs_tab6[256] = { +0x00000000LU, 0x9e3d68dbLU, 0x717ad0fbLU, 0xef47b820LU, 0xe2f4edbbLU, 0x7cc98560LU, 0x938e3d40LU, 0x0db3559bLU, +0x89a5973bLU, 0x1798ffe0LU, 0xf8df47c0LU, 0x66e22f1bLU, 0x6b517a80LU, 0xf56c125bLU, 0x1a2baa7bLU, 0x8416c2a0LU, +0x5f076376LU, 0xc13a0badLU, 0x2e7db38dLU, 0xb040db56LU, 0xbdf38ecdLU, 0x23cee616LU, 0xcc895e36LU, 0x52b436edLU, +0xd6a2f44dLU, 0x489f9c96LU, 0xa7d824b6LU, 0x39e54c6dLU, 0x345619f6LU, 0xaa6b712dLU, 0x452cc90dLU, 0xdb11a1d6LU, +0xbe0ec6ecLU, 0x2033ae37LU, 0xcf741617LU, 0x51497eccLU, 0x5cfa2b57LU, 0xc2c7438cLU, 0x2d80fbacLU, 0xb3bd9377LU, +0x37ab51d7LU, 0xa996390cLU, 0x46d1812cLU, 0xd8ece9f7LU, 0xd55fbc6cLU, 0x4b62d4b7LU, 0xa4256c97LU, 0x3a18044cLU, +0xe109a59aLU, 0x7f34cd41LU, 0x90737561LU, 0x0e4e1dbaLU, 0x03fd4821LU, 0x9dc020faLU, 0x728798daLU, 0xecbaf001LU, +0x68ac32a1LU, 0xf6915a7aLU, 0x19d6e25aLU, 0x87eb8a81LU, 0x8a58df1aLU, 0x1465b7c1LU, 0xfb220fe1LU, 0x651f673aLU, +0x311cc195LU, 0xaf21a94eLU, 0x4066116eLU, 0xde5b79b5LU, 0xd3e82c2eLU, 0x4dd544f5LU, 0xa292fcd5LU, 0x3caf940eLU, +0xb8b956aeLU, 0x26843e75LU, 0xc9c38655LU, 0x57feee8eLU, 0x5a4dbb15LU, 0xc470d3ceLU, 0x2b376beeLU, 0xb50a0335LU, +0x6e1ba2e3LU, 0xf026ca38LU, 0x1f617218LU, 0x815c1ac3LU, 0x8cef4f58LU, 0x12d22783LU, 0xfd959fa3LU, 0x63a8f778LU, +0xe7be35d8LU, 0x79835d03LU, 0x96c4e523LU, 0x08f98df8LU, 0x054ad863LU, 0x9b77b0b8LU, 0x74300898LU, 0xea0d6043LU, +0x8f120779LU, 0x112f6fa2LU, 0xfe68d782LU, 0x6055bf59LU, 0x6de6eac2LU, 0xf3db8219LU, 0x1c9c3a39LU, 0x82a152e2LU, +0x06b79042LU, 0x988af899LU, 0x77cd40b9LU, 0xe9f02862LU, 0xe4437df9LU, 0x7a7e1522LU, 0x9539ad02LU, 0x0b04c5d9LU, +0xd015640fLU, 0x4e280cd4LU, 0xa16fb4f4LU, 0x3f52dc2fLU, 0x32e189b4LU, 0xacdce16fLU, 0x439b594fLU, 0xdda63194LU, +0x59b0f334LU, 0xc78d9befLU, 0x28ca23cfLU, 0xb6f74b14LU, 0xbb441e8fLU, 0x25797654LU, 0xca3ece74LU, 0x5403a6afLU, +0x6238cf67LU, 0xfc05a7bcLU, 0x13421f9cLU, 0x8d7f7747LU, 0x80cc22dcLU, 0x1ef14a07LU, 0xf1b6f227LU, 0x6f8b9afcLU, +0xeb9d585cLU, 0x75a03087LU, 0x9ae788a7LU, 0x04dae07cLU, 0x0969b5e7LU, 0x9754dd3cLU, 0x7813651cLU, 0xe62e0dc7LU, +0x3d3fac11LU, 0xa302c4caLU, 0x4c457ceaLU, 0xd2781431LU, 0xdfcb41aaLU, 0x41f62971LU, 0xaeb19151LU, 0x308cf98aLU, +0xb49a3b2aLU, 0x2aa753f1LU, 0xc5e0ebd1LU, 0x5bdd830aLU, 0x566ed691LU, 0xc853be4aLU, 0x2714066aLU, 0xb9296eb1LU, +0xdc36098bLU, 0x420b6150LU, 0xad4cd970LU, 0x3371b1abLU, 0x3ec2e430LU, 0xa0ff8cebLU, 0x4fb834cbLU, 0xd1855c10LU, +0x55939eb0LU, 0xcbaef66bLU, 0x24e94e4bLU, 0xbad42690LU, 0xb767730bLU, 0x295a1bd0LU, 0xc61da3f0LU, 0x5820cb2bLU, +0x83316afdLU, 0x1d0c0226LU, 0xf24bba06LU, 0x6c76d2ddLU, 0x61c58746LU, 0xfff8ef9dLU, 0x10bf57bdLU, 0x8e823f66LU, +0x0a94fdc6LU, 0x94a9951dLU, 0x7bee2d3dLU, 0xe5d345e6LU, 0xe860107dLU, 0x765d78a6LU, 0x991ac086LU, 0x0727a85dLU, +0x53240ef2LU, 0xcd196629LU, 0x225ede09LU, 0xbc63b6d2LU, 0xb1d0e349LU, 0x2fed8b92LU, 0xc0aa33b2LU, 0x5e975b69LU, +0xda8199c9LU, 0x44bcf112LU, 0xabfb4932LU, 0x35c621e9LU, 0x38757472LU, 0xa6481ca9LU, 0x490fa489LU, 0xd732cc52LU, +0x0c236d84LU, 0x921e055fLU, 0x7d59bd7fLU, 0xe364d5a4LU, 0xeed7803fLU, 0x70eae8e4LU, 0x9fad50c4LU, 0x0190381fLU, +0x8586fabfLU, 0x1bbb9264LU, 0xf4fc2a44LU, 0x6ac1429fLU, 0x67721704LU, 0xf94f7fdfLU, 0x1608c7ffLU, 0x8835af24LU, +0xed2ac81eLU, 0x7317a0c5LU, 0x9c5018e5LU, 0x026d703eLU, 0x0fde25a5LU, 0x91e34d7eLU, 0x7ea4f55eLU, 0xe0999d85LU, +0x648f5f25LU, 0xfab237feLU, 0x15f58fdeLU, 0x8bc8e705LU, 0x867bb29eLU, 0x1846da45LU, 0xf7016265LU, 0x693c0abeLU, +0xb22dab68LU, 0x2c10c3b3LU, 0xc3577b93LU, 0x5d6a1348LU, 0x50d946d3LU, 0xcee42e08LU, 0x21a39628LU, 0xbf9efef3LU, +0x3b883c53LU, 0xa5b55488LU, 0x4af2eca8LU, 0xd4cf8473LU, 0xd97cd1e8LU, 0x4741b933LU, 0xa8060113LU, 0x363b69c8LU }; + +static const ulong32 rs_tab7[256] = { +0x00000000LU, 0x0319e59eLU, 0x06328771LU, 0x052b62efLU, 0x0c6443e2LU, 0x0f7da67cLU, 0x0a56c493LU, 0x094f210dLU, +0x18c88689LU, 0x1bd16317LU, 0x1efa01f8LU, 0x1de3e466LU, 0x14acc56bLU, 0x17b520f5LU, 0x129e421aLU, 0x1187a784LU, +0x30dd415fLU, 0x33c4a4c1LU, 0x36efc62eLU, 0x35f623b0LU, 0x3cb902bdLU, 0x3fa0e723LU, 0x3a8b85ccLU, 0x39926052LU, +0x2815c7d6LU, 0x2b0c2248LU, 0x2e2740a7LU, 0x2d3ea539LU, 0x24718434LU, 0x276861aaLU, 0x22430345LU, 0x215ae6dbLU, +0x60f782beLU, 0x63ee6720LU, 0x66c505cfLU, 0x65dce051LU, 0x6c93c15cLU, 0x6f8a24c2LU, 0x6aa1462dLU, 0x69b8a3b3LU, +0x783f0437LU, 0x7b26e1a9LU, 0x7e0d8346LU, 0x7d1466d8LU, 0x745b47d5LU, 0x7742a24bLU, 0x7269c0a4LU, 0x7170253aLU, +0x502ac3e1LU, 0x5333267fLU, 0x56184490LU, 0x5501a10eLU, 0x5c4e8003LU, 0x5f57659dLU, 0x5a7c0772LU, 0x5965e2ecLU, +0x48e24568LU, 0x4bfba0f6LU, 0x4ed0c219LU, 0x4dc92787LU, 0x4486068aLU, 0x479fe314LU, 0x42b481fbLU, 0x41ad6465LU, +0xc0a34931LU, 0xc3baacafLU, 0xc691ce40LU, 0xc5882bdeLU, 0xccc70ad3LU, 0xcfdeef4dLU, 0xcaf58da2LU, 0xc9ec683cLU, +0xd86bcfb8LU, 0xdb722a26LU, 0xde5948c9LU, 0xdd40ad57LU, 0xd40f8c5aLU, 0xd71669c4LU, 0xd23d0b2bLU, 0xd124eeb5LU, +0xf07e086eLU, 0xf367edf0LU, 0xf64c8f1fLU, 0xf5556a81LU, 0xfc1a4b8cLU, 0xff03ae12LU, 0xfa28ccfdLU, 0xf9312963LU, +0xe8b68ee7LU, 0xebaf6b79LU, 0xee840996LU, 0xed9dec08LU, 0xe4d2cd05LU, 0xe7cb289bLU, 0xe2e04a74LU, 0xe1f9afeaLU, +0xa054cb8fLU, 0xa34d2e11LU, 0xa6664cfeLU, 0xa57fa960LU, 0xac30886dLU, 0xaf296df3LU, 0xaa020f1cLU, 0xa91bea82LU, +0xb89c4d06LU, 0xbb85a898LU, 0xbeaeca77LU, 0xbdb72fe9LU, 0xb4f80ee4LU, 0xb7e1eb7aLU, 0xb2ca8995LU, 0xb1d36c0bLU, +0x90898ad0LU, 0x93906f4eLU, 0x96bb0da1LU, 0x95a2e83fLU, 0x9cedc932LU, 0x9ff42cacLU, 0x9adf4e43LU, 0x99c6abddLU, +0x88410c59LU, 0x8b58e9c7LU, 0x8e738b28LU, 0x8d6a6eb6LU, 0x84254fbbLU, 0x873caa25LU, 0x8217c8caLU, 0x810e2d54LU, +0xcd0b9262LU, 0xce1277fcLU, 0xcb391513LU, 0xc820f08dLU, 0xc16fd180LU, 0xc276341eLU, 0xc75d56f1LU, 0xc444b36fLU, +0xd5c314ebLU, 0xd6daf175LU, 0xd3f1939aLU, 0xd0e87604LU, 0xd9a75709LU, 0xdabeb297LU, 0xdf95d078LU, 0xdc8c35e6LU, +0xfdd6d33dLU, 0xfecf36a3LU, 0xfbe4544cLU, 0xf8fdb1d2LU, 0xf1b290dfLU, 0xf2ab7541LU, 0xf78017aeLU, 0xf499f230LU, +0xe51e55b4LU, 0xe607b02aLU, 0xe32cd2c5LU, 0xe035375bLU, 0xe97a1656LU, 0xea63f3c8LU, 0xef489127LU, 0xec5174b9LU, +0xadfc10dcLU, 0xaee5f542LU, 0xabce97adLU, 0xa8d77233LU, 0xa198533eLU, 0xa281b6a0LU, 0xa7aad44fLU, 0xa4b331d1LU, +0xb5349655LU, 0xb62d73cbLU, 0xb3061124LU, 0xb01ff4baLU, 0xb950d5b7LU, 0xba493029LU, 0xbf6252c6LU, 0xbc7bb758LU, +0x9d215183LU, 0x9e38b41dLU, 0x9b13d6f2LU, 0x980a336cLU, 0x91451261LU, 0x925cf7ffLU, 0x97779510LU, 0x946e708eLU, +0x85e9d70aLU, 0x86f03294LU, 0x83db507bLU, 0x80c2b5e5LU, 0x898d94e8LU, 0x8a947176LU, 0x8fbf1399LU, 0x8ca6f607LU, +0x0da8db53LU, 0x0eb13ecdLU, 0x0b9a5c22LU, 0x0883b9bcLU, 0x01cc98b1LU, 0x02d57d2fLU, 0x07fe1fc0LU, 0x04e7fa5eLU, +0x15605ddaLU, 0x1679b844LU, 0x1352daabLU, 0x104b3f35LU, 0x19041e38LU, 0x1a1dfba6LU, 0x1f369949LU, 0x1c2f7cd7LU, +0x3d759a0cLU, 0x3e6c7f92LU, 0x3b471d7dLU, 0x385ef8e3LU, 0x3111d9eeLU, 0x32083c70LU, 0x37235e9fLU, 0x343abb01LU, +0x25bd1c85LU, 0x26a4f91bLU, 0x238f9bf4LU, 0x20967e6aLU, 0x29d95f67LU, 0x2ac0baf9LU, 0x2febd816LU, 0x2cf23d88LU, +0x6d5f59edLU, 0x6e46bc73LU, 0x6b6dde9cLU, 0x68743b02LU, 0x613b1a0fLU, 0x6222ff91LU, 0x67099d7eLU, 0x641078e0LU, +0x7597df64LU, 0x768e3afaLU, 0x73a55815LU, 0x70bcbd8bLU, 0x79f39c86LU, 0x7aea7918LU, 0x7fc11bf7LU, 0x7cd8fe69LU, +0x5d8218b2LU, 0x5e9bfd2cLU, 0x5bb09fc3LU, 0x58a97a5dLU, 0x51e65b50LU, 0x52ffbeceLU, 0x57d4dc21LU, 0x54cd39bfLU, +0x454a9e3bLU, 0x46537ba5LU, 0x4378194aLU, 0x4061fcd4LU, 0x492eddd9LU, 0x4a373847LU, 0x4f1c5aa8LU, 0x4c05bf36LU }; + +#endif /* LTC_TWOFISH_ALL_TABLES */ + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/twofish/twofish_tab.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/xtea.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/xtea.c new file mode 100644 index 0000000000..376109e9b0 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/ciphers/xtea.c @@ -0,0 +1,211 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file xtea.c + Implementation of LTC_XTEA, Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_XTEA + +const struct ltc_cipher_descriptor xtea_desc = +{ + "xtea", + 1, + 16, 16, 8, 32, + &xtea_setup, + &xtea_ecb_encrypt, + &xtea_ecb_decrypt, + &xtea_test, + &xtea_done, + &xtea_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + unsigned long x, sum, K[4]; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + /* check arguments */ + if (keylen != 16) { + return CRYPT_INVALID_KEYSIZE; + } + + if (num_rounds != 0 && num_rounds != 32) { + return CRYPT_INVALID_ROUNDS; + } + + /* load key */ + LOAD32L(K[0], key+0); + LOAD32L(K[1], key+4); + LOAD32L(K[2], key+8); + LOAD32L(K[3], key+12); + + for (x = sum = 0; x < 32; x++) { + skey->xtea.A[x] = (sum + K[sum&3]) & 0xFFFFFFFFUL; + sum = (sum + 0x9E3779B9UL) & 0xFFFFFFFFUL; + skey->xtea.B[x] = (sum + K[(sum>>11)&3]) & 0xFFFFFFFFUL; + } + +#ifdef LTC_CLEAN_STACK + zeromem(&K, sizeof(K)); +#endif + + return CRYPT_OK; +} + +/** + Encrypts a block of text with LTC_XTEA + @param pt The input plaintext (8 bytes) + @param ct The output ciphertext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + unsigned long y, z; + int r; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + LOAD32L(y, &pt[0]); + LOAD32L(z, &pt[4]); + for (r = 0; r < 32; r += 4) { + y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r])) & 0xFFFFFFFFUL; + z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r])) & 0xFFFFFFFFUL; + + y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r+1])) & 0xFFFFFFFFUL; + z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r+1])) & 0xFFFFFFFFUL; + + y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r+2])) & 0xFFFFFFFFUL; + z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r+2])) & 0xFFFFFFFFUL; + + y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r+3])) & 0xFFFFFFFFUL; + z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r+3])) & 0xFFFFFFFFUL; + } + STORE32L(y, &ct[0]); + STORE32L(z, &ct[4]); + return CRYPT_OK; +} + +/** + Decrypts a block of text with LTC_XTEA + @param ct The input ciphertext (8 bytes) + @param pt The output plaintext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + unsigned long y, z; + int r; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + LOAD32L(y, &ct[0]); + LOAD32L(z, &ct[4]); + for (r = 31; r >= 0; r -= 4) { + z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r])) & 0xFFFFFFFFUL; + y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r])) & 0xFFFFFFFFUL; + + z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r-1])) & 0xFFFFFFFFUL; + y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r-1])) & 0xFFFFFFFFUL; + + z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r-2])) & 0xFFFFFFFFUL; + y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r-2])) & 0xFFFFFFFFUL; + + z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r-3])) & 0xFFFFFFFFUL; + y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r-3])) & 0xFFFFFFFFUL; + } + STORE32L(y, &pt[0]); + STORE32L(z, &pt[4]); + return CRYPT_OK; +} + +/** + Performs a self-test of the LTC_XTEA block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int xtea_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const unsigned char key[16] = + { 0x78, 0x56, 0x34, 0x12, 0xf0, 0xcd, 0xcb, 0x9a, + 0x48, 0x37, 0x26, 0x15, 0xc0, 0xbf, 0xae, 0x9d }; + static const unsigned char pt[8] = + { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + static const unsigned char ct[8] = + { 0x75, 0xd7, 0xc5, 0xbf, 0xcf, 0x58, 0xc9, 0x3f }; + unsigned char tmp[2][8]; + symmetric_key skey; + int err, y; + + if ((err = xtea_setup(key, 16, 0, &skey)) != CRYPT_OK) { + return err; + } + xtea_ecb_encrypt(pt, tmp[0], &skey); + xtea_ecb_decrypt(tmp[0], tmp[1], &skey); + + if (XMEMCMP(tmp[0], ct, 8) != 0 || XMEMCMP(tmp[1], pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) xtea_ecb_encrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 1000; y++) xtea_ecb_decrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + + return CRYPT_OK; + #endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void xtea_done(symmetric_key *skey) +{ +} + +/** + Gets suitable key size + @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. + @return CRYPT_OK if the input key size is acceptable. +*/ +int xtea_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize < 16) { + return CRYPT_INVALID_KEYSIZE; + } + *keysize = 16; + return CRYPT_OK; +} + + +#endif + + + + +/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/xtea.c,v $ */ +/* $Revision: 1.14 $ */ +/* $Date: 2007/05/12 14:20:27 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ccm/ccm_memory.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ccm/ccm_memory.c new file mode 100644 index 0000000000..bf0e6d620e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ccm/ccm_memory.c @@ -0,0 +1,351 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ccm_memory.c + CCM support, process a block of memory, Tom St Denis +*/ + +#ifdef LTC_CCM_MODE + +/** + CCM encrypt/decrypt and produce an authentication tag + @param cipher The index of the cipher desired + @param key The secret key to use + @param keylen The length of the secret key (octets) + @param uskey A previously scheduled key [optional can be NULL] + @param nonce The session nonce [use once] + @param noncelen The length of the nonce + @param header The header for the session + @param headerlen The length of the header (octets) + @param pt [out] The plaintext + @param ptlen The length of the plaintext (octets) + @param ct [out] The ciphertext + @param tag [out] The destination tag + @param taglen [in/out] The max size and resulting size of the authentication tag + @param direction Encrypt or Decrypt direction (0 or 1) + @return CRYPT_OK if successful +*/ +int ccm_memory(int cipher, + const unsigned char *key, unsigned long keylen, + symmetric_key *uskey, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction) +{ + unsigned char PAD[16], ctr[16], CTRPAD[16], b; + symmetric_key *skey; + int err; + unsigned long len, L, x, y, z, CTRlen; + + if (uskey == NULL) { + LTC_ARGCHK(key != NULL); + } + LTC_ARGCHK(nonce != NULL); + if (headerlen > 0) { + LTC_ARGCHK(header != NULL); + } + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(tag != NULL); + LTC_ARGCHK(taglen != NULL); + +#ifdef LTC_FAST + if (16 % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + + /* check cipher input */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + if (cipher_descriptor[cipher].block_length != 16) { + return CRYPT_INVALID_CIPHER; + } + + /* make sure the taglen is even and <= 16 */ + *taglen &= ~1; + if (*taglen > 16) { + *taglen = 16; + } + + /* can't use < 4 */ + if (*taglen < 4) { + return CRYPT_INVALID_ARG; + } + + /* is there an accelerator? */ + if (cipher_descriptor[cipher].accel_ccm_memory != NULL) { + return cipher_descriptor[cipher].accel_ccm_memory( + key, keylen, + uskey, + nonce, noncelen, + header, headerlen, + pt, ptlen, + ct, + tag, taglen, + direction); + } + + /* let's get the L value */ + len = ptlen; + L = 0; + while (len) { + ++L; + len >>= 8; + } + if (L <= 1) { + L = 2; + } + + /* increase L to match the nonce len */ + noncelen = (noncelen > 13) ? 13 : noncelen; + if ((15 - noncelen) > L) { + L = 15 - noncelen; + } + + /* decrease noncelen to match L */ + if ((noncelen + L) > 15) { + noncelen = 15 - L; + } + + /* allocate mem for the symmetric key */ + if (uskey == NULL) { + skey = XMALLOC(sizeof(*skey)); + if (skey == NULL) { + return CRYPT_MEM; + } + + /* initialize the cipher */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) { + XFREE(skey); + return err; + } + } else { + skey = uskey; + } + + /* form B_0 == flags | Nonce N | l(m) */ + x = 0; + PAD[x++] = (unsigned char)(((headerlen > 0) ? (1<<6) : 0) | + (((*taglen - 2)>>1)<<3) | + (L-1)); + + /* nonce */ + for (y = 0; y < (16 - (L + 1)); y++) { + PAD[x++] = nonce[y]; + } + + /* store len */ + len = ptlen; + + /* shift len so the upper bytes of len are the contents of the length */ + for (y = L; y < 4; y++) { + len <<= 8; + } + + /* store l(m) (only store 32-bits) */ + for (y = 0; L > 4 && (L-y)>4; y++) { + PAD[x++] = 0; + } + for (; y < L; y++) { + PAD[x++] = (unsigned char)((len >> 24) & 255); + len <<= 8; + } + + /* encrypt PAD */ + if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { + goto error; + } + + /* handle header */ + if (headerlen > 0) { + x = 0; + + /* store length */ + if (headerlen < ((1UL<<16) - (1UL<<8))) { + PAD[x++] ^= (headerlen>>8) & 255; + PAD[x++] ^= headerlen & 255; + } else { + PAD[x++] ^= 0xFF; + PAD[x++] ^= 0xFE; + PAD[x++] ^= (headerlen>>24) & 255; + PAD[x++] ^= (headerlen>>16) & 255; + PAD[x++] ^= (headerlen>>8) & 255; + PAD[x++] ^= headerlen & 255; + } + + /* now add the data */ + for (y = 0; y < headerlen; y++) { + if (x == 16) { + /* full block so let's encrypt it */ + if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { + goto error; + } + x = 0; + } + PAD[x++] ^= header[y]; + } + + /* remainder? */ + if (x != 0) { + if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { + goto error; + } + } + } + + /* setup the ctr counter */ + x = 0; + + /* flags */ + ctr[x++] = (unsigned char)L-1; + + /* nonce */ + for (y = 0; y < (16 - (L+1)); ++y) { + ctr[x++] = nonce[y]; + } + /* offset */ + while (x < 16) { + ctr[x++] = 0; + } + + x = 0; + CTRlen = 16; + + /* now handle the PT */ + if (ptlen > 0) { + y = 0; +#ifdef LTC_FAST + if (ptlen & ~15) { + if (direction == CCM_ENCRYPT) { + for (; y < (ptlen & ~15); y += 16) { + /* increment the ctr? */ + for (z = 15; z > 15-L; z--) { + ctr[z] = (ctr[z] + 1) & 255; + if (ctr[z]) break; + } + if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { + goto error; + } + + /* xor the PT against the pad first */ + for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)(&PAD[z])) ^= *((LTC_FAST_TYPE*)(&pt[y+z])); + *((LTC_FAST_TYPE*)(&ct[y+z])) = *((LTC_FAST_TYPE*)(&pt[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z])); + } + if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { + goto error; + } + } + } else { + for (; y < (ptlen & ~15); y += 16) { + /* increment the ctr? */ + for (z = 15; z > 15-L; z--) { + ctr[z] = (ctr[z] + 1) & 255; + if (ctr[z]) break; + } + if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { + goto error; + } + + /* xor the PT against the pad last */ + for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)(&pt[y+z])) = *((LTC_FAST_TYPE*)(&ct[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z])); + *((LTC_FAST_TYPE*)(&PAD[z])) ^= *((LTC_FAST_TYPE*)(&pt[y+z])); + } + if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { + goto error; + } + } + } + } +#endif + + for (; y < ptlen; y++) { + /* increment the ctr? */ + if (CTRlen == 16) { + for (z = 15; z > 15-L; z--) { + ctr[z] = (ctr[z] + 1) & 255; + if (ctr[z]) break; + } + if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { + goto error; + } + CTRlen = 0; + } + + /* if we encrypt we add the bytes to the MAC first */ + if (direction == CCM_ENCRYPT) { + b = pt[y]; + ct[y] = b ^ CTRPAD[CTRlen++]; + } else { + b = ct[y] ^ CTRPAD[CTRlen++]; + pt[y] = b; + } + + if (x == 16) { + if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { + goto error; + } + x = 0; + } + PAD[x++] ^= b; + } + + if (x != 0) { + if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { + goto error; + } + } + } + + /* setup CTR for the TAG (zero the count) */ + for (y = 15; y > 15 - L; y--) { + ctr[y] = 0x00; + } + if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { + goto error; + } + + if (skey != uskey) { + cipher_descriptor[cipher].done(skey); + } + + /* store the TAG */ + for (x = 0; x < 16 && x < *taglen; x++) { + tag[x] = PAD[x] ^ CTRPAD[x]; + } + *taglen = x; + +#ifdef LTC_CLEAN_STACK + zeromem(skey, sizeof(*skey)); + zeromem(PAD, sizeof(PAD)); + zeromem(CTRPAD, sizeof(CTRPAD)); +#endif +error: + if (skey != uskey) { + XFREE(skey); + } + + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ccm/ccm_memory.c,v $ */ +/* $Revision: 1.20 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ccm/ccm_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ccm/ccm_test.c new file mode 100644 index 0000000000..a76ab55134 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ccm/ccm_test.c @@ -0,0 +1,180 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ccm_test.c + CCM support, process a block of memory, Tom St Denis +*/ + +#ifdef LTC_CCM_MODE + +int ccm_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + unsigned char key[16]; + unsigned char nonce[16]; + int noncelen; + unsigned char header[64]; + int headerlen; + unsigned char pt[64]; + int ptlen; + unsigned char ct[64]; + unsigned char tag[16]; + int taglen; + } tests[] = { + +/* 13 byte nonce, 8 byte auth, 23 byte pt */ +{ + { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF }, + { 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0, + 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 }, + 13, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }, + 8, + { 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E }, + 23, + { 0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2, + 0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80, + 0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84 }, + { 0x17, 0xe8, 0xd1, 0x2c, 0xfd, 0xf9, 0x26, 0xe0 }, + 8 +}, + +/* 13 byte nonce, 12 byte header, 19 byte pt */ +{ + { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF }, + { 0x00, 0x00, 0x00, 0x06, 0x05, 0x04, 0x03, 0xA0, + 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 }, + 13, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B }, + 12, + { 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E }, + 19, + { 0xA2, 0x8C, 0x68, 0x65, 0x93, 0x9A, 0x9A, 0x79, + 0xFA, 0xAA, 0x5C, 0x4C, 0x2A, 0x9D, 0x4A, 0x91, + 0xCD, 0xAC, 0x8C }, + { 0x96, 0xC8, 0x61, 0xB9, 0xC9, 0xE6, 0x1E, 0xF1 }, + 8 +}, + +/* supplied by Brian Gladman */ +{ + { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f }, + { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 }, + 7, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }, + 8, + { 0x20, 0x21, 0x22, 0x23 }, + 4, + { 0x71, 0x62, 0x01, 0x5b }, + { 0x4d, 0xac, 0x25, 0x5d }, + 4 +}, + +{ + { 0xc9, 0x7c, 0x1f, 0x67, 0xce, 0x37, 0x11, 0x85, + 0x51, 0x4a, 0x8a, 0x19, 0xf2, 0xbd, 0xd5, 0x2f }, + { 0x00, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0xb5, + 0x03, 0x97, 0x76, 0xe7, 0x0c }, + 13, + { 0x08, 0x40, 0x0f, 0xd2, 0xe1, 0x28, 0xa5, 0x7c, + 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0xab, 0xae, + 0xa5, 0xb8, 0xfc, 0xba, 0x00, 0x00 }, + 22, + { 0xf8, 0xba, 0x1a, 0x55, 0xd0, 0x2f, 0x85, 0xae, + 0x96, 0x7b, 0xb6, 0x2f, 0xb6, 0xcd, 0xa8, 0xeb, + 0x7e, 0x78, 0xa0, 0x50 }, + 20, + { 0xf3, 0xd0, 0xa2, 0xfe, 0x9a, 0x3d, 0xbf, 0x23, + 0x42, 0xa6, 0x43, 0xe4, 0x32, 0x46, 0xe8, 0x0c, + 0x3c, 0x04, 0xd0, 0x19 }, + { 0x78, 0x45, 0xce, 0x0b, 0x16, 0xf9, 0x76, 0x23 }, + 8 +}, + +}; + unsigned long taglen, x; + unsigned char buf[64], buf2[64], tag2[16], tag[16]; + int err, idx; + symmetric_key skey; + + idx = find_cipher("aes"); + if (idx == -1) { + idx = find_cipher("rijndael"); + if (idx == -1) { + return CRYPT_NOP; + } + } + + for (x = 0; x < (sizeof(tests)/sizeof(tests[0])); x++) { + taglen = tests[x].taglen; + if ((err = cipher_descriptor[idx].setup(tests[x].key, 16, 0, &skey)) != CRYPT_OK) { + return err; + } + + if ((err = ccm_memory(idx, + tests[x].key, 16, + &skey, + tests[x].nonce, tests[x].noncelen, + tests[x].header, tests[x].headerlen, + (unsigned char*)tests[x].pt, tests[x].ptlen, + buf, + tag, &taglen, 0)) != CRYPT_OK) { + return err; + } + + if (XMEMCMP(buf, tests[x].ct, tests[x].ptlen)) { + return CRYPT_FAIL_TESTVECTOR; + } + if (XMEMCMP(tag, tests[x].tag, tests[x].taglen)) { + return CRYPT_FAIL_TESTVECTOR; + } + + if ((err = ccm_memory(idx, + tests[x].key, 16, + NULL, + tests[x].nonce, tests[x].noncelen, + tests[x].header, tests[x].headerlen, + buf2, tests[x].ptlen, + buf, + tag2, &taglen, 1 )) != CRYPT_OK) { + return err; + } + + if (XMEMCMP(buf2, tests[x].pt, tests[x].ptlen)) { + return CRYPT_FAIL_TESTVECTOR; + } + if (XMEMCMP(tag2, tests[x].tag, tests[x].taglen)) { + return CRYPT_FAIL_TESTVECTOR; + } + cipher_descriptor[idx].done(&skey); + } + return CRYPT_OK; +#endif +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ccm/ccm_test.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_addheader.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_addheader.c new file mode 100644 index 0000000000..de17312974 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_addheader.c @@ -0,0 +1,38 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +/** + @file eax_addheader.c + EAX implementation, add meta-data, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_EAX_MODE + +/** + add header (metadata) to the stream + @param eax The current EAX state + @param header The header (meta-data) data you wish to add to the state + @param length The length of the header data + @return CRYPT_OK if successful +*/ +int eax_addheader(eax_state *eax, const unsigned char *header, + unsigned long length) +{ + LTC_ARGCHK(eax != NULL); + LTC_ARGCHK(header != NULL); + return omac_process(&eax->headeromac, header, length); +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_addheader.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_decrypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_decrypt.c new file mode 100644 index 0000000000..e89d1fdb1a --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_decrypt.c @@ -0,0 +1,50 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file eax_decrypt.c + EAX implementation, decrypt block, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_EAX_MODE + +/** + Decrypt data with the EAX protocol + @param eax The EAX state + @param ct The ciphertext + @param pt [out] The plaintext + @param length The length (octets) of the ciphertext + @return CRYPT_OK if successful +*/ +int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, + unsigned long length) +{ + int err; + + LTC_ARGCHK(eax != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + + /* omac ciphertext */ + if ((err = omac_process(&eax->ctomac, ct, length)) != CRYPT_OK) { + return err; + } + + /* decrypt */ + return ctr_decrypt(ct, pt, length, &eax->ctr); +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_decrypt.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_decrypt_verify_memory.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_decrypt_verify_memory.c new file mode 100644 index 0000000000..93e6f36a12 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_decrypt_verify_memory.c @@ -0,0 +1,108 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file eax_decrypt_verify_memory.c + EAX implementation, decrypt block of memory, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_EAX_MODE + +/** + Decrypt a block of memory and verify the provided MAC tag with EAX + @param cipher The index of the cipher desired + @param key The secret key + @param keylen The length of the key (octets) + @param nonce The nonce data (use once) for the session + @param noncelen The length of the nonce data. + @param header The session header data + @param headerlen The length of the header (octets) + @param ct The ciphertext + @param ctlen The length of the ciphertext (octets) + @param pt [out] The plaintext + @param tag The authentication tag provided by the encoder + @param taglen [in/out] The length of the tag (octets) + @param stat [out] The result of the decryption (1==valid tag, 0==invalid) + @return CRYPT_OK if successful regardless of the resulting tag comparison +*/ +int eax_decrypt_verify_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + unsigned char *tag, unsigned long taglen, + int *stat) +{ + int err; + eax_state *eax; + unsigned char *buf; + unsigned long buflen; + + LTC_ARGCHK(stat != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(tag != NULL); + + /* default to zero */ + *stat = 0; + + /* allocate ram */ + buf = XMALLOC(taglen); + eax = XMALLOC(sizeof(*eax)); + if (eax == NULL || buf == NULL) { + if (eax != NULL) { + XFREE(eax); + } + if (buf != NULL) { + XFREE(buf); + } + return CRYPT_MEM; + } + + if ((err = eax_init(eax, cipher, key, keylen, nonce, noncelen, header, headerlen)) != CRYPT_OK) { + goto LBL_ERR; + } + + if ((err = eax_decrypt(eax, ct, pt, ctlen)) != CRYPT_OK) { + goto LBL_ERR; + } + + buflen = taglen; + if ((err = eax_done(eax, buf, &buflen)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* compare tags */ + if (buflen >= taglen && XMEMCMP(buf, tag, taglen) == 0) { + *stat = 1; + } + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(buf, taglen); + zeromem(eax, sizeof(*eax)); +#endif + + XFREE(eax); + XFREE(buf); + + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_decrypt_verify_memory.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_done.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_done.c new file mode 100644 index 0000000000..43fc87a48b --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_done.c @@ -0,0 +1,94 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file eax_done.c + EAX implementation, terminate session, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_EAX_MODE + +/** + Terminate an EAX session and get the tag. + @param eax The EAX state + @param tag [out] The destination of the authentication tag + @param taglen [in/out] The max length and resulting length of the authentication tag + @return CRYPT_OK if successful +*/ +int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen) +{ + int err; + unsigned char *headermac, *ctmac; + unsigned long x, len; + + LTC_ARGCHK(eax != NULL); + LTC_ARGCHK(tag != NULL); + LTC_ARGCHK(taglen != NULL); + + /* allocate ram */ + headermac = XMALLOC(MAXBLOCKSIZE); + ctmac = XMALLOC(MAXBLOCKSIZE); + + if (headermac == NULL || ctmac == NULL) { + if (headermac != NULL) { + XFREE(headermac); + } + if (ctmac != NULL) { + XFREE(ctmac); + } + return CRYPT_MEM; + } + + /* finish ctomac */ + len = MAXBLOCKSIZE; + if ((err = omac_done(&eax->ctomac, ctmac, &len)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* finish headeromac */ + + /* note we specifically don't reset len so the two lens are minimal */ + + if ((err = omac_done(&eax->headeromac, headermac, &len)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* terminate the CTR chain */ + if ((err = ctr_done(&eax->ctr)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* compute N xor H xor C */ + for (x = 0; x < len && x < *taglen; x++) { + tag[x] = eax->N[x] ^ headermac[x] ^ ctmac[x]; + } + *taglen = x; + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(ctmac, MAXBLOCKSIZE); + zeromem(headermac, MAXBLOCKSIZE); + zeromem(eax, sizeof(*eax)); +#endif + + XFREE(ctmac); + XFREE(headermac); + + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_done.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_encrypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_encrypt.c new file mode 100644 index 0000000000..1bf6d6e065 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_encrypt.c @@ -0,0 +1,51 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file eax_encrypt.c + EAX implementation, encrypt block by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_EAX_MODE + +/** + Encrypt with EAX a block of data. + @param eax The EAX state + @param pt The plaintext to encrypt + @param ct [out] The ciphertext as encrypted + @param length The length of the plaintext (octets) + @return CRYPT_OK if successful +*/ +int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, + unsigned long length) +{ + int err; + + LTC_ARGCHK(eax != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + + /* encrypt */ + if ((err = ctr_encrypt(pt, ct, length, &eax->ctr)) != CRYPT_OK) { + return err; + } + + /* omac ciphertext */ + return omac_process(&eax->ctomac, ct, length); +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_encrypt.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_encrypt_authenticate_memory.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_encrypt_authenticate_memory.c new file mode 100644 index 0000000000..5a3f602cb9 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_encrypt_authenticate_memory.c @@ -0,0 +1,82 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file eax_encrypt_authenticate_memory.c + EAX implementation, encrypt a block of memory, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_EAX_MODE + +/** + EAX encrypt and produce an authentication tag + @param cipher The index of the cipher desired + @param key The secret key to use + @param keylen The length of the secret key (octets) + @param nonce The session nonce [use once] + @param noncelen The length of the nonce + @param header The header for the session + @param headerlen The length of the header (octets) + @param pt The plaintext + @param ptlen The length of the plaintext (octets) + @param ct [out] The ciphertext + @param tag [out] The destination tag + @param taglen [in/out] The max size and resulting size of the authentication tag + @return CRYPT_OK if successful +*/ +int eax_encrypt_authenticate_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen) +{ + int err; + eax_state *eax; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(tag != NULL); + LTC_ARGCHK(taglen != NULL); + + eax = XMALLOC(sizeof(*eax)); + + if ((err = eax_init(eax, cipher, key, keylen, nonce, noncelen, header, headerlen)) != CRYPT_OK) { + goto LBL_ERR; + } + + if ((err = eax_encrypt(eax, pt, ct, ptlen)) != CRYPT_OK) { + goto LBL_ERR; + } + + if ((err = eax_done(eax, tag, taglen)) != CRYPT_OK) { + goto LBL_ERR; + } + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(eax, sizeof(*eax)); +#endif + + XFREE(eax); + + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_encrypt_authenticate_memory.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_init.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_init.c new file mode 100644 index 0000000000..b635d7187e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_init.c @@ -0,0 +1,144 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file eax_init.c + EAX implementation, initialized EAX state, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_EAX_MODE + +/** + Initialized an EAX state + @param eax [out] The EAX state to initialize + @param cipher The index of the desired cipher + @param key The secret key + @param keylen The length of the secret key (octets) + @param nonce The use-once nonce for the session + @param noncelen The length of the nonce (octets) + @param header The header for the EAX state + @param headerlen The header length (octets) + @return CRYPT_OK if successful +*/ +int eax_init(eax_state *eax, int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen) +{ + unsigned char *buf; + int err, blklen; + omac_state *omac; + unsigned long len; + + + LTC_ARGCHK(eax != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(nonce != NULL); + if (headerlen > 0) { + LTC_ARGCHK(header != NULL); + } + + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + blklen = cipher_descriptor[cipher].block_length; + + /* allocate ram */ + buf = XMALLOC(MAXBLOCKSIZE); + omac = XMALLOC(sizeof(*omac)); + + if (buf == NULL || omac == NULL) { + if (buf != NULL) { + XFREE(buf); + } + if (omac != NULL) { + XFREE(omac); + } + return CRYPT_MEM; + } + + /* N = LTC_OMAC_0K(nonce) */ + zeromem(buf, MAXBLOCKSIZE); + if ((err = omac_init(omac, cipher, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* omac the [0]_n */ + if ((err = omac_process(omac, buf, blklen)) != CRYPT_OK) { + goto LBL_ERR; + } + /* omac the nonce */ + if ((err = omac_process(omac, nonce, noncelen)) != CRYPT_OK) { + goto LBL_ERR; + } + /* store result */ + len = sizeof(eax->N); + if ((err = omac_done(omac, eax->N, &len)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* H = LTC_OMAC_1K(header) */ + zeromem(buf, MAXBLOCKSIZE); + buf[blklen - 1] = 1; + + if ((err = omac_init(&eax->headeromac, cipher, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* omac the [1]_n */ + if ((err = omac_process(&eax->headeromac, buf, blklen)) != CRYPT_OK) { + goto LBL_ERR; + } + /* omac the header */ + if (headerlen != 0) { + if ((err = omac_process(&eax->headeromac, header, headerlen)) != CRYPT_OK) { + goto LBL_ERR; + } + } + + /* note we don't finish the headeromac, this allows us to add more header later */ + + /* setup the CTR mode */ + if ((err = ctr_start(cipher, eax->N, key, keylen, 0, CTR_COUNTER_BIG_ENDIAN, &eax->ctr)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* setup the LTC_OMAC for the ciphertext */ + if ((err = omac_init(&eax->ctomac, cipher, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* omac [2]_n */ + zeromem(buf, MAXBLOCKSIZE); + buf[blklen-1] = 2; + if ((err = omac_process(&eax->ctomac, buf, blklen)) != CRYPT_OK) { + goto LBL_ERR; + } + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(buf, MAXBLOCKSIZE); + zeromem(omac, sizeof(*omac)); +#endif + + XFREE(omac); + XFREE(buf); + + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_init.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_test.c new file mode 100644 index 0000000000..b87670053e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/eax/eax_test.c @@ -0,0 +1,282 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file eax_test.c + EAX implementation, self-test, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_EAX_MODE + +/** + Test the EAX implementation + @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled +*/ +int eax_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + int keylen, + noncelen, + headerlen, + msglen; + + unsigned char key[MAXBLOCKSIZE], + nonce[MAXBLOCKSIZE], + header[MAXBLOCKSIZE], + plaintext[MAXBLOCKSIZE], + ciphertext[MAXBLOCKSIZE], + tag[MAXBLOCKSIZE]; + } tests[] = { + +/* NULL message */ +{ + 16, 0, 0, 0, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* nonce */ + { 0 }, + /* header */ + { 0 }, + /* plaintext */ + { 0 }, + /* ciphertext */ + { 0 }, + /* tag */ + { 0x9a, 0xd0, 0x7e, 0x7d, 0xbf, 0xf3, 0x01, 0xf5, + 0x05, 0xde, 0x59, 0x6b, 0x96, 0x15, 0xdf, 0xff } +}, + +/* test with nonce */ +{ + 16, 16, 0, 0, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* nonce */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* header */ + { 0 }, + /* plaintext */ + { 0 }, + /* ciphertext */ + { 0 }, + /* tag */ + { 0x1c, 0xe1, 0x0d, 0x3e, 0xff, 0xd4, 0xca, 0xdb, + 0xe2, 0xe4, 0x4b, 0x58, 0xd6, 0x0a, 0xb9, 0xec } +}, + +/* test with header [no nonce] */ +{ + 16, 0, 16, 0, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* nonce */ + { 0 }, + /* header */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* plaintext */ + { 0 }, + /* ciphertext */ + { 0 }, + /* tag */ + { 0x3a, 0x69, 0x8f, 0x7a, 0x27, 0x0e, 0x51, 0xb0, + 0xf6, 0x5b, 0x3d, 0x3e, 0x47, 0x19, 0x3c, 0xff } +}, + +/* test with header + nonce + plaintext */ +{ + 16, 16, 16, 32, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* nonce */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* header */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* plaintext */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, + /* ciphertext */ + { 0x29, 0xd8, 0x78, 0xd1, 0xa3, 0xbe, 0x85, 0x7b, + 0x6f, 0xb8, 0xc8, 0xea, 0x59, 0x50, 0xa7, 0x78, + 0x33, 0x1f, 0xbf, 0x2c, 0xcf, 0x33, 0x98, 0x6f, + 0x35, 0xe8, 0xcf, 0x12, 0x1d, 0xcb, 0x30, 0xbc }, + /* tag */ + { 0x4f, 0xbe, 0x03, 0x38, 0xbe, 0x1c, 0x8c, 0x7e, + 0x1d, 0x7a, 0xe7, 0xe4, 0x5b, 0x92, 0xc5, 0x87 } +}, + +/* test with header + nonce + plaintext [not even sizes!] */ +{ + 16, 15, 14, 29, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* nonce */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e }, + /* header */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d }, + /* plaintext */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c }, + /* ciphertext */ + { 0xdd, 0x25, 0xc7, 0x54, 0xc5, 0xb1, 0x7c, 0x59, + 0x28, 0xb6, 0x9b, 0x73, 0x15, 0x5f, 0x7b, 0xb8, + 0x88, 0x8f, 0xaf, 0x37, 0x09, 0x1a, 0xd9, 0x2c, + 0x8a, 0x24, 0xdb, 0x86, 0x8b }, + /* tag */ + { 0x0d, 0x1a, 0x14, 0xe5, 0x22, 0x24, 0xff, 0xd2, + 0x3a, 0x05, 0xfa, 0x02, 0xcd, 0xef, 0x52, 0xda } +}, + +/* Vectors from Brian Gladman */ + +{ + 16, 16, 8, 0, + /* key */ + { 0x23, 0x39, 0x52, 0xde, 0xe4, 0xd5, 0xed, 0x5f, + 0x9b, 0x9c, 0x6d, 0x6f, 0xf8, 0x0f, 0xf4, 0x78 }, + /* nonce */ + { 0x62, 0xec, 0x67, 0xf9, 0xc3, 0xa4, 0xa4, 0x07, + 0xfc, 0xb2, 0xa8, 0xc4, 0x90, 0x31, 0xa8, 0xb3 }, + /* header */ + { 0x6b, 0xfb, 0x91, 0x4f, 0xd0, 0x7e, 0xae, 0x6b }, + /* PT */ + { 0x00 }, + /* CT */ + { 0x00 }, + /* tag */ + { 0xe0, 0x37, 0x83, 0x0e, 0x83, 0x89, 0xf2, 0x7b, + 0x02, 0x5a, 0x2d, 0x65, 0x27, 0xe7, 0x9d, 0x01 } +}, + +{ + 16, 16, 8, 2, + /* key */ + { 0x91, 0x94, 0x5d, 0x3f, 0x4d, 0xcb, 0xee, 0x0b, + 0xf4, 0x5e, 0xf5, 0x22, 0x55, 0xf0, 0x95, 0xa4 }, + /* nonce */ + { 0xbe, 0xca, 0xf0, 0x43, 0xb0, 0xa2, 0x3d, 0x84, + 0x31, 0x94, 0xba, 0x97, 0x2c, 0x66, 0xde, 0xbd }, + /* header */ + { 0xfa, 0x3b, 0xfd, 0x48, 0x06, 0xeb, 0x53, 0xfa }, + /* PT */ + { 0xf7, 0xfb }, + /* CT */ + { 0x19, 0xdd }, + /* tag */ + { 0x5c, 0x4c, 0x93, 0x31, 0x04, 0x9d, 0x0b, 0xda, + 0xb0, 0x27, 0x74, 0x08, 0xf6, 0x79, 0x67, 0xe5 } +}, + +{ + 16, 16, 8, 5, + /* key */ + { 0x01, 0xf7, 0x4a, 0xd6, 0x40, 0x77, 0xf2, 0xe7, + 0x04, 0xc0, 0xf6, 0x0a, 0xda, 0x3d, 0xd5, 0x23 }, + /* nonce */ + { 0x70, 0xc3, 0xdb, 0x4f, 0x0d, 0x26, 0x36, 0x84, + 0x00, 0xa1, 0x0e, 0xd0, 0x5d, 0x2b, 0xff, 0x5e }, + /* header */ + { 0x23, 0x4a, 0x34, 0x63, 0xc1, 0x26, 0x4a, 0xc6 }, + /* PT */ + { 0x1a, 0x47, 0xcb, 0x49, 0x33 }, + /* CT */ + { 0xd8, 0x51, 0xd5, 0xba, 0xe0 }, + /* Tag */ + { 0x3a, 0x59, 0xf2, 0x38, 0xa2, 0x3e, 0x39, 0x19, + 0x9d, 0xc9, 0x26, 0x66, 0x26, 0xc4, 0x0f, 0x80 } +} + +}; + int err, x, idx, res; + unsigned long len; + unsigned char outct[MAXBLOCKSIZE], outtag[MAXBLOCKSIZE]; + + /* AES can be under rijndael or aes... try to find it */ + if ((idx = find_cipher("aes")) == -1) { + if ((idx = find_cipher("rijndael")) == -1) { + return CRYPT_NOP; + } + } + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + len = sizeof(outtag); + if ((err = eax_encrypt_authenticate_memory(idx, tests[x].key, tests[x].keylen, + tests[x].nonce, tests[x].noncelen, tests[x].header, tests[x].headerlen, + tests[x].plaintext, tests[x].msglen, outct, outtag, &len)) != CRYPT_OK) { + return err; + } + if (XMEMCMP(outct, tests[x].ciphertext, tests[x].msglen) || XMEMCMP(outtag, tests[x].tag, len)) { +#if 0 + unsigned long y; + printf("\n\nFailure: \nCT:\n"); + for (y = 0; y < (unsigned long)tests[x].msglen; ) { + printf("0x%02x", outct[y]); + if (y < (unsigned long)(tests[x].msglen-1)) printf(", "); + if (!(++y % 8)) printf("\n"); + } + printf("\nTAG:\n"); + for (y = 0; y < len; ) { + printf("0x%02x", outtag[y]); + if (y < len-1) printf(", "); + if (!(++y % 8)) printf("\n"); + } +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + /* test decrypt */ + if ((err = eax_decrypt_verify_memory(idx, tests[x].key, tests[x].keylen, + tests[x].nonce, tests[x].noncelen, tests[x].header, tests[x].headerlen, + outct, tests[x].msglen, outct, outtag, len, &res)) != CRYPT_OK) { + return err; + } + if ((res != 1) || XMEMCMP(outct, tests[x].plaintext, tests[x].msglen)) { +#if 0 + unsigned long y; + printf("\n\nFailure (res == %d): \nPT:\n", res); + for (y = 0; y < (unsigned long)tests[x].msglen; ) { + printf("0x%02x", outct[y]); + if (y < (unsigned long)(tests[x].msglen-1)) printf(", "); + if (!(++y % 8)) printf("\n"); + } + printf("\n\n"); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + } + return CRYPT_OK; +#endif /* LTC_TEST */ +} + +#endif /* LTC_EAX_MODE */ + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_test.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_add_aad.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_add_aad.c new file mode 100644 index 0000000000..69c88fb15f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_add_aad.c @@ -0,0 +1,124 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file gcm_add_aad.c + GCM implementation, Add AAD data to the stream, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_GCM_MODE + +/** + Add AAD to the GCM state + @param gcm The GCM state + @param adata The additional authentication data to add to the GCM state + @param adatalen The length of the AAD data. + @return CRYPT_OK on success + */ +int gcm_add_aad(gcm_state *gcm, + const unsigned char *adata, unsigned long adatalen) +{ + unsigned long x; + int err; +#ifdef LTC_FAST + unsigned long y; +#endif + + LTC_ARGCHK(gcm != NULL); + if (adatalen > 0) { + LTC_ARGCHK(adata != NULL); + } + + if (gcm->buflen > 16 || gcm->buflen < 0) { + return CRYPT_INVALID_ARG; + } + + if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) { + return err; + } + + /* in IV mode? */ + if (gcm->mode == LTC_GCM_MODE_IV) { + /* let's process the IV */ + if (gcm->ivmode || gcm->buflen != 12) { + for (x = 0; x < (unsigned long)gcm->buflen; x++) { + gcm->X[x] ^= gcm->buf[x]; + } + if (gcm->buflen) { + gcm->totlen += gcm->buflen * CONST64(8); + gcm_mult_h(gcm, gcm->X); + } + + /* mix in the length */ + zeromem(gcm->buf, 8); + STORE64H(gcm->totlen, gcm->buf+8); + for (x = 0; x < 16; x++) { + gcm->X[x] ^= gcm->buf[x]; + } + gcm_mult_h(gcm, gcm->X); + + /* copy counter out */ + XMEMCPY(gcm->Y, gcm->X, 16); + zeromem(gcm->X, 16); + } else { + XMEMCPY(gcm->Y, gcm->buf, 12); + gcm->Y[12] = 0; + gcm->Y[13] = 0; + gcm->Y[14] = 0; + gcm->Y[15] = 1; + } + XMEMCPY(gcm->Y_0, gcm->Y, 16); + zeromem(gcm->buf, 16); + gcm->buflen = 0; + gcm->totlen = 0; + gcm->mode = LTC_GCM_MODE_AAD; + } + + if (gcm->mode != LTC_GCM_MODE_AAD || gcm->buflen >= 16) { + return CRYPT_INVALID_ARG; + } + + x = 0; +#ifdef LTC_FAST + if (gcm->buflen == 0) { + for (x = 0; x < (adatalen & ~15); x += 16) { + for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&adata[x + y])); + } + gcm_mult_h(gcm, gcm->X); + gcm->totlen += 128; + } + adata += x; + } +#endif + + + /* start adding AAD data to the state */ + for (; x < adatalen; x++) { + gcm->X[gcm->buflen++] ^= *adata++; + + if (gcm->buflen == 16) { + /* GF mult it */ + gcm_mult_h(gcm, gcm->X); + gcm->buflen = 0; + gcm->totlen += 128; + } + } + + return CRYPT_OK; +} +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_add_aad.c,v $ */ +/* $Revision: 1.18 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_add_iv.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_add_iv.c new file mode 100644 index 0000000000..a66911f38e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_add_iv.c @@ -0,0 +1,94 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file gcm_add_iv.c + GCM implementation, add IV data to the state, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_GCM_MODE + +/** + Add IV data to the GCM state + @param gcm The GCM state + @param IV The initial value data to add + @param IVlen The length of the IV + @return CRYPT_OK on success + */ +int gcm_add_iv(gcm_state *gcm, + const unsigned char *IV, unsigned long IVlen) +{ + unsigned long x, y; + int err; + + LTC_ARGCHK(gcm != NULL); + if (IVlen > 0) { + LTC_ARGCHK(IV != NULL); + } + + /* must be in IV mode */ + if (gcm->mode != LTC_GCM_MODE_IV) { + return CRYPT_INVALID_ARG; + } + + if (gcm->buflen >= 16 || gcm->buflen < 0) { + return CRYPT_INVALID_ARG; + } + + if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) { + return err; + } + + + /* trip the ivmode flag */ + if (IVlen + gcm->buflen > 12) { + gcm->ivmode |= 1; + } + + x = 0; +#ifdef LTC_FAST + if (gcm->buflen == 0) { + for (x = 0; x < (IVlen & ~15); x += 16) { + for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&IV[x + y])); + } + gcm_mult_h(gcm, gcm->X); + gcm->totlen += 128; + } + IV += x; + } +#endif + + /* start adding IV data to the state */ + for (; x < IVlen; x++) { + gcm->buf[gcm->buflen++] = *IV++; + + if (gcm->buflen == 16) { + /* GF mult it */ + for (y = 0; y < 16; y++) { + gcm->X[y] ^= gcm->buf[y]; + } + gcm_mult_h(gcm, gcm->X); + gcm->buflen = 0; + gcm->totlen += 128; + } + } + + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_add_iv.c,v $ */ +/* $Revision: 1.9 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_done.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_done.c new file mode 100644 index 0000000000..29dcdb9a54 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_done.c @@ -0,0 +1,83 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file gcm_done.c + GCM implementation, Terminate the stream, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_GCM_MODE + +/** + Terminate a GCM stream + @param gcm The GCM state + @param tag [out] The destination for the MAC tag + @param taglen [in/out] The length of the MAC tag + @return CRYPT_OK on success + */ +int gcm_done(gcm_state *gcm, + unsigned char *tag, unsigned long *taglen) +{ + unsigned long x; + int err; + + LTC_ARGCHK(gcm != NULL); + LTC_ARGCHK(tag != NULL); + LTC_ARGCHK(taglen != NULL); + + if (gcm->buflen > 16 || gcm->buflen < 0) { + return CRYPT_INVALID_ARG; + } + + if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) { + return err; + } + + + if (gcm->mode != LTC_GCM_MODE_TEXT) { + return CRYPT_INVALID_ARG; + } + + /* handle remaining ciphertext */ + if (gcm->buflen) { + gcm->pttotlen += gcm->buflen * CONST64(8); + gcm_mult_h(gcm, gcm->X); + } + + /* length */ + STORE64H(gcm->totlen, gcm->buf); + STORE64H(gcm->pttotlen, gcm->buf+8); + for (x = 0; x < 16; x++) { + gcm->X[x] ^= gcm->buf[x]; + } + gcm_mult_h(gcm, gcm->X); + + /* encrypt original counter */ + if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y_0, gcm->buf, &gcm->K)) != CRYPT_OK) { + return err; + } + for (x = 0; x < 16 && x < *taglen; x++) { + tag[x] = gcm->buf[x] ^ gcm->X[x]; + } + *taglen = x; + + cipher_descriptor[gcm->cipher].done(&gcm->K); + + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_done.c,v $ */ +/* $Revision: 1.11 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_gf_mult.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_gf_mult.c new file mode 100644 index 0000000000..2e6b3950e4 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_gf_mult.c @@ -0,0 +1,220 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file gcm_gf_mult.c + GCM implementation, do the GF mult, by Tom St Denis +*/ +#include "tomcrypt.h" + +#if defined(LTC_GCM_TABLES) || defined(LRW_TABLES) || ((defined(LTC_GCM_MODE) || defined(LTC_GCM_MODE)) && defined(LTC_FAST)) + +/* this is x*2^128 mod p(x) ... the results are 16 bytes each stored in a packed format. Since only the + * lower 16 bits are not zero'ed I removed the upper 14 bytes */ +const unsigned char gcm_shift_table[256*2] = { +0x00, 0x00, 0x01, 0xc2, 0x03, 0x84, 0x02, 0x46, 0x07, 0x08, 0x06, 0xca, 0x04, 0x8c, 0x05, 0x4e, +0x0e, 0x10, 0x0f, 0xd2, 0x0d, 0x94, 0x0c, 0x56, 0x09, 0x18, 0x08, 0xda, 0x0a, 0x9c, 0x0b, 0x5e, +0x1c, 0x20, 0x1d, 0xe2, 0x1f, 0xa4, 0x1e, 0x66, 0x1b, 0x28, 0x1a, 0xea, 0x18, 0xac, 0x19, 0x6e, +0x12, 0x30, 0x13, 0xf2, 0x11, 0xb4, 0x10, 0x76, 0x15, 0x38, 0x14, 0xfa, 0x16, 0xbc, 0x17, 0x7e, +0x38, 0x40, 0x39, 0x82, 0x3b, 0xc4, 0x3a, 0x06, 0x3f, 0x48, 0x3e, 0x8a, 0x3c, 0xcc, 0x3d, 0x0e, +0x36, 0x50, 0x37, 0x92, 0x35, 0xd4, 0x34, 0x16, 0x31, 0x58, 0x30, 0x9a, 0x32, 0xdc, 0x33, 0x1e, +0x24, 0x60, 0x25, 0xa2, 0x27, 0xe4, 0x26, 0x26, 0x23, 0x68, 0x22, 0xaa, 0x20, 0xec, 0x21, 0x2e, +0x2a, 0x70, 0x2b, 0xb2, 0x29, 0xf4, 0x28, 0x36, 0x2d, 0x78, 0x2c, 0xba, 0x2e, 0xfc, 0x2f, 0x3e, +0x70, 0x80, 0x71, 0x42, 0x73, 0x04, 0x72, 0xc6, 0x77, 0x88, 0x76, 0x4a, 0x74, 0x0c, 0x75, 0xce, +0x7e, 0x90, 0x7f, 0x52, 0x7d, 0x14, 0x7c, 0xd6, 0x79, 0x98, 0x78, 0x5a, 0x7a, 0x1c, 0x7b, 0xde, +0x6c, 0xa0, 0x6d, 0x62, 0x6f, 0x24, 0x6e, 0xe6, 0x6b, 0xa8, 0x6a, 0x6a, 0x68, 0x2c, 0x69, 0xee, +0x62, 0xb0, 0x63, 0x72, 0x61, 0x34, 0x60, 0xf6, 0x65, 0xb8, 0x64, 0x7a, 0x66, 0x3c, 0x67, 0xfe, +0x48, 0xc0, 0x49, 0x02, 0x4b, 0x44, 0x4a, 0x86, 0x4f, 0xc8, 0x4e, 0x0a, 0x4c, 0x4c, 0x4d, 0x8e, +0x46, 0xd0, 0x47, 0x12, 0x45, 0x54, 0x44, 0x96, 0x41, 0xd8, 0x40, 0x1a, 0x42, 0x5c, 0x43, 0x9e, +0x54, 0xe0, 0x55, 0x22, 0x57, 0x64, 0x56, 0xa6, 0x53, 0xe8, 0x52, 0x2a, 0x50, 0x6c, 0x51, 0xae, +0x5a, 0xf0, 0x5b, 0x32, 0x59, 0x74, 0x58, 0xb6, 0x5d, 0xf8, 0x5c, 0x3a, 0x5e, 0x7c, 0x5f, 0xbe, +0xe1, 0x00, 0xe0, 0xc2, 0xe2, 0x84, 0xe3, 0x46, 0xe6, 0x08, 0xe7, 0xca, 0xe5, 0x8c, 0xe4, 0x4e, +0xef, 0x10, 0xee, 0xd2, 0xec, 0x94, 0xed, 0x56, 0xe8, 0x18, 0xe9, 0xda, 0xeb, 0x9c, 0xea, 0x5e, +0xfd, 0x20, 0xfc, 0xe2, 0xfe, 0xa4, 0xff, 0x66, 0xfa, 0x28, 0xfb, 0xea, 0xf9, 0xac, 0xf8, 0x6e, +0xf3, 0x30, 0xf2, 0xf2, 0xf0, 0xb4, 0xf1, 0x76, 0xf4, 0x38, 0xf5, 0xfa, 0xf7, 0xbc, 0xf6, 0x7e, +0xd9, 0x40, 0xd8, 0x82, 0xda, 0xc4, 0xdb, 0x06, 0xde, 0x48, 0xdf, 0x8a, 0xdd, 0xcc, 0xdc, 0x0e, +0xd7, 0x50, 0xd6, 0x92, 0xd4, 0xd4, 0xd5, 0x16, 0xd0, 0x58, 0xd1, 0x9a, 0xd3, 0xdc, 0xd2, 0x1e, +0xc5, 0x60, 0xc4, 0xa2, 0xc6, 0xe4, 0xc7, 0x26, 0xc2, 0x68, 0xc3, 0xaa, 0xc1, 0xec, 0xc0, 0x2e, +0xcb, 0x70, 0xca, 0xb2, 0xc8, 0xf4, 0xc9, 0x36, 0xcc, 0x78, 0xcd, 0xba, 0xcf, 0xfc, 0xce, 0x3e, +0x91, 0x80, 0x90, 0x42, 0x92, 0x04, 0x93, 0xc6, 0x96, 0x88, 0x97, 0x4a, 0x95, 0x0c, 0x94, 0xce, +0x9f, 0x90, 0x9e, 0x52, 0x9c, 0x14, 0x9d, 0xd6, 0x98, 0x98, 0x99, 0x5a, 0x9b, 0x1c, 0x9a, 0xde, +0x8d, 0xa0, 0x8c, 0x62, 0x8e, 0x24, 0x8f, 0xe6, 0x8a, 0xa8, 0x8b, 0x6a, 0x89, 0x2c, 0x88, 0xee, +0x83, 0xb0, 0x82, 0x72, 0x80, 0x34, 0x81, 0xf6, 0x84, 0xb8, 0x85, 0x7a, 0x87, 0x3c, 0x86, 0xfe, +0xa9, 0xc0, 0xa8, 0x02, 0xaa, 0x44, 0xab, 0x86, 0xae, 0xc8, 0xaf, 0x0a, 0xad, 0x4c, 0xac, 0x8e, +0xa7, 0xd0, 0xa6, 0x12, 0xa4, 0x54, 0xa5, 0x96, 0xa0, 0xd8, 0xa1, 0x1a, 0xa3, 0x5c, 0xa2, 0x9e, +0xb5, 0xe0, 0xb4, 0x22, 0xb6, 0x64, 0xb7, 0xa6, 0xb2, 0xe8, 0xb3, 0x2a, 0xb1, 0x6c, 0xb0, 0xae, +0xbb, 0xf0, 0xba, 0x32, 0xb8, 0x74, 0xb9, 0xb6, 0xbc, 0xf8, 0xbd, 0x3a, 0xbf, 0x7c, 0xbe, 0xbe }; + +#endif + + +#if defined(LTC_GCM_MODE) || defined(LRW_MODE) + +#ifndef LTC_FAST +/* right shift */ +static void gcm_rightshift(unsigned char *a) +{ + int x; + for (x = 15; x > 0; x--) { + a[x] = (a[x]>>1) | ((a[x-1]<<7)&0x80); + } + a[0] >>= 1; +} + +/* c = b*a */ +static const unsigned char mask[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; +static const unsigned char poly[] = { 0x00, 0xE1 }; + + +/** + GCM GF multiplier (internal use only) bitserial + @param a First value + @param b Second value + @param c Destination for a * b + */ +void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c) +{ + unsigned char Z[16], V[16]; + unsigned x, y, z; + + zeromem(Z, 16); + XMEMCPY(V, a, 16); + for (x = 0; x < 128; x++) { + if (b[x>>3] & mask[x&7]) { + for (y = 0; y < 16; y++) { + Z[y] ^= V[y]; + } + } + z = V[15] & 0x01; + gcm_rightshift(V); + V[0] ^= poly[z]; + } + XMEMCPY(c, Z, 16); +} + +#else + +/* map normal numbers to "ieee" way ... e.g. bit reversed */ +#define M(x) ( ((x&8)>>3) | ((x&4)>>1) | ((x&2)<<1) | ((x&1)<<3) ) + +#define BPD (sizeof(LTC_FAST_TYPE) * 8) +#define WPV (1 + (16 / sizeof(LTC_FAST_TYPE))) + +/** + GCM GF multiplier (internal use only) word oriented + @param a First value + @param b Second value + @param c Destination for a * b + */ +void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c) +{ + int i, j, k, u; + LTC_FAST_TYPE B[16][WPV], tmp[32 / sizeof(LTC_FAST_TYPE)], pB[16 / sizeof(LTC_FAST_TYPE)], zz, z; + unsigned char pTmp[32]; + + /* create simple tables */ + zeromem(B[0], sizeof(B[0])); + zeromem(B[M(1)], sizeof(B[M(1)])); + +#ifdef ENDIAN_32BITWORD + for (i = 0; i < 4; i++) { + LOAD32H(B[M(1)][i], a + (i<<2)); + LOAD32L(pB[i], b + (i<<2)); + } +#else + for (i = 0; i < 2; i++) { + LOAD64H(B[M(1)][i], a + (i<<3)); + LOAD64L(pB[i], b + (i<<3)); + } +#endif + + /* now create 2, 4 and 8 */ + B[M(2)][0] = B[M(1)][0] >> 1; + B[M(4)][0] = B[M(1)][0] >> 2; + B[M(8)][0] = B[M(1)][0] >> 3; + for (i = 1; i < (int)WPV; i++) { + B[M(2)][i] = (B[M(1)][i-1] << (BPD-1)) | (B[M(1)][i] >> 1); + B[M(4)][i] = (B[M(1)][i-1] << (BPD-2)) | (B[M(1)][i] >> 2); + B[M(8)][i] = (B[M(1)][i-1] << (BPD-3)) | (B[M(1)][i] >> 3); + } + + /* now all values with two bits which are 3, 5, 6, 9, 10, 12 */ + for (i = 0; i < (int)WPV; i++) { + B[M(3)][i] = B[M(1)][i] ^ B[M(2)][i]; + B[M(5)][i] = B[M(1)][i] ^ B[M(4)][i]; + B[M(6)][i] = B[M(2)][i] ^ B[M(4)][i]; + B[M(9)][i] = B[M(1)][i] ^ B[M(8)][i]; + B[M(10)][i] = B[M(2)][i] ^ B[M(8)][i]; + B[M(12)][i] = B[M(8)][i] ^ B[M(4)][i]; + + /* now all 3 bit values and the only 4 bit value: 7, 11, 13, 14, 15 */ + B[M(7)][i] = B[M(3)][i] ^ B[M(4)][i]; + B[M(11)][i] = B[M(3)][i] ^ B[M(8)][i]; + B[M(13)][i] = B[M(1)][i] ^ B[M(12)][i]; + B[M(14)][i] = B[M(6)][i] ^ B[M(8)][i]; + B[M(15)][i] = B[M(7)][i] ^ B[M(8)][i]; + } + + zeromem(tmp, sizeof(tmp)); + + /* compute product four bits of each word at a time */ + /* for each nibble */ + for (i = (BPD/4)-1; i >= 0; i--) { + /* for each word */ + for (j = 0; j < (int)(WPV-1); j++) { + /* grab the 4 bits recall the nibbles are backwards so it's a shift by (i^1)*4 */ + u = (pB[j] >> ((i^1)<<2)) & 15; + + /* add offset by the word count the table looked up value to the result */ + for (k = 0; k < (int)WPV; k++) { + tmp[k+j] ^= B[u][k]; + } + } + /* shift result up by 4 bits */ + if (i != 0) { + for (z = j = 0; j < (int)(32 / sizeof(LTC_FAST_TYPE)); j++) { + zz = tmp[j] << (BPD-4); + tmp[j] = (tmp[j] >> 4) | z; + z = zz; + } + } + } + + /* store product */ +#ifdef ENDIAN_32BITWORD + for (i = 0; i < 8; i++) { + STORE32H(tmp[i], pTmp + (i<<2)); + } +#else + for (i = 0; i < 4; i++) { + STORE64H(tmp[i], pTmp + (i<<3)); + } +#endif + + /* reduce by taking most significant byte and adding the appropriate two byte sequence 16 bytes down */ + for (i = 31; i >= 16; i--) { + pTmp[i-16] ^= gcm_shift_table[((unsigned)pTmp[i]<<1)]; + pTmp[i-15] ^= gcm_shift_table[((unsigned)pTmp[i]<<1)+1]; + } + + for (i = 0; i < 16; i++) { + c[i] = pTmp[i]; + } + +} + +#endif + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_gf_mult.c,v $ */ +/* $Revision: 1.25 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_init.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_init.c new file mode 100644 index 0000000000..78c76574e5 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_init.c @@ -0,0 +1,107 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file gcm_init.c + GCM implementation, initialize state, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_GCM_MODE + +/** + Initialize a GCM state + @param gcm The GCM state to initialize + @param cipher The index of the cipher to use + @param key The secret key + @param keylen The length of the secret key + @return CRYPT_OK on success + */ +int gcm_init(gcm_state *gcm, int cipher, + const unsigned char *key, int keylen) +{ + int err; + unsigned char B[16]; +#ifdef LTC_GCM_TABLES + int x, y, z, t; +#endif + + LTC_ARGCHK(gcm != NULL); + LTC_ARGCHK(key != NULL); + +#ifdef LTC_FAST + if (16 % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + + /* is cipher valid? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + if (cipher_descriptor[cipher].block_length != 16) { + return CRYPT_INVALID_CIPHER; + } + + /* schedule key */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &gcm->K)) != CRYPT_OK) { + return err; + } + + /* H = E(0) */ + zeromem(B, 16); + if ((err = cipher_descriptor[cipher].ecb_encrypt(B, gcm->H, &gcm->K)) != CRYPT_OK) { + return err; + } + + /* setup state */ + zeromem(gcm->buf, sizeof(gcm->buf)); + zeromem(gcm->X, sizeof(gcm->X)); + gcm->cipher = cipher; + gcm->mode = LTC_GCM_MODE_IV; + gcm->ivmode = 0; + gcm->buflen = 0; + gcm->totlen = 0; + gcm->pttotlen = 0; + +#ifdef LTC_GCM_TABLES + /* setup tables */ + + /* generate the first table as it has no shifting (from which we make the other tables) */ + zeromem(B, 16); + for (y = 0; y < 256; y++) { + B[0] = y; + gcm_gf_mult(gcm->H, B, &gcm->PC[0][y][0]); + } + + /* now generate the rest of the tables based the previous table */ + for (x = 1; x < 16; x++) { + for (y = 0; y < 256; y++) { + /* now shift it right by 8 bits */ + t = gcm->PC[x-1][y][15]; + for (z = 15; z > 0; z--) { + gcm->PC[x][y][z] = gcm->PC[x-1][y][z-1]; + } + gcm->PC[x][y][0] = gcm_shift_table[t<<1]; + gcm->PC[x][y][1] ^= gcm_shift_table[(t<<1)+1]; + } + } + +#endif + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_init.c,v $ */ +/* $Revision: 1.20 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_memory.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_memory.c new file mode 100644 index 0000000000..324e75baa8 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_memory.c @@ -0,0 +1,109 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file gcm_memory.c + GCM implementation, process a packet, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_GCM_MODE + +/** + Process an entire GCM packet in one call. + @param cipher Index of cipher to use + @param key The secret key + @param keylen The length of the secret key + @param IV The initial vector + @param IVlen The length of the initial vector + @param adata The additional authentication data (header) + @param adatalen The length of the adata + @param pt The plaintext + @param ptlen The length of the plaintext (ciphertext length is the same) + @param ct The ciphertext + @param tag [out] The MAC tag + @param taglen [in/out] The MAC tag length + @param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT) + @return CRYPT_OK on success + */ +int gcm_memory( int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *IV, unsigned long IVlen, + const unsigned char *adata, unsigned long adatalen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction) +{ + void *orig; + gcm_state *gcm; + int err; + + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + if (cipher_descriptor[cipher].accel_gcm_memory != NULL) { + return + cipher_descriptor[cipher].accel_gcm_memory + (key, keylen, + IV, IVlen, + adata, adatalen, + pt, ptlen, + ct, + tag, taglen, + direction); + } + + + +#ifndef LTC_GCM_TABLES_SSE2 + orig = gcm = XMALLOC(sizeof(*gcm)); +#else + orig = gcm = XMALLOC(sizeof(*gcm) + 16); +#endif + if (gcm == NULL) { + return CRYPT_MEM; + } + + /* Force GCM to be on a multiple of 16 so we can use 128-bit aligned operations + * note that we only modify gcm and keep orig intact. This code is not portable + * but again it's only for SSE2 anyways, so who cares? + */ +#ifdef LTC_GCM_TABLES_SSE2 + if ((unsigned long)gcm & 15) { + gcm = (gcm_state *)((unsigned long)gcm + (16 - ((unsigned long)gcm & 15))); + } +#endif + + if ((err = gcm_init(gcm, cipher, key, keylen)) != CRYPT_OK) { + goto LTC_ERR; + } + if ((err = gcm_add_iv(gcm, IV, IVlen)) != CRYPT_OK) { + goto LTC_ERR; + } + if ((err = gcm_add_aad(gcm, adata, adatalen)) != CRYPT_OK) { + goto LTC_ERR; + } + if ((err = gcm_process(gcm, pt, ptlen, ct, direction)) != CRYPT_OK) { + goto LTC_ERR; + } + err = gcm_done(gcm, tag, taglen); +LTC_ERR: + XFREE(orig); + return err; +} +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_memory.c,v $ */ +/* $Revision: 1.25 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_mult_h.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_mult_h.c new file mode 100644 index 0000000000..e86b183abc --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_mult_h.c @@ -0,0 +1,58 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file gcm_mult_h.c + GCM implementation, do the GF mult, by Tom St Denis +*/ +#include "tomcrypt.h" + +#if defined(LTC_GCM_MODE) +/** + GCM multiply by H + @param gcm The GCM state which holds the H value + @param I The value to multiply H by + */ +void gcm_mult_h(gcm_state *gcm, unsigned char *I) +{ + unsigned char T[16]; +#ifdef LTC_GCM_TABLES + int x, y; +#ifdef LTC_GCM_TABLES_SSE2 + asm("movdqa (%0),%%xmm0"::"r"(&gcm->PC[0][I[0]][0])); + for (x = 1; x < 16; x++) { + asm("pxor (%0),%%xmm0"::"r"(&gcm->PC[x][I[x]][0])); + } + asm("movdqa %%xmm0,(%0)"::"r"(&T)); +#else + XMEMCPY(T, &gcm->PC[0][I[0]][0], 16); + for (x = 1; x < 16; x++) { +#ifdef LTC_FAST + for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE *)(T + y)) ^= *((LTC_FAST_TYPE *)(&gcm->PC[x][I[x]][y])); + } +#else + for (y = 0; y < 16; y++) { + T[y] ^= gcm->PC[x][I[x]][y]; + } +#endif /* LTC_FAST */ + } +#endif /* LTC_GCM_TABLES_SSE2 */ +#else + gcm_gf_mult(gcm->H, I, T); +#endif + XMEMCPY(I, T, 16); +} +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_mult_h.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_process.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_process.c new file mode 100644 index 0000000000..97c7f65a8d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_process.c @@ -0,0 +1,152 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file gcm_process.c + GCM implementation, process message data, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_GCM_MODE + +/** + Process plaintext/ciphertext through GCM + @param gcm The GCM state + @param pt The plaintext + @param ptlen The plaintext length (ciphertext length is the same) + @param ct The ciphertext + @param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT) + @return CRYPT_OK on success + */ +int gcm_process(gcm_state *gcm, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + int direction) +{ + unsigned long x; + int y, err; + unsigned char b; + + LTC_ARGCHK(gcm != NULL); + if (ptlen > 0) { + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + } + + if (gcm->buflen > 16 || gcm->buflen < 0) { + return CRYPT_INVALID_ARG; + } + + if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) { + return err; + } + + /* in AAD mode? */ + if (gcm->mode == LTC_GCM_MODE_AAD) { + /* let's process the AAD */ + if (gcm->buflen) { + gcm->totlen += gcm->buflen * CONST64(8); + gcm_mult_h(gcm, gcm->X); + } + + /* increment counter */ + for (y = 15; y >= 12; y--) { + if (++gcm->Y[y] & 255) { break; } + } + /* encrypt the counter */ + if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { + return err; + } + + gcm->buflen = 0; + gcm->mode = LTC_GCM_MODE_TEXT; + } + + if (gcm->mode != LTC_GCM_MODE_TEXT) { + return CRYPT_INVALID_ARG; + } + + x = 0; +#ifdef LTC_FAST + if (gcm->buflen == 0) { + if (direction == GCM_ENCRYPT) { + for (x = 0; x < (ptlen & ~15); x += 16) { + /* ctr encrypt */ + for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)(&ct[x + y])) = *((LTC_FAST_TYPE*)(&pt[x+y])) ^ *((LTC_FAST_TYPE*)(&gcm->buf[y])); + *((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&ct[x+y])); + } + /* GMAC it */ + gcm->pttotlen += 128; + gcm_mult_h(gcm, gcm->X); + /* increment counter */ + for (y = 15; y >= 12; y--) { + if (++gcm->Y[y] & 255) { break; } + } + if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { + return err; + } + } + } else { + for (x = 0; x < (ptlen & ~15); x += 16) { + /* ctr encrypt */ + for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&ct[x+y])); + *((LTC_FAST_TYPE*)(&pt[x + y])) = *((LTC_FAST_TYPE*)(&ct[x+y])) ^ *((LTC_FAST_TYPE*)(&gcm->buf[y])); + } + /* GMAC it */ + gcm->pttotlen += 128; + gcm_mult_h(gcm, gcm->X); + /* increment counter */ + for (y = 15; y >= 12; y--) { + if (++gcm->Y[y] & 255) { break; } + } + if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { + return err; + } + } + } + } +#endif + + /* process text */ + for (; x < ptlen; x++) { + if (gcm->buflen == 16) { + gcm->pttotlen += 128; + gcm_mult_h(gcm, gcm->X); + + /* increment counter */ + for (y = 15; y >= 12; y--) { + if (++gcm->Y[y] & 255) { break; } + } + if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { + return err; + } + gcm->buflen = 0; + } + + if (direction == GCM_ENCRYPT) { + b = ct[x] = pt[x] ^ gcm->buf[gcm->buflen]; + } else { + b = ct[x]; + pt[x] = ct[x] ^ gcm->buf[gcm->buflen]; + } + gcm->X[gcm->buflen++] ^= b; + } + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_process.c,v $ */ +/* $Revision: 1.16 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_reset.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_reset.c new file mode 100644 index 0000000000..ea13cda6bf --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_reset.c @@ -0,0 +1,44 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file gcm_reset.c + GCM implementation, reset a used state so it can accept IV data, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_GCM_MODE + +/** + Reset a GCM state to as if you just called gcm_init(). This saves the initialization time. + @param gcm The GCM state to reset + @return CRYPT_OK on success +*/ +int gcm_reset(gcm_state *gcm) +{ + LTC_ARGCHK(gcm != NULL); + + zeromem(gcm->buf, sizeof(gcm->buf)); + zeromem(gcm->X, sizeof(gcm->X)); + gcm->mode = LTC_GCM_MODE_IV; + gcm->ivmode = 0; + gcm->buflen = 0; + gcm->totlen = 0; + gcm->pttotlen = 0; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_reset.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_test.c new file mode 100644 index 0000000000..2585c5aaa0 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/gcm/gcm_test.c @@ -0,0 +1,413 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file gcm_test.c + GCM implementation, testing, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_GCM_MODE + +/** + Test the GCM code + @return CRYPT_OK on success + */ +int gcm_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + unsigned char K[32]; + int keylen; + unsigned char P[128]; + unsigned long ptlen; + unsigned char A[128]; + unsigned long alen; + unsigned char IV[128]; + unsigned long IVlen; + unsigned char C[128]; + unsigned char T[16]; + } tests[] = { + +/* test case #1 */ +{ + /* key */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + 16, + + /* plaintext */ + { 0 }, + 0, + + /* AAD data */ + { 0 }, + 0, + + /* IV */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }, + 12, + + /* ciphertext */ + { 0 }, + + /* tag */ + { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, + 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a } +}, + +/* test case #2 */ +{ + /* key */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + 16, + + /* PT */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + 16, + + /* ADATA */ + { 0 }, + 0, + + /* IV */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }, + 12, + + /* CT */ + { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, + 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 }, + + /* TAG */ + { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, + 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf } +}, + +/* test case #3 */ +{ + /* key */ + { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, }, + 16, + + /* PT */ + { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, }, + 64, + + /* ADATA */ + { 0 }, + 0, + + /* IV */ + { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88, }, + 12, + + /* CT */ + { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85, }, + + /* TAG */ + { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, + 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4, } +}, + +/* test case #4 */ +{ + /* key */ + { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, }, + 16, + + /* PT */ + { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, }, + 60, + + /* ADATA */ + { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, }, + 20, + + /* IV */ + { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88, }, + 12, + + /* CT */ + { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91, }, + + /* TAG */ + { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, + 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47, } + +}, + +/* test case #5 */ +{ + /* key */ + { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, }, + 16, + + /* PT */ + { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, }, + 60, + + /* ADATA */ + { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, }, + 20, + + /* IV */ + { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, }, + 8, + + /* CT */ + { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, + 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, + 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, + 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23, + 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, + 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, + 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07, + 0xc2, 0x3f, 0x45, 0x98, }, + + /* TAG */ + { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, + 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb, } +}, + +/* test case #6 */ +{ + /* key */ + { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, }, + 16, + + /* PT */ + { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, }, + 60, + + /* ADATA */ + { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, }, + 20, + + /* IV */ + { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, + 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, + 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, + 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, + 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, + 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, + 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, + 0xa6, 0x37, 0xb3, 0x9b, }, + 60, + + /* CT */ + { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, + 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, + 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, + 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7, + 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, + 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, + 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03, + 0x4c, 0x34, 0xae, 0xe5, }, + + /* TAG */ + { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, + 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50, } +}, + +/* test case #46 from BG (catches the LTC bug of v1.15) */ +{ + /* key */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + 16, + + /* PT */ + { 0xa2, 0xaa, 0xb3, 0xad, 0x8b, 0x17, 0xac, 0xdd, + 0xa2, 0x88, 0x42, 0x6c, 0xd7, 0xc4, 0x29, 0xb7, + 0xca, 0x86, 0xb7, 0xac, 0xa0, 0x58, 0x09, 0xc7, + 0x0c, 0xe8, 0x2d, 0xb2, 0x57, 0x11, 0xcb, 0x53, + 0x02, 0xeb, 0x27, 0x43, 0xb0, 0x36, 0xf3, 0xd7, + 0x50, 0xd6, 0xcf, 0x0d, 0xc0, 0xac, 0xb9, 0x29, + 0x50, 0xd5, 0x46, 0xdb, 0x30, 0x8f, 0x93, 0xb4, + 0xff, 0x24, 0x4a, 0xfa, 0x9d, 0xc7, 0x2b, 0xcd, + 0x75, 0x8d, 0x2c }, + 67, + + /* ADATA */ + { 0x68, 0x8e, 0x1a, 0xa9, 0x84, 0xde, 0x92, 0x6d, + 0xc7, 0xb4, 0xc4, 0x7f, 0x44 }, + 13, + + /* IV */ + { 0xb7, 0x21, 0x38, 0xb5, 0xa0, 0x5f, 0xf5, 0x07, + 0x0e, 0x8c, 0xd9, 0x41, 0x83, 0xf7, 0x61, 0xd8 }, + 16, + + /* CT */ + { 0xcb, 0xc8, 0xd2, 0xf1, 0x54, 0x81, 0xa4, 0xcc, + 0x7d, 0xd1, 0xe1, 0x9a, 0xaa, 0x83, 0xde, 0x56, + 0x78, 0x48, 0x3e, 0xc3, 0x59, 0xae, 0x7d, 0xec, + 0x2a, 0xb8, 0xd5, 0x34, 0xe0, 0x90, 0x6f, 0x4b, + 0x46, 0x63, 0xfa, 0xff, 0x58, 0xa8, 0xb2, 0xd7, + 0x33, 0xb8, 0x45, 0xee, 0xf7, 0xc9, 0xb3, 0x31, + 0xe9, 0xe1, 0x0e, 0xb2, 0x61, 0x2c, 0x99, 0x5f, + 0xeb, 0x1a, 0xc1, 0x5a, 0x62, 0x86, 0xcc, 0xe8, + 0xb2, 0x97, 0xa8 }, + + /* TAG */ + { 0x8d, 0x2d, 0x2a, 0x93, 0x72, 0x62, 0x6f, 0x6b, + 0xee, 0x85, 0x80, 0x27, 0x6a, 0x63, 0x66, 0xbf } +} + +/* rest of test cases are the same except AES key size changes... ignored... */ +}; + int idx, err; + unsigned long x, y; + unsigned char out[2][128], T[2][16]; + + /* find aes */ + idx = find_cipher("aes"); + if (idx == -1) { + idx = find_cipher("rijndael"); + if (idx == -1) { + return CRYPT_NOP; + } + } + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + y = sizeof(T[0]); + if ((err = gcm_memory(idx, tests[x].K, tests[x].keylen, + tests[x].IV, tests[x].IVlen, + tests[x].A, tests[x].alen, + (unsigned char*)tests[x].P, tests[x].ptlen, + out[0], T[0], &y, GCM_ENCRYPT)) != CRYPT_OK) { + return err; + } + + if (XMEMCMP(out[0], tests[x].C, tests[x].ptlen)) { +#if 0 + printf("\nCiphertext wrong %lu\n", x); + for (y = 0; y < tests[x].ptlen; y++) { + printf("%02x", out[0][y] & 255); + } + printf("\n"); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + if (XMEMCMP(T[0], tests[x].T, 16)) { +#if 0 + printf("\nTag on plaintext wrong %lu\n", x); + for (y = 0; y < 16; y++) { + printf("%02x", T[0][y] & 255); + } + printf("\n"); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + y = sizeof(T[1]); + if ((err = gcm_memory(idx, tests[x].K, tests[x].keylen, + tests[x].IV, tests[x].IVlen, + tests[x].A, tests[x].alen, + out[1], tests[x].ptlen, + out[0], T[1], &y, GCM_DECRYPT)) != CRYPT_OK) { + return err; + } + + if (XMEMCMP(out[1], tests[x].P, tests[x].ptlen)) { +#if 0 + printf("\nplaintext wrong %lu\n", x); + for (y = 0; y < tests[x].ptlen; y++) { + printf("%02x", out[0][y] & 255); + } + printf("\n"); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + if (XMEMCMP(T[1], tests[x].T, 16)) { +#if 0 + printf("\nTag on ciphertext wrong %lu\n", x); + for (y = 0; y < 16; y++) { + printf("%02x", T[1][y] & 255); + } + printf("\n"); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + } + return CRYPT_OK; +#endif +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_test.c,v $ */ +/* $Revision: 1.22 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_decrypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_decrypt.c new file mode 100644 index 0000000000..914c03774a --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_decrypt.c @@ -0,0 +1,79 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file ocb_decrypt.c + OCB implementation, decrypt data, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_OCB_MODE + +/** + Decrypt a block with OCB. + @param ocb The OCB state + @param ct The ciphertext (length of the block size of the block cipher) + @param pt [out] The plaintext (length of ct) + @return CRYPT_OK if successful +*/ +int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt) +{ + unsigned char Z[MAXBLOCKSIZE], tmp[MAXBLOCKSIZE]; + int err, x; + + LTC_ARGCHK(ocb != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + + /* check if valid cipher */ + if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { + return err; + } + LTC_ARGCHK(cipher_descriptor[ocb->cipher].ecb_decrypt != NULL); + + /* check length */ + if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) { + return CRYPT_INVALID_ARG; + } + + /* Get Z[i] value */ + ocb_shift_xor(ocb, Z); + + /* xor ct in, encrypt, xor Z out */ + for (x = 0; x < ocb->block_len; x++) { + tmp[x] = ct[x] ^ Z[x]; + } + if ((err = cipher_descriptor[ocb->cipher].ecb_decrypt(tmp, pt, &ocb->key)) != CRYPT_OK) { + return err; + } + for (x = 0; x < ocb->block_len; x++) { + pt[x] ^= Z[x]; + } + + /* compute checksum */ + for (x = 0; x < ocb->block_len; x++) { + ocb->checksum[x] ^= pt[x]; + } + + +#ifdef LTC_CLEAN_STACK + zeromem(Z, sizeof(Z)); + zeromem(tmp, sizeof(tmp)); +#endif + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_decrypt.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_decrypt_verify_memory.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_decrypt_verify_memory.c new file mode 100644 index 0000000000..d3d036cd71 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_decrypt_verify_memory.c @@ -0,0 +1,86 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file ocb_decrypt_verify_memory.c + OCB implementation, helper to decrypt block of memory, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_OCB_MODE + +/** + Decrypt and compare the tag with OCB. + @param cipher The index of the cipher desired + @param key The secret key + @param keylen The length of the secret key (octets) + @param nonce The session nonce (length of the block size of the block cipher) + @param ct The ciphertext + @param ctlen The length of the ciphertext (octets) + @param pt [out] The plaintext + @param tag The tag to compare against + @param taglen The length of the tag (octets) + @param stat [out] The result of the tag comparison (1==valid, 0==invalid) + @return CRYPT_OK if successful regardless of the tag comparison +*/ +int ocb_decrypt_verify_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + const unsigned char *tag, unsigned long taglen, + int *stat) +{ + int err; + ocb_state *ocb; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(nonce != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(tag != NULL); + LTC_ARGCHK(stat != NULL); + + /* allocate memory */ + ocb = XMALLOC(sizeof(ocb_state)); + if (ocb == NULL) { + return CRYPT_MEM; + } + + if ((err = ocb_init(ocb, cipher, key, keylen, nonce)) != CRYPT_OK) { + goto LBL_ERR; + } + + while (ctlen > (unsigned long)ocb->block_len) { + if ((err = ocb_decrypt(ocb, ct, pt)) != CRYPT_OK) { + goto LBL_ERR; + } + ctlen -= ocb->block_len; + pt += ocb->block_len; + ct += ocb->block_len; + } + + err = ocb_done_decrypt(ocb, ct, ctlen, pt, tag, taglen, stat); +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(ocb, sizeof(ocb_state)); +#endif + + XFREE(ocb); + + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_decrypt_verify_memory.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_done_decrypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_done_decrypt.c new file mode 100644 index 0000000000..1b9e34658c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_done_decrypt.c @@ -0,0 +1,80 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file ocb_done_decrypt.c + OCB implementation, terminate decryption, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_OCB_MODE + +/** + Terminate a decrypting OCB state + @param ocb The OCB state + @param ct The ciphertext (if any) + @param ctlen The length of the ciphertext (octets) + @param pt [out] The plaintext + @param tag The authentication tag (to compare against) + @param taglen The length of the authentication tag provided + @param stat [out] The result of the tag comparison + @return CRYPT_OK if the process was successful regardless if the tag is valid +*/ +int ocb_done_decrypt(ocb_state *ocb, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + const unsigned char *tag, unsigned long taglen, int *stat) +{ + int err; + unsigned char *tagbuf; + unsigned long tagbuflen; + + LTC_ARGCHK(ocb != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(tag != NULL); + LTC_ARGCHK(stat != NULL); + + /* default to failed */ + *stat = 0; + + /* allocate memory */ + tagbuf = XMALLOC(MAXBLOCKSIZE); + if (tagbuf == NULL) { + return CRYPT_MEM; + } + + tagbuflen = MAXBLOCKSIZE; + if ((err = s_ocb_done(ocb, ct, ctlen, pt, tagbuf, &tagbuflen, 1)) != CRYPT_OK) { + goto LBL_ERR; + } + + if (taglen <= tagbuflen && XMEMCMP(tagbuf, tag, taglen) == 0) { + *stat = 1; + } + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(tagbuf, MAXBLOCKSIZE); +#endif + + XFREE(tagbuf); + + return err; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_done_decrypt.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_done_encrypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_done_encrypt.c new file mode 100644 index 0000000000..0fc15a5e03 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_done_encrypt.c @@ -0,0 +1,46 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file ocb_done_encrypt.c + OCB implementation, terminate encryption, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_OCB_MODE + +/** + Terminate an encryption OCB state + @param ocb The OCB state + @param pt Remaining plaintext (if any) + @param ptlen The length of the plaintext (octets) + @param ct [out] The ciphertext (if any) + @param tag [out] The tag for the OCB stream + @param taglen [in/out] The max size and resulting size of the tag + @return CRYPT_OK if successful +*/ +int ocb_done_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, unsigned char *tag, unsigned long *taglen) +{ + LTC_ARGCHK(ocb != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(tag != NULL); + LTC_ARGCHK(taglen != NULL); + return s_ocb_done(ocb, pt, ptlen, ct, tag, taglen, 0); +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_done_encrypt.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_encrypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_encrypt.c new file mode 100644 index 0000000000..c375b4f918 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_encrypt.c @@ -0,0 +1,72 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file ocb_encrypt.c + OCB implementation, encrypt data, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_OCB_MODE + +/** + Encrypt a block of data with OCB. + @param ocb The OCB state + @param pt The plaintext (length of the block size of the block cipher) + @param ct [out] The ciphertext (same size as the pt) + @return CRYPT_OK if successful +*/ +int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct) +{ + unsigned char Z[MAXBLOCKSIZE], tmp[MAXBLOCKSIZE]; + int err, x; + + LTC_ARGCHK(ocb != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { + return err; + } + if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) { + return CRYPT_INVALID_ARG; + } + + /* compute checksum */ + for (x = 0; x < ocb->block_len; x++) { + ocb->checksum[x] ^= pt[x]; + } + + /* Get Z[i] value */ + ocb_shift_xor(ocb, Z); + + /* xor pt in, encrypt, xor Z out */ + for (x = 0; x < ocb->block_len; x++) { + tmp[x] = pt[x] ^ Z[x]; + } + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, ct, &ocb->key)) != CRYPT_OK) { + return err; + } + for (x = 0; x < ocb->block_len; x++) { + ct[x] ^= Z[x]; + } + +#ifdef LTC_CLEAN_STACK + zeromem(Z, sizeof(Z)); + zeromem(tmp, sizeof(tmp)); +#endif + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_encrypt.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_encrypt_authenticate_memory.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_encrypt_authenticate_memory.c new file mode 100644 index 0000000000..85a862b412 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_encrypt_authenticate_memory.c @@ -0,0 +1,84 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file ocb_encrypt_authenticate_memory.c + OCB implementation, encrypt block of memory, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_OCB_MODE + +/** + Encrypt and generate an authentication code for a buffer of memory + @param cipher The index of the cipher desired + @param key The secret key + @param keylen The length of the secret key (octets) + @param nonce The session nonce (length of the block ciphers block size) + @param pt The plaintext + @param ptlen The length of the plaintext (octets) + @param ct [out] The ciphertext + @param tag [out] The authentication tag + @param taglen [in/out] The max size and resulting size of the authentication tag + @return CRYPT_OK if successful +*/ +int ocb_encrypt_authenticate_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen) +{ + int err; + ocb_state *ocb; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(nonce != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(tag != NULL); + LTC_ARGCHK(taglen != NULL); + + /* allocate ram */ + ocb = XMALLOC(sizeof(ocb_state)); + if (ocb == NULL) { + return CRYPT_MEM; + } + + if ((err = ocb_init(ocb, cipher, key, keylen, nonce)) != CRYPT_OK) { + goto LBL_ERR; + } + + while (ptlen > (unsigned long)ocb->block_len) { + if ((err = ocb_encrypt(ocb, pt, ct)) != CRYPT_OK) { + goto LBL_ERR; + } + ptlen -= ocb->block_len; + pt += ocb->block_len; + ct += ocb->block_len; + } + + err = ocb_done_encrypt(ocb, pt, ptlen, ct, tag, taglen); +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(ocb, sizeof(ocb_state)); +#endif + + XFREE(ocb); + + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_encrypt_authenticate_memory.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_init.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_init.c new file mode 100644 index 0000000000..86663f21c8 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_init.c @@ -0,0 +1,137 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file ocb_init.c + OCB implementation, initialize state, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_OCB_MODE + +static const struct { + int len; + unsigned char poly_div[MAXBLOCKSIZE], + poly_mul[MAXBLOCKSIZE]; +} polys[] = { +{ + 8, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B } +}, { + 16, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 } +} +}; + +/** + Initialize an OCB context. + @param ocb [out] The destination of the OCB state + @param cipher The index of the desired cipher + @param key The secret key + @param keylen The length of the secret key (octets) + @param nonce The session nonce (length of the block size of the cipher) + @return CRYPT_OK if successful +*/ +int ocb_init(ocb_state *ocb, int cipher, + const unsigned char *key, unsigned long keylen, const unsigned char *nonce) +{ + int poly, x, y, m, err; + + LTC_ARGCHK(ocb != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(nonce != NULL); + + /* valid cipher? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* determine which polys to use */ + ocb->block_len = cipher_descriptor[cipher].block_length; + for (poly = 0; poly < (int)(sizeof(polys)/sizeof(polys[0])); poly++) { + if (polys[poly].len == ocb->block_len) { + break; + } + } + if (polys[poly].len != ocb->block_len) { + return CRYPT_INVALID_ARG; + } + + /* schedule the key */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ocb->key)) != CRYPT_OK) { + return err; + } + + /* find L = E[0] */ + zeromem(ocb->L, ocb->block_len); + if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->L, ocb->L, &ocb->key)) != CRYPT_OK) { + return err; + } + + /* find R = E[N xor L] */ + for (x = 0; x < ocb->block_len; x++) { + ocb->R[x] = ocb->L[x] ^ nonce[x]; + } + if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->R, ocb->R, &ocb->key)) != CRYPT_OK) { + return err; + } + + /* find Ls[i] = L << i for i == 0..31 */ + XMEMCPY(ocb->Ls[0], ocb->L, ocb->block_len); + for (x = 1; x < 32; x++) { + m = ocb->Ls[x-1][0] >> 7; + for (y = 0; y < ocb->block_len-1; y++) { + ocb->Ls[x][y] = ((ocb->Ls[x-1][y] << 1) | (ocb->Ls[x-1][y+1] >> 7)) & 255; + } + ocb->Ls[x][ocb->block_len-1] = (ocb->Ls[x-1][ocb->block_len-1] << 1) & 255; + + if (m == 1) { + for (y = 0; y < ocb->block_len; y++) { + ocb->Ls[x][y] ^= polys[poly].poly_mul[y]; + } + } + } + + /* find Lr = L / x */ + m = ocb->L[ocb->block_len-1] & 1; + + /* shift right */ + for (x = ocb->block_len - 1; x > 0; x--) { + ocb->Lr[x] = ((ocb->L[x] >> 1) | (ocb->L[x-1] << 7)) & 255; + } + ocb->Lr[0] = ocb->L[0] >> 1; + + if (m == 1) { + for (x = 0; x < ocb->block_len; x++) { + ocb->Lr[x] ^= polys[poly].poly_div[x]; + } + } + + /* set Li, checksum */ + zeromem(ocb->Li, ocb->block_len); + zeromem(ocb->checksum, ocb->block_len); + + /* set other params */ + ocb->block_index = 1; + ocb->cipher = cipher; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_init.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_ntz.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_ntz.c new file mode 100644 index 0000000000..236c1e4e0a --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_ntz.c @@ -0,0 +1,42 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file ocb_ntz.c + OCB implementation, internal function, by Tom St Denis +*/ + +#include "tomcrypt.h" + +#ifdef LTC_OCB_MODE + +/** + Returns the number of leading zero bits [from lsb up] + @param x The 32-bit value to observe + @return The number of bits [from the lsb up] that are zero +*/ +int ocb_ntz(unsigned long x) +{ + int c; + x &= 0xFFFFFFFFUL; + c = 0; + while ((x & 1) == 0) { + ++c; + x >>= 1; + } + return c; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_ntz.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_shift_xor.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_shift_xor.c new file mode 100644 index 0000000000..abeaff5eaf --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_shift_xor.c @@ -0,0 +1,39 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file ocb_shift_xor.c + OCB implementation, internal function, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_OCB_MODE + +/** + Compute the shift/xor for OCB (internal function) + @param ocb The OCB state + @param Z The destination of the shift +*/ +void ocb_shift_xor(ocb_state *ocb, unsigned char *Z) +{ + int x, y; + y = ocb_ntz(ocb->block_index++); + for (x = 0; x < ocb->block_len; x++) { + ocb->Li[x] ^= ocb->Ls[y][x]; + Z[x] = ocb->Li[x] ^ ocb->R[x]; + } +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_shift_xor.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_test.c new file mode 100644 index 0000000000..765f90e1c6 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/ocb_test.c @@ -0,0 +1,237 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file ocb_test.c + OCB implementation, self-test by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_OCB_MODE + +/** + Test the OCB protocol + @return CRYPT_OK if successful +*/ +int ocb_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + int ptlen; + unsigned char key[16], nonce[16], pt[34], ct[34], tag[16]; + } tests[] = { + + /* OCB-AES-128-0B */ +{ + 0, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* nonce */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + /* pt */ + { 0 }, + /* ct */ + { 0 }, + /* tag */ + { 0x15, 0xd3, 0x7d, 0xd7, 0xc8, 0x90, 0xd5, 0xd6, + 0xac, 0xab, 0x92, 0x7b, 0xc0, 0xdc, 0x60, 0xee }, +}, + + + /* OCB-AES-128-3B */ +{ + 3, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* nonce */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + /* pt */ + { 0x00, 0x01, 0x02 }, + /* ct */ + { 0xfc, 0xd3, 0x7d }, + /* tag */ + { 0x02, 0x25, 0x47, 0x39, 0xa5, 0xe3, 0x56, 0x5a, + 0xe2, 0xdc, 0xd6, 0x2c, 0x65, 0x97, 0x46, 0xba }, +}, + + /* OCB-AES-128-16B */ +{ + 16, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* nonce */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + /* pt */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* ct */ + { 0x37, 0xdf, 0x8c, 0xe1, 0x5b, 0x48, 0x9b, 0xf3, + 0x1d, 0x0f, 0xc4, 0x4d, 0xa1, 0xfa, 0xf6, 0xd6 }, + /* tag */ + { 0xdf, 0xb7, 0x63, 0xeb, 0xdb, 0x5f, 0x0e, 0x71, + 0x9c, 0x7b, 0x41, 0x61, 0x80, 0x80, 0x04, 0xdf }, +}, + + /* OCB-AES-128-20B */ +{ + 20, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* nonce */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + /* pt */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13 }, + /* ct */ + { 0x01, 0xa0, 0x75, 0xf0, 0xd8, 0x15, 0xb1, 0xa4, + 0xe9, 0xc8, 0x81, 0xa1, 0xbc, 0xff, 0xc3, 0xeb, + 0x70, 0x03, 0xeb, 0x55}, + /* tag */ + { 0x75, 0x30, 0x84, 0x14, 0x4e, 0xb6, 0x3b, 0x77, + 0x0b, 0x06, 0x3c, 0x2e, 0x23, 0xcd, 0xa0, 0xbb }, +}, + + /* OCB-AES-128-32B */ +{ + 32, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* nonce */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + /* pt */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, + /* ct */ + { 0x01, 0xa0, 0x75, 0xf0, 0xd8, 0x15, 0xb1, 0xa4, + 0xe9, 0xc8, 0x81, 0xa1, 0xbc, 0xff, 0xc3, 0xeb, + 0x4a, 0xfc, 0xbb, 0x7f, 0xed, 0xc0, 0x8c, 0xa8, + 0x65, 0x4c, 0x6d, 0x30, 0x4d, 0x16, 0x12, 0xfa }, + + /* tag */ + { 0xc1, 0x4c, 0xbf, 0x2c, 0x1a, 0x1f, 0x1c, 0x3c, + 0x13, 0x7e, 0xad, 0xea, 0x1f, 0x2f, 0x2f, 0xcf }, +}, + + /* OCB-AES-128-34B */ +{ + 34, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* nonce */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + /* pt */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21 }, + /* ct */ + { 0x01, 0xa0, 0x75, 0xf0, 0xd8, 0x15, 0xb1, 0xa4, + 0xe9, 0xc8, 0x81, 0xa1, 0xbc, 0xff, 0xc3, 0xeb, + 0xd4, 0x90, 0x3d, 0xd0, 0x02, 0x5b, 0xa4, 0xaa, + 0x83, 0x7c, 0x74, 0xf1, 0x21, 0xb0, 0x26, 0x0f, + 0xa9, 0x5d }, + + /* tag */ + { 0xcf, 0x83, 0x41, 0xbb, 0x10, 0x82, 0x0c, 0xcf, + 0x14, 0xbd, 0xec, 0x56, 0xb8, 0xd7, 0xd6, 0xab }, +}, + +}; + + int err, x, idx, res; + unsigned long len; + unsigned char outct[MAXBLOCKSIZE], outtag[MAXBLOCKSIZE]; + + /* AES can be under rijndael or aes... try to find it */ + if ((idx = find_cipher("aes")) == -1) { + if ((idx = find_cipher("rijndael")) == -1) { + return CRYPT_NOP; + } + } + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + len = sizeof(outtag); + if ((err = ocb_encrypt_authenticate_memory(idx, tests[x].key, 16, + tests[x].nonce, tests[x].pt, tests[x].ptlen, outct, outtag, &len)) != CRYPT_OK) { + return err; + } + + if (XMEMCMP(outtag, tests[x].tag, len) || XMEMCMP(outct, tests[x].ct, tests[x].ptlen)) { +#if 0 + unsigned long y; + printf("\n\nFailure: \nCT:\n"); + for (y = 0; y < (unsigned long)tests[x].ptlen; ) { + printf("0x%02x", outct[y]); + if (y < (unsigned long)(tests[x].ptlen-1)) printf(", "); + if (!(++y % 8)) printf("\n"); + } + printf("\nTAG:\n"); + for (y = 0; y < len; ) { + printf("0x%02x", outtag[y]); + if (y < len-1) printf(", "); + if (!(++y % 8)) printf("\n"); + } +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + if ((err = ocb_decrypt_verify_memory(idx, tests[x].key, 16, tests[x].nonce, outct, tests[x].ptlen, + outct, tests[x].tag, len, &res)) != CRYPT_OK) { + return err; + } + if ((res != 1) || XMEMCMP(tests[x].pt, outct, tests[x].ptlen)) { +#if 0 + unsigned long y; + printf("\n\nFailure-decrypt: \nPT:\n"); + for (y = 0; y < (unsigned long)tests[x].ptlen; ) { + printf("0x%02x", outct[y]); + if (y < (unsigned long)(tests[x].ptlen-1)) printf(", "); + if (!(++y % 8)) printf("\n"); + } + printf("\nres = %d\n\n", res); +#endif + } + } + return CRYPT_OK; +#endif /* LTC_TEST */ +} + +#endif /* LTC_OCB_MODE */ + + +/* some comments + + -- it's hard to seek + -- hard to stream [you can't emit ciphertext until full block] + -- The setup is somewhat complicated... +*/ + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_test.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/s_ocb_done.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/s_ocb_done.c new file mode 100644 index 0000000000..8e6de8cfcf --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/encauth/ocb/s_ocb_done.c @@ -0,0 +1,148 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file s_ocb_done.c + OCB implementation, internal helper, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_OCB_MODE + +/* Since the last block is encrypted in CTR mode the same code can + * be used to finish a decrypt or encrypt stream. The only difference + * is we XOR the final ciphertext into the checksum so we have to xor it + * before we CTR [decrypt] or after [encrypt] + * + * the names pt/ptlen/ct really just mean in/inlen/out but this is the way I wrote it... + */ + +/** + Shared code to finish an OCB stream + @param ocb The OCB state + @param pt The remaining plaintext [or input] + @param ptlen The length of the input (octets) + @param ct [out] The output buffer + @param tag [out] The destination for the authentication tag + @param taglen [in/out] The max size and resulting size of the authentication tag + @param mode The mode we are terminating, 0==encrypt, 1==decrypt + @return CRYPT_OK if successful +*/ +int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode) + +{ + unsigned char *Z, *Y, *X; + int err, x; + + LTC_ARGCHK(ocb != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(tag != NULL); + LTC_ARGCHK(taglen != NULL); + if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { + return err; + } + if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length || + (int)ptlen > ocb->block_len || (int)ptlen < 0) { + return CRYPT_INVALID_ARG; + } + + /* allocate ram */ + Z = XMALLOC(MAXBLOCKSIZE); + Y = XMALLOC(MAXBLOCKSIZE); + X = XMALLOC(MAXBLOCKSIZE); + if (X == NULL || Y == NULL || Z == NULL) { + if (X != NULL) { + XFREE(X); + } + if (Y != NULL) { + XFREE(Y); + } + if (Z != NULL) { + XFREE(Z); + } + return CRYPT_MEM; + } + + /* compute X[m] = len(pt[m]) XOR Lr XOR Z[m] */ + ocb_shift_xor(ocb, X); + XMEMCPY(Z, X, ocb->block_len); + + X[ocb->block_len-1] ^= (ptlen*8)&255; + X[ocb->block_len-2] ^= ((ptlen*8)>>8)&255; + for (x = 0; x < ocb->block_len; x++) { + X[x] ^= ocb->Lr[x]; + } + + /* Y[m] = E(X[m])) */ + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(X, Y, &ocb->key)) != CRYPT_OK) { + goto error; + } + + if (mode == 1) { + /* decrypt mode, so let's xor it first */ + /* xor C[m] into checksum */ + for (x = 0; x < (int)ptlen; x++) { + ocb->checksum[x] ^= ct[x]; + } + } + + /* C[m] = P[m] xor Y[m] */ + for (x = 0; x < (int)ptlen; x++) { + ct[x] = pt[x] ^ Y[x]; + } + + if (mode == 0) { + /* encrypt mode */ + /* xor C[m] into checksum */ + for (x = 0; x < (int)ptlen; x++) { + ocb->checksum[x] ^= ct[x]; + } + } + + /* xor Y[m] and Z[m] into checksum */ + for (x = 0; x < ocb->block_len; x++) { + ocb->checksum[x] ^= Y[x] ^ Z[x]; + } + + /* encrypt checksum, er... tag!! */ + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->checksum, X, &ocb->key)) != CRYPT_OK) { + goto error; + } + cipher_descriptor[ocb->cipher].done(&ocb->key); + + /* now store it */ + for (x = 0; x < ocb->block_len && x < (int)*taglen; x++) { + tag[x] = X[x]; + } + *taglen = x; + +#ifdef LTC_CLEAN_STACK + zeromem(X, MAXBLOCKSIZE); + zeromem(Y, MAXBLOCKSIZE); + zeromem(Z, MAXBLOCKSIZE); + zeromem(ocb, sizeof(*ocb)); +#endif +error: + XFREE(X); + XFREE(Y); + XFREE(Z); + + return err; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/s_ocb_done.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/chc/chc.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/chc/chc.c new file mode 100644 index 0000000000..de7804834f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/chc/chc.c @@ -0,0 +1,298 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +#include "tomcrypt.h" + +/** + @file chc.c + CHC support. (Tom St Denis) +*/ + +#ifdef LTC_CHC_HASH + +#define UNDEFED_HASH -17 + +/* chc settings */ +static int cipher_idx=UNDEFED_HASH, /* which cipher */ + cipher_blocksize; /* blocksize of cipher */ + + +const struct ltc_hash_descriptor chc_desc = { + "chc_hash", 12, 0, 0, { 0 }, 0, + &chc_init, + &chc_process, + &chc_done, + &chc_test, + NULL +}; + +/** + Initialize the CHC state with a given cipher + @param cipher The index of the cipher you wish to bind + @return CRYPT_OK if successful +*/ +int chc_register(int cipher) +{ + int err, kl, idx; + + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* will it be valid? */ + kl = cipher_descriptor[cipher].block_length; + + /* must be >64 bit block */ + if (kl <= 8) { + return CRYPT_INVALID_CIPHER; + } + + /* can we use the ideal keysize? */ + if ((err = cipher_descriptor[cipher].keysize(&kl)) != CRYPT_OK) { + return err; + } + /* we require that key size == block size be a valid choice */ + if (kl != cipher_descriptor[cipher].block_length) { + return CRYPT_INVALID_CIPHER; + } + + /* determine if chc_hash has been register_hash'ed already */ + if ((err = hash_is_valid(idx = find_hash("chc_hash"))) != CRYPT_OK) { + return err; + } + + /* store into descriptor */ + hash_descriptor[idx].hashsize = + hash_descriptor[idx].blocksize = cipher_descriptor[cipher].block_length; + + /* store the idx and block size */ + cipher_idx = cipher; + cipher_blocksize = cipher_descriptor[cipher].block_length; + return CRYPT_OK; +} + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int chc_init(hash_state *md) +{ + symmetric_key *key; + unsigned char buf[MAXBLOCKSIZE]; + int err; + + LTC_ARGCHK(md != NULL); + + /* is the cipher valid? */ + if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) { + return err; + } + + if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) { + return CRYPT_INVALID_CIPHER; + } + + if ((key = XMALLOC(sizeof(*key))) == NULL) { + return CRYPT_MEM; + } + + /* zero key and what not */ + zeromem(buf, cipher_blocksize); + if ((err = cipher_descriptor[cipher_idx].setup(buf, cipher_blocksize, 0, key)) != CRYPT_OK) { + XFREE(key); + return err; + } + + /* encrypt zero block */ + cipher_descriptor[cipher_idx].ecb_encrypt(buf, md->chc.state, key); + + /* zero other members */ + md->chc.length = 0; + md->chc.curlen = 0; + zeromem(md->chc.buf, sizeof(md->chc.buf)); + XFREE(key); + return CRYPT_OK; +} + +/* + key <= state + T0,T1 <= block + T0 <= encrypt T0 + state <= state xor T0 xor T1 +*/ +static int chc_compress(hash_state *md, unsigned char *buf) +{ + unsigned char T[2][MAXBLOCKSIZE]; + symmetric_key *key; + int err, x; + + if ((key = XMALLOC(sizeof(*key))) == NULL) { + return CRYPT_MEM; + } + if ((err = cipher_descriptor[cipher_idx].setup(md->chc.state, cipher_blocksize, 0, key)) != CRYPT_OK) { + XFREE(key); + return err; + } + XMEMCPY(T[1], buf, cipher_blocksize); + cipher_descriptor[cipher_idx].ecb_encrypt(buf, T[0], key); + for (x = 0; x < cipher_blocksize; x++) { + md->chc.state[x] ^= T[0][x] ^ T[1][x]; + } + XFREE(key); +#ifdef LTC_CLEAN_STACK + zeromem(T, sizeof(T)); + zeromem(&key, sizeof(key)); +#endif + return CRYPT_OK; +} + +/* function for processing blocks */ +int _chc_process(hash_state * md, const unsigned char *buf, unsigned long len); +HASH_PROCESS(_chc_process, chc_compress, chc, (unsigned long)cipher_blocksize) + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +int chc_process(hash_state * md, const unsigned char *in, unsigned long inlen) +{ + int err; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(in != NULL); + + /* is the cipher valid? */ + if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) { + return err; + } + if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) { + return CRYPT_INVALID_CIPHER; + } + + return _chc_process(md, in, inlen); +} + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (length of the block size of the block cipher) + @return CRYPT_OK if successful +*/ +int chc_done(hash_state *md, unsigned char *out) +{ + int err; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + /* is the cipher valid? */ + if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) { + return err; + } + if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) { + return CRYPT_INVALID_CIPHER; + } + + if (md->chc.curlen >= sizeof(md->chc.buf)) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->chc.length += md->chc.curlen * 8; + + /* append the '1' bit */ + md->chc.buf[md->chc.curlen++] = (unsigned char)0x80; + + /* if the length is currently above l-8 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->chc.curlen > (unsigned long)(cipher_blocksize - 8)) { + while (md->chc.curlen < (unsigned long)cipher_blocksize) { + md->chc.buf[md->chc.curlen++] = (unsigned char)0; + } + chc_compress(md, md->chc.buf); + md->chc.curlen = 0; + } + + /* pad upto l-8 bytes of zeroes */ + while (md->chc.curlen < (unsigned long)(cipher_blocksize - 8)) { + md->chc.buf[md->chc.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->chc.length, md->chc.buf+(cipher_blocksize-8)); + chc_compress(md, md->chc.buf); + + /* copy output */ + XMEMCPY(out, md->chc.state, cipher_blocksize); + +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int chc_test(void) +{ + static const struct { + unsigned char *msg, + md[MAXBLOCKSIZE]; + int len; + } tests[] = { +{ + (unsigned char *)"hello world", + { 0xcf, 0x57, 0x9d, 0xc3, 0x0a, 0x0e, 0xea, 0x61, + 0x0d, 0x54, 0x47, 0xc4, 0x3c, 0x06, 0xf5, 0x4e }, + 16 +} +}; + int x, oldhashidx, idx; + unsigned char out[MAXBLOCKSIZE]; + hash_state md; + + /* AES can be under rijndael or aes... try to find it */ + if ((idx = find_cipher("aes")) == -1) { + if ((idx = find_cipher("rijndael")) == -1) { + return CRYPT_NOP; + } + } + oldhashidx = cipher_idx; + chc_register(idx); + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + chc_init(&md); + chc_process(&md, tests[x].msg, strlen((char *)tests[x].msg)); + chc_done(&md, out); + if (XMEMCMP(out, tests[x].md, tests[x].len)) { + return CRYPT_FAIL_TESTVECTOR; + } + } + if (oldhashidx != UNDEFED_HASH) { + chc_register(oldhashidx); + } + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/hashes/chc/chc.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/helper/hash_file.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/helper/hash_file.c new file mode 100644 index 0000000000..7fa6642ea6 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/helper/hash_file.c @@ -0,0 +1,57 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file hash_file.c + Hash a file, Tom St Denis +*/ + +/** + @param hash The index of the hash desired + @param fname The name of the file you wish to hash + @param out [out] The destination of the digest + @param outlen [in/out] The max size and resulting size of the message digest + @result CRYPT_OK if successful +*/ +int hash_file(int hash, const char *fname, unsigned char *out, unsigned long *outlen) +{ +#ifdef LTC_NO_FILE + return CRYPT_NOP; +#else + FILE *in; + int err; + LTC_ARGCHK(fname != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + in = fopen(fname, "rb"); + if (in == NULL) { + return CRYPT_FILE_NOTFOUND; + } + + err = hash_filehandle(hash, in, out, outlen); + if (fclose(in) != 0) { + return CRYPT_ERROR; + } + + return err; +#endif +} + + +/* $Source: /cvs/libtom/libtomcrypt/src/hashes/helper/hash_file.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/helper/hash_filehandle.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/helper/hash_filehandle.c new file mode 100644 index 0000000000..8e5fe409b9 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/helper/hash_filehandle.c @@ -0,0 +1,72 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file hash_filehandle.c + Hash open files, Tom St Denis +*/ + +#ifndef LTC_NO_FILE +/** + Hash data from an open file handle. + @param hash The index of the hash you want to use + @param in The FILE* handle of the file you want to hash + @param out [out] The destination of the digest + @param outlen [in/out] The max size and resulting size of the digest + @result CRYPT_OK if successful +*/ +int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen) +{ +#ifdef LTC_NO_FILE + return CRYPT_NOP; +#else + hash_state md; + unsigned char buf[512]; + size_t x; + int err; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(in != NULL); + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + if (*outlen < hash_descriptor[hash].hashsize) { + *outlen = hash_descriptor[hash].hashsize; + return CRYPT_BUFFER_OVERFLOW; + } + if ((err = hash_descriptor[hash].init(&md)) != CRYPT_OK) { + return err; + } + + *outlen = hash_descriptor[hash].hashsize; + do { + x = fread(buf, 1, sizeof(buf), in); + if ((err = hash_descriptor[hash].process(&md, buf, x)) != CRYPT_OK) { + return err; + } + } while (x == sizeof(buf)); + err = hash_descriptor[hash].done(&md, out); + +#ifdef LTC_CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return err; +#endif +} +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/hashes/helper/hash_filehandle.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/helper/hash_memory.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/helper/hash_memory.c new file mode 100644 index 0000000000..04e591272c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/helper/hash_memory.c @@ -0,0 +1,69 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file hash_memory.c + Hash memory helper, Tom St Denis +*/ + +/** + Hash a block of memory and store the digest. + @param hash The index of the hash you wish to use + @param in The data you wish to hash + @param inlen The length of the data to hash (octets) + @param out [out] Where to store the digest + @param outlen [in/out] Max size and resulting size of the digest + @return CRYPT_OK if successful +*/ +int hash_memory(int hash, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) +{ + hash_state *md; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + if (*outlen < hash_descriptor[hash].hashsize) { + *outlen = hash_descriptor[hash].hashsize; + return CRYPT_BUFFER_OVERFLOW; + } + + md = XMALLOC(sizeof(hash_state)); + if (md == NULL) { + return CRYPT_MEM; + } + + if ((err = hash_descriptor[hash].init(md)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash].process(md, in, inlen)) != CRYPT_OK) { + goto LBL_ERR; + } + err = hash_descriptor[hash].done(md, out); + *outlen = hash_descriptor[hash].hashsize; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + XFREE(md); + + return err; +} + +/* $Source: /cvs/libtom/libtomcrypt/src/hashes/helper/hash_memory.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/helper/hash_memory_multi.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/helper/hash_memory_multi.c new file mode 100644 index 0000000000..4f68268663 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/helper/hash_memory_multi.c @@ -0,0 +1,87 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" +#include +/** + @file hash_memory_multi.c + Hash (multiple buffers) memory helper, Tom St Denis +*/ + +/** + Hash multiple (non-adjacent) blocks of memory at once. + @param hash The index of the hash you wish to use + @param out [out] Where to store the digest + @param outlen [in/out] Max size and resulting size of the digest + @param in The data you wish to hash + @param inlen The length of the data to hash (octets) + @param ... tuples of (data,len) pairs to hash, terminated with a (NULL,x) (x=don't care) + @return CRYPT_OK if successful +*/ +int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...) +{ + hash_state *md; + int err; + va_list args; + const unsigned char *curptr; + unsigned long curlen; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + if (*outlen < hash_descriptor[hash].hashsize) { + *outlen = hash_descriptor[hash].hashsize; + return CRYPT_BUFFER_OVERFLOW; + } + + md = XMALLOC(sizeof(hash_state)); + if (md == NULL) { + return CRYPT_MEM; + } + + if ((err = hash_descriptor[hash].init(md)) != CRYPT_OK) { + goto LBL_ERR; + } + + va_start(args, inlen); + curptr = in; + curlen = inlen; + for (;;) { + /* process buf */ + if ((err = hash_descriptor[hash].process(md, curptr, curlen)) != CRYPT_OK) { + goto LBL_ERR; + } + /* step to next */ + curptr = va_arg(args, const unsigned char*); + if (curptr == NULL) { + break; + } + curlen = va_arg(args, unsigned long); + } + err = hash_descriptor[hash].done(md, out); + *outlen = hash_descriptor[hash].hashsize; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + XFREE(md); + va_end(args); + return err; +} + +/* $Source: /cvs/libtom/libtomcrypt/src/hashes/helper/hash_memory_multi.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/md2.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/md2.c new file mode 100644 index 0000000000..af1739ac0c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/md2.c @@ -0,0 +1,251 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @param md2.c + LTC_MD2 (RFC 1319) hash function implementation by Tom St Denis +*/ + +#ifdef LTC_MD2 + +const struct ltc_hash_descriptor md2_desc = +{ + "md2", + 7, + 16, + 16, + + /* OID */ + { 1, 2, 840, 113549, 2, 2, }, + 6, + + &md2_init, + &md2_process, + &md2_done, + &md2_test, + NULL +}; + +static const unsigned char PI_SUBST[256] = { + 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, + 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, + 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, + 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, + 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, + 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, + 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, + 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, + 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157, + 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27, + 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, + 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, + 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, + 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, + 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233, + 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228, + 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237, + 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 +}; + +/* adds 16 bytes to the checksum */ +static void md2_update_chksum(hash_state *md) +{ + int j; + unsigned char L; + L = md->md2.chksum[15]; + for (j = 0; j < 16; j++) { + +/* caution, the RFC says its "C[j] = S[M[i*16+j] xor L]" but the reference source code [and test vectors] say + otherwise. +*/ + L = (md->md2.chksum[j] ^= PI_SUBST[(int)(md->md2.buf[j] ^ L)] & 255); + } +} + +static void md2_compress(hash_state *md) +{ + int j, k; + unsigned char t; + + /* copy block */ + for (j = 0; j < 16; j++) { + md->md2.X[16+j] = md->md2.buf[j]; + md->md2.X[32+j] = md->md2.X[j] ^ md->md2.X[16+j]; + } + + t = (unsigned char)0; + + /* do 18 rounds */ + for (j = 0; j < 18; j++) { + for (k = 0; k < 48; k++) { + t = (md->md2.X[k] ^= PI_SUBST[(int)(t & 255)]); + } + t = (t + (unsigned char)j) & 255; + } +} + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int md2_init(hash_state *md) +{ + LTC_ARGCHK(md != NULL); + + /* LTC_MD2 uses a zero'ed state... */ + zeromem(md->md2.X, sizeof(md->md2.X)); + zeromem(md->md2.chksum, sizeof(md->md2.chksum)); + zeromem(md->md2.buf, sizeof(md->md2.buf)); + md->md2.curlen = 0; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +int md2_process(hash_state *md, const unsigned char *in, unsigned long inlen) +{ + unsigned long n; + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(in != NULL); + if (md-> md2 .curlen > sizeof(md-> md2 .buf)) { + return CRYPT_INVALID_ARG; + } + while (inlen > 0) { + n = MIN(inlen, (16 - md->md2.curlen)); + XMEMCPY(md->md2.buf + md->md2.curlen, in, (size_t)n); + md->md2.curlen += n; + in += n; + inlen -= n; + + /* is 16 bytes full? */ + if (md->md2.curlen == 16) { + md2_compress(md); + md2_update_chksum(md); + md->md2.curlen = 0; + } + } + return CRYPT_OK; +} + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (16 bytes) + @return CRYPT_OK if successful +*/ +int md2_done(hash_state * md, unsigned char *out) +{ + unsigned long i, k; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->md2.curlen >= sizeof(md->md2.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* pad the message */ + k = 16 - md->md2.curlen; + for (i = md->md2.curlen; i < 16; i++) { + md->md2.buf[i] = (unsigned char)k; + } + + /* hash and update */ + md2_compress(md); + md2_update_chksum(md); + + /* hash checksum */ + XMEMCPY(md->md2.buf, md->md2.chksum, 16); + md2_compress(md); + + /* output is lower 16 bytes of X */ + XMEMCPY(out, md->md2.X, 16); + +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int md2_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char md[16]; + } tests[] = { + { "", + {0x83,0x50,0xe5,0xa3,0xe2,0x4c,0x15,0x3d, + 0xf2,0x27,0x5c,0x9f,0x80,0x69,0x27,0x73 + } + }, + { "a", + {0x32,0xec,0x01,0xec,0x4a,0x6d,0xac,0x72, + 0xc0,0xab,0x96,0xfb,0x34,0xc0,0xb5,0xd1 + } + }, + { "message digest", + {0xab,0x4f,0x49,0x6b,0xfb,0x2a,0x53,0x0b, + 0x21,0x9f,0xf3,0x30,0x31,0xfe,0x06,0xb0 + } + }, + { "abcdefghijklmnopqrstuvwxyz", + {0x4e,0x8d,0xdf,0xf3,0x65,0x02,0x92,0xab, + 0x5a,0x41,0x08,0xc3,0xaa,0x47,0x94,0x0b + } + }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + {0xda,0x33,0xde,0xf2,0xa4,0x2d,0xf1,0x39, + 0x75,0x35,0x28,0x46,0xc3,0x03,0x38,0xcd + } + }, + { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", + {0xd5,0x97,0x6f,0x79,0xd8,0x3d,0x3a,0x0d, + 0xc9,0x80,0x6c,0x3c,0x66,0xf3,0xef,0xd8 + } + } + }; + int i; + hash_state md; + unsigned char buf[16]; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + md2_init(&md); + md2_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + md2_done(&md, buf); + if (XMEMCMP(buf, tests[i].md, 16) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/hashes/md2.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:25:28 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/md4.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/md4.c new file mode 100644 index 0000000000..a030d3018d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/md4.c @@ -0,0 +1,307 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @param md4.c + Submitted by Dobes Vandermeer (dobes@smartt.com) +*/ + +#ifdef LTC_MD4 + +const struct ltc_hash_descriptor md4_desc = +{ + "md4", + 6, + 16, + 64, + + /* OID */ + { 1, 2, 840, 113549, 2, 4, }, + 6, + + &md4_init, + &md4_process, + &md4_done, + &md4_test, + NULL +}; + +#define S11 3 +#define S12 7 +#define S13 11 +#define S14 19 +#define S21 3 +#define S22 5 +#define S23 9 +#define S24 13 +#define S31 3 +#define S32 9 +#define S33 11 +#define S34 15 + +/* F, G and H are basic LTC_MD4 functions. */ +#define F(x, y, z) (z ^ (x & (y ^ z))) +#define G(x, y, z) ((x & y) | (z & (x | y))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) + +/* ROTATE_LEFT rotates x left n bits. */ +#define ROTATE_LEFT(x, n) ROLc(x, n) + +/* FF, GG and HH are transformations for rounds 1, 2 and 3 */ +/* Rotation is separate from addition to prevent recomputation */ + +#define FF(a, b, c, d, x, s) { \ + (a) += F ((b), (c), (d)) + (x); \ + (a) = ROTATE_LEFT ((a), (s)); \ + } +#define GG(a, b, c, d, x, s) { \ + (a) += G ((b), (c), (d)) + (x) + 0x5a827999UL; \ + (a) = ROTATE_LEFT ((a), (s)); \ + } +#define HH(a, b, c, d, x, s) { \ + (a) += H ((b), (c), (d)) + (x) + 0x6ed9eba1UL; \ + (a) = ROTATE_LEFT ((a), (s)); \ + } + +#ifdef LTC_CLEAN_STACK +static int _md4_compress(hash_state *md, unsigned char *buf) +#else +static int md4_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 x[16], a, b, c, d; + int i; + + /* copy state */ + a = md->md4.state[0]; + b = md->md4.state[1]; + c = md->md4.state[2]; + d = md->md4.state[3]; + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD32L(x[i], buf + (4*i)); + } + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11); /* 1 */ + FF (d, a, b, c, x[ 1], S12); /* 2 */ + FF (c, d, a, b, x[ 2], S13); /* 3 */ + FF (b, c, d, a, x[ 3], S14); /* 4 */ + FF (a, b, c, d, x[ 4], S11); /* 5 */ + FF (d, a, b, c, x[ 5], S12); /* 6 */ + FF (c, d, a, b, x[ 6], S13); /* 7 */ + FF (b, c, d, a, x[ 7], S14); /* 8 */ + FF (a, b, c, d, x[ 8], S11); /* 9 */ + FF (d, a, b, c, x[ 9], S12); /* 10 */ + FF (c, d, a, b, x[10], S13); /* 11 */ + FF (b, c, d, a, x[11], S14); /* 12 */ + FF (a, b, c, d, x[12], S11); /* 13 */ + FF (d, a, b, c, x[13], S12); /* 14 */ + FF (c, d, a, b, x[14], S13); /* 15 */ + FF (b, c, d, a, x[15], S14); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 0], S21); /* 17 */ + GG (d, a, b, c, x[ 4], S22); /* 18 */ + GG (c, d, a, b, x[ 8], S23); /* 19 */ + GG (b, c, d, a, x[12], S24); /* 20 */ + GG (a, b, c, d, x[ 1], S21); /* 21 */ + GG (d, a, b, c, x[ 5], S22); /* 22 */ + GG (c, d, a, b, x[ 9], S23); /* 23 */ + GG (b, c, d, a, x[13], S24); /* 24 */ + GG (a, b, c, d, x[ 2], S21); /* 25 */ + GG (d, a, b, c, x[ 6], S22); /* 26 */ + GG (c, d, a, b, x[10], S23); /* 27 */ + GG (b, c, d, a, x[14], S24); /* 28 */ + GG (a, b, c, d, x[ 3], S21); /* 29 */ + GG (d, a, b, c, x[ 7], S22); /* 30 */ + GG (c, d, a, b, x[11], S23); /* 31 */ + GG (b, c, d, a, x[15], S24); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 0], S31); /* 33 */ + HH (d, a, b, c, x[ 8], S32); /* 34 */ + HH (c, d, a, b, x[ 4], S33); /* 35 */ + HH (b, c, d, a, x[12], S34); /* 36 */ + HH (a, b, c, d, x[ 2], S31); /* 37 */ + HH (d, a, b, c, x[10], S32); /* 38 */ + HH (c, d, a, b, x[ 6], S33); /* 39 */ + HH (b, c, d, a, x[14], S34); /* 40 */ + HH (a, b, c, d, x[ 1], S31); /* 41 */ + HH (d, a, b, c, x[ 9], S32); /* 42 */ + HH (c, d, a, b, x[ 5], S33); /* 43 */ + HH (b, c, d, a, x[13], S34); /* 44 */ + HH (a, b, c, d, x[ 3], S31); /* 45 */ + HH (d, a, b, c, x[11], S32); /* 46 */ + HH (c, d, a, b, x[ 7], S33); /* 47 */ + HH (b, c, d, a, x[15], S34); /* 48 */ + + + /* Update our state */ + md->md4.state[0] = md->md4.state[0] + a; + md->md4.state[1] = md->md4.state[1] + b; + md->md4.state[2] = md->md4.state[2] + c; + md->md4.state[3] = md->md4.state[3] + d; + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +static int md4_compress(hash_state *md, unsigned char *buf) +{ + int err; + err = _md4_compress(md, buf); + burn_stack(sizeof(ulong32) * 20 + sizeof(int)); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int md4_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + md->md4.state[0] = 0x67452301UL; + md->md4.state[1] = 0xefcdab89UL; + md->md4.state[2] = 0x98badcfeUL; + md->md4.state[3] = 0x10325476UL; + md->md4.length = 0; + md->md4.curlen = 0; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(md4_process, md4_compress, md4, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (16 bytes) + @return CRYPT_OK if successful +*/ +int md4_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->md4.curlen >= sizeof(md->md4.buf)) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->md4.length += md->md4.curlen * 8; + + /* append the '1' bit */ + md->md4.buf[md->md4.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->md4.curlen > 56) { + while (md->md4.curlen < 64) { + md->md4.buf[md->md4.curlen++] = (unsigned char)0; + } + md4_compress(md, md->md4.buf); + md->md4.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->md4.curlen < 56) { + md->md4.buf[md->md4.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->md4.length, md->md4.buf+56); + md4_compress(md, md->md4.buf); + + /* copy output */ + for (i = 0; i < 4; i++) { + STORE32L(md->md4.state[i], out+(4*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int md4_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct md4_test_case { + char *input; + unsigned char digest[16]; + } cases[] = { + { "", + {0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31, + 0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0} }, + { "a", + {0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46, + 0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24} }, + { "abc", + {0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52, + 0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d} }, + { "message digest", + {0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8, + 0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b} }, + { "abcdefghijklmnopqrstuvwxyz", + {0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd, + 0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9} }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + {0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35, + 0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4} }, + { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", + {0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19, + 0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36} }, + }; + int i; + hash_state md; + unsigned char digest[16]; + + for(i = 0; i < (int)(sizeof(cases) / sizeof(cases[0])); i++) { + md4_init(&md); + md4_process(&md, (unsigned char *)cases[i].input, (unsigned long)strlen(cases[i].input)); + md4_done(&md, digest); + if (XMEMCMP(digest, cases[i].digest, 16) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + } + return CRYPT_OK; + #endif +} + +#endif + + + +/* $Source: /cvs/libtom/libtomcrypt/src/hashes/md4.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:25:28 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/md5.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/md5.c new file mode 100644 index 0000000000..78a861af8e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/md5.c @@ -0,0 +1,368 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + + +/** + @file md5.c + LTC_MD5 hash function by Tom St Denis +*/ + +#ifdef LTC_MD5 + +const struct ltc_hash_descriptor md5_desc = +{ + "md5", + 3, + 16, + 64, + + /* OID */ + { 1, 2, 840, 113549, 2, 5, }, + 6, + + &md5_init, + &md5_process, + &md5_done, + &md5_test, + NULL +}; + +#define F(x,y,z) (z ^ (x & (y ^ z))) +#define G(x,y,z) (y ^ (z & (y ^ x))) +#define H(x,y,z) (x^y^z) +#define I(x,y,z) (y^(x|(~z))) + +#ifdef LTC_SMALL_CODE + +#define FF(a,b,c,d,M,s,t) \ + a = (a + F(b,c,d) + M + t); a = ROL(a, s) + b; + +#define GG(a,b,c,d,M,s,t) \ + a = (a + G(b,c,d) + M + t); a = ROL(a, s) + b; + +#define HH(a,b,c,d,M,s,t) \ + a = (a + H(b,c,d) + M + t); a = ROL(a, s) + b; + +#define II(a,b,c,d,M,s,t) \ + a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b; + +static const unsigned char Worder[64] = { + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12, + 5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2, + 0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9 +}; + +static const unsigned char Rorder[64] = { + 7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22, + 5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20, + 4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23, + 6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21 +}; + +static const ulong32 Korder[64] = { +0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL, 0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL, +0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL, 0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL, +0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL, 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL, +0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL, 0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL, +0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL, 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL, +0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL, 0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL, +0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL, 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL, +0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL, 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL +}; + +#else + +#define FF(a,b,c,d,M,s,t) \ + a = (a + F(b,c,d) + M + t); a = ROLc(a, s) + b; + +#define GG(a,b,c,d,M,s,t) \ + a = (a + G(b,c,d) + M + t); a = ROLc(a, s) + b; + +#define HH(a,b,c,d,M,s,t) \ + a = (a + H(b,c,d) + M + t); a = ROLc(a, s) + b; + +#define II(a,b,c,d,M,s,t) \ + a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b; + + +#endif + +#ifdef LTC_CLEAN_STACK +static int _md5_compress(hash_state *md, unsigned char *buf) +#else +static int md5_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 i, W[16], a, b, c, d; +#ifdef LTC_SMALL_CODE + ulong32 t; +#endif + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD32L(W[i], buf + (4*i)); + } + + /* copy state */ + a = md->md5.state[0]; + b = md->md5.state[1]; + c = md->md5.state[2]; + d = md->md5.state[3]; + +#ifdef LTC_SMALL_CODE + for (i = 0; i < 16; ++i) { + FF(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]); + t = d; d = c; c = b; b = a; a = t; + } + + for (; i < 32; ++i) { + GG(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]); + t = d; d = c; c = b; b = a; a = t; + } + + for (; i < 48; ++i) { + HH(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]); + t = d; d = c; c = b; b = a; a = t; + } + + for (; i < 64; ++i) { + II(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]); + t = d; d = c; c = b; b = a; a = t; + } + +#else + FF(a,b,c,d,W[0],7,0xd76aa478UL) + FF(d,a,b,c,W[1],12,0xe8c7b756UL) + FF(c,d,a,b,W[2],17,0x242070dbUL) + FF(b,c,d,a,W[3],22,0xc1bdceeeUL) + FF(a,b,c,d,W[4],7,0xf57c0fafUL) + FF(d,a,b,c,W[5],12,0x4787c62aUL) + FF(c,d,a,b,W[6],17,0xa8304613UL) + FF(b,c,d,a,W[7],22,0xfd469501UL) + FF(a,b,c,d,W[8],7,0x698098d8UL) + FF(d,a,b,c,W[9],12,0x8b44f7afUL) + FF(c,d,a,b,W[10],17,0xffff5bb1UL) + FF(b,c,d,a,W[11],22,0x895cd7beUL) + FF(a,b,c,d,W[12],7,0x6b901122UL) + FF(d,a,b,c,W[13],12,0xfd987193UL) + FF(c,d,a,b,W[14],17,0xa679438eUL) + FF(b,c,d,a,W[15],22,0x49b40821UL) + GG(a,b,c,d,W[1],5,0xf61e2562UL) + GG(d,a,b,c,W[6],9,0xc040b340UL) + GG(c,d,a,b,W[11],14,0x265e5a51UL) + GG(b,c,d,a,W[0],20,0xe9b6c7aaUL) + GG(a,b,c,d,W[5],5,0xd62f105dUL) + GG(d,a,b,c,W[10],9,0x02441453UL) + GG(c,d,a,b,W[15],14,0xd8a1e681UL) + GG(b,c,d,a,W[4],20,0xe7d3fbc8UL) + GG(a,b,c,d,W[9],5,0x21e1cde6UL) + GG(d,a,b,c,W[14],9,0xc33707d6UL) + GG(c,d,a,b,W[3],14,0xf4d50d87UL) + GG(b,c,d,a,W[8],20,0x455a14edUL) + GG(a,b,c,d,W[13],5,0xa9e3e905UL) + GG(d,a,b,c,W[2],9,0xfcefa3f8UL) + GG(c,d,a,b,W[7],14,0x676f02d9UL) + GG(b,c,d,a,W[12],20,0x8d2a4c8aUL) + HH(a,b,c,d,W[5],4,0xfffa3942UL) + HH(d,a,b,c,W[8],11,0x8771f681UL) + HH(c,d,a,b,W[11],16,0x6d9d6122UL) + HH(b,c,d,a,W[14],23,0xfde5380cUL) + HH(a,b,c,d,W[1],4,0xa4beea44UL) + HH(d,a,b,c,W[4],11,0x4bdecfa9UL) + HH(c,d,a,b,W[7],16,0xf6bb4b60UL) + HH(b,c,d,a,W[10],23,0xbebfbc70UL) + HH(a,b,c,d,W[13],4,0x289b7ec6UL) + HH(d,a,b,c,W[0],11,0xeaa127faUL) + HH(c,d,a,b,W[3],16,0xd4ef3085UL) + HH(b,c,d,a,W[6],23,0x04881d05UL) + HH(a,b,c,d,W[9],4,0xd9d4d039UL) + HH(d,a,b,c,W[12],11,0xe6db99e5UL) + HH(c,d,a,b,W[15],16,0x1fa27cf8UL) + HH(b,c,d,a,W[2],23,0xc4ac5665UL) + II(a,b,c,d,W[0],6,0xf4292244UL) + II(d,a,b,c,W[7],10,0x432aff97UL) + II(c,d,a,b,W[14],15,0xab9423a7UL) + II(b,c,d,a,W[5],21,0xfc93a039UL) + II(a,b,c,d,W[12],6,0x655b59c3UL) + II(d,a,b,c,W[3],10,0x8f0ccc92UL) + II(c,d,a,b,W[10],15,0xffeff47dUL) + II(b,c,d,a,W[1],21,0x85845dd1UL) + II(a,b,c,d,W[8],6,0x6fa87e4fUL) + II(d,a,b,c,W[15],10,0xfe2ce6e0UL) + II(c,d,a,b,W[6],15,0xa3014314UL) + II(b,c,d,a,W[13],21,0x4e0811a1UL) + II(a,b,c,d,W[4],6,0xf7537e82UL) + II(d,a,b,c,W[11],10,0xbd3af235UL) + II(c,d,a,b,W[2],15,0x2ad7d2bbUL) + II(b,c,d,a,W[9],21,0xeb86d391UL) +#endif + + md->md5.state[0] = md->md5.state[0] + a; + md->md5.state[1] = md->md5.state[1] + b; + md->md5.state[2] = md->md5.state[2] + c; + md->md5.state[3] = md->md5.state[3] + d; + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +static int md5_compress(hash_state *md, unsigned char *buf) +{ + int err; + err = _md5_compress(md, buf); + burn_stack(sizeof(ulong32) * 21); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int md5_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + md->md5.state[0] = 0x67452301UL; + md->md5.state[1] = 0xefcdab89UL; + md->md5.state[2] = 0x98badcfeUL; + md->md5.state[3] = 0x10325476UL; + md->md5.curlen = 0; + md->md5.length = 0; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(md5_process, md5_compress, md5, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (16 bytes) + @return CRYPT_OK if successful +*/ +int md5_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->md5.curlen >= sizeof(md->md5.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* increase the length of the message */ + md->md5.length += md->md5.curlen * 8; + + /* append the '1' bit */ + md->md5.buf[md->md5.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->md5.curlen > 56) { + while (md->md5.curlen < 64) { + md->md5.buf[md->md5.curlen++] = (unsigned char)0; + } + md5_compress(md, md->md5.buf); + md->md5.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->md5.curlen < 56) { + md->md5.buf[md->md5.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->md5.length, md->md5.buf+56); + md5_compress(md, md->md5.buf); + + /* copy output */ + for (i = 0; i < 4; i++) { + STORE32L(md->md5.state[i], out+(4*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int md5_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[16]; + } tests[] = { + { "", + { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, + 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } }, + { "a", + {0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, + 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } }, + { "abc", + { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, + 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } }, + { "message digest", + { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d, + 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } }, + { "abcdefghijklmnopqrstuvwxyz", + { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, + 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5, + 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } }, + { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", + { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, + 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } }, + { NULL, { 0 } } + }; + + int i; + unsigned char tmp[16]; + hash_state md; + + for (i = 0; tests[i].msg != NULL; i++) { + md5_init(&md); + md5_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + md5_done(&md, tmp); + if (XMEMCMP(tmp, tests[i].hash, 16) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif + + + +/* $Source: /cvs/libtom/libtomcrypt/src/hashes/md5.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:25:28 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/rmd128.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/rmd128.c new file mode 100644 index 0000000000..5f3c9279b9 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/rmd128.c @@ -0,0 +1,410 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @param rmd128.c + RMD128 Hash function +*/ + +/* Implementation of LTC_RIPEMD-128 based on the source by Antoon Bosselaers, ESAT-COSIC + * + * This source has been radically overhauled to be portable and work within + * the LibTomCrypt API by Tom St Denis + */ + +#ifdef LTC_RIPEMD128 + +const struct ltc_hash_descriptor rmd128_desc = +{ + "rmd128", + 8, + 16, + 64, + + /* OID */ + { 1, 0, 10118, 3, 0, 50 }, + 6, + + &rmd128_init, + &rmd128_process, + &rmd128_done, + &rmd128_test, + NULL +}; + +/* the four basic functions F(), G() and H() */ +#define F(x, y, z) ((x) ^ (y) ^ (z)) +#define G(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define H(x, y, z) (((x) | ~(y)) ^ (z)) +#define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) + +/* the eight basic operations FF() through III() */ +#define FF(a, b, c, d, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROLc((a), (s)); + +#define GG(a, b, c, d, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ + (a) = ROLc((a), (s)); + +#define HH(a, b, c, d, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ + (a) = ROLc((a), (s)); + +#define II(a, b, c, d, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ + (a) = ROLc((a), (s)); + +#define FFF(a, b, c, d, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROLc((a), (s)); + +#define GGG(a, b, c, d, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\ + (a) = ROLc((a), (s)); + +#define HHH(a, b, c, d, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\ + (a) = ROLc((a), (s)); + +#define III(a, b, c, d, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\ + (a) = ROLc((a), (s)); + +#ifdef LTC_CLEAN_STACK +static int _rmd128_compress(hash_state *md, unsigned char *buf) +#else +static int rmd128_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,X[16]; + int i; + + /* load words X */ + for (i = 0; i < 16; i++){ + LOAD32L(X[i], buf + (4 * i)); + } + + /* load state */ + aa = aaa = md->rmd128.state[0]; + bb = bbb = md->rmd128.state[1]; + cc = ccc = md->rmd128.state[2]; + dd = ddd = md->rmd128.state[3]; + + /* round 1 */ + FF(aa, bb, cc, dd, X[ 0], 11); + FF(dd, aa, bb, cc, X[ 1], 14); + FF(cc, dd, aa, bb, X[ 2], 15); + FF(bb, cc, dd, aa, X[ 3], 12); + FF(aa, bb, cc, dd, X[ 4], 5); + FF(dd, aa, bb, cc, X[ 5], 8); + FF(cc, dd, aa, bb, X[ 6], 7); + FF(bb, cc, dd, aa, X[ 7], 9); + FF(aa, bb, cc, dd, X[ 8], 11); + FF(dd, aa, bb, cc, X[ 9], 13); + FF(cc, dd, aa, bb, X[10], 14); + FF(bb, cc, dd, aa, X[11], 15); + FF(aa, bb, cc, dd, X[12], 6); + FF(dd, aa, bb, cc, X[13], 7); + FF(cc, dd, aa, bb, X[14], 9); + FF(bb, cc, dd, aa, X[15], 8); + + /* round 2 */ + GG(aa, bb, cc, dd, X[ 7], 7); + GG(dd, aa, bb, cc, X[ 4], 6); + GG(cc, dd, aa, bb, X[13], 8); + GG(bb, cc, dd, aa, X[ 1], 13); + GG(aa, bb, cc, dd, X[10], 11); + GG(dd, aa, bb, cc, X[ 6], 9); + GG(cc, dd, aa, bb, X[15], 7); + GG(bb, cc, dd, aa, X[ 3], 15); + GG(aa, bb, cc, dd, X[12], 7); + GG(dd, aa, bb, cc, X[ 0], 12); + GG(cc, dd, aa, bb, X[ 9], 15); + GG(bb, cc, dd, aa, X[ 5], 9); + GG(aa, bb, cc, dd, X[ 2], 11); + GG(dd, aa, bb, cc, X[14], 7); + GG(cc, dd, aa, bb, X[11], 13); + GG(bb, cc, dd, aa, X[ 8], 12); + + /* round 3 */ + HH(aa, bb, cc, dd, X[ 3], 11); + HH(dd, aa, bb, cc, X[10], 13); + HH(cc, dd, aa, bb, X[14], 6); + HH(bb, cc, dd, aa, X[ 4], 7); + HH(aa, bb, cc, dd, X[ 9], 14); + HH(dd, aa, bb, cc, X[15], 9); + HH(cc, dd, aa, bb, X[ 8], 13); + HH(bb, cc, dd, aa, X[ 1], 15); + HH(aa, bb, cc, dd, X[ 2], 14); + HH(dd, aa, bb, cc, X[ 7], 8); + HH(cc, dd, aa, bb, X[ 0], 13); + HH(bb, cc, dd, aa, X[ 6], 6); + HH(aa, bb, cc, dd, X[13], 5); + HH(dd, aa, bb, cc, X[11], 12); + HH(cc, dd, aa, bb, X[ 5], 7); + HH(bb, cc, dd, aa, X[12], 5); + + /* round 4 */ + II(aa, bb, cc, dd, X[ 1], 11); + II(dd, aa, bb, cc, X[ 9], 12); + II(cc, dd, aa, bb, X[11], 14); + II(bb, cc, dd, aa, X[10], 15); + II(aa, bb, cc, dd, X[ 0], 14); + II(dd, aa, bb, cc, X[ 8], 15); + II(cc, dd, aa, bb, X[12], 9); + II(bb, cc, dd, aa, X[ 4], 8); + II(aa, bb, cc, dd, X[13], 9); + II(dd, aa, bb, cc, X[ 3], 14); + II(cc, dd, aa, bb, X[ 7], 5); + II(bb, cc, dd, aa, X[15], 6); + II(aa, bb, cc, dd, X[14], 8); + II(dd, aa, bb, cc, X[ 5], 6); + II(cc, dd, aa, bb, X[ 6], 5); + II(bb, cc, dd, aa, X[ 2], 12); + + /* parallel round 1 */ + III(aaa, bbb, ccc, ddd, X[ 5], 8); + III(ddd, aaa, bbb, ccc, X[14], 9); + III(ccc, ddd, aaa, bbb, X[ 7], 9); + III(bbb, ccc, ddd, aaa, X[ 0], 11); + III(aaa, bbb, ccc, ddd, X[ 9], 13); + III(ddd, aaa, bbb, ccc, X[ 2], 15); + III(ccc, ddd, aaa, bbb, X[11], 15); + III(bbb, ccc, ddd, aaa, X[ 4], 5); + III(aaa, bbb, ccc, ddd, X[13], 7); + III(ddd, aaa, bbb, ccc, X[ 6], 7); + III(ccc, ddd, aaa, bbb, X[15], 8); + III(bbb, ccc, ddd, aaa, X[ 8], 11); + III(aaa, bbb, ccc, ddd, X[ 1], 14); + III(ddd, aaa, bbb, ccc, X[10], 14); + III(ccc, ddd, aaa, bbb, X[ 3], 12); + III(bbb, ccc, ddd, aaa, X[12], 6); + + /* parallel round 2 */ + HHH(aaa, bbb, ccc, ddd, X[ 6], 9); + HHH(ddd, aaa, bbb, ccc, X[11], 13); + HHH(ccc, ddd, aaa, bbb, X[ 3], 15); + HHH(bbb, ccc, ddd, aaa, X[ 7], 7); + HHH(aaa, bbb, ccc, ddd, X[ 0], 12); + HHH(ddd, aaa, bbb, ccc, X[13], 8); + HHH(ccc, ddd, aaa, bbb, X[ 5], 9); + HHH(bbb, ccc, ddd, aaa, X[10], 11); + HHH(aaa, bbb, ccc, ddd, X[14], 7); + HHH(ddd, aaa, bbb, ccc, X[15], 7); + HHH(ccc, ddd, aaa, bbb, X[ 8], 12); + HHH(bbb, ccc, ddd, aaa, X[12], 7); + HHH(aaa, bbb, ccc, ddd, X[ 4], 6); + HHH(ddd, aaa, bbb, ccc, X[ 9], 15); + HHH(ccc, ddd, aaa, bbb, X[ 1], 13); + HHH(bbb, ccc, ddd, aaa, X[ 2], 11); + + /* parallel round 3 */ + GGG(aaa, bbb, ccc, ddd, X[15], 9); + GGG(ddd, aaa, bbb, ccc, X[ 5], 7); + GGG(ccc, ddd, aaa, bbb, X[ 1], 15); + GGG(bbb, ccc, ddd, aaa, X[ 3], 11); + GGG(aaa, bbb, ccc, ddd, X[ 7], 8); + GGG(ddd, aaa, bbb, ccc, X[14], 6); + GGG(ccc, ddd, aaa, bbb, X[ 6], 6); + GGG(bbb, ccc, ddd, aaa, X[ 9], 14); + GGG(aaa, bbb, ccc, ddd, X[11], 12); + GGG(ddd, aaa, bbb, ccc, X[ 8], 13); + GGG(ccc, ddd, aaa, bbb, X[12], 5); + GGG(bbb, ccc, ddd, aaa, X[ 2], 14); + GGG(aaa, bbb, ccc, ddd, X[10], 13); + GGG(ddd, aaa, bbb, ccc, X[ 0], 13); + GGG(ccc, ddd, aaa, bbb, X[ 4], 7); + GGG(bbb, ccc, ddd, aaa, X[13], 5); + + /* parallel round 4 */ + FFF(aaa, bbb, ccc, ddd, X[ 8], 15); + FFF(ddd, aaa, bbb, ccc, X[ 6], 5); + FFF(ccc, ddd, aaa, bbb, X[ 4], 8); + FFF(bbb, ccc, ddd, aaa, X[ 1], 11); + FFF(aaa, bbb, ccc, ddd, X[ 3], 14); + FFF(ddd, aaa, bbb, ccc, X[11], 14); + FFF(ccc, ddd, aaa, bbb, X[15], 6); + FFF(bbb, ccc, ddd, aaa, X[ 0], 14); + FFF(aaa, bbb, ccc, ddd, X[ 5], 6); + FFF(ddd, aaa, bbb, ccc, X[12], 9); + FFF(ccc, ddd, aaa, bbb, X[ 2], 12); + FFF(bbb, ccc, ddd, aaa, X[13], 9); + FFF(aaa, bbb, ccc, ddd, X[ 9], 12); + FFF(ddd, aaa, bbb, ccc, X[ 7], 5); + FFF(ccc, ddd, aaa, bbb, X[10], 15); + FFF(bbb, ccc, ddd, aaa, X[14], 8); + + /* combine results */ + ddd += cc + md->rmd128.state[1]; /* final result for MDbuf[0] */ + md->rmd128.state[1] = md->rmd128.state[2] + dd + aaa; + md->rmd128.state[2] = md->rmd128.state[3] + aa + bbb; + md->rmd128.state[3] = md->rmd128.state[0] + bb + ccc; + md->rmd128.state[0] = ddd; + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +static int rmd128_compress(hash_state *md, unsigned char *buf) +{ + int err; + err = _rmd128_compress(md, buf); + burn_stack(sizeof(ulong32) * 24 + sizeof(int)); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int rmd128_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + md->rmd128.state[0] = 0x67452301UL; + md->rmd128.state[1] = 0xefcdab89UL; + md->rmd128.state[2] = 0x98badcfeUL; + md->rmd128.state[3] = 0x10325476UL; + md->rmd128.curlen = 0; + md->rmd128.length = 0; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(rmd128_process, rmd128_compress, rmd128, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (16 bytes) + @return CRYPT_OK if successful +*/ +int rmd128_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->rmd128.curlen >= sizeof(md->rmd128.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* increase the length of the message */ + md->rmd128.length += md->rmd128.curlen * 8; + + /* append the '1' bit */ + md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->rmd128.curlen > 56) { + while (md->rmd128.curlen < 64) { + md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0; + } + rmd128_compress(md, md->rmd128.buf); + md->rmd128.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->rmd128.curlen < 56) { + md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->rmd128.length, md->rmd128.buf+56); + rmd128_compress(md, md->rmd128.buf); + + /* copy output */ + for (i = 0; i < 4; i++) { + STORE32L(md->rmd128.state[i], out+(4*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int rmd128_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + char *msg; + unsigned char md[16]; + } tests[] = { + { "", + { 0xcd, 0xf2, 0x62, 0x13, 0xa1, 0x50, 0xdc, 0x3e, + 0xcb, 0x61, 0x0f, 0x18, 0xf6, 0xb3, 0x8b, 0x46 } + }, + { "a", + { 0x86, 0xbe, 0x7a, 0xfa, 0x33, 0x9d, 0x0f, 0xc7, + 0xcf, 0xc7, 0x85, 0xe7, 0x2f, 0x57, 0x8d, 0x33 } + }, + { "abc", + { 0xc1, 0x4a, 0x12, 0x19, 0x9c, 0x66, 0xe4, 0xba, + 0x84, 0x63, 0x6b, 0x0f, 0x69, 0x14, 0x4c, 0x77 } + }, + { "message digest", + { 0x9e, 0x32, 0x7b, 0x3d, 0x6e, 0x52, 0x30, 0x62, + 0xaf, 0xc1, 0x13, 0x2d, 0x7d, 0xf9, 0xd1, 0xb8 } + }, + { "abcdefghijklmnopqrstuvwxyz", + { 0xfd, 0x2a, 0xa6, 0x07, 0xf7, 0x1d, 0xc8, 0xf5, + 0x10, 0x71, 0x49, 0x22, 0xb3, 0x71, 0x83, 0x4e } + }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + { 0xd1, 0xe9, 0x59, 0xeb, 0x17, 0x9c, 0x91, 0x1f, + 0xae, 0xa4, 0x62, 0x4c, 0x60, 0xc5, 0xc7, 0x02 } + } + }; + int x; + unsigned char buf[16]; + hash_state md; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + rmd128_init(&md); + rmd128_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg)); + rmd128_done(&md, buf); + if (XMEMCMP(buf, tests[x].md, 16) != 0) { + #if 0 + printf("Failed test %d\n", x); + #endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/hashes/rmd128.c,v $ */ +/* $Revision: 1.11 $ */ +/* $Date: 2007/05/12 14:25:28 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/rmd160.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/rmd160.c new file mode 100644 index 0000000000..a6decab24f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/rmd160.c @@ -0,0 +1,469 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rmd160.c + RMD160 hash function +*/ + +/* Implementation of LTC_RIPEMD-160 based on the source by Antoon Bosselaers, ESAT-COSIC + * + * This source has been radically overhauled to be portable and work within + * the LibTomCrypt API by Tom St Denis + */ + +#ifdef LTC_RIPEMD160 + +const struct ltc_hash_descriptor rmd160_desc = +{ + "rmd160", + 9, + 20, + 64, + + /* OID */ + { 1, 3, 36, 3, 2, 1, }, + 6, + + &rmd160_init, + &rmd160_process, + &rmd160_done, + &rmd160_test, + NULL +}; + +/* the five basic functions F(), G() and H() */ +#define F(x, y, z) ((x) ^ (y) ^ (z)) +#define G(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define H(x, y, z) (((x) | ~(y)) ^ (z)) +#define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) +#define J(x, y, z) ((x) ^ ((y) | ~(z))) + +/* the ten basic operations FF() through III() */ +#define FF(a, b, c, d, e, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define GG(a, b, c, d, e, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define HH(a, b, c, d, e, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define II(a, b, c, d, e, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define JJ(a, b, c, d, e, x, s) \ + (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define FFF(a, b, c, d, e, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define GGG(a, b, c, d, e, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define HHH(a, b, c, d, e, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define III(a, b, c, d, e, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define JJJ(a, b, c, d, e, x, s) \ + (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + + +#ifdef LTC_CLEAN_STACK +static int _rmd160_compress(hash_state *md, unsigned char *buf) +#else +static int rmd160_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,X[16]; + int i; + + /* load words X */ + for (i = 0; i < 16; i++){ + LOAD32L(X[i], buf + (4 * i)); + } + + /* load state */ + aa = aaa = md->rmd160.state[0]; + bb = bbb = md->rmd160.state[1]; + cc = ccc = md->rmd160.state[2]; + dd = ddd = md->rmd160.state[3]; + ee = eee = md->rmd160.state[4]; + + /* round 1 */ + FF(aa, bb, cc, dd, ee, X[ 0], 11); + FF(ee, aa, bb, cc, dd, X[ 1], 14); + FF(dd, ee, aa, bb, cc, X[ 2], 15); + FF(cc, dd, ee, aa, bb, X[ 3], 12); + FF(bb, cc, dd, ee, aa, X[ 4], 5); + FF(aa, bb, cc, dd, ee, X[ 5], 8); + FF(ee, aa, bb, cc, dd, X[ 6], 7); + FF(dd, ee, aa, bb, cc, X[ 7], 9); + FF(cc, dd, ee, aa, bb, X[ 8], 11); + FF(bb, cc, dd, ee, aa, X[ 9], 13); + FF(aa, bb, cc, dd, ee, X[10], 14); + FF(ee, aa, bb, cc, dd, X[11], 15); + FF(dd, ee, aa, bb, cc, X[12], 6); + FF(cc, dd, ee, aa, bb, X[13], 7); + FF(bb, cc, dd, ee, aa, X[14], 9); + FF(aa, bb, cc, dd, ee, X[15], 8); + + /* round 2 */ + GG(ee, aa, bb, cc, dd, X[ 7], 7); + GG(dd, ee, aa, bb, cc, X[ 4], 6); + GG(cc, dd, ee, aa, bb, X[13], 8); + GG(bb, cc, dd, ee, aa, X[ 1], 13); + GG(aa, bb, cc, dd, ee, X[10], 11); + GG(ee, aa, bb, cc, dd, X[ 6], 9); + GG(dd, ee, aa, bb, cc, X[15], 7); + GG(cc, dd, ee, aa, bb, X[ 3], 15); + GG(bb, cc, dd, ee, aa, X[12], 7); + GG(aa, bb, cc, dd, ee, X[ 0], 12); + GG(ee, aa, bb, cc, dd, X[ 9], 15); + GG(dd, ee, aa, bb, cc, X[ 5], 9); + GG(cc, dd, ee, aa, bb, X[ 2], 11); + GG(bb, cc, dd, ee, aa, X[14], 7); + GG(aa, bb, cc, dd, ee, X[11], 13); + GG(ee, aa, bb, cc, dd, X[ 8], 12); + + /* round 3 */ + HH(dd, ee, aa, bb, cc, X[ 3], 11); + HH(cc, dd, ee, aa, bb, X[10], 13); + HH(bb, cc, dd, ee, aa, X[14], 6); + HH(aa, bb, cc, dd, ee, X[ 4], 7); + HH(ee, aa, bb, cc, dd, X[ 9], 14); + HH(dd, ee, aa, bb, cc, X[15], 9); + HH(cc, dd, ee, aa, bb, X[ 8], 13); + HH(bb, cc, dd, ee, aa, X[ 1], 15); + HH(aa, bb, cc, dd, ee, X[ 2], 14); + HH(ee, aa, bb, cc, dd, X[ 7], 8); + HH(dd, ee, aa, bb, cc, X[ 0], 13); + HH(cc, dd, ee, aa, bb, X[ 6], 6); + HH(bb, cc, dd, ee, aa, X[13], 5); + HH(aa, bb, cc, dd, ee, X[11], 12); + HH(ee, aa, bb, cc, dd, X[ 5], 7); + HH(dd, ee, aa, bb, cc, X[12], 5); + + /* round 4 */ + II(cc, dd, ee, aa, bb, X[ 1], 11); + II(bb, cc, dd, ee, aa, X[ 9], 12); + II(aa, bb, cc, dd, ee, X[11], 14); + II(ee, aa, bb, cc, dd, X[10], 15); + II(dd, ee, aa, bb, cc, X[ 0], 14); + II(cc, dd, ee, aa, bb, X[ 8], 15); + II(bb, cc, dd, ee, aa, X[12], 9); + II(aa, bb, cc, dd, ee, X[ 4], 8); + II(ee, aa, bb, cc, dd, X[13], 9); + II(dd, ee, aa, bb, cc, X[ 3], 14); + II(cc, dd, ee, aa, bb, X[ 7], 5); + II(bb, cc, dd, ee, aa, X[15], 6); + II(aa, bb, cc, dd, ee, X[14], 8); + II(ee, aa, bb, cc, dd, X[ 5], 6); + II(dd, ee, aa, bb, cc, X[ 6], 5); + II(cc, dd, ee, aa, bb, X[ 2], 12); + + /* round 5 */ + JJ(bb, cc, dd, ee, aa, X[ 4], 9); + JJ(aa, bb, cc, dd, ee, X[ 0], 15); + JJ(ee, aa, bb, cc, dd, X[ 5], 5); + JJ(dd, ee, aa, bb, cc, X[ 9], 11); + JJ(cc, dd, ee, aa, bb, X[ 7], 6); + JJ(bb, cc, dd, ee, aa, X[12], 8); + JJ(aa, bb, cc, dd, ee, X[ 2], 13); + JJ(ee, aa, bb, cc, dd, X[10], 12); + JJ(dd, ee, aa, bb, cc, X[14], 5); + JJ(cc, dd, ee, aa, bb, X[ 1], 12); + JJ(bb, cc, dd, ee, aa, X[ 3], 13); + JJ(aa, bb, cc, dd, ee, X[ 8], 14); + JJ(ee, aa, bb, cc, dd, X[11], 11); + JJ(dd, ee, aa, bb, cc, X[ 6], 8); + JJ(cc, dd, ee, aa, bb, X[15], 5); + JJ(bb, cc, dd, ee, aa, X[13], 6); + + /* parallel round 1 */ + JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9); + JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13); + JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15); + JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5); + JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7); + JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14); + JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12); + JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6); + + /* parallel round 2 */ + III(eee, aaa, bbb, ccc, ddd, X[ 6], 9); + III(ddd, eee, aaa, bbb, ccc, X[11], 13); + III(ccc, ddd, eee, aaa, bbb, X[ 3], 15); + III(bbb, ccc, ddd, eee, aaa, X[ 7], 7); + III(aaa, bbb, ccc, ddd, eee, X[ 0], 12); + III(eee, aaa, bbb, ccc, ddd, X[13], 8); + III(ddd, eee, aaa, bbb, ccc, X[ 5], 9); + III(ccc, ddd, eee, aaa, bbb, X[10], 11); + III(bbb, ccc, ddd, eee, aaa, X[14], 7); + III(aaa, bbb, ccc, ddd, eee, X[15], 7); + III(eee, aaa, bbb, ccc, ddd, X[ 8], 12); + III(ddd, eee, aaa, bbb, ccc, X[12], 7); + III(ccc, ddd, eee, aaa, bbb, X[ 4], 6); + III(bbb, ccc, ddd, eee, aaa, X[ 9], 15); + III(aaa, bbb, ccc, ddd, eee, X[ 1], 13); + III(eee, aaa, bbb, ccc, ddd, X[ 2], 11); + + /* parallel round 3 */ + HHH(ddd, eee, aaa, bbb, ccc, X[15], 9); + HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7); + HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15); + HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11); + HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8); + HHH(ddd, eee, aaa, bbb, ccc, X[14], 6); + HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6); + HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14); + HHH(aaa, bbb, ccc, ddd, eee, X[11], 12); + HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13); + HHH(ddd, eee, aaa, bbb, ccc, X[12], 5); + HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14); + HHH(bbb, ccc, ddd, eee, aaa, X[10], 13); + HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13); + HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7); + HHH(ddd, eee, aaa, bbb, ccc, X[13], 5); + + /* parallel round 4 */ + GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15); + GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5); + GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8); + GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11); + GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14); + GGG(ccc, ddd, eee, aaa, bbb, X[11], 14); + GGG(bbb, ccc, ddd, eee, aaa, X[15], 6); + GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14); + GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6); + GGG(ddd, eee, aaa, bbb, ccc, X[12], 9); + GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12); + GGG(bbb, ccc, ddd, eee, aaa, X[13], 9); + GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12); + GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5); + GGG(ddd, eee, aaa, bbb, ccc, X[10], 15); + GGG(ccc, ddd, eee, aaa, bbb, X[14], 8); + + /* parallel round 5 */ + FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8); + FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12); + FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9); + FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12); + FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5); + FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14); + FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6); + FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8); + FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13); + FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6); + FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15); + FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13); + FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11); + FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11); + + /* combine results */ + ddd += cc + md->rmd160.state[1]; /* final result for md->rmd160.state[0] */ + md->rmd160.state[1] = md->rmd160.state[2] + dd + eee; + md->rmd160.state[2] = md->rmd160.state[3] + ee + aaa; + md->rmd160.state[3] = md->rmd160.state[4] + aa + bbb; + md->rmd160.state[4] = md->rmd160.state[0] + bb + ccc; + md->rmd160.state[0] = ddd; + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +static int rmd160_compress(hash_state *md, unsigned char *buf) +{ + int err; + err = _rmd160_compress(md, buf); + burn_stack(sizeof(ulong32) * 26 + sizeof(int)); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int rmd160_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + md->rmd160.state[0] = 0x67452301UL; + md->rmd160.state[1] = 0xefcdab89UL; + md->rmd160.state[2] = 0x98badcfeUL; + md->rmd160.state[3] = 0x10325476UL; + md->rmd160.state[4] = 0xc3d2e1f0UL; + md->rmd160.curlen = 0; + md->rmd160.length = 0; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(rmd160_process, rmd160_compress, rmd160, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (20 bytes) + @return CRYPT_OK if successful +*/ +int rmd160_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->rmd160.curlen >= sizeof(md->rmd160.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* increase the length of the message */ + md->rmd160.length += md->rmd160.curlen * 8; + + /* append the '1' bit */ + md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->rmd160.curlen > 56) { + while (md->rmd160.curlen < 64) { + md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0; + } + rmd160_compress(md, md->rmd160.buf); + md->rmd160.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->rmd160.curlen < 56) { + md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->rmd160.length, md->rmd160.buf+56); + rmd160_compress(md, md->rmd160.buf); + + /* copy output */ + for (i = 0; i < 5; i++) { + STORE32L(md->rmd160.state[i], out+(4*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int rmd160_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + char *msg; + unsigned char md[20]; + } tests[] = { + { "", + { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28, + 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 } + }, + { "a", + { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae, + 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe } + }, + { "abc", + { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04, + 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc } + }, + { "message digest", + { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8, + 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 } + }, + { "abcdefghijklmnopqrstuvwxyz", + { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb, + 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc } + }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05, + 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b } + } + }; + int x; + unsigned char buf[20]; + hash_state md; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + rmd160_init(&md); + rmd160_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg)); + rmd160_done(&md, buf); + if (XMEMCMP(buf, tests[x].md, 20) != 0) { +#if 0 + printf("Failed test %d\n", x); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/hashes/rmd160.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:25:28 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/rmd256.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/rmd256.c new file mode 100644 index 0000000000..8187e9cd4e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/rmd256.c @@ -0,0 +1,430 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @param rmd256.c + RLTC_MD256 Hash function +*/ + +#ifdef LTC_RIPEMD256 + +const struct ltc_hash_descriptor rmd256_desc = +{ + "rmd256", + 8, + 32, + 64, + + /* OID */ + { 1, 3, 36, 3, 2, 3 }, + 6, + + &rmd256_init, + &rmd256_process, + &rmd256_done, + &rmd256_test, + NULL +}; + +/* the four basic functions F(), G() and H() */ +#define F(x, y, z) ((x) ^ (y) ^ (z)) +#define G(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define H(x, y, z) (((x) | ~(y)) ^ (z)) +#define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) + +/* the eight basic operations FF() through III() */ +#define FF(a, b, c, d, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROLc((a), (s)); + +#define GG(a, b, c, d, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ + (a) = ROLc((a), (s)); + +#define HH(a, b, c, d, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ + (a) = ROLc((a), (s)); + +#define II(a, b, c, d, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ + (a) = ROLc((a), (s)); + +#define FFF(a, b, c, d, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROLc((a), (s)); + +#define GGG(a, b, c, d, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\ + (a) = ROLc((a), (s)); + +#define HHH(a, b, c, d, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\ + (a) = ROLc((a), (s)); + +#define III(a, b, c, d, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\ + (a) = ROLc((a), (s)); + +#ifdef LTC_CLEAN_STACK +static int _rmd256_compress(hash_state *md, unsigned char *buf) +#else +static int rmd256_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,tmp,X[16]; + int i; + + /* load words X */ + for (i = 0; i < 16; i++){ + LOAD32L(X[i], buf + (4 * i)); + } + + /* load state */ + aa = md->rmd256.state[0]; + bb = md->rmd256.state[1]; + cc = md->rmd256.state[2]; + dd = md->rmd256.state[3]; + aaa = md->rmd256.state[4]; + bbb = md->rmd256.state[5]; + ccc = md->rmd256.state[6]; + ddd = md->rmd256.state[7]; + + /* round 1 */ + FF(aa, bb, cc, dd, X[ 0], 11); + FF(dd, aa, bb, cc, X[ 1], 14); + FF(cc, dd, aa, bb, X[ 2], 15); + FF(bb, cc, dd, aa, X[ 3], 12); + FF(aa, bb, cc, dd, X[ 4], 5); + FF(dd, aa, bb, cc, X[ 5], 8); + FF(cc, dd, aa, bb, X[ 6], 7); + FF(bb, cc, dd, aa, X[ 7], 9); + FF(aa, bb, cc, dd, X[ 8], 11); + FF(dd, aa, bb, cc, X[ 9], 13); + FF(cc, dd, aa, bb, X[10], 14); + FF(bb, cc, dd, aa, X[11], 15); + FF(aa, bb, cc, dd, X[12], 6); + FF(dd, aa, bb, cc, X[13], 7); + FF(cc, dd, aa, bb, X[14], 9); + FF(bb, cc, dd, aa, X[15], 8); + + /* parallel round 1 */ + III(aaa, bbb, ccc, ddd, X[ 5], 8); + III(ddd, aaa, bbb, ccc, X[14], 9); + III(ccc, ddd, aaa, bbb, X[ 7], 9); + III(bbb, ccc, ddd, aaa, X[ 0], 11); + III(aaa, bbb, ccc, ddd, X[ 9], 13); + III(ddd, aaa, bbb, ccc, X[ 2], 15); + III(ccc, ddd, aaa, bbb, X[11], 15); + III(bbb, ccc, ddd, aaa, X[ 4], 5); + III(aaa, bbb, ccc, ddd, X[13], 7); + III(ddd, aaa, bbb, ccc, X[ 6], 7); + III(ccc, ddd, aaa, bbb, X[15], 8); + III(bbb, ccc, ddd, aaa, X[ 8], 11); + III(aaa, bbb, ccc, ddd, X[ 1], 14); + III(ddd, aaa, bbb, ccc, X[10], 14); + III(ccc, ddd, aaa, bbb, X[ 3], 12); + III(bbb, ccc, ddd, aaa, X[12], 6); + + tmp = aa; aa = aaa; aaa = tmp; + + /* round 2 */ + GG(aa, bb, cc, dd, X[ 7], 7); + GG(dd, aa, bb, cc, X[ 4], 6); + GG(cc, dd, aa, bb, X[13], 8); + GG(bb, cc, dd, aa, X[ 1], 13); + GG(aa, bb, cc, dd, X[10], 11); + GG(dd, aa, bb, cc, X[ 6], 9); + GG(cc, dd, aa, bb, X[15], 7); + GG(bb, cc, dd, aa, X[ 3], 15); + GG(aa, bb, cc, dd, X[12], 7); + GG(dd, aa, bb, cc, X[ 0], 12); + GG(cc, dd, aa, bb, X[ 9], 15); + GG(bb, cc, dd, aa, X[ 5], 9); + GG(aa, bb, cc, dd, X[ 2], 11); + GG(dd, aa, bb, cc, X[14], 7); + GG(cc, dd, aa, bb, X[11], 13); + GG(bb, cc, dd, aa, X[ 8], 12); + + /* parallel round 2 */ + HHH(aaa, bbb, ccc, ddd, X[ 6], 9); + HHH(ddd, aaa, bbb, ccc, X[11], 13); + HHH(ccc, ddd, aaa, bbb, X[ 3], 15); + HHH(bbb, ccc, ddd, aaa, X[ 7], 7); + HHH(aaa, bbb, ccc, ddd, X[ 0], 12); + HHH(ddd, aaa, bbb, ccc, X[13], 8); + HHH(ccc, ddd, aaa, bbb, X[ 5], 9); + HHH(bbb, ccc, ddd, aaa, X[10], 11); + HHH(aaa, bbb, ccc, ddd, X[14], 7); + HHH(ddd, aaa, bbb, ccc, X[15], 7); + HHH(ccc, ddd, aaa, bbb, X[ 8], 12); + HHH(bbb, ccc, ddd, aaa, X[12], 7); + HHH(aaa, bbb, ccc, ddd, X[ 4], 6); + HHH(ddd, aaa, bbb, ccc, X[ 9], 15); + HHH(ccc, ddd, aaa, bbb, X[ 1], 13); + HHH(bbb, ccc, ddd, aaa, X[ 2], 11); + + tmp = bb; bb = bbb; bbb = tmp; + + /* round 3 */ + HH(aa, bb, cc, dd, X[ 3], 11); + HH(dd, aa, bb, cc, X[10], 13); + HH(cc, dd, aa, bb, X[14], 6); + HH(bb, cc, dd, aa, X[ 4], 7); + HH(aa, bb, cc, dd, X[ 9], 14); + HH(dd, aa, bb, cc, X[15], 9); + HH(cc, dd, aa, bb, X[ 8], 13); + HH(bb, cc, dd, aa, X[ 1], 15); + HH(aa, bb, cc, dd, X[ 2], 14); + HH(dd, aa, bb, cc, X[ 7], 8); + HH(cc, dd, aa, bb, X[ 0], 13); + HH(bb, cc, dd, aa, X[ 6], 6); + HH(aa, bb, cc, dd, X[13], 5); + HH(dd, aa, bb, cc, X[11], 12); + HH(cc, dd, aa, bb, X[ 5], 7); + HH(bb, cc, dd, aa, X[12], 5); + + /* parallel round 3 */ + GGG(aaa, bbb, ccc, ddd, X[15], 9); + GGG(ddd, aaa, bbb, ccc, X[ 5], 7); + GGG(ccc, ddd, aaa, bbb, X[ 1], 15); + GGG(bbb, ccc, ddd, aaa, X[ 3], 11); + GGG(aaa, bbb, ccc, ddd, X[ 7], 8); + GGG(ddd, aaa, bbb, ccc, X[14], 6); + GGG(ccc, ddd, aaa, bbb, X[ 6], 6); + GGG(bbb, ccc, ddd, aaa, X[ 9], 14); + GGG(aaa, bbb, ccc, ddd, X[11], 12); + GGG(ddd, aaa, bbb, ccc, X[ 8], 13); + GGG(ccc, ddd, aaa, bbb, X[12], 5); + GGG(bbb, ccc, ddd, aaa, X[ 2], 14); + GGG(aaa, bbb, ccc, ddd, X[10], 13); + GGG(ddd, aaa, bbb, ccc, X[ 0], 13); + GGG(ccc, ddd, aaa, bbb, X[ 4], 7); + GGG(bbb, ccc, ddd, aaa, X[13], 5); + + tmp = cc; cc = ccc; ccc = tmp; + + /* round 4 */ + II(aa, bb, cc, dd, X[ 1], 11); + II(dd, aa, bb, cc, X[ 9], 12); + II(cc, dd, aa, bb, X[11], 14); + II(bb, cc, dd, aa, X[10], 15); + II(aa, bb, cc, dd, X[ 0], 14); + II(dd, aa, bb, cc, X[ 8], 15); + II(cc, dd, aa, bb, X[12], 9); + II(bb, cc, dd, aa, X[ 4], 8); + II(aa, bb, cc, dd, X[13], 9); + II(dd, aa, bb, cc, X[ 3], 14); + II(cc, dd, aa, bb, X[ 7], 5); + II(bb, cc, dd, aa, X[15], 6); + II(aa, bb, cc, dd, X[14], 8); + II(dd, aa, bb, cc, X[ 5], 6); + II(cc, dd, aa, bb, X[ 6], 5); + II(bb, cc, dd, aa, X[ 2], 12); + + /* parallel round 4 */ + FFF(aaa, bbb, ccc, ddd, X[ 8], 15); + FFF(ddd, aaa, bbb, ccc, X[ 6], 5); + FFF(ccc, ddd, aaa, bbb, X[ 4], 8); + FFF(bbb, ccc, ddd, aaa, X[ 1], 11); + FFF(aaa, bbb, ccc, ddd, X[ 3], 14); + FFF(ddd, aaa, bbb, ccc, X[11], 14); + FFF(ccc, ddd, aaa, bbb, X[15], 6); + FFF(bbb, ccc, ddd, aaa, X[ 0], 14); + FFF(aaa, bbb, ccc, ddd, X[ 5], 6); + FFF(ddd, aaa, bbb, ccc, X[12], 9); + FFF(ccc, ddd, aaa, bbb, X[ 2], 12); + FFF(bbb, ccc, ddd, aaa, X[13], 9); + FFF(aaa, bbb, ccc, ddd, X[ 9], 12); + FFF(ddd, aaa, bbb, ccc, X[ 7], 5); + FFF(ccc, ddd, aaa, bbb, X[10], 15); + FFF(bbb, ccc, ddd, aaa, X[14], 8); + + tmp = dd; dd = ddd; ddd = tmp; + + /* combine results */ + md->rmd256.state[0] += aa; + md->rmd256.state[1] += bb; + md->rmd256.state[2] += cc; + md->rmd256.state[3] += dd; + md->rmd256.state[4] += aaa; + md->rmd256.state[5] += bbb; + md->rmd256.state[6] += ccc; + md->rmd256.state[7] += ddd; + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +static int rmd256_compress(hash_state *md, unsigned char *buf) +{ + int err; + err = _rmd256_compress(md, buf); + burn_stack(sizeof(ulong32) * 25 + sizeof(int)); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int rmd256_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + md->rmd256.state[0] = 0x67452301UL; + md->rmd256.state[1] = 0xefcdab89UL; + md->rmd256.state[2] = 0x98badcfeUL; + md->rmd256.state[3] = 0x10325476UL; + md->rmd256.state[4] = 0x76543210UL; + md->rmd256.state[5] = 0xfedcba98UL; + md->rmd256.state[6] = 0x89abcdefUL; + md->rmd256.state[7] = 0x01234567UL; + md->rmd256.curlen = 0; + md->rmd256.length = 0; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(rmd256_process, rmd256_compress, rmd256, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (16 bytes) + @return CRYPT_OK if successful +*/ +int rmd256_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->rmd256.curlen >= sizeof(md->rmd256.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* increase the length of the message */ + md->rmd256.length += md->rmd256.curlen * 8; + + /* append the '1' bit */ + md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->rmd256.curlen > 56) { + while (md->rmd256.curlen < 64) { + md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0; + } + rmd256_compress(md, md->rmd256.buf); + md->rmd256.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->rmd256.curlen < 56) { + md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->rmd256.length, md->rmd256.buf+56); + rmd256_compress(md, md->rmd256.buf); + + /* copy output */ + for (i = 0; i < 8; i++) { + STORE32L(md->rmd256.state[i], out+(4*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int rmd256_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + char *msg; + unsigned char md[32]; + } tests[] = { + { "", + { 0x02, 0xba, 0x4c, 0x4e, 0x5f, 0x8e, 0xcd, 0x18, + 0x77, 0xfc, 0x52, 0xd6, 0x4d, 0x30, 0xe3, 0x7a, + 0x2d, 0x97, 0x74, 0xfb, 0x1e, 0x5d, 0x02, 0x63, + 0x80, 0xae, 0x01, 0x68, 0xe3, 0xc5, 0x52, 0x2d } + }, + { "a", + { 0xf9, 0x33, 0x3e, 0x45, 0xd8, 0x57, 0xf5, 0xd9, + 0x0a, 0x91, 0xba, 0xb7, 0x0a, 0x1e, 0xba, 0x0c, + 0xfb, 0x1b, 0xe4, 0xb0, 0x78, 0x3c, 0x9a, 0xcf, + 0xcd, 0x88, 0x3a, 0x91, 0x34, 0x69, 0x29, 0x25 } + }, + { "abc", + { 0xaf, 0xbd, 0x6e, 0x22, 0x8b, 0x9d, 0x8c, 0xbb, + 0xce, 0xf5, 0xca, 0x2d, 0x03, 0xe6, 0xdb, 0xa1, + 0x0a, 0xc0, 0xbc, 0x7d, 0xcb, 0xe4, 0x68, 0x0e, + 0x1e, 0x42, 0xd2, 0xe9, 0x75, 0x45, 0x9b, 0x65 } + }, + { "message digest", + { 0x87, 0xe9, 0x71, 0x75, 0x9a, 0x1c, 0xe4, 0x7a, + 0x51, 0x4d, 0x5c, 0x91, 0x4c, 0x39, 0x2c, 0x90, + 0x18, 0xc7, 0xc4, 0x6b, 0xc1, 0x44, 0x65, 0x55, + 0x4a, 0xfc, 0xdf, 0x54, 0xa5, 0x07, 0x0c, 0x0e } + }, + { "abcdefghijklmnopqrstuvwxyz", + { 0x64, 0x9d, 0x30, 0x34, 0x75, 0x1e, 0xa2, 0x16, + 0x77, 0x6b, 0xf9, 0xa1, 0x8a, 0xcc, 0x81, 0xbc, + 0x78, 0x96, 0x11, 0x8a, 0x51, 0x97, 0x96, 0x87, + 0x82, 0xdd, 0x1f, 0xd9, 0x7d, 0x8d, 0x51, 0x33 } + }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + { 0x57, 0x40, 0xa4, 0x08, 0xac, 0x16, 0xb7, 0x20, + 0xb8, 0x44, 0x24, 0xae, 0x93, 0x1c, 0xbb, 0x1f, + 0xe3, 0x63, 0xd1, 0xd0, 0xbf, 0x40, 0x17, 0xf1, + 0xa8, 0x9f, 0x7e, 0xa6, 0xde, 0x77, 0xa0, 0xb8 } + } + }; + int x; + unsigned char buf[32]; + hash_state md; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + rmd256_init(&md); + rmd256_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg)); + rmd256_done(&md, buf); + if (XMEMCMP(buf, tests[x].md, 32) != 0) { + #if 0 + printf("Failed test %d\n", x); + #endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + +#endif diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/rmd320.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/rmd320.c new file mode 100644 index 0000000000..a24cfdc4b6 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/rmd320.c @@ -0,0 +1,494 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rmd320.c + RMD320 hash function +*/ + +#ifdef LTC_RIPEMD320 + +const struct ltc_hash_descriptor rmd320_desc = +{ + "rmd320", + 9, + 40, + 64, + + /* OID */ + { 0 }, + 0, + + &rmd320_init, + &rmd320_process, + &rmd320_done, + &rmd320_test, + NULL +}; + +/* the five basic functions F(), G() and H() */ +#define F(x, y, z) ((x) ^ (y) ^ (z)) +#define G(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define H(x, y, z) (((x) | ~(y)) ^ (z)) +#define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) +#define J(x, y, z) ((x) ^ ((y) | ~(z))) + +/* the ten basic operations FF() through III() */ +#define FF(a, b, c, d, e, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define GG(a, b, c, d, e, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define HH(a, b, c, d, e, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define II(a, b, c, d, e, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define JJ(a, b, c, d, e, x, s) \ + (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define FFF(a, b, c, d, e, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define GGG(a, b, c, d, e, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define HHH(a, b, c, d, e, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define III(a, b, c, d, e, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define JJJ(a, b, c, d, e, x, s) \ + (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + + +#ifdef LTC_CLEAN_STACK +static int _rmd320_compress(hash_state *md, unsigned char *buf) +#else +static int rmd320_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,tmp,X[16]; + int i; + + /* load words X */ + for (i = 0; i < 16; i++){ + LOAD32L(X[i], buf + (4 * i)); + } + + /* load state */ + aa = md->rmd320.state[0]; + bb = md->rmd320.state[1]; + cc = md->rmd320.state[2]; + dd = md->rmd320.state[3]; + ee = md->rmd320.state[4]; + aaa = md->rmd320.state[5]; + bbb = md->rmd320.state[6]; + ccc = md->rmd320.state[7]; + ddd = md->rmd320.state[8]; + eee = md->rmd320.state[9]; + + /* round 1 */ + FF(aa, bb, cc, dd, ee, X[ 0], 11); + FF(ee, aa, bb, cc, dd, X[ 1], 14); + FF(dd, ee, aa, bb, cc, X[ 2], 15); + FF(cc, dd, ee, aa, bb, X[ 3], 12); + FF(bb, cc, dd, ee, aa, X[ 4], 5); + FF(aa, bb, cc, dd, ee, X[ 5], 8); + FF(ee, aa, bb, cc, dd, X[ 6], 7); + FF(dd, ee, aa, bb, cc, X[ 7], 9); + FF(cc, dd, ee, aa, bb, X[ 8], 11); + FF(bb, cc, dd, ee, aa, X[ 9], 13); + FF(aa, bb, cc, dd, ee, X[10], 14); + FF(ee, aa, bb, cc, dd, X[11], 15); + FF(dd, ee, aa, bb, cc, X[12], 6); + FF(cc, dd, ee, aa, bb, X[13], 7); + FF(bb, cc, dd, ee, aa, X[14], 9); + FF(aa, bb, cc, dd, ee, X[15], 8); + + /* parallel round 1 */ + JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9); + JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13); + JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15); + JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5); + JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7); + JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14); + JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12); + JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6); + + tmp = aa; aa = aaa; aaa = tmp; + + /* round 2 */ + GG(ee, aa, bb, cc, dd, X[ 7], 7); + GG(dd, ee, aa, bb, cc, X[ 4], 6); + GG(cc, dd, ee, aa, bb, X[13], 8); + GG(bb, cc, dd, ee, aa, X[ 1], 13); + GG(aa, bb, cc, dd, ee, X[10], 11); + GG(ee, aa, bb, cc, dd, X[ 6], 9); + GG(dd, ee, aa, bb, cc, X[15], 7); + GG(cc, dd, ee, aa, bb, X[ 3], 15); + GG(bb, cc, dd, ee, aa, X[12], 7); + GG(aa, bb, cc, dd, ee, X[ 0], 12); + GG(ee, aa, bb, cc, dd, X[ 9], 15); + GG(dd, ee, aa, bb, cc, X[ 5], 9); + GG(cc, dd, ee, aa, bb, X[ 2], 11); + GG(bb, cc, dd, ee, aa, X[14], 7); + GG(aa, bb, cc, dd, ee, X[11], 13); + GG(ee, aa, bb, cc, dd, X[ 8], 12); + + /* parallel round 2 */ + III(eee, aaa, bbb, ccc, ddd, X[ 6], 9); + III(ddd, eee, aaa, bbb, ccc, X[11], 13); + III(ccc, ddd, eee, aaa, bbb, X[ 3], 15); + III(bbb, ccc, ddd, eee, aaa, X[ 7], 7); + III(aaa, bbb, ccc, ddd, eee, X[ 0], 12); + III(eee, aaa, bbb, ccc, ddd, X[13], 8); + III(ddd, eee, aaa, bbb, ccc, X[ 5], 9); + III(ccc, ddd, eee, aaa, bbb, X[10], 11); + III(bbb, ccc, ddd, eee, aaa, X[14], 7); + III(aaa, bbb, ccc, ddd, eee, X[15], 7); + III(eee, aaa, bbb, ccc, ddd, X[ 8], 12); + III(ddd, eee, aaa, bbb, ccc, X[12], 7); + III(ccc, ddd, eee, aaa, bbb, X[ 4], 6); + III(bbb, ccc, ddd, eee, aaa, X[ 9], 15); + III(aaa, bbb, ccc, ddd, eee, X[ 1], 13); + III(eee, aaa, bbb, ccc, ddd, X[ 2], 11); + + tmp = bb; bb = bbb; bbb = tmp; + + /* round 3 */ + HH(dd, ee, aa, bb, cc, X[ 3], 11); + HH(cc, dd, ee, aa, bb, X[10], 13); + HH(bb, cc, dd, ee, aa, X[14], 6); + HH(aa, bb, cc, dd, ee, X[ 4], 7); + HH(ee, aa, bb, cc, dd, X[ 9], 14); + HH(dd, ee, aa, bb, cc, X[15], 9); + HH(cc, dd, ee, aa, bb, X[ 8], 13); + HH(bb, cc, dd, ee, aa, X[ 1], 15); + HH(aa, bb, cc, dd, ee, X[ 2], 14); + HH(ee, aa, bb, cc, dd, X[ 7], 8); + HH(dd, ee, aa, bb, cc, X[ 0], 13); + HH(cc, dd, ee, aa, bb, X[ 6], 6); + HH(bb, cc, dd, ee, aa, X[13], 5); + HH(aa, bb, cc, dd, ee, X[11], 12); + HH(ee, aa, bb, cc, dd, X[ 5], 7); + HH(dd, ee, aa, bb, cc, X[12], 5); + + /* parallel round 3 */ + HHH(ddd, eee, aaa, bbb, ccc, X[15], 9); + HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7); + HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15); + HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11); + HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8); + HHH(ddd, eee, aaa, bbb, ccc, X[14], 6); + HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6); + HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14); + HHH(aaa, bbb, ccc, ddd, eee, X[11], 12); + HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13); + HHH(ddd, eee, aaa, bbb, ccc, X[12], 5); + HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14); + HHH(bbb, ccc, ddd, eee, aaa, X[10], 13); + HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13); + HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7); + HHH(ddd, eee, aaa, bbb, ccc, X[13], 5); + + tmp = cc; cc = ccc; ccc = tmp; + + /* round 4 */ + II(cc, dd, ee, aa, bb, X[ 1], 11); + II(bb, cc, dd, ee, aa, X[ 9], 12); + II(aa, bb, cc, dd, ee, X[11], 14); + II(ee, aa, bb, cc, dd, X[10], 15); + II(dd, ee, aa, bb, cc, X[ 0], 14); + II(cc, dd, ee, aa, bb, X[ 8], 15); + II(bb, cc, dd, ee, aa, X[12], 9); + II(aa, bb, cc, dd, ee, X[ 4], 8); + II(ee, aa, bb, cc, dd, X[13], 9); + II(dd, ee, aa, bb, cc, X[ 3], 14); + II(cc, dd, ee, aa, bb, X[ 7], 5); + II(bb, cc, dd, ee, aa, X[15], 6); + II(aa, bb, cc, dd, ee, X[14], 8); + II(ee, aa, bb, cc, dd, X[ 5], 6); + II(dd, ee, aa, bb, cc, X[ 6], 5); + II(cc, dd, ee, aa, bb, X[ 2], 12); + + /* parallel round 4 */ + GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15); + GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5); + GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8); + GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11); + GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14); + GGG(ccc, ddd, eee, aaa, bbb, X[11], 14); + GGG(bbb, ccc, ddd, eee, aaa, X[15], 6); + GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14); + GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6); + GGG(ddd, eee, aaa, bbb, ccc, X[12], 9); + GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12); + GGG(bbb, ccc, ddd, eee, aaa, X[13], 9); + GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12); + GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5); + GGG(ddd, eee, aaa, bbb, ccc, X[10], 15); + GGG(ccc, ddd, eee, aaa, bbb, X[14], 8); + + tmp = dd; dd = ddd; ddd = tmp; + + /* round 5 */ + JJ(bb, cc, dd, ee, aa, X[ 4], 9); + JJ(aa, bb, cc, dd, ee, X[ 0], 15); + JJ(ee, aa, bb, cc, dd, X[ 5], 5); + JJ(dd, ee, aa, bb, cc, X[ 9], 11); + JJ(cc, dd, ee, aa, bb, X[ 7], 6); + JJ(bb, cc, dd, ee, aa, X[12], 8); + JJ(aa, bb, cc, dd, ee, X[ 2], 13); + JJ(ee, aa, bb, cc, dd, X[10], 12); + JJ(dd, ee, aa, bb, cc, X[14], 5); + JJ(cc, dd, ee, aa, bb, X[ 1], 12); + JJ(bb, cc, dd, ee, aa, X[ 3], 13); + JJ(aa, bb, cc, dd, ee, X[ 8], 14); + JJ(ee, aa, bb, cc, dd, X[11], 11); + JJ(dd, ee, aa, bb, cc, X[ 6], 8); + JJ(cc, dd, ee, aa, bb, X[15], 5); + JJ(bb, cc, dd, ee, aa, X[13], 6); + + /* parallel round 5 */ + FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8); + FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12); + FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9); + FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12); + FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5); + FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14); + FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6); + FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8); + FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13); + FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6); + FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15); + FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13); + FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11); + FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11); + + tmp = ee; ee = eee; eee = tmp; + + /* combine results */ + md->rmd320.state[0] += aa; + md->rmd320.state[1] += bb; + md->rmd320.state[2] += cc; + md->rmd320.state[3] += dd; + md->rmd320.state[4] += ee; + md->rmd320.state[5] += aaa; + md->rmd320.state[6] += bbb; + md->rmd320.state[7] += ccc; + md->rmd320.state[8] += ddd; + md->rmd320.state[9] += eee; + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +static int rmd320_compress(hash_state *md, unsigned char *buf) +{ + int err; + err = _rmd320_compress(md, buf); + burn_stack(sizeof(ulong32) * 27 + sizeof(int)); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int rmd320_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + md->rmd320.state[0] = 0x67452301UL; + md->rmd320.state[1] = 0xefcdab89UL; + md->rmd320.state[2] = 0x98badcfeUL; + md->rmd320.state[3] = 0x10325476UL; + md->rmd320.state[4] = 0xc3d2e1f0UL; + md->rmd320.state[5] = 0x76543210UL; + md->rmd320.state[6] = 0xfedcba98UL; + md->rmd320.state[7] = 0x89abcdefUL; + md->rmd320.state[8] = 0x01234567UL; + md->rmd320.state[9] = 0x3c2d1e0fUL; + md->rmd320.curlen = 0; + md->rmd320.length = 0; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(rmd320_process, rmd320_compress, rmd320, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (20 bytes) + @return CRYPT_OK if successful +*/ +int rmd320_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->rmd320.curlen >= sizeof(md->rmd320.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* increase the length of the message */ + md->rmd320.length += md->rmd320.curlen * 8; + + /* append the '1' bit */ + md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->rmd320.curlen > 56) { + while (md->rmd320.curlen < 64) { + md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0; + } + rmd320_compress(md, md->rmd320.buf); + md->rmd320.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->rmd320.curlen < 56) { + md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->rmd320.length, md->rmd320.buf+56); + rmd320_compress(md, md->rmd320.buf); + + /* copy output */ + for (i = 0; i < 10; i++) { + STORE32L(md->rmd320.state[i], out+(4*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int rmd320_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + char *msg; + unsigned char md[40]; + } tests[] = { + { "", + { 0x22, 0xd6, 0x5d, 0x56, 0x61, 0x53, 0x6c, 0xdc, 0x75, 0xc1, + 0xfd, 0xf5, 0xc6, 0xde, 0x7b, 0x41, 0xb9, 0xf2, 0x73, 0x25, + 0xeb, 0xc6, 0x1e, 0x85, 0x57, 0x17, 0x7d, 0x70, 0x5a, 0x0e, + 0xc8, 0x80, 0x15, 0x1c, 0x3a, 0x32, 0xa0, 0x08, 0x99, 0xb8 } + }, + { "a", + { 0xce, 0x78, 0x85, 0x06, 0x38, 0xf9, 0x26, 0x58, 0xa5, 0xa5, + 0x85, 0x09, 0x75, 0x79, 0x92, 0x6d, 0xda, 0x66, 0x7a, 0x57, + 0x16, 0x56, 0x2c, 0xfc, 0xf6, 0xfb, 0xe7, 0x7f, 0x63, 0x54, + 0x2f, 0x99, 0xb0, 0x47, 0x05, 0xd6, 0x97, 0x0d, 0xff, 0x5d } + }, + { "abc", + { 0xde, 0x4c, 0x01, 0xb3, 0x05, 0x4f, 0x89, 0x30, 0xa7, 0x9d, + 0x09, 0xae, 0x73, 0x8e, 0x92, 0x30, 0x1e, 0x5a, 0x17, 0x08, + 0x5b, 0xef, 0xfd, 0xc1, 0xb8, 0xd1, 0x16, 0x71, 0x3e, 0x74, + 0xf8, 0x2f, 0xa9, 0x42, 0xd6, 0x4c, 0xdb, 0xc4, 0x68, 0x2d } + }, + { "message digest", + { 0x3a, 0x8e, 0x28, 0x50, 0x2e, 0xd4, 0x5d, 0x42, 0x2f, 0x68, + 0x84, 0x4f, 0x9d, 0xd3, 0x16, 0xe7, 0xb9, 0x85, 0x33, 0xfa, + 0x3f, 0x2a, 0x91, 0xd2, 0x9f, 0x84, 0xd4, 0x25, 0xc8, 0x8d, + 0x6b, 0x4e, 0xff, 0x72, 0x7d, 0xf6, 0x6a, 0x7c, 0x01, 0x97 } + }, + { "abcdefghijklmnopqrstuvwxyz", + { 0xca, 0xbd, 0xb1, 0x81, 0x0b, 0x92, 0x47, 0x0a, 0x20, 0x93, + 0xaa, 0x6b, 0xce, 0x05, 0x95, 0x2c, 0x28, 0x34, 0x8c, 0xf4, + 0x3f, 0xf6, 0x08, 0x41, 0x97, 0x51, 0x66, 0xbb, 0x40, 0xed, + 0x23, 0x40, 0x04, 0xb8, 0x82, 0x44, 0x63, 0xe6, 0xb0, 0x09 } + }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0xd0, 0x34, 0xa7, 0x95, 0x0c, 0xf7, 0x22, 0x02, 0x1b, 0xa4, + 0xb8, 0x4d, 0xf7, 0x69, 0xa5, 0xde, 0x20, 0x60, 0xe2, 0x59, + 0xdf, 0x4c, 0x9b, 0xb4, 0xa4, 0x26, 0x8c, 0x0e, 0x93, 0x5b, + 0xbc, 0x74, 0x70, 0xa9, 0x69, 0xc9, 0xd0, 0x72, 0xa1, 0xac } + } + }; + int x; + unsigned char buf[40]; + hash_state md; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + rmd320_init(&md); + rmd320_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg)); + rmd320_done(&md, buf); + if (XMEMCMP(buf, tests[x].md, 40) != 0) { +#if 0 + printf("Failed test %d\n", x); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + +#endif diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/sha1.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/sha1.c new file mode 100644 index 0000000000..a1a216e6b7 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/sha1.c @@ -0,0 +1,288 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file sha1.c + LTC_SHA1 code by Tom St Denis +*/ + + +#ifdef LTC_SHA1 + +const struct ltc_hash_descriptor sha1_desc = +{ + "sha1", + 2, + 20, + 64, + + /* OID */ + { 1, 3, 14, 3, 2, 26, }, + 6, + + &sha1_init, + &sha1_process, + &sha1_done, + &sha1_test, + NULL +}; + +#define F0(x,y,z) (z ^ (x & (y ^ z))) +#define F1(x,y,z) (x ^ y ^ z) +#define F2(x,y,z) ((x & y) | (z & (x | y))) +#define F3(x,y,z) (x ^ y ^ z) + +#ifdef LTC_CLEAN_STACK +static int _sha1_compress(hash_state *md, unsigned char *buf) +#else +static int sha1_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 a,b,c,d,e,W[80],i; +#ifdef LTC_SMALL_CODE + ulong32 t; +#endif + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD32H(W[i], buf + (4*i)); + } + + /* copy state */ + a = md->sha1.state[0]; + b = md->sha1.state[1]; + c = md->sha1.state[2]; + d = md->sha1.state[3]; + e = md->sha1.state[4]; + + /* expand it */ + for (i = 16; i < 80; i++) { + W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1); + } + + /* compress */ + /* round one */ + #define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30); + #define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30); + #define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30); + #define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30); + +#ifdef LTC_SMALL_CODE + + for (i = 0; i < 20; ) { + FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; + } + + for (; i < 40; ) { + FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; + } + + for (; i < 60; ) { + FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; + } + + for (; i < 80; ) { + FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; + } + +#else + + for (i = 0; i < 20; ) { + FF0(a,b,c,d,e,i++); + FF0(e,a,b,c,d,i++); + FF0(d,e,a,b,c,i++); + FF0(c,d,e,a,b,i++); + FF0(b,c,d,e,a,i++); + } + + /* round two */ + for (; i < 40; ) { + FF1(a,b,c,d,e,i++); + FF1(e,a,b,c,d,i++); + FF1(d,e,a,b,c,i++); + FF1(c,d,e,a,b,i++); + FF1(b,c,d,e,a,i++); + } + + /* round three */ + for (; i < 60; ) { + FF2(a,b,c,d,e,i++); + FF2(e,a,b,c,d,i++); + FF2(d,e,a,b,c,i++); + FF2(c,d,e,a,b,i++); + FF2(b,c,d,e,a,i++); + } + + /* round four */ + for (; i < 80; ) { + FF3(a,b,c,d,e,i++); + FF3(e,a,b,c,d,i++); + FF3(d,e,a,b,c,i++); + FF3(c,d,e,a,b,i++); + FF3(b,c,d,e,a,i++); + } +#endif + + #undef FF0 + #undef FF1 + #undef FF2 + #undef FF3 + + /* store */ + md->sha1.state[0] = md->sha1.state[0] + a; + md->sha1.state[1] = md->sha1.state[1] + b; + md->sha1.state[2] = md->sha1.state[2] + c; + md->sha1.state[3] = md->sha1.state[3] + d; + md->sha1.state[4] = md->sha1.state[4] + e; + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +static int sha1_compress(hash_state *md, unsigned char *buf) +{ + int err; + err = _sha1_compress(md, buf); + burn_stack(sizeof(ulong32) * 87); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int sha1_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + md->sha1.state[0] = 0x67452301UL; + md->sha1.state[1] = 0xefcdab89UL; + md->sha1.state[2] = 0x98badcfeUL; + md->sha1.state[3] = 0x10325476UL; + md->sha1.state[4] = 0xc3d2e1f0UL; + md->sha1.curlen = 0; + md->sha1.length = 0; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(sha1_process, sha1_compress, sha1, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (20 bytes) + @return CRYPT_OK if successful +*/ +int sha1_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->sha1.curlen >= sizeof(md->sha1.buf)) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->sha1.length += md->sha1.curlen * 8; + + /* append the '1' bit */ + md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->sha1.curlen > 56) { + while (md->sha1.curlen < 64) { + md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; + } + sha1_compress(md, md->sha1.buf); + md->sha1.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->sha1.curlen < 56) { + md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(md->sha1.length, md->sha1.buf+56); + sha1_compress(md, md->sha1.buf); + + /* copy output */ + for (i = 0; i < 5; i++) { + STORE32H(md->sha1.state[i], out+(4*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int sha1_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[20]; + } tests[] = { + { "abc", + { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, + 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, + 0x9c, 0xd0, 0xd8, 0x9d } + }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, + 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, + 0xE5, 0x46, 0x70, 0xF1 } + } + }; + + int i; + unsigned char tmp[20]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha1_init(&md); + sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha1_done(&md, tmp); + if (XMEMCMP(tmp, tests[i].hash, 20) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif + + + +/* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha1.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:25:28 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/sha2/sha224.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/sha2/sha224.c new file mode 100644 index 0000000000..78b50ac1c5 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/sha2/sha224.c @@ -0,0 +1,125 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +/** + @param sha224.c + LTC_SHA-224 new NIST standard based off of LTC_SHA-256 truncated to 224 bits (Tom St Denis) +*/ + +const struct ltc_hash_descriptor sha224_desc = +{ + "sha224", + 10, + 28, + 64, + + /* OID */ + { 2, 16, 840, 1, 101, 3, 4, 2, 4, }, + 9, + + &sha224_init, + &sha256_process, + &sha224_done, + &sha224_test, + NULL +}; + +/* init the sha256 er... sha224 state ;-) */ +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int sha224_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + + md->sha256.curlen = 0; + md->sha256.length = 0; + md->sha256.state[0] = 0xc1059ed8UL; + md->sha256.state[1] = 0x367cd507UL; + md->sha256.state[2] = 0x3070dd17UL; + md->sha256.state[3] = 0xf70e5939UL; + md->sha256.state[4] = 0xffc00b31UL; + md->sha256.state[5] = 0x68581511UL; + md->sha256.state[6] = 0x64f98fa7UL; + md->sha256.state[7] = 0xbefa4fa4UL; + return CRYPT_OK; +} + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (28 bytes) + @return CRYPT_OK if successful +*/ +int sha224_done(hash_state * md, unsigned char *out) +{ + unsigned char buf[32]; + int err; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + err = sha256_done(md, buf); + XMEMCPY(out, buf, 28); +#ifdef LTC_CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return err; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int sha224_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[28]; + } tests[] = { + { "abc", + { 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8, + 0x22, 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2, + 0x55, 0xb3, 0x2a, 0xad, 0xbc, 0xe4, 0xbd, + 0xa0, 0xb3, 0xf7, 0xe3, 0x6c, 0x9d, 0xa7 } + }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76, + 0xcc, 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89, + 0x01, 0x50, 0xb0, 0xc6, 0x45, 0x5c, 0xb4, + 0xf5, 0x8b, 0x19, 0x52, 0x52, 0x25, 0x25 } + }, + }; + + int i; + unsigned char tmp[28]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha224_init(&md); + sha224_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha224_done(&md, tmp); + if (XMEMCMP(tmp, tests[i].hash, 28) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + + +/* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha2/sha224.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:25:28 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/sha2/sha256.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/sha2/sha256.c new file mode 100644 index 0000000000..7162b37057 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/sha2/sha256.c @@ -0,0 +1,340 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file sha256.c + LTC_SHA256 by Tom St Denis +*/ + +#ifdef LTC_SHA256 + +const struct ltc_hash_descriptor sha256_desc = +{ + "sha256", + 0, + 32, + 64, + + /* OID */ + { 2, 16, 840, 1, 101, 3, 4, 2, 1, }, + 9, + + &sha256_init, + &sha256_process, + &sha256_done, + &sha256_test, + NULL +}; + +#ifdef LTC_SMALL_CODE +/* the K array */ +static const ulong32 K[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, + 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, + 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, + 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, + 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, + 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, + 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, + 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, + 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, + 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; +#endif + +/* Various logical functions */ +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) RORc((x),(n)) +#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) +#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) +#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) +#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) +#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) + +/* compress 512-bits */ +#ifdef LTC_CLEAN_STACK +static int _sha256_compress(hash_state * md, unsigned char *buf) +#else +static int sha256_compress(hash_state * md, unsigned char *buf) +#endif +{ + ulong32 S[8], W[64], t0, t1; +#ifdef LTC_SMALL_CODE + ulong32 t; +#endif + int i; + + /* copy state into S */ + for (i = 0; i < 8; i++) { + S[i] = md->sha256.state[i]; + } + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD32H(W[i], buf + (4*i)); + } + + /* fill W[16..63] */ + for (i = 16; i < 64; i++) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; + } + + /* Compress */ +#ifdef LTC_SMALL_CODE +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + for (i = 0; i < 64; ++i) { + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i); + t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; + S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; + } +#else +#define RND(a,b,c,d,e,f,g,h,i,ki) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2); + +#undef RND + +#endif + + /* feedback */ + for (i = 0; i < 8; i++) { + md->sha256.state[i] = md->sha256.state[i] + S[i]; + } + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +static int sha256_compress(hash_state * md, unsigned char *buf) +{ + int err; + err = _sha256_compress(md, buf); + burn_stack(sizeof(ulong32) * 74); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int sha256_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + + md->sha256.curlen = 0; + md->sha256.length = 0; + md->sha256.state[0] = 0x6A09E667UL; + md->sha256.state[1] = 0xBB67AE85UL; + md->sha256.state[2] = 0x3C6EF372UL; + md->sha256.state[3] = 0xA54FF53AUL; + md->sha256.state[4] = 0x510E527FUL; + md->sha256.state[5] = 0x9B05688CUL; + md->sha256.state[6] = 0x1F83D9ABUL; + md->sha256.state[7] = 0x5BE0CD19UL; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(sha256_process, sha256_compress, sha256, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (32 bytes) + @return CRYPT_OK if successful +*/ +int sha256_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->sha256.curlen >= sizeof(md->sha256.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* increase the length of the message */ + md->sha256.length += md->sha256.curlen * 8; + + /* append the '1' bit */ + md->sha256.buf[md->sha256.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->sha256.curlen > 56) { + while (md->sha256.curlen < 64) { + md->sha256.buf[md->sha256.curlen++] = (unsigned char)0; + } + sha256_compress(md, md->sha256.buf); + md->sha256.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->sha256.curlen < 56) { + md->sha256.buf[md->sha256.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(md->sha256.length, md->sha256.buf+56); + sha256_compress(md, md->sha256.buf); + + /* copy output */ + for (i = 0; i < 8; i++) { + STORE32H(md->sha256.state[i], out+(4*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int sha256_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[32]; + } tests[] = { + { "abc", + { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, + 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, + 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, + 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad } + }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, + 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, + 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, + 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 } + }, + }; + + int i; + unsigned char tmp[32]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha256_init(&md); + sha256_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha256_done(&md, tmp); + if (XMEMCMP(tmp, tests[i].hash, 32) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#ifdef LTC_SHA224 +#include "sha224.c" +#endif + +#endif + + + +/* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha2/sha256.c,v $ */ +/* $Revision: 1.11 $ */ +/* $Date: 2007/05/12 14:25:28 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/sha2/sha384.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/sha2/sha384.c new file mode 100644 index 0000000000..f7f94576dc --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/sha2/sha384.c @@ -0,0 +1,135 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +/** + @param sha384.c + LTC_SHA384 hash included in sha512.c, Tom St Denis +*/ + +const struct ltc_hash_descriptor sha384_desc = +{ + "sha384", + 4, + 48, + 128, + + /* OID */ + { 2, 16, 840, 1, 101, 3, 4, 2, 2, }, + 9, + + &sha384_init, + &sha512_process, + &sha384_done, + &sha384_test, + NULL +}; + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int sha384_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + + md->sha512.curlen = 0; + md->sha512.length = 0; + md->sha512.state[0] = CONST64(0xcbbb9d5dc1059ed8); + md->sha512.state[1] = CONST64(0x629a292a367cd507); + md->sha512.state[2] = CONST64(0x9159015a3070dd17); + md->sha512.state[3] = CONST64(0x152fecd8f70e5939); + md->sha512.state[4] = CONST64(0x67332667ffc00b31); + md->sha512.state[5] = CONST64(0x8eb44a8768581511); + md->sha512.state[6] = CONST64(0xdb0c2e0d64f98fa7); + md->sha512.state[7] = CONST64(0x47b5481dbefa4fa4); + return CRYPT_OK; +} + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (48 bytes) + @return CRYPT_OK if successful +*/ +int sha384_done(hash_state * md, unsigned char *out) +{ + unsigned char buf[64]; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->sha512.curlen >= sizeof(md->sha512.buf)) { + return CRYPT_INVALID_ARG; + } + + sha512_done(md, buf); + XMEMCPY(out, buf, 48); +#ifdef LTC_CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int sha384_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[48]; + } tests[] = { + { "abc", + { 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, + 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07, + 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, + 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, + 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23, + 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 } + }, + { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", + { 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8, + 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47, + 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2, + 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12, + 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9, + 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 } + }, + }; + + int i; + unsigned char tmp[48]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha384_init(&md); + sha384_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha384_done(&md, tmp); + if (XMEMCMP(tmp, tests[i].hash, 48) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + + + + + + +/* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha2/sha384.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:25:28 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/sha2/sha512.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/sha2/sha512.c new file mode 100644 index 0000000000..6b34aeb3b2 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/sha2/sha512.c @@ -0,0 +1,319 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @param sha512.c + LTC_SHA512 by Tom St Denis +*/ + +#ifdef LTC_SHA512 + +const struct ltc_hash_descriptor sha512_desc = +{ + "sha512", + 5, + 64, + 128, + + /* OID */ + { 2, 16, 840, 1, 101, 3, 4, 2, 3, }, + 9, + + &sha512_init, + &sha512_process, + &sha512_done, + &sha512_test, + NULL +}; + +/* the K array */ +static const ulong64 K[80] = { +CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd), +CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc), +CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019), +CONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118), +CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe), +CONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2), +CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1), +CONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694), +CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3), +CONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65), +CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483), +CONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5), +CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210), +CONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4), +CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725), +CONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70), +CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926), +CONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df), +CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8), +CONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b), +CONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001), +CONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30), +CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910), +CONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8), +CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53), +CONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8), +CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb), +CONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3), +CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60), +CONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec), +CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9), +CONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b), +CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207), +CONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178), +CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6), +CONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b), +CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493), +CONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c), +CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a), +CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817) +}; + +/* Various logical functions */ +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) ROR64c(x, n) +#define R(x, n) (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n)) +#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39)) +#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41)) +#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7)) +#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6)) + +/* compress 1024-bits */ +#ifdef LTC_CLEAN_STACK +static int _sha512_compress(hash_state * md, unsigned char *buf) +#else +static int sha512_compress(hash_state * md, unsigned char *buf) +#endif +{ + ulong64 S[8], W[80], t0, t1; + int i; + + /* copy state into S */ + for (i = 0; i < 8; i++) { + S[i] = md->sha512.state[i]; + } + + /* copy the state into 1024-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD64H(W[i], buf + (8*i)); + } + + /* fill W[16..79] */ + for (i = 16; i < 80; i++) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; + } + + /* Compress */ +#ifdef LTC_SMALL_CODE + for (i = 0; i < 80; i++) { + t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i]; + t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]); + S[7] = S[6]; + S[6] = S[5]; + S[5] = S[4]; + S[4] = S[3] + t0; + S[3] = S[2]; + S[2] = S[1]; + S[1] = S[0]; + S[0] = t0 + t1; + } +#else +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + for (i = 0; i < 80; i += 8) { + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7); + } +#endif + + + /* feedback */ + for (i = 0; i < 8; i++) { + md->sha512.state[i] = md->sha512.state[i] + S[i]; + } + + return CRYPT_OK; +} + +/* compress 1024-bits */ +#ifdef LTC_CLEAN_STACK +static int sha512_compress(hash_state * md, unsigned char *buf) +{ + int err; + err = _sha512_compress(md, buf); + burn_stack(sizeof(ulong64) * 90 + sizeof(int)); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int sha512_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + md->sha512.curlen = 0; + md->sha512.length = 0; + md->sha512.state[0] = CONST64(0x6a09e667f3bcc908); + md->sha512.state[1] = CONST64(0xbb67ae8584caa73b); + md->sha512.state[2] = CONST64(0x3c6ef372fe94f82b); + md->sha512.state[3] = CONST64(0xa54ff53a5f1d36f1); + md->sha512.state[4] = CONST64(0x510e527fade682d1); + md->sha512.state[5] = CONST64(0x9b05688c2b3e6c1f); + md->sha512.state[6] = CONST64(0x1f83d9abfb41bd6b); + md->sha512.state[7] = CONST64(0x5be0cd19137e2179); + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(sha512_process, sha512_compress, sha512, 128) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (64 bytes) + @return CRYPT_OK if successful +*/ +int sha512_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->sha512.curlen >= sizeof(md->sha512.buf)) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->sha512.length += md->sha512.curlen * CONST64(8); + + /* append the '1' bit */ + md->sha512.buf[md->sha512.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 112 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->sha512.curlen > 112) { + while (md->sha512.curlen < 128) { + md->sha512.buf[md->sha512.curlen++] = (unsigned char)0; + } + sha512_compress(md, md->sha512.buf); + md->sha512.curlen = 0; + } + + /* pad upto 120 bytes of zeroes + * note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash + * > 2^64 bits of data... :-) + */ + while (md->sha512.curlen < 120) { + md->sha512.buf[md->sha512.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(md->sha512.length, md->sha512.buf+120); + sha512_compress(md, md->sha512.buf); + + /* copy output */ + for (i = 0; i < 8; i++) { + STORE64H(md->sha512.state[i], out+(8*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int sha512_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[64]; + } tests[] = { + { "abc", + { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, + 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31, + 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, + 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, + 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, + 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, + 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, + 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f } + }, + { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", + { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda, + 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f, + 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1, + 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18, + 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4, + 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a, + 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54, + 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 } + }, + }; + + int i; + unsigned char tmp[64]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha512_init(&md); + sha512_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha512_done(&md, tmp); + if (XMEMCMP(tmp, tests[i].hash, 64) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#ifdef LTC_SHA384 + #include "sha384.c" +#endif + +#endif + + + + +/* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha2/sha512.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:25:28 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/tiger.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/tiger.c new file mode 100644 index 0000000000..c319ba31ad --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/tiger.c @@ -0,0 +1,814 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +#include "tomcrypt.h" + +/** + @file tiger.c + Tiger hash function, Tom St Denis +*/ + +#ifdef LTC_TIGER + +const struct ltc_hash_descriptor tiger_desc = +{ + "tiger", + 1, + 24, + 64, + + /* OID */ + { 1, 3, 6, 1, 4, 1, 11591, 12, 2, }, + 9, + + &tiger_init, + &tiger_process, + &tiger_done, + &tiger_test, + NULL +}; + +#define t1 (table) +#define t2 (table+256) +#define t3 (table+256*2) +#define t4 (table+256*3) + +static const ulong64 table[4*256] = { + CONST64(0x02AAB17CF7E90C5E) /* 0 */, CONST64(0xAC424B03E243A8EC) /* 1 */, + CONST64(0x72CD5BE30DD5FCD3) /* 2 */, CONST64(0x6D019B93F6F97F3A) /* 3 */, + CONST64(0xCD9978FFD21F9193) /* 4 */, CONST64(0x7573A1C9708029E2) /* 5 */, + CONST64(0xB164326B922A83C3) /* 6 */, CONST64(0x46883EEE04915870) /* 7 */, + CONST64(0xEAACE3057103ECE6) /* 8 */, CONST64(0xC54169B808A3535C) /* 9 */, + CONST64(0x4CE754918DDEC47C) /* 10 */, CONST64(0x0AA2F4DFDC0DF40C) /* 11 */, + CONST64(0x10B76F18A74DBEFA) /* 12 */, CONST64(0xC6CCB6235AD1AB6A) /* 13 */, + CONST64(0x13726121572FE2FF) /* 14 */, CONST64(0x1A488C6F199D921E) /* 15 */, + CONST64(0x4BC9F9F4DA0007CA) /* 16 */, CONST64(0x26F5E6F6E85241C7) /* 17 */, + CONST64(0x859079DBEA5947B6) /* 18 */, CONST64(0x4F1885C5C99E8C92) /* 19 */, + CONST64(0xD78E761EA96F864B) /* 20 */, CONST64(0x8E36428C52B5C17D) /* 21 */, + CONST64(0x69CF6827373063C1) /* 22 */, CONST64(0xB607C93D9BB4C56E) /* 23 */, + CONST64(0x7D820E760E76B5EA) /* 24 */, CONST64(0x645C9CC6F07FDC42) /* 25 */, + CONST64(0xBF38A078243342E0) /* 26 */, CONST64(0x5F6B343C9D2E7D04) /* 27 */, + CONST64(0xF2C28AEB600B0EC6) /* 28 */, CONST64(0x6C0ED85F7254BCAC) /* 29 */, + CONST64(0x71592281A4DB4FE5) /* 30 */, CONST64(0x1967FA69CE0FED9F) /* 31 */, + CONST64(0xFD5293F8B96545DB) /* 32 */, CONST64(0xC879E9D7F2A7600B) /* 33 */, + CONST64(0x860248920193194E) /* 34 */, CONST64(0xA4F9533B2D9CC0B3) /* 35 */, + CONST64(0x9053836C15957613) /* 36 */, CONST64(0xDB6DCF8AFC357BF1) /* 37 */, + CONST64(0x18BEEA7A7A370F57) /* 38 */, CONST64(0x037117CA50B99066) /* 39 */, + CONST64(0x6AB30A9774424A35) /* 40 */, CONST64(0xF4E92F02E325249B) /* 41 */, + CONST64(0x7739DB07061CCAE1) /* 42 */, CONST64(0xD8F3B49CECA42A05) /* 43 */, + CONST64(0xBD56BE3F51382F73) /* 44 */, CONST64(0x45FAED5843B0BB28) /* 45 */, + CONST64(0x1C813D5C11BF1F83) /* 46 */, CONST64(0x8AF0E4B6D75FA169) /* 47 */, + CONST64(0x33EE18A487AD9999) /* 48 */, CONST64(0x3C26E8EAB1C94410) /* 49 */, + CONST64(0xB510102BC0A822F9) /* 50 */, CONST64(0x141EEF310CE6123B) /* 51 */, + CONST64(0xFC65B90059DDB154) /* 52 */, CONST64(0xE0158640C5E0E607) /* 53 */, + CONST64(0x884E079826C3A3CF) /* 54 */, CONST64(0x930D0D9523C535FD) /* 55 */, + CONST64(0x35638D754E9A2B00) /* 56 */, CONST64(0x4085FCCF40469DD5) /* 57 */, + CONST64(0xC4B17AD28BE23A4C) /* 58 */, CONST64(0xCAB2F0FC6A3E6A2E) /* 59 */, + CONST64(0x2860971A6B943FCD) /* 60 */, CONST64(0x3DDE6EE212E30446) /* 61 */, + CONST64(0x6222F32AE01765AE) /* 62 */, CONST64(0x5D550BB5478308FE) /* 63 */, + CONST64(0xA9EFA98DA0EDA22A) /* 64 */, CONST64(0xC351A71686C40DA7) /* 65 */, + CONST64(0x1105586D9C867C84) /* 66 */, CONST64(0xDCFFEE85FDA22853) /* 67 */, + CONST64(0xCCFBD0262C5EEF76) /* 68 */, CONST64(0xBAF294CB8990D201) /* 69 */, + CONST64(0xE69464F52AFAD975) /* 70 */, CONST64(0x94B013AFDF133E14) /* 71 */, + CONST64(0x06A7D1A32823C958) /* 72 */, CONST64(0x6F95FE5130F61119) /* 73 */, + CONST64(0xD92AB34E462C06C0) /* 74 */, CONST64(0xED7BDE33887C71D2) /* 75 */, + CONST64(0x79746D6E6518393E) /* 76 */, CONST64(0x5BA419385D713329) /* 77 */, + CONST64(0x7C1BA6B948A97564) /* 78 */, CONST64(0x31987C197BFDAC67) /* 79 */, + CONST64(0xDE6C23C44B053D02) /* 80 */, CONST64(0x581C49FED002D64D) /* 81 */, + CONST64(0xDD474D6338261571) /* 82 */, CONST64(0xAA4546C3E473D062) /* 83 */, + CONST64(0x928FCE349455F860) /* 84 */, CONST64(0x48161BBACAAB94D9) /* 85 */, + CONST64(0x63912430770E6F68) /* 86 */, CONST64(0x6EC8A5E602C6641C) /* 87 */, + CONST64(0x87282515337DDD2B) /* 88 */, CONST64(0x2CDA6B42034B701B) /* 89 */, + CONST64(0xB03D37C181CB096D) /* 90 */, CONST64(0xE108438266C71C6F) /* 91 */, + CONST64(0x2B3180C7EB51B255) /* 92 */, CONST64(0xDF92B82F96C08BBC) /* 93 */, + CONST64(0x5C68C8C0A632F3BA) /* 94 */, CONST64(0x5504CC861C3D0556) /* 95 */, + CONST64(0xABBFA4E55FB26B8F) /* 96 */, CONST64(0x41848B0AB3BACEB4) /* 97 */, + CONST64(0xB334A273AA445D32) /* 98 */, CONST64(0xBCA696F0A85AD881) /* 99 */, + CONST64(0x24F6EC65B528D56C) /* 100 */, CONST64(0x0CE1512E90F4524A) /* 101 */, + CONST64(0x4E9DD79D5506D35A) /* 102 */, CONST64(0x258905FAC6CE9779) /* 103 */, + CONST64(0x2019295B3E109B33) /* 104 */, CONST64(0xF8A9478B73A054CC) /* 105 */, + CONST64(0x2924F2F934417EB0) /* 106 */, CONST64(0x3993357D536D1BC4) /* 107 */, + CONST64(0x38A81AC21DB6FF8B) /* 108 */, CONST64(0x47C4FBF17D6016BF) /* 109 */, + CONST64(0x1E0FAADD7667E3F5) /* 110 */, CONST64(0x7ABCFF62938BEB96) /* 111 */, + CONST64(0xA78DAD948FC179C9) /* 112 */, CONST64(0x8F1F98B72911E50D) /* 113 */, + CONST64(0x61E48EAE27121A91) /* 114 */, CONST64(0x4D62F7AD31859808) /* 115 */, + CONST64(0xECEBA345EF5CEAEB) /* 116 */, CONST64(0xF5CEB25EBC9684CE) /* 117 */, + CONST64(0xF633E20CB7F76221) /* 118 */, CONST64(0xA32CDF06AB8293E4) /* 119 */, + CONST64(0x985A202CA5EE2CA4) /* 120 */, CONST64(0xCF0B8447CC8A8FB1) /* 121 */, + CONST64(0x9F765244979859A3) /* 122 */, CONST64(0xA8D516B1A1240017) /* 123 */, + CONST64(0x0BD7BA3EBB5DC726) /* 124 */, CONST64(0xE54BCA55B86ADB39) /* 125 */, + CONST64(0x1D7A3AFD6C478063) /* 126 */, CONST64(0x519EC608E7669EDD) /* 127 */, + CONST64(0x0E5715A2D149AA23) /* 128 */, CONST64(0x177D4571848FF194) /* 129 */, + CONST64(0xEEB55F3241014C22) /* 130 */, CONST64(0x0F5E5CA13A6E2EC2) /* 131 */, + CONST64(0x8029927B75F5C361) /* 132 */, CONST64(0xAD139FABC3D6E436) /* 133 */, + CONST64(0x0D5DF1A94CCF402F) /* 134 */, CONST64(0x3E8BD948BEA5DFC8) /* 135 */, + CONST64(0xA5A0D357BD3FF77E) /* 136 */, CONST64(0xA2D12E251F74F645) /* 137 */, + CONST64(0x66FD9E525E81A082) /* 138 */, CONST64(0x2E0C90CE7F687A49) /* 139 */, + CONST64(0xC2E8BCBEBA973BC5) /* 140 */, CONST64(0x000001BCE509745F) /* 141 */, + CONST64(0x423777BBE6DAB3D6) /* 142 */, CONST64(0xD1661C7EAEF06EB5) /* 143 */, + CONST64(0xA1781F354DAACFD8) /* 144 */, CONST64(0x2D11284A2B16AFFC) /* 145 */, + CONST64(0xF1FC4F67FA891D1F) /* 146 */, CONST64(0x73ECC25DCB920ADA) /* 147 */, + CONST64(0xAE610C22C2A12651) /* 148 */, CONST64(0x96E0A810D356B78A) /* 149 */, + CONST64(0x5A9A381F2FE7870F) /* 150 */, CONST64(0xD5AD62EDE94E5530) /* 151 */, + CONST64(0xD225E5E8368D1427) /* 152 */, CONST64(0x65977B70C7AF4631) /* 153 */, + CONST64(0x99F889B2DE39D74F) /* 154 */, CONST64(0x233F30BF54E1D143) /* 155 */, + CONST64(0x9A9675D3D9A63C97) /* 156 */, CONST64(0x5470554FF334F9A8) /* 157 */, + CONST64(0x166ACB744A4F5688) /* 158 */, CONST64(0x70C74CAAB2E4AEAD) /* 159 */, + CONST64(0xF0D091646F294D12) /* 160 */, CONST64(0x57B82A89684031D1) /* 161 */, + CONST64(0xEFD95A5A61BE0B6B) /* 162 */, CONST64(0x2FBD12E969F2F29A) /* 163 */, + CONST64(0x9BD37013FEFF9FE8) /* 164 */, CONST64(0x3F9B0404D6085A06) /* 165 */, + CONST64(0x4940C1F3166CFE15) /* 166 */, CONST64(0x09542C4DCDF3DEFB) /* 167 */, + CONST64(0xB4C5218385CD5CE3) /* 168 */, CONST64(0xC935B7DC4462A641) /* 169 */, + CONST64(0x3417F8A68ED3B63F) /* 170 */, CONST64(0xB80959295B215B40) /* 171 */, + CONST64(0xF99CDAEF3B8C8572) /* 172 */, CONST64(0x018C0614F8FCB95D) /* 173 */, + CONST64(0x1B14ACCD1A3ACDF3) /* 174 */, CONST64(0x84D471F200BB732D) /* 175 */, + CONST64(0xC1A3110E95E8DA16) /* 176 */, CONST64(0x430A7220BF1A82B8) /* 177 */, + CONST64(0xB77E090D39DF210E) /* 178 */, CONST64(0x5EF4BD9F3CD05E9D) /* 179 */, + CONST64(0x9D4FF6DA7E57A444) /* 180 */, CONST64(0xDA1D60E183D4A5F8) /* 181 */, + CONST64(0xB287C38417998E47) /* 182 */, CONST64(0xFE3EDC121BB31886) /* 183 */, + CONST64(0xC7FE3CCC980CCBEF) /* 184 */, CONST64(0xE46FB590189BFD03) /* 185 */, + CONST64(0x3732FD469A4C57DC) /* 186 */, CONST64(0x7EF700A07CF1AD65) /* 187 */, + CONST64(0x59C64468A31D8859) /* 188 */, CONST64(0x762FB0B4D45B61F6) /* 189 */, + CONST64(0x155BAED099047718) /* 190 */, CONST64(0x68755E4C3D50BAA6) /* 191 */, + CONST64(0xE9214E7F22D8B4DF) /* 192 */, CONST64(0x2ADDBF532EAC95F4) /* 193 */, + CONST64(0x32AE3909B4BD0109) /* 194 */, CONST64(0x834DF537B08E3450) /* 195 */, + CONST64(0xFA209DA84220728D) /* 196 */, CONST64(0x9E691D9B9EFE23F7) /* 197 */, + CONST64(0x0446D288C4AE8D7F) /* 198 */, CONST64(0x7B4CC524E169785B) /* 199 */, + CONST64(0x21D87F0135CA1385) /* 200 */, CONST64(0xCEBB400F137B8AA5) /* 201 */, + CONST64(0x272E2B66580796BE) /* 202 */, CONST64(0x3612264125C2B0DE) /* 203 */, + CONST64(0x057702BDAD1EFBB2) /* 204 */, CONST64(0xD4BABB8EACF84BE9) /* 205 */, + CONST64(0x91583139641BC67B) /* 206 */, CONST64(0x8BDC2DE08036E024) /* 207 */, + CONST64(0x603C8156F49F68ED) /* 208 */, CONST64(0xF7D236F7DBEF5111) /* 209 */, + CONST64(0x9727C4598AD21E80) /* 210 */, CONST64(0xA08A0896670A5FD7) /* 211 */, + CONST64(0xCB4A8F4309EBA9CB) /* 212 */, CONST64(0x81AF564B0F7036A1) /* 213 */, + CONST64(0xC0B99AA778199ABD) /* 214 */, CONST64(0x959F1EC83FC8E952) /* 215 */, + CONST64(0x8C505077794A81B9) /* 216 */, CONST64(0x3ACAAF8F056338F0) /* 217 */, + CONST64(0x07B43F50627A6778) /* 218 */, CONST64(0x4A44AB49F5ECCC77) /* 219 */, + CONST64(0x3BC3D6E4B679EE98) /* 220 */, CONST64(0x9CC0D4D1CF14108C) /* 221 */, + CONST64(0x4406C00B206BC8A0) /* 222 */, CONST64(0x82A18854C8D72D89) /* 223 */, + CONST64(0x67E366B35C3C432C) /* 224 */, CONST64(0xB923DD61102B37F2) /* 225 */, + CONST64(0x56AB2779D884271D) /* 226 */, CONST64(0xBE83E1B0FF1525AF) /* 227 */, + CONST64(0xFB7C65D4217E49A9) /* 228 */, CONST64(0x6BDBE0E76D48E7D4) /* 229 */, + CONST64(0x08DF828745D9179E) /* 230 */, CONST64(0x22EA6A9ADD53BD34) /* 231 */, + CONST64(0xE36E141C5622200A) /* 232 */, CONST64(0x7F805D1B8CB750EE) /* 233 */, + CONST64(0xAFE5C7A59F58E837) /* 234 */, CONST64(0xE27F996A4FB1C23C) /* 235 */, + CONST64(0xD3867DFB0775F0D0) /* 236 */, CONST64(0xD0E673DE6E88891A) /* 237 */, + CONST64(0x123AEB9EAFB86C25) /* 238 */, CONST64(0x30F1D5D5C145B895) /* 239 */, + CONST64(0xBB434A2DEE7269E7) /* 240 */, CONST64(0x78CB67ECF931FA38) /* 241 */, + CONST64(0xF33B0372323BBF9C) /* 242 */, CONST64(0x52D66336FB279C74) /* 243 */, + CONST64(0x505F33AC0AFB4EAA) /* 244 */, CONST64(0xE8A5CD99A2CCE187) /* 245 */, + CONST64(0x534974801E2D30BB) /* 246 */, CONST64(0x8D2D5711D5876D90) /* 247 */, + CONST64(0x1F1A412891BC038E) /* 248 */, CONST64(0xD6E2E71D82E56648) /* 249 */, + CONST64(0x74036C3A497732B7) /* 250 */, CONST64(0x89B67ED96361F5AB) /* 251 */, + CONST64(0xFFED95D8F1EA02A2) /* 252 */, CONST64(0xE72B3BD61464D43D) /* 253 */, + CONST64(0xA6300F170BDC4820) /* 254 */, CONST64(0xEBC18760ED78A77A) /* 255 */, + CONST64(0xE6A6BE5A05A12138) /* 256 */, CONST64(0xB5A122A5B4F87C98) /* 257 */, + CONST64(0x563C6089140B6990) /* 258 */, CONST64(0x4C46CB2E391F5DD5) /* 259 */, + CONST64(0xD932ADDBC9B79434) /* 260 */, CONST64(0x08EA70E42015AFF5) /* 261 */, + CONST64(0xD765A6673E478CF1) /* 262 */, CONST64(0xC4FB757EAB278D99) /* 263 */, + CONST64(0xDF11C6862D6E0692) /* 264 */, CONST64(0xDDEB84F10D7F3B16) /* 265 */, + CONST64(0x6F2EF604A665EA04) /* 266 */, CONST64(0x4A8E0F0FF0E0DFB3) /* 267 */, + CONST64(0xA5EDEEF83DBCBA51) /* 268 */, CONST64(0xFC4F0A2A0EA4371E) /* 269 */, + CONST64(0xE83E1DA85CB38429) /* 270 */, CONST64(0xDC8FF882BA1B1CE2) /* 271 */, + CONST64(0xCD45505E8353E80D) /* 272 */, CONST64(0x18D19A00D4DB0717) /* 273 */, + CONST64(0x34A0CFEDA5F38101) /* 274 */, CONST64(0x0BE77E518887CAF2) /* 275 */, + CONST64(0x1E341438B3C45136) /* 276 */, CONST64(0xE05797F49089CCF9) /* 277 */, + CONST64(0xFFD23F9DF2591D14) /* 278 */, CONST64(0x543DDA228595C5CD) /* 279 */, + CONST64(0x661F81FD99052A33) /* 280 */, CONST64(0x8736E641DB0F7B76) /* 281 */, + CONST64(0x15227725418E5307) /* 282 */, CONST64(0xE25F7F46162EB2FA) /* 283 */, + CONST64(0x48A8B2126C13D9FE) /* 284 */, CONST64(0xAFDC541792E76EEA) /* 285 */, + CONST64(0x03D912BFC6D1898F) /* 286 */, CONST64(0x31B1AAFA1B83F51B) /* 287 */, + CONST64(0xF1AC2796E42AB7D9) /* 288 */, CONST64(0x40A3A7D7FCD2EBAC) /* 289 */, + CONST64(0x1056136D0AFBBCC5) /* 290 */, CONST64(0x7889E1DD9A6D0C85) /* 291 */, + CONST64(0xD33525782A7974AA) /* 292 */, CONST64(0xA7E25D09078AC09B) /* 293 */, + CONST64(0xBD4138B3EAC6EDD0) /* 294 */, CONST64(0x920ABFBE71EB9E70) /* 295 */, + CONST64(0xA2A5D0F54FC2625C) /* 296 */, CONST64(0xC054E36B0B1290A3) /* 297 */, + CONST64(0xF6DD59FF62FE932B) /* 298 */, CONST64(0x3537354511A8AC7D) /* 299 */, + CONST64(0xCA845E9172FADCD4) /* 300 */, CONST64(0x84F82B60329D20DC) /* 301 */, + CONST64(0x79C62CE1CD672F18) /* 302 */, CONST64(0x8B09A2ADD124642C) /* 303 */, + CONST64(0xD0C1E96A19D9E726) /* 304 */, CONST64(0x5A786A9B4BA9500C) /* 305 */, + CONST64(0x0E020336634C43F3) /* 306 */, CONST64(0xC17B474AEB66D822) /* 307 */, + CONST64(0x6A731AE3EC9BAAC2) /* 308 */, CONST64(0x8226667AE0840258) /* 309 */, + CONST64(0x67D4567691CAECA5) /* 310 */, CONST64(0x1D94155C4875ADB5) /* 311 */, + CONST64(0x6D00FD985B813FDF) /* 312 */, CONST64(0x51286EFCB774CD06) /* 313 */, + CONST64(0x5E8834471FA744AF) /* 314 */, CONST64(0xF72CA0AEE761AE2E) /* 315 */, + CONST64(0xBE40E4CDAEE8E09A) /* 316 */, CONST64(0xE9970BBB5118F665) /* 317 */, + CONST64(0x726E4BEB33DF1964) /* 318 */, CONST64(0x703B000729199762) /* 319 */, + CONST64(0x4631D816F5EF30A7) /* 320 */, CONST64(0xB880B5B51504A6BE) /* 321 */, + CONST64(0x641793C37ED84B6C) /* 322 */, CONST64(0x7B21ED77F6E97D96) /* 323 */, + CONST64(0x776306312EF96B73) /* 324 */, CONST64(0xAE528948E86FF3F4) /* 325 */, + CONST64(0x53DBD7F286A3F8F8) /* 326 */, CONST64(0x16CADCE74CFC1063) /* 327 */, + CONST64(0x005C19BDFA52C6DD) /* 328 */, CONST64(0x68868F5D64D46AD3) /* 329 */, + CONST64(0x3A9D512CCF1E186A) /* 330 */, CONST64(0x367E62C2385660AE) /* 331 */, + CONST64(0xE359E7EA77DCB1D7) /* 332 */, CONST64(0x526C0773749ABE6E) /* 333 */, + CONST64(0x735AE5F9D09F734B) /* 334 */, CONST64(0x493FC7CC8A558BA8) /* 335 */, + CONST64(0xB0B9C1533041AB45) /* 336 */, CONST64(0x321958BA470A59BD) /* 337 */, + CONST64(0x852DB00B5F46C393) /* 338 */, CONST64(0x91209B2BD336B0E5) /* 339 */, + CONST64(0x6E604F7D659EF19F) /* 340 */, CONST64(0xB99A8AE2782CCB24) /* 341 */, + CONST64(0xCCF52AB6C814C4C7) /* 342 */, CONST64(0x4727D9AFBE11727B) /* 343 */, + CONST64(0x7E950D0C0121B34D) /* 344 */, CONST64(0x756F435670AD471F) /* 345 */, + CONST64(0xF5ADD442615A6849) /* 346 */, CONST64(0x4E87E09980B9957A) /* 347 */, + CONST64(0x2ACFA1DF50AEE355) /* 348 */, CONST64(0xD898263AFD2FD556) /* 349 */, + CONST64(0xC8F4924DD80C8FD6) /* 350 */, CONST64(0xCF99CA3D754A173A) /* 351 */, + CONST64(0xFE477BACAF91BF3C) /* 352 */, CONST64(0xED5371F6D690C12D) /* 353 */, + CONST64(0x831A5C285E687094) /* 354 */, CONST64(0xC5D3C90A3708A0A4) /* 355 */, + CONST64(0x0F7F903717D06580) /* 356 */, CONST64(0x19F9BB13B8FDF27F) /* 357 */, + CONST64(0xB1BD6F1B4D502843) /* 358 */, CONST64(0x1C761BA38FFF4012) /* 359 */, + CONST64(0x0D1530C4E2E21F3B) /* 360 */, CONST64(0x8943CE69A7372C8A) /* 361 */, + CONST64(0xE5184E11FEB5CE66) /* 362 */, CONST64(0x618BDB80BD736621) /* 363 */, + CONST64(0x7D29BAD68B574D0B) /* 364 */, CONST64(0x81BB613E25E6FE5B) /* 365 */, + CONST64(0x071C9C10BC07913F) /* 366 */, CONST64(0xC7BEEB7909AC2D97) /* 367 */, + CONST64(0xC3E58D353BC5D757) /* 368 */, CONST64(0xEB017892F38F61E8) /* 369 */, + CONST64(0xD4EFFB9C9B1CC21A) /* 370 */, CONST64(0x99727D26F494F7AB) /* 371 */, + CONST64(0xA3E063A2956B3E03) /* 372 */, CONST64(0x9D4A8B9A4AA09C30) /* 373 */, + CONST64(0x3F6AB7D500090FB4) /* 374 */, CONST64(0x9CC0F2A057268AC0) /* 375 */, + CONST64(0x3DEE9D2DEDBF42D1) /* 376 */, CONST64(0x330F49C87960A972) /* 377 */, + CONST64(0xC6B2720287421B41) /* 378 */, CONST64(0x0AC59EC07C00369C) /* 379 */, + CONST64(0xEF4EAC49CB353425) /* 380 */, CONST64(0xF450244EEF0129D8) /* 381 */, + CONST64(0x8ACC46E5CAF4DEB6) /* 382 */, CONST64(0x2FFEAB63989263F7) /* 383 */, + CONST64(0x8F7CB9FE5D7A4578) /* 384 */, CONST64(0x5BD8F7644E634635) /* 385 */, + CONST64(0x427A7315BF2DC900) /* 386 */, CONST64(0x17D0C4AA2125261C) /* 387 */, + CONST64(0x3992486C93518E50) /* 388 */, CONST64(0xB4CBFEE0A2D7D4C3) /* 389 */, + CONST64(0x7C75D6202C5DDD8D) /* 390 */, CONST64(0xDBC295D8E35B6C61) /* 391 */, + CONST64(0x60B369D302032B19) /* 392 */, CONST64(0xCE42685FDCE44132) /* 393 */, + CONST64(0x06F3DDB9DDF65610) /* 394 */, CONST64(0x8EA4D21DB5E148F0) /* 395 */, + CONST64(0x20B0FCE62FCD496F) /* 396 */, CONST64(0x2C1B912358B0EE31) /* 397 */, + CONST64(0xB28317B818F5A308) /* 398 */, CONST64(0xA89C1E189CA6D2CF) /* 399 */, + CONST64(0x0C6B18576AAADBC8) /* 400 */, CONST64(0xB65DEAA91299FAE3) /* 401 */, + CONST64(0xFB2B794B7F1027E7) /* 402 */, CONST64(0x04E4317F443B5BEB) /* 403 */, + CONST64(0x4B852D325939D0A6) /* 404 */, CONST64(0xD5AE6BEEFB207FFC) /* 405 */, + CONST64(0x309682B281C7D374) /* 406 */, CONST64(0xBAE309A194C3B475) /* 407 */, + CONST64(0x8CC3F97B13B49F05) /* 408 */, CONST64(0x98A9422FF8293967) /* 409 */, + CONST64(0x244B16B01076FF7C) /* 410 */, CONST64(0xF8BF571C663D67EE) /* 411 */, + CONST64(0x1F0D6758EEE30DA1) /* 412 */, CONST64(0xC9B611D97ADEB9B7) /* 413 */, + CONST64(0xB7AFD5887B6C57A2) /* 414 */, CONST64(0x6290AE846B984FE1) /* 415 */, + CONST64(0x94DF4CDEACC1A5FD) /* 416 */, CONST64(0x058A5BD1C5483AFF) /* 417 */, + CONST64(0x63166CC142BA3C37) /* 418 */, CONST64(0x8DB8526EB2F76F40) /* 419 */, + CONST64(0xE10880036F0D6D4E) /* 420 */, CONST64(0x9E0523C9971D311D) /* 421 */, + CONST64(0x45EC2824CC7CD691) /* 422 */, CONST64(0x575B8359E62382C9) /* 423 */, + CONST64(0xFA9E400DC4889995) /* 424 */, CONST64(0xD1823ECB45721568) /* 425 */, + CONST64(0xDAFD983B8206082F) /* 426 */, CONST64(0xAA7D29082386A8CB) /* 427 */, + CONST64(0x269FCD4403B87588) /* 428 */, CONST64(0x1B91F5F728BDD1E0) /* 429 */, + CONST64(0xE4669F39040201F6) /* 430 */, CONST64(0x7A1D7C218CF04ADE) /* 431 */, + CONST64(0x65623C29D79CE5CE) /* 432 */, CONST64(0x2368449096C00BB1) /* 433 */, + CONST64(0xAB9BF1879DA503BA) /* 434 */, CONST64(0xBC23ECB1A458058E) /* 435 */, + CONST64(0x9A58DF01BB401ECC) /* 436 */, CONST64(0xA070E868A85F143D) /* 437 */, + CONST64(0x4FF188307DF2239E) /* 438 */, CONST64(0x14D565B41A641183) /* 439 */, + CONST64(0xEE13337452701602) /* 440 */, CONST64(0x950E3DCF3F285E09) /* 441 */, + CONST64(0x59930254B9C80953) /* 442 */, CONST64(0x3BF299408930DA6D) /* 443 */, + CONST64(0xA955943F53691387) /* 444 */, CONST64(0xA15EDECAA9CB8784) /* 445 */, + CONST64(0x29142127352BE9A0) /* 446 */, CONST64(0x76F0371FFF4E7AFB) /* 447 */, + CONST64(0x0239F450274F2228) /* 448 */, CONST64(0xBB073AF01D5E868B) /* 449 */, + CONST64(0xBFC80571C10E96C1) /* 450 */, CONST64(0xD267088568222E23) /* 451 */, + CONST64(0x9671A3D48E80B5B0) /* 452 */, CONST64(0x55B5D38AE193BB81) /* 453 */, + CONST64(0x693AE2D0A18B04B8) /* 454 */, CONST64(0x5C48B4ECADD5335F) /* 455 */, + CONST64(0xFD743B194916A1CA) /* 456 */, CONST64(0x2577018134BE98C4) /* 457 */, + CONST64(0xE77987E83C54A4AD) /* 458 */, CONST64(0x28E11014DA33E1B9) /* 459 */, + CONST64(0x270CC59E226AA213) /* 460 */, CONST64(0x71495F756D1A5F60) /* 461 */, + CONST64(0x9BE853FB60AFEF77) /* 462 */, CONST64(0xADC786A7F7443DBF) /* 463 */, + CONST64(0x0904456173B29A82) /* 464 */, CONST64(0x58BC7A66C232BD5E) /* 465 */, + CONST64(0xF306558C673AC8B2) /* 466 */, CONST64(0x41F639C6B6C9772A) /* 467 */, + CONST64(0x216DEFE99FDA35DA) /* 468 */, CONST64(0x11640CC71C7BE615) /* 469 */, + CONST64(0x93C43694565C5527) /* 470 */, CONST64(0xEA038E6246777839) /* 471 */, + CONST64(0xF9ABF3CE5A3E2469) /* 472 */, CONST64(0x741E768D0FD312D2) /* 473 */, + CONST64(0x0144B883CED652C6) /* 474 */, CONST64(0xC20B5A5BA33F8552) /* 475 */, + CONST64(0x1AE69633C3435A9D) /* 476 */, CONST64(0x97A28CA4088CFDEC) /* 477 */, + CONST64(0x8824A43C1E96F420) /* 478 */, CONST64(0x37612FA66EEEA746) /* 479 */, + CONST64(0x6B4CB165F9CF0E5A) /* 480 */, CONST64(0x43AA1C06A0ABFB4A) /* 481 */, + CONST64(0x7F4DC26FF162796B) /* 482 */, CONST64(0x6CBACC8E54ED9B0F) /* 483 */, + CONST64(0xA6B7FFEFD2BB253E) /* 484 */, CONST64(0x2E25BC95B0A29D4F) /* 485 */, + CONST64(0x86D6A58BDEF1388C) /* 486 */, CONST64(0xDED74AC576B6F054) /* 487 */, + CONST64(0x8030BDBC2B45805D) /* 488 */, CONST64(0x3C81AF70E94D9289) /* 489 */, + CONST64(0x3EFF6DDA9E3100DB) /* 490 */, CONST64(0xB38DC39FDFCC8847) /* 491 */, + CONST64(0x123885528D17B87E) /* 492 */, CONST64(0xF2DA0ED240B1B642) /* 493 */, + CONST64(0x44CEFADCD54BF9A9) /* 494 */, CONST64(0x1312200E433C7EE6) /* 495 */, + CONST64(0x9FFCC84F3A78C748) /* 496 */, CONST64(0xF0CD1F72248576BB) /* 497 */, + CONST64(0xEC6974053638CFE4) /* 498 */, CONST64(0x2BA7B67C0CEC4E4C) /* 499 */, + CONST64(0xAC2F4DF3E5CE32ED) /* 500 */, CONST64(0xCB33D14326EA4C11) /* 501 */, + CONST64(0xA4E9044CC77E58BC) /* 502 */, CONST64(0x5F513293D934FCEF) /* 503 */, + CONST64(0x5DC9645506E55444) /* 504 */, CONST64(0x50DE418F317DE40A) /* 505 */, + CONST64(0x388CB31A69DDE259) /* 506 */, CONST64(0x2DB4A83455820A86) /* 507 */, + CONST64(0x9010A91E84711AE9) /* 508 */, CONST64(0x4DF7F0B7B1498371) /* 509 */, + CONST64(0xD62A2EABC0977179) /* 510 */, CONST64(0x22FAC097AA8D5C0E) /* 511 */, + CONST64(0xF49FCC2FF1DAF39B) /* 512 */, CONST64(0x487FD5C66FF29281) /* 513 */, + CONST64(0xE8A30667FCDCA83F) /* 514 */, CONST64(0x2C9B4BE3D2FCCE63) /* 515 */, + CONST64(0xDA3FF74B93FBBBC2) /* 516 */, CONST64(0x2FA165D2FE70BA66) /* 517 */, + CONST64(0xA103E279970E93D4) /* 518 */, CONST64(0xBECDEC77B0E45E71) /* 519 */, + CONST64(0xCFB41E723985E497) /* 520 */, CONST64(0xB70AAA025EF75017) /* 521 */, + CONST64(0xD42309F03840B8E0) /* 522 */, CONST64(0x8EFC1AD035898579) /* 523 */, + CONST64(0x96C6920BE2B2ABC5) /* 524 */, CONST64(0x66AF4163375A9172) /* 525 */, + CONST64(0x2174ABDCCA7127FB) /* 526 */, CONST64(0xB33CCEA64A72FF41) /* 527 */, + CONST64(0xF04A4933083066A5) /* 528 */, CONST64(0x8D970ACDD7289AF5) /* 529 */, + CONST64(0x8F96E8E031C8C25E) /* 530 */, CONST64(0xF3FEC02276875D47) /* 531 */, + CONST64(0xEC7BF310056190DD) /* 532 */, CONST64(0xF5ADB0AEBB0F1491) /* 533 */, + CONST64(0x9B50F8850FD58892) /* 534 */, CONST64(0x4975488358B74DE8) /* 535 */, + CONST64(0xA3354FF691531C61) /* 536 */, CONST64(0x0702BBE481D2C6EE) /* 537 */, + CONST64(0x89FB24057DEDED98) /* 538 */, CONST64(0xAC3075138596E902) /* 539 */, + CONST64(0x1D2D3580172772ED) /* 540 */, CONST64(0xEB738FC28E6BC30D) /* 541 */, + CONST64(0x5854EF8F63044326) /* 542 */, CONST64(0x9E5C52325ADD3BBE) /* 543 */, + CONST64(0x90AA53CF325C4623) /* 544 */, CONST64(0xC1D24D51349DD067) /* 545 */, + CONST64(0x2051CFEEA69EA624) /* 546 */, CONST64(0x13220F0A862E7E4F) /* 547 */, + CONST64(0xCE39399404E04864) /* 548 */, CONST64(0xD9C42CA47086FCB7) /* 549 */, + CONST64(0x685AD2238A03E7CC) /* 550 */, CONST64(0x066484B2AB2FF1DB) /* 551 */, + CONST64(0xFE9D5D70EFBF79EC) /* 552 */, CONST64(0x5B13B9DD9C481854) /* 553 */, + CONST64(0x15F0D475ED1509AD) /* 554 */, CONST64(0x0BEBCD060EC79851) /* 555 */, + CONST64(0xD58C6791183AB7F8) /* 556 */, CONST64(0xD1187C5052F3EEE4) /* 557 */, + CONST64(0xC95D1192E54E82FF) /* 558 */, CONST64(0x86EEA14CB9AC6CA2) /* 559 */, + CONST64(0x3485BEB153677D5D) /* 560 */, CONST64(0xDD191D781F8C492A) /* 561 */, + CONST64(0xF60866BAA784EBF9) /* 562 */, CONST64(0x518F643BA2D08C74) /* 563 */, + CONST64(0x8852E956E1087C22) /* 564 */, CONST64(0xA768CB8DC410AE8D) /* 565 */, + CONST64(0x38047726BFEC8E1A) /* 566 */, CONST64(0xA67738B4CD3B45AA) /* 567 */, + CONST64(0xAD16691CEC0DDE19) /* 568 */, CONST64(0xC6D4319380462E07) /* 569 */, + CONST64(0xC5A5876D0BA61938) /* 570 */, CONST64(0x16B9FA1FA58FD840) /* 571 */, + CONST64(0x188AB1173CA74F18) /* 572 */, CONST64(0xABDA2F98C99C021F) /* 573 */, + CONST64(0x3E0580AB134AE816) /* 574 */, CONST64(0x5F3B05B773645ABB) /* 575 */, + CONST64(0x2501A2BE5575F2F6) /* 576 */, CONST64(0x1B2F74004E7E8BA9) /* 577 */, + CONST64(0x1CD7580371E8D953) /* 578 */, CONST64(0x7F6ED89562764E30) /* 579 */, + CONST64(0xB15926FF596F003D) /* 580 */, CONST64(0x9F65293DA8C5D6B9) /* 581 */, + CONST64(0x6ECEF04DD690F84C) /* 582 */, CONST64(0x4782275FFF33AF88) /* 583 */, + CONST64(0xE41433083F820801) /* 584 */, CONST64(0xFD0DFE409A1AF9B5) /* 585 */, + CONST64(0x4325A3342CDB396B) /* 586 */, CONST64(0x8AE77E62B301B252) /* 587 */, + CONST64(0xC36F9E9F6655615A) /* 588 */, CONST64(0x85455A2D92D32C09) /* 589 */, + CONST64(0xF2C7DEA949477485) /* 590 */, CONST64(0x63CFB4C133A39EBA) /* 591 */, + CONST64(0x83B040CC6EBC5462) /* 592 */, CONST64(0x3B9454C8FDB326B0) /* 593 */, + CONST64(0x56F56A9E87FFD78C) /* 594 */, CONST64(0x2DC2940D99F42BC6) /* 595 */, + CONST64(0x98F7DF096B096E2D) /* 596 */, CONST64(0x19A6E01E3AD852BF) /* 597 */, + CONST64(0x42A99CCBDBD4B40B) /* 598 */, CONST64(0xA59998AF45E9C559) /* 599 */, + CONST64(0x366295E807D93186) /* 600 */, CONST64(0x6B48181BFAA1F773) /* 601 */, + CONST64(0x1FEC57E2157A0A1D) /* 602 */, CONST64(0x4667446AF6201AD5) /* 603 */, + CONST64(0xE615EBCACFB0F075) /* 604 */, CONST64(0xB8F31F4F68290778) /* 605 */, + CONST64(0x22713ED6CE22D11E) /* 606 */, CONST64(0x3057C1A72EC3C93B) /* 607 */, + CONST64(0xCB46ACC37C3F1F2F) /* 608 */, CONST64(0xDBB893FD02AAF50E) /* 609 */, + CONST64(0x331FD92E600B9FCF) /* 610 */, CONST64(0xA498F96148EA3AD6) /* 611 */, + CONST64(0xA8D8426E8B6A83EA) /* 612 */, CONST64(0xA089B274B7735CDC) /* 613 */, + CONST64(0x87F6B3731E524A11) /* 614 */, CONST64(0x118808E5CBC96749) /* 615 */, + CONST64(0x9906E4C7B19BD394) /* 616 */, CONST64(0xAFED7F7E9B24A20C) /* 617 */, + CONST64(0x6509EADEEB3644A7) /* 618 */, CONST64(0x6C1EF1D3E8EF0EDE) /* 619 */, + CONST64(0xB9C97D43E9798FB4) /* 620 */, CONST64(0xA2F2D784740C28A3) /* 621 */, + CONST64(0x7B8496476197566F) /* 622 */, CONST64(0x7A5BE3E6B65F069D) /* 623 */, + CONST64(0xF96330ED78BE6F10) /* 624 */, CONST64(0xEEE60DE77A076A15) /* 625 */, + CONST64(0x2B4BEE4AA08B9BD0) /* 626 */, CONST64(0x6A56A63EC7B8894E) /* 627 */, + CONST64(0x02121359BA34FEF4) /* 628 */, CONST64(0x4CBF99F8283703FC) /* 629 */, + CONST64(0x398071350CAF30C8) /* 630 */, CONST64(0xD0A77A89F017687A) /* 631 */, + CONST64(0xF1C1A9EB9E423569) /* 632 */, CONST64(0x8C7976282DEE8199) /* 633 */, + CONST64(0x5D1737A5DD1F7ABD) /* 634 */, CONST64(0x4F53433C09A9FA80) /* 635 */, + CONST64(0xFA8B0C53DF7CA1D9) /* 636 */, CONST64(0x3FD9DCBC886CCB77) /* 637 */, + CONST64(0xC040917CA91B4720) /* 638 */, CONST64(0x7DD00142F9D1DCDF) /* 639 */, + CONST64(0x8476FC1D4F387B58) /* 640 */, CONST64(0x23F8E7C5F3316503) /* 641 */, + CONST64(0x032A2244E7E37339) /* 642 */, CONST64(0x5C87A5D750F5A74B) /* 643 */, + CONST64(0x082B4CC43698992E) /* 644 */, CONST64(0xDF917BECB858F63C) /* 645 */, + CONST64(0x3270B8FC5BF86DDA) /* 646 */, CONST64(0x10AE72BB29B5DD76) /* 647 */, + CONST64(0x576AC94E7700362B) /* 648 */, CONST64(0x1AD112DAC61EFB8F) /* 649 */, + CONST64(0x691BC30EC5FAA427) /* 650 */, CONST64(0xFF246311CC327143) /* 651 */, + CONST64(0x3142368E30E53206) /* 652 */, CONST64(0x71380E31E02CA396) /* 653 */, + CONST64(0x958D5C960AAD76F1) /* 654 */, CONST64(0xF8D6F430C16DA536) /* 655 */, + CONST64(0xC8FFD13F1BE7E1D2) /* 656 */, CONST64(0x7578AE66004DDBE1) /* 657 */, + CONST64(0x05833F01067BE646) /* 658 */, CONST64(0xBB34B5AD3BFE586D) /* 659 */, + CONST64(0x095F34C9A12B97F0) /* 660 */, CONST64(0x247AB64525D60CA8) /* 661 */, + CONST64(0xDCDBC6F3017477D1) /* 662 */, CONST64(0x4A2E14D4DECAD24D) /* 663 */, + CONST64(0xBDB5E6D9BE0A1EEB) /* 664 */, CONST64(0x2A7E70F7794301AB) /* 665 */, + CONST64(0xDEF42D8A270540FD) /* 666 */, CONST64(0x01078EC0A34C22C1) /* 667 */, + CONST64(0xE5DE511AF4C16387) /* 668 */, CONST64(0x7EBB3A52BD9A330A) /* 669 */, + CONST64(0x77697857AA7D6435) /* 670 */, CONST64(0x004E831603AE4C32) /* 671 */, + CONST64(0xE7A21020AD78E312) /* 672 */, CONST64(0x9D41A70C6AB420F2) /* 673 */, + CONST64(0x28E06C18EA1141E6) /* 674 */, CONST64(0xD2B28CBD984F6B28) /* 675 */, + CONST64(0x26B75F6C446E9D83) /* 676 */, CONST64(0xBA47568C4D418D7F) /* 677 */, + CONST64(0xD80BADBFE6183D8E) /* 678 */, CONST64(0x0E206D7F5F166044) /* 679 */, + CONST64(0xE258A43911CBCA3E) /* 680 */, CONST64(0x723A1746B21DC0BC) /* 681 */, + CONST64(0xC7CAA854F5D7CDD3) /* 682 */, CONST64(0x7CAC32883D261D9C) /* 683 */, + CONST64(0x7690C26423BA942C) /* 684 */, CONST64(0x17E55524478042B8) /* 685 */, + CONST64(0xE0BE477656A2389F) /* 686 */, CONST64(0x4D289B5E67AB2DA0) /* 687 */, + CONST64(0x44862B9C8FBBFD31) /* 688 */, CONST64(0xB47CC8049D141365) /* 689 */, + CONST64(0x822C1B362B91C793) /* 690 */, CONST64(0x4EB14655FB13DFD8) /* 691 */, + CONST64(0x1ECBBA0714E2A97B) /* 692 */, CONST64(0x6143459D5CDE5F14) /* 693 */, + CONST64(0x53A8FBF1D5F0AC89) /* 694 */, CONST64(0x97EA04D81C5E5B00) /* 695 */, + CONST64(0x622181A8D4FDB3F3) /* 696 */, CONST64(0xE9BCD341572A1208) /* 697 */, + CONST64(0x1411258643CCE58A) /* 698 */, CONST64(0x9144C5FEA4C6E0A4) /* 699 */, + CONST64(0x0D33D06565CF620F) /* 700 */, CONST64(0x54A48D489F219CA1) /* 701 */, + CONST64(0xC43E5EAC6D63C821) /* 702 */, CONST64(0xA9728B3A72770DAF) /* 703 */, + CONST64(0xD7934E7B20DF87EF) /* 704 */, CONST64(0xE35503B61A3E86E5) /* 705 */, + CONST64(0xCAE321FBC819D504) /* 706 */, CONST64(0x129A50B3AC60BFA6) /* 707 */, + CONST64(0xCD5E68EA7E9FB6C3) /* 708 */, CONST64(0xB01C90199483B1C7) /* 709 */, + CONST64(0x3DE93CD5C295376C) /* 710 */, CONST64(0xAED52EDF2AB9AD13) /* 711 */, + CONST64(0x2E60F512C0A07884) /* 712 */, CONST64(0xBC3D86A3E36210C9) /* 713 */, + CONST64(0x35269D9B163951CE) /* 714 */, CONST64(0x0C7D6E2AD0CDB5FA) /* 715 */, + CONST64(0x59E86297D87F5733) /* 716 */, CONST64(0x298EF221898DB0E7) /* 717 */, + CONST64(0x55000029D1A5AA7E) /* 718 */, CONST64(0x8BC08AE1B5061B45) /* 719 */, + CONST64(0xC2C31C2B6C92703A) /* 720 */, CONST64(0x94CC596BAF25EF42) /* 721 */, + CONST64(0x0A1D73DB22540456) /* 722 */, CONST64(0x04B6A0F9D9C4179A) /* 723 */, + CONST64(0xEFFDAFA2AE3D3C60) /* 724 */, CONST64(0xF7C8075BB49496C4) /* 725 */, + CONST64(0x9CC5C7141D1CD4E3) /* 726 */, CONST64(0x78BD1638218E5534) /* 727 */, + CONST64(0xB2F11568F850246A) /* 728 */, CONST64(0xEDFABCFA9502BC29) /* 729 */, + CONST64(0x796CE5F2DA23051B) /* 730 */, CONST64(0xAAE128B0DC93537C) /* 731 */, + CONST64(0x3A493DA0EE4B29AE) /* 732 */, CONST64(0xB5DF6B2C416895D7) /* 733 */, + CONST64(0xFCABBD25122D7F37) /* 734 */, CONST64(0x70810B58105DC4B1) /* 735 */, + CONST64(0xE10FDD37F7882A90) /* 736 */, CONST64(0x524DCAB5518A3F5C) /* 737 */, + CONST64(0x3C9E85878451255B) /* 738 */, CONST64(0x4029828119BD34E2) /* 739 */, + CONST64(0x74A05B6F5D3CECCB) /* 740 */, CONST64(0xB610021542E13ECA) /* 741 */, + CONST64(0x0FF979D12F59E2AC) /* 742 */, CONST64(0x6037DA27E4F9CC50) /* 743 */, + CONST64(0x5E92975A0DF1847D) /* 744 */, CONST64(0xD66DE190D3E623FE) /* 745 */, + CONST64(0x5032D6B87B568048) /* 746 */, CONST64(0x9A36B7CE8235216E) /* 747 */, + CONST64(0x80272A7A24F64B4A) /* 748 */, CONST64(0x93EFED8B8C6916F7) /* 749 */, + CONST64(0x37DDBFF44CCE1555) /* 750 */, CONST64(0x4B95DB5D4B99BD25) /* 751 */, + CONST64(0x92D3FDA169812FC0) /* 752 */, CONST64(0xFB1A4A9A90660BB6) /* 753 */, + CONST64(0x730C196946A4B9B2) /* 754 */, CONST64(0x81E289AA7F49DA68) /* 755 */, + CONST64(0x64669A0F83B1A05F) /* 756 */, CONST64(0x27B3FF7D9644F48B) /* 757 */, + CONST64(0xCC6B615C8DB675B3) /* 758 */, CONST64(0x674F20B9BCEBBE95) /* 759 */, + CONST64(0x6F31238275655982) /* 760 */, CONST64(0x5AE488713E45CF05) /* 761 */, + CONST64(0xBF619F9954C21157) /* 762 */, CONST64(0xEABAC46040A8EAE9) /* 763 */, + CONST64(0x454C6FE9F2C0C1CD) /* 764 */, CONST64(0x419CF6496412691C) /* 765 */, + CONST64(0xD3DC3BEF265B0F70) /* 766 */, CONST64(0x6D0E60F5C3578A9E) /* 767 */, + CONST64(0x5B0E608526323C55) /* 768 */, CONST64(0x1A46C1A9FA1B59F5) /* 769 */, + CONST64(0xA9E245A17C4C8FFA) /* 770 */, CONST64(0x65CA5159DB2955D7) /* 771 */, + CONST64(0x05DB0A76CE35AFC2) /* 772 */, CONST64(0x81EAC77EA9113D45) /* 773 */, + CONST64(0x528EF88AB6AC0A0D) /* 774 */, CONST64(0xA09EA253597BE3FF) /* 775 */, + CONST64(0x430DDFB3AC48CD56) /* 776 */, CONST64(0xC4B3A67AF45CE46F) /* 777 */, + CONST64(0x4ECECFD8FBE2D05E) /* 778 */, CONST64(0x3EF56F10B39935F0) /* 779 */, + CONST64(0x0B22D6829CD619C6) /* 780 */, CONST64(0x17FD460A74DF2069) /* 781 */, + CONST64(0x6CF8CC8E8510ED40) /* 782 */, CONST64(0xD6C824BF3A6ECAA7) /* 783 */, + CONST64(0x61243D581A817049) /* 784 */, CONST64(0x048BACB6BBC163A2) /* 785 */, + CONST64(0xD9A38AC27D44CC32) /* 786 */, CONST64(0x7FDDFF5BAAF410AB) /* 787 */, + CONST64(0xAD6D495AA804824B) /* 788 */, CONST64(0xE1A6A74F2D8C9F94) /* 789 */, + CONST64(0xD4F7851235DEE8E3) /* 790 */, CONST64(0xFD4B7F886540D893) /* 791 */, + CONST64(0x247C20042AA4BFDA) /* 792 */, CONST64(0x096EA1C517D1327C) /* 793 */, + CONST64(0xD56966B4361A6685) /* 794 */, CONST64(0x277DA5C31221057D) /* 795 */, + CONST64(0x94D59893A43ACFF7) /* 796 */, CONST64(0x64F0C51CCDC02281) /* 797 */, + CONST64(0x3D33BCC4FF6189DB) /* 798 */, CONST64(0xE005CB184CE66AF1) /* 799 */, + CONST64(0xFF5CCD1D1DB99BEA) /* 800 */, CONST64(0xB0B854A7FE42980F) /* 801 */, + CONST64(0x7BD46A6A718D4B9F) /* 802 */, CONST64(0xD10FA8CC22A5FD8C) /* 803 */, + CONST64(0xD31484952BE4BD31) /* 804 */, CONST64(0xC7FA975FCB243847) /* 805 */, + CONST64(0x4886ED1E5846C407) /* 806 */, CONST64(0x28CDDB791EB70B04) /* 807 */, + CONST64(0xC2B00BE2F573417F) /* 808 */, CONST64(0x5C9590452180F877) /* 809 */, + CONST64(0x7A6BDDFFF370EB00) /* 810 */, CONST64(0xCE509E38D6D9D6A4) /* 811 */, + CONST64(0xEBEB0F00647FA702) /* 812 */, CONST64(0x1DCC06CF76606F06) /* 813 */, + CONST64(0xE4D9F28BA286FF0A) /* 814 */, CONST64(0xD85A305DC918C262) /* 815 */, + CONST64(0x475B1D8732225F54) /* 816 */, CONST64(0x2D4FB51668CCB5FE) /* 817 */, + CONST64(0xA679B9D9D72BBA20) /* 818 */, CONST64(0x53841C0D912D43A5) /* 819 */, + CONST64(0x3B7EAA48BF12A4E8) /* 820 */, CONST64(0x781E0E47F22F1DDF) /* 821 */, + CONST64(0xEFF20CE60AB50973) /* 822 */, CONST64(0x20D261D19DFFB742) /* 823 */, + CONST64(0x16A12B03062A2E39) /* 824 */, CONST64(0x1960EB2239650495) /* 825 */, + CONST64(0x251C16FED50EB8B8) /* 826 */, CONST64(0x9AC0C330F826016E) /* 827 */, + CONST64(0xED152665953E7671) /* 828 */, CONST64(0x02D63194A6369570) /* 829 */, + CONST64(0x5074F08394B1C987) /* 830 */, CONST64(0x70BA598C90B25CE1) /* 831 */, + CONST64(0x794A15810B9742F6) /* 832 */, CONST64(0x0D5925E9FCAF8C6C) /* 833 */, + CONST64(0x3067716CD868744E) /* 834 */, CONST64(0x910AB077E8D7731B) /* 835 */, + CONST64(0x6A61BBDB5AC42F61) /* 836 */, CONST64(0x93513EFBF0851567) /* 837 */, + CONST64(0xF494724B9E83E9D5) /* 838 */, CONST64(0xE887E1985C09648D) /* 839 */, + CONST64(0x34B1D3C675370CFD) /* 840 */, CONST64(0xDC35E433BC0D255D) /* 841 */, + CONST64(0xD0AAB84234131BE0) /* 842 */, CONST64(0x08042A50B48B7EAF) /* 843 */, + CONST64(0x9997C4EE44A3AB35) /* 844 */, CONST64(0x829A7B49201799D0) /* 845 */, + CONST64(0x263B8307B7C54441) /* 846 */, CONST64(0x752F95F4FD6A6CA6) /* 847 */, + CONST64(0x927217402C08C6E5) /* 848 */, CONST64(0x2A8AB754A795D9EE) /* 849 */, + CONST64(0xA442F7552F72943D) /* 850 */, CONST64(0x2C31334E19781208) /* 851 */, + CONST64(0x4FA98D7CEAEE6291) /* 852 */, CONST64(0x55C3862F665DB309) /* 853 */, + CONST64(0xBD0610175D53B1F3) /* 854 */, CONST64(0x46FE6CB840413F27) /* 855 */, + CONST64(0x3FE03792DF0CFA59) /* 856 */, CONST64(0xCFE700372EB85E8F) /* 857 */, + CONST64(0xA7BE29E7ADBCE118) /* 858 */, CONST64(0xE544EE5CDE8431DD) /* 859 */, + CONST64(0x8A781B1B41F1873E) /* 860 */, CONST64(0xA5C94C78A0D2F0E7) /* 861 */, + CONST64(0x39412E2877B60728) /* 862 */, CONST64(0xA1265EF3AFC9A62C) /* 863 */, + CONST64(0xBCC2770C6A2506C5) /* 864 */, CONST64(0x3AB66DD5DCE1CE12) /* 865 */, + CONST64(0xE65499D04A675B37) /* 866 */, CONST64(0x7D8F523481BFD216) /* 867 */, + CONST64(0x0F6F64FCEC15F389) /* 868 */, CONST64(0x74EFBE618B5B13C8) /* 869 */, + CONST64(0xACDC82B714273E1D) /* 870 */, CONST64(0xDD40BFE003199D17) /* 871 */, + CONST64(0x37E99257E7E061F8) /* 872 */, CONST64(0xFA52626904775AAA) /* 873 */, + CONST64(0x8BBBF63A463D56F9) /* 874 */, CONST64(0xF0013F1543A26E64) /* 875 */, + CONST64(0xA8307E9F879EC898) /* 876 */, CONST64(0xCC4C27A4150177CC) /* 877 */, + CONST64(0x1B432F2CCA1D3348) /* 878 */, CONST64(0xDE1D1F8F9F6FA013) /* 879 */, + CONST64(0x606602A047A7DDD6) /* 880 */, CONST64(0xD237AB64CC1CB2C7) /* 881 */, + CONST64(0x9B938E7225FCD1D3) /* 882 */, CONST64(0xEC4E03708E0FF476) /* 883 */, + CONST64(0xFEB2FBDA3D03C12D) /* 884 */, CONST64(0xAE0BCED2EE43889A) /* 885 */, + CONST64(0x22CB8923EBFB4F43) /* 886 */, CONST64(0x69360D013CF7396D) /* 887 */, + CONST64(0x855E3602D2D4E022) /* 888 */, CONST64(0x073805BAD01F784C) /* 889 */, + CONST64(0x33E17A133852F546) /* 890 */, CONST64(0xDF4874058AC7B638) /* 891 */, + CONST64(0xBA92B29C678AA14A) /* 892 */, CONST64(0x0CE89FC76CFAADCD) /* 893 */, + CONST64(0x5F9D4E0908339E34) /* 894 */, CONST64(0xF1AFE9291F5923B9) /* 895 */, + CONST64(0x6E3480F60F4A265F) /* 896 */, CONST64(0xEEBF3A2AB29B841C) /* 897 */, + CONST64(0xE21938A88F91B4AD) /* 898 */, CONST64(0x57DFEFF845C6D3C3) /* 899 */, + CONST64(0x2F006B0BF62CAAF2) /* 900 */, CONST64(0x62F479EF6F75EE78) /* 901 */, + CONST64(0x11A55AD41C8916A9) /* 902 */, CONST64(0xF229D29084FED453) /* 903 */, + CONST64(0x42F1C27B16B000E6) /* 904 */, CONST64(0x2B1F76749823C074) /* 905 */, + CONST64(0x4B76ECA3C2745360) /* 906 */, CONST64(0x8C98F463B91691BD) /* 907 */, + CONST64(0x14BCC93CF1ADE66A) /* 908 */, CONST64(0x8885213E6D458397) /* 909 */, + CONST64(0x8E177DF0274D4711) /* 910 */, CONST64(0xB49B73B5503F2951) /* 911 */, + CONST64(0x10168168C3F96B6B) /* 912 */, CONST64(0x0E3D963B63CAB0AE) /* 913 */, + CONST64(0x8DFC4B5655A1DB14) /* 914 */, CONST64(0xF789F1356E14DE5C) /* 915 */, + CONST64(0x683E68AF4E51DAC1) /* 916 */, CONST64(0xC9A84F9D8D4B0FD9) /* 917 */, + CONST64(0x3691E03F52A0F9D1) /* 918 */, CONST64(0x5ED86E46E1878E80) /* 919 */, + CONST64(0x3C711A0E99D07150) /* 920 */, CONST64(0x5A0865B20C4E9310) /* 921 */, + CONST64(0x56FBFC1FE4F0682E) /* 922 */, CONST64(0xEA8D5DE3105EDF9B) /* 923 */, + CONST64(0x71ABFDB12379187A) /* 924 */, CONST64(0x2EB99DE1BEE77B9C) /* 925 */, + CONST64(0x21ECC0EA33CF4523) /* 926 */, CONST64(0x59A4D7521805C7A1) /* 927 */, + CONST64(0x3896F5EB56AE7C72) /* 928 */, CONST64(0xAA638F3DB18F75DC) /* 929 */, + CONST64(0x9F39358DABE9808E) /* 930 */, CONST64(0xB7DEFA91C00B72AC) /* 931 */, + CONST64(0x6B5541FD62492D92) /* 932 */, CONST64(0x6DC6DEE8F92E4D5B) /* 933 */, + CONST64(0x353F57ABC4BEEA7E) /* 934 */, CONST64(0x735769D6DA5690CE) /* 935 */, + CONST64(0x0A234AA642391484) /* 936 */, CONST64(0xF6F9508028F80D9D) /* 937 */, + CONST64(0xB8E319A27AB3F215) /* 938 */, CONST64(0x31AD9C1151341A4D) /* 939 */, + CONST64(0x773C22A57BEF5805) /* 940 */, CONST64(0x45C7561A07968633) /* 941 */, + CONST64(0xF913DA9E249DBE36) /* 942 */, CONST64(0xDA652D9B78A64C68) /* 943 */, + CONST64(0x4C27A97F3BC334EF) /* 944 */, CONST64(0x76621220E66B17F4) /* 945 */, + CONST64(0x967743899ACD7D0B) /* 946 */, CONST64(0xF3EE5BCAE0ED6782) /* 947 */, + CONST64(0x409F753600C879FC) /* 948 */, CONST64(0x06D09A39B5926DB6) /* 949 */, + CONST64(0x6F83AEB0317AC588) /* 950 */, CONST64(0x01E6CA4A86381F21) /* 951 */, + CONST64(0x66FF3462D19F3025) /* 952 */, CONST64(0x72207C24DDFD3BFB) /* 953 */, + CONST64(0x4AF6B6D3E2ECE2EB) /* 954 */, CONST64(0x9C994DBEC7EA08DE) /* 955 */, + CONST64(0x49ACE597B09A8BC4) /* 956 */, CONST64(0xB38C4766CF0797BA) /* 957 */, + CONST64(0x131B9373C57C2A75) /* 958 */, CONST64(0xB1822CCE61931E58) /* 959 */, + CONST64(0x9D7555B909BA1C0C) /* 960 */, CONST64(0x127FAFDD937D11D2) /* 961 */, + CONST64(0x29DA3BADC66D92E4) /* 962 */, CONST64(0xA2C1D57154C2ECBC) /* 963 */, + CONST64(0x58C5134D82F6FE24) /* 964 */, CONST64(0x1C3AE3515B62274F) /* 965 */, + CONST64(0xE907C82E01CB8126) /* 966 */, CONST64(0xF8ED091913E37FCB) /* 967 */, + CONST64(0x3249D8F9C80046C9) /* 968 */, CONST64(0x80CF9BEDE388FB63) /* 969 */, + CONST64(0x1881539A116CF19E) /* 970 */, CONST64(0x5103F3F76BD52457) /* 971 */, + CONST64(0x15B7E6F5AE47F7A8) /* 972 */, CONST64(0xDBD7C6DED47E9CCF) /* 973 */, + CONST64(0x44E55C410228BB1A) /* 974 */, CONST64(0xB647D4255EDB4E99) /* 975 */, + CONST64(0x5D11882BB8AAFC30) /* 976 */, CONST64(0xF5098BBB29D3212A) /* 977 */, + CONST64(0x8FB5EA14E90296B3) /* 978 */, CONST64(0x677B942157DD025A) /* 979 */, + CONST64(0xFB58E7C0A390ACB5) /* 980 */, CONST64(0x89D3674C83BD4A01) /* 981 */, + CONST64(0x9E2DA4DF4BF3B93B) /* 982 */, CONST64(0xFCC41E328CAB4829) /* 983 */, + CONST64(0x03F38C96BA582C52) /* 984 */, CONST64(0xCAD1BDBD7FD85DB2) /* 985 */, + CONST64(0xBBB442C16082AE83) /* 986 */, CONST64(0xB95FE86BA5DA9AB0) /* 987 */, + CONST64(0xB22E04673771A93F) /* 988 */, CONST64(0x845358C9493152D8) /* 989 */, + CONST64(0xBE2A488697B4541E) /* 990 */, CONST64(0x95A2DC2DD38E6966) /* 991 */, + CONST64(0xC02C11AC923C852B) /* 992 */, CONST64(0x2388B1990DF2A87B) /* 993 */, + CONST64(0x7C8008FA1B4F37BE) /* 994 */, CONST64(0x1F70D0C84D54E503) /* 995 */, + CONST64(0x5490ADEC7ECE57D4) /* 996 */, CONST64(0x002B3C27D9063A3A) /* 997 */, + CONST64(0x7EAEA3848030A2BF) /* 998 */, CONST64(0xC602326DED2003C0) /* 999 */, + CONST64(0x83A7287D69A94086) /* 1000 */, CONST64(0xC57A5FCB30F57A8A) /* 1001 */, + CONST64(0xB56844E479EBE779) /* 1002 */, CONST64(0xA373B40F05DCBCE9) /* 1003 */, + CONST64(0xD71A786E88570EE2) /* 1004 */, CONST64(0x879CBACDBDE8F6A0) /* 1005 */, + CONST64(0x976AD1BCC164A32F) /* 1006 */, CONST64(0xAB21E25E9666D78B) /* 1007 */, + CONST64(0x901063AAE5E5C33C) /* 1008 */, CONST64(0x9818B34448698D90) /* 1009 */, + CONST64(0xE36487AE3E1E8ABB) /* 1010 */, CONST64(0xAFBDF931893BDCB4) /* 1011 */, + CONST64(0x6345A0DC5FBBD519) /* 1012 */, CONST64(0x8628FE269B9465CA) /* 1013 */, + CONST64(0x1E5D01603F9C51EC) /* 1014 */, CONST64(0x4DE44006A15049B7) /* 1015 */, + CONST64(0xBF6C70E5F776CBB1) /* 1016 */, CONST64(0x411218F2EF552BED) /* 1017 */, + CONST64(0xCB0C0708705A36A3) /* 1018 */, CONST64(0xE74D14754F986044) /* 1019 */, + CONST64(0xCD56D9430EA8280E) /* 1020 */, CONST64(0xC12591D7535F5065) /* 1021 */, + CONST64(0xC83223F1720AEF96) /* 1022 */, CONST64(0xC3A0396F7363A51F) /* 1023 */}; + +#ifdef _MSC_VER + #define INLINE __inline +#else + #define INLINE +#endif + +/* one round of the hash function */ +INLINE static void tiger_round(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 x, int mul) +{ + ulong64 tmp; + tmp = (*c ^= x); + *a -= t1[byte(tmp, 0)] ^ t2[byte(tmp, 2)] ^ t3[byte(tmp, 4)] ^ t4[byte(tmp, 6)]; + tmp = (*b += t4[byte(tmp, 1)] ^ t3[byte(tmp, 3)] ^ t2[byte(tmp,5)] ^ t1[byte(tmp,7)]); + switch (mul) { + case 5: *b = (tmp << 2) + tmp; break; + case 7: *b = (tmp << 3) - tmp; break; + case 9: *b = (tmp << 3) + tmp; break; + } +} + +/* one complete pass */ +static void pass(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 *x, int mul) +{ + tiger_round(a,b,c,x[0],mul); + tiger_round(b,c,a,x[1],mul); + tiger_round(c,a,b,x[2],mul); + tiger_round(a,b,c,x[3],mul); + tiger_round(b,c,a,x[4],mul); + tiger_round(c,a,b,x[5],mul); + tiger_round(a,b,c,x[6],mul); + tiger_round(b,c,a,x[7],mul); +} + +/* The key mixing schedule */ +static void key_schedule(ulong64 *x) +{ + x[0] -= x[7] ^ CONST64(0xA5A5A5A5A5A5A5A5); + x[1] ^= x[0]; + x[2] += x[1]; + x[3] -= x[2] ^ ((~x[1])<<19); + x[4] ^= x[3]; + x[5] += x[4]; + x[6] -= x[5] ^ ((~x[4])>>23); + x[7] ^= x[6]; + x[0] += x[7]; + x[1] -= x[0] ^ ((~x[7])<<19); + x[2] ^= x[1]; + x[3] += x[2]; + x[4] -= x[3] ^ ((~x[2])>>23); + x[5] ^= x[4]; + x[6] += x[5]; + x[7] -= x[6] ^ CONST64(0x0123456789ABCDEF); +} + +#ifdef LTC_CLEAN_STACK +static int _tiger_compress(hash_state *md, unsigned char *buf) +#else +static int tiger_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong64 a, b, c, x[8]; + unsigned long i; + + /* load words */ + for (i = 0; i < 8; i++) { + LOAD64L(x[i],&buf[8*i]); + } + a = md->tiger.state[0]; + b = md->tiger.state[1]; + c = md->tiger.state[2]; + + pass(&a,&b,&c,x,5); + key_schedule(x); + pass(&c,&a,&b,x,7); + key_schedule(x); + pass(&b,&c,&a,x,9); + + /* store state */ + md->tiger.state[0] = a ^ md->tiger.state[0]; + md->tiger.state[1] = b - md->tiger.state[1]; + md->tiger.state[2] = c + md->tiger.state[2]; + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +static int tiger_compress(hash_state *md, unsigned char *buf) +{ + int err; + err = _tiger_compress(md, buf); + burn_stack(sizeof(ulong64) * 11 + sizeof(unsigned long)); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int tiger_init(hash_state *md) +{ + LTC_ARGCHK(md != NULL); + md->tiger.state[0] = CONST64(0x0123456789ABCDEF); + md->tiger.state[1] = CONST64(0xFEDCBA9876543210); + md->tiger.state[2] = CONST64(0xF096A5B4C3B2E187); + md->tiger.curlen = 0; + md->tiger.length = 0; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(tiger_process, tiger_compress, tiger, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (24 bytes) + @return CRYPT_OK if successful +*/ +int tiger_done(hash_state * md, unsigned char *out) +{ + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->tiger.curlen >= sizeof(md->tiger.buf)) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->tiger.length += md->tiger.curlen * 8; + + /* append the '1' bit */ + md->tiger.buf[md->tiger.curlen++] = (unsigned char)0x01; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. */ + if (md->tiger.curlen > 56) { + while (md->tiger.curlen < 64) { + md->tiger.buf[md->tiger.curlen++] = (unsigned char)0; + } + tiger_compress(md, md->tiger.buf); + md->tiger.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->tiger.curlen < 56) { + md->tiger.buf[md->tiger.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->tiger.length, md->tiger.buf+56); + tiger_compress(md, md->tiger.buf); + + /* copy output */ + STORE64L(md->tiger.state[0], &out[0]); + STORE64L(md->tiger.state[1], &out[8]); + STORE64L(md->tiger.state[2], &out[16]); +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int tiger_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[24]; + } tests[] = { + { "", + { 0x32, 0x93, 0xac, 0x63, 0x0c, 0x13, 0xf0, 0x24, + 0x5f, 0x92, 0xbb, 0xb1, 0x76, 0x6e, 0x16, 0x16, + 0x7a, 0x4e, 0x58, 0x49, 0x2d, 0xde, 0x73, 0xf3 } + }, + { "abc", + { 0x2a, 0xab, 0x14, 0x84, 0xe8, 0xc1, 0x58, 0xf2, + 0xbf, 0xb8, 0xc5, 0xff, 0x41, 0xb5, 0x7a, 0x52, + 0x51, 0x29, 0x13, 0x1c, 0x95, 0x7b, 0x5f, 0x93 } + }, + { "Tiger", + { 0xdd, 0x00, 0x23, 0x07, 0x99, 0xf5, 0x00, 0x9f, + 0xec, 0x6d, 0xeb, 0xc8, 0x38, 0xbb, 0x6a, 0x27, + 0xdf, 0x2b, 0x9d, 0x6f, 0x11, 0x0c, 0x79, 0x37 } + }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", + { 0xf7, 0x1c, 0x85, 0x83, 0x90, 0x2a, 0xfb, 0x87, + 0x9e, 0xdf, 0xe6, 0x10, 0xf8, 0x2c, 0x0d, 0x47, + 0x86, 0xa3, 0xa5, 0x34, 0x50, 0x44, 0x86, 0xb5 } + }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", + { 0xc5, 0x40, 0x34, 0xe5, 0xb4, 0x3e, 0xb8, 0x00, + 0x58, 0x48, 0xa7, 0xe0, 0xae, 0x6a, 0xac, 0x76, + 0xe4, 0xff, 0x59, 0x0a, 0xe7, 0x15, 0xfd, 0x25 } + }, + }; + + int i; + unsigned char tmp[24]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + tiger_init(&md); + tiger_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + tiger_done(&md, tmp); + if (XMEMCMP(tmp, tests[i].hash, 24) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif + +/* +Hash of "": + 24F0130C63AC9332 16166E76B1BB925F F373DE2D49584E7A +Hash of "abc": + F258C1E88414AB2A 527AB541FFC5B8BF 935F7B951C132951 +Hash of "Tiger": + 9F00F599072300DD 276ABB38C8EB6DEC 37790C116F9D2BDF +Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-": + 87FB2A9083851CF7 470D2CF810E6DF9E B586445034A5A386 +Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789": + 467DB80863EBCE48 8DF1CD1261655DE9 57896565975F9197 +Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham": + 0C410A042968868A 1671DA5A3FD29A72 5EC1E457D3CDB303 +Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge.": + EBF591D5AFA655CE 7F22894FF87F54AC 89C811B6B0DA3193 +Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge, 1996.": + 3D9AEB03D1BD1A63 57B2774DFD6D5B24 DD68151D503974FC +Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-": + 00B83EB4E53440C5 76AC6AAEE0A74858 25FD15E70A59FFE4 +*/ + + + + +/* $Source: /cvs/libtom/libtomcrypt/src/hashes/tiger.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:25:28 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/whirl/whirl.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/whirl/whirl.c new file mode 100644 index 0000000000..2d20ec006d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/whirl/whirl.c @@ -0,0 +1,314 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file whirl.c + LTC_WHIRLPOOL (using their new sbox) hash function by Tom St Denis +*/ + +#include "tomcrypt.h" + +#ifdef LTC_WHIRLPOOL + +const struct ltc_hash_descriptor whirlpool_desc = +{ + "whirlpool", + 11, + 64, + 64, + + /* OID */ + { 1, 0, 10118, 3, 0, 55 }, + 6, + + &whirlpool_init, + &whirlpool_process, + &whirlpool_done, + &whirlpool_test, + NULL +}; + +/* the sboxes */ +#include "whirltab.c" + +/* get a_{i,j} */ +#define GB(a,i,j) ((a[(i) & 7] >> (8 * (j))) & 255) + +/* shortcut macro to perform three functions at once */ +#define theta_pi_gamma(a, i) \ + SB0(GB(a, i-0, 7)) ^ \ + SB1(GB(a, i-1, 6)) ^ \ + SB2(GB(a, i-2, 5)) ^ \ + SB3(GB(a, i-3, 4)) ^ \ + SB4(GB(a, i-4, 3)) ^ \ + SB5(GB(a, i-5, 2)) ^ \ + SB6(GB(a, i-6, 1)) ^ \ + SB7(GB(a, i-7, 0)) + +#ifdef LTC_CLEAN_STACK +static int _whirlpool_compress(hash_state *md, unsigned char *buf) +#else +static int whirlpool_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong64 K[2][8], T[3][8]; + int x, y; + + /* load the block/state */ + for (x = 0; x < 8; x++) { + K[0][x] = md->whirlpool.state[x]; + + LOAD64H(T[0][x], buf + (8 * x)); + T[2][x] = T[0][x]; + T[0][x] ^= K[0][x]; + } + + /* do rounds 1..10 */ + for (x = 0; x < 10; x += 2) { + /* odd round */ + /* apply main transform to K[0] into K[1] */ + for (y = 0; y < 8; y++) { + K[1][y] = theta_pi_gamma(K[0], y); + } + /* xor the constant */ + K[1][0] ^= cont[x]; + + /* apply main transform to T[0] into T[1] */ + for (y = 0; y < 8; y++) { + T[1][y] = theta_pi_gamma(T[0], y) ^ K[1][y]; + } + + /* even round */ + /* apply main transform to K[1] into K[0] */ + for (y = 0; y < 8; y++) { + K[0][y] = theta_pi_gamma(K[1], y); + } + /* xor the constant */ + K[0][0] ^= cont[x+1]; + + /* apply main transform to T[1] into T[0] */ + for (y = 0; y < 8; y++) { + T[0][y] = theta_pi_gamma(T[1], y) ^ K[0][y]; + } + } + + /* store state */ + for (x = 0; x < 8; x++) { + md->whirlpool.state[x] ^= T[0][x] ^ T[2][x]; + } + + return CRYPT_OK; +} + + +#ifdef LTC_CLEAN_STACK +static int whirlpool_compress(hash_state *md, unsigned char *buf) +{ + int err; + err = _whirlpool_compress(md, buf); + burn_stack((5 * 8 * sizeof(ulong64)) + (2 * sizeof(int))); + return err; +} +#endif + + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int whirlpool_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + zeromem(&md->whirlpool, sizeof(md->whirlpool)); + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(whirlpool_process, whirlpool_compress, whirlpool, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (64 bytes) + @return CRYPT_OK if successful +*/ +int whirlpool_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->whirlpool.curlen >= sizeof(md->whirlpool.buf)) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->whirlpool.length += md->whirlpool.curlen * 8; + + /* append the '1' bit */ + md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 32 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->whirlpool.curlen > 32) { + while (md->whirlpool.curlen < 64) { + md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0; + } + whirlpool_compress(md, md->whirlpool.buf); + md->whirlpool.curlen = 0; + } + + /* pad upto 56 bytes of zeroes (should be 32 but we only support 64-bit lengths) */ + while (md->whirlpool.curlen < 56) { + md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(md->whirlpool.length, md->whirlpool.buf+56); + whirlpool_compress(md, md->whirlpool.buf); + + /* copy output */ + for (i = 0; i < 8; i++) { + STORE64H(md->whirlpool.state[i], out+(8*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(*md)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int whirlpool_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int len; + unsigned char msg[128], hash[64]; + } tests[] = { + + /* NULL Message */ +{ + 0, + { 0x00 }, + { 0x19, 0xFA, 0x61, 0xD7, 0x55, 0x22, 0xA4, 0x66, 0x9B, 0x44, 0xE3, 0x9C, 0x1D, 0x2E, 0x17, 0x26, + 0xC5, 0x30, 0x23, 0x21, 0x30, 0xD4, 0x07, 0xF8, 0x9A, 0xFE, 0xE0, 0x96, 0x49, 0x97, 0xF7, 0xA7, + 0x3E, 0x83, 0xBE, 0x69, 0x8B, 0x28, 0x8F, 0xEB, 0xCF, 0x88, 0xE3, 0xE0, 0x3C, 0x4F, 0x07, 0x57, + 0xEA, 0x89, 0x64, 0xE5, 0x9B, 0x63, 0xD9, 0x37, 0x08, 0xB1, 0x38, 0xCC, 0x42, 0xA6, 0x6E, 0xB3 } +}, + + + /* 448-bits of 0 bits */ +{ + + 56, + { 0x00 }, + { 0x0B, 0x3F, 0x53, 0x78, 0xEB, 0xED, 0x2B, 0xF4, 0xD7, 0xBE, 0x3C, 0xFD, 0x81, 0x8C, 0x1B, 0x03, + 0xB6, 0xBB, 0x03, 0xD3, 0x46, 0x94, 0x8B, 0x04, 0xF4, 0xF4, 0x0C, 0x72, 0x6F, 0x07, 0x58, 0x70, + 0x2A, 0x0F, 0x1E, 0x22, 0x58, 0x80, 0xE3, 0x8D, 0xD5, 0xF6, 0xED, 0x6D, 0xE9, 0xB1, 0xE9, 0x61, + 0xE4, 0x9F, 0xC1, 0x31, 0x8D, 0x7C, 0xB7, 0x48, 0x22, 0xF3, 0xD0, 0xE2, 0xE9, 0xA7, 0xE7, 0xB0 } +}, + + /* 520-bits of 0 bits */ +{ + 65, + { 0x00 }, + { 0x85, 0xE1, 0x24, 0xC4, 0x41, 0x5B, 0xCF, 0x43, 0x19, 0x54, 0x3E, 0x3A, 0x63, 0xFF, 0x57, 0x1D, + 0x09, 0x35, 0x4C, 0xEE, 0xBE, 0xE1, 0xE3, 0x25, 0x30, 0x8C, 0x90, 0x69, 0xF4, 0x3E, 0x2A, 0xE4, + 0xD0, 0xE5, 0x1D, 0x4E, 0xB1, 0xE8, 0x64, 0x28, 0x70, 0x19, 0x4E, 0x95, 0x30, 0xD8, 0xD8, 0xAF, + 0x65, 0x89, 0xD1, 0xBF, 0x69, 0x49, 0xDD, 0xF9, 0x0A, 0x7F, 0x12, 0x08, 0x62, 0x37, 0x95, 0xB9 } +}, + + /* 512-bits, leading set */ +{ + 64, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x10, 0x3E, 0x00, 0x55, 0xA9, 0xB0, 0x90, 0xE1, 0x1C, 0x8F, 0xDD, 0xEB, 0xBA, 0x06, 0xC0, 0x5A, + 0xCE, 0x8B, 0x64, 0xB8, 0x96, 0x12, 0x8F, 0x6E, 0xED, 0x30, 0x71, 0xFC, 0xF3, 0xDC, 0x16, 0x94, + 0x67, 0x78, 0xE0, 0x72, 0x23, 0x23, 0x3F, 0xD1, 0x80, 0xFC, 0x40, 0xCC, 0xDB, 0x84, 0x30, 0xA6, + 0x40, 0xE3, 0x76, 0x34, 0x27, 0x1E, 0x65, 0x5C, 0xA1, 0x67, 0x4E, 0xBF, 0xF5, 0x07, 0xF8, 0xCB } +}, + + /* 512-bits, leading set of second byte */ +{ + 64, + { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x35, 0x7B, 0x42, 0xEA, 0x79, 0xBC, 0x97, 0x86, 0x97, 0x5A, 0x3C, 0x44, 0x70, 0xAA, 0xB2, 0x3E, + 0x62, 0x29, 0x79, 0x7B, 0xAD, 0xBD, 0x54, 0x36, 0x5B, 0x54, 0x96, 0xE5, 0x5D, 0x9D, 0xD7, 0x9F, + 0xE9, 0x62, 0x4F, 0xB4, 0x22, 0x66, 0x93, 0x0A, 0x62, 0x8E, 0xD4, 0xDB, 0x08, 0xF9, 0xDD, 0x35, + 0xEF, 0x1B, 0xE1, 0x04, 0x53, 0xFC, 0x18, 0xF4, 0x2C, 0x7F, 0x5E, 0x1F, 0x9B, 0xAE, 0x55, 0xE0 } +}, + + /* 512-bits, leading set of last byte */ +{ + 64, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 }, + { 0x8B, 0x39, 0x04, 0xDD, 0x19, 0x81, 0x41, 0x26, 0xFD, 0x02, 0x74, 0xAB, 0x49, 0xC5, 0x97, 0xF6, + 0xD7, 0x75, 0x33, 0x52, 0xA2, 0xDD, 0x91, 0xFD, 0x8F, 0x9F, 0x54, 0x05, 0x4C, 0x54, 0xBF, 0x0F, + 0x06, 0xDB, 0x4F, 0xF7, 0x08, 0xA3, 0xA2, 0x8B, 0xC3, 0x7A, 0x92, 0x1E, 0xEE, 0x11, 0xED, 0x7B, + 0x6A, 0x53, 0x79, 0x32, 0xCC, 0x5E, 0x94, 0xEE, 0x1E, 0xA6, 0x57, 0x60, 0x7E, 0x36, 0xC9, 0xF7 } +}, + +}; + + int i; + unsigned char tmp[64]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { + whirlpool_init(&md); + whirlpool_process(&md, (unsigned char *)tests[i].msg, tests[i].len); + whirlpool_done(&md, tmp); + if (XMEMCMP(tmp, tests[i].hash, 64) != 0) { +#if 0 + printf("\nFailed test %d\n", i); + for (i = 0; i < 64; ) { + printf("%02x ", tmp[i]); + if (!(++i & 15)) printf("\n"); + } +#endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/hashes/whirl/whirl.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:21:44 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/whirl/whirltab.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/whirl/whirltab.c new file mode 100644 index 0000000000..1d153c3d30 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/hashes/whirl/whirltab.c @@ -0,0 +1,583 @@ +/** + @file whirltab.c + LTC_WHIRLPOOL tables, Tom St Denis +*/ +static const ulong64 sbox0[] = { +CONST64(0x18186018c07830d8), CONST64(0x23238c2305af4626), CONST64(0xc6c63fc67ef991b8), CONST64(0xe8e887e8136fcdfb), +CONST64(0x878726874ca113cb), CONST64(0xb8b8dab8a9626d11), CONST64(0x0101040108050209), CONST64(0x4f4f214f426e9e0d), +CONST64(0x3636d836adee6c9b), CONST64(0xa6a6a2a6590451ff), CONST64(0xd2d26fd2debdb90c), CONST64(0xf5f5f3f5fb06f70e), +CONST64(0x7979f979ef80f296), CONST64(0x6f6fa16f5fcede30), CONST64(0x91917e91fcef3f6d), CONST64(0x52525552aa07a4f8), +CONST64(0x60609d6027fdc047), CONST64(0xbcbccabc89766535), CONST64(0x9b9b569baccd2b37), CONST64(0x8e8e028e048c018a), +CONST64(0xa3a3b6a371155bd2), CONST64(0x0c0c300c603c186c), CONST64(0x7b7bf17bff8af684), CONST64(0x3535d435b5e16a80), +CONST64(0x1d1d741de8693af5), CONST64(0xe0e0a7e05347ddb3), CONST64(0xd7d77bd7f6acb321), CONST64(0xc2c22fc25eed999c), +CONST64(0x2e2eb82e6d965c43), CONST64(0x4b4b314b627a9629), CONST64(0xfefedffea321e15d), CONST64(0x575741578216aed5), +CONST64(0x15155415a8412abd), CONST64(0x7777c1779fb6eee8), CONST64(0x3737dc37a5eb6e92), CONST64(0xe5e5b3e57b56d79e), +CONST64(0x9f9f469f8cd92313), CONST64(0xf0f0e7f0d317fd23), CONST64(0x4a4a354a6a7f9420), CONST64(0xdada4fda9e95a944), +CONST64(0x58587d58fa25b0a2), CONST64(0xc9c903c906ca8fcf), CONST64(0x2929a429558d527c), CONST64(0x0a0a280a5022145a), +CONST64(0xb1b1feb1e14f7f50), CONST64(0xa0a0baa0691a5dc9), CONST64(0x6b6bb16b7fdad614), CONST64(0x85852e855cab17d9), +CONST64(0xbdbdcebd8173673c), CONST64(0x5d5d695dd234ba8f), CONST64(0x1010401080502090), CONST64(0xf4f4f7f4f303f507), +CONST64(0xcbcb0bcb16c08bdd), CONST64(0x3e3ef83eedc67cd3), CONST64(0x0505140528110a2d), CONST64(0x676781671fe6ce78), +CONST64(0xe4e4b7e47353d597), CONST64(0x27279c2725bb4e02), CONST64(0x4141194132588273), CONST64(0x8b8b168b2c9d0ba7), +CONST64(0xa7a7a6a7510153f6), CONST64(0x7d7de97dcf94fab2), CONST64(0x95956e95dcfb3749), CONST64(0xd8d847d88e9fad56), +CONST64(0xfbfbcbfb8b30eb70), CONST64(0xeeee9fee2371c1cd), CONST64(0x7c7ced7cc791f8bb), CONST64(0x6666856617e3cc71), +CONST64(0xdddd53dda68ea77b), CONST64(0x17175c17b84b2eaf), CONST64(0x4747014702468e45), CONST64(0x9e9e429e84dc211a), +CONST64(0xcaca0fca1ec589d4), CONST64(0x2d2db42d75995a58), CONST64(0xbfbfc6bf9179632e), CONST64(0x07071c07381b0e3f), +CONST64(0xadad8ead012347ac), CONST64(0x5a5a755aea2fb4b0), CONST64(0x838336836cb51bef), CONST64(0x3333cc3385ff66b6), +CONST64(0x636391633ff2c65c), CONST64(0x02020802100a0412), CONST64(0xaaaa92aa39384993), CONST64(0x7171d971afa8e2de), +CONST64(0xc8c807c80ecf8dc6), CONST64(0x19196419c87d32d1), CONST64(0x494939497270923b), CONST64(0xd9d943d9869aaf5f), +CONST64(0xf2f2eff2c31df931), CONST64(0xe3e3abe34b48dba8), CONST64(0x5b5b715be22ab6b9), CONST64(0x88881a8834920dbc), +CONST64(0x9a9a529aa4c8293e), CONST64(0x262698262dbe4c0b), CONST64(0x3232c8328dfa64bf), CONST64(0xb0b0fab0e94a7d59), +CONST64(0xe9e983e91b6acff2), CONST64(0x0f0f3c0f78331e77), CONST64(0xd5d573d5e6a6b733), CONST64(0x80803a8074ba1df4), +CONST64(0xbebec2be997c6127), CONST64(0xcdcd13cd26de87eb), CONST64(0x3434d034bde46889), CONST64(0x48483d487a759032), +CONST64(0xffffdbffab24e354), CONST64(0x7a7af57af78ff48d), CONST64(0x90907a90f4ea3d64), CONST64(0x5f5f615fc23ebe9d), +CONST64(0x202080201da0403d), CONST64(0x6868bd6867d5d00f), CONST64(0x1a1a681ad07234ca), CONST64(0xaeae82ae192c41b7), +CONST64(0xb4b4eab4c95e757d), CONST64(0x54544d549a19a8ce), CONST64(0x93937693ece53b7f), CONST64(0x222288220daa442f), +CONST64(0x64648d6407e9c863), CONST64(0xf1f1e3f1db12ff2a), CONST64(0x7373d173bfa2e6cc), CONST64(0x12124812905a2482), +CONST64(0x40401d403a5d807a), CONST64(0x0808200840281048), CONST64(0xc3c32bc356e89b95), CONST64(0xecec97ec337bc5df), +CONST64(0xdbdb4bdb9690ab4d), CONST64(0xa1a1bea1611f5fc0), CONST64(0x8d8d0e8d1c830791), CONST64(0x3d3df43df5c97ac8), +CONST64(0x97976697ccf1335b), CONST64(0x0000000000000000), CONST64(0xcfcf1bcf36d483f9), CONST64(0x2b2bac2b4587566e), +CONST64(0x7676c57697b3ece1), CONST64(0x8282328264b019e6), CONST64(0xd6d67fd6fea9b128), CONST64(0x1b1b6c1bd87736c3), +CONST64(0xb5b5eeb5c15b7774), CONST64(0xafaf86af112943be), CONST64(0x6a6ab56a77dfd41d), CONST64(0x50505d50ba0da0ea), +CONST64(0x45450945124c8a57), CONST64(0xf3f3ebf3cb18fb38), CONST64(0x3030c0309df060ad), CONST64(0xefef9bef2b74c3c4), +CONST64(0x3f3ffc3fe5c37eda), CONST64(0x55554955921caac7), CONST64(0xa2a2b2a2791059db), CONST64(0xeaea8fea0365c9e9), +CONST64(0x656589650fecca6a), CONST64(0xbabad2bab9686903), CONST64(0x2f2fbc2f65935e4a), CONST64(0xc0c027c04ee79d8e), +CONST64(0xdede5fdebe81a160), CONST64(0x1c1c701ce06c38fc), CONST64(0xfdfdd3fdbb2ee746), CONST64(0x4d4d294d52649a1f), +CONST64(0x92927292e4e03976), CONST64(0x7575c9758fbceafa), CONST64(0x06061806301e0c36), CONST64(0x8a8a128a249809ae), +CONST64(0xb2b2f2b2f940794b), CONST64(0xe6e6bfe66359d185), CONST64(0x0e0e380e70361c7e), CONST64(0x1f1f7c1ff8633ee7), +CONST64(0x6262956237f7c455), CONST64(0xd4d477d4eea3b53a), CONST64(0xa8a89aa829324d81), CONST64(0x96966296c4f43152), +CONST64(0xf9f9c3f99b3aef62), CONST64(0xc5c533c566f697a3), CONST64(0x2525942535b14a10), CONST64(0x59597959f220b2ab), +CONST64(0x84842a8454ae15d0), CONST64(0x7272d572b7a7e4c5), CONST64(0x3939e439d5dd72ec), CONST64(0x4c4c2d4c5a619816), +CONST64(0x5e5e655eca3bbc94), CONST64(0x7878fd78e785f09f), CONST64(0x3838e038ddd870e5), CONST64(0x8c8c0a8c14860598), +CONST64(0xd1d163d1c6b2bf17), CONST64(0xa5a5aea5410b57e4), CONST64(0xe2e2afe2434dd9a1), CONST64(0x616199612ff8c24e), +CONST64(0xb3b3f6b3f1457b42), CONST64(0x2121842115a54234), CONST64(0x9c9c4a9c94d62508), CONST64(0x1e1e781ef0663cee), +CONST64(0x4343114322528661), CONST64(0xc7c73bc776fc93b1), CONST64(0xfcfcd7fcb32be54f), CONST64(0x0404100420140824), +CONST64(0x51515951b208a2e3), CONST64(0x99995e99bcc72f25), CONST64(0x6d6da96d4fc4da22), CONST64(0x0d0d340d68391a65), +CONST64(0xfafacffa8335e979), CONST64(0xdfdf5bdfb684a369), CONST64(0x7e7ee57ed79bfca9), CONST64(0x242490243db44819), +CONST64(0x3b3bec3bc5d776fe), CONST64(0xabab96ab313d4b9a), CONST64(0xcece1fce3ed181f0), CONST64(0x1111441188552299), +CONST64(0x8f8f068f0c890383), CONST64(0x4e4e254e4a6b9c04), CONST64(0xb7b7e6b7d1517366), CONST64(0xebeb8beb0b60cbe0), +CONST64(0x3c3cf03cfdcc78c1), CONST64(0x81813e817cbf1ffd), CONST64(0x94946a94d4fe3540), CONST64(0xf7f7fbf7eb0cf31c), +CONST64(0xb9b9deb9a1676f18), CONST64(0x13134c13985f268b), CONST64(0x2c2cb02c7d9c5851), CONST64(0xd3d36bd3d6b8bb05), +CONST64(0xe7e7bbe76b5cd38c), CONST64(0x6e6ea56e57cbdc39), CONST64(0xc4c437c46ef395aa), CONST64(0x03030c03180f061b), +CONST64(0x565645568a13acdc), CONST64(0x44440d441a49885e), CONST64(0x7f7fe17fdf9efea0), CONST64(0xa9a99ea921374f88), +CONST64(0x2a2aa82a4d825467), CONST64(0xbbbbd6bbb16d6b0a), CONST64(0xc1c123c146e29f87), CONST64(0x53535153a202a6f1), +CONST64(0xdcdc57dcae8ba572), CONST64(0x0b0b2c0b58271653), CONST64(0x9d9d4e9d9cd32701), CONST64(0x6c6cad6c47c1d82b), +CONST64(0x3131c43195f562a4), CONST64(0x7474cd7487b9e8f3), CONST64(0xf6f6fff6e309f115), CONST64(0x464605460a438c4c), +CONST64(0xacac8aac092645a5), CONST64(0x89891e893c970fb5), CONST64(0x14145014a04428b4), CONST64(0xe1e1a3e15b42dfba), +CONST64(0x16165816b04e2ca6), CONST64(0x3a3ae83acdd274f7), CONST64(0x6969b9696fd0d206), CONST64(0x09092409482d1241), +CONST64(0x7070dd70a7ade0d7), CONST64(0xb6b6e2b6d954716f), CONST64(0xd0d067d0ceb7bd1e), CONST64(0xeded93ed3b7ec7d6), +CONST64(0xcccc17cc2edb85e2), CONST64(0x424215422a578468), CONST64(0x98985a98b4c22d2c), CONST64(0xa4a4aaa4490e55ed), +CONST64(0x2828a0285d885075), CONST64(0x5c5c6d5cda31b886), CONST64(0xf8f8c7f8933fed6b), CONST64(0x8686228644a411c2) +}; + +#ifdef LTC_SMALL_CODE + +#define SB0(x) sbox0[x] +#define SB1(x) ROR64c(sbox0[x], 8) +#define SB2(x) ROR64c(sbox0[x], 16) +#define SB3(x) ROR64c(sbox0[x], 24) +#define SB4(x) ROR64c(sbox0[x], 32) +#define SB5(x) ROR64c(sbox0[x], 40) +#define SB6(x) ROR64c(sbox0[x], 48) +#define SB7(x) ROR64c(sbox0[x], 56) + +#else + +#define SB0(x) sbox0[x] +#define SB1(x) sbox1[x] +#define SB2(x) sbox2[x] +#define SB3(x) sbox3[x] +#define SB4(x) sbox4[x] +#define SB5(x) sbox5[x] +#define SB6(x) sbox6[x] +#define SB7(x) sbox7[x] + + +static const ulong64 sbox1[] = { +CONST64(0xd818186018c07830), CONST64(0x2623238c2305af46), CONST64(0xb8c6c63fc67ef991), CONST64(0xfbe8e887e8136fcd), +CONST64(0xcb878726874ca113), CONST64(0x11b8b8dab8a9626d), CONST64(0x0901010401080502), CONST64(0x0d4f4f214f426e9e), +CONST64(0x9b3636d836adee6c), CONST64(0xffa6a6a2a6590451), CONST64(0x0cd2d26fd2debdb9), CONST64(0x0ef5f5f3f5fb06f7), +CONST64(0x967979f979ef80f2), CONST64(0x306f6fa16f5fcede), CONST64(0x6d91917e91fcef3f), CONST64(0xf852525552aa07a4), +CONST64(0x4760609d6027fdc0), CONST64(0x35bcbccabc897665), CONST64(0x379b9b569baccd2b), CONST64(0x8a8e8e028e048c01), +CONST64(0xd2a3a3b6a371155b), CONST64(0x6c0c0c300c603c18), CONST64(0x847b7bf17bff8af6), CONST64(0x803535d435b5e16a), +CONST64(0xf51d1d741de8693a), CONST64(0xb3e0e0a7e05347dd), CONST64(0x21d7d77bd7f6acb3), CONST64(0x9cc2c22fc25eed99), +CONST64(0x432e2eb82e6d965c), CONST64(0x294b4b314b627a96), CONST64(0x5dfefedffea321e1), CONST64(0xd5575741578216ae), +CONST64(0xbd15155415a8412a), CONST64(0xe87777c1779fb6ee), CONST64(0x923737dc37a5eb6e), CONST64(0x9ee5e5b3e57b56d7), +CONST64(0x139f9f469f8cd923), CONST64(0x23f0f0e7f0d317fd), CONST64(0x204a4a354a6a7f94), CONST64(0x44dada4fda9e95a9), +CONST64(0xa258587d58fa25b0), CONST64(0xcfc9c903c906ca8f), CONST64(0x7c2929a429558d52), CONST64(0x5a0a0a280a502214), +CONST64(0x50b1b1feb1e14f7f), CONST64(0xc9a0a0baa0691a5d), CONST64(0x146b6bb16b7fdad6), CONST64(0xd985852e855cab17), +CONST64(0x3cbdbdcebd817367), CONST64(0x8f5d5d695dd234ba), CONST64(0x9010104010805020), CONST64(0x07f4f4f7f4f303f5), +CONST64(0xddcbcb0bcb16c08b), CONST64(0xd33e3ef83eedc67c), CONST64(0x2d0505140528110a), CONST64(0x78676781671fe6ce), +CONST64(0x97e4e4b7e47353d5), CONST64(0x0227279c2725bb4e), CONST64(0x7341411941325882), CONST64(0xa78b8b168b2c9d0b), +CONST64(0xf6a7a7a6a7510153), CONST64(0xb27d7de97dcf94fa), CONST64(0x4995956e95dcfb37), CONST64(0x56d8d847d88e9fad), +CONST64(0x70fbfbcbfb8b30eb), CONST64(0xcdeeee9fee2371c1), CONST64(0xbb7c7ced7cc791f8), CONST64(0x716666856617e3cc), +CONST64(0x7bdddd53dda68ea7), CONST64(0xaf17175c17b84b2e), CONST64(0x454747014702468e), CONST64(0x1a9e9e429e84dc21), +CONST64(0xd4caca0fca1ec589), CONST64(0x582d2db42d75995a), CONST64(0x2ebfbfc6bf917963), CONST64(0x3f07071c07381b0e), +CONST64(0xacadad8ead012347), CONST64(0xb05a5a755aea2fb4), CONST64(0xef838336836cb51b), CONST64(0xb63333cc3385ff66), +CONST64(0x5c636391633ff2c6), CONST64(0x1202020802100a04), CONST64(0x93aaaa92aa393849), CONST64(0xde7171d971afa8e2), +CONST64(0xc6c8c807c80ecf8d), CONST64(0xd119196419c87d32), CONST64(0x3b49493949727092), CONST64(0x5fd9d943d9869aaf), +CONST64(0x31f2f2eff2c31df9), CONST64(0xa8e3e3abe34b48db), CONST64(0xb95b5b715be22ab6), CONST64(0xbc88881a8834920d), +CONST64(0x3e9a9a529aa4c829), CONST64(0x0b262698262dbe4c), CONST64(0xbf3232c8328dfa64), CONST64(0x59b0b0fab0e94a7d), +CONST64(0xf2e9e983e91b6acf), CONST64(0x770f0f3c0f78331e), CONST64(0x33d5d573d5e6a6b7), CONST64(0xf480803a8074ba1d), +CONST64(0x27bebec2be997c61), CONST64(0xebcdcd13cd26de87), CONST64(0x893434d034bde468), CONST64(0x3248483d487a7590), +CONST64(0x54ffffdbffab24e3), CONST64(0x8d7a7af57af78ff4), CONST64(0x6490907a90f4ea3d), CONST64(0x9d5f5f615fc23ebe), +CONST64(0x3d202080201da040), CONST64(0x0f6868bd6867d5d0), CONST64(0xca1a1a681ad07234), CONST64(0xb7aeae82ae192c41), +CONST64(0x7db4b4eab4c95e75), CONST64(0xce54544d549a19a8), CONST64(0x7f93937693ece53b), CONST64(0x2f222288220daa44), +CONST64(0x6364648d6407e9c8), CONST64(0x2af1f1e3f1db12ff), CONST64(0xcc7373d173bfa2e6), CONST64(0x8212124812905a24), +CONST64(0x7a40401d403a5d80), CONST64(0x4808082008402810), CONST64(0x95c3c32bc356e89b), CONST64(0xdfecec97ec337bc5), +CONST64(0x4ddbdb4bdb9690ab), CONST64(0xc0a1a1bea1611f5f), CONST64(0x918d8d0e8d1c8307), CONST64(0xc83d3df43df5c97a), +CONST64(0x5b97976697ccf133), CONST64(0x0000000000000000), CONST64(0xf9cfcf1bcf36d483), CONST64(0x6e2b2bac2b458756), +CONST64(0xe17676c57697b3ec), CONST64(0xe68282328264b019), CONST64(0x28d6d67fd6fea9b1), CONST64(0xc31b1b6c1bd87736), +CONST64(0x74b5b5eeb5c15b77), CONST64(0xbeafaf86af112943), CONST64(0x1d6a6ab56a77dfd4), CONST64(0xea50505d50ba0da0), +CONST64(0x5745450945124c8a), CONST64(0x38f3f3ebf3cb18fb), CONST64(0xad3030c0309df060), CONST64(0xc4efef9bef2b74c3), +CONST64(0xda3f3ffc3fe5c37e), CONST64(0xc755554955921caa), CONST64(0xdba2a2b2a2791059), CONST64(0xe9eaea8fea0365c9), +CONST64(0x6a656589650fecca), CONST64(0x03babad2bab96869), CONST64(0x4a2f2fbc2f65935e), CONST64(0x8ec0c027c04ee79d), +CONST64(0x60dede5fdebe81a1), CONST64(0xfc1c1c701ce06c38), CONST64(0x46fdfdd3fdbb2ee7), CONST64(0x1f4d4d294d52649a), +CONST64(0x7692927292e4e039), CONST64(0xfa7575c9758fbcea), CONST64(0x3606061806301e0c), CONST64(0xae8a8a128a249809), +CONST64(0x4bb2b2f2b2f94079), CONST64(0x85e6e6bfe66359d1), CONST64(0x7e0e0e380e70361c), CONST64(0xe71f1f7c1ff8633e), +CONST64(0x556262956237f7c4), CONST64(0x3ad4d477d4eea3b5), CONST64(0x81a8a89aa829324d), CONST64(0x5296966296c4f431), +CONST64(0x62f9f9c3f99b3aef), CONST64(0xa3c5c533c566f697), CONST64(0x102525942535b14a), CONST64(0xab59597959f220b2), +CONST64(0xd084842a8454ae15), CONST64(0xc57272d572b7a7e4), CONST64(0xec3939e439d5dd72), CONST64(0x164c4c2d4c5a6198), +CONST64(0x945e5e655eca3bbc), CONST64(0x9f7878fd78e785f0), CONST64(0xe53838e038ddd870), CONST64(0x988c8c0a8c148605), +CONST64(0x17d1d163d1c6b2bf), CONST64(0xe4a5a5aea5410b57), CONST64(0xa1e2e2afe2434dd9), CONST64(0x4e616199612ff8c2), +CONST64(0x42b3b3f6b3f1457b), CONST64(0x342121842115a542), CONST64(0x089c9c4a9c94d625), CONST64(0xee1e1e781ef0663c), +CONST64(0x6143431143225286), CONST64(0xb1c7c73bc776fc93), CONST64(0x4ffcfcd7fcb32be5), CONST64(0x2404041004201408), +CONST64(0xe351515951b208a2), CONST64(0x2599995e99bcc72f), CONST64(0x226d6da96d4fc4da), CONST64(0x650d0d340d68391a), +CONST64(0x79fafacffa8335e9), CONST64(0x69dfdf5bdfb684a3), CONST64(0xa97e7ee57ed79bfc), CONST64(0x19242490243db448), +CONST64(0xfe3b3bec3bc5d776), CONST64(0x9aabab96ab313d4b), CONST64(0xf0cece1fce3ed181), CONST64(0x9911114411885522), +CONST64(0x838f8f068f0c8903), CONST64(0x044e4e254e4a6b9c), CONST64(0x66b7b7e6b7d15173), CONST64(0xe0ebeb8beb0b60cb), +CONST64(0xc13c3cf03cfdcc78), CONST64(0xfd81813e817cbf1f), CONST64(0x4094946a94d4fe35), CONST64(0x1cf7f7fbf7eb0cf3), +CONST64(0x18b9b9deb9a1676f), CONST64(0x8b13134c13985f26), CONST64(0x512c2cb02c7d9c58), CONST64(0x05d3d36bd3d6b8bb), +CONST64(0x8ce7e7bbe76b5cd3), CONST64(0x396e6ea56e57cbdc), CONST64(0xaac4c437c46ef395), CONST64(0x1b03030c03180f06), +CONST64(0xdc565645568a13ac), CONST64(0x5e44440d441a4988), CONST64(0xa07f7fe17fdf9efe), CONST64(0x88a9a99ea921374f), +CONST64(0x672a2aa82a4d8254), CONST64(0x0abbbbd6bbb16d6b), CONST64(0x87c1c123c146e29f), CONST64(0xf153535153a202a6), +CONST64(0x72dcdc57dcae8ba5), CONST64(0x530b0b2c0b582716), CONST64(0x019d9d4e9d9cd327), CONST64(0x2b6c6cad6c47c1d8), +CONST64(0xa43131c43195f562), CONST64(0xf37474cd7487b9e8), CONST64(0x15f6f6fff6e309f1), CONST64(0x4c464605460a438c), +CONST64(0xa5acac8aac092645), CONST64(0xb589891e893c970f), CONST64(0xb414145014a04428), CONST64(0xbae1e1a3e15b42df), +CONST64(0xa616165816b04e2c), CONST64(0xf73a3ae83acdd274), CONST64(0x066969b9696fd0d2), CONST64(0x4109092409482d12), +CONST64(0xd77070dd70a7ade0), CONST64(0x6fb6b6e2b6d95471), CONST64(0x1ed0d067d0ceb7bd), CONST64(0xd6eded93ed3b7ec7), +CONST64(0xe2cccc17cc2edb85), CONST64(0x68424215422a5784), CONST64(0x2c98985a98b4c22d), CONST64(0xeda4a4aaa4490e55), +CONST64(0x752828a0285d8850), CONST64(0x865c5c6d5cda31b8), CONST64(0x6bf8f8c7f8933fed), CONST64(0xc28686228644a411) +}; + +static const ulong64 sbox2[] = { +CONST64(0x30d818186018c078), CONST64(0x462623238c2305af), CONST64(0x91b8c6c63fc67ef9), CONST64(0xcdfbe8e887e8136f), +CONST64(0x13cb878726874ca1), CONST64(0x6d11b8b8dab8a962), CONST64(0x0209010104010805), CONST64(0x9e0d4f4f214f426e), +CONST64(0x6c9b3636d836adee), CONST64(0x51ffa6a6a2a65904), CONST64(0xb90cd2d26fd2debd), CONST64(0xf70ef5f5f3f5fb06), +CONST64(0xf2967979f979ef80), CONST64(0xde306f6fa16f5fce), CONST64(0x3f6d91917e91fcef), CONST64(0xa4f852525552aa07), +CONST64(0xc04760609d6027fd), CONST64(0x6535bcbccabc8976), CONST64(0x2b379b9b569baccd), CONST64(0x018a8e8e028e048c), +CONST64(0x5bd2a3a3b6a37115), CONST64(0x186c0c0c300c603c), CONST64(0xf6847b7bf17bff8a), CONST64(0x6a803535d435b5e1), +CONST64(0x3af51d1d741de869), CONST64(0xddb3e0e0a7e05347), CONST64(0xb321d7d77bd7f6ac), CONST64(0x999cc2c22fc25eed), +CONST64(0x5c432e2eb82e6d96), CONST64(0x96294b4b314b627a), CONST64(0xe15dfefedffea321), CONST64(0xaed5575741578216), +CONST64(0x2abd15155415a841), CONST64(0xeee87777c1779fb6), CONST64(0x6e923737dc37a5eb), CONST64(0xd79ee5e5b3e57b56), +CONST64(0x23139f9f469f8cd9), CONST64(0xfd23f0f0e7f0d317), CONST64(0x94204a4a354a6a7f), CONST64(0xa944dada4fda9e95), +CONST64(0xb0a258587d58fa25), CONST64(0x8fcfc9c903c906ca), CONST64(0x527c2929a429558d), CONST64(0x145a0a0a280a5022), +CONST64(0x7f50b1b1feb1e14f), CONST64(0x5dc9a0a0baa0691a), CONST64(0xd6146b6bb16b7fda), CONST64(0x17d985852e855cab), +CONST64(0x673cbdbdcebd8173), CONST64(0xba8f5d5d695dd234), CONST64(0x2090101040108050), CONST64(0xf507f4f4f7f4f303), +CONST64(0x8bddcbcb0bcb16c0), CONST64(0x7cd33e3ef83eedc6), CONST64(0x0a2d050514052811), CONST64(0xce78676781671fe6), +CONST64(0xd597e4e4b7e47353), CONST64(0x4e0227279c2725bb), CONST64(0x8273414119413258), CONST64(0x0ba78b8b168b2c9d), +CONST64(0x53f6a7a7a6a75101), CONST64(0xfab27d7de97dcf94), CONST64(0x374995956e95dcfb), CONST64(0xad56d8d847d88e9f), +CONST64(0xeb70fbfbcbfb8b30), CONST64(0xc1cdeeee9fee2371), CONST64(0xf8bb7c7ced7cc791), CONST64(0xcc716666856617e3), +CONST64(0xa77bdddd53dda68e), CONST64(0x2eaf17175c17b84b), CONST64(0x8e45474701470246), CONST64(0x211a9e9e429e84dc), +CONST64(0x89d4caca0fca1ec5), CONST64(0x5a582d2db42d7599), CONST64(0x632ebfbfc6bf9179), CONST64(0x0e3f07071c07381b), +CONST64(0x47acadad8ead0123), CONST64(0xb4b05a5a755aea2f), CONST64(0x1bef838336836cb5), CONST64(0x66b63333cc3385ff), +CONST64(0xc65c636391633ff2), CONST64(0x041202020802100a), CONST64(0x4993aaaa92aa3938), CONST64(0xe2de7171d971afa8), +CONST64(0x8dc6c8c807c80ecf), CONST64(0x32d119196419c87d), CONST64(0x923b494939497270), CONST64(0xaf5fd9d943d9869a), +CONST64(0xf931f2f2eff2c31d), CONST64(0xdba8e3e3abe34b48), CONST64(0xb6b95b5b715be22a), CONST64(0x0dbc88881a883492), +CONST64(0x293e9a9a529aa4c8), CONST64(0x4c0b262698262dbe), CONST64(0x64bf3232c8328dfa), CONST64(0x7d59b0b0fab0e94a), +CONST64(0xcff2e9e983e91b6a), CONST64(0x1e770f0f3c0f7833), CONST64(0xb733d5d573d5e6a6), CONST64(0x1df480803a8074ba), +CONST64(0x6127bebec2be997c), CONST64(0x87ebcdcd13cd26de), CONST64(0x68893434d034bde4), CONST64(0x903248483d487a75), +CONST64(0xe354ffffdbffab24), CONST64(0xf48d7a7af57af78f), CONST64(0x3d6490907a90f4ea), CONST64(0xbe9d5f5f615fc23e), +CONST64(0x403d202080201da0), CONST64(0xd00f6868bd6867d5), CONST64(0x34ca1a1a681ad072), CONST64(0x41b7aeae82ae192c), +CONST64(0x757db4b4eab4c95e), CONST64(0xa8ce54544d549a19), CONST64(0x3b7f93937693ece5), CONST64(0x442f222288220daa), +CONST64(0xc86364648d6407e9), CONST64(0xff2af1f1e3f1db12), CONST64(0xe6cc7373d173bfa2), CONST64(0x248212124812905a), +CONST64(0x807a40401d403a5d), CONST64(0x1048080820084028), CONST64(0x9b95c3c32bc356e8), CONST64(0xc5dfecec97ec337b), +CONST64(0xab4ddbdb4bdb9690), CONST64(0x5fc0a1a1bea1611f), CONST64(0x07918d8d0e8d1c83), CONST64(0x7ac83d3df43df5c9), +CONST64(0x335b97976697ccf1), CONST64(0x0000000000000000), CONST64(0x83f9cfcf1bcf36d4), CONST64(0x566e2b2bac2b4587), +CONST64(0xece17676c57697b3), CONST64(0x19e68282328264b0), CONST64(0xb128d6d67fd6fea9), CONST64(0x36c31b1b6c1bd877), +CONST64(0x7774b5b5eeb5c15b), CONST64(0x43beafaf86af1129), CONST64(0xd41d6a6ab56a77df), CONST64(0xa0ea50505d50ba0d), +CONST64(0x8a5745450945124c), CONST64(0xfb38f3f3ebf3cb18), CONST64(0x60ad3030c0309df0), CONST64(0xc3c4efef9bef2b74), +CONST64(0x7eda3f3ffc3fe5c3), CONST64(0xaac755554955921c), CONST64(0x59dba2a2b2a27910), CONST64(0xc9e9eaea8fea0365), +CONST64(0xca6a656589650fec), CONST64(0x6903babad2bab968), CONST64(0x5e4a2f2fbc2f6593), CONST64(0x9d8ec0c027c04ee7), +CONST64(0xa160dede5fdebe81), CONST64(0x38fc1c1c701ce06c), CONST64(0xe746fdfdd3fdbb2e), CONST64(0x9a1f4d4d294d5264), +CONST64(0x397692927292e4e0), CONST64(0xeafa7575c9758fbc), CONST64(0x0c3606061806301e), CONST64(0x09ae8a8a128a2498), +CONST64(0x794bb2b2f2b2f940), CONST64(0xd185e6e6bfe66359), CONST64(0x1c7e0e0e380e7036), CONST64(0x3ee71f1f7c1ff863), +CONST64(0xc4556262956237f7), CONST64(0xb53ad4d477d4eea3), CONST64(0x4d81a8a89aa82932), CONST64(0x315296966296c4f4), +CONST64(0xef62f9f9c3f99b3a), CONST64(0x97a3c5c533c566f6), CONST64(0x4a102525942535b1), CONST64(0xb2ab59597959f220), +CONST64(0x15d084842a8454ae), CONST64(0xe4c57272d572b7a7), CONST64(0x72ec3939e439d5dd), CONST64(0x98164c4c2d4c5a61), +CONST64(0xbc945e5e655eca3b), CONST64(0xf09f7878fd78e785), CONST64(0x70e53838e038ddd8), CONST64(0x05988c8c0a8c1486), +CONST64(0xbf17d1d163d1c6b2), CONST64(0x57e4a5a5aea5410b), CONST64(0xd9a1e2e2afe2434d), CONST64(0xc24e616199612ff8), +CONST64(0x7b42b3b3f6b3f145), CONST64(0x42342121842115a5), CONST64(0x25089c9c4a9c94d6), CONST64(0x3cee1e1e781ef066), +CONST64(0x8661434311432252), CONST64(0x93b1c7c73bc776fc), CONST64(0xe54ffcfcd7fcb32b), CONST64(0x0824040410042014), +CONST64(0xa2e351515951b208), CONST64(0x2f2599995e99bcc7), CONST64(0xda226d6da96d4fc4), CONST64(0x1a650d0d340d6839), +CONST64(0xe979fafacffa8335), CONST64(0xa369dfdf5bdfb684), CONST64(0xfca97e7ee57ed79b), CONST64(0x4819242490243db4), +CONST64(0x76fe3b3bec3bc5d7), CONST64(0x4b9aabab96ab313d), CONST64(0x81f0cece1fce3ed1), CONST64(0x2299111144118855), +CONST64(0x03838f8f068f0c89), CONST64(0x9c044e4e254e4a6b), CONST64(0x7366b7b7e6b7d151), CONST64(0xcbe0ebeb8beb0b60), +CONST64(0x78c13c3cf03cfdcc), CONST64(0x1ffd81813e817cbf), CONST64(0x354094946a94d4fe), CONST64(0xf31cf7f7fbf7eb0c), +CONST64(0x6f18b9b9deb9a167), CONST64(0x268b13134c13985f), CONST64(0x58512c2cb02c7d9c), CONST64(0xbb05d3d36bd3d6b8), +CONST64(0xd38ce7e7bbe76b5c), CONST64(0xdc396e6ea56e57cb), CONST64(0x95aac4c437c46ef3), CONST64(0x061b03030c03180f), +CONST64(0xacdc565645568a13), CONST64(0x885e44440d441a49), CONST64(0xfea07f7fe17fdf9e), CONST64(0x4f88a9a99ea92137), +CONST64(0x54672a2aa82a4d82), CONST64(0x6b0abbbbd6bbb16d), CONST64(0x9f87c1c123c146e2), CONST64(0xa6f153535153a202), +CONST64(0xa572dcdc57dcae8b), CONST64(0x16530b0b2c0b5827), CONST64(0x27019d9d4e9d9cd3), CONST64(0xd82b6c6cad6c47c1), +CONST64(0x62a43131c43195f5), CONST64(0xe8f37474cd7487b9), CONST64(0xf115f6f6fff6e309), CONST64(0x8c4c464605460a43), +CONST64(0x45a5acac8aac0926), CONST64(0x0fb589891e893c97), CONST64(0x28b414145014a044), CONST64(0xdfbae1e1a3e15b42), +CONST64(0x2ca616165816b04e), CONST64(0x74f73a3ae83acdd2), CONST64(0xd2066969b9696fd0), CONST64(0x124109092409482d), +CONST64(0xe0d77070dd70a7ad), CONST64(0x716fb6b6e2b6d954), CONST64(0xbd1ed0d067d0ceb7), CONST64(0xc7d6eded93ed3b7e), +CONST64(0x85e2cccc17cc2edb), CONST64(0x8468424215422a57), CONST64(0x2d2c98985a98b4c2), CONST64(0x55eda4a4aaa4490e), +CONST64(0x50752828a0285d88), CONST64(0xb8865c5c6d5cda31), CONST64(0xed6bf8f8c7f8933f), CONST64(0x11c28686228644a4) +}; + +static const ulong64 sbox3[] = { +CONST64(0x7830d818186018c0), CONST64(0xaf462623238c2305), CONST64(0xf991b8c6c63fc67e), CONST64(0x6fcdfbe8e887e813), +CONST64(0xa113cb878726874c), CONST64(0x626d11b8b8dab8a9), CONST64(0x0502090101040108), CONST64(0x6e9e0d4f4f214f42), +CONST64(0xee6c9b3636d836ad), CONST64(0x0451ffa6a6a2a659), CONST64(0xbdb90cd2d26fd2de), CONST64(0x06f70ef5f5f3f5fb), +CONST64(0x80f2967979f979ef), CONST64(0xcede306f6fa16f5f), CONST64(0xef3f6d91917e91fc), CONST64(0x07a4f852525552aa), +CONST64(0xfdc04760609d6027), CONST64(0x766535bcbccabc89), CONST64(0xcd2b379b9b569bac), CONST64(0x8c018a8e8e028e04), +CONST64(0x155bd2a3a3b6a371), CONST64(0x3c186c0c0c300c60), CONST64(0x8af6847b7bf17bff), CONST64(0xe16a803535d435b5), +CONST64(0x693af51d1d741de8), CONST64(0x47ddb3e0e0a7e053), CONST64(0xacb321d7d77bd7f6), CONST64(0xed999cc2c22fc25e), +CONST64(0x965c432e2eb82e6d), CONST64(0x7a96294b4b314b62), CONST64(0x21e15dfefedffea3), CONST64(0x16aed55757415782), +CONST64(0x412abd15155415a8), CONST64(0xb6eee87777c1779f), CONST64(0xeb6e923737dc37a5), CONST64(0x56d79ee5e5b3e57b), +CONST64(0xd923139f9f469f8c), CONST64(0x17fd23f0f0e7f0d3), CONST64(0x7f94204a4a354a6a), CONST64(0x95a944dada4fda9e), +CONST64(0x25b0a258587d58fa), CONST64(0xca8fcfc9c903c906), CONST64(0x8d527c2929a42955), CONST64(0x22145a0a0a280a50), +CONST64(0x4f7f50b1b1feb1e1), CONST64(0x1a5dc9a0a0baa069), CONST64(0xdad6146b6bb16b7f), CONST64(0xab17d985852e855c), +CONST64(0x73673cbdbdcebd81), CONST64(0x34ba8f5d5d695dd2), CONST64(0x5020901010401080), CONST64(0x03f507f4f4f7f4f3), +CONST64(0xc08bddcbcb0bcb16), CONST64(0xc67cd33e3ef83eed), CONST64(0x110a2d0505140528), CONST64(0xe6ce78676781671f), +CONST64(0x53d597e4e4b7e473), CONST64(0xbb4e0227279c2725), CONST64(0x5882734141194132), CONST64(0x9d0ba78b8b168b2c), +CONST64(0x0153f6a7a7a6a751), CONST64(0x94fab27d7de97dcf), CONST64(0xfb374995956e95dc), CONST64(0x9fad56d8d847d88e), +CONST64(0x30eb70fbfbcbfb8b), CONST64(0x71c1cdeeee9fee23), CONST64(0x91f8bb7c7ced7cc7), CONST64(0xe3cc716666856617), +CONST64(0x8ea77bdddd53dda6), CONST64(0x4b2eaf17175c17b8), CONST64(0x468e454747014702), CONST64(0xdc211a9e9e429e84), +CONST64(0xc589d4caca0fca1e), CONST64(0x995a582d2db42d75), CONST64(0x79632ebfbfc6bf91), CONST64(0x1b0e3f07071c0738), +CONST64(0x2347acadad8ead01), CONST64(0x2fb4b05a5a755aea), CONST64(0xb51bef838336836c), CONST64(0xff66b63333cc3385), +CONST64(0xf2c65c636391633f), CONST64(0x0a04120202080210), CONST64(0x384993aaaa92aa39), CONST64(0xa8e2de7171d971af), +CONST64(0xcf8dc6c8c807c80e), CONST64(0x7d32d119196419c8), CONST64(0x70923b4949394972), CONST64(0x9aaf5fd9d943d986), +CONST64(0x1df931f2f2eff2c3), CONST64(0x48dba8e3e3abe34b), CONST64(0x2ab6b95b5b715be2), CONST64(0x920dbc88881a8834), +CONST64(0xc8293e9a9a529aa4), CONST64(0xbe4c0b262698262d), CONST64(0xfa64bf3232c8328d), CONST64(0x4a7d59b0b0fab0e9), +CONST64(0x6acff2e9e983e91b), CONST64(0x331e770f0f3c0f78), CONST64(0xa6b733d5d573d5e6), CONST64(0xba1df480803a8074), +CONST64(0x7c6127bebec2be99), CONST64(0xde87ebcdcd13cd26), CONST64(0xe468893434d034bd), CONST64(0x75903248483d487a), +CONST64(0x24e354ffffdbffab), CONST64(0x8ff48d7a7af57af7), CONST64(0xea3d6490907a90f4), CONST64(0x3ebe9d5f5f615fc2), +CONST64(0xa0403d202080201d), CONST64(0xd5d00f6868bd6867), CONST64(0x7234ca1a1a681ad0), CONST64(0x2c41b7aeae82ae19), +CONST64(0x5e757db4b4eab4c9), CONST64(0x19a8ce54544d549a), CONST64(0xe53b7f93937693ec), CONST64(0xaa442f222288220d), +CONST64(0xe9c86364648d6407), CONST64(0x12ff2af1f1e3f1db), CONST64(0xa2e6cc7373d173bf), CONST64(0x5a24821212481290), +CONST64(0x5d807a40401d403a), CONST64(0x2810480808200840), CONST64(0xe89b95c3c32bc356), CONST64(0x7bc5dfecec97ec33), +CONST64(0x90ab4ddbdb4bdb96), CONST64(0x1f5fc0a1a1bea161), CONST64(0x8307918d8d0e8d1c), CONST64(0xc97ac83d3df43df5), +CONST64(0xf1335b97976697cc), CONST64(0x0000000000000000), CONST64(0xd483f9cfcf1bcf36), CONST64(0x87566e2b2bac2b45), +CONST64(0xb3ece17676c57697), CONST64(0xb019e68282328264), CONST64(0xa9b128d6d67fd6fe), CONST64(0x7736c31b1b6c1bd8), +CONST64(0x5b7774b5b5eeb5c1), CONST64(0x2943beafaf86af11), CONST64(0xdfd41d6a6ab56a77), CONST64(0x0da0ea50505d50ba), +CONST64(0x4c8a574545094512), CONST64(0x18fb38f3f3ebf3cb), CONST64(0xf060ad3030c0309d), CONST64(0x74c3c4efef9bef2b), +CONST64(0xc37eda3f3ffc3fe5), CONST64(0x1caac75555495592), CONST64(0x1059dba2a2b2a279), CONST64(0x65c9e9eaea8fea03), +CONST64(0xecca6a656589650f), CONST64(0x686903babad2bab9), CONST64(0x935e4a2f2fbc2f65), CONST64(0xe79d8ec0c027c04e), +CONST64(0x81a160dede5fdebe), CONST64(0x6c38fc1c1c701ce0), CONST64(0x2ee746fdfdd3fdbb), CONST64(0x649a1f4d4d294d52), +CONST64(0xe0397692927292e4), CONST64(0xbceafa7575c9758f), CONST64(0x1e0c360606180630), CONST64(0x9809ae8a8a128a24), +CONST64(0x40794bb2b2f2b2f9), CONST64(0x59d185e6e6bfe663), CONST64(0x361c7e0e0e380e70), CONST64(0x633ee71f1f7c1ff8), +CONST64(0xf7c4556262956237), CONST64(0xa3b53ad4d477d4ee), CONST64(0x324d81a8a89aa829), CONST64(0xf4315296966296c4), +CONST64(0x3aef62f9f9c3f99b), CONST64(0xf697a3c5c533c566), CONST64(0xb14a102525942535), CONST64(0x20b2ab59597959f2), +CONST64(0xae15d084842a8454), CONST64(0xa7e4c57272d572b7), CONST64(0xdd72ec3939e439d5), CONST64(0x6198164c4c2d4c5a), +CONST64(0x3bbc945e5e655eca), CONST64(0x85f09f7878fd78e7), CONST64(0xd870e53838e038dd), CONST64(0x8605988c8c0a8c14), +CONST64(0xb2bf17d1d163d1c6), CONST64(0x0b57e4a5a5aea541), CONST64(0x4dd9a1e2e2afe243), CONST64(0xf8c24e616199612f), +CONST64(0x457b42b3b3f6b3f1), CONST64(0xa542342121842115), CONST64(0xd625089c9c4a9c94), CONST64(0x663cee1e1e781ef0), +CONST64(0x5286614343114322), CONST64(0xfc93b1c7c73bc776), CONST64(0x2be54ffcfcd7fcb3), CONST64(0x1408240404100420), +CONST64(0x08a2e351515951b2), CONST64(0xc72f2599995e99bc), CONST64(0xc4da226d6da96d4f), CONST64(0x391a650d0d340d68), +CONST64(0x35e979fafacffa83), CONST64(0x84a369dfdf5bdfb6), CONST64(0x9bfca97e7ee57ed7), CONST64(0xb44819242490243d), +CONST64(0xd776fe3b3bec3bc5), CONST64(0x3d4b9aabab96ab31), CONST64(0xd181f0cece1fce3e), CONST64(0x5522991111441188), +CONST64(0x8903838f8f068f0c), CONST64(0x6b9c044e4e254e4a), CONST64(0x517366b7b7e6b7d1), CONST64(0x60cbe0ebeb8beb0b), +CONST64(0xcc78c13c3cf03cfd), CONST64(0xbf1ffd81813e817c), CONST64(0xfe354094946a94d4), CONST64(0x0cf31cf7f7fbf7eb), +CONST64(0x676f18b9b9deb9a1), CONST64(0x5f268b13134c1398), CONST64(0x9c58512c2cb02c7d), CONST64(0xb8bb05d3d36bd3d6), +CONST64(0x5cd38ce7e7bbe76b), CONST64(0xcbdc396e6ea56e57), CONST64(0xf395aac4c437c46e), CONST64(0x0f061b03030c0318), +CONST64(0x13acdc565645568a), CONST64(0x49885e44440d441a), CONST64(0x9efea07f7fe17fdf), CONST64(0x374f88a9a99ea921), +CONST64(0x8254672a2aa82a4d), CONST64(0x6d6b0abbbbd6bbb1), CONST64(0xe29f87c1c123c146), CONST64(0x02a6f153535153a2), +CONST64(0x8ba572dcdc57dcae), CONST64(0x2716530b0b2c0b58), CONST64(0xd327019d9d4e9d9c), CONST64(0xc1d82b6c6cad6c47), +CONST64(0xf562a43131c43195), CONST64(0xb9e8f37474cd7487), CONST64(0x09f115f6f6fff6e3), CONST64(0x438c4c464605460a), +CONST64(0x2645a5acac8aac09), CONST64(0x970fb589891e893c), CONST64(0x4428b414145014a0), CONST64(0x42dfbae1e1a3e15b), +CONST64(0x4e2ca616165816b0), CONST64(0xd274f73a3ae83acd), CONST64(0xd0d2066969b9696f), CONST64(0x2d12410909240948), +CONST64(0xade0d77070dd70a7), CONST64(0x54716fb6b6e2b6d9), CONST64(0xb7bd1ed0d067d0ce), CONST64(0x7ec7d6eded93ed3b), +CONST64(0xdb85e2cccc17cc2e), CONST64(0x578468424215422a), CONST64(0xc22d2c98985a98b4), CONST64(0x0e55eda4a4aaa449), +CONST64(0x8850752828a0285d), CONST64(0x31b8865c5c6d5cda), CONST64(0x3fed6bf8f8c7f893), CONST64(0xa411c28686228644) +}; + +static const ulong64 sbox4[] = { +CONST64(0xc07830d818186018), CONST64(0x05af462623238c23), CONST64(0x7ef991b8c6c63fc6), CONST64(0x136fcdfbe8e887e8), +CONST64(0x4ca113cb87872687), CONST64(0xa9626d11b8b8dab8), CONST64(0x0805020901010401), CONST64(0x426e9e0d4f4f214f), +CONST64(0xadee6c9b3636d836), CONST64(0x590451ffa6a6a2a6), CONST64(0xdebdb90cd2d26fd2), CONST64(0xfb06f70ef5f5f3f5), +CONST64(0xef80f2967979f979), CONST64(0x5fcede306f6fa16f), CONST64(0xfcef3f6d91917e91), CONST64(0xaa07a4f852525552), +CONST64(0x27fdc04760609d60), CONST64(0x89766535bcbccabc), CONST64(0xaccd2b379b9b569b), CONST64(0x048c018a8e8e028e), +CONST64(0x71155bd2a3a3b6a3), CONST64(0x603c186c0c0c300c), CONST64(0xff8af6847b7bf17b), CONST64(0xb5e16a803535d435), +CONST64(0xe8693af51d1d741d), CONST64(0x5347ddb3e0e0a7e0), CONST64(0xf6acb321d7d77bd7), CONST64(0x5eed999cc2c22fc2), +CONST64(0x6d965c432e2eb82e), CONST64(0x627a96294b4b314b), CONST64(0xa321e15dfefedffe), CONST64(0x8216aed557574157), +CONST64(0xa8412abd15155415), CONST64(0x9fb6eee87777c177), CONST64(0xa5eb6e923737dc37), CONST64(0x7b56d79ee5e5b3e5), +CONST64(0x8cd923139f9f469f), CONST64(0xd317fd23f0f0e7f0), CONST64(0x6a7f94204a4a354a), CONST64(0x9e95a944dada4fda), +CONST64(0xfa25b0a258587d58), CONST64(0x06ca8fcfc9c903c9), CONST64(0x558d527c2929a429), CONST64(0x5022145a0a0a280a), +CONST64(0xe14f7f50b1b1feb1), CONST64(0x691a5dc9a0a0baa0), CONST64(0x7fdad6146b6bb16b), CONST64(0x5cab17d985852e85), +CONST64(0x8173673cbdbdcebd), CONST64(0xd234ba8f5d5d695d), CONST64(0x8050209010104010), CONST64(0xf303f507f4f4f7f4), +CONST64(0x16c08bddcbcb0bcb), CONST64(0xedc67cd33e3ef83e), CONST64(0x28110a2d05051405), CONST64(0x1fe6ce7867678167), +CONST64(0x7353d597e4e4b7e4), CONST64(0x25bb4e0227279c27), CONST64(0x3258827341411941), CONST64(0x2c9d0ba78b8b168b), +CONST64(0x510153f6a7a7a6a7), CONST64(0xcf94fab27d7de97d), CONST64(0xdcfb374995956e95), CONST64(0x8e9fad56d8d847d8), +CONST64(0x8b30eb70fbfbcbfb), CONST64(0x2371c1cdeeee9fee), CONST64(0xc791f8bb7c7ced7c), CONST64(0x17e3cc7166668566), +CONST64(0xa68ea77bdddd53dd), CONST64(0xb84b2eaf17175c17), CONST64(0x02468e4547470147), CONST64(0x84dc211a9e9e429e), +CONST64(0x1ec589d4caca0fca), CONST64(0x75995a582d2db42d), CONST64(0x9179632ebfbfc6bf), CONST64(0x381b0e3f07071c07), +CONST64(0x012347acadad8ead), CONST64(0xea2fb4b05a5a755a), CONST64(0x6cb51bef83833683), CONST64(0x85ff66b63333cc33), +CONST64(0x3ff2c65c63639163), CONST64(0x100a041202020802), CONST64(0x39384993aaaa92aa), CONST64(0xafa8e2de7171d971), +CONST64(0x0ecf8dc6c8c807c8), CONST64(0xc87d32d119196419), CONST64(0x7270923b49493949), CONST64(0x869aaf5fd9d943d9), +CONST64(0xc31df931f2f2eff2), CONST64(0x4b48dba8e3e3abe3), CONST64(0xe22ab6b95b5b715b), CONST64(0x34920dbc88881a88), +CONST64(0xa4c8293e9a9a529a), CONST64(0x2dbe4c0b26269826), CONST64(0x8dfa64bf3232c832), CONST64(0xe94a7d59b0b0fab0), +CONST64(0x1b6acff2e9e983e9), CONST64(0x78331e770f0f3c0f), CONST64(0xe6a6b733d5d573d5), CONST64(0x74ba1df480803a80), +CONST64(0x997c6127bebec2be), CONST64(0x26de87ebcdcd13cd), CONST64(0xbde468893434d034), CONST64(0x7a75903248483d48), +CONST64(0xab24e354ffffdbff), CONST64(0xf78ff48d7a7af57a), CONST64(0xf4ea3d6490907a90), CONST64(0xc23ebe9d5f5f615f), +CONST64(0x1da0403d20208020), CONST64(0x67d5d00f6868bd68), CONST64(0xd07234ca1a1a681a), CONST64(0x192c41b7aeae82ae), +CONST64(0xc95e757db4b4eab4), CONST64(0x9a19a8ce54544d54), CONST64(0xece53b7f93937693), CONST64(0x0daa442f22228822), +CONST64(0x07e9c86364648d64), CONST64(0xdb12ff2af1f1e3f1), CONST64(0xbfa2e6cc7373d173), CONST64(0x905a248212124812), +CONST64(0x3a5d807a40401d40), CONST64(0x4028104808082008), CONST64(0x56e89b95c3c32bc3), CONST64(0x337bc5dfecec97ec), +CONST64(0x9690ab4ddbdb4bdb), CONST64(0x611f5fc0a1a1bea1), CONST64(0x1c8307918d8d0e8d), CONST64(0xf5c97ac83d3df43d), +CONST64(0xccf1335b97976697), CONST64(0x0000000000000000), CONST64(0x36d483f9cfcf1bcf), CONST64(0x4587566e2b2bac2b), +CONST64(0x97b3ece17676c576), CONST64(0x64b019e682823282), CONST64(0xfea9b128d6d67fd6), CONST64(0xd87736c31b1b6c1b), +CONST64(0xc15b7774b5b5eeb5), CONST64(0x112943beafaf86af), CONST64(0x77dfd41d6a6ab56a), CONST64(0xba0da0ea50505d50), +CONST64(0x124c8a5745450945), CONST64(0xcb18fb38f3f3ebf3), CONST64(0x9df060ad3030c030), CONST64(0x2b74c3c4efef9bef), +CONST64(0xe5c37eda3f3ffc3f), CONST64(0x921caac755554955), CONST64(0x791059dba2a2b2a2), CONST64(0x0365c9e9eaea8fea), +CONST64(0x0fecca6a65658965), CONST64(0xb9686903babad2ba), CONST64(0x65935e4a2f2fbc2f), CONST64(0x4ee79d8ec0c027c0), +CONST64(0xbe81a160dede5fde), CONST64(0xe06c38fc1c1c701c), CONST64(0xbb2ee746fdfdd3fd), CONST64(0x52649a1f4d4d294d), +CONST64(0xe4e0397692927292), CONST64(0x8fbceafa7575c975), CONST64(0x301e0c3606061806), CONST64(0x249809ae8a8a128a), +CONST64(0xf940794bb2b2f2b2), CONST64(0x6359d185e6e6bfe6), CONST64(0x70361c7e0e0e380e), CONST64(0xf8633ee71f1f7c1f), +CONST64(0x37f7c45562629562), CONST64(0xeea3b53ad4d477d4), CONST64(0x29324d81a8a89aa8), CONST64(0xc4f4315296966296), +CONST64(0x9b3aef62f9f9c3f9), CONST64(0x66f697a3c5c533c5), CONST64(0x35b14a1025259425), CONST64(0xf220b2ab59597959), +CONST64(0x54ae15d084842a84), CONST64(0xb7a7e4c57272d572), CONST64(0xd5dd72ec3939e439), CONST64(0x5a6198164c4c2d4c), +CONST64(0xca3bbc945e5e655e), CONST64(0xe785f09f7878fd78), CONST64(0xddd870e53838e038), CONST64(0x148605988c8c0a8c), +CONST64(0xc6b2bf17d1d163d1), CONST64(0x410b57e4a5a5aea5), CONST64(0x434dd9a1e2e2afe2), CONST64(0x2ff8c24e61619961), +CONST64(0xf1457b42b3b3f6b3), CONST64(0x15a5423421218421), CONST64(0x94d625089c9c4a9c), CONST64(0xf0663cee1e1e781e), +CONST64(0x2252866143431143), CONST64(0x76fc93b1c7c73bc7), CONST64(0xb32be54ffcfcd7fc), CONST64(0x2014082404041004), +CONST64(0xb208a2e351515951), CONST64(0xbcc72f2599995e99), CONST64(0x4fc4da226d6da96d), CONST64(0x68391a650d0d340d), +CONST64(0x8335e979fafacffa), CONST64(0xb684a369dfdf5bdf), CONST64(0xd79bfca97e7ee57e), CONST64(0x3db4481924249024), +CONST64(0xc5d776fe3b3bec3b), CONST64(0x313d4b9aabab96ab), CONST64(0x3ed181f0cece1fce), CONST64(0x8855229911114411), +CONST64(0x0c8903838f8f068f), CONST64(0x4a6b9c044e4e254e), CONST64(0xd1517366b7b7e6b7), CONST64(0x0b60cbe0ebeb8beb), +CONST64(0xfdcc78c13c3cf03c), CONST64(0x7cbf1ffd81813e81), CONST64(0xd4fe354094946a94), CONST64(0xeb0cf31cf7f7fbf7), +CONST64(0xa1676f18b9b9deb9), CONST64(0x985f268b13134c13), CONST64(0x7d9c58512c2cb02c), CONST64(0xd6b8bb05d3d36bd3), +CONST64(0x6b5cd38ce7e7bbe7), CONST64(0x57cbdc396e6ea56e), CONST64(0x6ef395aac4c437c4), CONST64(0x180f061b03030c03), +CONST64(0x8a13acdc56564556), CONST64(0x1a49885e44440d44), CONST64(0xdf9efea07f7fe17f), CONST64(0x21374f88a9a99ea9), +CONST64(0x4d8254672a2aa82a), CONST64(0xb16d6b0abbbbd6bb), CONST64(0x46e29f87c1c123c1), CONST64(0xa202a6f153535153), +CONST64(0xae8ba572dcdc57dc), CONST64(0x582716530b0b2c0b), CONST64(0x9cd327019d9d4e9d), CONST64(0x47c1d82b6c6cad6c), +CONST64(0x95f562a43131c431), CONST64(0x87b9e8f37474cd74), CONST64(0xe309f115f6f6fff6), CONST64(0x0a438c4c46460546), +CONST64(0x092645a5acac8aac), CONST64(0x3c970fb589891e89), CONST64(0xa04428b414145014), CONST64(0x5b42dfbae1e1a3e1), +CONST64(0xb04e2ca616165816), CONST64(0xcdd274f73a3ae83a), CONST64(0x6fd0d2066969b969), CONST64(0x482d124109092409), +CONST64(0xa7ade0d77070dd70), CONST64(0xd954716fb6b6e2b6), CONST64(0xceb7bd1ed0d067d0), CONST64(0x3b7ec7d6eded93ed), +CONST64(0x2edb85e2cccc17cc), CONST64(0x2a57846842421542), CONST64(0xb4c22d2c98985a98), CONST64(0x490e55eda4a4aaa4), +CONST64(0x5d8850752828a028), CONST64(0xda31b8865c5c6d5c), CONST64(0x933fed6bf8f8c7f8), CONST64(0x44a411c286862286) +}; + +static const ulong64 sbox5[] = { +CONST64(0x18c07830d8181860), CONST64(0x2305af462623238c), CONST64(0xc67ef991b8c6c63f), CONST64(0xe8136fcdfbe8e887), +CONST64(0x874ca113cb878726), CONST64(0xb8a9626d11b8b8da), CONST64(0x0108050209010104), CONST64(0x4f426e9e0d4f4f21), +CONST64(0x36adee6c9b3636d8), CONST64(0xa6590451ffa6a6a2), CONST64(0xd2debdb90cd2d26f), CONST64(0xf5fb06f70ef5f5f3), +CONST64(0x79ef80f2967979f9), CONST64(0x6f5fcede306f6fa1), CONST64(0x91fcef3f6d91917e), CONST64(0x52aa07a4f8525255), +CONST64(0x6027fdc04760609d), CONST64(0xbc89766535bcbcca), CONST64(0x9baccd2b379b9b56), CONST64(0x8e048c018a8e8e02), +CONST64(0xa371155bd2a3a3b6), CONST64(0x0c603c186c0c0c30), CONST64(0x7bff8af6847b7bf1), CONST64(0x35b5e16a803535d4), +CONST64(0x1de8693af51d1d74), CONST64(0xe05347ddb3e0e0a7), CONST64(0xd7f6acb321d7d77b), CONST64(0xc25eed999cc2c22f), +CONST64(0x2e6d965c432e2eb8), CONST64(0x4b627a96294b4b31), CONST64(0xfea321e15dfefedf), CONST64(0x578216aed5575741), +CONST64(0x15a8412abd151554), CONST64(0x779fb6eee87777c1), CONST64(0x37a5eb6e923737dc), CONST64(0xe57b56d79ee5e5b3), +CONST64(0x9f8cd923139f9f46), CONST64(0xf0d317fd23f0f0e7), CONST64(0x4a6a7f94204a4a35), CONST64(0xda9e95a944dada4f), +CONST64(0x58fa25b0a258587d), CONST64(0xc906ca8fcfc9c903), CONST64(0x29558d527c2929a4), CONST64(0x0a5022145a0a0a28), +CONST64(0xb1e14f7f50b1b1fe), CONST64(0xa0691a5dc9a0a0ba), CONST64(0x6b7fdad6146b6bb1), CONST64(0x855cab17d985852e), +CONST64(0xbd8173673cbdbdce), CONST64(0x5dd234ba8f5d5d69), CONST64(0x1080502090101040), CONST64(0xf4f303f507f4f4f7), +CONST64(0xcb16c08bddcbcb0b), CONST64(0x3eedc67cd33e3ef8), CONST64(0x0528110a2d050514), CONST64(0x671fe6ce78676781), +CONST64(0xe47353d597e4e4b7), CONST64(0x2725bb4e0227279c), CONST64(0x4132588273414119), CONST64(0x8b2c9d0ba78b8b16), +CONST64(0xa7510153f6a7a7a6), CONST64(0x7dcf94fab27d7de9), CONST64(0x95dcfb374995956e), CONST64(0xd88e9fad56d8d847), +CONST64(0xfb8b30eb70fbfbcb), CONST64(0xee2371c1cdeeee9f), CONST64(0x7cc791f8bb7c7ced), CONST64(0x6617e3cc71666685), +CONST64(0xdda68ea77bdddd53), CONST64(0x17b84b2eaf17175c), CONST64(0x4702468e45474701), CONST64(0x9e84dc211a9e9e42), +CONST64(0xca1ec589d4caca0f), CONST64(0x2d75995a582d2db4), CONST64(0xbf9179632ebfbfc6), CONST64(0x07381b0e3f07071c), +CONST64(0xad012347acadad8e), CONST64(0x5aea2fb4b05a5a75), CONST64(0x836cb51bef838336), CONST64(0x3385ff66b63333cc), +CONST64(0x633ff2c65c636391), CONST64(0x02100a0412020208), CONST64(0xaa39384993aaaa92), CONST64(0x71afa8e2de7171d9), +CONST64(0xc80ecf8dc6c8c807), CONST64(0x19c87d32d1191964), CONST64(0x497270923b494939), CONST64(0xd9869aaf5fd9d943), +CONST64(0xf2c31df931f2f2ef), CONST64(0xe34b48dba8e3e3ab), CONST64(0x5be22ab6b95b5b71), CONST64(0x8834920dbc88881a), +CONST64(0x9aa4c8293e9a9a52), CONST64(0x262dbe4c0b262698), CONST64(0x328dfa64bf3232c8), CONST64(0xb0e94a7d59b0b0fa), +CONST64(0xe91b6acff2e9e983), CONST64(0x0f78331e770f0f3c), CONST64(0xd5e6a6b733d5d573), CONST64(0x8074ba1df480803a), +CONST64(0xbe997c6127bebec2), CONST64(0xcd26de87ebcdcd13), CONST64(0x34bde468893434d0), CONST64(0x487a75903248483d), +CONST64(0xffab24e354ffffdb), CONST64(0x7af78ff48d7a7af5), CONST64(0x90f4ea3d6490907a), CONST64(0x5fc23ebe9d5f5f61), +CONST64(0x201da0403d202080), CONST64(0x6867d5d00f6868bd), CONST64(0x1ad07234ca1a1a68), CONST64(0xae192c41b7aeae82), +CONST64(0xb4c95e757db4b4ea), CONST64(0x549a19a8ce54544d), CONST64(0x93ece53b7f939376), CONST64(0x220daa442f222288), +CONST64(0x6407e9c86364648d), CONST64(0xf1db12ff2af1f1e3), CONST64(0x73bfa2e6cc7373d1), CONST64(0x12905a2482121248), +CONST64(0x403a5d807a40401d), CONST64(0x0840281048080820), CONST64(0xc356e89b95c3c32b), CONST64(0xec337bc5dfecec97), +CONST64(0xdb9690ab4ddbdb4b), CONST64(0xa1611f5fc0a1a1be), CONST64(0x8d1c8307918d8d0e), CONST64(0x3df5c97ac83d3df4), +CONST64(0x97ccf1335b979766), CONST64(0x0000000000000000), CONST64(0xcf36d483f9cfcf1b), CONST64(0x2b4587566e2b2bac), +CONST64(0x7697b3ece17676c5), CONST64(0x8264b019e6828232), CONST64(0xd6fea9b128d6d67f), CONST64(0x1bd87736c31b1b6c), +CONST64(0xb5c15b7774b5b5ee), CONST64(0xaf112943beafaf86), CONST64(0x6a77dfd41d6a6ab5), CONST64(0x50ba0da0ea50505d), +CONST64(0x45124c8a57454509), CONST64(0xf3cb18fb38f3f3eb), CONST64(0x309df060ad3030c0), CONST64(0xef2b74c3c4efef9b), +CONST64(0x3fe5c37eda3f3ffc), CONST64(0x55921caac7555549), CONST64(0xa2791059dba2a2b2), CONST64(0xea0365c9e9eaea8f), +CONST64(0x650fecca6a656589), CONST64(0xbab9686903babad2), CONST64(0x2f65935e4a2f2fbc), CONST64(0xc04ee79d8ec0c027), +CONST64(0xdebe81a160dede5f), CONST64(0x1ce06c38fc1c1c70), CONST64(0xfdbb2ee746fdfdd3), CONST64(0x4d52649a1f4d4d29), +CONST64(0x92e4e03976929272), CONST64(0x758fbceafa7575c9), CONST64(0x06301e0c36060618), CONST64(0x8a249809ae8a8a12), +CONST64(0xb2f940794bb2b2f2), CONST64(0xe66359d185e6e6bf), CONST64(0x0e70361c7e0e0e38), CONST64(0x1ff8633ee71f1f7c), +CONST64(0x6237f7c455626295), CONST64(0xd4eea3b53ad4d477), CONST64(0xa829324d81a8a89a), CONST64(0x96c4f43152969662), +CONST64(0xf99b3aef62f9f9c3), CONST64(0xc566f697a3c5c533), CONST64(0x2535b14a10252594), CONST64(0x59f220b2ab595979), +CONST64(0x8454ae15d084842a), CONST64(0x72b7a7e4c57272d5), CONST64(0x39d5dd72ec3939e4), CONST64(0x4c5a6198164c4c2d), +CONST64(0x5eca3bbc945e5e65), CONST64(0x78e785f09f7878fd), CONST64(0x38ddd870e53838e0), CONST64(0x8c148605988c8c0a), +CONST64(0xd1c6b2bf17d1d163), CONST64(0xa5410b57e4a5a5ae), CONST64(0xe2434dd9a1e2e2af), CONST64(0x612ff8c24e616199), +CONST64(0xb3f1457b42b3b3f6), CONST64(0x2115a54234212184), CONST64(0x9c94d625089c9c4a), CONST64(0x1ef0663cee1e1e78), +CONST64(0x4322528661434311), CONST64(0xc776fc93b1c7c73b), CONST64(0xfcb32be54ffcfcd7), CONST64(0x0420140824040410), +CONST64(0x51b208a2e3515159), CONST64(0x99bcc72f2599995e), CONST64(0x6d4fc4da226d6da9), CONST64(0x0d68391a650d0d34), +CONST64(0xfa8335e979fafacf), CONST64(0xdfb684a369dfdf5b), CONST64(0x7ed79bfca97e7ee5), CONST64(0x243db44819242490), +CONST64(0x3bc5d776fe3b3bec), CONST64(0xab313d4b9aabab96), CONST64(0xce3ed181f0cece1f), CONST64(0x1188552299111144), +CONST64(0x8f0c8903838f8f06), CONST64(0x4e4a6b9c044e4e25), CONST64(0xb7d1517366b7b7e6), CONST64(0xeb0b60cbe0ebeb8b), +CONST64(0x3cfdcc78c13c3cf0), CONST64(0x817cbf1ffd81813e), CONST64(0x94d4fe354094946a), CONST64(0xf7eb0cf31cf7f7fb), +CONST64(0xb9a1676f18b9b9de), CONST64(0x13985f268b13134c), CONST64(0x2c7d9c58512c2cb0), CONST64(0xd3d6b8bb05d3d36b), +CONST64(0xe76b5cd38ce7e7bb), CONST64(0x6e57cbdc396e6ea5), CONST64(0xc46ef395aac4c437), CONST64(0x03180f061b03030c), +CONST64(0x568a13acdc565645), CONST64(0x441a49885e44440d), CONST64(0x7fdf9efea07f7fe1), CONST64(0xa921374f88a9a99e), +CONST64(0x2a4d8254672a2aa8), CONST64(0xbbb16d6b0abbbbd6), CONST64(0xc146e29f87c1c123), CONST64(0x53a202a6f1535351), +CONST64(0xdcae8ba572dcdc57), CONST64(0x0b582716530b0b2c), CONST64(0x9d9cd327019d9d4e), CONST64(0x6c47c1d82b6c6cad), +CONST64(0x3195f562a43131c4), CONST64(0x7487b9e8f37474cd), CONST64(0xf6e309f115f6f6ff), CONST64(0x460a438c4c464605), +CONST64(0xac092645a5acac8a), CONST64(0x893c970fb589891e), CONST64(0x14a04428b4141450), CONST64(0xe15b42dfbae1e1a3), +CONST64(0x16b04e2ca6161658), CONST64(0x3acdd274f73a3ae8), CONST64(0x696fd0d2066969b9), CONST64(0x09482d1241090924), +CONST64(0x70a7ade0d77070dd), CONST64(0xb6d954716fb6b6e2), CONST64(0xd0ceb7bd1ed0d067), CONST64(0xed3b7ec7d6eded93), +CONST64(0xcc2edb85e2cccc17), CONST64(0x422a578468424215), CONST64(0x98b4c22d2c98985a), CONST64(0xa4490e55eda4a4aa), +CONST64(0x285d8850752828a0), CONST64(0x5cda31b8865c5c6d), CONST64(0xf8933fed6bf8f8c7), CONST64(0x8644a411c2868622) +}; + +static const ulong64 sbox6[] = { +CONST64(0x6018c07830d81818), CONST64(0x8c2305af46262323), CONST64(0x3fc67ef991b8c6c6), CONST64(0x87e8136fcdfbe8e8), +CONST64(0x26874ca113cb8787), CONST64(0xdab8a9626d11b8b8), CONST64(0x0401080502090101), CONST64(0x214f426e9e0d4f4f), +CONST64(0xd836adee6c9b3636), CONST64(0xa2a6590451ffa6a6), CONST64(0x6fd2debdb90cd2d2), CONST64(0xf3f5fb06f70ef5f5), +CONST64(0xf979ef80f2967979), CONST64(0xa16f5fcede306f6f), CONST64(0x7e91fcef3f6d9191), CONST64(0x5552aa07a4f85252), +CONST64(0x9d6027fdc0476060), CONST64(0xcabc89766535bcbc), CONST64(0x569baccd2b379b9b), CONST64(0x028e048c018a8e8e), +CONST64(0xb6a371155bd2a3a3), CONST64(0x300c603c186c0c0c), CONST64(0xf17bff8af6847b7b), CONST64(0xd435b5e16a803535), +CONST64(0x741de8693af51d1d), CONST64(0xa7e05347ddb3e0e0), CONST64(0x7bd7f6acb321d7d7), CONST64(0x2fc25eed999cc2c2), +CONST64(0xb82e6d965c432e2e), CONST64(0x314b627a96294b4b), CONST64(0xdffea321e15dfefe), CONST64(0x41578216aed55757), +CONST64(0x5415a8412abd1515), CONST64(0xc1779fb6eee87777), CONST64(0xdc37a5eb6e923737), CONST64(0xb3e57b56d79ee5e5), +CONST64(0x469f8cd923139f9f), CONST64(0xe7f0d317fd23f0f0), CONST64(0x354a6a7f94204a4a), CONST64(0x4fda9e95a944dada), +CONST64(0x7d58fa25b0a25858), CONST64(0x03c906ca8fcfc9c9), CONST64(0xa429558d527c2929), CONST64(0x280a5022145a0a0a), +CONST64(0xfeb1e14f7f50b1b1), CONST64(0xbaa0691a5dc9a0a0), CONST64(0xb16b7fdad6146b6b), CONST64(0x2e855cab17d98585), +CONST64(0xcebd8173673cbdbd), CONST64(0x695dd234ba8f5d5d), CONST64(0x4010805020901010), CONST64(0xf7f4f303f507f4f4), +CONST64(0x0bcb16c08bddcbcb), CONST64(0xf83eedc67cd33e3e), CONST64(0x140528110a2d0505), CONST64(0x81671fe6ce786767), +CONST64(0xb7e47353d597e4e4), CONST64(0x9c2725bb4e022727), CONST64(0x1941325882734141), CONST64(0x168b2c9d0ba78b8b), +CONST64(0xa6a7510153f6a7a7), CONST64(0xe97dcf94fab27d7d), CONST64(0x6e95dcfb37499595), CONST64(0x47d88e9fad56d8d8), +CONST64(0xcbfb8b30eb70fbfb), CONST64(0x9fee2371c1cdeeee), CONST64(0xed7cc791f8bb7c7c), CONST64(0x856617e3cc716666), +CONST64(0x53dda68ea77bdddd), CONST64(0x5c17b84b2eaf1717), CONST64(0x014702468e454747), CONST64(0x429e84dc211a9e9e), +CONST64(0x0fca1ec589d4caca), CONST64(0xb42d75995a582d2d), CONST64(0xc6bf9179632ebfbf), CONST64(0x1c07381b0e3f0707), +CONST64(0x8ead012347acadad), CONST64(0x755aea2fb4b05a5a), CONST64(0x36836cb51bef8383), CONST64(0xcc3385ff66b63333), +CONST64(0x91633ff2c65c6363), CONST64(0x0802100a04120202), CONST64(0x92aa39384993aaaa), CONST64(0xd971afa8e2de7171), +CONST64(0x07c80ecf8dc6c8c8), CONST64(0x6419c87d32d11919), CONST64(0x39497270923b4949), CONST64(0x43d9869aaf5fd9d9), +CONST64(0xeff2c31df931f2f2), CONST64(0xabe34b48dba8e3e3), CONST64(0x715be22ab6b95b5b), CONST64(0x1a8834920dbc8888), +CONST64(0x529aa4c8293e9a9a), CONST64(0x98262dbe4c0b2626), CONST64(0xc8328dfa64bf3232), CONST64(0xfab0e94a7d59b0b0), +CONST64(0x83e91b6acff2e9e9), CONST64(0x3c0f78331e770f0f), CONST64(0x73d5e6a6b733d5d5), CONST64(0x3a8074ba1df48080), +CONST64(0xc2be997c6127bebe), CONST64(0x13cd26de87ebcdcd), CONST64(0xd034bde468893434), CONST64(0x3d487a7590324848), +CONST64(0xdbffab24e354ffff), CONST64(0xf57af78ff48d7a7a), CONST64(0x7a90f4ea3d649090), CONST64(0x615fc23ebe9d5f5f), +CONST64(0x80201da0403d2020), CONST64(0xbd6867d5d00f6868), CONST64(0x681ad07234ca1a1a), CONST64(0x82ae192c41b7aeae), +CONST64(0xeab4c95e757db4b4), CONST64(0x4d549a19a8ce5454), CONST64(0x7693ece53b7f9393), CONST64(0x88220daa442f2222), +CONST64(0x8d6407e9c8636464), CONST64(0xe3f1db12ff2af1f1), CONST64(0xd173bfa2e6cc7373), CONST64(0x4812905a24821212), +CONST64(0x1d403a5d807a4040), CONST64(0x2008402810480808), CONST64(0x2bc356e89b95c3c3), CONST64(0x97ec337bc5dfecec), +CONST64(0x4bdb9690ab4ddbdb), CONST64(0xbea1611f5fc0a1a1), CONST64(0x0e8d1c8307918d8d), CONST64(0xf43df5c97ac83d3d), +CONST64(0x6697ccf1335b9797), CONST64(0x0000000000000000), CONST64(0x1bcf36d483f9cfcf), CONST64(0xac2b4587566e2b2b), +CONST64(0xc57697b3ece17676), CONST64(0x328264b019e68282), CONST64(0x7fd6fea9b128d6d6), CONST64(0x6c1bd87736c31b1b), +CONST64(0xeeb5c15b7774b5b5), CONST64(0x86af112943beafaf), CONST64(0xb56a77dfd41d6a6a), CONST64(0x5d50ba0da0ea5050), +CONST64(0x0945124c8a574545), CONST64(0xebf3cb18fb38f3f3), CONST64(0xc0309df060ad3030), CONST64(0x9bef2b74c3c4efef), +CONST64(0xfc3fe5c37eda3f3f), CONST64(0x4955921caac75555), CONST64(0xb2a2791059dba2a2), CONST64(0x8fea0365c9e9eaea), +CONST64(0x89650fecca6a6565), CONST64(0xd2bab9686903baba), CONST64(0xbc2f65935e4a2f2f), CONST64(0x27c04ee79d8ec0c0), +CONST64(0x5fdebe81a160dede), CONST64(0x701ce06c38fc1c1c), CONST64(0xd3fdbb2ee746fdfd), CONST64(0x294d52649a1f4d4d), +CONST64(0x7292e4e039769292), CONST64(0xc9758fbceafa7575), CONST64(0x1806301e0c360606), CONST64(0x128a249809ae8a8a), +CONST64(0xf2b2f940794bb2b2), CONST64(0xbfe66359d185e6e6), CONST64(0x380e70361c7e0e0e), CONST64(0x7c1ff8633ee71f1f), +CONST64(0x956237f7c4556262), CONST64(0x77d4eea3b53ad4d4), CONST64(0x9aa829324d81a8a8), CONST64(0x6296c4f431529696), +CONST64(0xc3f99b3aef62f9f9), CONST64(0x33c566f697a3c5c5), CONST64(0x942535b14a102525), CONST64(0x7959f220b2ab5959), +CONST64(0x2a8454ae15d08484), CONST64(0xd572b7a7e4c57272), CONST64(0xe439d5dd72ec3939), CONST64(0x2d4c5a6198164c4c), +CONST64(0x655eca3bbc945e5e), CONST64(0xfd78e785f09f7878), CONST64(0xe038ddd870e53838), CONST64(0x0a8c148605988c8c), +CONST64(0x63d1c6b2bf17d1d1), CONST64(0xaea5410b57e4a5a5), CONST64(0xafe2434dd9a1e2e2), CONST64(0x99612ff8c24e6161), +CONST64(0xf6b3f1457b42b3b3), CONST64(0x842115a542342121), CONST64(0x4a9c94d625089c9c), CONST64(0x781ef0663cee1e1e), +CONST64(0x1143225286614343), CONST64(0x3bc776fc93b1c7c7), CONST64(0xd7fcb32be54ffcfc), CONST64(0x1004201408240404), +CONST64(0x5951b208a2e35151), CONST64(0x5e99bcc72f259999), CONST64(0xa96d4fc4da226d6d), CONST64(0x340d68391a650d0d), +CONST64(0xcffa8335e979fafa), CONST64(0x5bdfb684a369dfdf), CONST64(0xe57ed79bfca97e7e), CONST64(0x90243db448192424), +CONST64(0xec3bc5d776fe3b3b), CONST64(0x96ab313d4b9aabab), CONST64(0x1fce3ed181f0cece), CONST64(0x4411885522991111), +CONST64(0x068f0c8903838f8f), CONST64(0x254e4a6b9c044e4e), CONST64(0xe6b7d1517366b7b7), CONST64(0x8beb0b60cbe0ebeb), +CONST64(0xf03cfdcc78c13c3c), CONST64(0x3e817cbf1ffd8181), CONST64(0x6a94d4fe35409494), CONST64(0xfbf7eb0cf31cf7f7), +CONST64(0xdeb9a1676f18b9b9), CONST64(0x4c13985f268b1313), CONST64(0xb02c7d9c58512c2c), CONST64(0x6bd3d6b8bb05d3d3), +CONST64(0xbbe76b5cd38ce7e7), CONST64(0xa56e57cbdc396e6e), CONST64(0x37c46ef395aac4c4), CONST64(0x0c03180f061b0303), +CONST64(0x45568a13acdc5656), CONST64(0x0d441a49885e4444), CONST64(0xe17fdf9efea07f7f), CONST64(0x9ea921374f88a9a9), +CONST64(0xa82a4d8254672a2a), CONST64(0xd6bbb16d6b0abbbb), CONST64(0x23c146e29f87c1c1), CONST64(0x5153a202a6f15353), +CONST64(0x57dcae8ba572dcdc), CONST64(0x2c0b582716530b0b), CONST64(0x4e9d9cd327019d9d), CONST64(0xad6c47c1d82b6c6c), +CONST64(0xc43195f562a43131), CONST64(0xcd7487b9e8f37474), CONST64(0xfff6e309f115f6f6), CONST64(0x05460a438c4c4646), +CONST64(0x8aac092645a5acac), CONST64(0x1e893c970fb58989), CONST64(0x5014a04428b41414), CONST64(0xa3e15b42dfbae1e1), +CONST64(0x5816b04e2ca61616), CONST64(0xe83acdd274f73a3a), CONST64(0xb9696fd0d2066969), CONST64(0x2409482d12410909), +CONST64(0xdd70a7ade0d77070), CONST64(0xe2b6d954716fb6b6), CONST64(0x67d0ceb7bd1ed0d0), CONST64(0x93ed3b7ec7d6eded), +CONST64(0x17cc2edb85e2cccc), CONST64(0x15422a5784684242), CONST64(0x5a98b4c22d2c9898), CONST64(0xaaa4490e55eda4a4), +CONST64(0xa0285d8850752828), CONST64(0x6d5cda31b8865c5c), CONST64(0xc7f8933fed6bf8f8), CONST64(0x228644a411c28686) +}; + +static const ulong64 sbox7[] = { +CONST64(0x186018c07830d818), CONST64(0x238c2305af462623), CONST64(0xc63fc67ef991b8c6), CONST64(0xe887e8136fcdfbe8), +CONST64(0x8726874ca113cb87), CONST64(0xb8dab8a9626d11b8), CONST64(0x0104010805020901), CONST64(0x4f214f426e9e0d4f), +CONST64(0x36d836adee6c9b36), CONST64(0xa6a2a6590451ffa6), CONST64(0xd26fd2debdb90cd2), CONST64(0xf5f3f5fb06f70ef5), +CONST64(0x79f979ef80f29679), CONST64(0x6fa16f5fcede306f), CONST64(0x917e91fcef3f6d91), CONST64(0x525552aa07a4f852), +CONST64(0x609d6027fdc04760), CONST64(0xbccabc89766535bc), CONST64(0x9b569baccd2b379b), CONST64(0x8e028e048c018a8e), +CONST64(0xa3b6a371155bd2a3), CONST64(0x0c300c603c186c0c), CONST64(0x7bf17bff8af6847b), CONST64(0x35d435b5e16a8035), +CONST64(0x1d741de8693af51d), CONST64(0xe0a7e05347ddb3e0), CONST64(0xd77bd7f6acb321d7), CONST64(0xc22fc25eed999cc2), +CONST64(0x2eb82e6d965c432e), CONST64(0x4b314b627a96294b), CONST64(0xfedffea321e15dfe), CONST64(0x5741578216aed557), +CONST64(0x155415a8412abd15), CONST64(0x77c1779fb6eee877), CONST64(0x37dc37a5eb6e9237), CONST64(0xe5b3e57b56d79ee5), +CONST64(0x9f469f8cd923139f), CONST64(0xf0e7f0d317fd23f0), CONST64(0x4a354a6a7f94204a), CONST64(0xda4fda9e95a944da), +CONST64(0x587d58fa25b0a258), CONST64(0xc903c906ca8fcfc9), CONST64(0x29a429558d527c29), CONST64(0x0a280a5022145a0a), +CONST64(0xb1feb1e14f7f50b1), CONST64(0xa0baa0691a5dc9a0), CONST64(0x6bb16b7fdad6146b), CONST64(0x852e855cab17d985), +CONST64(0xbdcebd8173673cbd), CONST64(0x5d695dd234ba8f5d), CONST64(0x1040108050209010), CONST64(0xf4f7f4f303f507f4), +CONST64(0xcb0bcb16c08bddcb), CONST64(0x3ef83eedc67cd33e), CONST64(0x05140528110a2d05), CONST64(0x6781671fe6ce7867), +CONST64(0xe4b7e47353d597e4), CONST64(0x279c2725bb4e0227), CONST64(0x4119413258827341), CONST64(0x8b168b2c9d0ba78b), +CONST64(0xa7a6a7510153f6a7), CONST64(0x7de97dcf94fab27d), CONST64(0x956e95dcfb374995), CONST64(0xd847d88e9fad56d8), +CONST64(0xfbcbfb8b30eb70fb), CONST64(0xee9fee2371c1cdee), CONST64(0x7ced7cc791f8bb7c), CONST64(0x66856617e3cc7166), +CONST64(0xdd53dda68ea77bdd), CONST64(0x175c17b84b2eaf17), CONST64(0x47014702468e4547), CONST64(0x9e429e84dc211a9e), +CONST64(0xca0fca1ec589d4ca), CONST64(0x2db42d75995a582d), CONST64(0xbfc6bf9179632ebf), CONST64(0x071c07381b0e3f07), +CONST64(0xad8ead012347acad), CONST64(0x5a755aea2fb4b05a), CONST64(0x8336836cb51bef83), CONST64(0x33cc3385ff66b633), +CONST64(0x6391633ff2c65c63), CONST64(0x020802100a041202), CONST64(0xaa92aa39384993aa), CONST64(0x71d971afa8e2de71), +CONST64(0xc807c80ecf8dc6c8), CONST64(0x196419c87d32d119), CONST64(0x4939497270923b49), CONST64(0xd943d9869aaf5fd9), +CONST64(0xf2eff2c31df931f2), CONST64(0xe3abe34b48dba8e3), CONST64(0x5b715be22ab6b95b), CONST64(0x881a8834920dbc88), +CONST64(0x9a529aa4c8293e9a), CONST64(0x2698262dbe4c0b26), CONST64(0x32c8328dfa64bf32), CONST64(0xb0fab0e94a7d59b0), +CONST64(0xe983e91b6acff2e9), CONST64(0x0f3c0f78331e770f), CONST64(0xd573d5e6a6b733d5), CONST64(0x803a8074ba1df480), +CONST64(0xbec2be997c6127be), CONST64(0xcd13cd26de87ebcd), CONST64(0x34d034bde4688934), CONST64(0x483d487a75903248), +CONST64(0xffdbffab24e354ff), CONST64(0x7af57af78ff48d7a), CONST64(0x907a90f4ea3d6490), CONST64(0x5f615fc23ebe9d5f), +CONST64(0x2080201da0403d20), CONST64(0x68bd6867d5d00f68), CONST64(0x1a681ad07234ca1a), CONST64(0xae82ae192c41b7ae), +CONST64(0xb4eab4c95e757db4), CONST64(0x544d549a19a8ce54), CONST64(0x937693ece53b7f93), CONST64(0x2288220daa442f22), +CONST64(0x648d6407e9c86364), CONST64(0xf1e3f1db12ff2af1), CONST64(0x73d173bfa2e6cc73), CONST64(0x124812905a248212), +CONST64(0x401d403a5d807a40), CONST64(0x0820084028104808), CONST64(0xc32bc356e89b95c3), CONST64(0xec97ec337bc5dfec), +CONST64(0xdb4bdb9690ab4ddb), CONST64(0xa1bea1611f5fc0a1), CONST64(0x8d0e8d1c8307918d), CONST64(0x3df43df5c97ac83d), +CONST64(0x976697ccf1335b97), CONST64(0x0000000000000000), CONST64(0xcf1bcf36d483f9cf), CONST64(0x2bac2b4587566e2b), +CONST64(0x76c57697b3ece176), CONST64(0x82328264b019e682), CONST64(0xd67fd6fea9b128d6), CONST64(0x1b6c1bd87736c31b), +CONST64(0xb5eeb5c15b7774b5), CONST64(0xaf86af112943beaf), CONST64(0x6ab56a77dfd41d6a), CONST64(0x505d50ba0da0ea50), +CONST64(0x450945124c8a5745), CONST64(0xf3ebf3cb18fb38f3), CONST64(0x30c0309df060ad30), CONST64(0xef9bef2b74c3c4ef), +CONST64(0x3ffc3fe5c37eda3f), CONST64(0x554955921caac755), CONST64(0xa2b2a2791059dba2), CONST64(0xea8fea0365c9e9ea), +CONST64(0x6589650fecca6a65), CONST64(0xbad2bab9686903ba), CONST64(0x2fbc2f65935e4a2f), CONST64(0xc027c04ee79d8ec0), +CONST64(0xde5fdebe81a160de), CONST64(0x1c701ce06c38fc1c), CONST64(0xfdd3fdbb2ee746fd), CONST64(0x4d294d52649a1f4d), +CONST64(0x927292e4e0397692), CONST64(0x75c9758fbceafa75), CONST64(0x061806301e0c3606), CONST64(0x8a128a249809ae8a), +CONST64(0xb2f2b2f940794bb2), CONST64(0xe6bfe66359d185e6), CONST64(0x0e380e70361c7e0e), CONST64(0x1f7c1ff8633ee71f), +CONST64(0x62956237f7c45562), CONST64(0xd477d4eea3b53ad4), CONST64(0xa89aa829324d81a8), CONST64(0x966296c4f4315296), +CONST64(0xf9c3f99b3aef62f9), CONST64(0xc533c566f697a3c5), CONST64(0x25942535b14a1025), CONST64(0x597959f220b2ab59), +CONST64(0x842a8454ae15d084), CONST64(0x72d572b7a7e4c572), CONST64(0x39e439d5dd72ec39), CONST64(0x4c2d4c5a6198164c), +CONST64(0x5e655eca3bbc945e), CONST64(0x78fd78e785f09f78), CONST64(0x38e038ddd870e538), CONST64(0x8c0a8c148605988c), +CONST64(0xd163d1c6b2bf17d1), CONST64(0xa5aea5410b57e4a5), CONST64(0xe2afe2434dd9a1e2), CONST64(0x6199612ff8c24e61), +CONST64(0xb3f6b3f1457b42b3), CONST64(0x21842115a5423421), CONST64(0x9c4a9c94d625089c), CONST64(0x1e781ef0663cee1e), +CONST64(0x4311432252866143), CONST64(0xc73bc776fc93b1c7), CONST64(0xfcd7fcb32be54ffc), CONST64(0x0410042014082404), +CONST64(0x515951b208a2e351), CONST64(0x995e99bcc72f2599), CONST64(0x6da96d4fc4da226d), CONST64(0x0d340d68391a650d), +CONST64(0xfacffa8335e979fa), CONST64(0xdf5bdfb684a369df), CONST64(0x7ee57ed79bfca97e), CONST64(0x2490243db4481924), +CONST64(0x3bec3bc5d776fe3b), CONST64(0xab96ab313d4b9aab), CONST64(0xce1fce3ed181f0ce), CONST64(0x1144118855229911), +CONST64(0x8f068f0c8903838f), CONST64(0x4e254e4a6b9c044e), CONST64(0xb7e6b7d1517366b7), CONST64(0xeb8beb0b60cbe0eb), +CONST64(0x3cf03cfdcc78c13c), CONST64(0x813e817cbf1ffd81), CONST64(0x946a94d4fe354094), CONST64(0xf7fbf7eb0cf31cf7), +CONST64(0xb9deb9a1676f18b9), CONST64(0x134c13985f268b13), CONST64(0x2cb02c7d9c58512c), CONST64(0xd36bd3d6b8bb05d3), +CONST64(0xe7bbe76b5cd38ce7), CONST64(0x6ea56e57cbdc396e), CONST64(0xc437c46ef395aac4), CONST64(0x030c03180f061b03), +CONST64(0x5645568a13acdc56), CONST64(0x440d441a49885e44), CONST64(0x7fe17fdf9efea07f), CONST64(0xa99ea921374f88a9), +CONST64(0x2aa82a4d8254672a), CONST64(0xbbd6bbb16d6b0abb), CONST64(0xc123c146e29f87c1), CONST64(0x535153a202a6f153), +CONST64(0xdc57dcae8ba572dc), CONST64(0x0b2c0b582716530b), CONST64(0x9d4e9d9cd327019d), CONST64(0x6cad6c47c1d82b6c), +CONST64(0x31c43195f562a431), CONST64(0x74cd7487b9e8f374), CONST64(0xf6fff6e309f115f6), CONST64(0x4605460a438c4c46), +CONST64(0xac8aac092645a5ac), CONST64(0x891e893c970fb589), CONST64(0x145014a04428b414), CONST64(0xe1a3e15b42dfbae1), +CONST64(0x165816b04e2ca616), CONST64(0x3ae83acdd274f73a), CONST64(0x69b9696fd0d20669), CONST64(0x092409482d124109), +CONST64(0x70dd70a7ade0d770), CONST64(0xb6e2b6d954716fb6), CONST64(0xd067d0ceb7bd1ed0), CONST64(0xed93ed3b7ec7d6ed), +CONST64(0xcc17cc2edb85e2cc), CONST64(0x4215422a57846842), CONST64(0x985a98b4c22d2c98), CONST64(0xa4aaa4490e55eda4), +CONST64(0x28a0285d88507528), CONST64(0x5c6d5cda31b8865c), CONST64(0xf8c7f8933fed6bf8), CONST64(0x86228644a411c286) +}; + +#endif + +static const ulong64 cont[] = { +CONST64(0x1823c6e887b8014f), +CONST64(0x36a6d2f5796f9152), +CONST64(0x60bc9b8ea30c7b35), +CONST64(0x1de0d7c22e4bfe57), +CONST64(0x157737e59ff04ada), +CONST64(0x58c9290ab1a06b85), +CONST64(0xbd5d10f4cb3e0567), +CONST64(0xe427418ba77d95d8), +CONST64(0xfbee7c66dd17479e), +CONST64(0xca2dbf07ad5a8333), +CONST64(0x6302aa71c81949d9), +}; + + +/* $Source: /cvs/libtom/libtomcrypt/src/hashes/whirl/whirltab.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2007/05/12 14:21:44 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt.h b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt.h new file mode 100644 index 0000000000..da9f6b788d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt.h @@ -0,0 +1,87 @@ +#ifndef TOMCRYPT_H_ +#define TOMCRYPT_H_ +#include +#include +#include +#include +/*#include */ +#include +#include + +/* use configuration data */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* version */ +#define CRYPT 0x0117 +#define SCRYPT "1.17" + +/* max size of either a cipher/hash block or symmetric key [largest of the two] */ +#define MAXBLOCKSIZE 128 + +/* descriptor table size */ +#define TAB_SIZE 32 + +/* error codes [will be expanded in future releases] */ +enum { + CRYPT_OK=0, /* Result OK */ + CRYPT_ERROR, /* Generic Error */ + CRYPT_NOP, /* Not a failure but no operation was performed */ + + CRYPT_INVALID_KEYSIZE, /* Invalid key size given */ + CRYPT_INVALID_ROUNDS, /* Invalid number of rounds */ + CRYPT_FAIL_TESTVECTOR, /* Algorithm failed test vectors */ + + CRYPT_BUFFER_OVERFLOW, /* Not enough space for output */ + CRYPT_INVALID_PACKET, /* Invalid input packet given */ + + CRYPT_INVALID_PRNGSIZE, /* Invalid number of bits for a PRNG */ + CRYPT_ERROR_READPRNG, /* Could not read enough from PRNG */ + + CRYPT_INVALID_CIPHER, /* Invalid cipher specified */ + CRYPT_INVALID_HASH, /* Invalid hash specified */ + CRYPT_INVALID_PRNG, /* Invalid PRNG specified */ + + CRYPT_MEM, /* Out of memory */ + + CRYPT_PK_TYPE_MISMATCH, /* Not equivalent types of PK keys */ + CRYPT_PK_NOT_PRIVATE, /* Requires a private PK key */ + + CRYPT_INVALID_ARG, /* Generic invalid argument */ + CRYPT_FILE_NOTFOUND, /* File Not Found */ + + CRYPT_PK_INVALID_TYPE, /* Invalid type of PK key */ + CRYPT_PK_INVALID_SYSTEM,/* Invalid PK system specified */ + CRYPT_PK_DUP, /* Duplicate key already in key ring */ + CRYPT_PK_NOT_FOUND, /* Key not found in keyring */ + CRYPT_PK_INVALID_SIZE, /* Invalid size input for PK parameters */ + + CRYPT_INVALID_PRIME_SIZE,/* Invalid size of prime requested */ + CRYPT_PK_INVALID_PADDING /* Invalid padding on input */ +}; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus + } +#endif + +#endif /* TOMCRYPT_H_ */ + + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt.h,v $ */ +/* $Revision: 1.21 $ */ +/* $Date: 2006/12/16 19:34:05 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_argchk.h b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_argchk.h new file mode 100644 index 0000000000..c4981e3099 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_argchk.h @@ -0,0 +1,38 @@ +/* Defines the LTC_ARGCHK macro used within the library */ +/* ARGTYPE is defined in mycrypt_cfg.h */ +#if ARGTYPE == 0 + +/* #include */ + +/* this is the default LibTomCrypt macro */ +void crypt_argchk(char *v, char *s, int d); +#define LTC_ARGCHK(x) if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } +#define LTC_ARGCHKVD(x) LTC_ARGCHK(x) + +#elif ARGTYPE == 1 + +/* fatal type of error */ +#define LTC_ARGCHK(x) assert((x)) +#define LTC_ARGCHKVD(x) LTC_ARGCHK(x) + +#elif ARGTYPE == 2 + +#define LTC_ARGCHK(x) if (!(x)) { fprintf(stderr, "\nwarning: ARGCHK failed at %s:%d\n", __FILE__, __LINE__); } +#define LTC_ARGCHKVD(x) LTC_ARGCHK(x) + +#elif ARGTYPE == 3 + +#define LTC_ARGCHK(x) +#define LTC_ARGCHKVD(x) LTC_ARGCHK(x) + +#elif ARGTYPE == 4 + +#define LTC_ARGCHK(x) if (!(x)) return CRYPT_INVALID_ARG; +#define LTC_ARGCHKVD(x) if (!(x)) return; + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_argchk.h,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/08/27 20:50:21 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_cfg.h b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_cfg.h new file mode 100644 index 0000000000..cb8de0b90c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_cfg.h @@ -0,0 +1,136 @@ +/* This is the build config file. + * + * With this you can setup what to inlcude/exclude automatically during any build. Just comment + * out the line that #define's the word for the thing you want to remove. phew! + */ + +#ifndef TOMCRYPT_CFG_H +#define TOMCRYPT_CFG_H + +#if defined(_WIN32) || defined(_MSC_VER) +#define LTC_CALL __cdecl +#else +#ifndef LTC_CALL + #define LTC_CALL +#endif +#endif + +#ifndef LTC_EXPORT +#define LTC_EXPORT +#endif + +/* certain platforms use macros for these, making the prototypes broken */ +#ifndef LTC_NO_PROTOTYPES + +/* you can change how memory allocation works ... */ +LTC_EXPORT void * LTC_CALL XMALLOC(size_t n); +LTC_EXPORT void * LTC_CALL XREALLOC(void *p, size_t n); +LTC_EXPORT void * LTC_CALL XCALLOC(size_t n, size_t s); +LTC_EXPORT void LTC_CALL XFREE(void *p); + +LTC_EXPORT void LTC_CALL XQSORT(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *)); + + +/* change the clock function too */ +/* LTC_EXPORT clock_t LTC_CALL XCLOCK(void); */ + +/* various other functions */ +LTC_EXPORT void * LTC_CALL XMEMCPY(void *dest, const void *src, size_t n); +LTC_EXPORT int LTC_CALL XMEMCMP(const void *s1, const void *s2, size_t n); +LTC_EXPORT void * LTC_CALL XMEMSET(void *s, int c, size_t n); + +LTC_EXPORT int LTC_CALL XSTRCMP(const char *s1, const char *s2); + +#endif + +/* type of argument checking, 0=default, 1=fatal and 2=error+continue, 3=nothing */ +#ifndef ARGTYPE + #define ARGTYPE 0 +#endif + +/* Controls endianess and size of registers. Leave uncommented to get platform neutral [slower] code + * + * Note: in order to use the optimized macros your platform must support unaligned 32 and 64 bit read/writes. + * The x86 platforms allow this but some others [ARM for instance] do not. On those platforms you **MUST** + * use the portable [slower] macros. + */ + +/* detect x86-32 machines somewhat */ +#if !defined(__STRICT_ANSI__) && (defined(INTEL_CC) || (defined(_MSC_VER) && defined(WIN32)) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__)))) + #define ENDIAN_LITTLE + #define ENDIAN_32BITWORD + #define LTC_FAST + #define LTC_FAST_TYPE unsigned long +#endif + +/* detects MIPS R5900 processors (PS2) */ +#if (defined(__R5900) || defined(R5900) || defined(__R5900__)) && (defined(_mips) || defined(__mips__) || defined(mips)) + #define ENDIAN_LITTLE + #define ENDIAN_64BITWORD +#endif + +/* detect amd64 */ +#if !defined(__STRICT_ANSI__) && defined(__x86_64__) + #define ENDIAN_LITTLE + #define ENDIAN_64BITWORD + #define LTC_FAST + #define LTC_FAST_TYPE unsigned long +#endif + +/* detect PPC32 */ +#if !defined(__STRICT_ANSI__) && defined(LTC_PPC32) + #define ENDIAN_BIG + #define ENDIAN_32BITWORD + #define LTC_FAST + #define LTC_FAST_TYPE unsigned long +#endif + +/* detect sparc and sparc64 */ +#if defined(__sparc__) + #define ENDIAN_BIG + #if defined(__arch64__) + #define ENDIAN_64BITWORD + #else + #define ENDIAN_32BITWORD + #endif +#endif + + +#ifdef LTC_NO_FAST + #ifdef LTC_FAST + #undef LTC_FAST + #endif +#endif + +/* No asm is a quick way to disable anything "not portable" */ +#ifdef LTC_NO_ASM + #undef ENDIAN_LITTLE + #undef ENDIAN_BIG + #undef ENDIAN_32BITWORD + #undef ENDIAN_64BITWORD + #undef LTC_FAST + #undef LTC_FAST_TYPE + #define LTC_NO_ROLC + #define LTC_NO_BSWAP +#endif + +/* #define ENDIAN_LITTLE */ +/* #define ENDIAN_BIG */ + +/* #define ENDIAN_32BITWORD */ +/* #define ENDIAN_64BITWORD */ + +#if (defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) && !(defined(ENDIAN_32BITWORD) || defined(ENDIAN_64BITWORD)) + #error You must specify a word size as well as endianess in tomcrypt_cfg.h +#endif + +#if !(defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) + #define ENDIAN_NEUTRAL +#endif + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_cfg.h,v $ */ +/* $Revision: 1.19 $ */ +/* $Date: 2006/12/04 02:19:48 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_cipher.h b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_cipher.h new file mode 100644 index 0000000000..049182d776 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_cipher.h @@ -0,0 +1,891 @@ +/* ---- SYMMETRIC KEY STUFF ----- + * + * We put each of the ciphers scheduled keys in their own structs then we put all of + * the key formats in one union. This makes the function prototypes easier to use. + */ +#ifdef LTC_BLOWFISH +struct blowfish_key { + ulong32 S[4][256]; + ulong32 K[18]; +}; +#endif + +#ifdef LTC_RC5 +struct rc5_key { + int rounds; + ulong32 K[50]; +}; +#endif + +#ifdef LTC_RC6 +struct rc6_key { + ulong32 K[44]; +}; +#endif + +#ifdef LTC_SAFERP +struct saferp_key { + unsigned char K[33][16]; + long rounds; +}; +#endif + +#ifdef LTC_RIJNDAEL +struct rijndael_key { + ulong32 eK[60], dK[60]; + int Nr; +}; +#endif + +#ifdef LTC_KSEED +struct kseed_key { + ulong32 K[32], dK[32]; +}; +#endif + +#ifdef LTC_KASUMI +struct kasumi_key { + ulong32 KLi1[8], KLi2[8], + KOi1[8], KOi2[8], KOi3[8], + KIi1[8], KIi2[8], KIi3[8]; +}; +#endif + +#ifdef LTC_XTEA +struct xtea_key { + unsigned long A[32], B[32]; +}; +#endif + +#ifdef LTC_TWOFISH +#ifndef LTC_TWOFISH_SMALL + struct twofish_key { + ulong32 S[4][256], K[40]; + }; +#else + struct twofish_key { + ulong32 K[40]; + unsigned char S[32], start; + }; +#endif +#endif + +#ifdef LTC_SAFER +#define LTC_SAFER_K64_DEFAULT_NOF_ROUNDS 6 +#define LTC_SAFER_K128_DEFAULT_NOF_ROUNDS 10 +#define LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS 8 +#define LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS 10 +#define LTC_SAFER_MAX_NOF_ROUNDS 13 +#define LTC_SAFER_BLOCK_LEN 8 +#define LTC_SAFER_KEY_LEN (1 + LTC_SAFER_BLOCK_LEN * (1 + 2 * LTC_SAFER_MAX_NOF_ROUNDS)) +typedef unsigned char safer_block_t[LTC_SAFER_BLOCK_LEN]; +typedef unsigned char safer_key_t[LTC_SAFER_KEY_LEN]; +struct safer_key { safer_key_t key; }; +#endif + +#ifdef LTC_RC2 +struct rc2_key { unsigned xkey[64]; }; +#endif + +#ifdef LTC_DES +struct des_key { + ulong32 ek[32], dk[32]; +}; + +struct des3_key { + ulong32 ek[3][32], dk[3][32]; +}; +#endif + +#ifdef LTC_CAST5 +struct cast5_key { + ulong32 K[32], keylen; +}; +#endif + +#ifdef LTC_NOEKEON +struct noekeon_key { + ulong32 K[4], dK[4]; +}; +#endif + +#ifdef LTC_SKIPJACK +struct skipjack_key { + unsigned char key[10]; +}; +#endif + +#ifdef LTC_KHAZAD +struct khazad_key { + ulong64 roundKeyEnc[8 + 1]; + ulong64 roundKeyDec[8 + 1]; +}; +#endif + +#ifdef LTC_ANUBIS +struct anubis_key { + int keyBits; + int R; + ulong32 roundKeyEnc[18 + 1][4]; + ulong32 roundKeyDec[18 + 1][4]; +}; +#endif + +#ifdef LTC_MULTI2 +struct multi2_key { + int N; + ulong32 uk[8]; +}; +#endif + +typedef union Symmetric_key { +#ifdef LTC_DES + struct des_key des; + struct des3_key des3; +#endif +#ifdef LTC_RC2 + struct rc2_key rc2; +#endif +#ifdef LTC_SAFER + struct safer_key safer; +#endif +#ifdef LTC_TWOFISH + struct twofish_key twofish; +#endif +#ifdef LTC_BLOWFISH + struct blowfish_key blowfish; +#endif +#ifdef LTC_RC5 + struct rc5_key rc5; +#endif +#ifdef LTC_RC6 + struct rc6_key rc6; +#endif +#ifdef LTC_SAFERP + struct saferp_key saferp; +#endif +#ifdef LTC_RIJNDAEL + struct rijndael_key rijndael; +#endif +#ifdef LTC_XTEA + struct xtea_key xtea; +#endif +#ifdef LTC_CAST5 + struct cast5_key cast5; +#endif +#ifdef LTC_NOEKEON + struct noekeon_key noekeon; +#endif +#ifdef LTC_SKIPJACK + struct skipjack_key skipjack; +#endif +#ifdef LTC_KHAZAD + struct khazad_key khazad; +#endif +#ifdef LTC_ANUBIS + struct anubis_key anubis; +#endif +#ifdef LTC_KSEED + struct kseed_key kseed; +#endif +#ifdef LTC_KASUMI + struct kasumi_key kasumi; +#endif +#ifdef LTC_MULTI2 + struct multi2_key multi2; +#endif + void *data; +} symmetric_key; + +#ifdef LTC_ECB_MODE +/** A block cipher ECB structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen; + /** The scheduled key */ + symmetric_key key; +} symmetric_ECB; +#endif + +#ifdef LTC_CFB_MODE +/** A block cipher CFB structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen, + /** The padding offset */ + padlen; + /** The current IV */ + unsigned char IV[MAXBLOCKSIZE], + /** The pad used to encrypt/decrypt */ + pad[MAXBLOCKSIZE]; + /** The scheduled key */ + symmetric_key key; +} symmetric_CFB; +#endif + +#ifdef LTC_OFB_MODE +/** A block cipher OFB structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen, + /** The padding offset */ + padlen; + /** The current IV */ + unsigned char IV[MAXBLOCKSIZE]; + /** The scheduled key */ + symmetric_key key; +} symmetric_OFB; +#endif + +#ifdef LTC_CBC_MODE +/** A block cipher CBC structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen; + /** The current IV */ + unsigned char IV[MAXBLOCKSIZE]; + /** The scheduled key */ + symmetric_key key; +} symmetric_CBC; +#endif + + +#ifdef LTC_CTR_MODE +/** A block cipher CTR structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen, + /** The padding offset */ + padlen, + /** The mode (endianess) of the CTR, 0==little, 1==big */ + mode, + /** counter width */ + ctrlen; + + /** The counter */ + unsigned char ctr[MAXBLOCKSIZE], + /** The pad used to encrypt/decrypt */ + pad[MAXBLOCKSIZE]; + /** The scheduled key */ + symmetric_key key; +} symmetric_CTR; +#endif + + +#ifdef LTC_LRW_MODE +/** A LRW structure */ +typedef struct { + /** The index of the cipher chosen (must be a 128-bit block cipher) */ + int cipher; + + /** The current IV */ + unsigned char IV[16], + + /** the tweak key */ + tweak[16], + + /** The current pad, it's the product of the first 15 bytes against the tweak key */ + pad[16]; + + /** The scheduled symmetric key */ + symmetric_key key; + +#ifdef LRW_TABLES + /** The pre-computed multiplication table */ + unsigned char PC[16][256][16]; +#endif +} symmetric_LRW; +#endif + +#ifdef LTC_F8_MODE +/** A block cipher F8 structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen, + /** The padding offset */ + padlen; + /** The current IV */ + unsigned char IV[MAXBLOCKSIZE], + MIV[MAXBLOCKSIZE]; + /** Current block count */ + ulong32 blockcnt; + /** The scheduled key */ + symmetric_key key; +} symmetric_F8; +#endif + + +/** cipher descriptor table, last entry has "name == NULL" to mark the end of table */ +extern struct ltc_cipher_descriptor { + /** name of cipher */ + char *name; + /** internal ID */ + unsigned char ID; + /** min keysize (octets) */ + int min_key_length, + /** max keysize (octets) */ + max_key_length, + /** block size (octets) */ + block_length, + /** default number of rounds */ + default_rounds; + /** Setup the cipher + @param key The input symmetric key + @param keylen The length of the input key (octets) + @param num_rounds The requested number of rounds (0==default) + @param skey [out] The destination of the scheduled key + @return CRYPT_OK if successful + */ + int (*setup)(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); + /** Encrypt a block + @param pt The plaintext + @param ct [out] The ciphertext + @param skey The scheduled key + @return CRYPT_OK if successful + */ + int (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); + /** Decrypt a block + @param ct The ciphertext + @param pt [out] The plaintext + @param skey The scheduled key + @return CRYPT_OK if successful + */ + int (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); + /** Test the block cipher + @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled + */ + int (*test)(void); + + /** Terminate the context + @param skey The scheduled key + */ + void (*done)(symmetric_key *skey); + + /** Determine a key size + @param keysize [in/out] The size of the key desired and the suggested size + @return CRYPT_OK if successful + */ + int (*keysize)(int *keysize); + +/** Accelerators **/ + /** Accelerated ECB encryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, symmetric_key *skey); + + /** Accelerated ECB decryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, symmetric_key *skey); + + /** Accelerated CBC encryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, symmetric_key *skey); + + /** Accelerated CBC decryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, symmetric_key *skey); + + /** Accelerated CTR encryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param mode little or big endian counter (mode=0 or mode=1) + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, symmetric_key *skey); + + /** Accelerated LRW + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param tweak The LRW tweak + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_lrw_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey); + + /** Accelerated LRW + @param ct Ciphertext + @param pt Plaintext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param tweak The LRW tweak + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_lrw_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey); + + /** Accelerated CCM packet (one-shot) + @param key The secret key to use + @param keylen The length of the secret key (octets) + @param uskey A previously scheduled key [optional can be NULL] + @param nonce The session nonce [use once] + @param noncelen The length of the nonce + @param header The header for the session + @param headerlen The length of the header (octets) + @param pt [out] The plaintext + @param ptlen The length of the plaintext (octets) + @param ct [out] The ciphertext + @param tag [out] The destination tag + @param taglen [in/out] The max size and resulting size of the authentication tag + @param direction Encrypt or Decrypt direction (0 or 1) + @return CRYPT_OK if successful + */ + int (*accel_ccm_memory)( + const unsigned char *key, unsigned long keylen, + symmetric_key *uskey, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); + + /** Accelerated GCM packet (one shot) + @param key The secret key + @param keylen The length of the secret key + @param IV The initial vector + @param IVlen The length of the initial vector + @param adata The additional authentication data (header) + @param adatalen The length of the adata + @param pt The plaintext + @param ptlen The length of the plaintext (ciphertext length is the same) + @param ct The ciphertext + @param tag [out] The MAC tag + @param taglen [in/out] The MAC tag length + @param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT) + @return CRYPT_OK on success + */ + int (*accel_gcm_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *IV, unsigned long IVlen, + const unsigned char *adata, unsigned long adatalen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); + + /** Accelerated one shot LTC_OMAC + @param key The secret key + @param keylen The key length (octets) + @param in The message + @param inlen Length of message (octets) + @param out [out] Destination for tag + @param outlen [in/out] Initial and final size of out + @return CRYPT_OK on success + */ + int (*omac_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + + /** Accelerated one shot XCBC + @param key The secret key + @param keylen The key length (octets) + @param in The message + @param inlen Length of message (octets) + @param out [out] Destination for tag + @param outlen [in/out] Initial and final size of out + @return CRYPT_OK on success + */ + int (*xcbc_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + + /** Accelerated one shot F9 + @param key The secret key + @param keylen The key length (octets) + @param in The message + @param inlen Length of message (octets) + @param out [out] Destination for tag + @param outlen [in/out] Initial and final size of out + @return CRYPT_OK on success + @remark Requires manual padding + */ + int (*f9_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +} cipher_descriptor[]; + +#ifdef LTC_BLOWFISH +int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int blowfish_test(void); +void blowfish_done(symmetric_key *skey); +int blowfish_keysize(int *keysize); +extern const struct ltc_cipher_descriptor blowfish_desc; +#endif + +#ifdef LTC_RC5 +int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int rc5_test(void); +void rc5_done(symmetric_key *skey); +int rc5_keysize(int *keysize); +extern const struct ltc_cipher_descriptor rc5_desc; +#endif + +#ifdef LTC_RC6 +int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int rc6_test(void); +void rc6_done(symmetric_key *skey); +int rc6_keysize(int *keysize); +extern const struct ltc_cipher_descriptor rc6_desc; +#endif + +#ifdef LTC_RC2 +int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int rc2_test(void); +void rc2_done(symmetric_key *skey); +int rc2_keysize(int *keysize); +extern const struct ltc_cipher_descriptor rc2_desc; +#endif + +#ifdef LTC_SAFERP +int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int saferp_test(void); +void saferp_done(symmetric_key *skey); +int saferp_keysize(int *keysize); +extern const struct ltc_cipher_descriptor saferp_desc; +#endif + +#ifdef LTC_SAFER +int safer_k64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int safer_sk64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int safer_k128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int safer_sk128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int safer_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +int safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +int safer_k64_test(void); +int safer_sk64_test(void); +int safer_sk128_test(void); +void safer_done(symmetric_key *skey); +int safer_64_keysize(int *keysize); +int safer_128_keysize(int *keysize); +extern const struct ltc_cipher_descriptor safer_k64_desc, safer_k128_desc, safer_sk64_desc, safer_sk128_desc; +#endif + +#ifdef LTC_RIJNDAEL + +/* make aes an alias */ +#define aes_setup rijndael_setup +#define aes_ecb_encrypt rijndael_ecb_encrypt +#define aes_ecb_decrypt rijndael_ecb_decrypt +#define aes_test rijndael_test +#define aes_done rijndael_done +#define aes_keysize rijndael_keysize + +#define aes_enc_setup rijndael_enc_setup +#define aes_enc_ecb_encrypt rijndael_enc_ecb_encrypt +#define aes_enc_keysize rijndael_enc_keysize + +int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int rijndael_test(void); +void rijndael_done(symmetric_key *skey); +int rijndael_keysize(int *keysize); +int rijndael_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +void rijndael_enc_done(symmetric_key *skey); +int rijndael_enc_keysize(int *keysize); +extern const struct ltc_cipher_descriptor rijndael_desc, aes_desc; +extern const struct ltc_cipher_descriptor rijndael_enc_desc, aes_enc_desc; +#endif + +#ifdef LTC_XTEA +int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int xtea_test(void); +void xtea_done(symmetric_key *skey); +int xtea_keysize(int *keysize); +extern const struct ltc_cipher_descriptor xtea_desc; +#endif + +#ifdef LTC_TWOFISH +int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int twofish_test(void); +void twofish_done(symmetric_key *skey); +int twofish_keysize(int *keysize); +extern const struct ltc_cipher_descriptor twofish_desc; +#endif + +#ifdef LTC_DES +int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int des_test(void); +void des_done(symmetric_key *skey); +int des_keysize(int *keysize); +int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int des3_test(void); +void des3_done(symmetric_key *skey); +int des3_keysize(int *keysize); +extern const struct ltc_cipher_descriptor des_desc, des3_desc; +#endif + +#ifdef LTC_CAST5 +int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int cast5_test(void); +void cast5_done(symmetric_key *skey); +int cast5_keysize(int *keysize); +extern const struct ltc_cipher_descriptor cast5_desc; +#endif + +#ifdef LTC_NOEKEON +int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int noekeon_test(void); +void noekeon_done(symmetric_key *skey); +int noekeon_keysize(int *keysize); +extern const struct ltc_cipher_descriptor noekeon_desc; +#endif + +#ifdef LTC_SKIPJACK +int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int skipjack_test(void); +void skipjack_done(symmetric_key *skey); +int skipjack_keysize(int *keysize); +extern const struct ltc_cipher_descriptor skipjack_desc; +#endif + +#ifdef LTC_KHAZAD +int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int khazad_test(void); +void khazad_done(symmetric_key *skey); +int khazad_keysize(int *keysize); +extern const struct ltc_cipher_descriptor khazad_desc; +#endif + +#ifdef LTC_ANUBIS +int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int anubis_test(void); +void anubis_done(symmetric_key *skey); +int anubis_keysize(int *keysize); +extern const struct ltc_cipher_descriptor anubis_desc; +#endif + +#ifdef LTC_KSEED +int kseed_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int kseed_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int kseed_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int kseed_test(void); +void kseed_done(symmetric_key *skey); +int kseed_keysize(int *keysize); +extern const struct ltc_cipher_descriptor kseed_desc; +#endif + +#ifdef LTC_KASUMI +int kasumi_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int kasumi_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int kasumi_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int kasumi_test(void); +void kasumi_done(symmetric_key *skey); +int kasumi_keysize(int *keysize); +extern const struct ltc_cipher_descriptor kasumi_desc; +#endif + + +#ifdef LTC_MULTI2 +int multi2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int multi2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int multi2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int multi2_test(void); +void multi2_done(symmetric_key *skey); +int multi2_keysize(int *keysize); +extern const struct ltc_cipher_descriptor multi2_desc; +#endif + +#ifdef LTC_ECB_MODE +int ecb_start(int cipher, const unsigned char *key, + int keylen, int num_rounds, symmetric_ECB *ecb); +int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_ECB *ecb); +int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_ECB *ecb); +int ecb_done(symmetric_ECB *ecb); +#endif + +#ifdef LTC_CFB_MODE +int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_CFB *cfb); +int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb); +int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb); +int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb); +int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb); +int cfb_done(symmetric_CFB *cfb); +#endif + +#ifdef LTC_OFB_MODE +int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_OFB *ofb); +int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb); +int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb); +int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb); +int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb); +int ofb_done(symmetric_OFB *ofb); +#endif + +#ifdef LTC_CBC_MODE +int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_CBC *cbc); +int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CBC *cbc); +int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CBC *cbc); +int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc); +int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc); +int cbc_done(symmetric_CBC *cbc); +#endif + +#ifdef LTC_CTR_MODE + +#define CTR_COUNTER_LITTLE_ENDIAN 0x0000 +#define CTR_COUNTER_BIG_ENDIAN 0x1000 +#define LTC_CTR_RFC3686 0x2000 + +int ctr_start( int cipher, + const unsigned char *IV, + const unsigned char *key, int keylen, + int num_rounds, int ctr_mode, + symmetric_CTR *ctr); +int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr); +int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr); +int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr); +int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr); +int ctr_done(symmetric_CTR *ctr); +int ctr_test(void); +#endif + +#ifdef LTC_LRW_MODE + +#define LRW_ENCRYPT 0 +#define LRW_DECRYPT 1 + +int lrw_start( int cipher, + const unsigned char *IV, + const unsigned char *key, int keylen, + const unsigned char *tweak, + int num_rounds, + symmetric_LRW *lrw); +int lrw_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_LRW *lrw); +int lrw_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_LRW *lrw); +int lrw_getiv(unsigned char *IV, unsigned long *len, symmetric_LRW *lrw); +int lrw_setiv(const unsigned char *IV, unsigned long len, symmetric_LRW *lrw); +int lrw_done(symmetric_LRW *lrw); +int lrw_test(void); + +/* don't call */ +int lrw_process(const unsigned char *pt, unsigned char *ct, unsigned long len, int mode, symmetric_LRW *lrw); +#endif + +#ifdef LTC_F8_MODE +int f8_start( int cipher, const unsigned char *IV, + const unsigned char *key, int keylen, + const unsigned char *salt_key, int skeylen, + int num_rounds, symmetric_F8 *f8); +int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_F8 *f8); +int f8_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_F8 *f8); +int f8_getiv(unsigned char *IV, unsigned long *len, symmetric_F8 *f8); +int f8_setiv(const unsigned char *IV, unsigned long len, symmetric_F8 *f8); +int f8_done(symmetric_F8 *f8); +int f8_test_mode(void); +#endif + +#ifdef LTC_XTS_MODE +typedef struct { + symmetric_key key1, key2; + int cipher; +} symmetric_xts; + +int xts_start( int cipher, + const unsigned char *key1, + const unsigned char *key2, + unsigned long keylen, + int num_rounds, + symmetric_xts *xts); + +int xts_encrypt( + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + const unsigned char *tweak, + symmetric_xts *xts); +int xts_decrypt( + const unsigned char *ct, unsigned long ptlen, + unsigned char *pt, + const unsigned char *tweak, + symmetric_xts *xts); + +void xts_done(symmetric_xts *xts); +int xts_test(void); +void xts_mult_x(unsigned char *I); +#endif + +int find_cipher(const char *name); +int find_cipher_any(const char *name, int blocklen, int keylen); +int find_cipher_id(unsigned char ID); +int register_cipher(const struct ltc_cipher_descriptor *cipher); +int unregister_cipher(const struct ltc_cipher_descriptor *cipher); +int cipher_is_valid(int idx); + +LTC_MUTEX_PROTO(ltc_cipher_mutex) + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_cipher.h,v $ */ +/* $Revision: 1.54 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_custom.h b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_custom.h new file mode 100644 index 0000000000..117ae00793 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_custom.h @@ -0,0 +1,406 @@ +#ifndef TOMCRYPT_CUSTOM_H_ +#define TOMCRYPT_CUSTOM_H_ + +/* macros for various libc functions you can change for embedded targets */ +#ifndef XMALLOC + #ifdef malloc + #define LTC_NO_PROTOTYPES + #endif +#define XMALLOC malloc +#endif +#ifndef XREALLOC + #ifdef realloc + #define LTC_NO_PROTOTYPES + #endif +#define XREALLOC realloc +#endif +#ifndef XCALLOC + #ifdef calloc + #define LTC_NO_PROTOTYPES + #endif +#define XCALLOC calloc +#endif +#ifndef XFREE + #ifdef free + #define LTC_NO_PROTOTYPES + #endif +#define XFREE free +#endif + +#ifndef XMEMSET + #ifdef memset + #define LTC_NO_PROTOTYPES + #endif +#define XMEMSET memset +#endif +#ifndef XMEMCPY + #ifdef memcpy + #define LTC_NO_PROTOTYPES + #endif +#define XMEMCPY memcpy +#endif +#ifndef XMEMCMP + #ifdef memcmp + #define LTC_NO_PROTOTYPES + #endif +#define XMEMCMP memcmp +#endif +#ifndef XSTRCMP + #ifdef strcmp + #define LTC_NO_PROTOTYPES + #endif +#define XSTRCMP strcmp +#endif + +#ifndef XCLOCK +#define XCLOCK clock +#endif +#ifndef XCLOCKS_PER_SEC +#define XCLOCKS_PER_SEC CLOCKS_PER_SEC +#endif + +#ifndef XQSORT + #ifdef qsort + #define LTC_NO_PROTOTYPES + #endif +#define XQSORT qsort +#endif + +/* Easy button? */ +#ifdef LTC_EASY + #define LTC_NO_CIPHERS + #define LTC_RIJNDAEL + #define LTC_BLOWFISH + #define LTC_DES + #define LTC_CAST5 + + #define LTC_NO_MODES + #define LTC_ECB_MODE + #define LTC_CBC_MODE + #define LTC_CTR_MODE + + #define LTC_NO_HASHES + #define LTC_SHA1 + #define LTC_SHA512 + #define LTC_SHA384 + #define LTC_SHA256 + #define LTC_SHA224 + + #define LTC_NO_MACS + #define LTC_HMAC + #define LTC_OMAC + #define LTC_CCM_MODE + + #define LTC_NO_PRNGS + #define LTC_SPRNG + #define LTC_YARROW + #define LTC_DEVRANDOM + #define TRY_URANDOM_FIRST + + #define LTC_NO_PK + #define LTC_MRSA + #define LTC_MECC +#endif + +/* Use small code where possible */ +/* #define LTC_SMALL_CODE */ + +/* Enable self-test test vector checking */ +#ifndef LTC_NO_TEST + #define LTC_TEST +#endif + +/* clean the stack of functions which put private information on stack */ +/* #define LTC_CLEAN_STACK */ + +/* disable all file related functions */ +/* #define LTC_NO_FILE */ + +/* disable all forms of ASM */ +/* #define LTC_NO_ASM */ + +/* disable FAST mode */ +/* #define LTC_NO_FAST */ + +/* disable BSWAP on x86 */ +/* #define LTC_NO_BSWAP */ + +/* ---> Symmetric Block Ciphers <--- */ +#ifndef LTC_NO_CIPHERS + +#define LTC_BLOWFISH +#define LTC_RC2 +#define LTC_RC5 +#define LTC_RC6 +#define LTC_SAFERP +#define LTC_RIJNDAEL +#define LTC_XTEA +/* _TABLES tells it to use tables during setup, _SMALL means to use the smaller scheduled key format + * (saves 4KB of ram), _ALL_TABLES enables all tables during setup */ +#define LTC_TWOFISH +#ifndef LTC_NO_TABLES + #define LTC_TWOFISH_TABLES + /* #define LTC_TWOFISH_ALL_TABLES */ +#else + #define LTC_TWOFISH_SMALL +#endif +/* #define LTC_TWOFISH_SMALL */ +/* LTC_DES includes EDE triple-LTC_DES */ +#define LTC_DES +#define LTC_CAST5 +#define LTC_NOEKEON +#define LTC_SKIPJACK +#define LTC_SAFER +#define LTC_KHAZAD +#define LTC_ANUBIS +#define LTC_ANUBIS_TWEAK +#define LTC_KSEED +#define LTC_KASUMI + +#endif /* LTC_NO_CIPHERS */ + + +/* ---> Block Cipher Modes of Operation <--- */ +#ifndef LTC_NO_MODES + +#define LTC_CFB_MODE +#define LTC_OFB_MODE +#define LTC_ECB_MODE +#define LTC_CBC_MODE +#define LTC_CTR_MODE + +/* F8 chaining mode */ +#define LTC_F8_MODE + +/* LRW mode */ +#define LTC_LRW_MODE +#ifndef LTC_NO_TABLES + /* like GCM mode this will enable 16 8x128 tables [64KB] that make + * seeking very fast. + */ + #define LRW_TABLES +#endif + +/* XTS mode */ +#define LTC_XTS_MODE + +#endif /* LTC_NO_MODES */ + +/* ---> One-Way Hash Functions <--- */ +#ifndef LTC_NO_HASHES + +#define LTC_CHC_HASH +#define LTC_WHIRLPOOL +#define LTC_SHA512 +#define LTC_SHA384 +#define LTC_SHA256 +#define LTC_SHA224 +#define LTC_TIGER +#define LTC_SHA1 +#define LTC_MD5 +#define LTC_MD4 +#define LTC_MD2 +#define LTC_RIPEMD128 +#define LTC_RIPEMD160 +#define LTC_RIPEMD256 +#define LTC_RIPEMD320 + +#endif /* LTC_NO_HASHES */ + +/* ---> MAC functions <--- */ +#ifndef LTC_NO_MACS + +#define LTC_HMAC +#define LTC_OMAC +#define LTC_PMAC +#define LTC_XCBC +#define LTC_F9_MODE +#define LTC_PELICAN + +#if defined(LTC_PELICAN) && !defined(LTC_RIJNDAEL) + #error Pelican-MAC requires LTC_RIJNDAEL +#endif + +/* ---> Encrypt + Authenticate Modes <--- */ + +#define LTC_EAX_MODE +#if defined(LTC_EAX_MODE) && !(defined(LTC_CTR_MODE) && defined(LTC_OMAC)) + #error LTC_EAX_MODE requires CTR and LTC_OMAC mode +#endif + +#define LTC_OCB_MODE +#define LTC_CCM_MODE +#define LTC_GCM_MODE + +/* Use 64KiB tables */ +#ifndef LTC_NO_TABLES + #define LTC_GCM_TABLES +#endif + +/* USE SSE2? requires GCC works on x86_32 and x86_64*/ +#ifdef LTC_GCM_TABLES +/* #define LTC_GCM_TABLES_SSE2 */ +#endif + +#endif /* LTC_NO_MACS */ + +/* Various tidbits of modern neatoness */ +#define LTC_BASE64 + +/* --> Pseudo Random Number Generators <--- */ +#ifndef LTC_NO_PRNGS + +/* Yarrow */ +#define LTC_YARROW +/* which descriptor of AES to use? */ +/* 0 = rijndael_enc 1 = aes_enc, 2 = rijndael [full], 3 = aes [full] */ +#define LTC_YARROW_AES 0 + +#if defined(LTC_YARROW) && !defined(LTC_CTR_MODE) + #error LTC_YARROW requires LTC_CTR_MODE chaining mode to be defined! +#endif + +/* a PRNG that simply reads from an available system source */ +#define LTC_SPRNG + +/* The LTC_RC4 stream cipher */ +#define LTC_RC4 + +/* Fortuna PRNG */ +#define LTC_FORTUNA +/* reseed every N calls to the read function */ +#define LTC_FORTUNA_WD 10 +/* number of pools (4..32) can save a bit of ram by lowering the count */ +#define LTC_FORTUNA_POOLS 32 + +/* Greg's LTC_SOBER128 PRNG ;-0 */ +#define LTC_SOBER128 + +/* the *nix style /dev/random device */ +#define LTC_DEVRANDOM +/* try /dev/urandom before trying /dev/random */ +#define TRY_URANDOM_FIRST + +#endif /* LTC_NO_PRNGS */ + +/* ---> math provider? <--- */ +#ifndef LTC_NO_MATH + +/* LibTomMath */ +/* #define LTM_LTC_DESC */ + +/* TomsFastMath */ +/* #define TFM_LTC_DESC */ + +#endif /* LTC_NO_MATH */ + +/* ---> Public Key Crypto <--- */ +#ifndef LTC_NO_PK + +/* Include RSA support */ +#define LTC_MRSA + +/* Include Katja (a Rabin variant like RSA) */ +/* #define MKAT */ + +/* Digital Signature Algorithm */ +#define LTC_MDSA + +/* ECC */ +#define LTC_MECC + +/* use Shamir's trick for point mul (speeds up signature verification) */ +#define LTC_ECC_SHAMIR + +#if defined(TFM_LTC_DESC) && defined(LTC_MECC) + #define LTC_MECC_ACCEL +#endif + +/* do we want fixed point ECC */ +/* #define LTC_MECC_FP */ + +/* Timing Resistant? */ +/* #define LTC_ECC_TIMING_RESISTANT */ + +#endif /* LTC_NO_PK */ + +/* LTC_PKCS #1 (RSA) and #5 (Password Handling) stuff */ +#ifndef LTC_NO_PKCS + +#define LTC_PKCS_1 +#define LTC_PKCS_5 + +/* Include ASN.1 DER (required by DSA/RSA) */ +#define LTC_DER + +#endif /* LTC_NO_PKCS */ + +/* cleanup */ + +#ifdef LTC_MECC +/* Supported ECC Key Sizes */ +#ifndef LTC_NO_CURVES + #define ECC112 + #define ECC128 + #define ECC160 + #define ECC192 + #define ECC224 + #define ECC256 + #define ECC384 + #define ECC521 +#endif +#endif + +#if defined(LTC_MECC) || defined(LTC_MRSA) || defined(LTC_MDSA) || defined(MKATJA) + /* Include the MPI functionality? (required by the PK algorithms) */ + #define MPI +#endif + +#ifdef LTC_MRSA + #define LTC_PKCS_1 +#endif + +#if defined(LTC_DER) && !defined(MPI) + #error ASN.1 DER requires MPI functionality +#endif + +#if (defined(LTC_MDSA) || defined(LTC_MRSA) || defined(LTC_MECC) || defined(MKATJA)) && !defined(LTC_DER) + #error PK requires ASN.1 DER functionality, make sure LTC_DER is enabled +#endif + +/* THREAD management */ +#ifdef LTC_PTHREAD + +#include + +#define LTC_MUTEX_GLOBAL(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER; +#define LTC_MUTEX_PROTO(x) extern pthread_mutex_t x; +#define LTC_MUTEX_TYPE(x) pthread_mutex_t x; +#define LTC_MUTEX_INIT(x) pthread_mutex_init(x, NULL); +#define LTC_MUTEX_LOCK(x) pthread_mutex_lock(x); +#define LTC_MUTEX_UNLOCK(x) pthread_mutex_unlock(x); + +#else + +/* default no functions */ +#define LTC_MUTEX_GLOBAL(x) +#define LTC_MUTEX_PROTO(x) +#define LTC_MUTEX_TYPE(x) +#define LTC_MUTEX_INIT(x) +#define LTC_MUTEX_LOCK(x) +#define LTC_MUTEX_UNLOCK(x) + +#endif + +/* Debuggers */ + +/* define this if you use Valgrind, note: it CHANGES the way SOBER-128 and LTC_RC4 work (see the code) */ +/* #define LTC_VALGRIND */ + +#endif + + + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_custom.h,v $ */ +/* $Revision: 1.73 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_hash.h b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_hash.h new file mode 100644 index 0000000000..791f247d9d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_hash.h @@ -0,0 +1,381 @@ +/* ---- HASH FUNCTIONS ---- */ +#ifdef LTC_SHA512 +struct sha512_state { + ulong64 length, state[8]; + unsigned long curlen; + unsigned char buf[128]; +}; +#endif + +#ifdef LTC_SHA256 +struct sha256_state { + ulong64 length; + ulong32 state[8], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef LTC_SHA1 +struct sha1_state { + ulong64 length; + ulong32 state[5], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef LTC_MD5 +struct md5_state { + ulong64 length; + ulong32 state[4], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef LTC_MD4 +struct md4_state { + ulong64 length; + ulong32 state[4], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef LTC_TIGER +struct tiger_state { + ulong64 state[3], length; + unsigned long curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef LTC_MD2 +struct md2_state { + unsigned char chksum[16], X[48], buf[16]; + unsigned long curlen; +}; +#endif + +#ifdef LTC_RIPEMD128 +struct rmd128_state { + ulong64 length; + unsigned char buf[64]; + ulong32 curlen, state[4]; +}; +#endif + +#ifdef LTC_RIPEMD160 +struct rmd160_state { + ulong64 length; + unsigned char buf[64]; + ulong32 curlen, state[5]; +}; +#endif + +#ifdef LTC_RIPEMD256 +struct rmd256_state { + ulong64 length; + unsigned char buf[64]; + ulong32 curlen, state[8]; +}; +#endif + +#ifdef LTC_RIPEMD320 +struct rmd320_state { + ulong64 length; + unsigned char buf[64]; + ulong32 curlen, state[10]; +}; +#endif + +#ifdef LTC_WHIRLPOOL +struct whirlpool_state { + ulong64 length, state[8]; + unsigned char buf[64]; + ulong32 curlen; +}; +#endif + +#ifdef LTC_CHC_HASH +struct chc_state { + ulong64 length; + unsigned char state[MAXBLOCKSIZE], buf[MAXBLOCKSIZE]; + ulong32 curlen; +}; +#endif + +typedef union Hash_state { + char dummy[1]; +#ifdef LTC_CHC_HASH + struct chc_state chc; +#endif +#ifdef LTC_WHIRLPOOL + struct whirlpool_state whirlpool; +#endif +#ifdef LTC_SHA512 + struct sha512_state sha512; +#endif +#ifdef LTC_SHA256 + struct sha256_state sha256; +#endif +#ifdef LTC_SHA1 + struct sha1_state sha1; +#endif +#ifdef LTC_MD5 + struct md5_state md5; +#endif +#ifdef LTC_MD4 + struct md4_state md4; +#endif +#ifdef LTC_MD2 + struct md2_state md2; +#endif +#ifdef LTC_TIGER + struct tiger_state tiger; +#endif +#ifdef LTC_RIPEMD128 + struct rmd128_state rmd128; +#endif +#ifdef LTC_RIPEMD160 + struct rmd160_state rmd160; +#endif +#ifdef LTC_RIPEMD256 + struct rmd256_state rmd256; +#endif +#ifdef LTC_RIPEMD320 + struct rmd320_state rmd320; +#endif + void *data; +} hash_state; + +/** hash descriptor */ +extern struct ltc_hash_descriptor { + /** name of hash */ + char *name; + /** internal ID */ + unsigned char ID; + /** Size of digest in octets */ + unsigned long hashsize; + /** Input block size in octets */ + unsigned long blocksize; + /** ASN.1 OID */ + unsigned long OID[16]; + /** Length of DER encoding */ + unsigned long OIDlen; + + /** Init a hash state + @param hash The hash to initialize + @return CRYPT_OK if successful + */ + int (*init)(hash_state *hash); + /** Process a block of data + @param hash The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful + */ + int (*process)(hash_state *hash, const unsigned char *in, unsigned long inlen); + /** Produce the digest and store it + @param hash The hash state + @param out [out] The destination of the digest + @return CRYPT_OK if successful + */ + int (*done)(hash_state *hash, unsigned char *out); + /** Self-test + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled + */ + int (*test)(void); + + /* accelerated hmac callback: if you need to-do multiple packets just use the generic hmac_memory and provide a hash callback */ + int (*hmac_block)(const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +} hash_descriptor[]; + +#ifdef LTC_CHC_HASH +int chc_register(int cipher); +int chc_init(hash_state * md); +int chc_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int chc_done(hash_state * md, unsigned char *hash); +int chc_test(void); +extern const struct ltc_hash_descriptor chc_desc; +#endif + +#ifdef LTC_WHIRLPOOL +int whirlpool_init(hash_state * md); +int whirlpool_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int whirlpool_done(hash_state * md, unsigned char *hash); +int whirlpool_test(void); +extern const struct ltc_hash_descriptor whirlpool_desc; +#endif + +#ifdef LTC_SHA512 +int sha512_init(hash_state * md); +int sha512_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int sha512_done(hash_state * md, unsigned char *hash); +int sha512_test(void); +extern const struct ltc_hash_descriptor sha512_desc; +#endif + +#ifdef LTC_SHA384 +#ifndef LTC_SHA512 + #error LTC_SHA512 is required for LTC_SHA384 +#endif +int sha384_init(hash_state * md); +#define sha384_process sha512_process +int sha384_done(hash_state * md, unsigned char *hash); +int sha384_test(void); +extern const struct ltc_hash_descriptor sha384_desc; +#endif + +#ifdef LTC_SHA256 +int sha256_init(hash_state * md); +int sha256_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int sha256_done(hash_state * md, unsigned char *hash); +int sha256_test(void); +extern const struct ltc_hash_descriptor sha256_desc; + +#ifdef LTC_SHA224 +#ifndef LTC_SHA256 + #error LTC_SHA256 is required for LTC_SHA224 +#endif +int sha224_init(hash_state * md); +#define sha224_process sha256_process +int sha224_done(hash_state * md, unsigned char *hash); +int sha224_test(void); +extern const struct ltc_hash_descriptor sha224_desc; +#endif +#endif + +#ifdef LTC_SHA1 +int sha1_init(hash_state * md); +int sha1_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int sha1_done(hash_state * md, unsigned char *hash); +int sha1_test(void); +extern const struct ltc_hash_descriptor sha1_desc; +#endif + +#ifdef LTC_MD5 +int md5_init(hash_state * md); +int md5_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int md5_done(hash_state * md, unsigned char *hash); +int md5_test(void); +extern const struct ltc_hash_descriptor md5_desc; +#endif + +#ifdef LTC_MD4 +int md4_init(hash_state * md); +int md4_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int md4_done(hash_state * md, unsigned char *hash); +int md4_test(void); +extern const struct ltc_hash_descriptor md4_desc; +#endif + +#ifdef LTC_MD2 +int md2_init(hash_state * md); +int md2_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int md2_done(hash_state * md, unsigned char *hash); +int md2_test(void); +extern const struct ltc_hash_descriptor md2_desc; +#endif + +#ifdef LTC_TIGER +int tiger_init(hash_state * md); +int tiger_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int tiger_done(hash_state * md, unsigned char *hash); +int tiger_test(void); +extern const struct ltc_hash_descriptor tiger_desc; +#endif + +#ifdef LTC_RIPEMD128 +int rmd128_init(hash_state * md); +int rmd128_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int rmd128_done(hash_state * md, unsigned char *hash); +int rmd128_test(void); +extern const struct ltc_hash_descriptor rmd128_desc; +#endif + +#ifdef LTC_RIPEMD160 +int rmd160_init(hash_state * md); +int rmd160_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int rmd160_done(hash_state * md, unsigned char *hash); +int rmd160_test(void); +extern const struct ltc_hash_descriptor rmd160_desc; +#endif + +#ifdef LTC_RIPEMD256 +int rmd256_init(hash_state * md); +int rmd256_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int rmd256_done(hash_state * md, unsigned char *hash); +int rmd256_test(void); +extern const struct ltc_hash_descriptor rmd256_desc; +#endif + +#ifdef LTC_RIPEMD320 +int rmd320_init(hash_state * md); +int rmd320_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int rmd320_done(hash_state * md, unsigned char *hash); +int rmd320_test(void); +extern const struct ltc_hash_descriptor rmd320_desc; +#endif + + +int find_hash(const char *name); +int find_hash_id(unsigned char ID); +int find_hash_oid(const unsigned long *ID, unsigned long IDlen); +int find_hash_any(const char *name, int digestlen); +int register_hash(const struct ltc_hash_descriptor *hash); +int unregister_hash(const struct ltc_hash_descriptor *hash); +int hash_is_valid(int idx); + +LTC_MUTEX_PROTO(ltc_hash_mutex) + +int hash_memory(int hash, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...); +#ifndef LTC_NO_FILE +int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen); +int hash_file(int hash, const char *fname, unsigned char *out, unsigned long *outlen); +#endif + +/* a simple macro for making hash "process" functions */ +#define HASH_PROCESS(func_name, compress_name, state_var, block_size) \ +int func_name (hash_state * md, const unsigned char *in, unsigned long inlen) \ +{ \ + unsigned long n; \ + int err; \ + LTC_ARGCHK(md != NULL); \ + LTC_ARGCHK(in != NULL); \ + if (md-> state_var .curlen > sizeof(md-> state_var .buf)) { \ + return CRYPT_INVALID_ARG; \ + } \ + while (inlen > 0) { \ + if (md-> state_var .curlen == 0 && inlen >= block_size) { \ + if ((err = compress_name (md, (unsigned char *)in)) != CRYPT_OK) { \ + return err; \ + } \ + md-> state_var .length += block_size * 8; \ + in += block_size; \ + inlen -= block_size; \ + } else { \ + n = MIN(inlen, (block_size - md-> state_var .curlen)); \ + memcpy(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n); \ + md-> state_var .curlen += n; \ + in += n; \ + inlen -= n; \ + if (md-> state_var .curlen == block_size) { \ + if ((err = compress_name (md, md-> state_var .buf)) != CRYPT_OK) { \ + return err; \ + } \ + md-> state_var .length += 8*block_size; \ + md-> state_var .curlen = 0; \ + } \ + } \ + } \ + return CRYPT_OK; \ +} + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_hash.h,v $ */ +/* $Revision: 1.22 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_mac.h b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_mac.h new file mode 100644 index 0000000000..2501b72461 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_mac.h @@ -0,0 +1,384 @@ +#ifdef LTC_HMAC +typedef struct Hmac_state { + hash_state md; + int hash; + hash_state hashstate; + unsigned char *key; +} hmac_state; + +int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen); +int hmac_process(hmac_state *hmac, const unsigned char *in, unsigned long inlen); +int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen); +int hmac_test(void); +int hmac_memory(int hash, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int hmac_memory_multi(int hash, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...); +int hmac_file(int hash, const char *fname, const unsigned char *key, + unsigned long keylen, + unsigned char *dst, unsigned long *dstlen); +#endif + +#ifdef LTC_OMAC + +typedef struct { + int cipher_idx, + buflen, + blklen; + unsigned char block[MAXBLOCKSIZE], + prev[MAXBLOCKSIZE], + Lu[2][MAXBLOCKSIZE]; + symmetric_key key; +} omac_state; + +int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen); +int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen); +int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen); +int omac_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int omac_memory_multi(int cipher, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...); +int omac_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen); +int omac_test(void); +#endif /* LTC_OMAC */ + +#ifdef LTC_PMAC + +typedef struct { + unsigned char Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */ + Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */ + Lr[MAXBLOCKSIZE], /* L * x^-1 */ + block[MAXBLOCKSIZE], /* currently accumulated block */ + checksum[MAXBLOCKSIZE]; /* current checksum */ + + symmetric_key key; /* scheduled key for cipher */ + unsigned long block_index; /* index # for current block */ + int cipher_idx, /* cipher idx */ + block_len, /* length of block */ + buflen; /* number of bytes in the buffer */ +} pmac_state; + +int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen); +int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen); +int pmac_done(pmac_state *pmac, unsigned char *out, unsigned long *outlen); + +int pmac_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *msg, unsigned long msglen, + unsigned char *out, unsigned long *outlen); + +int pmac_memory_multi(int cipher, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...); + +int pmac_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen); + +int pmac_test(void); + +/* internal functions */ +int pmac_ntz(unsigned long x); +void pmac_shift_xor(pmac_state *pmac); + +#endif /* PMAC */ + +#ifdef LTC_EAX_MODE + +#if !(defined(LTC_OMAC) && defined(LTC_CTR_MODE)) + #error LTC_EAX_MODE requires LTC_OMAC and CTR +#endif + +typedef struct { + unsigned char N[MAXBLOCKSIZE]; + symmetric_CTR ctr; + omac_state headeromac, ctomac; +} eax_state; + +int eax_init(eax_state *eax, int cipher, const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen); + +int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length); +int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length); +int eax_addheader(eax_state *eax, const unsigned char *header, unsigned long length); +int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen); + +int eax_encrypt_authenticate_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen); + +int eax_decrypt_verify_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + unsigned char *tag, unsigned long taglen, + int *stat); + + int eax_test(void); +#endif /* EAX MODE */ + +#ifdef LTC_OCB_MODE +typedef struct { + unsigned char L[MAXBLOCKSIZE], /* L value */ + Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */ + Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */ + Lr[MAXBLOCKSIZE], /* L * x^-1 */ + R[MAXBLOCKSIZE], /* R value */ + checksum[MAXBLOCKSIZE]; /* current checksum */ + + symmetric_key key; /* scheduled key for cipher */ + unsigned long block_index; /* index # for current block */ + int cipher, /* cipher idx */ + block_len; /* length of block */ +} ocb_state; + +int ocb_init(ocb_state *ocb, int cipher, + const unsigned char *key, unsigned long keylen, const unsigned char *nonce); + +int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct); +int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt); + +int ocb_done_encrypt(ocb_state *ocb, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen); + +int ocb_done_decrypt(ocb_state *ocb, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + const unsigned char *tag, unsigned long taglen, int *stat); + +int ocb_encrypt_authenticate_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen); + +int ocb_decrypt_verify_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + const unsigned char *tag, unsigned long taglen, + int *stat); + +int ocb_test(void); + +/* internal functions */ +void ocb_shift_xor(ocb_state *ocb, unsigned char *Z); +int ocb_ntz(unsigned long x); +int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode); + +#endif /* LTC_OCB_MODE */ + +#ifdef LTC_CCM_MODE + +#define CCM_ENCRYPT 0 +#define CCM_DECRYPT 1 + +int ccm_memory(int cipher, + const unsigned char *key, unsigned long keylen, + symmetric_key *uskey, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); + +int ccm_test(void); + +#endif /* LTC_CCM_MODE */ + +#if defined(LRW_MODE) || defined(LTC_GCM_MODE) +void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c); +#endif + + +/* table shared between GCM and LRW */ +#if defined(LTC_GCM_TABLES) || defined(LRW_TABLES) || ((defined(LTC_GCM_MODE) || defined(LTC_GCM_MODE)) && defined(LTC_FAST)) +extern const unsigned char gcm_shift_table[]; +#endif + +#ifdef LTC_GCM_MODE + +#define GCM_ENCRYPT 0 +#define GCM_DECRYPT 1 + +#define LTC_GCM_MODE_IV 0 +#define LTC_GCM_MODE_AAD 1 +#define LTC_GCM_MODE_TEXT 2 + +typedef struct { + symmetric_key K; + unsigned char H[16], /* multiplier */ + X[16], /* accumulator */ + Y[16], /* counter */ + Y_0[16], /* initial counter */ + buf[16]; /* buffer for stuff */ + + int cipher, /* which cipher */ + ivmode, /* Which mode is the IV in? */ + mode, /* mode the GCM code is in */ + buflen; /* length of data in buf */ + + ulong64 totlen, /* 64-bit counter used for IV and AAD */ + pttotlen; /* 64-bit counter for the PT */ + +#ifdef LTC_GCM_TABLES + unsigned char PC[16][256][16] /* 16 tables of 8x128 */ +#ifdef LTC_GCM_TABLES_SSE2 +__attribute__ ((aligned (16))) +#endif +; +#endif +} gcm_state; + +void gcm_mult_h(gcm_state *gcm, unsigned char *I); + +int gcm_init(gcm_state *gcm, int cipher, + const unsigned char *key, int keylen); + +int gcm_reset(gcm_state *gcm); + +int gcm_add_iv(gcm_state *gcm, + const unsigned char *IV, unsigned long IVlen); + +int gcm_add_aad(gcm_state *gcm, + const unsigned char *adata, unsigned long adatalen); + +int gcm_process(gcm_state *gcm, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + int direction); + +int gcm_done(gcm_state *gcm, + unsigned char *tag, unsigned long *taglen); + +int gcm_memory( int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *IV, unsigned long IVlen, + const unsigned char *adata, unsigned long adatalen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); +int gcm_test(void); + +#endif /* LTC_GCM_MODE */ + +#ifdef LTC_PELICAN + +typedef struct pelican_state +{ + symmetric_key K; + unsigned char state[16]; + int buflen; +} pelican_state; + +int pelican_init(pelican_state *pelmac, const unsigned char *key, unsigned long keylen); +int pelican_process(pelican_state *pelmac, const unsigned char *in, unsigned long inlen); +int pelican_done(pelican_state *pelmac, unsigned char *out); +int pelican_test(void); + +int pelican_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out); + +#endif + +#ifdef LTC_XCBC + +/* add this to "keylen" to xcbc_init to use a pure three-key XCBC MAC */ +#define LTC_XCBC_PURE 0x8000UL + +typedef struct { + unsigned char K[3][MAXBLOCKSIZE], + IV[MAXBLOCKSIZE]; + + symmetric_key key; + + int cipher, + buflen, + blocksize; +} xcbc_state; + +int xcbc_init(xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned long keylen); +int xcbc_process(xcbc_state *xcbc, const unsigned char *in, unsigned long inlen); +int xcbc_done(xcbc_state *xcbc, unsigned char *out, unsigned long *outlen); +int xcbc_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int xcbc_memory_multi(int cipher, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...); +int xcbc_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen); +int xcbc_test(void); + +#endif + +#ifdef LTC_F9_MODE + +typedef struct { + unsigned char akey[MAXBLOCKSIZE], + ACC[MAXBLOCKSIZE], + IV[MAXBLOCKSIZE]; + + symmetric_key key; + + int cipher, + buflen, + keylen, + blocksize; +} f9_state; + +int f9_init(f9_state *f9, int cipher, const unsigned char *key, unsigned long keylen); +int f9_process(f9_state *f9, const unsigned char *in, unsigned long inlen); +int f9_done(f9_state *f9, unsigned char *out, unsigned long *outlen); +int f9_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int f9_memory_multi(int cipher, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...); +int f9_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen); +int f9_test(void); + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_mac.h,v $ */ +/* $Revision: 1.23 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_macros.h b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_macros.h new file mode 100644 index 0000000000..3ee4b2914a --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_macros.h @@ -0,0 +1,424 @@ +/* fix for MSVC ...evil! */ +#ifdef _MSC_VER + #define CONST64(n) n ## ui64 + typedef unsigned __int64 ulong64; +#else + #define CONST64(n) n ## ULL + typedef unsigned long long ulong64; +#endif + +/* this is the "32-bit at least" data type + * Re-define it to suit your platform but it must be at least 32-bits + */ +#if defined(__x86_64__) || (defined(__sparc__) && defined(__arch64__)) + typedef unsigned ulong32; +#else + typedef unsigned long ulong32; +#endif + +/* ---- HELPER MACROS ---- */ +#ifdef ENDIAN_NEUTRAL + +#define STORE32L(x, y) \ + { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD32L(x, y) \ + { x = ((unsigned long)((y)[3] & 255)<<24) | \ + ((unsigned long)((y)[2] & 255)<<16) | \ + ((unsigned long)((y)[1] & 255)<<8) | \ + ((unsigned long)((y)[0] & 255)); } + +#define STORE64L(x, y) \ + { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD64L(x, y) \ + { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } + +#define STORE32H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ + (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } + +#define LOAD32H(x, y) \ + { x = ((unsigned long)((y)[0] & 255)<<24) | \ + ((unsigned long)((y)[1] & 255)<<16) | \ + ((unsigned long)((y)[2] & 255)<<8) | \ + ((unsigned long)((y)[3] & 255)); } + +#define STORE64H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + +#define LOAD64H(x, y) \ + { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ + (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } + +#endif /* ENDIAN_NEUTRAL */ + +#ifdef ENDIAN_LITTLE + +#if !defined(LTC_NO_BSWAP) && (defined(INTEL_CC) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__) || defined(__x86_64__)))) + +#define STORE32H(x, y) \ +asm __volatile__ ( \ + "bswapl %0 \n\t" \ + "movl %0,(%1)\n\t" \ + "bswapl %0 \n\t" \ + ::"r"(x), "r"(y)); + +#define LOAD32H(x, y) \ +asm __volatile__ ( \ + "movl (%1),%0\n\t" \ + "bswapl %0\n\t" \ + :"=r"(x): "r"(y)); + +#else + +#define STORE32H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ + (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } + +#define LOAD32H(x, y) \ + { x = ((unsigned long)((y)[0] & 255)<<24) | \ + ((unsigned long)((y)[1] & 255)<<16) | \ + ((unsigned long)((y)[2] & 255)<<8) | \ + ((unsigned long)((y)[3] & 255)); } + +#endif + + +/* x86_64 processor */ +#if !defined(LTC_NO_BSWAP) && (defined(__GNUC__) && defined(__x86_64__)) + +#define STORE64H(x, y) \ +asm __volatile__ ( \ + "bswapq %0 \n\t" \ + "movq %0,(%1)\n\t" \ + "bswapq %0 \n\t" \ + ::"r"(x), "r"(y)); + +#define LOAD64H(x, y) \ +asm __volatile__ ( \ + "movq (%1),%0\n\t" \ + "bswapq %0\n\t" \ + :"=r"(x): "r"(y)); + +#else + +#define STORE64H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + +#define LOAD64H(x, y) \ + { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ + (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } + +#endif + +#ifdef ENDIAN_32BITWORD + +#define STORE32L(x, y) \ + { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } + +#define LOAD32L(x, y) \ + XMEMCPY(&(x), y, 4); + +#define STORE64L(x, y) \ + { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD64L(x, y) \ + { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } + +#else /* 64-bit words then */ + +#define STORE32L(x, y) \ + { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } + +#define LOAD32L(x, y) \ + { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } + +#define STORE64L(x, y) \ + { ulong64 __t = (x); XMEMCPY(y, &__t, 8); } + +#define LOAD64L(x, y) \ + { XMEMCPY(&(x), y, 8); } + +#endif /* ENDIAN_64BITWORD */ + +#endif /* ENDIAN_LITTLE */ + +#ifdef ENDIAN_BIG +#define STORE32L(x, y) \ + { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD32L(x, y) \ + { x = ((unsigned long)((y)[3] & 255)<<24) | \ + ((unsigned long)((y)[2] & 255)<<16) | \ + ((unsigned long)((y)[1] & 255)<<8) | \ + ((unsigned long)((y)[0] & 255)); } + +#define STORE64L(x, y) \ + { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD64L(x, y) \ + { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } + +#ifdef ENDIAN_32BITWORD + +#define STORE32H(x, y) \ + { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } + +#define LOAD32H(x, y) \ + XMEMCPY(&(x), y, 4); + +#define STORE64H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + +#define LOAD64H(x, y) \ + { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \ + (((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); } + +#else /* 64-bit words then */ + +#define STORE32H(x, y) \ + { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } + +#define LOAD32H(x, y) \ + { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } + +#define STORE64H(x, y) \ + { ulong64 __t = (x); XMEMCPY(y, &__t, 8); } + +#define LOAD64H(x, y) \ + { XMEMCPY(&(x), y, 8); } + +#endif /* ENDIAN_64BITWORD */ +#endif /* ENDIAN_BIG */ + +#define BSWAP(x) ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL) | \ + ((x>>8)&0x0000FF00UL) | ((x<<8)&0x00FF0000UL) ) + + +/* 32-bit Rotates */ +#if defined(_MSC_VER) + +/* instrinsic rotate */ +#include +#pragma intrinsic(_lrotr,_lrotl) +#define ROR(x,n) _lrotr(x,n) +#define ROL(x,n) _lrotl(x,n) +#define RORc(x,n) _lrotr(x,n) +#define ROLc(x,n) _lrotl(x,n) + +#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(INTEL_CC) && !defined(LTC_NO_ASM) + +static inline unsigned ROL(unsigned word, int i) +{ + asm ("roll %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +static inline unsigned ROR(unsigned word, int i) +{ + asm ("rorl %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +#ifndef LTC_NO_ROLC + +static inline unsigned ROLc(unsigned word, const int i) +{ + asm ("roll %2,%0" + :"=r" (word) + :"0" (word),"I" (i)); + return word; +} + +static inline unsigned RORc(unsigned word, const int i) +{ + asm ("rorl %2,%0" + :"=r" (word) + :"0" (word),"I" (i)); + return word; +} + +#else + +#define ROLc ROL +#define RORc ROR + +#endif + +#elif !defined(__STRICT_ANSI__) && defined(LTC_PPC32) + +static inline unsigned ROL(unsigned word, int i) +{ + asm ("rotlw %0,%0,%2" + :"=r" (word) + :"0" (word),"r" (i)); + return word; +} + +static inline unsigned ROR(unsigned word, int i) +{ + asm ("rotlw %0,%0,%2" + :"=r" (word) + :"0" (word),"r" (32-i)); + return word; +} + +#ifndef LTC_NO_ROLC + +static inline unsigned ROLc(unsigned word, const int i) +{ + asm ("rotlwi %0,%0,%2" + :"=r" (word) + :"0" (word),"I" (i)); + return word; +} + +static inline unsigned RORc(unsigned word, const int i) +{ + asm ("rotrwi %0,%0,%2" + :"=r" (word) + :"0" (word),"I" (i)); + return word; +} + +#else + +#define ROLc ROL +#define RORc ROR + +#endif + + +#else + +/* rotates the hard way */ +#define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) +#define ROR(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) +#define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) +#define RORc(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) + +#endif + + +/* 64-bit Rotates */ +#if !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__x86_64__) && !defined(LTC_NO_ASM) + +static inline unsigned long ROL64(unsigned long word, int i) +{ + asm("rolq %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +static inline unsigned long ROR64(unsigned long word, int i) +{ + asm("rorq %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +#ifndef LTC_NO_ROLC + +static inline unsigned long ROL64c(unsigned long word, const int i) +{ + asm("rolq %2,%0" + :"=r" (word) + :"0" (word),"J" (i)); + return word; +} + +static inline unsigned long ROR64c(unsigned long word, const int i) +{ + asm("rorq %2,%0" + :"=r" (word) + :"0" (word),"J" (i)); + return word; +} + +#else /* LTC_NO_ROLC */ + +#define ROL64c ROL64 +#define ROR64c ROR64 + +#endif + +#else /* Not x86_64 */ + +#define ROL64(x, y) \ + ( (((x)<<((ulong64)(y)&63)) | \ + (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#define ROR64(x, y) \ + ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \ + ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#define ROL64c(x, y) \ + ( (((x)<<((ulong64)(y)&63)) | \ + (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#define ROR64c(x, y) \ + ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \ + ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#endif + +#ifndef MAX + #define MAX(x, y) ( ((x)>(y))?(x):(y) ) +#endif + +#ifndef MIN + #define MIN(x, y) ( ((x)<(y))?(x):(y) ) +#endif + +/* extract a byte portably */ +#ifdef _MSC_VER + #define byte(x, n) ((unsigned char)((x) >> (8 * (n)))) +#else + #define byte(x, n) (((x) >> (8 * (n))) & 255) +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_macros.h,v $ */ +/* $Revision: 1.15 $ */ +/* $Date: 2006/11/29 23:43:57 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_math.h b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_math.h new file mode 100644 index 0000000000..08a29dbe1a --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_math.h @@ -0,0 +1,500 @@ +/** math functions **/ + +#define LTC_MP_LT -1 +#define LTC_MP_EQ 0 +#define LTC_MP_GT 1 + +#define LTC_MP_NO 0 +#define LTC_MP_YES 1 + +#ifndef LTC_MECC + typedef void ecc_point; +#endif + +#ifndef LTC_MRSA + typedef void rsa_key; +#endif + +/** math descriptor */ +typedef struct { + /** Name of the math provider */ + char *name; + + /** Bits per digit, amount of bits must fit in an unsigned long */ + int bits_per_digit; + +/* ---- init/deinit functions ---- */ + + /** initialize a bignum + @param a The number to initialize + @return CRYPT_OK on success + */ + int (*init)(void **a); + + /** init copy + @param dst The number to initialize and write to + @param src The number to copy from + @return CRYPT_OK on success + */ + int (*init_copy)(void **dst, void *src); + + /** deinit + @param a The number to free + @return CRYPT_OK on success + */ + void (*deinit)(void *a); + +/* ---- data movement ---- */ + + /** negate + @param src The number to negate + @param dst The destination + @return CRYPT_OK on success + */ + int (*neg)(void *src, void *dst); + + /** copy + @param src The number to copy from + @param dst The number to write to + @return CRYPT_OK on success + */ + int (*copy)(void *src, void *dst); + +/* ---- trivial low level functions ---- */ + + /** set small constant + @param a Number to write to + @param n Source upto bits_per_digit (actually meant for very small constants) + @return CRYPT_OK on succcess + */ + int (*set_int)(void *a, unsigned long n); + + /** get small constant + @param a Number to read, only fetches upto bits_per_digit from the number + @return The lower bits_per_digit of the integer (unsigned) + */ + unsigned long (*get_int)(void *a); + + /** get digit n + @param a The number to read from + @param n The number of the digit to fetch + @return The bits_per_digit sized n'th digit of a + */ + unsigned long (*get_digit)(void *a, int n); + + /** Get the number of digits that represent the number + @param a The number to count + @return The number of digits used to represent the number + */ + int (*get_digit_count)(void *a); + + /** compare two integers + @param a The left side integer + @param b The right side integer + @return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise. (signed comparison) + */ + int (*compare)(void *a, void *b); + + /** compare against int + @param a The left side integer + @param b The right side integer (upto bits_per_digit) + @return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise. (signed comparison) + */ + int (*compare_d)(void *a, unsigned long n); + + /** Count the number of bits used to represent the integer + @param a The integer to count + @return The number of bits required to represent the integer + */ + int (*count_bits)(void * a); + + /** Count the number of LSB bits which are zero + @param a The integer to count + @return The number of contiguous zero LSB bits + */ + int (*count_lsb_bits)(void *a); + + /** Compute a power of two + @param a The integer to store the power in + @param n The power of two you want to store (a = 2^n) + @return CRYPT_OK on success + */ + int (*twoexpt)(void *a , int n); + +/* ---- radix conversions ---- */ + + /** read ascii string + @param a The integer to store into + @param str The string to read + @param radix The radix the integer has been represented in (2-64) + @return CRYPT_OK on success + */ + int (*read_radix)(void *a, const char *str, int radix); + + /** write number to string + @param a The integer to store + @param str The destination for the string + @param radix The radix the integer is to be represented in (2-64) + @return CRYPT_OK on success + */ + int (*write_radix)(void *a, char *str, int radix); + + /** get size as unsigned char string + @param a The integer to get the size (when stored in array of octets) + @return The length of the integer + */ + unsigned long (*unsigned_size)(void *a); + + /** store an integer as an array of octets + @param src The integer to store + @param dst The buffer to store the integer in + @return CRYPT_OK on success + */ + int (*unsigned_write)(void *src, unsigned char *dst); + + /** read an array of octets and store as integer + @param dst The integer to load + @param src The array of octets + @param len The number of octets + @return CRYPT_OK on success + */ + int (*unsigned_read)(void *dst, unsigned char *src, unsigned long len); + +/* ---- basic math ---- */ + + /** add two integers + @param a The first source integer + @param b The second source integer + @param c The destination of "a + b" + @return CRYPT_OK on success + */ + int (*add)(void *a, void *b, void *c); + + + /** add two integers + @param a The first source integer + @param b The second source integer (single digit of upto bits_per_digit in length) + @param c The destination of "a + b" + @return CRYPT_OK on success + */ + int (*addi)(void *a, unsigned long b, void *c); + + /** subtract two integers + @param a The first source integer + @param b The second source integer + @param c The destination of "a - b" + @return CRYPT_OK on success + */ + int (*sub)(void *a, void *b, void *c); + + /** subtract two integers + @param a The first source integer + @param b The second source integer (single digit of upto bits_per_digit in length) + @param c The destination of "a - b" + @return CRYPT_OK on success + */ + int (*subi)(void *a, unsigned long b, void *c); + + /** multiply two integers + @param a The first source integer + @param b The second source integer (single digit of upto bits_per_digit in length) + @param c The destination of "a * b" + @return CRYPT_OK on success + */ + int (*mul)(void *a, void *b, void *c); + + /** multiply two integers + @param a The first source integer + @param b The second source integer (single digit of upto bits_per_digit in length) + @param c The destination of "a * b" + @return CRYPT_OK on success + */ + int (*muli)(void *a, unsigned long b, void *c); + + /** Square an integer + @param a The integer to square + @param b The destination + @return CRYPT_OK on success + */ + int (*sqr)(void *a, void *b); + + /** Divide an integer + @param a The dividend + @param b The divisor + @param c The quotient (can be NULL to signify don't care) + @param d The remainder (can be NULL to signify don't care) + @return CRYPT_OK on success + */ + int (*mpdiv)(void *a, void *b, void *c, void *d); + + /** divide by two + @param a The integer to divide (shift right) + @param b The destination + @return CRYPT_OK on success + */ + int (*div_2)(void *a, void *b); + + /** Get remainder (small value) + @param a The integer to reduce + @param b The modulus (upto bits_per_digit in length) + @param c The destination for the residue + @return CRYPT_OK on success + */ + int (*modi)(void *a, unsigned long b, unsigned long *c); + + /** gcd + @param a The first integer + @param b The second integer + @param c The destination for (a, b) + @return CRYPT_OK on success + */ + int (*gcd)(void *a, void *b, void *c); + + /** lcm + @param a The first integer + @param b The second integer + @param c The destination for [a, b] + @return CRYPT_OK on success + */ + int (*lcm)(void *a, void *b, void *c); + + /** Modular multiplication + @param a The first source + @param b The second source + @param c The modulus + @param d The destination (a*b mod c) + @return CRYPT_OK on success + */ + int (*mulmod)(void *a, void *b, void *c, void *d); + + /** Modular squaring + @param a The first source + @param b The modulus + @param c The destination (a*a mod b) + @return CRYPT_OK on success + */ + int (*sqrmod)(void *a, void *b, void *c); + + /** Modular inversion + @param a The value to invert + @param b The modulus + @param c The destination (1/a mod b) + @return CRYPT_OK on success + */ + int (*invmod)(void *, void *, void *); + +/* ---- reduction ---- */ + + /** setup montgomery + @param a The modulus + @param b The destination for the reduction digit + @return CRYPT_OK on success + */ + int (*montgomery_setup)(void *a, void **b); + + /** get normalization value + @param a The destination for the normalization value + @param b The modulus + @return CRYPT_OK on success + */ + int (*montgomery_normalization)(void *a, void *b); + + /** reduce a number + @param a The number [and dest] to reduce + @param b The modulus + @param c The value "b" from montgomery_setup() + @return CRYPT_OK on success + */ + int (*montgomery_reduce)(void *a, void *b, void *c); + + /** clean up (frees memory) + @param a The value "b" from montgomery_setup() + @return CRYPT_OK on success + */ + void (*montgomery_deinit)(void *a); + +/* ---- exponentiation ---- */ + + /** Modular exponentiation + @param a The base integer + @param b The power (can be negative) integer + @param c The modulus integer + @param d The destination + @return CRYPT_OK on success + */ + int (*exptmod)(void *a, void *b, void *c, void *d); + + /** Primality testing + @param a The integer to test + @param b The destination of the result (FP_YES if prime) + @return CRYPT_OK on success + */ + int (*isprime)(void *a, int *b); + +/* ---- (optional) ecc point math ---- */ + + /** ECC GF(p) point multiplication (from the NIST curves) + @param k The integer to multiply the point by + @param G The point to multiply + @param R The destination for kG + @param modulus The modulus for the field + @param map Boolean indicated whether to map back to affine or not (can be ignored if you work in affine only) + @return CRYPT_OK on success + */ + int (*ecc_ptmul)(void *k, ecc_point *G, ecc_point *R, void *modulus, int map); + + /** ECC GF(p) point addition + @param P The first point + @param Q The second point + @param R The destination of P + Q + @param modulus The modulus + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success + */ + int (*ecc_ptadd)(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp); + + /** ECC GF(p) point double + @param P The first point + @param R The destination of 2P + @param modulus The modulus + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success + */ + int (*ecc_ptdbl)(ecc_point *P, ecc_point *R, void *modulus, void *mp); + + /** ECC mapping from projective to affine, currently uses (x,y,z) => (x/z^2, y/z^3, 1) + @param P The point to map + @param modulus The modulus + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success + @remark The mapping can be different but keep in mind a ecc_point only has three + integers (x,y,z) so if you use a different mapping you have to make it fit. + */ + int (*ecc_map)(ecc_point *P, void *modulus, void *mp); + + /** Computes kA*A + kB*B = C using Shamir's Trick + @param A First point to multiply + @param kA What to multiple A by + @param B Second point to multiply + @param kB What to multiple B by + @param C [out] Destination point (can overlap with A or B + @param modulus Modulus for curve + @return CRYPT_OK on success + */ + int (*ecc_mul2add)(ecc_point *A, void *kA, + ecc_point *B, void *kB, + ecc_point *C, + void *modulus); + +/* ---- (optional) rsa optimized math (for internal CRT) ---- */ + + /** RSA Key Generation + @param prng An active PRNG state + @param wprng The index of the PRNG desired + @param size The size of the modulus (key size) desired (octets) + @param e The "e" value (public key). e==65537 is a good choice + @param key [out] Destination of a newly created private key pair + @return CRYPT_OK if successful, upon error all allocated ram is freed + */ + int (*rsa_keygen)(prng_state *prng, int wprng, int size, long e, rsa_key *key); + + + /** RSA exponentiation + @param in The octet array representing the base + @param inlen The length of the input + @param out The destination (to be stored in an octet array format) + @param outlen The length of the output buffer and the resulting size (zero padded to the size of the modulus) + @param which PK_PUBLIC for public RSA and PK_PRIVATE for private RSA + @param key The RSA key to use + @return CRYPT_OK on success + */ + int (*rsa_me)(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int which, + rsa_key *key); +} ltc_math_descriptor; + +extern ltc_math_descriptor ltc_mp; + +int ltc_init_multi(void **a, ...); +void ltc_deinit_multi(void *a, ...); + +#ifdef LTM_DESC +extern const ltc_math_descriptor ltm_desc; +#endif + +#ifdef TFM_DESC +extern const ltc_math_descriptor tfm_desc; +#endif + +#ifdef GMP_DESC +extern const ltc_math_descriptor gmp_desc; +#endif + +#if !defined(DESC_DEF_ONLY) && defined(LTC_SOURCE) + +#define MP_DIGIT_BIT ltc_mp.bits_per_digit + +/* some handy macros */ +#define mp_init(a) ltc_mp.init(a) +#define mp_init_multi ltc_init_multi +#define mp_clear(a) ltc_mp.deinit(a) +#define mp_clear_multi ltc_deinit_multi +#define mp_init_copy(a, b) ltc_mp.init_copy(a, b) + +#define mp_neg(a, b) ltc_mp.neg(a, b) +#define mp_copy(a, b) ltc_mp.copy(a, b) + +#define mp_set(a, b) ltc_mp.set_int(a, b) +#define mp_set_int(a, b) ltc_mp.set_int(a, b) +#define mp_get_int(a) ltc_mp.get_int(a) +#define mp_get_digit(a, n) ltc_mp.get_digit(a, n) +#define mp_get_digit_count(a) ltc_mp.get_digit_count(a) +#define mp_cmp(a, b) ltc_mp.compare(a, b) +#define mp_cmp_d(a, b) ltc_mp.compare_d(a, b) +#define mp_count_bits(a) ltc_mp.count_bits(a) +#define mp_cnt_lsb(a) ltc_mp.count_lsb_bits(a) +#define mp_2expt(a, b) ltc_mp.twoexpt(a, b) + +#define mp_read_radix(a, b, c) ltc_mp.read_radix(a, b, c) +#define mp_toradix(a, b, c) ltc_mp.write_radix(a, b, c) +#define mp_unsigned_bin_size(a) ltc_mp.unsigned_size(a) +#define mp_to_unsigned_bin(a, b) ltc_mp.unsigned_write(a, b) +#define mp_read_unsigned_bin(a, b, c) ltc_mp.unsigned_read(a, b, c) + +#define mp_add(a, b, c) ltc_mp.add(a, b, c) +#define mp_add_d(a, b, c) ltc_mp.addi(a, b, c) +#define mp_sub(a, b, c) ltc_mp.sub(a, b, c) +#define mp_sub_d(a, b, c) ltc_mp.subi(a, b, c) +#define mp_mul(a, b, c) ltc_mp.mul(a, b, c) +#define mp_mul_d(a, b, c) ltc_mp.muli(a, b, c) +#define mp_sqr(a, b) ltc_mp.sqr(a, b) +#define mp_div(a, b, c, d) ltc_mp.mpdiv(a, b, c, d) +#define mp_div_2(a, b) ltc_mp.div_2(a, b) +#define mp_mod(a, b, c) ltc_mp.mpdiv(a, b, NULL, c) +#define mp_mod_d(a, b, c) ltc_mp.modi(a, b, c) +#define mp_gcd(a, b, c) ltc_mp.gcd(a, b, c) +#define mp_lcm(a, b, c) ltc_mp.lcm(a, b, c) + +#define mp_mulmod(a, b, c, d) ltc_mp.mulmod(a, b, c, d) +#define mp_sqrmod(a, b, c) ltc_mp.sqrmod(a, b, c) +#define mp_invmod(a, b, c) ltc_mp.invmod(a, b, c) + +#define mp_montgomery_setup(a, b) ltc_mp.montgomery_setup(a, b) +#define mp_montgomery_normalization(a, b) ltc_mp.montgomery_normalization(a, b) +#define mp_montgomery_reduce(a, b, c) ltc_mp.montgomery_reduce(a, b, c) +#define mp_montgomery_free(a) ltc_mp.montgomery_deinit(a) + +#define mp_exptmod(a,b,c,d) ltc_mp.exptmod(a,b,c,d) +#define mp_prime_is_prime(a, b, c) ltc_mp.isprime(a, c) + +#define mp_iszero(a) (mp_cmp_d(a, 0) == LTC_MP_EQ ? LTC_MP_YES : LTC_MP_NO) +#define mp_isodd(a) (mp_get_digit_count(a) > 0 ? (mp_get_digit(a, 0) & 1 ? LTC_MP_YES : LTC_MP_NO) : LTC_MP_NO) +#define mp_exch(a, b) do { void *ABC__tmp = a; a = b; b = ABC__tmp; } while(0); + +#define mp_tohex(a, b) mp_toradix(a, b, 16) + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_math.h,v $ */ +/* $Revision: 1.44 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_misc.h b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_misc.h new file mode 100644 index 0000000000..e16a411851 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_misc.h @@ -0,0 +1,23 @@ +/* ---- LTC_BASE64 Routines ---- */ +#ifdef LTC_BASE64 +int base64_encode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen); + +int base64_decode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen); +#endif + +/* ---- MEM routines ---- */ +void zeromem(void *dst, size_t len); +void burn_stack(unsigned long len); + +const char *error_to_string(int err); + +extern const char *crypt_build_settings; + +/* ---- HMM ---- */ +int crypt_fsa(void *mp, ...); + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_misc.h,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_pk.h b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_pk.h new file mode 100644 index 0000000000..ae23a90314 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_pk.h @@ -0,0 +1,552 @@ +/* ---- NUMBER THEORY ---- */ + +enum { + PK_PUBLIC=0, + PK_PRIVATE=1 +}; + +int rand_prime(void *N, long len, prng_state *prng, int wprng); + +/* ---- RSA ---- */ +#ifdef LTC_MRSA + +/* Min and Max RSA key sizes (in bits) */ +#define MIN_RSA_SIZE 1024 +#define MAX_RSA_SIZE 4096 + +/** RSA LTC_PKCS style key */ +typedef struct Rsa_key { + /** Type of key, PK_PRIVATE or PK_PUBLIC */ + int type; + /** The public exponent */ + void *e; + /** The private exponent */ + void *d; + /** The modulus */ + void *N; + /** The p factor of N */ + void *p; + /** The q factor of N */ + void *q; + /** The 1/q mod p CRT param */ + void *qP; + /** The d mod (p - 1) CRT param */ + void *dP; + /** The d mod (q - 1) CRT param */ + void *dQ; +} rsa_key; + +int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key); + +int rsa_exptmod(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int which, + rsa_key *key); + +void rsa_free(rsa_key *key); + +/* These use LTC_PKCS #1 v2.0 padding */ +#define rsa_encrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, _key) \ + rsa_encrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, LTC_LTC_PKCS_1_OAEP, _key) + +#define rsa_decrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, _stat, _key) \ + rsa_decrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, LTC_LTC_PKCS_1_OAEP, _stat, _key) + +#define rsa_sign_hash(_in, _inlen, _out, _outlen, _prng, _prng_idx, _hash_idx, _saltlen, _key) \ + rsa_sign_hash_ex(_in, _inlen, _out, _outlen, LTC_LTC_PKCS_1_PSS, _prng, _prng_idx, _hash_idx, _saltlen, _key) + +#define rsa_verify_hash(_sig, _siglen, _hash, _hashlen, _hash_idx, _saltlen, _stat, _key) \ + rsa_verify_hash_ex(_sig, _siglen, _hash, _hashlen, LTC_LTC_PKCS_1_PSS, _hash_idx, _saltlen, _stat, _key) + +/* These can be switched between LTC_PKCS #1 v2.x and LTC_PKCS #1 v1.5 paddings */ +int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + prng_state *prng, int prng_idx, int hash_idx, int padding, rsa_key *key); + +int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + int hash_idx, int padding, + int *stat, rsa_key *key); + +int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + int padding, + prng_state *prng, int prng_idx, + int hash_idx, unsigned long saltlen, + rsa_key *key); + +int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int padding, + int hash_idx, unsigned long saltlen, + int *stat, rsa_key *key); + +/* LTC_PKCS #1 import/export */ +int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key); +int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key); + +#endif + +/* ---- Katja ---- */ +#ifdef MKAT + +/* Min and Max KAT key sizes (in bits) */ +#define MIN_KAT_SIZE 1024 +#define MAX_KAT_SIZE 4096 + +/** Katja LTC_PKCS style key */ +typedef struct KAT_key { + /** Type of key, PK_PRIVATE or PK_PUBLIC */ + int type; + /** The private exponent */ + void *d; + /** The modulus */ + void *N; + /** The p factor of N */ + void *p; + /** The q factor of N */ + void *q; + /** The 1/q mod p CRT param */ + void *qP; + /** The d mod (p - 1) CRT param */ + void *dP; + /** The d mod (q - 1) CRT param */ + void *dQ; + /** The pq param */ + void *pq; +} katja_key; + +int katja_make_key(prng_state *prng, int wprng, int size, katja_key *key); + +int katja_exptmod(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int which, + katja_key *key); + +void katja_free(katja_key *key); + +/* These use LTC_PKCS #1 v2.0 padding */ +int katja_encrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + prng_state *prng, int prng_idx, int hash_idx, katja_key *key); + +int katja_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + int hash_idx, int *stat, + katja_key *key); + +/* LTC_PKCS #1 import/export */ +int katja_export(unsigned char *out, unsigned long *outlen, int type, katja_key *key); +int katja_import(const unsigned char *in, unsigned long inlen, katja_key *key); + +#endif + +/* ---- ECC Routines ---- */ +#ifdef LTC_MECC + +/* size of our temp buffers for exported keys */ +#define ECC_BUF_SIZE 256 + +/* max private key size */ +#define ECC_MAXSIZE 66 + +/** Structure defines a NIST GF(p) curve */ +typedef struct { + /** The size of the curve in octets */ + int size; + + /** name of curve */ + char *name; + + /** The prime that defines the field the curve is in (encoded in hex) */ + char *prime; + + /** The fields B param (hex) */ + char *B; + + /** The order of the curve (hex) */ + char *order; + + /** The x co-ordinate of the base point on the curve (hex) */ + char *Gx; + + /** The y co-ordinate of the base point on the curve (hex) */ + char *Gy; +} ltc_ecc_set_type; + +/** A point on a ECC curve, stored in Jacbobian format such that (x,y,z) => (x/z^2, y/z^3, 1) when interpretted as affine */ +typedef struct { + /** The x co-ordinate */ + void *x; + + /** The y co-ordinate */ + void *y; + + /** The z co-ordinate */ + void *z; +} ecc_point; + +/** An ECC key */ +typedef struct { + /** Type of key, PK_PRIVATE or PK_PUBLIC */ + int type; + + /** Index into the ltc_ecc_sets[] for the parameters of this curve; if -1, then this key is using user supplied curve in dp */ + int idx; + + /** pointer to domain parameters; either points to NIST curves (identified by idx >= 0) or user supplied curve */ + const ltc_ecc_set_type *dp; + + /** The public key */ + ecc_point pubkey; + + /** The private key */ + void *k; +} ecc_key; + +/** the ECC params provided */ +extern const ltc_ecc_set_type ltc_ecc_sets[]; + +int ecc_test(void); +void ecc_sizes(int *low, int *high); +int ecc_get_size(ecc_key *key); + +int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key); +int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp); +void ecc_free(ecc_key *key); + +int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); +int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key); +int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp); + +int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen); +int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key); +int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp); + +int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, + unsigned char *out, unsigned long *outlen); + +int ecc_encrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, int hash, + ecc_key *key); + +int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + ecc_key *key); + +int ecc_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, ecc_key *key); + +int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, ecc_key *key); + +/* low level functions */ +ecc_point *ltc_ecc_new_point(void); +void ltc_ecc_del_point(ecc_point *p); +int ltc_ecc_is_valid_idx(int n); + +/* point ops (mp == montgomery digit) */ +#if !defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC) || defined(GMP_LTC_DESC) +/* R = 2P */ +int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp); + +/* R = P + Q */ +int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp); +#endif + +#if defined(LTC_MECC_FP) +/* optimized point multiplication using fixed point cache (HAC algorithm 14.117) */ +int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map); + +/* functions for saving/loading/freeing/adding to fixed point cache */ +int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen); +int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen); +void ltc_ecc_fp_free(void); +int ltc_ecc_fp_add_point(ecc_point *g, void *modulus, int lock); + +/* lock/unlock all points currently in fixed point cache */ +void ltc_ecc_fp_tablelock(int lock); +#endif + +/* R = kG */ +int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map); + +#ifdef LTC_ECC_SHAMIR +/* kA*A + kB*B = C */ +int ltc_ecc_mul2add(ecc_point *A, void *kA, + ecc_point *B, void *kB, + ecc_point *C, + void *modulus); + +#ifdef LTC_MECC_FP +/* Shamir's trick with optimized point multiplication using fixed point cache */ +int ltc_ecc_fp_mul2add(ecc_point *A, void *kA, + ecc_point *B, void *kB, + ecc_point *C, void *modulus); +#endif + +#endif + + +/* map P to affine from projective */ +int ltc_ecc_map(ecc_point *P, void *modulus, void *mp); + +#endif + +#ifdef LTC_MDSA + +/* Max diff between group and modulus size in bytes */ +#define LTC_MDSA_DELTA 512 + +/* Max DSA group size in bytes (default allows 4k-bit groups) */ +#define LTC_MDSA_MAX_GROUP 512 + +/** DSA key structure */ +typedef struct { + /** The key type, PK_PRIVATE or PK_PUBLIC */ + int type; + + /** The order of the sub-group used in octets */ + int qord; + + /** The generator */ + void *g; + + /** The prime used to generate the sub-group */ + void *q; + + /** The large prime that generats the field the contains the sub-group */ + void *p; + + /** The private key */ + void *x; + + /** The public key */ + void *y; +} dsa_key; + +int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key); +void dsa_free(dsa_key *key); + +int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen, + void *r, void *s, + prng_state *prng, int wprng, dsa_key *key); + +int dsa_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, dsa_key *key); + +int dsa_verify_hash_raw( void *r, void *s, + const unsigned char *hash, unsigned long hashlen, + int *stat, dsa_key *key); + +int dsa_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, dsa_key *key); + +int dsa_encrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, int hash, + dsa_key *key); + +int dsa_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + dsa_key *key); + +int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key); +int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key); +int dsa_verify_key(dsa_key *key, int *stat); + +int dsa_shared_secret(void *private_key, void *base, + dsa_key *public_key, + unsigned char *out, unsigned long *outlen); +#endif + +#ifdef LTC_DER +/* DER handling */ + +enum { + LTC_ASN1_EOL, + LTC_ASN1_BOOLEAN, + LTC_ASN1_INTEGER, + LTC_ASN1_SHORT_INTEGER, + LTC_ASN1_BIT_STRING, + LTC_ASN1_OCTET_STRING, + LTC_ASN1_NULL, + LTC_ASN1_OBJECT_IDENTIFIER, + LTC_ASN1_IA5_STRING, + LTC_ASN1_PRINTABLE_STRING, + LTC_ASN1_UTF8_STRING, + LTC_ASN1_UTCTIME, + LTC_ASN1_CHOICE, + LTC_ASN1_SEQUENCE, + LTC_ASN1_SET, + LTC_ASN1_SETOF +}; + +/** A LTC ASN.1 list type */ +typedef struct ltc_asn1_list_ { + /** The LTC ASN.1 enumerated type identifier */ + int type; + /** The data to encode or place for decoding */ + void *data; + /** The size of the input or resulting output */ + unsigned long size; + /** The used flag, this is used by the CHOICE ASN.1 type to indicate which choice was made */ + int used; + /** prev/next entry in the list */ + struct ltc_asn1_list_ *prev, *next, *child, *parent; +} ltc_asn1_list; + +#define LTC_SET_ASN1(list, index, Type, Data, Size) \ + do { \ + int LTC_MACRO_temp = (index); \ + ltc_asn1_list *LTC_MACRO_list = (list); \ + LTC_MACRO_list[LTC_MACRO_temp].type = (Type); \ + LTC_MACRO_list[LTC_MACRO_temp].data = (void*)(Data); \ + LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \ + LTC_MACRO_list[LTC_MACRO_temp].used = 0; \ + } while (0); + +/* SEQUENCE */ +int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int type_of); + +#define der_encode_sequence(list, inlen, out, outlen) der_encode_sequence_ex(list, inlen, out, outlen, LTC_ASN1_SEQUENCE) + +int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, + ltc_asn1_list *list, unsigned long outlen, int ordered); + +#define der_decode_sequence(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 1) + +int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, + unsigned long *outlen); + +/* SET */ +#define der_decode_set(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 0) +#define der_length_set der_length_sequence +int der_encode_set(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +int der_encode_setof(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +/* VA list handy helpers with triplets of */ +int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...); +int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...); + +/* FLEXI DECODER handle unknown list decoder */ +int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out); +void der_free_sequence_flexi(ltc_asn1_list *list); +void der_sequence_free(ltc_asn1_list *in); + +/* BOOLEAN */ +int der_length_boolean(unsigned long *outlen); +int der_encode_boolean(int in, + unsigned char *out, unsigned long *outlen); +int der_decode_boolean(const unsigned char *in, unsigned long inlen, + int *out); +/* INTEGER */ +int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen); +int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num); +int der_length_integer(void *num, unsigned long *len); + +/* INTEGER -- handy for 0..2^32-1 values */ +int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num); +int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen); +int der_length_short_integer(unsigned long num, unsigned long *outlen); + +/* BIT STRING */ +int der_encode_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_decode_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_length_bit_string(unsigned long nbits, unsigned long *outlen); + +/* OCTET STRING */ +int der_encode_octet_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_decode_octet_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_length_octet_string(unsigned long noctets, unsigned long *outlen); + +/* OBJECT IDENTIFIER */ +int der_encode_object_identifier(unsigned long *words, unsigned long nwords, + unsigned char *out, unsigned long *outlen); +int der_decode_object_identifier(const unsigned char *in, unsigned long inlen, + unsigned long *words, unsigned long *outlen); +int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen); +unsigned long der_object_identifier_bits(unsigned long x); + +/* IA5 STRING */ +int der_encode_ia5_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen); + +int der_ia5_char_encode(int c); +int der_ia5_value_decode(int v); + +/* Printable STRING */ +int der_encode_printable_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_decode_printable_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen); + +int der_printable_char_encode(int c); +int der_printable_value_decode(int v); + +/* UTF-8 */ +#if (defined(SIZE_MAX) || __STDC_VERSION__ >= 199901L || defined(WCHAR_MAX) || defined(_WCHAR_T) || defined(_WCHAR_T_DEFINED) || defined (__WCHAR_TYPE__)) && !defined(LTC_NO_WCHAR) +#include +#else +typedef ulong32 wchar_t; +#endif + +int der_encode_utf8_string(const wchar_t *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, + wchar_t *out, unsigned long *outlen); +unsigned long der_utf8_charsize(const wchar_t c); +int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen); + + +/* CHOICE */ +int der_decode_choice(const unsigned char *in, unsigned long *inlen, + ltc_asn1_list *list, unsigned long outlen); + +/* UTCTime */ +typedef struct { + unsigned YY, /* year */ + MM, /* month */ + DD, /* day */ + hh, /* hour */ + mm, /* minute */ + ss, /* second */ + off_dir, /* timezone offset direction 0 == +, 1 == - */ + off_hh, /* timezone offset hours */ + off_mm; /* timezone offset minutes */ +} ltc_utctime; + +int der_encode_utctime(ltc_utctime *utctime, + unsigned char *out, unsigned long *outlen); + +int der_decode_utctime(const unsigned char *in, unsigned long *inlen, + ltc_utctime *out); + +int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen); + + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_pk.h,v $ */ +/* $Revision: 1.81 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_pkcs.h b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_pkcs.h new file mode 100644 index 0000000000..b7ba708bee --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_pkcs.h @@ -0,0 +1,89 @@ +/* LTC_PKCS Header Info */ + +/* ===> LTC_PKCS #1 -- RSA Cryptography <=== */ +#ifdef LTC_PKCS_1 + +enum ltc_pkcs_1_v1_5_blocks +{ + LTC_LTC_PKCS_1_EMSA = 1, /* Block type 1 (LTC_PKCS #1 v1.5 signature padding) */ + LTC_LTC_PKCS_1_EME = 2 /* Block type 2 (LTC_PKCS #1 v1.5 encryption padding) */ +}; + +enum ltc_pkcs_1_paddings +{ + LTC_LTC_PKCS_1_V1_5 = 1, /* LTC_PKCS #1 v1.5 padding (\sa ltc_pkcs_1_v1_5_blocks) */ + LTC_LTC_PKCS_1_OAEP = 2, /* LTC_PKCS #1 v2.0 encryption padding */ + LTC_LTC_PKCS_1_PSS = 3 /* LTC_PKCS #1 v2.1 signature padding */ +}; + +int pkcs_1_mgf1( int hash_idx, + const unsigned char *seed, unsigned long seedlen, + unsigned char *mask, unsigned long masklen); + +int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out); +int pkcs_1_os2ip(void *n, unsigned char *in, unsigned long inlen); + +/* *** v1.5 padding */ +int pkcs_1_v1_5_encode(const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + prng_state *prng, + int prng_idx, + unsigned char *out, + unsigned long *outlen); + +int pkcs_1_v1_5_decode(const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + unsigned char *out, + unsigned long *outlen, + int *is_valid); + +/* *** v2.1 padding */ +int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, + const unsigned char *lparam, unsigned long lparamlen, + unsigned long modulus_bitlen, prng_state *prng, + int prng_idx, int hash_idx, + unsigned char *out, unsigned long *outlen); + +int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, + const unsigned char *lparam, unsigned long lparamlen, + unsigned long modulus_bitlen, int hash_idx, + unsigned char *out, unsigned long *outlen, + int *res); + +int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, + unsigned long saltlen, prng_state *prng, + int prng_idx, int hash_idx, + unsigned long modulus_bitlen, + unsigned char *out, unsigned long *outlen); + +int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, + const unsigned char *sig, unsigned long siglen, + unsigned long saltlen, int hash_idx, + unsigned long modulus_bitlen, int *res); + +#endif /* LTC_PKCS_1 */ + +/* ===> LTC_PKCS #5 -- Password Based Cryptography <=== */ +#ifdef LTC_PKCS_5 + +/* Algorithm #1 (old) */ +int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen); + +/* Algorithm #2 (new) */ +int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, unsigned long salt_len, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen); + +#endif /* LTC_PKCS_5 */ + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_pkcs.h,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_prng.h b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_prng.h new file mode 100644 index 0000000000..7dd30262db --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/headers/tomcrypt_prng.h @@ -0,0 +1,199 @@ +/* ---- PRNG Stuff ---- */ +#ifdef LTC_YARROW +struct yarrow_prng { + int cipher, hash; + unsigned char pool[MAXBLOCKSIZE]; + symmetric_CTR ctr; + LTC_MUTEX_TYPE(prng_lock) +}; +#endif + +#ifdef LTC_RC4 +struct rc4_prng { + int x, y; + unsigned char buf[256]; +}; +#endif + +#ifdef LTC_FORTUNA +struct fortuna_prng { + hash_state pool[LTC_FORTUNA_POOLS]; /* the pools */ + + symmetric_key skey; + + unsigned char K[32], /* the current key */ + IV[16]; /* IV for CTR mode */ + + unsigned long pool_idx, /* current pool we will add to */ + pool0_len, /* length of 0'th pool */ + wd; + + ulong64 reset_cnt; /* number of times we have reset */ + LTC_MUTEX_TYPE(prng_lock) +}; +#endif + +#ifdef LTC_SOBER128 +struct sober128_prng { + ulong32 R[17], /* Working storage for the shift register */ + initR[17], /* saved register contents */ + konst, /* key dependent constant */ + sbuf; /* partial word encryption buffer */ + + int nbuf, /* number of part-word stream bits buffered */ + flag, /* first add_entropy call or not? */ + set; /* did we call add_entropy to set key? */ + +}; +#endif + +typedef union Prng_state { + char dummy[1]; +#ifdef LTC_YARROW + struct yarrow_prng yarrow; +#endif +#ifdef LTC_RC4 + struct rc4_prng rc4; +#endif +#ifdef LTC_FORTUNA + struct fortuna_prng fortuna; +#endif +#ifdef LTC_SOBER128 + struct sober128_prng sober128; +#endif +} prng_state; + +/** PRNG descriptor */ +extern struct ltc_prng_descriptor { + /** Name of the PRNG */ + char *name; + /** size in bytes of exported state */ + int export_size; + /** Start a PRNG state + @param prng [out] The state to initialize + @return CRYPT_OK if successful + */ + int (*start)(prng_state *prng); + /** Add entropy to the PRNG + @param in The entropy + @param inlen Length of the entropy (octets)\ + @param prng The PRNG state + @return CRYPT_OK if successful + */ + int (*add_entropy)(const unsigned char *in, unsigned long inlen, prng_state *prng); + /** Ready a PRNG state to read from + @param prng The PRNG state to ready + @return CRYPT_OK if successful + */ + int (*ready)(prng_state *prng); + /** Read from the PRNG + @param out [out] Where to store the data + @param outlen Length of data desired (octets) + @param prng The PRNG state to read from + @return Number of octets read + */ + unsigned long (*read)(unsigned char *out, unsigned long outlen, prng_state *prng); + /** Terminate a PRNG state + @param prng The PRNG state to terminate + @return CRYPT_OK if successful + */ + int (*done)(prng_state *prng); + /** Export a PRNG state + @param out [out] The destination for the state + @param outlen [in/out] The max size and resulting size of the PRNG state + @param prng The PRNG to export + @return CRYPT_OK if successful + */ + int (*pexport)(unsigned char *out, unsigned long *outlen, prng_state *prng); + /** Import a PRNG state + @param in The data to import + @param inlen The length of the data to import (octets) + @param prng The PRNG to initialize/import + @return CRYPT_OK if successful + */ + int (*pimport)(const unsigned char *in, unsigned long inlen, prng_state *prng); + /** Self-test the PRNG + @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled + */ + int (*test)(void); +} prng_descriptor[]; + +#ifdef LTC_YARROW +int yarrow_start(prng_state *prng); +int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); +int yarrow_ready(prng_state *prng); +unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng); +int yarrow_done(prng_state *prng); +int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng); +int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng); +int yarrow_test(void); +extern const struct ltc_prng_descriptor yarrow_desc; +#endif + +#ifdef LTC_FORTUNA +int fortuna_start(prng_state *prng); +int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); +int fortuna_ready(prng_state *prng); +unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state *prng); +int fortuna_done(prng_state *prng); +int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng); +int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng); +int fortuna_test(void); +extern const struct ltc_prng_descriptor fortuna_desc; +#endif + +#ifdef LTC_RC4 +int rc4_start(prng_state *prng); +int rc4_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); +int rc4_ready(prng_state *prng); +unsigned long rc4_read(unsigned char *out, unsigned long outlen, prng_state *prng); +int rc4_done(prng_state *prng); +int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng); +int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng); +int rc4_test(void); +extern const struct ltc_prng_descriptor rc4_desc; +#endif + +#ifdef LTC_SPRNG +int sprng_start(prng_state *prng); +int sprng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); +int sprng_ready(prng_state *prng); +unsigned long sprng_read(unsigned char *out, unsigned long outlen, prng_state *prng); +int sprng_done(prng_state *prng); +int sprng_export(unsigned char *out, unsigned long *outlen, prng_state *prng); +int sprng_import(const unsigned char *in, unsigned long inlen, prng_state *prng); +int sprng_test(void); +extern const struct ltc_prng_descriptor sprng_desc; +#endif + +#ifdef LTC_SOBER128 +int sober128_start(prng_state *prng); +int sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); +int sober128_ready(prng_state *prng); +unsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state *prng); +int sober128_done(prng_state *prng); +int sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng); +int sober128_import(const unsigned char *in, unsigned long inlen, prng_state *prng); +int sober128_test(void); +extern const struct ltc_prng_descriptor sober128_desc; +#endif + +int find_prng(const char *name); +int register_prng(const struct ltc_prng_descriptor *prng); +int unregister_prng(const struct ltc_prng_descriptor *prng); +int prng_is_valid(int idx); +LTC_MUTEX_PROTO(ltc_prng_mutex) + +/* Slow RNG you **might** be able to use to seed a PRNG with. Be careful as this + * might not work on all platforms as planned + */ +unsigned long rng_get_bytes(unsigned char *out, + unsigned long outlen, + void (*callback)(void)); + +int rng_make_prng(int bits, int wprng, prng_state *prng, void (*callback)(void)); + + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_prng.h,v $ */ +/* $Revision: 1.9 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/f9/f9_done.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/f9/f9_done.c new file mode 100644 index 0000000000..bd9b5a6c13 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/f9/f9_done.c @@ -0,0 +1,76 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file f9_done.c + f9 Support, terminate the state +*/ + +#ifdef LTC_F9_MODE + +/** Terminate the f9-MAC state + @param f9 f9 state to terminate + @param out [out] Destination for the MAC tag + @param outlen [in/out] Destination size and final tag size + Return CRYPT_OK on success +*/ +int f9_done(f9_state *f9, unsigned char *out, unsigned long *outlen) +{ + int err, x; + LTC_ARGCHK(f9 != NULL); + LTC_ARGCHK(out != NULL); + + /* check structure */ + if ((err = cipher_is_valid(f9->cipher)) != CRYPT_OK) { + return err; + } + + if ((f9->blocksize > cipher_descriptor[f9->cipher].block_length) || (f9->blocksize < 0) || + (f9->buflen > f9->blocksize) || (f9->buflen < 0)) { + return CRYPT_INVALID_ARG; + } + + if (f9->buflen != 0) { + /* encrypt */ + cipher_descriptor[f9->cipher].ecb_encrypt(f9->IV, f9->IV, &f9->key); + f9->buflen = 0; + for (x = 0; x < f9->blocksize; x++) { + f9->ACC[x] ^= f9->IV[x]; + } + } + + /* schedule modified key */ + if ((err = cipher_descriptor[f9->cipher].setup(f9->akey, f9->keylen, 0, &f9->key)) != CRYPT_OK) { + return err; + } + + /* encrypt the ACC */ + cipher_descriptor[f9->cipher].ecb_encrypt(f9->ACC, f9->ACC, &f9->key); + cipher_descriptor[f9->cipher].done(&f9->key); + + /* extract tag */ + for (x = 0; x < f9->blocksize && (unsigned long)x < *outlen; x++) { + out[x] = f9->ACC[x]; + } + *outlen = x; + +#ifdef LTC_CLEAN_STACK + zeromem(f9, sizeof(*f9)); +#endif + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/f9/f9_done.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/f9/f9_file.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/f9/f9_file.c new file mode 100644 index 0000000000..ae934e83c2 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/f9/f9_file.c @@ -0,0 +1,83 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file f9_file.c + f9 support, process a file, Tom St Denis +*/ + +#ifdef LTC_F9_MODE + +/** + f9 a file + @param cipher The index of the cipher desired + @param key The secret key + @param keylen The length of the secret key (octets) + @param filename The name of the file you wish to f9 + @param out [out] Where the authentication tag is to be stored + @param outlen [in/out] The max size and resulting size of the authentication tag + @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled +*/ +int f9_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen) +{ +#ifdef LTC_NO_FILE + return CRYPT_NOP; +#else + int err, x; + f9_state f9; + FILE *in; + unsigned char buf[512]; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(filename != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + in = fopen(filename, "rb"); + if (in == NULL) { + return CRYPT_FILE_NOTFOUND; + } + + if ((err = f9_init(&f9, cipher, key, keylen)) != CRYPT_OK) { + fclose(in); + return err; + } + + do { + x = fread(buf, 1, sizeof(buf), in); + if ((err = f9_process(&f9, buf, x)) != CRYPT_OK) { + fclose(in); + return err; + } + } while (x == sizeof(buf)); + fclose(in); + + if ((err = f9_done(&f9, out, outlen)) != CRYPT_OK) { + return err; + } + +#ifdef LTC_CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + + return CRYPT_OK; +#endif +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/f9/f9_file.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/f9/f9_init.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/f9/f9_init.c new file mode 100644 index 0000000000..64122a9969 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/f9/f9_init.c @@ -0,0 +1,69 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file f9_init.c + F9 Support, start an F9 state +*/ + +#ifdef LTC_F9_MODE + +/** Initialize F9-MAC state + @param f9 [out] f9 state to initialize + @param cipher Index of cipher to use + @param key [in] Secret key + @param keylen Length of secret key in octets + Return CRYPT_OK on success +*/ +int f9_init(f9_state *f9, int cipher, const unsigned char *key, unsigned long keylen) +{ + int x, err; + + LTC_ARGCHK(f9 != NULL); + LTC_ARGCHK(key != NULL); + + /* schedule the key */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + +#ifdef LTC_FAST + if (cipher_descriptor[cipher].block_length % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &f9->key)) != CRYPT_OK) { + goto done; + } + + /* make the second key */ + for (x = 0; (unsigned)x < keylen; x++) { + f9->akey[x] = key[x] ^ 0xAA; + } + + /* setup struct */ + zeromem(f9->IV, cipher_descriptor[cipher].block_length); + zeromem(f9->ACC, cipher_descriptor[cipher].block_length); + f9->blocksize = cipher_descriptor[cipher].block_length; + f9->cipher = cipher; + f9->buflen = 0; + f9->keylen = keylen; +done: + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/f9/f9_init.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/f9/f9_memory.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/f9/f9_memory.c new file mode 100644 index 0000000000..77958a402f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/f9/f9_memory.c @@ -0,0 +1,71 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file f9_process.c + f9 Support, Process a block through F9-MAC +*/ + +#ifdef LTC_F9_MODE + +/** f9-MAC a block of memory + @param cipher Index of cipher to use + @param key [in] Secret key + @param keylen Length of key in octets + @param in [in] Message to MAC + @param inlen Length of input in octets + @param out [out] Destination for the MAC tag + @param outlen [in/out] Output size and final tag size + Return CRYPT_OK on success. +*/ +int f9_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + f9_state *f9; + int err; + + /* is the cipher valid? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* Use accelerator if found */ + if (cipher_descriptor[cipher].f9_memory != NULL) { + return cipher_descriptor[cipher].f9_memory(key, keylen, in, inlen, out, outlen); + } + + f9 = XCALLOC(1, sizeof(*f9)); + if (f9 == NULL) { + return CRYPT_MEM; + } + + if ((err = f9_init(f9, cipher, key, keylen)) != CRYPT_OK) { + goto done; + } + + if ((err = f9_process(f9, in, inlen)) != CRYPT_OK) { + goto done; + } + + err = f9_done(f9, out, outlen); +done: + XFREE(f9); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/f9/f9_memory.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/f9/f9_memory_multi.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/f9/f9_memory_multi.c new file mode 100644 index 0000000000..b8ad1ff535 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/f9/f9_memory_multi.c @@ -0,0 +1,90 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" +#include + +/** + @file f9_memory_multi.c + f9 support, process multiple blocks of memory, Tom St Denis +*/ + +#ifdef LTC_F9_MODE + +/** + f9 multiple blocks of memory + @param cipher The index of the desired cipher + @param key The secret key + @param keylen The length of the secret key (octets) + @param out [out] The destination of the authentication tag + @param outlen [in/out] The max size and resulting size of the authentication tag (octets) + @param in The data to send through f9 + @param inlen The length of the data to send through f9 (octets) + @param ... tuples of (data,len) pairs to f9, terminated with a (NULL,x) (x=don't care) + @return CRYPT_OK if successful +*/ +int f9_memory_multi(int cipher, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...) +{ + int err; + f9_state *f9; + va_list args; + const unsigned char *curptr; + unsigned long curlen; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* allocate ram for f9 state */ + f9 = XMALLOC(sizeof(f9_state)); + if (f9 == NULL) { + return CRYPT_MEM; + } + + /* f9 process the message */ + if ((err = f9_init(f9, cipher, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + va_start(args, inlen); + curptr = in; + curlen = inlen; + for (;;) { + /* process buf */ + if ((err = f9_process(f9, curptr, curlen)) != CRYPT_OK) { + goto LBL_ERR; + } + /* step to next */ + curptr = va_arg(args, const unsigned char*); + if (curptr == NULL) { + break; + } + curlen = va_arg(args, unsigned long); + } + if ((err = f9_done(f9, out, outlen)) != CRYPT_OK) { + goto LBL_ERR; + } +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(f9, sizeof(f9_state)); +#endif + XFREE(f9); + va_end(args); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/f9/f9_memory_multi.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/f9/f9_process.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/f9/f9_process.c new file mode 100644 index 0000000000..9b490c2ef6 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/f9/f9_process.c @@ -0,0 +1,77 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file f9_process.c + f9 Support, process blocks with f9 +*/ + +#ifdef LTC_F9_MODE + +/** Process data through f9-MAC + @param f9 The f9-MAC state + @param in Input data to process + @param inlen Length of input in octets + Return CRYPT_OK on success +*/ +int f9_process(f9_state *f9, const unsigned char *in, unsigned long inlen) +{ + int err, x; + + LTC_ARGCHK(f9 != NULL); + LTC_ARGCHK(in != NULL); + + /* check structure */ + if ((err = cipher_is_valid(f9->cipher)) != CRYPT_OK) { + return err; + } + + if ((f9->blocksize > cipher_descriptor[f9->cipher].block_length) || (f9->blocksize < 0) || + (f9->buflen > f9->blocksize) || (f9->buflen < 0)) { + return CRYPT_INVALID_ARG; + } + +#ifdef LTC_FAST + if (f9->buflen == 0) { + while (inlen >= (unsigned long)f9->blocksize) { + for (x = 0; x < f9->blocksize; x += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)&(f9->IV[x])) ^= *((LTC_FAST_TYPE*)&(in[x])); + } + cipher_descriptor[f9->cipher].ecb_encrypt(f9->IV, f9->IV, &f9->key); + for (x = 0; x < f9->blocksize; x += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)&(f9->ACC[x])) ^= *((LTC_FAST_TYPE*)&(f9->IV[x])); + } + in += f9->blocksize; + inlen -= f9->blocksize; + } + } +#endif + + while (inlen) { + if (f9->buflen == f9->blocksize) { + cipher_descriptor[f9->cipher].ecb_encrypt(f9->IV, f9->IV, &f9->key); + for (x = 0; x < f9->blocksize; x++) { + f9->ACC[x] ^= f9->IV[x]; + } + f9->buflen = 0; + } + f9->IV[f9->buflen++] ^= *in++; + --inlen; + } + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/f9/f9_process.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/f9/f9_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/f9/f9_test.c new file mode 100644 index 0000000000..323a444c43 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/f9/f9_test.c @@ -0,0 +1,77 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file f9_test.c + f9 Support, Test F9 mode +*/ + +#ifdef LTC_F9_MODE + +/** Test f9-MAC mode + Return CRYPT_OK on succes +*/ +int f9_test(void) +{ +#ifdef LTC_NO_TEST + return CRYPT_NOP; +#else + static const struct { + int msglen; + unsigned char K[16], M[128], T[4]; + } tests[] = { +{ + 20, + { 0x2B, 0xD6, 0x45, 0x9F, 0x82, 0xC5, 0xB3, 0x00, 0x95, 0x2C, 0x49, 0x10, 0x48, 0x81, 0xFF, 0x48 }, + { 0x38, 0xA6, 0xF0, 0x56, 0xB8, 0xAE, 0xFD, 0xA9, 0x33, 0x32, 0x34, 0x62, 0x63, 0x39, 0x38, 0x61, 0x37, 0x34, 0x79, 0x40 }, + { 0x46, 0xE0, 0x0D, 0x4B } +}, + +{ + 105, + { 0x83, 0xFD, 0x23, 0xA2, 0x44, 0xA7, 0x4C, 0xF3, 0x58, 0xDA, 0x30, 0x19, 0xF1, 0x72, 0x26, 0x35 }, + { 0x36, 0xAF, 0x61, 0x44, 0x4F, 0x30, 0x2A, 0xD2, + 0x35, 0xC6, 0x87, 0x16, 0x63, 0x3C, 0x66, 0xFB, 0x75, 0x0C, 0x26, 0x68, 0x65, 0xD5, 0x3C, 0x11, 0xEA, 0x05, 0xB1, 0xE9, 0xFA, 0x49, 0xC8, 0x39, 0x8D, 0x48, 0xE1, 0xEF, 0xA5, 0x90, 0x9D, 0x39, + 0x47, 0x90, 0x28, 0x37, 0xF5, 0xAE, 0x96, 0xD5, 0xA0, 0x5B, 0xC8, 0xD6, 0x1C, 0xA8, 0xDB, 0xEF, 0x1B, 0x13, 0xA4, 0xB4, 0xAB, 0xFE, 0x4F, 0xB1, 0x00, 0x60, 0x45, 0xB6, 0x74, 0xBB, 0x54, 0x72, + 0x93, 0x04, 0xC3, 0x82, 0xBE, 0x53, 0xA5, 0xAF, 0x05, 0x55, 0x61, 0x76, 0xF6, 0xEA, 0xA2, 0xEF, 0x1D, 0x05, 0xE4, 0xB0, 0x83, 0x18, 0x1E, 0xE6, 0x74, 0xCD, 0xA5, 0xA4, 0x85, 0xF7, 0x4D, 0x7A, + 0x40|0x80 }, + { 0x95, 0xAE, 0x41, 0xBA }, +} +}; + unsigned char T[16]; + unsigned long taglen; + int err, x, idx; + + /* find kasumi */ + if ((idx = find_cipher("kasumi")) == -1) { + return CRYPT_NOP; + } + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + taglen = 4; + if ((err = f9_memory(idx, tests[x].K, 16, tests[x].M, tests[x].msglen, T, &taglen)) != CRYPT_OK) { + return err; + } + if (taglen != 4 || XMEMCMP(T, tests[x].T, 4)) { + return CRYPT_FAIL_TESTVECTOR; + } + } + + return CRYPT_OK; +#endif +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/f9/f9_test.c,v $ */ +/* $Revision: 1.9 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/hmac/hmac_done.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/hmac/hmac_done.c new file mode 100644 index 0000000000..616dd98457 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/hmac/hmac_done.c @@ -0,0 +1,109 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file hmac_done.c + LTC_HMAC support, terminate stream, Tom St Denis/Dobes Vandermeer +*/ + +#ifdef LTC_HMAC + +#define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize + +/** + Terminate an LTC_HMAC session + @param hmac The LTC_HMAC state + @param out [out] The destination of the LTC_HMAC authentication tag + @param outlen [in/out] The max size and resulting size of the LTC_HMAC authentication tag + @return CRYPT_OK if successful +*/ +int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen) +{ + unsigned char *buf, *isha; + unsigned long hashsize, i; + int hash, err; + + LTC_ARGCHK(hmac != NULL); + LTC_ARGCHK(out != NULL); + + /* test hash */ + hash = hmac->hash; + if((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + /* get the hash message digest size */ + hashsize = hash_descriptor[hash].hashsize; + + /* allocate buffers */ + buf = XMALLOC(LTC_HMAC_BLOCKSIZE); + isha = XMALLOC(hashsize); + if (buf == NULL || isha == NULL) { + if (buf != NULL) { + XFREE(buf); + } + if (isha != NULL) { + XFREE(isha); + } + return CRYPT_MEM; + } + + /* Get the hash of the first LTC_HMAC vector plus the data */ + if ((err = hash_descriptor[hash].done(&hmac->md, isha)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* Create the second LTC_HMAC vector vector for step (3) */ + for(i=0; i < LTC_HMAC_BLOCKSIZE; i++) { + buf[i] = hmac->key[i] ^ 0x5C; + } + + /* Now calculate the "outer" hash for step (5), (6), and (7) */ + if ((err = hash_descriptor[hash].init(&hmac->md)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash].process(&hmac->md, buf, LTC_HMAC_BLOCKSIZE)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash].process(&hmac->md, isha, hashsize)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash].done(&hmac->md, buf)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* copy to output */ + for (i = 0; i < hashsize && i < *outlen; i++) { + out[i] = buf[i]; + } + *outlen = i; + + err = CRYPT_OK; +LBL_ERR: + XFREE(hmac->key); +#ifdef LTC_CLEAN_STACK + zeromem(isha, hashsize); + zeromem(buf, hashsize); + zeromem(hmac, sizeof(*hmac)); +#endif + + XFREE(isha); + XFREE(buf); + + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_done.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/hmac/hmac_file.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/hmac/hmac_file.c new file mode 100644 index 0000000000..ab3d60baba --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/hmac/hmac_file.c @@ -0,0 +1,93 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file hmac_file.c + LTC_HMAC support, process a file, Tom St Denis/Dobes Vandermeer +*/ + +#ifdef LTC_HMAC + +/** + LTC_HMAC a file + @param hash The index of the hash you wish to use + @param fname The name of the file you wish to LTC_HMAC + @param key The secret key + @param keylen The length of the secret key + @param out [out] The LTC_HMAC authentication tag + @param outlen [in/out] The max size and resulting size of the authentication tag + @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled +*/ +int hmac_file(int hash, const char *fname, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen) +{ +#ifdef LTC_NO_FILE + return CRYPT_NOP; +#else + hmac_state hmac; + FILE *in; + unsigned char buf[512]; + size_t x; + int err; + + LTC_ARGCHK(fname != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + if ((err = hmac_init(&hmac, hash, key, keylen)) != CRYPT_OK) { + return err; + } + + in = fopen(fname, "rb"); + if (in == NULL) { + return CRYPT_FILE_NOTFOUND; + } + + /* process the file contents */ + do { + x = fread(buf, 1, sizeof(buf), in); + if ((err = hmac_process(&hmac, buf, (unsigned long)x)) != CRYPT_OK) { + /* we don't trap this error since we're already returning an error! */ + fclose(in); + return err; + } + } while (x == sizeof(buf)); + + if (fclose(in) != 0) { + return CRYPT_ERROR; + } + + /* get final hmac */ + if ((err = hmac_done(&hmac, out, outlen)) != CRYPT_OK) { + return err; + } + +#ifdef LTC_CLEAN_STACK + /* clear memory */ + zeromem(buf, sizeof(buf)); +#endif + return CRYPT_OK; +#endif +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_file.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/hmac/hmac_init.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/hmac/hmac_init.c new file mode 100644 index 0000000000..a18e871a47 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/hmac/hmac_init.c @@ -0,0 +1,112 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file hmac_init.c + LTC_HMAC support, initialize state, Tom St Denis/Dobes Vandermeer +*/ + +#ifdef LTC_HMAC + +#define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize + +/** + Initialize an LTC_HMAC context. + @param hmac The LTC_HMAC state + @param hash The index of the hash you want to use + @param key The secret key + @param keylen The length of the secret key (octets) + @return CRYPT_OK if successful +*/ +int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen) +{ + unsigned char *buf; + unsigned long hashsize; + unsigned long i, z; + int err; + + LTC_ARGCHK(hmac != NULL); + LTC_ARGCHK(key != NULL); + + /* valid hash? */ + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + hmac->hash = hash; + hashsize = hash_descriptor[hash].hashsize; + + /* valid key length? */ + if (keylen == 0) { + return CRYPT_INVALID_KEYSIZE; + } + + /* allocate ram for buf */ + buf = XMALLOC(LTC_HMAC_BLOCKSIZE); + if (buf == NULL) { + return CRYPT_MEM; + } + + /* allocate memory for key */ + hmac->key = XMALLOC(LTC_HMAC_BLOCKSIZE); + if (hmac->key == NULL) { + XFREE(buf); + return CRYPT_MEM; + } + + /* (1) make sure we have a large enough key */ + if(keylen > LTC_HMAC_BLOCKSIZE) { + z = LTC_HMAC_BLOCKSIZE; + if ((err = hash_memory(hash, key, keylen, hmac->key, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + if(hashsize < LTC_HMAC_BLOCKSIZE) { + zeromem((hmac->key) + hashsize, (size_t)(LTC_HMAC_BLOCKSIZE - hashsize)); + } + keylen = hashsize; + } else { + XMEMCPY(hmac->key, key, (size_t)keylen); + if(keylen < LTC_HMAC_BLOCKSIZE) { + zeromem((hmac->key) + keylen, (size_t)(LTC_HMAC_BLOCKSIZE - keylen)); + } + } + + /* Create the initial vector for step (3) */ + for(i=0; i < LTC_HMAC_BLOCKSIZE; i++) { + buf[i] = hmac->key[i] ^ 0x36; + } + + /* Pre-pend that to the hash data */ + if ((err = hash_descriptor[hash].init(&hmac->md)) != CRYPT_OK) { + goto LBL_ERR; + } + + if ((err = hash_descriptor[hash].process(&hmac->md, buf, LTC_HMAC_BLOCKSIZE)) != CRYPT_OK) { + goto LBL_ERR; + } + goto done; +LBL_ERR: + /* free the key since we failed */ + XFREE(hmac->key); +done: +#ifdef LTC_CLEAN_STACK + zeromem(buf, LTC_HMAC_BLOCKSIZE); +#endif + + XFREE(buf); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_init.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/hmac/hmac_memory.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/hmac/hmac_memory.c new file mode 100644 index 0000000000..b11a53656a --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/hmac/hmac_memory.c @@ -0,0 +1,88 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file hmac_memory.c + LTC_HMAC support, process a block of memory, Tom St Denis/Dobes Vandermeer +*/ + +#ifdef LTC_HMAC + +/** + LTC_HMAC a block of memory to produce the authentication tag + @param hash The index of the hash to use + @param key The secret key + @param keylen The length of the secret key (octets) + @param in The data to LTC_HMAC + @param inlen The length of the data to LTC_HMAC (octets) + @param out [out] Destination of the authentication tag + @param outlen [in/out] Max size and resulting size of authentication tag + @return CRYPT_OK if successful +*/ +int hmac_memory(int hash, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + hmac_state *hmac; + int err; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* make sure hash descriptor is valid */ + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + /* is there a descriptor? */ + if (hash_descriptor[hash].hmac_block != NULL) { + return hash_descriptor[hash].hmac_block(key, keylen, in, inlen, out, outlen); + } + + /* nope, so call the hmac functions */ + /* allocate ram for hmac state */ + hmac = XMALLOC(sizeof(hmac_state)); + if (hmac == NULL) { + return CRYPT_MEM; + } + + if ((err = hmac_init(hmac, hash, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + + if ((err = hmac_process(hmac, in, inlen)) != CRYPT_OK) { + goto LBL_ERR; + } + + if ((err = hmac_done(hmac, out, outlen)) != CRYPT_OK) { + goto LBL_ERR; + } + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(hmac, sizeof(hmac_state)); +#endif + + XFREE(hmac); + return err; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_memory.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/hmac/hmac_memory_multi.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/hmac/hmac_memory_multi.c new file mode 100644 index 0000000000..f94cc09210 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/hmac/hmac_memory_multi.c @@ -0,0 +1,92 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" +#include + +/** + @file hmac_memory_multi.c + LTC_HMAC support, process multiple blocks of memory, Tom St Denis/Dobes Vandermeer +*/ + +#ifdef LTC_HMAC + +/** + LTC_HMAC multiple blocks of memory to produce the authentication tag + @param hash The index of the hash to use + @param key The secret key + @param keylen The length of the secret key (octets) + @param out [out] Destination of the authentication tag + @param outlen [in/out] Max size and resulting size of authentication tag + @param in The data to LTC_HMAC + @param inlen The length of the data to LTC_HMAC (octets) + @param ... tuples of (data,len) pairs to LTC_HMAC, terminated with a (NULL,x) (x=don't care) + @return CRYPT_OK if successful +*/ +int hmac_memory_multi(int hash, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...) + +{ + hmac_state *hmac; + int err; + va_list args; + const unsigned char *curptr; + unsigned long curlen; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* allocate ram for hmac state */ + hmac = XMALLOC(sizeof(hmac_state)); + if (hmac == NULL) { + return CRYPT_MEM; + } + + if ((err = hmac_init(hmac, hash, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + + va_start(args, inlen); + curptr = in; + curlen = inlen; + for (;;) { + /* process buf */ + if ((err = hmac_process(hmac, curptr, curlen)) != CRYPT_OK) { + goto LBL_ERR; + } + /* step to next */ + curptr = va_arg(args, const unsigned char*); + if (curptr == NULL) { + break; + } + curlen = va_arg(args, unsigned long); + } + if ((err = hmac_done(hmac, out, outlen)) != CRYPT_OK) { + goto LBL_ERR; + } +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(hmac, sizeof(hmac_state)); +#endif + XFREE(hmac); + va_end(args); + return err; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_memory_multi.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/hmac/hmac_process.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/hmac/hmac_process.c new file mode 100644 index 0000000000..68cd98b310 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/hmac/hmac_process.c @@ -0,0 +1,43 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file hmac_process.c + LTC_HMAC support, process data, Tom St Denis/Dobes Vandermeer +*/ + +#ifdef LTC_HMAC + +/** + Process data through LTC_HMAC + @param hmac The hmac state + @param in The data to send through LTC_HMAC + @param inlen The length of the data to LTC_HMAC (octets) + @return CRYPT_OK if successful +*/ +int hmac_process(hmac_state *hmac, const unsigned char *in, unsigned long inlen) +{ + int err; + LTC_ARGCHK(hmac != NULL); + LTC_ARGCHK(in != NULL); + if ((err = hash_is_valid(hmac->hash)) != CRYPT_OK) { + return err; + } + return hash_descriptor[hmac->hash].process(&hmac->md, in, inlen); +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_process.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/hmac/hmac_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/hmac/hmac_test.c new file mode 100644 index 0000000000..d1c446e932 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/hmac/hmac_test.c @@ -0,0 +1,316 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file hmac_test.c + LTC_HMAC support, self-test, Tom St Denis/Dobes Vandermeer +*/ + +#ifdef LTC_HMAC + +#define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize + +/* + TEST CASES SOURCE: + +Network Working Group P. Cheng +Request for Comments: 2202 IBM +Category: Informational R. Glenn + NIST + September 1997 + Test Cases for LTC_HMAC-LTC_MD5 and LTC_HMAC-LTC_SHA-1 +*/ + +/** + LTC_HMAC self-test + @return CRYPT_OK if successful, CRYPT_NOP if tests have been disabled. +*/ +int hmac_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + unsigned char digest[MAXBLOCKSIZE]; + int i; + + static const struct hmac_test_case { + int num; + char *algo; + unsigned char key[128]; + unsigned long keylen; + unsigned char data[128]; + unsigned long datalen; + unsigned char digest[MAXBLOCKSIZE]; + } cases[] = { + /* + 3. Test Cases for LTC_HMAC-LTC_SHA-1 + + test_case = 1 + key = 0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c + key_len = 20 + data = "Hi Ther 20 + digest = 0x4c1a03424b55e07fe7f27be1d58bb9324a9a5a04 + digest-96 = 0x4c1a03424b55e07fe7f27be1 + */ + { 5, "sha1", + {0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c}, 20, + "Test With Truncation", 20, + {0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f, 0xe7, 0xf2, + 0x7b, 0xe1, 0xd5, 0x8b, 0xb9, 0x32, 0x4a, 0x9a, 0x5a, 0x04} }, + + /* + test_case = 6 + key = 0xaa repeated 80 times + key_len = 80 + data = "Test Using Larger Than Block-Size Key - Hash Key First" + data_len = 54 + digest = 0xaa4ae5e15272d00e95705637ce8a3b55ed402112 + */ + { 6, "sha1", + {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80, + "Test Using Larger Than Block-Size Key - Hash Key First", 54, + {0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e, + 0x95, 0x70, 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55, + 0xed, 0x40, 0x21, 0x12} }, + + /* + test_case = 7 + key = 0xaa repeated 80 times + key_len = 80 + data = "Test Using Larger Than Block-Size Key and Larger + Than One Block-Size Data" + data_len = 73 + digest = 0xe8e99d0f45237d786d6bbaa7965c7808bbff1a91 + */ + { 7, "sha1", + {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80, + "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73, + {0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78, 0x6d, + 0x6b, 0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08, 0xbb, 0xff, 0x1a, 0x91} }, + + /* + 2. Test Cases for LTC_HMAC-LTC_MD5 + + test_case = 1 + key = 0x0b 0b 0b 0b + 0b 0b 0b 0b + 0b 0b 0b 0b + 0b 0b 0b 0b + key_len = 16 + data = "Hi There" + data_len = 8 + digest = 0x92 94 72 7a + 36 38 bb 1c + 13 f4 8e f8 + 15 8b fc 9d + */ + { 1, "md5", + {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b}, 16, + "Hi There", 8, + {0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c, + 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d} }, + /* + test_case = 2 + key = "Jefe" + key_len = 4 + data = "what do ya want for nothing?" + data_len = 28 + digest = 0x750c783e6ab0b503eaa86e310a5db738 + */ + { 2, "md5", + "Jefe", 4, + "what do ya want for nothing?", 28, + {0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03, + 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38} }, + + /* + test_case = 3 + key = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + key_len 16 + data = 0xdd repeated 50 times + data_len = 50 + digest = 0x56be34521d144c88dbb8c733f0e8b3f6 + */ + { 3, "md5", + {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 16, + {0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd}, 50, + {0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88, + 0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6} }, + /* + + test_case = 4 + key = 0x0102030405060708090a0b0c0d0e0f10111213141516171819 + key_len 25 + data = 0xcd repeated 50 times + data_len = 50 + digest = 0x697eaf0aca3a3aea3a75164746ffaa79 + */ + { 4, "md5", + {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x19}, 25, + {0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd}, 50, + {0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea, + 0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79} }, + + + /* + + test_case = 5 + key = 0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c + key_len = 16 + data = "Test With Truncation" + data_len = 20 + digest = 0x56461ef2342edc00f9bab995690efd4c + digest-96 0x56461ef2342edc00f9bab995 + */ + { 5, "md5", + {0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c}, 16, + "Test With Truncation", 20, + {0x56, 0x46, 0x1e, 0xf2, 0x34, 0x2e, 0xdc, 0x00, + 0xf9, 0xba, 0xb9, 0x95, 0x69, 0x0e, 0xfd, 0x4c} }, + + /* + + test_case = 6 + key = 0xaa repeated 80 times + key_len = 80 + data = "Test Using Larger Than Block-Size Key - Hash +Key First" + data_len = 54 + digest = 0x6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd + */ + { 6, "md5", + {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80, + "Test Using Larger Than Block-Size Key - Hash Key First", 54, + {0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f, + 0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd} }, + + /* + + test_case = 7 + key = 0xaa repeated 80 times + key_len = 80 + data = "Test Using Larger Than Block-Size Key and Larger + Than One Block-Size Data" + data_len = 73 + digest = 0x6f630fad67cda0ee1fb1f562db3aa53e + */ + { 7, "md5", + {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80, + "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73, + {0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee, + 0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e} } + }; + + unsigned long outlen; + int err; + int tested=0,failed=0; + for(i=0; i < (int)(sizeof(cases) / sizeof(cases[0])); i++) { + int hash = find_hash(cases[i].algo); + if (hash == -1) continue; + ++tested; + outlen = sizeof(digest); + if((err = hmac_memory(hash, cases[i].key, cases[i].keylen, cases[i].data, cases[i].datalen, digest, &outlen)) != CRYPT_OK) { +#if 0 + printf("LTC_HMAC-%s test #%d, %s\n", cases[i].algo, cases[i].num, error_to_string(err)); +#endif + return err; + } + + if(XMEMCMP(digest, cases[i].digest, (size_t)hash_descriptor[hash].hashsize) != 0) { + failed++; +#if 0 + unsigned int j; + printf("\nLTC_HMAC-%s test #%d:\n", cases[i].algo, cases[i].num); + printf( "Result: 0x"); + for(j=0; j < hash_descriptor[hash].hashsize; j++) { + printf("%2x ", digest[j]); + } + printf("\nCorrect: 0x"); + for(j=0; j < hash_descriptor[hash].hashsize; j++) { + printf("%2x ", cases[i].digest[j]); + } + printf("\n"); + return CRYPT_ERROR; +#endif + } else { + /* printf("LTC_HMAC-%s test #%d: Passed\n", cases[i].algo, cases[i].num); */ + } + } + + if (failed != 0) { + return CRYPT_FAIL_TESTVECTOR; + } else if (tested == 0) { + return CRYPT_NOP; + } else { + return CRYPT_OK; + } + #endif +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_test.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/omac/omac_done.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/omac/omac_done.c new file mode 100644 index 0000000000..3550ca11b8 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/omac/omac_done.c @@ -0,0 +1,86 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file omac_done.c + LTC_OMAC1 support, terminate a stream, Tom St Denis +*/ + +#ifdef LTC_OMAC + +/** + Terminate an LTC_OMAC stream + @param omac The LTC_OMAC state + @param out [out] Destination for the authentication tag + @param outlen [in/out] The max size and resulting size of the authentication tag + @return CRYPT_OK if successful +*/ +int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen) +{ + int err, mode; + unsigned x; + + LTC_ARGCHK(omac != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + if ((err = cipher_is_valid(omac->cipher_idx)) != CRYPT_OK) { + return err; + } + + if ((omac->buflen > (int)sizeof(omac->block)) || (omac->buflen < 0) || + (omac->blklen > (int)sizeof(omac->block)) || (omac->buflen > omac->blklen)) { + return CRYPT_INVALID_ARG; + } + + /* figure out mode */ + if (omac->buflen != omac->blklen) { + /* add the 0x80 byte */ + omac->block[omac->buflen++] = 0x80; + + /* pad with 0x00 */ + while (omac->buflen < omac->blklen) { + omac->block[omac->buflen++] = 0x00; + } + mode = 1; + } else { + mode = 0; + } + + /* now xor prev + Lu[mode] */ + for (x = 0; x < (unsigned)omac->blklen; x++) { + omac->block[x] ^= omac->prev[x] ^ omac->Lu[mode][x]; + } + + /* encrypt it */ + if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->block, &omac->key)) != CRYPT_OK) { + return err; + } + cipher_descriptor[omac->cipher_idx].done(&omac->key); + + /* output it */ + for (x = 0; x < (unsigned)omac->blklen && x < *outlen; x++) { + out[x] = omac->block[x]; + } + *outlen = x; + +#ifdef LTC_CLEAN_STACK + zeromem(omac, sizeof(*omac)); +#endif + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/omac/omac_done.c,v $ */ +/* $Revision: 1.9 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/omac/omac_file.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/omac/omac_file.c new file mode 100644 index 0000000000..0e2f082b73 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/omac/omac_file.c @@ -0,0 +1,83 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file omac_file.c + LTC_OMAC1 support, process a file, Tom St Denis +*/ + +#ifdef LTC_OMAC + +/** + LTC_OMAC a file + @param cipher The index of the cipher desired + @param key The secret key + @param keylen The length of the secret key (octets) + @param filename The name of the file you wish to LTC_OMAC + @param out [out] Where the authentication tag is to be stored + @param outlen [in/out] The max size and resulting size of the authentication tag + @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled +*/ +int omac_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen) +{ +#ifdef LTC_NO_FILE + return CRYPT_NOP; +#else + int err, x; + omac_state omac; + FILE *in; + unsigned char buf[512]; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(filename != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + in = fopen(filename, "rb"); + if (in == NULL) { + return CRYPT_FILE_NOTFOUND; + } + + if ((err = omac_init(&omac, cipher, key, keylen)) != CRYPT_OK) { + fclose(in); + return err; + } + + do { + x = fread(buf, 1, sizeof(buf), in); + if ((err = omac_process(&omac, buf, x)) != CRYPT_OK) { + fclose(in); + return err; + } + } while (x == sizeof(buf)); + fclose(in); + + if ((err = omac_done(&omac, out, outlen)) != CRYPT_OK) { + return err; + } + +#ifdef LTC_CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + + return CRYPT_OK; +#endif +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/omac/omac_file.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/omac/omac_init.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/omac/omac_init.c new file mode 100644 index 0000000000..8e15194725 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/omac/omac_init.c @@ -0,0 +1,101 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file omac_init.c + LTC_OMAC1 support, initialize state, by Tom St Denis +*/ + + +#ifdef LTC_OMAC + +/** + Initialize an LTC_OMAC state + @param omac The LTC_OMAC state to initialize + @param cipher The index of the desired cipher + @param key The secret key + @param keylen The length of the secret key (octets) + @return CRYPT_OK if successful +*/ +int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen) +{ + int err, x, y, mask, msb, len; + + LTC_ARGCHK(omac != NULL); + LTC_ARGCHK(key != NULL); + + /* schedule the key */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + +#ifdef LTC_FAST + if (cipher_descriptor[cipher].block_length % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + + /* now setup the system */ + switch (cipher_descriptor[cipher].block_length) { + case 8: mask = 0x1B; + len = 8; + break; + case 16: mask = 0x87; + len = 16; + break; + default: return CRYPT_INVALID_ARG; + } + + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &omac->key)) != CRYPT_OK) { + return err; + } + + /* ok now we need Lu and Lu^2 [calc one from the other] */ + + /* first calc L which is Ek(0) */ + zeromem(omac->Lu[0], cipher_descriptor[cipher].block_length); + if ((err = cipher_descriptor[cipher].ecb_encrypt(omac->Lu[0], omac->Lu[0], &omac->key)) != CRYPT_OK) { + return err; + } + + /* now do the mults, whoopy! */ + for (x = 0; x < 2; x++) { + /* if msb(L * u^(x+1)) = 0 then just shift, otherwise shift and xor constant mask */ + msb = omac->Lu[x][0] >> 7; + + /* shift left */ + for (y = 0; y < (len - 1); y++) { + omac->Lu[x][y] = ((omac->Lu[x][y] << 1) | (omac->Lu[x][y+1] >> 7)) & 255; + } + omac->Lu[x][len - 1] = ((omac->Lu[x][len - 1] << 1) ^ (msb ? mask : 0)) & 255; + + /* copy up as require */ + if (x == 0) { + XMEMCPY(omac->Lu[1], omac->Lu[0], sizeof(omac->Lu[0])); + } + } + + /* setup state */ + omac->cipher_idx = cipher; + omac->buflen = 0; + omac->blklen = len; + zeromem(omac->prev, sizeof(omac->prev)); + zeromem(omac->block, sizeof(omac->block)); + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/omac/omac_init.c,v $ */ +/* $Revision: 1.12 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/omac/omac_memory.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/omac/omac_memory.c new file mode 100644 index 0000000000..228e0f9e39 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/omac/omac_memory.c @@ -0,0 +1,85 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file omac_memory.c + LTC_OMAC1 support, process a block of memory, Tom St Denis +*/ + +#ifdef LTC_OMAC + +/** + LTC_OMAC a block of memory + @param cipher The index of the desired cipher + @param key The secret key + @param keylen The length of the secret key (octets) + @param in The data to send through LTC_OMAC + @param inlen The length of the data to send through LTC_OMAC (octets) + @param out [out] The destination of the authentication tag + @param outlen [in/out] The max size and resulting size of the authentication tag (octets) + @return CRYPT_OK if successful +*/ +int omac_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + int err; + omac_state *omac; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* is the cipher valid? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* Use accelerator if found */ + if (cipher_descriptor[cipher].omac_memory != NULL) { + return cipher_descriptor[cipher].omac_memory(key, keylen, in, inlen, out, outlen); + } + + /* allocate ram for omac state */ + omac = XMALLOC(sizeof(omac_state)); + if (omac == NULL) { + return CRYPT_MEM; + } + + /* omac process the message */ + if ((err = omac_init(omac, cipher, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = omac_process(omac, in, inlen)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = omac_done(omac, out, outlen)) != CRYPT_OK) { + goto LBL_ERR; + } + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(omac, sizeof(omac_state)); +#endif + + XFREE(omac); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/omac/omac_memory.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/omac/omac_memory_multi.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/omac/omac_memory_multi.c new file mode 100644 index 0000000000..abd5b27eb0 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/omac/omac_memory_multi.c @@ -0,0 +1,90 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" +#include + +/** + @file omac_memory_multi.c + LTC_OMAC1 support, process multiple blocks of memory, Tom St Denis +*/ + +#ifdef LTC_OMAC + +/** + LTC_OMAC multiple blocks of memory + @param cipher The index of the desired cipher + @param key The secret key + @param keylen The length of the secret key (octets) + @param out [out] The destination of the authentication tag + @param outlen [in/out] The max size and resulting size of the authentication tag (octets) + @param in The data to send through LTC_OMAC + @param inlen The length of the data to send through LTC_OMAC (octets) + @param ... tuples of (data,len) pairs to LTC_OMAC, terminated with a (NULL,x) (x=don't care) + @return CRYPT_OK if successful +*/ +int omac_memory_multi(int cipher, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...) +{ + int err; + omac_state *omac; + va_list args; + const unsigned char *curptr; + unsigned long curlen; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* allocate ram for omac state */ + omac = XMALLOC(sizeof(omac_state)); + if (omac == NULL) { + return CRYPT_MEM; + } + + /* omac process the message */ + if ((err = omac_init(omac, cipher, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + va_start(args, inlen); + curptr = in; + curlen = inlen; + for (;;) { + /* process buf */ + if ((err = omac_process(omac, curptr, curlen)) != CRYPT_OK) { + goto LBL_ERR; + } + /* step to next */ + curptr = va_arg(args, const unsigned char*); + if (curptr == NULL) { + break; + } + curlen = va_arg(args, unsigned long); + } + if ((err = omac_done(omac, out, outlen)) != CRYPT_OK) { + goto LBL_ERR; + } +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(omac, sizeof(omac_state)); +#endif + XFREE(omac); + va_end(args); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/omac/omac_memory_multi.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/omac/omac_process.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/omac/omac_process.c new file mode 100644 index 0000000000..c8036c5be6 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/omac/omac_process.c @@ -0,0 +1,89 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file omac_process.c + LTC_OMAC1 support, process data, Tom St Denis +*/ + + +#ifdef LTC_OMAC + +/** + Process data through LTC_OMAC + @param omac The LTC_OMAC state + @param in The input data to send through LTC_OMAC + @param inlen The length of the input (octets) + @return CRYPT_OK if successful +*/ +int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen) +{ + unsigned long n, x, blklen; + int err; + + LTC_ARGCHK(omac != NULL); + LTC_ARGCHK(in != NULL); + if ((err = cipher_is_valid(omac->cipher_idx)) != CRYPT_OK) { + return err; + } + + if ((omac->buflen > (int)sizeof(omac->block)) || (omac->buflen < 0) || + (omac->blklen > (int)sizeof(omac->block)) || (omac->buflen > omac->blklen)) { + return CRYPT_INVALID_ARG; + } + +#ifdef LTC_FAST + blklen = cipher_descriptor[omac->cipher_idx].block_length; + if (omac->buflen == 0 && inlen > blklen) { + unsigned long y; + for (x = 0; x < (inlen - blklen); x += blklen) { + for (y = 0; y < blklen; y += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)(&omac->prev[y])) ^= *((LTC_FAST_TYPE*)(&in[y])); + } + in += blklen; + if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->prev, omac->prev, &omac->key)) != CRYPT_OK) { + return err; + } + } + inlen -= x; + } +#endif + + while (inlen != 0) { + /* ok if the block is full we xor in prev, encrypt and replace prev */ + if (omac->buflen == omac->blklen) { + for (x = 0; x < (unsigned long)omac->blklen; x++) { + omac->block[x] ^= omac->prev[x]; + } + if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->prev, &omac->key)) != CRYPT_OK) { + return err; + } + omac->buflen = 0; + } + + /* add bytes */ + n = MIN(inlen, (unsigned long)(omac->blklen - omac->buflen)); + XMEMCPY(omac->block + omac->buflen, in, n); + omac->buflen += n; + inlen -= n; + in += n; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/omac/omac_process.c,v $ */ +/* $Revision: 1.13 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/omac/omac_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/omac/omac_test.c new file mode 100644 index 0000000000..7fb23aa31d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/omac/omac_test.c @@ -0,0 +1,110 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file omac_test.c + LTC_OMAC1 support, self-test, by Tom St Denis +*/ + +#ifdef LTC_OMAC + +/** + Test the LTC_OMAC setup + @return CRYPT_OK if successful, CRYPT_NOP if tests have been disabled +*/ +int omac_test(void) +{ +#if !defined(LTC_TEST) + return CRYPT_NOP; +#else + static const struct { + int keylen, msglen; + unsigned char key[16], msg[64], tag[16]; + } tests[] = { + { 16, 0, + { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, + { 0x00 }, + { 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28, + 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46 } + }, + { 16, 16, + { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, + { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a }, + { 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, + 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c } + }, + { 16, 40, + { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, + { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11 }, + { 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30, + 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27 } + }, + { 16, 64, + { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, + { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 }, + { 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, + 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe } + } + + }; + unsigned char out[16]; + int x, err, idx; + unsigned long len; + + + /* AES can be under rijndael or aes... try to find it */ + if ((idx = find_cipher("aes")) == -1) { + if ((idx = find_cipher("rijndael")) == -1) { + return CRYPT_NOP; + } + } + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + len = sizeof(out); + if ((err = omac_memory(idx, tests[x].key, tests[x].keylen, tests[x].msg, tests[x].msglen, out, &len)) != CRYPT_OK) { + return err; + } + + if (XMEMCMP(out, tests[x].tag, 16) != 0) { +#if 0 + int y; + printf("\n\nTag: "); + for (y = 0; y < 16; y++) printf("%02x", out[y]); printf("\n\n"); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/omac/omac_test.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pelican/pelican.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pelican/pelican.c new file mode 100644 index 0000000000..b586408210 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pelican/pelican.c @@ -0,0 +1,165 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pelican.c + Pelican MAC, initialize state, by Tom St Denis +*/ + +#ifdef LTC_PELICAN + +#define ENCRYPT_ONLY +#define PELI_TAB +#include "../../ciphers/aes/aes_tab.c" + +/** + Initialize a Pelican state + @param pelmac The Pelican state to initialize + @param key The secret key + @param keylen The length of the secret key (octets) + @return CRYPT_OK if successful +*/ +int pelican_init(pelican_state *pelmac, const unsigned char *key, unsigned long keylen) +{ + int err; + + LTC_ARGCHK(pelmac != NULL); + LTC_ARGCHK(key != NULL); + +#ifdef LTC_FAST + if (16 % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + + if ((err = aes_setup(key, keylen, 0, &pelmac->K)) != CRYPT_OK) { + return err; + } + + zeromem(pelmac->state, 16); + aes_ecb_encrypt(pelmac->state, pelmac->state, &pelmac->K); + pelmac->buflen = 0; + + return CRYPT_OK; +} + +static void four_rounds(pelican_state *pelmac) +{ + ulong32 s0, s1, s2, s3, t0, t1, t2, t3; + int r; + + LOAD32H(s0, pelmac->state ); + LOAD32H(s1, pelmac->state + 4); + LOAD32H(s2, pelmac->state + 8); + LOAD32H(s3, pelmac->state + 12); + for (r = 0; r < 4; r++) { + t0 = + Te0(byte(s0, 3)) ^ + Te1(byte(s1, 2)) ^ + Te2(byte(s2, 1)) ^ + Te3(byte(s3, 0)); + t1 = + Te0(byte(s1, 3)) ^ + Te1(byte(s2, 2)) ^ + Te2(byte(s3, 1)) ^ + Te3(byte(s0, 0)); + t2 = + Te0(byte(s2, 3)) ^ + Te1(byte(s3, 2)) ^ + Te2(byte(s0, 1)) ^ + Te3(byte(s1, 0)); + t3 = + Te0(byte(s3, 3)) ^ + Te1(byte(s0, 2)) ^ + Te2(byte(s1, 1)) ^ + Te3(byte(s2, 0)); + s0 = t0; s1 = t1; s2 = t2; s3 = t3; + } + STORE32H(s0, pelmac->state ); + STORE32H(s1, pelmac->state + 4); + STORE32H(s2, pelmac->state + 8); + STORE32H(s3, pelmac->state + 12); +} + +/** + Process a block of text through Pelican + @param pelmac The Pelican MAC state + @param in The input + @param inlen The length input (octets) + @return CRYPT_OK on success + */ +int pelican_process(pelican_state *pelmac, const unsigned char *in, unsigned long inlen) +{ + + LTC_ARGCHK(pelmac != NULL); + LTC_ARGCHK(in != NULL); + + /* check range */ + if (pelmac->buflen < 0 || pelmac->buflen > 15) { + return CRYPT_INVALID_ARG; + } + +#ifdef LTC_FAST + if (pelmac->buflen == 0) { + while (inlen & ~15) { + int x; + for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)((unsigned char *)pelmac->state + x)) ^= *((LTC_FAST_TYPE*)((unsigned char *)in + x)); + } + four_rounds(pelmac); + in += 16; + inlen -= 16; + } + } +#endif + + while (inlen--) { + pelmac->state[pelmac->buflen++] ^= *in++; + if (pelmac->buflen == 16) { + four_rounds(pelmac); + pelmac->buflen = 0; + } + } + return CRYPT_OK; +} + +/** + Terminate Pelican MAC + @param pelmac The Pelican MAC state + @param out [out] The TAG + @return CRYPT_OK on sucess +*/ +int pelican_done(pelican_state *pelmac, unsigned char *out) +{ + LTC_ARGCHK(pelmac != NULL); + LTC_ARGCHK(out != NULL); + + /* check range */ + if (pelmac->buflen < 0 || pelmac->buflen > 16) { + return CRYPT_INVALID_ARG; + } + + if (pelmac->buflen == 16) { + four_rounds(pelmac); + pelmac->buflen = 0; + } + pelmac->state[pelmac->buflen++] ^= 0x80; + aes_ecb_encrypt(pelmac->state, out, &pelmac->K); + aes_done(&pelmac->K); + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/pelican/pelican.c,v $ */ +/* $Revision: 1.20 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pelican/pelican_memory.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pelican/pelican_memory.c new file mode 100644 index 0000000000..e9f9900776 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pelican/pelican_memory.c @@ -0,0 +1,59 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pelican_memory.c + Pelican MAC, MAC a block of memory, by Tom St Denis +*/ + +#ifdef LTC_PELICAN + +/** + Pelican block of memory + @param key The key for the MAC + @param keylen The length of the key (octets) + @param in The input to MAC + @param inlen The length of the input (octets) + @param out [out] The output TAG + @return CRYPT_OK on success +*/ +int pelican_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out) +{ + pelican_state *pel; + int err; + + pel = XMALLOC(sizeof(*pel)); + if (pel == NULL) { + return CRYPT_MEM; + } + + if ((err = pelican_init(pel, key, keylen)) != CRYPT_OK) { + XFREE(pel); + return err; + } + if ((err = pelican_process(pel, in ,inlen)) != CRYPT_OK) { + XFREE(pel); + return err; + } + err = pelican_done(pel, out); + XFREE(pel); + return err; +} + + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/pelican/pelican_memory.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pelican/pelican_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pelican/pelican_test.c new file mode 100644 index 0000000000..474d562ad7 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pelican/pelican_test.c @@ -0,0 +1,120 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pelican_test.c + Pelican MAC, test, by Tom St Denis +*/ + +#ifdef LTC_PELICAN + +int pelican_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + unsigned char K[32], MSG[64], T[16]; + int keylen, ptlen; + } tests[] = { +/* K=16, M=0 */ +{ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, + { 0 }, + { 0xeb, 0x58, 0x37, 0x15, 0xf8, 0x34, 0xde, 0xe5, + 0xa4, 0xd1, 0x6e, 0xe4, 0xb9, 0xd7, 0x76, 0x0e, }, + 16, 0 +}, + +/* K=16, M=3 */ +{ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, + { 0x00, 0x01, 0x02 }, + { 0x1c, 0x97, 0x40, 0x60, 0x6c, 0x58, 0x17, 0x2d, + 0x03, 0x94, 0x19, 0x70, 0x81, 0xc4, 0x38, 0x54, }, + 16, 3 +}, + +/* K=16, M=16 */ +{ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, + { 0x03, 0xcc, 0x46, 0xb8, 0xac, 0xa7, 0x9c, 0x36, + 0x1e, 0x8c, 0x6e, 0xa6, 0x7b, 0x89, 0x32, 0x49, }, + 16, 16 +}, + +/* K=16, M=32 */ +{ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, + { 0x89, 0xcc, 0x36, 0x58, 0x1b, 0xdd, 0x4d, 0xb5, + 0x78, 0xbb, 0xac, 0xf0, 0xff, 0x8b, 0x08, 0x15, }, + 16, 32 +}, + +/* K=16, M=35 */ +{ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x23 }, + { 0x4a, 0x7d, 0x45, 0x4d, 0xcd, 0xb5, 0xda, 0x8d, + 0x48, 0x78, 0x16, 0x48, 0x5d, 0x45, 0x95, 0x99, }, + 16, 35 +}, +}; + int x, err; + unsigned char out[16]; + pelican_state pel; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + if ((err = pelican_init(&pel, tests[x].K, tests[x].keylen)) != CRYPT_OK) { + return err; + } + if ((err = pelican_process(&pel, tests[x].MSG, tests[x].ptlen)) != CRYPT_OK) { + return err; + } + if ((err = pelican_done(&pel, out)) != CRYPT_OK) { + return err; + } + + if (XMEMCMP(out, tests[x].T, 16)) { +#if 0 + int y; + printf("\nFailed test %d\n", x); + printf("{ "); for (y = 0; y < 16; ) { printf("0x%02x, ", out[y]); if (!(++y & 7)) printf("\n"); } printf(" }\n"); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/pelican/pelican_test.c,v $ */ +/* $Revision: 1.14 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_done.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_done.c new file mode 100644 index 0000000000..90e41a77bf --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_done.c @@ -0,0 +1,74 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pmac_done.c + PMAC implementation, terminate a session, by Tom St Denis +*/ + +#ifdef LTC_PMAC + +int pmac_done(pmac_state *state, unsigned char *out, unsigned long *outlen) +{ + int err, x; + + LTC_ARGCHK(state != NULL); + LTC_ARGCHK(out != NULL); + if ((err = cipher_is_valid(state->cipher_idx)) != CRYPT_OK) { + return err; + } + + if ((state->buflen > (int)sizeof(state->block)) || (state->buflen < 0) || + (state->block_len > (int)sizeof(state->block)) || (state->buflen > state->block_len)) { + return CRYPT_INVALID_ARG; + } + + + /* handle padding. If multiple xor in L/x */ + + if (state->buflen == state->block_len) { + /* xor Lr against the checksum */ + for (x = 0; x < state->block_len; x++) { + state->checksum[x] ^= state->block[x] ^ state->Lr[x]; + } + } else { + /* otherwise xor message bytes then the 0x80 byte */ + for (x = 0; x < state->buflen; x++) { + state->checksum[x] ^= state->block[x]; + } + state->checksum[x] ^= 0x80; + } + + /* encrypt it */ + if ((err = cipher_descriptor[state->cipher_idx].ecb_encrypt(state->checksum, state->checksum, &state->key)) != CRYPT_OK) { + return err; + } + cipher_descriptor[state->cipher_idx].done(&state->key); + + /* store it */ + for (x = 0; x < state->block_len && x < (int)*outlen; x++) { + out[x] = state->checksum[x]; + } + *outlen = x; + +#ifdef LTC_CLEAN_STACK + zeromem(state, sizeof(*state)); +#endif + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_done.c,v $ */ +/* $Revision: 1.9 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_file.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_file.c new file mode 100644 index 0000000000..708b7586d0 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_file.c @@ -0,0 +1,84 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pmac_file.c + PMAC implementation, process a file, by Tom St Denis +*/ + +#ifdef LTC_PMAC + +/** + PMAC a file + @param cipher The index of the cipher desired + @param key The secret key + @param keylen The length of the secret key (octets) + @param filename The name of the file to send through PMAC + @param out [out] Destination for the authentication tag + @param outlen [in/out] Max size and resulting size of the authentication tag + @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled +*/ +int pmac_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen) +{ +#ifdef LTC_NO_FILE + return CRYPT_NOP; +#else + int err, x; + pmac_state pmac; + FILE *in; + unsigned char buf[512]; + + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(filename != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + in = fopen(filename, "rb"); + if (in == NULL) { + return CRYPT_FILE_NOTFOUND; + } + + if ((err = pmac_init(&pmac, cipher, key, keylen)) != CRYPT_OK) { + fclose(in); + return err; + } + + do { + x = fread(buf, 1, sizeof(buf), in); + if ((err = pmac_process(&pmac, buf, x)) != CRYPT_OK) { + fclose(in); + return err; + } + } while (x == sizeof(buf)); + fclose(in); + + if ((err = pmac_done(&pmac, out, outlen)) != CRYPT_OK) { + return err; + } + +#ifdef LTC_CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + + return CRYPT_OK; +#endif +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_file.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_init.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_init.c new file mode 100644 index 0000000000..1261f8c6a7 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_init.c @@ -0,0 +1,147 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pmac_init.c + PMAC implementation, initialize state, by Tom St Denis +*/ + +#ifdef LTC_PMAC + +static const struct { + int len; + unsigned char poly_div[MAXBLOCKSIZE], + poly_mul[MAXBLOCKSIZE]; +} polys[] = { +{ + 8, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B } +}, { + 16, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 } +} +}; + +/** + Initialize a PMAC state + @param pmac The PMAC state to initialize + @param cipher The index of the desired cipher + @param key The secret key + @param keylen The length of the secret key (octets) + @return CRYPT_OK if successful +*/ +int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen) +{ + int poly, x, y, m, err; + unsigned char *L; + + LTC_ARGCHK(pmac != NULL); + LTC_ARGCHK(key != NULL); + + /* valid cipher? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* determine which polys to use */ + pmac->block_len = cipher_descriptor[cipher].block_length; + for (poly = 0; poly < (int)(sizeof(polys)/sizeof(polys[0])); poly++) { + if (polys[poly].len == pmac->block_len) { + break; + } + } + if (polys[poly].len != pmac->block_len) { + return CRYPT_INVALID_ARG; + } + +#ifdef LTC_FAST + if (pmac->block_len % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + + + /* schedule the key */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &pmac->key)) != CRYPT_OK) { + return err; + } + + /* allocate L */ + L = XMALLOC(pmac->block_len); + if (L == NULL) { + return CRYPT_MEM; + } + + /* find L = E[0] */ + zeromem(L, pmac->block_len); + if ((err = cipher_descriptor[cipher].ecb_encrypt(L, L, &pmac->key)) != CRYPT_OK) { + goto error; + } + + /* find Ls[i] = L << i for i == 0..31 */ + XMEMCPY(pmac->Ls[0], L, pmac->block_len); + for (x = 1; x < 32; x++) { + m = pmac->Ls[x-1][0] >> 7; + for (y = 0; y < pmac->block_len-1; y++) { + pmac->Ls[x][y] = ((pmac->Ls[x-1][y] << 1) | (pmac->Ls[x-1][y+1] >> 7)) & 255; + } + pmac->Ls[x][pmac->block_len-1] = (pmac->Ls[x-1][pmac->block_len-1] << 1) & 255; + + if (m == 1) { + for (y = 0; y < pmac->block_len; y++) { + pmac->Ls[x][y] ^= polys[poly].poly_mul[y]; + } + } + } + + /* find Lr = L / x */ + m = L[pmac->block_len-1] & 1; + + /* shift right */ + for (x = pmac->block_len - 1; x > 0; x--) { + pmac->Lr[x] = ((L[x] >> 1) | (L[x-1] << 7)) & 255; + } + pmac->Lr[0] = L[0] >> 1; + + if (m == 1) { + for (x = 0; x < pmac->block_len; x++) { + pmac->Lr[x] ^= polys[poly].poly_div[x]; + } + } + + /* zero buffer, counters, etc... */ + pmac->block_index = 1; + pmac->cipher_idx = cipher; + pmac->buflen = 0; + zeromem(pmac->block, sizeof(pmac->block)); + zeromem(pmac->Li, sizeof(pmac->Li)); + zeromem(pmac->checksum, sizeof(pmac->checksum)); + err = CRYPT_OK; +error: +#ifdef LTC_CLEAN_STACK + zeromem(L, pmac->block_len); +#endif + + XFREE(L); + + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_init.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_memory.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_memory.c new file mode 100644 index 0000000000..254e53bd58 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_memory.c @@ -0,0 +1,74 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pmac_memory.c + PMAC implementation, process a block of memory, by Tom St Denis +*/ + +#ifdef LTC_PMAC + +/** + PMAC a block of memory + @param cipher The index of the cipher desired + @param key The secret key + @param keylen The length of the secret key (octets) + @param in The data you wish to send through PMAC + @param inlen The length of data you wish to send through PMAC (octets) + @param out [out] Destination for the authentication tag + @param outlen [in/out] The max size and resulting size of the authentication tag + @return CRYPT_OK if successful +*/ +int pmac_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + int err; + pmac_state *pmac; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* allocate ram for pmac state */ + pmac = XMALLOC(sizeof(pmac_state)); + if (pmac == NULL) { + return CRYPT_MEM; + } + + if ((err = pmac_init(pmac, cipher, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = pmac_process(pmac, in, inlen)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = pmac_done(pmac, out, outlen)) != CRYPT_OK) { + goto LBL_ERR; + } + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(pmac, sizeof(pmac_state)); +#endif + + XFREE(pmac); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_memory.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_memory_multi.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_memory_multi.c new file mode 100644 index 0000000000..dfac221e06 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_memory_multi.c @@ -0,0 +1,89 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" +#include + +/** + @file pmac_memory_multi.c + PMAC implementation, process multiple blocks of memory, by Tom St Denis +*/ + +#ifdef LTC_PMAC + +/** + PMAC multiple blocks of memory + @param cipher The index of the cipher desired + @param key The secret key + @param keylen The length of the secret key (octets) + @param out [out] Destination for the authentication tag + @param outlen [in/out] The max size and resulting size of the authentication tag + @param in The data you wish to send through PMAC + @param inlen The length of data you wish to send through PMAC (octets) + @param ... tuples of (data,len) pairs to PMAC, terminated with a (NULL,x) (x=don't care) + @return CRYPT_OK if successful +*/ +int pmac_memory_multi(int cipher, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...) +{ + int err; + pmac_state *pmac; + va_list args; + const unsigned char *curptr; + unsigned long curlen; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* allocate ram for pmac state */ + pmac = XMALLOC(sizeof(pmac_state)); + if (pmac == NULL) { + return CRYPT_MEM; + } + + if ((err = pmac_init(pmac, cipher, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + va_start(args, inlen); + curptr = in; + curlen = inlen; + for (;;) { + /* process buf */ + if ((err = pmac_process(pmac, curptr, curlen)) != CRYPT_OK) { + goto LBL_ERR; + } + /* step to next */ + curptr = va_arg(args, const unsigned char*); + if (curptr == NULL) { + break; + } + curlen = va_arg(args, unsigned long); + } + if ((err = pmac_done(pmac, out, outlen)) != CRYPT_OK) { + goto LBL_ERR; + } +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(pmac, sizeof(pmac_state)); +#endif + XFREE(pmac); + va_end(args); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_memory_multi.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_ntz.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_ntz.c new file mode 100644 index 0000000000..9e48bbc103 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_ntz.c @@ -0,0 +1,39 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pmac_ntz.c + PMAC implementation, internal function, by Tom St Denis +*/ + +#ifdef LTC_PMAC + +/** + Internal PMAC function +*/ +int pmac_ntz(unsigned long x) +{ + int c; + x &= 0xFFFFFFFFUL; + c = 0; + while ((x & 1) == 0) { + ++c; + x >>= 1; + } + return c; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_ntz.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_process.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_process.c new file mode 100644 index 0000000000..4e9d7e868a --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_process.c @@ -0,0 +1,100 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pmac_process.c + PMAC implementation, process data, by Tom St Denis +*/ + + +#ifdef LTC_PMAC + +/** + Process data in a PMAC stream + @param pmac The PMAC state + @param in The data to send through PMAC + @param inlen The length of the data to send through PMAC + @return CRYPT_OK if successful +*/ +int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen) +{ + int err, n; + unsigned long x; + unsigned char Z[MAXBLOCKSIZE]; + + LTC_ARGCHK(pmac != NULL); + LTC_ARGCHK(in != NULL); + if ((err = cipher_is_valid(pmac->cipher_idx)) != CRYPT_OK) { + return err; + } + + if ((pmac->buflen > (int)sizeof(pmac->block)) || (pmac->buflen < 0) || + (pmac->block_len > (int)sizeof(pmac->block)) || (pmac->buflen > pmac->block_len)) { + return CRYPT_INVALID_ARG; + } + +#ifdef LTC_FAST + if (pmac->buflen == 0 && inlen > 16) { + unsigned long y; + for (x = 0; x < (inlen - 16); x += 16) { + pmac_shift_xor(pmac); + for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)(&Z[y])) = *((LTC_FAST_TYPE*)(&in[y])) ^ *((LTC_FAST_TYPE*)(&pmac->Li[y])); + } + if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key)) != CRYPT_OK) { + return err; + } + for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)(&pmac->checksum[y])) ^= *((LTC_FAST_TYPE*)(&Z[y])); + } + in += 16; + } + inlen -= x; + } +#endif + + while (inlen != 0) { + /* ok if the block is full we xor in prev, encrypt and replace prev */ + if (pmac->buflen == pmac->block_len) { + pmac_shift_xor(pmac); + for (x = 0; x < (unsigned long)pmac->block_len; x++) { + Z[x] = pmac->Li[x] ^ pmac->block[x]; + } + if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key)) != CRYPT_OK) { + return err; + } + for (x = 0; x < (unsigned long)pmac->block_len; x++) { + pmac->checksum[x] ^= Z[x]; + } + pmac->buflen = 0; + } + + /* add bytes */ + n = MIN(inlen, (unsigned long)(pmac->block_len - pmac->buflen)); + XMEMCPY(pmac->block + pmac->buflen, in, n); + pmac->buflen += n; + inlen -= n; + in += n; + } + +#ifdef LTC_CLEAN_STACK + zeromem(Z, sizeof(Z)); +#endif + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_process.c,v $ */ +/* $Revision: 1.9 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_shift_xor.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_shift_xor.c new file mode 100644 index 0000000000..c92514fe64 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_shift_xor.c @@ -0,0 +1,44 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pmac_shift_xor.c + PMAC implementation, internal function, by Tom St Denis +*/ + +#ifdef LTC_PMAC + +/** + Internal function. Performs the state update (adding correct multiple) + @param pmac The PMAC state. +*/ +void pmac_shift_xor(pmac_state *pmac) +{ + int x, y; + y = pmac_ntz(pmac->block_index++); +#ifdef LTC_FAST + for (x = 0; x < pmac->block_len; x += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)((unsigned char *)pmac->Li + x)) ^= + *((LTC_FAST_TYPE*)((unsigned char *)pmac->Ls[y] + x)); + } +#else + for (x = 0; x < pmac->block_len; x++) { + pmac->Li[x] ^= pmac->Ls[y][x]; + } +#endif +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_shift_xor.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_test.c new file mode 100644 index 0000000000..357796ecc6 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/pmac/pmac_test.c @@ -0,0 +1,165 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pmac_test.c + PMAC implementation, self-test, by Tom St Denis +*/ + + +#ifdef LTC_PMAC + +/** + Test the LTC_OMAC implementation + @return CRYPT_OK if successful, CRYPT_NOP if testing has been disabled +*/ +int pmac_test(void) +{ +#if !defined(LTC_TEST) + return CRYPT_NOP; +#else + static const struct { + int msglen; + unsigned char key[16], msg[34], tag[16]; + } tests[] = { + + /* PMAC-AES-128-0B */ +{ + 0, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* msg */ + { 0x00 }, + /* tag */ + { 0x43, 0x99, 0x57, 0x2c, 0xd6, 0xea, 0x53, 0x41, + 0xb8, 0xd3, 0x58, 0x76, 0xa7, 0x09, 0x8a, 0xf7 } +}, + + /* PMAC-AES-128-3B */ +{ + 3, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* msg */ + { 0x00, 0x01, 0x02 }, + /* tag */ + { 0x25, 0x6b, 0xa5, 0x19, 0x3c, 0x1b, 0x99, 0x1b, + 0x4d, 0xf0, 0xc5, 0x1f, 0x38, 0x8a, 0x9e, 0x27 } +}, + + /* PMAC-AES-128-16B */ +{ + 16, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* msg */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* tag */ + { 0xeb, 0xbd, 0x82, 0x2f, 0xa4, 0x58, 0xda, 0xf6, + 0xdf, 0xda, 0xd7, 0xc2, 0x7d, 0xa7, 0x63, 0x38 } +}, + + /* PMAC-AES-128-20B */ +{ + 20, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* msg */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13 }, + /* tag */ + { 0x04, 0x12, 0xca, 0x15, 0x0b, 0xbf, 0x79, 0x05, + 0x8d, 0x8c, 0x75, 0xa5, 0x8c, 0x99, 0x3f, 0x55 } +}, + + /* PMAC-AES-128-32B */ +{ + 32, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* msg */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, + /* tag */ + { 0xe9, 0x7a, 0xc0, 0x4e, 0x9e, 0x5e, 0x33, 0x99, + 0xce, 0x53, 0x55, 0xcd, 0x74, 0x07, 0xbc, 0x75 } +}, + + /* PMAC-AES-128-34B */ +{ + 34, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* msg */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21 }, + /* tag */ + { 0x5c, 0xba, 0x7d, 0x5e, 0xb2, 0x4f, 0x7c, 0x86, + 0xcc, 0xc5, 0x46, 0x04, 0xe5, 0x3d, 0x55, 0x12 } +} + +}; + int err, x, idx; + unsigned long len; + unsigned char outtag[MAXBLOCKSIZE]; + + /* AES can be under rijndael or aes... try to find it */ + if ((idx = find_cipher("aes")) == -1) { + if ((idx = find_cipher("rijndael")) == -1) { + return CRYPT_NOP; + } + } + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + len = sizeof(outtag); + if ((err = pmac_memory(idx, tests[x].key, 16, tests[x].msg, tests[x].msglen, outtag, &len)) != CRYPT_OK) { + return err; + } + + if (XMEMCMP(outtag, tests[x].tag, len)) { +#if 0 + unsigned long y; + printf("\nTAG:\n"); + for (y = 0; y < len; ) { + printf("0x%02x", outtag[y]); + if (y < len-1) printf(", "); + if (!(++y % 8)) printf("\n"); + } +#endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif /* LTC_TEST */ +} + +#endif /* PMAC_MODE */ + + + + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_test.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/xcbc/xcbc_done.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/xcbc/xcbc_done.c new file mode 100644 index 0000000000..b71a946d88 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/xcbc/xcbc_done.c @@ -0,0 +1,76 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file xcbc_done.c + XCBC Support, terminate the state +*/ + +#ifdef LTC_XCBC + +/** Terminate the XCBC-MAC state + @param xcbc XCBC state to terminate + @param out [out] Destination for the MAC tag + @param outlen [in/out] Destination size and final tag size + Return CRYPT_OK on success +*/ +int xcbc_done(xcbc_state *xcbc, unsigned char *out, unsigned long *outlen) +{ + int err, x; + LTC_ARGCHK(xcbc != NULL); + LTC_ARGCHK(out != NULL); + + /* check structure */ + if ((err = cipher_is_valid(xcbc->cipher)) != CRYPT_OK) { + return err; + } + + if ((xcbc->blocksize > cipher_descriptor[xcbc->cipher].block_length) || (xcbc->blocksize < 0) || + (xcbc->buflen > xcbc->blocksize) || (xcbc->buflen < 0)) { + return CRYPT_INVALID_ARG; + } + + /* which key do we use? */ + if (xcbc->buflen == xcbc->blocksize) { + /* k2 */ + for (x = 0; x < xcbc->blocksize; x++) { + xcbc->IV[x] ^= xcbc->K[1][x]; + } + } else { + xcbc->IV[xcbc->buflen] ^= 0x80; + /* k3 */ + for (x = 0; x < xcbc->blocksize; x++) { + xcbc->IV[x] ^= xcbc->K[2][x]; + } + } + + /* encrypt */ + cipher_descriptor[xcbc->cipher].ecb_encrypt(xcbc->IV, xcbc->IV, &xcbc->key); + cipher_descriptor[xcbc->cipher].done(&xcbc->key); + + /* extract tag */ + for (x = 0; x < xcbc->blocksize && (unsigned long)x < *outlen; x++) { + out[x] = xcbc->IV[x]; + } + *outlen = x; + +#ifdef LTC_CLEAN_STACK + zeromem(xcbc, sizeof(*xcbc)); +#endif + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/xcbc/xcbc_done.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/xcbc/xcbc_file.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/xcbc/xcbc_file.c new file mode 100644 index 0000000000..be168ebc4a --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/xcbc/xcbc_file.c @@ -0,0 +1,83 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file xcbc_file.c + XCBC support, process a file, Tom St Denis +*/ + +#ifdef LTC_XCBC + +/** + XCBC a file + @param cipher The index of the cipher desired + @param key The secret key + @param keylen The length of the secret key (octets) + @param filename The name of the file you wish to XCBC + @param out [out] Where the authentication tag is to be stored + @param outlen [in/out] The max size and resulting size of the authentication tag + @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled +*/ +int xcbc_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen) +{ +#ifdef LTC_NO_FILE + return CRYPT_NOP; +#else + int err, x; + xcbc_state xcbc; + FILE *in; + unsigned char buf[512]; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(filename != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + in = fopen(filename, "rb"); + if (in == NULL) { + return CRYPT_FILE_NOTFOUND; + } + + if ((err = xcbc_init(&xcbc, cipher, key, keylen)) != CRYPT_OK) { + fclose(in); + return err; + } + + do { + x = fread(buf, 1, sizeof(buf), in); + if ((err = xcbc_process(&xcbc, buf, x)) != CRYPT_OK) { + fclose(in); + return err; + } + } while (x == sizeof(buf)); + fclose(in); + + if ((err = xcbc_done(&xcbc, out, outlen)) != CRYPT_OK) { + return err; + } + +#ifdef LTC_CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + + return CRYPT_OK; +#endif +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/xcbc/xcbc_file.c,v $ */ +/* $Revision: 1.2 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/xcbc/xcbc_init.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/xcbc/xcbc_init.c new file mode 100644 index 0000000000..2fa5032750 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/xcbc/xcbc_init.c @@ -0,0 +1,107 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file xcbc_init.c + XCBC Support, start an XCBC state +*/ + +#ifdef LTC_XCBC + +/** Initialize XCBC-MAC state + @param xcbc [out] XCBC state to initialize + @param cipher Index of cipher to use + @param key [in] Secret key + @param keylen Length of secret key in octets + Return CRYPT_OK on success +*/ +int xcbc_init(xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned long keylen) +{ + int x, y, err; + symmetric_key *skey; + unsigned long k1; + + LTC_ARGCHK(xcbc != NULL); + LTC_ARGCHK(key != NULL); + + /* schedule the key */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + +#ifdef LTC_FAST + if (cipher_descriptor[cipher].block_length % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + + skey = NULL; + + /* are we in pure XCBC mode with three keys? */ + if (keylen & LTC_XCBC_PURE) { + keylen &= ~LTC_XCBC_PURE; + + if (keylen < 2UL*cipher_descriptor[cipher].block_length) { + return CRYPT_INVALID_ARG; + } + + k1 = keylen - 2*cipher_descriptor[cipher].block_length; + XMEMCPY(xcbc->K[0], key, k1); + XMEMCPY(xcbc->K[1], key+k1, cipher_descriptor[cipher].block_length); + XMEMCPY(xcbc->K[2], key+k1 + cipher_descriptor[cipher].block_length, cipher_descriptor[cipher].block_length); + } else { + /* use the key expansion */ + k1 = cipher_descriptor[cipher].block_length; + + /* schedule the user key */ + skey = XCALLOC(1, sizeof(*skey)); + if (skey == NULL) { + return CRYPT_MEM; + } + + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) { + goto done; + } + + /* make the three keys */ + for (y = 0; y < 3; y++) { + for (x = 0; x < cipher_descriptor[cipher].block_length; x++) { + xcbc->K[y][x] = y + 1; + } + cipher_descriptor[cipher].ecb_encrypt(xcbc->K[y], xcbc->K[y], skey); + } + } + + /* setup K1 */ + err = cipher_descriptor[cipher].setup(xcbc->K[0], k1, 0, &xcbc->key); + + /* setup struct */ + zeromem(xcbc->IV, cipher_descriptor[cipher].block_length); + xcbc->blocksize = cipher_descriptor[cipher].block_length; + xcbc->cipher = cipher; + xcbc->buflen = 0; +done: + cipher_descriptor[cipher].done(skey); + if (skey != NULL) { +#ifdef LTC_CLEAN_STACK + zeromem(skey, sizeof(*skey)); +#endif + XFREE(skey); + } + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/xcbc/xcbc_init.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/02/20 13:07:58 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/xcbc/xcbc_memory.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/xcbc/xcbc_memory.c new file mode 100644 index 0000000000..8f194a1acb --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/xcbc/xcbc_memory.c @@ -0,0 +1,71 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file xcbc_process.c + XCBC Support, XCBC-MAC a block of memory +*/ + +#ifdef LTC_XCBC + +/** XCBC-MAC a block of memory + @param cipher Index of cipher to use + @param key [in] Secret key + @param keylen Length of key in octets + @param in [in] Message to MAC + @param inlen Length of input in octets + @param out [out] Destination for the MAC tag + @param outlen [in/out] Output size and final tag size + Return CRYPT_OK on success. +*/ +int xcbc_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + xcbc_state *xcbc; + int err; + + /* is the cipher valid? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* Use accelerator if found */ + if (cipher_descriptor[cipher].xcbc_memory != NULL) { + return cipher_descriptor[cipher].xcbc_memory(key, keylen, in, inlen, out, outlen); + } + + xcbc = XCALLOC(1, sizeof(*xcbc)); + if (xcbc == NULL) { + return CRYPT_MEM; + } + + if ((err = xcbc_init(xcbc, cipher, key, keylen)) != CRYPT_OK) { + goto done; + } + + if ((err = xcbc_process(xcbc, in, inlen)) != CRYPT_OK) { + goto done; + } + + err = xcbc_done(xcbc, out, outlen); +done: + XFREE(xcbc); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/xcbc/xcbc_memory.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/xcbc/xcbc_memory_multi.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/xcbc/xcbc_memory_multi.c new file mode 100644 index 0000000000..5f65bd4162 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/xcbc/xcbc_memory_multi.c @@ -0,0 +1,90 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" +#include + +/** + @file xcbc_memory_multi.c + XCBC support, process multiple blocks of memory, Tom St Denis +*/ + +#ifdef LTC_XCBC + +/** + XCBC multiple blocks of memory + @param cipher The index of the desired cipher + @param key The secret key + @param keylen The length of the secret key (octets) + @param out [out] The destination of the authentication tag + @param outlen [in/out] The max size and resulting size of the authentication tag (octets) + @param in The data to send through XCBC + @param inlen The length of the data to send through XCBC (octets) + @param ... tuples of (data,len) pairs to XCBC, terminated with a (NULL,x) (x=don't care) + @return CRYPT_OK if successful +*/ +int xcbc_memory_multi(int cipher, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...) +{ + int err; + xcbc_state *xcbc; + va_list args; + const unsigned char *curptr; + unsigned long curlen; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* allocate ram for xcbc state */ + xcbc = XMALLOC(sizeof(xcbc_state)); + if (xcbc == NULL) { + return CRYPT_MEM; + } + + /* xcbc process the message */ + if ((err = xcbc_init(xcbc, cipher, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + va_start(args, inlen); + curptr = in; + curlen = inlen; + for (;;) { + /* process buf */ + if ((err = xcbc_process(xcbc, curptr, curlen)) != CRYPT_OK) { + goto LBL_ERR; + } + /* step to next */ + curptr = va_arg(args, const unsigned char*); + if (curptr == NULL) { + break; + } + curlen = va_arg(args, unsigned long); + } + if ((err = xcbc_done(xcbc, out, outlen)) != CRYPT_OK) { + goto LBL_ERR; + } +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(xcbc, sizeof(xcbc_state)); +#endif + XFREE(xcbc); + va_end(args); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/xcbc/xcbc_memory_multi.c,v $ */ +/* $Revision: 1.2 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/xcbc/xcbc_process.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/xcbc/xcbc_process.c new file mode 100644 index 0000000000..75bdaf724c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/xcbc/xcbc_process.c @@ -0,0 +1,74 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file xcbc_process.c + XCBC Support, process blocks with XCBC +*/ + +#ifdef LTC_XCBC + +/** Process data through XCBC-MAC + @param xcbc The XCBC-MAC state + @param in Input data to process + @param inlen Length of input in octets + Return CRYPT_OK on success +*/ +int xcbc_process(xcbc_state *xcbc, const unsigned char *in, unsigned long inlen) +{ + int err; +#ifdef LTC_FAST + int x; +#endif + + LTC_ARGCHK(xcbc != NULL); + LTC_ARGCHK(in != NULL); + + /* check structure */ + if ((err = cipher_is_valid(xcbc->cipher)) != CRYPT_OK) { + return err; + } + + if ((xcbc->blocksize > cipher_descriptor[xcbc->cipher].block_length) || (xcbc->blocksize < 0) || + (xcbc->buflen > xcbc->blocksize) || (xcbc->buflen < 0)) { + return CRYPT_INVALID_ARG; + } + +#ifdef LTC_FAST + if (xcbc->buflen == 0) { + while (inlen > (unsigned long)xcbc->blocksize) { + for (x = 0; x < xcbc->blocksize; x += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)&(xcbc->IV[x])) ^= *((LTC_FAST_TYPE*)&(in[x])); + } + cipher_descriptor[xcbc->cipher].ecb_encrypt(xcbc->IV, xcbc->IV, &xcbc->key); + in += xcbc->blocksize; + inlen -= xcbc->blocksize; + } + } +#endif + + while (inlen) { + if (xcbc->buflen == xcbc->blocksize) { + cipher_descriptor[xcbc->cipher].ecb_encrypt(xcbc->IV, xcbc->IV, &xcbc->key); + xcbc->buflen = 0; + } + xcbc->IV[xcbc->buflen++] ^= *in++; + --inlen; + } + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/xcbc/xcbc_process.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/xcbc/xcbc_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/xcbc/xcbc_test.c new file mode 100644 index 0000000000..ae44712a6c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/mac/xcbc/xcbc_test.c @@ -0,0 +1,127 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file xcbc_test.c + XCBC Support, Test XCBC-MAC mode +*/ + +#ifdef LTC_XCBC + +/** Test XCBC-MAC mode + Return CRYPT_OK on succes +*/ +int xcbc_test(void) +{ +#ifdef LTC_NO_TEST + return CRYPT_NOP; +#else + static const struct { + int msglen; + unsigned char K[16], M[34], T[16]; + } tests[] = { +{ + 0, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + + { 0 }, + + { 0x75, 0xf0, 0x25, 0x1d, 0x52, 0x8a, 0xc0, 0x1c, + 0x45, 0x73, 0xdf, 0xd5, 0x84, 0xd7, 0x9f, 0x29 } +}, + +{ + 3, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + + { 0x00, 0x01, 0x02 }, + + { 0x5b, 0x37, 0x65, 0x80, 0xae, 0x2f, 0x19, 0xaf, + 0xe7, 0x21, 0x9c, 0xee, 0xf1, 0x72, 0x75, 0x6f } +}, + +{ + 16, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + + { 0xd2, 0xa2, 0x46, 0xfa, 0x34, 0x9b, 0x68, 0xa7, + 0x99, 0x98, 0xa4, 0x39, 0x4f, 0xf7, 0xa2, 0x63 } +}, + +{ + 32, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, + + { 0xf5, 0x4f, 0x0e, 0xc8, 0xd2, 0xb9, 0xf3, 0xd3, + 0x68, 0x07, 0x73, 0x4b, 0xd5, 0x28, 0x3f, 0xd4 } +}, + +{ + 34, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21 }, + + { 0xbe, 0xcb, 0xb3, 0xbc, 0xcd, 0xb5, 0x18, 0xa3, + 0x06, 0x77, 0xd5, 0x48, 0x1f, 0xb6, 0xb4, 0xd8 }, +}, + + + +}; + unsigned char T[16]; + unsigned long taglen; + int err, x, idx; + + /* AES can be under rijndael or aes... try to find it */ + if ((idx = find_cipher("aes")) == -1) { + if ((idx = find_cipher("rijndael")) == -1) { + return CRYPT_NOP; + } + } + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + taglen = 16; + if ((err = xcbc_memory(idx, tests[x].K, 16, tests[x].M, tests[x].msglen, T, &taglen)) != CRYPT_OK) { + return err; + } + if (taglen != 16 || XMEMCMP(T, tests[x].T, 16)) { + return CRYPT_FAIL_TESTVECTOR; + } + } + + return CRYPT_OK; +#endif +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/mac/xcbc/xcbc_test.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/math/fp/ltc_ecc_fp_mulmod.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/math/fp/ltc_ecc_fp_mulmod.c new file mode 100644 index 0000000000..1dcdb29823 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/math/fp/ltc_ecc_fp_mulmod.c @@ -0,0 +1,1586 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ltc_ecc_fp_mulmod.c + ECC Crypto, Tom St Denis +*/ + +#if defined(LTC_MECC) && defined(LTC_MECC_FP) +#include + +/* number of entries in the cache */ +#ifndef FP_ENTRIES +#define FP_ENTRIES 16 +#endif + +/* number of bits in LUT */ +#ifndef FP_LUT +#define FP_LUT 8U +#endif + +#if (FP_LUT > 12) || (FP_LUT < 2) + #error FP_LUT must be between 2 and 12 inclusively +#endif + +/** Our FP cache */ +static struct { + ecc_point *g, /* cached COPY of base point */ + *LUT[1U< 6 + { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 }, + { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 }, + { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 }, + { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 }, + { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 }, + { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 }, + { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 }, + { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 }, +#if FP_LUT > 7 + { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 }, + { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 }, + { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 }, + { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 }, + { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 }, + { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 }, + { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 }, + { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 }, + { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 }, + { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 }, + { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 }, + { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 }, + { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 }, + { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 }, + { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 }, + { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 }, +#if FP_LUT > 8 + { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 }, + { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 }, + { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 }, + { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 }, + { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 }, + { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 }, + { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 }, + { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 }, + { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 }, + { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 }, + { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 }, + { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 }, + { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 }, + { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 }, + { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 }, + { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 }, + { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 }, + { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 }, + { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 }, + { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 }, + { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 }, + { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 }, + { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 }, + { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 }, + { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 }, + { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 }, + { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 }, + { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 }, + { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 }, + { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 }, + { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 }, + { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 }, +#if FP_LUT > 9 + { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 }, + { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 }, + { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 }, + { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 }, + { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 }, + { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 }, + { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 }, + { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 }, + { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 }, + { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 }, + { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 }, + { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 }, + { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 }, + { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 }, + { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 }, + { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 }, + { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 }, + { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 }, + { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 }, + { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 }, + { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 }, + { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 }, + { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 }, + { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 }, + { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 }, + { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 }, + { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 }, + { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 }, + { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 }, + { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 }, + { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 }, + { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 }, + { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 }, + { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 }, + { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 }, + { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 }, + { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 }, + { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 }, + { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 }, + { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 }, + { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 }, + { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 }, + { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 }, + { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 }, + { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 }, + { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 }, + { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 }, + { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 }, + { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 }, + { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 }, + { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 }, + { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 }, + { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 }, + { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 }, + { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 }, + { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 }, + { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 }, + { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 }, + { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 }, + { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 }, + { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 }, + { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 }, + { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 }, + { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 }, +#if FP_LUT > 10 + { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 }, + { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 }, + { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 }, + { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 }, + { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 }, + { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 }, + { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 }, + { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 }, + { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 }, + { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 }, + { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 }, + { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 }, + { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 }, + { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 }, + { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 }, + { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 }, + { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 }, + { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 }, + { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 }, + { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 }, + { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 }, + { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 }, + { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 }, + { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 }, + { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 }, + { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 }, + { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 }, + { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 }, + { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 }, + { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 }, + { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 }, + { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 }, + { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 }, + { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 }, + { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 }, + { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 }, + { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 }, + { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 }, + { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 }, + { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 }, + { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 }, + { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 }, + { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 }, + { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 }, + { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 }, + { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 }, + { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 }, + { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 }, + { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 }, + { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 }, + { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 }, + { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 }, + { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 }, + { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 }, + { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 }, + { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 }, + { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 }, + { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 }, + { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 }, + { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 }, + { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 }, + { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 }, + { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 }, + { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 }, + { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 }, + { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 }, + { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 }, + { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 }, + { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 }, + { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 }, + { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 }, + { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 }, + { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 }, + { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 }, + { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 }, + { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 }, + { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 }, + { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 }, + { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 }, + { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 }, + { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 }, + { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 }, + { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 }, + { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 }, + { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 }, + { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 }, + { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 }, + { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 }, + { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 }, + { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 }, + { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 }, + { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 }, + { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 }, + { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 }, + { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 }, + { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 }, + { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 }, + { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 }, + { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 }, + { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 }, + { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 }, + { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 }, + { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 }, + { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 }, + { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 }, + { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 }, + { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 }, + { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 }, + { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 }, + { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 }, + { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 }, + { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 }, + { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 }, + { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 }, + { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 }, + { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 }, + { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 }, + { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 }, + { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 }, + { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 }, + { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 }, + { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 }, + { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 }, + { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 }, + { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 }, + { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 }, + { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 }, + { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 }, +#if FP_LUT > 11 + { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 }, + { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 }, + { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 }, + { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 }, + { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 }, + { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 }, + { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 }, + { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 }, + { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 }, + { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 }, + { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 }, + { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 }, + { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 }, + { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 }, + { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 }, + { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 }, + { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 }, + { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 }, + { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 }, + { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 }, + { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 }, + { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 }, + { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 }, + { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 }, + { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 }, + { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 }, + { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 }, + { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 }, + { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 }, + { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 }, + { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 }, + { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 }, + { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 }, + { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 }, + { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 }, + { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 }, + { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 }, + { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 }, + { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 }, + { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 }, + { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 }, + { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 }, + { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 }, + { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 }, + { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 }, + { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 }, + { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 }, + { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 }, + { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 }, + { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 }, + { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 }, + { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 }, + { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 }, + { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 }, + { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 }, + { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 }, + { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 }, + { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 }, + { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 }, + { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 }, + { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 }, + { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 }, + { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 }, + { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 }, + { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 }, + { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 }, + { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 }, + { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 }, + { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 }, + { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 }, + { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 }, + { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 }, + { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 }, + { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 }, + { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 }, + { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 }, + { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 }, + { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 }, + { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 }, + { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 }, + { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 }, + { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 }, + { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 }, + { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 }, + { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 }, + { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 }, + { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 }, + { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 }, + { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 }, + { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 }, + { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 }, + { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 }, + { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 }, + { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 }, + { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 }, + { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 }, + { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 }, + { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 }, + { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 }, + { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 }, + { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 }, + { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 }, + { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 }, + { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 }, + { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 }, + { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 }, + { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 }, + { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 }, + { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 }, + { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 }, + { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 }, + { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 }, + { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 }, + { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 }, + { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 }, + { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 }, + { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 }, + { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 }, + { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 }, + { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 }, + { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 }, + { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 }, + { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 }, + { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 }, + { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 }, + { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 }, + { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 }, + { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 }, + { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 }, + { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 }, + { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 }, + { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 }, + { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 }, + { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 }, + { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 }, + { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 }, + { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 }, + { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 }, + { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 }, + { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 }, + { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 }, + { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 }, + { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 }, + { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 }, + { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 }, + { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 }, + { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 }, + { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 }, + { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 }, + { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 }, + { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 }, + { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 }, + { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 }, + { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 }, + { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 }, + { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 }, + { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 }, + { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 }, + { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 }, + { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 }, + { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 }, + { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 }, + { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 }, + { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 }, + { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 }, + { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 }, + { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 }, + { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 }, + { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 }, + { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 }, + { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 }, + { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 }, + { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 }, + { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 }, + { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 }, + { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 }, + { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 }, + { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 }, + { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 }, + { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 }, + { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 }, + { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 }, + { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 }, + { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 }, + { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 }, + { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 }, + { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 }, + { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 }, + { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 }, + { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 }, + { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 }, + { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 }, + { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 }, + { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 }, + { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 }, + { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 }, + { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 }, + { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 }, + { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 }, + { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 }, + { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 }, + { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 }, + { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 }, + { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 }, + { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 }, + { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 }, + { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 }, + { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 }, + { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 }, + { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 }, + { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 }, + { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 }, + { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 }, + { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 }, + { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 }, + { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 }, + { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 }, + { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 }, + { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 }, + { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 }, + { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 }, + { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 }, + { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 }, + { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 }, + { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 }, + { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 }, + { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 }, + { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 }, + { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 }, + { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 }, + { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 }, + { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 }, + { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 }, + { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 }, + { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 }, + { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 }, + { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 }, + { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 }, + { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 }, + { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 }, + { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 }, + { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 }, + { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 }, + { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 }, + { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 }, + { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 }, + { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 }, + { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 }, + { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 }, + { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 }, + { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 }, + { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 }, + { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 }, + { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 }, + { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 }, + { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 }, +#endif +#endif +#endif +#endif +#endif +#endif +}; + +/* find a hole and free as required, return -1 if no hole found */ +static int find_hole(void) +{ + unsigned x; + int y, z; + for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) { + if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) { + z = x; + y = fp_cache[x].lru_count; + } + } + + /* decrease all */ + for (x = 0; x < FP_ENTRIES; x++) { + if (fp_cache[x].lru_count > 3) { + --(fp_cache[x].lru_count); + } + } + + /* free entry z */ + if (z >= 0 && fp_cache[z].g) { + if (fp_cache[z].mu != NULL) { + mp_clear(fp_cache[z].mu); + fp_cache[z].mu = NULL; + } + ltc_ecc_del_point(fp_cache[z].g); + fp_cache[z].g = NULL; + for (x = 0; x < (1U<x, g->x) == LTC_MP_EQ && + mp_cmp(fp_cache[x].g->y, g->y) == LTC_MP_EQ && + mp_cmp(fp_cache[x].g->z, g->z) == LTC_MP_EQ) { + break; + } + } + if (x == FP_ENTRIES) { + x = -1; + } + return x; +} + +/* add a new base to the cache */ +static int add_entry(int idx, ecc_point *g) +{ + unsigned x, y; + + /* allocate base and LUT */ + fp_cache[idx].g = ltc_ecc_new_point(); + if (fp_cache[idx].g == NULL) { + return CRYPT_MEM; + } + + /* copy x and y */ + if ((mp_copy(g->x, fp_cache[idx].g->x) != CRYPT_OK) || + (mp_copy(g->y, fp_cache[idx].g->y) != CRYPT_OK) || + (mp_copy(g->z, fp_cache[idx].g->z) != CRYPT_OK)) { + ltc_ecc_del_point(fp_cache[idx].g); + fp_cache[idx].g = NULL; + return CRYPT_MEM; + } + + for (x = 0; x < (1U<x, mu, modulus, fp_cache[idx].LUT[1]->x) != CRYPT_OK) || + (mp_mulmod(fp_cache[idx].g->y, mu, modulus, fp_cache[idx].LUT[1]->y) != CRYPT_OK) || + (mp_mulmod(fp_cache[idx].g->z, mu, modulus, fp_cache[idx].LUT[1]->z) != CRYPT_OK)) { goto ERR; } + + /* make all single bit entries */ + for (x = 1; x < FP_LUT; x++) { + if ((mp_copy(fp_cache[idx].LUT[1<<(x-1)]->x, fp_cache[idx].LUT[1<x) != CRYPT_OK) || + (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->y, fp_cache[idx].LUT[1<y) != CRYPT_OK) || + (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->z, fp_cache[idx].LUT[1<z) != CRYPT_OK)) { goto ERR; } + + /* now double it bitlen/FP_LUT times */ + for (y = 0; y < lut_gap; y++) { + if ((err = ltc_mp.ecc_ptdbl(fp_cache[idx].LUT[1<z, modulus, mp)) != CRYPT_OK) { goto ERR; } + + /* invert it */ + if ((err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus, fp_cache[idx].LUT[x]->z)) != CRYPT_OK) { goto ERR; } + + /* now square it */ + if ((err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, tmp)) != CRYPT_OK) { goto ERR; } + + /* fix x */ + if ((err = mp_mulmod(fp_cache[idx].LUT[x]->x, tmp, modulus, fp_cache[idx].LUT[x]->x)) != CRYPT_OK) { goto ERR; } + + /* get 1/z^3 */ + if ((err = mp_mulmod(tmp, fp_cache[idx].LUT[x]->z, modulus, tmp)) != CRYPT_OK) { goto ERR; } + + /* fix y */ + if ((err = mp_mulmod(fp_cache[idx].LUT[x]->y, tmp, modulus, fp_cache[idx].LUT[x]->y)) != CRYPT_OK) { goto ERR; } + + /* free z */ + mp_clear(fp_cache[idx].LUT[x]->z); + fp_cache[idx].LUT[x]->z = NULL; + } + mp_clear(tmp); + + return CRYPT_OK; +ERR: + err = CRYPT_MEM; +DONE: + for (y = 0; y < (1U< mp_unsigned_bin_size(modulus)) { + /* find order */ + y = mp_unsigned_bin_size(modulus); + for (x = 0; ltc_ecc_sets[x].size; x++) { + if (y <= (unsigned)ltc_ecc_sets[x].size) break; + } + + /* back off if we are on the 521 bit curve */ + if (y == 66) --x; + + if ((err = mp_init(&order)) != CRYPT_OK) { + return err; + } + if ((err = mp_read_radix(order, ltc_ecc_sets[x].order, 16)) != CRYPT_OK) { + mp_clear(&order); + return err; + } + + /* k must be less than modulus */ + if (mp_cmp(k, order) != LTC_MP_LT) { + if ((err = mp_init(&tk)) != CRYPT_OK) { + mp_clear(order); + return err; + } + if ((err = mp_mod(k, order, tk)) != CRYPT_OK) { + mp_clear(tk); + mp_clear(order); + return err; + } + } else { + tk = k; + } + mp_clear(order); + } else { + tk = k; + } + + /* get bitlen and round up to next multiple of FP_LUT */ + bitlen = mp_unsigned_bin_size(modulus) << 3; + x = bitlen % FP_LUT; + if (x) { + bitlen += FP_LUT - x; + } + lut_gap = bitlen / FP_LUT; + + /* get the k value */ + if (mp_unsigned_bin_size(tk) > (sizeof(kb) - 2)) { + if (tk != k) { + mp_clear(tk); + } + return CRYPT_BUFFER_OVERFLOW; + } + + /* store k */ + zeromem(kb, sizeof(kb)); + if ((err = mp_to_unsigned_bin(tk, kb)) != CRYPT_OK) { + if (tk != k) { + mp_clear(tk); + } + return err; + } + + /* let's reverse kb so it's little endian */ + x = 0; + y = mp_unsigned_bin_size(tk) - 1; + if (tk != k) { + mp_clear(tk); + } + while ((unsigned)x < y) { + z = kb[x]; kb[x] = kb[y]; kb[y] = z; + ++x; --y; + } + + /* at this point we can start, yipee */ + first = 1; + for (x = lut_gap-1; x >= 0; x--) { + /* extract FP_LUT bits from kb spread out by lut_gap bits and offset by x bits from the start */ + bitpos = x; + for (y = z = 0; y < FP_LUT; y++) { + z |= ((kb[bitpos>>3] >> (bitpos&7)) & 1) << y; + bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid the mult in each loop */ + } + + /* double if not first */ + if (!first) { + if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { + return err; + } + } + + /* add if not first, otherwise copy */ + if (!first && z) { + if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx].LUT[z], R, modulus, mp)) != CRYPT_OK) { + return err; + } + } else if (z) { + if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != CRYPT_OK) || + (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != CRYPT_OK) || + (mp_copy(fp_cache[idx].mu, R->z) != CRYPT_OK)) { return CRYPT_MEM; } + first = 0; + } + } + z = 0; + zeromem(kb, sizeof(kb)); + /* map R back from projective space */ + if (map) { + err = ltc_ecc_map(R, modulus, mp); + } else { + err = CRYPT_OK; + } + return err; +} + +#ifdef LTC_ECC_SHAMIR +/* perform a fixed point ECC mulmod */ +static int accel_fp_mul2add(int idx1, int idx2, + void *kA, void *kB, + ecc_point *R, void *modulus, void *mp) +{ + unsigned char kb[2][128]; + int x; + unsigned y, z, err, bitlen, bitpos, lut_gap, first, zA, zB; + void *tka, *tkb, *order; + + /* if it's smaller than modulus we fine */ + if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) { + /* find order */ + y = mp_unsigned_bin_size(modulus); + for (x = 0; ltc_ecc_sets[x].size; x++) { + if (y <= (unsigned)ltc_ecc_sets[x].size) break; + } + + /* back off if we are on the 521 bit curve */ + if (y == 66) --x; + + if ((err = mp_init(&order)) != CRYPT_OK) { + return err; + } + if ((err = mp_read_radix(order, ltc_ecc_sets[x].order, 16)) != CRYPT_OK) { + mp_clear(&order); + return err; + } + + /* kA must be less than modulus */ + if (mp_cmp(kA, order) != LTC_MP_LT) { + if ((err = mp_init(&tka)) != CRYPT_OK) { + mp_clear(order); + return err; + } + if ((err = mp_mod(kA, order, tka)) != CRYPT_OK) { + mp_clear(tka); + mp_clear(order); + return err; + } + } else { + tka = kA; + } + mp_clear(order); + } else { + tka = kA; + } + + /* if it's smaller than modulus we fine */ + if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) { + /* find order */ + y = mp_unsigned_bin_size(modulus); + for (x = 0; ltc_ecc_sets[x].size; x++) { + if (y <= (unsigned)ltc_ecc_sets[x].size) break; + } + + /* back off if we are on the 521 bit curve */ + if (y == 66) --x; + + if ((err = mp_init(&order)) != CRYPT_OK) { + return err; + } + if ((err = mp_read_radix(order, ltc_ecc_sets[x].order, 16)) != CRYPT_OK) { + mp_clear(&order); + return err; + } + + /* kB must be less than modulus */ + if (mp_cmp(kB, order) != LTC_MP_LT) { + if ((err = mp_init(&tkb)) != CRYPT_OK) { + mp_clear(order); + return err; + } + if ((err = mp_mod(kB, order, tkb)) != CRYPT_OK) { + mp_clear(tkb); + mp_clear(order); + return err; + } + } else { + tkb = kB; + } + mp_clear(order); + } else { + tkb = kB; + } + + /* get bitlen and round up to next multiple of FP_LUT */ + bitlen = mp_unsigned_bin_size(modulus) << 3; + x = bitlen % FP_LUT; + if (x) { + bitlen += FP_LUT - x; + } + lut_gap = bitlen / FP_LUT; + + /* get the k value */ + if ((mp_unsigned_bin_size(tka) > (sizeof(kb[0]) - 2)) || (mp_unsigned_bin_size(tkb) > (sizeof(kb[0]) - 2)) ) { + if (tka != kA) { + mp_clear(tka); + } + if (tkb != kB) { + mp_clear(tkb); + } + return CRYPT_BUFFER_OVERFLOW; + } + + /* store k */ + zeromem(kb, sizeof(kb)); + if ((err = mp_to_unsigned_bin(tka, kb[0])) != CRYPT_OK) { + if (tka != kA) { + mp_clear(tka); + } + if (tkb != kB) { + mp_clear(tkb); + } + return err; + } + + /* let's reverse kb so it's little endian */ + x = 0; + y = mp_unsigned_bin_size(tka) - 1; + if (tka != kA) { + mp_clear(tka); + } + while ((unsigned)x < y) { + z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = z; + ++x; --y; + } + + /* store b */ + if ((err = mp_to_unsigned_bin(tkb, kb[1])) != CRYPT_OK) { + if (tkb != kB) { + mp_clear(tkb); + } + return err; + } + + x = 0; + y = mp_unsigned_bin_size(tkb) - 1; + if (tkb != kB) { + mp_clear(tkb); + } + while ((unsigned)x < y) { + z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = z; + ++x; --y; + } + + /* at this point we can start, yipee */ + first = 1; + for (x = lut_gap-1; x >= 0; x--) { + /* extract FP_LUT bits from kb spread out by lut_gap bits and offset by x bits from the start */ + bitpos = x; + for (y = zA = zB = 0; y < FP_LUT; y++) { + zA |= ((kb[0][bitpos>>3] >> (bitpos&7)) & 1) << y; + zB |= ((kb[1][bitpos>>3] >> (bitpos&7)) & 1) << y; + bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid the mult in each loop */ + } + + /* double if not first */ + if (!first) { + if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { + return err; + } + } + + /* add if not first, otherwise copy */ + if (!first) { + if (zA) { + if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx1].LUT[zA], R, modulus, mp)) != CRYPT_OK) { + return err; + } + } + if (zB) { + if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx2].LUT[zB], R, modulus, mp)) != CRYPT_OK) { + return err; + } + } + } else { + if (zA) { + if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != CRYPT_OK) || + (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != CRYPT_OK) || + (mp_copy(fp_cache[idx1].mu, R->z) != CRYPT_OK)) { return CRYPT_MEM; } + first = 0; + } + if (zB && first == 0) { + if (zB) { + if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx2].LUT[zB], R, modulus, mp)) != CRYPT_OK) { + return err; + } + } + } else if (zB && first == 1) { + if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != CRYPT_OK) || + (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != CRYPT_OK) || + (mp_copy(fp_cache[idx2].mu, R->z) != CRYPT_OK)) { return CRYPT_MEM; } + first = 0; + } + } + } + zeromem(kb, sizeof(kb)); + return ltc_ecc_map(R, modulus, mp); +} + +/** ECC Fixed Point mulmod global + Computes kA*A + kB*B = C using Shamir's Trick + @param A First point to multiply + @param kA What to multiple A by + @param B Second point to multiply + @param kB What to multiple B by + @param C [out] Destination point (can overlap with A or B) + @param modulus Modulus for curve + @return CRYPT_OK on success +*/ +int ltc_ecc_fp_mul2add(ecc_point *A, void *kA, + ecc_point *B, void *kB, + ecc_point *C, void *modulus) +{ + int idx1, idx2, err; + void *mp, *mu; + + mp = NULL; + mu = NULL; + LTC_MUTEX_LOCK(<c_ecc_fp_lock); + /* find point */ + idx1 = find_base(A); + + /* no entry? */ + if (idx1 == -1) { + /* find hole and add it */ + if ((idx1 = find_hole()) >= 0) { + if ((err = add_entry(idx1, A)) != CRYPT_OK) { + goto LBL_ERR; + } + } + } + if (idx1 != -1) { + /* increment LRU */ + ++(fp_cache[idx1].lru_count); + } + + /* find point */ + idx2 = find_base(B); + + /* no entry? */ + if (idx2 == -1) { + /* find hole and add it */ + if ((idx2 = find_hole()) >= 0) { + if ((err = add_entry(idx2, B)) != CRYPT_OK) { + goto LBL_ERR; + } + } + } + if (idx2 != -1) { + /* increment LRU */ + ++(fp_cache[idx2].lru_count); + } + + /* if it's 2 build the LUT, if it's higher just use the LUT */ + if (idx1 >= 0 && fp_cache[idx1].lru_count == 2) { + /* compute mp */ + if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } + + /* compute mu */ + if ((err = mp_init(&mu)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* build the LUT */ + if ((err = build_lut(idx1, modulus, mp, mu)) != CRYPT_OK) { + goto LBL_ERR;; + } + } + + /* if it's 2 build the LUT, if it's higher just use the LUT */ + if (idx2 >= 0 && fp_cache[idx2].lru_count == 2) { + if (mp == NULL) { + /* compute mp */ + if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } + + /* compute mu */ + if ((err = mp_init(&mu)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { + goto LBL_ERR; + } + } + + /* build the LUT */ + if ((err = build_lut(idx2, modulus, mp, mu)) != CRYPT_OK) { + goto LBL_ERR;; + } + } + + + if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].lru_count >= 2 && fp_cache[idx2].lru_count >= 2) { + if (mp == NULL) { + /* compute mp */ + if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } + } + err = accel_fp_mul2add(idx1, idx2, kA, kB, C, modulus, mp); + } else { + err = ltc_ecc_mul2add(A, kA, B, kB, C, modulus); + } +LBL_ERR: + LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); + if (mp != NULL) { + mp_montgomery_free(mp); + } + if (mu != NULL) { + mp_clear(mu); + } + return err; +} +#endif + +/** ECC Fixed Point mulmod global + @param k The multiplicand + @param G Base point to multiply + @param R [out] Destination of product + @param modulus The modulus for the curve + @param map [boolean] If non-zero maps the point back to affine co-ordinates, otherwise it's left in jacobian-montgomery form + @return CRYPT_OK if successful +*/ +int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map) +{ + int idx, err; + void *mp, *mu; + + mp = NULL; + mu = NULL; + LTC_MUTEX_LOCK(<c_ecc_fp_lock); + /* find point */ + idx = find_base(G); + + /* no entry? */ + if (idx == -1) { + /* find hole and add it */ + idx = find_hole(); + + if (idx >= 0) { + if ((err = add_entry(idx, G)) != CRYPT_OK) { + goto LBL_ERR; + } + } + } + if (idx != -1) { + /* increment LRU */ + ++(fp_cache[idx].lru_count); + } + + + /* if it's 2 build the LUT, if it's higher just use the LUT */ + if (idx >= 0 && fp_cache[idx].lru_count == 2) { + /* compute mp */ + if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } + + /* compute mu */ + if ((err = mp_init(&mu)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* build the LUT */ + if ((err = build_lut(idx, modulus, mp, mu)) != CRYPT_OK) { + goto LBL_ERR;; + } + } + + if (idx >= 0 && fp_cache[idx].lru_count >= 2) { + if (mp == NULL) { + /* compute mp */ + if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } + } + err = accel_fp_mul(idx, k, R, modulus, mp, map); + } else { + err = ltc_ecc_mulmod(k, G, R, modulus, map); + } +LBL_ERR: + LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); + if (mp != NULL) { + mp_montgomery_free(mp); + } + if (mu != NULL) { + mp_clear(mu); + } + return err; +} + +/* helper function for freeing the cache ... must be called with the cache mutex locked */ +static void ltc_ecc_fp_free_cache(void) +{ + unsigned x, y; + for (x = 0; x < FP_ENTRIES; x++) { + if (fp_cache[x].g != NULL) { + for (y = 0; y < (1U<= 0) { + /* it is already in the cache ... just check that the LUT is initialized */ + if(fp_cache[idx].lru_count >= 2) { + LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); + return CRYPT_OK; + } + } + + if(idx == -1 && (idx = find_hole()) == -1) { + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + if ((err = add_entry(idx, g)) != CRYPT_OK) { + goto LBL_ERR; + } + /* compute mp */ + if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* compute mu */ + if ((err = mp_init(&mu)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* build the LUT */ + if ((err = build_lut(idx, modulus, mp, mu)) != CRYPT_OK) { + goto LBL_ERR; + } + fp_cache[idx].lru_count = 2; + fp_cache[idx].lock = lock; +LBL_ERR: + LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); + if (mp != NULL) { + mp_montgomery_free(mp); + } + if (mu != NULL) { + mp_clear(mu); + } + return err; +} + +/** Prevent/permit the FP cache from being updated + @param flag If flag is 0, remove cache lock (unlock), otherwise lock it +*/ +void ltc_ecc_fp_tablelock(int lock) +{ + int i; + + LTC_MUTEX_LOCK(<c_ecc_fp_lock); + for (i = 0; i < FP_ENTRIES; i++) { + fp_cache[i].lock = lock; + } + LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); +} + +/** Export the current cache as a binary packet + @param out [out] pointer to malloc'ed space containing the packet + @param outlen [out] size of exported packet + @return CRYPT_OK if successful +*/ +int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen) +{ + ltc_asn1_list *cache_entry; + unsigned int i, j, k; + unsigned long fp_entries, fp_lut, num_entries; + int err; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + fp_entries = FP_ENTRIES; + fp_lut = FP_LUT; + num_entries = 0; + + LTC_MUTEX_LOCK(<c_ecc_fp_lock); + /* + * build the list; + Cache DEFINITIONS ::= + BEGIN + CacheDump ::= SEQUENCE { + numEntries SHORTINTEGER, + maxEntries SHORTINTEGER, + numLUT SHORTINTEGER, + cache SEQUENCE OF INTEGER + } + END + * + */ + /* + * The cache itself is a point (3 INTEGERS), + * the LUT as pairs of INTEGERS (2 * 1<x, 1); + LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].g->y, 1); + LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].g->z, 1); + for (k = 0; k < (1U<x, 1); + LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].LUT[k]->y, 1); + } + LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].mu, 1); + } + LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_EOL, 0, 0); + + LTC_SET_ASN1(cache_entry, 0, LTC_ASN1_SHORT_INTEGER, &num_entries, 1); + + if ((err = der_length_sequence(cache_entry, j, outlen)) != CRYPT_OK) { + goto save_err; + } + if ((*out = XMALLOC(*outlen)) == NULL) { + err = CRYPT_MEM; + goto save_err; + } + err = der_encode_sequence(cache_entry, j, *out, outlen); +save_err: + XFREE(cache_entry); + LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); + return err; +} + +/** Import a binary packet into the current cache + @param in [in] pointer to packet + @param inlen [in] size of packet (bytes) + @return CRYPT_OK if successful +*/ +int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen) +{ + int err; + ltc_asn1_list *asn1_list; + unsigned long num_entries, fp_entries, fp_lut; + unsigned long i, j; + unsigned int x; + + LTC_ARGCHK(in != NULL); + if (inlen == 0) { + return CRYPT_INVALID_ARG; + } + + /* zero indecies */ + i = 0; + j = 0; + asn1_list = NULL; + + LTC_MUTEX_LOCK(<c_ecc_fp_lock); + /* + * start with an empty cache + */ + ltc_ecc_fp_free_cache(); + + /* + * decode the input packet: It consists of a sequence with a few + * integers (including the FP_ENTRIES and FP_LUT sizes), followed by a + * SEQUENCE which is the cache itself. + * + * use standard decoding for the first part, then flexible for the second + */ + if((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_SHORT_INTEGER, 1, &num_entries, + LTC_ASN1_SHORT_INTEGER, 1, &fp_entries, + LTC_ASN1_SHORT_INTEGER, 1, &fp_lut, + LTC_ASN1_EOL, 0, 0)) != CRYPT_OK) { + goto ERR_OUT; + } + if (fp_entries != FP_ENTRIES || fp_lut != FP_LUT || num_entries > fp_entries) { + err = CRYPT_INVALID_PACKET; + goto ERR_OUT; + } + if ((asn1_list = XCALLOC(3+num_entries*(4+2*(1<x, 1); + LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].g->y, 1); + LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].g->z, 1); + for (x = 0; x < (1U<x, &p->y, NULL)) != CRYPT_OK) { + goto ERR_OUT; + } + p->z = NULL; + LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, p->x, 1); + LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, p->y, 1); + } + if((err = mp_init(&fp_cache[i].mu)) != CRYPT_OK) { + goto ERR_OUT; + } + LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].mu, 1); + fp_cache[i].lru_count = 3; + fp_cache[i].lock = 1; + } + + if ((err = der_decode_sequence(in, inlen, asn1_list, j)) != CRYPT_OK) { + goto ERR_OUT; + } + XFREE(asn1_list); + LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); + return CRYPT_OK; +ERR_OUT: + if(asn1_list) + XFREE(asn1_list); + ltc_ecc_fp_free_cache(); + LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); + return err; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/math/fp/ltc_ecc_fp_mulmod.c,v $ */ +/* $Revision: 1.33 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/math/gmp_desc.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/math/gmp_desc.c new file mode 100644 index 0000000000..0c150d42cf --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/math/gmp_desc.c @@ -0,0 +1,478 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +#define DESC_DEF_ONLY +#include "tomcrypt.h" + +#ifdef GMP_DESC + +#include +#include + +static int init(void **a) +{ + LTC_ARGCHK(a != NULL); + + *a = XCALLOC(1, sizeof(__mpz_struct)); + if (*a == NULL) { + return CRYPT_MEM; + } + mpz_init(((__mpz_struct *)*a)); + return CRYPT_OK; +} + +static void deinit(void *a) +{ + LTC_ARGCHKVD(a != NULL); + mpz_clear(a); + XFREE(a); +} + +static int neg(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + mpz_neg(b, a); + return CRYPT_OK; +} + +static int copy(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + mpz_set(b, a); + return CRYPT_OK; +} + +static int init_copy(void **a, void *b) +{ + if (init(a) != CRYPT_OK) { + return CRYPT_MEM; + } + return copy(b, *a); +} + +/* ---- trivial ---- */ +static int set_int(void *a, unsigned long b) +{ + LTC_ARGCHK(a != NULL); + mpz_set_ui(((__mpz_struct *)a), b); + return CRYPT_OK; +} + +static unsigned long get_int(void *a) +{ + LTC_ARGCHK(a != NULL); + return mpz_get_ui(a); +} + +static unsigned long get_digit(void *a, int n) +{ + LTC_ARGCHK(a != NULL); + return mpz_getlimbn(a, n); +} + +static int get_digit_count(void *a) +{ + LTC_ARGCHK(a != NULL); + return mpz_size(a); +} + +static int compare(void *a, void *b) +{ + int ret; + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + ret = mpz_cmp(a, b); + if (ret < 0) { + return LTC_MP_LT; + } else if (ret > 0) { + return LTC_MP_GT; + } else { + return LTC_MP_EQ; + } +} + +static int compare_d(void *a, unsigned long b) +{ + int ret; + LTC_ARGCHK(a != NULL); + ret = mpz_cmp_ui(((__mpz_struct *)a), b); + if (ret < 0) { + return LTC_MP_LT; + } else if (ret > 0) { + return LTC_MP_GT; + } else { + return LTC_MP_EQ; + } +} + +static int count_bits(void *a) +{ + LTC_ARGCHK(a != NULL); + return mpz_sizeinbase(a, 2); +} + +static int count_lsb_bits(void *a) +{ + LTC_ARGCHK(a != NULL); + return mpz_scan1(a, 0); +} + + +static int twoexpt(void *a, int n) +{ + LTC_ARGCHK(a != NULL); + mpz_set_ui(a, 0); + mpz_setbit(a, n); + return CRYPT_OK; +} + +/* ---- conversions ---- */ + +/* read ascii string */ +static int read_radix(void *a, const char *b, int radix) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + mpz_set_str(a, b, radix); + return CRYPT_OK; +} + +/* write one */ +static int write_radix(void *a, char *b, int radix) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + mpz_get_str(b, radix, a); + return CRYPT_OK; +} + +/* get size as unsigned char string */ +static unsigned long unsigned_size(void *a) +{ + unsigned long t; + LTC_ARGCHK(a != NULL); + t = mpz_sizeinbase(a, 2); + if (mpz_cmp_ui(((__mpz_struct *)a), 0) == 0) return 0; + return (t>>3) + ((t&7)?1:0); +} + +/* store */ +static int unsigned_write(void *a, unsigned char *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + mpz_export(b, NULL, 1, 1, 1, 0, ((__mpz_struct*)a)); + return CRYPT_OK; +} + +/* read */ +static int unsigned_read(void *a, unsigned char *b, unsigned long len) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + mpz_import(a, len, 1, 1, 1, 0, b); + return CRYPT_OK; +} + +/* add */ +static int add(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + mpz_add(c, a, b); + return CRYPT_OK; +} + +static int addi(void *a, unsigned long b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + mpz_add_ui(c, a, b); + return CRYPT_OK; +} + +/* sub */ +static int sub(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + mpz_sub(c, a, b); + return CRYPT_OK; +} + +static int subi(void *a, unsigned long b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + mpz_sub_ui(c, a, b); + return CRYPT_OK; +} + +/* mul */ +static int mul(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + mpz_mul(c, a, b); + return CRYPT_OK; +} + +static int muli(void *a, unsigned long b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + mpz_mul_ui(c, a, b); + return CRYPT_OK; +} + +/* sqr */ +static int sqr(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + mpz_mul(b, a, a); + return CRYPT_OK; +} + +/* div */ +static int divide(void *a, void *b, void *c, void *d) +{ + mpz_t tmp; + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + if (c != NULL) { + mpz_init(tmp); + mpz_divexact(tmp, a, b); + } + if (d != NULL) { + mpz_mod(d, a, b); + } + if (c != NULL) { + mpz_set(c, tmp); + mpz_clear(tmp); + } + return CRYPT_OK; +} + +static int div_2(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + mpz_divexact_ui(b, a, 2); + return CRYPT_OK; +} + +/* modi */ +static int modi(void *a, unsigned long b, unsigned long *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + + *c = mpz_fdiv_ui(a, b); + return CRYPT_OK; +} + +/* gcd */ +static int gcd(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + mpz_gcd(c, a, b); + return CRYPT_OK; +} + +/* lcm */ +static int lcm(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + mpz_lcm(c, a, b); + return CRYPT_OK; +} + +static int mulmod(void *a, void *b, void *c, void *d) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + LTC_ARGCHK(d != NULL); + mpz_mul(d, a, b); + mpz_mod(d, d, c); + return CRYPT_OK; +} + +static int sqrmod(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + mpz_mul(c, a, a); + mpz_mod(c, c, b); + return CRYPT_OK; +} + +/* invmod */ +static int invmod(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + mpz_invert(c, a, b); + return CRYPT_OK; +} + +/* setup */ +static int montgomery_setup(void *a, void **b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + *b = (void *)1; + return CRYPT_OK; +} + +/* get normalization value */ +static int montgomery_normalization(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + mpz_set_ui(a, 1); + return CRYPT_OK; +} + +/* reduce */ +static int montgomery_reduce(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + mpz_mod(a, a, b); + return CRYPT_OK; +} + +/* clean up */ +static void montgomery_deinit(void *a) +{ +} + +static int exptmod(void *a, void *b, void *c, void *d) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + LTC_ARGCHK(d != NULL); + mpz_powm(d, a, b, c); + return CRYPT_OK; +} + +static int isprime(void *a, int *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + *b = mpz_probab_prime_p(a, 8) > 0 ? LTC_MP_YES : LTC_MP_NO; + return CRYPT_OK; +} + +const ltc_math_descriptor gmp_desc = { + "GNU MP", + sizeof(mp_limb_t) * CHAR_BIT - GMP_NAIL_BITS, + + &init, + &init_copy, + &deinit, + + &neg, + ©, + + &set_int, + &get_int, + &get_digit, + &get_digit_count, + &compare, + &compare_d, + &count_bits, + &count_lsb_bits, + &twoexpt, + + &read_radix, + &write_radix, + &unsigned_size, + &unsigned_write, + &unsigned_read, + + &add, + &addi, + &sub, + &subi, + &mul, + &muli, + &sqr, + ÷, + &div_2, + &modi, + &gcd, + &lcm, + + &mulmod, + &sqrmod, + &invmod, + + &montgomery_setup, + &montgomery_normalization, + &montgomery_reduce, + &montgomery_deinit, + + &exptmod, + &isprime, + +#ifdef LTC_MECC +#ifdef LTC_MECC_FP + <c_ecc_fp_mulmod, +#else + <c_ecc_mulmod, +#endif /* LTC_MECC_FP */ + <c_ecc_projective_add_point, + <c_ecc_projective_dbl_point, + <c_ecc_map, +#ifdef LTC_ECC_SHAMIR +#ifdef LTC_MECC_FP + <c_ecc_fp_mul2add, +#else + <c_ecc_mul2add, +#endif /* LTC_MECC_FP */ +#else + NULL, +#endif /* LTC_ECC_SHAMIR */ +#else + NULL, NULL, NULL, NULL, NULL +#endif /* LTC_MECC */ + +#ifdef LTC_MRSA + &rsa_make_key, + &rsa_exptmod, +#else + NULL, NULL +#endif + +}; + + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/math/gmp_desc.c,v $ */ +/* $Revision: 1.16 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/math/ltm_desc.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/math/ltm_desc.c new file mode 100644 index 0000000000..8e0848e2a5 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/math/ltm_desc.c @@ -0,0 +1,483 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +#define DESC_DEF_ONLY +#include "tomcrypt.h" + +#ifdef LTM_DESC + +#include + +static const struct { + int mpi_code, ltc_code; +} mpi_to_ltc_codes[] = { + { MP_OKAY , CRYPT_OK}, + { MP_MEM , CRYPT_MEM}, + { MP_VAL , CRYPT_INVALID_ARG}, +}; + +/** + Convert a MPI error to a LTC error (Possibly the most powerful function ever! Oh wait... no) + @param err The error to convert + @return The equivalent LTC error code or CRYPT_ERROR if none found +*/ +static int mpi_to_ltc_error(int err) +{ + int x; + + for (x = 0; x < (int)(sizeof(mpi_to_ltc_codes)/sizeof(mpi_to_ltc_codes[0])); x++) { + if (err == mpi_to_ltc_codes[x].mpi_code) { + return mpi_to_ltc_codes[x].ltc_code; + } + } + return CRYPT_ERROR; +} + +static int init(void **a) +{ + int err; + + LTC_ARGCHK(a != NULL); + + *a = XCALLOC(1, sizeof(mp_int)); + if (*a == NULL) { + return CRYPT_MEM; + } + + if ((err = mpi_to_ltc_error(mp_init(*a))) != CRYPT_OK) { + XFREE(*a); + } + return err; +} + +static void deinit(void *a) +{ + LTC_ARGCHKVD(a != NULL); + mp_clear(a); + XFREE(a); +} + +static int neg(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_neg(a, b)); +} + +static int copy(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_copy(a, b)); +} + +static int init_copy(void **a, void *b) +{ + if (init(a) != CRYPT_OK) { + return CRYPT_MEM; + } + return copy(b, *a); +} + +/* ---- trivial ---- */ +static int set_int(void *a, unsigned long b) +{ + LTC_ARGCHK(a != NULL); + return mpi_to_ltc_error(mp_set_int(a, b)); +} + +static unsigned long get_int(void *a) +{ + LTC_ARGCHK(a != NULL); + return mp_get_int(a); +} + +static unsigned long get_digit(void *a, int n) +{ + mp_int *A; + LTC_ARGCHK(a != NULL); + A = a; + return (n >= A->used || n < 0) ? 0 : A->dp[n]; +} + +static int get_digit_count(void *a) +{ + mp_int *A; + LTC_ARGCHK(a != NULL); + A = a; + return A->used; +} + +static int compare(void *a, void *b) +{ + int ret; + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + ret = mp_cmp(a, b); + switch (ret) { + case MP_LT: return LTC_MP_LT; + case MP_EQ: return LTC_MP_EQ; + case MP_GT: return LTC_MP_GT; + } + return 0; +} + +static int compare_d(void *a, unsigned long b) +{ + int ret; + LTC_ARGCHK(a != NULL); + ret = mp_cmp_d(a, b); + switch (ret) { + case MP_LT: return LTC_MP_LT; + case MP_EQ: return LTC_MP_EQ; + case MP_GT: return LTC_MP_GT; + } + return 0; +} + +static int count_bits(void *a) +{ + LTC_ARGCHK(a != NULL); + return mp_count_bits(a); +} + +static int count_lsb_bits(void *a) +{ + LTC_ARGCHK(a != NULL); + return mp_cnt_lsb(a); +} + + +static int twoexpt(void *a, int n) +{ + LTC_ARGCHK(a != NULL); + return mpi_to_ltc_error(mp_2expt(a, n)); +} + +/* ---- conversions ---- */ + +/* read ascii string */ +static int read_radix(void *a, const char *b, int radix) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_read_radix(a, b, radix)); +} + +/* write one */ +static int write_radix(void *a, char *b, int radix) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_toradix(a, b, radix)); +} + +/* get size as unsigned char string */ +static unsigned long unsigned_size(void *a) +{ + LTC_ARGCHK(a != NULL); + return mp_unsigned_bin_size(a); +} + +/* store */ +static int unsigned_write(void *a, unsigned char *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_to_unsigned_bin(a, b)); +} + +/* read */ +static int unsigned_read(void *a, unsigned char *b, unsigned long len) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_read_unsigned_bin(a, b, len)); +} + +/* add */ +static int add(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_add(a, b, c)); +} + +static int addi(void *a, unsigned long b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_add_d(a, b, c)); +} + +/* sub */ +static int sub(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_sub(a, b, c)); +} + +static int subi(void *a, unsigned long b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_sub_d(a, b, c)); +} + +/* mul */ +static int mul(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_mul(a, b, c)); +} + +static int muli(void *a, unsigned long b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_mul_d(a, b, c)); +} + +/* sqr */ +static int sqr(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_sqr(a, b)); +} + +/* div */ +static int divide(void *a, void *b, void *c, void *d) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_div(a, b, c, d)); +} + +static int div_2(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_div_2(a, b)); +} + +/* modi */ +static int modi(void *a, unsigned long b, unsigned long *c) +{ + mp_digit tmp; + int err; + + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + + if ((err = mpi_to_ltc_error(mp_mod_d(a, b, &tmp))) != CRYPT_OK) { + return err; + } + *c = tmp; + return CRYPT_OK; +} + +/* gcd */ +static int gcd(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_gcd(a, b, c)); +} + +/* lcm */ +static int lcm(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_lcm(a, b, c)); +} + +static int mulmod(void *a, void *b, void *c, void *d) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + LTC_ARGCHK(d != NULL); + return mpi_to_ltc_error(mp_mulmod(a,b,c,d)); +} + +static int sqrmod(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_sqrmod(a,b,c)); +} + +/* invmod */ +static int invmod(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_invmod(a, b, c)); +} + +/* setup */ +static int montgomery_setup(void *a, void **b) +{ + int err; + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + *b = XCALLOC(1, sizeof(mp_digit)); + if (*b == NULL) { + return CRYPT_MEM; + } + if ((err = mpi_to_ltc_error(mp_montgomery_setup(a, (mp_digit *)*b))) != CRYPT_OK) { + XFREE(*b); + } + return err; +} + +/* get normalization value */ +static int montgomery_normalization(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_montgomery_calc_normalization(a, b)); +} + +/* reduce */ +static int montgomery_reduce(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_montgomery_reduce(a, b, *((mp_digit *)c))); +} + +/* clean up */ +static void montgomery_deinit(void *a) +{ + XFREE(a); +} + +static int exptmod(void *a, void *b, void *c, void *d) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + LTC_ARGCHK(d != NULL); + return mpi_to_ltc_error(mp_exptmod(a,b,c,d)); +} + +static int isprime(void *a, int *b) +{ + int err; + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + err = mpi_to_ltc_error(mp_prime_is_prime(a, 8, b)); + *b = (*b == MP_YES) ? LTC_MP_YES : LTC_MP_NO; + return err; +} + +const ltc_math_descriptor ltm_desc = { + + "LibTomMath", + (int)DIGIT_BIT, + + &init, + &init_copy, + &deinit, + + &neg, + ©, + + &set_int, + &get_int, + &get_digit, + &get_digit_count, + &compare, + &compare_d, + &count_bits, + &count_lsb_bits, + &twoexpt, + + &read_radix, + &write_radix, + &unsigned_size, + &unsigned_write, + &unsigned_read, + + &add, + &addi, + &sub, + &subi, + &mul, + &muli, + &sqr, + ÷, + &div_2, + &modi, + &gcd, + &lcm, + + &mulmod, + &sqrmod, + &invmod, + + &montgomery_setup, + &montgomery_normalization, + &montgomery_reduce, + &montgomery_deinit, + + &exptmod, + &isprime, + +#ifdef LTC_MECC +#ifdef LTC_MECC_FP + <c_ecc_fp_mulmod, +#else + <c_ecc_mulmod, +#endif + <c_ecc_projective_add_point, + <c_ecc_projective_dbl_point, + <c_ecc_map, +#ifdef LTC_ECC_SHAMIR +#ifdef LTC_MECC_FP + <c_ecc_fp_mul2add, +#else + <c_ecc_mul2add, +#endif /* LTC_MECC_FP */ +#else + NULL, +#endif /* LTC_ECC_SHAMIR */ +#else + NULL, NULL, NULL, NULL, NULL, +#endif /* LTC_MECC */ + +#ifdef LTC_MRSA + &rsa_make_key, + &rsa_exptmod, +#else + NULL, NULL +#endif +}; + + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/math/ltm_desc.c,v $ */ +/* $Revision: 1.31 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/math/multi.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/math/multi.c new file mode 100644 index 0000000000..f144beaf5f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/math/multi.c @@ -0,0 +1,61 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +#ifdef MPI +#include + +int ltc_init_multi(void **a, ...) +{ + void **cur = a; + int np = 0; + va_list args; + + va_start(args, a); + while (cur != NULL) { + if (mp_init(cur) != CRYPT_OK) { + /* failed */ + va_list clean_list; + + va_start(clean_list, a); + cur = a; + while (np--) { + mp_clear(*cur); + cur = va_arg(clean_list, void**); + } + va_end(clean_list); + return CRYPT_MEM; + } + ++np; + cur = va_arg(args, void**); + } + va_end(args); + return CRYPT_OK; +} + +void ltc_deinit_multi(void *a, ...) +{ + void *cur = a; + va_list args; + + va_start(args, a); + while (cur != NULL) { + mp_clear(cur); + cur = va_arg(args, void *); + } + va_end(args); +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/math/multi.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/math/rand_prime.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/math/rand_prime.c new file mode 100644 index 0000000000..2a0ac141ab --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/math/rand_prime.c @@ -0,0 +1,87 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rand_prime.c + Generate a random prime, Tom St Denis +*/ + +#define USE_BBS 1 + +int rand_prime(void *N, long len, prng_state *prng, int wprng) +{ + int err, res, type; + unsigned char *buf; + + LTC_ARGCHK(N != NULL); + + /* get type */ + if (len < 0) { + type = USE_BBS; + len = -len; + } else { + type = 0; + } + + /* allow sizes between 2 and 512 bytes for a prime size */ + if (len < 2 || len > 512) { + return CRYPT_INVALID_PRIME_SIZE; + } + + /* valid PRNG? Better be! */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* allocate buffer to work with */ + buf = XCALLOC(1, len); + if (buf == NULL) { + return CRYPT_MEM; + } + + do { + /* generate value */ + if (prng_descriptor[wprng].read(buf, len, prng) != (unsigned long)len) { + XFREE(buf); + return CRYPT_ERROR_READPRNG; + } + + /* munge bits */ + buf[0] |= 0x80 | 0x40; + buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00); + + /* load value */ + if ((err = mp_read_unsigned_bin(N, buf, len)) != CRYPT_OK) { + XFREE(buf); + return err; + } + + /* test */ + if ((err = mp_prime_is_prime(N, 8, &res)) != CRYPT_OK) { + XFREE(buf); + return err; + } + } while (res == LTC_MP_NO); + +#ifdef LTC_CLEAN_STACK + zeromem(buf, len); +#endif + + XFREE(buf); + return CRYPT_OK; +} + + + +/* $Source: /cvs/libtom/libtomcrypt/src/math/rand_prime.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/math/tfm_desc.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/math/tfm_desc.c new file mode 100644 index 0000000000..cce7d967e7 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/math/tfm_desc.c @@ -0,0 +1,777 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +#define DESC_DEF_ONLY +#include "tomcrypt.h" + +#ifdef TFM_DESC + +#include + +static const struct { + int tfm_code, ltc_code; +} tfm_to_ltc_codes[] = { + { FP_OKAY , CRYPT_OK}, + { FP_MEM , CRYPT_MEM}, + { FP_VAL , CRYPT_INVALID_ARG}, +}; + +/** + Convert a tfm error to a LTC error (Possibly the most powerful function ever! Oh wait... no) + @param err The error to convert + @return The equivalent LTC error code or CRYPT_ERROR if none found +*/ +static int tfm_to_ltc_error(int err) +{ + int x; + + for (x = 0; x < (int)(sizeof(tfm_to_ltc_codes)/sizeof(tfm_to_ltc_codes[0])); x++) { + if (err == tfm_to_ltc_codes[x].tfm_code) { + return tfm_to_ltc_codes[x].ltc_code; + } + } + return CRYPT_ERROR; +} + +static int init(void **a) +{ + LTC_ARGCHK(a != NULL); + + *a = XCALLOC(1, sizeof(fp_int)); + if (*a == NULL) { + return CRYPT_MEM; + } + fp_init(*a); + return CRYPT_OK; +} + +static void deinit(void *a) +{ + LTC_ARGCHKVD(a != NULL); + XFREE(a); +} + +static int neg(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + fp_neg(((fp_int*)a), ((fp_int*)b)); + return CRYPT_OK; +} + +static int copy(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + fp_copy(a, b); + return CRYPT_OK; +} + +static int init_copy(void **a, void *b) +{ + if (init(a) != CRYPT_OK) { + return CRYPT_MEM; + } + return copy(b, *a); +} + +/* ---- trivial ---- */ +static int set_int(void *a, unsigned long b) +{ + LTC_ARGCHK(a != NULL); + fp_set(a, b); + return CRYPT_OK; +} + +static unsigned long get_int(void *a) +{ + fp_int *A; + LTC_ARGCHK(a != NULL); + A = a; + return A->used > 0 ? A->dp[0] : 0; +} + +static unsigned long get_digit(void *a, int n) +{ + fp_int *A; + LTC_ARGCHK(a != NULL); + A = a; + return (n >= A->used || n < 0) ? 0 : A->dp[n]; +} + +static int get_digit_count(void *a) +{ + fp_int *A; + LTC_ARGCHK(a != NULL); + A = a; + return A->used; +} + +static int compare(void *a, void *b) +{ + int ret; + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + ret = fp_cmp(a, b); + switch (ret) { + case FP_LT: return LTC_MP_LT; + case FP_EQ: return LTC_MP_EQ; + case FP_GT: return LTC_MP_GT; + } + return 0; +} + +static int compare_d(void *a, unsigned long b) +{ + int ret; + LTC_ARGCHK(a != NULL); + ret = fp_cmp_d(a, b); + switch (ret) { + case FP_LT: return LTC_MP_LT; + case FP_EQ: return LTC_MP_EQ; + case FP_GT: return LTC_MP_GT; + } + return 0; +} + +static int count_bits(void *a) +{ + LTC_ARGCHK(a != NULL); + return fp_count_bits(a); +} + +static int count_lsb_bits(void *a) +{ + LTC_ARGCHK(a != NULL); + return fp_cnt_lsb(a); +} + +static int twoexpt(void *a, int n) +{ + LTC_ARGCHK(a != NULL); + fp_2expt(a, n); + return CRYPT_OK; +} + +/* ---- conversions ---- */ + +/* read ascii string */ +static int read_radix(void *a, const char *b, int radix) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return tfm_to_ltc_error(fp_read_radix(a, (char *)b, radix)); +} + +/* write one */ +static int write_radix(void *a, char *b, int radix) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return tfm_to_ltc_error(fp_toradix(a, b, radix)); +} + +/* get size as unsigned char string */ +static unsigned long unsigned_size(void *a) +{ + LTC_ARGCHK(a != NULL); + return fp_unsigned_bin_size(a); +} + +/* store */ +static int unsigned_write(void *a, unsigned char *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + fp_to_unsigned_bin(a, b); + return CRYPT_OK; +} + +/* read */ +static int unsigned_read(void *a, unsigned char *b, unsigned long len) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + fp_read_unsigned_bin(a, b, len); + return CRYPT_OK; +} + +/* add */ +static int add(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + fp_add(a, b, c); + return CRYPT_OK; +} + +static int addi(void *a, unsigned long b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + fp_add_d(a, b, c); + return CRYPT_OK; +} + +/* sub */ +static int sub(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + fp_sub(a, b, c); + return CRYPT_OK; +} + +static int subi(void *a, unsigned long b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + fp_sub_d(a, b, c); + return CRYPT_OK; +} + +/* mul */ +static int mul(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + fp_mul(a, b, c); + return CRYPT_OK; +} + +static int muli(void *a, unsigned long b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + fp_mul_d(a, b, c); + return CRYPT_OK; +} + +/* sqr */ +static int sqr(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + fp_sqr(a, b); + return CRYPT_OK; +} + +/* div */ +static int divide(void *a, void *b, void *c, void *d) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return tfm_to_ltc_error(fp_div(a, b, c, d)); +} + +static int div_2(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + fp_div_2(a, b); + return CRYPT_OK; +} + +/* modi */ +static int modi(void *a, unsigned long b, unsigned long *c) +{ + fp_digit tmp; + int err; + + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + + if ((err = tfm_to_ltc_error(fp_mod_d(a, b, &tmp))) != CRYPT_OK) { + return err; + } + *c = tmp; + return CRYPT_OK; +} + +/* gcd */ +static int gcd(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + fp_gcd(a, b, c); + return CRYPT_OK; +} + +/* lcm */ +static int lcm(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + fp_lcm(a, b, c); + return CRYPT_OK; +} + +static int mulmod(void *a, void *b, void *c, void *d) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + LTC_ARGCHK(d != NULL); + return tfm_to_ltc_error(fp_mulmod(a,b,c,d)); +} + +static int sqrmod(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return tfm_to_ltc_error(fp_sqrmod(a,b,c)); +} + +/* invmod */ +static int invmod(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return tfm_to_ltc_error(fp_invmod(a, b, c)); +} + +/* setup */ +static int montgomery_setup(void *a, void **b) +{ + int err; + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + *b = XCALLOC(1, sizeof(fp_digit)); + if (*b == NULL) { + return CRYPT_MEM; + } + if ((err = tfm_to_ltc_error(fp_montgomery_setup(a, (fp_digit *)*b))) != CRYPT_OK) { + XFREE(*b); + } + return err; +} + +/* get normalization value */ +static int montgomery_normalization(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + fp_montgomery_calc_normalization(a, b); + return CRYPT_OK; +} + +/* reduce */ +static int montgomery_reduce(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + fp_montgomery_reduce(a, b, *((fp_digit *)c)); + return CRYPT_OK; +} + +/* clean up */ +static void montgomery_deinit(void *a) +{ + XFREE(a); +} + +static int exptmod(void *a, void *b, void *c, void *d) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + LTC_ARGCHK(d != NULL); + return tfm_to_ltc_error(fp_exptmod(a,b,c,d)); +} + +static int isprime(void *a, int *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + *b = (fp_isprime(a) == FP_YES) ? LTC_MP_YES : LTC_MP_NO; + return CRYPT_OK; +} + +#if defined(LTC_MECC) && defined(LTC_MECC_ACCEL) + +static int tfm_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *Mp) +{ + fp_int t1, t2; + fp_digit mp; + + LTC_ARGCHK(P != NULL); + LTC_ARGCHK(R != NULL); + LTC_ARGCHK(modulus != NULL); + LTC_ARGCHK(Mp != NULL); + + mp = *((fp_digit*)Mp); + + fp_init(&t1); + fp_init(&t2); + + if (P != R) { + fp_copy(P->x, R->x); + fp_copy(P->y, R->y); + fp_copy(P->z, R->z); + } + + /* t1 = Z * Z */ + fp_sqr(R->z, &t1); + fp_montgomery_reduce(&t1, modulus, mp); + /* Z = Y * Z */ + fp_mul(R->z, R->y, R->z); + fp_montgomery_reduce(R->z, modulus, mp); + /* Z = 2Z */ + fp_add(R->z, R->z, R->z); + if (fp_cmp(R->z, modulus) != FP_LT) { + fp_sub(R->z, modulus, R->z); + } + + /* &t2 = X - T1 */ + fp_sub(R->x, &t1, &t2); + if (fp_cmp_d(&t2, 0) == FP_LT) { + fp_add(&t2, modulus, &t2); + } + /* T1 = X + T1 */ + fp_add(&t1, R->x, &t1); + if (fp_cmp(&t1, modulus) != FP_LT) { + fp_sub(&t1, modulus, &t1); + } + /* T2 = T1 * T2 */ + fp_mul(&t1, &t2, &t2); + fp_montgomery_reduce(&t2, modulus, mp); + /* T1 = 2T2 */ + fp_add(&t2, &t2, &t1); + if (fp_cmp(&t1, modulus) != FP_LT) { + fp_sub(&t1, modulus, &t1); + } + /* T1 = T1 + T2 */ + fp_add(&t1, &t2, &t1); + if (fp_cmp(&t1, modulus) != FP_LT) { + fp_sub(&t1, modulus, &t1); + } + + /* Y = 2Y */ + fp_add(R->y, R->y, R->y); + if (fp_cmp(R->y, modulus) != FP_LT) { + fp_sub(R->y, modulus, R->y); + } + /* Y = Y * Y */ + fp_sqr(R->y, R->y); + fp_montgomery_reduce(R->y, modulus, mp); + /* T2 = Y * Y */ + fp_sqr(R->y, &t2); + fp_montgomery_reduce(&t2, modulus, mp); + /* T2 = T2/2 */ + if (fp_isodd(&t2)) { + fp_add(&t2, modulus, &t2); + } + fp_div_2(&t2, &t2); + /* Y = Y * X */ + fp_mul(R->y, R->x, R->y); + fp_montgomery_reduce(R->y, modulus, mp); + + /* X = T1 * T1 */ + fp_sqr(&t1, R->x); + fp_montgomery_reduce(R->x, modulus, mp); + /* X = X - Y */ + fp_sub(R->x, R->y, R->x); + if (fp_cmp_d(R->x, 0) == FP_LT) { + fp_add(R->x, modulus, R->x); + } + /* X = X - Y */ + fp_sub(R->x, R->y, R->x); + if (fp_cmp_d(R->x, 0) == FP_LT) { + fp_add(R->x, modulus, R->x); + } + + /* Y = Y - X */ + fp_sub(R->y, R->x, R->y); + if (fp_cmp_d(R->y, 0) == FP_LT) { + fp_add(R->y, modulus, R->y); + } + /* Y = Y * T1 */ + fp_mul(R->y, &t1, R->y); + fp_montgomery_reduce(R->y, modulus, mp); + /* Y = Y - T2 */ + fp_sub(R->y, &t2, R->y); + if (fp_cmp_d(R->y, 0) == FP_LT) { + fp_add(R->y, modulus, R->y); + } + + return CRYPT_OK; +} + +/** + Add two ECC points + @param P The point to add + @param Q The point to add + @param R [out] The destination of the double + @param modulus The modulus of the field the ECC curve is in + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success +*/ +static int tfm_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *Mp) +{ + fp_int t1, t2, x, y, z; + fp_digit mp; + + LTC_ARGCHK(P != NULL); + LTC_ARGCHK(Q != NULL); + LTC_ARGCHK(R != NULL); + LTC_ARGCHK(modulus != NULL); + LTC_ARGCHK(Mp != NULL); + + mp = *((fp_digit*)Mp); + + fp_init(&t1); + fp_init(&t2); + fp_init(&x); + fp_init(&y); + fp_init(&z); + + /* should we dbl instead? */ + fp_sub(modulus, Q->y, &t1); + if ( (fp_cmp(P->x, Q->x) == FP_EQ) && + (Q->z != NULL && fp_cmp(P->z, Q->z) == FP_EQ) && + (fp_cmp(P->y, Q->y) == FP_EQ || fp_cmp(P->y, &t1) == FP_EQ)) { + return tfm_ecc_projective_dbl_point(P, R, modulus, Mp); + } + + fp_copy(P->x, &x); + fp_copy(P->y, &y); + fp_copy(P->z, &z); + + /* if Z is one then these are no-operations */ + if (Q->z != NULL) { + /* T1 = Z' * Z' */ + fp_sqr(Q->z, &t1); + fp_montgomery_reduce(&t1, modulus, mp); + /* X = X * T1 */ + fp_mul(&t1, &x, &x); + fp_montgomery_reduce(&x, modulus, mp); + /* T1 = Z' * T1 */ + fp_mul(Q->z, &t1, &t1); + fp_montgomery_reduce(&t1, modulus, mp); + /* Y = Y * T1 */ + fp_mul(&t1, &y, &y); + fp_montgomery_reduce(&y, modulus, mp); + } + + /* T1 = Z*Z */ + fp_sqr(&z, &t1); + fp_montgomery_reduce(&t1, modulus, mp); + /* T2 = X' * T1 */ + fp_mul(Q->x, &t1, &t2); + fp_montgomery_reduce(&t2, modulus, mp); + /* T1 = Z * T1 */ + fp_mul(&z, &t1, &t1); + fp_montgomery_reduce(&t1, modulus, mp); + /* T1 = Y' * T1 */ + fp_mul(Q->y, &t1, &t1); + fp_montgomery_reduce(&t1, modulus, mp); + + /* Y = Y - T1 */ + fp_sub(&y, &t1, &y); + if (fp_cmp_d(&y, 0) == FP_LT) { + fp_add(&y, modulus, &y); + } + /* T1 = 2T1 */ + fp_add(&t1, &t1, &t1); + if (fp_cmp(&t1, modulus) != FP_LT) { + fp_sub(&t1, modulus, &t1); + } + /* T1 = Y + T1 */ + fp_add(&t1, &y, &t1); + if (fp_cmp(&t1, modulus) != FP_LT) { + fp_sub(&t1, modulus, &t1); + } + /* X = X - T2 */ + fp_sub(&x, &t2, &x); + if (fp_cmp_d(&x, 0) == FP_LT) { + fp_add(&x, modulus, &x); + } + /* T2 = 2T2 */ + fp_add(&t2, &t2, &t2); + if (fp_cmp(&t2, modulus) != FP_LT) { + fp_sub(&t2, modulus, &t2); + } + /* T2 = X + T2 */ + fp_add(&t2, &x, &t2); + if (fp_cmp(&t2, modulus) != FP_LT) { + fp_sub(&t2, modulus, &t2); + } + + /* if Z' != 1 */ + if (Q->z != NULL) { + /* Z = Z * Z' */ + fp_mul(&z, Q->z, &z); + fp_montgomery_reduce(&z, modulus, mp); + } + + /* Z = Z * X */ + fp_mul(&z, &x, &z); + fp_montgomery_reduce(&z, modulus, mp); + + /* T1 = T1 * X */ + fp_mul(&t1, &x, &t1); + fp_montgomery_reduce(&t1, modulus, mp); + /* X = X * X */ + fp_sqr(&x, &x); + fp_montgomery_reduce(&x, modulus, mp); + /* T2 = T2 * x */ + fp_mul(&t2, &x, &t2); + fp_montgomery_reduce(&t2, modulus, mp); + /* T1 = T1 * X */ + fp_mul(&t1, &x, &t1); + fp_montgomery_reduce(&t1, modulus, mp); + + /* X = Y*Y */ + fp_sqr(&y, &x); + fp_montgomery_reduce(&x, modulus, mp); + /* X = X - T2 */ + fp_sub(&x, &t2, &x); + if (fp_cmp_d(&x, 0) == FP_LT) { + fp_add(&x, modulus, &x); + } + + /* T2 = T2 - X */ + fp_sub(&t2, &x, &t2); + if (fp_cmp_d(&t2, 0) == FP_LT) { + fp_add(&t2, modulus, &t2); + } + /* T2 = T2 - X */ + fp_sub(&t2, &x, &t2); + if (fp_cmp_d(&t2, 0) == FP_LT) { + fp_add(&t2, modulus, &t2); + } + /* T2 = T2 * Y */ + fp_mul(&t2, &y, &t2); + fp_montgomery_reduce(&t2, modulus, mp); + /* Y = T2 - T1 */ + fp_sub(&t2, &t1, &y); + if (fp_cmp_d(&y, 0) == FP_LT) { + fp_add(&y, modulus, &y); + } + /* Y = Y/2 */ + if (fp_isodd(&y)) { + fp_add(&y, modulus, &y); + } + fp_div_2(&y, &y); + + fp_copy(&x, R->x); + fp_copy(&y, R->y); + fp_copy(&z, R->z); + + return CRYPT_OK; +} + + +#endif + +const ltc_math_descriptor tfm_desc = { + + "TomsFastMath", + (int)DIGIT_BIT, + + &init, + &init_copy, + &deinit, + + &neg, + ©, + + &set_int, + &get_int, + &get_digit, + &get_digit_count, + &compare, + &compare_d, + &count_bits, + &count_lsb_bits, + &twoexpt, + + &read_radix, + &write_radix, + &unsigned_size, + &unsigned_write, + &unsigned_read, + + &add, + &addi, + &sub, + &subi, + &mul, + &muli, + &sqr, + ÷, + &div_2, + &modi, + &gcd, + &lcm, + + &mulmod, + &sqrmod, + &invmod, + + &montgomery_setup, + &montgomery_normalization, + &montgomery_reduce, + &montgomery_deinit, + + &exptmod, + &isprime, + +#ifdef LTC_MECC +#ifdef LTC_MECC_FP + <c_ecc_fp_mulmod, +#else + <c_ecc_mulmod, +#endif /* LTC_MECC_FP */ +#ifdef LTC_MECC_ACCEL + &tfm_ecc_projective_add_point, + &tfm_ecc_projective_dbl_point, +#else + <c_ecc_projective_add_point, + <c_ecc_projective_dbl_point, +#endif /* LTC_MECC_ACCEL */ + <c_ecc_map, +#ifdef LTC_ECC_SHAMIR +#ifdef LTC_MECC_FP + <c_ecc_fp_mul2add, +#else + <c_ecc_mul2add, +#endif /* LTC_MECC_FP */ +#else + NULL, +#endif /* LTC_ECC_SHAMIR */ +#else + NULL, NULL, NULL, NULL, NULL, +#endif /* LTC_MECC */ + +#ifdef LTC_MRSA + &rsa_make_key, + &rsa_exptmod, +#else + NULL, NULL +#endif + +}; + + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/math/tfm_desc.c,v $ */ +/* $Revision: 1.28 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/base64/base64_decode.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/base64/base64_decode.c new file mode 100644 index 0000000000..f9dd6e901c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/base64/base64_decode.c @@ -0,0 +1,104 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file base64_decode.c + Compliant base64 code donated by Wayne Scott (wscott@bitmover.com) +*/ + + +#ifdef LTC_BASE64 + +static const unsigned char map[256] = { +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, +255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, +255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255 }; + +/** + base64 decode a block of memory + @param in The base64 data to decode + @param inlen The length of the base64 data + @param out [out] The destination of the binary decoded data + @param outlen [in/out] The max size and resulting size of the decoded data + @return CRYPT_OK if successful +*/ +int base64_decode(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long t, x, y, z; + unsigned char c; + int g; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + g = 3; + for (x = y = z = t = 0; x < inlen; x++) { + c = map[in[x]&0xFF]; + if (c == 255) continue; + /* the final = symbols are read and used to trim the remaining bytes */ + if (c == 254) { + c = 0; + /* prevent g < 0 which would potentially allow an overflow later */ + if (--g < 0) { + return CRYPT_INVALID_PACKET; + } + } else if (g != 3) { + /* we only allow = to be at the end */ + return CRYPT_INVALID_PACKET; + } + + t = (t<<6)|c; + + if (++y == 4) { + if (z + g > *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + out[z++] = (unsigned char)((t>>16)&255); + if (g > 1) out[z++] = (unsigned char)((t>>8)&255); + if (g > 2) out[z++] = (unsigned char)(t&255); + y = t = 0; + } + } + if (y != 0) { + return CRYPT_INVALID_PACKET; + } + *outlen = z; + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/base64/base64_decode.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/base64/base64_encode.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/base64/base64_encode.c new file mode 100644 index 0000000000..35ed4a1315 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/base64/base64_encode.c @@ -0,0 +1,81 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file base64_encode.c + Compliant base64 encoder donated by Wayne Scott (wscott@bitmover.com) +*/ + + +#ifdef LTC_BASE64 + +static const char *codes = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/** + base64 Encode a buffer (NUL terminated) + @param in The input buffer to encode + @param inlen The length of the input buffer + @param out [out] The destination of the base64 encoded data + @param outlen [in/out] The max size and resulting size + @return CRYPT_OK if successful +*/ +int base64_encode(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long i, len2, leven; + unsigned char *p; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* valid output size ? */ + len2 = 4 * ((inlen + 2) / 3); + if (*outlen < len2 + 1) { + *outlen = len2 + 1; + return CRYPT_BUFFER_OVERFLOW; + } + p = out; + leven = 3*(inlen / 3); + for (i = 0; i < leven; i += 3) { + *p++ = codes[(in[0] >> 2) & 0x3F]; + *p++ = codes[(((in[0] & 3) << 4) + (in[1] >> 4)) & 0x3F]; + *p++ = codes[(((in[1] & 0xf) << 2) + (in[2] >> 6)) & 0x3F]; + *p++ = codes[in[2] & 0x3F]; + in += 3; + } + /* Pad it if necessary... */ + if (i < inlen) { + unsigned a = in[0]; + unsigned b = (i+1 < inlen) ? in[1] : 0; + + *p++ = codes[(a >> 2) & 0x3F]; + *p++ = codes[(((a & 3) << 4) + (b >> 4)) & 0x3F]; + *p++ = (i+1 < inlen) ? codes[(((b & 0xf) << 2)) & 0x3F] : '='; + *p++ = '='; + } + + /* append a NULL byte */ + *p = '\0'; + + /* return ok */ + *outlen = p - out; + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/base64/base64_encode.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/burn_stack.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/burn_stack.c new file mode 100644 index 0000000000..3b96de4f6e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/burn_stack.c @@ -0,0 +1,34 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file burn_stack.c + Burn stack, Tom St Denis +*/ + +/** + Burn some stack memory + @param len amount of stack to burn in bytes +*/ +void burn_stack(unsigned long len) +{ + unsigned char buf[32]; + zeromem(buf, sizeof(buf)); + if (len > (unsigned long)sizeof(buf)) + burn_stack(len - sizeof(buf)); +} + + + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/burn_stack.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt.c new file mode 100644 index 0000000000..c474680ee9 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt.c @@ -0,0 +1,373 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt.c + Build strings, Tom St Denis +*/ + +const char *crypt_build_settings = + "LibTomCrypt " SCRYPT " (Tom St Denis, tomstdenis@gmail.com)\n" + "LibTomCrypt is public domain software.\n" + "Built on " __DATE__ " at " __TIME__ "\n\n\n" + "Endianess: " +#if defined(ENDIAN_NEUTRAL) + "neutral\n" +#elif defined(ENDIAN_LITTLE) + "little" + #if defined(ENDIAN_32BITWORD) + " (32-bit words)\n" + #else + " (64-bit words)\n" + #endif +#elif defined(ENDIAN_BIG) + "big" + #if defined(ENDIAN_32BITWORD) + " (32-bit words)\n" + #else + " (64-bit words)\n" + #endif +#endif + "Clean stack: " +#if defined(LTC_CLEAN_STACK) + "enabled\n" +#else + "disabled\n" +#endif + "Ciphers built-in:\n" +#if defined(LTC_BLOWFISH) + " Blowfish\n" +#endif +#if defined(LTC_RC2) + " LTC_RC2\n" +#endif +#if defined(LTC_RC5) + " LTC_RC5\n" +#endif +#if defined(LTC_RC6) + " LTC_RC6\n" +#endif +#if defined(LTC_SAFERP) + " Safer+\n" +#endif +#if defined(LTC_SAFER) + " Safer\n" +#endif +#if defined(LTC_RIJNDAEL) + " Rijndael\n" +#endif +#if defined(LTC_XTEA) + " LTC_XTEA\n" +#endif +#if defined(LTC_TWOFISH) + " Twofish " + #if defined(LTC_TWOFISH_SMALL) && defined(LTC_TWOFISH_TABLES) && defined(LTC_TWOFISH_ALL_TABLES) + "(small, tables, all_tables)\n" + #elif defined(LTC_TWOFISH_SMALL) && defined(LTC_TWOFISH_TABLES) + "(small, tables)\n" + #elif defined(LTC_TWOFISH_SMALL) && defined(LTC_TWOFISH_ALL_TABLES) + "(small, all_tables)\n" + #elif defined(LTC_TWOFISH_TABLES) && defined(LTC_TWOFISH_ALL_TABLES) + "(tables, all_tables)\n" + #elif defined(LTC_TWOFISH_SMALL) + "(small)\n" + #elif defined(LTC_TWOFISH_TABLES) + "(tables)\n" + #elif defined(LTC_TWOFISH_ALL_TABLES) + "(all_tables)\n" + #else + "\n" + #endif +#endif +#if defined(LTC_DES) + " LTC_DES\n" +#endif +#if defined(LTC_CAST5) + " LTC_CAST5\n" +#endif +#if defined(LTC_NOEKEON) + " Noekeon\n" +#endif +#if defined(LTC_SKIPJACK) + " Skipjack\n" +#endif +#if defined(LTC_KHAZAD) + " Khazad\n" +#endif +#if defined(LTC_ANUBIS) + " Anubis " +#endif +#if defined(LTC_ANUBIS_TWEAK) + " (tweaked)" +#endif + "\n" +#if defined(LTC_KSEED) + " LTC_KSEED\n" +#endif +#if defined(LTC_KASUMI) + " KASUMI\n" +#endif + + "\nHashes built-in:\n" +#if defined(LTC_SHA512) + " LTC_SHA-512\n" +#endif +#if defined(LTC_SHA384) + " LTC_SHA-384\n" +#endif +#if defined(LTC_SHA256) + " LTC_SHA-256\n" +#endif +#if defined(LTC_SHA224) + " LTC_SHA-224\n" +#endif +#if defined(LTC_TIGER) + " LTC_TIGER\n" +#endif +#if defined(LTC_SHA1) + " LTC_SHA1\n" +#endif +#if defined(LTC_MD5) + " LTC_MD5\n" +#endif +#if defined(LTC_MD4) + " LTC_MD4\n" +#endif +#if defined(LTC_MD2) + " LTC_MD2\n" +#endif +#if defined(LTC_RIPEMD128) + " LTC_RIPEMD128\n" +#endif +#if defined(LTC_RIPEMD160) + " LTC_RIPEMD160\n" +#endif +#if defined(LTC_RIPEMD256) + " LTC_RIPEMD256\n" +#endif +#if defined(LTC_RIPEMD320) + " LTC_RIPEMD320\n" +#endif +#if defined(LTC_WHIRLPOOL) + " LTC_WHIRLPOOL\n" +#endif +#if defined(LTC_CHC_HASH) + " LTC_CHC_HASH \n" +#endif + + "\nBlock Chaining Modes:\n" +#if defined(LTC_CFB_MODE) + " CFB\n" +#endif +#if defined(LTC_OFB_MODE) + " OFB\n" +#endif +#if defined(LTC_ECB_MODE) + " ECB\n" +#endif +#if defined(LTC_CBC_MODE) + " CBC\n" +#endif +#if defined(LTC_CTR_MODE) + " CTR " +#endif +#if defined(LTC_CTR_OLD) + " (CTR_OLD) " +#endif + "\n" +#if defined(LRW_MODE) + " LRW_MODE" +#if defined(LRW_TABLES) + " (LRW_TABLES) " +#endif + "\n" +#endif +#if defined(LTC_F8_MODE) + " F8 MODE\n" +#endif +#if defined(LTC_XTS_MODE) + " LTC_XTS_MODE\n" +#endif + + "\nMACs:\n" +#if defined(LTC_HMAC) + " LTC_HMAC\n" +#endif +#if defined(LTC_OMAC) + " LTC_OMAC\n" +#endif +#if defined(LTC_PMAC) + " PMAC\n" +#endif +#if defined(LTC_PELICAN) + " LTC_PELICAN\n" +#endif +#if defined(LTC_XCBC) + " XCBC-MAC\n" +#endif +#if defined(LTC_F9_MODE) + " F9-MAC\n" +#endif + + "\nENC + AUTH modes:\n" +#if defined(LTC_EAX_MODE) + " LTC_EAX_MODE\n" +#endif +#if defined(LTC_OCB_MODE) + " LTC_OCB_MODE\n" +#endif +#if defined(LTC_CCM_MODE) + " LTC_CCM_MODE\n" +#endif +#if defined(LTC_GCM_MODE) + " LTC_GCM_MODE " +#endif +#if defined(LTC_GCM_TABLES) + " (LTC_GCM_TABLES) " +#endif + "\n" + + "\nPRNG:\n" +#if defined(LTC_YARROW) + " Yarrow\n" +#endif +#if defined(LTC_SPRNG) + " LTC_SPRNG\n" +#endif +#if defined(LTC_RC4) + " LTC_RC4\n" +#endif +#if defined(LTC_FORTUNA) + " Fortuna\n" +#endif +#if defined(LTC_SOBER128) + " LTC_SOBER128\n" +#endif + + "\nPK Algs:\n" +#if defined(LTC_MRSA) + " RSA \n" +#endif +#if defined(LTC_MECC) + " ECC\n" +#endif +#if defined(LTC_MDSA) + " DSA\n" +#endif +#if defined(MKAT) + " Katja\n" +#endif + + "\nCompiler:\n" +#if defined(WIN32) + " WIN32 platform detected.\n" +#endif +#if defined(__CYGWIN__) + " CYGWIN Detected.\n" +#endif +#if defined(__DJGPP__) + " DJGPP Detected.\n" +#endif +#if defined(_MSC_VER) + " MSVC compiler detected.\n" +#endif +#if defined(__GNUC__) + " GCC compiler detected.\n" +#endif +#if defined(INTEL_CC) + " Intel C Compiler detected.\n" +#endif +#if defined(__x86_64__) + " x86-64 detected.\n" +#endif +#if defined(LTC_PPC32) + " LTC_PPC32 defined \n" +#endif + + "\nVarious others: " +#if defined(LTC_BASE64) + " LTC_BASE64 " +#endif +#if defined(MPI) + " MPI " +#endif +#if defined(TRY_UNRANDOM_FIRST) + " TRY_UNRANDOM_FIRST " +#endif +#if defined(LTC_TEST) + " LTC_TEST " +#endif +#if defined(LTC_PKCS_1) + " LTC_PKCS#1 " +#endif +#if defined(LTC_PKCS_5) + " LTC_PKCS#5 " +#endif +#if defined(LTC_SMALL_CODE) + " LTC_SMALL_CODE " +#endif +#if defined(LTC_NO_FILE) + " LTC_NO_FILE " +#endif +#if defined(LTC_DER) + " LTC_DER " +#endif +#if defined(LTC_FAST) + " LTC_FAST " +#endif +#if defined(LTC_NO_FAST) + " LTC_NO_FAST " +#endif +#if defined(LTC_NO_BSWAP) + " LTC_NO_BSWAP " +#endif +#if defined(LTC_NO_ASM) + " LTC_NO_ASM " +#endif +#if defined(LTC_NO_TEST) + " LTC_NO_TEST " +#endif +#if defined(LTC_NO_TABLES) + " LTC_NO_TABLES " +#endif +#if defined(LTC_PTHREAD) + " LTC_PTHREAD " +#endif +#if defined(LTM_LTC_DESC) + " LTM_DESC " +#endif +#if defined(TFM_LTC_DESC) + " TFM_DESC " +#endif +#if defined(LTC_MECC_ACCEL) + " LTC_MECC_ACCEL " +#endif +#if defined(GMP_LTC_DESC) + " GMP_DESC " +#endif +#if defined(LTC_EASY) + " (easy) " +#endif +#if defined(LTC_MECC_FP) + " LTC_MECC_FP " +#endif +#if defined(LTC_ECC_SHAMIR) + " LTC_ECC_SHAMIR " +#endif + "\n" + "\n\n\n" + ; + + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt.c,v $ */ +/* $Revision: 1.36 $ */ +/* $Date: 2007/05/12 14:46:12 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_argchk.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_argchk.c new file mode 100644 index 0000000000..c217d57d07 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_argchk.c @@ -0,0 +1,30 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_argchk.c + Perform argument checking, Tom St Denis +*/ + +#if (ARGTYPE == 0) +#include +void crypt_argchk(char *v, char *s, int d) +{ + fprintf(stderr, "LTC_ARGCHK '%s' failure on line %d of file %s\n", + v, d, s); + abort(); +} +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_argchk.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_cipher_descriptor.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_cipher_descriptor.c new file mode 100644 index 0000000000..2ca50c7c3c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_cipher_descriptor.c @@ -0,0 +1,27 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_cipher_descriptor.c + Stores the cipher descriptor table, Tom St Denis +*/ + +struct ltc_cipher_descriptor cipher_descriptor[TAB_SIZE] = { +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } + }; + +LTC_MUTEX_GLOBAL(ltc_cipher_mutex) + + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_cipher_descriptor.c,v $ */ +/* $Revision: 1.13 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_cipher_is_valid.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_cipher_is_valid.c new file mode 100644 index 0000000000..e9cb2d0102 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_cipher_is_valid.c @@ -0,0 +1,36 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_cipher_is_valid.c + Determine if cipher is valid, Tom St Denis +*/ + +/* + Test if a cipher index is valid + @param idx The index of the cipher to search for + @return CRYPT_OK if valid +*/ +int cipher_is_valid(int idx) +{ + LTC_MUTEX_LOCK(<c_cipher_mutex); + if (idx < 0 || idx >= TAB_SIZE || cipher_descriptor[idx].name == NULL) { + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return CRYPT_INVALID_CIPHER; + } + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return CRYPT_OK; +} + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_cipher_is_valid.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_cipher.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_cipher.c new file mode 100644 index 0000000000..ad249f6582 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_cipher.c @@ -0,0 +1,41 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_find_cipher.c + Find a cipher in the descriptor tables, Tom St Denis +*/ + +/** + Find a registered cipher by name + @param name The name of the cipher to look for + @return >= 0 if found, -1 if not present +*/ +int find_cipher(const char *name) +{ + int x; + LTC_ARGCHK(name != NULL); + LTC_MUTEX_LOCK(<c_cipher_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (cipher_descriptor[x].name != NULL && !XSTRCMP(cipher_descriptor[x].name, name)) { + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return x; + } + } + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return -1; +} + + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_cipher.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_cipher_any.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_cipher_any.c new file mode 100644 index 0000000000..31f717fd35 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_cipher_any.c @@ -0,0 +1,50 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_find_cipher_any.c + Find a cipher in the descriptor tables, Tom St Denis +*/ + +/** + Find a cipher flexibly. First by name then if not present by block and key size + @param name The name of the cipher desired + @param blocklen The minimum length of the block cipher desired (octets) + @param keylen The minimum length of the key size desired (octets) + @return >= 0 if found, -1 if not present +*/ +int find_cipher_any(const char *name, int blocklen, int keylen) +{ + int x; + + LTC_ARGCHK(name != NULL); + + x = find_cipher(name); + if (x != -1) return x; + + LTC_MUTEX_LOCK(<c_cipher_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (cipher_descriptor[x].name == NULL) { + continue; + } + if (blocklen <= (int)cipher_descriptor[x].block_length && keylen <= (int)cipher_descriptor[x].max_key_length) { + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return x; + } + } + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return -1; +} + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_cipher_any.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_cipher_id.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_cipher_id.c new file mode 100644 index 0000000000..cde62292a4 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_cipher_id.c @@ -0,0 +1,40 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_find_cipher_id.c + Find cipher by ID, Tom St Denis +*/ + +/** + Find a cipher by ID number + @param ID The ID (not same as index) of the cipher to find + @return >= 0 if found, -1 if not present +*/ +int find_cipher_id(unsigned char ID) +{ + int x; + LTC_MUTEX_LOCK(<c_cipher_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (cipher_descriptor[x].ID == ID) { + x = (cipher_descriptor[x].name == NULL) ? -1 : x; + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return x; + } + } + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return -1; +} + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_cipher_id.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_hash.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_hash.c new file mode 100644 index 0000000000..87eb8ffff0 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_hash.c @@ -0,0 +1,40 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_find_hash.c + Find a hash, Tom St Denis +*/ + +/** + Find a registered hash by name + @param name The name of the hash to look for + @return >= 0 if found, -1 if not present +*/ +int find_hash(const char *name) +{ + int x; + LTC_ARGCHK(name != NULL); + LTC_MUTEX_LOCK(<c_hash_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (hash_descriptor[x].name != NULL && XSTRCMP(hash_descriptor[x].name, name) == 0) { + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return x; + } + } + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return -1; +} + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_hash.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_hash_any.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_hash_any.c new file mode 100644 index 0000000000..a479bb798f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_hash_any.c @@ -0,0 +1,49 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_find_hash_any.c + Find a hash, Tom St Denis +*/ + +/** + Find a hash flexibly. First by name then if not present by digest size + @param name The name of the hash desired + @param digestlen The minimum length of the digest size (octets) + @return >= 0 if found, -1 if not present +*/int find_hash_any(const char *name, int digestlen) +{ + int x, y, z; + LTC_ARGCHK(name != NULL); + + x = find_hash(name); + if (x != -1) return x; + + LTC_MUTEX_LOCK(<c_hash_mutex); + y = MAXBLOCKSIZE+1; + z = -1; + for (x = 0; x < TAB_SIZE; x++) { + if (hash_descriptor[x].name == NULL) { + continue; + } + if ((int)hash_descriptor[x].hashsize >= digestlen && (int)hash_descriptor[x].hashsize < y) { + z = x; + y = hash_descriptor[x].hashsize; + } + } + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return z; +} + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_hash_any.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_hash_id.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_hash_id.c new file mode 100644 index 0000000000..68d9ca3164 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_hash_id.c @@ -0,0 +1,40 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_find_hash_id.c + Find hash by ID, Tom St Denis +*/ + +/** + Find a hash by ID number + @param ID The ID (not same as index) of the hash to find + @return >= 0 if found, -1 if not present +*/ +int find_hash_id(unsigned char ID) +{ + int x; + LTC_MUTEX_LOCK(<c_hash_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (hash_descriptor[x].ID == ID) { + x = (hash_descriptor[x].name == NULL) ? -1 : x; + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return x; + } + } + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return -1; +} + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_hash_id.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_hash_oid.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_hash_oid.c new file mode 100644 index 0000000000..05333eead4 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_hash_oid.c @@ -0,0 +1,35 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_find_hash_oid.c + Find a hash, Tom St Denis +*/ + +int find_hash_oid(const unsigned long *ID, unsigned long IDlen) +{ + int x; + LTC_ARGCHK(ID != NULL); + LTC_MUTEX_LOCK(<c_hash_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (hash_descriptor[x].name != NULL && hash_descriptor[x].OIDlen == IDlen && !XMEMCMP(hash_descriptor[x].OID, ID, sizeof(unsigned long) * IDlen)) { + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return x; + } + } + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return -1; +} + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_hash_oid.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_prng.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_prng.c new file mode 100644 index 0000000000..a9dcddc357 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_find_prng.c @@ -0,0 +1,41 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_find_prng.c + Find a PRNG, Tom St Denis +*/ + +/** + Find a registered PRNG by name + @param name The name of the PRNG to look for + @return >= 0 if found, -1 if not present +*/ +int find_prng(const char *name) +{ + int x; + LTC_ARGCHK(name != NULL); + LTC_MUTEX_LOCK(<c_prng_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if ((prng_descriptor[x].name != NULL) && XSTRCMP(prng_descriptor[x].name, name) == 0) { + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return x; + } + } + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return -1; +} + + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_prng.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_fsa.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_fsa.c new file mode 100644 index 0000000000..027d4ccfed --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_fsa.c @@ -0,0 +1,59 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" +#include + +/** + @file crypt_fsa.c + LibTomCrypt FULL SPEED AHEAD!, Tom St Denis +*/ + +/* format is ltc_mp, cipher_desc, [cipher_desc], NULL, hash_desc, [hash_desc], NULL, prng_desc, [prng_desc], NULL */ +int crypt_fsa(void *mp, ...) +{ + int err; + va_list args; + void *p; + + va_start(args, mp); + if (mp != NULL) { + XMEMCPY(<c_mp, mp, sizeof(ltc_mp)); + } + + while ((p = va_arg(args, void*)) != NULL) { + if ((err = register_cipher(p)) != CRYPT_OK) { + va_end(args); + return err; + } + } + + while ((p = va_arg(args, void*)) != NULL) { + if ((err = register_hash(p)) != CRYPT_OK) { + va_end(args); + return err; + } + } + + while ((p = va_arg(args, void*)) != NULL) { + if ((err = register_prng(p)) != CRYPT_OK) { + va_end(args); + return err; + } + } + + va_end(args); + return CRYPT_OK; +} + + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_fsa.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_hash_descriptor.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_hash_descriptor.c new file mode 100644 index 0000000000..eef281340f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_hash_descriptor.c @@ -0,0 +1,27 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_hash_descriptor.c + Stores the hash descriptor table, Tom St Denis +*/ + +struct ltc_hash_descriptor hash_descriptor[TAB_SIZE] = { +{ NULL, 0, 0, 0, { 0 }, 0, NULL, NULL, NULL, NULL, NULL } +}; + +LTC_MUTEX_GLOBAL(ltc_hash_mutex) + + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_hash_descriptor.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_hash_is_valid.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_hash_is_valid.c new file mode 100644 index 0000000000..107f70f35c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_hash_is_valid.c @@ -0,0 +1,36 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_hash_is_valid.c + Determine if hash is valid, Tom St Denis +*/ + +/* + Test if a hash index is valid + @param idx The index of the hash to search for + @return CRYPT_OK if valid +*/ +int hash_is_valid(int idx) +{ + LTC_MUTEX_LOCK(<c_hash_mutex); + if (idx < 0 || idx >= TAB_SIZE || hash_descriptor[idx].name == NULL) { + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return CRYPT_INVALID_HASH; + } + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return CRYPT_OK; +} + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_hash_is_valid.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_ltc_mp_descriptor.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_ltc_mp_descriptor.c new file mode 100644 index 0000000000..0577d1dfb3 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_ltc_mp_descriptor.c @@ -0,0 +1,13 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +ltc_math_descriptor ltc_mp; diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_prng_descriptor.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_prng_descriptor.c new file mode 100644 index 0000000000..67cb6a0d69 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_prng_descriptor.c @@ -0,0 +1,26 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_prng_descriptor.c + Stores the PRNG descriptors, Tom St Denis +*/ +struct ltc_prng_descriptor prng_descriptor[TAB_SIZE] = { +{ NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } +}; + +LTC_MUTEX_GLOBAL(ltc_prng_mutex) + + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_prng_descriptor.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_prng_is_valid.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_prng_is_valid.c new file mode 100644 index 0000000000..6ec7634049 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_prng_is_valid.c @@ -0,0 +1,36 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_prng_is_valid.c + Determine if PRNG is valid, Tom St Denis +*/ + +/* + Test if a PRNG index is valid + @param idx The index of the PRNG to search for + @return CRYPT_OK if valid +*/ +int prng_is_valid(int idx) +{ + LTC_MUTEX_LOCK(<c_prng_mutex); + if (idx < 0 || idx >= TAB_SIZE || prng_descriptor[idx].name == NULL) { + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return CRYPT_INVALID_PRNG; + } + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return CRYPT_OK; +} + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_prng_is_valid.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_register_cipher.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_register_cipher.c new file mode 100644 index 0000000000..c8bfeb7d22 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_register_cipher.c @@ -0,0 +1,54 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_register_cipher.c + Register a cipher, Tom St Denis +*/ + +/** + Register a cipher with the descriptor table + @param cipher The cipher you wish to register + @return value >= 0 if successfully added (or already present), -1 if unsuccessful +*/ +int register_cipher(const struct ltc_cipher_descriptor *cipher) +{ + int x; + + LTC_ARGCHK(cipher != NULL); + + /* is it already registered? */ + LTC_MUTEX_LOCK(<c_cipher_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (cipher_descriptor[x].name != NULL && cipher_descriptor[x].ID == cipher->ID) { + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return x; + } + } + + /* find a blank spot */ + for (x = 0; x < TAB_SIZE; x++) { + if (cipher_descriptor[x].name == NULL) { + XMEMCPY(&cipher_descriptor[x], cipher, sizeof(struct ltc_cipher_descriptor)); + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return x; + } + } + + /* no spot */ + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return -1; +} + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_register_cipher.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_register_hash.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_register_hash.c new file mode 100644 index 0000000000..ffdba10f26 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_register_hash.c @@ -0,0 +1,54 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_register_hash.c + Register a HASH, Tom St Denis +*/ + +/** + Register a hash with the descriptor table + @param hash The hash you wish to register + @return value >= 0 if successfully added (or already present), -1 if unsuccessful +*/ +int register_hash(const struct ltc_hash_descriptor *hash) +{ + int x; + + LTC_ARGCHK(hash != NULL); + + /* is it already registered? */ + LTC_MUTEX_LOCK(<c_hash_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (XMEMCMP(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) { + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return x; + } + } + + /* find a blank spot */ + for (x = 0; x < TAB_SIZE; x++) { + if (hash_descriptor[x].name == NULL) { + XMEMCPY(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)); + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return x; + } + } + + /* no spot */ + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return -1; +} + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_register_hash.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_register_prng.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_register_prng.c new file mode 100644 index 0000000000..8e8a29cb42 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_register_prng.c @@ -0,0 +1,54 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_register_prng.c + Register a PRNG, Tom St Denis +*/ + +/** + Register a PRNG with the descriptor table + @param prng The PRNG you wish to register + @return value >= 0 if successfully added (or already present), -1 if unsuccessful +*/ +int register_prng(const struct ltc_prng_descriptor *prng) +{ + int x; + + LTC_ARGCHK(prng != NULL); + + /* is it already registered? */ + LTC_MUTEX_LOCK(<c_prng_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (XMEMCMP(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) == 0) { + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return x; + } + } + + /* find a blank spot */ + for (x = 0; x < TAB_SIZE; x++) { + if (prng_descriptor[x].name == NULL) { + XMEMCPY(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)); + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return x; + } + } + + /* no spot */ + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return -1; +} + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_register_prng.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_unregister_cipher.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_unregister_cipher.c new file mode 100644 index 0000000000..4c46d24a43 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_unregister_cipher.c @@ -0,0 +1,45 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_unregister_cipher.c + Unregister a cipher, Tom St Denis +*/ + +/** + Unregister a cipher from the descriptor table + @param cipher The cipher descriptor to remove + @return CRYPT_OK on success +*/ +int unregister_cipher(const struct ltc_cipher_descriptor *cipher) +{ + int x; + + LTC_ARGCHK(cipher != NULL); + + /* is it already registered? */ + LTC_MUTEX_LOCK(<c_cipher_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (XMEMCMP(&cipher_descriptor[x], cipher, sizeof(struct ltc_cipher_descriptor)) == 0) { + cipher_descriptor[x].name = NULL; + cipher_descriptor[x].ID = 255; + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return CRYPT_OK; + } + } + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return CRYPT_ERROR; +} + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_unregister_cipher.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_unregister_hash.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_unregister_hash.c new file mode 100644 index 0000000000..34b88c040e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_unregister_hash.c @@ -0,0 +1,44 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_unregister_hash.c + Unregister a hash, Tom St Denis +*/ + +/** + Unregister a hash from the descriptor table + @param hash The hash descriptor to remove + @return CRYPT_OK on success +*/ +int unregister_hash(const struct ltc_hash_descriptor *hash) +{ + int x; + + LTC_ARGCHK(hash != NULL); + + /* is it already registered? */ + LTC_MUTEX_LOCK(<c_hash_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (XMEMCMP(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) { + hash_descriptor[x].name = NULL; + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return CRYPT_OK; + } + } + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return CRYPT_ERROR; +} + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_unregister_hash.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_unregister_prng.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_unregister_prng.c new file mode 100644 index 0000000000..99548becd1 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/crypt/crypt_unregister_prng.c @@ -0,0 +1,44 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_unregister_prng.c + Unregister a PRNG, Tom St Denis +*/ + +/** + Unregister a PRNG from the descriptor table + @param prng The PRNG descriptor to remove + @return CRYPT_OK on success +*/ +int unregister_prng(const struct ltc_prng_descriptor *prng) +{ + int x; + + LTC_ARGCHK(prng != NULL); + + /* is it already registered? */ + LTC_MUTEX_LOCK(<c_prng_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (XMEMCMP(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) != 0) { + prng_descriptor[x].name = NULL; + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return CRYPT_OK; + } + } + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return CRYPT_ERROR; +} + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_unregister_prng.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/error_to_string.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/error_to_string.c new file mode 100644 index 0000000000..28df3b5caf --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/error_to_string.c @@ -0,0 +1,74 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +#include "tomcrypt.h" + +/** + @file error_to_string.c + Convert error codes to ASCII strings, Tom St Denis +*/ + +static const char *err_2_str[] = +{ + "CRYPT_OK", + "CRYPT_ERROR", + "Non-fatal 'no-operation' requested.", + + "Invalid keysize for block cipher.", + "Invalid number of rounds for block cipher.", + "Algorithm failed test vectors.", + + "Buffer overflow.", + "Invalid input packet.", + + "Invalid number of bits for a PRNG.", + "Error reading the PRNG.", + + "Invalid cipher specified.", + "Invalid hash specified.", + "Invalid PRNG specified.", + + "Out of memory.", + + "Invalid PK key or key type specified for function.", + "A private PK key is required.", + + "Invalid argument provided.", + "File Not Found", + + "Invalid PK type.", + "Invalid PK system.", + "Duplicate PK key found on keyring.", + "Key not found in keyring.", + "Invalid sized parameter.", + + "Invalid size for prime.", + +}; + +/** + Convert an LTC error code to ASCII + @param err The error code + @return A pointer to the ASCII NUL terminated string for the error or "Invalid error code." if the err code was not valid. +*/ +const char *error_to_string(int err) +{ + if (err < 0 || err >= (int)(sizeof(err_2_str)/sizeof(err_2_str[0]))) { + return "Invalid error code."; + } else { + return err_2_str[err]; + } +} + + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/error_to_string.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/pkcs5/pkcs_5_1.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/pkcs5/pkcs_5_1.c new file mode 100644 index 0000000000..ea0c0ce8ba --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/pkcs5/pkcs_5_1.c @@ -0,0 +1,106 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include + +/** + @file pkcs_5_1.c + LTC_PKCS #5, Algorithm #1, Tom St Denis +*/ +#ifdef LTC_PKCS_5 +/** + Execute LTC_PKCS #5 v1 + @param password The password (or key) + @param password_len The length of the password (octet) + @param salt The salt (or nonce) which is 8 octets long + @param iteration_count The LTC_PKCS #5 v1 iteration count + @param hash_idx The index of the hash desired + @param out [out] The destination for this algorithm + @param outlen [in/out] The max size and resulting size of the algorithm output + @return CRYPT_OK if successful +*/ +int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen) +{ + int err; + unsigned long x; + hash_state *md; + unsigned char *buf; + + LTC_ARGCHK(password != NULL); + LTC_ARGCHK(salt != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* test hash IDX */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + + /* allocate memory */ + md = XMALLOC(sizeof(hash_state)); + buf = XMALLOC(MAXBLOCKSIZE); + if (md == NULL || buf == NULL) { + if (md != NULL) { + XFREE(md); + } + if (buf != NULL) { + XFREE(buf); + } + return CRYPT_MEM; + } + + /* hash initial password + salt */ + if ((err = hash_descriptor[hash_idx].init(md)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].process(md, password, password_len)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].process(md, salt, 8)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].done(md, buf)) != CRYPT_OK) { + goto LBL_ERR; + } + + while (--iteration_count) { + /* code goes here. */ + x = MAXBLOCKSIZE; + if ((err = hash_memory(hash_idx, buf, hash_descriptor[hash_idx].hashsize, buf, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + } + + /* copy upto outlen bytes */ + for (x = 0; x < hash_descriptor[hash_idx].hashsize && x < *outlen; x++) { + out[x] = buf[x]; + } + *outlen = x; + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(buf, MAXBLOCKSIZE); + zeromem(md, sizeof(hash_state)); +#endif + + XFREE(buf); + XFREE(md); + + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/pkcs5/pkcs_5_1.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/pkcs5/pkcs_5_2.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/pkcs5/pkcs_5_2.c new file mode 100644 index 0000000000..066599effc --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/pkcs5/pkcs_5_2.c @@ -0,0 +1,129 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include + +/** + @file pkcs_5_2.c + LTC_PKCS #5, Algorithm #2, Tom St Denis +*/ +#ifdef LTC_PKCS_5 + +/** + Execute LTC_PKCS #5 v2 + @param password The input password (or key) + @param password_len The length of the password (octets) + @param salt The salt (or nonce) + @param salt_len The length of the salt (octets) + @param iteration_count # of iterations desired for LTC_PKCS #5 v2 [read specs for more] + @param hash_idx The index of the hash desired + @param out [out] The destination for this algorithm + @param outlen [in/out] The max size and resulting size of the algorithm output + @return CRYPT_OK if successful +*/ +int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, unsigned long salt_len, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen) +{ + int err, itts; + ulong32 blkno; + unsigned long stored, left, x, y; + unsigned char *buf[2]; + hmac_state *hmac; + + LTC_ARGCHK(password != NULL); + LTC_ARGCHK(salt != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* test hash IDX */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + + buf[0] = XMALLOC(MAXBLOCKSIZE * 2); + hmac = XMALLOC(sizeof(hmac_state)); + if (hmac == NULL || buf[0] == NULL) { + if (hmac != NULL) { + XFREE(hmac); + } + if (buf[0] != NULL) { + XFREE(buf[0]); + } + return CRYPT_MEM; + } + /* buf[1] points to the second block of MAXBLOCKSIZE bytes */ + buf[1] = buf[0] + MAXBLOCKSIZE; + + left = *outlen; + blkno = 1; + stored = 0; + while (left != 0) { + /* process block number blkno */ + zeromem(buf[0], MAXBLOCKSIZE*2); + + /* store current block number and increment for next pass */ + STORE32H(blkno, buf[1]); + ++blkno; + + /* get PRF(P, S||int(blkno)) */ + if ((err = hmac_init(hmac, hash_idx, password, password_len)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hmac_process(hmac, salt, salt_len)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hmac_process(hmac, buf[1], 4)) != CRYPT_OK) { + goto LBL_ERR; + } + x = MAXBLOCKSIZE; + if ((err = hmac_done(hmac, buf[0], &x)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* now compute repeated and XOR it in buf[1] */ + XMEMCPY(buf[1], buf[0], x); + for (itts = 1; itts < iteration_count; ++itts) { + if ((err = hmac_memory(hash_idx, password, password_len, buf[0], x, buf[0], &x)) != CRYPT_OK) { + goto LBL_ERR; + } + for (y = 0; y < x; y++) { + buf[1][y] ^= buf[0][y]; + } + } + + /* now emit upto x bytes of buf[1] to output */ + for (y = 0; y < x && left != 0; ++y) { + out[stored++] = buf[1][y]; + --left; + } + } + *outlen = stored; + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(buf[0], MAXBLOCKSIZE*2); + zeromem(hmac, sizeof(hmac_state)); +#endif + + XFREE(hmac); + XFREE(buf[0]); + + return err; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/pkcs5/pkcs_5_2.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/zeromem.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/zeromem.c new file mode 100644 index 0000000000..a4bb124fdc --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/misc/zeromem.c @@ -0,0 +1,34 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file zeromem.c + Zero a block of memory, Tom St Denis +*/ + +/** + Zero a block of memory + @param out The destination of the area to zero + @param outlen The length of the area to zero (octets) +*/ +void zeromem(void *out, size_t outlen) +{ + unsigned char *mem = out; + LTC_ARGCHKVD(out != NULL); + while (outlen-- > 0) { + *mem++ = 0; + } +} + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/zeromem.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cbc/cbc_decrypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cbc/cbc_decrypt.c new file mode 100644 index 0000000000..b06a9f3831 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cbc/cbc_decrypt.c @@ -0,0 +1,97 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cbc_decrypt.c + CBC implementation, encrypt block, Tom St Denis +*/ + + +#ifdef LTC_CBC_MODE + +/** + CBC decrypt + @param ct Ciphertext + @param pt [out] Plaintext + @param len The number of bytes to process (must be multiple of block length) + @param cbc CBC state + @return CRYPT_OK if successful +*/ +int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CBC *cbc) +{ + int x, err; + unsigned char tmp[16]; +#ifdef LTC_FAST + LTC_FAST_TYPE tmpy; +#else + unsigned char tmpy; +#endif + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(cbc != NULL); + + if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen valid? */ + if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV)) { + return CRYPT_INVALID_ARG; + } + + if (len % cbc->blocklen) { + return CRYPT_INVALID_ARG; + } +#ifdef LTC_FAST + if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + + if (cipher_descriptor[cbc->cipher].accel_cbc_decrypt != NULL) { + return cipher_descriptor[cbc->cipher].accel_cbc_decrypt(ct, pt, len / cbc->blocklen, cbc->IV, &cbc->key); + } else { + while (len) { + /* decrypt */ + if ((err = cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key)) != CRYPT_OK) { + return err; + } + + /* xor IV against plaintext */ + #if defined(LTC_FAST) + for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) { + tmpy = *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) ^ *((LTC_FAST_TYPE*)((unsigned char *)tmp + x)); + *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) = *((LTC_FAST_TYPE*)((unsigned char *)ct + x)); + *((LTC_FAST_TYPE*)((unsigned char *)pt + x)) = tmpy; + } + #else + for (x = 0; x < cbc->blocklen; x++) { + tmpy = tmp[x] ^ cbc->IV[x]; + cbc->IV[x] = ct[x]; + pt[x] = tmpy; + } + #endif + + ct += cbc->blocklen; + pt += cbc->blocklen; + len -= cbc->blocklen; + } + } + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/cbc/cbc_decrypt.c,v $ */ +/* $Revision: 1.16 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cbc/cbc_done.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cbc/cbc_done.c new file mode 100644 index 0000000000..fbaf6f8510 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cbc/cbc_done.c @@ -0,0 +1,42 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cbc_done.c + CBC implementation, finish chain, Tom St Denis +*/ + +#ifdef LTC_CBC_MODE + +/** Terminate the chain + @param cbc The CBC chain to terminate + @return CRYPT_OK on success +*/ +int cbc_done(symmetric_CBC *cbc) +{ + int err; + LTC_ARGCHK(cbc != NULL); + + if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[cbc->cipher].done(&cbc->key); + return CRYPT_OK; +} + + + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/cbc/cbc_done.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cbc/cbc_encrypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cbc/cbc_encrypt.c new file mode 100644 index 0000000000..23d56a6c49 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cbc/cbc_encrypt.c @@ -0,0 +1,98 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cbc_encrypt.c + CBC implementation, encrypt block, Tom St Denis +*/ + + +#ifdef LTC_CBC_MODE + +/** + CBC encrypt + @param pt Plaintext + @param ct [out] Ciphertext + @param len The number of bytes to process (must be multiple of block length) + @param cbc CBC state + @return CRYPT_OK if successful +*/ +int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CBC *cbc) +{ + int x, err; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(cbc != NULL); + + if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen valid? */ + if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV)) { + return CRYPT_INVALID_ARG; + } + + if (len % cbc->blocklen) { + return CRYPT_INVALID_ARG; + } +#ifdef LTC_FAST + if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + + if (cipher_descriptor[cbc->cipher].accel_cbc_encrypt != NULL) { + return cipher_descriptor[cbc->cipher].accel_cbc_encrypt(pt, ct, len / cbc->blocklen, cbc->IV, &cbc->key); + } else { + while (len) { + /* xor IV against plaintext */ + #if defined(LTC_FAST) + for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) ^= *((LTC_FAST_TYPE*)((unsigned char *)pt + x)); + } + #else + for (x = 0; x < cbc->blocklen; x++) { + cbc->IV[x] ^= pt[x]; + } + #endif + + /* encrypt */ + if ((err = cipher_descriptor[cbc->cipher].ecb_encrypt(cbc->IV, ct, &cbc->key)) != CRYPT_OK) { + return err; + } + + /* store IV [ciphertext] for a future block */ + #if defined(LTC_FAST) + for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) = *((LTC_FAST_TYPE*)((unsigned char *)ct + x)); + } + #else + for (x = 0; x < cbc->blocklen; x++) { + cbc->IV[x] = ct[x]; + } + #endif + + ct += cbc->blocklen; + pt += cbc->blocklen; + len -= cbc->blocklen; + } + } + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/cbc/cbc_encrypt.c,v $ */ +/* $Revision: 1.14 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cbc/cbc_getiv.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cbc/cbc_getiv.c new file mode 100644 index 0000000000..e3fb8364fb --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cbc/cbc_getiv.c @@ -0,0 +1,46 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cbc_getiv.c + CBC implementation, get IV, Tom St Denis +*/ + +#ifdef LTC_CBC_MODE + +/** + Get the current initial vector + @param IV [out] The destination of the initial vector + @param len [in/out] The max size and resulting size of the initial vector + @param cbc The CBC state + @return CRYPT_OK if successful +*/ +int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc) +{ + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(len != NULL); + LTC_ARGCHK(cbc != NULL); + if ((unsigned long)cbc->blocklen > *len) { + *len = cbc->blocklen; + return CRYPT_BUFFER_OVERFLOW; + } + XMEMCPY(IV, cbc->IV, cbc->blocklen); + *len = cbc->blocklen; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/cbc/cbc_getiv.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cbc/cbc_setiv.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cbc/cbc_setiv.c new file mode 100644 index 0000000000..93a8e401a7 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cbc/cbc_setiv.c @@ -0,0 +1,44 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cbc_setiv.c + CBC implementation, set IV, Tom St Denis +*/ + + +#ifdef LTC_CBC_MODE + +/** + Set an initial vector + @param IV The initial vector + @param len The length of the vector (in octets) + @param cbc The CBC state + @return CRYPT_OK if successful +*/ +int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc) +{ + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(cbc != NULL); + if (len != (unsigned long)cbc->blocklen) { + return CRYPT_INVALID_ARG; + } + XMEMCPY(cbc->IV, IV, len); + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/cbc/cbc_setiv.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cbc/cbc_start.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cbc/cbc_start.c new file mode 100644 index 0000000000..a171b5c433 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cbc/cbc_start.c @@ -0,0 +1,62 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cbc_start.c + CBC implementation, start chain, Tom St Denis +*/ + +#ifdef LTC_CBC_MODE + +/** + Initialize a CBC context + @param cipher The index of the cipher desired + @param IV The initial vector + @param key The secret key + @param keylen The length of the secret key (octets) + @param num_rounds Number of rounds in the cipher desired (0 for default) + @param cbc The CBC state to initialize + @return CRYPT_OK if successful +*/ +int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_CBC *cbc) +{ + int x, err; + + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(cbc != NULL); + + /* bad param? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* setup cipher */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cbc->key)) != CRYPT_OK) { + return err; + } + + /* copy IV */ + cbc->blocklen = cipher_descriptor[cipher].block_length; + cbc->cipher = cipher; + for (x = 0; x < cbc->blocklen; x++) { + cbc->IV[x] = IV[x]; + } + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/cbc/cbc_start.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cfb/cfb_decrypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cfb/cfb_decrypt.c new file mode 100644 index 0000000000..5f74f3e164 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cfb/cfb_decrypt.c @@ -0,0 +1,67 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cfb_decrypt.c + CFB implementation, decrypt data, Tom St Denis +*/ + +#ifdef LTC_CFB_MODE + +/** + CFB decrypt + @param ct Ciphertext + @param pt [out] Plaintext + @param len Length of ciphertext (octets) + @param cfb CFB state + @return CRYPT_OK if successful +*/ +int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb) +{ + int err; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(cfb != NULL); + + if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen/padlen valid? */ + if (cfb->blocklen < 0 || cfb->blocklen > (int)sizeof(cfb->IV) || + cfb->padlen < 0 || cfb->padlen > (int)sizeof(cfb->pad)) { + return CRYPT_INVALID_ARG; + } + + while (len-- > 0) { + if (cfb->padlen == cfb->blocklen) { + if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) { + return err; + } + cfb->padlen = 0; + } + cfb->pad[cfb->padlen] = *ct; + *pt = *ct ^ cfb->IV[cfb->padlen]; + ++pt; + ++ct; + ++(cfb->padlen); + } + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/cfb/cfb_decrypt.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cfb/cfb_done.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cfb/cfb_done.c new file mode 100644 index 0000000000..3b42e9f72c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cfb/cfb_done.c @@ -0,0 +1,42 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cfb_done.c + CFB implementation, finish chain, Tom St Denis +*/ + +#ifdef LTC_CFB_MODE + +/** Terminate the chain + @param cfb The CFB chain to terminate + @return CRYPT_OK on success +*/ +int cfb_done(symmetric_CFB *cfb) +{ + int err; + LTC_ARGCHK(cfb != NULL); + + if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[cfb->cipher].done(&cfb->key); + return CRYPT_OK; +} + + + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/cfb/cfb_done.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cfb/cfb_encrypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cfb/cfb_encrypt.c new file mode 100644 index 0000000000..b0fb43abaf --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cfb/cfb_encrypt.c @@ -0,0 +1,65 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cfb_encrypt.c + CFB implementation, encrypt data, Tom St Denis +*/ + +#ifdef LTC_CFB_MODE + +/** + CFB encrypt + @param pt Plaintext + @param ct [out] Ciphertext + @param len Length of plaintext (octets) + @param cfb CFB state + @return CRYPT_OK if successful +*/ +int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb) +{ + int err; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(cfb != NULL); + + if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen/padlen valid? */ + if (cfb->blocklen < 0 || cfb->blocklen > (int)sizeof(cfb->IV) || + cfb->padlen < 0 || cfb->padlen > (int)sizeof(cfb->pad)) { + return CRYPT_INVALID_ARG; + } + + while (len-- > 0) { + if (cfb->padlen == cfb->blocklen) { + if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) { + return err; + } + cfb->padlen = 0; + } + cfb->pad[cfb->padlen] = (*ct = *pt ^ cfb->IV[cfb->padlen]); + ++pt; + ++ct; + ++(cfb->padlen); + } + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/cfb/cfb_encrypt.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cfb/cfb_getiv.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cfb/cfb_getiv.c new file mode 100644 index 0000000000..6e204e143a --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cfb/cfb_getiv.c @@ -0,0 +1,46 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cfb_getiv.c + CFB implementation, get IV, Tom St Denis +*/ + +#ifdef LTC_CFB_MODE + +/** + Get the current initial vector + @param IV [out] The destination of the initial vector + @param len [in/out] The max size and resulting size of the initial vector + @param cfb The CFB state + @return CRYPT_OK if successful +*/ +int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb) +{ + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(len != NULL); + LTC_ARGCHK(cfb != NULL); + if ((unsigned long)cfb->blocklen > *len) { + *len = cfb->blocklen; + return CRYPT_BUFFER_OVERFLOW; + } + XMEMCPY(IV, cfb->IV, cfb->blocklen); + *len = cfb->blocklen; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/cfb/cfb_getiv.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cfb/cfb_setiv.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cfb/cfb_setiv.c new file mode 100644 index 0000000000..2fc2dd8dcf --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cfb/cfb_setiv.c @@ -0,0 +1,52 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cfb_setiv.c + CFB implementation, set IV, Tom St Denis +*/ + +#ifdef LTC_CFB_MODE + +/** + Set an initial vector + @param IV The initial vector + @param len The length of the vector (in octets) + @param cfb The CFB state + @return CRYPT_OK if successful +*/ +int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb) +{ + int err; + + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(cfb != NULL); + + if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) { + return err; + } + + if (len != (unsigned long)cfb->blocklen) { + return CRYPT_INVALID_ARG; + } + + /* force next block */ + cfb->padlen = 0; + return cipher_descriptor[cfb->cipher].ecb_encrypt(IV, cfb->IV, &cfb->key); +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/cfb/cfb_setiv.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cfb/cfb_start.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cfb/cfb_start.c new file mode 100644 index 0000000000..26ba322357 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/cfb/cfb_start.c @@ -0,0 +1,65 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cfb_start.c + CFB implementation, start chain, Tom St Denis +*/ + + +#ifdef LTC_CFB_MODE + +/** + Initialize a CFB context + @param cipher The index of the cipher desired + @param IV The initial vector + @param key The secret key + @param keylen The length of the secret key (octets) + @param num_rounds Number of rounds in the cipher desired (0 for default) + @param cfb The CFB state to initialize + @return CRYPT_OK if successful +*/ +int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_CFB *cfb) +{ + int x, err; + + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(cfb != NULL); + + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + + /* copy data */ + cfb->cipher = cipher; + cfb->blocklen = cipher_descriptor[cipher].block_length; + for (x = 0; x < cfb->blocklen; x++) + cfb->IV[x] = IV[x]; + + /* init the cipher */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cfb->key)) != CRYPT_OK) { + return err; + } + + /* encrypt the IV */ + cfb->padlen = 0; + return cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->IV, cfb->IV, &cfb->key); +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/cfb/cfb_start.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ctr/ctr_decrypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ctr/ctr_decrypt.c new file mode 100644 index 0000000000..687ddeadb1 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ctr/ctr_decrypt.c @@ -0,0 +1,42 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ctr_decrypt.c + CTR implementation, decrypt data, Tom St Denis +*/ + +#ifdef LTC_CTR_MODE + +/** + CTR decrypt + @param ct Ciphertext + @param pt [out] Plaintext + @param len Length of ciphertext (octets) + @param ctr CTR state + @return CRYPT_OK if successful +*/ +int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr) +{ + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(ctr != NULL); + + return ctr_encrypt(ct, pt, len, ctr); +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/ctr/ctr_decrypt.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ctr/ctr_done.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ctr/ctr_done.c new file mode 100644 index 0000000000..5549520bc3 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ctr/ctr_done.c @@ -0,0 +1,42 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ctr_done.c + CTR implementation, finish chain, Tom St Denis +*/ + +#ifdef LTC_CTR_MODE + +/** Terminate the chain + @param ctr The CTR chain to terminate + @return CRYPT_OK on success +*/ +int ctr_done(symmetric_CTR *ctr) +{ + int err; + LTC_ARGCHK(ctr != NULL); + + if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[ctr->cipher].done(&ctr->key); + return CRYPT_OK; +} + + + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/ctr/ctr_done.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ctr/ctr_encrypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ctr/ctr_encrypt.c new file mode 100644 index 0000000000..bac41f71c7 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ctr/ctr_encrypt.c @@ -0,0 +1,112 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ctr_encrypt.c + CTR implementation, encrypt data, Tom St Denis +*/ + + +#ifdef LTC_CTR_MODE + +/** + CTR encrypt + @param pt Plaintext + @param ct [out] Ciphertext + @param len Length of plaintext (octets) + @param ctr CTR state + @return CRYPT_OK if successful +*/ +int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr) +{ + int x, err; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(ctr != NULL); + + if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen/padlen valid? */ + if (ctr->blocklen < 1 || ctr->blocklen > (int)sizeof(ctr->ctr) || + ctr->padlen < 0 || ctr->padlen > (int)sizeof(ctr->pad)) { + return CRYPT_INVALID_ARG; + } + +#ifdef LTC_FAST + if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + + /* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */ + if ((ctr->padlen == ctr->blocklen) && cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL && (len >= (unsigned long)ctr->blocklen)) { + if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) { + return err; + } + len %= ctr->blocklen; + } + + while (len) { + /* is the pad empty? */ + if (ctr->padlen == ctr->blocklen) { + /* increment counter */ + if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) { + /* little-endian */ + for (x = 0; x < ctr->ctrlen; x++) { + ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; + if (ctr->ctr[x] != (unsigned char)0) { + break; + } + } + } else { + /* big-endian */ + for (x = ctr->blocklen-1; x >= ctr->ctrlen; x--) { + ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; + if (ctr->ctr[x] != (unsigned char)0) { + break; + } + } + } + + /* encrypt it */ + if ((err = cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key)) != CRYPT_OK) { + return err; + } + ctr->padlen = 0; + } +#ifdef LTC_FAST + if (ctr->padlen == 0 && len >= (unsigned long)ctr->blocklen) { + for (x = 0; x < ctr->blocklen; x += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)((unsigned char *)ct + x)) = *((LTC_FAST_TYPE*)((unsigned char *)pt + x)) ^ + *((LTC_FAST_TYPE*)((unsigned char *)ctr->pad + x)); + } + pt += ctr->blocklen; + ct += ctr->blocklen; + len -= ctr->blocklen; + ctr->padlen = ctr->blocklen; + continue; + } +#endif + *ct++ = *pt++ ^ ctr->pad[ctr->padlen++]; + --len; + } + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/ctr/ctr_encrypt.c,v $ */ +/* $Revision: 1.22 $ */ +/* $Date: 2007/02/22 20:26:05 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ctr/ctr_getiv.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ctr/ctr_getiv.c new file mode 100644 index 0000000000..84a1832dcf --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ctr/ctr_getiv.c @@ -0,0 +1,46 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ctr_getiv.c + CTR implementation, get IV, Tom St Denis +*/ + +#ifdef LTC_CTR_MODE + +/** + Get the current initial vector + @param IV [out] The destination of the initial vector + @param len [in/out] The max size and resulting size of the initial vector + @param ctr The CTR state + @return CRYPT_OK if successful +*/ +int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr) +{ + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(len != NULL); + LTC_ARGCHK(ctr != NULL); + if ((unsigned long)ctr->blocklen > *len) { + *len = ctr->blocklen; + return CRYPT_BUFFER_OVERFLOW; + } + XMEMCPY(IV, ctr->ctr, ctr->blocklen); + *len = ctr->blocklen; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/ctr/ctr_getiv.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ctr/ctr_setiv.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ctr/ctr_setiv.c new file mode 100644 index 0000000000..5696768d46 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ctr/ctr_setiv.c @@ -0,0 +1,56 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ctr_setiv.c + CTR implementation, set IV, Tom St Denis +*/ + +#ifdef LTC_CTR_MODE + +/** + Set an initial vector + @param IV The initial vector + @param len The length of the vector (in octets) + @param ctr The CTR state + @return CRYPT_OK if successful +*/ +int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr) +{ + int err; + + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(ctr != NULL); + + /* bad param? */ + if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) { + return err; + } + + if (len != (unsigned long)ctr->blocklen) { + return CRYPT_INVALID_ARG; + } + + /* set IV */ + XMEMCPY(ctr->ctr, IV, len); + + /* force next block */ + ctr->padlen = 0; + return cipher_descriptor[ctr->cipher].ecb_encrypt(IV, ctr->pad, &ctr->key); +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/ctr/ctr_setiv.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ctr/ctr_start.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ctr/ctr_start.c new file mode 100644 index 0000000000..1d1e1bcab3 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ctr/ctr_start.c @@ -0,0 +1,101 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ctr_start.c + CTR implementation, start chain, Tom St Denis +*/ + + +#ifdef LTC_CTR_MODE + +/** + Initialize a CTR context + @param cipher The index of the cipher desired + @param IV The initial vector + @param key The secret key + @param keylen The length of the secret key (octets) + @param num_rounds Number of rounds in the cipher desired (0 for default) + @param ctr_mode The counter mode (CTR_COUNTER_LITTLE_ENDIAN or CTR_COUNTER_BIG_ENDIAN) + @param ctr The CTR state to initialize + @return CRYPT_OK if successful +*/ +int ctr_start( int cipher, + const unsigned char *IV, + const unsigned char *key, int keylen, + int num_rounds, int ctr_mode, + symmetric_CTR *ctr) +{ + int x, err; + + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ctr != NULL); + + /* bad param? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* ctrlen == counter width */ + ctr->ctrlen = (ctr_mode & 255) ? (ctr_mode & 255) : cipher_descriptor[cipher].block_length; + if (ctr->ctrlen > cipher_descriptor[cipher].block_length) { + return CRYPT_INVALID_ARG; + } + + if ((ctr_mode & 0x1000) == CTR_COUNTER_BIG_ENDIAN) { + ctr->ctrlen = cipher_descriptor[cipher].block_length - ctr->ctrlen; + } + + /* setup cipher */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ctr->key)) != CRYPT_OK) { + return err; + } + + /* copy ctr */ + ctr->blocklen = cipher_descriptor[cipher].block_length; + ctr->cipher = cipher; + ctr->padlen = 0; + ctr->mode = ctr_mode & 0x1000; + for (x = 0; x < ctr->blocklen; x++) { + ctr->ctr[x] = IV[x]; + } + + if (ctr_mode & LTC_CTR_RFC3686) { + /* increment the IV as per RFC 3686 */ + if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) { + /* little-endian */ + for (x = 0; x < ctr->ctrlen; x++) { + ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; + if (ctr->ctr[x] != (unsigned char)0) { + break; + } + } + } else { + /* big-endian */ + for (x = ctr->blocklen-1; x >= ctr->ctrlen; x--) { + ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; + if (ctr->ctr[x] != (unsigned char)0) { + break; + } + } + } + } + + return cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key); +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/ctr/ctr_start.c,v $ */ +/* $Revision: 1.15 $ */ +/* $Date: 2007/02/23 14:18:37 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ctr/ctr_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ctr/ctr_test.c new file mode 100644 index 0000000000..2b9babab77 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ctr/ctr_test.c @@ -0,0 +1,82 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ctr_test.c + CTR implementation, Tests again RFC 3686, Tom St Denis +*/ + +#ifdef LTC_CTR_MODE + +int ctr_test(void) +{ +#ifdef LTC_NO_TEST + return CRYPT_NOP; +#else + static const struct { + int keylen, msglen; + unsigned char key[32], IV[16], pt[64], ct[64]; + } tests[] = { +/* 128-bit key, 16-byte pt */ +{ + 16, 16, + {0xAE,0x68,0x52,0xF8,0x12,0x10,0x67,0xCC,0x4B,0xF7,0xA5,0x76,0x55,0x77,0xF3,0x9E }, + {0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, + {0x53,0x69,0x6E,0x67,0x6C,0x65,0x20,0x62,0x6C,0x6F,0x63,0x6B,0x20,0x6D,0x73,0x67 }, + {0xE4,0x09,0x5D,0x4F,0xB7,0xA7,0xB3,0x79,0x2D,0x61,0x75,0xA3,0x26,0x13,0x11,0xB8 }, +}, + +/* 128-bit key, 36-byte pt */ +{ + 16, 36, + {0x76,0x91,0xBE,0x03,0x5E,0x50,0x20,0xA8,0xAC,0x6E,0x61,0x85,0x29,0xF9,0xA0,0xDC }, + {0x00,0xE0,0x01,0x7B,0x27,0x77,0x7F,0x3F,0x4A,0x17,0x86,0xF0,0x00,0x00,0x00,0x00 }, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, + 0x20,0x21,0x22,0x23}, + {0xC1,0xCF,0x48,0xA8,0x9F,0x2F,0xFD,0xD9,0xCF,0x46,0x52,0xE9,0xEF,0xDB,0x72,0xD7, + 0x45,0x40,0xA4,0x2B,0xDE,0x6D,0x78,0x36,0xD5,0x9A,0x5C,0xEA,0xAE,0xF3,0x10,0x53, + 0x25,0xB2,0x07,0x2F }, +}, +}; + int idx, err, x; + unsigned char buf[64]; + symmetric_CTR ctr; + + /* AES can be under rijndael or aes... try to find it */ + if ((idx = find_cipher("aes")) == -1) { + if ((idx = find_cipher("rijndael")) == -1) { + return CRYPT_NOP; + } + } + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + if ((err = ctr_start(idx, tests[x].IV, tests[x].key, tests[x].keylen, 0, CTR_COUNTER_BIG_ENDIAN|LTC_CTR_RFC3686, &ctr)) != CRYPT_OK) { + return err; + } + if ((err = ctr_encrypt(tests[x].pt, buf, tests[x].msglen, &ctr)) != CRYPT_OK) { + return err; + } + ctr_done(&ctr); + if (XMEMCMP(buf, tests[x].ct, tests[x].msglen)) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/ctr/ctr_test.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ecb/ecb_decrypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ecb/ecb_decrypt.c new file mode 100644 index 0000000000..107d9a0312 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ecb/ecb_decrypt.c @@ -0,0 +1,61 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ecb_decrypt.c + ECB implementation, decrypt a block, Tom St Denis +*/ + +#ifdef LTC_ECB_MODE + +/** + ECB decrypt + @param ct Ciphertext + @param pt [out] Plaintext + @param len The number of octets to process (must be multiple of the cipher block size) + @param ecb ECB state + @return CRYPT_OK if successful +*/ +int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_ECB *ecb) +{ + int err; + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(ecb != NULL); + if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) { + return err; + } + if (len % cipher_descriptor[ecb->cipher].block_length) { + return CRYPT_INVALID_ARG; + } + + /* check for accel */ + if (cipher_descriptor[ecb->cipher].accel_ecb_decrypt != NULL) { + return cipher_descriptor[ecb->cipher].accel_ecb_decrypt(ct, pt, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key); + } else { + while (len) { + if ((err = cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key)) != CRYPT_OK) { + return err; + } + pt += cipher_descriptor[ecb->cipher].block_length; + ct += cipher_descriptor[ecb->cipher].block_length; + len -= cipher_descriptor[ecb->cipher].block_length; + } + } + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/ecb/ecb_decrypt.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ecb/ecb_done.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ecb/ecb_done.c new file mode 100644 index 0000000000..53f796102e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ecb/ecb_done.c @@ -0,0 +1,42 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ecb_done.c + ECB implementation, finish chain, Tom St Denis +*/ + +#ifdef LTC_ECB_MODE + +/** Terminate the chain + @param ecb The ECB chain to terminate + @return CRYPT_OK on success +*/ +int ecb_done(symmetric_ECB *ecb) +{ + int err; + LTC_ARGCHK(ecb != NULL); + + if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[ecb->cipher].done(&ecb->key); + return CRYPT_OK; +} + + + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/ecb/ecb_done.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ecb/ecb_encrypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ecb/ecb_encrypt.c new file mode 100644 index 0000000000..500c055dbf --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ecb/ecb_encrypt.c @@ -0,0 +1,61 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ecb_encrypt.c + ECB implementation, encrypt a block, Tom St Denis +*/ + +#ifdef LTC_ECB_MODE + +/** + ECB encrypt + @param pt Plaintext + @param ct [out] Ciphertext + @param len The number of octets to process (must be multiple of the cipher block size) + @param ecb ECB state + @return CRYPT_OK if successful +*/ +int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_ECB *ecb) +{ + int err; + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(ecb != NULL); + if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) { + return err; + } + if (len % cipher_descriptor[ecb->cipher].block_length) { + return CRYPT_INVALID_ARG; + } + + /* check for accel */ + if (cipher_descriptor[ecb->cipher].accel_ecb_encrypt != NULL) { + return cipher_descriptor[ecb->cipher].accel_ecb_encrypt(pt, ct, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key); + } else { + while (len) { + if ((err = cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key)) != CRYPT_OK) { + return err; + } + pt += cipher_descriptor[ecb->cipher].block_length; + ct += cipher_descriptor[ecb->cipher].block_length; + len -= cipher_descriptor[ecb->cipher].block_length; + } + } + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/ecb/ecb_encrypt.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ecb/ecb_start.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ecb/ecb_start.c new file mode 100644 index 0000000000..bb4899b378 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ecb/ecb_start.c @@ -0,0 +1,48 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ecb_start.c + ECB implementation, start chain, Tom St Denis +*/ + + +#ifdef LTC_ECB_MODE + +/** + Initialize a ECB context + @param cipher The index of the cipher desired + @param key The secret key + @param keylen The length of the secret key (octets) + @param num_rounds Number of rounds in the cipher desired (0 for default) + @param ecb The ECB state to initialize + @return CRYPT_OK if successful +*/ +int ecb_start(int cipher, const unsigned char *key, int keylen, int num_rounds, symmetric_ECB *ecb) +{ + int err; + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ecb != NULL); + + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + ecb->cipher = cipher; + ecb->blocklen = cipher_descriptor[cipher].block_length; + return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ecb->key); +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/ecb/ecb_start.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/f8/f8_decrypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/f8/f8_decrypt.c new file mode 100644 index 0000000000..8d939dfed9 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/f8/f8_decrypt.c @@ -0,0 +1,43 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file f8_decrypt.c + F8 implementation, decrypt data, Tom St Denis +*/ + +#ifdef LTC_F8_MODE + +/** + F8 decrypt + @param ct Ciphertext + @param pt [out] Plaintext + @param len Length of ciphertext (octets) + @param f8 F8 state + @return CRYPT_OK if successful +*/ +int f8_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_F8 *f8) +{ + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(f8 != NULL); + return f8_encrypt(ct, pt, len, f8); +} + + +#endif + + + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/f8/f8_decrypt.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/f8/f8_done.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/f8/f8_done.c new file mode 100644 index 0000000000..842c0ac697 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/f8/f8_done.c @@ -0,0 +1,42 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file f8_done.c + F8 implementation, finish chain, Tom St Denis +*/ + +#ifdef LTC_F8_MODE + +/** Terminate the chain + @param f8 The F8 chain to terminate + @return CRYPT_OK on success +*/ +int f8_done(symmetric_F8 *f8) +{ + int err; + LTC_ARGCHK(f8 != NULL); + + if ((err = cipher_is_valid(f8->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[f8->cipher].done(&f8->key); + return CRYPT_OK; +} + + + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/f8/f8_done.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/f8/f8_encrypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/f8/f8_encrypt.c new file mode 100644 index 0000000000..b1a9a5f409 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/f8/f8_encrypt.c @@ -0,0 +1,103 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file f8_encrypt.c + F8 implementation, encrypt data, Tom St Denis +*/ + +#ifdef LTC_F8_MODE + +/** + F8 encrypt + @param pt Plaintext + @param ct [out] Ciphertext + @param len Length of plaintext (octets) + @param f8 F8 state + @return CRYPT_OK if successful +*/ +int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_F8 *f8) +{ + int err, x; + unsigned char buf[MAXBLOCKSIZE]; + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(f8 != NULL); + if ((err = cipher_is_valid(f8->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen/padlen valid? */ + if (f8->blocklen < 0 || f8->blocklen > (int)sizeof(f8->IV) || + f8->padlen < 0 || f8->padlen > (int)sizeof(f8->IV)) { + return CRYPT_INVALID_ARG; + } + + zeromem(buf, sizeof(buf)); + + /* make sure the pad is empty */ + if (f8->padlen == f8->blocklen) { + /* xor of IV, MIV and blockcnt == what goes into cipher */ + STORE32H(f8->blockcnt, (buf+(f8->blocklen-4))); + ++(f8->blockcnt); + for (x = 0; x < f8->blocklen; x++) { + f8->IV[x] ^= f8->MIV[x] ^ buf[x]; + } + if ((err = cipher_descriptor[f8->cipher].ecb_encrypt(f8->IV, f8->IV, &f8->key)) != CRYPT_OK) { + return err; + } + f8->padlen = 0; + } + +#ifdef LTC_FAST + if (f8->padlen == 0) { + while (len >= (unsigned long)f8->blocklen) { + STORE32H(f8->blockcnt, (buf+(f8->blocklen-4))); + ++(f8->blockcnt); + for (x = 0; x < f8->blocklen; x += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)(&ct[x])) = *((LTC_FAST_TYPE*)(&pt[x])) ^ *((LTC_FAST_TYPE*)(&f8->IV[x])); + *((LTC_FAST_TYPE*)(&f8->IV[x])) ^= *((LTC_FAST_TYPE*)(&f8->MIV[x])) ^ *((LTC_FAST_TYPE*)(&buf[x])); + } + if ((err = cipher_descriptor[f8->cipher].ecb_encrypt(f8->IV, f8->IV, &f8->key)) != CRYPT_OK) { + return err; + } + len -= x; + pt += x; + ct += x; + } + } +#endif + + while (len > 0) { + if (f8->padlen == f8->blocklen) { + /* xor of IV, MIV and blockcnt == what goes into cipher */ + STORE32H(f8->blockcnt, (buf+(f8->blocklen-4))); + ++(f8->blockcnt); + for (x = 0; x < f8->blocklen; x++) { + f8->IV[x] ^= f8->MIV[x] ^ buf[x]; + } + if ((err = cipher_descriptor[f8->cipher].ecb_encrypt(f8->IV, f8->IV, &f8->key)) != CRYPT_OK) { + return err; + } + f8->padlen = 0; + } + *ct++ = *pt++ ^ f8->IV[f8->padlen++]; + --len; + } + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/f8/f8_encrypt.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/f8/f8_getiv.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/f8/f8_getiv.c new file mode 100644 index 0000000000..0758a880a2 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/f8/f8_getiv.c @@ -0,0 +1,46 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ofb_getiv.c + F8 implementation, get IV, Tom St Denis +*/ + +#ifdef LTC_F8_MODE + +/** + Get the current initial vector + @param IV [out] The destination of the initial vector + @param len [in/out] The max size and resulting size of the initial vector + @param f8 The F8 state + @return CRYPT_OK if successful +*/ +int f8_getiv(unsigned char *IV, unsigned long *len, symmetric_F8 *f8) +{ + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(len != NULL); + LTC_ARGCHK(f8 != NULL); + if ((unsigned long)f8->blocklen > *len) { + *len = f8->blocklen; + return CRYPT_BUFFER_OVERFLOW; + } + XMEMCPY(IV, f8->IV, f8->blocklen); + *len = f8->blocklen; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/f8/f8_getiv.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/f8/f8_setiv.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/f8/f8_setiv.c new file mode 100644 index 0000000000..f034a07e59 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/f8/f8_setiv.c @@ -0,0 +1,52 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file f8_setiv.c + F8 implementation, set IV, Tom St Denis +*/ + +#ifdef LTC_F8_MODE + +/** + Set an initial vector + @param IV The initial vector + @param len The length of the vector (in octets) + @param f8 The F8 state + @return CRYPT_OK if successful +*/ +int f8_setiv(const unsigned char *IV, unsigned long len, symmetric_F8 *f8) +{ + int err; + + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(f8 != NULL); + + if ((err = cipher_is_valid(f8->cipher)) != CRYPT_OK) { + return err; + } + + if (len != (unsigned long)f8->blocklen) { + return CRYPT_INVALID_ARG; + } + + /* force next block */ + f8->padlen = 0; + return cipher_descriptor[f8->cipher].ecb_encrypt(IV, f8->IV, &f8->key); +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/f8/f8_setiv.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/f8/f8_start.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/f8/f8_start.c new file mode 100644 index 0000000000..070bf4e4ab --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/f8/f8_start.c @@ -0,0 +1,98 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file f8_start.c + F8 implementation, start chain, Tom St Denis +*/ + + +#ifdef LTC_F8_MODE + +/** + Initialize an F8 context + @param cipher The index of the cipher desired + @param IV The initial vector + @param key The secret key + @param keylen The length of the secret key (octets) + @param salt_key The salting key for the IV + @param skeylen The length of the salting key (octets) + @param num_rounds Number of rounds in the cipher desired (0 for default) + @param f8 The F8 state to initialize + @return CRYPT_OK if successful +*/ +int f8_start( int cipher, const unsigned char *IV, + const unsigned char *key, int keylen, + const unsigned char *salt_key, int skeylen, + int num_rounds, symmetric_F8 *f8) +{ + int x, err; + unsigned char tkey[MAXBLOCKSIZE]; + + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(salt_key != NULL); + LTC_ARGCHK(f8 != NULL); + + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + +#ifdef LTC_FAST + if (cipher_descriptor[cipher].block_length % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + + /* copy details */ + f8->blockcnt = 0; + f8->cipher = cipher; + f8->blocklen = cipher_descriptor[cipher].block_length; + f8->padlen = f8->blocklen; + + /* now get key ^ salt_key [extend salt_ket with 0x55 as required to match length] */ + zeromem(tkey, sizeof(tkey)); + for (x = 0; x < keylen && x < (int)sizeof(tkey); x++) { + tkey[x] = key[x]; + } + for (x = 0; x < skeylen && x < (int)sizeof(tkey); x++) { + tkey[x] ^= salt_key[x]; + } + for (; x < keylen && x < (int)sizeof(tkey); x++) { + tkey[x] ^= 0x55; + } + + /* now encrypt with tkey[0..keylen-1] the IV and use that as the IV */ + if ((err = cipher_descriptor[cipher].setup(tkey, keylen, num_rounds, &f8->key)) != CRYPT_OK) { + return err; + } + + /* encrypt IV */ + if ((err = cipher_descriptor[f8->cipher].ecb_encrypt(IV, f8->MIV, &f8->key)) != CRYPT_OK) { + cipher_descriptor[f8->cipher].done(&f8->key); + return err; + } + zeromem(tkey, sizeof(tkey)); + zeromem(f8->IV, sizeof(f8->IV)); + + /* terminate this cipher */ + cipher_descriptor[f8->cipher].done(&f8->key); + + /* init the cipher */ + return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &f8->key); +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/f8/f8_start.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/f8/f8_test_mode.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/f8/f8_test_mode.c new file mode 100644 index 0000000000..0740382fd1 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/f8/f8_test_mode.c @@ -0,0 +1,76 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file f8_test_mode.c + F8 implementation, test, Tom St Denis +*/ + + +#ifdef LTC_F8_MODE + +int f8_test_mode(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const unsigned char key[16] = { 0x23, 0x48, 0x29, 0x00, 0x84, 0x67, 0xbe, 0x18, + 0x6c, 0x3d, 0xe1, 0x4a, 0xae, 0x72, 0xd6, 0x2c }; + static const unsigned char salt[4] = { 0x32, 0xf2, 0x87, 0x0d }; + static const unsigned char IV[16] = { 0x00, 0x6e, 0x5c, 0xba, 0x50, 0x68, 0x1d, 0xe5, + 0x5c, 0x62, 0x15, 0x99, 0xd4, 0x62, 0x56, 0x4a }; + static const unsigned char pt[39] = { 0x70, 0x73, 0x65, 0x75, 0x64, 0x6f, 0x72, 0x61, + 0x6e, 0x64, 0x6f, 0x6d, 0x6e, 0x65, 0x73, 0x73, + 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x6e, 0x65, 0x78, 0x74, 0x20, 0x62, 0x65, 0x73, + 0x74, 0x20, 0x74, 0x68, 0x69, 0x6e, 0x67 }; + static const unsigned char ct[39] = { 0x01, 0x9c, 0xe7, 0xa2, 0x6e, 0x78, 0x54, 0x01, + 0x4a, 0x63, 0x66, 0xaa, 0x95, 0xd4, 0xee, 0xfd, + 0x1a, 0xd4, 0x17, 0x2a, 0x14, 0xf9, 0xfa, 0xf4, + 0x55, 0xb7, 0xf1, 0xd4, 0xb6, 0x2b, 0xd0, 0x8f, + 0x56, 0x2c, 0x0e, 0xef, 0x7c, 0x48, 0x02 }; + unsigned char buf[39]; + symmetric_F8 f8; + int err, idx; + + idx = find_cipher("aes"); + if (idx == -1) { + idx = find_cipher("rijndael"); + if (idx == -1) return CRYPT_NOP; + } + + /* initialize the context */ + if ((err = f8_start(idx, IV, key, sizeof(key), salt, sizeof(salt), 0, &f8)) != CRYPT_OK) { + return err; + } + + /* encrypt block */ + if ((err = f8_encrypt(pt, buf, sizeof(pt), &f8)) != CRYPT_OK) { + f8_done(&f8); + return err; + } + f8_done(&f8); + + /* compare */ + if (XMEMCMP(buf, ct, sizeof(ct))) { + return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; +#endif +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/f8/f8_test_mode.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_decrypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_decrypt.c new file mode 100644 index 0000000000..da29e37af6 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_decrypt.c @@ -0,0 +1,51 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file lrw_decrypt.c + LRW_MODE implementation, Decrypt blocks, Tom St Denis +*/ + +#ifdef LTC_LRW_MODE + +/** + LRW decrypt blocks + @param ct The ciphertext + @param pt [out] The plaintext + @param len The length in octets, must be a multiple of 16 + @param lrw The LRW state +*/ +int lrw_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_LRW *lrw) +{ + int err; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(lrw != NULL); + + if ((err = cipher_is_valid(lrw->cipher)) != CRYPT_OK) { + return err; + } + + if (cipher_descriptor[lrw->cipher].accel_lrw_decrypt != NULL) { + return cipher_descriptor[lrw->cipher].accel_lrw_decrypt(ct, pt, len, lrw->IV, lrw->tweak, &lrw->key); + } + + return lrw_process(ct, pt, len, LRW_DECRYPT, lrw); +} + + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/lrw/lrw_decrypt.c,v $ */ +/* $Revision: 1.9 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_done.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_done.c new file mode 100644 index 0000000000..06047e8d14 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_done.c @@ -0,0 +1,42 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file lrw_done.c + LRW_MODE implementation, Free resources, Tom St Denis +*/ + +#ifdef LTC_LRW_MODE + +/** + Terminate a LRW state + @param lrw The state to terminate + @return CRYPT_OK if successful +*/ +int lrw_done(symmetric_LRW *lrw) +{ + int err; + + LTC_ARGCHK(lrw != NULL); + + if ((err = cipher_is_valid(lrw->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[lrw->cipher].done(&lrw->key); + + return CRYPT_OK; +} + +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/modes/lrw/lrw_done.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_encrypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_encrypt.c new file mode 100644 index 0000000000..4a8951a1d0 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_encrypt.c @@ -0,0 +1,50 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file lrw_encrypt.c + LRW_MODE implementation, Encrypt blocks, Tom St Denis +*/ + +#ifdef LTC_LRW_MODE + +/** + LRW encrypt blocks + @param pt The plaintext + @param ct [out] The ciphertext + @param len The length in octets, must be a multiple of 16 + @param lrw The LRW state +*/ +int lrw_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_LRW *lrw) +{ + int err; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(lrw != NULL); + + if ((err = cipher_is_valid(lrw->cipher)) != CRYPT_OK) { + return err; + } + + if (cipher_descriptor[lrw->cipher].accel_lrw_encrypt != NULL) { + return cipher_descriptor[lrw->cipher].accel_lrw_encrypt(pt, ct, len, lrw->IV, lrw->tweak, &lrw->key); + } + + return lrw_process(pt, ct, len, LRW_ENCRYPT, lrw); +} + + +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/modes/lrw/lrw_encrypt.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_getiv.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_getiv.c new file mode 100644 index 0000000000..3ddccb2a0d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_getiv.c @@ -0,0 +1,45 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file lrw_getiv.c + LRW_MODE implementation, Retrieve the current IV, Tom St Denis +*/ + +#ifdef LTC_LRW_MODE + +/** + Get the IV for LRW + @param IV [out] The IV, must be 16 octets + @param len Length ... must be at least 16 :-) + @param lrw The LRW state to read + @return CRYPT_OK if successful +*/ +int lrw_getiv(unsigned char *IV, unsigned long *len, symmetric_LRW *lrw) +{ + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(len != NULL); + LTC_ARGCHK(lrw != NULL); + if (*len < 16) { + *len = 16; + return CRYPT_BUFFER_OVERFLOW; + } + + XMEMCPY(IV, lrw->IV, 16); + *len = 16; + return CRYPT_OK; +} + +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/modes/lrw/lrw_getiv.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_process.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_process.c new file mode 100644 index 0000000000..243923f598 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_process.c @@ -0,0 +1,120 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file lrw_process.c + LRW_MODE implementation, Encrypt/decrypt blocks, Tom St Denis +*/ + +#ifdef LTC_LRW_MODE + +/** + Process blocks with LRW, since decrypt/encrypt are largely the same they share this code. + @param pt The "input" data + @param ct [out] The "output" data + @param len The length of the input, must be a multiple of 128-bits (16 octets) + @param mode LRW_ENCRYPT or LRW_DECRYPT + @param lrw The LRW state + @return CRYPT_OK if successful +*/ +int lrw_process(const unsigned char *pt, unsigned char *ct, unsigned long len, int mode, symmetric_LRW *lrw) +{ + unsigned char prod[16]; + int x, err; +#ifdef LRW_TABLES + int y; +#endif + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(lrw != NULL); + + if (len & 15) { + return CRYPT_INVALID_ARG; + } + + while (len) { + /* copy pad */ + XMEMCPY(prod, lrw->pad, 16); + + /* increment IV */ + for (x = 15; x >= 0; x--) { + lrw->IV[x] = (lrw->IV[x] + 1) & 255; + if (lrw->IV[x]) { + break; + } + } + + /* update pad */ +#ifdef LRW_TABLES + /* for each byte changed we undo it's affect on the pad then add the new product */ + for (; x < 16; x++) { +#ifdef LTC_FAST + for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE *)(lrw->pad + y)) ^= *((LTC_FAST_TYPE *)(&lrw->PC[x][lrw->IV[x]][y])) ^ *((LTC_FAST_TYPE *)(&lrw->PC[x][(lrw->IV[x]-1)&255][y])); + } +#else + for (y = 0; y < 16; y++) { + lrw->pad[y] ^= lrw->PC[x][lrw->IV[x]][y] ^ lrw->PC[x][(lrw->IV[x]-1)&255][y]; + } +#endif + } +#else + gcm_gf_mult(lrw->tweak, lrw->IV, lrw->pad); +#endif + + /* xor prod */ +#ifdef LTC_FAST + for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE *)(ct + x)) = *((LTC_FAST_TYPE *)(pt + x)) ^ *((LTC_FAST_TYPE *)(prod + x)); + } +#else + for (x = 0; x < 16; x++) { + ct[x] = pt[x] ^ prod[x]; + } +#endif + + /* send through cipher */ + if (mode == LRW_ENCRYPT) { + if ((err = cipher_descriptor[lrw->cipher].ecb_encrypt(ct, ct, &lrw->key)) != CRYPT_OK) { + return err; + } + } else { + if ((err = cipher_descriptor[lrw->cipher].ecb_decrypt(ct, ct, &lrw->key)) != CRYPT_OK) { + return err; + } + } + + /* xor prod */ +#ifdef LTC_FAST + for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE *)(ct + x)) = *((LTC_FAST_TYPE *)(ct + x)) ^ *((LTC_FAST_TYPE *)(prod + x)); + } +#else + for (x = 0; x < 16; x++) { + ct[x] = ct[x] ^ prod[x]; + } +#endif + + /* move to next */ + pt += 16; + ct += 16; + len -= 16; + } + + return CRYPT_OK; +} + +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/modes/lrw/lrw_process.c,v $ */ +/* $Revision: 1.11 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_setiv.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_setiv.c new file mode 100644 index 0000000000..dd1d852882 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_setiv.c @@ -0,0 +1,79 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file lrw_setiv.c + LRW_MODE implementation, Set the current IV, Tom St Denis +*/ + +#ifdef LTC_LRW_MODE + +/** + Set the IV for LRW + @param IV The IV, must be 16 octets + @param len Length ... must be 16 :-) + @param lrw The LRW state to update + @return CRYPT_OK if successful +*/ +int lrw_setiv(const unsigned char *IV, unsigned long len, symmetric_LRW *lrw) +{ + int err; +#ifdef LRW_TABLES + unsigned char T[16]; + int x, y; +#endif + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(lrw != NULL); + + if (len != 16) { + return CRYPT_INVALID_ARG; + } + + if ((err = cipher_is_valid(lrw->cipher)) != CRYPT_OK) { + return err; + } + + /* copy the IV */ + XMEMCPY(lrw->IV, IV, 16); + + /* check if we have to actually do work */ + if (cipher_descriptor[lrw->cipher].accel_lrw_encrypt != NULL && cipher_descriptor[lrw->cipher].accel_lrw_decrypt != NULL) { + /* we have accelerators, let's bail since they don't use lrw->pad anyways */ + return CRYPT_OK; + } + +#ifdef LRW_TABLES + XMEMCPY(T, &lrw->PC[0][IV[0]][0], 16); + for (x = 1; x < 16; x++) { +#ifdef LTC_FAST + for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE *)(T + y)) ^= *((LTC_FAST_TYPE *)(&lrw->PC[x][IV[x]][y])); + } +#else + for (y = 0; y < 16; y++) { + T[y] ^= lrw->PC[x][IV[x]][y]; + } +#endif + } + XMEMCPY(lrw->pad, T, 16); +#else + gcm_gf_mult(lrw->tweak, IV, lrw->pad); +#endif + + return CRYPT_OK; +} + + +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/modes/lrw/lrw_setiv.c,v $ */ +/* $Revision: 1.13 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_start.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_start.c new file mode 100644 index 0000000000..6cd3b99c6c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_start.c @@ -0,0 +1,103 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file lrw_start.c + LRW_MODE implementation, start mode, Tom St Denis +*/ + +#ifdef LTC_LRW_MODE + +/** + Initialize the LRW context + @param cipher The cipher desired, must be a 128-bit block cipher + @param IV The index value, must be 128-bits + @param key The cipher key + @param keylen The length of the cipher key in octets + @param tweak The tweak value (second key), must be 128-bits + @param num_rounds The number of rounds for the cipher (0 == default) + @param lrw [out] The LRW state + @return CRYPT_OK on success. +*/ +int lrw_start( int cipher, + const unsigned char *IV, + const unsigned char *key, int keylen, + const unsigned char *tweak, + int num_rounds, + symmetric_LRW *lrw) +{ + int err; +#ifdef LRW_TABLES + unsigned char B[16]; + int x, y, z, t; +#endif + + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(tweak != NULL); + LTC_ARGCHK(lrw != NULL); + +#ifdef LTC_FAST + if (16 % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + + /* is cipher valid? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + if (cipher_descriptor[cipher].block_length != 16) { + return CRYPT_INVALID_CIPHER; + } + + /* schedule key */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &lrw->key)) != CRYPT_OK) { + return err; + } + lrw->cipher = cipher; + + /* copy the IV and tweak */ + XMEMCPY(lrw->tweak, tweak, 16); + +#ifdef LRW_TABLES + /* setup tables */ + /* generate the first table as it has no shifting (from which we make the other tables) */ + zeromem(B, 16); + for (y = 0; y < 256; y++) { + B[0] = y; + gcm_gf_mult(tweak, B, &lrw->PC[0][y][0]); + } + + /* now generate the rest of the tables based the previous table */ + for (x = 1; x < 16; x++) { + for (y = 0; y < 256; y++) { + /* now shift it right by 8 bits */ + t = lrw->PC[x-1][y][15]; + for (z = 15; z > 0; z--) { + lrw->PC[x][y][z] = lrw->PC[x-1][y][z-1]; + } + lrw->PC[x][y][0] = gcm_shift_table[t<<1]; + lrw->PC[x][y][1] ^= gcm_shift_table[(t<<1)+1]; + } + } +#endif + + /* generate first pad */ + return lrw_setiv(IV, 16, lrw); +} + + +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/modes/lrw/lrw_start.c,v $ */ +/* $Revision: 1.12 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_test.c new file mode 100644 index 0000000000..a2951587c4 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/lrw/lrw_test.c @@ -0,0 +1,136 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file lrw_test.c + LRW_MODE implementation, test LRW, Tom St Denis +*/ + +#ifdef LTC_LRW_MODE + +/** + Test LRW against specs + @return CRYPT_OK if goodly +*/ +int lrw_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + unsigned char key[16], tweak[16], IV[16], P[16], expected_tweak[16], C[16]; + } tests[] = { + +{ +{ 0x45, 0x62, 0xac, 0x25, 0xf8, 0x28, 0x17, 0x6d, 0x4c, 0x26, 0x84, 0x14, 0xb5, 0x68, 0x01, 0x85 }, +{ 0x25, 0x8e, 0x2a, 0x05, 0xe7, 0x3e, 0x9d, 0x03, 0xee, 0x5a, 0x83, 0x0c, 0xcc, 0x09, 0x4c, 0x87 }, +{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, +{ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 }, +{ 0x25, 0x8e, 0x2a, 0x05, 0xe7, 0x3e, 0x9d, 0x03, 0xee, 0x5a, 0x83, 0x0c, 0xcc, 0x09, 0x4c, 0x87 }, +{ 0xf1, 0xb2, 0x73, 0xcd, 0x65, 0xa3, 0xdf, 0x5f, 0xe9, 0x5d, 0x48, 0x92, 0x54, 0x63, 0x4e, 0xb8 } +}, + +{ +{ 0x59, 0x70, 0x47, 0x14, 0xf5, 0x57, 0x47, 0x8c, 0xd7, 0x79, 0xe8, 0x0f, 0x54, 0x88, 0x79, 0x44 }, +{ 0x35, 0x23, 0xc2, 0xde, 0xc5, 0x69, 0x4f, 0xa8, 0x72, 0xa9, 0xac, 0xa7, 0x0b, 0x2b, 0xee, 0xbc }, +{ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, +{ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 }, +{ 0x1a, 0x91, 0xe1, 0x6f, 0x62, 0xb4, 0xa7, 0xd4, 0x39, 0x54, 0xd6, 0x53, 0x85, 0x95, 0xf7, 0x5e }, +{ 0x00, 0xc8, 0x2b, 0xae, 0x95, 0xbb, 0xcd, 0xe5, 0x27, 0x4f, 0x07, 0x69, 0xb2, 0x60, 0xe1, 0x36 }, +}, + +{ +{ 0x59, 0x70, 0x47, 0x14, 0xf5, 0x57, 0x47, 0x8c, 0xd7, 0x79, 0xe8, 0x0f, 0x54, 0x88, 0x79, 0x44 }, +{ 0x67, 0x53, 0xc9, 0x0c, 0xb7, 0xd8, 0xcd, 0xe5, 0x06, 0xa0, 0x47, 0x78, 0x1a, 0xad, 0x85, 0x11 }, +{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }, +{ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 }, +{ 0x1a, 0x91, 0xe1, 0x6f, 0x62, 0xb4, 0xa7, 0xd4, 0x39, 0x54, 0xd6, 0x53, 0x85, 0x95, 0xf7, 0x5e }, +{ 0x00, 0xc8, 0x2b, 0xae, 0x95, 0xbb, 0xcd, 0xe5, 0x27, 0x4f, 0x07, 0x69, 0xb2, 0x60, 0xe1, 0x36 }, +}, + +{ + +{ 0xd8, 0x2a, 0x91, 0x34, 0xb2, 0x6a, 0x56, 0x50, 0x30, 0xfe, 0x69, 0xe2, 0x37, 0x7f, 0x98, 0x47 }, +{ 0x4e, 0xb5, 0x5d, 0x31, 0x05, 0x97, 0x3a, 0x3f, 0x5e, 0x23, 0xda, 0xfb, 0x5a, 0x45, 0xd6, 0xc0 }, +{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 }, +{ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 }, +{ 0x18, 0xc9, 0x1f, 0x6d, 0x60, 0x1a, 0x1a, 0x37, 0x5d, 0x0b, 0x0e, 0xf7, 0x3a, 0xd5, 0x74, 0xc4 }, +{ 0x76, 0x32, 0x21, 0x83, 0xed, 0x8f, 0xf1, 0x82, 0xf9, 0x59, 0x62, 0x03, 0x69, 0x0e, 0x5e, 0x01 }, + +} +}; + + int idx, err, x; + symmetric_LRW lrw; + unsigned char buf[2][16]; + + idx = find_cipher("aes"); + if (idx == -1) { + idx = find_cipher("rijndael"); + if (idx == -1) { + return CRYPT_NOP; + } + } + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + /* schedule it */ + if ((err = lrw_start(idx, tests[x].IV, tests[x].key, 16, tests[x].tweak, 0, &lrw)) != CRYPT_OK) { + return err; + } + + /* check pad against expected tweak */ + if (XMEMCMP(tests[x].expected_tweak, lrw.pad, 16)) { + lrw_done(&lrw); + return CRYPT_FAIL_TESTVECTOR; + } + + /* process block */ + if ((err = lrw_encrypt(tests[x].P, buf[0], 16, &lrw)) != CRYPT_OK) { + lrw_done(&lrw); + return err; + } + + if (XMEMCMP(buf[0], tests[x].C, 16)) { + lrw_done(&lrw); + return CRYPT_FAIL_TESTVECTOR; + } + + /* process block */ + if ((err = lrw_setiv(tests[x].IV, 16, &lrw)) != CRYPT_OK) { + lrw_done(&lrw); + return err; + } + + if ((err = lrw_decrypt(buf[0], buf[1], 16, &lrw)) != CRYPT_OK) { + lrw_done(&lrw); + return err; + } + + if (XMEMCMP(buf[1], tests[x].P, 16)) { + lrw_done(&lrw); + return CRYPT_FAIL_TESTVECTOR; + } + if ((err = lrw_done(&lrw)) != CRYPT_OK) { + return err; + } + } + return CRYPT_OK; +#endif +} + +#endif + + + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/lrw/lrw_test.c,v $ */ +/* $Revision: 1.12 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ofb/ofb_decrypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ofb/ofb_decrypt.c new file mode 100644 index 0000000000..bcdda34c38 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ofb/ofb_decrypt.c @@ -0,0 +1,43 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ofb_decrypt.c + OFB implementation, decrypt data, Tom St Denis +*/ + +#ifdef LTC_OFB_MODE + +/** + OFB decrypt + @param ct Ciphertext + @param pt [out] Plaintext + @param len Length of ciphertext (octets) + @param ofb OFB state + @return CRYPT_OK if successful +*/ +int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb) +{ + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(ofb != NULL); + return ofb_encrypt(ct, pt, len, ofb); +} + + +#endif + + + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/ofb/ofb_decrypt.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ofb/ofb_done.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ofb/ofb_done.c new file mode 100644 index 0000000000..143cff4624 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ofb/ofb_done.c @@ -0,0 +1,42 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ofb_done.c + OFB implementation, finish chain, Tom St Denis +*/ + +#ifdef LTC_OFB_MODE + +/** Terminate the chain + @param ofb The OFB chain to terminate + @return CRYPT_OK on success +*/ +int ofb_done(symmetric_OFB *ofb) +{ + int err; + LTC_ARGCHK(ofb != NULL); + + if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[ofb->cipher].done(&ofb->key); + return CRYPT_OK; +} + + + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/ofb/ofb_done.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ofb/ofb_encrypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ofb/ofb_encrypt.c new file mode 100644 index 0000000000..9d695d0adf --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ofb/ofb_encrypt.c @@ -0,0 +1,60 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ofb_encrypt.c + OFB implementation, encrypt data, Tom St Denis +*/ + +#ifdef LTC_OFB_MODE + +/** + OFB encrypt + @param pt Plaintext + @param ct [out] Ciphertext + @param len Length of plaintext (octets) + @param ofb OFB state + @return CRYPT_OK if successful +*/ +int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb) +{ + int err; + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(ofb != NULL); + if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen/padlen valid? */ + if (ofb->blocklen < 0 || ofb->blocklen > (int)sizeof(ofb->IV) || + ofb->padlen < 0 || ofb->padlen > (int)sizeof(ofb->IV)) { + return CRYPT_INVALID_ARG; + } + + while (len-- > 0) { + if (ofb->padlen == ofb->blocklen) { + if ((err = cipher_descriptor[ofb->cipher].ecb_encrypt(ofb->IV, ofb->IV, &ofb->key)) != CRYPT_OK) { + return err; + } + ofb->padlen = 0; + } + *ct++ = *pt++ ^ ofb->IV[(ofb->padlen)++]; + } + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/ofb/ofb_encrypt.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ofb/ofb_getiv.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ofb/ofb_getiv.c new file mode 100644 index 0000000000..19fc56987f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ofb/ofb_getiv.c @@ -0,0 +1,46 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ofb_getiv.c + OFB implementation, get IV, Tom St Denis +*/ + +#ifdef LTC_OFB_MODE + +/** + Get the current initial vector + @param IV [out] The destination of the initial vector + @param len [in/out] The max size and resulting size of the initial vector + @param ofb The OFB state + @return CRYPT_OK if successful +*/ +int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb) +{ + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(len != NULL); + LTC_ARGCHK(ofb != NULL); + if ((unsigned long)ofb->blocklen > *len) { + *len = ofb->blocklen; + return CRYPT_BUFFER_OVERFLOW; + } + XMEMCPY(IV, ofb->IV, ofb->blocklen); + *len = ofb->blocklen; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/ofb/ofb_getiv.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ofb/ofb_setiv.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ofb/ofb_setiv.c new file mode 100644 index 0000000000..8d9032f128 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ofb/ofb_setiv.c @@ -0,0 +1,52 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ofb_setiv.c + OFB implementation, set IV, Tom St Denis +*/ + +#ifdef LTC_OFB_MODE + +/** + Set an initial vector + @param IV The initial vector + @param len The length of the vector (in octets) + @param ofb The OFB state + @return CRYPT_OK if successful +*/ +int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb) +{ + int err; + + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(ofb != NULL); + + if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) { + return err; + } + + if (len != (unsigned long)ofb->blocklen) { + return CRYPT_INVALID_ARG; + } + + /* force next block */ + ofb->padlen = 0; + return cipher_descriptor[ofb->cipher].ecb_encrypt(IV, ofb->IV, &ofb->key); +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/ofb/ofb_setiv.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ofb/ofb_start.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ofb/ofb_start.c new file mode 100644 index 0000000000..fcbfb1b0a1 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/ofb/ofb_start.c @@ -0,0 +1,60 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ofb_start.c + OFB implementation, start chain, Tom St Denis +*/ + + +#ifdef LTC_OFB_MODE + +/** + Initialize a OFB context + @param cipher The index of the cipher desired + @param IV The initial vector + @param key The secret key + @param keylen The length of the secret key (octets) + @param num_rounds Number of rounds in the cipher desired (0 for default) + @param ofb The OFB state to initialize + @return CRYPT_OK if successful +*/ +int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_OFB *ofb) +{ + int x, err; + + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ofb != NULL); + + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* copy details */ + ofb->cipher = cipher; + ofb->blocklen = cipher_descriptor[cipher].block_length; + for (x = 0; x < ofb->blocklen; x++) { + ofb->IV[x] = IV[x]; + } + + /* init the cipher */ + ofb->padlen = ofb->blocklen; + return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ofb->key); +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/ofb/ofb_start.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/xts/xts_decrypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/xts/xts_decrypt.c new file mode 100644 index 0000000000..5787ab1693 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/xts/xts_decrypt.c @@ -0,0 +1,140 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects +*/ + +#ifdef LTC_XTS_MODE + +static int tweak_uncrypt(const unsigned char *C, unsigned char *P, unsigned char *T, symmetric_xts *xts) +{ + unsigned long x; + int err; + + /* tweak encrypt block i */ +#ifdef LTC_FAST + for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)&P[x]) = *((LTC_FAST_TYPE*)&C[x]) ^ *((LTC_FAST_TYPE*)&T[x]); + } +#else + for (x = 0; x < 16; x++) { + P[x] = C[x] ^ T[x]; + } +#endif + + err = cipher_descriptor[xts->cipher].ecb_decrypt(P, P, &xts->key1); + +#ifdef LTC_FAST + for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)&P[x]) ^= *((LTC_FAST_TYPE*)&T[x]); + } +#else + for (x = 0; x < 16; x++) { + P[x] = P[x] ^ T[x]; + } +#endif + + /* LFSR the tweak */ + xts_mult_x(T); + + return err; +} + +/** XTS Decryption + @param ct [in] Ciphertext + @param ptlen Length of plaintext (and ciphertext) + @param pt [out] Plaintext + @param tweak [in] The 128--bit encryption tweak (e.g. sector number) + @param xts The XTS structure + Returns CRYPT_OK upon success +*/int xts_decrypt( + const unsigned char *ct, unsigned long ptlen, + unsigned char *pt, + const unsigned char *tweak, + symmetric_xts *xts) +{ + unsigned char PP[16], CC[16], T[16]; + unsigned long i, m, mo, lim; + int err; + + /* check inputs */ + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(tweak != NULL); + LTC_ARGCHK(xts != NULL); + + /* check if valid */ + if ((err = cipher_is_valid(xts->cipher)) != CRYPT_OK) { + return err; + } + + /* get number of blocks */ + m = ptlen >> 4; + mo = ptlen & 15; + + /* must have at least one full block */ + if (m == 0) { + return CRYPT_INVALID_ARG; + } + + /* encrypt the tweak */ + if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(tweak, T, &xts->key2)) != CRYPT_OK) { + return err; + } + + /* for i = 0 to m-2 do */ + if (mo == 0) { + lim = m; + } else { + lim = m - 1; + } + + for (i = 0; i < lim; i++) { + err = tweak_uncrypt(ct, pt, T, xts); + ct += 16; + pt += 16; + } + + /* if ptlen not divide 16 then */ + if (mo > 0) { + XMEMCPY(CC, T, 16); + xts_mult_x(CC); + + /* PP = tweak decrypt block m-1 */ + if ((err = tweak_uncrypt(ct, PP, CC, xts)) != CRYPT_OK) { + return err; + } + + /* Pm = first ptlen % 16 bytes of PP */ + for (i = 0; i < mo; i++) { + CC[i] = ct[16+i]; + pt[16+i] = PP[i]; + } + for (; i < 16; i++) { + CC[i] = PP[i]; + } + + /* Pm-1 = Tweak uncrypt CC */ + if ((err = tweak_uncrypt(CC, pt, T, xts)) != CRYPT_OK) { + return err; + } + } + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/xts/xts_decrypt.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2007/05/12 14:05:56 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/xts/xts_done.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/xts/xts_done.c new file mode 100644 index 0000000000..74a9093937 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/xts/xts_done.c @@ -0,0 +1,33 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects +*/ + +#ifdef LTC_XTS_MODE + +/** Terminate XTS state + @param XTS The state to terminate +*/ +void xts_done(symmetric_xts *xts) +{ + LTC_ARGCHKVD(xts != NULL); + cipher_descriptor[xts->cipher].done(&xts->key1); + cipher_descriptor[xts->cipher].done(&xts->key2); +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/xts/xts_done.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2007/03/10 23:59:09 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/xts/xts_encrypt.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/xts/xts_encrypt.c new file mode 100644 index 0000000000..49020a9986 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/xts/xts_encrypt.c @@ -0,0 +1,141 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects +*/ + +#ifdef LTC_XTS_MODE + +static int tweak_crypt(const unsigned char *P, unsigned char *C, unsigned char *T, symmetric_xts *xts) +{ + unsigned long x; + int err; + + /* tweak encrypt block i */ +#ifdef LTC_FAST + for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)&C[x]) = *((LTC_FAST_TYPE*)&P[x]) ^ *((LTC_FAST_TYPE*)&T[x]); + } +#else + for (x = 0; x < 16; x++) { + C[x] = P[x] ^ T[x]; + } +#endif + + if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(C, C, &xts->key1)) != CRYPT_OK) { + return err; + } + +#ifdef LTC_FAST + for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)&C[x]) ^= *((LTC_FAST_TYPE*)&T[x]); + } +#else + for (x = 0; x < 16; x++) { + C[x] = C[x] ^ T[x]; + } +#endif + + /* LFSR the tweak */ + xts_mult_x(T); + + return CRYPT_OK; +} + +/** XTS Encryption + @param pt [in] Plaintext + @param ptlen Length of plaintext (and ciphertext) + @param ct [out] Ciphertext + @param tweak [in] The 128--bit encryption tweak (e.g. sector number) + @param xts The XTS structure + Returns CRYPT_OK upon success +*/ +int xts_encrypt( + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + const unsigned char *tweak, + symmetric_xts *xts) +{ + unsigned char PP[16], CC[16], T[16]; + unsigned long i, m, mo, lim; + int err; + + /* check inputs */ + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(tweak != NULL); + LTC_ARGCHK(xts != NULL); + + /* check if valid */ + if ((err = cipher_is_valid(xts->cipher)) != CRYPT_OK) { + return err; + } + + /* get number of blocks */ + m = ptlen >> 4; + mo = ptlen & 15; + + /* must have at least one full block */ + if (m == 0) { + return CRYPT_INVALID_ARG; + } + + /* encrypt the tweak */ + if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(tweak, T, &xts->key2)) != CRYPT_OK) { + return err; + } + + /* for i = 0 to m-2 do */ + if (mo == 0) { + lim = m; + } else { + lim = m - 1; + } + + for (i = 0; i < lim; i++) { + err = tweak_crypt(pt, ct, T, xts); + ct += 16; + pt += 16; + } + + /* if ptlen not divide 16 then */ + if (mo > 0) { + /* CC = tweak encrypt block m-1 */ + if ((err = tweak_crypt(pt, CC, T, xts)) != CRYPT_OK) { + return err; + } + + /* Cm = first ptlen % 16 bytes of CC */ + for (i = 0; i < mo; i++) { + PP[i] = pt[16+i]; + ct[16+i] = CC[i]; + } + + for (; i < 16; i++) { + PP[i] = CC[i]; + } + + /* Cm-1 = Tweak encrypt PP */ + if ((err = tweak_crypt(PP, ct, T, xts)) != CRYPT_OK) { + return err; + } + } + + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/xts/xts_encrypt.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2007/05/12 14:05:56 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/xts/xts_init.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/xts/xts_init.c new file mode 100644 index 0000000000..a6ddfcfd12 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/xts/xts_init.c @@ -0,0 +1,68 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects +*/ + +#ifdef LTC_XTS_MODE + + +/** Start XTS mode + @param cipher The index of the cipher to use + @param key1 The encrypt key + @param key2 The tweak encrypt key + @param keylen The length of the keys (each) in octets + @param num_rounds The number of rounds for the cipher (0 == default) + @param xts [out] XTS structure + Returns CRYPT_OK upon success. +*/ +int xts_start( int cipher, + const unsigned char *key1, + const unsigned char *key2, + unsigned long keylen, + int num_rounds, + symmetric_xts *xts) +{ + int err; + + /* check inputs */ + LTC_ARGCHK(key1 != NULL); + LTC_ARGCHK(key2 != NULL); + LTC_ARGCHK(xts != NULL); + + /* check if valid */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + if (cipher_descriptor[cipher].block_length != 16) { + return CRYPT_INVALID_ARG; + } + + /* schedule the two ciphers */ + if ((err = cipher_descriptor[cipher].setup(key1, keylen, num_rounds, &xts->key1)) != CRYPT_OK) { + return err; + } + if ((err = cipher_descriptor[cipher].setup(key2, keylen, num_rounds, &xts->key2)) != CRYPT_OK) { + return err; + } + xts->cipher = cipher; + + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/xts/xts_init.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2007/03/10 23:59:09 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/xts/xts_mult_x.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/xts/xts_mult_x.c new file mode 100644 index 0000000000..9d1185119e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/xts/xts_mult_x.c @@ -0,0 +1,41 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects +*/ + +#ifdef LTC_XTS_MODE + +/** multiply by x + @param I The value to multiply by x (LFSR shift) +*/ +void xts_mult_x(unsigned char *I) +{ + int x; + unsigned char t, tt; + + for (x = t = 0; x < 16; x++) { + tt = I[x] >> 7; + I[x] = ((I[x] << 1) | t) & 0xFF; + t = tt; + } + if (tt) { + I[0] ^= 0x87; + } +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/xts/xts_mult_x.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2007/03/10 23:59:09 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/xts/xts_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/xts/xts_test.c new file mode 100644 index 0000000000..d9b478c6e2 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/modes/xts/xts_test.c @@ -0,0 +1,198 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +#ifdef LTC_XTS_MODE + +/** + Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects + Returns CRYPT_OK upon success. +*/ +int xts_test(void) +{ +#ifdef LTC_NO_TEST + return CRYPT_NOP; +#else + static const struct { + int keylen; + unsigned char key1[32]; + unsigned char key2[32]; + ulong64 seqnum; + unsigned long PTLEN; + unsigned char PTX[512], CTX[512]; + } tests[] = { + +/* #1 32 byte key, 32 byte PTX */ +{ + 32, + { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, + { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, + 0, + 32, + { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, + { 0x91,0x7c,0xf6,0x9e,0xbd,0x68,0xb2,0xec,0x9b,0x9f,0xe9,0xa3,0xea,0xdd,0xa6,0x92,0xcd,0x43,0xd2,0xf5,0x95,0x98,0xed,0x85,0x8c,0x02,0xc2,0x65,0x2f,0xbf,0x92,0x2e }, +}, + +/* #2, 32 byte key, 32 byte PTX */ +{ + 32, + { 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11 }, + { 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22 }, + CONST64(0x3333333333), + 32, + { 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44 }, + { 0xc4,0x54,0x18,0x5e,0x6a,0x16,0x93,0x6e,0x39,0x33,0x40,0x38,0xac,0xef,0x83,0x8b,0xfb,0x18,0x6f,0xff,0x74,0x80,0xad,0xc4,0x28,0x93,0x82,0xec,0xd6,0xd3,0x94,0xf0 }, +}, + +/* #5 from xts.7, 32 byte key, 32 byte PTX */ +{ + 32, + { 0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0 }, + { 0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,0xb7,0xb6,0xb5,0xb4,0xb3,0xb2,0xb1,0xb0 }, + CONST64(0x123456789a), + 32, + { 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44 }, + { 0xb0,0x1f,0x86,0xf8,0xed,0xc1,0x86,0x37,0x06,0xfa,0x8a,0x42,0x53,0xe3,0x4f,0x28,0xaf,0x31,0x9d,0xe3,0x83,0x34,0x87,0x0f,0x4d,0xd1,0xf9,0x4c,0xbe,0x98,0x32,0xf1 }, +}, + +/* #4, 32 byte key, 512 byte PTX */ +{ + 32, + { 0x27,0x18,0x28,0x18,0x28,0x45,0x90,0x45,0x23,0x53,0x60,0x28,0x74,0x71,0x35,0x26 }, + { 0x31,0x41,0x59,0x26,0x53,0x58,0x97,0x93,0x23,0x84,0x62,0x64,0x33,0x83,0x27,0x95 }, + 0, + 512, + { +0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, +0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, +0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, +0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f, +0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, +0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf, +0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf, +0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff, +0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, +0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, +0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, +0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f, +0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, +0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf, +0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf, +0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff, + }, + { +0x27,0xa7,0x47,0x9b,0xef,0xa1,0xd4,0x76,0x48,0x9f,0x30,0x8c,0xd4,0xcf,0xa6,0xe2,0xa9,0x6e,0x4b,0xbe,0x32,0x08,0xff,0x25,0x28,0x7d,0xd3,0x81,0x96,0x16,0xe8,0x9c, +0xc7,0x8c,0xf7,0xf5,0xe5,0x43,0x44,0x5f,0x83,0x33,0xd8,0xfa,0x7f,0x56,0x00,0x00,0x05,0x27,0x9f,0xa5,0xd8,0xb5,0xe4,0xad,0x40,0xe7,0x36,0xdd,0xb4,0xd3,0x54,0x12, +0x32,0x80,0x63,0xfd,0x2a,0xab,0x53,0xe5,0xea,0x1e,0x0a,0x9f,0x33,0x25,0x00,0xa5,0xdf,0x94,0x87,0xd0,0x7a,0x5c,0x92,0xcc,0x51,0x2c,0x88,0x66,0xc7,0xe8,0x60,0xce, +0x93,0xfd,0xf1,0x66,0xa2,0x49,0x12,0xb4,0x22,0x97,0x61,0x46,0xae,0x20,0xce,0x84,0x6b,0xb7,0xdc,0x9b,0xa9,0x4a,0x76,0x7a,0xae,0xf2,0x0c,0x0d,0x61,0xad,0x02,0x65, +0x5e,0xa9,0x2d,0xc4,0xc4,0xe4,0x1a,0x89,0x52,0xc6,0x51,0xd3,0x31,0x74,0xbe,0x51,0xa1,0x0c,0x42,0x11,0x10,0xe6,0xd8,0x15,0x88,0xed,0xe8,0x21,0x03,0xa2,0x52,0xd8, +0xa7,0x50,0xe8,0x76,0x8d,0xef,0xff,0xed,0x91,0x22,0x81,0x0a,0xae,0xb9,0x9f,0x91,0x72,0xaf,0x82,0xb6,0x04,0xdc,0x4b,0x8e,0x51,0xbc,0xb0,0x82,0x35,0xa6,0xf4,0x34, +0x13,0x32,0xe4,0xca,0x60,0x48,0x2a,0x4b,0xa1,0xa0,0x3b,0x3e,0x65,0x00,0x8f,0xc5,0xda,0x76,0xb7,0x0b,0xf1,0x69,0x0d,0xb4,0xea,0xe2,0x9c,0x5f,0x1b,0xad,0xd0,0x3c, +0x5c,0xcf,0x2a,0x55,0xd7,0x05,0xdd,0xcd,0x86,0xd4,0x49,0x51,0x1c,0xeb,0x7e,0xc3,0x0b,0xf1,0x2b,0x1f,0xa3,0x5b,0x91,0x3f,0x9f,0x74,0x7a,0x8a,0xfd,0x1b,0x13,0x0e, +0x94,0xbf,0xf9,0x4e,0xff,0xd0,0x1a,0x91,0x73,0x5c,0xa1,0x72,0x6a,0xcd,0x0b,0x19,0x7c,0x4e,0x5b,0x03,0x39,0x36,0x97,0xe1,0x26,0x82,0x6f,0xb6,0xbb,0xde,0x8e,0xcc, +0x1e,0x08,0x29,0x85,0x16,0xe2,0xc9,0xed,0x03,0xff,0x3c,0x1b,0x78,0x60,0xf6,0xde,0x76,0xd4,0xce,0xcd,0x94,0xc8,0x11,0x98,0x55,0xef,0x52,0x97,0xca,0x67,0xe9,0xf3, +0xe7,0xff,0x72,0xb1,0xe9,0x97,0x85,0xca,0x0a,0x7e,0x77,0x20,0xc5,0xb3,0x6d,0xc6,0xd7,0x2c,0xac,0x95,0x74,0xc8,0xcb,0xbc,0x2f,0x80,0x1e,0x23,0xe5,0x6f,0xd3,0x44, +0xb0,0x7f,0x22,0x15,0x4b,0xeb,0xa0,0xf0,0x8c,0xe8,0x89,0x1e,0x64,0x3e,0xd9,0x95,0xc9,0x4d,0x9a,0x69,0xc9,0xf1,0xb5,0xf4,0x99,0x02,0x7a,0x78,0x57,0x2a,0xee,0xbd, +0x74,0xd2,0x0c,0xc3,0x98,0x81,0xc2,0x13,0xee,0x77,0x0b,0x10,0x10,0xe4,0xbe,0xa7,0x18,0x84,0x69,0x77,0xae,0x11,0x9f,0x7a,0x02,0x3a,0xb5,0x8c,0xca,0x0a,0xd7,0x52, +0xaf,0xe6,0x56,0xbb,0x3c,0x17,0x25,0x6a,0x9f,0x6e,0x9b,0xf1,0x9f,0xdd,0x5a,0x38,0xfc,0x82,0xbb,0xe8,0x72,0xc5,0x53,0x9e,0xdb,0x60,0x9e,0xf4,0xf7,0x9c,0x20,0x3e, +0xbb,0x14,0x0f,0x2e,0x58,0x3c,0xb2,0xad,0x15,0xb4,0xaa,0x5b,0x65,0x50,0x16,0xa8,0x44,0x92,0x77,0xdb,0xd4,0x77,0xef,0x2c,0x8d,0x6c,0x01,0x7d,0xb7,0x38,0xb1,0x8d, +0xeb,0x4a,0x42,0x7d,0x19,0x23,0xce,0x3f,0xf2,0x62,0x73,0x57,0x79,0xa4,0x18,0xf2,0x0a,0x28,0x2d,0xf9,0x20,0x14,0x7b,0xea,0xbe,0x42,0x1e,0xe5,0x31,0x9d,0x05,0x68, + } +}, + +/* #7, 32 byte key, 17 byte PTX */ +{ + 32, + { 0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0 }, + { 0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,0xb7,0xb6,0xb5,0xb4,0xb3,0xb2,0xb1,0xb0 }, + CONST64(0x123456789a), + 17, + { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10 }, + { 0x6c,0x16,0x25,0xdb,0x46,0x71,0x52,0x2d,0x3d,0x75,0x99,0x60,0x1d,0xe7,0xca,0x09,0xed }, +}, + +/* #15, 32 byte key, 25 byte PTX */ +{ + 32, + { 0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0 }, + { 0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,0xb7,0xb6,0xb5,0xb4,0xb3,0xb2,0xb1,0xb0 }, + CONST64(0x123456789a), + 25, + { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18 }, + { 0x8f,0x4d,0xcb,0xad,0x55,0x55,0x8d,0x7b,0x4e,0x01,0xd9,0x37,0x9c,0xd4,0xea,0x22,0xed,0xbf,0x9d,0xac,0xe4,0x5d,0x6f,0x6a,0x73 }, +}, + +/* #21, 32 byte key, 31 byte PTX */ +{ + 32, + { 0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0 }, + { 0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,0xb7,0xb6,0xb5,0xb4,0xb3,0xb2,0xb1,0xb0 }, + CONST64(0x123456789a), + 31, + { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e }, + { 0xd0,0x5b,0xc0,0x90,0xa8,0xe0,0x4f,0x1b,0x3d,0x3e,0xcd,0xd5,0xba,0xec,0x0f,0xd4,0xed,0xbf,0x9d,0xac,0xe4,0x5d,0x6f,0x6a,0x73,0x06,0xe6,0x4b,0xe5,0xdd,0x82 }, +}, + +}; + unsigned char OUT[512], T[16]; + ulong64 seq; + symmetric_xts xts; + int i, err, idx; + + /* AES can be under rijndael or aes... try to find it */ + if ((idx = find_cipher("aes")) == -1) { + if ((idx = find_cipher("rijndael")) == -1) { + return CRYPT_NOP; + } + } + + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { + err = xts_start(idx, tests[i].key1, tests[i].key2, tests[i].keylen/2, 0, &xts); + if (err != CRYPT_OK) { + return err; + } + + seq = tests[i].seqnum; + STORE64L(seq,T); + XMEMSET(T+8, 0, 8); + + err = xts_encrypt(tests[i].PTX, tests[i].PTLEN, OUT, T, &xts); + if (err != CRYPT_OK) { + xts_done(&xts); + return err; + } + + if (XMEMCMP(OUT, tests[i].CTX, tests[i].PTLEN)) { + xts_done(&xts); + return CRYPT_FAIL_TESTVECTOR; + } + + err = xts_decrypt(tests[i].CTX, tests[i].PTLEN, OUT, T, &xts); + if (err != CRYPT_OK) { + xts_done(&xts); + return err; + } + + if (XMEMCMP(OUT, tests[i].PTX, tests[i].PTLEN)) { + xts_done(&xts); + return CRYPT_FAIL_TESTVECTOR; + } + xts_done(&xts); + } + return CRYPT_OK; +#endif +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/modes/xts/xts_test.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2007/03/10 23:59:09 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/bit/der_decode_bit_string.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/bit/der_decode_bit_string.c new file mode 100644 index 0000000000..e72464b3fb --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/bit/der_decode_bit_string.c @@ -0,0 +1,102 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_bit_string.c + ASN.1 DER, encode a BIT STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a BIT STRING + @param in The DER encoded BIT STRING + @param inlen The size of the DER BIT STRING + @param out [out] The array of bits stored (one per char) + @param outlen [in/out] The number of bits stored + @return CRYPT_OK if successful +*/ +int der_decode_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long dlen, blen, x, y; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* packet must be at least 4 bytes */ + if (inlen < 4) { + return CRYPT_INVALID_ARG; + } + + /* check for 0x03 */ + if ((in[0]&0x1F) != 0x03) { + return CRYPT_INVALID_PACKET; + } + + /* offset in the data */ + x = 1; + + /* get the length of the data */ + if (in[x] & 0x80) { + /* long format get number of length bytes */ + y = in[x++] & 0x7F; + + /* invalid if 0 or > 2 */ + if (y == 0 || y > 2) { + return CRYPT_INVALID_PACKET; + } + + /* read the data len */ + dlen = 0; + while (y--) { + dlen = (dlen << 8) | (unsigned long)in[x++]; + } + } else { + /* short format */ + dlen = in[x++] & 0x7F; + } + + /* is the data len too long or too short? */ + if ((dlen == 0) || (dlen + x > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* get padding count */ + blen = ((dlen - 1) << 3) - (in[x++] & 7); + + /* too many bits? */ + if (blen > *outlen) { + *outlen = blen; + return CRYPT_BUFFER_OVERFLOW; + } + + /* decode/store the bits */ + for (y = 0; y < blen; y++) { + out[y] = (in[x] & (1 << (7 - (y & 7)))) ? 1 : 0; + if ((y & 7) == 7) { + ++x; + } + } + + /* we done */ + *outlen = blen; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_decode_bit_string.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/bit/der_encode_bit_string.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/bit/der_encode_bit_string.c new file mode 100644 index 0000000000..d77ea5a3d1 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/bit/der_encode_bit_string.c @@ -0,0 +1,89 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_bit_string.c + ASN.1 DER, encode a BIT STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a BIT STRING + @param in The array of bits to store (one per char) + @param inlen The number of bits tostore + @param out [out] The destination for the DER encoded BIT STRING + @param outlen [in/out] The max size and resulting size of the DER BIT STRING + @return CRYPT_OK if successful +*/ +int der_encode_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long len, x, y; + unsigned char buf; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* avoid overflows */ + if ((err = der_length_bit_string(inlen, &len)) != CRYPT_OK) { + return err; + } + + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + /* store header (include bit padding count in length) */ + x = 0; + y = (inlen >> 3) + ((inlen&7) ? 1 : 0) + 1; + + out[x++] = 0x03; + if (y < 128) { + out[x++] = (unsigned char)y; + } else if (y < 256) { + out[x++] = 0x81; + out[x++] = (unsigned char)y; + } else if (y < 65536) { + out[x++] = 0x82; + out[x++] = (unsigned char)((y>>8)&255); + out[x++] = (unsigned char)(y&255); + } + + /* store number of zero padding bits */ + out[x++] = (unsigned char)((8 - inlen) & 7); + + /* store the bits in big endian format */ + for (y = buf = 0; y < inlen; y++) { + buf |= (in[y] ? 1 : 0) << (7 - (y & 7)); + if ((y & 7) == 7) { + out[x++] = buf; + buf = 0; + } + } + /* store last byte */ + if (inlen & 7) { + out[x++] = buf; + } + *outlen = x; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_encode_bit_string.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/bit/der_length_bit_string.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/bit/der_length_bit_string.c new file mode 100644 index 0000000000..c7bfd60fbd --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/bit/der_length_bit_string.c @@ -0,0 +1,54 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_bit_string.c + ASN.1 DER, get length of BIT STRING, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Gets length of DER encoding of BIT STRING + @param nbits The number of bits in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_bit_string(unsigned long nbits, unsigned long *outlen) +{ + unsigned long nbytes; + LTC_ARGCHK(outlen != NULL); + + /* get the number of the bytes */ + nbytes = (nbits >> 3) + ((nbits & 7) ? 1 : 0) + 1; + + if (nbytes < 128) { + /* 03 LL PP DD DD DD ... */ + *outlen = 2 + nbytes; + } else if (nbytes < 256) { + /* 03 81 LL PP DD DD DD ... */ + *outlen = 3 + nbytes; + } else if (nbytes < 65536) { + /* 03 82 LL LL PP DD DD DD ... */ + *outlen = 4 + nbytes; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_length_bit_string.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/boolean/der_decode_boolean.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/boolean/der_decode_boolean.c new file mode 100644 index 0000000000..e0572290ba --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/boolean/der_decode_boolean.c @@ -0,0 +1,47 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_boolean.c + ASN.1 DER, decode a BOOLEAN, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Read a BOOLEAN + @param in The destination for the DER encoded BOOLEAN + @param inlen The size of the DER BOOLEAN + @param out [out] The boolean to decode + @return CRYPT_OK if successful +*/ +int der_decode_boolean(const unsigned char *in, unsigned long inlen, + int *out) +{ + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + + if (inlen != 3 || in[0] != 0x01 || in[1] != 0x01 || (in[2] != 0x00 && in[2] != 0xFF)) { + return CRYPT_INVALID_ARG; + } + + *out = (in[2]==0xFF) ? 1 : 0; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/boolean/der_decode_boolean.c,v $ */ +/* $Revision: 1.2 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/boolean/der_encode_boolean.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/boolean/der_encode_boolean.c new file mode 100644 index 0000000000..f169da6ae7 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/boolean/der_encode_boolean.c @@ -0,0 +1,51 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_boolean.c + ASN.1 DER, encode a BOOLEAN, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a BOOLEAN + @param in The boolean to encode + @param out [out] The destination for the DER encoded BOOLEAN + @param outlen [in/out] The max size and resulting size of the DER BOOLEAN + @return CRYPT_OK if successful +*/ +int der_encode_boolean(int in, + unsigned char *out, unsigned long *outlen) +{ + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(out != NULL); + + if (*outlen < 3) { + *outlen = 3; + return CRYPT_BUFFER_OVERFLOW; + } + + *outlen = 3; + out[0] = 0x01; + out[1] = 0x01; + out[2] = in ? 0xFF : 0x00; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/boolean/der_encode_boolean.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/boolean/der_length_boolean.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/boolean/der_length_boolean.c new file mode 100644 index 0000000000..91030b9fbf --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/boolean/der_length_boolean.c @@ -0,0 +1,35 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_boolean.c + ASN.1 DER, get length of a BOOLEAN, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Gets length of DER encoding of a BOOLEAN + @param outlen [out] The length of the DER encoding + @return CRYPT_OK if successful +*/ +int der_length_boolean(unsigned long *outlen) +{ + LTC_ARGCHK(outlen != NULL); + *outlen = 3; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/boolean/der_length_boolean.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c new file mode 100644 index 0000000000..627a6d1bd7 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c @@ -0,0 +1,182 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_choice.c + ASN.1 DER, decode a CHOICE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Decode a CHOICE + @param in The DER encoded input + @param inlen [in/out] The size of the input and resulting size of read type + @param list The list of items to decode + @param outlen The number of items in the list + @return CRYPT_OK on success +*/ +int der_decode_choice(const unsigned char *in, unsigned long *inlen, + ltc_asn1_list *list, unsigned long outlen) +{ + unsigned long size, x, z; + void *data; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen != NULL); + LTC_ARGCHK(list != NULL); + + /* get blk size */ + if (*inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* set all of the "used" flags to zero */ + for (x = 0; x < outlen; x++) { + list[x].used = 0; + } + + /* now scan until we have a winner */ + for (x = 0; x < outlen; x++) { + size = list[x].size; + data = list[x].data; + + switch (list[x].type) { + case LTC_ASN1_INTEGER: + if (der_decode_integer(in, *inlen, data) == CRYPT_OK) { + if (der_length_integer(data, &z) == CRYPT_OK) { + list[x].used = 1; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_SHORT_INTEGER: + if (der_decode_short_integer(in, *inlen, data) == CRYPT_OK) { + if (der_length_short_integer(size, &z) == CRYPT_OK) { + list[x].used = 1; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_BIT_STRING: + if (der_decode_bit_string(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_bit_string(size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_OCTET_STRING: + if (der_decode_octet_string(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_octet_string(size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_NULL: + if (*inlen == 2 && in[x] == 0x05 && in[x+1] == 0x00) { + *inlen = 2; + list[x].used = 1; + return CRYPT_OK; + } + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + if (der_decode_object_identifier(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_object_identifier(data, size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_IA5_STRING: + if (der_decode_ia5_string(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_ia5_string(data, size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + + case LTC_ASN1_PRINTABLE_STRING: + if (der_decode_printable_string(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_printable_string(data, size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_UTF8_STRING: + if (der_decode_utf8_string(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_utf8_string(data, size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_UTCTIME: + z = *inlen; + if (der_decode_utctime(in, &z, data) == CRYPT_OK) { + list[x].used = 1; + *inlen = z; + return CRYPT_OK; + } + break; + + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: + case LTC_ASN1_SEQUENCE: + if (der_decode_sequence(in, *inlen, data, size) == CRYPT_OK) { + if (der_length_sequence(data, size, &z) == CRYPT_OK) { + list[x].used = 1; + *inlen = z; + return CRYPT_OK; + } + } + break; + + default: + return CRYPT_INVALID_ARG; + } + } + + return CRYPT_INVALID_PACKET; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c,v $ */ +/* $Revision: 1.9 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/ia5/der_decode_ia5_string.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/ia5/der_decode_ia5_string.c new file mode 100644 index 0000000000..7a26767526 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/ia5/der_decode_ia5_string.c @@ -0,0 +1,96 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_ia5_string.c + ASN.1 DER, encode a IA5 STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a IA5 STRING + @param in The DER encoded IA5 STRING + @param inlen The size of the DER IA5 STRING + @param out [out] The array of octets stored (one per char) + @param outlen [in/out] The number of octets stored + @return CRYPT_OK if successful +*/ +int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int t; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* must have header at least */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check for 0x16 */ + if ((in[0] & 0x1F) != 0x16) { + return CRYPT_INVALID_PACKET; + } + x = 1; + + /* decode the length */ + if (in[x] & 0x80) { + /* valid # of bytes in length are 1,2,3 */ + y = in[x] & 0x7F; + if ((y == 0) || (y > 3) || ((x + y) > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* read the length in */ + len = 0; + ++x; + while (y--) { + len = (len << 8) | in[x++]; + } + } else { + len = in[x++] & 0x7F; + } + + /* is it too long? */ + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + if (len + x > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read the data */ + for (y = 0; y < len; y++) { + t = der_ia5_value_decode(in[x++]); + if (t == -1) { + return CRYPT_INVALID_ARG; + } + out[y] = t; + } + + *outlen = y; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/ia5/der_decode_ia5_string.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/ia5/der_encode_ia5_string.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/ia5/der_encode_ia5_string.c new file mode 100644 index 0000000000..cfbddc3b34 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/ia5/der_encode_ia5_string.c @@ -0,0 +1,85 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_ia5_string.c + ASN.1 DER, encode a IA5 STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Store an IA5 STRING + @param in The array of IA5 to store (one per char) + @param inlen The number of IA5 to store + @param out [out] The destination for the DER encoded IA5 STRING + @param outlen [in/out] The max size and resulting size of the DER IA5 STRING + @return CRYPT_OK if successful +*/ +int der_encode_ia5_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get the size */ + if ((err = der_length_ia5_string(in, inlen, &len)) != CRYPT_OK) { + return err; + } + + /* too big? */ + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + /* encode the header+len */ + x = 0; + out[x++] = 0x16; + if (inlen < 128) { + out[x++] = (unsigned char)inlen; + } else if (inlen < 256) { + out[x++] = 0x81; + out[x++] = (unsigned char)inlen; + } else if (inlen < 65536UL) { + out[x++] = 0x82; + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); + } else if (inlen < 16777216UL) { + out[x++] = 0x83; + out[x++] = (unsigned char)((inlen>>16)&255); + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); + } else { + return CRYPT_INVALID_ARG; + } + + /* store octets */ + for (y = 0; y < inlen; y++) { + out[x++] = der_ia5_char_encode(in[y]); + } + + /* retun length */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/ia5/der_encode_ia5_string.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/ia5/der_length_ia5_string.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/ia5/der_length_ia5_string.c new file mode 100644 index 0000000000..e2c3f9beda --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/ia5/der_length_ia5_string.c @@ -0,0 +1,194 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_ia5_string.c + ASN.1 DER, get length of IA5 STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +static const struct { + int code, value; +} ia5_table[] = { +{ '\0', 0 }, +{ '\a', 7 }, +{ '\b', 8 }, +{ '\t', 9 }, +{ '\n', 10 }, +{ '\f', 12 }, +{ '\r', 13 }, +{ ' ', 32 }, +{ '!', 33 }, +{ '"', 34 }, +{ '#', 35 }, +{ '$', 36 }, +{ '%', 37 }, +{ '&', 38 }, +{ '\'', 39 }, +{ '(', 40 }, +{ ')', 41 }, +{ '*', 42 }, +{ '+', 43 }, +{ ',', 44 }, +{ '-', 45 }, +{ '.', 46 }, +{ '/', 47 }, +{ '0', 48 }, +{ '1', 49 }, +{ '2', 50 }, +{ '3', 51 }, +{ '4', 52 }, +{ '5', 53 }, +{ '6', 54 }, +{ '7', 55 }, +{ '8', 56 }, +{ '9', 57 }, +{ ':', 58 }, +{ ';', 59 }, +{ '<', 60 }, +{ '=', 61 }, +{ '>', 62 }, +{ '?', 63 }, +{ '@', 64 }, +{ 'A', 65 }, +{ 'B', 66 }, +{ 'C', 67 }, +{ 'D', 68 }, +{ 'E', 69 }, +{ 'F', 70 }, +{ 'G', 71 }, +{ 'H', 72 }, +{ 'I', 73 }, +{ 'J', 74 }, +{ 'K', 75 }, +{ 'L', 76 }, +{ 'M', 77 }, +{ 'N', 78 }, +{ 'O', 79 }, +{ 'P', 80 }, +{ 'Q', 81 }, +{ 'R', 82 }, +{ 'S', 83 }, +{ 'T', 84 }, +{ 'U', 85 }, +{ 'V', 86 }, +{ 'W', 87 }, +{ 'X', 88 }, +{ 'Y', 89 }, +{ 'Z', 90 }, +{ '[', 91 }, +{ '\\', 92 }, +{ ']', 93 }, +{ '^', 94 }, +{ '_', 95 }, +{ '`', 96 }, +{ 'a', 97 }, +{ 'b', 98 }, +{ 'c', 99 }, +{ 'd', 100 }, +{ 'e', 101 }, +{ 'f', 102 }, +{ 'g', 103 }, +{ 'h', 104 }, +{ 'i', 105 }, +{ 'j', 106 }, +{ 'k', 107 }, +{ 'l', 108 }, +{ 'm', 109 }, +{ 'n', 110 }, +{ 'o', 111 }, +{ 'p', 112 }, +{ 'q', 113 }, +{ 'r', 114 }, +{ 's', 115 }, +{ 't', 116 }, +{ 'u', 117 }, +{ 'v', 118 }, +{ 'w', 119 }, +{ 'x', 120 }, +{ 'y', 121 }, +{ 'z', 122 }, +{ '{', 123 }, +{ '|', 124 }, +{ '}', 125 }, +{ '~', 126 } +}; + +int der_ia5_char_encode(int c) +{ + int x; + for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) { + if (ia5_table[x].code == c) { + return ia5_table[x].value; + } + } + return -1; +} + +int der_ia5_value_decode(int v) +{ + int x; + for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) { + if (ia5_table[x].value == v) { + return ia5_table[x].code; + } + } + return -1; +} + +/** + Gets length of DER encoding of IA5 STRING + @param octets The values you want to encode + @param noctets The number of octets in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen) +{ + unsigned long x; + + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(octets != NULL); + + /* scan string for validity */ + for (x = 0; x < noctets; x++) { + if (der_ia5_char_encode(octets[x]) == -1) { + return CRYPT_INVALID_ARG; + } + } + + if (noctets < 128) { + /* 16 LL DD DD DD ... */ + *outlen = 2 + noctets; + } else if (noctets < 256) { + /* 16 81 LL DD DD DD ... */ + *outlen = 3 + noctets; + } else if (noctets < 65536UL) { + /* 16 82 LL LL DD DD DD ... */ + *outlen = 4 + noctets; + } else if (noctets < 16777216UL) { + /* 16 83 LL LL LL DD DD DD ... */ + *outlen = 5 + noctets; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/ia5/der_length_ia5_string.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c new file mode 100644 index 0000000000..e126118a65 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c @@ -0,0 +1,110 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_integer.c + ASN.1 DER, decode an integer, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Read a mp_int integer + @param in The DER encoded data + @param inlen Size of DER encoded data + @param num The first mp_int to decode + @return CRYPT_OK if successful +*/ +int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num) +{ + unsigned long x, y, z; + int err; + + LTC_ARGCHK(num != NULL); + LTC_ARGCHK(in != NULL); + + /* min DER INTEGER is 0x02 01 00 == 0 */ + if (inlen < (1 + 1 + 1)) { + return CRYPT_INVALID_PACKET; + } + + /* ok expect 0x02 when we AND with 0001 1111 [1F] */ + x = 0; + if ((in[x++] & 0x1F) != 0x02) { + return CRYPT_INVALID_PACKET; + } + + /* now decode the len stuff */ + z = in[x++]; + + if ((z & 0x80) == 0x00) { + /* short form */ + + /* will it overflow? */ + if (x + z > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* no so read it */ + if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, z)) != CRYPT_OK) { + return err; + } + } else { + /* long form */ + z &= 0x7F; + + /* will number of length bytes overflow? (or > 4) */ + if (((x + z) > inlen) || (z > 4) || (z == 0)) { + return CRYPT_INVALID_PACKET; + } + + /* now read it in */ + y = 0; + while (z--) { + y = ((unsigned long)(in[x++])) | (y << 8); + } + + /* now will reading y bytes overrun? */ + if ((x + y) > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* no so read it */ + if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, y)) != CRYPT_OK) { + return err; + } + } + + /* see if it's negative */ + if (in[x] & 0x80) { + void *tmp; + if (mp_init(&tmp) != CRYPT_OK) { + return CRYPT_MEM; + } + + if (mp_2expt(tmp, mp_count_bits(num)) != CRYPT_OK || mp_sub(num, tmp, num) != CRYPT_OK) { + mp_clear(tmp); + return CRYPT_MEM; + } + mp_clear(tmp); + } + + return CRYPT_OK; + +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/integer/der_encode_integer.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/integer/der_encode_integer.c new file mode 100644 index 0000000000..3ead07a289 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/integer/der_encode_integer.c @@ -0,0 +1,130 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_integer.c + ASN.1 DER, encode an integer, Tom St Denis +*/ + + +#ifdef LTC_DER + +/* Exports a positive bignum as DER format (upto 2^32 bytes in size) */ +/** + Store a mp_int integer + @param num The first mp_int to encode + @param out [out] The destination for the DER encoded integers + @param outlen [in/out] The max size and resulting size of the DER encoded integers + @return CRYPT_OK if successful +*/ +int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen) +{ + unsigned long tmplen, y; + int err, leading_zero; + + LTC_ARGCHK(num != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* find out how big this will be */ + if ((err = der_length_integer(num, &tmplen)) != CRYPT_OK) { + return err; + } + + if (*outlen < tmplen) { + *outlen = tmplen; + return CRYPT_BUFFER_OVERFLOW; + } + + if (mp_cmp_d(num, 0) != LTC_MP_LT) { + /* we only need a leading zero if the msb of the first byte is one */ + if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == LTC_MP_YES) { + leading_zero = 1; + } else { + leading_zero = 0; + } + + /* get length of num in bytes (plus 1 since we force the msbyte to zero) */ + y = mp_unsigned_bin_size(num) + leading_zero; + } else { + leading_zero = 0; + y = mp_count_bits(num); + y = y + (8 - (y & 7)); + y = y >> 3; + if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --y; + } + + /* now store initial data */ + *out++ = 0x02; + if (y < 128) { + /* short form */ + *out++ = (unsigned char)y; + } else if (y < 256) { + *out++ = 0x81; + *out++ = (unsigned char)y; + } else if (y < 65536UL) { + *out++ = 0x82; + *out++ = (unsigned char)((y>>8)&255); + *out++ = (unsigned char)y; + } else if (y < 16777216UL) { + *out++ = 0x83; + *out++ = (unsigned char)((y>>16)&255); + *out++ = (unsigned char)((y>>8)&255); + *out++ = (unsigned char)y; + } else { + return CRYPT_INVALID_ARG; + } + + /* now store msbyte of zero if num is non-zero */ + if (leading_zero) { + *out++ = 0x00; + } + + /* if it's not zero store it as big endian */ + if (mp_cmp_d(num, 0) == LTC_MP_GT) { + /* now store the mpint */ + if ((err = mp_to_unsigned_bin(num, out)) != CRYPT_OK) { + return err; + } + } else if (mp_iszero(num) != LTC_MP_YES) { + void *tmp; + + /* negative */ + if (mp_init(&tmp) != CRYPT_OK) { + return CRYPT_MEM; + } + + /* 2^roundup and subtract */ + y = mp_count_bits(num); + y = y + (8 - (y & 7)); + if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) y -= 8; + if (mp_2expt(tmp, y) != CRYPT_OK || mp_add(tmp, num, tmp) != CRYPT_OK) { + mp_clear(tmp); + return CRYPT_MEM; + } + if ((err = mp_to_unsigned_bin(tmp, out)) != CRYPT_OK) { + mp_clear(tmp); + return err; + } + mp_clear(tmp); + } + + /* we good */ + *outlen = tmplen; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_encode_integer.c,v $ */ +/* $Revision: 1.9 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/integer/der_length_integer.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/integer/der_length_integer.c new file mode 100644 index 0000000000..cb07bfbf28 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/integer/der_length_integer.c @@ -0,0 +1,82 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_integer.c + ASN.1 DER, get length of encoding, Tom St Denis +*/ + + +#ifdef LTC_DER +/** + Gets length of DER encoding of num + @param num The int to get the size of + @param outlen [out] The length of the DER encoding for the given integer + @return CRYPT_OK if successful +*/ +int der_length_integer(void *num, unsigned long *outlen) +{ + unsigned long z, len; + int leading_zero; + + LTC_ARGCHK(num != NULL); + LTC_ARGCHK(outlen != NULL); + + if (mp_cmp_d(num, 0) != LTC_MP_LT) { + /* positive */ + + /* we only need a leading zero if the msb of the first byte is one */ + if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == LTC_MP_YES) { + leading_zero = 1; + } else { + leading_zero = 0; + } + + /* size for bignum */ + z = len = leading_zero + mp_unsigned_bin_size(num); + } else { + /* it's negative */ + /* find power of 2 that is a multiple of eight and greater than count bits */ + leading_zero = 0; + z = mp_count_bits(num); + z = z + (8 - (z & 7)); + if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --z; + len = z = z >> 3; + } + + /* now we need a length */ + if (z < 128) { + /* short form */ + ++len; + } else { + /* long form (relies on z != 0), assumes length bytes < 128 */ + ++len; + + while (z) { + ++len; + z >>= 8; + } + } + + /* we need a 0x02 to indicate it's INTEGER */ + ++len; + + /* return length */ + *outlen = len; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_length_integer.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c new file mode 100644 index 0000000000..6e1e428755 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c @@ -0,0 +1,99 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_object_identifier.c + ASN.1 DER, Decode Object Identifier, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Decode OID data and store the array of integers in words + @param in The OID DER encoded data + @param inlen The length of the OID data + @param words [out] The destination of the OID words + @param outlen [in/out] The number of OID words + @return CRYPT_OK if successful +*/ +int der_decode_object_identifier(const unsigned char *in, unsigned long inlen, + unsigned long *words, unsigned long *outlen) +{ + unsigned long x, y, t, len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(words != NULL); + LTC_ARGCHK(outlen != NULL); + + /* header is at least 3 bytes */ + if (inlen < 3) { + return CRYPT_INVALID_PACKET; + } + + /* must be room for at least two words */ + if (*outlen < 2) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* decode the packet header */ + x = 0; + if ((in[x++] & 0x1F) != 0x06) { + return CRYPT_INVALID_PACKET; + } + + /* get the length */ + if (in[x] < 128) { + len = in[x++]; + } else { + if (in[x] < 0x81 || in[x] > 0x82) { + return CRYPT_INVALID_PACKET; + } + y = in[x++] & 0x7F; + len = 0; + while (y--) { + len = (len << 8) | (unsigned long)in[x++]; + } + } + + if (len < 1 || (len + x) > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* decode words */ + y = 0; + t = 0; + while (len--) { + t = (t << 7) | (in[x] & 0x7F); + if (!(in[x++] & 0x80)) { + /* store t */ + if (y >= *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + if (y == 0) { + words[0] = t / 40; + words[1] = t % 40; + y = 2; + } else { + words[y++] = t; + } + t = 0; + } + } + + *outlen = y; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c new file mode 100644 index 0000000000..6a1ff8b621 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c @@ -0,0 +1,111 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_object_identifier.c + ASN.1 DER, Encode Object Identifier, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Encode an OID + @param words The words to encode (upto 32-bits each) + @param nwords The number of words in the OID + @param out [out] Destination of OID data + @param outlen [in/out] The max and resulting size of the OID + @return CRYPT_OK if successful +*/ +int der_encode_object_identifier(unsigned long *words, unsigned long nwords, + unsigned char *out, unsigned long *outlen) +{ + unsigned long i, x, y, z, t, mask, wordbuf; + int err; + + LTC_ARGCHK(words != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* check length */ + if ((err = der_length_object_identifier(words, nwords, &x)) != CRYPT_OK) { + return err; + } + if (x > *outlen) { + *outlen = x; + return CRYPT_BUFFER_OVERFLOW; + } + + /* compute length to store OID data */ + z = 0; + wordbuf = words[0] * 40 + words[1]; + for (y = 1; y < nwords; y++) { + t = der_object_identifier_bits(wordbuf); + z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0); + if (y < nwords - 1) { + wordbuf = words[y + 1]; + } + } + + /* store header + length */ + x = 0; + out[x++] = 0x06; + if (z < 128) { + out[x++] = (unsigned char)z; + } else if (z < 256) { + out[x++] = 0x81; + out[x++] = (unsigned char)z; + } else if (z < 65536UL) { + out[x++] = 0x82; + out[x++] = (unsigned char)((z>>8)&255); + out[x++] = (unsigned char)(z&255); + } else { + return CRYPT_INVALID_ARG; + } + + /* store first byte */ + wordbuf = words[0] * 40 + words[1]; + for (i = 1; i < nwords; i++) { + /* store 7 bit words in little endian */ + t = wordbuf & 0xFFFFFFFF; + if (t) { + y = x; + mask = 0; + while (t) { + out[x++] = (unsigned char)((t & 0x7F) | mask); + t >>= 7; + mask |= 0x80; /* upper bit is set on all but the last byte */ + } + /* now swap bytes y...x-1 */ + z = x - 1; + while (y < z) { + t = out[y]; out[y] = out[z]; out[z] = (unsigned char)t; + ++y; + --z; + } + } else { + /* zero word */ + out[x++] = 0x00; + } + + if (i < nwords - 1) { + wordbuf = words[i + 1]; + } + } + + *outlen = x; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/object_identifier/der_length_object_identifier.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/object_identifier/der_length_object_identifier.c new file mode 100644 index 0000000000..5dbef5dce6 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/object_identifier/der_length_object_identifier.c @@ -0,0 +1,89 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_object_identifier.c + ASN.1 DER, get length of Object Identifier, Tom St Denis +*/ + +#ifdef LTC_DER + +unsigned long der_object_identifier_bits(unsigned long x) +{ + unsigned long c; + x &= 0xFFFFFFFF; + c = 0; + while (x) { + ++c; + x >>= 1; + } + return c; +} + + +/** + Gets length of DER encoding of Object Identifier + @param nwords The number of OID words + @param words The actual OID words to get the size of + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen) +{ + unsigned long y, z, t, wordbuf; + + LTC_ARGCHK(words != NULL); + LTC_ARGCHK(outlen != NULL); + + + /* must be >= 2 words */ + if (nwords < 2) { + return CRYPT_INVALID_ARG; + } + + /* word1 = 0,1,2,3 and word2 0..39 */ + if (words[0] > 3 || (words[0] < 2 && words[1] > 39)) { + return CRYPT_INVALID_ARG; + } + + /* leading word is the first two */ + z = 0; + wordbuf = words[0] * 40 + words[1]; + for (y = 1; y < nwords; y++) { + t = der_object_identifier_bits(wordbuf); + z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0); + if (y < nwords - 1) { + /* grab next word */ + wordbuf = words[y+1]; + } + } + + /* now depending on the length our length encoding changes */ + if (z < 128) { + z += 2; + } else if (z < 256) { + z += 3; + } else if (z < 65536UL) { + z += 4; + } else { + return CRYPT_INVALID_ARG; + } + + *outlen = z; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/object_identifier/der_length_object_identifier.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/octet/der_decode_octet_string.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/octet/der_decode_octet_string.c new file mode 100644 index 0000000000..f542a063ad --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/octet/der_decode_octet_string.c @@ -0,0 +1,91 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_octet_string.c + ASN.1 DER, encode a OCTET STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a OCTET STRING + @param in The DER encoded OCTET STRING + @param inlen The size of the DER OCTET STRING + @param out [out] The array of octets stored (one per char) + @param outlen [in/out] The number of octets stored + @return CRYPT_OK if successful +*/ +int der_decode_octet_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* must have header at least */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check for 0x04 */ + if ((in[0] & 0x1F) != 0x04) { + return CRYPT_INVALID_PACKET; + } + x = 1; + + /* decode the length */ + if (in[x] & 0x80) { + /* valid # of bytes in length are 1,2,3 */ + y = in[x] & 0x7F; + if ((y == 0) || (y > 3) || ((x + y) > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* read the length in */ + len = 0; + ++x; + while (y--) { + len = (len << 8) | in[x++]; + } + } else { + len = in[x++] & 0x7F; + } + + /* is it too long? */ + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + if (len + x > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read the data */ + for (y = 0; y < len; y++) { + out[y] = in[x++]; + } + + *outlen = y; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/octet/der_decode_octet_string.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/octet/der_encode_octet_string.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/octet/der_encode_octet_string.c new file mode 100644 index 0000000000..d2d95c851e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/octet/der_encode_octet_string.c @@ -0,0 +1,86 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_octet_string.c + ASN.1 DER, encode a OCTET STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store an OCTET STRING + @param in The array of OCTETS to store (one per char) + @param inlen The number of OCTETS to store + @param out [out] The destination for the DER encoded OCTET STRING + @param outlen [in/out] The max size and resulting size of the DER OCTET STRING + @return CRYPT_OK if successful +*/ +int der_encode_octet_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get the size */ + if ((err = der_length_octet_string(inlen, &len)) != CRYPT_OK) { + return err; + } + + /* too big? */ + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + /* encode the header+len */ + x = 0; + out[x++] = 0x04; + if (inlen < 128) { + out[x++] = (unsigned char)inlen; + } else if (inlen < 256) { + out[x++] = 0x81; + out[x++] = (unsigned char)inlen; + } else if (inlen < 65536UL) { + out[x++] = 0x82; + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); + } else if (inlen < 16777216UL) { + out[x++] = 0x83; + out[x++] = (unsigned char)((inlen>>16)&255); + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); + } else { + return CRYPT_INVALID_ARG; + } + + /* store octets */ + for (y = 0; y < inlen; y++) { + out[x++] = in[y]; + } + + /* retun length */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/octet/der_encode_octet_string.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/octet/der_length_octet_string.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/octet/der_length_octet_string.c new file mode 100644 index 0000000000..0ab6f7021a --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/octet/der_length_octet_string.c @@ -0,0 +1,53 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_octet_string.c + ASN.1 DER, get length of OCTET STRING, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Gets length of DER encoding of OCTET STRING + @param noctets The number of octets in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_octet_string(unsigned long noctets, unsigned long *outlen) +{ + LTC_ARGCHK(outlen != NULL); + + if (noctets < 128) { + /* 04 LL DD DD DD ... */ + *outlen = 2 + noctets; + } else if (noctets < 256) { + /* 04 81 LL DD DD DD ... */ + *outlen = 3 + noctets; + } else if (noctets < 65536UL) { + /* 04 82 LL LL DD DD DD ... */ + *outlen = 4 + noctets; + } else if (noctets < 16777216UL) { + /* 04 83 LL LL LL DD DD DD ... */ + *outlen = 5 + noctets; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/octet/der_length_octet_string.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/printable_string/der_decode_printable_string.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/printable_string/der_decode_printable_string.c new file mode 100644 index 0000000000..c7798446cd --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/printable_string/der_decode_printable_string.c @@ -0,0 +1,96 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_printable_string.c + ASN.1 DER, encode a printable STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a printable STRING + @param in The DER encoded printable STRING + @param inlen The size of the DER printable STRING + @param out [out] The array of octets stored (one per char) + @param outlen [in/out] The number of octets stored + @return CRYPT_OK if successful +*/ +int der_decode_printable_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int t; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* must have header at least */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check for 0x13 */ + if ((in[0] & 0x1F) != 0x13) { + return CRYPT_INVALID_PACKET; + } + x = 1; + + /* decode the length */ + if (in[x] & 0x80) { + /* valid # of bytes in length are 1,2,3 */ + y = in[x] & 0x7F; + if ((y == 0) || (y > 3) || ((x + y) > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* read the length in */ + len = 0; + ++x; + while (y--) { + len = (len << 8) | in[x++]; + } + } else { + len = in[x++] & 0x7F; + } + + /* is it too long? */ + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + if (len + x > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read the data */ + for (y = 0; y < len; y++) { + t = der_printable_value_decode(in[x++]); + if (t == -1) { + return CRYPT_INVALID_ARG; + } + out[y] = t; + } + + *outlen = y; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/printable_string/der_decode_printable_string.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/printable_string/der_encode_printable_string.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/printable_string/der_encode_printable_string.c new file mode 100644 index 0000000000..918ada7c2f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/printable_string/der_encode_printable_string.c @@ -0,0 +1,85 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_printable_string.c + ASN.1 DER, encode a printable STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Store an printable STRING + @param in The array of printable to store (one per char) + @param inlen The number of printable to store + @param out [out] The destination for the DER encoded printable STRING + @param outlen [in/out] The max size and resulting size of the DER printable STRING + @return CRYPT_OK if successful +*/ +int der_encode_printable_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get the size */ + if ((err = der_length_printable_string(in, inlen, &len)) != CRYPT_OK) { + return err; + } + + /* too big? */ + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + /* encode the header+len */ + x = 0; + out[x++] = 0x13; + if (inlen < 128) { + out[x++] = (unsigned char)inlen; + } else if (inlen < 256) { + out[x++] = 0x81; + out[x++] = (unsigned char)inlen; + } else if (inlen < 65536UL) { + out[x++] = 0x82; + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); + } else if (inlen < 16777216UL) { + out[x++] = 0x83; + out[x++] = (unsigned char)((inlen>>16)&255); + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); + } else { + return CRYPT_INVALID_ARG; + } + + /* store octets */ + for (y = 0; y < inlen; y++) { + out[x++] = der_printable_char_encode(in[y]); + } + + /* retun length */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/printable_string/der_encode_printable_string.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/printable_string/der_length_printable_string.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/printable_string/der_length_printable_string.c new file mode 100644 index 0000000000..4957ece181 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/printable_string/der_length_printable_string.c @@ -0,0 +1,166 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_printable_string.c + ASN.1 DER, get length of Printable STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +static const struct { + int code, value; +} printable_table[] = { +{ ' ', 32 }, +{ '\'', 39 }, +{ '(', 40 }, +{ ')', 41 }, +{ '+', 43 }, +{ ',', 44 }, +{ '-', 45 }, +{ '.', 46 }, +{ '/', 47 }, +{ '0', 48 }, +{ '1', 49 }, +{ '2', 50 }, +{ '3', 51 }, +{ '4', 52 }, +{ '5', 53 }, +{ '6', 54 }, +{ '7', 55 }, +{ '8', 56 }, +{ '9', 57 }, +{ ':', 58 }, +{ '=', 61 }, +{ '?', 63 }, +{ 'A', 65 }, +{ 'B', 66 }, +{ 'C', 67 }, +{ 'D', 68 }, +{ 'E', 69 }, +{ 'F', 70 }, +{ 'G', 71 }, +{ 'H', 72 }, +{ 'I', 73 }, +{ 'J', 74 }, +{ 'K', 75 }, +{ 'L', 76 }, +{ 'M', 77 }, +{ 'N', 78 }, +{ 'O', 79 }, +{ 'P', 80 }, +{ 'Q', 81 }, +{ 'R', 82 }, +{ 'S', 83 }, +{ 'T', 84 }, +{ 'U', 85 }, +{ 'V', 86 }, +{ 'W', 87 }, +{ 'X', 88 }, +{ 'Y', 89 }, +{ 'Z', 90 }, +{ 'a', 97 }, +{ 'b', 98 }, +{ 'c', 99 }, +{ 'd', 100 }, +{ 'e', 101 }, +{ 'f', 102 }, +{ 'g', 103 }, +{ 'h', 104 }, +{ 'i', 105 }, +{ 'j', 106 }, +{ 'k', 107 }, +{ 'l', 108 }, +{ 'm', 109 }, +{ 'n', 110 }, +{ 'o', 111 }, +{ 'p', 112 }, +{ 'q', 113 }, +{ 'r', 114 }, +{ 's', 115 }, +{ 't', 116 }, +{ 'u', 117 }, +{ 'v', 118 }, +{ 'w', 119 }, +{ 'x', 120 }, +{ 'y', 121 }, +{ 'z', 122 }, +}; + +int der_printable_char_encode(int c) +{ + int x; + for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) { + if (printable_table[x].code == c) { + return printable_table[x].value; + } + } + return -1; +} + +int der_printable_value_decode(int v) +{ + int x; + for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) { + if (printable_table[x].value == v) { + return printable_table[x].code; + } + } + return -1; +} + +/** + Gets length of DER encoding of Printable STRING + @param octets The values you want to encode + @param noctets The number of octets in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen) +{ + unsigned long x; + + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(octets != NULL); + + /* scan string for validity */ + for (x = 0; x < noctets; x++) { + if (der_printable_char_encode(octets[x]) == -1) { + return CRYPT_INVALID_ARG; + } + } + + if (noctets < 128) { + /* 16 LL DD DD DD ... */ + *outlen = 2 + noctets; + } else if (noctets < 256) { + /* 16 81 LL DD DD DD ... */ + *outlen = 3 + noctets; + } else if (noctets < 65536UL) { + /* 16 82 LL LL DD DD DD ... */ + *outlen = 4 + noctets; + } else if (noctets < 16777216UL) { + /* 16 83 LL LL LL DD DD DD ... */ + *outlen = 5 + noctets; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/printable_string/der_length_printable_string.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_ex.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_ex.c new file mode 100644 index 0000000000..5c46adcca3 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_ex.c @@ -0,0 +1,287 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" +#include + + +/** + @file der_decode_sequence_ex.c + ASN.1 DER, decode a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Decode a SEQUENCE + @param in The DER encoded input + @param inlen The size of the input + @param list The list of items to decode + @param outlen The number of items in the list + @param ordered Search an unordeded or ordered list + @return CRYPT_OK on success +*/ +int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, + ltc_asn1_list *list, unsigned long outlen, int ordered) +{ + int err, type; + unsigned long size, x, y, z, i, blksize; + void *data; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(list != NULL); + + /* get blk size */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* sequence type? We allow 0x30 SEQUENCE and 0x31 SET since fundamentally they're the same structure */ + x = 0; + if (in[x] != 0x30 && in[x] != 0x31) { + return CRYPT_INVALID_PACKET; + } + ++x; + + if (in[x] < 128) { + blksize = in[x++]; + } else if (in[x] & 0x80) { + if (in[x] < 0x81 || in[x] > 0x83) { + return CRYPT_INVALID_PACKET; + } + y = in[x++] & 0x7F; + + /* would reading the len bytes overrun? */ + if (x + y > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read len */ + blksize = 0; + while (y--) { + blksize = (blksize << 8) | (unsigned long)in[x++]; + } + } + + /* would this blksize overflow? */ + if (x + blksize > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* mark all as unused */ + for (i = 0; i < outlen; i++) { + list[i].used = 0; + } + + /* ok read data */ + inlen = blksize; + for (i = 0; i < outlen; i++) { + z = 0; + type = list[i].type; + size = list[i].size; + data = list[i].data; + if (!ordered && list[i].used == 1) { continue; } + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + z = inlen; + if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = der_length_boolean(&z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_INTEGER: + z = inlen; + if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + if ((err = der_length_integer(data, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_SHORT_INTEGER: + z = inlen; + if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) { + goto LBL_ERR; + } + + break; + + case LTC_ASN1_BIT_STRING: + z = inlen; + if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_OCTET_STRING: + z = inlen; + if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_octet_string(size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_NULL: + if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) { + if (!ordered) { continue; } + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + z = 2; + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + z = inlen; + if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_IA5_STRING: + z = inlen; + if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_ia5_string(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + + case LTC_ASN1_PRINTABLE_STRING: + z = inlen; + if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_printable_string(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_UTF8_STRING: + z = inlen; + if ((err = der_decode_utf8_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_utf8_string(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_UTCTIME: + z = inlen; + if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + break; + + case LTC_ASN1_SET: + z = inlen; + if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_SETOF: + case LTC_ASN1_SEQUENCE: + /* detect if we have the right type */ + if ((type == LTC_ASN1_SETOF && (in[x] & 0x3F) != 0x31) || (type == LTC_ASN1_SEQUENCE && (in[x] & 0x3F) != 0x30)) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + z = inlen; + if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + + case LTC_ASN1_CHOICE: + z = inlen; + if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + break; + + default: + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + x += z; + inlen -= z; + list[i].used = 1; + if (!ordered) { + /* restart the decoder */ + i = -1; + } + } + + for (i = 0; i < outlen; i++) { + if (list[i].used == 0) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + } + err = CRYPT_OK; + +LBL_ERR: + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_ex.c,v $ */ +/* $Revision: 1.16 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_flexi.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_flexi.c new file mode 100644 index 0000000000..d175d1e531 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_flexi.c @@ -0,0 +1,386 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_sequence_flexi.c + ASN.1 DER, decode an array of ASN.1 types with a flexi parser, Tom St Denis +*/ + +#ifdef LTC_DER + +static unsigned long fetch_length(const unsigned char *in, unsigned long inlen) +{ + unsigned long x, y, z; + + y = 0; + + /* skip type and read len */ + if (inlen < 2) { + return 0xFFFFFFFF; + } + ++in; ++y; + + /* read len */ + x = *in++; ++y; + + /* <128 means literal */ + if (x < 128) { + return x+y; + } + x &= 0x7F; /* the lower 7 bits are the length of the length */ + inlen -= 2; + + /* len means len of len! */ + if (x == 0 || x > 4 || x > inlen) { + return 0xFFFFFFFF; + } + + y += x; + z = 0; + while (x--) { + z = (z<<8) | ((unsigned long)*in); + ++in; + } + return z+y; +} + +/** + ASN.1 DER Flexi(ble) decoder will decode arbitrary DER packets and create a linked list of the decoded elements. + @param in The input buffer + @param inlen [in/out] The length of the input buffer and on output the amount of decoded data + @param out [out] A pointer to the linked list + @return CRYPT_OK on success. +*/ +int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out) +{ + ltc_asn1_list *l; + unsigned long err, type, len, totlen, x, y; + void *realloc_tmp; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen != NULL); + LTC_ARGCHK(out != NULL); + + l = NULL; + totlen = 0; + + /* scan the input and and get lengths and what not */ + while (*inlen) { + /* read the type byte */ + type = *in; + + /* fetch length */ + len = fetch_length(in, *inlen); + if (len > *inlen) { + err = CRYPT_INVALID_PACKET; + goto error; + } + + /* alloc new link */ + if (l == NULL) { + l = XCALLOC(1, sizeof(*l)); + if (l == NULL) { + err = CRYPT_MEM; + goto error; + } + } else { + l->next = XCALLOC(1, sizeof(*l)); + if (l->next == NULL) { + err = CRYPT_MEM; + goto error; + } + l->next->prev = l; + l = l->next; + } + + /* now switch on type */ + switch (type) { + case 0x01: /* BOOLEAN */ + l->type = LTC_ASN1_BOOLEAN; + l->size = 1; + l->data = XCALLOC(1, sizeof(int)); + + if ((err = der_decode_boolean(in, *inlen, l->data)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_boolean(&len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x02: /* INTEGER */ + /* init field */ + l->type = LTC_ASN1_INTEGER; + l->size = 1; + if ((err = mp_init(&l->data)) != CRYPT_OK) { + goto error; + } + + /* decode field */ + if ((err = der_decode_integer(in, *inlen, l->data)) != CRYPT_OK) { + goto error; + } + + /* calc length of object */ + if ((err = der_length_integer(l->data, &len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x03: /* BIT */ + /* init field */ + l->type = LTC_ASN1_BIT_STRING; + l->size = len * 8; /* *8 because we store decoded bits one per char and they are encoded 8 per char. */ + + if ((l->data = XCALLOC(1, l->size)) == NULL) { + err = CRYPT_MEM; + goto error; + } + + if ((err = der_decode_bit_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_bit_string(l->size, &len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x04: /* OCTET */ + + /* init field */ + l->type = LTC_ASN1_OCTET_STRING; + l->size = len; + + if ((l->data = XCALLOC(1, l->size)) == NULL) { + err = CRYPT_MEM; + goto error; + } + + if ((err = der_decode_octet_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_octet_string(l->size, &len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x05: /* NULL */ + + /* valid NULL is 0x05 0x00 */ + if (in[0] != 0x05 || in[1] != 0x00) { + err = CRYPT_INVALID_PACKET; + goto error; + } + + /* simple to store ;-) */ + l->type = LTC_ASN1_NULL; + l->data = NULL; + l->size = 0; + len = 2; + + break; + + case 0x06: /* OID */ + + /* init field */ + l->type = LTC_ASN1_OBJECT_IDENTIFIER; + l->size = len; + + if ((l->data = XCALLOC(len, sizeof(unsigned long))) == NULL) { + err = CRYPT_MEM; + goto error; + } + + if ((err = der_decode_object_identifier(in, *inlen, l->data, &l->size)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_object_identifier(l->data, l->size, &len)) != CRYPT_OK) { + goto error; + } + + /* resize it to save a bunch of mem */ + if ((realloc_tmp = XREALLOC(l->data, l->size * sizeof(unsigned long))) == NULL) { + /* out of heap but this is not an error */ + break; + } + l->data = realloc_tmp; + break; + + case 0x0C: /* UTF8 */ + + /* init field */ + l->type = LTC_ASN1_UTF8_STRING; + l->size = len; + + if ((l->data = XCALLOC(sizeof(wchar_t), l->size)) == NULL) { + err = CRYPT_MEM; + goto error; + } + + if ((err = der_decode_utf8_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_utf8_string(l->data, l->size, &len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x13: /* PRINTABLE */ + + /* init field */ + l->type = LTC_ASN1_PRINTABLE_STRING; + l->size = len; + + if ((l->data = XCALLOC(1, l->size)) == NULL) { + err = CRYPT_MEM; + goto error; + } + + if ((err = der_decode_printable_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_printable_string(l->data, l->size, &len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x16: /* IA5 */ + + /* init field */ + l->type = LTC_ASN1_IA5_STRING; + l->size = len; + + if ((l->data = XCALLOC(1, l->size)) == NULL) { + err = CRYPT_MEM; + goto error; + } + + if ((err = der_decode_ia5_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_ia5_string(l->data, l->size, &len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x17: /* UTC TIME */ + + /* init field */ + l->type = LTC_ASN1_UTCTIME; + l->size = 1; + + if ((l->data = XCALLOC(1, sizeof(ltc_utctime))) == NULL) { + err = CRYPT_MEM; + goto error; + } + + len = *inlen; + if ((err = der_decode_utctime(in, &len, l->data)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_utctime(l->data, &len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x30: /* SEQUENCE */ + case 0x31: /* SET */ + + /* init field */ + l->type = (type == 0x30) ? LTC_ASN1_SEQUENCE : LTC_ASN1_SET; + + /* we have to decode the SEQUENCE header and get it's length */ + + /* move past type */ + ++in; --(*inlen); + + /* read length byte */ + x = *in++; --(*inlen); + + /* smallest SEQUENCE/SET header */ + y = 2; + + /* now if it's > 127 the next bytes are the length of the length */ + if (x > 128) { + x &= 0x7F; + in += x; + *inlen -= x; + + /* update sequence header len */ + y += x; + } + + /* Sequence elements go as child */ + len = len - y; + if ((err = der_decode_sequence_flexi(in, &len, &(l->child))) != CRYPT_OK) { + goto error; + } + + /* len update */ + totlen += y; + + /* link them up y0 */ + l->child->parent = l; + + break; + default: + /* invalid byte ... this is a soft error */ + /* remove link */ + l = l->prev; + XFREE(l->next); + l->next = NULL; + goto outside; + } + + /* advance pointers */ + totlen += len; + in += len; + *inlen -= len; + } + +outside: + + /* rewind l please */ + while (l->prev != NULL || l->parent != NULL) { + if (l->parent != NULL) { + l = l->parent; + } else { + l = l->prev; + } + } + + /* return */ + *out = l; + *inlen = totlen; + return CRYPT_OK; + +error: + /* free list */ + der_sequence_free(l); + + return err; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_flexi.c,v $ */ +/* $Revision: 1.26 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_multi.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_multi.c new file mode 100644 index 0000000000..235420498a --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_multi.c @@ -0,0 +1,139 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" +#include + + +/** + @file der_decode_sequence_multi.c + ASN.1 DER, decode a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Decode a SEQUENCE type using a VA list + @param in Input buffer + @param inlen Length of input in octets + @remark <...> is of the form (int, unsigned long, void*) + @return CRYPT_OK on success +*/ +int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) +{ + int err, type; + unsigned long size, x; + void *data; + va_list args; + ltc_asn1_list *list; + + LTC_ARGCHK(in != NULL); + + /* get size of output that will be required */ + va_start(args, inlen); + x = 0; + for (;;) { + type = va_arg(args, int); + size = va_arg(args, unsigned long); + data = va_arg(args, void*); + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: + case LTC_ASN1_BIT_STRING: + case LTC_ASN1_OCTET_STRING: + case LTC_ASN1_NULL: + case LTC_ASN1_OBJECT_IDENTIFIER: + case LTC_ASN1_IA5_STRING: + case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_UTF8_STRING: + case LTC_ASN1_UTCTIME: + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: + case LTC_ASN1_SEQUENCE: + case LTC_ASN1_CHOICE: + ++x; + break; + + default: + va_end(args); + return CRYPT_INVALID_ARG; + } + } + va_end(args); + + /* allocate structure for x elements */ + if (x == 0) { + return CRYPT_NOP; + } + + list = XCALLOC(sizeof(*list), x); + if (list == NULL) { + return CRYPT_MEM; + } + + /* fill in the structure */ + va_start(args, inlen); + x = 0; + for (;;) { + type = va_arg(args, int); + size = va_arg(args, unsigned long); + data = va_arg(args, void*); + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: + case LTC_ASN1_BIT_STRING: + case LTC_ASN1_OCTET_STRING: + case LTC_ASN1_NULL: + case LTC_ASN1_OBJECT_IDENTIFIER: + case LTC_ASN1_IA5_STRING: + case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_UTF8_STRING: + case LTC_ASN1_UTCTIME: + case LTC_ASN1_SEQUENCE: + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: + case LTC_ASN1_CHOICE: + list[x].type = type; + list[x].size = size; + list[x++].data = data; + break; + + default: + va_end(args); + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + va_end(args); + + err = der_decode_sequence(in, inlen, list, x); +LBL_ERR: + XFREE(list); + return err; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_multi.c,v $ */ +/* $Revision: 1.13 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_ex.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_ex.c new file mode 100644 index 0000000000..ab7a343493 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_ex.c @@ -0,0 +1,335 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" +#include + + +/** + @file der_encode_sequence_ex.c + ASN.1 DER, encode a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Encode a SEQUENCE + @param list The list of items to encode + @param inlen The number of items in the list + @param out [out] The destination + @param outlen [in/out] The size of the output + @param type_of LTC_ASN1_SEQUENCE or LTC_ASN1_SET/LTC_ASN1_SETOF + @return CRYPT_OK on success +*/ +int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int type_of) +{ + int err, type; + unsigned long size, x, y, z, i; + void *data; + + LTC_ARGCHK(list != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get size of output that will be required */ + y = 0; + for (i = 0; i < inlen; i++) { + type = list[i].type; + size = list[i].size; + data = list[i].data; + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + if ((err = der_length_boolean(&x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_INTEGER: + if ((err = der_length_integer(data, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_SHORT_INTEGER: + if ((err = der_length_short_integer(*((unsigned long*)data), &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_BIT_STRING: + if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_OCTET_STRING: + if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_NULL: + y += 2; + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_IA5_STRING: + if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_PRINTABLE_STRING: + if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_UTF8_STRING: + if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_UTCTIME: + if ((err = der_length_utctime(data, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: + case LTC_ASN1_SEQUENCE: + if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + default: + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + + /* calc header size */ + z = y; + if (y < 128) { + y += 2; + } else if (y < 256) { + /* 0x30 0x81 LL */ + y += 3; + } else if (y < 65536UL) { + /* 0x30 0x82 LL LL */ + y += 4; + } else if (y < 16777216UL) { + /* 0x30 0x83 LL LL LL */ + y += 5; + } else { + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + + /* too big ? */ + if (*outlen < y) { + *outlen = y; + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + + /* store header */ + x = 0; + out[x++] = (type_of == LTC_ASN1_SEQUENCE) ? 0x30 : 0x31; + + if (z < 128) { + out[x++] = (unsigned char)z; + } else if (z < 256) { + out[x++] = 0x81; + out[x++] = (unsigned char)z; + } else if (z < 65536UL) { + out[x++] = 0x82; + out[x++] = (unsigned char)((z>>8UL)&255); + out[x++] = (unsigned char)(z&255); + } else if (z < 16777216UL) { + out[x++] = 0x83; + out[x++] = (unsigned char)((z>>16UL)&255); + out[x++] = (unsigned char)((z>>8UL)&255); + out[x++] = (unsigned char)(z&255); + } + + /* store data */ + *outlen -= x; + for (i = 0; i < inlen; i++) { + type = list[i].type; + size = list[i].size; + data = list[i].data; + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + z = *outlen; + if ((err = der_encode_boolean(*((int *)data), out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_INTEGER: + z = *outlen; + if ((err = der_encode_integer(data, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_SHORT_INTEGER: + z = *outlen; + if ((err = der_encode_short_integer(*((unsigned long*)data), out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_BIT_STRING: + z = *outlen; + if ((err = der_encode_bit_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_OCTET_STRING: + z = *outlen; + if ((err = der_encode_octet_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_NULL: + out[x++] = 0x05; + out[x++] = 0x00; + *outlen -= 2; + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + z = *outlen; + if ((err = der_encode_object_identifier(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_IA5_STRING: + z = *outlen; + if ((err = der_encode_ia5_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_PRINTABLE_STRING: + z = *outlen; + if ((err = der_encode_printable_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_UTF8_STRING: + z = *outlen; + if ((err = der_encode_utf8_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_UTCTIME: + z = *outlen; + if ((err = der_encode_utctime(data, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_SET: + z = *outlen; + if ((err = der_encode_set(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_SETOF: + z = *outlen; + if ((err = der_encode_setof(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_SEQUENCE: + z = *outlen; + if ((err = der_encode_sequence_ex(data, size, out + x, &z, type)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + default: + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + *outlen = x; + err = CRYPT_OK; + +LBL_ERR: + return err; +} + +#endif diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_multi.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_multi.c new file mode 100644 index 0000000000..4c0596c96f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_multi.c @@ -0,0 +1,138 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" +#include + + +/** + @file der_encode_sequence_multi.c + ASN.1 DER, encode a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Encode a SEQUENCE type using a VA list + @param out [out] Destination for data + @param outlen [in/out] Length of buffer and resulting length of output + @remark <...> is of the form (int, unsigned long, void*) + @return CRYPT_OK on success +*/ +int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) +{ + int err, type; + unsigned long size, x; + void *data; + va_list args; + ltc_asn1_list *list; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get size of output that will be required */ + va_start(args, outlen); + x = 0; + for (;;) { + type = va_arg(args, int); + size = va_arg(args, unsigned long); + data = va_arg(args, void*); + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: + case LTC_ASN1_BIT_STRING: + case LTC_ASN1_OCTET_STRING: + case LTC_ASN1_NULL: + case LTC_ASN1_OBJECT_IDENTIFIER: + case LTC_ASN1_IA5_STRING: + case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_UTF8_STRING: + case LTC_ASN1_UTCTIME: + case LTC_ASN1_SEQUENCE: + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: + ++x; + break; + + default: + va_end(args); + return CRYPT_INVALID_ARG; + } + } + va_end(args); + + /* allocate structure for x elements */ + if (x == 0) { + return CRYPT_NOP; + } + + list = XCALLOC(sizeof(*list), x); + if (list == NULL) { + return CRYPT_MEM; + } + + /* fill in the structure */ + va_start(args, outlen); + x = 0; + for (;;) { + type = va_arg(args, int); + size = va_arg(args, unsigned long); + data = va_arg(args, void*); + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: + case LTC_ASN1_BIT_STRING: + case LTC_ASN1_OCTET_STRING: + case LTC_ASN1_NULL: + case LTC_ASN1_OBJECT_IDENTIFIER: + case LTC_ASN1_IA5_STRING: + case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_UTF8_STRING: + case LTC_ASN1_UTCTIME: + case LTC_ASN1_SEQUENCE: + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: + list[x].type = type; + list[x].size = size; + list[x++].data = data; + break; + + default: + va_end(args); + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + va_end(args); + + err = der_encode_sequence(list, x, out, outlen); +LBL_ERR: + XFREE(list); + return err; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_multi.c,v $ */ +/* $Revision: 1.12 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/sequence/der_length_sequence.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/sequence/der_length_sequence.c new file mode 100644 index 0000000000..7a09d019ec --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/sequence/der_length_sequence.c @@ -0,0 +1,169 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_sequence.c + ASN.1 DER, length a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Get the length of a DER sequence + @param list The sequences of items in the SEQUENCE + @param inlen The number of items + @param outlen [out] The length required in octets to store it + @return CRYPT_OK on success +*/ +int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, + unsigned long *outlen) +{ + int err, type; + unsigned long size, x, y, z, i; + void *data; + + LTC_ARGCHK(list != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get size of output that will be required */ + y = 0; + for (i = 0; i < inlen; i++) { + type = list[i].type; + size = list[i].size; + data = list[i].data; + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + if ((err = der_length_boolean(&x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_INTEGER: + if ((err = der_length_integer(data, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_SHORT_INTEGER: + if ((err = der_length_short_integer(*((unsigned long *)data), &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_BIT_STRING: + if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_OCTET_STRING: + if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_NULL: + y += 2; + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_IA5_STRING: + if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_PRINTABLE_STRING: + if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_UTCTIME: + if ((err = der_length_utctime(data, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_UTF8_STRING: + if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: + case LTC_ASN1_SEQUENCE: + if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + + default: + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + + /* calc header size */ + z = y; + if (y < 128) { + y += 2; + } else if (y < 256) { + /* 0x30 0x81 LL */ + y += 3; + } else if (y < 65536UL) { + /* 0x30 0x82 LL LL */ + y += 4; + } else if (y < 16777216UL) { + /* 0x30 0x83 LL LL LL */ + y += 5; + } else { + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + + /* store size */ + *outlen = y; + err = CRYPT_OK; + +LBL_ERR: + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_length_sequence.c,v $ */ +/* $Revision: 1.14 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/sequence/der_sequence_free.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/sequence/der_sequence_free.c new file mode 100644 index 0000000000..95e21d0776 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/sequence/der_sequence_free.c @@ -0,0 +1,65 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_sequence_free.c + ASN.1 DER, free's a structure allocated by der_decode_sequence_flexi(), Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Free memory allocated by der_decode_sequence_flexi() + @param in The list to free +*/ +void der_sequence_free(ltc_asn1_list *in) +{ + ltc_asn1_list *l; + + /* walk to the start of the chain */ + while (in->prev != NULL || in->parent != NULL) { + if (in->parent != NULL) { + in = in->parent; + } else { + in = in->prev; + } + } + + /* now walk the list and free stuff */ + while (in != NULL) { + /* is there a child? */ + if (in->child) { + /* disconnect */ + in->child->parent = NULL; + der_sequence_free(in->child); + } + + switch (in->type) { + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: + case LTC_ASN1_SEQUENCE: break; + case LTC_ASN1_INTEGER : if (in->data != NULL) { mp_clear(in->data); } break; + default : if (in->data != NULL) { XFREE(in->data); } + } + + /* move to next and free current */ + l = in->next; + free(in); + in = l; + } +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_sequence_free.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/set/der_encode_set.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/set/der_encode_set.c new file mode 100644 index 0000000000..9d5265a9f2 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/set/der_encode_set.c @@ -0,0 +1,103 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_set.c + ASN.1 DER, Encode a SET, Tom St Denis +*/ + +#ifdef LTC_DER + +/* LTC define to ASN.1 TAG */ +static int ltc_to_asn1(int v) +{ + switch (v) { + case LTC_ASN1_BOOLEAN: return 0x01; + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: return 0x02; + case LTC_ASN1_BIT_STRING: return 0x03; + case LTC_ASN1_OCTET_STRING: return 0x04; + case LTC_ASN1_NULL: return 0x05; + case LTC_ASN1_OBJECT_IDENTIFIER: return 0x06; + case LTC_ASN1_UTF8_STRING: return 0x0C; + case LTC_ASN1_PRINTABLE_STRING: return 0x13; + case LTC_ASN1_IA5_STRING: return 0x16; + case LTC_ASN1_UTCTIME: return 0x17; + case LTC_ASN1_SEQUENCE: return 0x30; + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: return 0x31; + default: return -1; + } +} + + +static int qsort_helper(const void *a, const void *b) +{ + ltc_asn1_list *A = (ltc_asn1_list *)a, *B = (ltc_asn1_list *)b; + int r; + + r = ltc_to_asn1(A->type) - ltc_to_asn1(B->type); + + /* for QSORT the order is UNDEFINED if they are "equal" which means it is NOT DETERMINISTIC. So we force it to be :-) */ + if (r == 0) { + /* their order in the original list now determines the position */ + return A->used - B->used; + } else { + return r; + } +} + +/* + Encode a SET type + @param list The list of items to encode + @param inlen The number of items in the list + @param out [out] The destination + @param outlen [in/out] The size of the output + @return CRYPT_OK on success +*/ +int der_encode_set(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + ltc_asn1_list *copy; + unsigned long x; + int err; + + /* make copy of list */ + copy = XCALLOC(inlen, sizeof(*copy)); + if (copy == NULL) { + return CRYPT_MEM; + } + + /* fill in used member with index so we can fully sort it */ + for (x = 0; x < inlen; x++) { + copy[x] = list[x]; + copy[x].used = x; + } + + /* sort it by the "type" field */ + XQSORT(copy, inlen, sizeof(*copy), &qsort_helper); + + /* call der_encode_sequence_ex() */ + err = der_encode_sequence_ex(copy, inlen, out, outlen, LTC_ASN1_SET); + + /* free list */ + XFREE(copy); + + return err; +} + + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/set/der_encode_set.c,v $ */ +/* $Revision: 1.12 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/set/der_encode_setof.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/set/der_encode_setof.c new file mode 100644 index 0000000000..95cf3ccbbe --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/set/der_encode_setof.c @@ -0,0 +1,162 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_setof.c + ASN.1 DER, Encode SET OF, Tom St Denis +*/ + +#ifdef LTC_DER + +struct edge { + unsigned char *start; + unsigned long size; +}; + +static int qsort_helper(const void *a, const void *b) +{ + struct edge *A = (struct edge *)a, *B = (struct edge *)b; + int r; + unsigned long x; + + /* compare min length */ + r = XMEMCMP(A->start, B->start, MIN(A->size, B->size)); + + if (r == 0 && A->size != B->size) { + if (A->size > B->size) { + for (x = B->size; x < A->size; x++) { + if (A->start[x]) { + return 1; + } + } + } else { + for (x = A->size; x < B->size; x++) { + if (B->start[x]) { + return -1; + } + } + } + } + + return r; +} + +/** + Encode a SETOF stucture + @param list The list of items to encode + @param inlen The number of items in the list + @param out [out] The destination + @param outlen [in/out] The size of the output + @return CRYPT_OK on success +*/ +int der_encode_setof(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, z, hdrlen; + int err; + struct edge *edges; + unsigned char *ptr, *buf; + + /* check that they're all the same type */ + for (x = 1; x < inlen; x++) { + if (list[x].type != list[x-1].type) { + return CRYPT_INVALID_ARG; + } + } + + /* alloc buffer to store copy of output */ + buf = XCALLOC(1, *outlen); + if (buf == NULL) { + return CRYPT_MEM; + } + + /* encode list */ + if ((err = der_encode_sequence_ex(list, inlen, buf, outlen, LTC_ASN1_SETOF)) != CRYPT_OK) { + XFREE(buf); + return err; + } + + /* allocate edges */ + edges = XCALLOC(inlen, sizeof(*edges)); + if (edges == NULL) { + XFREE(buf); + return CRYPT_MEM; + } + + /* skip header */ + ptr = buf + 1; + + /* now skip length data */ + x = *ptr++; + if (x >= 0x80) { + ptr += (x & 0x7F); + } + + /* get the size of the static header */ + hdrlen = ((unsigned long)ptr) - ((unsigned long)buf); + + + /* scan for edges */ + x = 0; + while (ptr < (buf + *outlen)) { + /* store start */ + edges[x].start = ptr; + + /* skip type */ + z = 1; + + /* parse length */ + y = ptr[z++]; + if (y < 128) { + edges[x].size = y; + } else { + y &= 0x7F; + edges[x].size = 0; + while (y--) { + edges[x].size = (edges[x].size << 8) | ((unsigned long)ptr[z++]); + } + } + + /* skip content */ + edges[x].size += z; + ptr += edges[x].size; + ++x; + } + + /* sort based on contents (using edges) */ + XQSORT(edges, inlen, sizeof(*edges), &qsort_helper); + + /* copy static header */ + XMEMCPY(out, buf, hdrlen); + + /* copy+sort using edges+indecies to output from buffer */ + for (y = hdrlen, x = 0; x < inlen; x++) { + XMEMCPY(out+y, edges[x].start, edges[x].size); + y += edges[x].size; + } + +#ifdef LTC_CLEAN_STACK + zeromem(buf, *outlen); +#endif + + /* free buffers */ + XFREE(edges); + XFREE(buf); + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/set/der_encode_setof.c,v $ */ +/* $Revision: 1.12 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/short_integer/der_decode_short_integer.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/short_integer/der_decode_short_integer.c new file mode 100644 index 0000000000..fbb89a4f85 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/short_integer/der_decode_short_integer.c @@ -0,0 +1,68 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_short_integer.c + ASN.1 DER, decode an integer, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Read a short integer + @param in The DER encoded data + @param inlen Size of data + @param num [out] The integer to decode + @return CRYPT_OK if successful +*/ +int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num) +{ + unsigned long len, x, y; + + LTC_ARGCHK(num != NULL); + LTC_ARGCHK(in != NULL); + + /* check length */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check header */ + x = 0; + if ((in[x++] & 0x1F) != 0x02) { + return CRYPT_INVALID_PACKET; + } + + /* get the packet len */ + len = in[x++]; + + if (x + len > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read number */ + y = 0; + while (len--) { + y = (y<<8) | (unsigned long)in[x++]; + } + *num = y; + + return CRYPT_OK; + +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/short_integer/der_decode_short_integer.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/short_integer/der_encode_short_integer.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/short_integer/der_encode_short_integer.c new file mode 100644 index 0000000000..759737e4f3 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/short_integer/der_encode_short_integer.c @@ -0,0 +1,97 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_short_integer.c + ASN.1 DER, encode an integer, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a short integer in the range (0,2^32-1) + @param num The integer to encode + @param out [out] The destination for the DER encoded integers + @param outlen [in/out] The max size and resulting size of the DER encoded integers + @return CRYPT_OK if successful +*/ +int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen) +{ + unsigned long len, x, y, z; + int err; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* force to 32 bits */ + num &= 0xFFFFFFFFUL; + + /* find out how big this will be */ + if ((err = der_length_short_integer(num, &len)) != CRYPT_OK) { + return err; + } + + if (*outlen < len) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + /* get len of output */ + z = 0; + y = num; + while (y) { + ++z; + y >>= 8; + } + + /* handle zero */ + if (z == 0) { + z = 1; + } + + /* see if msb is set */ + z += (num&(1UL<<((z<<3) - 1))) ? 1 : 0; + + /* adjust the number so the msB is non-zero */ + for (x = 0; (z <= 4) && (x < (4 - z)); x++) { + num <<= 8; + } + + /* store header */ + x = 0; + out[x++] = 0x02; + out[x++] = (unsigned char)z; + + /* if 31st bit is set output a leading zero and decrement count */ + if (z == 5) { + out[x++] = 0; + --z; + } + + /* store values */ + for (y = 0; y < z; y++) { + out[x++] = (unsigned char)((num >> 24) & 0xFF); + num <<= 8; + } + + /* we good */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/short_integer/der_encode_short_integer.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/short_integer/der_length_short_integer.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/short_integer/der_length_short_integer.c new file mode 100644 index 0000000000..f8770b3acf --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/short_integer/der_length_short_integer.c @@ -0,0 +1,70 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_short_integer.c + ASN.1 DER, get length of encoding, Tom St Denis +*/ + + +#ifdef LTC_DER +/** + Gets length of DER encoding of num + @param num The integer to get the size of + @param outlen [out] The length of the DER encoding for the given integer + @return CRYPT_OK if successful +*/ +int der_length_short_integer(unsigned long num, unsigned long *outlen) +{ + unsigned long z, y, len; + + LTC_ARGCHK(outlen != NULL); + + /* force to 32 bits */ + num &= 0xFFFFFFFFUL; + + /* get the number of bytes */ + z = 0; + y = num; + while (y) { + ++z; + y >>= 8; + } + + /* handle zero */ + if (z == 0) { + z = 1; + } + + /* we need a 0x02 to indicate it's INTEGER */ + len = 1; + + /* length byte */ + ++len; + + /* bytes in value */ + len += z; + + /* see if msb is set */ + len += (num&(1UL<<((z<<3) - 1))) ? 1 : 0; + + /* return length */ + *outlen = len; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/short_integer/der_length_short_integer.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/utctime/der_decode_utctime.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/utctime/der_decode_utctime.c new file mode 100644 index 0000000000..e825e905a7 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/utctime/der_decode_utctime.c @@ -0,0 +1,127 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_utctime.c + ASN.1 DER, decode a UTCTIME, Tom St Denis +*/ + +#ifdef LTC_DER + +static int char_to_int(unsigned char x) +{ + switch (x) { + case '0': return 0; + case '1': return 1; + case '2': return 2; + case '3': return 3; + case '4': return 4; + case '5': return 5; + case '6': return 6; + case '7': return 7; + case '8': return 8; + case '9': return 9; + } + return 100; +} + +#define DECODE_V(y, max) \ + y = char_to_int(buf[x])*10 + char_to_int(buf[x+1]); \ + if (y >= max) return CRYPT_INVALID_PACKET; \ + x += 2; + +/** + Decodes a UTC time structure in DER format (reads all 6 valid encoding formats) + @param in Input buffer + @param inlen Length of input buffer in octets + @param out [out] Destination of UTC time structure + @return CRYPT_OK if successful +*/ +int der_decode_utctime(const unsigned char *in, unsigned long *inlen, + ltc_utctime *out) +{ + unsigned char buf[32]; + unsigned long x; + int y; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen != NULL); + LTC_ARGCHK(out != NULL); + + /* check header */ + if (*inlen < 2UL || (in[1] >= sizeof(buf)) || ((in[1] + 2UL) > *inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* decode the string */ + for (x = 0; x < in[1]; x++) { + y = der_ia5_value_decode(in[x+2]); + if (y == -1) { + return CRYPT_INVALID_PACKET; + } + buf[x] = y; + } + *inlen = 2 + x; + + + /* possible encodings are +YYMMDDhhmmZ +YYMMDDhhmm+hh'mm' +YYMMDDhhmm-hh'mm' +YYMMDDhhmmssZ +YYMMDDhhmmss+hh'mm' +YYMMDDhhmmss-hh'mm' + + So let's do a trivial decode upto [including] mm + */ + + x = 0; + DECODE_V(out->YY, 100); + DECODE_V(out->MM, 13); + DECODE_V(out->DD, 32); + DECODE_V(out->hh, 24); + DECODE_V(out->mm, 60); + + /* clear timezone and seconds info */ + out->off_dir = out->off_hh = out->off_mm = out->ss = 0; + + /* now is it Z, +, - or 0-9 */ + if (buf[x] == 'Z') { + return CRYPT_OK; + } else if (buf[x] == '+' || buf[x] == '-') { + out->off_dir = (buf[x++] == '+') ? 0 : 1; + DECODE_V(out->off_hh, 24); + DECODE_V(out->off_mm, 60); + return CRYPT_OK; + } + + /* decode seconds */ + DECODE_V(out->ss, 60); + + /* now is it Z, +, - */ + if (buf[x] == 'Z') { + return CRYPT_OK; + } else if (buf[x] == '+' || buf[x] == '-') { + out->off_dir = (buf[x++] == '+') ? 0 : 1; + DECODE_V(out->off_hh, 24); + DECODE_V(out->off_mm, 60); + return CRYPT_OK; + } else { + return CRYPT_INVALID_PACKET; + } +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utctime/der_decode_utctime.c,v $ */ +/* $Revision: 1.9 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/utctime/der_encode_utctime.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/utctime/der_encode_utctime.c new file mode 100644 index 0000000000..02a43ffc34 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/utctime/der_encode_utctime.c @@ -0,0 +1,83 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_utctime.c + ASN.1 DER, encode a UTCTIME, Tom St Denis +*/ + +#ifdef LTC_DER + +static const char *baseten = "0123456789"; + +#define STORE_V(y) \ + out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \ + out[x++] = der_ia5_char_encode(baseten[y % 10]); + +/** + Encodes a UTC time structure in DER format + @param utctime The UTC time structure to encode + @param out The destination of the DER encoding of the UTC time structure + @param outlen [in/out] The length of the DER encoding + @return CRYPT_OK if successful +*/ +int der_encode_utctime(ltc_utctime *utctime, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, tmplen; + int err; + + LTC_ARGCHK(utctime != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if ((err = der_length_utctime(utctime, &tmplen)) != CRYPT_OK) { + return err; + } + if (tmplen > *outlen) { + *outlen = tmplen; + return CRYPT_BUFFER_OVERFLOW; + } + + /* store header */ + out[0] = 0x17; + + /* store values */ + x = 2; + STORE_V(utctime->YY); + STORE_V(utctime->MM); + STORE_V(utctime->DD); + STORE_V(utctime->hh); + STORE_V(utctime->mm); + STORE_V(utctime->ss); + + if (utctime->off_mm || utctime->off_hh) { + out[x++] = der_ia5_char_encode(utctime->off_dir ? '-' : '+'); + STORE_V(utctime->off_hh); + STORE_V(utctime->off_mm); + } else { + out[x++] = der_ia5_char_encode('Z'); + } + + /* store length */ + out[1] = (unsigned char)(x - 2); + + /* all good let's return */ + *outlen = x; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utctime/der_encode_utctime.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/utctime/der_length_utctime.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/utctime/der_length_utctime.c new file mode 100644 index 0000000000..e5922b0230 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/utctime/der_length_utctime.c @@ -0,0 +1,46 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_utctime.c + ASN.1 DER, get length of UTCTIME, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Gets length of DER encoding of UTCTIME + @param utctime The UTC time structure to get the size of + @param outlen [out] The length of the DER encoding + @return CRYPT_OK if successful +*/ +int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen) +{ + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(utctime != NULL); + + if (utctime->off_hh == 0 && utctime->off_mm == 0) { + /* we encode as YYMMDDhhmmssZ */ + *outlen = 2 + 13; + } else { + /* we encode as YYMMDDhhmmss{+|-}hh'mm' */ + *outlen = 2 + 17; + } + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utctime/der_length_utctime.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/utf8/der_decode_utf8_string.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/utf8/der_decode_utf8_string.c new file mode 100644 index 0000000000..b35145f178 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/utf8/der_decode_utf8_string.c @@ -0,0 +1,111 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_utf8_string.c + ASN.1 DER, encode a UTF8 STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a UTF8 STRING + @param in The DER encoded UTF8 STRING + @param inlen The size of the DER UTF8 STRING + @param out [out] The array of utf8s stored (one per char) + @param outlen [in/out] The number of utf8s stored + @return CRYPT_OK if successful +*/ +int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, + wchar_t *out, unsigned long *outlen) +{ + wchar_t tmp; + unsigned long x, y, z, len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* must have header at least */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check for 0x0C */ + if ((in[0] & 0x1F) != 0x0C) { + return CRYPT_INVALID_PACKET; + } + x = 1; + + /* decode the length */ + if (in[x] & 0x80) { + /* valid # of bytes in length are 1,2,3 */ + y = in[x] & 0x7F; + if ((y == 0) || (y > 3) || ((x + y) > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* read the length in */ + len = 0; + ++x; + while (y--) { + len = (len << 8) | in[x++]; + } + } else { + len = in[x++] & 0x7F; + } + + if (len + x > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* proceed to decode */ + for (y = 0; x < inlen; ) { + /* get first byte */ + tmp = in[x++]; + + /* count number of bytes */ + for (z = 0; (tmp & 0x80) && (z <= 4); z++, tmp = (tmp << 1) & 0xFF); + + if (z > 4 || (x + (z - 1) > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* decode, grab upper bits */ + tmp >>= z; + + /* grab remaining bytes */ + if (z > 1) { --z; } + while (z-- != 0) { + if ((in[x] & 0xC0) != 0x80) { + return CRYPT_INVALID_PACKET; + } + tmp = (tmp << 6) | ((wchar_t)in[x++] & 0x3F); + } + + if (y > *outlen) { + *outlen = y; + return CRYPT_BUFFER_OVERFLOW; + } + out[y++] = tmp; + } + *outlen = y; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utf8/der_decode_utf8_string.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/utf8/der_encode_utf8_string.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/utf8/der_encode_utf8_string.c new file mode 100644 index 0000000000..a093376a29 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/utf8/der_encode_utf8_string.c @@ -0,0 +1,105 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_utf8_string.c + ASN.1 DER, encode a UTF8 STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store an UTF8 STRING + @param in The array of UTF8 to store (one per wchar_t) + @param inlen The number of UTF8 to store + @param out [out] The destination for the DER encoded UTF8 STRING + @param outlen [in/out] The max size and resulting size of the DER UTF8 STRING + @return CRYPT_OK if successful +*/ +int der_encode_utf8_string(const wchar_t *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get the size */ + for (x = len = 0; x < inlen; x++) { + if (in[x] < 0 || in[x] > 0x1FFFF) { + return CRYPT_INVALID_ARG; + } + len += der_utf8_charsize(in[x]); + } + + if (len < 128) { + y = 2 + len; + } else if (len < 256) { + y = 3 + len; + } else if (len < 65536UL) { + y = 4 + len; + } else if (len < 16777216UL) { + y = 5 + len; + } else { + return CRYPT_INVALID_ARG; + } + + /* too big? */ + if (y > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + /* encode the header+len */ + x = 0; + out[x++] = 0x0C; + if (len < 128) { + out[x++] = (unsigned char)len; + } else if (len < 256) { + out[x++] = 0x81; + out[x++] = (unsigned char)len; + } else if (len < 65536UL) { + out[x++] = 0x82; + out[x++] = (unsigned char)((len>>8)&255); + out[x++] = (unsigned char)(len&255); + } else if (len < 16777216UL) { + out[x++] = 0x83; + out[x++] = (unsigned char)((len>>16)&255); + out[x++] = (unsigned char)((len>>8)&255); + out[x++] = (unsigned char)(len&255); + } else { + return CRYPT_INVALID_ARG; + } + + /* store UTF8 */ + for (y = 0; y < inlen; y++) { + switch (der_utf8_charsize(in[y])) { + case 1: out[x++] = (unsigned char)in[y]; break; + case 2: out[x++] = 0xC0 | ((in[y] >> 6) & 0x1F); out[x++] = 0x80 | (in[y] & 0x3F); break; + case 3: out[x++] = 0xE0 | ((in[y] >> 12) & 0x0F); out[x++] = 0x80 | ((in[y] >> 6) & 0x3F); out[x++] = 0x80 | (in[y] & 0x3F); break; + case 4: out[x++] = 0xF0 | ((in[y] >> 18) & 0x07); out[x++] = 0x80 | ((in[y] >> 12) & 0x3F); out[x++] = 0x80 | ((in[y] >> 6) & 0x3F); out[x++] = 0x80 | (in[y] & 0x3F); break; + } + } + + /* retun length */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utf8/der_encode_utf8_string.c,v $ */ +/* $Revision: 1.9 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/utf8/der_length_utf8_string.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/utf8/der_length_utf8_string.c new file mode 100644 index 0000000000..e65baf728d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/asn1/der/utf8/der_length_utf8_string.c @@ -0,0 +1,83 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_utf8_string.c + ASN.1 DER, get length of UTF8 STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +/** Return the size in bytes of a UTF-8 character + @param c The UTF-8 character to measure + @return The size in bytes +*/ +unsigned long der_utf8_charsize(const wchar_t c) +{ + if (c <= 0x7F) { + return 1; + } else if (c <= 0x7FF) { + return 2; + } else if (c <= 0xFFFF) { + return 3; + } else { + return 4; + } +} + +/** + Gets length of DER encoding of UTF8 STRING + @param in The characters to measure the length of + @param noctets The number of octets in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen) +{ + unsigned long x, len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(outlen != NULL); + + len = 0; + for (x = 0; x < noctets; x++) { + if (in[x] < 0 || in[x] > 0x10FFFF) { + return CRYPT_INVALID_ARG; + } + len += der_utf8_charsize(in[x]); + } + + if (len < 128) { + /* 0C LL DD DD DD ... */ + *outlen = 2 + len; + } else if (len < 256) { + /* 0C 81 LL DD DD DD ... */ + *outlen = 3 + len; + } else if (len < 65536UL) { + /* 0C 82 LL LL DD DD DD ... */ + *outlen = 4 + len; + } else if (len < 16777216UL) { + /* 0C 83 LL LL LL DD DD DD ... */ + *outlen = 5 + len; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utf8/der_length_utf8_string.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_decrypt_key.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_decrypt_key.c new file mode 100644 index 0000000000..a78cc6e3d8 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_decrypt_key.c @@ -0,0 +1,138 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file dsa_decrypt_key.c + DSA Crypto, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Decrypt an DSA encrypted key + @param in The ciphertext + @param inlen The length of the ciphertext (octets) + @param out [out] The plaintext + @param outlen [in/out] The max size and resulting size of the plaintext + @param key The corresponding private DSA key + @return CRYPT_OK if successful +*/ +int dsa_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + dsa_key *key) +{ + unsigned char *skey, *expt; + void *g_pub; + unsigned long x, y, hashOID[32]; + int hash, err; + ltc_asn1_list decode[3]; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* right key type? */ + if (key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* decode to find out hash */ + LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0])); + + if ((err = der_decode_sequence(in, inlen, decode, 1)) != CRYPT_OK) { + return err; + } + + hash = find_hash_oid(hashOID, decode[0].size); + if (hash_is_valid(hash) != CRYPT_OK) { + return CRYPT_INVALID_PACKET; + } + + /* we now have the hash! */ + + if ((err = mp_init(&g_pub)) != CRYPT_OK) { + return err; + } + + /* allocate memory */ + expt = XMALLOC(mp_unsigned_bin_size(key->p) + 1); + skey = XMALLOC(MAXBLOCKSIZE); + if (expt == NULL || skey == NULL) { + if (expt != NULL) { + XFREE(expt); + } + if (skey != NULL) { + XFREE(skey); + } + mp_clear(g_pub); + return CRYPT_MEM; + } + + LTC_SET_ASN1(decode, 1, LTC_ASN1_INTEGER, g_pub, 1UL); + LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING, skey, MAXBLOCKSIZE); + + /* read the structure in now */ + if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* make shared key */ + x = mp_unsigned_bin_size(key->p) + 1; + if ((err = dsa_shared_secret(key->x, g_pub, key, expt, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + + y = MIN(mp_unsigned_bin_size(key->p) + 1, MAXBLOCKSIZE); + if ((err = hash_memory(hash, expt, x, expt, &y)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* ensure the hash of the shared secret is at least as big as the encrypt itself */ + if (decode[2].size > y) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + /* avoid buffer overflow */ + if (*outlen < decode[2].size) { + *outlen = decode[2].size; + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + + /* Decrypt the key */ + for (x = 0; x < decode[2].size; x++) { + out[x] = expt[x] ^ skey[x]; + } + *outlen = x; + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(expt, mp_unsigned_bin_size(key->p) + 1); + zeromem(skey, MAXBLOCKSIZE); +#endif + + XFREE(expt); + XFREE(skey); + + mp_clear(g_pub); + + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_decrypt_key.c,v $ */ +/* $Revision: 1.11 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_encrypt_key.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_encrypt_key.c new file mode 100644 index 0000000000..890e9a5a7c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_encrypt_key.c @@ -0,0 +1,134 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file dsa_encrypt_key.c + DSA Crypto, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Encrypt a symmetric key with DSA + @param in The symmetric key you want to encrypt + @param inlen The length of the key to encrypt (octets) + @param out [out] The destination for the ciphertext + @param outlen [in/out] The max size and resulting size of the ciphertext + @param prng An active PRNG state + @param wprng The index of the PRNG you wish to use + @param hash The index of the hash you want to use + @param key The DSA key you want to encrypt to + @return CRYPT_OK if successful +*/ +int dsa_encrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, int hash, + dsa_key *key) +{ + unsigned char *expt, *skey; + void *g_pub, *g_priv; + unsigned long x, y; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* check that wprng/cipher/hash are not invalid */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + if (inlen > hash_descriptor[hash].hashsize) { + return CRYPT_INVALID_HASH; + } + + /* make a random key and export the public copy */ + if ((err = mp_init_multi(&g_pub, &g_priv, NULL)) != CRYPT_OK) { + return err; + } + + expt = XMALLOC(mp_unsigned_bin_size(key->p) + 1); + skey = XMALLOC(MAXBLOCKSIZE); + if (expt == NULL || skey == NULL) { + if (expt != NULL) { + XFREE(expt); + } + if (skey != NULL) { + XFREE(skey); + } + mp_clear_multi(g_pub, g_priv, NULL); + return CRYPT_MEM; + } + + /* make a random x, g^x pair */ + x = mp_unsigned_bin_size(key->q); + if (prng_descriptor[wprng].read(expt, x, prng) != x) { + err = CRYPT_ERROR_READPRNG; + goto LBL_ERR; + } + + /* load x */ + if ((err = mp_read_unsigned_bin(g_priv, expt, x)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* compute y */ + if ((err = mp_exptmod(key->g, g_priv, key->p, g_pub)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* make random key */ + x = mp_unsigned_bin_size(key->p) + 1; + if ((err = dsa_shared_secret(g_priv, key->y, key, expt, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + + y = MAXBLOCKSIZE; + if ((err = hash_memory(hash, expt, x, skey, &y)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* Encrypt key */ + for (x = 0; x < inlen; x++) { + skey[x] ^= in[x]; + } + + err = der_encode_sequence_multi(out, outlen, + LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash].OIDlen, hash_descriptor[hash].OID, + LTC_ASN1_INTEGER, 1UL, g_pub, + LTC_ASN1_OCTET_STRING, inlen, skey, + LTC_ASN1_EOL, 0UL, NULL); + +LBL_ERR: +#ifdef LTC_CLEAN_STACK + /* clean up */ + zeromem(expt, mp_unsigned_bin_size(key->p) + 1); + zeromem(skey, MAXBLOCKSIZE); +#endif + + XFREE(skey); + XFREE(expt); + + mp_clear_multi(g_pub, g_priv, NULL); + return err; +} + +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_encrypt_key.c,v $ */ +/* $Revision: 1.9 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_export.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_export.c new file mode 100644 index 0000000000..3b6f9bb7f6 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_export.c @@ -0,0 +1,72 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file dsa_export.c + DSA implementation, export key, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Export a DSA key to a binary packet + @param out [out] Where to store the packet + @param outlen [in/out] The max size and resulting size of the packet + @param type The type of key to export (PK_PRIVATE or PK_PUBLIC) + @param key The key to export + @return CRYPT_OK if successful +*/ +int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key) +{ + unsigned char flags[1]; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* can we store the static header? */ + if (type == PK_PRIVATE && key->type != PK_PRIVATE) { + return CRYPT_PK_TYPE_MISMATCH; + } + + if (type != PK_PUBLIC && type != PK_PRIVATE) { + return CRYPT_INVALID_ARG; + } + + flags[0] = (type != PK_PUBLIC) ? 1 : 0; + + if (type == PK_PRIVATE) { + return der_encode_sequence_multi(out, outlen, + LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_INTEGER, 1UL, key->g, + LTC_ASN1_INTEGER, 1UL, key->p, + LTC_ASN1_INTEGER, 1UL, key->q, + LTC_ASN1_INTEGER, 1UL, key->y, + LTC_ASN1_INTEGER, 1UL, key->x, + LTC_ASN1_EOL, 0UL, NULL); + } else { + return der_encode_sequence_multi(out, outlen, + LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_INTEGER, 1UL, key->g, + LTC_ASN1_INTEGER, 1UL, key->p, + LTC_ASN1_INTEGER, 1UL, key->q, + LTC_ASN1_INTEGER, 1UL, key->y, + LTC_ASN1_EOL, 0UL, NULL); + } +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_export.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_free.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_free.c new file mode 100644 index 0000000000..a589d1662b --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_free.c @@ -0,0 +1,34 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file dsa_free.c + DSA implementation, free a DSA key, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Free a DSA key + @param key The key to free from memory +*/ +void dsa_free(dsa_key *key) +{ + LTC_ARGCHKVD(key != NULL); + mp_clear_multi(key->g, key->q, key->p, key->x, key->y, NULL); +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_free.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_import.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_import.c new file mode 100644 index 0000000000..975b305dc7 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_import.c @@ -0,0 +1,90 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file dsa_import.c + DSA implementation, import a DSA key, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Import a DSA key + @param in The binary packet to import from + @param inlen The length of the binary packet + @param key [out] Where to store the imported key + @return CRYPT_OK if successful, upon error this function will free all allocated memory +*/ +int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key) +{ + unsigned char flags[1]; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + + /* init key */ + if (mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL) != CRYPT_OK) { + return CRYPT_MEM; + } + + /* get key type */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto error; + } + + if (flags[0] == 1) { + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_INTEGER, 1UL, key->g, + LTC_ASN1_INTEGER, 1UL, key->p, + LTC_ASN1_INTEGER, 1UL, key->q, + LTC_ASN1_INTEGER, 1UL, key->y, + LTC_ASN1_INTEGER, 1UL, key->x, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto error; + } + key->type = PK_PRIVATE; + } else { + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_INTEGER, 1UL, key->g, + LTC_ASN1_INTEGER, 1UL, key->p, + LTC_ASN1_INTEGER, 1UL, key->q, + LTC_ASN1_INTEGER, 1UL, key->y, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto error; + } + key->type = PK_PUBLIC; + } + key->qord = mp_unsigned_bin_size(key->q); + + if (key->qord >= LTC_MDSA_MAX_GROUP || key->qord <= 15 || + (unsigned long)key->qord >= mp_unsigned_bin_size(key->p) || (mp_unsigned_bin_size(key->p) - key->qord) >= LTC_MDSA_DELTA) { + err = CRYPT_INVALID_PACKET; + goto error; + } + + return CRYPT_OK; +error: + mp_clear_multi(key->p, key->g, key->q, key->x, key->y, NULL); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_import.c,v $ */ +/* $Revision: 1.14 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_make_key.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_make_key.c new file mode 100644 index 0000000000..d3b8c5ea28 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_make_key.c @@ -0,0 +1,137 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file dsa_make_key.c + DSA implementation, generate a DSA key, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Create a DSA key + @param prng An active PRNG state + @param wprng The index of the PRNG desired + @param group_size Size of the multiplicative group (octets) + @param modulus_size Size of the modulus (octets) + @param key [out] Where to store the created key + @return CRYPT_OK if successful, upon error this function will free all allocated memory +*/ +int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key) +{ + void *tmp, *tmp2; + int err, res; + unsigned char *buf; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + + /* check prng */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* check size */ + if (group_size >= LTC_MDSA_MAX_GROUP || group_size <= 15 || + group_size >= modulus_size || (modulus_size - group_size) >= LTC_MDSA_DELTA) { + return CRYPT_INVALID_ARG; + } + + /* allocate ram */ + buf = XMALLOC(LTC_MDSA_DELTA); + if (buf == NULL) { + return CRYPT_MEM; + } + + /* init mp_ints */ + if ((err = mp_init_multi(&tmp, &tmp2, &key->g, &key->q, &key->p, &key->x, &key->y, NULL)) != CRYPT_OK) { + XFREE(buf); + return err; + } + + /* make our prime q */ + if ((err = rand_prime(key->q, group_size, prng, wprng)) != CRYPT_OK) { goto error; } + + /* double q */ + if ((err = mp_add(key->q, key->q, tmp)) != CRYPT_OK) { goto error; } + + /* now make a random string and multply it against q */ + if (prng_descriptor[wprng].read(buf+1, modulus_size - group_size, prng) != (unsigned long)(modulus_size - group_size)) { + err = CRYPT_ERROR_READPRNG; + goto error; + } + + /* force magnitude */ + buf[0] |= 0xC0; + + /* force even */ + buf[modulus_size - group_size - 1] &= ~1; + + if ((err = mp_read_unsigned_bin(tmp2, buf, modulus_size - group_size)) != CRYPT_OK) { goto error; } + if ((err = mp_mul(key->q, tmp2, key->p)) != CRYPT_OK) { goto error; } + if ((err = mp_add_d(key->p, 1, key->p)) != CRYPT_OK) { goto error; } + + /* now loop until p is prime */ + for (;;) { + if ((err = mp_prime_is_prime(key->p, 8, &res)) != CRYPT_OK) { goto error; } + if (res == LTC_MP_YES) break; + + /* add 2q to p and 2 to tmp2 */ + if ((err = mp_add(tmp, key->p, key->p)) != CRYPT_OK) { goto error; } + if ((err = mp_add_d(tmp2, 2, tmp2)) != CRYPT_OK) { goto error; } + } + + /* now p = (q * tmp2) + 1 is prime, find a value g for which g^tmp2 != 1 */ + mp_set(key->g, 1); + + do { + if ((err = mp_add_d(key->g, 1, key->g)) != CRYPT_OK) { goto error; } + if ((err = mp_exptmod(key->g, tmp2, key->p, tmp)) != CRYPT_OK) { goto error; } + } while (mp_cmp_d(tmp, 1) == LTC_MP_EQ); + + /* at this point tmp generates a group of order q mod p */ + mp_exch(tmp, key->g); + + /* so now we have our DH structure, generator g, order q, modulus p + Now we need a random exponent [mod q] and it's power g^x mod p + */ + do { + if (prng_descriptor[wprng].read(buf, group_size, prng) != (unsigned long)group_size) { + err = CRYPT_ERROR_READPRNG; + goto error; + } + if ((err = mp_read_unsigned_bin(key->x, buf, group_size)) != CRYPT_OK) { goto error; } + } while (mp_cmp_d(key->x, 1) != LTC_MP_GT); + if ((err = mp_exptmod(key->g, key->x, key->p, key->y)) != CRYPT_OK) { goto error; } + + key->type = PK_PRIVATE; + key->qord = group_size; + +#ifdef LTC_CLEAN_STACK + zeromem(buf, LTC_MDSA_DELTA); +#endif + + err = CRYPT_OK; + goto done; +error: + mp_clear_multi(key->g, key->q, key->p, key->x, key->y, NULL); +done: + mp_clear_multi(tmp, tmp2, NULL); + XFREE(buf); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_make_key.c,v $ */ +/* $Revision: 1.12 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_shared_secret.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_shared_secret.c new file mode 100644 index 0000000000..cbba5a2b2c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_shared_secret.c @@ -0,0 +1,71 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file dsa_shared_secret.c + DSA Crypto, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Create a DSA shared secret between two keys + @param private_key The private DSA key (the exponent) + @param base The base of the exponentiation (allows this to be used for both encrypt and decrypt) + @param public_key The public key + @param out [out] Destination of the shared secret + @param outlen [in/out] The max size and resulting size of the shared secret + @return CRYPT_OK if successful +*/ +int dsa_shared_secret(void *private_key, void *base, + dsa_key *public_key, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x; + void *res; + int err; + + LTC_ARGCHK(private_key != NULL); + LTC_ARGCHK(public_key != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* make new point */ + if ((err = mp_init(&res)) != CRYPT_OK) { + return err; + } + + if ((err = mp_exptmod(base, private_key, public_key->p, res)) != CRYPT_OK) { + mp_clear(res); + return err; + } + + x = (unsigned long)mp_unsigned_bin_size(res); + if (*outlen < x) { + *outlen = x; + err = CRYPT_BUFFER_OVERFLOW; + goto done; + } + zeromem(out, x); + if ((err = mp_to_unsigned_bin(res, out + (x - mp_unsigned_bin_size(res)))) != CRYPT_OK) { goto done; } + + err = CRYPT_OK; + *outlen = x; +done: + mp_clear(res); + return err; +} + +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_shared_secret.c,v $ */ +/* $Revision: 1.9 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_sign_hash.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_sign_hash.c new file mode 100644 index 0000000000..e4b3bc9c98 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_sign_hash.c @@ -0,0 +1,156 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file dsa_sign_hash.c + DSA implementation, sign a hash, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Sign a hash with DSA + @param in The hash to sign + @param inlen The length of the hash to sign + @param r The "r" integer of the signature (caller must initialize with mp_init() first) + @param s The "s" integer of the signature (caller must initialize with mp_init() first) + @param prng An active PRNG state + @param wprng The index of the PRNG desired + @param key A private DSA key + @return CRYPT_OK if successful +*/ +int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen, + void *r, void *s, + prng_state *prng, int wprng, dsa_key *key) +{ + void *k, *kinv, *tmp; + unsigned char *buf; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(r != NULL); + LTC_ARGCHK(s != NULL); + LTC_ARGCHK(key != NULL); + + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + if (key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* check group order size */ + if (key->qord >= LTC_MDSA_MAX_GROUP) { + return CRYPT_INVALID_ARG; + } + + buf = XMALLOC(LTC_MDSA_MAX_GROUP); + if (buf == NULL) { + return CRYPT_MEM; + } + + /* Init our temps */ + if ((err = mp_init_multi(&k, &kinv, &tmp, NULL)) != CRYPT_OK) { goto ERRBUF; } + +retry: + + do { + /* gen random k */ + if (prng_descriptor[wprng].read(buf, key->qord, prng) != (unsigned long)key->qord) { + err = CRYPT_ERROR_READPRNG; + goto error; + } + + /* read k */ + if ((err = mp_read_unsigned_bin(k, buf, key->qord)) != CRYPT_OK) { goto error; } + + /* k > 1 ? */ + if (mp_cmp_d(k, 1) != LTC_MP_GT) { goto retry; } + + /* test gcd */ + if ((err = mp_gcd(k, key->q, tmp)) != CRYPT_OK) { goto error; } + } while (mp_cmp_d(tmp, 1) != LTC_MP_EQ); + + /* now find 1/k mod q */ + if ((err = mp_invmod(k, key->q, kinv)) != CRYPT_OK) { goto error; } + + /* now find r = g^k mod p mod q */ + if ((err = mp_exptmod(key->g, k, key->p, r)) != CRYPT_OK) { goto error; } + if ((err = mp_mod(r, key->q, r)) != CRYPT_OK) { goto error; } + + if (mp_iszero(r) == LTC_MP_YES) { goto retry; } + + /* now find s = (in + xr)/k mod q */ + if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, inlen)) != CRYPT_OK) { goto error; } + if ((err = mp_mul(key->x, r, s)) != CRYPT_OK) { goto error; } + if ((err = mp_add(s, tmp, s)) != CRYPT_OK) { goto error; } + if ((err = mp_mulmod(s, kinv, key->q, s)) != CRYPT_OK) { goto error; } + + if (mp_iszero(s) == LTC_MP_YES) { goto retry; } + + err = CRYPT_OK; +error: + mp_clear_multi(k, kinv, tmp, NULL); +ERRBUF: +#ifdef LTC_CLEAN_STACK + zeromem(buf, LTC_MDSA_MAX_GROUP); +#endif + XFREE(buf); + return err; +} + +/** + Sign a hash with DSA + @param in The hash to sign + @param inlen The length of the hash to sign + @param out [out] Where to store the signature + @param outlen [in/out] The max size and resulting size of the signature + @param prng An active PRNG state + @param wprng The index of the PRNG desired + @param key A private DSA key + @return CRYPT_OK if successful +*/ +int dsa_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, dsa_key *key) +{ + void *r, *s; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + if (mp_init_multi(&r, &s, NULL) != CRYPT_OK) { + return CRYPT_MEM; + } + + if ((err = dsa_sign_hash_raw(in, inlen, r, s, prng, wprng, key)) != CRYPT_OK) { + goto error; + } + + err = der_encode_sequence_multi(out, outlen, + LTC_ASN1_INTEGER, 1UL, r, + LTC_ASN1_INTEGER, 1UL, s, + LTC_ASN1_EOL, 0UL, NULL); + +error: + mp_clear_multi(r, s, NULL); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_sign_hash.c,v $ */ +/* $Revision: 1.14 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_verify_hash.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_verify_hash.c new file mode 100644 index 0000000000..61b8d91f95 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_verify_hash.c @@ -0,0 +1,126 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file dsa_verify_hash.c + DSA implementation, verify a signature, Tom St Denis +*/ + + +#ifdef LTC_MDSA + +/** + Verify a DSA signature + @param r DSA "r" parameter + @param s DSA "s" parameter + @param hash The hash that was signed + @param hashlen The length of the hash that was signed + @param stat [out] The result of the signature verification, 1==valid, 0==invalid + @param key The corresponding public DH key + @return CRYPT_OK if successful (even if the signature is invalid) +*/ +int dsa_verify_hash_raw( void *r, void *s, + const unsigned char *hash, unsigned long hashlen, + int *stat, dsa_key *key) +{ + void *w, *v, *u1, *u2; + int err; + + LTC_ARGCHK(r != NULL); + LTC_ARGCHK(s != NULL); + LTC_ARGCHK(stat != NULL); + LTC_ARGCHK(key != NULL); + + /* default to invalid signature */ + *stat = 0; + + /* init our variables */ + if ((err = mp_init_multi(&w, &v, &u1, &u2, NULL)) != CRYPT_OK) { + return err; + } + + /* neither r or s can be null or >q*/ + if (mp_iszero(r) == LTC_MP_YES || mp_iszero(s) == LTC_MP_YES || mp_cmp(r, key->q) != LTC_MP_LT || mp_cmp(s, key->q) != LTC_MP_LT) { + err = CRYPT_INVALID_PACKET; + goto error; + } + + /* w = 1/s mod q */ + if ((err = mp_invmod(s, key->q, w)) != CRYPT_OK) { goto error; } + + /* u1 = m * w mod q */ + if ((err = mp_read_unsigned_bin(u1, (unsigned char *)hash, hashlen)) != CRYPT_OK) { goto error; } + if ((err = mp_mulmod(u1, w, key->q, u1)) != CRYPT_OK) { goto error; } + + /* u2 = r*w mod q */ + if ((err = mp_mulmod(r, w, key->q, u2)) != CRYPT_OK) { goto error; } + + /* v = g^u1 * y^u2 mod p mod q */ + if ((err = mp_exptmod(key->g, u1, key->p, u1)) != CRYPT_OK) { goto error; } + if ((err = mp_exptmod(key->y, u2, key->p, u2)) != CRYPT_OK) { goto error; } + if ((err = mp_mulmod(u1, u2, key->p, v)) != CRYPT_OK) { goto error; } + if ((err = mp_mod(v, key->q, v)) != CRYPT_OK) { goto error; } + + /* if r = v then we're set */ + if (mp_cmp(r, v) == LTC_MP_EQ) { + *stat = 1; + } + + err = CRYPT_OK; +error: + mp_clear_multi(w, v, u1, u2, NULL); + return err; +} + +/** + Verify a DSA signature + @param sig The signature + @param siglen The length of the signature (octets) + @param hash The hash that was signed + @param hashlen The length of the hash that was signed + @param stat [out] The result of the signature verification, 1==valid, 0==invalid + @param key The corresponding public DH key + @return CRYPT_OK if successful (even if the signature is invalid) +*/ +int dsa_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, dsa_key *key) +{ + int err; + void *r, *s; + + if ((err = mp_init_multi(&r, &s, NULL)) != CRYPT_OK) { + return CRYPT_MEM; + } + + /* decode the sequence */ + if ((err = der_decode_sequence_multi(sig, siglen, + LTC_ASN1_INTEGER, 1UL, r, + LTC_ASN1_INTEGER, 1UL, s, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* do the op */ + err = dsa_verify_hash_raw(r, s, hash, hashlen, stat, key); + +LBL_ERR: + mp_clear_multi(r, s, NULL); + return err; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_verify_hash.c,v $ */ +/* $Revision: 1.15 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_verify_key.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_verify_key.c new file mode 100644 index 0000000000..4df2323264 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/dsa/dsa_verify_key.c @@ -0,0 +1,100 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file dsa_verify_key.c + DSA implementation, verify a key, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Verify a DSA key for validity + @param key The key to verify + @param stat [out] Result of test, 1==valid, 0==invalid + @return CRYPT_OK if successful +*/ +int dsa_verify_key(dsa_key *key, int *stat) +{ + void *tmp, *tmp2; + int res, err; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(stat != NULL); + + /* default to an invalid key */ + *stat = 0; + + /* first make sure key->q and key->p are prime */ + if ((err = mp_prime_is_prime(key->q, 8, &res)) != CRYPT_OK) { + return err; + } + if (res == 0) { + return CRYPT_OK; + } + + if ((err = mp_prime_is_prime(key->p, 8, &res)) != CRYPT_OK) { + return err; + } + if (res == 0) { + return CRYPT_OK; + } + + /* now make sure that g is not -1, 0 or 1 and

g, 0) == LTC_MP_EQ || mp_cmp_d(key->g, 1) == LTC_MP_EQ) { + return CRYPT_OK; + } + if ((err = mp_init_multi(&tmp, &tmp2, NULL)) != CRYPT_OK) { return err; } + if ((err = mp_sub_d(key->p, 1, tmp)) != CRYPT_OK) { goto error; } + if (mp_cmp(tmp, key->g) == LTC_MP_EQ || mp_cmp(key->g, key->p) != LTC_MP_LT) { + err = CRYPT_OK; + goto error; + } + + /* 1 < y < p-1 */ + if (!(mp_cmp_d(key->y, 1) == LTC_MP_GT && mp_cmp(key->y, tmp) == LTC_MP_LT)) { + err = CRYPT_OK; + goto error; + } + + /* now we have to make sure that g^q = 1, and that p-1/q gives 0 remainder */ + if ((err = mp_div(tmp, key->q, tmp, tmp2)) != CRYPT_OK) { goto error; } + if (mp_iszero(tmp2) != LTC_MP_YES) { + err = CRYPT_OK; + goto error; + } + + if ((err = mp_exptmod(key->g, key->q, key->p, tmp)) != CRYPT_OK) { goto error; } + if (mp_cmp_d(tmp, 1) != LTC_MP_EQ) { + err = CRYPT_OK; + goto error; + } + + /* now we have to make sure that y^q = 1, this makes sure y \in g^x mod p */ + if ((err = mp_exptmod(key->y, key->q, key->p, tmp)) != CRYPT_OK) { goto error; } + if (mp_cmp_d(tmp, 1) != LTC_MP_EQ) { + err = CRYPT_OK; + goto error; + } + + /* at this point we are out of tests ;-( */ + err = CRYPT_OK; + *stat = 1; +error: + mp_clear_multi(tmp, tmp2, NULL); + return err; +} +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_verify_key.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc.c new file mode 100644 index 0000000000..ba3bfc891e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc.c @@ -0,0 +1,126 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "tomcrypt.h" + +/** + @file ecc.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/* This holds the key settings. ***MUST*** be organized by size from smallest to largest. */ +const ltc_ecc_set_type ltc_ecc_sets[] = { +#ifdef ECC112 +{ + 14, + "SECP112R1", + "DB7C2ABF62E35E668076BEAD208B", + "659EF8BA043916EEDE8911702B22", + "DB7C2ABF62E35E7628DFAC6561C5", + "09487239995A5EE76B55F9C2F098", + "A89CE5AF8724C0A23E0E0FF77500" +}, +#endif +#ifdef ECC128 +{ + 16, + "SECP128R1", + "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", + "E87579C11079F43DD824993C2CEE5ED3", + "FFFFFFFE0000000075A30D1B9038A115", + "161FF7528B899B2D0C28607CA52C5B86", + "CF5AC8395BAFEB13C02DA292DDED7A83", +}, +#endif +#ifdef ECC160 +{ + 20, + "SECP160R1", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", + "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", + "0100000000000000000001F4C8F927AED3CA752257", + "4A96B5688EF573284664698968C38BB913CBFC82", + "23A628553168947D59DCC912042351377AC5FB32", +}, +#endif +#ifdef ECC192 +{ + 24, + "ECC-192", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", + "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", + "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", + "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", + "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811", +}, +#endif +#ifdef ECC224 +{ + 28, + "ECC-224", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", + "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", + "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", + "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", +}, +#endif +#ifdef ECC256 +{ + 32, + "ECC-256", + "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", + "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", + "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", +}, +#endif +#ifdef ECC384 +{ + 48, + "ECC-384", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", + "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", + "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", +}, +#endif +#ifdef ECC521 +{ + 66, + "ECC-521", + "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", + "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", + "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", + "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", +}, +#endif +{ + 0, + NULL, NULL, NULL, NULL, NULL, NULL +} +}; + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc.c,v $ */ +/* $Revision: 1.40 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_ansi_x963_export.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_ansi_x963_export.c new file mode 100644 index 0000000000..024a354d67 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_ansi_x963_export.c @@ -0,0 +1,72 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "tomcrypt.h" + +/** + @file ecc_ansi_x963_export.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** ECC X9.63 (Sec. 4.3.6) uncompressed export + @param key Key to export + @param out [out] destination of export + @param outlen [in/out] Length of destination and final output size + Return CRYPT_OK on success +*/ +int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen) +{ + unsigned char buf[ECC_BUF_SIZE]; + unsigned long numlen; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if (ltc_ecc_is_valid_idx(key->idx) == 0) { + return CRYPT_INVALID_ARG; + } + numlen = key->dp->size; + + if (*outlen < (1 + 2*numlen)) { + *outlen = 1 + 2*numlen; + return CRYPT_BUFFER_OVERFLOW; + } + + /* store byte 0x04 */ + out[0] = 0x04; + + /* pad and store x */ + zeromem(buf, sizeof(buf)); + mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - mp_unsigned_bin_size(key->pubkey.x))); + XMEMCPY(out+1, buf, numlen); + + /* pad and store y */ + zeromem(buf, sizeof(buf)); + mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - mp_unsigned_bin_size(key->pubkey.y))); + XMEMCPY(out+1+numlen, buf, numlen); + + *outlen = 1 + 2*numlen; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_ansi_x963_export.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_ansi_x963_import.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_ansi_x963_import.c new file mode 100644 index 0000000000..907bc2fdfe --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_ansi_x963_import.c @@ -0,0 +1,104 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "tomcrypt.h" + +/** + @file ecc_ansi_x963_import.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** Import an ANSI X9.63 format public key + @param in The input data to read + @param inlen The length of the input data + @param key [out] destination to store imported key \ +*/ +int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key) +{ + return ecc_ansi_x963_import_ex(in, inlen, key, NULL); +} + +int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp) +{ + int x, err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + + /* must be odd */ + if ((inlen & 1) == 0) { + return CRYPT_INVALID_ARG; + } + + /* init key */ + if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL) != CRYPT_OK) { + return CRYPT_MEM; + } + + /* check for 4, 6 or 7 */ + if (in[0] != 4 && in[0] != 6 && in[0] != 7) { + err = CRYPT_INVALID_PACKET; + goto error; + } + + /* read data */ + if ((err = mp_read_unsigned_bin(key->pubkey.x, (unsigned char *)in+1, (inlen-1)>>1)) != CRYPT_OK) { + goto error; + } + + if ((err = mp_read_unsigned_bin(key->pubkey.y, (unsigned char *)in+1+((inlen-1)>>1), (inlen-1)>>1)) != CRYPT_OK) { + goto error; + } + if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto error; } + + if (dp == NULL) { + /* determine the idx */ + for (x = 0; ltc_ecc_sets[x].size != 0; x++) { + if ((unsigned)ltc_ecc_sets[x].size >= ((inlen-1)>>1)) { + break; + } + } + if (ltc_ecc_sets[x].size == 0) { + err = CRYPT_INVALID_PACKET; + goto error; + } + /* set the idx */ + key->idx = x; + key->dp = <c_ecc_sets[x]; + } else { + if (((inlen-1)>>1) != (unsigned long) dp->size) { + err = CRYPT_INVALID_PACKET; + goto error; + } + key->idx = -1; + key->dp = dp; + } + key->type = PK_PUBLIC; + + /* we're done */ + return CRYPT_OK; +error: + mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_ansi_x963_import.c,v $ */ +/* $Revision: 1.11 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_decrypt_key.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_decrypt_key.c new file mode 100644 index 0000000000..50ef31d764 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_decrypt_key.c @@ -0,0 +1,149 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "tomcrypt.h" + +/** + @file ecc_decrypt_key.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** + Decrypt an ECC encrypted key + @param in The ciphertext + @param inlen The length of the ciphertext (octets) + @param out [out] The plaintext + @param outlen [in/out] The max size and resulting size of the plaintext + @param key The corresponding private ECC key + @return CRYPT_OK if successful +*/ +int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + ecc_key *key) +{ + unsigned char *ecc_shared, *skey, *pub_expt; + unsigned long x, y, hashOID[32]; + int hash, err; + ecc_key pubkey; + ltc_asn1_list decode[3]; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* right key type? */ + if (key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* decode to find out hash */ + LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0])); + + if ((err = der_decode_sequence(in, inlen, decode, 1)) != CRYPT_OK) { + return err; + } + + hash = find_hash_oid(hashOID, decode[0].size); + if (hash_is_valid(hash) != CRYPT_OK) { + return CRYPT_INVALID_PACKET; + } + + /* we now have the hash! */ + + /* allocate memory */ + pub_expt = XMALLOC(ECC_BUF_SIZE); + ecc_shared = XMALLOC(ECC_BUF_SIZE); + skey = XMALLOC(MAXBLOCKSIZE); + if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) { + if (pub_expt != NULL) { + XFREE(pub_expt); + } + if (ecc_shared != NULL) { + XFREE(ecc_shared); + } + if (skey != NULL) { + XFREE(skey); + } + return CRYPT_MEM; + } + LTC_SET_ASN1(decode, 1, LTC_ASN1_OCTET_STRING, pub_expt, ECC_BUF_SIZE); + LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING, skey, MAXBLOCKSIZE); + + /* read the structure in now */ + if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* import ECC key from packet */ + if ((err = ecc_import(decode[1].data, decode[1].size, &pubkey)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* make shared key */ + x = ECC_BUF_SIZE; + if ((err = ecc_shared_secret(key, &pubkey, ecc_shared, &x)) != CRYPT_OK) { + ecc_free(&pubkey); + goto LBL_ERR; + } + ecc_free(&pubkey); + + y = MIN(ECC_BUF_SIZE, MAXBLOCKSIZE); + if ((err = hash_memory(hash, ecc_shared, x, ecc_shared, &y)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* ensure the hash of the shared secret is at least as big as the encrypt itself */ + if (decode[2].size > y) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + /* avoid buffer overflow */ + if (*outlen < decode[2].size) { + *outlen = decode[2].size; + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + + /* Decrypt the key */ + for (x = 0; x < decode[2].size; x++) { + out[x] = skey[x] ^ ecc_shared[x]; + } + *outlen = x; + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(pub_expt, ECC_BUF_SIZE); + zeromem(ecc_shared, ECC_BUF_SIZE); + zeromem(skey, MAXBLOCKSIZE); +#endif + + XFREE(pub_expt); + XFREE(ecc_shared); + XFREE(skey); + + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_decrypt_key.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_encrypt_key.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_encrypt_key.c new file mode 100644 index 0000000000..2edb2914df --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_encrypt_key.c @@ -0,0 +1,135 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "tomcrypt.h" + +/** + @file ecc_encrypt_key.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** + Encrypt a symmetric key with ECC + @param in The symmetric key you want to encrypt + @param inlen The length of the key to encrypt (octets) + @param out [out] The destination for the ciphertext + @param outlen [in/out] The max size and resulting size of the ciphertext + @param prng An active PRNG state + @param wprng The index of the PRNG you wish to use + @param hash The index of the hash you want to use + @param key The ECC key you want to encrypt to + @return CRYPT_OK if successful +*/ +int ecc_encrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, int hash, + ecc_key *key) +{ + unsigned char *pub_expt, *ecc_shared, *skey; + ecc_key pubkey; + unsigned long x, y, pubkeysize; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* check that wprng/cipher/hash are not invalid */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + if (inlen > hash_descriptor[hash].hashsize) { + return CRYPT_INVALID_HASH; + } + + /* make a random key and export the public copy */ + if ((err = ecc_make_key_ex(prng, wprng, &pubkey, key->dp)) != CRYPT_OK) { + return err; + } + + pub_expt = XMALLOC(ECC_BUF_SIZE); + ecc_shared = XMALLOC(ECC_BUF_SIZE); + skey = XMALLOC(MAXBLOCKSIZE); + if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) { + if (pub_expt != NULL) { + XFREE(pub_expt); + } + if (ecc_shared != NULL) { + XFREE(ecc_shared); + } + if (skey != NULL) { + XFREE(skey); + } + ecc_free(&pubkey); + return CRYPT_MEM; + } + + pubkeysize = ECC_BUF_SIZE; + if ((err = ecc_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) { + ecc_free(&pubkey); + goto LBL_ERR; + } + + /* make random key */ + x = ECC_BUF_SIZE; + if ((err = ecc_shared_secret(&pubkey, key, ecc_shared, &x)) != CRYPT_OK) { + ecc_free(&pubkey); + goto LBL_ERR; + } + ecc_free(&pubkey); + y = MAXBLOCKSIZE; + if ((err = hash_memory(hash, ecc_shared, x, skey, &y)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* Encrypt key */ + for (x = 0; x < inlen; x++) { + skey[x] ^= in[x]; + } + + err = der_encode_sequence_multi(out, outlen, + LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash].OIDlen, hash_descriptor[hash].OID, + LTC_ASN1_OCTET_STRING, pubkeysize, pub_expt, + LTC_ASN1_OCTET_STRING, inlen, skey, + LTC_ASN1_EOL, 0UL, NULL); + +LBL_ERR: +#ifdef LTC_CLEAN_STACK + /* clean up */ + zeromem(pub_expt, ECC_BUF_SIZE); + zeromem(ecc_shared, ECC_BUF_SIZE); + zeromem(skey, MAXBLOCKSIZE); +#endif + + XFREE(skey); + XFREE(ecc_shared); + XFREE(pub_expt); + + return err; +} + +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_encrypt_key.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_export.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_export.c new file mode 100644 index 0000000000..e2c4305753 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_export.c @@ -0,0 +1,81 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "tomcrypt.h" + +/** + @file ecc_export.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** + Export an ECC key as a binary packet + @param out [out] Destination for the key + @param outlen [in/out] Max size and resulting size of the exported key + @param type The type of key you want to export (PK_PRIVATE or PK_PUBLIC) + @param key The key to export + @return CRYPT_OK if successful +*/ +int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key) +{ + int err; + unsigned char flags[1]; + unsigned long key_size; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* type valid? */ + if (key->type != PK_PRIVATE && type == PK_PRIVATE) { + return CRYPT_PK_TYPE_MISMATCH; + } + + if (ltc_ecc_is_valid_idx(key->idx) == 0) { + return CRYPT_INVALID_ARG; + } + + /* we store the NIST byte size */ + key_size = key->dp->size; + + if (type == PK_PRIVATE) { + flags[0] = 1; + err = der_encode_sequence_multi(out, outlen, + LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, + LTC_ASN1_INTEGER, 1UL, key->pubkey.x, + LTC_ASN1_INTEGER, 1UL, key->pubkey.y, + LTC_ASN1_INTEGER, 1UL, key->k, + LTC_ASN1_EOL, 0UL, NULL); + } else { + flags[0] = 0; + err = der_encode_sequence_multi(out, outlen, + LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, + LTC_ASN1_INTEGER, 1UL, key->pubkey.x, + LTC_ASN1_INTEGER, 1UL, key->pubkey.y, + LTC_ASN1_EOL, 0UL, NULL); + } + + return err; +} + +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_export.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_free.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_free.c new file mode 100644 index 0000000000..c78c72ed03 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_free.c @@ -0,0 +1,39 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "tomcrypt.h" + +/** + @file ecc_free.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** + Free an ECC key from memory + @param key The key you wish to free +*/ +void ecc_free(ecc_key *key) +{ + LTC_ARGCHKVD(key != NULL); + mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL); +} + +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_free.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_get_size.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_get_size.c new file mode 100644 index 0000000000..29a68e7a78 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_get_size.c @@ -0,0 +1,43 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "tomcrypt.h" + +/** + @file ecc_get_size.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** + Get the size of an ECC key + @param key The key to get the size of + @return The size (octets) of the key or INT_MAX on error +*/ +int ecc_get_size(ecc_key *key) +{ + LTC_ARGCHK(key != NULL); + if (ltc_ecc_is_valid_idx(key->idx)) + return key->dp->size; + else + return INT_MAX; /* large value known to cause it to fail when passed to ecc_make_key() */ +} + +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_get_size.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_import.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_import.c new file mode 100644 index 0000000000..9156b090bd --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_import.c @@ -0,0 +1,171 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "tomcrypt.h" + +/** + @file ecc_import.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +static int is_point(ecc_key *key) +{ + void *prime, *b, *t1, *t2; + int err; + + if ((err = mp_init_multi(&prime, &b, &t1, &t2, NULL)) != CRYPT_OK) { + return err; + } + + /* load prime and b */ + if ((err = mp_read_radix(prime, key->dp->prime, 16)) != CRYPT_OK) { goto error; } + if ((err = mp_read_radix(b, key->dp->B, 16)) != CRYPT_OK) { goto error; } + + /* compute y^2 */ + if ((err = mp_sqr(key->pubkey.y, t1)) != CRYPT_OK) { goto error; } + + /* compute x^3 */ + if ((err = mp_sqr(key->pubkey.x, t2)) != CRYPT_OK) { goto error; } + if ((err = mp_mod(t2, prime, t2)) != CRYPT_OK) { goto error; } + if ((err = mp_mul(key->pubkey.x, t2, t2)) != CRYPT_OK) { goto error; } + + /* compute y^2 - x^3 */ + if ((err = mp_sub(t1, t2, t1)) != CRYPT_OK) { goto error; } + + /* compute y^2 - x^3 + 3x */ + if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; } + if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; } + if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; } + if ((err = mp_mod(t1, prime, t1)) != CRYPT_OK) { goto error; } + while (mp_cmp_d(t1, 0) == LTC_MP_LT) { + if ((err = mp_add(t1, prime, t1)) != CRYPT_OK) { goto error; } + } + while (mp_cmp(t1, prime) != LTC_MP_LT) { + if ((err = mp_sub(t1, prime, t1)) != CRYPT_OK) { goto error; } + } + + /* compare to b */ + if (mp_cmp(t1, b) != LTC_MP_EQ) { + err = CRYPT_INVALID_PACKET; + } else { + err = CRYPT_OK; + } + +error: + mp_clear_multi(prime, b, t1, t2, NULL); + return err; +} + +/** + Import an ECC key from a binary packet + @param in The packet to import + @param inlen The length of the packet + @param key [out] The destination of the import + @return CRYPT_OK if successful, upon error all allocated memory will be freed +*/ +int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key) +{ + return ecc_import_ex(in, inlen, key, NULL); +} + +/** + Import an ECC key from a binary packet, using user supplied domain params rather than one of the NIST ones + @param in The packet to import + @param inlen The length of the packet + @param key [out] The destination of the import + @param dp pointer to user supplied params; must be the same as the params used when exporting + @return CRYPT_OK if successful, upon error all allocated memory will be freed +*/ +int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp) +{ + unsigned long key_size; + unsigned char flags[1]; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + + /* init key */ + if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL) != CRYPT_OK) { + return CRYPT_MEM; + } + + /* find out what type of key it is */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_BIT_STRING, 1UL, &flags, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto done; + } + + + if (flags[0] == 1) { + /* private key */ + key->type = PK_PRIVATE; + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, + LTC_ASN1_INTEGER, 1UL, key->pubkey.x, + LTC_ASN1_INTEGER, 1UL, key->pubkey.y, + LTC_ASN1_INTEGER, 1UL, key->k, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto done; + } + } else { + /* public key */ + key->type = PK_PUBLIC; + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, + LTC_ASN1_INTEGER, 1UL, key->pubkey.x, + LTC_ASN1_INTEGER, 1UL, key->pubkey.y, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto done; + } + } + + if (dp == NULL) { + /* find the idx */ + for (key->idx = 0; ltc_ecc_sets[key->idx].size && (unsigned long)ltc_ecc_sets[key->idx].size != key_size; ++key->idx); + if (ltc_ecc_sets[key->idx].size == 0) { + err = CRYPT_INVALID_PACKET; + goto done; + } + key->dp = <c_ecc_sets[key->idx]; + } else { + key->idx = -1; + key->dp = dp; + } + /* set z */ + if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto done; } + + /* is it a point on the curve? */ + if ((err = is_point(key)) != CRYPT_OK) { + goto done; + } + + /* we're good */ + return CRYPT_OK; +done: + mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL); + return err; +} +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_import.c,v $ */ +/* $Revision: 1.13 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_make_key.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_make_key.c new file mode 100644 index 0000000000..943964418b --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_make_key.c @@ -0,0 +1,129 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "tomcrypt.h" + +/** + @file ecc_make_key.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** + Make a new ECC key + @param prng An active PRNG state + @param wprng The index of the PRNG you wish to use + @param keysize The keysize for the new key (in octets from 20 to 65 bytes) + @param key [out] Destination of the newly created key + @return CRYPT_OK if successful, upon error all allocated memory will be freed +*/ +int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key) +{ + int x, err; + + /* find key size */ + for (x = 0; (keysize > ltc_ecc_sets[x].size) && (ltc_ecc_sets[x].size != 0); x++); + keysize = ltc_ecc_sets[x].size; + + if (keysize > ECC_MAXSIZE || ltc_ecc_sets[x].size == 0) { + return CRYPT_INVALID_KEYSIZE; + } + err = ecc_make_key_ex(prng, wprng, key, <c_ecc_sets[x]); + key->idx = x; + return err; +} + +int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp) +{ + int err; + ecc_point *base; + void *prime, *order; + unsigned char *buf; + int keysize; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + LTC_ARGCHK(dp != NULL); + + /* good prng? */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + key->idx = -1; + key->dp = dp; + keysize = dp->size; + + /* allocate ram */ + base = NULL; + buf = XMALLOC(ECC_MAXSIZE); + if (buf == NULL) { + return CRYPT_MEM; + } + + /* make up random string */ + if (prng_descriptor[wprng].read(buf, (unsigned long)keysize, prng) != (unsigned long)keysize) { + err = CRYPT_ERROR_READPRNG; + goto ERR_BUF; + } + + /* setup the key variables */ + if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, &order, NULL)) != CRYPT_OK) { + goto ERR_BUF; + } + base = ltc_ecc_new_point(); + if (base == NULL) { + err = CRYPT_MEM; + goto errkey; + } + + /* read in the specs for this key */ + if ((err = mp_read_radix(prime, (char *)key->dp->prime, 16)) != CRYPT_OK) { goto errkey; } + if ((err = mp_read_radix(order, (char *)key->dp->order, 16)) != CRYPT_OK) { goto errkey; } + if ((err = mp_read_radix(base->x, (char *)key->dp->Gx, 16)) != CRYPT_OK) { goto errkey; } + if ((err = mp_read_radix(base->y, (char *)key->dp->Gy, 16)) != CRYPT_OK) { goto errkey; } + if ((err = mp_set(base->z, 1)) != CRYPT_OK) { goto errkey; } + if ((err = mp_read_unsigned_bin(key->k, (unsigned char *)buf, keysize)) != CRYPT_OK) { goto errkey; } + + /* the key should be smaller than the order of base point */ + if (mp_cmp(key->k, order) != LTC_MP_LT) { + if((err = mp_mod(key->k, order, key->k)) != CRYPT_OK) { goto errkey; } + } + /* make the public key */ + if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, prime, 1)) != CRYPT_OK) { goto errkey; } + key->type = PK_PRIVATE; + + /* free up ram */ + err = CRYPT_OK; + goto cleanup; +errkey: + mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL); +cleanup: + ltc_ecc_del_point(base); + mp_clear_multi(prime, order, NULL); +ERR_BUF: +#ifdef LTC_CLEAN_STACK + zeromem(buf, ECC_MAXSIZE); +#endif + XFREE(buf); + return err; +} + +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_make_key.c,v $ */ +/* $Revision: 1.13 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_shared_secret.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_shared_secret.c new file mode 100644 index 0000000000..b79aa33b72 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_shared_secret.c @@ -0,0 +1,94 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "tomcrypt.h" + +/** + @file ecc_shared_secret.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** + Create an ECC shared secret between two keys + @param private_key The private ECC key + @param public_key The public key + @param out [out] Destination of the shared secret (Conforms to EC-DH from ANSI X9.63) + @param outlen [in/out] The max size and resulting size of the shared secret + @return CRYPT_OK if successful +*/ +int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x; + ecc_point *result; + void *prime; + int err; + + LTC_ARGCHK(private_key != NULL); + LTC_ARGCHK(public_key != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* type valid? */ + if (private_key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + if (ltc_ecc_is_valid_idx(private_key->idx) == 0 || ltc_ecc_is_valid_idx(public_key->idx) == 0) { + return CRYPT_INVALID_ARG; + } + + if (XSTRCMP(private_key->dp->name, public_key->dp->name) != 0) { + return CRYPT_PK_TYPE_MISMATCH; + } + + /* make new point */ + result = ltc_ecc_new_point(); + if (result == NULL) { + return CRYPT_MEM; + } + + if ((err = mp_init(&prime)) != CRYPT_OK) { + ltc_ecc_del_point(result); + return err; + } + + if ((err = mp_read_radix(prime, (char *)private_key->dp->prime, 16)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.ecc_ptmul(private_key->k, &public_key->pubkey, result, prime, 1)) != CRYPT_OK) { goto done; } + + x = (unsigned long)mp_unsigned_bin_size(prime); + if (*outlen < x) { + *outlen = x; + err = CRYPT_BUFFER_OVERFLOW; + goto done; + } + zeromem(out, x); + if ((err = mp_to_unsigned_bin(result->x, out + (x - mp_unsigned_bin_size(result->x)))) != CRYPT_OK) { goto done; } + + err = CRYPT_OK; + *outlen = x; +done: + mp_clear(prime); + ltc_ecc_del_point(result); + return err; +} + +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_shared_secret.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_sign_hash.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_sign_hash.c new file mode 100644 index 0000000000..e891b15977 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_sign_hash.c @@ -0,0 +1,113 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "tomcrypt.h" + +/** + @file ecc_sign_hash.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** + Sign a message digest + @param in The message digest to sign + @param inlen The length of the digest + @param out [out] The destination for the signature + @param outlen [in/out] The max size and resulting size of the signature + @param prng An active PRNG state + @param wprng The index of the PRNG you wish to use + @param key A private ECC key + @return CRYPT_OK if successful +*/ +int ecc_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, ecc_key *key) +{ + ecc_key pubkey; + void *r, *s, *e, *p; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* is this a private key? */ + if (key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* is the IDX valid ? */ + if (ltc_ecc_is_valid_idx(key->idx) != 1) { + return CRYPT_PK_INVALID_TYPE; + } + + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* get the hash and load it as a bignum into 'e' */ + /* init the bignums */ + if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != CRYPT_OK) { + return err; + } + if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK) { goto errnokey; } + if ((err = mp_read_unsigned_bin(e, (unsigned char *)in, (int)inlen)) != CRYPT_OK) { goto errnokey; } + + /* make up a key and export the public copy */ + for (;;) { + if ((err = ecc_make_key_ex(prng, wprng, &pubkey, key->dp)) != CRYPT_OK) { + goto errnokey; + } + + /* find r = x1 mod n */ + if ((err = mp_mod(pubkey.pubkey.x, p, r)) != CRYPT_OK) { goto error; } + + if (mp_iszero(r) == LTC_MP_YES) { + ecc_free(&pubkey); + } else { + /* find s = (e + xr)/k */ + if ((err = mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK) { goto error; } /* k = 1/k */ + if ((err = mp_mulmod(key->k, r, p, s)) != CRYPT_OK) { goto error; } /* s = xr */ + if ((err = mp_add(e, s, s)) != CRYPT_OK) { goto error; } /* s = e + xr */ + if ((err = mp_mod(s, p, s)) != CRYPT_OK) { goto error; } /* s = e + xr */ + if ((err = mp_mulmod(s, pubkey.k, p, s)) != CRYPT_OK) { goto error; } /* s = (e + xr)/k */ + ecc_free(&pubkey); + if (mp_iszero(s) == LTC_MP_NO) { + break; + } + } + } + + /* store as SEQUENCE { r, s -- integer } */ + err = der_encode_sequence_multi(out, outlen, + LTC_ASN1_INTEGER, 1UL, r, + LTC_ASN1_INTEGER, 1UL, s, + LTC_ASN1_EOL, 0UL, NULL); + goto errnokey; +error: + ecc_free(&pubkey); +errnokey: + mp_clear_multi(r, s, p, e, NULL); + return err; +} + +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_sign_hash.c,v $ */ +/* $Revision: 1.11 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_sizes.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_sizes.c new file mode 100644 index 0000000000..71509f8a56 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_sizes.c @@ -0,0 +1,47 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "tomcrypt.h" + +/** + @file ecc_sizes.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +void ecc_sizes(int *low, int *high) +{ + int i; + LTC_ARGCHKVD(low != NULL); + LTC_ARGCHKVD(high != NULL); + + *low = INT_MAX; + *high = 0; + for (i = 0; ltc_ecc_sets[i].size != 0; i++) { + if (ltc_ecc_sets[i].size < *low) { + *low = ltc_ecc_sets[i].size; + } + if (ltc_ecc_sets[i].size > *high) { + *high = ltc_ecc_sets[i].size; + } + } +} + +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_sizes.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_test.c new file mode 100644 index 0000000000..26930ea14b --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_test.c @@ -0,0 +1,94 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "tomcrypt.h" + +/** + @file ecc_test.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** + Perform on the ECC system + @return CRYPT_OK if successful +*/ +int ecc_test(void) +{ + void *modulus, *order; + ecc_point *G, *GG; + int i, err, primality; + + if ((err = mp_init_multi(&modulus, &order, NULL)) != CRYPT_OK) { + return err; + } + + G = ltc_ecc_new_point(); + GG = ltc_ecc_new_point(); + if (G == NULL || GG == NULL) { + mp_clear_multi(modulus, order, NULL); + ltc_ecc_del_point(G); + ltc_ecc_del_point(GG); + return CRYPT_MEM; + } + + for (i = 0; ltc_ecc_sets[i].size; i++) { + #if 0 + printf("Testing %d\n", ltc_ecc_sets[i].size); + #endif + if ((err = mp_read_radix(modulus, (char *)ltc_ecc_sets[i].prime, 16)) != CRYPT_OK) { goto done; } + if ((err = mp_read_radix(order, (char *)ltc_ecc_sets[i].order, 16)) != CRYPT_OK) { goto done; } + + /* is prime actually prime? */ + if ((err = mp_prime_is_prime(modulus, 8, &primality)) != CRYPT_OK) { goto done; } + if (primality == 0) { + err = CRYPT_FAIL_TESTVECTOR; + goto done; + } + + /* is order prime ? */ + if ((err = mp_prime_is_prime(order, 8, &primality)) != CRYPT_OK) { goto done; } + if (primality == 0) { + err = CRYPT_FAIL_TESTVECTOR; + goto done; + } + + if ((err = mp_read_radix(G->x, (char *)ltc_ecc_sets[i].Gx, 16)) != CRYPT_OK) { goto done; } + if ((err = mp_read_radix(G->y, (char *)ltc_ecc_sets[i].Gy, 16)) != CRYPT_OK) { goto done; } + mp_set(G->z, 1); + + /* then we should have G == (order + 1)G */ + if ((err = mp_add_d(order, 1, order)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.ecc_ptmul(order, G, GG, modulus, 1)) != CRYPT_OK) { goto done; } + if (mp_cmp(G->x, GG->x) != LTC_MP_EQ || mp_cmp(G->y, GG->y) != LTC_MP_EQ) { + err = CRYPT_FAIL_TESTVECTOR; + goto done; + } + } + err = CRYPT_OK; +done: + ltc_ecc_del_point(GG); + ltc_ecc_del_point(G); + mp_clear_multi(order, modulus, NULL); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_test.c,v $ */ +/* $Revision: 1.12 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_verify_hash.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_verify_hash.c new file mode 100644 index 0000000000..a8e7a370cf --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ecc_verify_hash.c @@ -0,0 +1,164 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "tomcrypt.h" + +/** + @file ecc_verify_hash.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/* verify + * + * w = s^-1 mod n + * u1 = xw + * u2 = rw + * X = u1*G + u2*Q + * v = X_x1 mod n + * accept if v == r + */ + +/** + Verify an ECC signature + @param sig The signature to verify + @param siglen The length of the signature (octets) + @param hash The hash (message digest) that was signed + @param hashlen The length of the hash (octets) + @param stat Result of signature, 1==valid, 0==invalid + @param key The corresponding public ECC key + @return CRYPT_OK if successful (even if the signature is not valid) +*/ +int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, ecc_key *key) +{ + ecc_point *mG, *mQ; + void *r, *s, *v, *w, *u1, *u2, *e, *p, *m; + void *mp; + int err; + + LTC_ARGCHK(sig != NULL); + LTC_ARGCHK(hash != NULL); + LTC_ARGCHK(stat != NULL); + LTC_ARGCHK(key != NULL); + + /* default to invalid signature */ + *stat = 0; + mp = NULL; + + /* is the IDX valid ? */ + if (ltc_ecc_is_valid_idx(key->idx) != 1) { + return CRYPT_PK_INVALID_TYPE; + } + + /* allocate ints */ + if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, NULL)) != CRYPT_OK) { + return CRYPT_MEM; + } + + /* allocate points */ + mG = ltc_ecc_new_point(); + mQ = ltc_ecc_new_point(); + if (mQ == NULL || mG == NULL) { + err = CRYPT_MEM; + goto error; + } + + /* parse header */ + if ((err = der_decode_sequence_multi(sig, siglen, + LTC_ASN1_INTEGER, 1UL, r, + LTC_ASN1_INTEGER, 1UL, s, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto error; + } + + /* get the order */ + if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK) { goto error; } + + /* get the modulus */ + if ((err = mp_read_radix(m, (char *)key->dp->prime, 16)) != CRYPT_OK) { goto error; } + + /* check for zero */ + if (mp_iszero(r) || mp_iszero(s) || mp_cmp(r, p) != LTC_MP_LT || mp_cmp(s, p) != LTC_MP_LT) { + err = CRYPT_INVALID_PACKET; + goto error; + } + + /* read hash */ + if ((err = mp_read_unsigned_bin(e, (unsigned char *)hash, (int)hashlen)) != CRYPT_OK) { goto error; } + + /* w = s^-1 mod n */ + if ((err = mp_invmod(s, p, w)) != CRYPT_OK) { goto error; } + + /* u1 = ew */ + if ((err = mp_mulmod(e, w, p, u1)) != CRYPT_OK) { goto error; } + + /* u2 = rw */ + if ((err = mp_mulmod(r, w, p, u2)) != CRYPT_OK) { goto error; } + + /* find mG and mQ */ + if ((err = mp_read_radix(mG->x, (char *)key->dp->Gx, 16)) != CRYPT_OK) { goto error; } + if ((err = mp_read_radix(mG->y, (char *)key->dp->Gy, 16)) != CRYPT_OK) { goto error; } + if ((err = mp_set(mG->z, 1)) != CRYPT_OK) { goto error; } + + if ((err = mp_copy(key->pubkey.x, mQ->x)) != CRYPT_OK) { goto error; } + if ((err = mp_copy(key->pubkey.y, mQ->y)) != CRYPT_OK) { goto error; } + if ((err = mp_copy(key->pubkey.z, mQ->z)) != CRYPT_OK) { goto error; } + + /* compute u1*mG + u2*mQ = mG */ + if (ltc_mp.ecc_mul2add == NULL) { + if ((err = ltc_mp.ecc_ptmul(u1, mG, mG, m, 0)) != CRYPT_OK) { goto error; } + if ((err = ltc_mp.ecc_ptmul(u2, mQ, mQ, m, 0)) != CRYPT_OK) { goto error; } + + /* find the montgomery mp */ + if ((err = mp_montgomery_setup(m, &mp)) != CRYPT_OK) { goto error; } + + /* add them */ + if ((err = ltc_mp.ecc_ptadd(mQ, mG, mG, m, mp)) != CRYPT_OK) { goto error; } + + /* reduce */ + if ((err = ltc_mp.ecc_map(mG, m, mp)) != CRYPT_OK) { goto error; } + } else { + /* use Shamir's trick to compute u1*mG + u2*mQ using half of the doubles */ + if ((err = ltc_mp.ecc_mul2add(mG, u1, mQ, u2, mG, m)) != CRYPT_OK) { goto error; } + } + + /* v = X_x1 mod n */ + if ((err = mp_mod(mG->x, p, v)) != CRYPT_OK) { goto error; } + + /* does v == r */ + if (mp_cmp(v, r) == LTC_MP_EQ) { + *stat = 1; + } + + /* clear up and return */ + err = CRYPT_OK; +error: + ltc_ecc_del_point(mG); + ltc_ecc_del_point(mQ); + mp_clear_multi(r, s, v, w, u1, u2, p, e, m, NULL); + if (mp != NULL) { + mp_montgomery_free(mp); + } + return err; +} + +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_verify_hash.c,v $ */ +/* $Revision: 1.14 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_is_valid_idx.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_is_valid_idx.c new file mode 100644 index 0000000000..c656f86b6d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_is_valid_idx.c @@ -0,0 +1,45 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "tomcrypt.h" + +/** + @file ltc_ecc_is_valid_idx.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** Returns whether an ECC idx is valid or not + @param n The idx number to check + @return 1 if valid, 0 if not +*/ +int ltc_ecc_is_valid_idx(int n) +{ + int x; + + for (x = 0; ltc_ecc_sets[x].size != 0; x++); + /* -1 is a valid index --- indicating that the domain params were supplied by the user */ + if ((n >= -1) && (n < x)) { + return 1; + } + return 0; +} + +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_is_valid_idx.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_map.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_map.c new file mode 100644 index 0000000000..f1eb8405b7 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_map.c @@ -0,0 +1,75 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "tomcrypt.h" + +/** + @file ltc_ecc_map.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** + Map a projective jacbobian point back to affine space + @param P [in/out] The point to map + @param modulus The modulus of the field the ECC curve is in + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success +*/ +int ltc_ecc_map(ecc_point *P, void *modulus, void *mp) +{ + void *t1, *t2; + int err; + + LTC_ARGCHK(P != NULL); + LTC_ARGCHK(modulus != NULL); + LTC_ARGCHK(mp != NULL); + + if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) { + return CRYPT_MEM; + } + + /* first map z back to normal */ + if ((err = mp_montgomery_reduce(P->z, modulus, mp)) != CRYPT_OK) { goto done; } + + /* get 1/z */ + if ((err = mp_invmod(P->z, modulus, t1)) != CRYPT_OK) { goto done; } + + /* get 1/z^2 and 1/z^3 */ + if ((err = mp_sqr(t1, t2)) != CRYPT_OK) { goto done; } + if ((err = mp_mod(t2, modulus, t2)) != CRYPT_OK) { goto done; } + if ((err = mp_mul(t1, t2, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_mod(t1, modulus, t1)) != CRYPT_OK) { goto done; } + + /* multiply against x/y */ + if ((err = mp_mul(P->x, t2, P->x)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(P->x, modulus, mp)) != CRYPT_OK) { goto done; } + if ((err = mp_mul(P->y, t1, P->y)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(P->y, modulus, mp)) != CRYPT_OK) { goto done; } + if ((err = mp_set(P->z, 1)) != CRYPT_OK) { goto done; } + + err = CRYPT_OK; +done: + mp_clear_multi(t1, t2, NULL); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_map.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c new file mode 100644 index 0000000000..b47f30f7ae --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c @@ -0,0 +1,207 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "tomcrypt.h" + +/** + @file ltc_ecc_mul2add.c + ECC Crypto, Shamir's Trick, Tom St Denis +*/ + +#ifdef LTC_MECC + +#ifdef LTC_ECC_SHAMIR + +/** Computes kA*A + kB*B = C using Shamir's Trick + @param A First point to multiply + @param kA What to multiple A by + @param B Second point to multiply + @param kB What to multiple B by + @param C [out] Destination point (can overlap with A or B + @param modulus Modulus for curve + @return CRYPT_OK on success +*/ +int ltc_ecc_mul2add(ecc_point *A, void *kA, + ecc_point *B, void *kB, + ecc_point *C, + void *modulus) +{ + ecc_point *precomp[16]; + unsigned bitbufA, bitbufB, lenA, lenB, len, x, y, nA, nB, nibble; + unsigned char *tA, *tB; + int err, first; + void *mp, *mu; + + /* argchks */ + LTC_ARGCHK(A != NULL); + LTC_ARGCHK(B != NULL); + LTC_ARGCHK(C != NULL); + LTC_ARGCHK(kA != NULL); + LTC_ARGCHK(kB != NULL); + LTC_ARGCHK(modulus != NULL); + + /* allocate memory */ + tA = XCALLOC(1, ECC_BUF_SIZE); + if (tA == NULL) { + return CRYPT_MEM; + } + tB = XCALLOC(1, ECC_BUF_SIZE); + if (tB == NULL) { + XFREE(tA); + return CRYPT_MEM; + } + + /* get sizes */ + lenA = mp_unsigned_bin_size(kA); + lenB = mp_unsigned_bin_size(kB); + len = MAX(lenA, lenB); + + /* sanity check */ + if ((lenA > ECC_BUF_SIZE) || (lenB > ECC_BUF_SIZE)) { + err = CRYPT_INVALID_ARG; + goto ERR_T; + } + + /* extract and justify kA */ + mp_to_unsigned_bin(kA, (len - lenA) + tA); + + /* extract and justify kB */ + mp_to_unsigned_bin(kB, (len - lenB) + tB); + + /* allocate the table */ + for (x = 0; x < 16; x++) { + precomp[x] = ltc_ecc_new_point(); + if (precomp[x] == NULL) { + for (y = 0; y < x; ++y) { + ltc_ecc_del_point(precomp[y]); + } + err = CRYPT_MEM; + goto ERR_T; + } + } + + /* init montgomery reduction */ + if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { + goto ERR_P; + } + if ((err = mp_init(&mu)) != CRYPT_OK) { + goto ERR_MP; + } + if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { + goto ERR_MU; + } + + /* copy ones ... */ + if ((err = mp_mulmod(A->x, mu, modulus, precomp[1]->x)) != CRYPT_OK) { goto ERR_MU; } + if ((err = mp_mulmod(A->y, mu, modulus, precomp[1]->y)) != CRYPT_OK) { goto ERR_MU; } + if ((err = mp_mulmod(A->z, mu, modulus, precomp[1]->z)) != CRYPT_OK) { goto ERR_MU; } + + if ((err = mp_mulmod(B->x, mu, modulus, precomp[1<<2]->x)) != CRYPT_OK) { goto ERR_MU; } + if ((err = mp_mulmod(B->y, mu, modulus, precomp[1<<2]->y)) != CRYPT_OK) { goto ERR_MU; } + if ((err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z)) != CRYPT_OK) { goto ERR_MU; } + + /* precomp [i,0](A + B) table */ + if ((err = ltc_mp.ecc_ptdbl(precomp[1], precomp[2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + if ((err = ltc_mp.ecc_ptadd(precomp[1], precomp[2], precomp[3], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + + /* precomp [0,i](A + B) table */ + if ((err = ltc_mp.ecc_ptdbl(precomp[1<<2], precomp[2<<2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + if ((err = ltc_mp.ecc_ptadd(precomp[1<<2], precomp[2<<2], precomp[3<<2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + + /* precomp [i,j](A + B) table (i != 0, j != 0) */ + for (x = 1; x < 4; x++) { + for (y = 1; y < 4; y++) { + if ((err = ltc_mp.ecc_ptadd(precomp[x], precomp[(y<<2)], precomp[x+(y<<2)], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + } + } + + nibble = 3; + first = 1; + bitbufA = tA[0]; + bitbufB = tB[0]; + + /* for every byte of the multiplicands */ + for (x = -1;; ) { + /* grab a nibble */ + if (++nibble == 4) { + ++x; if (x == len) break; + bitbufA = tA[x]; + bitbufB = tB[x]; + nibble = 0; + } + + /* extract two bits from both, shift/update */ + nA = (bitbufA >> 6) & 0x03; + nB = (bitbufB >> 6) & 0x03; + bitbufA = (bitbufA << 2) & 0xFF; + bitbufB = (bitbufB << 2) & 0xFF; + + /* if both zero, if first, continue */ + if ((nA == 0) && (nB == 0) && (first == 1)) { + continue; + } + + /* double twice, only if this isn't the first */ + if (first == 0) { + /* double twice */ + if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + } + + /* if not both zero */ + if ((nA != 0) || (nB != 0)) { + if (first == 1) { + /* if first, copy from table */ + first = 0; + if ((err = mp_copy(precomp[nA + (nB<<2)]->x, C->x)) != CRYPT_OK) { goto ERR_MU; } + if ((err = mp_copy(precomp[nA + (nB<<2)]->y, C->y)) != CRYPT_OK) { goto ERR_MU; } + if ((err = mp_copy(precomp[nA + (nB<<2)]->z, C->z)) != CRYPT_OK) { goto ERR_MU; } + } else { + /* if not first, add from table */ + if ((err = ltc_mp.ecc_ptadd(C, precomp[nA + (nB<<2)], C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + } + } + } + + /* reduce to affine */ + err = ltc_ecc_map(C, modulus, mp); + + /* clean up */ +ERR_MU: + mp_clear(mu); +ERR_MP: + mp_montgomery_free(mp); +ERR_P: + for (x = 0; x < 16; x++) { + ltc_ecc_del_point(precomp[x]); + } +ERR_T: +#ifdef LTC_CLEAN_STACK + zeromem(tA, ECC_BUF_SIZE); + zeromem(tB, ECC_BUF_SIZE); +#endif + XFREE(tA); + XFREE(tB); + + return err; +} + +#endif +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c new file mode 100644 index 0000000000..7b77321e8c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c @@ -0,0 +1,222 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "tomcrypt.h" + +/** + @file ltc_ecc_mulmod.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC +#ifndef LTC_ECC_TIMING_RESISTANT + +/* size of sliding window, don't change this! */ +#define WINSIZE 4 + +/** + Perform a point multiplication + @param k The scalar to multiply by + @param G The base point + @param R [out] Destination for kG + @param modulus The modulus of the field the ECC curve is in + @param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective) + @return CRYPT_OK on success +*/ +int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map) +{ + ecc_point *tG, *M[8]; + int i, j, err; + void *mu, *mp; + unsigned long buf; + int first, bitbuf, bitcpy, bitcnt, mode, digidx; + + LTC_ARGCHK(k != NULL); + LTC_ARGCHK(G != NULL); + LTC_ARGCHK(R != NULL); + LTC_ARGCHK(modulus != NULL); + + /* init montgomery reduction */ + if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { + return err; + } + if ((err = mp_init(&mu)) != CRYPT_OK) { + mp_montgomery_free(mp); + return err; + } + if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { + mp_montgomery_free(mp); + mp_clear(mu); + return err; + } + + /* alloc ram for window temps */ + for (i = 0; i < 8; i++) { + M[i] = ltc_ecc_new_point(); + if (M[i] == NULL) { + for (j = 0; j < i; j++) { + ltc_ecc_del_point(M[j]); + } + mp_montgomery_free(mp); + mp_clear(mu); + return CRYPT_MEM; + } + } + + /* make a copy of G incase R==G */ + tG = ltc_ecc_new_point(); + if (tG == NULL) { err = CRYPT_MEM; goto done; } + + /* tG = G and convert to montgomery */ + if (mp_cmp_d(mu, 1) == LTC_MP_EQ) { + if ((err = mp_copy(G->x, tG->x)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(G->y, tG->y)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(G->z, tG->z)) != CRYPT_OK) { goto done; } + } else { + if ((err = mp_mulmod(G->x, mu, modulus, tG->x)) != CRYPT_OK) { goto done; } + if ((err = mp_mulmod(G->y, mu, modulus, tG->y)) != CRYPT_OK) { goto done; } + if ((err = mp_mulmod(G->z, mu, modulus, tG->z)) != CRYPT_OK) { goto done; } + } + mp_clear(mu); + mu = NULL; + + /* calc the M tab, which holds kG for k==8..15 */ + /* M[0] == 8G */ + if ((err = ltc_mp.ecc_ptdbl(tG, M[0], modulus, mp)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], modulus, mp)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], modulus, mp)) != CRYPT_OK) { goto done; } + + /* now find (8+k)G for k=1..7 */ + for (j = 9; j < 16; j++) { + if ((err = ltc_mp.ecc_ptadd(M[j-9], tG, M[j-8], modulus, mp)) != CRYPT_OK) { goto done; } + } + + /* setup sliding window */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = mp_get_digit_count(k) - 1; + bitcpy = bitbuf = 0; + first = 1; + + /* perform ops */ + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + if (digidx == -1) { + break; + } + buf = mp_get_digit(k, digidx); + bitcnt = (int) ltc_mp.bits_per_digit; + --digidx; + } + + /* grab the next msb from the ltiplicand */ + i = (buf >> (ltc_mp.bits_per_digit - 1)) & 1; + buf <<= 1; + + /* skip leading zero bits */ + if (mode == 0 && i == 0) { + continue; + } + + /* if the bit is zero and mode == 1 then we double */ + if (mode == 1 && i == 0) { + if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; } + continue; + } + + /* else we add it to the window */ + bitbuf |= (i << (WINSIZE - ++bitcpy)); + mode = 2; + + if (bitcpy == WINSIZE) { + /* if this is the first window we do a simple copy */ + if (first == 1) { + /* R = kG [k = first window] */ + if ((err = mp_copy(M[bitbuf-8]->x, R->x)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(M[bitbuf-8]->y, R->y)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(M[bitbuf-8]->z, R->z)) != CRYPT_OK) { goto done; } + first = 0; + } else { + /* normal window */ + /* ok window is filled so double as required and add */ + /* double first */ + for (j = 0; j < WINSIZE; j++) { + if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; } + } + + /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */ + if ((err = ltc_mp.ecc_ptadd(R, M[bitbuf-8], R, modulus, mp)) != CRYPT_OK) { goto done; } + } + /* empty window and reset */ + bitcpy = bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then double/add */ + if (mode == 2 && bitcpy > 0) { + /* double then add */ + for (j = 0; j < bitcpy; j++) { + /* only double if we have had at least one add first */ + if (first == 0) { + if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; } + } + + bitbuf <<= 1; + if ((bitbuf & (1 << WINSIZE)) != 0) { + if (first == 1){ + /* first add, so copy */ + if ((err = mp_copy(tG->x, R->x)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(tG->y, R->y)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(tG->z, R->z)) != CRYPT_OK) { goto done; } + first = 0; + } else { + /* then add */ + if ((err = ltc_mp.ecc_ptadd(R, tG, R, modulus, mp)) != CRYPT_OK) { goto done; } + } + } + } + } + + /* map R back from projective space */ + if (map) { + err = ltc_ecc_map(R, modulus, mp); + } else { + err = CRYPT_OK; + } +done: + if (mu != NULL) { + mp_clear(mu); + } + mp_montgomery_free(mp); + ltc_ecc_del_point(tG); + for (i = 0; i < 8; i++) { + ltc_ecc_del_point(M[i]); + } + return err; +} + +#endif + +#undef WINSIZE + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c,v $ */ +/* $Revision: 1.26 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod_timing.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod_timing.c new file mode 100644 index 0000000000..da7ac82670 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod_timing.c @@ -0,0 +1,166 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "tomcrypt.h" + +/** + @file ltc_ecc_mulmod_timing.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +#ifdef LTC_ECC_TIMING_RESISTANT + +/** + Perform a point multiplication (timing resistant) + @param k The scalar to multiply by + @param G The base point + @param R [out] Destination for kG + @param modulus The modulus of the field the ECC curve is in + @param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective) + @return CRYPT_OK on success +*/ +int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map) +{ + ecc_point *tG, *M[3]; + int i, j, err; + void *mu, *mp; + unsigned long buf; + int first, bitbuf, bitcpy, bitcnt, mode, digidx; + + LTC_ARGCHK(k != NULL); + LTC_ARGCHK(G != NULL); + LTC_ARGCHK(R != NULL); + LTC_ARGCHK(modulus != NULL); + + /* init montgomery reduction */ + if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { + return err; + } + if ((err = mp_init(&mu)) != CRYPT_OK) { + mp_montgomery_free(mp); + return err; + } + if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { + mp_clear(mu); + mp_montgomery_free(mp); + return err; + } + + /* alloc ram for window temps */ + for (i = 0; i < 3; i++) { + M[i] = ltc_ecc_new_point(); + if (M[i] == NULL) { + for (j = 0; j < i; j++) { + ltc_ecc_del_point(M[j]); + } + mp_clear(mu); + mp_montgomery_free(mp); + return CRYPT_MEM; + } + } + + /* make a copy of G incase R==G */ + tG = ltc_ecc_new_point(); + if (tG == NULL) { err = CRYPT_MEM; goto done; } + + /* tG = G and convert to montgomery */ + if ((err = mp_mulmod(G->x, mu, modulus, tG->x)) != CRYPT_OK) { goto done; } + if ((err = mp_mulmod(G->y, mu, modulus, tG->y)) != CRYPT_OK) { goto done; } + if ((err = mp_mulmod(G->z, mu, modulus, tG->z)) != CRYPT_OK) { goto done; } + mp_clear(mu); + mu = NULL; + + /* calc the M tab */ + /* M[0] == G */ + if ((err = mp_copy(tG->x, M[0]->x)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(tG->y, M[0]->y)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(tG->z, M[0]->z)) != CRYPT_OK) { goto done; } + /* M[1] == 2G */ + if ((err = ltc_mp.ecc_ptdbl(tG, M[1], modulus, mp)) != CRYPT_OK) { goto done; } + + /* setup sliding window */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = mp_get_digit_count(k) - 1; + bitcpy = bitbuf = 0; + first = 1; + + /* perform ops */ + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + if (digidx == -1) { + break; + } + buf = mp_get_digit(k, digidx); + bitcnt = (int) MP_DIGIT_BIT; + --digidx; + } + + /* grab the next msb from the ltiplicand */ + i = (buf >> (MP_DIGIT_BIT - 1)) & 1; + buf <<= 1; + + if (mode == 0 && i == 0) { + /* dummy operations */ + if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; } + continue; + } + + if (mode == 0 && i == 1) { + mode = 1; + /* dummy operations */ + if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; } + continue; + } + + if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[i^1], modulus, mp)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.ecc_ptdbl(M[i], M[i], modulus, mp)) != CRYPT_OK) { goto done; } + } + + /* copy result out */ + if ((err = mp_copy(M[0]->x, R->x)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(M[0]->y, R->y)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(M[0]->z, R->z)) != CRYPT_OK) { goto done; } + + /* map R back from projective space */ + if (map) { + err = ltc_ecc_map(R, modulus, mp); + } else { + err = CRYPT_OK; + } +done: + if (mu != NULL) { + mp_clear(mu); + } + mp_montgomery_free(mp); + ltc_ecc_del_point(tG); + for (i = 0; i < 3; i++) { + ltc_ecc_del_point(M[i]); + } + return err; +} + +#endif +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod_timing.c,v $ */ +/* $Revision: 1.13 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_points.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_points.c new file mode 100644 index 0000000000..2e4879fb20 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_points.c @@ -0,0 +1,59 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "tomcrypt.h" + +/** + @file ltc_ecc_points.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** + Allocate a new ECC point + @return A newly allocated point or NULL on error +*/ +ecc_point *ltc_ecc_new_point(void) +{ + ecc_point *p; + p = XCALLOC(1, sizeof(*p)); + if (p == NULL) { + return NULL; + } + if (mp_init_multi(&p->x, &p->y, &p->z, NULL) != CRYPT_OK) { + XFREE(p); + return NULL; + } + return p; +} + +/** Free an ECC point from memory + @param p The point to free +*/ +void ltc_ecc_del_point(ecc_point *p) +{ + /* prevents free'ing null arguments */ + if (p != NULL) { + mp_clear_multi(p->x, p->y, p->z, NULL); /* note: p->z may be NULL but that's ok with this function anyways */ + XFREE(p); + } +} + +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_points.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c new file mode 100644 index 0000000000..8b040a39b7 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c @@ -0,0 +1,195 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "tomcrypt.h" + +/** + @file ltc_ecc_projective_add_point.c + ECC Crypto, Tom St Denis +*/ + +#if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC)) + +/** + Add two ECC points + @param P The point to add + @param Q The point to add + @param R [out] The destination of the double + @param modulus The modulus of the field the ECC curve is in + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success +*/ +int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp) +{ + void *t1, *t2, *x, *y, *z; + int err; + + LTC_ARGCHK(P != NULL); + LTC_ARGCHK(Q != NULL); + LTC_ARGCHK(R != NULL); + LTC_ARGCHK(modulus != NULL); + LTC_ARGCHK(mp != NULL); + + if ((err = mp_init_multi(&t1, &t2, &x, &y, &z, NULL)) != CRYPT_OK) { + return err; + } + + /* should we dbl instead? */ + if ((err = mp_sub(modulus, Q->y, t1)) != CRYPT_OK) { goto done; } + + if ( (mp_cmp(P->x, Q->x) == LTC_MP_EQ) && + (Q->z != NULL && mp_cmp(P->z, Q->z) == LTC_MP_EQ) && + (mp_cmp(P->y, Q->y) == LTC_MP_EQ || mp_cmp(P->y, t1) == LTC_MP_EQ)) { + mp_clear_multi(t1, t2, x, y, z, NULL); + return ltc_ecc_projective_dbl_point(P, R, modulus, mp); + } + + if ((err = mp_copy(P->x, x)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(P->y, y)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(P->z, z)) != CRYPT_OK) { goto done; } + + /* if Z is one then these are no-operations */ + if (Q->z != NULL) { + /* T1 = Z' * Z' */ + if ((err = mp_sqr(Q->z, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + /* X = X * T1 */ + if ((err = mp_mul(t1, x, x)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; } + /* T1 = Z' * T1 */ + if ((err = mp_mul(Q->z, t1, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + /* Y = Y * T1 */ + if ((err = mp_mul(t1, y, y)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(y, modulus, mp)) != CRYPT_OK) { goto done; } + } + + /* T1 = Z*Z */ + if ((err = mp_sqr(z, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + /* T2 = X' * T1 */ + if ((err = mp_mul(Q->x, t1, t2)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } + /* T1 = Z * T1 */ + if ((err = mp_mul(z, t1, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + /* T1 = Y' * T1 */ + if ((err = mp_mul(Q->y, t1, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + + /* Y = Y - T1 */ + if ((err = mp_sub(y, t1, y)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(y, 0) == LTC_MP_LT) { + if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; } + } + /* T1 = 2T1 */ + if ((err = mp_add(t1, t1, t1)) != CRYPT_OK) { goto done; } + if (mp_cmp(t1, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } + } + /* T1 = Y + T1 */ + if ((err = mp_add(t1, y, t1)) != CRYPT_OK) { goto done; } + if (mp_cmp(t1, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } + } + /* X = X - T2 */ + if ((err = mp_sub(x, t2, x)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(x, 0) == LTC_MP_LT) { + if ((err = mp_add(x, modulus, x)) != CRYPT_OK) { goto done; } + } + /* T2 = 2T2 */ + if ((err = mp_add(t2, t2, t2)) != CRYPT_OK) { goto done; } + if (mp_cmp(t2, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t2, modulus, t2)) != CRYPT_OK) { goto done; } + } + /* T2 = X + T2 */ + if ((err = mp_add(t2, x, t2)) != CRYPT_OK) { goto done; } + if (mp_cmp(t2, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t2, modulus, t2)) != CRYPT_OK) { goto done; } + } + + /* if Z' != 1 */ + if (Q->z != NULL) { + /* Z = Z * Z' */ + if ((err = mp_mul(z, Q->z, z)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(z, modulus, mp)) != CRYPT_OK) { goto done; } + } + + /* Z = Z * X */ + if ((err = mp_mul(z, x, z)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(z, modulus, mp)) != CRYPT_OK) { goto done; } + + /* T1 = T1 * X */ + if ((err = mp_mul(t1, x, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + /* X = X * X */ + if ((err = mp_sqr(x, x)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; } + /* T2 = T2 * x */ + if ((err = mp_mul(t2, x, t2)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } + /* T1 = T1 * X */ + if ((err = mp_mul(t1, x, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + + /* X = Y*Y */ + if ((err = mp_sqr(y, x)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; } + /* X = X - T2 */ + if ((err = mp_sub(x, t2, x)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(x, 0) == LTC_MP_LT) { + if ((err = mp_add(x, modulus, x)) != CRYPT_OK) { goto done; } + } + + /* T2 = T2 - X */ + if ((err = mp_sub(t2, x, t2)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(t2, 0) == LTC_MP_LT) { + if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; } + } + /* T2 = T2 - X */ + if ((err = mp_sub(t2, x, t2)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(t2, 0) == LTC_MP_LT) { + if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; } + } + /* T2 = T2 * Y */ + if ((err = mp_mul(t2, y, t2)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } + /* Y = T2 - T1 */ + if ((err = mp_sub(t2, t1, y)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(y, 0) == LTC_MP_LT) { + if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; } + } + /* Y = Y/2 */ + if (mp_isodd(y)) { + if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; } + } + if ((err = mp_div_2(y, y)) != CRYPT_OK) { goto done; } + + if ((err = mp_copy(x, R->x)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(y, R->y)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(z, R->z)) != CRYPT_OK) { goto done; } + + err = CRYPT_OK; +done: + mp_clear_multi(t1, t2, x, y, z, NULL); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c,v $ */ +/* $Revision: 1.16 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c new file mode 100644 index 0000000000..55bb4a1b70 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c @@ -0,0 +1,146 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "tomcrypt.h" + +/** + @file ltc_ecc_projective_dbl_point.c + ECC Crypto, Tom St Denis +*/ + +#if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC)) + +/** + Double an ECC point + @param P The point to double + @param R [out] The destination of the double + @param modulus The modulus of the field the ECC curve is in + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success +*/ +int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp) +{ + void *t1, *t2; + int err; + + LTC_ARGCHK(P != NULL); + LTC_ARGCHK(R != NULL); + LTC_ARGCHK(modulus != NULL); + LTC_ARGCHK(mp != NULL); + + if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) { + return err; + } + + if (P != R) { + if ((err = mp_copy(P->x, R->x)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(P->y, R->y)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(P->z, R->z)) != CRYPT_OK) { goto done; } + } + + /* t1 = Z * Z */ + if ((err = mp_sqr(R->z, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + /* Z = Y * Z */ + if ((err = mp_mul(R->z, R->y, R->z)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(R->z, modulus, mp)) != CRYPT_OK) { goto done; } + /* Z = 2Z */ + if ((err = mp_add(R->z, R->z, R->z)) != CRYPT_OK) { goto done; } + if (mp_cmp(R->z, modulus) != LTC_MP_LT) { + if ((err = mp_sub(R->z, modulus, R->z)) != CRYPT_OK) { goto done; } + } + + /* T2 = X - T1 */ + if ((err = mp_sub(R->x, t1, t2)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(t2, 0) == LTC_MP_LT) { + if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; } + } + /* T1 = X + T1 */ + if ((err = mp_add(t1, R->x, t1)) != CRYPT_OK) { goto done; } + if (mp_cmp(t1, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } + } + /* T2 = T1 * T2 */ + if ((err = mp_mul(t1, t2, t2)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } + /* T1 = 2T2 */ + if ((err = mp_add(t2, t2, t1)) != CRYPT_OK) { goto done; } + if (mp_cmp(t1, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } + } + /* T1 = T1 + T2 */ + if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; } + if (mp_cmp(t1, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } + } + + /* Y = 2Y */ + if ((err = mp_add(R->y, R->y, R->y)) != CRYPT_OK) { goto done; } + if (mp_cmp(R->y, modulus) != LTC_MP_LT) { + if ((err = mp_sub(R->y, modulus, R->y)) != CRYPT_OK) { goto done; } + } + /* Y = Y * Y */ + if ((err = mp_sqr(R->y, R->y)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; } + /* T2 = Y * Y */ + if ((err = mp_sqr(R->y, t2)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } + /* T2 = T2/2 */ + if (mp_isodd(t2)) { + if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; } + } + if ((err = mp_div_2(t2, t2)) != CRYPT_OK) { goto done; } + /* Y = Y * X */ + if ((err = mp_mul(R->y, R->x, R->y)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; } + + /* X = T1 * T1 */ + if ((err = mp_sqr(t1, R->x)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(R->x, modulus, mp)) != CRYPT_OK) { goto done; } + /* X = X - Y */ + if ((err = mp_sub(R->x, R->y, R->x)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(R->x, 0) == LTC_MP_LT) { + if ((err = mp_add(R->x, modulus, R->x)) != CRYPT_OK) { goto done; } + } + /* X = X - Y */ + if ((err = mp_sub(R->x, R->y, R->x)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(R->x, 0) == LTC_MP_LT) { + if ((err = mp_add(R->x, modulus, R->x)) != CRYPT_OK) { goto done; } + } + + /* Y = Y - X */ + if ((err = mp_sub(R->y, R->x, R->y)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(R->y, 0) == LTC_MP_LT) { + if ((err = mp_add(R->y, modulus, R->y)) != CRYPT_OK) { goto done; } + } + /* Y = Y * T1 */ + if ((err = mp_mul(R->y, t1, R->y)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; } + /* Y = Y - T2 */ + if ((err = mp_sub(R->y, t2, R->y)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(R->y, 0) == LTC_MP_LT) { + if ((err = mp_add(R->y, modulus, R->y)) != CRYPT_OK) { goto done; } + } + + err = CRYPT_OK; +done: + mp_clear_multi(t1, t2, NULL); + return err; +} +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c,v $ */ +/* $Revision: 1.11 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/katja/katja_decrypt_key.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/katja/katja_decrypt_key.c new file mode 100644 index 0000000000..02a1031e36 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/katja/katja_decrypt_key.c @@ -0,0 +1,105 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file katja_decrypt_key.c + Katja LTC_PKCS #1 OAEP Decryption, Tom St Denis +*/ + +#ifdef MKAT + +/** + (LTC_PKCS #1 v2.0) decrypt then OAEP depad + @param in The ciphertext + @param inlen The length of the ciphertext (octets) + @param out [out] The plaintext + @param outlen [in/out] The max size and resulting size of the plaintext (octets) + @param lparam The system "lparam" value + @param lparamlen The length of the lparam value (octets) + @param hash_idx The index of the hash desired + @param stat [out] Result of the decryption, 1==valid, 0==invalid + @param key The corresponding private Katja key + @return CRYPT_OK if succcessul (even if invalid) +*/ +int katja_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + int hash_idx, int *stat, + katja_key *key) +{ + unsigned long modulus_bitlen, modulus_bytelen, x; + int err; + unsigned char *tmp; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(stat != NULL); + + /* default to invalid */ + *stat = 0; + + /* valid hash ? */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + + /* get modulus len in bits */ + modulus_bitlen = mp_count_bits( (key->N)); + + /* payload is upto pq, so we know q is 1/3rd the size of N and therefore pq is 2/3th the size */ + modulus_bitlen = ((modulus_bitlen << 1) / 3); + + /* round down to next byte */ + modulus_bitlen -= (modulus_bitlen & 7) + 8; + + /* outlen must be at least the size of the modulus */ + modulus_bytelen = mp_unsigned_bin_size( (key->N)); + if (modulus_bytelen != inlen) { + return CRYPT_INVALID_PACKET; + } + + /* allocate ram */ + tmp = XMALLOC(inlen); + if (tmp == NULL) { + return CRYPT_MEM; + } + + /* rsa decode the packet */ + x = inlen; + if ((err = katja_exptmod(in, inlen, tmp, &x, PK_PRIVATE, key)) != CRYPT_OK) { + XFREE(tmp); + return err; + } + + /* shift right by modulus_bytelen - modulus_bitlen/8 bytes */ + for (x = 0; x < (modulus_bitlen >> 3); x++) { + tmp[x] = tmp[x+(modulus_bytelen-(modulus_bitlen>>3))]; + } + + /* now OAEP decode the packet */ + err = pkcs_1_oaep_decode(tmp, x, lparam, lparamlen, modulus_bitlen, hash_idx, + out, outlen, stat); + + XFREE(tmp); + return err; +} + +#endif /* LTC_MRSA */ + + + + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/katja/katja_decrypt_key.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/katja/katja_encrypt_key.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/katja/katja_encrypt_key.c new file mode 100644 index 0000000000..d056fe32ef --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/katja/katja_encrypt_key.c @@ -0,0 +1,87 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file katja_encrypt_key.c + Katja LTC_PKCS-style OAEP encryption, Tom St Denis +*/ + +#ifdef MKAT + +/** + (LTC_PKCS #1 v2.0) OAEP pad then encrypt + @param in The plaintext + @param inlen The length of the plaintext (octets) + @param out [out] The ciphertext + @param outlen [in/out] The max size and resulting size of the ciphertext + @param lparam The system "lparam" for the encryption + @param lparamlen The length of lparam (octets) + @param prng An active PRNG + @param prng_idx The index of the desired prng + @param hash_idx The index of the desired hash + @param key The Katja key to encrypt to + @return CRYPT_OK if successful +*/ +int katja_encrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + prng_state *prng, int prng_idx, int hash_idx, katja_key *key) +{ + unsigned long modulus_bitlen, modulus_bytelen, x; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* valid prng and hash ? */ + if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { + return err; + } + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + + /* get modulus len in bits */ + modulus_bitlen = mp_count_bits((key->N)); + + /* payload is upto pq, so we know q is 1/3rd the size of N and therefore pq is 2/3th the size */ + modulus_bitlen = ((modulus_bitlen << 1) / 3); + + /* round down to next byte */ + modulus_bitlen -= (modulus_bitlen & 7) + 8; + + /* outlen must be at least the size of the modulus */ + modulus_bytelen = mp_unsigned_bin_size((key->N)); + if (modulus_bytelen > *outlen) { + *outlen = modulus_bytelen; + return CRYPT_BUFFER_OVERFLOW; + } + + /* OAEP pad the key */ + x = *outlen; + if ((err = pkcs_1_oaep_encode(in, inlen, lparam, + lparamlen, modulus_bitlen, prng, prng_idx, hash_idx, + out, &x)) != CRYPT_OK) { + return err; + } + + /* Katja exptmod the OAEP pad */ + return katja_exptmod(out, x, out, outlen, PK_PUBLIC, key); +} + +#endif /* LTC_MRSA */ + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/katja/katja_encrypt_key.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/katja/katja_export.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/katja/katja_export.c new file mode 100644 index 0000000000..4347cd9cc1 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/katja/katja_export.c @@ -0,0 +1,75 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file katja_export.c + Export Katja LTC_PKCS-style keys, Tom St Denis +*/ + +#ifdef MKAT + +/** + This will export either an KatjaPublicKey or KatjaPrivateKey + @param out [out] Destination of the packet + @param outlen [in/out] The max size and resulting size of the packet + @param type The type of exported key (PK_PRIVATE or PK_PUBLIC) + @param key The Katja key to export + @return CRYPT_OK if successful +*/ +int katja_export(unsigned char *out, unsigned long *outlen, int type, katja_key *key) +{ + int err; + unsigned long zero=0; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* type valid? */ + if (!(key->type == PK_PRIVATE) && (type == PK_PRIVATE)) { + return CRYPT_PK_INVALID_TYPE; + } + + if (type == PK_PRIVATE) { + /* private key */ + /* output is + Version, n, d, p, q, d mod (p-1), d mod (q - 1), 1/q mod p, pq + */ + if ((err = der_encode_sequence_multi(out, outlen, + LTC_ASN1_SHORT_INTEGER, 1UL, &zero, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_INTEGER, 1UL, key->d, + LTC_ASN1_INTEGER, 1UL, key->p, + LTC_ASN1_INTEGER, 1UL, key->q, + LTC_ASN1_INTEGER, 1UL, key->dP, + LTC_ASN1_INTEGER, 1UL, key->dQ, + LTC_ASN1_INTEGER, 1UL, key->qP, + LTC_ASN1_INTEGER, 1UL, key->pq, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + return err; + } + + /* clear zero and return */ + return CRYPT_OK; + } else { + /* public key */ + return der_encode_sequence_multi(out, outlen, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_EOL, 0UL, NULL); + } +} + +#endif /* LTC_MRSA */ + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/katja/katja_export.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/katja/katja_exptmod.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/katja/katja_exptmod.c new file mode 100644 index 0000000000..f2616cdc49 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/katja/katja_exptmod.c @@ -0,0 +1,115 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file katja_exptmod.c + Katja LTC_PKCS-style exptmod, Tom St Denis +*/ + +#ifdef MKAT + +/** + Compute an RSA modular exponentiation + @param in The input data to send into RSA + @param inlen The length of the input (octets) + @param out [out] The destination + @param outlen [in/out] The max size and resulting size of the output + @param which Which exponent to use, e.g. PK_PRIVATE or PK_PUBLIC + @param key The RSA key to use + @return CRYPT_OK if successful +*/ +int katja_exptmod(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int which, + katja_key *key) +{ + void *tmp, *tmpa, *tmpb; + unsigned long x; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* is the key of the right type for the operation? */ + if (which == PK_PRIVATE && (key->type != PK_PRIVATE)) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* must be a private or public operation */ + if (which != PK_PRIVATE && which != PK_PUBLIC) { + return CRYPT_PK_INVALID_TYPE; + } + + /* init and copy into tmp */ + if ((err = mp_init_multi(&tmp, &tmpa, &tmpb, NULL)) != CRYPT_OK) { return err; } + if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, (int)inlen)) != CRYPT_OK) { goto error; } + + /* sanity check on the input */ + if (mp_cmp(key->N, tmp) == LTC_MP_LT) { + err = CRYPT_PK_INVALID_SIZE; + goto done; + } + + /* are we using the private exponent and is the key optimized? */ + if (which == PK_PRIVATE) { + /* tmpa = tmp^dP mod p */ + if ((err = mp_exptmod(tmp, key->dP, key->p, tmpa)) != CRYPT_OK) { goto error; } + + /* tmpb = tmp^dQ mod q */ + if ((err = mp_exptmod(tmp, key->dQ, key->q, tmpb)) != CRYPT_OK) { goto error; } + + /* tmp = (tmpa - tmpb) * qInv (mod p) */ + if ((err = mp_sub(tmpa, tmpb, tmp)) != CRYPT_OK) { goto error; } + if ((err = mp_mulmod(tmp, key->qP, key->p, tmp)) != CRYPT_OK) { goto error; } + + /* tmp = tmpb + q * tmp */ + if ((err = mp_mul(tmp, key->q, tmp)) != CRYPT_OK) { goto error; } + if ((err = mp_add(tmp, tmpb, tmp)) != CRYPT_OK) { goto error; } + } else { + /* exptmod it */ + if ((err = mp_exptmod(tmp, key->N, key->N, tmp)) != CRYPT_OK) { goto error; } + } + + /* read it back */ + x = (unsigned long)mp_unsigned_bin_size(key->N); + if (x > *outlen) { + *outlen = x; + err = CRYPT_BUFFER_OVERFLOW; + goto done; + } + + /* this should never happen ... */ + if (mp_unsigned_bin_size(tmp) > mp_unsigned_bin_size(key->N)) { + err = CRYPT_ERROR; + goto done; + } + *outlen = x; + + /* convert it */ + zeromem(out, x); + if ((err = mp_to_unsigned_bin(tmp, out+(x-mp_unsigned_bin_size(tmp)))) != CRYPT_OK) { goto error; } + + /* clean up and return */ + err = CRYPT_OK; + goto done; +error: +done: + mp_clear_multi(tmp, tmpa, tmpb, NULL); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/katja/katja_exptmod.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/katja/katja_free.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/katja/katja_free.c new file mode 100644 index 0000000000..17b249c622 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/katja/katja_free.c @@ -0,0 +1,35 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file katja_free.c + Free an Katja key, Tom St Denis +*/ + +#ifdef MKAT + +/** + Free an Katja key from memory + @param key The RSA key to free +*/ +void katja_free(katja_key *key) +{ + LTC_ARGCHK(key != NULL); + mp_clear_multi( key->d, key->N, key->dQ, key->dP, + key->qP, key->p, key->q, key->pq, NULL); +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/katja/katja_free.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/katja/katja_import.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/katja/katja_import.c new file mode 100644 index 0000000000..f3dc80f808 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/katja/katja_import.c @@ -0,0 +1,81 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file katja_import.c + Import a LTC_PKCS-style Katja key, Tom St Denis +*/ + +#ifdef MKAT + +/** + Import an KatjaPublicKey or KatjaPrivateKey [two-prime only, only support >= 1024-bit keys, defined in LTC_PKCS #1 v2.1] + @param in The packet to import from + @param inlen It's length (octets) + @param key [out] Destination for newly imported key + @return CRYPT_OK if successful, upon error allocated memory is freed +*/ +int katja_import(const unsigned char *in, unsigned long inlen, katja_key *key) +{ + int err; + void *zero; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + + /* init key */ + if ((err = mp_init_multi(&zero, &key->d, &key->N, &key->dQ, + &key->dP, &key->qP, &key->p, &key->q, &key->pq, NULL)) != CRYPT_OK) { + return err; + } + + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + + if (mp_cmp_d(key->N, 0) == LTC_MP_EQ) { + /* it's a private key */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_INTEGER, 1UL, zero, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_INTEGER, 1UL, key->d, + LTC_ASN1_INTEGER, 1UL, key->p, + LTC_ASN1_INTEGER, 1UL, key->q, + LTC_ASN1_INTEGER, 1UL, key->dP, + LTC_ASN1_INTEGER, 1UL, key->dQ, + LTC_ASN1_INTEGER, 1UL, key->qP, + LTC_ASN1_INTEGER, 1UL, key->pq, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + key->type = PK_PRIVATE; + } else { + /* public we have N */ + key->type = PK_PUBLIC; + } + mp_clear(zero); + return CRYPT_OK; +LBL_ERR: + mp_clear_multi(zero, key->d, key->N, key->dQ, key->dP, + key->qP, key->p, key->q, key->pq, NULL); + return err; +} + +#endif /* LTC_MRSA */ + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/katja/katja_import.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/katja/katja_make_key.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/katja/katja_make_key.c new file mode 100644 index 0000000000..cae83da47c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/katja/katja_make_key.c @@ -0,0 +1,101 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file katja_make_key.c + Katja key generation, Tom St Denis +*/ + +#ifdef MKAT + +/** + Create a Katja key + @param prng An active PRNG state + @param wprng The index of the PRNG desired + @param size The size of the modulus (key size) desired (octets) + @param key [out] Destination of a newly created private key pair + @return CRYPT_OK if successful, upon error all allocated ram is freed +*/ +int katja_make_key(prng_state *prng, int wprng, int size, katja_key *key) +{ + void *p, *q, *tmp1, *tmp2; + int err; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + + if ((size < (MIN_KAT_SIZE/8)) || (size > (MAX_KAT_SIZE/8))) { + return CRYPT_INVALID_KEYSIZE; + } + + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, NULL)) != CRYPT_OK) { + return err; + } + + /* divide size by three */ + size = (((size << 3) / 3) + 7) >> 3; + + /* make prime "q" (we negate size to make q == 3 mod 4) */ + if ((err = rand_prime(q, -size, prng, wprng)) != CRYPT_OK) { goto done; } + if ((err = mp_sub_d(q, 1, tmp1)) != CRYPT_OK) { goto done; } + + /* make prime "p" */ + do { + if ((err = rand_prime(p, size+1, prng, wprng)) != CRYPT_OK) { goto done; } + if ((err = mp_gcd(p, tmp1, tmp2)) != CRYPT_OK) { goto done; } + } while (mp_cmp_d(tmp2, 1) != LTC_MP_EQ); + + /* make key */ + if ((err = mp_init_multi(&key->d, &key->N, &key->dQ, &key->dP, + &key->qP, &key->p, &key->q, &key->pq, NULL)) != CRYPT_OK) { + goto error; + } + + /* n=p^2q and 1/n mod pq */ + if ((err = mp_copy( p, key->p)) != CRYPT_OK) { goto error2; } + if ((err = mp_copy( q, key->q)) != CRYPT_OK) { goto error2; } + if ((err = mp_mul(key->p, key->q, key->pq)) != CRYPT_OK) { goto error2; } /* tmp1 = pq */ + if ((err = mp_mul(key->pq, key->p, key->N)) != CRYPT_OK) { goto error2; } /* N = p^2q */ + if ((err = mp_sub_d( p, 1, tmp1)) != CRYPT_OK) { goto error2; } /* tmp1 = q-1 */ + if ((err = mp_sub_d( q, 1, tmp2)) != CRYPT_OK) { goto error2; } /* tmp2 = p-1 */ + if ((err = mp_lcm(tmp1, tmp2, key->d)) != CRYPT_OK) { goto error2; } /* tmp1 = lcd(p-1,q-1) */ + if ((err = mp_invmod( key->N, key->d, key->d)) != CRYPT_OK) { goto error2; } /* key->d = 1/N mod pq */ + + /* optimize for CRT now */ + /* find d mod q-1 and d mod p-1 */ + if ((err = mp_mod( key->d, tmp1, key->dP)) != CRYPT_OK) { goto error2; } /* dP = d mod p-1 */ + if ((err = mp_mod( key->d, tmp2, key->dQ)) != CRYPT_OK) { goto error2; } /* dQ = d mod q-1 */ + if ((err = mp_invmod( q, p, key->qP)) != CRYPT_OK) { goto error2; } /* qP = 1/q mod p */ + + /* set key type (in this case it's CRT optimized) */ + key->type = PK_PRIVATE; + + /* return ok and free temps */ + err = CRYPT_OK; + goto done; +error2: + mp_clear_multi( key->d, key->N, key->dQ, key->dP, key->qP, key->p, key->q, key->pq, NULL); +error: +done: + mp_clear_multi( tmp2, tmp1, p, q, NULL); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/katja/katja_make_key.c,v $ */ +/* $Revision: 1.11 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_i2osp.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_i2osp.c new file mode 100644 index 0000000000..6ec2ebbaf3 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_i2osp.c @@ -0,0 +1,51 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pkcs_1_i2osp.c + Integer to Octet I2OSP, Tom St Denis +*/ + +#ifdef LTC_PKCS_1 + +/* always stores the same # of bytes, pads with leading zero bytes + as required + */ + +/** + LTC_PKCS #1 Integer to binary + @param n The integer to store + @param modulus_len The length of the RSA modulus + @param out [out] The destination for the integer + @return CRYPT_OK if successful +*/ +int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out) +{ + unsigned long size; + + size = mp_unsigned_bin_size(n); + + if (size > modulus_len) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* store it */ + zeromem(out, modulus_len); + return mp_to_unsigned_bin(n, out+(modulus_len-size)); +} + +#endif /* LTC_PKCS_1 */ + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_i2osp.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c new file mode 100644 index 0000000000..8564688c09 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c @@ -0,0 +1,108 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pkcs_1_mgf1.c + The Mask Generation Function (MGF1) for LTC_PKCS #1, Tom St Denis +*/ + +#ifdef LTC_PKCS_1 + +/** + Perform LTC_PKCS #1 MGF1 (internal) + @param seed The seed for MGF1 + @param seedlen The length of the seed + @param hash_idx The index of the hash desired + @param mask [out] The destination + @param masklen The length of the mask desired + @return CRYPT_OK if successful +*/ +int pkcs_1_mgf1(int hash_idx, + const unsigned char *seed, unsigned long seedlen, + unsigned char *mask, unsigned long masklen) +{ + unsigned long hLen, x; + ulong32 counter; + int err; + hash_state *md; + unsigned char *buf; + + LTC_ARGCHK(seed != NULL); + LTC_ARGCHK(mask != NULL); + + /* ensure valid hash */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + + /* get hash output size */ + hLen = hash_descriptor[hash_idx].hashsize; + + /* allocate memory */ + md = XMALLOC(sizeof(hash_state)); + buf = XMALLOC(hLen); + if (md == NULL || buf == NULL) { + if (md != NULL) { + XFREE(md); + } + if (buf != NULL) { + XFREE(buf); + } + return CRYPT_MEM; + } + + /* start counter */ + counter = 0; + + while (masklen > 0) { + /* handle counter */ + STORE32H(counter, buf); + ++counter; + + /* get hash of seed || counter */ + if ((err = hash_descriptor[hash_idx].init(md)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].process(md, seed, seedlen)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].process(md, buf, 4)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].done(md, buf)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* store it */ + for (x = 0; x < hLen && masklen > 0; x++, masklen--) { + *mask++ = buf[x]; + } + } + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(buf, hLen); + zeromem(md, sizeof(hash_state)); +#endif + + XFREE(buf); + XFREE(md); + + return err; +} + +#endif /* LTC_PKCS_1 */ + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c new file mode 100644 index 0000000000..14f6be2030 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c @@ -0,0 +1,189 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pkcs_1_oaep_decode.c + OAEP Padding for LTC_PKCS #1, Tom St Denis +*/ + +#ifdef LTC_PKCS_1 + +/** + LTC_PKCS #1 v2.00 OAEP decode + @param msg The encoded data to decode + @param msglen The length of the encoded data (octets) + @param lparam The session or system data (can be NULL) + @param lparamlen The length of the lparam + @param modulus_bitlen The bit length of the RSA modulus + @param hash_idx The index of the hash desired + @param out [out] Destination of decoding + @param outlen [in/out] The max size and resulting size of the decoding + @param res [out] Result of decoding, 1==valid, 0==invalid + @return CRYPT_OK if successful (even if invalid) +*/ +int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, + const unsigned char *lparam, unsigned long lparamlen, + unsigned long modulus_bitlen, int hash_idx, + unsigned char *out, unsigned long *outlen, + int *res) +{ + unsigned char *DB, *seed, *mask; + unsigned long hLen, x, y, modulus_len; + int err; + + LTC_ARGCHK(msg != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(res != NULL); + + /* default to invalid packet */ + *res = 0; + + /* test valid hash */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + hLen = hash_descriptor[hash_idx].hashsize; + modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); + + /* test hash/message size */ + if ((2*hLen >= (modulus_len - 2)) || (msglen != modulus_len)) { + return CRYPT_PK_INVALID_SIZE; + } + + /* allocate ram for DB/mask/salt of size modulus_len */ + DB = XMALLOC(modulus_len); + mask = XMALLOC(modulus_len); + seed = XMALLOC(hLen); + if (DB == NULL || mask == NULL || seed == NULL) { + if (DB != NULL) { + XFREE(DB); + } + if (mask != NULL) { + XFREE(mask); + } + if (seed != NULL) { + XFREE(seed); + } + return CRYPT_MEM; + } + + /* ok so it's now in the form + + 0x00 || maskedseed || maskedDB + + 1 || hLen || modulus_len - hLen - 1 + + */ + + /* must have leading 0x00 byte */ + if (msg[0] != 0x00) { + err = CRYPT_OK; + goto LBL_ERR; + } + + /* now read the masked seed */ + x = 1; + XMEMCPY(seed, msg + x, hLen); + x += hLen; + + /* now read the masked DB */ + XMEMCPY(DB, msg + x, modulus_len - hLen - 1); + x += modulus_len - hLen - 1; + + /* compute MGF1 of maskedDB (hLen) */ + if ((err = pkcs_1_mgf1(hash_idx, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* XOR against seed */ + for (y = 0; y < hLen; y++) { + seed[y] ^= mask[y]; + } + + /* compute MGF1 of seed (k - hlen - 1) */ + if ((err = pkcs_1_mgf1(hash_idx, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* xor against DB */ + for (y = 0; y < (modulus_len - hLen - 1); y++) { + DB[y] ^= mask[y]; + } + + /* now DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes */ + + /* compute lhash and store it in seed [reuse temps!] */ + x = modulus_len; + if (lparam != NULL) { + if ((err = hash_memory(hash_idx, lparam, lparamlen, seed, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + } else { + /* can't pass hash_memory a NULL so use DB with zero length */ + if ((err = hash_memory(hash_idx, DB, 0, seed, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + } + + /* compare the lhash'es */ + if (XMEMCMP(seed, DB, hLen) != 0) { + err = CRYPT_OK; + goto LBL_ERR; + } + + /* now zeroes before a 0x01 */ + for (x = hLen; x < (modulus_len - hLen - 1) && DB[x] == 0x00; x++) { + /* step... */ + } + + /* error out if wasn't 0x01 */ + if (x == (modulus_len - hLen - 1) || DB[x] != 0x01) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + /* rest is the message (and skip 0x01) */ + if ((modulus_len - hLen - 1 - ++x) > *outlen) { + *outlen = modulus_len - hLen - 1 - x; + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + + /* copy message */ + *outlen = modulus_len - hLen - 1 - x; + XMEMCPY(out, DB + x, modulus_len - hLen - 1 - x); + x += modulus_len - hLen - 1; + + /* valid packet */ + *res = 1; + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(DB, modulus_len); + zeromem(seed, hLen); + zeromem(mask, modulus_len); +#endif + + XFREE(seed); + XFREE(mask); + XFREE(DB); + + return err; +} + +#endif /* LTC_PKCS_1 */ + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c,v $ */ +/* $Revision: 1.13 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_encode.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_encode.c new file mode 100644 index 0000000000..f5a1b38333 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_encode.c @@ -0,0 +1,173 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pkcs_1_oaep_encode.c + OAEP Padding for LTC_PKCS #1, Tom St Denis +*/ + +#ifdef LTC_PKCS_1 + +/** + LTC_PKCS #1 v2.00 OAEP encode + @param msg The data to encode + @param msglen The length of the data to encode (octets) + @param lparam A session or system parameter (can be NULL) + @param lparamlen The length of the lparam data + @param modulus_bitlen The bit length of the RSA modulus + @param prng An active PRNG state + @param prng_idx The index of the PRNG desired + @param hash_idx The index of the hash desired + @param out [out] The destination for the encoded data + @param outlen [in/out] The max size and resulting size of the encoded data + @return CRYPT_OK if successful +*/ +int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, + const unsigned char *lparam, unsigned long lparamlen, + unsigned long modulus_bitlen, prng_state *prng, + int prng_idx, int hash_idx, + unsigned char *out, unsigned long *outlen) +{ + unsigned char *DB, *seed, *mask; + unsigned long hLen, x, y, modulus_len; + int err; + + LTC_ARGCHK(msg != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* test valid hash */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + + /* valid prng */ + if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { + return err; + } + + hLen = hash_descriptor[hash_idx].hashsize; + modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); + + /* test message size */ + if ((2*hLen >= (modulus_len - 2)) || (msglen > (modulus_len - 2*hLen - 2))) { + return CRYPT_PK_INVALID_SIZE; + } + + /* allocate ram for DB/mask/salt of size modulus_len */ + DB = XMALLOC(modulus_len); + mask = XMALLOC(modulus_len); + seed = XMALLOC(hLen); + if (DB == NULL || mask == NULL || seed == NULL) { + if (DB != NULL) { + XFREE(DB); + } + if (mask != NULL) { + XFREE(mask); + } + if (seed != NULL) { + XFREE(seed); + } + return CRYPT_MEM; + } + + /* get lhash */ + /* DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes */ + x = modulus_len; + if (lparam != NULL) { + if ((err = hash_memory(hash_idx, lparam, lparamlen, DB, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + } else { + /* can't pass hash_memory a NULL so use DB with zero length */ + if ((err = hash_memory(hash_idx, DB, 0, DB, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + } + + /* append PS then 0x01 (to lhash) */ + x = hLen; + y = modulus_len - msglen - 2*hLen - 2; + XMEMSET(DB+x, 0, y); + x += y; + + /* 0x01 byte */ + DB[x++] = 0x01; + + /* message (length = msglen) */ + XMEMCPY(DB+x, msg, msglen); + x += msglen; + + /* now choose a random seed */ + if (prng_descriptor[prng_idx].read(seed, hLen, prng) != hLen) { + err = CRYPT_ERROR_READPRNG; + goto LBL_ERR; + } + + /* compute MGF1 of seed (k - hlen - 1) */ + if ((err = pkcs_1_mgf1(hash_idx, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* xor against DB */ + for (y = 0; y < (modulus_len - hLen - 1); y++) { + DB[y] ^= mask[y]; + } + + /* compute MGF1 of maskedDB (hLen) */ + if ((err = pkcs_1_mgf1(hash_idx, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* XOR against seed */ + for (y = 0; y < hLen; y++) { + seed[y] ^= mask[y]; + } + + /* create string of length modulus_len */ + if (*outlen < modulus_len) { + *outlen = modulus_len; + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + + /* start output which is 0x00 || maskedSeed || maskedDB */ + x = 0; + out[x++] = 0x00; + XMEMCPY(out+x, seed, hLen); + x += hLen; + XMEMCPY(out+x, DB, modulus_len - hLen - 1); + x += modulus_len - hLen - 1; + + *outlen = x; + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(DB, modulus_len); + zeromem(seed, hLen); + zeromem(mask, modulus_len); +#endif + + XFREE(seed); + XFREE(mask); + XFREE(DB); + + return err; +} + +#endif /* LTC_PKCS_1 */ + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_encode.c,v $ */ +/* $Revision: 1.9 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_os2ip.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_os2ip.c new file mode 100644 index 0000000000..0793f71df8 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_os2ip.c @@ -0,0 +1,36 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pkcs_1_os2ip.c + Octet to Integer OS2IP, Tom St Denis +*/ +#ifdef LTC_PKCS_1 + +/** + Read a binary string into an mp_int + @param n [out] The mp_int destination + @param in The binary string to read + @param inlen The length of the binary string + @return CRYPT_OK if successful +*/ +int pkcs_1_os2ip(void *n, unsigned char *in, unsigned long inlen) +{ + return mp_read_unsigned_bin(n, in, inlen); +} + +#endif /* LTC_PKCS_1 */ + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_os2ip.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c new file mode 100644 index 0000000000..2c00aa8569 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c @@ -0,0 +1,177 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pkcs_1_pss_decode.c + LTC_PKCS #1 PSS Signature Padding, Tom St Denis +*/ + +#ifdef LTC_PKCS_1 + +/** + LTC_PKCS #1 v2.00 PSS decode + @param msghash The hash to verify + @param msghashlen The length of the hash (octets) + @param sig The signature data (encoded data) + @param siglen The length of the signature data (octets) + @param saltlen The length of the salt used (octets) + @param hash_idx The index of the hash desired + @param modulus_bitlen The bit length of the RSA modulus + @param res [out] The result of the comparison, 1==valid, 0==invalid + @return CRYPT_OK if successful (even if the comparison failed) +*/ +int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, + const unsigned char *sig, unsigned long siglen, + unsigned long saltlen, int hash_idx, + unsigned long modulus_bitlen, int *res) +{ + unsigned char *DB, *mask, *salt, *hash; + unsigned long x, y, hLen, modulus_len; + int err; + hash_state md; + + LTC_ARGCHK(msghash != NULL); + LTC_ARGCHK(res != NULL); + + /* default to invalid */ + *res = 0; + + /* ensure hash is valid */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + + hLen = hash_descriptor[hash_idx].hashsize; + modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0); + + /* check sizes */ + if ((saltlen > modulus_len) || + (modulus_len < hLen + saltlen + 2) || (siglen != modulus_len)) { + return CRYPT_PK_INVALID_SIZE; + } + + /* allocate ram for DB/mask/salt/hash of size modulus_len */ + DB = XMALLOC(modulus_len); + mask = XMALLOC(modulus_len); + salt = XMALLOC(modulus_len); + hash = XMALLOC(modulus_len); + if (DB == NULL || mask == NULL || salt == NULL || hash == NULL) { + if (DB != NULL) { + XFREE(DB); + } + if (mask != NULL) { + XFREE(mask); + } + if (salt != NULL) { + XFREE(salt); + } + if (hash != NULL) { + XFREE(hash); + } + return CRYPT_MEM; + } + + /* ensure the 0xBC byte */ + if (sig[siglen-1] != 0xBC) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + /* copy out the DB */ + x = 0; + XMEMCPY(DB, sig + x, modulus_len - hLen - 1); + x += modulus_len - hLen - 1; + + /* copy out the hash */ + XMEMCPY(hash, sig + x, hLen); + x += hLen; + + /* check the MSB */ + if ((sig[0] & ~(0xFF >> ((modulus_len<<3) - (modulus_bitlen-1)))) != 0) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + /* generate mask of length modulus_len - hLen - 1 from hash */ + if ((err = pkcs_1_mgf1(hash_idx, hash, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* xor against DB */ + for (y = 0; y < (modulus_len - hLen - 1); y++) { + DB[y] ^= mask[y]; + } + + /* now clear the first byte [make sure smaller than modulus] */ + DB[0] &= 0xFF >> ((modulus_len<<3) - (modulus_bitlen-1)); + + /* DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */ + + /* check for zeroes and 0x01 */ + for (x = 0; x < modulus_len - saltlen - hLen - 2; x++) { + if (DB[x] != 0x00) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + } + + /* check for the 0x01 */ + if (DB[x++] != 0x01) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + /* M = (eight) 0x00 || msghash || salt, mask = H(M) */ + if ((err = hash_descriptor[hash_idx].init(&md)) != CRYPT_OK) { + goto LBL_ERR; + } + zeromem(mask, 8); + if ((err = hash_descriptor[hash_idx].process(&md, mask, 8)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].process(&md, msghash, msghashlen)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].process(&md, DB+x, saltlen)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].done(&md, mask)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* mask == hash means valid signature */ + if (XMEMCMP(mask, hash, hLen) == 0) { + *res = 1; + } + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(DB, modulus_len); + zeromem(mask, modulus_len); + zeromem(salt, modulus_len); + zeromem(hash, modulus_len); +#endif + + XFREE(hash); + XFREE(salt); + XFREE(mask); + XFREE(DB); + + return err; +} + +#endif /* LTC_PKCS_1 */ + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c,v $ */ +/* $Revision: 1.11 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_encode.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_encode.c new file mode 100644 index 0000000000..9f54b5d389 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_encode.c @@ -0,0 +1,175 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pkcs_1_pss_encode.c + LTC_PKCS #1 PSS Signature Padding, Tom St Denis +*/ + +#ifdef LTC_PKCS_1 + +/** + LTC_PKCS #1 v2.00 Signature Encoding + @param msghash The hash to encode + @param msghashlen The length of the hash (octets) + @param saltlen The length of the salt desired (octets) + @param prng An active PRNG context + @param prng_idx The index of the PRNG desired + @param hash_idx The index of the hash desired + @param modulus_bitlen The bit length of the RSA modulus + @param out [out] The destination of the encoding + @param outlen [in/out] The max size and resulting size of the encoded data + @return CRYPT_OK if successful +*/ +int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, + unsigned long saltlen, prng_state *prng, + int prng_idx, int hash_idx, + unsigned long modulus_bitlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned char *DB, *mask, *salt, *hash; + unsigned long x, y, hLen, modulus_len; + int err; + hash_state md; + + LTC_ARGCHK(msghash != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* ensure hash and PRNG are valid */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { + return err; + } + + hLen = hash_descriptor[hash_idx].hashsize; + modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0); + + /* check sizes */ + if ((saltlen > modulus_len) || (modulus_len < hLen + saltlen + 2)) { + return CRYPT_PK_INVALID_SIZE; + } + + /* allocate ram for DB/mask/salt/hash of size modulus_len */ + DB = XMALLOC(modulus_len); + mask = XMALLOC(modulus_len); + salt = XMALLOC(modulus_len); + hash = XMALLOC(modulus_len); + if (DB == NULL || mask == NULL || salt == NULL || hash == NULL) { + if (DB != NULL) { + XFREE(DB); + } + if (mask != NULL) { + XFREE(mask); + } + if (salt != NULL) { + XFREE(salt); + } + if (hash != NULL) { + XFREE(hash); + } + return CRYPT_MEM; + } + + + /* generate random salt */ + if (saltlen > 0) { + if (prng_descriptor[prng_idx].read(salt, saltlen, prng) != saltlen) { + err = CRYPT_ERROR_READPRNG; + goto LBL_ERR; + } + } + + /* M = (eight) 0x00 || msghash || salt, hash = H(M) */ + if ((err = hash_descriptor[hash_idx].init(&md)) != CRYPT_OK) { + goto LBL_ERR; + } + zeromem(DB, 8); + if ((err = hash_descriptor[hash_idx].process(&md, DB, 8)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].process(&md, msghash, msghashlen)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].process(&md, salt, saltlen)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].done(&md, hash)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* generate DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */ + x = 0; + XMEMSET(DB + x, 0, modulus_len - saltlen - hLen - 2); + x += modulus_len - saltlen - hLen - 2; + DB[x++] = 0x01; + XMEMCPY(DB + x, salt, saltlen); + x += saltlen; + + /* generate mask of length modulus_len - hLen - 1 from hash */ + if ((err = pkcs_1_mgf1(hash_idx, hash, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* xor against DB */ + for (y = 0; y < (modulus_len - hLen - 1); y++) { + DB[y] ^= mask[y]; + } + + /* output is DB || hash || 0xBC */ + if (*outlen < modulus_len) { + *outlen = modulus_len; + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + + /* DB len = modulus_len - hLen - 1 */ + y = 0; + XMEMCPY(out + y, DB, modulus_len - hLen - 1); + y += modulus_len - hLen - 1; + + /* hash */ + XMEMCPY(out + y, hash, hLen); + y += hLen; + + /* 0xBC */ + out[y] = 0xBC; + + /* now clear the 8*modulus_len - modulus_bitlen most significant bits */ + out[0] &= 0xFF >> ((modulus_len<<3) - (modulus_bitlen-1)); + + /* store output size */ + *outlen = modulus_len; + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(DB, modulus_len); + zeromem(mask, modulus_len); + zeromem(salt, modulus_len); + zeromem(hash, modulus_len); +#endif + + XFREE(hash); + XFREE(salt); + XFREE(mask); + XFREE(DB); + + return err; +} + +#endif /* LTC_PKCS_1 */ + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_encode.c,v $ */ +/* $Revision: 1.9 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c new file mode 100644 index 0000000000..bec9caf76a --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c @@ -0,0 +1,110 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** @file pkcs_1_v1_5_decode.c + * + * LTC_PKCS #1 v1.5 Padding. (Andreas Lange) + */ + +#ifdef LTC_PKCS_1 + +/** @brief LTC_PKCS #1 v1.5 decode. + * + * @param msg The encoded data to decode + * @param msglen The length of the encoded data (octets) + * @param block_type Block type to use in padding (\sa ltc_pkcs_1_v1_5_blocks) + * @param modulus_bitlen The bit length of the RSA modulus + * @param out [out] Destination of decoding + * @param outlen [in/out] The max size and resulting size of the decoding + * @param is_valid [out] Boolean whether the padding was valid + * + * @return CRYPT_OK if successful (even if invalid) + */ +int pkcs_1_v1_5_decode(const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + unsigned char *out, + unsigned long *outlen, + int *is_valid) +{ + unsigned long modulus_len, ps_len, i; + int result; + + /* default to invalid packet */ + *is_valid = 0; + + modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); + + /* test message size */ + + if ((msglen > modulus_len) || (modulus_len < 11)) { + return CRYPT_PK_INVALID_SIZE; + } + + /* separate encoded message */ + + if ((msg[0] != 0x00) || (msg[1] != (unsigned char)block_type)) { + result = CRYPT_INVALID_PACKET; + goto bail; + } + + if (block_type == LTC_LTC_PKCS_1_EME) { + for (i = 2; i < modulus_len; i++) { + /* separator */ + if (msg[i] == 0x00) { break; } + } + ps_len = i++ - 2; + + if ((i >= modulus_len) || (ps_len < 8)) { + /* There was no octet with hexadecimal value 0x00 to separate ps from m, + * or the length of ps is less than 8 octets. + */ + result = CRYPT_INVALID_PACKET; + goto bail; + } + } else { + for (i = 2; i < modulus_len - 1; i++) { + if (msg[i] != 0xFF) { break; } + } + + /* separator check */ + if (msg[i] != 0) { + /* There was no octet with hexadecimal value 0x00 to separate ps from m. */ + result = CRYPT_INVALID_PACKET; + goto bail; + } + + ps_len = i - 2; + } + + if (*outlen < (msglen - (2 + ps_len + 1))) { + *outlen = msglen - (2 + ps_len + 1); + result = CRYPT_BUFFER_OVERFLOW; + goto bail; + } + + *outlen = (msglen - (2 + ps_len + 1)); + XMEMCPY(out, &msg[2 + ps_len + 1], *outlen); + + /* valid packet */ + *is_valid = 1; + result = CRYPT_OK; +bail: + return result; +} /* pkcs_1_v1_5_decode */ + +#endif /* #ifdef LTC_PKCS_1 */ + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_encode.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_encode.c new file mode 100644 index 0000000000..36aaa02f5a --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_encode.c @@ -0,0 +1,111 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/*! \file pkcs_1_v1_5_encode.c + * + * LTC_PKCS #1 v1.5 Padding (Andreas Lange) + */ + +#ifdef LTC_PKCS_1 + +/*! \brief LTC_PKCS #1 v1.5 encode. + * + * \param msg The data to encode + * \param msglen The length of the data to encode (octets) + * \param block_type Block type to use in padding (\sa ltc_pkcs_1_v1_5_blocks) + * \param modulus_bitlen The bit length of the RSA modulus + * \param prng An active PRNG state (only for LTC_LTC_PKCS_1_EME) + * \param prng_idx The index of the PRNG desired (only for LTC_LTC_PKCS_1_EME) + * \param out [out] The destination for the encoded data + * \param outlen [in/out] The max size and resulting size of the encoded data + * + * \return CRYPT_OK if successful + */ +int pkcs_1_v1_5_encode(const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + prng_state *prng, + int prng_idx, + unsigned char *out, + unsigned long *outlen) +{ + unsigned long modulus_len, ps_len, i; + unsigned char *ps; + int result; + + /* valid block_type? */ + if ((block_type != LTC_LTC_PKCS_1_EMSA) && + (block_type != LTC_LTC_PKCS_1_EME)) { + return CRYPT_PK_INVALID_PADDING; + } + + if (block_type == LTC_LTC_PKCS_1_EME) { /* encryption padding, we need a valid PRNG */ + if ((result = prng_is_valid(prng_idx)) != CRYPT_OK) { + return result; + } + } + + modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); + + /* test message size */ + if ((msglen + 11) > modulus_len) { + return CRYPT_PK_INVALID_SIZE; + } + + if (*outlen < modulus_len) { + *outlen = modulus_len; + result = CRYPT_BUFFER_OVERFLOW; + goto bail; + } + + /* generate an octets string PS */ + ps = &out[2]; + ps_len = modulus_len - msglen - 3; + + if (block_type == LTC_LTC_PKCS_1_EME) { + /* now choose a random ps */ + if (prng_descriptor[prng_idx].read(ps, ps_len, prng) != ps_len) { + result = CRYPT_ERROR_READPRNG; + goto bail; + } + + /* transform zero bytes (if any) to non-zero random bytes */ + for (i = 0; i < ps_len; i++) { + while (ps[i] == 0) { + if (prng_descriptor[prng_idx].read(&ps[i], 1, prng) != 1) { + result = CRYPT_ERROR_READPRNG; + goto bail; + } + } + } + } else { + XMEMSET(ps, 0xFF, ps_len); + } + + /* create string of length modulus_len */ + out[0] = 0x00; + out[1] = (unsigned char)block_type; /* block_type 1 or 2 */ + out[2 + ps_len] = 0x00; + XMEMCPY(&out[2 + ps_len + 1], msg, msglen); + *outlen = modulus_len; + + result = CRYPT_OK; +bail: + return result; +} /* pkcs_1_v1_5_encode */ + +#endif /* #ifdef LTC_PKCS_1 */ + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_encode.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_decrypt_key.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_decrypt_key.c new file mode 100644 index 0000000000..f3b8c486f2 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_decrypt_key.c @@ -0,0 +1,105 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rsa_decrypt_key.c + RSA LTC_PKCS #1 Decryption, Tom St Denis and Andreas Lange +*/ + +#ifdef LTC_MRSA + +/** + LTC_PKCS #1 decrypt then v1.5 or OAEP depad + @param in The ciphertext + @param inlen The length of the ciphertext (octets) + @param out [out] The plaintext + @param outlen [in/out] The max size and resulting size of the plaintext (octets) + @param lparam The system "lparam" value + @param lparamlen The length of the lparam value (octets) + @param hash_idx The index of the hash desired + @param padding Type of padding (LTC_LTC_PKCS_1_OAEP or LTC_LTC_PKCS_1_V1_5) + @param stat [out] Result of the decryption, 1==valid, 0==invalid + @param key The corresponding private RSA key + @return CRYPT_OK if succcessul (even if invalid) +*/ +int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + int hash_idx, int padding, + int *stat, rsa_key *key) +{ + unsigned long modulus_bitlen, modulus_bytelen, x; + int err; + unsigned char *tmp; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(stat != NULL); + + /* default to invalid */ + *stat = 0; + + /* valid padding? */ + + if ((padding != LTC_LTC_PKCS_1_V1_5) && + (padding != LTC_LTC_PKCS_1_OAEP)) { + return CRYPT_PK_INVALID_PADDING; + } + + if (padding == LTC_LTC_PKCS_1_OAEP) { + /* valid hash ? */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + } + + /* get modulus len in bits */ + modulus_bitlen = mp_count_bits( (key->N)); + + /* outlen must be at least the size of the modulus */ + modulus_bytelen = mp_unsigned_bin_size( (key->N)); + if (modulus_bytelen != inlen) { + return CRYPT_INVALID_PACKET; + } + + /* allocate ram */ + tmp = XMALLOC(inlen); + if (tmp == NULL) { + return CRYPT_MEM; + } + + /* rsa decode the packet */ + x = inlen; + if ((err = ltc_mp.rsa_me(in, inlen, tmp, &x, PK_PRIVATE, key)) != CRYPT_OK) { + XFREE(tmp); + return err; + } + + if (padding == LTC_LTC_PKCS_1_OAEP) { + /* now OAEP decode the packet */ + err = pkcs_1_oaep_decode(tmp, x, lparam, lparamlen, modulus_bitlen, hash_idx, + out, outlen, stat); + } else { + /* now LTC_PKCS #1 v1.5 depad the packet */ + err = pkcs_1_v1_5_decode(tmp, x, LTC_LTC_PKCS_1_EME, modulus_bitlen, out, outlen, stat); + } + + XFREE(tmp); + return err; +} + +#endif /* LTC_MRSA */ + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_decrypt_key.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_encrypt_key.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_encrypt_key.c new file mode 100644 index 0000000000..4729595521 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_encrypt_key.c @@ -0,0 +1,102 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rsa_encrypt_key.c + RSA LTC_PKCS #1 encryption, Tom St Denis and Andreas Lange +*/ + +#ifdef LTC_MRSA + +/** + (LTC_PKCS #1 v2.0) OAEP pad then encrypt + @param in The plaintext + @param inlen The length of the plaintext (octets) + @param out [out] The ciphertext + @param outlen [in/out] The max size and resulting size of the ciphertext + @param lparam The system "lparam" for the encryption + @param lparamlen The length of lparam (octets) + @param prng An active PRNG + @param prng_idx The index of the desired prng + @param hash_idx The index of the desired hash + @param padding Type of padding (LTC_LTC_PKCS_1_OAEP or LTC_LTC_PKCS_1_V1_5) + @param key The RSA key to encrypt to + @return CRYPT_OK if successful +*/ +int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + prng_state *prng, int prng_idx, int hash_idx, int padding, rsa_key *key) +{ + unsigned long modulus_bitlen, modulus_bytelen, x; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* valid padding? */ + if ((padding != LTC_LTC_PKCS_1_V1_5) && + (padding != LTC_LTC_PKCS_1_OAEP)) { + return CRYPT_PK_INVALID_PADDING; + } + + /* valid prng? */ + if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { + return err; + } + + if (padding == LTC_LTC_PKCS_1_OAEP) { + /* valid hash? */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + } + + /* get modulus len in bits */ + modulus_bitlen = mp_count_bits( (key->N)); + + /* outlen must be at least the size of the modulus */ + modulus_bytelen = mp_unsigned_bin_size( (key->N)); + if (modulus_bytelen > *outlen) { + *outlen = modulus_bytelen; + return CRYPT_BUFFER_OVERFLOW; + } + + if (padding == LTC_LTC_PKCS_1_OAEP) { + /* OAEP pad the key */ + x = *outlen; + if ((err = pkcs_1_oaep_encode(in, inlen, lparam, + lparamlen, modulus_bitlen, prng, prng_idx, hash_idx, + out, &x)) != CRYPT_OK) { + return err; + } + } else { + /* LTC_PKCS #1 v1.5 pad the key */ + x = *outlen; + if ((err = pkcs_1_v1_5_encode(in, inlen, LTC_LTC_PKCS_1_EME, + modulus_bitlen, prng, prng_idx, + out, &x)) != CRYPT_OK) { + return err; + } + } + + /* rsa exptmod the OAEP or LTC_PKCS #1 v1.5 pad */ + return ltc_mp.rsa_me(out, x, out, outlen, PK_PUBLIC, key); +} + +#endif /* LTC_MRSA */ + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_encrypt_key.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_export.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_export.c new file mode 100644 index 0000000000..ef1d33cbce --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_export.c @@ -0,0 +1,69 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rsa_export.c + Export RSA LTC_PKCS keys, Tom St Denis +*/ + +#ifdef LTC_MRSA + +/** + This will export either an RSAPublicKey or RSAPrivateKey [defined in LTC_PKCS #1 v2.1] + @param out [out] Destination of the packet + @param outlen [in/out] The max size and resulting size of the packet + @param type The type of exported key (PK_PRIVATE or PK_PUBLIC) + @param key The RSA key to export + @return CRYPT_OK if successful +*/ +int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key) +{ + unsigned long zero=0; + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* type valid? */ + if (!(key->type == PK_PRIVATE) && (type == PK_PRIVATE)) { + return CRYPT_PK_INVALID_TYPE; + } + + if (type == PK_PRIVATE) { + /* private key */ + /* output is + Version, n, e, d, p, q, d mod (p-1), d mod (q - 1), 1/q mod p + */ + return der_encode_sequence_multi(out, outlen, + LTC_ASN1_SHORT_INTEGER, 1UL, &zero, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_INTEGER, 1UL, key->e, + LTC_ASN1_INTEGER, 1UL, key->d, + LTC_ASN1_INTEGER, 1UL, key->p, + LTC_ASN1_INTEGER, 1UL, key->q, + LTC_ASN1_INTEGER, 1UL, key->dP, + LTC_ASN1_INTEGER, 1UL, key->dQ, + LTC_ASN1_INTEGER, 1UL, key->qP, + LTC_ASN1_EOL, 0UL, NULL); + } else { + /* public key */ + return der_encode_sequence_multi(out, outlen, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_INTEGER, 1UL, key->e, + LTC_ASN1_EOL, 0UL, NULL); + } +} + +#endif /* LTC_MRSA */ + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_export.c,v $ */ +/* $Revision: 1.17 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_exptmod.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_exptmod.c new file mode 100644 index 0000000000..306d063811 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_exptmod.c @@ -0,0 +1,113 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rsa_exptmod.c + RSA LTC_PKCS exptmod, Tom St Denis +*/ + +#ifdef LTC_MRSA + +/** + Compute an RSA modular exponentiation + @param in The input data to send into RSA + @param inlen The length of the input (octets) + @param out [out] The destination + @param outlen [in/out] The max size and resulting size of the output + @param which Which exponent to use, e.g. PK_PRIVATE or PK_PUBLIC + @param key The RSA key to use + @return CRYPT_OK if successful +*/ +int rsa_exptmod(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int which, + rsa_key *key) +{ + void *tmp, *tmpa, *tmpb; + unsigned long x; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* is the key of the right type for the operation? */ + if (which == PK_PRIVATE && (key->type != PK_PRIVATE)) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* must be a private or public operation */ + if (which != PK_PRIVATE && which != PK_PUBLIC) { + return CRYPT_PK_INVALID_TYPE; + } + + /* init and copy into tmp */ + if ((err = mp_init_multi(&tmp, &tmpa, &tmpb, NULL)) != CRYPT_OK) { return err; } + if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, (int)inlen)) != CRYPT_OK) { goto error; } + + /* sanity check on the input */ + if (mp_cmp(key->N, tmp) == LTC_MP_LT) { + err = CRYPT_PK_INVALID_SIZE; + goto error; + } + + /* are we using the private exponent and is the key optimized? */ + if (which == PK_PRIVATE) { + /* tmpa = tmp^dP mod p */ + if ((err = mp_exptmod(tmp, key->dP, key->p, tmpa)) != CRYPT_OK) { goto error; } + + /* tmpb = tmp^dQ mod q */ + if ((err = mp_exptmod(tmp, key->dQ, key->q, tmpb)) != CRYPT_OK) { goto error; } + + /* tmp = (tmpa - tmpb) * qInv (mod p) */ + if ((err = mp_sub(tmpa, tmpb, tmp)) != CRYPT_OK) { goto error; } + if ((err = mp_mulmod(tmp, key->qP, key->p, tmp)) != CRYPT_OK) { goto error; } + + /* tmp = tmpb + q * tmp */ + if ((err = mp_mul(tmp, key->q, tmp)) != CRYPT_OK) { goto error; } + if ((err = mp_add(tmp, tmpb, tmp)) != CRYPT_OK) { goto error; } + } else { + /* exptmod it */ + if ((err = mp_exptmod(tmp, key->e, key->N, tmp)) != CRYPT_OK) { goto error; } + } + + /* read it back */ + x = (unsigned long)mp_unsigned_bin_size(key->N); + if (x > *outlen) { + *outlen = x; + err = CRYPT_BUFFER_OVERFLOW; + goto error; + } + + /* this should never happen ... */ + if (mp_unsigned_bin_size(tmp) > mp_unsigned_bin_size(key->N)) { + err = CRYPT_ERROR; + goto error; + } + *outlen = x; + + /* convert it */ + zeromem(out, x); + if ((err = mp_to_unsigned_bin(tmp, out+(x-mp_unsigned_bin_size(tmp)))) != CRYPT_OK) { goto error; } + + /* clean up and return */ + err = CRYPT_OK; +error: + mp_clear_multi(tmp, tmpa, tmpb, NULL); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_exptmod.c,v $ */ +/* $Revision: 1.18 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_free.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_free.c new file mode 100644 index 0000000000..46fe046791 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_free.c @@ -0,0 +1,34 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rsa_free.c + Free an RSA key, Tom St Denis +*/ + +#ifdef LTC_MRSA + +/** + Free an RSA key from memory + @param key The RSA key to free +*/ +void rsa_free(rsa_key *key) +{ + LTC_ARGCHKVD(key != NULL); + mp_clear_multi(key->e, key->d, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL); +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_free.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_import.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_import.c new file mode 100644 index 0000000000..5120bc1f1b --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_import.c @@ -0,0 +1,143 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rsa_import.c + Import a LTC_PKCS RSA key, Tom St Denis +*/ + +#ifdef LTC_MRSA + +/** + Import an RSAPublicKey or RSAPrivateKey [two-prime only, only support >= 1024-bit keys, defined in LTC_PKCS #1 v2.1] + @param in The packet to import from + @param inlen It's length (octets) + @param key [out] Destination for newly imported key + @return CRYPT_OK if successful, upon error allocated memory is freed +*/ +int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) +{ + int err; + void *zero; + unsigned char *tmpbuf; + unsigned long t, x, y, z, tmpoid[16]; + ltc_asn1_list ssl_pubkey_hashoid[2]; + ltc_asn1_list ssl_pubkey[2]; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + + /* init key */ + if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, + &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) { + return err; + } + + /* see if the OpenSSL DER format RSA public key will work */ + tmpbuf = XCALLOC(1, MAX_RSA_SIZE*8); + if (tmpbuf == NULL) { + err = CRYPT_MEM; + goto LBL_ERR; + } + + /* this includes the internal hash ID and optional params (NULL in this case) */ + LTC_SET_ASN1(ssl_pubkey_hashoid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0])); + LTC_SET_ASN1(ssl_pubkey_hashoid, 1, LTC_ASN1_NULL, NULL, 0); + + /* the actual format of the SSL DER key is odd, it stores a RSAPublicKey in a **BIT** string ... so we have to extract it + then proceed to convert bit to octet + */ + LTC_SET_ASN1(ssl_pubkey, 0, LTC_ASN1_SEQUENCE, &ssl_pubkey_hashoid, 2); + LTC_SET_ASN1(ssl_pubkey, 1, LTC_ASN1_BIT_STRING, tmpbuf, MAX_RSA_SIZE*8); + + if (der_decode_sequence(in, inlen, + ssl_pubkey, 2UL) == CRYPT_OK) { + + /* ok now we have to reassemble the BIT STRING to an OCTET STRING. Thanks OpenSSL... */ + for (t = y = z = x = 0; x < ssl_pubkey[1].size; x++) { + y = (y << 1) | tmpbuf[x]; + if (++z == 8) { + tmpbuf[t++] = (unsigned char)y; + y = 0; + z = 0; + } + } + + /* now it should be SEQUENCE { INTEGER, INTEGER } */ + if ((err = der_decode_sequence_multi(tmpbuf, t, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_INTEGER, 1UL, key->e, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + XFREE(tmpbuf); + goto LBL_ERR; + } + XFREE(tmpbuf); + key->type = PK_PUBLIC; + return CRYPT_OK; + } + XFREE(tmpbuf); + + /* not SSL public key, try to match against LTC_PKCS #1 standards */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + + if (mp_cmp_d(key->N, 0) == LTC_MP_EQ) { + if ((err = mp_init(&zero)) != CRYPT_OK) { + goto LBL_ERR; + } + /* it's a private key */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_INTEGER, 1UL, zero, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_INTEGER, 1UL, key->e, + LTC_ASN1_INTEGER, 1UL, key->d, + LTC_ASN1_INTEGER, 1UL, key->p, + LTC_ASN1_INTEGER, 1UL, key->q, + LTC_ASN1_INTEGER, 1UL, key->dP, + LTC_ASN1_INTEGER, 1UL, key->dQ, + LTC_ASN1_INTEGER, 1UL, key->qP, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + mp_clear(zero); + goto LBL_ERR; + } + mp_clear(zero); + key->type = PK_PRIVATE; + } else if (mp_cmp_d(key->N, 1) == LTC_MP_EQ) { + /* we don't support multi-prime RSA */ + err = CRYPT_PK_INVALID_TYPE; + goto LBL_ERR; + } else { + /* it's a public key and we lack e */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_INTEGER, 1UL, key->e, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + key->type = PK_PUBLIC; + } + return CRYPT_OK; +LBL_ERR: + mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL); + return err; +} + +#endif /* LTC_MRSA */ + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_import.c,v $ */ +/* $Revision: 1.23 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_make_key.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_make_key.c new file mode 100644 index 0000000000..7a3be3adac --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_make_key.c @@ -0,0 +1,112 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rsa_make_key.c + RSA key generation, Tom St Denis +*/ + +#ifdef LTC_MRSA + +/** + Create an RSA key + @param prng An active PRNG state + @param wprng The index of the PRNG desired + @param size The size of the modulus (key size) desired (octets) + @param e The "e" value (public key). e==65537 is a good choice + @param key [out] Destination of a newly created private key pair + @return CRYPT_OK if successful, upon error all allocated ram is freed +*/ +int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key) +{ + void *p, *q, *tmp1, *tmp2, *tmp3; + int err; + + LTC_ARGCHK(ltc_mp.name != NULL); + LTC_ARGCHK(key != NULL); + + if ((size < (MIN_RSA_SIZE/8)) || (size > (MAX_RSA_SIZE/8))) { + return CRYPT_INVALID_KEYSIZE; + } + + if ((e < 3) || ((e & 1) == 0)) { + return CRYPT_INVALID_ARG; + } + + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != CRYPT_OK) { + return err; + } + + /* make primes p and q (optimization provided by Wayne Scott) */ + if ((err = mp_set_int(tmp3, e)) != CRYPT_OK) { goto errkey; } /* tmp3 = e */ + + /* make prime "p" */ + do { + if ((err = rand_prime( p, size/2, prng, wprng)) != CRYPT_OK) { goto errkey; } + if ((err = mp_sub_d( p, 1, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = p-1 */ + if ((err = mp_gcd( tmp1, tmp3, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = gcd(p-1, e) */ + } while (mp_cmp_d( tmp2, 1) != 0); /* while e divides p-1 */ + + /* make prime "q" */ + do { + if ((err = rand_prime( q, size/2, prng, wprng)) != CRYPT_OK) { goto errkey; } + if ((err = mp_sub_d( q, 1, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = q-1 */ + if ((err = mp_gcd( tmp1, tmp3, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = gcd(q-1, e) */ + } while (mp_cmp_d( tmp2, 1) != 0); /* while e divides q-1 */ + + /* tmp1 = lcm(p-1, q-1) */ + if ((err = mp_sub_d( p, 1, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = p-1 */ + /* tmp1 = q-1 (previous do/while loop) */ + if ((err = mp_lcm( tmp1, tmp2, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = lcm(p-1, q-1) */ + + /* make key */ + if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) { + goto errkey; + } + + if ((err = mp_set_int( key->e, e)) != CRYPT_OK) { goto errkey; } /* key->e = e */ + if ((err = mp_invmod( key->e, tmp1, key->d)) != CRYPT_OK) { goto errkey; } /* key->d = 1/e mod lcm(p-1,q-1) */ + if ((err = mp_mul( p, q, key->N)) != CRYPT_OK) { goto errkey; } /* key->N = pq */ + + /* optimize for CRT now */ + /* find d mod q-1 and d mod p-1 */ + if ((err = mp_sub_d( p, 1, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = q-1 */ + if ((err = mp_sub_d( q, 1, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = p-1 */ + if ((err = mp_mod( key->d, tmp1, key->dP)) != CRYPT_OK) { goto errkey; } /* dP = d mod p-1 */ + if ((err = mp_mod( key->d, tmp2, key->dQ)) != CRYPT_OK) { goto errkey; } /* dQ = d mod q-1 */ + if ((err = mp_invmod( q, p, key->qP)) != CRYPT_OK) { goto errkey; } /* qP = 1/q mod p */ + + if ((err = mp_copy( p, key->p)) != CRYPT_OK) { goto errkey; } + if ((err = mp_copy( q, key->q)) != CRYPT_OK) { goto errkey; } + + /* set key type (in this case it's CRT optimized) */ + key->type = PK_PRIVATE; + + /* return ok and free temps */ + err = CRYPT_OK; + goto cleanup; +errkey: + mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL); +cleanup: + mp_clear_multi(tmp3, tmp2, tmp1, p, q, NULL); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_make_key.c,v $ */ +/* $Revision: 1.16 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_sign_hash.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_sign_hash.c new file mode 100644 index 0000000000..85e1b5427f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_sign_hash.c @@ -0,0 +1,134 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rsa_sign_hash.c + RSA LTC_PKCS #1 v1.5 and v2 PSS sign hash, Tom St Denis and Andreas Lange +*/ + +#ifdef LTC_MRSA + +/** + LTC_PKCS #1 pad then sign + @param in The hash to sign + @param inlen The length of the hash to sign (octets) + @param out [out] The signature + @param outlen [in/out] The max size and resulting size of the signature + @param padding Type of padding (LTC_LTC_PKCS_1_PSS or LTC_LTC_PKCS_1_V1_5) + @param prng An active PRNG state + @param prng_idx The index of the PRNG desired + @param hash_idx The index of the hash desired + @param saltlen The length of the salt desired (octets) + @param key The private RSA key to use + @return CRYPT_OK if successful +*/ +int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + int padding, + prng_state *prng, int prng_idx, + int hash_idx, unsigned long saltlen, + rsa_key *key) +{ + unsigned long modulus_bitlen, modulus_bytelen, x, y; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* valid padding? */ + if ((padding != LTC_LTC_PKCS_1_V1_5) && (padding != LTC_LTC_PKCS_1_PSS)) { + return CRYPT_PK_INVALID_PADDING; + } + + if (padding == LTC_LTC_PKCS_1_PSS) { + /* valid prng and hash ? */ + if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { + return err; + } + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + } + + /* get modulus len in bits */ + modulus_bitlen = mp_count_bits((key->N)); + + /* outlen must be at least the size of the modulus */ + modulus_bytelen = mp_unsigned_bin_size((key->N)); + if (modulus_bytelen > *outlen) { + *outlen = modulus_bytelen; + return CRYPT_BUFFER_OVERFLOW; + } + + if (padding == LTC_LTC_PKCS_1_PSS) { + /* PSS pad the key */ + x = *outlen; + if ((err = pkcs_1_pss_encode(in, inlen, saltlen, prng, prng_idx, + hash_idx, modulus_bitlen, out, &x)) != CRYPT_OK) { + return err; + } + } else { + /* LTC_PKCS #1 v1.5 pad the hash */ + unsigned char *tmpin; + ltc_asn1_list digestinfo[2], siginfo[2]; + + /* not all hashes have OIDs... so sad */ + if (hash_descriptor[hash_idx].OIDlen == 0) { + return CRYPT_INVALID_ARG; + } + + /* construct the SEQUENCE + SEQUENCE { + SEQUENCE {hashoid OID + blah NULL + } + hash OCTET STRING + } + */ + LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash_idx].OID, hash_descriptor[hash_idx].OIDlen); + LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0); + LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); + LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, in, inlen); + + /* allocate memory for the encoding */ + y = mp_unsigned_bin_size(key->N); + tmpin = XMALLOC(y); + if (tmpin == NULL) { + return CRYPT_MEM; + } + + if ((err = der_encode_sequence(siginfo, 2, tmpin, &y)) != CRYPT_OK) { + XFREE(tmpin); + return err; + } + + x = *outlen; + if ((err = pkcs_1_v1_5_encode(tmpin, y, LTC_LTC_PKCS_1_EMSA, + modulus_bitlen, NULL, 0, + out, &x)) != CRYPT_OK) { + XFREE(tmpin); + return err; + } + XFREE(tmpin); + } + + /* RSA encode it */ + return ltc_mp.rsa_me(out, x, out, outlen, PK_PRIVATE, key); +} + +#endif /* LTC_MRSA */ + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_sign_hash.c,v $ */ +/* $Revision: 1.11 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_verify_hash.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_verify_hash.c new file mode 100644 index 0000000000..f8a7424bbb --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/pk/rsa/rsa_verify_hash.c @@ -0,0 +1,167 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rsa_verify_hash.c + RSA LTC_PKCS #1 v1.5 or v2 PSS signature verification, Tom St Denis and Andreas Lange +*/ + +#ifdef LTC_MRSA + +/** + LTC_PKCS #1 de-sign then v1.5 or PSS depad + @param sig The signature data + @param siglen The length of the signature data (octets) + @param hash The hash of the message that was signed + @param hashlen The length of the hash of the message that was signed (octets) + @param padding Type of padding (LTC_LTC_PKCS_1_PSS or LTC_LTC_PKCS_1_V1_5) + @param hash_idx The index of the desired hash + @param saltlen The length of the salt used during signature + @param stat [out] The result of the signature comparison, 1==valid, 0==invalid + @param key The public RSA key corresponding to the key that performed the signature + @return CRYPT_OK on success (even if the signature is invalid) +*/ +int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int padding, + int hash_idx, unsigned long saltlen, + int *stat, rsa_key *key) +{ + unsigned long modulus_bitlen, modulus_bytelen, x; + int err; + unsigned char *tmpbuf; + + LTC_ARGCHK(hash != NULL); + LTC_ARGCHK(sig != NULL); + LTC_ARGCHK(stat != NULL); + LTC_ARGCHK(key != NULL); + + /* default to invalid */ + *stat = 0; + + /* valid padding? */ + + if ((padding != LTC_LTC_PKCS_1_V1_5) && + (padding != LTC_LTC_PKCS_1_PSS)) { + return CRYPT_PK_INVALID_PADDING; + } + + if (padding == LTC_LTC_PKCS_1_PSS) { + /* valid hash ? */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + } + + /* get modulus len in bits */ + modulus_bitlen = mp_count_bits( (key->N)); + + /* outlen must be at least the size of the modulus */ + modulus_bytelen = mp_unsigned_bin_size( (key->N)); + if (modulus_bytelen != siglen) { + return CRYPT_INVALID_PACKET; + } + + /* allocate temp buffer for decoded sig */ + tmpbuf = XMALLOC(siglen); + if (tmpbuf == NULL) { + return CRYPT_MEM; + } + + /* RSA decode it */ + x = siglen; + if ((err = ltc_mp.rsa_me(sig, siglen, tmpbuf, &x, PK_PUBLIC, key)) != CRYPT_OK) { + XFREE(tmpbuf); + return err; + } + + /* make sure the output is the right size */ + if (x != siglen) { + XFREE(tmpbuf); + return CRYPT_INVALID_PACKET; + } + + if (padding == LTC_LTC_PKCS_1_PSS) { + /* PSS decode and verify it */ + err = pkcs_1_pss_decode(hash, hashlen, tmpbuf, x, saltlen, hash_idx, modulus_bitlen, stat); + } else { + /* LTC_PKCS #1 v1.5 decode it */ + unsigned char *out; + unsigned long outlen, loid[16]; + int decoded; + ltc_asn1_list digestinfo[2], siginfo[2]; + + /* not all hashes have OIDs... so sad */ + if (hash_descriptor[hash_idx].OIDlen == 0) { + err = CRYPT_INVALID_ARG; + goto bail_2; + } + + /* allocate temp buffer for decoded hash */ + outlen = ((modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0)) - 3; + out = XMALLOC(outlen); + if (out == NULL) { + err = CRYPT_MEM; + goto bail_2; + } + + if ((err = pkcs_1_v1_5_decode(tmpbuf, x, LTC_LTC_PKCS_1_EMSA, modulus_bitlen, out, &outlen, &decoded)) != CRYPT_OK) { + XFREE(out); + goto bail_2; + } + + /* now we must decode out[0...outlen-1] using ASN.1, test the OID and then test the hash */ + /* construct the SEQUENCE + SEQUENCE { + SEQUENCE {hashoid OID + blah NULL + } + hash OCTET STRING + } + */ + LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, loid, sizeof(loid)/sizeof(loid[0])); + LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0); + LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); + LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen); + + if ((err = der_decode_sequence(out, outlen, siginfo, 2)) != CRYPT_OK) { + XFREE(out); + goto bail_2; + } + + /* test OID */ + if ((digestinfo[0].size == hash_descriptor[hash_idx].OIDlen) && + (XMEMCMP(digestinfo[0].data, hash_descriptor[hash_idx].OID, sizeof(unsigned long) * hash_descriptor[hash_idx].OIDlen) == 0) && + (siginfo[1].size == hashlen) && + (XMEMCMP(siginfo[1].data, hash, hashlen) == 0)) { + *stat = 1; + } + +#ifdef LTC_CLEAN_STACK + zeromem(out, outlen); +#endif + XFREE(out); + } + +bail_2: +#ifdef LTC_CLEAN_STACK + zeromem(tmpbuf, siglen); +#endif + XFREE(tmpbuf); + return err; +} + +#endif /* LTC_MRSA */ + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_verify_hash.c,v $ */ +/* $Revision: 1.13 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/fortuna.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/fortuna.c new file mode 100644 index 0000000000..bc309a65fc --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/fortuna.c @@ -0,0 +1,427 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file fortuna.c + Fortuna PRNG, Tom St Denis +*/ + +/* Implementation of Fortuna by Tom St Denis + +We deviate slightly here for reasons of simplicity [and to fit in the API]. First all "sources" +in the AddEntropy function are fixed to 0. Second since no reliable timer is provided +we reseed automatically when len(pool0) >= 64 or every LTC_FORTUNA_WD calls to the read function */ + +#ifdef LTC_FORTUNA + +/* requries LTC_SHA256 and AES */ +#if !(defined(LTC_RIJNDAEL) && defined(LTC_SHA256)) + #error LTC_FORTUNA requires LTC_SHA256 and LTC_RIJNDAEL (AES) +#endif + +#ifndef LTC_FORTUNA_POOLS + #warning LTC_FORTUNA_POOLS was not previously defined (old headers?) + #define LTC_FORTUNA_POOLS 32 +#endif + +#if LTC_FORTUNA_POOLS < 4 || LTC_FORTUNA_POOLS > 32 + #error LTC_FORTUNA_POOLS must be in [4..32] +#endif + +const struct ltc_prng_descriptor fortuna_desc = { + "fortuna", 1024, + &fortuna_start, + &fortuna_add_entropy, + &fortuna_ready, + &fortuna_read, + &fortuna_done, + &fortuna_export, + &fortuna_import, + &fortuna_test +}; + +/* update the IV */ +static void fortuna_update_iv(prng_state *prng) +{ + int x; + unsigned char *IV; + /* update IV */ + IV = prng->fortuna.IV; + for (x = 0; x < 16; x++) { + IV[x] = (IV[x] + 1) & 255; + if (IV[x] != 0) break; + } +} + +/* reseed the PRNG */ +static int fortuna_reseed(prng_state *prng) +{ + unsigned char tmp[MAXBLOCKSIZE]; + hash_state md; + int err, x; + + ++prng->fortuna.reset_cnt; + + /* new K == LTC_SHA256(K || s) where s == LTC_SHA256(P0) || LTC_SHA256(P1) ... */ + sha256_init(&md); + if ((err = sha256_process(&md, prng->fortuna.K, 32)) != CRYPT_OK) { + sha256_done(&md, tmp); + return err; + } + + for (x = 0; x < LTC_FORTUNA_POOLS; x++) { + if (x == 0 || ((prng->fortuna.reset_cnt >> (x-1)) & 1) == 0) { + /* terminate this hash */ + if ((err = sha256_done(&prng->fortuna.pool[x], tmp)) != CRYPT_OK) { + sha256_done(&md, tmp); + return err; + } + /* add it to the string */ + if ((err = sha256_process(&md, tmp, 32)) != CRYPT_OK) { + sha256_done(&md, tmp); + return err; + } + /* reset this pool */ + if ((err = sha256_init(&prng->fortuna.pool[x])) != CRYPT_OK) { + sha256_done(&md, tmp); + return err; + } + } else { + break; + } + } + + /* finish key */ + if ((err = sha256_done(&md, prng->fortuna.K)) != CRYPT_OK) { + return err; + } + if ((err = rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey)) != CRYPT_OK) { + return err; + } + fortuna_update_iv(prng); + + /* reset pool len */ + prng->fortuna.pool0_len = 0; + prng->fortuna.wd = 0; + + +#ifdef LTC_CLEAN_STACK + zeromem(&md, sizeof(md)); + zeromem(tmp, sizeof(tmp)); +#endif + + return CRYPT_OK; +} + +/** + Start the PRNG + @param prng [out] The PRNG state to initialize + @return CRYPT_OK if successful +*/ +int fortuna_start(prng_state *prng) +{ + int err, x, y; + unsigned char tmp[MAXBLOCKSIZE]; + + LTC_ARGCHK(prng != NULL); + + /* initialize the pools */ + for (x = 0; x < LTC_FORTUNA_POOLS; x++) { + if ((err = sha256_init(&prng->fortuna.pool[x])) != CRYPT_OK) { + for (y = 0; y < x; y++) { + sha256_done(&prng->fortuna.pool[y], tmp); + } + return err; + } + } + prng->fortuna.pool_idx = prng->fortuna.pool0_len = prng->fortuna.wd = 0; + prng->fortuna.reset_cnt = 0; + + /* reset bufs */ + zeromem(prng->fortuna.K, 32); + if ((err = rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey)) != CRYPT_OK) { + for (x = 0; x < LTC_FORTUNA_POOLS; x++) { + sha256_done(&prng->fortuna.pool[x], tmp); + } + return err; + } + zeromem(prng->fortuna.IV, 16); + + LTC_MUTEX_INIT(&prng->fortuna.prng_lock) + + return CRYPT_OK; +} + +/** + Add entropy to the PRNG state + @param in The data to add + @param inlen Length of the data to add + @param prng PRNG state to update + @return CRYPT_OK if successful +*/ +int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + unsigned char tmp[2]; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(prng != NULL); + + LTC_MUTEX_LOCK(&prng->fortuna.prng_lock); + + /* ensure inlen <= 32 */ + if (inlen > 32) { + LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); + return CRYPT_INVALID_ARG; + } + + /* add s || length(in) || in to pool[pool_idx] */ + tmp[0] = 0; + tmp[1] = (unsigned char)inlen; + if ((err = sha256_process(&prng->fortuna.pool[prng->fortuna.pool_idx], tmp, 2)) != CRYPT_OK) { + LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); + return err; + } + if ((err = sha256_process(&prng->fortuna.pool[prng->fortuna.pool_idx], in, inlen)) != CRYPT_OK) { + LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); + return err; + } + if (prng->fortuna.pool_idx == 0) { + prng->fortuna.pool0_len += inlen; + } + if (++(prng->fortuna.pool_idx) == LTC_FORTUNA_POOLS) { + prng->fortuna.pool_idx = 0; + } + + LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); + return CRYPT_OK; +} + +/** + Make the PRNG ready to read from + @param prng The PRNG to make active + @return CRYPT_OK if successful +*/ +int fortuna_ready(prng_state *prng) +{ + return fortuna_reseed(prng); +} + +/** + Read from the PRNG + @param out Destination + @param outlen Length of output + @param prng The active PRNG to read from + @return Number of octets read +*/ +unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state *prng) +{ + unsigned char tmp[16]; + int err; + unsigned long tlen; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(prng != NULL); + + LTC_MUTEX_LOCK(&prng->fortuna.prng_lock); + + /* do we have to reseed? */ + if (++prng->fortuna.wd == LTC_FORTUNA_WD || prng->fortuna.pool0_len >= 64) { + if ((err = fortuna_reseed(prng)) != CRYPT_OK) { + LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); + return 0; + } + } + + /* now generate the blocks required */ + tlen = outlen; + + /* handle whole blocks without the extra XMEMCPY */ + while (outlen >= 16) { + /* encrypt the IV and store it */ + rijndael_ecb_encrypt(prng->fortuna.IV, out, &prng->fortuna.skey); + out += 16; + outlen -= 16; + fortuna_update_iv(prng); + } + + /* left over bytes? */ + if (outlen > 0) { + rijndael_ecb_encrypt(prng->fortuna.IV, tmp, &prng->fortuna.skey); + XMEMCPY(out, tmp, outlen); + fortuna_update_iv(prng); + } + + /* generate new key */ + rijndael_ecb_encrypt(prng->fortuna.IV, prng->fortuna.K , &prng->fortuna.skey); fortuna_update_iv(prng); + rijndael_ecb_encrypt(prng->fortuna.IV, prng->fortuna.K+16, &prng->fortuna.skey); fortuna_update_iv(prng); + if ((err = rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey)) != CRYPT_OK) { + LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); + return 0; + } + +#ifdef LTC_CLEAN_STACK + zeromem(tmp, sizeof(tmp)); +#endif + LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); + return tlen; +} + +/** + Terminate the PRNG + @param prng The PRNG to terminate + @return CRYPT_OK if successful +*/ +int fortuna_done(prng_state *prng) +{ + int err, x; + unsigned char tmp[32]; + + LTC_ARGCHK(prng != NULL); + LTC_MUTEX_LOCK(&prng->fortuna.prng_lock); + + /* terminate all the hashes */ + for (x = 0; x < LTC_FORTUNA_POOLS; x++) { + if ((err = sha256_done(&(prng->fortuna.pool[x]), tmp)) != CRYPT_OK) { + LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); + return err; + } + } + /* call cipher done when we invent one ;-) */ + +#ifdef LTC_CLEAN_STACK + zeromem(tmp, sizeof(tmp)); +#endif + + LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); + return CRYPT_OK; +} + +/** + Export the PRNG state + @param out [out] Destination + @param outlen [in/out] Max size and resulting size of the state + @param prng The PRNG to export + @return CRYPT_OK if successful +*/ +int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng) +{ + int x, err; + hash_state *md; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(prng != NULL); + + LTC_MUTEX_LOCK(&prng->fortuna.prng_lock); + + /* we'll write bytes for s&g's */ + if (*outlen < 32*LTC_FORTUNA_POOLS) { + LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); + *outlen = 32*LTC_FORTUNA_POOLS; + return CRYPT_BUFFER_OVERFLOW; + } + + md = XMALLOC(sizeof(hash_state)); + if (md == NULL) { + LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); + return CRYPT_MEM; + } + + /* to emit the state we copy each pool, terminate it then hash it again so + * an attacker who sees the state can't determine the current state of the PRNG + */ + for (x = 0; x < LTC_FORTUNA_POOLS; x++) { + /* copy the PRNG */ + XMEMCPY(md, &(prng->fortuna.pool[x]), sizeof(*md)); + + /* terminate it */ + if ((err = sha256_done(md, out+x*32)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* now hash it */ + if ((err = sha256_init(md)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = sha256_process(md, out+x*32, 32)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = sha256_done(md, out+x*32)) != CRYPT_OK) { + goto LBL_ERR; + } + } + *outlen = 32*LTC_FORTUNA_POOLS; + err = CRYPT_OK; + +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(*md)); +#endif + XFREE(md); + LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); + return err; +} + +/** + Import a PRNG state + @param in The PRNG state + @param inlen Size of the state + @param prng The PRNG to import + @return CRYPT_OK if successful +*/ +int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + int err, x; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(prng != NULL); + + if (inlen != 32*LTC_FORTUNA_POOLS) { + return CRYPT_INVALID_ARG; + } + + if ((err = fortuna_start(prng)) != CRYPT_OK) { + return err; + } + for (x = 0; x < LTC_FORTUNA_POOLS; x++) { + if ((err = fortuna_add_entropy(in+x*32, 32, prng)) != CRYPT_OK) { + return err; + } + } + return err; +} + +/** + PRNG self-test + @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled +*/ +int fortuna_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + int err; + + if ((err = sha256_test()) != CRYPT_OK) { + return err; + } + return rijndael_test(); +#endif +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/prngs/fortuna.c,v $ */ +/* $Revision: 1.16 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/rc4.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/rc4.c new file mode 100644 index 0000000000..73d4700492 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/rc4.c @@ -0,0 +1,269 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rc4.c + LTC_RC4 PRNG, Tom St Denis +*/ + +#ifdef LTC_RC4 + +const struct ltc_prng_descriptor rc4_desc = +{ + "rc4", 32, + &rc4_start, + &rc4_add_entropy, + &rc4_ready, + &rc4_read, + &rc4_done, + &rc4_export, + &rc4_import, + &rc4_test +}; + +/** + Start the PRNG + @param prng [out] The PRNG state to initialize + @return CRYPT_OK if successful +*/ +int rc4_start(prng_state *prng) +{ + LTC_ARGCHK(prng != NULL); + + /* set keysize to zero */ + prng->rc4.x = 0; + + return CRYPT_OK; +} + +/** + Add entropy to the PRNG state + @param in The data to add + @param inlen Length of the data to add + @param prng PRNG state to update + @return CRYPT_OK if successful +*/ +int rc4_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(prng != NULL); + + /* trim as required */ + if (prng->rc4.x + inlen > 256) { + if (prng->rc4.x == 256) { + /* I can't possibly accept another byte, ok maybe a mint wafer... */ + return CRYPT_OK; + } else { + /* only accept part of it */ + inlen = 256 - prng->rc4.x; + } + } + + while (inlen--) { + prng->rc4.buf[prng->rc4.x++] = *in++; + } + + return CRYPT_OK; + +} + +/** + Make the PRNG ready to read from + @param prng The PRNG to make active + @return CRYPT_OK if successful +*/ +int rc4_ready(prng_state *prng) +{ + unsigned char key[256], tmp, *s; + int keylen, x, y, j; + + LTC_ARGCHK(prng != NULL); + + /* extract the key */ + s = prng->rc4.buf; + XMEMCPY(key, s, 256); + keylen = prng->rc4.x; + + /* make LTC_RC4 perm and shuffle */ + for (x = 0; x < 256; x++) { + s[x] = x; + } + + for (j = x = y = 0; x < 256; x++) { + y = (y + prng->rc4.buf[x] + key[j++]) & 255; + if (j == keylen) { + j = 0; + } + tmp = s[x]; s[x] = s[y]; s[y] = tmp; + } + prng->rc4.x = 0; + prng->rc4.y = 0; + +#ifdef LTC_CLEAN_STACK + zeromem(key, sizeof(key)); +#endif + + return CRYPT_OK; +} + +/** + Read from the PRNG + @param out Destination + @param outlen Length of output + @param prng The active PRNG to read from + @return Number of octets read +*/ +unsigned long rc4_read(unsigned char *out, unsigned long outlen, prng_state *prng) +{ + unsigned char x, y, *s, tmp; + unsigned long n; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(prng != NULL); + +#ifdef LTC_VALGRIND + zeromem(out, outlen); +#endif + + n = outlen; + x = prng->rc4.x; + y = prng->rc4.y; + s = prng->rc4.buf; + while (outlen--) { + x = (x + 1) & 255; + y = (y + s[x]) & 255; + tmp = s[x]; s[x] = s[y]; s[y] = tmp; + tmp = (s[x] + s[y]) & 255; + *out++ ^= s[tmp]; + } + prng->rc4.x = x; + prng->rc4.y = y; + return n; +} + +/** + Terminate the PRNG + @param prng The PRNG to terminate + @return CRYPT_OK if successful +*/ +int rc4_done(prng_state *prng) +{ + LTC_ARGCHK(prng != NULL); + return CRYPT_OK; +} + +/** + Export the PRNG state + @param out [out] Destination + @param outlen [in/out] Max size and resulting size of the state + @param prng The PRNG to export + @return CRYPT_OK if successful +*/ +int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng) +{ + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(prng != NULL); + + if (*outlen < 32) { + *outlen = 32; + return CRYPT_BUFFER_OVERFLOW; + } + + if (rc4_read(out, 32, prng) != 32) { + return CRYPT_ERROR_READPRNG; + } + *outlen = 32; + + return CRYPT_OK; +} + +/** + Import a PRNG state + @param in The PRNG state + @param inlen Size of the state + @param prng The PRNG to import + @return CRYPT_OK if successful +*/ +int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + int err; + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(prng != NULL); + + if (inlen != 32) { + return CRYPT_INVALID_ARG; + } + + if ((err = rc4_start(prng)) != CRYPT_OK) { + return err; + } + return rc4_add_entropy(in, 32, prng); +} + +/** + PRNG self-test + @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled +*/ +int rc4_test(void) +{ +#if !defined(LTC_TEST) || defined(LTC_VALGRIND) + return CRYPT_NOP; +#else + static const struct { + unsigned char key[8], pt[8], ct[8]; + } tests[] = { +{ + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + { 0x75, 0xb7, 0x87, 0x80, 0x99, 0xe0, 0xc5, 0x96 } +} +}; + prng_state prng; + unsigned char dst[8]; + int err, x; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + if ((err = rc4_start(&prng)) != CRYPT_OK) { + return err; + } + if ((err = rc4_add_entropy(tests[x].key, 8, &prng)) != CRYPT_OK) { + return err; + } + if ((err = rc4_ready(&prng)) != CRYPT_OK) { + return err; + } + XMEMCPY(dst, tests[x].pt, 8); + if (rc4_read(dst, 8, &prng) != 8) { + return CRYPT_ERROR_READPRNG; + } + rc4_done(&prng); + if (XMEMCMP(dst, tests[x].ct, 8)) { +#if 0 + int y; + printf("\n\nLTC_RC4 failed, I got:\n"); + for (y = 0; y < 8; y++) printf("%02x ", dst[y]); + printf("\n"); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/prngs/rc4.c,v $ */ +/* $Revision: 1.11 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/rng_get_bytes.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/rng_get_bytes.c new file mode 100644 index 0000000000..54552c19a8 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/rng_get_bytes.c @@ -0,0 +1,148 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rng_get_bytes.c + portable way to get secure random bits to feed a PRNG (Tom St Denis) +*/ + +#ifdef LTC_DEVRANDOM +/* on *NIX read /dev/random */ +static unsigned long rng_nix(unsigned char *buf, unsigned long len, + void (*callback)(void)) +{ +#ifdef LTC_NO_FILE + return 0; +#else + FILE *f; + unsigned long x; +#ifdef TRY_URANDOM_FIRST + f = fopen("/dev/urandom", "rb"); + if (f == NULL) +#endif /* TRY_URANDOM_FIRST */ + f = fopen("/dev/random", "rb"); + + if (f == NULL) { + return 0; + } + + /* disable buffering */ + if (setvbuf(f, NULL, _IONBF, 0) != 0) { + fclose(f); + return 0; + } + + x = (unsigned long)fread(buf, 1, (size_t)len, f); + fclose(f); + return x; +#endif /* LTC_NO_FILE */ +} + +#endif /* LTC_DEVRANDOM */ + +/* on ANSI C platforms with 100 < CLOCKS_PER_SEC < 10000 */ +#if defined(CLOCKS_PER_SEC) && !defined(WINCE) + +#define ANSI_RNG + +static unsigned long rng_ansic(unsigned char *buf, unsigned long len, + void (*callback)(void)) +{ + clock_t t1; + int l, acc, bits, a, b; + + if (XCLOCKS_PER_SEC < 100 || XCLOCKS_PER_SEC > 10000) { + return 0; + } + + l = len; + bits = 8; + acc = a = b = 0; + while (len--) { + if (callback != NULL) callback(); + while (bits--) { + do { + t1 = XCLOCK(); while (t1 == XCLOCK()) a ^= 1; + t1 = XCLOCK(); while (t1 == XCLOCK()) b ^= 1; + } while (a == b); + acc = (acc << 1) | a; + } + *buf++ = acc; + acc = 0; + bits = 8; + } + acc = bits = a = b = 0; + return l; +} + +#endif + +/* Try the Microsoft CSP */ +#if defined(WIN32) || defined(WINCE) +#define _WIN32_WINNT 0x0400 +#ifdef WINCE + #define UNDER_CE + #define ARM +#endif +#include +#include + +static unsigned long rng_win32(unsigned char *buf, unsigned long len, + void (*callback)(void)) +{ + HCRYPTPROV hProv = 0; + if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, + (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) && + !CryptAcquireContext (&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET)) + return 0; + + if (CryptGenRandom(hProv, len, buf) == TRUE) { + CryptReleaseContext(hProv, 0); + return len; + } else { + CryptReleaseContext(hProv, 0); + return 0; + } +} + +#endif /* WIN32 */ + +/** + Read the system RNG + @param out Destination + @param outlen Length desired (octets) + @param callback Pointer to void function to act as "callback" when RNG is slow. This can be NULL + @return Number of octets read +*/ +unsigned long rng_get_bytes(unsigned char *out, unsigned long outlen, + void (*callback)(void)) +{ + unsigned long x; + + LTC_ARGCHK(out != NULL); + +#if defined(LTC_DEVRANDOM) + x = rng_nix(out, outlen, callback); if (x != 0) { return x; } +#endif +#ifdef WIN32 + x = rng_win32(out, outlen, callback); if (x != 0) { return x; } +#endif +#ifdef ANSI_RNG + x = rng_ansic(out, outlen, callback); if (x != 0) { return x; } +#endif + return 0; +} + +/* $Source: /cvs/libtom/libtomcrypt/src/prngs/rng_get_bytes.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/rng_make_prng.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/rng_make_prng.c new file mode 100644 index 0000000000..dba307cf60 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/rng_make_prng.c @@ -0,0 +1,69 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rng_make_prng.c + portable way to get secure random bits to feed a PRNG (Tom St Denis) +*/ + +/** + Create a PRNG from a RNG + @param bits Number of bits of entropy desired (64 ... 1024) + @param wprng Index of which PRNG to setup + @param prng [out] PRNG state to initialize + @param callback A pointer to a void function for when the RNG is slow, this can be NULL + @return CRYPT_OK if successful +*/ +int rng_make_prng(int bits, int wprng, prng_state *prng, + void (*callback)(void)) +{ + unsigned char buf[256]; + int err; + + LTC_ARGCHK(prng != NULL); + + /* check parameter */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + if (bits < 64 || bits > 1024) { + return CRYPT_INVALID_PRNGSIZE; + } + + if ((err = prng_descriptor[wprng].start(prng)) != CRYPT_OK) { + return err; + } + + bits = ((bits/8)+((bits&7)!=0?1:0)) * 2; + if (rng_get_bytes(buf, (unsigned long)bits, callback) != (unsigned long)bits) { + return CRYPT_ERROR_READPRNG; + } + + if ((err = prng_descriptor[wprng].add_entropy(buf, (unsigned long)bits, prng)) != CRYPT_OK) { + return err; + } + + if ((err = prng_descriptor[wprng].ready(prng)) != CRYPT_OK) { + return err; + } + + #ifdef LTC_CLEAN_STACK + zeromem(buf, sizeof(buf)); + #endif + return CRYPT_OK; +} + + +/* $Source: /cvs/libtom/libtomcrypt/src/prngs/rng_make_prng.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/sober128.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/sober128.c new file mode 100644 index 0000000000..8be7edc4a1 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/sober128.c @@ -0,0 +1,500 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file sober128.c + Implementation of SOBER-128 by Tom St Denis. + Based on s128fast.c reference code supplied by Greg Rose of QUALCOMM. +*/ + +#ifdef LTC_SOBER128 + +#include "sober128tab.c" + +const struct ltc_prng_descriptor sober128_desc = +{ + "sober128", 64, + &sober128_start, + &sober128_add_entropy, + &sober128_ready, + &sober128_read, + &sober128_done, + &sober128_export, + &sober128_import, + &sober128_test +}; + +/* don't change these... */ +#define N 17 +#define FOLD N /* how many iterations of folding to do */ +#define INITKONST 0x6996c53a /* value of KONST to use during key loading */ +#define KEYP 15 /* where to insert key words */ +#define FOLDP 4 /* where to insert non-linear feedback */ + +#define B(x,i) ((unsigned char)(((x) >> (8*i)) & 0xFF)) + +static ulong32 BYTE2WORD(unsigned char *b) +{ + ulong32 t; + LOAD32L(t, b); + return t; +} + +#define WORD2BYTE(w, b) STORE32L(b, w) + +static void XORWORD(ulong32 w, unsigned char *b) +{ + ulong32 t; + LOAD32L(t, b); + t ^= w; + STORE32L(t, b); +} + +/* give correct offset for the current position of the register, + * where logically R[0] is at position "zero". + */ +#define OFF(zero, i) (((zero)+(i)) % N) + +/* step the LFSR */ +/* After stepping, "zero" moves right one place */ +#define STEP(R,z) \ + R[OFF(z,0)] = R[OFF(z,15)] ^ R[OFF(z,4)] ^ (R[OFF(z,0)] << 8) ^ Multab[(R[OFF(z,0)] >> 24) & 0xFF]; + +static void cycle(ulong32 *R) +{ + ulong32 t; + int i; + + STEP(R,0); + t = R[0]; + for (i = 1; i < N; ++i) { + R[i-1] = R[i]; + } + R[N-1] = t; +} + +/* Return a non-linear function of some parts of the register. + */ +#define NLFUNC(c,z) \ +{ \ + t = c->R[OFF(z,0)] + c->R[OFF(z,16)]; \ + t ^= Sbox[(t >> 24) & 0xFF]; \ + t = RORc(t, 8); \ + t = ((t + c->R[OFF(z,1)]) ^ c->konst) + c->R[OFF(z,6)]; \ + t ^= Sbox[(t >> 24) & 0xFF]; \ + t = t + c->R[OFF(z,13)]; \ +} + +static ulong32 nltap(struct sober128_prng *c) +{ + ulong32 t; + NLFUNC(c, 0); + return t; +} + +/** + Start the PRNG + @param prng [out] The PRNG state to initialize + @return CRYPT_OK if successful +*/ +int sober128_start(prng_state *prng) +{ + int i; + struct sober128_prng *c; + + LTC_ARGCHK(prng != NULL); + + c = &(prng->sober128); + + /* Register initialised to Fibonacci numbers */ + c->R[0] = 1; + c->R[1] = 1; + for (i = 2; i < N; ++i) { + c->R[i] = c->R[i-1] + c->R[i-2]; + } + c->konst = INITKONST; + + /* next add_entropy will be the key */ + c->flag = 1; + c->set = 0; + + return CRYPT_OK; +} + +/* Save the current register state + */ +static void s128_savestate(struct sober128_prng *c) +{ + int i; + for (i = 0; i < N; ++i) { + c->initR[i] = c->R[i]; + } +} + +/* initialise to previously saved register state + */ +static void s128_reloadstate(struct sober128_prng *c) +{ + int i; + + for (i = 0; i < N; ++i) { + c->R[i] = c->initR[i]; + } +} + +/* Initialise "konst" + */ +static void s128_genkonst(struct sober128_prng *c) +{ + ulong32 newkonst; + + do { + cycle(c->R); + newkonst = nltap(c); + } while ((newkonst & 0xFF000000) == 0); + c->konst = newkonst; +} + +/* Load key material into the register + */ +#define ADDKEY(k) \ + c->R[KEYP] += (k); + +#define XORNL(nl) \ + c->R[FOLDP] ^= (nl); + +/* nonlinear diffusion of register for key */ +#define DROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); c->R[OFF((z+1),FOLDP)] ^= t; +static void s128_diffuse(struct sober128_prng *c) +{ + ulong32 t; + /* relies on FOLD == N == 17! */ + DROUND(0); + DROUND(1); + DROUND(2); + DROUND(3); + DROUND(4); + DROUND(5); + DROUND(6); + DROUND(7); + DROUND(8); + DROUND(9); + DROUND(10); + DROUND(11); + DROUND(12); + DROUND(13); + DROUND(14); + DROUND(15); + DROUND(16); +} + +/** + Add entropy to the PRNG state + @param in The data to add + @param inlen Length of the data to add + @param prng PRNG state to update + @return CRYPT_OK if successful +*/ +int sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + struct sober128_prng *c; + ulong32 i, k; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(prng != NULL); + c = &(prng->sober128); + + if (c->flag == 1) { + /* this is the first call to the add_entropy so this input is the key */ + /* inlen must be multiple of 4 bytes */ + if ((inlen & 3) != 0) { + return CRYPT_INVALID_KEYSIZE; + } + + for (i = 0; i < inlen; i += 4) { + k = BYTE2WORD((unsigned char *)&in[i]); + ADDKEY(k); + cycle(c->R); + XORNL(nltap(c)); + } + + /* also fold in the length of the key */ + ADDKEY(inlen); + + /* now diffuse */ + s128_diffuse(c); + + s128_genkonst(c); + s128_savestate(c); + c->nbuf = 0; + c->flag = 0; + c->set = 1; + } else { + /* ok we are adding an IV then... */ + s128_reloadstate(c); + + /* inlen must be multiple of 4 bytes */ + if ((inlen & 3) != 0) { + return CRYPT_INVALID_KEYSIZE; + } + + for (i = 0; i < inlen; i += 4) { + k = BYTE2WORD((unsigned char *)&in[i]); + ADDKEY(k); + cycle(c->R); + XORNL(nltap(c)); + } + + /* also fold in the length of the key */ + ADDKEY(inlen); + + /* now diffuse */ + s128_diffuse(c); + c->nbuf = 0; + } + + return CRYPT_OK; +} + +/** + Make the PRNG ready to read from + @param prng The PRNG to make active + @return CRYPT_OK if successful +*/ +int sober128_ready(prng_state *prng) +{ + return prng->sober128.set == 1 ? CRYPT_OK : CRYPT_ERROR; +} + +/* XOR pseudo-random bytes into buffer + */ +#define SROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); XORWORD(t, out+(z*4)); + +/** + Read from the PRNG + @param out Destination + @param outlen Length of output + @param prng The active PRNG to read from + @return Number of octets read +*/ +unsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state *prng) +{ + struct sober128_prng *c; + ulong32 t, tlen; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(prng != NULL); + +#ifdef LTC_VALGRIND + zeromem(out, outlen); +#endif + + c = &(prng->sober128); + t = 0; + tlen = outlen; + + /* handle any previously buffered bytes */ + while (c->nbuf != 0 && outlen != 0) { + *out++ ^= c->sbuf & 0xFF; + c->sbuf >>= 8; + c->nbuf -= 8; + --outlen; + } + +#ifndef LTC_SMALL_CODE + /* do lots at a time, if there's enough to do */ + while (outlen >= N*4) { + SROUND(0); + SROUND(1); + SROUND(2); + SROUND(3); + SROUND(4); + SROUND(5); + SROUND(6); + SROUND(7); + SROUND(8); + SROUND(9); + SROUND(10); + SROUND(11); + SROUND(12); + SROUND(13); + SROUND(14); + SROUND(15); + SROUND(16); + out += 4*N; + outlen -= 4*N; + } +#endif + + /* do small or odd size buffers the slow way */ + while (4 <= outlen) { + cycle(c->R); + t = nltap(c); + XORWORD(t, out); + out += 4; + outlen -= 4; + } + + /* handle any trailing bytes */ + if (outlen != 0) { + cycle(c->R); + c->sbuf = nltap(c); + c->nbuf = 32; + while (c->nbuf != 0 && outlen != 0) { + *out++ ^= c->sbuf & 0xFF; + c->sbuf >>= 8; + c->nbuf -= 8; + --outlen; + } + } + + return tlen; +} + +/** + Terminate the PRNG + @param prng The PRNG to terminate + @return CRYPT_OK if successful +*/ +int sober128_done(prng_state *prng) +{ + LTC_ARGCHK(prng != NULL); + return CRYPT_OK; +} + +/** + Export the PRNG state + @param out [out] Destination + @param outlen [in/out] Max size and resulting size of the state + @param prng The PRNG to export + @return CRYPT_OK if successful +*/ +int sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng) +{ + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(prng != NULL); + + if (*outlen < 64) { + *outlen = 64; + return CRYPT_BUFFER_OVERFLOW; + } + + if (sober128_read(out, 64, prng) != 64) { + return CRYPT_ERROR_READPRNG; + } + *outlen = 64; + + return CRYPT_OK; +} + +/** + Import a PRNG state + @param in The PRNG state + @param inlen Size of the state + @param prng The PRNG to import + @return CRYPT_OK if successful +*/ +int sober128_import(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + int err; + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(prng != NULL); + + if (inlen != 64) { + return CRYPT_INVALID_ARG; + } + + if ((err = sober128_start(prng)) != CRYPT_OK) { + return err; + } + if ((err = sober128_add_entropy(in, 64, prng)) != CRYPT_OK) { + return err; + } + return sober128_ready(prng); +} + +/** + PRNG self-test + @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled +*/ +int sober128_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + int keylen, ivlen, len; + unsigned char key[16], iv[4], out[20]; + } tests[] = { + +{ + 16, 4, 20, + + /* key */ + { 0x74, 0x65, 0x73, 0x74, 0x20, 0x6b, 0x65, 0x79, + 0x20, 0x31, 0x32, 0x38, 0x62, 0x69, 0x74, 0x73 }, + + /* IV */ + { 0x00, 0x00, 0x00, 0x00 }, + + /* expected output */ + { 0x43, 0x50, 0x0c, 0xcf, 0x89, 0x91, 0x9f, 0x1d, + 0xaa, 0x37, 0x74, 0x95, 0xf4, 0xb4, 0x58, 0xc2, + 0x40, 0x37, 0x8b, 0xbb } +} + +}; + prng_state prng; + unsigned char dst[20]; + int err, x; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + if ((err = sober128_start(&prng)) != CRYPT_OK) { + return err; + } + if ((err = sober128_add_entropy(tests[x].key, tests[x].keylen, &prng)) != CRYPT_OK) { + return err; + } + /* add IV */ + if ((err = sober128_add_entropy(tests[x].iv, tests[x].ivlen, &prng)) != CRYPT_OK) { + return err; + } + + /* ready up */ + if ((err = sober128_ready(&prng)) != CRYPT_OK) { + return err; + } + XMEMSET(dst, 0, tests[x].len); + if (sober128_read(dst, tests[x].len, &prng) != (unsigned long)tests[x].len) { + return CRYPT_ERROR_READPRNG; + } + sober128_done(&prng); + if (XMEMCMP(dst, tests[x].out, tests[x].len)) { +#if 0 + printf("\n\nLTC_SOBER128 failed, I got:\n"); + for (y = 0; y < tests[x].len; y++) printf("%02x ", dst[y]); + printf("\n"); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/prngs/sober128.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/sober128tab.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/sober128tab.c new file mode 100644 index 0000000000..be3d0c4494 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/sober128tab.c @@ -0,0 +1,162 @@ +/** + @file sober128tab.c + SOBER-128 Tables +*/ +/* $Id: sober128tab.c,v 1.2 2005/05/05 14:35:59 tom Exp $ */ +/* @(#)TuringMultab.h 1.3 (QUALCOMM) 02/09/03 */ +/* Multiplication table for Turing using 0xD02B4367 */ +static const ulong32 Multab[256] = { + 0x00000000, 0xD02B4367, 0xED5686CE, 0x3D7DC5A9, + 0x97AC41D1, 0x478702B6, 0x7AFAC71F, 0xAAD18478, + 0x631582EF, 0xB33EC188, 0x8E430421, 0x5E684746, + 0xF4B9C33E, 0x24928059, 0x19EF45F0, 0xC9C40697, + 0xC62A4993, 0x16010AF4, 0x2B7CCF5D, 0xFB578C3A, + 0x51860842, 0x81AD4B25, 0xBCD08E8C, 0x6CFBCDEB, + 0xA53FCB7C, 0x7514881B, 0x48694DB2, 0x98420ED5, + 0x32938AAD, 0xE2B8C9CA, 0xDFC50C63, 0x0FEE4F04, + 0xC154926B, 0x117FD10C, 0x2C0214A5, 0xFC2957C2, + 0x56F8D3BA, 0x86D390DD, 0xBBAE5574, 0x6B851613, + 0xA2411084, 0x726A53E3, 0x4F17964A, 0x9F3CD52D, + 0x35ED5155, 0xE5C61232, 0xD8BBD79B, 0x089094FC, + 0x077EDBF8, 0xD755989F, 0xEA285D36, 0x3A031E51, + 0x90D29A29, 0x40F9D94E, 0x7D841CE7, 0xADAF5F80, + 0x646B5917, 0xB4401A70, 0x893DDFD9, 0x59169CBE, + 0xF3C718C6, 0x23EC5BA1, 0x1E919E08, 0xCEBADD6F, + 0xCFA869D6, 0x1F832AB1, 0x22FEEF18, 0xF2D5AC7F, + 0x58042807, 0x882F6B60, 0xB552AEC9, 0x6579EDAE, + 0xACBDEB39, 0x7C96A85E, 0x41EB6DF7, 0x91C02E90, + 0x3B11AAE8, 0xEB3AE98F, 0xD6472C26, 0x066C6F41, + 0x09822045, 0xD9A96322, 0xE4D4A68B, 0x34FFE5EC, + 0x9E2E6194, 0x4E0522F3, 0x7378E75A, 0xA353A43D, + 0x6A97A2AA, 0xBABCE1CD, 0x87C12464, 0x57EA6703, + 0xFD3BE37B, 0x2D10A01C, 0x106D65B5, 0xC04626D2, + 0x0EFCFBBD, 0xDED7B8DA, 0xE3AA7D73, 0x33813E14, + 0x9950BA6C, 0x497BF90B, 0x74063CA2, 0xA42D7FC5, + 0x6DE97952, 0xBDC23A35, 0x80BFFF9C, 0x5094BCFB, + 0xFA453883, 0x2A6E7BE4, 0x1713BE4D, 0xC738FD2A, + 0xC8D6B22E, 0x18FDF149, 0x258034E0, 0xF5AB7787, + 0x5F7AF3FF, 0x8F51B098, 0xB22C7531, 0x62073656, + 0xABC330C1, 0x7BE873A6, 0x4695B60F, 0x96BEF568, + 0x3C6F7110, 0xEC443277, 0xD139F7DE, 0x0112B4B9, + 0xD31DD2E1, 0x03369186, 0x3E4B542F, 0xEE601748, + 0x44B19330, 0x949AD057, 0xA9E715FE, 0x79CC5699, + 0xB008500E, 0x60231369, 0x5D5ED6C0, 0x8D7595A7, + 0x27A411DF, 0xF78F52B8, 0xCAF29711, 0x1AD9D476, + 0x15379B72, 0xC51CD815, 0xF8611DBC, 0x284A5EDB, + 0x829BDAA3, 0x52B099C4, 0x6FCD5C6D, 0xBFE61F0A, + 0x7622199D, 0xA6095AFA, 0x9B749F53, 0x4B5FDC34, + 0xE18E584C, 0x31A51B2B, 0x0CD8DE82, 0xDCF39DE5, + 0x1249408A, 0xC26203ED, 0xFF1FC644, 0x2F348523, + 0x85E5015B, 0x55CE423C, 0x68B38795, 0xB898C4F2, + 0x715CC265, 0xA1778102, 0x9C0A44AB, 0x4C2107CC, + 0xE6F083B4, 0x36DBC0D3, 0x0BA6057A, 0xDB8D461D, + 0xD4630919, 0x04484A7E, 0x39358FD7, 0xE91ECCB0, + 0x43CF48C8, 0x93E40BAF, 0xAE99CE06, 0x7EB28D61, + 0xB7768BF6, 0x675DC891, 0x5A200D38, 0x8A0B4E5F, + 0x20DACA27, 0xF0F18940, 0xCD8C4CE9, 0x1DA70F8E, + 0x1CB5BB37, 0xCC9EF850, 0xF1E33DF9, 0x21C87E9E, + 0x8B19FAE6, 0x5B32B981, 0x664F7C28, 0xB6643F4F, + 0x7FA039D8, 0xAF8B7ABF, 0x92F6BF16, 0x42DDFC71, + 0xE80C7809, 0x38273B6E, 0x055AFEC7, 0xD571BDA0, + 0xDA9FF2A4, 0x0AB4B1C3, 0x37C9746A, 0xE7E2370D, + 0x4D33B375, 0x9D18F012, 0xA06535BB, 0x704E76DC, + 0xB98A704B, 0x69A1332C, 0x54DCF685, 0x84F7B5E2, + 0x2E26319A, 0xFE0D72FD, 0xC370B754, 0x135BF433, + 0xDDE1295C, 0x0DCA6A3B, 0x30B7AF92, 0xE09CECF5, + 0x4A4D688D, 0x9A662BEA, 0xA71BEE43, 0x7730AD24, + 0xBEF4ABB3, 0x6EDFE8D4, 0x53A22D7D, 0x83896E1A, + 0x2958EA62, 0xF973A905, 0xC40E6CAC, 0x14252FCB, + 0x1BCB60CF, 0xCBE023A8, 0xF69DE601, 0x26B6A566, + 0x8C67211E, 0x5C4C6279, 0x6131A7D0, 0xB11AE4B7, + 0x78DEE220, 0xA8F5A147, 0x958864EE, 0x45A32789, + 0xEF72A3F1, 0x3F59E096, 0x0224253F, 0xD20F6658, +}; + +/* $Id: sober128tab.c,v 1.2 2005/05/05 14:35:59 tom Exp $ */ +/* Sbox for SOBER-128 */ +/* + * This is really the combination of two SBoxes; the least significant + * 24 bits comes from: + * 8->32 Sbox generated by Millan et. al. at Queensland University of + * Technology. See: E. Dawson, W. Millan, L. Burnett, G. Carter, + * "On the Design of 8*32 S-boxes". Unpublished report, by the + * Information Systems Research Centre, + * Queensland University of Technology, 1999. + * + * The most significant 8 bits are the Skipjack "F table", which can be + * found at http://csrc.nist.gov/CryptoToolkit/skipjack/skipjack.pdf . + * In this optimised table, though, the intent is to XOR the word from + * the table selected by the high byte with the input word. Thus, the + * high byte is actually the Skipjack F-table entry XORED with its + * table index. + */ +static const ulong32 Sbox[256] = { + 0xa3aa1887, 0xd65e435c, 0x0b65c042, 0x800e6ef4, + 0xfc57ee20, 0x4d84fed3, 0xf066c502, 0xf354e8ae, + 0xbb2ee9d9, 0x281f38d4, 0x1f829b5d, 0x735cdf3c, + 0x95864249, 0xbc2e3963, 0xa1f4429f, 0xf6432c35, + 0xf7f40325, 0x3cc0dd70, 0x5f973ded, 0x9902dc5e, + 0xda175b42, 0x590012bf, 0xdc94d78c, 0x39aab26b, + 0x4ac11b9a, 0x8c168146, 0xc3ea8ec5, 0x058ac28f, + 0x52ed5c0f, 0x25b4101c, 0x5a2db082, 0x370929e1, + 0x2a1843de, 0xfe8299fc, 0x202fbc4b, 0x833915dd, + 0x33a803fa, 0xd446b2de, 0x46233342, 0x4fcee7c3, + 0x3ad607ef, 0x9e97ebab, 0x507f859b, 0xe81f2e2f, + 0xc55b71da, 0xd7e2269a, 0x1339c3d1, 0x7ca56b36, + 0xa6c9def2, 0xb5c9fc5f, 0x5927b3a3, 0x89a56ddf, + 0xc625b510, 0x560f85a7, 0xace82e71, 0x2ecb8816, + 0x44951e2a, 0x97f5f6af, 0xdfcbc2b3, 0xce4ff55d, + 0xcb6b6214, 0x2b0b83e3, 0x549ea6f5, 0x9de041af, + 0x792f1f17, 0xf73b99ee, 0x39a65ec0, 0x4c7016c6, + 0x857709a4, 0xd6326e01, 0xc7b280d9, 0x5cfb1418, + 0xa6aff227, 0xfd548203, 0x506b9d96, 0xa117a8c0, + 0x9cd5bf6e, 0xdcee7888, 0x61fcfe64, 0xf7a193cd, + 0x050d0184, 0xe8ae4930, 0x88014f36, 0xd6a87088, + 0x6bad6c2a, 0x1422c678, 0xe9204de7, 0xb7c2e759, + 0x0200248e, 0x013b446b, 0xda0d9fc2, 0x0414a895, + 0x3a6cc3a1, 0x56fef170, 0x86c19155, 0xcf7b8a66, + 0x551b5e69, 0xb4a8623e, 0xa2bdfa35, 0xc4f068cc, + 0x573a6acd, 0x6355e936, 0x03602db9, 0x0edf13c1, + 0x2d0bb16d, 0x6980b83c, 0xfeb23763, 0x3dd8a911, + 0x01b6bc13, 0xf55579d7, 0xf55c2fa8, 0x19f4196e, + 0xe7db5476, 0x8d64a866, 0xc06e16ad, 0xb17fc515, + 0xc46feb3c, 0x8bc8a306, 0xad6799d9, 0x571a9133, + 0x992466dd, 0x92eb5dcd, 0xac118f50, 0x9fafb226, + 0xa1b9cef3, 0x3ab36189, 0x347a19b1, 0x62c73084, + 0xc27ded5c, 0x6c8bc58f, 0x1cdde421, 0xed1e47fb, + 0xcdcc715e, 0xb9c0ff99, 0x4b122f0f, 0xc4d25184, + 0xaf7a5e6c, 0x5bbf18bc, 0x8dd7c6e0, 0x5fb7e420, + 0x521f523f, 0x4ad9b8a2, 0xe9da1a6b, 0x97888c02, + 0x19d1e354, 0x5aba7d79, 0xa2cc7753, 0x8c2d9655, + 0x19829da1, 0x531590a7, 0x19c1c149, 0x3d537f1c, + 0x50779b69, 0xed71f2b7, 0x463c58fa, 0x52dc4418, + 0xc18c8c76, 0xc120d9f0, 0xafa80d4d, 0x3b74c473, + 0xd09410e9, 0x290e4211, 0xc3c8082b, 0x8f6b334a, + 0x3bf68ed2, 0xa843cc1b, 0x8d3c0ff3, 0x20e564a0, + 0xf8f55a4f, 0x2b40f8e7, 0xfea7f15f, 0xcf00fe21, + 0x8a6d37d6, 0xd0d506f1, 0xade00973, 0xefbbde36, + 0x84670fa8, 0xfa31ab9e, 0xaedab618, 0xc01f52f5, + 0x6558eb4f, 0x71b9e343, 0x4b8d77dd, 0x8cb93da6, + 0x740fd52d, 0x425412f8, 0xc5a63360, 0x10e53ad0, + 0x5a700f1c, 0x8324ed0b, 0xe53dc1ec, 0x1a366795, + 0x6d549d15, 0xc5ce46d7, 0xe17abe76, 0x5f48e0a0, + 0xd0f07c02, 0x941249b7, 0xe49ed6ba, 0x37a47f78, + 0xe1cfffbd, 0xb007ca84, 0xbb65f4da, 0xb59f35da, + 0x33d2aa44, 0x417452ac, 0xc0d674a7, 0x2d61a46a, + 0xdc63152a, 0x3e12b7aa, 0x6e615927, 0xa14fb118, + 0xa151758d, 0xba81687b, 0xe152f0b3, 0x764254ed, + 0x34c77271, 0x0a31acab, 0x54f94aec, 0xb9e994cd, + 0x574d9e81, 0x5b623730, 0xce8a21e8, 0x37917f0b, + 0xe8a9b5d6, 0x9697adf8, 0xf3d30431, 0x5dcac921, + 0x76b35d46, 0xaa430a36, 0xc2194022, 0x22bca65e, + 0xdaec70ba, 0xdfaea8cc, 0x777bae8b, 0x242924d5, + 0x1f098a5a, 0x4b396b81, 0x55de2522, 0x435c1cb8, + 0xaeb8fe1d, 0x9db3c697, 0x5b164f83, 0xe0c16376, + 0xa319224c, 0xd0203b35, 0x433ac0fe, 0x1466a19a, + 0x45f0b24f, 0x51fda998, 0xc0d52d71, 0xfa0896a8, + 0xf9e6053f, 0xa4b0d300, 0xd499cbcc, 0xb95e3d40, +}; + +/* $Source: /cvs/libtom/libtomcrypt/src/prngs/sober128tab.c,v $ */ +/* $Revision: 1.2 $ */ +/* $Date: 2005/05/05 14:35:59 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/sprng.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/sprng.c new file mode 100644 index 0000000000..ae524cd86d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/sprng.c @@ -0,0 +1,136 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file sprng.c + Secure PRNG, Tom St Denis +*/ + +/* A secure PRNG using the RNG functions. Basically this is a + * wrapper that allows you to use a secure RNG as a PRNG + * in the various other functions. + */ + +#ifdef LTC_SPRNG + +const struct ltc_prng_descriptor sprng_desc = +{ + "sprng", 0, + &sprng_start, + &sprng_add_entropy, + &sprng_ready, + &sprng_read, + &sprng_done, + &sprng_export, + &sprng_import, + &sprng_test +}; + +/** + Start the PRNG + @param prng [out] The PRNG state to initialize + @return CRYPT_OK if successful +*/ +int sprng_start(prng_state *prng) +{ + return CRYPT_OK; +} + +/** + Add entropy to the PRNG state + @param in The data to add + @param inlen Length of the data to add + @param prng PRNG state to update + @return CRYPT_OK if successful +*/ +int sprng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + return CRYPT_OK; +} + +/** + Make the PRNG ready to read from + @param prng The PRNG to make active + @return CRYPT_OK if successful +*/ +int sprng_ready(prng_state *prng) +{ + return CRYPT_OK; +} + +/** + Read from the PRNG + @param out Destination + @param outlen Length of output + @param prng The active PRNG to read from + @return Number of octets read +*/ +unsigned long sprng_read(unsigned char *out, unsigned long outlen, prng_state *prng) +{ + LTC_ARGCHK(out != NULL); + return rng_get_bytes(out, outlen, NULL); +} + +/** + Terminate the PRNG + @param prng The PRNG to terminate + @return CRYPT_OK if successful +*/ +int sprng_done(prng_state *prng) +{ + return CRYPT_OK; +} + +/** + Export the PRNG state + @param out [out] Destination + @param outlen [in/out] Max size and resulting size of the state + @param prng The PRNG to export + @return CRYPT_OK if successful +*/ +int sprng_export(unsigned char *out, unsigned long *outlen, prng_state *prng) +{ + LTC_ARGCHK(outlen != NULL); + + *outlen = 0; + return CRYPT_OK; +} + +/** + Import a PRNG state + @param in The PRNG state + @param inlen Size of the state + @param prng The PRNG to import + @return CRYPT_OK if successful +*/ +int sprng_import(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + return CRYPT_OK; +} + +/** + PRNG self-test + @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled +*/ +int sprng_test(void) +{ + return CRYPT_OK; +} + +#endif + + + + +/* $Source: /cvs/libtom/libtomcrypt/src/prngs/sprng.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/yarrow.c b/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/yarrow.c new file mode 100644 index 0000000000..d05ccd163b --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/src/prngs/yarrow.c @@ -0,0 +1,362 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file yarrow.c + Yarrow PRNG, Tom St Denis +*/ + +#ifdef LTC_YARROW + +const struct ltc_prng_descriptor yarrow_desc = +{ + "yarrow", 64, + &yarrow_start, + &yarrow_add_entropy, + &yarrow_ready, + &yarrow_read, + &yarrow_done, + &yarrow_export, + &yarrow_import, + &yarrow_test +}; + +/** + Start the PRNG + @param prng [out] The PRNG state to initialize + @return CRYPT_OK if successful +*/ +int yarrow_start(prng_state *prng) +{ + int err; + + LTC_ARGCHK(prng != NULL); + + /* these are the default hash/cipher combo used */ +#ifdef LTC_RIJNDAEL +#if LTC_YARROW_AES==0 + prng->yarrow.cipher = register_cipher(&rijndael_enc_desc); +#elif LTC_YARROW_AES==1 + prng->yarrow.cipher = register_cipher(&aes_enc_desc); +#elif LTC_YARROW_AES==2 + prng->yarrow.cipher = register_cipher(&rijndael_desc); +#elif LTC_YARROW_AES==3 + prng->yarrow.cipher = register_cipher(&aes_desc); +#endif +#elif defined(LTC_BLOWFISH) + prng->yarrow.cipher = register_cipher(&blowfish_desc); +#elif defined(LTC_TWOFISH) + prng->yarrow.cipher = register_cipher(&twofish_desc); +#elif defined(LTC_RC6) + prng->yarrow.cipher = register_cipher(&rc6_desc); +#elif defined(LTC_RC5) + prng->yarrow.cipher = register_cipher(&rc5_desc); +#elif defined(LTC_SAFERP) + prng->yarrow.cipher = register_cipher(&saferp_desc); +#elif defined(LTC_RC2) + prng->yarrow.cipher = register_cipher(&rc2_desc); +#elif defined(LTC_NOEKEON) + prng->yarrow.cipher = register_cipher(&noekeon_desc); +#elif defined(LTC_ANUBIS) + prng->yarrow.cipher = register_cipher(&anubis_desc); +#elif defined(LTC_KSEED) + prng->yarrow.cipher = register_cipher(&kseed_desc); +#elif defined(LTC_KHAZAD) + prng->yarrow.cipher = register_cipher(&khazad_desc); +#elif defined(LTC_CAST5) + prng->yarrow.cipher = register_cipher(&cast5_desc); +#elif defined(LTC_XTEA) + prng->yarrow.cipher = register_cipher(&xtea_desc); +#elif defined(LTC_SAFER) + prng->yarrow.cipher = register_cipher(&safer_sk128_desc); +#elif defined(LTC_DES) + prng->yarrow.cipher = register_cipher(&des3_desc); +#else + #error LTC_YARROW needs at least one CIPHER +#endif + if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) { + return err; + } + +#ifdef LTC_SHA256 + prng->yarrow.hash = register_hash(&sha256_desc); +#elif defined(LTC_SHA512) + prng->yarrow.hash = register_hash(&sha512_desc); +#elif defined(LTC_TIGER) + prng->yarrow.hash = register_hash(&tiger_desc); +#elif defined(LTC_SHA1) + prng->yarrow.hash = register_hash(&sha1_desc); +#elif defined(LTC_RIPEMD320) + prng->yarrow.hash = register_hash(&rmd320_desc); +#elif defined(LTC_RIPEMD256) + prng->yarrow.hash = register_hash(&rmd256_desc); +#elif defined(LTC_RIPEMD160) + prng->yarrow.hash = register_hash(&rmd160_desc); +#elif defined(LTC_RIPEMD128) + prng->yarrow.hash = register_hash(&rmd128_desc); +#elif defined(LTC_MD5) + prng->yarrow.hash = register_hash(&md5_desc); +#elif defined(LTC_MD4) + prng->yarrow.hash = register_hash(&md4_desc); +#elif defined(LTC_MD2) + prng->yarrow.hash = register_hash(&md2_desc); +#elif defined(LTC_WHIRLPOOL) + prng->yarrow.hash = register_hash(&whirlpool_desc); +#else + #error LTC_YARROW needs at least one HASH +#endif + if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { + return err; + } + + /* zero the memory used */ + zeromem(prng->yarrow.pool, sizeof(prng->yarrow.pool)); + LTC_MUTEX_INIT(&prng->yarrow.prng_lock) + + return CRYPT_OK; +} + +/** + Add entropy to the PRNG state + @param in The data to add + @param inlen Length of the data to add + @param prng PRNG state to update + @return CRYPT_OK if successful +*/ +int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + hash_state md; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(prng != NULL); + + LTC_MUTEX_LOCK(&prng->yarrow.prng_lock); + + if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { + LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); + return err; + } + + /* start the hash */ + if ((err = hash_descriptor[prng->yarrow.hash].init(&md)) != CRYPT_OK) { + LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); + return err; + } + + /* hash the current pool */ + if ((err = hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool, + hash_descriptor[prng->yarrow.hash].hashsize)) != CRYPT_OK) { + LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); + return err; + } + + /* add the new entropy */ + if ((err = hash_descriptor[prng->yarrow.hash].process(&md, in, inlen)) != CRYPT_OK) { + LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); + return err; + } + + /* store result */ + if ((err = hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool)) != CRYPT_OK) { + LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); + return err; + } + + LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); + return CRYPT_OK; +} + +/** + Make the PRNG ready to read from + @param prng The PRNG to make active + @return CRYPT_OK if successful +*/ +int yarrow_ready(prng_state *prng) +{ + int ks, err; + + LTC_ARGCHK(prng != NULL); + LTC_MUTEX_LOCK(&prng->yarrow.prng_lock); + + if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { + LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); + return err; + } + + if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) { + LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); + return err; + } + + /* setup CTR mode using the "pool" as the key */ + ks = (int)hash_descriptor[prng->yarrow.hash].hashsize; + if ((err = cipher_descriptor[prng->yarrow.cipher].keysize(&ks)) != CRYPT_OK) { + LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); + return err; + } + + if ((err = ctr_start(prng->yarrow.cipher, /* what cipher to use */ + prng->yarrow.pool, /* IV */ + prng->yarrow.pool, ks, /* KEY and key size */ + 0, /* number of rounds */ + CTR_COUNTER_LITTLE_ENDIAN, /* little endian counter */ + &prng->yarrow.ctr)) != CRYPT_OK) { + LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); + return err; + } + LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); + return CRYPT_OK; +} + +/** + Read from the PRNG + @param out Destination + @param outlen Length of output + @param prng The active PRNG to read from + @return Number of octets read +*/ +unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng) +{ + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(prng != NULL); + + LTC_MUTEX_LOCK(&prng->yarrow.prng_lock); + + /* put out in predictable state first */ + zeromem(out, outlen); + + /* now randomize it */ + if (ctr_encrypt(out, out, outlen, &prng->yarrow.ctr) != CRYPT_OK) { + LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); + return 0; + } + LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); + return outlen; +} + +/** + Terminate the PRNG + @param prng The PRNG to terminate + @return CRYPT_OK if successful +*/ +int yarrow_done(prng_state *prng) +{ + int err; + LTC_ARGCHK(prng != NULL); + + LTC_MUTEX_LOCK(&prng->yarrow.prng_lock); + + /* call cipher done when we invent one ;-) */ + + /* we invented one */ + err = ctr_done(&prng->yarrow.ctr); + + LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); + return err; +} + +/** + Export the PRNG state + @param out [out] Destination + @param outlen [in/out] Max size and resulting size of the state + @param prng The PRNG to export + @return CRYPT_OK if successful +*/ +int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng) +{ + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(prng != NULL); + + LTC_MUTEX_LOCK(&prng->yarrow.prng_lock); + + /* we'll write 64 bytes for s&g's */ + if (*outlen < 64) { + LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); + *outlen = 64; + return CRYPT_BUFFER_OVERFLOW; + } + + if (yarrow_read(out, 64, prng) != 64) { + LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); + return CRYPT_ERROR_READPRNG; + } + *outlen = 64; + + return CRYPT_OK; +} + +/** + Import a PRNG state + @param in The PRNG state + @param inlen Size of the state + @param prng The PRNG to import + @return CRYPT_OK if successful +*/ +int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(prng != NULL); + + LTC_MUTEX_LOCK(&prng->yarrow.prng_lock); + + if (inlen != 64) { + LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); + return CRYPT_INVALID_ARG; + } + + if ((err = yarrow_start(prng)) != CRYPT_OK) { + LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); + return err; + } + err = yarrow_add_entropy(in, 64, prng); + LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); + return err; +} + +/** + PRNG self-test + @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled +*/ +int yarrow_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + int err; + prng_state prng; + + if ((err = yarrow_start(&prng)) != CRYPT_OK) { + return err; + } + + /* now let's test the hash/cipher that was chosen */ + if ((err = cipher_descriptor[prng.yarrow.cipher].test()) != CRYPT_OK) { + return err; + } + if ((err = hash_descriptor[prng.yarrow.hash].test()) != CRYPT_OK) { + return err; + } + + return CRYPT_OK; +#endif +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/prngs/yarrow.c,v $ */ +/* $Revision: 1.16 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/testbuild.sh b/xmhf-64/xmhf/third-party/libtomcrypt/testbuild.sh new file mode 100644 index 0000000000..6a9e3e6f44 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/testbuild.sh @@ -0,0 +1,11 @@ +#!/bin/bash +echo "$1 (Build Only, $2, $3)..." +make clean 1>/dev/null 2>/dev/null +echo -n "building..." +touch testok.txt +CFLAGS="$2 $CFLAGS $4" EXTRALIBS="$5" make -f $3 test tv_gen 1>gcc_1.txt 2>gcc_2.txt || (echo "build $1 failed see gcc_2.txt for more information" && cat gcc_2.txt && rm -f testok.txt && exit 1) +if find testok.txt -type f 1>/dev/null 2>/dev/null ; then + echo "successful" + exit 0 +fi +exit 1 diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/testme.sh b/xmhf-64/xmhf/third-party/libtomcrypt/testme.sh new file mode 100644 index 0000000000..b62fda8dc1 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/testme.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +# date +echo "date="`date` + +# output version +echo "Testing verion" `grep "^VERSION=" makefile | sed "s/.*=//"` +#grep "VERSION=" makefile | perl -e "@a = split('=', <>); print @a[1];"` + +# get uname +echo "uname="`uname -a` + +# get gcc name +echo "gcc="`gcc -dumpversion` +echo + +# stock build +bash run.sh "STOCK" " " "$1" "$2" "$3" || exit 1 + +# SMALL code +bash run.sh "SMALL" "-DLTC_SMALL_CODE" "$1" "$2" "$3" || exit 1 + +# NOTABLES +bash run.sh "NOTABLES" "-DLTC_NO_TABLES" "$1" "$2" "$3" || exit 1 + +# SMALL+NOTABLES +bash run.sh "SMALL+NOTABLES" "-DLTC_SMALL_CODE -DLTC_NO_TABLES" "$1" "$2" "$3" || exit 1 + +# CLEANSTACK +bash run.sh "CLEANSTACK" "-DLTC_CLEAN_STACK" "$1" "$2" "$3" || exit 1 + +# CLEANSTACK + SMALL +bash run.sh "CLEANSTACK+SMALL" "-DLTC_SMALL_CODE -DLTC_CLEAN_STACK" "$1" "$2" "$3" || exit 1 + +# CLEANSTACK + NOTABLES +bash run.sh "CLEANSTACK+NOTABLES" "-DLTC_NO_TABLES -DLTC_CLEAN_STACK" "$1" "$2" "$3" || exit 1 + +# CLEANSTACK + NOTABLES + SMALL +bash run.sh "CLEANSTACK+NOTABLES+SMALL" "-DLTC_NO_TABLES -DLTC_CLEAN_STACK -DLTC_SMALL_CODE" "$1" "$2" "$3" || exit 1 + +# NO_FAST +bash run.sh "NO_FAST" "-DLTC_NO_FAST" "$1" "$2" "$3" || exit 1 + +# NO_FAST + NOTABLES +bash run.sh "NO_FAST+NOTABLES" "-DLTC_NO_FAST -DLTC_NO_TABLES" "$1" "$2" "$3" || exit 1 + +# NO_ASM +bash run.sh "NO_ASM" "-DLTC_NO_ASM" "$1" "$2" "$3" || exit 1 + +# test build with no testing +bash testbuild.sh "NOTEST" "-DLTC_NO_TEST" "$1" "$2" "$3" || exit 1 + +# test build with no file routines +bash testbuild.sh "NOFILE" "-DLTC_NO_FILE" "$1" "$2" "$3" || exit 1 + +# $Source: /cvs/libtom/libtomcrypt/testme.sh,v $ +# $Revision: 1.20 $ +# $Date: 2006/01/26 14:49:43 $ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/testprof/base64_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/base64_test.c new file mode 100644 index 0000000000..10a7ddf337 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/base64_test.c @@ -0,0 +1,24 @@ +#include + +int base64_test(void) +{ + unsigned char in[64], out[256], tmp[64]; + unsigned long x, l1, l2; + + for (x = 0; x < 64; x++) { + yarrow_read(in, x, &yarrow_prng); + l1 = sizeof(out); + DO(base64_encode(in, x, out, &l1)); + l2 = sizeof(tmp); + DO(base64_decode(out, l1, tmp, &l2)); + if (l2 != x || memcmp(tmp, in, x)) { + fprintf(stderr, "base64 failed %lu %lu %lu", x, l1, l2); + return 1; + } + } + return 0; +} + +/* $Source: /cvs/libtom/libtomcrypt/testprof/base64_test.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2005/05/21 12:51:25 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/testprof/cipher_hash_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/cipher_hash_test.c new file mode 100644 index 0000000000..6e55bba6ae --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/cipher_hash_test.c @@ -0,0 +1,45 @@ +/* test the ciphers and hashes using their built-in self-tests */ + +#include + +int cipher_hash_test(void) +{ + int x; + unsigned char buf[4096]; + unsigned long n; + prng_state nprng; + + /* test ciphers */ + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + DO(cipher_descriptor[x].test()); + } + + /* test hashes */ + for (x = 0; hash_descriptor[x].name != NULL; x++) { + DO(hash_descriptor[x].test()); + } + + /* test prngs (test, import/export */ + for (x = 0; prng_descriptor[x].name != NULL; x++) { + DO(prng_descriptor[x].test()); + DO(prng_descriptor[x].start(&nprng)); + DO(prng_descriptor[x].add_entropy((unsigned char *)"helloworld12", 12, &nprng)); + DO(prng_descriptor[x].ready(&nprng)); + n = sizeof(buf); + DO(prng_descriptor[x].pexport(buf, &n, &nprng)); + prng_descriptor[x].done(&nprng); + DO(prng_descriptor[x].pimport(buf, n, &nprng)); + DO(prng_descriptor[x].ready(&nprng)); + if (prng_descriptor[x].read(buf, 100, &nprng) != 100) { + fprintf(stderr, "Error reading from imported PRNG!\n"); + exit(EXIT_FAILURE); + } + prng_descriptor[x].done(&nprng); + } + + return 0; +} + +/* $Source: /cvs/libtom/libtomcrypt/testprof/cipher_hash_test.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2005/05/05 14:35:59 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/testprof/der_tests.c b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/der_tests.c new file mode 100644 index 0000000000..ce666a4c9a --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/der_tests.c @@ -0,0 +1,853 @@ +#include +#if defined(GMP_LTC_DESC) || defined(USE_GMP) +#include +#endif + +#ifndef LTC_DER + +int der_tests(void) +{ + fprintf(stderr, "NOP"); + return 0; +} + +#else + +static void der_set_test(void) +{ + ltc_asn1_list list[10]; + static const unsigned char oct_str[] = { 1, 2, 3, 4 }; + static const unsigned char bin_str[] = { 1, 0, 0, 1 }; + static const unsigned long int_val = 12345678UL; + + unsigned char strs[10][10], outbuf[128]; + unsigned long x, val, outlen; + int err; + + /* make structure and encode it */ + LTC_SET_ASN1(list, 0, LTC_ASN1_OCTET_STRING, oct_str, sizeof(oct_str)); + LTC_SET_ASN1(list, 1, LTC_ASN1_BIT_STRING, bin_str, sizeof(bin_str)); + LTC_SET_ASN1(list, 2, LTC_ASN1_SHORT_INTEGER, &int_val, 1); + + /* encode it */ + outlen = sizeof(outbuf); + if ((err = der_encode_set(list, 3, outbuf, &outlen)) != CRYPT_OK) { + fprintf(stderr, "error encoding set: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + + + /* first let's test the set_decoder out of order to see what happens, we should get all the fields we expect even though they're in a diff order */ + LTC_SET_ASN1(list, 0, LTC_ASN1_BIT_STRING, strs[1], sizeof(strs[1])); + LTC_SET_ASN1(list, 1, LTC_ASN1_SHORT_INTEGER, &val, 1); + LTC_SET_ASN1(list, 2, LTC_ASN1_OCTET_STRING, strs[0], sizeof(strs[0])); + + if ((err = der_decode_set(outbuf, outlen, list, 3)) != CRYPT_OK) { + fprintf(stderr, "error decoding set using der_decode_set: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + + /* now compare the items */ + if (memcmp(strs[0], oct_str, sizeof(oct_str))) { + fprintf(stderr, "error decoding set using der_decode_set (oct_str is wrong):\n"); + exit(EXIT_FAILURE); + } + + if (memcmp(strs[1], bin_str, sizeof(bin_str))) { + fprintf(stderr, "error decoding set using der_decode_set (bin_str is wrong):\n"); + exit(EXIT_FAILURE); + } + + if (val != int_val) { + fprintf(stderr, "error decoding set using der_decode_set (int_val is wrong):\n"); + exit(EXIT_FAILURE); + } + + strcpy((char*)strs[0], "one"); + strcpy((char*)strs[1], "one2"); + strcpy((char*)strs[2], "two"); + strcpy((char*)strs[3], "aaa"); + strcpy((char*)strs[4], "aaaa"); + strcpy((char*)strs[5], "aab"); + strcpy((char*)strs[6], "aaab"); + strcpy((char*)strs[7], "bbb"); + strcpy((char*)strs[8], "bbba"); + strcpy((char*)strs[9], "bbbb"); + + for (x = 0; x < 10; x++) { + LTC_SET_ASN1(list, x, LTC_ASN1_PRINTABLE_STRING, strs[x], strlen((char*)strs[x])); + } + + outlen = sizeof(outbuf); + if ((err = der_encode_setof(list, 10, outbuf, &outlen)) != CRYPT_OK) { + fprintf(stderr, "error encoding SET OF: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + + for (x = 0; x < 10; x++) { + LTC_SET_ASN1(list, x, LTC_ASN1_PRINTABLE_STRING, strs[x], sizeof(strs[x]) - 1); + } + XMEMSET(strs, 0, sizeof(strs)); + + if ((err = der_decode_set(outbuf, outlen, list, 10)) != CRYPT_OK) { + fprintf(stderr, "error decoding SET OF: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + + /* now compare */ + for (x = 1; x < 10; x++) { + if (!(strlen((char*)strs[x-1]) <= strlen((char*)strs[x])) && strcmp((char*)strs[x-1], (char*)strs[x]) >= 0) { + fprintf(stderr, "error SET OF order at %lu is wrong\n", x); + exit(EXIT_FAILURE); + } + } + +} + + +/* we are encoding + + SEQUENCE { + PRINTABLE "printable" + IA5 "ia5" + SEQUENCE { + INTEGER 12345678 + UTCTIME { 91, 5, 6, 16, 45, 40, 1, 7, 0 } + SEQUENCE { + OCTET STRING { 1, 2, 3, 4 } + BIT STRING { 1, 0, 0, 1 } + SEQUENCE { + OID { 1, 2, 840, 113549 } + NULL + SET OF { + PRINTABLE "333" // WILL GET SORTED + PRINTABLE "222" + } + } + } + } + +*/ + +static void der_flexi_test(void) +{ + static const char printable_str[] = "printable"; + static const char set1_str[] = "333"; + static const char set2_str[] = "222"; + static const char ia5_str[] = "ia5"; + static const unsigned long int_val = 12345678UL; + static const ltc_utctime utctime = { 91, 5, 6, 16, 45, 40, 1, 7, 0 }; + static const unsigned char oct_str[] = { 1, 2, 3, 4 }; + static const unsigned char bit_str[] = { 1, 0, 0, 1 }; + static const unsigned long oid_str[] = { 1, 2, 840, 113549 }; + + unsigned char encode_buf[192]; + unsigned long encode_buf_len, decode_len; + int err; + + ltc_asn1_list static_list[5][3], *decoded_list, *l; + + /* build list */ + LTC_SET_ASN1(static_list[0], 0, LTC_ASN1_PRINTABLE_STRING, (void *)printable_str, strlen(printable_str)); + LTC_SET_ASN1(static_list[0], 1, LTC_ASN1_IA5_STRING, (void *)ia5_str, strlen(ia5_str)); + LTC_SET_ASN1(static_list[0], 2, LTC_ASN1_SEQUENCE, static_list[1], 3); + + LTC_SET_ASN1(static_list[1], 0, LTC_ASN1_SHORT_INTEGER, (void *)&int_val, 1); + LTC_SET_ASN1(static_list[1], 1, LTC_ASN1_UTCTIME, (void *)&utctime, 1); + LTC_SET_ASN1(static_list[1], 2, LTC_ASN1_SEQUENCE, static_list[2], 3); + + LTC_SET_ASN1(static_list[2], 0, LTC_ASN1_OCTET_STRING, (void *)oct_str, 4); + LTC_SET_ASN1(static_list[2], 1, LTC_ASN1_BIT_STRING, (void *)bit_str, 4); + LTC_SET_ASN1(static_list[2], 2, LTC_ASN1_SEQUENCE, static_list[3], 3); + + LTC_SET_ASN1(static_list[3], 0, LTC_ASN1_OBJECT_IDENTIFIER,(void *)oid_str, 4); + LTC_SET_ASN1(static_list[3], 1, LTC_ASN1_NULL, NULL, 0); + LTC_SET_ASN1(static_list[3], 2, LTC_ASN1_SETOF, static_list[4], 2); + + LTC_SET_ASN1(static_list[4], 0, LTC_ASN1_PRINTABLE_STRING, set1_str, strlen(set1_str)); + LTC_SET_ASN1(static_list[4], 1, LTC_ASN1_PRINTABLE_STRING, set2_str, strlen(set2_str)); + + /* encode it */ + encode_buf_len = sizeof(encode_buf); + if ((err = der_encode_sequence(&static_list[0][0], 3, encode_buf, &encode_buf_len)) != CRYPT_OK) { + fprintf(stderr, "Encoding static_list: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + +#if 0 + { + FILE *f; + f = fopen("t.bin", "wb"); + fwrite(encode_buf, 1, encode_buf_len, f); + fclose(f); + } +#endif + + /* decode with flexi */ + decode_len = encode_buf_len; + if ((err = der_decode_sequence_flexi(encode_buf, &decode_len, &decoded_list)) != CRYPT_OK) { + fprintf(stderr, "decoding static_list: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + + if (decode_len != encode_buf_len) { + fprintf(stderr, "Decode len of %lu does not match encode len of %lu \n", decode_len, encode_buf_len); + exit(EXIT_FAILURE); + } + + /* we expect l->next to be NULL and l->child to not be */ + l = decoded_list; + if (l->next != NULL || l->child == NULL) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + /* we expect a SEQUENCE */ + if (l->type != LTC_ASN1_SEQUENCE) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + l = l->child; + + /* PRINTABLE STRING */ + /* we expect printable_str */ + if (l->next == NULL || l->child != NULL) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + if (l->type != LTC_ASN1_PRINTABLE_STRING) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + if (l->size != strlen(printable_str) || memcmp(printable_str, l->data, l->size)) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + /* move to next */ + l = l->next; + + /* IA5 STRING */ + /* we expect ia5_str */ + if (l->next == NULL || l->child != NULL) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + if (l->type != LTC_ASN1_IA5_STRING) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + if (l->size != strlen(ia5_str) || memcmp(ia5_str, l->data, l->size)) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + /* move to next */ + l = l->next; + + /* expect child anve move down */ + + if (l->next != NULL || l->child == NULL) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + if (l->type != LTC_ASN1_SEQUENCE) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + l = l->child; + + + /* INTEGER */ + + if (l->next == NULL || l->child != NULL) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + if (l->type != LTC_ASN1_INTEGER) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + if (mp_cmp_d(l->data, 12345678UL) != LTC_MP_EQ) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + /* move to next */ + l = l->next; + + /* UTCTIME */ + + if (l->next == NULL || l->child != NULL) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + if (l->type != LTC_ASN1_UTCTIME) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + if (memcmp(l->data, &utctime, sizeof(utctime))) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + /* move to next */ + l = l->next; + + /* expect child anve move down */ + + if (l->next != NULL || l->child == NULL) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + if (l->type != LTC_ASN1_SEQUENCE) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + l = l->child; + + + /* OCTET STRING */ + /* we expect oct_str */ + if (l->next == NULL || l->child != NULL) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + if (l->type != LTC_ASN1_OCTET_STRING) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + if (l->size != sizeof(oct_str) || memcmp(oct_str, l->data, l->size)) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + /* move to next */ + l = l->next; + + /* BIT STRING */ + /* we expect oct_str */ + if (l->next == NULL || l->child != NULL) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + if (l->type != LTC_ASN1_BIT_STRING) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + if (l->size != sizeof(bit_str) || memcmp(bit_str, l->data, l->size)) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + /* move to next */ + l = l->next; + + /* expect child anve move down */ + + if (l->next != NULL || l->child == NULL) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + if (l->type != LTC_ASN1_SEQUENCE) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + l = l->child; + + + /* OID STRING */ + /* we expect oid_str */ + if (l->next == NULL || l->child != NULL) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + if (l->type != LTC_ASN1_OBJECT_IDENTIFIER) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + if (l->size != sizeof(oid_str)/sizeof(oid_str[0]) || memcmp(oid_str, l->data, l->size*sizeof(oid_str[0]))) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + /* move to next */ + l = l->next; + + /* NULL */ + if (l->type != LTC_ASN1_NULL) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + /* move to next */ + l = l->next; + + /* expect child anve move down */ + if (l->next != NULL || l->child == NULL) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + if (l->type != LTC_ASN1_SET) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + l = l->child; + + /* PRINTABLE STRING */ + /* we expect printable_str */ + if (l->next == NULL || l->child != NULL) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + if (l->type != LTC_ASN1_PRINTABLE_STRING) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + +/* note we compare set2_str FIRST because the SET OF is sorted and "222" comes before "333" */ + if (l->size != strlen(set2_str) || memcmp(set2_str, l->data, l->size)) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + /* move to next */ + l = l->next; + + /* PRINTABLE STRING */ + /* we expect printable_str */ + if (l->type != LTC_ASN1_PRINTABLE_STRING) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + if (l->size != strlen(set1_str) || memcmp(set1_str, l->data, l->size)) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + + der_sequence_free(l); + +} + +static int der_choice_test(void) +{ + ltc_asn1_list types[7], host[1]; + unsigned char bitbuf[10], octetbuf[10], ia5buf[10], printbuf[10], outbuf[256]; + unsigned long integer, oidbuf[10], outlen, inlen, x, y; + void *mpinteger; + ltc_utctime utctime = { 91, 5, 6, 16, 45, 40, 1, 7, 0 }; + + /* setup variables */ + for (x = 0; x < sizeof(bitbuf); x++) { bitbuf[x] = x & 1; } + for (x = 0; x < sizeof(octetbuf); x++) { octetbuf[x] = x; } + for (x = 0; x < sizeof(ia5buf); x++) { ia5buf[x] = 'a'; } + for (x = 0; x < sizeof(printbuf); x++) { printbuf[x] = 'a'; } + integer = 1; + for (x = 0; x < sizeof(oidbuf)/sizeof(oidbuf[0]); x++) { oidbuf[x] = x + 1; } + DO(mp_init(&mpinteger)); + + for (x = 0; x < 14; x++) { + /* setup list */ + LTC_SET_ASN1(types, 0, LTC_ASN1_PRINTABLE_STRING, printbuf, sizeof(printbuf)); + LTC_SET_ASN1(types, 1, LTC_ASN1_BIT_STRING, bitbuf, sizeof(bitbuf)); + LTC_SET_ASN1(types, 2, LTC_ASN1_OCTET_STRING, octetbuf, sizeof(octetbuf)); + LTC_SET_ASN1(types, 3, LTC_ASN1_IA5_STRING, ia5buf, sizeof(ia5buf)); + if (x > 7) { + LTC_SET_ASN1(types, 4, LTC_ASN1_SHORT_INTEGER, &integer, 1); + } else { + LTC_SET_ASN1(types, 4, LTC_ASN1_INTEGER, mpinteger, 1); + } + LTC_SET_ASN1(types, 5, LTC_ASN1_OBJECT_IDENTIFIER, oidbuf, sizeof(oidbuf)/sizeof(oidbuf[0])); + LTC_SET_ASN1(types, 6, LTC_ASN1_UTCTIME, &utctime, 1); + + LTC_SET_ASN1(host, 0, LTC_ASN1_CHOICE, types, 7); + + + /* encode */ + outlen = sizeof(outbuf); + DO(der_encode_sequence(&types[x>6?x-7:x], 1, outbuf, &outlen)); + + /* decode it */ + inlen = outlen; + DO(der_decode_sequence(outbuf, inlen, &host[0], 1)); + + for (y = 0; y < 7; y++) { + if (types[y].used && y != (x>6?x-7:x)) { + fprintf(stderr, "CHOICE, flag %lu in trial %lu was incorrectly set to one\n", y, x); + return 1; + } + if (!types[y].used && y == (x>6?x-7:x)) { + fprintf(stderr, "CHOICE, flag %lu in trial %lu was incorrectly set to zero\n", y, x); + return 1; + } + } + } + mp_clear(mpinteger); + return 0; +} + + +int der_tests(void) +{ + unsigned long x, y, z, zz, oid[2][32]; + unsigned char buf[3][2048]; + void *a, *b, *c, *d, *e, *f, *g; + + static const unsigned char rsa_oid_der[] = { 0x06, 0x06, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d }; + static const unsigned long rsa_oid[] = { 1, 2, 840, 113549 }; + + static const unsigned char rsa_ia5[] = "test1@rsa.com"; + static const unsigned char rsa_ia5_der[] = { 0x16, 0x0d, 0x74, 0x65, 0x73, 0x74, 0x31, + 0x40, 0x72, 0x73, 0x61, 0x2e, 0x63, 0x6f, 0x6d }; + + static const unsigned char rsa_printable[] = "Test User 1"; + static const unsigned char rsa_printable_der[] = { 0x13, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, + 0x73, 0x65, 0x72, 0x20, 0x31 }; + + static const ltc_utctime rsa_time1 = { 91, 5, 6, 16, 45, 40, 1, 7, 0 }; + static const ltc_utctime rsa_time2 = { 91, 5, 6, 23, 45, 40, 0, 0, 0 }; + ltc_utctime tmp_time; + + static const unsigned char rsa_time1_der[] = { 0x17, 0x11, 0x39, 0x31, 0x30, 0x35, 0x30, 0x36, 0x31, 0x36, 0x34, 0x35, 0x34, 0x30, 0x2D, 0x30, 0x37, 0x30, 0x30 }; + static const unsigned char rsa_time2_der[] = { 0x17, 0x0d, 0x39, 0x31, 0x30, 0x35, 0x30, 0x36, 0x32, 0x33, 0x34, 0x35, 0x34, 0x30, 0x5a }; + + static const wchar_t utf8_1[] = { 0x0041, 0x2262, 0x0391, 0x002E }; + static const unsigned char utf8_1_der[] = { 0x0C, 0x07, 0x41, 0xE2, 0x89, 0xA2, 0xCE, 0x91, 0x2E }; + static const wchar_t utf8_2[] = { 0xD55C, 0xAD6D, 0xC5B4 }; + static const unsigned char utf8_2_der[] = { 0x0C, 0x09, 0xED, 0x95, 0x9C, 0xEA, 0xB5, 0xAD, 0xEC, 0x96, 0xB4 }; + + unsigned char utf8_buf[32]; + wchar_t utf8_out[32]; + + DO(mp_init_multi(&a, &b, &c, &d, &e, &f, &g, NULL)); + for (zz = 0; zz < 16; zz++) { +#ifdef USE_TFM + for (z = 0; z < 256; z++) { +#else + for (z = 0; z < 1024; z++) { +#endif + if (yarrow_read(buf[0], z, &yarrow_prng) != z) { + fprintf(stderr, "Failed to read %lu bytes from yarrow\n", z); + return 1; + } + DO(mp_read_unsigned_bin(a, buf[0], z)); +/* if (mp_iszero(a) == LTC_MP_NO) { a.sign = buf[0][0] & 1 ? LTC_MP_ZPOS : LTC_MP_NEG; } */ + x = sizeof(buf[0]); + DO(der_encode_integer(a, buf[0], &x)); + DO(der_length_integer(a, &y)); + if (y != x) { fprintf(stderr, "DER INTEGER size mismatch\n"); return 1; } + mp_set_int(b, 0); + DO(der_decode_integer(buf[0], y, b)); + if (y != x || mp_cmp(a, b) != LTC_MP_EQ) { + fprintf(stderr, "%lu: %lu vs %lu\n", z, x, y); + mp_clear_multi(a, b, c, d, e, f, g, NULL); + return 1; + } + } + } + +/* test short integer */ + for (zz = 0; zz < 256; zz++) { + for (z = 1; z < 4; z++) { + if (yarrow_read(buf[0], z, &yarrow_prng) != z) { + fprintf(stderr, "Failed to read %lu bytes from yarrow\n", z); + return 1; + } + /* encode with normal */ + DO(mp_read_unsigned_bin(a, buf[0], z)); + + x = sizeof(buf[0]); + DO(der_encode_integer(a, buf[0], &x)); + + /* encode with short */ + y = sizeof(buf[1]); + DO(der_encode_short_integer(mp_get_int(a), buf[1], &y)); + if (x != y || memcmp(buf[0], buf[1], x)) { + fprintf(stderr, "DER INTEGER short encoding failed, %lu, %lu\n", x, y); + for (z = 0; z < x; z++) fprintf(stderr, "%02x ", buf[0][z]); fprintf(stderr, "\n"); + for (z = 0; z < y; z++) fprintf(stderr, "%02x ", buf[1][z]); fprintf(stderr, "\n"); + mp_clear_multi(a, b, c, d, e, f, g, NULL); + return 1; + } + + /* decode it */ + x = 0; + DO(der_decode_short_integer(buf[1], y, &x)); + if (x != mp_get_int(a)) { + fprintf(stderr, "DER INTEGER short decoding failed, %lu, %lu\n", x, mp_get_int(a)); + mp_clear_multi(a, b, c, d, e, f, g, NULL); + return 1; + } + } + } + mp_clear_multi(a, b, c, d, e, f, g, NULL); + + +/* Test bit string */ + for (zz = 1; zz < 1536; zz++) { + yarrow_read(buf[0], zz, &yarrow_prng); + for (z = 0; z < zz; z++) { + buf[0][z] &= 0x01; + } + x = sizeof(buf[1]); + DO(der_encode_bit_string(buf[0], zz, buf[1], &x)); + DO(der_length_bit_string(zz, &y)); + if (y != x) { + fprintf(stderr, "\nDER BIT STRING length of encoded not match expected : %lu, %lu, %lu\n", z, x, y); + return 1; + } + + y = sizeof(buf[2]); + DO(der_decode_bit_string(buf[1], x, buf[2], &y)); + if (y != zz || memcmp(buf[0], buf[2], zz)) { + fprintf(stderr, "%lu, %lu, %d\n", y, zz, memcmp(buf[0], buf[2], zz)); + return 1; + } + } + +/* Test octet string */ + for (zz = 1; zz < 1536; zz++) { + yarrow_read(buf[0], zz, &yarrow_prng); + x = sizeof(buf[1]); + DO(der_encode_octet_string(buf[0], zz, buf[1], &x)); + DO(der_length_octet_string(zz, &y)); + if (y != x) { + fprintf(stderr, "\nDER OCTET STRING length of encoded not match expected : %lu, %lu, %lu\n", z, x, y); + return 1; + } + y = sizeof(buf[2]); + DO(der_decode_octet_string(buf[1], x, buf[2], &y)); + if (y != zz || memcmp(buf[0], buf[2], zz)) { + fprintf(stderr, "%lu, %lu, %d\n", y, zz, memcmp(buf[0], buf[2], zz)); + return 1; + } + } + +/* test OID */ + x = sizeof(buf[0]); + DO(der_encode_object_identifier((unsigned long*)rsa_oid, sizeof(rsa_oid)/sizeof(rsa_oid[0]), buf[0], &x)); + if (x != sizeof(rsa_oid_der) || memcmp(rsa_oid_der, buf[0], x)) { + fprintf(stderr, "rsa_oid_der encode failed to match, %lu, ", x); + for (y = 0; y < x; y++) fprintf(stderr, "%02x ", buf[0][y]); + fprintf(stderr, "\n"); + return 1; + } + + y = sizeof(oid[0])/sizeof(oid[0][0]); + DO(der_decode_object_identifier(buf[0], x, oid[0], &y)); + if (y != sizeof(rsa_oid)/sizeof(rsa_oid[0]) || memcmp(rsa_oid, oid[0], sizeof(rsa_oid))) { + fprintf(stderr, "rsa_oid_der decode failed to match, %lu, ", y); + for (z = 0; z < y; z++) fprintf(stderr, "%lu ", oid[0][z]); + fprintf(stderr, "\n"); + return 1; + } + + /* do random strings */ + for (zz = 0; zz < 5000; zz++) { + /* pick a random number of words */ + yarrow_read(buf[0], 4, &yarrow_prng); + LOAD32L(z, buf[0]); + z = 2 + (z % ((sizeof(oid[0])/sizeof(oid[0][0])) - 2)); + + /* fill them in */ + oid[0][0] = buf[0][0] % 3; + oid[0][1] = buf[0][1] % 40; + + for (y = 2; y < z; y++) { + yarrow_read(buf[0], 4, &yarrow_prng); + LOAD32L(oid[0][y], buf[0]); + } + + /* encode it */ + x = sizeof(buf[0]); + DO(der_encode_object_identifier(oid[0], z, buf[0], &x)); + DO(der_length_object_identifier(oid[0], z, &y)); + if (x != y) { + fprintf(stderr, "Random OID %lu test failed, length mismatch: %lu, %lu\n", z, x, y); + for (x = 0; x < z; x++) fprintf(stderr, "%lu\n", oid[0][x]); + return 1; + } + + /* decode it */ + y = sizeof(oid[0])/sizeof(oid[0][0]); + DO(der_decode_object_identifier(buf[0], x, oid[1], &y)); + if (y != z) { + fprintf(stderr, "Random OID %lu test failed, decode length mismatch: %lu, %lu\n", z, x, y); + return 1; + } + if (memcmp(oid[0], oid[1], sizeof(oid[0][0]) * z)) { + fprintf(stderr, "Random OID %lu test failed, decoded values wrong\n", z); + for (x = 0; x < z; x++) fprintf(stderr, "%lu\n", oid[0][x]); fprintf(stderr, "\n\n Got \n\n"); + for (x = 0; x < z; x++) fprintf(stderr, "%lu\n", oid[1][x]); + return 1; + } + } + +/* IA5 string */ + x = sizeof(buf[0]); + DO(der_encode_ia5_string(rsa_ia5, strlen((char*)rsa_ia5), buf[0], &x)); + if (x != sizeof(rsa_ia5_der) || memcmp(buf[0], rsa_ia5_der, x)) { + fprintf(stderr, "IA5 encode failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_ia5_der)); + return 1; + } + DO(der_length_ia5_string(rsa_ia5, strlen((char*)rsa_ia5), &y)); + if (y != x) { + fprintf(stderr, "IA5 length failed to match: %lu, %lu\n", x, y); + return 1; + } + y = sizeof(buf[1]); + DO(der_decode_ia5_string(buf[0], x, buf[1], &y)); + if (y != strlen((char*)rsa_ia5) || memcmp(buf[1], rsa_ia5, strlen((char*)rsa_ia5))) { + fprintf(stderr, "DER IA5 failed test vector\n"); + return 1; + } + +/* Printable string */ + x = sizeof(buf[0]); + DO(der_encode_printable_string(rsa_printable, strlen((char*)rsa_printable), buf[0], &x)); + if (x != sizeof(rsa_printable_der) || memcmp(buf[0], rsa_printable_der, x)) { + fprintf(stderr, "PRINTABLE encode failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_printable_der)); + return 1; + } + DO(der_length_printable_string(rsa_printable, strlen((char*)rsa_printable), &y)); + if (y != x) { + fprintf(stderr, "printable length failed to match: %lu, %lu\n", x, y); + return 1; + } + y = sizeof(buf[1]); + DO(der_decode_printable_string(buf[0], x, buf[1], &y)); + if (y != strlen((char*)rsa_printable) || memcmp(buf[1], rsa_printable, strlen((char*)rsa_printable))) { + fprintf(stderr, "DER printable failed test vector\n"); + return 1; + } + +/* Test UTC time */ + x = sizeof(buf[0]); + DO(der_encode_utctime((ltc_utctime*)&rsa_time1, buf[0], &x)); + if (x != sizeof(rsa_time1_der) || memcmp(buf[0], rsa_time1_der, x)) { + fprintf(stderr, "UTCTIME encode of rsa_time1 failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_time1_der)); +fprintf(stderr, "\n\n"); +for (y = 0; y < x; y++) fprintf(stderr, "%02x ", buf[0][y]); printf("\n"); + + return 1; + } + DO(der_length_utctime((ltc_utctime*)&rsa_time1, &y)); + if (y != x) { + fprintf(stderr, "UTCTIME length failed to match for rsa_time1: %lu, %lu\n", x, y); + return 1; + } + DO(der_decode_utctime(buf[0], &y, &tmp_time)); + if (y != x || memcmp(&rsa_time1, &tmp_time, sizeof(ltc_utctime))) { + fprintf(stderr, "UTCTIME decode failed for rsa_time1: %lu %lu\n", x, y); +fprintf(stderr, "\n\n%u %u %u %u %u %u %u %u %u\n\n", +tmp_time.YY, +tmp_time.MM, +tmp_time.DD, +tmp_time.hh, +tmp_time.mm, +tmp_time.ss, +tmp_time.off_dir, +tmp_time.off_mm, +tmp_time.off_hh); + return 1; + } + + x = sizeof(buf[0]); + DO(der_encode_utctime((ltc_utctime*)&rsa_time2, buf[0], &x)); + if (x != sizeof(rsa_time2_der) || memcmp(buf[0], rsa_time2_der, x)) { + fprintf(stderr, "UTCTIME encode of rsa_time2 failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_time1_der)); +fprintf(stderr, "\n\n"); +for (y = 0; y < x; y++) fprintf(stderr, "%02x ", buf[0][y]); printf("\n"); + + return 1; + } + DO(der_length_utctime((ltc_utctime*)&rsa_time2, &y)); + if (y != x) { + fprintf(stderr, "UTCTIME length failed to match for rsa_time2: %lu, %lu\n", x, y); + return 1; + } + DO(der_decode_utctime(buf[0], &y, &tmp_time)); + if (y != x || memcmp(&rsa_time2, &tmp_time, sizeof(ltc_utctime))) { + fprintf(stderr, "UTCTIME decode failed for rsa_time2: %lu %lu\n", x, y); +fprintf(stderr, "\n\n%u %u %u %u %u %u %u %u %u\n\n", +tmp_time.YY, +tmp_time.MM, +tmp_time.DD, +tmp_time.hh, +tmp_time.mm, +tmp_time.ss, +tmp_time.off_dir, +tmp_time.off_mm, +tmp_time.off_hh); + + + return 1; + } + + /* UTF 8 */ + /* encode it */ + x = sizeof(utf8_buf); + DO(der_encode_utf8_string(utf8_1, sizeof(utf8_1) / sizeof(utf8_1[0]), utf8_buf, &x)); + if (x != sizeof(utf8_1_der) || memcmp(utf8_buf, utf8_1_der, x)) { + fprintf(stderr, "DER UTF8_1 encoded to %lu bytes\n", x); + for (y = 0; y < x; y++) fprintf(stderr, "%02x ", (unsigned)utf8_buf[y]); fprintf(stderr, "\n"); + return 1; + } + /* decode it */ + y = sizeof(utf8_out) / sizeof(utf8_out[0]); + DO(der_decode_utf8_string(utf8_buf, x, utf8_out, &y)); + if (y != (sizeof(utf8_1) / sizeof(utf8_1[0])) || memcmp(utf8_1, utf8_out, y * sizeof(wchar_t))) { + fprintf(stderr, "DER UTF8_1 decoded to %lu wchar_t\n", y); + for (x = 0; x < y; x++) fprintf(stderr, "%04lx ", (unsigned long)utf8_out[x]); fprintf(stderr, "\n"); + return 1; + } + + /* encode it */ + x = sizeof(utf8_buf); + DO(der_encode_utf8_string(utf8_2, sizeof(utf8_2) / sizeof(utf8_2[0]), utf8_buf, &x)); + if (x != sizeof(utf8_2_der) || memcmp(utf8_buf, utf8_2_der, x)) { + fprintf(stderr, "DER UTF8_2 encoded to %lu bytes\n", x); + for (y = 0; y < x; y++) fprintf(stderr, "%02x ", (unsigned)utf8_buf[y]); fprintf(stderr, "\n"); + return 1; + } + /* decode it */ + y = sizeof(utf8_out) / sizeof(utf8_out[0]); + DO(der_decode_utf8_string(utf8_buf, x, utf8_out, &y)); + if (y != (sizeof(utf8_2) / sizeof(utf8_2[0])) || memcmp(utf8_2, utf8_out, y * sizeof(wchar_t))) { + fprintf(stderr, "DER UTF8_2 decoded to %lu wchar_t\n", y); + for (x = 0; x < y; x++) fprintf(stderr, "%04lx ", (unsigned long)utf8_out[x]); fprintf(stderr, "\n"); + return 1; + } + + + der_set_test(); + der_flexi_test(); + return der_choice_test(); +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/testprof/der_tests.c,v $ */ +/* $Revision: 1.50 $ */ +/* $Date: 2007/05/12 14:20:27 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/testprof/dsa_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/dsa_test.c new file mode 100644 index 0000000000..e259969f50 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/dsa_test.c @@ -0,0 +1,82 @@ +#include + +#ifdef LTC_MDSA + +int dsa_test(void) +{ + unsigned char msg[16], out[1024], out2[1024]; + unsigned long x, y; + int stat1, stat2; + dsa_key key, key2; + + /* make a random key */ + DO(dsa_make_key(&yarrow_prng, find_prng("yarrow"), 20, 128, &key)); + + /* verify it */ + DO(dsa_verify_key(&key, &stat1)); + if (stat1 == 0) { fprintf(stderr, "dsa_verify_key "); return 1; } + + /* encrypt a message */ + for (x = 0; x < 16; x++) { msg[x] = x; } + x = sizeof(out); + DO(dsa_encrypt_key(msg, 16, out, &x, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"), &key)); + + /* decrypt */ + y = sizeof(out2); + DO(dsa_decrypt_key(out, x, out2, &y, &key)); + + if (y != 16 || memcmp(out2, msg, 16)) { + fprintf(stderr, "dsa_decrypt failed, y == %lu\n", y); + return 1; + } + + /* sign the message */ + x = sizeof(out); + DO(dsa_sign_hash(msg, sizeof(msg), out, &x, &yarrow_prng, find_prng("yarrow"), &key)); + + /* verify it once */ + DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key)); + + /* Modify and verify again */ + msg[0] ^= 1; + DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat2, &key)); + msg[0] ^= 1; + if (!(stat1 == 1 && stat2 == 0)) { fprintf(stderr, "dsa_verify %d %d", stat1, stat2); return 1; } + + /* test exporting it */ + x = sizeof(out2); + DO(dsa_export(out2, &x, PK_PRIVATE, &key)); + DO(dsa_import(out2, x, &key2)); + + /* verify a signature with it */ + DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key2)); + if (stat1 == 0) { fprintf(stderr, "dsa_verify (import private) %d ", stat1); return 1; } + dsa_free(&key2); + + /* export as public now */ + x = sizeof(out2); + DO(dsa_export(out2, &x, PK_PUBLIC, &key)); + + DO(dsa_import(out2, x, &key2)); + /* verify a signature with it */ + DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key2)); + if (stat1 == 0) { fprintf(stderr, "dsa_verify (import public) %d ", stat1); return 1; } + dsa_free(&key2); + dsa_free(&key); + + return 0; +} + +#else + +int dsa_test(void) +{ + fprintf(stderr, "NOP"); + return 0; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/testprof/dsa_test.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/testprof/ecc_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/ecc_test.c new file mode 100644 index 0000000000..2c82c8b43d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/ecc_test.c @@ -0,0 +1,252 @@ +#include + +#ifdef LTC_MECC + +static int sizes[] = { +#ifdef ECC112 +14, +#endif +#ifdef ECC128 +16, +#endif +#ifdef ECC160 +20, +#endif +#ifdef ECC192 +24, +#endif +#ifdef ECC224 +28, +#endif +#ifdef ECC256 +32, +#endif +#ifdef ECC384 +48, +#endif +#ifdef ECC521 +65 +#endif +}; + +#ifdef LTC_ECC_SHAMIR +int ecc_test_shamir(void) +{ + void *modulus, *mp, *kA, *kB, *rA, *rB; + ecc_point *G, *A, *B, *C1, *C2; + int x, y, z; + unsigned char buf[ECC_BUF_SIZE]; + + DO(mp_init_multi(&kA, &kB, &rA, &rB, &modulus, NULL)); + LTC_ARGCHK((G = ltc_ecc_new_point()) != NULL); + LTC_ARGCHK((A = ltc_ecc_new_point()) != NULL); + LTC_ARGCHK((B = ltc_ecc_new_point()) != NULL); + LTC_ARGCHK((C1 = ltc_ecc_new_point()) != NULL); + LTC_ARGCHK((C2 = ltc_ecc_new_point()) != NULL); + + for (x = 0; x < (int)(sizeof(sizes)/sizeof(sizes[0])); x++) { + /* get the base point */ + for (z = 0; ltc_ecc_sets[z].name; z++) { + if (sizes[z] < ltc_ecc_sets[z].size) break; + } + LTC_ARGCHK(ltc_ecc_sets[z].name != NULL); + + /* load it */ + DO(mp_read_radix(G->x, ltc_ecc_sets[z].Gx, 16)); + DO(mp_read_radix(G->y, ltc_ecc_sets[z].Gy, 16)); + DO(mp_set(G->z, 1)); + DO(mp_read_radix(modulus, ltc_ecc_sets[z].prime, 16)); + DO(mp_montgomery_setup(modulus, &mp)); + + /* do 100 random tests */ + for (y = 0; y < 100; y++) { + /* pick a random r1, r2 */ + LTC_ARGCHK(yarrow_read(buf, sizes[x], &yarrow_prng) == sizes[x]); + DO(mp_read_unsigned_bin(rA, buf, sizes[x])); + LTC_ARGCHK(yarrow_read(buf, sizes[x], &yarrow_prng) == sizes[x]); + DO(mp_read_unsigned_bin(rB, buf, sizes[x])); + + /* compute rA * G = A */ + DO(ltc_mp.ecc_ptmul(rA, G, A, modulus, 1)); + + /* compute rB * G = B */ + DO(ltc_mp.ecc_ptmul(rB, G, B, modulus, 1)); + + /* pick a random kA, kB */ + LTC_ARGCHK(yarrow_read(buf, sizes[x], &yarrow_prng) == sizes[x]); + DO(mp_read_unsigned_bin(kA, buf, sizes[x])); + LTC_ARGCHK(yarrow_read(buf, sizes[x], &yarrow_prng) == sizes[x]); + DO(mp_read_unsigned_bin(kB, buf, sizes[x])); + + /* now, compute kA*A + kB*B = C1 using the older method */ + DO(ltc_mp.ecc_ptmul(kA, A, C1, modulus, 0)); + DO(ltc_mp.ecc_ptmul(kB, B, C2, modulus, 0)); + DO(ltc_mp.ecc_ptadd(C1, C2, C1, modulus, mp)); + DO(ltc_mp.ecc_map(C1, modulus, mp)); + + /* now compute using mul2add */ + DO(ltc_mp.ecc_mul2add(A, kA, B, kB, C2, modulus)); + + /* is they the sames? */ + if ((mp_cmp(C1->x, C2->x) != LTC_MP_EQ) || (mp_cmp(C1->y, C2->y) != LTC_MP_EQ) || (mp_cmp(C1->z, C2->z) != LTC_MP_EQ)) { + fprintf(stderr, "ECC failed shamir test: size=%d, testno=%d\n", sizes[x], y); + return 1; + } + } + mp_montgomery_free(mp); + } + ltc_ecc_del_point(C2); + ltc_ecc_del_point(C1); + ltc_ecc_del_point(B); + ltc_ecc_del_point(A); + ltc_ecc_del_point(G); + mp_clear_multi(kA, kB, rA, rB, modulus, NULL); + return 0; +} +#endif + +int ecc_tests (void) +{ + unsigned char buf[4][4096]; + unsigned long x, y, z, s; + int stat, stat2; + ecc_key usera, userb, pubKey, privKey; + + DO(ecc_test ()); + DO(ecc_test ()); + DO(ecc_test ()); + DO(ecc_test ()); + DO(ecc_test ()); + + for (s = 0; s < (sizeof(sizes)/sizeof(sizes[0])); s++) { + /* make up two keys */ + DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &usera)); + DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &userb)); + + /* make the shared secret */ + x = sizeof(buf[0]); + DO(ecc_shared_secret (&usera, &userb, buf[0], &x)); + + y = sizeof(buf[1]); + DO(ecc_shared_secret (&userb, &usera, buf[1], &y)); + + if (y != x) { + fprintf(stderr, "ecc Shared keys are not same size."); + return 1; + } + + if (memcmp (buf[0], buf[1], x)) { + fprintf(stderr, "ecc Shared keys not same contents."); + return 1; + } + + /* now export userb */ + y = sizeof(buf[0]); + DO(ecc_export (buf[1], &y, PK_PUBLIC, &userb)); + ecc_free (&userb); + + /* import and make the shared secret again */ + DO(ecc_import (buf[1], y, &userb)); + + z = sizeof(buf[0]); + DO(ecc_shared_secret (&usera, &userb, buf[2], &z)); + + if (z != x) { + fprintf(stderr, "failed. Size don't match?"); + return 1; + } + if (memcmp (buf[0], buf[2], x)) { + fprintf(stderr, "Failed. Contents didn't match."); + return 1; + } + + /* export with ANSI X9.63 */ + y = sizeof(buf[1]); + DO(ecc_ansi_x963_export(&userb, buf[1], &y)); + ecc_free (&userb); + + /* now import the ANSI key */ + DO(ecc_ansi_x963_import(buf[1], y, &userb)); + + /* shared secret */ + z = sizeof(buf[0]); + DO(ecc_shared_secret (&usera, &userb, buf[2], &z)); + + if (z != x) { + fprintf(stderr, "failed. Size don't match?"); + return 1; + } + if (memcmp (buf[0], buf[2], x)) { + fprintf(stderr, "Failed. Contents didn't match."); + return 1; + } + + ecc_free (&usera); + ecc_free (&userb); + + /* test encrypt_key */ + DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &usera)); + + /* export key */ + x = sizeof(buf[0]); + DO(ecc_export(buf[0], &x, PK_PUBLIC, &usera)); + DO(ecc_import(buf[0], x, &pubKey)); + x = sizeof(buf[0]); + DO(ecc_export(buf[0], &x, PK_PRIVATE, &usera)); + DO(ecc_import(buf[0], x, &privKey)); + + for (x = 0; x < 32; x++) { + buf[0][x] = x; + } + y = sizeof (buf[1]); + DO(ecc_encrypt_key (buf[0], 32, buf[1], &y, &yarrow_prng, find_prng ("yarrow"), find_hash ("sha256"), &pubKey)); + zeromem (buf[0], sizeof (buf[0])); + x = sizeof (buf[0]); + DO(ecc_decrypt_key (buf[1], y, buf[0], &x, &privKey)); + if (x != 32) { + fprintf(stderr, "Failed (length)"); + return 1; + } + for (x = 0; x < 32; x++) { + if (buf[0][x] != x) { + fprintf(stderr, "Failed (contents)"); + return 1; + } + } + /* test sign_hash */ + for (x = 0; x < 16; x++) { + buf[0][x] = x; + } + x = sizeof (buf[1]); + DO(ecc_sign_hash (buf[0], 16, buf[1], &x, &yarrow_prng, find_prng ("yarrow"), &privKey)); + DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat, &pubKey)); + buf[0][0] ^= 1; + DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat2, &privKey)); + if (!(stat == 1 && stat2 == 0)) { + fprintf(stderr, "ecc_verify_hash failed %d, %d, ", stat, stat2); + return 1; + } + ecc_free (&usera); + ecc_free (&pubKey); + ecc_free (&privKey); + } +#ifdef LTC_ECC_SHAMIR + return ecc_test_shamir(); +#else + return 0; +#endif +} + +#else + +int ecc_tests(void) +{ + fprintf(stderr, "NOP"); + return 0; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/testprof/ecc_test.c,v $ */ +/* $Revision: 1.22 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/testprof/katja_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/katja_test.c new file mode 100644 index 0000000000..3b29dfe207 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/katja_test.c @@ -0,0 +1,231 @@ +#include + +#ifdef MKAT + +int katja_test(void) +{ + unsigned char in[1024], out[1024], tmp[1024]; + katja_key key, privKey, pubKey; + int hash_idx, prng_idx, stat, stat2, size; + unsigned long kat_msgsize, len, len2, cnt; + static unsigned char lparam[] = { 0x01, 0x02, 0x03, 0x04 }; + + hash_idx = find_hash("sha1"); + prng_idx = find_prng("yarrow"); + if (hash_idx == -1 || prng_idx == -1) { + fprintf(stderr, "katja_test requires LTC_SHA1 and yarrow"); + return 1; + } + +for (size = 1024; size <= 2048; size += 256) { + + /* make 10 random key */ + for (cnt = 0; cnt < 10; cnt++) { + DO(katja_make_key(&yarrow_prng, prng_idx, size/8, &key)); + if (mp_count_bits(key.N) < size - 7) { + fprintf(stderr, "katja_%d key modulus has %d bits\n", size, mp_count_bits(key.N)); + +len = mp_unsigned_bin_size(key.N); +mp_to_unsigned_bin(key.N, tmp); + fprintf(stderr, "N == \n"); +for (cnt = 0; cnt < len; ) { + fprintf(stderr, "%02x ", tmp[cnt]); + if (!(++cnt & 15)) fprintf(stderr, "\n"); +} + +len = mp_unsigned_bin_size(key.p); +mp_to_unsigned_bin(key.p, tmp); + fprintf(stderr, "p == \n"); +for (cnt = 0; cnt < len; ) { + fprintf(stderr, "%02x ", tmp[cnt]); + if (!(++cnt & 15)) fprintf(stderr, "\n"); +} + +len = mp_unsigned_bin_size(key.q); +mp_to_unsigned_bin(key.q, tmp); + fprintf(stderr, "\nq == \n"); +for (cnt = 0; cnt < len; ) { + fprintf(stderr, "%02x ", tmp[cnt]); + if (!(++cnt & 15)) fprintf(stderr, "\n"); +} + fprintf(stderr, "\n"); + + + return 1; + } + if (cnt != 9) { + katja_free(&key); + } + } + /* encrypt the key (without lparam) */ + for (cnt = 0; cnt < 4; cnt++) { + for (kat_msgsize = 1; kat_msgsize <= 42; kat_msgsize++) { + /* make a random key/msg */ + yarrow_read(in, kat_msgsize, &yarrow_prng); + + len = sizeof(out); + len2 = kat_msgsize; + + DO(katja_encrypt_key(in, kat_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, hash_idx, &key)); + /* change a byte */ + out[8] ^= 1; + DO(katja_decrypt_key(out, len, tmp, &len2, NULL, 0, hash_idx, &stat2, &key)); + /* change a byte back */ + out[8] ^= 1; + if (len2 != kat_msgsize) { + fprintf(stderr, "\nkatja_decrypt_key mismatch len %lu (first decrypt)", len2); + return 1; + } + + len2 = kat_msgsize; + DO(katja_decrypt_key(out, len, tmp, &len2, NULL, 0, hash_idx, &stat, &key)); + if (!(stat == 1 && stat2 == 0)) { + fprintf(stderr, "katja_decrypt_key failed"); + return 1; + } + if (len2 != kat_msgsize || memcmp(tmp, in, kat_msgsize)) { + unsigned long x; + fprintf(stderr, "\nkatja_decrypt_key mismatch, len %lu (second decrypt)\n", len2); + fprintf(stderr, "Original contents: \n"); + for (x = 0; x < kat_msgsize; ) { + fprintf(stderr, "%02x ", in[x]); + if (!(++x % 16)) { + fprintf(stderr, "\n"); + } + } + fprintf(stderr, "\n"); + fprintf(stderr, "Output contents: \n"); + for (x = 0; x < kat_msgsize; ) { + fprintf(stderr, "%02x ", out[x]); + if (!(++x % 16)) { + fprintf(stderr, "\n"); + } + } + fprintf(stderr, "\n"); + return 1; + } + } + } + + /* encrypt the key (with lparam) */ + for (kat_msgsize = 1; kat_msgsize <= 42; kat_msgsize++) { + len = sizeof(out); + len2 = kat_msgsize; + DO(katja_encrypt_key(in, kat_msgsize, out, &len, lparam, sizeof(lparam), &yarrow_prng, prng_idx, hash_idx, &key)); + /* change a byte */ + out[8] ^= 1; + DO(katja_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), hash_idx, &stat2, &key)); + if (len2 != kat_msgsize) { + fprintf(stderr, "\nkatja_decrypt_key mismatch len %lu (first decrypt)", len2); + return 1; + } + /* change a byte back */ + out[8] ^= 1; + + len2 = kat_msgsize; + DO(katja_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), hash_idx, &stat, &key)); + if (!(stat == 1 && stat2 == 0)) { + fprintf(stderr, "katja_decrypt_key failed"); + return 1; + } + if (len2 != kat_msgsize || memcmp(tmp, in, kat_msgsize)) { + fprintf(stderr, "katja_decrypt_key mismatch len %lu", len2); + return 1; + } + } + +#if 0 + + /* sign a message (unsalted, lower cholestorol and Atkins approved) now */ + len = sizeof(out); + DO(katja_sign_hash(in, 20, out, &len, &yarrow_prng, prng_idx, hash_idx, 0, &key)); + +/* export key and import as both private and public */ + len2 = sizeof(tmp); + DO(katja_export(tmp, &len2, PK_PRIVATE, &key)); + DO(katja_import(tmp, len2, &privKey)); + len2 = sizeof(tmp); + DO(katja_export(tmp, &len2, PK_PUBLIC, &key)); + DO(katja_import(tmp, len2, &pubKey)); + + /* verify with original */ + DO(katja_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &key)); + /* change a byte */ + in[0] ^= 1; + DO(katja_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &key)); + + if (!(stat == 1 && stat2 == 0)) { + fprintf(stderr, "katja_verify_hash (unsalted, origKey) failed, %d, %d", stat, stat2); + katja_free(&key); + katja_free(&pubKey); + katja_free(&privKey); + return 1; + } + + /* verify with privKey */ + /* change a byte */ + in[0] ^= 1; + DO(katja_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &privKey)); + /* change a byte */ + in[0] ^= 1; + DO(katja_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &privKey)); + + if (!(stat == 1 && stat2 == 0)) { + fprintf(stderr, "katja_verify_hash (unsalted, privKey) failed, %d, %d", stat, stat2); + katja_free(&key); + katja_free(&pubKey); + katja_free(&privKey); + return 1; + } + + /* verify with pubKey */ + /* change a byte */ + in[0] ^= 1; + DO(katja_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &pubKey)); + /* change a byte */ + in[0] ^= 1; + DO(katja_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &pubKey)); + + if (!(stat == 1 && stat2 == 0)) { + fprintf(stderr, "katja_verify_hash (unsalted, pubkey) failed, %d, %d", stat, stat2); + katja_free(&key); + katja_free(&pubKey); + katja_free(&privKey); + return 1; + } + + /* sign a message (salted) now (use privKey to make, pubKey to verify) */ + len = sizeof(out); + DO(katja_sign_hash(in, 20, out, &len, &yarrow_prng, prng_idx, hash_idx, 8, &privKey)); + DO(katja_verify_hash(out, len, in, 20, hash_idx, 8, &stat, &pubKey)); + /* change a byte */ + in[0] ^= 1; + DO(katja_verify_hash(out, len, in, 20, hash_idx, 8, &stat2, &pubKey)); + + if (!(stat == 1 && stat2 == 0)) { + fprintf(stderr, "katja_verify_hash (salted) failed, %d, %d", stat, stat2); + katja_free(&key); + katja_free(&pubKey); + katja_free(&privKey); + return 1; + } +#endif + + katja_free(&key); + katja_free(&pubKey); + katja_free(&privKey); +} + + /* free the key and return */ + return 0; +} + +#else + +int katja_test(void) +{ + fprintf(stderr, "NOP"); + return 0; +} + +#endif diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/testprof/mac_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/mac_test.c new file mode 100644 index 0000000000..32481aaf0c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/mac_test.c @@ -0,0 +1,41 @@ +/* test pmac/omac/hmac */ +#include + +int mac_test(void) +{ +#ifdef LTC_HMAC + DO(hmac_test()); +#endif +#ifdef LTC_PMAC + DO(pmac_test()); +#endif +#ifdef LTC_OMAC + DO(omac_test()); +#endif +#ifdef LTC_XCBC + DO(xcbc_test()); +#endif +#ifdef LTC_F9_MODE + DO(f9_test()); +#endif +#ifdef LTC_EAX_MODE + DO(eax_test()); +#endif +#ifdef LTC_OCB_MODE + DO(ocb_test()); +#endif +#ifdef LTC_CCM_MODE + DO(ccm_test()); +#endif +#ifdef LTC_GCM_MODE + DO(gcm_test()); +#endif +#ifdef LTC_PELICAN + DO(pelican_test()); +#endif + return 0; +} + +/* $Source: /cvs/libtom/libtomcrypt/testprof/mac_test.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/testprof/makefile b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/makefile new file mode 100644 index 0000000000..4cc70ff59e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/makefile @@ -0,0 +1,24 @@ +CFLAGS += -I../src/headers -I./ -Wall -W + +# ranlib tools +ifndef RANLIB + RANLIB=ranlib +endif + +OBJECTS = base64_test.o cipher_hash_test.o der_tests.o \ +dsa_test.o ecc_test.o mac_test.o modes_test.o pkcs_1_test.o rsa_test.o \ +store_test.o test_driver.o x86_prof.o katja_test.o + +ifndef LIBTEST_S + LIBTEST_S=libtomcrypt_prof.a +endif + +default: $(LIBTEST_S) + +$(LIBTEST_S): $(OBJECTS) + $(AR) $(ARFLAGS) $@ $(OBJECTS) + $(RANLIB) $@ + +clean: + rm -f *.o *.a + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/testprof/makefile.icc b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/makefile.icc new file mode 100644 index 0000000000..60628ce190 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/makefile.icc @@ -0,0 +1,20 @@ +CFLAGS += -I../src/headers -I./ +CC=icc + +OBJECTS = base64_test.o cipher_hash_test.o der_tests.o \ +dsa_test.o ecc_test.o mac_test.o modes_test.o pkcs_1_test.o rsa_test.o \ +store_test.o test_driver.o x86_prof.o katja_test.o + +ifndef LIBTEST_S + LIBTEST_S = libtomcrypt_prof.a +endif + +default: $(LIBTEST_S) + +$(LIBTEST_S): $(OBJECTS) + $(AR) $(ARFLAGS) $@ $(OBJECTS) + ranlib $@ + +clean: + rm -f *.o *.a + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/testprof/makefile.msvc b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/makefile.msvc new file mode 100644 index 0000000000..d330f9332d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/makefile.msvc @@ -0,0 +1,10 @@ +CFLAGS = /I../src/headers/ /I./ /Ox /DWIN32 /DLTC_SOURCE /W3 /Fo$@ + +OBJECTS=base64_test.obj cipher_hash_test.obj der_tests.obj \ +dsa_test.obj ecc_test.obj mac_test.obj modes_test.obj pkcs_1_test.obj \ +rsa_test.obj store_test.obj test_driver.obj x86_prof.obj katja_test.obj + +tomcrypt_prof.lib: $(OBJECTS) + lib /out:tomcrypt_prof.lib $(OBJECTS) + + diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/testprof/makefile.shared b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/makefile.shared new file mode 100644 index 0000000000..b3abba5526 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/makefile.shared @@ -0,0 +1,24 @@ +CC=libtool --mode=compile gcc + +CFLAGS += -I../src/headers -I./ -Wall -W + +# ranlib tools +ifndef RANLIB + RANLIB=ranlib +endif + +OBJECTS = base64_test.o cipher_hash_test.o der_tests.o \ +dsa_test.o ecc_test.o mac_test.o modes_test.o pkcs_1_test.o rsa_test.o \ +store_test.o test_driver.o x86_prof.o katja_test.o + +ifndef LIBTEST + LIBTEST=libtomcrypt_prof.la +endif + +default: $(LIBTEST) + +$(LIBTEST): $(OBJECTS) + libtool --silent --mode=link gcc $(CFLAGS) `find . -type f | grep "[.]lo" | xargs` -o $@ -rpath $(LIBPATH) -version-info $(VERSION) + +install: $(LIBTEST) + libtool --silent --mode=install install -c $(LIBTEST) $(DESTDIR)$(LIBPATH)/$(LIBTEST) diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/testprof/modes_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/modes_test.c new file mode 100644 index 0000000000..475429b73e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/modes_test.c @@ -0,0 +1,119 @@ +/* test CFB/OFB/CBC modes */ +#include + +int modes_test(void) +{ + unsigned char pt[64], ct[64], tmp[64], key[16], iv[16], iv2[16]; + int cipher_idx; +#ifdef LTC_CBC_MODE + symmetric_CBC cbc; +#endif +#ifdef LTC_CFB_MODE + symmetric_CFB cfb; +#endif +#ifdef LTC_OFB_MODE + symmetric_OFB ofb; +#endif + unsigned long l; + + /* make a random pt, key and iv */ + yarrow_read(pt, 64, &yarrow_prng); + yarrow_read(key, 16, &yarrow_prng); + yarrow_read(iv, 16, &yarrow_prng); + + /* get idx of AES handy */ + cipher_idx = find_cipher("aes"); + if (cipher_idx == -1) { + fprintf(stderr, "test requires AES"); + return 1; + } + +#ifdef LTC_F8_MODE + DO(f8_test_mode()); +#endif + +#ifdef LTC_LRW_MODE + DO(lrw_test()); +#endif + +#ifdef LTC_CBC_MODE + /* test CBC mode */ + /* encode the block */ + DO(cbc_start(cipher_idx, iv, key, 16, 0, &cbc)); + l = sizeof(iv2); + DO(cbc_getiv(iv2, &l, &cbc)); + if (l != 16 || memcmp(iv2, iv, 16)) { + fprintf(stderr, "cbc_getiv failed"); + return 1; + } + DO(cbc_encrypt(pt, ct, 64, &cbc)); + + /* decode the block */ + DO(cbc_setiv(iv2, l, &cbc)); + zeromem(tmp, sizeof(tmp)); + DO(cbc_decrypt(ct, tmp, 64, &cbc)); + if (memcmp(tmp, pt, 64) != 0) { + fprintf(stderr, "CBC failed"); + return 1; + } +#endif + +#ifdef LTC_CFB_MODE + /* test CFB mode */ + /* encode the block */ + DO(cfb_start(cipher_idx, iv, key, 16, 0, &cfb)); + l = sizeof(iv2); + DO(cfb_getiv(iv2, &l, &cfb)); + /* note we don't memcmp iv2/iv since cfb_start processes the IV for the first block */ + if (l != 16) { + fprintf(stderr, "cfb_getiv failed"); + return 1; + } + DO(cfb_encrypt(pt, ct, 64, &cfb)); + + /* decode the block */ + DO(cfb_setiv(iv, l, &cfb)); + zeromem(tmp, sizeof(tmp)); + DO(cfb_decrypt(ct, tmp, 64, &cfb)); + if (memcmp(tmp, pt, 64) != 0) { + fprintf(stderr, "CFB failed"); + return 1; + } +#endif + +#ifdef LTC_OFB_MODE + /* test OFB mode */ + /* encode the block */ + DO(ofb_start(cipher_idx, iv, key, 16, 0, &ofb)); + l = sizeof(iv2); + DO(ofb_getiv(iv2, &l, &ofb)); + if (l != 16 || memcmp(iv2, iv, 16)) { + fprintf(stderr, "ofb_getiv failed"); + return 1; + } + DO(ofb_encrypt(pt, ct, 64, &ofb)); + + /* decode the block */ + DO(ofb_setiv(iv2, l, &ofb)); + zeromem(tmp, sizeof(tmp)); + DO(ofb_decrypt(ct, tmp, 64, &ofb)); + if (memcmp(tmp, pt, 64) != 0) { + fprintf(stderr, "OFB failed"); + return 1; + } +#endif + +#ifdef LTC_CTR_MODE + DO(ctr_test()); +#endif + +#ifdef LTC_XTS_MODE + DO(xts_test()); +#endif + + return 0; +} + +/* $Source: /cvs/libtom/libtomcrypt/testprof/modes_test.c,v $ */ +/* $Revision: 1.15 $ */ +/* $Date: 2007/02/16 16:36:25 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/testprof/pkcs_1_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/pkcs_1_test.c new file mode 100644 index 0000000000..f9279d8edc --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/pkcs_1_test.c @@ -0,0 +1,93 @@ +#include + +#ifdef LTC_PKCS_1 + +int pkcs_1_test(void) +{ + unsigned char buf[3][128]; + int res1, res2, res3, prng_idx, hash_idx, err; + unsigned long x, y, l1, l2, l3, i1, i2, lparamlen, saltlen, modlen; + static const unsigned char lparam[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; + + /* get hash/prng */ + hash_idx = find_hash("sha1"); + prng_idx = find_prng("yarrow"); + + if (hash_idx == -1 || prng_idx == -1) { + fprintf(stderr, "pkcs_1 tests require sha1/yarrow"); + return 1; + } + + srand(time(NULL)); + /* do many tests */ + for (x = 0; x < 100; x++) { + zeromem(buf, sizeof(buf)); + + /* make a dummy message (of random length) */ + l3 = (rand() & 31) + 8; + for (y = 0; y < l3; y++) buf[0][y] = rand() & 255; + + /* pick a random lparam len [0..16] */ + lparamlen = abs(rand()) % 17; + + /* pick a random saltlen 0..16 */ + saltlen = abs(rand()) % 17; + + /* LTC_PKCS #1 v2.0 supports modlens not multiple of 8 */ + modlen = 800 + (abs(rand()) % 224); + + /* encode it */ + l1 = sizeof(buf[1]); + DO(pkcs_1_oaep_encode(buf[0], l3, lparam, lparamlen, modlen, &yarrow_prng, prng_idx, hash_idx, buf[1], &l1)); + + /* decode it */ + l2 = sizeof(buf[2]); + DO(pkcs_1_oaep_decode(buf[1], l1, lparam, lparamlen, modlen, hash_idx, buf[2], &l2, &res1)); + + if (res1 != 1 || l2 != l3 || memcmp(buf[2], buf[0], l3) != 0) { + fprintf(stderr, "Outsize == %lu, should have been %lu, res1 = %d, lparamlen = %lu, msg contents follow.\n", l2, l3, res1, lparamlen); + fprintf(stderr, "ORIGINAL:\n"); + for (x = 0; x < l3; x++) { + fprintf(stderr, "%02x ", buf[0][x]); + } + fprintf(stderr, "\nRESULT:\n"); + for (x = 0; x < l2; x++) { + fprintf(stderr, "%02x ", buf[2][x]); + } + fprintf(stderr, "\n\n"); + return 1; + } + + /* test PSS */ + l1 = sizeof(buf[1]); + DO(pkcs_1_pss_encode(buf[0], l3, saltlen, &yarrow_prng, prng_idx, hash_idx, modlen, buf[1], &l1)); + DO(pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res1)); + + buf[0][i1 = abs(rand()) % l3] ^= 1; + DO(pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res2)); + + buf[0][i1] ^= 1; + buf[1][i2 = abs(rand()) % (l1 - 1)] ^= 1; + pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res3); + if (!(res1 == 1 && res2 == 0 && res3 == 0)) { + fprintf(stderr, "PSS failed: %d, %d, %d, %lu, %lu\n", res1, res2, res3, l3, saltlen); + return 1; + } + } + return 0; +} + +#else + +int pkcs_1_test(void) +{ + fprintf(stderr, "NOP"); + return 0; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/testprof/pkcs_1_test.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/testprof/rsa_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/rsa_test.c new file mode 100644 index 0000000000..a6f1316a32 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/rsa_test.c @@ -0,0 +1,387 @@ +#include + +#ifdef LTC_MRSA + +#define RSA_MSGSIZE 78 + +/* These are test keys [see file test.key] that I use to test my import/export against */ +static const unsigned char openssl_private_rsa[] = { + 0x30, 0x82, 0x02, 0x5e, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xcf, 0x9a, 0xde, 0x64, 0x8a, + 0xda, 0xc8, 0x33, 0x20, 0xa9, 0xd7, 0x83, 0x31, 0x19, 0x54, 0xb2, 0x9a, 0x85, 0xa7, 0xa1, 0xb7, + 0x75, 0x33, 0xb6, 0xa9, 0xac, 0x84, 0x24, 0xb3, 0xde, 0xdb, 0x7d, 0x85, 0x2d, 0x96, 0x65, 0xe5, + 0x3f, 0x72, 0x95, 0x24, 0x9f, 0x28, 0x68, 0xca, 0x4f, 0xdb, 0x44, 0x1c, 0x3e, 0x60, 0x12, 0x8a, + 0xdd, 0x26, 0xa5, 0xeb, 0xff, 0x0b, 0x5e, 0xd4, 0x88, 0x38, 0x49, 0x2a, 0x6e, 0x5b, 0xbf, 0x12, + 0x37, 0x47, 0xbd, 0x05, 0x6b, 0xbc, 0xdb, 0xf3, 0xee, 0xe4, 0x11, 0x8e, 0x41, 0x68, 0x7c, 0x61, + 0x13, 0xd7, 0x42, 0xc8, 0x80, 0xbe, 0x36, 0x8f, 0xdc, 0x08, 0x8b, 0x4f, 0xac, 0xa4, 0xe2, 0x76, + 0x0c, 0xc9, 0x63, 0x6c, 0x49, 0x58, 0x93, 0xed, 0xcc, 0xaa, 0xdc, 0x25, 0x3b, 0x0a, 0x60, 0x3f, + 0x8b, 0x54, 0x3a, 0xc3, 0x4d, 0x31, 0xe7, 0x94, 0xa4, 0x44, 0xfd, 0x02, 0x03, 0x01, 0x00, 0x01, + 0x02, 0x81, 0x81, 0x00, 0xc8, 0x62, 0xb9, 0xea, 0xde, 0x44, 0x53, 0x1d, 0x56, 0x97, 0xd9, 0x97, + 0x9e, 0x1a, 0xcf, 0x30, 0x1e, 0x0a, 0x88, 0x45, 0x86, 0x29, 0x30, 0xa3, 0x4d, 0x9f, 0x61, 0x65, + 0x73, 0xe0, 0xd6, 0x87, 0x8f, 0xb6, 0xf3, 0x06, 0xa3, 0x82, 0xdc, 0x7c, 0xac, 0xfe, 0x9b, 0x28, + 0x9a, 0xae, 0xfd, 0xfb, 0xfe, 0x2f, 0x0e, 0xd8, 0x97, 0x04, 0xe3, 0xbb, 0x1f, 0xd1, 0xec, 0x0d, + 0xba, 0xa3, 0x49, 0x7f, 0x47, 0xac, 0x8a, 0x44, 0x04, 0x7e, 0x86, 0xb7, 0x39, 0x42, 0x3f, 0xad, + 0x1e, 0xb7, 0x0e, 0xa5, 0x51, 0xf4, 0x40, 0x63, 0x1e, 0xfd, 0xbd, 0xea, 0x9f, 0x41, 0x9f, 0xa8, + 0x90, 0x1d, 0x6f, 0x0a, 0x5a, 0x95, 0x13, 0x11, 0x0d, 0x80, 0xaf, 0x5f, 0x64, 0x98, 0x8a, 0x2c, + 0x78, 0x68, 0x65, 0xb0, 0x2b, 0x8b, 0xa2, 0x53, 0x87, 0xca, 0xf1, 0x64, 0x04, 0xab, 0xf2, 0x7b, + 0xdb, 0x83, 0xc8, 0x81, 0x02, 0x41, 0x00, 0xf7, 0xbe, 0x5e, 0x23, 0xc3, 0x32, 0x3f, 0xbf, 0x8b, + 0x8e, 0x3a, 0xee, 0xfc, 0xfc, 0xcb, 0xe5, 0xf7, 0xf1, 0x0b, 0xbc, 0x42, 0x82, 0xae, 0xd5, 0x7a, + 0x3e, 0xca, 0xf7, 0xd5, 0x69, 0x3f, 0x64, 0x25, 0xa2, 0x1f, 0xb7, 0x75, 0x75, 0x05, 0x92, 0x42, + 0xeb, 0xb8, 0xf1, 0xf3, 0x0a, 0x05, 0xe3, 0x94, 0xd1, 0x55, 0x78, 0x35, 0xa0, 0x36, 0xa0, 0x9b, + 0x7c, 0x92, 0x84, 0x6c, 0xdd, 0xdc, 0x4d, 0x02, 0x41, 0x00, 0xd6, 0x86, 0x0e, 0x85, 0x42, 0x0b, + 0x04, 0x08, 0x84, 0x21, 0x60, 0xf0, 0x0e, 0x0d, 0x88, 0xfd, 0x1e, 0x36, 0x10, 0x65, 0x4f, 0x1e, + 0x53, 0xb4, 0x08, 0x72, 0x80, 0x5c, 0x3f, 0x59, 0x66, 0x17, 0xe6, 0x98, 0xf2, 0xe9, 0x6c, 0x7a, + 0x06, 0x4c, 0xac, 0x76, 0x3d, 0xed, 0x8c, 0xa1, 0xce, 0xad, 0x1b, 0xbd, 0xb4, 0x7d, 0x28, 0xbc, + 0xe3, 0x0e, 0x38, 0x8d, 0x99, 0xd8, 0x05, 0xb5, 0xa3, 0x71, 0x02, 0x40, 0x6d, 0xeb, 0xc3, 0x2d, + 0x2e, 0xf0, 0x5e, 0xa4, 0x88, 0x31, 0x05, 0x29, 0x00, 0x8a, 0xd1, 0x95, 0x29, 0x9b, 0x83, 0xcf, + 0x75, 0xdb, 0x31, 0xe3, 0x7a, 0x27, 0xde, 0x3a, 0x74, 0x30, 0x0c, 0x76, 0x4c, 0xd4, 0x50, 0x2a, + 0x40, 0x2d, 0x39, 0xd9, 0x99, 0x63, 0xa9, 0x5d, 0x80, 0xae, 0x53, 0xca, 0x94, 0x3f, 0x05, 0x23, + 0x1e, 0xf8, 0x05, 0x04, 0xe1, 0xb8, 0x35, 0xf2, 0x17, 0xb3, 0xa0, 0x89, 0x02, 0x41, 0x00, 0xab, + 0x90, 0x88, 0xfa, 0x60, 0x08, 0x29, 0x50, 0x9a, 0x43, 0x8b, 0xa0, 0x50, 0xcc, 0xd8, 0x5a, 0xfe, + 0x97, 0x64, 0x63, 0x71, 0x74, 0x22, 0xa3, 0x20, 0x02, 0x5a, 0xcf, 0xeb, 0xc6, 0x16, 0x95, 0x54, + 0xd1, 0xcb, 0xab, 0x8d, 0x1a, 0xc6, 0x00, 0xfa, 0x08, 0x92, 0x9c, 0x71, 0xd5, 0x52, 0x52, 0x35, + 0x96, 0x71, 0x4b, 0x8b, 0x92, 0x0c, 0xd0, 0xe9, 0xbf, 0xad, 0x63, 0x0b, 0xa5, 0xe9, 0xb1, 0x02, + 0x41, 0x00, 0xdc, 0xcc, 0x27, 0xc8, 0xe4, 0xdc, 0x62, 0x48, 0xd5, 0x9b, 0xaf, 0xf5, 0xab, 0x60, + 0xf6, 0x21, 0xfd, 0x53, 0xe2, 0xb7, 0x5d, 0x09, 0xc9, 0x1a, 0xa1, 0x04, 0xa9, 0xfc, 0x61, 0x2c, + 0x5d, 0x04, 0x58, 0x3a, 0x5a, 0x39, 0xf1, 0x4a, 0x21, 0x56, 0x67, 0xfd, 0xcc, 0x20, 0xa3, 0x8f, + 0x78, 0x18, 0x5a, 0x79, 0x3d, 0x2e, 0x8e, 0x7e, 0x86, 0x0a, 0xe6, 0xa8, 0x33, 0xc1, 0x04, 0x17, + 0x4a, 0x9f, }; + + +/*** openssl public RSA key in DER format */ +static const unsigned char openssl_public_rsa[] = { + 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, + 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xcf, 0x9a, 0xde, + 0x64, 0x8a, 0xda, 0xc8, 0x33, 0x20, 0xa9, 0xd7, 0x83, 0x31, 0x19, 0x54, 0xb2, 0x9a, 0x85, 0xa7, + 0xa1, 0xb7, 0x75, 0x33, 0xb6, 0xa9, 0xac, 0x84, 0x24, 0xb3, 0xde, 0xdb, 0x7d, 0x85, 0x2d, 0x96, + 0x65, 0xe5, 0x3f, 0x72, 0x95, 0x24, 0x9f, 0x28, 0x68, 0xca, 0x4f, 0xdb, 0x44, 0x1c, 0x3e, 0x60, + 0x12, 0x8a, 0xdd, 0x26, 0xa5, 0xeb, 0xff, 0x0b, 0x5e, 0xd4, 0x88, 0x38, 0x49, 0x2a, 0x6e, 0x5b, + 0xbf, 0x12, 0x37, 0x47, 0xbd, 0x05, 0x6b, 0xbc, 0xdb, 0xf3, 0xee, 0xe4, 0x11, 0x8e, 0x41, 0x68, + 0x7c, 0x61, 0x13, 0xd7, 0x42, 0xc8, 0x80, 0xbe, 0x36, 0x8f, 0xdc, 0x08, 0x8b, 0x4f, 0xac, 0xa4, + 0xe2, 0x76, 0x0c, 0xc9, 0x63, 0x6c, 0x49, 0x58, 0x93, 0xed, 0xcc, 0xaa, 0xdc, 0x25, 0x3b, 0x0a, + 0x60, 0x3f, 0x8b, 0x54, 0x3a, 0xc3, 0x4d, 0x31, 0xe7, 0x94, 0xa4, 0x44, 0xfd, 0x02, 0x03, 0x01, + 0x00, 0x01, }; + +/* same key but with extra headers stripped */ +static const unsigned char openssl_public_rsa_stripped[] = { + 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xcf, 0x9a, 0xde, + 0x64, 0x8a, 0xda, 0xc8, 0x33, 0x20, 0xa9, 0xd7, 0x83, 0x31, 0x19, 0x54, 0xb2, 0x9a, 0x85, 0xa7, + 0xa1, 0xb7, 0x75, 0x33, 0xb6, 0xa9, 0xac, 0x84, 0x24, 0xb3, 0xde, 0xdb, 0x7d, 0x85, 0x2d, 0x96, + 0x65, 0xe5, 0x3f, 0x72, 0x95, 0x24, 0x9f, 0x28, 0x68, 0xca, 0x4f, 0xdb, 0x44, 0x1c, 0x3e, 0x60, + 0x12, 0x8a, 0xdd, 0x26, 0xa5, 0xeb, 0xff, 0x0b, 0x5e, 0xd4, 0x88, 0x38, 0x49, 0x2a, 0x6e, 0x5b, + 0xbf, 0x12, 0x37, 0x47, 0xbd, 0x05, 0x6b, 0xbc, 0xdb, 0xf3, 0xee, 0xe4, 0x11, 0x8e, 0x41, 0x68, + 0x7c, 0x61, 0x13, 0xd7, 0x42, 0xc8, 0x80, 0xbe, 0x36, 0x8f, 0xdc, 0x08, 0x8b, 0x4f, 0xac, 0xa4, + 0xe2, 0x76, 0x0c, 0xc9, 0x63, 0x6c, 0x49, 0x58, 0x93, 0xed, 0xcc, 0xaa, 0xdc, 0x25, 0x3b, 0x0a, + 0x60, 0x3f, 0x8b, 0x54, 0x3a, 0xc3, 0x4d, 0x31, 0xe7, 0x94, 0xa4, 0x44, 0xfd, 0x02, 0x03, 0x01, + 0x00, 0x01, }; + +static int rsa_compat_test(void) +{ + rsa_key key; + unsigned char buf[1024]; + unsigned long len; + + /* try reading the key */ + DO(rsa_import(openssl_private_rsa, sizeof(openssl_private_rsa), &key)); + + /* now try to export private/public and compare */ + len = sizeof(buf); + DO(rsa_export(buf, &len, PK_PRIVATE, &key)); + if (len != sizeof(openssl_private_rsa) || memcmp(buf, openssl_private_rsa, len)) { + fprintf(stderr, "RSA private export failed to match OpenSSL output, %lu, %lu\n", len, (unsigned long)sizeof(openssl_private_rsa)); + return 1; + } + + len = sizeof(buf); + DO(rsa_export(buf, &len, PK_PUBLIC, &key)); + if (len != sizeof(openssl_public_rsa_stripped) || memcmp(buf, openssl_public_rsa_stripped, len)) { + fprintf(stderr, "RSA(private) public export failed to match OpenSSL output\n"); + return 1; + } + rsa_free(&key); + + /* try reading the public key */ + DO(rsa_import(openssl_public_rsa_stripped, sizeof(openssl_public_rsa_stripped), &key)); + len = sizeof(buf); + DO(rsa_export(buf, &len, PK_PUBLIC, &key)); + if (len != sizeof(openssl_public_rsa_stripped) || memcmp(buf, openssl_public_rsa_stripped, len)) { + fprintf(stderr, "RSA(public) stripped public import failed to match OpenSSL output\n"); + return 1; + } + rsa_free(&key); + + /* try reading the public key */ + DO(rsa_import(openssl_public_rsa, sizeof(openssl_public_rsa), &key)); + len = sizeof(buf); + DO(rsa_export(buf, &len, PK_PUBLIC, &key)); + if (len != sizeof(openssl_public_rsa_stripped) || memcmp(buf, openssl_public_rsa_stripped, len)) { + fprintf(stderr, "RSA(public) SSL public import failed to match OpenSSL output\n"); + return 1; + } + rsa_free(&key); + + return 0; +} + +int rsa_test(void) +{ + unsigned char in[1024], out[1024], tmp[1024]; + rsa_key key, privKey, pubKey; + int hash_idx, prng_idx, stat, stat2; + unsigned long rsa_msgsize, len, len2, cnt; + static unsigned char lparam[] = { 0x01, 0x02, 0x03, 0x04 }; + + if (rsa_compat_test() != 0) { + return 1; + } + + hash_idx = find_hash("sha1"); + prng_idx = find_prng("yarrow"); + if (hash_idx == -1 || prng_idx == -1) { + fprintf(stderr, "rsa_test requires LTC_SHA1 and yarrow"); + return 1; + } + + /* make 10 random key */ + for (cnt = 0; cnt < 10; cnt++) { + DO(rsa_make_key(&yarrow_prng, prng_idx, 1024/8, 65537, &key)); + if (mp_count_bits(key.N) != 1024) { + fprintf(stderr, "rsa_1024 key modulus has %d bits\n", mp_count_bits(key.N)); + +len = mp_unsigned_bin_size(key.N); +mp_to_unsigned_bin(key.N, tmp); + fprintf(stderr, "N == \n"); +for (cnt = 0; cnt < len; ) { + fprintf(stderr, "%02x ", tmp[cnt]); + if (!(++cnt & 15)) fprintf(stderr, "\n"); +} + +len = mp_unsigned_bin_size(key.p); +mp_to_unsigned_bin(key.p, tmp); + fprintf(stderr, "p == \n"); +for (cnt = 0; cnt < len; ) { + fprintf(stderr, "%02x ", tmp[cnt]); + if (!(++cnt & 15)) fprintf(stderr, "\n"); +} + +len = mp_unsigned_bin_size(key.q); +mp_to_unsigned_bin(key.q, tmp); + fprintf(stderr, "\nq == \n"); +for (cnt = 0; cnt < len; ) { + fprintf(stderr, "%02x ", tmp[cnt]); + if (!(++cnt & 15)) fprintf(stderr, "\n"); +} + fprintf(stderr, "\n"); + + + return 1; + } + if (cnt != 9) { + rsa_free(&key); + } + } + + /* encrypt the key (without lparam) */ + for (cnt = 0; cnt < 4; cnt++) { + for (rsa_msgsize = 1; rsa_msgsize <= 86; rsa_msgsize++) { + /* make a random key/msg */ + yarrow_read(in, rsa_msgsize, &yarrow_prng); + + len = sizeof(out); + len2 = rsa_msgsize; + + DO(rsa_encrypt_key(in, rsa_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, hash_idx, &key)); + /* change a byte */ + out[8] ^= 1; + DO(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, hash_idx, &stat2, &key)); + /* change a byte back */ + out[8] ^= 1; + if (len2 != rsa_msgsize) { + fprintf(stderr, "\nrsa_decrypt_key mismatch len %lu (first decrypt)", len2); + return 1; + } + + len2 = rsa_msgsize; + DO(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, hash_idx, &stat, &key)); + if (!(stat == 1 && stat2 == 0)) { + fprintf(stderr, "rsa_decrypt_key failed"); + return 1; + } + if (len2 != rsa_msgsize || memcmp(tmp, in, rsa_msgsize)) { + unsigned long x; + fprintf(stderr, "\nrsa_decrypt_key mismatch, len %lu (second decrypt)\n", len2); + fprintf(stderr, "Original contents: \n"); + for (x = 0; x < rsa_msgsize; ) { + fprintf(stderr, "%02x ", in[x]); + if (!(++x % 16)) { + fprintf(stderr, "\n"); + } + } + fprintf(stderr, "\n"); + fprintf(stderr, "Output contents: \n"); + for (x = 0; x < rsa_msgsize; ) { + fprintf(stderr, "%02x ", out[x]); + if (!(++x % 16)) { + fprintf(stderr, "\n"); + } + } + fprintf(stderr, "\n"); + return 1; + } + } + } + + /* encrypt the key (with lparam) */ + for (rsa_msgsize = 1; rsa_msgsize <= 86; rsa_msgsize++) { + len = sizeof(out); + len2 = rsa_msgsize; + DO(rsa_encrypt_key(in, rsa_msgsize, out, &len, lparam, sizeof(lparam), &yarrow_prng, prng_idx, hash_idx, &key)); + /* change a byte */ + out[8] ^= 1; + DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), hash_idx, &stat2, &key)); + if (len2 != rsa_msgsize) { + fprintf(stderr, "\nrsa_decrypt_key mismatch len %lu (first decrypt)", len2); + return 1; + } + /* change a byte back */ + out[8] ^= 1; + + len2 = rsa_msgsize; + DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), hash_idx, &stat, &key)); + if (!(stat == 1 && stat2 == 0)) { + fprintf(stderr, "rsa_decrypt_key failed"); + return 1; + } + if (len2 != rsa_msgsize || memcmp(tmp, in, rsa_msgsize)) { + fprintf(stderr, "rsa_decrypt_key mismatch len %lu", len2); + return 1; + } + } + + /* encrypt the key LTC_PKCS #1 v1.5 (payload from 1 to 117 bytes) */ + for (rsa_msgsize = 1; rsa_msgsize <= 117; rsa_msgsize++) { + len = sizeof(out); + len2 = rsa_msgsize; + DO(rsa_encrypt_key_ex(in, rsa_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, 0, LTC_LTC_PKCS_1_V1_5, &key)); + + len2 = rsa_msgsize; + DO(rsa_decrypt_key_ex(out, len, tmp, &len2, NULL, 0, 0, LTC_LTC_PKCS_1_V1_5, &stat, &key)); + if (!(stat == 1 && stat2 == 0)) { + fprintf(stderr, "rsa_decrypt_key_ex failed, %d, %d", stat, stat2); + return 1; + } + if (len2 != rsa_msgsize || memcmp(tmp, in, rsa_msgsize)) { + fprintf(stderr, "rsa_decrypt_key_ex mismatch len %lu", len2); + return 1; + } + } + + /* sign a message (unsalted, lower cholestorol and Atkins approved) now */ + len = sizeof(out); + DO(rsa_sign_hash(in, 20, out, &len, &yarrow_prng, prng_idx, hash_idx, 0, &key)); + +/* export key and import as both private and public */ + len2 = sizeof(tmp); + DO(rsa_export(tmp, &len2, PK_PRIVATE, &key)); + DO(rsa_import(tmp, len2, &privKey)); + len2 = sizeof(tmp); + DO(rsa_export(tmp, &len2, PK_PUBLIC, &key)); + DO(rsa_import(tmp, len2, &pubKey)); + + /* verify with original */ + DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &key)); + /* change a byte */ + in[0] ^= 1; + DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &key)); + + if (!(stat == 1 && stat2 == 0)) { + fprintf(stderr, "rsa_verify_hash (unsalted, origKey) failed, %d, %d", stat, stat2); + rsa_free(&key); + rsa_free(&pubKey); + rsa_free(&privKey); + return 1; + } + + /* verify with privKey */ + /* change a byte */ + in[0] ^= 1; + DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &privKey)); + /* change a byte */ + in[0] ^= 1; + DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &privKey)); + + if (!(stat == 1 && stat2 == 0)) { + fprintf(stderr, "rsa_verify_hash (unsalted, privKey) failed, %d, %d", stat, stat2); + rsa_free(&key); + rsa_free(&pubKey); + rsa_free(&privKey); + return 1; + } + + /* verify with pubKey */ + /* change a byte */ + in[0] ^= 1; + DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &pubKey)); + /* change a byte */ + in[0] ^= 1; + DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &pubKey)); + + if (!(stat == 1 && stat2 == 0)) { + fprintf(stderr, "rsa_verify_hash (unsalted, pubkey) failed, %d, %d", stat, stat2); + rsa_free(&key); + rsa_free(&pubKey); + rsa_free(&privKey); + return 1; + } + + /* sign a message (salted) now (use privKey to make, pubKey to verify) */ + len = sizeof(out); + DO(rsa_sign_hash(in, 20, out, &len, &yarrow_prng, prng_idx, hash_idx, 8, &privKey)); + DO(rsa_verify_hash(out, len, in, 20, hash_idx, 8, &stat, &pubKey)); + /* change a byte */ + in[0] ^= 1; + DO(rsa_verify_hash(out, len, in, 20, hash_idx, 8, &stat2, &pubKey)); + + if (!(stat == 1 && stat2 == 0)) { + fprintf(stderr, "rsa_verify_hash (salted) failed, %d, %d", stat, stat2); + rsa_free(&key); + rsa_free(&pubKey); + rsa_free(&privKey); + return 1; + } + + /* sign a message with LTC_PKCS #1 v1.5 */ + len = sizeof(out); + DO(rsa_sign_hash_ex(in, 20, out, &len, LTC_LTC_PKCS_1_V1_5, &yarrow_prng, prng_idx, hash_idx, 8, &privKey)); + DO(rsa_verify_hash_ex(out, len, in, 20, LTC_LTC_PKCS_1_V1_5, hash_idx, 8, &stat, &pubKey)); + /* change a byte */ + in[0] ^= 1; + DO(rsa_verify_hash_ex(out, len, in, 20, LTC_LTC_PKCS_1_V1_5, hash_idx, 8, &stat2, &pubKey)); + + if (!(stat == 1 && stat2 == 0)) { + fprintf(stderr, "rsa_verify_hash_ex failed, %d, %d", stat, stat2); + rsa_free(&key); + rsa_free(&pubKey); + rsa_free(&privKey); + return 1; + } + + /* free the key and return */ + rsa_free(&key); + rsa_free(&pubKey); + rsa_free(&privKey); + return 0; +} + +#else + +int rsa_test(void) +{ + fprintf(stderr, "NOP"); + return 0; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/testprof/rsa_test.c,v $ */ +/* $Revision: 1.20 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/testprof/store_test.c b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/store_test.c new file mode 100644 index 0000000000..5a38d65082 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/store_test.c @@ -0,0 +1,78 @@ +#include + +/* Test store/load macros with offsets */ +int store_test(void) +{ + unsigned char buf[256]; + int y; + ulong32 L, L1; + ulong64 LL, LL1; +#ifdef LTC_FAST + int x, z; +#endif + + for (y = 0; y < 4; y++) { + L = 0x12345678UL; + L1 = 0; + STORE32L(L, buf + y); + LOAD32L(L1, buf + y); + if (L1 != L) { + fprintf(stderr, "\n32L failed at offset %d\n", y); + return 1; + } + STORE32H(L, buf + y); + LOAD32H(L1, buf + y); + if (L1 != L) { + fprintf(stderr, "\n32H failed at offset %d\n", y); + return 1; + } + } + + for (y = 0; y < 8; y++) { + LL = CONST64 (0x01020304050607); + LL1 = 0; + STORE64L(LL, buf + y); + LOAD64L(LL1, buf + y); + if (LL1 != LL) { + fprintf(stderr, "\n64L failed at offset %d\n", y); + return 1; + } + STORE64H(LL, buf + y); + LOAD64H(LL1, buf + y); + if (LL1 != LL) { + fprintf(stderr, "\n64H failed at offset %d\n", y); + return 1; + } + } + +/* test LTC_FAST */ +#ifdef LTC_FAST + y = 16; + + for (z = 0; z < y; z++) { + /* fill y bytes with random */ + yarrow_read(buf+z, y, &yarrow_prng); + yarrow_read(buf+z+y, y, &yarrow_prng); + + /* now XOR it byte for byte */ + for (x = 0; x < y; x++) { + buf[2*y+z+x] = buf[z+x] ^ buf[z+y+x]; + } + + /* now XOR it word for word */ + for (x = 0; x < y; x += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)(&buf[3*y+z+x])) = *((LTC_FAST_TYPE*)(&buf[z+x])) ^ *((LTC_FAST_TYPE*)(&buf[z+y+x])); + } + + if (memcmp(&buf[2*y+z], &buf[3*y+z], y)) { + fprintf(stderr, "\nLTC_FAST failed at offset %d\n", z); + return 1; + } + } +#endif + return 0; +} + +/* $Source: /cvs/libtom/libtomcrypt/testprof/store_test.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2005/05/05 14:35:59 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/testprof/test.der b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/test.der new file mode 100644 index 0000000000..d7041f9bae Binary files /dev/null and b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/test.der differ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/testprof/test.key b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/test.key new file mode 100644 index 0000000000..e4996c35cc --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/test.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXgIBAAKBgQDPmt5kitrIMyCp14MxGVSymoWnobd1M7aprIQks97bfYUtlmXl +P3KVJJ8oaMpP20QcPmASit0mpev/C17UiDhJKm5bvxI3R70Fa7zb8+7kEY5BaHxh +E9dCyIC+No/cCItPrKTidgzJY2xJWJPtzKrcJTsKYD+LVDrDTTHnlKRE/QIDAQAB +AoGBAMhiuereRFMdVpfZl54azzAeCohFhikwo02fYWVz4NaHj7bzBqOC3Hys/pso +mq79+/4vDtiXBOO7H9HsDbqjSX9HrIpEBH6GtzlCP60etw6lUfRAYx79veqfQZ+o +kB1vClqVExENgK9fZJiKLHhoZbAri6JTh8rxZASr8nvbg8iBAkEA975eI8MyP7+L +jjru/PzL5ffxC7xCgq7Vej7K99VpP2Qloh+3dXUFkkLruPHzCgXjlNFVeDWgNqCb +fJKEbN3cTQJBANaGDoVCCwQIhCFg8A4NiP0eNhBlTx5TtAhygFw/WWYX5pjy6Wx6 +Bkysdj3tjKHOrRu9tH0ovOMOOI2Z2AW1o3ECQG3rwy0u8F6kiDEFKQCK0ZUpm4PP +ddsx43on3jp0MAx2TNRQKkAtOdmZY6ldgK5TypQ/BSMe+AUE4bg18hezoIkCQQCr +kIj6YAgpUJpDi6BQzNha/pdkY3F0IqMgAlrP68YWlVTRy6uNGsYA+giSnHHVUlI1 +lnFLi5IM0Om/rWMLpemxAkEA3MwnyOTcYkjVm6/1q2D2If1T4rddCckaoQSp/GEs +XQRYOlo58UohVmf9zCCjj3gYWnk9Lo5+hgrmqDPBBBdKnw== +-----END RSA PRIVATE KEY----- diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/testprof/test_driver.c b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/test_driver.c new file mode 100644 index 0000000000..25740a0398 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/test_driver.c @@ -0,0 +1,15 @@ +#include + +void run_cmd(int res, int line, char *file, char *cmd) +{ + if (res != CRYPT_OK) { + fprintf(stderr, "%s (%d)\n%s:%d:%s\n", error_to_string(res), res, file, line, cmd); + if (res != CRYPT_NOP) { + exit(EXIT_FAILURE); + } + } +} + +/* $Source: /cvs/libtom/libtomcrypt/testprof/test_driver.c,v $ */ +/* $Revision: 1.2 $ */ +/* $Date: 2006/11/13 23:14:33 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/testprof/tomcrypt_test.h b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/tomcrypt_test.h new file mode 100644 index 0000000000..b4396fba96 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/tomcrypt_test.h @@ -0,0 +1,83 @@ + +#ifndef __TEST_H_ +#define __TEST_H_ + +#include + +/* enable stack testing */ +/* #define STACK_TEST */ + +/* stack testing, define this if stack usage goes downwards [e.g. x86] */ +#define STACK_DOWN + +typedef struct { + char *name, *prov, *req; + int (*entry)(void); +} test_entry; + +extern prng_state yarrow_prng; + +void run_cmd(int res, int line, char *file, char *cmd); + +#ifdef LTC_VERBOSE +#define DO(x) do { fprintf(stderr, "%s:\n", #x); run_cmd((x), __LINE__, __FILE__, #x); } while (0); +#else +#define DO(x) do { run_cmd((x), __LINE__, __FILE__, #x); } while (0); +#endif + +/* TESTS */ +int cipher_hash_test(void); +int modes_test(void); +int mac_test(void); +int pkcs_1_test(void); +int store_test(void); +int rsa_test(void); +int katja_test(void); +int ecc_tests(void); +int dsa_test(void); +int der_tests(void); + +/* timing */ +#define KTIMES 25 +#define TIMES 100000 + +extern struct list { + int id; + unsigned long spd1, spd2, avg; +} results[]; + +extern int no_results; + +int sorter(const void *a, const void *b); +void tally_results(int type); +ulong64 rdtsc (void); + +void t_start(void); +ulong64 t_read(void); +void init_timer(void); + +/* register default algs */ +void reg_algs(void); +int time_keysched(void); +int time_cipher(void); +int time_cipher2(void); +int time_cipher3(void); +int time_hash(void); +void time_mult(void); +void time_sqr(void); +void time_prng(void); +void time_rsa(void); +void time_dsa(void); +void time_katja(void); +void time_ecc(void); +void time_macs_(unsigned long MAC_SIZE); +void time_macs(void); +void time_encmacs(void); + + + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/testprof/tomcrypt_test.h,v $ */ +/* $Revision: 1.14 $ */ +/* $Date: 2006/10/18 03:36:34 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/testprof/x86_prof.c b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/x86_prof.c new file mode 100644 index 0000000000..593e685f82 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/testprof/x86_prof.c @@ -0,0 +1,1439 @@ +#include + +prng_state yarrow_prng; + +struct list results[100]; +int no_results; +int sorter(const void *a, const void *b) +{ + const struct list *A, *B; + A = a; + B = b; + if (A->avg < B->avg) return -1; + if (A->avg > B->avg) return 1; + return 0; +} + +void tally_results(int type) +{ + int x; + + /* qsort the results */ + qsort(results, no_results, sizeof(struct list), &sorter); + + fprintf(stderr, "\n"); + if (type == 0) { + for (x = 0; x < no_results; x++) { + fprintf(stderr, "%-20s: Schedule at %6lu\n", cipher_descriptor[results[x].id].name, (unsigned long)results[x].spd1); + } + } else if (type == 1) { + for (x = 0; x < no_results; x++) { + printf + ("%-20s[%3d]: Encrypt at %5lu, Decrypt at %5lu\n", cipher_descriptor[results[x].id].name, cipher_descriptor[results[x].id].ID, results[x].spd1, results[x].spd2); + } + } else { + for (x = 0; x < no_results; x++) { + printf + ("%-20s: Process at %5lu\n", hash_descriptor[results[x].id].name, results[x].spd1 / 1000); + } + } +} + +/* RDTSC from Scott Duplichan */ +ulong64 rdtsc (void) + { + #if defined __GNUC__ && !defined(LTC_NO_ASM) + #ifdef INTEL_CC + ulong64 a; + asm ( " rdtsc ":"=A"(a)); + return a; + #elif defined(__i386__) || defined(__x86_64__) + ulong64 a; + asm __volatile__ ("rdtsc\nmovl %%eax,(%0)\nmovl %%edx,4(%0)\n"::"r"(&a):"%eax","%edx"); + return a; + #elif defined(LTC_PPC32) || defined(TFM_PPC32) + unsigned long a, b; + __asm__ __volatile__ ("mftbu %1 \nmftb %0\n":"=r"(a), "=r"(b)); + return (((ulong64)b) << 32ULL) | ((ulong64)a); + #elif defined(__ia64__) /* gcc-IA64 version */ + unsigned long result; + __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory"); + while (__builtin_expect ((int) result == -1, 0)) + __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory"); + return result; + #elif defined(__sparc__) + #if defined(__arch64__) + ulong64 a; + asm volatile("rd %%tick,%0" : "=r" (a)); + return a; + #else + register unsigned long x, y; + __asm__ __volatile__ ("rd %%tick, %0; clruw %0, %1; srlx %0, 32, %0" : "=r" (x), "=r" (y) : "0" (x), "1" (y)); + return ((unsigned long long) x << 32) | y; + #endif + #else + return XCLOCK(); + #endif + + /* Microsoft and Intel Windows compilers */ + #elif defined _M_IX86 && !defined(LTC_NO_ASM) + __asm rdtsc + #elif defined _M_AMD64 && !defined(LTC_NO_ASM) + return __rdtsc (); + #elif defined _M_IA64 && !defined(LTC_NO_ASM) + #if defined __INTEL_COMPILER + #include + #endif + return __getReg (3116); + #else + return XCLOCK(); + #endif + } + +static ulong64 timer, skew = 0; + +void t_start(void) +{ + timer = rdtsc(); +} + +ulong64 t_read(void) +{ + return rdtsc() - timer; +} + +void init_timer(void) +{ + ulong64 c1, c2, t1, t2, t3; + unsigned long y1; + + c1 = c2 = (ulong64)-1; + for (y1 = 0; y1 < TIMES*100; y1++) { + t_start(); + t1 = t_read(); + t3 = t_read(); + t2 = (t_read() - t1)>>1; + + c1 = (t1 > c1) ? t1 : c1; + c2 = (t2 > c2) ? t2 : c2; + } + skew = c2 - c1; + fprintf(stderr, "Clock Skew: %lu\n", (unsigned long)skew); +} + +void reg_algs(void) +{ + int err; +#ifdef LTC_RIJNDAEL + register_cipher (&aes_desc); +#endif +#ifdef LTC_BLOWFISH + register_cipher (&blowfish_desc); +#endif +#ifdef LTC_XTEA + register_cipher (&xtea_desc); +#endif +#ifdef LTC_RC5 + register_cipher (&rc5_desc); +#endif +#ifdef LTC_RC6 + register_cipher (&rc6_desc); +#endif +#ifdef LTC_SAFERP + register_cipher (&saferp_desc); +#endif +#ifdef LTC_TWOFISH + register_cipher (&twofish_desc); +#endif +#ifdef LTC_SAFER + register_cipher (&safer_k64_desc); + register_cipher (&safer_sk64_desc); + register_cipher (&safer_k128_desc); + register_cipher (&safer_sk128_desc); +#endif +#ifdef LTC_RC2 + register_cipher (&rc2_desc); +#endif +#ifdef LTC_DES + register_cipher (&des_desc); + register_cipher (&des3_desc); +#endif +#ifdef LTC_CAST5 + register_cipher (&cast5_desc); +#endif +#ifdef LTC_NOEKEON + register_cipher (&noekeon_desc); +#endif +#ifdef LTC_SKIPJACK + register_cipher (&skipjack_desc); +#endif +#ifdef LTC_KHAZAD + register_cipher (&khazad_desc); +#endif +#ifdef LTC_ANUBIS + register_cipher (&anubis_desc); +#endif +#ifdef LTC_KSEED + register_cipher (&kseed_desc); +#endif +#ifdef LTC_KASUMI + register_cipher (&kasumi_desc); +#endif +#ifdef LTC_MULTI2 + register_cipher (&multi2_desc); +#endif + +#ifdef LTC_TIGER + register_hash (&tiger_desc); +#endif +#ifdef LTC_MD2 + register_hash (&md2_desc); +#endif +#ifdef LTC_MD4 + register_hash (&md4_desc); +#endif +#ifdef LTC_MD5 + register_hash (&md5_desc); +#endif +#ifdef LTC_SHA1 + register_hash (&sha1_desc); +#endif +#ifdef LTC_SHA224 + register_hash (&sha224_desc); +#endif +#ifdef LTC_SHA256 + register_hash (&sha256_desc); +#endif +#ifdef LTC_SHA384 + register_hash (&sha384_desc); +#endif +#ifdef LTC_SHA512 + register_hash (&sha512_desc); +#endif +#ifdef LTC_RIPEMD128 + register_hash (&rmd128_desc); +#endif +#ifdef LTC_RIPEMD160 + register_hash (&rmd160_desc); +#endif +#ifdef LTC_RIPEMD256 + register_hash (&rmd256_desc); +#endif +#ifdef LTC_RIPEMD320 + register_hash (&rmd320_desc); +#endif +#ifdef LTC_WHIRLPOOL + register_hash (&whirlpool_desc); +#endif +#ifdef LTC_CHC_HASH + register_hash(&chc_desc); + if ((err = chc_register(register_cipher(&aes_desc))) != CRYPT_OK) { + fprintf(stderr, "chc_register error: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } +#endif + + +#ifndef LTC_YARROW + #error This demo requires Yarrow. +#endif +register_prng(&yarrow_desc); +#ifdef LTC_FORTUNA +register_prng(&fortuna_desc); +#endif +#ifdef LTC_RC4 +register_prng(&rc4_desc); +#endif +#ifdef LTC_SOBER128 +register_prng(&sober128_desc); +#endif + + if ((err = rng_make_prng(128, find_prng("yarrow"), &yarrow_prng, NULL)) != CRYPT_OK) { + fprintf(stderr, "rng_make_prng failed: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + +} + +int time_keysched(void) +{ + unsigned long x, y1; + ulong64 t1, c1; + symmetric_key skey; + int kl; + int (*func) (const unsigned char *, int , int , symmetric_key *); + unsigned char key[MAXBLOCKSIZE]; + + fprintf(stderr, "\n\nKey Schedule Time Trials for the Symmetric Ciphers:\n(Times are cycles per key)\n"); + no_results = 0; + for (x = 0; cipher_descriptor[x].name != NULL; x++) { +#define DO1(k) func(k, kl, 0, &skey); + + func = cipher_descriptor[x].setup; + kl = cipher_descriptor[x].min_key_length; + c1 = (ulong64)-1; + for (y1 = 0; y1 < KTIMES; y1++) { + yarrow_read(key, kl, &yarrow_prng); + t_start(); + DO1(key); + t1 = t_read(); + c1 = (t1 > c1) ? c1 : t1; + } + t1 = c1 - skew; + results[no_results].spd1 = results[no_results].avg = t1; + results[no_results++].id = x; + fprintf(stderr, "."); fflush(stdout); + +#undef DO1 + } + tally_results(0); + + return 0; +} + +int time_cipher(void) +{ + unsigned long x, y1; + ulong64 t1, t2, c1, c2, a1, a2; + symmetric_ECB ecb; + unsigned char key[MAXBLOCKSIZE], pt[4096]; + int err; + + fprintf(stderr, "\n\nECB Time Trials for the Symmetric Ciphers:\n"); + no_results = 0; + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + ecb_start(x, key, cipher_descriptor[x].min_key_length, 0, &ecb); + + /* sanity check on cipher */ + if ((err = cipher_descriptor[x].test()) != CRYPT_OK) { + fprintf(stderr, "\n\nERROR: Cipher %s failed self-test %s\n", cipher_descriptor[x].name, error_to_string(err)); + exit(EXIT_FAILURE); + } + +#define DO1 ecb_encrypt(pt, pt, sizeof(pt), &ecb); +#define DO2 DO1 DO1 + + c1 = c2 = (ulong64)-1; + for (y1 = 0; y1 < 100; y1++) { + t_start(); + DO1; + t1 = t_read(); + DO2; + t2 = t_read(); + t2 -= t1; + + c1 = (t1 > c1 ? c1 : t1); + c2 = (t2 > c2 ? c2 : t2); + } + a1 = c2 - c1 - skew; + +#undef DO1 +#undef DO2 +#define DO1 ecb_decrypt(pt, pt, sizeof(pt), &ecb); +#define DO2 DO1 DO1 + + c1 = c2 = (ulong64)-1; + for (y1 = 0; y1 < 100; y1++) { + t_start(); + DO1; + t1 = t_read(); + DO2; + t2 = t_read(); + t2 -= t1; + + c1 = (t1 > c1 ? c1 : t1); + c2 = (t2 > c2 ? c2 : t2); + } + a2 = c2 - c1 - skew; + ecb_done(&ecb); + + results[no_results].id = x; + results[no_results].spd1 = a1/(sizeof(pt)/cipher_descriptor[x].block_length); + results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length); + results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2; + ++no_results; + fprintf(stderr, "."); fflush(stdout); + +#undef DO2 +#undef DO1 + } + tally_results(1); + + return 0; +} + +#ifdef LTC_CBC_MODE +int time_cipher2(void) +{ + unsigned long x, y1; + ulong64 t1, t2, c1, c2, a1, a2; + symmetric_CBC cbc; + unsigned char key[MAXBLOCKSIZE], pt[4096]; + int err; + + fprintf(stderr, "\n\nCBC Time Trials for the Symmetric Ciphers:\n"); + no_results = 0; + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + cbc_start(x, pt, key, cipher_descriptor[x].min_key_length, 0, &cbc); + + /* sanity check on cipher */ + if ((err = cipher_descriptor[x].test()) != CRYPT_OK) { + fprintf(stderr, "\n\nERROR: Cipher %s failed self-test %s\n", cipher_descriptor[x].name, error_to_string(err)); + exit(EXIT_FAILURE); + } + +#define DO1 cbc_encrypt(pt, pt, sizeof(pt), &cbc); +#define DO2 DO1 DO1 + + c1 = c2 = (ulong64)-1; + for (y1 = 0; y1 < 100; y1++) { + t_start(); + DO1; + t1 = t_read(); + DO2; + t2 = t_read(); + t2 -= t1; + + c1 = (t1 > c1 ? c1 : t1); + c2 = (t2 > c2 ? c2 : t2); + } + a1 = c2 - c1 - skew; + +#undef DO1 +#undef DO2 +#define DO1 cbc_decrypt(pt, pt, sizeof(pt), &cbc); +#define DO2 DO1 DO1 + + c1 = c2 = (ulong64)-1; + for (y1 = 0; y1 < 100; y1++) { + t_start(); + DO1; + t1 = t_read(); + DO2; + t2 = t_read(); + t2 -= t1; + + c1 = (t1 > c1 ? c1 : t1); + c2 = (t2 > c2 ? c2 : t2); + } + a2 = c2 - c1 - skew; + cbc_done(&cbc); + + results[no_results].id = x; + results[no_results].spd1 = a1/(sizeof(pt)/cipher_descriptor[x].block_length); + results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length); + results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2; + ++no_results; + fprintf(stderr, "."); fflush(stdout); + +#undef DO2 +#undef DO1 + } + tally_results(1); + + return 0; +} +#else +int time_cipher2(void) { fprintf(stderr, "NO CBC\n"); return 0; } +#endif + +#ifdef LTC_CTR_MODE +int time_cipher3(void) +{ + unsigned long x, y1; + ulong64 t1, t2, c1, c2, a1, a2; + symmetric_CTR ctr; + unsigned char key[MAXBLOCKSIZE], pt[4096]; + int err; + + fprintf(stderr, "\n\nCTR Time Trials for the Symmetric Ciphers:\n"); + no_results = 0; + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + ctr_start(x, pt, key, cipher_descriptor[x].min_key_length, 0, CTR_COUNTER_LITTLE_ENDIAN, &ctr); + + /* sanity check on cipher */ + if ((err = cipher_descriptor[x].test()) != CRYPT_OK) { + fprintf(stderr, "\n\nERROR: Cipher %s failed self-test %s\n", cipher_descriptor[x].name, error_to_string(err)); + exit(EXIT_FAILURE); + } + +#define DO1 ctr_encrypt(pt, pt, sizeof(pt), &ctr); +#define DO2 DO1 DO1 + + c1 = c2 = (ulong64)-1; + for (y1 = 0; y1 < 100; y1++) { + t_start(); + DO1; + t1 = t_read(); + DO2; + t2 = t_read(); + t2 -= t1; + + c1 = (t1 > c1 ? c1 : t1); + c2 = (t2 > c2 ? c2 : t2); + } + a1 = c2 - c1 - skew; + +#undef DO1 +#undef DO2 +#define DO1 ctr_decrypt(pt, pt, sizeof(pt), &ctr); +#define DO2 DO1 DO1 + + c1 = c2 = (ulong64)-1; + for (y1 = 0; y1 < 100; y1++) { + t_start(); + DO1; + t1 = t_read(); + DO2; + t2 = t_read(); + t2 -= t1; + + c1 = (t1 > c1 ? c1 : t1); + c2 = (t2 > c2 ? c2 : t2); + } + a2 = c2 - c1 - skew; + ctr_done(&ctr); + + results[no_results].id = x; + results[no_results].spd1 = a1/(sizeof(pt)/cipher_descriptor[x].block_length); + results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length); + results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2; + ++no_results; + fprintf(stderr, "."); fflush(stdout); + +#undef DO2 +#undef DO1 + } + tally_results(1); + + return 0; +} +#else +int time_cipher3(void) { fprintf(stderr, "NO CTR\n"); return 0; } +#endif + +#ifdef LTC_LRW_MODE +int time_cipher4(void) +{ + unsigned long x, y1; + ulong64 t1, t2, c1, c2, a1, a2; + symmetric_LRW lrw; + unsigned char key[MAXBLOCKSIZE], pt[4096]; + int err; + + fprintf(stderr, "\n\nLRW Time Trials for the Symmetric Ciphers:\n"); + no_results = 0; + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + if (cipher_descriptor[x].block_length != 16) continue; + lrw_start(x, pt, key, cipher_descriptor[x].min_key_length, key, 0, &lrw); + + /* sanity check on cipher */ + if ((err = cipher_descriptor[x].test()) != CRYPT_OK) { + fprintf(stderr, "\n\nERROR: Cipher %s failed self-test %s\n", cipher_descriptor[x].name, error_to_string(err)); + exit(EXIT_FAILURE); + } + +#define DO1 lrw_encrypt(pt, pt, sizeof(pt), &lrw); +#define DO2 DO1 DO1 + + c1 = c2 = (ulong64)-1; + for (y1 = 0; y1 < 100; y1++) { + t_start(); + DO1; + t1 = t_read(); + DO2; + t2 = t_read(); + t2 -= t1; + + c1 = (t1 > c1 ? c1 : t1); + c2 = (t2 > c2 ? c2 : t2); + } + a1 = c2 - c1 - skew; + +#undef DO1 +#undef DO2 +#define DO1 lrw_decrypt(pt, pt, sizeof(pt), &lrw); +#define DO2 DO1 DO1 + + c1 = c2 = (ulong64)-1; + for (y1 = 0; y1 < 100; y1++) { + t_start(); + DO1; + t1 = t_read(); + DO2; + t2 = t_read(); + t2 -= t1; + + c1 = (t1 > c1 ? c1 : t1); + c2 = (t2 > c2 ? c2 : t2); + } + a2 = c2 - c1 - skew; + + lrw_done(&lrw); + + results[no_results].id = x; + results[no_results].spd1 = a1/(sizeof(pt)/cipher_descriptor[x].block_length); + results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length); + results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2; + ++no_results; + fprintf(stderr, "."); fflush(stdout); + +#undef DO2 +#undef DO1 + } + tally_results(1); + + return 0; +} +#else +int time_cipher4(void) { fprintf(stderr, "NO LRW\n"); return 0; } +#endif + + +int time_hash(void) +{ + unsigned long x, y1, len; + ulong64 t1, t2, c1, c2; + hash_state md; + int (*func)(hash_state *, const unsigned char *, unsigned long), err; + unsigned char pt[MAXBLOCKSIZE]; + + + fprintf(stderr, "\n\nHASH Time Trials for:\n"); + no_results = 0; + for (x = 0; hash_descriptor[x].name != NULL; x++) { + + /* sanity check on hash */ + if ((err = hash_descriptor[x].test()) != CRYPT_OK) { + fprintf(stderr, "\n\nERROR: Hash %s failed self-test %s\n", hash_descriptor[x].name, error_to_string(err)); + exit(EXIT_FAILURE); + } + + hash_descriptor[x].init(&md); + +#define DO1 func(&md,pt,len); +#define DO2 DO1 DO1 + + func = hash_descriptor[x].process; + len = hash_descriptor[x].blocksize; + + c1 = c2 = (ulong64)-1; + for (y1 = 0; y1 < TIMES; y1++) { + t_start(); + DO1; + t1 = t_read(); + DO2; + t2 = t_read() - t1; + c1 = (t1 > c1) ? c1 : t1; + c2 = (t2 > c2) ? c2 : t2; + } + t1 = c2 - c1 - skew; + t1 = ((t1 * CONST64(1000))) / ((ulong64)hash_descriptor[x].blocksize); + results[no_results].id = x; + results[no_results].spd1 = results[no_results].avg = t1; + ++no_results; + fprintf(stderr, "."); fflush(stdout); +#undef DO2 +#undef DO1 + } + tally_results(2); + + return 0; +} + +#undef MPI +/*#warning you need an mp_rand!!!*/ + +#ifdef MPI +void time_mult(void) +{ + ulong64 t1, t2; + unsigned long x, y; + void *a, *b, *c; + + fprintf(stderr, "Timing Multiplying:\n"); + mp_init_multi(&a,&b,&c,NULL); + for (x = 128/DIGIT_BIT; x <= 1536/DIGIT_BIT; x += 128/DIGIT_BIT) { + mp_rand(&a, x); + mp_rand(&b, x); + +#define DO1 mp_mul(&a, &b, &c); +#define DO2 DO1; DO1; + + t2 = -1; + for (y = 0; y < TIMES; y++) { + t_start(); + t1 = t_read(); + DO2; + t1 = (t_read() - t1)>>1; + if (t1 < t2) t2 = t1; + } + fprintf(stderr, "%4lu bits: %9llu cycles\n", x*DIGIT_BIT, t2); + } + mp_clear_multi(&a,&b,&c,NULL); + +#undef DO1 +#undef DO2 +} + +void time_sqr(void) +{ + ulong64 t1, t2; + unsigned long x, y; + mp_int a, b; + + fprintf(stderr, "Timing Squaring:\n"); + mp_init_multi(&a,&b,NULL); + for (x = 128/DIGIT_BIT; x <= 1536/DIGIT_BIT; x += 128/DIGIT_BIT) { + mp_rand(&a, x); + +#define DO1 mp_sqr(&a, &b); +#define DO2 DO1; DO1; + + t2 = -1; + for (y = 0; y < TIMES; y++) { + t_start(); + t1 = t_read(); + DO2; + t1 = (t_read() - t1)>>1; + if (t1 < t2) t2 = t1; + } + fprintf(stderr, "%4lu bits: %9llu cycles\n", x*DIGIT_BIT, t2); + } + mp_clear_multi(&a,&b,NULL); + +#undef DO1 +#undef DO2 +} +#else +void time_mult(void) { fprintf(stderr, "NO MULT\n"); } +void time_sqr(void) { fprintf(stderr, "NO SQR\n"); } +#endif + +void time_prng(void) +{ + ulong64 t1, t2; + unsigned char buf[4096]; + prng_state tprng; + unsigned long x, y; + int err; + + fprintf(stderr, "Timing PRNGs (cycles/byte output, cycles add_entropy (32 bytes) :\n"); + for (x = 0; prng_descriptor[x].name != NULL; x++) { + + /* sanity check on prng */ + if ((err = prng_descriptor[x].test()) != CRYPT_OK) { + fprintf(stderr, "\n\nERROR: PRNG %s failed self-test %s\n", prng_descriptor[x].name, error_to_string(err)); + exit(EXIT_FAILURE); + } + + prng_descriptor[x].start(&tprng); + zeromem(buf, 256); + prng_descriptor[x].add_entropy(buf, 256, &tprng); + prng_descriptor[x].ready(&tprng); + t2 = -1; + +#define DO1 if (prng_descriptor[x].read(buf, 4096, &tprng) != 4096) { fprintf(stderr, "\n\nERROR READ != 4096\n\n"); exit(EXIT_FAILURE); } +#define DO2 DO1 DO1 + for (y = 0; y < 10000; y++) { + t_start(); + t1 = t_read(); + DO2; + t1 = (t_read() - t1)>>1; + if (t1 < t2) t2 = t1; + } + fprintf(stderr, "%20s: %5llu ", prng_descriptor[x].name, t2>>12); +#undef DO2 +#undef DO1 + +#define DO1 prng_descriptor[x].start(&tprng); prng_descriptor[x].add_entropy(buf, 32, &tprng); prng_descriptor[x].ready(&tprng); prng_descriptor[x].done(&tprng); +#define DO2 DO1 DO1 + for (y = 0; y < 10000; y++) { + t_start(); + t1 = t_read(); + DO2; + t1 = (t_read() - t1)>>1; + if (t1 < t2) t2 = t1; + } + fprintf(stderr, "%5llu\n", t2); +#undef DO2 +#undef DO1 + + } +} + +#ifdef LTC_MDSA +/* time various DSA operations */ +void time_dsa(void) +{ + dsa_key key; + ulong64 t1, t2; + unsigned long x, y; + int err; +static const struct { + int group, modulus; +} groups[] = { +{ 20, 96 }, +{ 20, 128 }, +{ 24, 192 }, +{ 28, 256 }, +{ 32, 512 } +}; + + for (x = 0; x < (sizeof(groups)/sizeof(groups[0])); x++) { + t2 = 0; + for (y = 0; y < 4; y++) { + t_start(); + t1 = t_read(); + if ((err = dsa_make_key(&yarrow_prng, find_prng("yarrow"), groups[x].group, groups[x].modulus, &key)) != CRYPT_OK) { + fprintf(stderr, "\n\ndsa_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + t2 += t1; + +#ifdef LTC_PROFILE + t2 <<= 2; + break; +#endif + if (y < 3) { + dsa_free(&key); + } + } + t2 >>= 2; + fprintf(stderr, "DSA-(%lu, %lu) make_key took %15llu cycles\n", (unsigned long)groups[x].group*8, (unsigned long)groups[x].modulus*8, t2); + } +} +#endif + + +#ifdef LTC_MRSA +/* time various RSA operations */ +void time_rsa(void) +{ + rsa_key key; + ulong64 t1, t2; + unsigned char buf[2][2048]; + unsigned long x, y, z, zzz; + int err, zz, stat; + + for (x = 1024; x <= 2048; x += 256) { + t2 = 0; + for (y = 0; y < 4; y++) { + t_start(); + t1 = t_read(); + if ((err = rsa_make_key(&yarrow_prng, find_prng("yarrow"), x/8, 65537, &key)) != CRYPT_OK) { + fprintf(stderr, "\n\nrsa_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + t2 += t1; + +#ifdef LTC_PROFILE + t2 <<= 2; + break; +#endif + + if (y < 3) { + rsa_free(&key); + } + } + t2 >>= 2; + fprintf(stderr, "RSA-%lu make_key took %15llu cycles\n", x, t2); + + t2 = 0; + for (y = 0; y < 16; y++) { + t_start(); + t1 = t_read(); + z = sizeof(buf[1]); + if ((err = rsa_encrypt_key(buf[0], 32, buf[1], &z, (const unsigned char *)"testprog", 8, &yarrow_prng, + find_prng("yarrow"), find_hash("sha1"), + &key)) != CRYPT_OK) { + fprintf(stderr, "\n\nrsa_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + t2 += t1; +#ifdef LTC_PROFILE + t2 <<= 4; + break; +#endif + } + t2 >>= 4; + fprintf(stderr, "RSA-%lu encrypt_key took %15llu cycles\n", x, t2); + + t2 = 0; + for (y = 0; y < 2048; y++) { + t_start(); + t1 = t_read(); + zzz = sizeof(buf[0]); + if ((err = rsa_decrypt_key(buf[1], z, buf[0], &zzz, (const unsigned char *)"testprog", 8, find_hash("sha1"), + &zz, &key)) != CRYPT_OK) { + fprintf(stderr, "\n\nrsa_decrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + t2 += t1; +#ifdef LTC_PROFILE + t2 <<= 11; + break; +#endif + } + t2 >>= 11; + fprintf(stderr, "RSA-%lu decrypt_key took %15llu cycles\n", x, t2); + + t2 = 0; + for (y = 0; y < 256; y++) { + t_start(); + t1 = t_read(); + z = sizeof(buf[1]); + if ((err = rsa_sign_hash(buf[0], 20, buf[1], &z, &yarrow_prng, + find_prng("yarrow"), find_hash("sha1"), 8, &key)) != CRYPT_OK) { + fprintf(stderr, "\n\nrsa_sign_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + t2 += t1; +#ifdef LTC_PROFILE + t2 <<= 8; + break; +#endif + } + t2 >>= 8; + fprintf(stderr, "RSA-%lu sign_hash took %15llu cycles\n", x, t2); + + t2 = 0; + for (y = 0; y < 2048; y++) { + t_start(); + t1 = t_read(); + if ((err = rsa_verify_hash(buf[1], z, buf[0], 20, find_hash("sha1"), 8, &stat, &key)) != CRYPT_OK) { + fprintf(stderr, "\n\nrsa_verify_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); + exit(EXIT_FAILURE); + } + if (stat == 0) { + fprintf(stderr, "\n\nrsa_verify_hash for RSA-%lu failed to verify signature(%lu)\n", x, y); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + t2 += t1; +#ifdef LTC_PROFILE + t2 <<= 11; + break; +#endif + } + t2 >>= 11; + fprintf(stderr, "RSA-%lu verify_hash took %15llu cycles\n", x, t2); + fprintf(stderr, "\n\n"); + rsa_free(&key); + } +} +#else +void time_rsa(void) { fprintf(stderr, "NO RSA\n"); } +#endif + +#ifdef MKAT +/* time various KAT operations */ +void time_katja(void) +{ + katja_key key; + ulong64 t1, t2; + unsigned char buf[2][4096]; + unsigned long x, y, z, zzz; + int err, zz; + + for (x = 1024; x <= 2048; x += 256) { + t2 = 0; + for (y = 0; y < 4; y++) { + t_start(); + t1 = t_read(); + if ((err = katja_make_key(&yarrow_prng, find_prng("yarrow"), x/8, &key)) != CRYPT_OK) { + fprintf(stderr, "\n\nkatja_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + t2 += t1; + + if (y < 3) { + katja_free(&key); + } + } + t2 >>= 2; + fprintf(stderr, "Katja-%lu make_key took %15llu cycles\n", x, t2); + + t2 = 0; + for (y = 0; y < 16; y++) { + t_start(); + t1 = t_read(); + z = sizeof(buf[1]); + if ((err = katja_encrypt_key(buf[0], 32, buf[1], &z, "testprog", 8, &yarrow_prng, + find_prng("yarrow"), find_hash("sha1"), + &key)) != CRYPT_OK) { + fprintf(stderr, "\n\nkatja_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + t2 += t1; + } + t2 >>= 4; + fprintf(stderr, "Katja-%lu encrypt_key took %15llu cycles\n", x, t2); + + t2 = 0; + for (y = 0; y < 2048; y++) { + t_start(); + t1 = t_read(); + zzz = sizeof(buf[0]); + if ((err = katja_decrypt_key(buf[1], z, buf[0], &zzz, "testprog", 8, find_hash("sha1"), + &zz, &key)) != CRYPT_OK) { + fprintf(stderr, "\n\nkatja_decrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + t2 += t1; + } + t2 >>= 11; + fprintf(stderr, "Katja-%lu decrypt_key took %15llu cycles\n", x, t2); + + + katja_free(&key); + } +} +#else +void time_katja(void) { fprintf(stderr, "NO Katja\n"); } +#endif + +#ifdef LTC_MECC +/* time various ECC operations */ +void time_ecc(void) +{ + ecc_key key; + ulong64 t1, t2; + unsigned char buf[2][256]; + unsigned long i, w, x, y, z; + int err, stat; + static unsigned long sizes[] = { +#ifdef ECC112 +112/8, +#endif +#ifdef ECC128 +128/8, +#endif +#ifdef ECC160 +160/8, +#endif +#ifdef ECC192 +192/8, +#endif +#ifdef ECC224 +224/8, +#endif +#ifdef ECC256 +256/8, +#endif +#ifdef ECC384 +384/8, +#endif +#ifdef ECC521 +521/8, +#endif +100000}; + + for (x = sizes[i=0]; x < 100000; x = sizes[++i]) { + t2 = 0; + for (y = 0; y < 256; y++) { + t_start(); + t1 = t_read(); + if ((err = ecc_make_key(&yarrow_prng, find_prng("yarrow"), x, &key)) != CRYPT_OK) { + fprintf(stderr, "\n\necc_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + t2 += t1; + +#ifdef LTC_PROFILE + t2 <<= 8; + break; +#endif + + if (y < 255) { + ecc_free(&key); + } + } + t2 >>= 8; + fprintf(stderr, "ECC-%lu make_key took %15llu cycles\n", x*8, t2); + + t2 = 0; + for (y = 0; y < 256; y++) { + t_start(); + t1 = t_read(); + z = sizeof(buf[1]); + if ((err = ecc_encrypt_key(buf[0], 20, buf[1], &z, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"), + &key)) != CRYPT_OK) { + fprintf(stderr, "\n\necc_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + t2 += t1; +#ifdef LTC_PROFILE + t2 <<= 8; + break; +#endif + } + t2 >>= 8; + fprintf(stderr, "ECC-%lu encrypt_key took %15llu cycles\n", x*8, t2); + + t2 = 0; + for (y = 0; y < 256; y++) { + t_start(); + t1 = t_read(); + w = 20; + if ((err = ecc_decrypt_key(buf[1], z, buf[0], &w, &key)) != CRYPT_OK) { + fprintf(stderr, "\n\necc_decrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + t2 += t1; +#ifdef LTC_PROFILE + t2 <<= 8; + break; +#endif + } + t2 >>= 8; + fprintf(stderr, "ECC-%lu decrypt_key took %15llu cycles\n", x*8, t2); + + t2 = 0; + for (y = 0; y < 256; y++) { + t_start(); + t1 = t_read(); + z = sizeof(buf[1]); + if ((err = ecc_sign_hash(buf[0], 20, buf[1], &z, &yarrow_prng, + find_prng("yarrow"), &key)) != CRYPT_OK) { + fprintf(stderr, "\n\necc_sign_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + t2 += t1; +#ifdef LTC_PROFILE + t2 <<= 8; + break; +#endif + } + t2 >>= 8; + fprintf(stderr, "ECC-%lu sign_hash took %15llu cycles\n", x*8, t2); + + t2 = 0; + for (y = 0; y < 256; y++) { + t_start(); + t1 = t_read(); + if ((err = ecc_verify_hash(buf[1], z, buf[0], 20, &stat, &key)) != CRYPT_OK) { + fprintf(stderr, "\n\necc_verify_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); + exit(EXIT_FAILURE); + } + if (stat == 0) { + fprintf(stderr, "\n\necc_verify_hash for ECC-%lu failed to verify signature(%lu)\n", x*8, y); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + t2 += t1; +#ifdef LTC_PROFILE + t2 <<= 8; + break; +#endif + } + t2 >>= 8; + fprintf(stderr, "ECC-%lu verify_hash took %15llu cycles\n", x*8, t2); + + fprintf(stderr, "\n\n"); + ecc_free(&key); + } +} +#else +void time_ecc(void) { fprintf(stderr, "NO ECC\n"); } +#endif + +void time_macs_(unsigned long MAC_SIZE) +{ + unsigned char *buf, key[16], tag[16]; + ulong64 t1, t2; + unsigned long x, z; + int err, cipher_idx, hash_idx; + + fprintf(stderr, "\nMAC Timings (cycles/byte on %luKB blocks):\n", MAC_SIZE); + + buf = XMALLOC(MAC_SIZE*1024); + if (buf == NULL) { + fprintf(stderr, "\n\nout of heap yo\n\n"); + exit(EXIT_FAILURE); + } + + cipher_idx = find_cipher("aes"); + hash_idx = find_hash("sha1"); + + if (cipher_idx == -1 || hash_idx == -1) { + fprintf(stderr, "Warning the MAC tests requires AES and LTC_SHA1 to operate... so sorry\n"); + return; + } + + yarrow_read(buf, MAC_SIZE*1024, &yarrow_prng); + yarrow_read(key, 16, &yarrow_prng); + +#ifdef LTC_OMAC + t2 = -1; + for (x = 0; x < 10000; x++) { + t_start(); + t1 = t_read(); + z = 16; + if ((err = omac_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) { + fprintf(stderr, "\n\nomac error... %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + if (t1 < t2) t2 = t1; + } + fprintf(stderr, "LTC_OMAC-%s\t\t%9llu\n", cipher_descriptor[cipher_idx].name, t2/(ulong64)(MAC_SIZE*1024)); +#endif + +#ifdef LTC_XCBC + t2 = -1; + for (x = 0; x < 10000; x++) { + t_start(); + t1 = t_read(); + z = 16; + if ((err = xcbc_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) { + fprintf(stderr, "\n\nxcbc error... %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + if (t1 < t2) t2 = t1; + } + fprintf(stderr, "XCBC-%s\t\t%9llu\n", cipher_descriptor[cipher_idx].name, t2/(ulong64)(MAC_SIZE*1024)); +#endif + +#ifdef LTC_F9_MODE + t2 = -1; + for (x = 0; x < 10000; x++) { + t_start(); + t1 = t_read(); + z = 16; + if ((err = f9_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) { + fprintf(stderr, "\n\nF9 error... %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + if (t1 < t2) t2 = t1; + } + fprintf(stderr, "F9-%s\t\t\t%9llu\n", cipher_descriptor[cipher_idx].name, t2/(ulong64)(MAC_SIZE*1024)); +#endif + +#ifdef LTC_PMAC + t2 = -1; + for (x = 0; x < 10000; x++) { + t_start(); + t1 = t_read(); + z = 16; + if ((err = pmac_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) { + fprintf(stderr, "\n\npmac error... %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + if (t1 < t2) t2 = t1; + } + fprintf(stderr, "PMAC-AES\t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); +#endif + +#ifdef LTC_PELICAN + t2 = -1; + for (x = 0; x < 10000; x++) { + t_start(); + t1 = t_read(); + z = 16; + if ((err = pelican_memory(key, 16, buf, MAC_SIZE*1024, tag)) != CRYPT_OK) { + fprintf(stderr, "\n\npelican error... %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + if (t1 < t2) t2 = t1; + } + fprintf(stderr, "LTC_PELICAN \t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); +#endif + +#ifdef LTC_HMAC + t2 = -1; + for (x = 0; x < 10000; x++) { + t_start(); + t1 = t_read(); + z = 16; + if ((err = hmac_memory(hash_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) { + fprintf(stderr, "\n\nhmac error... %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + if (t1 < t2) t2 = t1; + } + fprintf(stderr, "LTC_HMAC-%s\t\t%9llu\n", hash_descriptor[hash_idx].name, t2/(ulong64)(MAC_SIZE*1024)); +#endif + + XFREE(buf); +} + +void time_macs(void) +{ + time_macs_(1); + time_macs_(4); + time_macs_(32); +} + +void time_encmacs_(unsigned long MAC_SIZE) +{ + unsigned char *buf, IV[16], key[16], tag[16]; + ulong64 t1, t2; + unsigned long x, z; + int err, cipher_idx; + symmetric_key skey; + + fprintf(stderr, "\nENC+MAC Timings (zero byte AAD, 16 byte IV, cycles/byte on %luKB blocks):\n", MAC_SIZE); + + buf = XMALLOC(MAC_SIZE*1024); + if (buf == NULL) { + fprintf(stderr, "\n\nout of heap yo\n\n"); + exit(EXIT_FAILURE); + } + + cipher_idx = find_cipher("aes"); + + yarrow_read(buf, MAC_SIZE*1024, &yarrow_prng); + yarrow_read(key, 16, &yarrow_prng); + yarrow_read(IV, 16, &yarrow_prng); + +#ifdef LTC_EAX_MODE + t2 = -1; + for (x = 0; x < 10000; x++) { + t_start(); + t1 = t_read(); + z = 16; + if ((err = eax_encrypt_authenticate_memory(cipher_idx, key, 16, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z)) != CRYPT_OK) { + fprintf(stderr, "\nEAX error... %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + if (t1 < t2) t2 = t1; + } + fprintf(stderr, "EAX \t\t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); +#endif + +#ifdef LTC_OCB_MODE + t2 = -1; + for (x = 0; x < 10000; x++) { + t_start(); + t1 = t_read(); + z = 16; + if ((err = ocb_encrypt_authenticate_memory(cipher_idx, key, 16, IV, buf, MAC_SIZE*1024, buf, tag, &z)) != CRYPT_OK) { + fprintf(stderr, "\nOCB error... %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + if (t1 < t2) t2 = t1; + } + fprintf(stderr, "OCB \t\t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); +#endif + +#ifdef LTC_CCM_MODE + t2 = -1; + for (x = 0; x < 10000; x++) { + t_start(); + t1 = t_read(); + z = 16; + if ((err = ccm_memory(cipher_idx, key, 16, NULL, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z, CCM_ENCRYPT)) != CRYPT_OK) { + fprintf(stderr, "\nCCM error... %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + if (t1 < t2) t2 = t1; + } + fprintf(stderr, "CCM (no-precomp) \t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); + + cipher_descriptor[cipher_idx].setup(key, 16, 0, &skey); + t2 = -1; + for (x = 0; x < 10000; x++) { + t_start(); + t1 = t_read(); + z = 16; + if ((err = ccm_memory(cipher_idx, key, 16, &skey, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z, CCM_ENCRYPT)) != CRYPT_OK) { + fprintf(stderr, "\nCCM error... %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + if (t1 < t2) t2 = t1; + } + fprintf(stderr, "CCM (precomp) \t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); + cipher_descriptor[cipher_idx].done(&skey); +#endif + +#ifdef LTC_GCM_MODE + t2 = -1; + for (x = 0; x < 100; x++) { + t_start(); + t1 = t_read(); + z = 16; + if ((err = gcm_memory(cipher_idx, key, 16, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z, GCM_ENCRYPT)) != CRYPT_OK) { + fprintf(stderr, "\nGCM error... %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + if (t1 < t2) t2 = t1; + } + fprintf(stderr, "GCM (no-precomp)\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); + + { + gcm_state gcm +#ifdef LTC_GCM_TABLES_SSE2 +__attribute__ ((aligned (16))) +#endif +; + + if ((err = gcm_init(&gcm, cipher_idx, key, 16)) != CRYPT_OK) { fprintf(stderr, "gcm_init: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } + t2 = -1; + for (x = 0; x < 10000; x++) { + t_start(); + t1 = t_read(); + z = 16; + if ((err = gcm_reset(&gcm)) != CRYPT_OK) { + fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); + exit(EXIT_FAILURE); + } + if ((err = gcm_add_iv(&gcm, IV, 16)) != CRYPT_OK) { + fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); + exit(EXIT_FAILURE); + } + if ((err = gcm_add_aad(&gcm, NULL, 0)) != CRYPT_OK) { + fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); + exit(EXIT_FAILURE); + } + if ((err = gcm_process(&gcm, buf, MAC_SIZE*1024, buf, GCM_ENCRYPT)) != CRYPT_OK) { + fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); + exit(EXIT_FAILURE); + } + + if ((err = gcm_done(&gcm, tag, &z)) != CRYPT_OK) { + fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + if (t1 < t2) t2 = t1; + } + fprintf(stderr, "GCM (precomp)\t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); + } + +#endif + +} + +void time_encmacs(void) +{ + time_encmacs_(1); + time_encmacs_(4); + time_encmacs_(32); +} + +/* $Source: /cvs/libtom/libtomcrypt/testprof/x86_prof.c,v $ */ +/* $Revision: 1.58 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/xmhf-64/xmhf/third-party/libtomcrypt/updatemakes.sh b/xmhf-64/xmhf/third-party/libtomcrypt/updatemakes.sh new file mode 100644 index 0000000000..9b6cbde9a1 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtomcrypt/updatemakes.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +bash genlist.sh > tmplist + +perl filter.pl makefile tmplist +mv -f tmp.delme makefile + +perl filter.pl makefile.icc tmplist +mv -f tmp.delme makefile.icc + +perl filter.pl makefile.shared tmplist +mv -f tmp.delme makefile.shared + +perl filter.pl makefile.unix tmplist +mv -f tmp.delme makefile.unix + +perl filter.pl makefile.msvc tmplist +sed -e 's/\.o /.obj /g' < tmp.delme > makefile.msvc + +rm -f tmplist +rm -f tmp.delme diff --git a/xmhf-64/xmhf/third-party/libtommath/LICENSE b/xmhf-64/xmhf/third-party/libtommath/LICENSE new file mode 100644 index 0000000000..5baa792a65 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/LICENSE @@ -0,0 +1,4 @@ +LibTomMath is hereby released into the Public Domain. + +-- Tom St Denis + diff --git a/xmhf-64/xmhf/third-party/libtommath/bn.ilg b/xmhf-64/xmhf/third-party/libtommath/bn.ilg new file mode 100644 index 0000000000..3c859f0346 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn.ilg @@ -0,0 +1,6 @@ +This is makeindex, version 2.14 [02-Oct-2002] (kpathsea + Thai support). +Scanning input file bn.idx....done (79 entries accepted, 0 rejected). +Sorting entries....done (511 comparisons). +Generating output file bn.ind....done (82 lines written, 0 warnings). +Output written in bn.ind. +Transcript written in bn.ilg. diff --git a/xmhf-64/xmhf/third-party/libtommath/bn.ind b/xmhf-64/xmhf/third-party/libtommath/bn.ind new file mode 100644 index 0000000000..3c3d288ce9 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn.ind @@ -0,0 +1,82 @@ +\begin{theindex} + + \item mp\_add, \hyperpage{23} + \item mp\_add\_d, \hyperpage{44} + \item mp\_and, \hyperpage{23} + \item mp\_clear, \hyperpage{9} + \item mp\_clear\_multi, \hyperpage{10} + \item mp\_cmp, \hyperpage{19} + \item mp\_cmp\_d, \hyperpage{20} + \item mp\_cmp\_mag, \hyperpage{18} + \item mp\_div, \hyperpage{24} + \item mp\_div\_2, \hyperpage{21} + \item mp\_div\_2d, \hyperpage{22} + \item mp\_div\_d, \hyperpage{44} + \item mp\_dr\_reduce, \hyperpage{33} + \item mp\_dr\_setup, \hyperpage{33} + \item MP\_EQ, \hyperpage{18} + \item mp\_error\_to\_string, \hyperpage{7} + \item mp\_expt\_d, \hyperpage{35} + \item mp\_exptmod, \hyperpage{35} + \item mp\_exteuclid, \hyperpage{43} + \item mp\_gcd, \hyperpage{43} + \item mp\_get\_int, \hyperpage{16} + \item mp\_grow, \hyperpage{13} + \item MP\_GT, \hyperpage{18} + \item mp\_init, \hyperpage{8} + \item mp\_init\_copy, \hyperpage{10} + \item mp\_init\_multi, \hyperpage{10} + \item mp\_init\_set, \hyperpage{17} + \item mp\_init\_set\_int, \hyperpage{17} + \item mp\_init\_size, \hyperpage{11} + \item mp\_int, \hyperpage{8} + \item mp\_invmod, \hyperpage{44} + \item mp\_jacobi, \hyperpage{43} + \item mp\_lcm, \hyperpage{43} + \item mp\_lshd, \hyperpage{23} + \item MP\_LT, \hyperpage{18} + \item MP\_MEM, \hyperpage{7} + \item mp\_mod, \hyperpage{29} + \item mp\_mod\_d, \hyperpage{44} + \item mp\_montgomery\_calc\_normalization, \hyperpage{31} + \item mp\_montgomery\_reduce, \hyperpage{31} + \item mp\_montgomery\_setup, \hyperpage{31} + \item mp\_mul, \hyperpage{25} + \item mp\_mul\_2, \hyperpage{21} + \item mp\_mul\_2d, \hyperpage{22} + \item mp\_mul\_d, \hyperpage{44} + \item mp\_n\_root, \hyperpage{35} + \item mp\_neg, \hyperpage{24} + \item MP\_NO, \hyperpage{7} + \item MP\_OKAY, \hyperpage{7} + \item mp\_or, \hyperpage{23} + \item mp\_prime\_fermat, \hyperpage{37} + \item mp\_prime\_is\_divisible, \hyperpage{37} + \item mp\_prime\_is\_prime, \hyperpage{38} + \item mp\_prime\_miller\_rabin, \hyperpage{37} + \item mp\_prime\_next\_prime, \hyperpage{38} + \item mp\_prime\_rabin\_miller\_trials, \hyperpage{38} + \item mp\_prime\_random, \hyperpage{38} + \item mp\_prime\_random\_ex, \hyperpage{39} + \item mp\_radix\_size, \hyperpage{41} + \item mp\_read\_radix, \hyperpage{41} + \item mp\_read\_unsigned\_bin, \hyperpage{42} + \item mp\_reduce, \hyperpage{30} + \item mp\_reduce\_2k, \hyperpage{34} + \item mp\_reduce\_2k\_setup, \hyperpage{34} + \item mp\_reduce\_setup, \hyperpage{29} + \item mp\_rshd, \hyperpage{23} + \item mp\_set, \hyperpage{15} + \item mp\_set\_int, \hyperpage{16} + \item mp\_shrink, \hyperpage{12} + \item mp\_sqr, \hyperpage{26} + \item mp\_sub, \hyperpage{23} + \item mp\_sub\_d, \hyperpage{44} + \item mp\_to\_unsigned\_bin, \hyperpage{42} + \item mp\_toradix, \hyperpage{41} + \item mp\_unsigned\_bin\_size, \hyperpage{41} + \item MP\_VAL, \hyperpage{7} + \item mp\_xor, \hyperpage{23} + \item MP\_YES, \hyperpage{7} + +\end{theindex} diff --git a/xmhf-64/xmhf/third-party/libtommath/bn.pdf b/xmhf-64/xmhf/third-party/libtommath/bn.pdf new file mode 100644 index 0000000000..078628c6cc Binary files /dev/null and b/xmhf-64/xmhf/third-party/libtommath/bn.pdf differ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn.tex b/xmhf-64/xmhf/third-party/libtommath/bn.tex new file mode 100644 index 0000000000..71b6840b16 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn.tex @@ -0,0 +1,1835 @@ +\documentclass[synpaper]{book} +\usepackage{hyperref} +\usepackage{makeidx} +\usepackage{amssymb} +\usepackage{color} +\usepackage{alltt} +\usepackage{graphicx} +\usepackage{layout} +\def\union{\cup} +\def\intersect{\cap} +\def\getsrandom{\stackrel{\rm R}{\gets}} +\def\cross{\times} +\def\cat{\hspace{0.5em} \| \hspace{0.5em}} +\def\catn{$\|$} +\def\divides{\hspace{0.3em} | \hspace{0.3em}} +\def\nequiv{\not\equiv} +\def\approx{\raisebox{0.2ex}{\mbox{\small $\sim$}}} +\def\lcm{{\rm lcm}} +\def\gcd{{\rm gcd}} +\def\log{{\rm log}} +\def\ord{{\rm ord}} +\def\abs{{\mathit abs}} +\def\rep{{\mathit rep}} +\def\mod{{\mathit\ mod\ }} +\renewcommand{\pmod}[1]{\ ({\rm mod\ }{#1})} +\newcommand{\floor}[1]{\left\lfloor{#1}\right\rfloor} +\newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil} +\def\Or{{\rm\ or\ }} +\def\And{{\rm\ and\ }} +\def\iff{\hspace{1em}\Longleftrightarrow\hspace{1em}} +\def\implies{\Rightarrow} +\def\undefined{{\rm ``undefined"}} +\def\Proof{\vspace{1ex}\noindent {\bf Proof:}\hspace{1em}} +\let\oldphi\phi +\def\phi{\varphi} +\def\Pr{{\rm Pr}} +\newcommand{\str}[1]{{\mathbf{#1}}} +\def\F{{\mathbb F}} +\def\N{{\mathbb N}} +\def\Z{{\mathbb Z}} +\def\R{{\mathbb R}} +\def\C{{\mathbb C}} +\def\Q{{\mathbb Q}} +\definecolor{DGray}{gray}{0.5} +\newcommand{\emailaddr}[1]{\mbox{$<${#1}$>$}} +\def\twiddle{\raisebox{0.3ex}{\mbox{\tiny $\sim$}}} +\def\gap{\vspace{0.5ex}} +\makeindex +\begin{document} +\frontmatter +\pagestyle{empty} +\title{LibTomMath User Manual \\ v0.42.0} +\author{Tom St Denis \\ tomstdenis@gmail.com} +\maketitle +This text, the library and the accompanying textbook are all hereby placed in the public domain. This book has been +formatted for B5 [176x250] paper using the \LaTeX{} {\em book} macro package. + +\vspace{10cm} + +\begin{flushright}Open Source. Open Academia. Open Minds. + +\mbox{ } + +Tom St Denis, + +Ontario, Canada +\end{flushright} + +\tableofcontents +\listoffigures +\mainmatter +\pagestyle{headings} +\chapter{Introduction} +\section{What is LibTomMath?} +LibTomMath is a library of source code which provides a series of efficient and carefully written functions for manipulating +large integer numbers. It was written in portable ISO C source code so that it will build on any platform with a conforming +C compiler. + +In a nutshell the library was written from scratch with verbose comments to help instruct computer science students how +to implement ``bignum'' math. However, the resulting code has proven to be very useful. It has been used by numerous +universities, commercial and open source software developers. It has been used on a variety of platforms ranging from +Linux and Windows based x86 to ARM based Gameboys and PPC based MacOS machines. + +\section{License} +As of the v0.25 the library source code has been placed in the public domain with every new release. As of the v0.28 +release the textbook ``Implementing Multiple Precision Arithmetic'' has been placed in the public domain with every new +release as well. This textbook is meant to compliment the project by providing a more solid walkthrough of the development +algorithms used in the library. + +Since both\footnote{Note that the MPI files under mtest/ are copyrighted by Michael Fromberger. They are not required to use LibTomMath.} are in the +public domain everyone is entitled to do with them as they see fit. + +\section{Building LibTomMath} + +LibTomMath is meant to be very ``GCC friendly'' as it comes with a makefile well suited for GCC. However, the library will +also build in MSVC, Borland C out of the box. For any other ISO C compiler a makefile will have to be made by the end +developer. + +\subsection{Static Libraries} +To build as a static library for GCC issue the following +\begin{alltt} +make +\end{alltt} + +command. This will build the library and archive the object files in ``libtommath.a''. Now you link against +that and include ``tommath.h'' within your programs. Alternatively to build with MSVC issue the following +\begin{alltt} +nmake -f makefile.msvc +\end{alltt} + +This will build the library and archive the object files in ``tommath.lib''. This has been tested with MSVC +version 6.00 with service pack 5. + +\subsection{Shared Libraries} +To build as a shared library for GCC issue the following +\begin{alltt} +make -f makefile.shared +\end{alltt} +This requires the ``libtool'' package (common on most Linux/BSD systems). It will build LibTomMath as both shared +and static then install (by default) into /usr/lib as well as install the header files in /usr/include. The shared +library (resource) will be called ``libtommath.la'' while the static library called ``libtommath.a''. Generally +you use libtool to link your application against the shared object. + +There is limited support for making a ``DLL'' in windows via the ``makefile.cygwin\_dll'' makefile. It requires +Cygwin to work with since it requires the auto-export/import functionality. The resulting DLL and import library +``libtommath.dll.a'' can be used to link LibTomMath dynamically to any Windows program using Cygwin. + +\subsection{Testing} +To build the library and the test harness type + +\begin{alltt} +make test +\end{alltt} + +This will build the library, ``test'' and ``mtest/mtest''. The ``test'' program will accept test vectors and verify the +results. ``mtest/mtest'' will generate test vectors using the MPI library by Michael Fromberger\footnote{A copy of MPI +is included in the package}. Simply pipe mtest into test using + +\begin{alltt} +mtest/mtest | test +\end{alltt} + +If you do not have a ``/dev/urandom'' style RNG source you will have to write your own PRNG and simply pipe that into +mtest. For example, if your PRNG program is called ``myprng'' simply invoke + +\begin{alltt} +myprng | mtest/mtest | test +\end{alltt} + +This will output a row of numbers that are increasing. Each column is a different test (such as addition, multiplication, etc) +that is being performed. The numbers represent how many times the test was invoked. If an error is detected the program +will exit with a dump of the relevent numbers it was working with. + +\section{Build Configuration} +LibTomMath can configured at build time in three phases we shall call ``depends'', ``tweaks'' and ``trims''. +Each phase changes how the library is built and they are applied one after another respectively. + +To make the system more powerful you can tweak the build process. Classes are defined in the file +``tommath\_superclass.h''. By default, the symbol ``LTM\_ALL'' shall be defined which simply +instructs the system to build all of the functions. This is how LibTomMath used to be packaged. This will give you +access to every function LibTomMath offers. + +However, there are cases where such a build is not optional. For instance, you want to perform RSA operations. You +don't need the vast majority of the library to perform these operations. Aside from LTM\_ALL there is +another pre--defined class ``SC\_RSA\_1'' which works in conjunction with the RSA from LibTomCrypt. Additional +classes can be defined base on the need of the user. + +\subsection{Build Depends} +In the file tommath\_class.h you will see a large list of C ``defines'' followed by a series of ``ifdefs'' +which further define symbols. All of the symbols (technically they're macros $\ldots$) represent a given C source +file. For instance, BN\_MP\_ADD\_C represents the file ``bn\_mp\_add.c''. When a define has been enabled the +function in the respective file will be compiled and linked into the library. Accordingly when the define +is absent the file will not be compiled and not contribute any size to the library. + +You will also note that the header tommath\_class.h is actually recursively included (it includes itself twice). +This is to help resolve as many dependencies as possible. In the last pass the symbol LTM\_LAST will be defined. +This is useful for ``trims''. + +\subsection{Build Tweaks} +A tweak is an algorithm ``alternative''. For example, to provide tradeoffs (usually between size and space). +They can be enabled at any pass of the configuration phase. + +\begin{small} +\begin{center} +\begin{tabular}{|l|l|} +\hline \textbf{Define} & \textbf{Purpose} \\ +\hline BN\_MP\_DIV\_SMALL & Enables a slower, smaller and equally \\ + & functional mp\_div() function \\ +\hline +\end{tabular} +\end{center} +\end{small} + +\subsection{Build Trims} +A trim is a manner of removing functionality from a function that is not required. For instance, to perform +RSA cryptography you only require exponentiation with odd moduli so even moduli support can be safely removed. +Build trims are meant to be defined on the last pass of the configuration which means they are to be defined +only if LTM\_LAST has been defined. + +\subsubsection{Moduli Related} +\begin{small} +\begin{center} +\begin{tabular}{|l|l|} +\hline \textbf{Restriction} & \textbf{Undefine} \\ +\hline Exponentiation with odd moduli only & BN\_S\_MP\_EXPTMOD\_C \\ + & BN\_MP\_REDUCE\_C \\ + & BN\_MP\_REDUCE\_SETUP\_C \\ + & BN\_S\_MP\_MUL\_HIGH\_DIGS\_C \\ + & BN\_FAST\_S\_MP\_MUL\_HIGH\_DIGS\_C \\ +\hline Exponentiation with random odd moduli & (The above plus the following) \\ + & BN\_MP\_REDUCE\_2K\_C \\ + & BN\_MP\_REDUCE\_2K\_SETUP\_C \\ + & BN\_MP\_REDUCE\_IS\_2K\_C \\ + & BN\_MP\_DR\_IS\_MODULUS\_C \\ + & BN\_MP\_DR\_REDUCE\_C \\ + & BN\_MP\_DR\_SETUP\_C \\ +\hline Modular inverse odd moduli only & BN\_MP\_INVMOD\_SLOW\_C \\ +\hline Modular inverse (both, smaller/slower) & BN\_FAST\_MP\_INVMOD\_C \\ +\hline +\end{tabular} +\end{center} +\end{small} + +\subsubsection{Operand Size Related} +\begin{small} +\begin{center} +\begin{tabular}{|l|l|} +\hline \textbf{Restriction} & \textbf{Undefine} \\ +\hline Moduli $\le 2560$ bits & BN\_MP\_MONTGOMERY\_REDUCE\_C \\ + & BN\_S\_MP\_MUL\_DIGS\_C \\ + & BN\_S\_MP\_MUL\_HIGH\_DIGS\_C \\ + & BN\_S\_MP\_SQR\_C \\ +\hline Polynomial Schmolynomial & BN\_MP\_KARATSUBA\_MUL\_C \\ + & BN\_MP\_KARATSUBA\_SQR\_C \\ + & BN\_MP\_TOOM\_MUL\_C \\ + & BN\_MP\_TOOM\_SQR\_C \\ + +\hline +\end{tabular} +\end{center} +\end{small} + + +\section{Purpose of LibTomMath} +Unlike GNU MP (GMP) Library, LIP, OpenSSL or various other commercial kits (Miracl), LibTomMath was not written with +bleeding edge performance in mind. First and foremost LibTomMath was written to be entirely open. Not only is the +source code public domain (unlike various other GPL/etc licensed code), not only is the code freely downloadable but the +source code is also accessible for computer science students attempting to learn ``BigNum'' or multiple precision +arithmetic techniques. + +LibTomMath was written to be an instructive collection of source code. This is why there are many comments, only one +function per source file and often I use a ``middle-road'' approach where I don't cut corners for an extra 2\% speed +increase. + +Source code alone cannot really teach how the algorithms work which is why I also wrote a textbook that accompanies +the library (beat that!). + +So you may be thinking ``should I use LibTomMath?'' and the answer is a definite maybe. Let me tabulate what I think +are the pros and cons of LibTomMath by comparing it to the math routines from GnuPG\footnote{GnuPG v1.2.3 versus LibTomMath v0.28}. + +\newpage\begin{figure}[here] +\begin{small} +\begin{center} +\begin{tabular}{|l|c|c|l|} +\hline \textbf{Criteria} & \textbf{Pro} & \textbf{Con} & \textbf{Notes} \\ +\hline Few lines of code per file & X & & GnuPG $ = 300.9$, LibTomMath $ = 71.97$ \\ +\hline Commented function prototypes & X && GnuPG function names are cryptic. \\ +\hline Speed && X & LibTomMath is slower. \\ +\hline Totally free & X & & GPL has unfavourable restrictions.\\ +\hline Large function base & X & & GnuPG is barebones. \\ +\hline Five modular reduction algorithms & X & & Faster modular exponentiation for a variety of moduli. \\ +\hline Portable & X & & GnuPG requires configuration to build. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{LibTomMath Valuation} +\end{figure} + +It may seem odd to compare LibTomMath to GnuPG since the math in GnuPG is only a small portion of the entire application. +However, LibTomMath was written with cryptography in mind. It provides essentially all of the functions a cryptosystem +would require when working with large integers. + +So it may feel tempting to just rip the math code out of GnuPG (or GnuMP where it was taken from originally) in your +own application but I think there are reasons not to. While LibTomMath is slower than libraries such as GnuMP it is +not normally significantly slower. On x86 machines the difference is normally a factor of two when performing modular +exponentiations. It depends largely on the processor, compiler and the moduli being used. + +Essentially the only time you wouldn't use LibTomMath is when blazing speed is the primary concern. However, +on the other side of the coin LibTomMath offers you a totally free (public domain) well structured math library +that is very flexible, complete and performs well in resource contrained environments. Fast RSA for example can +be performed with as little as 8KB of ram for data (again depending on build options). + +\chapter{Getting Started with LibTomMath} +\section{Building Programs} +In order to use LibTomMath you must include ``tommath.h'' and link against the appropriate library file (typically +libtommath.a). There is no library initialization required and the entire library is thread safe. + +\section{Return Codes} +There are three possible return codes a function may return. + +\index{MP\_OKAY}\index{MP\_YES}\index{MP\_NO}\index{MP\_VAL}\index{MP\_MEM} +\begin{figure}[here!] +\begin{center} +\begin{small} +\begin{tabular}{|l|l|} +\hline \textbf{Code} & \textbf{Meaning} \\ +\hline MP\_OKAY & The function succeeded. \\ +\hline MP\_VAL & The function input was invalid. \\ +\hline MP\_MEM & Heap memory exhausted. \\ +\hline &\\ +\hline MP\_YES & Response is yes. \\ +\hline MP\_NO & Response is no. \\ +\hline +\end{tabular} +\end{small} +\end{center} +\caption{Return Codes} +\end{figure} + +The last two codes listed are not actually ``return'ed'' by a function. They are placed in an integer (the caller must +provide the address of an integer it can store to) which the caller can access. To convert one of the three return codes +to a string use the following function. + +\index{mp\_error\_to\_string} +\begin{alltt} +char *mp_error_to_string(int code); +\end{alltt} + +This will return a pointer to a string which describes the given error code. It will not work for the return codes +MP\_YES and MP\_NO. + +\section{Data Types} +The basic ``multiple precision integer'' type is known as the ``mp\_int'' within LibTomMath. This data type is used to +organize all of the data required to manipulate the integer it represents. Within LibTomMath it has been prototyped +as the following. + +\index{mp\_int} +\begin{alltt} +typedef struct \{ + int used, alloc, sign; + mp_digit *dp; +\} mp_int; +\end{alltt} + +Where ``mp\_digit'' is a data type that represents individual digits of the integer. By default, an mp\_digit is the +ISO C ``unsigned long'' data type and each digit is $28-$bits long. The mp\_digit type can be configured to suit other +platforms by defining the appropriate macros. + +All LTM functions that use the mp\_int type will expect a pointer to mp\_int structure. You must allocate memory to +hold the structure itself by yourself (whether off stack or heap it doesn't matter). The very first thing that must be +done to use an mp\_int is that it must be initialized. + +\section{Function Organization} + +The arithmetic functions of the library are all organized to have the same style prototype. That is source operands +are passed on the left and the destination is on the right. For instance, + +\begin{alltt} +mp_add(&a, &b, &c); /* c = a + b */ +mp_mul(&a, &a, &c); /* c = a * a */ +mp_div(&a, &b, &c, &d); /* c = [a/b], d = a mod b */ +\end{alltt} + +Another feature of the way the functions have been implemented is that source operands can be destination operands as well. +For instance, + +\begin{alltt} +mp_add(&a, &b, &b); /* b = a + b */ +mp_div(&a, &b, &a, &c); /* a = [a/b], c = a mod b */ +\end{alltt} + +This allows operands to be re-used which can make programming simpler. + +\section{Initialization} +\subsection{Single Initialization} +A single mp\_int can be initialized with the ``mp\_init'' function. + +\index{mp\_init} +\begin{alltt} +int mp_init (mp_int * a); +\end{alltt} + +This function expects a pointer to an mp\_int structure and will initialize the members of the structure so the mp\_int +represents the default integer which is zero. If the functions returns MP\_OKAY then the mp\_int is ready to be used +by the other LibTomMath functions. + +\begin{small} \begin{alltt} +int main(void) +\{ + mp_int number; + int result; + + if ((result = mp_init(&number)) != MP_OKAY) \{ + printf("Error initializing the number. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* use the number */ + + return EXIT_SUCCESS; +\} +\end{alltt} \end{small} + +\subsection{Single Free} +When you are finished with an mp\_int it is ideal to return the heap it used back to the system. The following function +provides this functionality. + +\index{mp\_clear} +\begin{alltt} +void mp_clear (mp_int * a); +\end{alltt} + +The function expects a pointer to a previously initialized mp\_int structure and frees the heap it uses. It sets the +pointer\footnote{The ``dp'' member.} within the mp\_int to \textbf{NULL} which is used to prevent double free situations. +Is is legal to call mp\_clear() twice on the same mp\_int in a row. + +\begin{small} \begin{alltt} +int main(void) +\{ + mp_int number; + int result; + + if ((result = mp_init(&number)) != MP_OKAY) \{ + printf("Error initializing the number. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* use the number */ + + /* We're done with it. */ + mp_clear(&number); + + return EXIT_SUCCESS; +\} +\end{alltt} \end{small} + +\subsection{Multiple Initializations} +Certain algorithms require more than one large integer. In these instances it is ideal to initialize all of the mp\_int +variables in an ``all or nothing'' fashion. That is, they are either all initialized successfully or they are all +not initialized. + +The mp\_init\_multi() function provides this functionality. + +\index{mp\_init\_multi} \index{mp\_clear\_multi} +\begin{alltt} +int mp_init_multi(mp_int *mp, ...); +\end{alltt} + +It accepts a \textbf{NULL} terminated list of pointers to mp\_int structures. It will attempt to initialize them all +at once. If the function returns MP\_OKAY then all of the mp\_int variables are ready to use, otherwise none of them +are available for use. A complementary mp\_clear\_multi() function allows multiple mp\_int variables to be free'd +from the heap at the same time. + +\begin{small} \begin{alltt} +int main(void) +\{ + mp_int num1, num2, num3; + int result; + + if ((result = mp_init_multi(&num1, + &num2, + &num3, NULL)) != MP\_OKAY) \{ + printf("Error initializing the numbers. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* use the numbers */ + + /* We're done with them. */ + mp_clear_multi(&num1, &num2, &num3, NULL); + + return EXIT_SUCCESS; +\} +\end{alltt} \end{small} + +\subsection{Other Initializers} +To initialized and make a copy of an mp\_int the mp\_init\_copy() function has been provided. + +\index{mp\_init\_copy} +\begin{alltt} +int mp_init_copy (mp_int * a, mp_int * b); +\end{alltt} + +This function will initialize $a$ and make it a copy of $b$ if all goes well. + +\begin{small} \begin{alltt} +int main(void) +\{ + mp_int num1, num2; + int result; + + /* initialize and do work on num1 ... */ + + /* We want a copy of num1 in num2 now */ + if ((result = mp_init_copy(&num2, &num1)) != MP_OKAY) \{ + printf("Error initializing the copy. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* now num2 is ready and contains a copy of num1 */ + + /* We're done with them. */ + mp_clear_multi(&num1, &num2, NULL); + + return EXIT_SUCCESS; +\} +\end{alltt} \end{small} + +Another less common initializer is mp\_init\_size() which allows the user to initialize an mp\_int with a given +default number of digits. By default, all initializers allocate \textbf{MP\_PREC} digits. This function lets +you override this behaviour. + +\index{mp\_init\_size} +\begin{alltt} +int mp_init_size (mp_int * a, int size); +\end{alltt} + +The $size$ parameter must be greater than zero. If the function succeeds the mp\_int $a$ will be initialized +to have $size$ digits (which are all initially zero). + +\begin{small} \begin{alltt} +int main(void) +\{ + mp_int number; + int result; + + /* we need a 60-digit number */ + if ((result = mp_init_size(&number, 60)) != MP_OKAY) \{ + printf("Error initializing the number. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* use the number */ + + return EXIT_SUCCESS; +\} +\end{alltt} \end{small} + +\section{Maintenance Functions} + +\subsection{Reducing Memory Usage} +When an mp\_int is in a state where it won't be changed again\footnote{A Diffie-Hellman modulus for instance.} excess +digits can be removed to return memory to the heap with the mp\_shrink() function. + +\index{mp\_shrink} +\begin{alltt} +int mp_shrink (mp_int * a); +\end{alltt} + +This will remove excess digits of the mp\_int $a$. If the operation fails the mp\_int should be intact without the +excess digits being removed. Note that you can use a shrunk mp\_int in further computations, however, such operations +will require heap operations which can be slow. It is not ideal to shrink mp\_int variables that you will further +modify in the system (unless you are seriously low on memory). + +\begin{small} \begin{alltt} +int main(void) +\{ + mp_int number; + int result; + + if ((result = mp_init(&number)) != MP_OKAY) \{ + printf("Error initializing the number. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* use the number [e.g. pre-computation] */ + + /* We're done with it for now. */ + if ((result = mp_shrink(&number)) != MP_OKAY) \{ + printf("Error shrinking the number. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* use it .... */ + + + /* we're done with it. */ + mp_clear(&number); + + return EXIT_SUCCESS; +\} +\end{alltt} \end{small} + +\subsection{Adding additional digits} + +Within the mp\_int structure are two parameters which control the limitations of the array of digits that represent +the integer the mp\_int is meant to equal. The \textit{used} parameter dictates how many digits are significant, that is, +contribute to the value of the mp\_int. The \textit{alloc} parameter dictates how many digits are currently available in +the array. If you need to perform an operation that requires more digits you will have to mp\_grow() the mp\_int to +your desired size. + +\index{mp\_grow} +\begin{alltt} +int mp_grow (mp_int * a, int size); +\end{alltt} + +This will grow the array of digits of $a$ to $size$. If the \textit{alloc} parameter is already bigger than +$size$ the function will not do anything. + +\begin{small} \begin{alltt} +int main(void) +\{ + mp_int number; + int result; + + if ((result = mp_init(&number)) != MP_OKAY) \{ + printf("Error initializing the number. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* use the number */ + + /* We need to add 20 digits to the number */ + if ((result = mp_grow(&number, number.alloc + 20)) != MP_OKAY) \{ + printf("Error growing the number. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + + /* use the number */ + + /* we're done with it. */ + mp_clear(&number); + + return EXIT_SUCCESS; +\} +\end{alltt} \end{small} + +\chapter{Basic Operations} +\section{Small Constants} +Setting mp\_ints to small constants is a relatively common operation. To accomodate these instances there are two +small constant assignment functions. The first function is used to set a single digit constant while the second sets +an ISO C style ``unsigned long'' constant. The reason for both functions is efficiency. Setting a single digit is quick but the +domain of a digit can change (it's always at least $0 \ldots 127$). + +\subsection{Single Digit} + +Setting a single digit can be accomplished with the following function. + +\index{mp\_set} +\begin{alltt} +void mp_set (mp_int * a, mp_digit b); +\end{alltt} + +This will zero the contents of $a$ and make it represent an integer equal to the value of $b$. Note that this +function has a return type of \textbf{void}. It cannot cause an error so it is safe to assume the function +succeeded. + +\begin{small} \begin{alltt} +int main(void) +\{ + mp_int number; + int result; + + if ((result = mp_init(&number)) != MP_OKAY) \{ + printf("Error initializing the number. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* set the number to 5 */ + mp_set(&number, 5); + + /* we're done with it. */ + mp_clear(&number); + + return EXIT_SUCCESS; +\} +\end{alltt} \end{small} + +\subsection{Long Constants} + +To set a constant that is the size of an ISO C ``unsigned long'' and larger than a single digit the following function +can be used. + +\index{mp\_set\_int} +\begin{alltt} +int mp_set_int (mp_int * a, unsigned long b); +\end{alltt} + +This will assign the value of the 32-bit variable $b$ to the mp\_int $a$. Unlike mp\_set() this function will always +accept a 32-bit input regardless of the size of a single digit. However, since the value may span several digits +this function can fail if it runs out of heap memory. + +To get the ``unsigned long'' copy of an mp\_int the following function can be used. + +\index{mp\_get\_int} +\begin{alltt} +unsigned long mp_get_int (mp_int * a); +\end{alltt} + +This will return the 32 least significant bits of the mp\_int $a$. + +\begin{small} \begin{alltt} +int main(void) +\{ + mp_int number; + int result; + + if ((result = mp_init(&number)) != MP_OKAY) \{ + printf("Error initializing the number. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* set the number to 654321 (note this is bigger than 127) */ + if ((result = mp_set_int(&number, 654321)) != MP_OKAY) \{ + printf("Error setting the value of the number. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + printf("number == \%lu", mp_get_int(&number)); + + /* we're done with it. */ + mp_clear(&number); + + return EXIT_SUCCESS; +\} +\end{alltt} \end{small} + +This should output the following if the program succeeds. + +\begin{alltt} +number == 654321 +\end{alltt} + +\subsection{Initialize and Setting Constants} +To both initialize and set small constants the following two functions are available. +\index{mp\_init\_set} \index{mp\_init\_set\_int} +\begin{alltt} +int mp_init_set (mp_int * a, mp_digit b); +int mp_init_set_int (mp_int * a, unsigned long b); +\end{alltt} + +Both functions work like the previous counterparts except they first mp\_init $a$ before setting the values. + +\begin{alltt} +int main(void) +\{ + mp_int number1, number2; + int result; + + /* initialize and set a single digit */ + if ((result = mp_init_set(&number1, 100)) != MP_OKAY) \{ + printf("Error setting number1: \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* initialize and set a long */ + if ((result = mp_init_set_int(&number2, 1023)) != MP_OKAY) \{ + printf("Error setting number2: \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* display */ + printf("Number1, Number2 == \%lu, \%lu", + mp_get_int(&number1), mp_get_int(&number2)); + + /* clear */ + mp_clear_multi(&number1, &number2, NULL); + + return EXIT_SUCCESS; +\} +\end{alltt} + +If this program succeeds it shall output. +\begin{alltt} +Number1, Number2 == 100, 1023 +\end{alltt} + +\section{Comparisons} + +Comparisons in LibTomMath are always performed in a ``left to right'' fashion. There are three possible return codes +for any comparison. + +\index{MP\_GT} \index{MP\_EQ} \index{MP\_LT} +\begin{figure}[here] +\begin{center} +\begin{tabular}{|c|c|} +\hline \textbf{Result Code} & \textbf{Meaning} \\ +\hline MP\_GT & $a > b$ \\ +\hline MP\_EQ & $a = b$ \\ +\hline MP\_LT & $a < b$ \\ +\hline +\end{tabular} +\end{center} +\caption{Comparison Codes for $a, b$} +\label{fig:CMP} +\end{figure} + +In figure \ref{fig:CMP} two integers $a$ and $b$ are being compared. In this case $a$ is said to be ``to the left'' of +$b$. + +\subsection{Unsigned comparison} + +An unsigned comparison considers only the digits themselves and not the associated \textit{sign} flag of the +mp\_int structures. This is analogous to an absolute comparison. The function mp\_cmp\_mag() will compare two +mp\_int variables based on their digits only. + +\index{mp\_cmp\_mag} +\begin{alltt} +int mp_cmp_mag(mp_int * a, mp_int * b); +\end{alltt} +This will compare $a$ to $b$ placing $a$ to the left of $b$. This function cannot fail and will return one of the +three compare codes listed in figure \ref{fig:CMP}. + +\begin{small} \begin{alltt} +int main(void) +\{ + mp_int number1, number2; + int result; + + if ((result = mp_init_multi(&number1, &number2, NULL)) != MP_OKAY) \{ + printf("Error initializing the numbers. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* set the number1 to 5 */ + mp_set(&number1, 5); + + /* set the number2 to -6 */ + mp_set(&number2, 6); + if ((result = mp_neg(&number2, &number2)) != MP_OKAY) \{ + printf("Error negating number2. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + switch(mp_cmp_mag(&number1, &number2)) \{ + case MP_GT: printf("|number1| > |number2|"); break; + case MP_EQ: printf("|number1| = |number2|"); break; + case MP_LT: printf("|number1| < |number2|"); break; + \} + + /* we're done with it. */ + mp_clear_multi(&number1, &number2, NULL); + + return EXIT_SUCCESS; +\} +\end{alltt} \end{small} + +If this program\footnote{This function uses the mp\_neg() function which is discussed in section \ref{sec:NEG}.} completes +successfully it should print the following. + +\begin{alltt} +|number1| < |number2| +\end{alltt} + +This is because $\vert -6 \vert = 6$ and obviously $5 < 6$. + +\subsection{Signed comparison} + +To compare two mp\_int variables based on their signed value the mp\_cmp() function is provided. + +\index{mp\_cmp} +\begin{alltt} +int mp_cmp(mp_int * a, mp_int * b); +\end{alltt} + +This will compare $a$ to the left of $b$. It will first compare the signs of the two mp\_int variables. If they +differ it will return immediately based on their signs. If the signs are equal then it will compare the digits +individually. This function will return one of the compare conditions codes listed in figure \ref{fig:CMP}. + +\begin{small} \begin{alltt} +int main(void) +\{ + mp_int number1, number2; + int result; + + if ((result = mp_init_multi(&number1, &number2, NULL)) != MP_OKAY) \{ + printf("Error initializing the numbers. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* set the number1 to 5 */ + mp_set(&number1, 5); + + /* set the number2 to -6 */ + mp_set(&number2, 6); + if ((result = mp_neg(&number2, &number2)) != MP_OKAY) \{ + printf("Error negating number2. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + switch(mp_cmp(&number1, &number2)) \{ + case MP_GT: printf("number1 > number2"); break; + case MP_EQ: printf("number1 = number2"); break; + case MP_LT: printf("number1 < number2"); break; + \} + + /* we're done with it. */ + mp_clear_multi(&number1, &number2, NULL); + + return EXIT_SUCCESS; +\} +\end{alltt} \end{small} + +If this program\footnote{This function uses the mp\_neg() function which is discussed in section \ref{sec:NEG}.} completes +successfully it should print the following. + +\begin{alltt} +number1 > number2 +\end{alltt} + +\subsection{Single Digit} + +To compare a single digit against an mp\_int the following function has been provided. + +\index{mp\_cmp\_d} +\begin{alltt} +int mp_cmp_d(mp_int * a, mp_digit b); +\end{alltt} + +This will compare $a$ to the left of $b$ using a signed comparison. Note that it will always treat $b$ as +positive. This function is rather handy when you have to compare against small values such as $1$ (which often +comes up in cryptography). The function cannot fail and will return one of the tree compare condition codes +listed in figure \ref{fig:CMP}. + + +\begin{small} \begin{alltt} +int main(void) +\{ + mp_int number; + int result; + + if ((result = mp_init(&number)) != MP_OKAY) \{ + printf("Error initializing the number. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* set the number to 5 */ + mp_set(&number, 5); + + switch(mp_cmp_d(&number, 7)) \{ + case MP_GT: printf("number > 7"); break; + case MP_EQ: printf("number = 7"); break; + case MP_LT: printf("number < 7"); break; + \} + + /* we're done with it. */ + mp_clear(&number); + + return EXIT_SUCCESS; +\} +\end{alltt} \end{small} + +If this program functions properly it will print out the following. + +\begin{alltt} +number < 7 +\end{alltt} + +\section{Logical Operations} + +Logical operations are operations that can be performed either with simple shifts or boolean operators such as +AND, XOR and OR directly. These operations are very quick. + +\subsection{Multiplication by two} + +Multiplications and divisions by any power of two can be performed with quick logical shifts either left or +right depending on the operation. + +When multiplying or dividing by two a special case routine can be used which are as follows. +\index{mp\_mul\_2} \index{mp\_div\_2} +\begin{alltt} +int mp_mul_2(mp_int * a, mp_int * b); +int mp_div_2(mp_int * a, mp_int * b); +\end{alltt} + +The former will assign twice $a$ to $b$ while the latter will assign half $a$ to $b$. These functions are fast +since the shift counts and maskes are hardcoded into the routines. + +\begin{small} \begin{alltt} +int main(void) +\{ + mp_int number; + int result; + + if ((result = mp_init(&number)) != MP_OKAY) \{ + printf("Error initializing the number. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* set the number to 5 */ + mp_set(&number, 5); + + /* multiply by two */ + if ((result = mp\_mul\_2(&number, &number)) != MP_OKAY) \{ + printf("Error multiplying the number. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + switch(mp_cmp_d(&number, 7)) \{ + case MP_GT: printf("2*number > 7"); break; + case MP_EQ: printf("2*number = 7"); break; + case MP_LT: printf("2*number < 7"); break; + \} + + /* now divide by two */ + if ((result = mp\_div\_2(&number, &number)) != MP_OKAY) \{ + printf("Error dividing the number. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + switch(mp_cmp_d(&number, 7)) \{ + case MP_GT: printf("2*number/2 > 7"); break; + case MP_EQ: printf("2*number/2 = 7"); break; + case MP_LT: printf("2*number/2 < 7"); break; + \} + + /* we're done with it. */ + mp_clear(&number); + + return EXIT_SUCCESS; +\} +\end{alltt} \end{small} + +If this program is successful it will print out the following text. + +\begin{alltt} +2*number > 7 +2*number/2 < 7 +\end{alltt} + +Since $10 > 7$ and $5 < 7$. To multiply by a power of two the following function can be used. + +\index{mp\_mul\_2d} +\begin{alltt} +int mp_mul_2d(mp_int * a, int b, mp_int * c); +\end{alltt} + +This will multiply $a$ by $2^b$ and store the result in ``c''. If the value of $b$ is less than or equal to +zero the function will copy $a$ to ``c'' without performing any further actions. + +To divide by a power of two use the following. + +\index{mp\_div\_2d} +\begin{alltt} +int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d); +\end{alltt} +Which will divide $a$ by $2^b$, store the quotient in ``c'' and the remainder in ``d'. If $b \le 0$ then the +function simply copies $a$ over to ``c'' and zeroes $d$. The variable $d$ may be passed as a \textbf{NULL} +value to signal that the remainder is not desired. + +\subsection{Polynomial Basis Operations} + +Strictly speaking the organization of the integers within the mp\_int structures is what is known as a +``polynomial basis''. This simply means a field element is stored by divisions of a radix. For example, if +$f(x) = \sum_{i=0}^{k} y_ix^k$ for any vector $\vec y$ then the array of digits in $\vec y$ are said to be +the polynomial basis representation of $z$ if $f(\beta) = z$ for a given radix $\beta$. + +To multiply by the polynomial $g(x) = x$ all you have todo is shift the digits of the basis left one place. The +following function provides this operation. + +\index{mp\_lshd} +\begin{alltt} +int mp_lshd (mp_int * a, int b); +\end{alltt} + +This will multiply $a$ in place by $x^b$ which is equivalent to shifting the digits left $b$ places and inserting zeroes +in the least significant digits. Similarly to divide by a power of $x$ the following function is provided. + +\index{mp\_rshd} +\begin{alltt} +void mp_rshd (mp_int * a, int b) +\end{alltt} +This will divide $a$ in place by $x^b$ and discard the remainder. This function cannot fail as it performs the operations +in place and no new digits are required to complete it. + +\subsection{AND, OR and XOR Operations} + +While AND, OR and XOR operations are not typical ``bignum functions'' they can be useful in several instances. The +three functions are prototyped as follows. + +\index{mp\_or} \index{mp\_and} \index{mp\_xor} +\begin{alltt} +int mp_or (mp_int * a, mp_int * b, mp_int * c); +int mp_and (mp_int * a, mp_int * b, mp_int * c); +int mp_xor (mp_int * a, mp_int * b, mp_int * c); +\end{alltt} + +Which compute $c = a \odot b$ where $\odot$ is one of OR, AND or XOR. + +\section{Addition and Subtraction} + +To compute an addition or subtraction the following two functions can be used. + +\index{mp\_add} \index{mp\_sub} +\begin{alltt} +int mp_add (mp_int * a, mp_int * b, mp_int * c); +int mp_sub (mp_int * a, mp_int * b, mp_int * c) +\end{alltt} + +Which perform $c = a \odot b$ where $\odot$ is one of signed addition or subtraction. The operations are fully sign +aware. + +\section{Sign Manipulation} +\subsection{Negation} +\label{sec:NEG} +Simple integer negation can be performed with the following. + +\index{mp\_neg} +\begin{alltt} +int mp_neg (mp_int * a, mp_int * b); +\end{alltt} + +Which assigns $-a$ to $b$. + +\subsection{Absolute} +Simple integer absolutes can be performed with the following. + +\index{mp\_neg} +\begin{alltt} +int mp_abs (mp_int * a, mp_int * b); +\end{alltt} + +Which assigns $\vert a \vert$ to $b$. + +\section{Integer Division and Remainder} +To perform a complete and general integer division with remainder use the following function. + +\index{mp\_div} +\begin{alltt} +int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d); +\end{alltt} + +This divides $a$ by $b$ and stores the quotient in $c$ and $d$. The signed quotient is computed such that +$bc + d = a$. Note that either of $c$ or $d$ can be set to \textbf{NULL} if their value is not required. If +$b$ is zero the function returns \textbf{MP\_VAL}. + + +\chapter{Multiplication and Squaring} +\section{Multiplication} +A full signed integer multiplication can be performed with the following. +\index{mp\_mul} +\begin{alltt} +int mp_mul (mp_int * a, mp_int * b, mp_int * c); +\end{alltt} +Which assigns the full signed product $ab$ to $c$. This function actually breaks into one of four cases which are +specific multiplication routines optimized for given parameters. First there are the Toom-Cook multiplications which +should only be used with very large inputs. This is followed by the Karatsuba multiplications which are for moderate +sized inputs. Then followed by the Comba and baseline multipliers. + +Fortunately for the developer you don't really need to know this unless you really want to fine tune the system. mp\_mul() +will determine on its own\footnote{Some tweaking may be required.} what routine to use automatically when it is called. + +\begin{alltt} +int main(void) +\{ + mp_int number1, number2; + int result; + + /* Initialize the numbers */ + if ((result = mp_init_multi(&number1, + &number2, NULL)) != MP_OKAY) \{ + printf("Error initializing the numbers. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* set the terms */ + if ((result = mp_set_int(&number, 257)) != MP_OKAY) \{ + printf("Error setting number1. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + if ((result = mp_set_int(&number2, 1023)) != MP_OKAY) \{ + printf("Error setting number2. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* multiply them */ + if ((result = mp_mul(&number1, &number2, + &number1)) != MP_OKAY) \{ + printf("Error multiplying terms. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* display */ + printf("number1 * number2 == \%lu", mp_get_int(&number1)); + + /* free terms and return */ + mp_clear_multi(&number1, &number2, NULL); + + return EXIT_SUCCESS; +\} +\end{alltt} + +If this program succeeds it shall output the following. + +\begin{alltt} +number1 * number2 == 262911 +\end{alltt} + +\section{Squaring} +Since squaring can be performed faster than multiplication it is performed it's own function instead of just using +mp\_mul(). + +\index{mp\_sqr} +\begin{alltt} +int mp_sqr (mp_int * a, mp_int * b); +\end{alltt} + +Will square $a$ and store it in $b$. Like the case of multiplication there are four different squaring +algorithms all which can be called from mp\_sqr(). It is ideal to use mp\_sqr over mp\_mul when squaring terms because +of the speed difference. + +\section{Tuning Polynomial Basis Routines} + +Both of the Toom-Cook and Karatsuba multiplication algorithms are faster than the traditional $O(n^2)$ approach that +the Comba and baseline algorithms use. At $O(n^{1.464973})$ and $O(n^{1.584962})$ running times respectively they require +considerably less work. For example, a 10000-digit multiplication would take roughly 724,000 single precision +multiplications with Toom-Cook or 100,000,000 single precision multiplications with the standard Comba (a factor +of 138). + +So why not always use Karatsuba or Toom-Cook? The simple answer is that they have so much overhead that they're not +actually faster than Comba until you hit distinct ``cutoff'' points. For Karatsuba with the default configuration, +GCC 3.3.1 and an Athlon XP processor the cutoff point is roughly 110 digits (about 70 for the Intel P4). That is, at +110 digits Karatsuba and Comba multiplications just about break even and for 110+ digits Karatsuba is faster. + +Toom-Cook has incredible overhead and is probably only useful for very large inputs. So far no known cutoff points +exist and for the most part I just set the cutoff points very high to make sure they're not called. + +A demo program in the ``etc/'' directory of the project called ``tune.c'' can be used to find the cutoff points. This +can be built with GCC as follows + +\begin{alltt} +make XXX +\end{alltt} +Where ``XXX'' is one of the following entries from the table \ref{fig:tuning}. + +\begin{figure}[here] +\begin{center} +\begin{small} +\begin{tabular}{|l|l|} +\hline \textbf{Value of XXX} & \textbf{Meaning} \\ +\hline tune & Builds portable tuning application \\ +\hline tune86 & Builds x86 (pentium and up) program for COFF \\ +\hline tune86c & Builds x86 program for Cygwin \\ +\hline tune86l & Builds x86 program for Linux (ELF format) \\ +\hline +\end{tabular} +\end{small} +\end{center} +\caption{Build Names for Tuning Programs} +\label{fig:tuning} +\end{figure} + +When the program is running it will output a series of measurements for different cutoff points. It will first find +good Karatsuba squaring and multiplication points. Then it proceeds to find Toom-Cook points. Note that the Toom-Cook +tuning takes a very long time as the cutoff points are likely to be very high. + +\chapter{Modular Reduction} + +Modular reduction is process of taking the remainder of one quantity divided by another. Expressed +as (\ref{eqn:mod}) the modular reduction is equivalent to the remainder of $b$ divided by $c$. + +\begin{equation} +a \equiv b \mbox{ (mod }c\mbox{)} +\label{eqn:mod} +\end{equation} + +Of particular interest to cryptography are reductions where $b$ is limited to the range $0 \le b < c^2$ since particularly +fast reduction algorithms can be written for the limited range. + +Note that one of the four optimized reduction algorithms are automatically chosen in the modular exponentiation +algorithm mp\_exptmod when an appropriate modulus is detected. + +\section{Straight Division} +In order to effect an arbitrary modular reduction the following algorithm is provided. + +\index{mp\_mod} +\begin{alltt} +int mp_mod(mp_int *a, mp_int *b, mp_int *c); +\end{alltt} + +This reduces $a$ modulo $b$ and stores the result in $c$. The sign of $c$ shall agree with the sign +of $b$. This algorithm accepts an input $a$ of any range and is not limited by $0 \le a < b^2$. + +\section{Barrett Reduction} + +Barrett reduction is a generic optimized reduction algorithm that requires pre--computation to achieve +a decent speedup over straight division. First a $\mu$ value must be precomputed with the following function. + +\index{mp\_reduce\_setup} +\begin{alltt} +int mp_reduce_setup(mp_int *a, mp_int *b); +\end{alltt} + +Given a modulus in $b$ this produces the required $\mu$ value in $a$. For any given modulus this only has to +be computed once. Modular reduction can now be performed with the following. + +\index{mp\_reduce} +\begin{alltt} +int mp_reduce(mp_int *a, mp_int *b, mp_int *c); +\end{alltt} + +This will reduce $a$ in place modulo $b$ with the precomputed $\mu$ value in $c$. $a$ must be in the range +$0 \le a < b^2$. + +\begin{alltt} +int main(void) +\{ + mp_int a, b, c, mu; + int result; + + /* initialize a,b to desired values, mp_init mu, + * c and set c to 1...we want to compute a^3 mod b + */ + + /* get mu value */ + if ((result = mp_reduce_setup(&mu, b)) != MP_OKAY) \{ + printf("Error getting mu. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* square a to get c = a^2 */ + if ((result = mp_sqr(&a, &c)) != MP_OKAY) \{ + printf("Error squaring. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* now reduce `c' modulo b */ + if ((result = mp_reduce(&c, &b, &mu)) != MP_OKAY) \{ + printf("Error reducing. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* multiply a to get c = a^3 */ + if ((result = mp_mul(&a, &c, &c)) != MP_OKAY) \{ + printf("Error reducing. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* now reduce `c' modulo b */ + if ((result = mp_reduce(&c, &b, &mu)) != MP_OKAY) \{ + printf("Error reducing. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* c now equals a^3 mod b */ + + return EXIT_SUCCESS; +\} +\end{alltt} + +This program will calculate $a^3 \mbox{ mod }b$ if all the functions succeed. + +\section{Montgomery Reduction} + +Montgomery is a specialized reduction algorithm for any odd moduli. Like Barrett reduction a pre--computation +step is required. This is accomplished with the following. + +\index{mp\_montgomery\_setup} +\begin{alltt} +int mp_montgomery_setup(mp_int *a, mp_digit *mp); +\end{alltt} + +For the given odd moduli $a$ the precomputation value is placed in $mp$. The reduction is computed with the +following. + +\index{mp\_montgomery\_reduce} +\begin{alltt} +int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp); +\end{alltt} +This reduces $a$ in place modulo $m$ with the pre--computed value $mp$. $a$ must be in the range +$0 \le a < b^2$. + +Montgomery reduction is faster than Barrett reduction for moduli smaller than the ``comba'' limit. With the default +setup for instance, the limit is $127$ digits ($3556$--bits). Note that this function is not limited to +$127$ digits just that it falls back to a baseline algorithm after that point. + +An important observation is that this reduction does not return $a \mbox{ mod }m$ but $aR^{-1} \mbox{ mod }m$ +where $R = \beta^n$, $n$ is the n number of digits in $m$ and $\beta$ is radix used (default is $2^{28}$). + +To quickly calculate $R$ the following function was provided. + +\index{mp\_montgomery\_calc\_normalization} +\begin{alltt} +int mp_montgomery_calc_normalization(mp_int *a, mp_int *b); +\end{alltt} +Which calculates $a = R$ for the odd moduli $b$ without using multiplication or division. + +The normal modus operandi for Montgomery reductions is to normalize the integers before entering the system. For +example, to calculate $a^3 \mbox { mod }b$ using Montgomery reduction the value of $a$ can be normalized by +multiplying it by $R$. Consider the following code snippet. + +\begin{alltt} +int main(void) +\{ + mp_int a, b, c, R; + mp_digit mp; + int result; + + /* initialize a,b to desired values, + * mp_init R, c and set c to 1.... + */ + + /* get normalization */ + if ((result = mp_montgomery_calc_normalization(&R, b)) != MP_OKAY) \{ + printf("Error getting norm. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* get mp value */ + if ((result = mp_montgomery_setup(&c, &mp)) != MP_OKAY) \{ + printf("Error setting up montgomery. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* normalize `a' so now a is equal to aR */ + if ((result = mp_mulmod(&a, &R, &b, &a)) != MP_OKAY) \{ + printf("Error computing aR. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* square a to get c = a^2R^2 */ + if ((result = mp_sqr(&a, &c)) != MP_OKAY) \{ + printf("Error squaring. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* now reduce `c' back down to c = a^2R^2 * R^-1 == a^2R */ + if ((result = mp_montgomery_reduce(&c, &b, mp)) != MP_OKAY) \{ + printf("Error reducing. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* multiply a to get c = a^3R^2 */ + if ((result = mp_mul(&a, &c, &c)) != MP_OKAY) \{ + printf("Error reducing. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* now reduce `c' back down to c = a^3R^2 * R^-1 == a^3R */ + if ((result = mp_montgomery_reduce(&c, &b, mp)) != MP_OKAY) \{ + printf("Error reducing. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* now reduce (again) `c' back down to c = a^3R * R^-1 == a^3 */ + if ((result = mp_montgomery_reduce(&c, &b, mp)) != MP_OKAY) \{ + printf("Error reducing. \%s", + mp_error_to_string(result)); + return EXIT_FAILURE; + \} + + /* c now equals a^3 mod b */ + + return EXIT_SUCCESS; +\} +\end{alltt} + +This particular example does not look too efficient but it demonstrates the point of the algorithm. By +normalizing the inputs the reduced results are always of the form $aR$ for some variable $a$. This allows +a single final reduction to correct for the normalization and the fast reduction used within the algorithm. + +For more details consider examining the file \textit{bn\_mp\_exptmod\_fast.c}. + +\section{Restricted Dimminished Radix} + +``Dimminished Radix'' reduction refers to reduction with respect to moduli that are ameniable to simple +digit shifting and small multiplications. In this case the ``restricted'' variant refers to moduli of the +form $\beta^k - p$ for some $k \ge 0$ and $0 < p < \beta$ where $\beta$ is the radix (default to $2^{28}$). + +As in the case of Montgomery reduction there is a pre--computation phase required for a given modulus. + +\index{mp\_dr\_setup} +\begin{alltt} +void mp_dr_setup(mp_int *a, mp_digit *d); +\end{alltt} + +This computes the value required for the modulus $a$ and stores it in $d$. This function cannot fail +and does not return any error codes. After the pre--computation a reduction can be performed with the +following. + +\index{mp\_dr\_reduce} +\begin{alltt} +int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp); +\end{alltt} + +This reduces $a$ in place modulo $b$ with the pre--computed value $mp$. $b$ must be of a restricted +dimminished radix form and $a$ must be in the range $0 \le a < b^2$. Dimminished radix reductions are +much faster than both Barrett and Montgomery reductions as they have a much lower asymtotic running time. + +Since the moduli are restricted this algorithm is not particularly useful for something like Rabin, RSA or +BBS cryptographic purposes. This reduction algorithm is useful for Diffie-Hellman and ECC where fixed +primes are acceptable. + +Note that unlike Montgomery reduction there is no normalization process. The result of this function is +equal to the correct residue. + +\section{Unrestricted Dimminshed Radix} + +Unrestricted reductions work much like the restricted counterparts except in this case the moduli is of the +form $2^k - p$ for $0 < p < \beta$. In this sense the unrestricted reductions are more flexible as they +can be applied to a wider range of numbers. + +\index{mp\_reduce\_2k\_setup} +\begin{alltt} +int mp_reduce_2k_setup(mp_int *a, mp_digit *d); +\end{alltt} + +This will compute the required $d$ value for the given moduli $a$. + +\index{mp\_reduce\_2k} +\begin{alltt} +int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d); +\end{alltt} + +This will reduce $a$ in place modulo $n$ with the pre--computed value $d$. From my experience this routine is +slower than mp\_dr\_reduce but faster for most moduli sizes than the Montgomery reduction. + +\chapter{Exponentiation} +\section{Single Digit Exponentiation} +\index{mp\_expt\_d} +\begin{alltt} +int mp_expt_d (mp_int * a, mp_digit b, mp_int * c) +\end{alltt} +This computes $c = a^b$ using a simple binary left-to-right algorithm. It is faster than repeated multiplications by +$a$ for all values of $b$ greater than three. + +\section{Modular Exponentiation} +\index{mp\_exptmod} +\begin{alltt} +int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) +\end{alltt} +This computes $Y \equiv G^X \mbox{ (mod }P\mbox{)}$ using a variable width sliding window algorithm. This function +will automatically detect the fastest modular reduction technique to use during the operation. For negative values of +$X$ the operation is performed as $Y \equiv (G^{-1} \mbox{ mod }P)^{\vert X \vert} \mbox{ (mod }P\mbox{)}$ provided that +$gcd(G, P) = 1$. + +This function is actually a shell around the two internal exponentiation functions. This routine will automatically +detect when Barrett, Montgomery, Restricted and Unrestricted Dimminished Radix based exponentiation can be used. Generally +moduli of the a ``restricted dimminished radix'' form lead to the fastest modular exponentiations. Followed by Montgomery +and the other two algorithms. + +\section{Root Finding} +\index{mp\_n\_root} +\begin{alltt} +int mp_n_root (mp_int * a, mp_digit b, mp_int * c) +\end{alltt} +This computes $c = a^{1/b}$ such that $c^b \le a$ and $(c+1)^b > a$. The implementation of this function is not +ideal for values of $b$ greater than three. It will work but become very slow. So unless you are working with very small +numbers (less than 1000 bits) I'd avoid $b > 3$ situations. Will return a positive root only for even roots and return +a root with the sign of the input for odd roots. For example, performing $4^{1/2}$ will return $2$ whereas $(-8)^{1/3}$ +will return $-2$. + +This algorithm uses the ``Newton Approximation'' method and will converge on the correct root fairly quickly. Since +the algorithm requires raising $a$ to the power of $b$ it is not ideal to attempt to find roots for large +values of $b$. If particularly large roots are required then a factor method could be used instead. For example, +$a^{1/16}$ is equivalent to $\left (a^{1/4} \right)^{1/4}$ or simply +$\left ( \left ( \left ( a^{1/2} \right )^{1/2} \right )^{1/2} \right )^{1/2}$ + +\chapter{Prime Numbers} +\section{Trial Division} +\index{mp\_prime\_is\_divisible} +\begin{alltt} +int mp_prime_is_divisible (mp_int * a, int *result) +\end{alltt} +This will attempt to evenly divide $a$ by a list of primes\footnote{Default is the first 256 primes.} and store the +outcome in ``result''. That is if $result = 0$ then $a$ is not divisible by the primes, otherwise it is. Note that +if the function does not return \textbf{MP\_OKAY} the value in ``result'' should be considered undefined\footnote{Currently +the default is to set it to zero first.}. + +\section{Fermat Test} +\index{mp\_prime\_fermat} +\begin{alltt} +int mp_prime_fermat (mp_int * a, mp_int * b, int *result) +\end{alltt} +Performs a Fermat primality test to the base $b$. That is it computes $b^a \mbox{ mod }a$ and tests whether the value is +equal to $b$ or not. If the values are equal then $a$ is probably prime and $result$ is set to one. Otherwise $result$ +is set to zero. + +\section{Miller-Rabin Test} +\index{mp\_prime\_miller\_rabin} +\begin{alltt} +int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result) +\end{alltt} +Performs a Miller-Rabin test to the base $b$ of $a$. This test is much stronger than the Fermat test and is very hard to +fool (besides with Carmichael numbers). If $a$ passes the test (therefore is probably prime) $result$ is set to one. +Otherwise $result$ is set to zero. + +Note that is suggested that you use the Miller-Rabin test instead of the Fermat test since all of the failures of +Miller-Rabin are a subset of the failures of the Fermat test. + +\subsection{Required Number of Tests} +Generally to ensure a number is very likely to be prime you have to perform the Miller-Rabin with at least a half-dozen +or so unique bases. However, it has been proven that the probability of failure goes down as the size of the input goes up. +This is why a simple function has been provided to help out. + +\index{mp\_prime\_rabin\_miller\_trials} +\begin{alltt} +int mp_prime_rabin_miller_trials(int size) +\end{alltt} +This returns the number of trials required for a $2^{-96}$ (or lower) probability of failure for a given ``size'' expressed +in bits. This comes in handy specially since larger numbers are slower to test. For example, a 512-bit number would +require ten tests whereas a 1024-bit number would only require four tests. + +You should always still perform a trial division before a Miller-Rabin test though. + +\section{Primality Testing} +\index{mp\_prime\_is\_prime} +\begin{alltt} +int mp_prime_is_prime (mp_int * a, int t, int *result) +\end{alltt} +This will perform a trial division followed by $t$ rounds of Miller-Rabin tests on $a$ and store the result in $result$. +If $a$ passes all of the tests $result$ is set to one, otherwise it is set to zero. Note that $t$ is bounded by +$1 \le t < PRIME\_SIZE$ where $PRIME\_SIZE$ is the number of primes in the prime number table (by default this is $256$). + +\section{Next Prime} +\index{mp\_prime\_next\_prime} +\begin{alltt} +int mp_prime_next_prime(mp_int *a, int t, int bbs_style) +\end{alltt} +This finds the next prime after $a$ that passes mp\_prime\_is\_prime() with $t$ tests. Set $bbs\_style$ to one if you +want only the next prime congruent to $3 \mbox{ mod } 4$, otherwise set it to zero to find any next prime. + +\section{Random Primes} +\index{mp\_prime\_random} +\begin{alltt} +int mp_prime_random(mp_int *a, int t, int size, int bbs, + ltm_prime_callback cb, void *dat) +\end{alltt} +This will find a prime greater than $256^{size}$ which can be ``bbs\_style'' or not depending on $bbs$ and must pass +$t$ rounds of tests. The ``ltm\_prime\_callback'' is a typedef for + +\begin{alltt} +typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat); +\end{alltt} + +Which is a function that must read $len$ bytes (and return the amount stored) into $dst$. The $dat$ variable is simply +copied from the original input. It can be used to pass RNG context data to the callback. The function +mp\_prime\_random() is more suitable for generating primes which must be secret (as in the case of RSA) since there +is no skew on the least significant bits. + +\textit{Note:} As of v0.30 of the LibTomMath library this function has been deprecated. It is still available +but users are encouraged to use the new mp\_prime\_random\_ex() function instead. + +\subsection{Extended Generation} +\index{mp\_prime\_random\_ex} +\begin{alltt} +int mp_prime_random_ex(mp_int *a, int t, + int size, int flags, + ltm_prime_callback cb, void *dat); +\end{alltt} +This will generate a prime in $a$ using $t$ tests of the primality testing algorithms. The variable $size$ +specifies the bit length of the prime desired. The variable $flags$ specifies one of several options available +(see fig. \ref{fig:primeopts}) which can be OR'ed together. The callback parameters are used as in +mp\_prime\_random(). + +\begin{figure}[here] +\begin{center} +\begin{small} +\begin{tabular}{|r|l|} +\hline \textbf{Flag} & \textbf{Meaning} \\ +\hline LTM\_PRIME\_BBS & Make the prime congruent to $3$ modulo $4$ \\ +\hline LTM\_PRIME\_SAFE & Make a prime $p$ such that $(p - 1)/2$ is also prime. \\ + & This option implies LTM\_PRIME\_BBS as well. \\ +\hline LTM\_PRIME\_2MSB\_OFF & Makes sure that the bit adjacent to the most significant bit \\ + & Is forced to zero. \\ +\hline LTM\_PRIME\_2MSB\_ON & Makes sure that the bit adjacent to the most significant bit \\ + & Is forced to one. \\ +\hline +\end{tabular} +\end{small} +\end{center} +\caption{Primality Generation Options} +\label{fig:primeopts} +\end{figure} + +\chapter{Input and Output} +\section{ASCII Conversions} +\subsection{To ASCII} +\index{mp\_toradix} +\begin{alltt} +int mp_toradix (mp_int * a, char *str, int radix); +\end{alltt} +This still store $a$ in ``str'' as a base-``radix'' string of ASCII chars. This function appends a NUL character +to terminate the string. Valid values of ``radix'' line in the range $[2, 64]$. To determine the size (exact) required +by the conversion before storing any data use the following function. + +\index{mp\_radix\_size} +\begin{alltt} +int mp_radix_size (mp_int * a, int radix, int *size) +\end{alltt} +This stores in ``size'' the number of characters (including space for the NUL terminator) required. Upon error this +function returns an error code and ``size'' will be zero. + +\subsection{From ASCII} +\index{mp\_read\_radix} +\begin{alltt} +int mp_read_radix (mp_int * a, char *str, int radix); +\end{alltt} +This will read the base-``radix'' NUL terminated string from ``str'' into $a$. It will stop reading when it reads a +character it does not recognize (which happens to include th NUL char... imagine that...). A single leading $-$ sign +can be used to denote a negative number. + +\section{Binary Conversions} + +Converting an mp\_int to and from binary is another keen idea. + +\index{mp\_unsigned\_bin\_size} +\begin{alltt} +int mp_unsigned_bin_size(mp_int *a); +\end{alltt} + +This will return the number of bytes (octets) required to store the unsigned copy of the integer $a$. + +\index{mp\_to\_unsigned\_bin} +\begin{alltt} +int mp_to_unsigned_bin(mp_int *a, unsigned char *b); +\end{alltt} +This will store $a$ into the buffer $b$ in big--endian format. Fortunately this is exactly what DER (or is it ASN?) +requires. It does not store the sign of the integer. + +\index{mp\_read\_unsigned\_bin} +\begin{alltt} +int mp_read_unsigned_bin(mp_int *a, unsigned char *b, int c); +\end{alltt} +This will read in an unsigned big--endian array of bytes (octets) from $b$ of length $c$ into $a$. The resulting +integer $a$ will always be positive. + +For those who acknowledge the existence of negative numbers (heretic!) there are ``signed'' versions of the +previous functions. + +\begin{alltt} +int mp_signed_bin_size(mp_int *a); +int mp_read_signed_bin(mp_int *a, unsigned char *b, int c); +int mp_to_signed_bin(mp_int *a, unsigned char *b); +\end{alltt} +They operate essentially the same as the unsigned copies except they prefix the data with zero or non--zero +byte depending on the sign. If the sign is zpos (e.g. not negative) the prefix is zero, otherwise the prefix +is non--zero. + +\chapter{Algebraic Functions} +\section{Extended Euclidean Algorithm} +\index{mp\_exteuclid} +\begin{alltt} +int mp_exteuclid(mp_int *a, mp_int *b, + mp_int *U1, mp_int *U2, mp_int *U3); +\end{alltt} + +This finds the triple U1/U2/U3 using the Extended Euclidean algorithm such that the following equation holds. + +\begin{equation} +a \cdot U1 + b \cdot U2 = U3 +\end{equation} + +Any of the U1/U2/U3 paramters can be set to \textbf{NULL} if they are not desired. + +\section{Greatest Common Divisor} +\index{mp\_gcd} +\begin{alltt} +int mp_gcd (mp_int * a, mp_int * b, mp_int * c) +\end{alltt} +This will compute the greatest common divisor of $a$ and $b$ and store it in $c$. + +\section{Least Common Multiple} +\index{mp\_lcm} +\begin{alltt} +int mp_lcm (mp_int * a, mp_int * b, mp_int * c) +\end{alltt} +This will compute the least common multiple of $a$ and $b$ and store it in $c$. + +\section{Jacobi Symbol} +\index{mp\_jacobi} +\begin{alltt} +int mp_jacobi (mp_int * a, mp_int * p, int *c) +\end{alltt} +This will compute the Jacobi symbol for $a$ with respect to $p$. If $p$ is prime this essentially computes the Legendre +symbol. The result is stored in $c$ and can take on one of three values $\lbrace -1, 0, 1 \rbrace$. If $p$ is prime +then the result will be $-1$ when $a$ is not a quadratic residue modulo $p$. The result will be $0$ if $a$ divides $p$ +and the result will be $1$ if $a$ is a quadratic residue modulo $p$. + +\section{Modular Inverse} +\index{mp\_invmod} +\begin{alltt} +int mp_invmod (mp_int * a, mp_int * b, mp_int * c) +\end{alltt} +Computes the multiplicative inverse of $a$ modulo $b$ and stores the result in $c$ such that $ac \equiv 1 \mbox{ (mod }b\mbox{)}$. + +\section{Single Digit Functions} + +For those using small numbers (\textit{snicker snicker}) there are several ``helper'' functions + +\index{mp\_add\_d} \index{mp\_sub\_d} \index{mp\_mul\_d} \index{mp\_div\_d} \index{mp\_mod\_d} +\begin{alltt} +int mp_add_d(mp_int *a, mp_digit b, mp_int *c); +int mp_sub_d(mp_int *a, mp_digit b, mp_int *c); +int mp_mul_d(mp_int *a, mp_digit b, mp_int *c); +int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d); +int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c); +\end{alltt} + +These work like the full mp\_int capable variants except the second parameter $b$ is a mp\_digit. These +functions fairly handy if you have to work with relatively small numbers since you will not have to allocate +an entire mp\_int to store a number like $1$ or $2$. + +\input{bn.ind} + +\end{document} diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_error.c b/xmhf-64/xmhf/third-party/libtommath/bn_error.c new file mode 100644 index 0000000000..250057bf43 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_error.c @@ -0,0 +1,47 @@ +#include +#ifdef BN_ERROR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +static const struct { + int code; + char *msg; +} msgs[] = { + { MP_OKAY, "Successful" }, + { MP_MEM, "Out of heap" }, + { MP_VAL, "Value out of range" } +}; + +/* return a char * string for a given code */ +char *mp_error_to_string(int code) +{ + int x; + + /* scan the lookup table for the given message */ + for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) { + if (msgs[x].code == code) { + return msgs[x].msg; + } + } + + /* generic reply for invalid code */ + return "Invalid error code"; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_fast_mp_invmod.c b/xmhf-64/xmhf/third-party/libtommath/bn_fast_mp_invmod.c new file mode 100644 index 0000000000..08eba1f93b --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_fast_mp_invmod.c @@ -0,0 +1,148 @@ +#include +#ifdef BN_FAST_MP_INVMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* computes the modular inverse via binary extended euclidean algorithm, + * that is c = 1/a mod b + * + * Based on slow invmod except this is optimized for the case where b is + * odd as per HAC Note 14.64 on pp. 610 + */ +int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int x, y, u, v, B, D; + int res, neg; + + /* 2. [modified] b must be odd */ + if (mp_iseven (b) == 1) { + return MP_VAL; + } + + /* init all our temps */ + if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) { + return res; + } + + /* x == modulus, y == value to invert */ + if ((res = mp_copy (b, &x)) != MP_OKAY) { + goto LBL_ERR; + } + + /* we need y = |a| */ + if ((res = mp_mod (a, b, &y)) != MP_OKAY) { + goto LBL_ERR; + } + + /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ + if ((res = mp_copy (&x, &u)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_copy (&y, &v)) != MP_OKAY) { + goto LBL_ERR; + } + mp_set (&D, 1); + +top: + /* 4. while u is even do */ + while (mp_iseven (&u) == 1) { + /* 4.1 u = u/2 */ + if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { + goto LBL_ERR; + } + /* 4.2 if B is odd then */ + if (mp_isodd (&B) == 1) { + if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* B = B/2 */ + if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 5. while v is even do */ + while (mp_iseven (&v) == 1) { + /* 5.1 v = v/2 */ + if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { + goto LBL_ERR; + } + /* 5.2 if D is odd then */ + if (mp_isodd (&D) == 1) { + /* D = (D-x)/2 */ + if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* D = D/2 */ + if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 6. if u >= v then */ + if (mp_cmp (&u, &v) != MP_LT) { + /* u = u - v, B = B - D */ + if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } else { + /* v - v - u, D = D - B */ + if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* if not zero goto step 4 */ + if (mp_iszero (&u) == 0) { + goto top; + } + + /* now a = C, b = D, gcd == g*v */ + + /* if v != 1 then there is no inverse */ + if (mp_cmp_d (&v, 1) != MP_EQ) { + res = MP_VAL; + goto LBL_ERR; + } + + /* b is now the inverse */ + neg = a->sign; + while (D.sign == MP_NEG) { + if ((res = mp_add (&D, b, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + mp_exch (&D, c); + c->sign = neg; + res = MP_OKAY; + +LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_fast_mp_montgomery_reduce.c b/xmhf-64/xmhf/third-party/libtommath/bn_fast_mp_montgomery_reduce.c new file mode 100644 index 0000000000..1a816895f3 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_fast_mp_montgomery_reduce.c @@ -0,0 +1,172 @@ +#include +#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* computes xR**-1 == x (mod N) via Montgomery Reduction + * + * This is an optimized implementation of montgomery_reduce + * which uses the comba method to quickly calculate the columns of the + * reduction. + * + * Based on Algorithm 14.32 on pp.601 of HAC. +*/ +int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) +{ + int ix, res, olduse; + mp_word W[MP_WARRAY]; + + /* get old used count */ + olduse = x->used; + + /* grow a as required */ + if (x->alloc < n->used + 1) { + if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) { + return res; + } + } + + /* first we have to get the digits of the input into + * an array of double precision words W[...] + */ + { + register mp_word *_W; + register mp_digit *tmpx; + + /* alias for the W[] array */ + _W = W; + + /* alias for the digits of x*/ + tmpx = x->dp; + + /* copy the digits of a into W[0..a->used-1] */ + for (ix = 0; ix < x->used; ix++) { + *_W++ = *tmpx++; + } + + /* zero the high words of W[a->used..m->used*2] */ + for (; ix < n->used * 2 + 1; ix++) { + *_W++ = 0; + } + } + + /* now we proceed to zero successive digits + * from the least significant upwards + */ + for (ix = 0; ix < n->used; ix++) { + /* mu = ai * m' mod b + * + * We avoid a double precision multiplication (which isn't required) + * by casting the value down to a mp_digit. Note this requires + * that W[ix-1] have the carry cleared (see after the inner loop) + */ + register mp_digit mu; + mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK); + + /* a = a + mu * m * b**i + * + * This is computed in place and on the fly. The multiplication + * by b**i is handled by offseting which columns the results + * are added to. + * + * Note the comba method normally doesn't handle carries in the + * inner loop In this case we fix the carry from the previous + * column since the Montgomery reduction requires digits of the + * result (so far) [see above] to work. This is + * handled by fixing up one carry after the inner loop. The + * carry fixups are done in order so after these loops the + * first m->used words of W[] have the carries fixed + */ + { + register int iy; + register mp_digit *tmpn; + register mp_word *_W; + + /* alias for the digits of the modulus */ + tmpn = n->dp; + + /* Alias for the columns set by an offset of ix */ + _W = W + ix; + + /* inner loop */ + for (iy = 0; iy < n->used; iy++) { + *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++); + } + } + + /* now fix carry for next digit, W[ix+1] */ + W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT); + } + + /* now we have to propagate the carries and + * shift the words downward [all those least + * significant digits we zeroed]. + */ + { + register mp_digit *tmpx; + register mp_word *_W, *_W1; + + /* nox fix rest of carries */ + + /* alias for current word */ + _W1 = W + ix; + + /* alias for next word, where the carry goes */ + _W = W + ++ix; + + for (; ix <= n->used * 2 + 1; ix++) { + *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT); + } + + /* copy out, A = A/b**n + * + * The result is A/b**n but instead of converting from an + * array of mp_word to mp_digit than calling mp_rshd + * we just copy them in the right order + */ + + /* alias for destination word */ + tmpx = x->dp; + + /* alias for shifted double precision result */ + _W = W + n->used; + + for (ix = 0; ix < n->used + 1; ix++) { + *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK)); + } + + /* zero oldused digits, if the input a was larger than + * m->used+1 we'll have to clear the digits + */ + for (; ix < olduse; ix++) { + *tmpx++ = 0; + } + } + + /* set the max used and clamp */ + x->used = n->used + 1; + mp_clamp (x); + + /* if A >= m then A = A - m */ + if (mp_cmp_mag (x, n) != MP_LT) { + return s_mp_sub (x, n, x); + } + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_fast_s_mp_mul_digs.c b/xmhf-64/xmhf/third-party/libtommath/bn_fast_s_mp_mul_digs.c new file mode 100644 index 0000000000..53fe4fe87f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_fast_s_mp_mul_digs.c @@ -0,0 +1,107 @@ +#include +#ifdef BN_FAST_S_MP_MUL_DIGS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Fast (comba) multiplier + * + * This is the fast column-array [comba] multiplier. It is + * designed to compute the columns of the product first + * then handle the carries afterwards. This has the effect + * of making the nested loops that compute the columns very + * simple and schedulable on super-scalar processors. + * + * This has been modified to produce a variable number of + * digits of output so if say only a half-product is required + * you don't have to compute the upper half (a feature + * required for fast Barrett reduction). + * + * Based on Algorithm 14.12 on pp.595 of HAC. + * + */ +int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + int olduse, res, pa, ix, iz; + mp_digit W[MP_WARRAY]; + register mp_word _W; + + /* grow the destination as required */ + if (c->alloc < digs) { + if ((res = mp_grow (c, digs)) != MP_OKAY) { + return res; + } + } + + /* number of output digits to produce */ + pa = MIN(digs, a->used + b->used); + + /* clear the carry */ + _W = 0; + for (ix = 0; ix < pa; ix++) { + int tx, ty; + int iy; + mp_digit *tmpx, *tmpy; + + /* get offsets into the two bignums */ + ty = MIN(b->used-1, ix); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = b->dp + ty; + + /* this is the number of times the loop will iterrate, essentially + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MIN(a->used-tx, ty+1); + + /* execute loop */ + for (iz = 0; iz < iy; ++iz) { + _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); + + } + + /* store term */ + W[ix] = ((mp_digit)_W) & MP_MASK; + + /* make next carry */ + _W = _W >> ((mp_word)DIGIT_BIT); + } + + /* setup dest */ + olduse = c->used; + c->used = pa; + + { + register mp_digit *tmpc; + tmpc = c->dp; + for (ix = 0; ix < pa+1; ix++) { + /* now extract the previous digit [below the carry] */ + *tmpc++ = W[ix]; + } + + /* clear unused digits [that existed in the old copy of c] */ + for (; ix < olduse; ix++) { + *tmpc++ = 0; + } + } + mp_clamp (c); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_fast_s_mp_mul_high_digs.c b/xmhf-64/xmhf/third-party/libtommath/bn_fast_s_mp_mul_high_digs.c new file mode 100644 index 0000000000..3e9d0825a0 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_fast_s_mp_mul_high_digs.c @@ -0,0 +1,98 @@ +#include +#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* this is a modified version of fast_s_mul_digs that only produces + * output digits *above* digs. See the comments for fast_s_mul_digs + * to see how it works. + * + * This is used in the Barrett reduction since for one of the multiplications + * only the higher digits were needed. This essentially halves the work. + * + * Based on Algorithm 14.12 on pp.595 of HAC. + */ +int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + int olduse, res, pa, ix, iz; + mp_digit W[MP_WARRAY]; + mp_word _W; + + /* grow the destination as required */ + pa = a->used + b->used; + if (c->alloc < pa) { + if ((res = mp_grow (c, pa)) != MP_OKAY) { + return res; + } + } + + /* number of output digits to produce */ + pa = a->used + b->used; + _W = 0; + for (ix = digs; ix < pa; ix++) { + int tx, ty, iy; + mp_digit *tmpx, *tmpy; + + /* get offsets into the two bignums */ + ty = MIN(b->used-1, ix); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = b->dp + ty; + + /* this is the number of times the loop will iterrate, essentially its + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MIN(a->used-tx, ty+1); + + /* execute loop */ + for (iz = 0; iz < iy; iz++) { + _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); + } + + /* store term */ + W[ix] = ((mp_digit)_W) & MP_MASK; + + /* make next carry */ + _W = _W >> ((mp_word)DIGIT_BIT); + } + + /* setup dest */ + olduse = c->used; + c->used = pa; + + { + register mp_digit *tmpc; + + tmpc = c->dp + digs; + for (ix = digs; ix < pa; ix++) { + /* now extract the previous digit [below the carry] */ + *tmpc++ = W[ix]; + } + + /* clear unused digits [that existed in the old copy of c] */ + for (; ix < olduse; ix++) { + *tmpc++ = 0; + } + } + mp_clamp (c); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_fast_s_mp_sqr.c b/xmhf-64/xmhf/third-party/libtommath/bn_fast_s_mp_sqr.c new file mode 100644 index 0000000000..893d14318a --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_fast_s_mp_sqr.c @@ -0,0 +1,114 @@ +#include +#ifdef BN_FAST_S_MP_SQR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* the jist of squaring... + * you do like mult except the offset of the tmpx [one that + * starts closer to zero] can't equal the offset of tmpy. + * So basically you set up iy like before then you min it with + * (ty-tx) so that it never happens. You double all those + * you add in the inner loop + +After that loop you do the squares and add them in. +*/ + +int fast_s_mp_sqr (mp_int * a, mp_int * b) +{ + int olduse, res, pa, ix, iz; + mp_digit W[MP_WARRAY], *tmpx; + mp_word W1; + + /* grow the destination as required */ + pa = a->used + a->used; + if (b->alloc < pa) { + if ((res = mp_grow (b, pa)) != MP_OKAY) { + return res; + } + } + + /* number of output digits to produce */ + W1 = 0; + for (ix = 0; ix < pa; ix++) { + int tx, ty, iy; + mp_word _W; + mp_digit *tmpy; + + /* clear counter */ + _W = 0; + + /* get offsets into the two bignums */ + ty = MIN(a->used-1, ix); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = a->dp + ty; + + /* this is the number of times the loop will iterrate, essentially + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MIN(a->used-tx, ty+1); + + /* now for squaring tx can never equal ty + * we halve the distance since they approach at a rate of 2x + * and we have to round because odd cases need to be executed + */ + iy = MIN(iy, (ty-tx+1)>>1); + + /* execute loop */ + for (iz = 0; iz < iy; iz++) { + _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); + } + + /* double the inner product and add carry */ + _W = _W + _W + W1; + + /* even columns have the square term in them */ + if ((ix&1) == 0) { + _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]); + } + + /* store it */ + W[ix] = (mp_digit)(_W & MP_MASK); + + /* make next carry */ + W1 = _W >> ((mp_word)DIGIT_BIT); + } + + /* setup dest */ + olduse = b->used; + b->used = a->used+a->used; + + { + mp_digit *tmpb; + tmpb = b->dp; + for (ix = 0; ix < pa; ix++) { + *tmpb++ = W[ix] & MP_MASK; + } + + /* clear unused digits [that existed in the old copy of c] */ + for (; ix < olduse; ix++) { + *tmpb++ = 0; + } + } + mp_clamp (b); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_2expt.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_2expt.c new file mode 100644 index 0000000000..a422daba35 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_2expt.c @@ -0,0 +1,48 @@ +#include +#ifdef BN_MP_2EXPT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* computes a = 2**b + * + * Simple algorithm which zeroes the int, grows it then just sets one bit + * as required. + */ +int +mp_2expt (mp_int * a, int b) +{ + int res; + + /* zero a as per default */ + mp_zero (a); + + /* grow a to accomodate the single bit */ + if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) { + return res; + } + + /* set the used count of where the bit will go */ + a->used = b / DIGIT_BIT + 1; + + /* put the single bit in its place */ + a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT); + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_abs.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_abs.c new file mode 100644 index 0000000000..215cc22915 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_abs.c @@ -0,0 +1,43 @@ +#include +#ifdef BN_MP_ABS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* b = |a| + * + * Simple function copies the input and fixes the sign to positive + */ +int +mp_abs (mp_int * a, mp_int * b) +{ + int res; + + /* copy a to b */ + if (a != b) { + if ((res = mp_copy (a, b)) != MP_OKAY) { + return res; + } + } + + /* force the sign of b to positive */ + b->sign = MP_ZPOS; + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_add.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_add.c new file mode 100644 index 0000000000..122c8501dc --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_add.c @@ -0,0 +1,53 @@ +#include +#ifdef BN_MP_ADD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* high level addition (handles signs) */ +int mp_add (mp_int * a, mp_int * b, mp_int * c) +{ + int sa, sb, res; + + /* get sign of both inputs */ + sa = a->sign; + sb = b->sign; + + /* handle two cases, not four */ + if (sa == sb) { + /* both positive or both negative */ + /* add their magnitudes, copy the sign */ + c->sign = sa; + res = s_mp_add (a, b, c); + } else { + /* one positive, the other negative */ + /* subtract the one with the greater magnitude from */ + /* the one of the lesser magnitude. The result gets */ + /* the sign of the one with the greater magnitude. */ + if (mp_cmp_mag (a, b) == MP_LT) { + c->sign = sb; + res = s_mp_sub (b, a, c); + } else { + c->sign = sa; + res = s_mp_sub (a, b, c); + } + } + return res; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_add_d.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_add_d.c new file mode 100644 index 0000000000..aec8fc8923 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_add_d.c @@ -0,0 +1,112 @@ +#include +#ifdef BN_MP_ADD_D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* single digit addition */ +int +mp_add_d (mp_int * a, mp_digit b, mp_int * c) +{ + int res, ix, oldused; + mp_digit *tmpa, *tmpc, mu; + + /* grow c as required */ + if (c->alloc < a->used + 1) { + if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* if a is negative and |a| >= b, call c = |a| - b */ + if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) { + /* temporarily fix sign of a */ + a->sign = MP_ZPOS; + + /* c = |a| - b */ + res = mp_sub_d(a, b, c); + + /* fix sign */ + a->sign = c->sign = MP_NEG; + + /* clamp */ + mp_clamp(c); + + return res; + } + + /* old number of used digits in c */ + oldused = c->used; + + /* sign always positive */ + c->sign = MP_ZPOS; + + /* source alias */ + tmpa = a->dp; + + /* destination alias */ + tmpc = c->dp; + + /* if a is positive */ + if (a->sign == MP_ZPOS) { + /* add digit, after this we're propagating + * the carry. + */ + *tmpc = *tmpa++ + b; + mu = *tmpc >> DIGIT_BIT; + *tmpc++ &= MP_MASK; + + /* now handle rest of the digits */ + for (ix = 1; ix < a->used; ix++) { + *tmpc = *tmpa++ + mu; + mu = *tmpc >> DIGIT_BIT; + *tmpc++ &= MP_MASK; + } + /* set final carry */ + ix++; + *tmpc++ = mu; + + /* setup size */ + c->used = a->used + 1; + } else { + /* a was negative and |a| < b */ + c->used = 1; + + /* the result is a single digit */ + if (a->used == 1) { + *tmpc++ = b - a->dp[0]; + } else { + *tmpc++ = b; + } + + /* setup count so the clearing of oldused + * can fall through correctly + */ + ix = 1; + } + + /* now zero to oldused */ + while (ix++ < oldused) { + *tmpc++ = 0; + } + mp_clamp(c); + + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_addmod.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_addmod.c new file mode 100644 index 0000000000..037665908f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_addmod.c @@ -0,0 +1,41 @@ +#include +#ifdef BN_MP_ADDMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* d = a + b (mod c) */ +int +mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + int res; + mp_int t; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_add (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, c, d); + mp_clear (&t); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_and.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_and.c new file mode 100644 index 0000000000..22dfbffb97 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_and.c @@ -0,0 +1,57 @@ +#include +#ifdef BN_MP_AND_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* AND two ints together */ +int +mp_and (mp_int * a, mp_int * b, mp_int * c) +{ + int res, ix, px; + mp_int t, *x; + + if (a->used > b->used) { + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + px = b->used; + x = b; + } else { + if ((res = mp_init_copy (&t, b)) != MP_OKAY) { + return res; + } + px = a->used; + x = a; + } + + for (ix = 0; ix < px; ix++) { + t.dp[ix] &= x->dp[ix]; + } + + /* zero digits above the last from the smallest mp_int */ + for (; ix < t.used; ix++) { + t.dp[ix] = 0; + } + + mp_clamp (&t); + mp_exch (c, &t); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_clamp.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_clamp.c new file mode 100644 index 0000000000..3cec958377 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_clamp.c @@ -0,0 +1,44 @@ +#include +#ifdef BN_MP_CLAMP_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* trim unused digits + * + * This is used to ensure that leading zero digits are + * trimed and the leading "used" digit will be non-zero + * Typically very fast. Also fixes the sign if there + * are no more leading digits + */ +void +mp_clamp (mp_int * a) +{ + /* decrease used while the most significant digit is + * zero. + */ + while (a->used > 0 && a->dp[a->used - 1] == 0) { + --(a->used); + } + + /* reset the sign flag if used == 0 */ + if (a->used == 0) { + a->sign = MP_ZPOS; + } +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_clear.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_clear.c new file mode 100644 index 0000000000..72301dfaba --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_clear.c @@ -0,0 +1,44 @@ +#include +#ifdef BN_MP_CLEAR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* clear one (frees) */ +void +mp_clear (mp_int * a) +{ + int i; + + /* only do anything if a hasn't been freed previously */ + if (a->dp != NULL) { + /* first zero the digits */ + for (i = 0; i < a->used; i++) { + a->dp[i] = 0; + } + + /* free ram */ + XFREE(a->dp); + + /* reset members to make debugging easier */ + a->dp = NULL; + a->alloc = a->used = 0; + a->sign = MP_ZPOS; + } +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_clear_multi.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_clear_multi.c new file mode 100644 index 0000000000..8c6a23a3a3 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_clear_multi.c @@ -0,0 +1,34 @@ +#include +#ifdef BN_MP_CLEAR_MULTI_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include + +void mp_clear_multi(mp_int *mp, ...) +{ + mp_int* next_mp = mp; + va_list args; + va_start(args, mp); + while (next_mp != NULL) { + mp_clear(next_mp); + next_mp = va_arg(args, mp_int*); + } + va_end(args); +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_cmp.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_cmp.c new file mode 100644 index 0000000000..38d54e25aa --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_cmp.c @@ -0,0 +1,43 @@ +#include +#ifdef BN_MP_CMP_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* compare two ints (signed)*/ +int +mp_cmp (mp_int * a, mp_int * b) +{ + /* compare based on sign */ + if (a->sign != b->sign) { + if (a->sign == MP_NEG) { + return MP_LT; + } else { + return MP_GT; + } + } + + /* compare digits */ + if (a->sign == MP_NEG) { + /* if negative compare opposite direction */ + return mp_cmp_mag(b, a); + } else { + return mp_cmp_mag(a, b); + } +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_cmp_d.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_cmp_d.c new file mode 100644 index 0000000000..0d5bcb4bda --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_cmp_d.c @@ -0,0 +1,44 @@ +#include +#ifdef BN_MP_CMP_D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* compare a digit */ +int mp_cmp_d(mp_int * a, mp_digit b) +{ + /* compare based on sign */ + if (a->sign == MP_NEG) { + return MP_LT; + } + + /* compare based on magnitude */ + if (a->used > 1) { + return MP_GT; + } + + /* compare the only digit of a to b */ + if (a->dp[0] > b) { + return MP_GT; + } else if (a->dp[0] < b) { + return MP_LT; + } else { + return MP_EQ; + } +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_cmp_mag.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_cmp_mag.c new file mode 100644 index 0000000000..39cd98dd83 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_cmp_mag.c @@ -0,0 +1,55 @@ +#include +#ifdef BN_MP_CMP_MAG_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* compare maginitude of two ints (unsigned) */ +int mp_cmp_mag (mp_int * a, mp_int * b) +{ + int n; + mp_digit *tmpa, *tmpb; + + /* compare based on # of non-zero digits */ + if (a->used > b->used) { + return MP_GT; + } + + if (a->used < b->used) { + return MP_LT; + } + + /* alias for a */ + tmpa = a->dp + (a->used - 1); + + /* alias for b */ + tmpb = b->dp + (a->used - 1); + + /* compare based on digits */ + for (n = 0; n < a->used; ++n, --tmpa, --tmpb) { + if (*tmpa > *tmpb) { + return MP_GT; + } + + if (*tmpa < *tmpb) { + return MP_LT; + } + } + return MP_EQ; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_cnt_lsb.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_cnt_lsb.c new file mode 100644 index 0000000000..863da5d70c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_cnt_lsb.c @@ -0,0 +1,53 @@ +#include +#ifdef BN_MP_CNT_LSB_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +static const int lnz[16] = { + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 +}; + +/* Counts the number of lsbs which are zero before the first zero bit */ +int mp_cnt_lsb(mp_int *a) +{ + int x; + mp_digit q, qq; + + /* easy out */ + if (mp_iszero(a) == 1) { + return 0; + } + + /* scan lower digits until non-zero */ + for (x = 0; x < a->used && a->dp[x] == 0; x++); + q = a->dp[x]; + x *= DIGIT_BIT; + + /* now scan this digit until a 1 is found */ + if ((q & 1) == 0) { + do { + qq = q & 15; + x += lnz[qq]; + q >>= 4; + } while (qq == 0); + } + return x; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_copy.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_copy.c new file mode 100644 index 0000000000..45cac61eea --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_copy.c @@ -0,0 +1,68 @@ +#include +#ifdef BN_MP_COPY_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* copy, b = a */ +int +mp_copy (mp_int * a, mp_int * b) +{ + int res, n; + + /* if dst == src do nothing */ + if (a == b) { + return MP_OKAY; + } + + /* grow dest */ + if (b->alloc < a->used) { + if ((res = mp_grow (b, a->used)) != MP_OKAY) { + return res; + } + } + + /* zero b and copy the parameters over */ + { + register mp_digit *tmpa, *tmpb; + + /* pointer aliases */ + + /* source */ + tmpa = a->dp; + + /* destination */ + tmpb = b->dp; + + /* copy all the digits */ + for (n = 0; n < a->used; n++) { + *tmpb++ = *tmpa++; + } + + /* clear high digits */ + for (; n < b->used; n++) { + *tmpb++ = 0; + } + } + + /* copy used count and sign */ + b->used = a->used; + b->sign = a->sign; + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_count_bits.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_count_bits.c new file mode 100644 index 0000000000..b5a1036deb --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_count_bits.c @@ -0,0 +1,45 @@ +#include +#ifdef BN_MP_COUNT_BITS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* returns the number of bits in an int */ +int +mp_count_bits (mp_int * a) +{ + int r; + mp_digit q; + + /* shortcut */ + if (a->used == 0) { + return 0; + } + + /* get number of digits and add that */ + r = (a->used - 1) * DIGIT_BIT; + + /* take the last digit and count the bits in it */ + q = a->dp[a->used - 1]; + while (q > ((mp_digit) 0)) { + ++r; + q >>= ((mp_digit) 1); + } + return r; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_div.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_div.c new file mode 100644 index 0000000000..db97dbd22b --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_div.c @@ -0,0 +1,292 @@ +#include +#ifdef BN_MP_DIV_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +#ifdef BN_MP_DIV_SMALL + +/* slower bit-bang division... also smaller */ +int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + mp_int ta, tb, tq, q; + int res, n, n2; + + /* is divisor zero ? */ + if (mp_iszero (b) == 1) { + return MP_VAL; + } + + /* if a < b then q=0, r = a */ + if (mp_cmp_mag (a, b) == MP_LT) { + if (d != NULL) { + res = mp_copy (a, d); + } else { + res = MP_OKAY; + } + if (c != NULL) { + mp_zero (c); + } + return res; + } + + /* init our temps */ + if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL) != MP_OKAY)) { + return res; + } + + + mp_set(&tq, 1); + n = mp_count_bits(a) - mp_count_bits(b); + if (((res = mp_abs(a, &ta)) != MP_OKAY) || + ((res = mp_abs(b, &tb)) != MP_OKAY) || + ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) || + ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) { + goto LBL_ERR; + } + + while (n-- >= 0) { + if (mp_cmp(&tb, &ta) != MP_GT) { + if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) || + ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) { + goto LBL_ERR; + } + } + if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) || + ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) { + goto LBL_ERR; + } + } + + /* now q == quotient and ta == remainder */ + n = a->sign; + n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG); + if (c != NULL) { + mp_exch(c, &q); + c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2; + } + if (d != NULL) { + mp_exch(d, &ta); + d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n; + } +LBL_ERR: + mp_clear_multi(&ta, &tb, &tq, &q, NULL); + return res; +} + +#else + +/* integer signed division. + * c*b + d == a [e.g. a/b, c=quotient, d=remainder] + * HAC pp.598 Algorithm 14.20 + * + * Note that the description in HAC is horribly + * incomplete. For example, it doesn't consider + * the case where digits are removed from 'x' in + * the inner loop. It also doesn't consider the + * case that y has fewer than three digits, etc.. + * + * The overall algorithm is as described as + * 14.20 from HAC but fixed to treat these cases. +*/ +int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + mp_int q, x, y, t1, t2; + int res, n, t, i, norm, neg; + + /* is divisor zero ? */ + if (mp_iszero (b) == 1) { + return MP_VAL; + } + + /* if a < b then q=0, r = a */ + if (mp_cmp_mag (a, b) == MP_LT) { + if (d != NULL) { + res = mp_copy (a, d); + } else { + res = MP_OKAY; + } + if (c != NULL) { + mp_zero (c); + } + return res; + } + + if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) { + return res; + } + q.used = a->used + 2; + + if ((res = mp_init (&t1)) != MP_OKAY) { + goto LBL_Q; + } + + if ((res = mp_init (&t2)) != MP_OKAY) { + goto LBL_T1; + } + + if ((res = mp_init_copy (&x, a)) != MP_OKAY) { + goto LBL_T2; + } + + if ((res = mp_init_copy (&y, b)) != MP_OKAY) { + goto LBL_X; + } + + /* fix the sign */ + neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; + x.sign = y.sign = MP_ZPOS; + + /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */ + norm = mp_count_bits(&y) % DIGIT_BIT; + if (norm < (int)(DIGIT_BIT-1)) { + norm = (DIGIT_BIT-1) - norm; + if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) { + goto LBL_Y; + } + if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) { + goto LBL_Y; + } + } else { + norm = 0; + } + + /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */ + n = x.used - 1; + t = y.used - 1; + + /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */ + if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */ + goto LBL_Y; + } + + while (mp_cmp (&x, &y) != MP_LT) { + ++(q.dp[n - t]); + if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) { + goto LBL_Y; + } + } + + /* reset y by shifting it back down */ + mp_rshd (&y, n - t); + + /* step 3. for i from n down to (t + 1) */ + for (i = n; i >= (t + 1); i--) { + if (i > x.used) { + continue; + } + + /* step 3.1 if xi == yt then set q{i-t-1} to b-1, + * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ + if (x.dp[i] == y.dp[t]) { + q.dp[i - t - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1); + } else { + mp_word tmp; + tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT); + tmp |= ((mp_word) x.dp[i - 1]); + tmp /= ((mp_word) y.dp[t]); + if (tmp > (mp_word) MP_MASK) + tmp = MP_MASK; + q.dp[i - t - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK)); + } + + /* while (q{i-t-1} * (yt * b + y{t-1})) > + xi * b**2 + xi-1 * b + xi-2 + + do q{i-t-1} -= 1; + */ + q.dp[i - t - 1] = (q.dp[i - t - 1] + 1) & MP_MASK; + do { + q.dp[i - t - 1] = (q.dp[i - t - 1] - 1) & MP_MASK; + + /* find left hand */ + mp_zero (&t1); + t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1]; + t1.dp[1] = y.dp[t]; + t1.used = 2; + if ((res = mp_mul_d (&t1, q.dp[i - t - 1], &t1)) != MP_OKAY) { + goto LBL_Y; + } + + /* find right hand */ + t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2]; + t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1]; + t2.dp[2] = x.dp[i]; + t2.used = 3; + } while (mp_cmp_mag(&t1, &t2) == MP_GT); + + /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */ + if ((res = mp_mul_d (&y, q.dp[i - t - 1], &t1)) != MP_OKAY) { + goto LBL_Y; + } + + if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) { + goto LBL_Y; + } + + if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) { + goto LBL_Y; + } + + /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */ + if (x.sign == MP_NEG) { + if ((res = mp_copy (&y, &t1)) != MP_OKAY) { + goto LBL_Y; + } + if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) { + goto LBL_Y; + } + if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) { + goto LBL_Y; + } + + q.dp[i - t - 1] = (q.dp[i - t - 1] - 1UL) & MP_MASK; + } + } + + /* now q is the quotient and x is the remainder + * [which we have to normalize] + */ + + /* get sign before writing to c */ + x.sign = x.used == 0 ? MP_ZPOS : a->sign; + + if (c != NULL) { + mp_clamp (&q); + mp_exch (&q, c); + c->sign = neg; + } + + if (d != NULL) { + mp_div_2d (&x, norm, &x, NULL); + mp_exch (&x, d); + } + + res = MP_OKAY; + +LBL_Y:mp_clear (&y); +LBL_X:mp_clear (&x); +LBL_T2:mp_clear (&t2); +LBL_T1:mp_clear (&t1); +LBL_Q:mp_clear (&q); + return res; +} + +#endif + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_div_2.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_div_2.c new file mode 100644 index 0000000000..64ef823f77 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_div_2.c @@ -0,0 +1,68 @@ +#include +#ifdef BN_MP_DIV_2_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* b = a/2 */ +int mp_div_2(mp_int * a, mp_int * b) +{ + int x, res, oldused; + + /* copy */ + if (b->alloc < a->used) { + if ((res = mp_grow (b, a->used)) != MP_OKAY) { + return res; + } + } + + oldused = b->used; + b->used = a->used; + { + register mp_digit r, rr, *tmpa, *tmpb; + + /* source alias */ + tmpa = a->dp + b->used - 1; + + /* dest alias */ + tmpb = b->dp + b->used - 1; + + /* carry */ + r = 0; + for (x = b->used - 1; x >= 0; x--) { + /* get the carry for the next iteration */ + rr = *tmpa & 1; + + /* shift the current digit, add in carry and store */ + *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); + + /* forward carry to next iteration */ + r = rr; + } + + /* zero excess digits */ + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } + } + b->sign = a->sign; + mp_clamp (b); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_div_2d.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_div_2d.c new file mode 100644 index 0000000000..72936a4a9a --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_div_2d.c @@ -0,0 +1,97 @@ +#include +#ifdef BN_MP_DIV_2D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* shift right by a certain bit count (store quotient in c, optional remainder in d) */ +int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) +{ + mp_digit D, r, rr; + int x, res; + mp_int t; + + + /* if the shift count is <= 0 then we do no work */ + if (b <= 0) { + res = mp_copy (a, c); + if (d != NULL) { + mp_zero (d); + } + return res; + } + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + /* get the remainder */ + if (d != NULL) { + if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + } + + /* copy */ + if ((res = mp_copy (a, c)) != MP_OKAY) { + mp_clear (&t); + return res; + } + + /* shift by as many digits in the bit count */ + if (b >= (int)DIGIT_BIT) { + mp_rshd (c, b / DIGIT_BIT); + } + + /* shift any bit count < DIGIT_BIT */ + D = (mp_digit) (b % DIGIT_BIT); + if (D != 0) { + register mp_digit *tmpc, mask, shift; + + /* mask */ + mask = (((mp_digit)1) << D) - 1; + + /* shift for lsb */ + shift = DIGIT_BIT - D; + + /* alias */ + tmpc = c->dp + (c->used - 1); + + /* carry */ + r = 0; + for (x = c->used - 1; x >= 0; x--) { + /* get the lower bits of this word in a temp */ + rr = *tmpc & mask; + + /* shift the current word and mix in the carry bits from the previous word */ + *tmpc = (*tmpc >> D) | (r << shift); + --tmpc; + + /* set the carry to the carry bits of the current word found above */ + r = rr; + } + } + mp_clamp (c); + if (d != NULL) { + mp_exch (&t, d); + } + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_div_3.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_div_3.c new file mode 100644 index 0000000000..fa456d7619 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_div_3.c @@ -0,0 +1,79 @@ +#include +#ifdef BN_MP_DIV_3_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* divide by three (based on routine from MPI and the GMP manual) */ +int +mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) +{ + mp_int q; + mp_word w, t; + mp_digit b; + int res, ix; + + /* b = 2**DIGIT_BIT / 3 */ + b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3); + + if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { + return res; + } + + q.used = a->used; + q.sign = a->sign; + w = 0; + for (ix = a->used - 1; ix >= 0; ix--) { + w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); + + if (w >= 3) { + /* multiply w by [1/3] */ + t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT); + + /* now subtract 3 * [w/3] from w, to get the remainder */ + w -= t+t+t; + + /* fixup the remainder as required since + * the optimization is not exact. + */ + while (w >= 3) { + t += 1; + w -= 3; + } + } else { + t = 0; + } + q.dp[ix] = (mp_digit)t; + } + + /* [optional] store the remainder */ + if (d != NULL) { + *d = (mp_digit)w; + } + + /* [optional] store the quotient */ + if (c != NULL) { + mp_clamp(&q); + mp_exch(&q, c); + } + mp_clear(&q); + + return res; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_div_d.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_div_d.c new file mode 100644 index 0000000000..a95de2b3a1 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_div_d.c @@ -0,0 +1,115 @@ +#include +#ifdef BN_MP_DIV_D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +static int s_is_power_of_two(mp_digit b, int *p) +{ + int x; + + /* fast return if no power of two */ + if ((b==0) || (b & (b-1))) { + return 0; + } + + for (x = 0; x < DIGIT_BIT; x++) { + if (b == (((mp_digit)1)<dp[0] & ((((mp_digit)1)<used)) != MP_OKAY) { + return res; + } + + q.used = a->used; + q.sign = a->sign; + w = 0; + for (ix = a->used - 1; ix >= 0; ix--) { + w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); + + if (w >= b) { + t = (mp_digit)(w / b); + w -= ((mp_word)t) * ((mp_word)b); + } else { + t = 0; + } + q.dp[ix] = (mp_digit)t; + } + + if (d != NULL) { + *d = (mp_digit)w; + } + + if (c != NULL) { + mp_clamp(&q); + mp_exch(&q, c); + } + mp_clear(&q); + + return res; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_dr_is_modulus.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_dr_is_modulus.c new file mode 100644 index 0000000000..52b4fdfc2f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_dr_is_modulus.c @@ -0,0 +1,43 @@ +#include +#ifdef BN_MP_DR_IS_MODULUS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* determines if a number is a valid DR modulus */ +int mp_dr_is_modulus(mp_int *a) +{ + int ix; + + /* must be at least two digits */ + if (a->used < 2) { + return 0; + } + + /* must be of the form b**k - a [a <= b] so all + * but the first digit must be equal to -1 (mod b). + */ + for (ix = 1; ix < a->used; ix++) { + if (a->dp[ix] != MP_MASK) { + return 0; + } + } + return 1; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_dr_reduce.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_dr_reduce.c new file mode 100644 index 0000000000..47f0c6031e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_dr_reduce.c @@ -0,0 +1,94 @@ +#include +#ifdef BN_MP_DR_REDUCE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* reduce "x" in place modulo "n" using the Diminished Radix algorithm. + * + * Based on algorithm from the paper + * + * "Generating Efficient Primes for Discrete Log Cryptosystems" + * Chae Hoon Lim, Pil Joong Lee, + * POSTECH Information Research Laboratories + * + * The modulus must be of a special format [see manual] + * + * Has been modified to use algorithm 7.10 from the LTM book instead + * + * Input x must be in the range 0 <= x <= (n-1)**2 + */ +int +mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k) +{ + int err, i, m; + mp_word r; + mp_digit mu, *tmpx1, *tmpx2; + + /* m = digits in modulus */ + m = n->used; + + /* ensure that "x" has at least 2m digits */ + if (x->alloc < m + m) { + if ((err = mp_grow (x, m + m)) != MP_OKAY) { + return err; + } + } + +/* top of loop, this is where the code resumes if + * another reduction pass is required. + */ +top: + /* aliases for digits */ + /* alias for lower half of x */ + tmpx1 = x->dp; + + /* alias for upper half of x, or x/B**m */ + tmpx2 = x->dp + m; + + /* set carry to zero */ + mu = 0; + + /* compute (x mod B**m) + k * [x/B**m] inline and inplace */ + for (i = 0; i < m; i++) { + r = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu; + *tmpx1++ = (mp_digit)(r & MP_MASK); + mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT)); + } + + /* set final carry */ + *tmpx1++ = mu; + + /* zero words above m */ + for (i = m + 1; i < x->used; i++) { + *tmpx1++ = 0; + } + + /* clamp, sub and return */ + mp_clamp (x); + + /* if x >= n then subtract and reduce again + * Each successive "recursion" makes the input smaller and smaller. + */ + if (mp_cmp_mag (x, n) != MP_LT) { + s_mp_sub(x, n, x); + goto top; + } + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_dr_setup.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_dr_setup.c new file mode 100644 index 0000000000..7c24fcbdfb --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_dr_setup.c @@ -0,0 +1,32 @@ +#include +#ifdef BN_MP_DR_SETUP_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* determines the setup value */ +void mp_dr_setup(mp_int *a, mp_digit *d) +{ + /* the casts are required if DIGIT_BIT is one less than + * the number of bits in a mp_digit [e.g. DIGIT_BIT==31] + */ + *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - + ((mp_word)a->dp[0])); +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_exch.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_exch.c new file mode 100644 index 0000000000..a53304f397 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_exch.c @@ -0,0 +1,34 @@ +#include +#ifdef BN_MP_EXCH_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* swap the elements of two integers, for cases where you can't simply swap the + * mp_int pointers around + */ +void +mp_exch (mp_int * a, mp_int * b) +{ + mp_int t; + + t = *a; + *a = *b; + *b = t; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_expt_d.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_expt_d.c new file mode 100644 index 0000000000..f9357cc599 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_expt_d.c @@ -0,0 +1,57 @@ +#include +#ifdef BN_MP_EXPT_D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* calculate c = a**b using a square-multiply algorithm */ +int mp_expt_d (mp_int * a, mp_digit b, mp_int * c) +{ + int res, x; + mp_int g; + + if ((res = mp_init_copy (&g, a)) != MP_OKAY) { + return res; + } + + /* set initial result */ + mp_set (c, 1); + + for (x = 0; x < (int) DIGIT_BIT; x++) { + /* square */ + if ((res = mp_sqr (c, c)) != MP_OKAY) { + mp_clear (&g); + return res; + } + + /* if the bit is set multiply */ + if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) { + if ((res = mp_mul (c, &g, c)) != MP_OKAY) { + mp_clear (&g); + return res; + } + } + + /* shift to next bit */ + b <<= 1; + } + + mp_clear (&g); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_exptmod.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_exptmod.c new file mode 100644 index 0000000000..13fe387cda --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_exptmod.c @@ -0,0 +1,112 @@ +#include +#ifdef BN_MP_EXPTMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + + +/* this is a shell function that calls either the normal or Montgomery + * exptmod functions. Originally the call to the montgomery code was + * embedded in the normal function but that wasted alot of stack space + * for nothing (since 99% of the time the Montgomery code would be called) + */ +int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) +{ + int dr; + + /* modulus P must be positive */ + if (P->sign == MP_NEG) { + return MP_VAL; + } + + /* if exponent X is negative we have to recurse */ + if (X->sign == MP_NEG) { +#ifdef BN_MP_INVMOD_C + mp_int tmpG, tmpX; + int err; + + /* first compute 1/G mod P */ + if ((err = mp_init(&tmpG)) != MP_OKAY) { + return err; + } + if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) { + mp_clear(&tmpG); + return err; + } + + /* now get |X| */ + if ((err = mp_init(&tmpX)) != MP_OKAY) { + mp_clear(&tmpG); + return err; + } + if ((err = mp_abs(X, &tmpX)) != MP_OKAY) { + mp_clear_multi(&tmpG, &tmpX, NULL); + return err; + } + + /* and now compute (1/G)**|X| instead of G**X [X < 0] */ + err = mp_exptmod(&tmpG, &tmpX, P, Y); + mp_clear_multi(&tmpG, &tmpX, NULL); + return err; +#else + /* no invmod */ + return MP_VAL; +#endif + } + +/* modified diminished radix reduction */ +#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_C) + if (mp_reduce_is_2k_l(P) == MP_YES) { + return s_mp_exptmod(G, X, P, Y, 1); + } +#endif + +#ifdef BN_MP_DR_IS_MODULUS_C + /* is it a DR modulus? */ + dr = mp_dr_is_modulus(P); +#else + /* default to no */ + dr = 0; +#endif + +#ifdef BN_MP_REDUCE_IS_2K_C + /* if not, is it a unrestricted DR modulus? */ + if (dr == 0) { + dr = mp_reduce_is_2k(P) << 1; + } +#endif + + /* if the modulus is odd or dr != 0 use the montgomery method */ +#ifdef BN_MP_EXPTMOD_FAST_C + if (mp_isodd (P) == 1 || dr != 0) { + return mp_exptmod_fast (G, X, P, Y, dr); + } else { +#endif +#ifdef BN_S_MP_EXPTMOD_C + /* otherwise use the generic Barrett reduction technique */ + return s_mp_exptmod (G, X, P, Y, 0); +#else + /* no exptmod for evens */ + return MP_VAL; +#endif +#ifdef BN_MP_EXPTMOD_FAST_C + } +#endif +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_exptmod_fast.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_exptmod_fast.c new file mode 100644 index 0000000000..26bff78aa2 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_exptmod_fast.c @@ -0,0 +1,321 @@ +#include +#ifdef BN_MP_EXPTMOD_FAST_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85 + * + * Uses a left-to-right k-ary sliding window to compute the modular exponentiation. + * The value of k changes based on the size of the exponent. + * + * Uses Montgomery or Diminished Radix reduction [whichever appropriate] + */ + +#ifdef MP_LOW_MEM + #define TAB_SIZE 32 +#else + #define TAB_SIZE 256 +#endif + +int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) +{ + mp_int M[TAB_SIZE], res; + mp_digit buf, mp; + int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; + + /* use a pointer to the reduction algorithm. This allows us to use + * one of many reduction algorithms without modding the guts of + * the code with if statements everywhere. + */ + int (*redux)(mp_int*,mp_int*,mp_digit); + + /* find window size */ + x = mp_count_bits (X); + if (x <= 7) { + winsize = 2; + } else if (x <= 36) { + winsize = 3; + } else if (x <= 140) { + winsize = 4; + } else if (x <= 450) { + winsize = 5; + } else if (x <= 1303) { + winsize = 6; + } else if (x <= 3529) { + winsize = 7; + } else { + winsize = 8; + } + +#ifdef MP_LOW_MEM + if (winsize > 5) { + winsize = 5; + } +#endif + + /* init M array */ + /* init first cell */ + if ((err = mp_init(&M[1])) != MP_OKAY) { + return err; + } + + /* now init the second half of the array */ + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + if ((err = mp_init(&M[x])) != MP_OKAY) { + for (y = 1<<(winsize-1); y < x; y++) { + mp_clear (&M[y]); + } + mp_clear(&M[1]); + return err; + } + } + + /* determine and setup reduction code */ + if (redmode == 0) { +#ifdef BN_MP_MONTGOMERY_SETUP_C + /* now setup montgomery */ + if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) { + goto LBL_M; + } +#else + err = MP_VAL; + goto LBL_M; +#endif + + /* automatically pick the comba one if available (saves quite a few calls/ifs) */ +#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C + if (((P->used * 2 + 1) < MP_WARRAY) && + P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + redux = fast_mp_montgomery_reduce; + } else +#endif + { +#ifdef BN_MP_MONTGOMERY_REDUCE_C + /* use slower baseline Montgomery method */ + redux = mp_montgomery_reduce; +#else + err = MP_VAL; + goto LBL_M; +#endif + } + } else if (redmode == 1) { +#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C) + /* setup DR reduction for moduli of the form B**k - b */ + mp_dr_setup(P, &mp); + redux = mp_dr_reduce; +#else + err = MP_VAL; + goto LBL_M; +#endif + } else { +#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C) + /* setup DR reduction for moduli of the form 2**k - b */ + if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) { + goto LBL_M; + } + redux = mp_reduce_2k; +#else + err = MP_VAL; + goto LBL_M; +#endif + } + + /* setup result */ + if ((err = mp_init (&res)) != MP_OKAY) { + goto LBL_M; + } + + /* create M table + * + + * + * The first half of the table is not computed though accept for M[0] and M[1] + */ + + if (redmode == 0) { +#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C + /* now we need R mod m */ + if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) { + goto LBL_RES; + } +#else + err = MP_VAL; + goto LBL_RES; +#endif + + /* now set M[1] to G * R mod m */ + if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) { + goto LBL_RES; + } + } else { + mp_set(&res, 1); + if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) { + goto LBL_RES; + } + } + + /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */ + if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_RES; + } + + for (x = 0; x < (winsize - 1); x++) { + if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* create upper table */ + for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { + if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&M[x], P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* set initial mode and bit cnt */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = X->used - 1; + bitcpy = 0; + bitbuf = 0; + + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits so break */ + if (digidx == -1) { + break; + } + /* read next digit and reset bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int)DIGIT_BIT; + } + + /* grab the next msb from the exponent */ + y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1; + buf <<= (mp_digit)1; + + /* if the bit is zero and mode == 0 then we ignore it + * These represent the leading zero bits before the first 1 bit + * in the exponent. Technically this opt is not required but it + * does lower the # of trivial squaring/reductions used + */ + if (mode == 0 && y == 0) { + continue; + } + + /* if the bit is zero and mode == 1 then we square */ + if (mode == 1 && y == 0) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + continue; + } + + /* else we add it to the window */ + bitbuf |= (y << (winsize - ++bitcpy)); + mode = 2; + + if (bitcpy == winsize) { + /* ok window is filled so square as required and multiply */ + /* square first */ + for (x = 0; x < winsize; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* then multiply */ + if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + + /* empty window and reset */ + bitcpy = 0; + bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then square/multiply */ + if (mode == 2 && bitcpy > 0) { + /* square then multiply if the bit is set */ + for (x = 0; x < bitcpy; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + + /* get next bit of the window */ + bitbuf <<= 1; + if ((bitbuf & (1 << winsize)) != 0) { + /* then multiply */ + if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + } + } + + if (redmode == 0) { + /* fixup result if Montgomery reduction is used + * recall that any value in a Montgomery system is + * actually multiplied by R mod n. So we have + * to reduce one more time to cancel out the factor + * of R. + */ + if ((err = redux(&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* swap res with Y */ + mp_exch (&res, Y); + err = MP_OKAY; +LBL_RES:mp_clear (&res); +LBL_M: + mp_clear(&M[1]); + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + mp_clear (&M[x]); + } + return err; +} +#endif + + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_exteuclid.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_exteuclid.c new file mode 100644 index 0000000000..9eb785a7af --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_exteuclid.c @@ -0,0 +1,82 @@ +#include +#ifdef BN_MP_EXTEUCLID_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Extended euclidean algorithm of (a, b) produces + a*u1 + b*u2 = u3 + */ +int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3) +{ + mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp; + int err; + + if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) { + return err; + } + + /* initialize, (u1,u2,u3) = (1,0,a) */ + mp_set(&u1, 1); + if ((err = mp_copy(a, &u3)) != MP_OKAY) { goto _ERR; } + + /* initialize, (v1,v2,v3) = (0,1,b) */ + mp_set(&v2, 1); + if ((err = mp_copy(b, &v3)) != MP_OKAY) { goto _ERR; } + + /* loop while v3 != 0 */ + while (mp_iszero(&v3) == MP_NO) { + /* q = u3/v3 */ + if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto _ERR; } + + /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */ + if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) { goto _ERR; } + if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto _ERR; } + if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) { goto _ERR; } + if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto _ERR; } + if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) { goto _ERR; } + if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto _ERR; } + + /* (u1,u2,u3) = (v1,v2,v3) */ + if ((err = mp_copy(&v1, &u1)) != MP_OKAY) { goto _ERR; } + if ((err = mp_copy(&v2, &u2)) != MP_OKAY) { goto _ERR; } + if ((err = mp_copy(&v3, &u3)) != MP_OKAY) { goto _ERR; } + + /* (v1,v2,v3) = (t1,t2,t3) */ + if ((err = mp_copy(&t1, &v1)) != MP_OKAY) { goto _ERR; } + if ((err = mp_copy(&t2, &v2)) != MP_OKAY) { goto _ERR; } + if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { goto _ERR; } + } + + /* make sure U3 >= 0 */ + if (u3.sign == MP_NEG) { + mp_neg(&u1, &u1); + mp_neg(&u2, &u2); + mp_neg(&u3, &u3); + } + + /* copy result out */ + if (U1 != NULL) { mp_exch(U1, &u1); } + if (U2 != NULL) { mp_exch(U2, &u2); } + if (U3 != NULL) { mp_exch(U3, &u3); } + + err = MP_OKAY; +_ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL); + return err; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_fread.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_fread.c new file mode 100644 index 0000000000..578f76a7c5 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_fread.c @@ -0,0 +1,67 @@ +#include +#ifdef BN_MP_FREAD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* read a bigint from a file stream in ASCII */ +int mp_fread(mp_int *a, int radix, FILE *stream) +{ + int err, ch, neg, y; + + /* clear a */ + mp_zero(a); + + /* if first digit is - then set negative */ + ch = fgetc(stream); + if (ch == '-') { + neg = MP_NEG; + ch = fgetc(stream); + } else { + neg = MP_ZPOS; + } + + for (;;) { + /* find y in the radix map */ + for (y = 0; y < radix; y++) { + if (mp_s_rmap[y] == ch) { + break; + } + } + if (y == radix) { + break; + } + + /* shift up and add */ + if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) { + return err; + } + if ((err = mp_add_d(a, y, a)) != MP_OKAY) { + return err; + } + + ch = fgetc(stream); + } + if (mp_cmp_d(a, 0) != MP_EQ) { + a->sign = neg; + } + + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_fwrite.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_fwrite.c new file mode 100644 index 0000000000..36a6d21463 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_fwrite.c @@ -0,0 +1,52 @@ +#include +#ifdef BN_MP_FWRITE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +int mp_fwrite(mp_int *a, int radix, FILE *stream) +{ + char *buf; + int err, len, x; + + if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) { + return err; + } + + buf = OPT_CAST(char) XMALLOC (len); + if (buf == NULL) { + return MP_MEM; + } + + if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) { + XFREE (buf); + return err; + } + + for (x = 0; x < len; x++) { + if (fputc(buf[x], stream) == EOF) { + XFREE (buf); + return MP_VAL; + } + } + + XFREE (buf); + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_gcd.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_gcd.c new file mode 100644 index 0000000000..61525cbc5a --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_gcd.c @@ -0,0 +1,105 @@ +#include +#ifdef BN_MP_GCD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Greatest Common Divisor using the binary method */ +int mp_gcd (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int u, v; + int k, u_lsb, v_lsb, res; + + /* either zero than gcd is the largest */ + if (mp_iszero (a) == MP_YES) { + return mp_abs (b, c); + } + if (mp_iszero (b) == MP_YES) { + return mp_abs (a, c); + } + + /* get copies of a and b we can modify */ + if ((res = mp_init_copy (&u, a)) != MP_OKAY) { + return res; + } + + if ((res = mp_init_copy (&v, b)) != MP_OKAY) { + goto LBL_U; + } + + /* must be positive for the remainder of the algorithm */ + u.sign = v.sign = MP_ZPOS; + + /* B1. Find the common power of two for u and v */ + u_lsb = mp_cnt_lsb(&u); + v_lsb = mp_cnt_lsb(&v); + k = MIN(u_lsb, v_lsb); + + if (k > 0) { + /* divide the power of two out */ + if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) { + goto LBL_V; + } + + if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) { + goto LBL_V; + } + } + + /* divide any remaining factors of two out */ + if (u_lsb != k) { + if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) { + goto LBL_V; + } + } + + if (v_lsb != k) { + if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) { + goto LBL_V; + } + } + + while (mp_iszero(&v) == 0) { + /* make sure v is the largest */ + if (mp_cmp_mag(&u, &v) == MP_GT) { + /* swap u and v to make sure v is >= u */ + mp_exch(&u, &v); + } + + /* subtract smallest from largest */ + if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) { + goto LBL_V; + } + + /* Divide out all factors of two */ + if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) { + goto LBL_V; + } + } + + /* multiply by 2**k which we divided out at the beginning */ + if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) { + goto LBL_V; + } + c->sign = MP_ZPOS; + res = MP_OKAY; +LBL_V:mp_clear (&u); +LBL_U:mp_clear (&v); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_get_int.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_get_int.c new file mode 100644 index 0000000000..0ea23e736d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_get_int.c @@ -0,0 +1,45 @@ +#include +#ifdef BN_MP_GET_INT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* get the lower 32-bits of an mp_int */ +unsigned long mp_get_int(mp_int * a) +{ + int i; + unsigned long res; + + if (a->used == 0) { + return 0; + } + + /* get number of digits of the lsb we have to read */ + i = MIN(a->used,(int)((sizeof(unsigned long)*CHAR_BIT+DIGIT_BIT-1)/DIGIT_BIT))-1; + + /* get most significant digit of result */ + res = DIGIT(a,i); + + while (--i >= 0) { + res = (res << DIGIT_BIT) | DIGIT(a,i); + } + + /* force result to 32-bits always so it is consistent on non 32-bit platforms */ + return res & 0xFFFFFFFFUL; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_grow.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_grow.c new file mode 100644 index 0000000000..f1c1cab54e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_grow.c @@ -0,0 +1,57 @@ +#include +#ifdef BN_MP_GROW_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* grow as required */ +int mp_grow (mp_int * a, int size) +{ + int i; + mp_digit *tmp; + + /* if the alloc size is smaller alloc more ram */ + if (a->alloc < size) { + /* ensure there are always at least MP_PREC digits extra on top */ + size += (MP_PREC * 2) - (size % MP_PREC); + + /* reallocate the array a->dp + * + * We store the return in a temporary variable + * in case the operation failed we don't want + * to overwrite the dp member of a. + */ + tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size); + if (tmp == NULL) { + /* reallocation failed but "a" is still valid [can be freed] */ + return MP_MEM; + } + + /* reallocation succeeded so set a->dp */ + a->dp = tmp; + + /* zero excess digits */ + i = a->alloc; + a->alloc = size; + for (; i < a->alloc; i++) { + a->dp[i] = 0; + } + } + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_init.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_init.c new file mode 100644 index 0000000000..79cca3cf6c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_init.c @@ -0,0 +1,46 @@ +#include +#ifdef BN_MP_INIT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* init a new mp_int */ +int mp_init (mp_int * a) +{ + int i; + + /* allocate memory required and clear it */ + a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC); + if (a->dp == NULL) { + return MP_MEM; + } + + /* set the digits to zero */ + for (i = 0; i < MP_PREC; i++) { + a->dp[i] = 0; + } + + /* set the used to zero, allocated digits to the default precision + * and sign to positive */ + a->used = 0; + a->alloc = MP_PREC; + a->sign = MP_ZPOS; + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_init_copy.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_init_copy.c new file mode 100644 index 0000000000..8ce0ef969e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_init_copy.c @@ -0,0 +1,32 @@ +#include +#ifdef BN_MP_INIT_COPY_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* creates "a" then copies b into it */ +int mp_init_copy (mp_int * a, mp_int * b) +{ + int res; + + if ((res = mp_init (a)) != MP_OKAY) { + return res; + } + return mp_copy (b, a); +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_init_multi.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_init_multi.c new file mode 100644 index 0000000000..0d81d1caba --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_init_multi.c @@ -0,0 +1,59 @@ +#include +#ifdef BN_MP_INIT_MULTI_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include + +int mp_init_multi(mp_int *mp, ...) +{ + mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ + int n = 0; /* Number of ok inits */ + mp_int* cur_arg = mp; + va_list args; + + va_start(args, mp); /* init args to next argument from caller */ + while (cur_arg != NULL) { + if (mp_init(cur_arg) != MP_OKAY) { + /* Oops - error! Back-track and mp_clear what we already + succeeded in init-ing, then return error. + */ + va_list clean_args; + + /* end the current list */ + va_end(args); + + /* now start cleaning up */ + cur_arg = mp; + va_start(clean_args, mp); + while (n--) { + mp_clear(cur_arg); + cur_arg = va_arg(clean_args, mp_int*); + } + va_end(clean_args); + res = MP_MEM; + break; + } + n++; + cur_arg = va_arg(args, mp_int*); + } + va_end(args); + return res; /* Assumed ok, if error flagged above. */ +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_init_set.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_init_set.c new file mode 100644 index 0000000000..f9b08e924b --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_init_set.c @@ -0,0 +1,32 @@ +#include +#ifdef BN_MP_INIT_SET_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* initialize and set a digit */ +int mp_init_set (mp_int * a, mp_digit b) +{ + int err; + if ((err = mp_init(a)) != MP_OKAY) { + return err; + } + mp_set(a, b); + return err; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_init_set_int.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_init_set_int.c new file mode 100644 index 0000000000..9473c3f1e9 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_init_set_int.c @@ -0,0 +1,31 @@ +#include +#ifdef BN_MP_INIT_SET_INT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* initialize and set a digit */ +int mp_init_set_int (mp_int * a, unsigned long b) +{ + int err; + if ((err = mp_init(a)) != MP_OKAY) { + return err; + } + return mp_set_int(a, b); +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_init_size.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_init_size.c new file mode 100644 index 0000000000..ac40a7db03 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_init_size.c @@ -0,0 +1,48 @@ +#include +#ifdef BN_MP_INIT_SIZE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* init an mp_init for a given size */ +int mp_init_size (mp_int * a, int size) +{ + int x; + + /* pad size so there are always extra digits */ + size += (MP_PREC * 2) - (size % MP_PREC); + + /* alloc mem */ + a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size); + if (a->dp == NULL) { + return MP_MEM; + } + + /* set the members */ + a->used = 0; + a->alloc = size; + a->sign = MP_ZPOS; + + /* zero the digits */ + for (x = 0; x < size; x++) { + a->dp[x] = 0; + } + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_invmod.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_invmod.c new file mode 100644 index 0000000000..f4bdc17ea7 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_invmod.c @@ -0,0 +1,43 @@ +#include +#ifdef BN_MP_INVMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* hac 14.61, pp608 */ +int mp_invmod (mp_int * a, mp_int * b, mp_int * c) +{ + /* b cannot be negative */ + if (b->sign == MP_NEG || mp_iszero(b) == 1) { + return MP_VAL; + } + +#ifdef BN_FAST_MP_INVMOD_C + /* if the modulus is odd we can use a faster routine instead */ + if (mp_isodd (b) == 1) { + return fast_mp_invmod (a, b, c); + } +#endif + +#ifdef BN_MP_INVMOD_SLOW_C + return mp_invmod_slow(a, b, c); +#endif + + return MP_VAL; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_invmod_slow.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_invmod_slow.c new file mode 100644 index 0000000000..02fdeaaed9 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_invmod_slow.c @@ -0,0 +1,175 @@ +#include +#ifdef BN_MP_INVMOD_SLOW_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* hac 14.61, pp608 */ +int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int x, y, u, v, A, B, C, D; + int res; + + /* b cannot be negative */ + if (b->sign == MP_NEG || mp_iszero(b) == 1) { + return MP_VAL; + } + + /* init temps */ + if ((res = mp_init_multi(&x, &y, &u, &v, + &A, &B, &C, &D, NULL)) != MP_OKAY) { + return res; + } + + /* x = a, y = b */ + if ((res = mp_mod(a, b, &x)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_copy (b, &y)) != MP_OKAY) { + goto LBL_ERR; + } + + /* 2. [modified] if x,y are both even then return an error! */ + if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) { + res = MP_VAL; + goto LBL_ERR; + } + + /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ + if ((res = mp_copy (&x, &u)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_copy (&y, &v)) != MP_OKAY) { + goto LBL_ERR; + } + mp_set (&A, 1); + mp_set (&D, 1); + +top: + /* 4. while u is even do */ + while (mp_iseven (&u) == 1) { + /* 4.1 u = u/2 */ + if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { + goto LBL_ERR; + } + /* 4.2 if A or B is odd then */ + if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) { + /* A = (A+y)/2, B = (B-x)/2 */ + if ((res = mp_add (&A, &y, &A)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* A = A/2, B = B/2 */ + if ((res = mp_div_2 (&A, &A)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 5. while v is even do */ + while (mp_iseven (&v) == 1) { + /* 5.1 v = v/2 */ + if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { + goto LBL_ERR; + } + /* 5.2 if C or D is odd then */ + if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) { + /* C = (C+y)/2, D = (D-x)/2 */ + if ((res = mp_add (&C, &y, &C)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* C = C/2, D = D/2 */ + if ((res = mp_div_2 (&C, &C)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 6. if u >= v then */ + if (mp_cmp (&u, &v) != MP_LT) { + /* u = u - v, A = A - C, B = B - D */ + if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } else { + /* v - v - u, C = C - A, D = D - B */ + if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* if not zero goto step 4 */ + if (mp_iszero (&u) == 0) + goto top; + + /* now a = C, b = D, gcd == g*v */ + + /* if v != 1 then there is no inverse */ + if (mp_cmp_d (&v, 1) != MP_EQ) { + res = MP_VAL; + goto LBL_ERR; + } + + /* if its too low */ + while (mp_cmp_d(&C, 0) == MP_LT) { + if ((res = mp_add(&C, b, &C)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* too big */ + while (mp_cmp_mag(&C, b) != MP_LT) { + if ((res = mp_sub(&C, b, &C)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* C is now the inverse */ + mp_exch (&C, c); + res = MP_OKAY; +LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_is_square.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_is_square.c new file mode 100644 index 0000000000..336c86946d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_is_square.c @@ -0,0 +1,109 @@ +#include +#ifdef BN_MP_IS_SQUARE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Check if remainders are possible squares - fast exclude non-squares */ +static const char rem_128[128] = { + 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 +}; + +static const char rem_105[105] = { + 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 +}; + +/* Store non-zero to ret if arg is square, and zero if not */ +int mp_is_square(mp_int *arg,int *ret) +{ + int res; + mp_digit c; + mp_int t; + unsigned long r; + + /* Default to Non-square :) */ + *ret = MP_NO; + + if (arg->sign == MP_NEG) { + return MP_VAL; + } + + /* digits used? (TSD) */ + if (arg->used == 0) { + return MP_OKAY; + } + + /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */ + if (rem_128[127 & DIGIT(arg,0)] == 1) { + return MP_OKAY; + } + + /* Next check mod 105 (3*5*7) */ + if ((res = mp_mod_d(arg,105,&c)) != MP_OKAY) { + return res; + } + if (rem_105[c] == 1) { + return MP_OKAY; + } + + + if ((res = mp_init_set_int(&t,11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) { + return res; + } + if ((res = mp_mod(arg,&t,&t)) != MP_OKAY) { + goto ERR; + } + r = mp_get_int(&t); + /* Check for other prime modules, note it's not an ERROR but we must + * free "t" so the easiest way is to goto ERR. We know that res + * is already equal to MP_OKAY from the mp_mod call + */ + if ( (1L<<(r%11)) & 0x5C4L ) goto ERR; + if ( (1L<<(r%13)) & 0x9E4L ) goto ERR; + if ( (1L<<(r%17)) & 0x5CE8L ) goto ERR; + if ( (1L<<(r%19)) & 0x4F50CL ) goto ERR; + if ( (1L<<(r%23)) & 0x7ACCA0L ) goto ERR; + if ( (1L<<(r%29)) & 0xC2EDD0CL ) goto ERR; + if ( (1L<<(r%31)) & 0x6DE2B848L ) goto ERR; + + /* Final check - is sqr(sqrt(arg)) == arg ? */ + if ((res = mp_sqrt(arg,&t)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sqr(&t,&t)) != MP_OKAY) { + goto ERR; + } + + *ret = (mp_cmp_mag(&t,arg) == MP_EQ) ? MP_YES : MP_NO; +ERR:mp_clear(&t); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_jacobi.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_jacobi.c new file mode 100644 index 0000000000..07a9d65a24 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_jacobi.c @@ -0,0 +1,105 @@ +#include +#ifdef BN_MP_JACOBI_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* computes the jacobi c = (a | n) (or Legendre if n is prime) + * HAC pp. 73 Algorithm 2.149 + */ +int mp_jacobi (mp_int * a, mp_int * p, int *c) +{ + mp_int a1, p1; + int k, s, r, res; + mp_digit residue; + + /* if p <= 0 return MP_VAL */ + if (mp_cmp_d(p, 0) != MP_GT) { + return MP_VAL; + } + + /* step 1. if a == 0, return 0 */ + if (mp_iszero (a) == 1) { + *c = 0; + return MP_OKAY; + } + + /* step 2. if a == 1, return 1 */ + if (mp_cmp_d (a, 1) == MP_EQ) { + *c = 1; + return MP_OKAY; + } + + /* default */ + s = 0; + + /* step 3. write a = a1 * 2**k */ + if ((res = mp_init_copy (&a1, a)) != MP_OKAY) { + return res; + } + + if ((res = mp_init (&p1)) != MP_OKAY) { + goto LBL_A1; + } + + /* divide out larger power of two */ + k = mp_cnt_lsb(&a1); + if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) { + goto LBL_P1; + } + + /* step 4. if e is even set s=1 */ + if ((k & 1) == 0) { + s = 1; + } else { + /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */ + residue = p->dp[0] & 7; + + if (residue == 1 || residue == 7) { + s = 1; + } else if (residue == 3 || residue == 5) { + s = -1; + } + } + + /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */ + if ( ((p->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) { + s = -s; + } + + /* if a1 == 1 we're done */ + if (mp_cmp_d (&a1, 1) == MP_EQ) { + *c = s; + } else { + /* n1 = n mod a1 */ + if ((res = mp_mod (p, &a1, &p1)) != MP_OKAY) { + goto LBL_P1; + } + if ((res = mp_jacobi (&p1, &a1, &r)) != MP_OKAY) { + goto LBL_P1; + } + *c = s * r; + } + + /* done */ + res = MP_OKAY; +LBL_P1:mp_clear (&p1); +LBL_A1:mp_clear (&a1); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_karatsuba_mul.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_karatsuba_mul.c new file mode 100644 index 0000000000..d88986ef4f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_karatsuba_mul.c @@ -0,0 +1,167 @@ +#include +#ifdef BN_MP_KARATSUBA_MUL_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* c = |a| * |b| using Karatsuba Multiplication using + * three half size multiplications + * + * Let B represent the radix [e.g. 2**DIGIT_BIT] and + * let n represent half of the number of digits in + * the min(a,b) + * + * a = a1 * B**n + a0 + * b = b1 * B**n + b0 + * + * Then, a * b => + a1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0 + * + * Note that a1b1 and a0b0 are used twice and only need to be + * computed once. So in total three half size (half # of + * digit) multiplications are performed, a0b0, a1b1 and + * (a1+b1)(a0+b0) + * + * Note that a multiplication of half the digits requires + * 1/4th the number of single precision multiplications so in + * total after one call 25% of the single precision multiplications + * are saved. Note also that the call to mp_mul can end up back + * in this function if the a0, a1, b0, or b1 are above the threshold. + * This is known as divide-and-conquer and leads to the famous + * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than + * the standard O(N**2) that the baseline/comba methods use. + * Generally though the overhead of this method doesn't pay off + * until a certain size (N ~ 80) is reached. + */ +int mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int x0, x1, y0, y1, t1, x0y0, x1y1; + int B, err; + + /* default the return code to an error */ + err = MP_MEM; + + /* min # of digits */ + B = MIN (a->used, b->used); + + /* now divide in two */ + B = B >> 1; + + /* init copy all the temps */ + if (mp_init_size (&x0, B) != MP_OKAY) + goto ERR; + if (mp_init_size (&x1, a->used - B) != MP_OKAY) + goto X0; + if (mp_init_size (&y0, B) != MP_OKAY) + goto X1; + if (mp_init_size (&y1, b->used - B) != MP_OKAY) + goto Y0; + + /* init temps */ + if (mp_init_size (&t1, B * 2) != MP_OKAY) + goto Y1; + if (mp_init_size (&x0y0, B * 2) != MP_OKAY) + goto T1; + if (mp_init_size (&x1y1, B * 2) != MP_OKAY) + goto X0Y0; + + /* now shift the digits */ + x0.used = y0.used = B; + x1.used = a->used - B; + y1.used = b->used - B; + + { + register int x; + register mp_digit *tmpa, *tmpb, *tmpx, *tmpy; + + /* we copy the digits directly instead of using higher level functions + * since we also need to shift the digits + */ + tmpa = a->dp; + tmpb = b->dp; + + tmpx = x0.dp; + tmpy = y0.dp; + for (x = 0; x < B; x++) { + *tmpx++ = *tmpa++; + *tmpy++ = *tmpb++; + } + + tmpx = x1.dp; + for (x = B; x < a->used; x++) { + *tmpx++ = *tmpa++; + } + + tmpy = y1.dp; + for (x = B; x < b->used; x++) { + *tmpy++ = *tmpb++; + } + } + + /* only need to clamp the lower words since by definition the + * upper words x1/y1 must have a known number of digits + */ + mp_clamp (&x0); + mp_clamp (&y0); + + /* now calc the products x0y0 and x1y1 */ + /* after this x0 is no longer required, free temp [x0==t2]! */ + if (mp_mul (&x0, &y0, &x0y0) != MP_OKAY) + goto X1Y1; /* x0y0 = x0*y0 */ + if (mp_mul (&x1, &y1, &x1y1) != MP_OKAY) + goto X1Y1; /* x1y1 = x1*y1 */ + + /* now calc x1+x0 and y1+y0 */ + if (s_mp_add (&x1, &x0, &t1) != MP_OKAY) + goto X1Y1; /* t1 = x1 - x0 */ + if (s_mp_add (&y1, &y0, &x0) != MP_OKAY) + goto X1Y1; /* t2 = y1 - y0 */ + if (mp_mul (&t1, &x0, &t1) != MP_OKAY) + goto X1Y1; /* t1 = (x1 + x0) * (y1 + y0) */ + + /* add x0y0 */ + if (mp_add (&x0y0, &x1y1, &x0) != MP_OKAY) + goto X1Y1; /* t2 = x0y0 + x1y1 */ + if (s_mp_sub (&t1, &x0, &t1) != MP_OKAY) + goto X1Y1; /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */ + + /* shift by B */ + if (mp_lshd (&t1, B) != MP_OKAY) + goto X1Y1; /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))< +#ifdef BN_MP_KARATSUBA_SQR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Karatsuba squaring, computes b = a*a using three + * half size squarings + * + * See comments of karatsuba_mul for details. It + * is essentially the same algorithm but merely + * tuned to perform recursive squarings. + */ +int mp_karatsuba_sqr (mp_int * a, mp_int * b) +{ + mp_int x0, x1, t1, t2, x0x0, x1x1; + int B, err; + + err = MP_MEM; + + /* min # of digits */ + B = a->used; + + /* now divide in two */ + B = B >> 1; + + /* init copy all the temps */ + if (mp_init_size (&x0, B) != MP_OKAY) + goto ERR; + if (mp_init_size (&x1, a->used - B) != MP_OKAY) + goto X0; + + /* init temps */ + if (mp_init_size (&t1, a->used * 2) != MP_OKAY) + goto X1; + if (mp_init_size (&t2, a->used * 2) != MP_OKAY) + goto T1; + if (mp_init_size (&x0x0, B * 2) != MP_OKAY) + goto T2; + if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY) + goto X0X0; + + { + register int x; + register mp_digit *dst, *src; + + src = a->dp; + + /* now shift the digits */ + dst = x0.dp; + for (x = 0; x < B; x++) { + *dst++ = *src++; + } + + dst = x1.dp; + for (x = B; x < a->used; x++) { + *dst++ = *src++; + } + } + + x0.used = B; + x1.used = a->used - B; + + mp_clamp (&x0); + + /* now calc the products x0*x0 and x1*x1 */ + if (mp_sqr (&x0, &x0x0) != MP_OKAY) + goto X1X1; /* x0x0 = x0*x0 */ + if (mp_sqr (&x1, &x1x1) != MP_OKAY) + goto X1X1; /* x1x1 = x1*x1 */ + + /* now calc (x1+x0)**2 */ + if (s_mp_add (&x1, &x0, &t1) != MP_OKAY) + goto X1X1; /* t1 = x1 - x0 */ + if (mp_sqr (&t1, &t1) != MP_OKAY) + goto X1X1; /* t1 = (x1 - x0) * (x1 - x0) */ + + /* add x0y0 */ + if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY) + goto X1X1; /* t2 = x0x0 + x1x1 */ + if (s_mp_sub (&t1, &t2, &t1) != MP_OKAY) + goto X1X1; /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */ + + /* shift by B */ + if (mp_lshd (&t1, B) != MP_OKAY) + goto X1X1; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))< +#ifdef BN_MP_LCM_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* computes least common multiple as |a*b|/(a, b) */ +int mp_lcm (mp_int * a, mp_int * b, mp_int * c) +{ + int res; + mp_int t1, t2; + + + if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) { + return res; + } + + /* t1 = get the GCD of the two inputs */ + if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) { + goto LBL_T; + } + + /* divide the smallest by the GCD */ + if (mp_cmp_mag(a, b) == MP_LT) { + /* store quotient in t2 such that t2 * b is the LCM */ + if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) { + goto LBL_T; + } + res = mp_mul(b, &t2, c); + } else { + /* store quotient in t2 such that t2 * a is the LCM */ + if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) { + goto LBL_T; + } + res = mp_mul(a, &t2, c); + } + + /* fix the sign to positive */ + c->sign = MP_ZPOS; + +LBL_T: + mp_clear_multi (&t1, &t2, NULL); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_lshd.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_lshd.c new file mode 100644 index 0000000000..87c216bfc7 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_lshd.c @@ -0,0 +1,67 @@ +#include +#ifdef BN_MP_LSHD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* shift left a certain amount of digits */ +int mp_lshd (mp_int * a, int b) +{ + int x, res; + + /* if its less than zero return */ + if (b <= 0) { + return MP_OKAY; + } + + /* grow to fit the new digits */ + if (a->alloc < a->used + b) { + if ((res = mp_grow (a, a->used + b)) != MP_OKAY) { + return res; + } + } + + { + register mp_digit *top, *bottom; + + /* increment the used by the shift amount then copy upwards */ + a->used += b; + + /* top */ + top = a->dp + a->used - 1; + + /* base */ + bottom = a->dp + a->used - 1 - b; + + /* much like mp_rshd this is implemented using a sliding window + * except the window goes the otherway around. Copying from + * the bottom to the top. see bn_mp_rshd.c for more info. + */ + for (x = a->used - 1; x >= b; x--) { + *top-- = *bottom--; + } + + /* zero the lower digits */ + top = a->dp; + for (x = 0; x < b; x++) { + *top++ = 0; + } + } + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_mod.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_mod.c new file mode 100644 index 0000000000..68283285f9 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_mod.c @@ -0,0 +1,48 @@ +#include +#ifdef BN_MP_MOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* c = a mod b, 0 <= c < b */ +int +mp_mod (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int t; + int res; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + + if (t.sign != b->sign) { + res = mp_add (b, &t, c); + } else { + res = MP_OKAY; + mp_exch (&t, c); + } + + mp_clear (&t); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_mod_2d.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_mod_2d.c new file mode 100644 index 0000000000..77f13c3d56 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_mod_2d.c @@ -0,0 +1,55 @@ +#include +#ifdef BN_MP_MOD_2D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* calc a value mod 2**b */ +int +mp_mod_2d (mp_int * a, int b, mp_int * c) +{ + int x, res; + + /* if b is <= 0 then zero the int */ + if (b <= 0) { + mp_zero (c); + return MP_OKAY; + } + + /* if the modulus is larger than the value than return */ + if (b >= (int) (a->used * DIGIT_BIT)) { + res = mp_copy (a, c); + return res; + } + + /* copy */ + if ((res = mp_copy (a, c)) != MP_OKAY) { + return res; + } + + /* zero digits above the last digit of the modulus */ + for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) { + c->dp[x] = 0; + } + /* clear the digit that is not completely outside/inside the modulus */ + c->dp[b / DIGIT_BIT] &= + (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1)); + mp_clamp (c); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_mod_d.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_mod_d.c new file mode 100644 index 0000000000..4ad3d90d5a --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_mod_d.c @@ -0,0 +1,27 @@ +#include +#ifdef BN_MP_MOD_D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +int +mp_mod_d (mp_int * a, mp_digit b, mp_digit * c) +{ + return mp_div_d(a, b, NULL, c); +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_montgomery_calc_normalization.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_montgomery_calc_normalization.c new file mode 100644 index 0000000000..4825ab50a1 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_montgomery_calc_normalization.c @@ -0,0 +1,59 @@ +#include +#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* + * shifts with subtractions when the result is greater than b. + * + * The method is slightly modified to shift B unconditionally upto just under + * the leading bit of b. This saves alot of multiple precision shifting. + */ +int mp_montgomery_calc_normalization (mp_int * a, mp_int * b) +{ + int x, bits, res; + + /* how many bits of last digit does b use */ + bits = mp_count_bits (b) % DIGIT_BIT; + + if (b->used > 1) { + if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) { + return res; + } + } else { + mp_set(a, 1); + bits = 1; + } + + + /* now compute C = A * B mod b */ + for (x = bits - 1; x < (int)DIGIT_BIT; x++) { + if ((res = mp_mul_2 (a, a)) != MP_OKAY) { + return res; + } + if (mp_cmp_mag (a, b) != MP_LT) { + if ((res = s_mp_sub (a, b, a)) != MP_OKAY) { + return res; + } + } + } + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_montgomery_reduce.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_montgomery_reduce.c new file mode 100644 index 0000000000..3c73268075 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_montgomery_reduce.c @@ -0,0 +1,118 @@ +#include +#ifdef BN_MP_MONTGOMERY_REDUCE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* computes xR**-1 == x (mod N) via Montgomery Reduction */ +int +mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) +{ + int ix, res, digs; + mp_digit mu; + + /* can the fast reduction [comba] method be used? + * + * Note that unlike in mul you're safely allowed *less* + * than the available columns [255 per default] since carries + * are fixed up in the inner loop. + */ + digs = n->used * 2 + 1; + if ((digs < MP_WARRAY) && + n->used < + (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + return fast_mp_montgomery_reduce (x, n, rho); + } + + /* grow the input as required */ + if (x->alloc < digs) { + if ((res = mp_grow (x, digs)) != MP_OKAY) { + return res; + } + } + x->used = digs; + + for (ix = 0; ix < n->used; ix++) { + /* mu = ai * rho mod b + * + * The value of rho must be precalculated via + * montgomery_setup() such that + * it equals -1/n0 mod b this allows the + * following inner loop to reduce the + * input one digit at a time + */ + mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK); + + /* a = a + mu * m * b**i */ + { + register int iy; + register mp_digit *tmpn, *tmpx, u; + register mp_word r; + + /* alias for digits of the modulus */ + tmpn = n->dp; + + /* alias for the digits of x [the input] */ + tmpx = x->dp + ix; + + /* set the carry to zero */ + u = 0; + + /* Multiply and add in place */ + for (iy = 0; iy < n->used; iy++) { + /* compute product and sum */ + r = ((mp_word)mu) * ((mp_word)*tmpn++) + + ((mp_word) u) + ((mp_word) * tmpx); + + /* get carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + + /* fix digit */ + *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK)); + } + /* At this point the ix'th digit of x should be zero */ + + + /* propagate carries upwards as required*/ + while (u) { + *tmpx += u; + u = *tmpx >> DIGIT_BIT; + *tmpx++ &= MP_MASK; + } + } + } + + /* at this point the n.used'th least + * significant digits of x are all zero + * which means we can shift x to the + * right by n.used digits and the + * residue is unchanged. + */ + + /* x = x/b**n.used */ + mp_clamp(x); + mp_rshd (x, n->used); + + /* if x >= n then x = x - n */ + if (mp_cmp_mag (x, n) != MP_LT) { + return s_mp_sub (x, n, x); + } + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_montgomery_setup.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_montgomery_setup.c new file mode 100644 index 0000000000..0de27bb55d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_montgomery_setup.c @@ -0,0 +1,59 @@ +#include +#ifdef BN_MP_MONTGOMERY_SETUP_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* setups the montgomery reduction stuff */ +int +mp_montgomery_setup (mp_int * n, mp_digit * rho) +{ + mp_digit x, b; + +/* fast inversion mod 2**k + * + * Based on the fact that + * + * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n) + * => 2*X*A - X*X*A*A = 1 + * => 2*(1) - (1) = 1 + */ + b = n->dp[0]; + + if ((b & 1) == 0) { + return MP_VAL; + } + + x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ + x *= 2 - b * x; /* here x*a==1 mod 2**8 */ +#if !defined(MP_8BIT) + x *= 2 - b * x; /* here x*a==1 mod 2**16 */ +#endif +#if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT)) + x *= 2 - b * x; /* here x*a==1 mod 2**32 */ +#endif +#ifdef MP_64BIT + x *= 2 - b * x; /* here x*a==1 mod 2**64 */ +#endif + + /* rho = -1/m mod b */ + *rho = (unsigned long)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK; + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_mul.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_mul.c new file mode 100644 index 0000000000..deaac4239e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_mul.c @@ -0,0 +1,66 @@ +#include +#ifdef BN_MP_MUL_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* high level multiplication (handles sign) */ +int mp_mul (mp_int * a, mp_int * b, mp_int * c) +{ + int res, neg; + neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; + + /* use Toom-Cook? */ +#ifdef BN_MP_TOOM_MUL_C + if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) { + res = mp_toom_mul(a, b, c); + } else +#endif +#ifdef BN_MP_KARATSUBA_MUL_C + /* use Karatsuba? */ + if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) { + res = mp_karatsuba_mul (a, b, c); + } else +#endif + { + /* can we use the fast multiplier? + * + * The fast multiplier can be used if the output will + * have less than MP_WARRAY digits and the number of + * digits won't affect carry propagation + */ + int digs = a->used + b->used + 1; + +#ifdef BN_FAST_S_MP_MUL_DIGS_C + if ((digs < MP_WARRAY) && + MIN(a->used, b->used) <= + (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + res = fast_s_mp_mul_digs (a, b, c, digs); + } else +#endif +#ifdef BN_S_MP_MUL_DIGS_C + res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */ +#else + res = MP_VAL; +#endif + + } + c->sign = (c->used > 0) ? neg : MP_ZPOS; + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_mul_2.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_mul_2.c new file mode 100644 index 0000000000..4f7f43fa0a --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_mul_2.c @@ -0,0 +1,82 @@ +#include +#ifdef BN_MP_MUL_2_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* b = a*2 */ +int mp_mul_2(mp_int * a, mp_int * b) +{ + int x, res, oldused; + + /* grow to accomodate result */ + if (b->alloc < a->used + 1) { + if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) { + return res; + } + } + + oldused = b->used; + b->used = a->used; + + { + register mp_digit r, rr, *tmpa, *tmpb; + + /* alias for source */ + tmpa = a->dp; + + /* alias for dest */ + tmpb = b->dp; + + /* carry */ + r = 0; + for (x = 0; x < a->used; x++) { + + /* get what will be the *next* carry bit from the + * MSB of the current digit + */ + rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1)); + + /* now shift up this digit, add in the carry [from the previous] */ + *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK; + + /* copy the carry that would be from the source + * digit into the next iteration + */ + r = rr; + } + + /* new leading digit? */ + if (r != 0) { + /* add a MSB which is always 1 at this point */ + *tmpb = 1; + ++(b->used); + } + + /* now zero any excess digits on the destination + * that we didn't write to + */ + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } + } + b->sign = a->sign; + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_mul_2d.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_mul_2d.c new file mode 100644 index 0000000000..ad9a3def84 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_mul_2d.c @@ -0,0 +1,85 @@ +#include +#ifdef BN_MP_MUL_2D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* shift left by a certain bit count */ +int mp_mul_2d (mp_int * a, int b, mp_int * c) +{ + mp_digit d; + int res; + + /* copy */ + if (a != c) { + if ((res = mp_copy (a, c)) != MP_OKAY) { + return res; + } + } + + if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) { + if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) { + return res; + } + } + + /* shift by as many digits in the bit count */ + if (b >= (int)DIGIT_BIT) { + if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) { + return res; + } + } + + /* shift any bit count < DIGIT_BIT */ + d = (mp_digit) (b % DIGIT_BIT); + if (d != 0) { + register mp_digit *tmpc, shift, mask, r, rr; + register int x; + + /* bitmask for carries */ + mask = (((mp_digit)1) << d) - 1; + + /* shift for msbs */ + shift = DIGIT_BIT - d; + + /* alias */ + tmpc = c->dp; + + /* carry */ + r = 0; + for (x = 0; x < c->used; x++) { + /* get the higher bits of the current word */ + rr = (*tmpc >> shift) & mask; + + /* shift the current word and OR in the carry */ + *tmpc = ((*tmpc << d) | r) & MP_MASK; + ++tmpc; + + /* set the carry to the carry bits of the current word */ + r = rr; + } + + /* set final carry */ + if (r != 0) { + c->dp[(c->used)++] = r; + } + } + mp_clamp (c); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_mul_d.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_mul_d.c new file mode 100644 index 0000000000..13c60668af --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_mul_d.c @@ -0,0 +1,79 @@ +#include +#ifdef BN_MP_MUL_D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* multiply by a digit */ +int +mp_mul_d (mp_int * a, mp_digit b, mp_int * c) +{ + mp_digit u, *tmpa, *tmpc; + mp_word r; + int ix, res, olduse; + + /* make sure c is big enough to hold a*b */ + if (c->alloc < a->used + 1) { + if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* get the original destinations used count */ + olduse = c->used; + + /* set the sign */ + c->sign = a->sign; + + /* alias for a->dp [source] */ + tmpa = a->dp; + + /* alias for c->dp [dest] */ + tmpc = c->dp; + + /* zero carry */ + u = 0; + + /* compute columns */ + for (ix = 0; ix < a->used; ix++) { + /* compute product and carry sum for this term */ + r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b); + + /* mask off higher bits to get a single digit */ + *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* send carry into next iteration */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + + /* store final carry [if any] and increment ix offset */ + *tmpc++ = u; + ++ix; + + /* now zero digits above the top */ + while (ix++ < olduse) { + *tmpc++ = 0; + } + + /* set used count */ + c->used = a->used + 1; + mp_clamp(c); + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_mulmod.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_mulmod.c new file mode 100644 index 0000000000..eebca37db0 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_mulmod.c @@ -0,0 +1,40 @@ +#include +#ifdef BN_MP_MULMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* d = a * b (mod c) */ +int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + int res; + mp_int t; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_mul (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, c, d); + mp_clear (&t); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_n_root.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_n_root.c new file mode 100644 index 0000000000..2bdf975add --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_n_root.c @@ -0,0 +1,132 @@ +#include +#ifdef BN_MP_N_ROOT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* find the n'th root of an integer + * + * Result found such that (c)**b <= a and (c+1)**b > a + * + * This algorithm uses Newton's approximation + * x[i+1] = x[i] - f(x[i])/f'(x[i]) + * which will find the root in log(N) time where + * each step involves a fair bit. This is not meant to + * find huge roots [square and cube, etc]. + */ +int mp_n_root (mp_int * a, mp_digit b, mp_int * c) +{ + mp_int t1, t2, t3; + int res, neg; + + /* input must be positive if b is even */ + if ((b & 1) == 0 && a->sign == MP_NEG) { + return MP_VAL; + } + + if ((res = mp_init (&t1)) != MP_OKAY) { + return res; + } + + if ((res = mp_init (&t2)) != MP_OKAY) { + goto LBL_T1; + } + + if ((res = mp_init (&t3)) != MP_OKAY) { + goto LBL_T2; + } + + /* if a is negative fudge the sign but keep track */ + neg = a->sign; + a->sign = MP_ZPOS; + + /* t2 = 2 */ + mp_set (&t2, 2); + + do { + /* t1 = t2 */ + if ((res = mp_copy (&t2, &t1)) != MP_OKAY) { + goto LBL_T3; + } + + /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */ + + /* t3 = t1**(b-1) */ + if ((res = mp_expt_d (&t1, b - 1, &t3)) != MP_OKAY) { + goto LBL_T3; + } + + /* numerator */ + /* t2 = t1**b */ + if ((res = mp_mul (&t3, &t1, &t2)) != MP_OKAY) { + goto LBL_T3; + } + + /* t2 = t1**b - a */ + if ((res = mp_sub (&t2, a, &t2)) != MP_OKAY) { + goto LBL_T3; + } + + /* denominator */ + /* t3 = t1**(b-1) * b */ + if ((res = mp_mul_d (&t3, b, &t3)) != MP_OKAY) { + goto LBL_T3; + } + + /* t3 = (t1**b - a)/(b * t1**(b-1)) */ + if ((res = mp_div (&t2, &t3, &t3, NULL)) != MP_OKAY) { + goto LBL_T3; + } + + if ((res = mp_sub (&t1, &t3, &t2)) != MP_OKAY) { + goto LBL_T3; + } + } while (mp_cmp (&t1, &t2) != MP_EQ); + + /* result can be off by a few so check */ + for (;;) { + if ((res = mp_expt_d (&t1, b, &t2)) != MP_OKAY) { + goto LBL_T3; + } + + if (mp_cmp (&t2, a) == MP_GT) { + if ((res = mp_sub_d (&t1, 1, &t1)) != MP_OKAY) { + goto LBL_T3; + } + } else { + break; + } + } + + /* reset the sign of a first */ + a->sign = neg; + + /* set the result */ + mp_exch (&t1, c); + + /* set the sign of the result */ + c->sign = neg; + + res = MP_OKAY; + +LBL_T3:mp_clear (&t3); +LBL_T2:mp_clear (&t2); +LBL_T1:mp_clear (&t1); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_neg.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_neg.c new file mode 100644 index 0000000000..0e868ce55d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_neg.c @@ -0,0 +1,40 @@ +#include +#ifdef BN_MP_NEG_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* b = -a */ +int mp_neg (mp_int * a, mp_int * b) +{ + int res; + if (a != b) { + if ((res = mp_copy (a, b)) != MP_OKAY) { + return res; + } + } + + if (mp_iszero(b) != MP_YES) { + b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS; + } else { + b->sign = MP_ZPOS; + } + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_or.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_or.c new file mode 100644 index 0000000000..5c2761a879 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_or.c @@ -0,0 +1,50 @@ +#include +#ifdef BN_MP_OR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* OR two ints together */ +int mp_or (mp_int * a, mp_int * b, mp_int * c) +{ + int res, ix, px; + mp_int t, *x; + + if (a->used > b->used) { + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + px = b->used; + x = b; + } else { + if ((res = mp_init_copy (&t, b)) != MP_OKAY) { + return res; + } + px = a->used; + x = a; + } + + for (ix = 0; ix < px; ix++) { + t.dp[ix] |= x->dp[ix]; + } + mp_clamp (&t); + mp_exch (c, &t); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_prime_fermat.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_prime_fermat.c new file mode 100644 index 0000000000..b4b668b38f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_prime_fermat.c @@ -0,0 +1,62 @@ +#include +#ifdef BN_MP_PRIME_FERMAT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* performs one Fermat test. + * + * If "a" were prime then b**a == b (mod a) since the order of + * the multiplicative sub-group would be phi(a) = a-1. That means + * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a). + * + * Sets result to 1 if the congruence holds, or zero otherwise. + */ +int mp_prime_fermat (mp_int * a, mp_int * b, int *result) +{ + mp_int t; + int err; + + /* default to composite */ + *result = MP_NO; + + /* ensure b > 1 */ + if (mp_cmp_d(b, 1) != MP_GT) { + return MP_VAL; + } + + /* init t */ + if ((err = mp_init (&t)) != MP_OKAY) { + return err; + } + + /* compute t = b**a mod a */ + if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) { + goto LBL_T; + } + + /* is it equal to b? */ + if (mp_cmp (&t, b) == MP_EQ) { + *result = MP_YES; + } + + err = MP_OKAY; +LBL_T:mp_clear (&t); + return err; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_prime_is_divisible.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_prime_is_divisible.c new file mode 100644 index 0000000000..7993ead580 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_prime_is_divisible.c @@ -0,0 +1,50 @@ +#include +#ifdef BN_MP_PRIME_IS_DIVISIBLE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* determines if an integers is divisible by one + * of the first PRIME_SIZE primes or not + * + * sets result to 0 if not, 1 if yes + */ +int mp_prime_is_divisible (mp_int * a, int *result) +{ + int err, ix; + mp_digit res; + + /* default to not */ + *result = MP_NO; + + for (ix = 0; ix < PRIME_SIZE; ix++) { + /* what is a mod LBL_prime_tab[ix] */ + if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) { + return err; + } + + /* is the residue zero? */ + if (res == 0) { + *result = MP_YES; + return MP_OKAY; + } + } + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_prime_is_prime.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_prime_is_prime.c new file mode 100644 index 0000000000..09908df58b --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_prime_is_prime.c @@ -0,0 +1,83 @@ +#include +#ifdef BN_MP_PRIME_IS_PRIME_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* performs a variable number of rounds of Miller-Rabin + * + * Probability of error after t rounds is no more than + + * + * Sets result to 1 if probably prime, 0 otherwise + */ +int mp_prime_is_prime (mp_int * a, int t, int *result) +{ + mp_int b; + int ix, err, res; + + /* default to no */ + *result = MP_NO; + + /* valid value of t? */ + if (t <= 0 || t > PRIME_SIZE) { + return MP_VAL; + } + + /* is the input equal to one of the primes in the table? */ + for (ix = 0; ix < PRIME_SIZE; ix++) { + if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) { + *result = 1; + return MP_OKAY; + } + } + + /* first perform trial division */ + if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) { + return err; + } + + /* return if it was trivially divisible */ + if (res == MP_YES) { + return MP_OKAY; + } + + /* now perform the miller-rabin rounds */ + if ((err = mp_init (&b)) != MP_OKAY) { + return err; + } + + for (ix = 0; ix < t; ix++) { + /* set the prime */ + mp_set (&b, ltm_prime_tab[ix]); + + if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) { + goto LBL_B; + } + + if (res == MP_NO) { + goto LBL_B; + } + } + + /* passed the test */ + *result = MP_YES; +LBL_B:mp_clear (&b); + return err; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_prime_miller_rabin.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_prime_miller_rabin.c new file mode 100644 index 0000000000..085e1e8f84 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_prime_miller_rabin.c @@ -0,0 +1,103 @@ +#include +#ifdef BN_MP_PRIME_MILLER_RABIN_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Miller-Rabin test of "a" to the base of "b" as described in + * HAC pp. 139 Algorithm 4.24 + * + * Sets result to 0 if definitely composite or 1 if probably prime. + * Randomly the chance of error is no more than 1/4 and often + * very much lower. + */ +int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result) +{ + mp_int n1, y, r; + int s, j, err; + + /* default */ + *result = MP_NO; + + /* ensure b > 1 */ + if (mp_cmp_d(b, 1) != MP_GT) { + return MP_VAL; + } + + /* get n1 = a - 1 */ + if ((err = mp_init_copy (&n1, a)) != MP_OKAY) { + return err; + } + if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) { + goto LBL_N1; + } + + /* set 2**s * r = n1 */ + if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) { + goto LBL_N1; + } + + /* count the number of least significant bits + * which are zero + */ + s = mp_cnt_lsb(&r); + + /* now divide n - 1 by 2**s */ + if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) { + goto LBL_R; + } + + /* compute y = b**r mod a */ + if ((err = mp_init (&y)) != MP_OKAY) { + goto LBL_R; + } + if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) { + goto LBL_Y; + } + + /* if y != 1 and y != n1 do */ + if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) { + j = 1; + /* while j <= s-1 and y != n1 */ + while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) { + if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) { + goto LBL_Y; + } + + /* if y == 1 then composite */ + if (mp_cmp_d (&y, 1) == MP_EQ) { + goto LBL_Y; + } + + ++j; + } + + /* if y != n1 then composite */ + if (mp_cmp (&y, &n1) != MP_EQ) { + goto LBL_Y; + } + } + + /* probably prime now */ + *result = MP_YES; +LBL_Y:mp_clear (&y); +LBL_R:mp_clear (&r); +LBL_N1:mp_clear (&n1); + return err; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_prime_next_prime.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_prime_next_prime.c new file mode 100644 index 0000000000..37a03c64f9 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_prime_next_prime.c @@ -0,0 +1,170 @@ +#include +#ifdef BN_MP_PRIME_NEXT_PRIME_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* finds the next prime after the number "a" using "t" trials + * of Miller-Rabin. + * + * bbs_style = 1 means the prime must be congruent to 3 mod 4 + */ +int mp_prime_next_prime(mp_int *a, int t, int bbs_style) +{ + int err, res, x, y; + mp_digit res_tab[PRIME_SIZE], step, kstep; + mp_int b; + + /* ensure t is valid */ + if (t <= 0 || t > PRIME_SIZE) { + return MP_VAL; + } + + /* force positive */ + a->sign = MP_ZPOS; + + /* simple algo if a is less than the largest prime in the table */ + if (mp_cmp_d(a, ltm_prime_tab[PRIME_SIZE-1]) == MP_LT) { + /* find which prime it is bigger than */ + for (x = PRIME_SIZE - 2; x >= 0; x--) { + if (mp_cmp_d(a, ltm_prime_tab[x]) != MP_LT) { + if (bbs_style == 1) { + /* ok we found a prime smaller or + * equal [so the next is larger] + * + * however, the prime must be + * congruent to 3 mod 4 + */ + if ((ltm_prime_tab[x + 1] & 3) != 3) { + /* scan upwards for a prime congruent to 3 mod 4 */ + for (y = x + 1; y < PRIME_SIZE; y++) { + if ((ltm_prime_tab[y] & 3) == 3) { + mp_set(a, ltm_prime_tab[y]); + return MP_OKAY; + } + } + } + } else { + mp_set(a, ltm_prime_tab[x + 1]); + return MP_OKAY; + } + } + } + /* at this point a maybe 1 */ + if (mp_cmp_d(a, 1) == MP_EQ) { + mp_set(a, 2); + return MP_OKAY; + } + /* fall through to the sieve */ + } + + /* generate a prime congruent to 3 mod 4 or 1/3 mod 4? */ + if (bbs_style == 1) { + kstep = 4; + } else { + kstep = 2; + } + + /* at this point we will use a combination of a sieve and Miller-Rabin */ + + if (bbs_style == 1) { + /* if a mod 4 != 3 subtract the correct value to make it so */ + if ((a->dp[0] & 3) != 3) { + if ((err = mp_sub_d(a, (a->dp[0] & 3) + 1, a)) != MP_OKAY) { return err; }; + } + } else { + if (mp_iseven(a) == 1) { + /* force odd */ + if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { + return err; + } + } + } + + /* generate the restable */ + for (x = 1; x < PRIME_SIZE; x++) { + if ((err = mp_mod_d(a, ltm_prime_tab[x], res_tab + x)) != MP_OKAY) { + return err; + } + } + + /* init temp used for Miller-Rabin Testing */ + if ((err = mp_init(&b)) != MP_OKAY) { + return err; + } + + for (;;) { + /* skip to the next non-trivially divisible candidate */ + step = 0; + do { + /* y == 1 if any residue was zero [e.g. cannot be prime] */ + y = 0; + + /* increase step to next candidate */ + step += kstep; + + /* compute the new residue without using division */ + for (x = 1; x < PRIME_SIZE; x++) { + /* add the step to each residue */ + res_tab[x] += kstep; + + /* subtract the modulus [instead of using division] */ + if (res_tab[x] >= ltm_prime_tab[x]) { + res_tab[x] -= ltm_prime_tab[x]; + } + + /* set flag if zero */ + if (res_tab[x] == 0) { + y = 1; + } + } + } while (y == 1 && step < ((((mp_digit)1)<= ((((mp_digit)1)< +#ifdef BN_MP_PRIME_RABIN_MILLER_TRIALS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + + +static const struct { + int k, t; +} sizes[] = { +{ 128, 28 }, +{ 256, 16 }, +{ 384, 10 }, +{ 512, 7 }, +{ 640, 6 }, +{ 768, 5 }, +{ 896, 4 }, +{ 1024, 4 } +}; + +/* returns # of RM trials required for a given bit size */ +int mp_prime_rabin_miller_trials(int size) +{ + int x; + + for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) { + if (sizes[x].k == size) { + return sizes[x].t; + } else if (sizes[x].k > size) { + return (x == 0) ? sizes[0].t : sizes[x - 1].t; + } + } + return sizes[x-1].t + 1; +} + + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_prime_random_ex.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_prime_random_ex.c new file mode 100644 index 0000000000..c6afd672d7 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_prime_random_ex.c @@ -0,0 +1,125 @@ +#include +#ifdef BN_MP_PRIME_RANDOM_EX_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* makes a truly random prime of a given size (bits), + * + * Flags are as follows: + * + * LTM_PRIME_BBS - make prime congruent to 3 mod 4 + * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS) + * LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero + * LTM_PRIME_2MSB_ON - make the 2nd highest bit one + * + * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can + * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself + * so it can be NULL + * + */ + +/* This is possibly the mother of all prime generation functions, muahahahahaha! */ +int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat) +{ + unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb; + int res, err, bsize, maskOR_msb_offset; + + /* sanity check the input */ + if (size <= 1 || t <= 0) { + return MP_VAL; + } + + /* LTM_PRIME_SAFE implies LTM_PRIME_BBS */ + if (flags & LTM_PRIME_SAFE) { + flags |= LTM_PRIME_BBS; + } + + /* calc the byte size */ + bsize = (size>>3) + ((size&7)?1:0); + + /* we need a buffer of bsize bytes */ + tmp = OPT_CAST(unsigned char) XMALLOC(bsize); + if (tmp == NULL) { + return MP_MEM; + } + + /* calc the maskAND value for the MSbyte*/ + maskAND = ((size&7) == 0) ? 0xFF : (0xFF >> (8 - (size & 7))); + + /* calc the maskOR_msb */ + maskOR_msb = 0; + maskOR_msb_offset = ((size & 7) == 1) ? 1 : 0; + if (flags & LTM_PRIME_2MSB_ON) { + maskOR_msb |= 0x80 >> ((9 - size) & 7); + } + + /* get the maskOR_lsb */ + maskOR_lsb = 1; + if (flags & LTM_PRIME_BBS) { + maskOR_lsb |= 3; + } + + do { + /* read the bytes */ + if (cb(tmp, bsize, dat) != bsize) { + err = MP_VAL; + goto error; + } + + /* work over the MSbyte */ + tmp[0] &= maskAND; + tmp[0] |= 1 << ((size - 1) & 7); + + /* mix in the maskORs */ + tmp[maskOR_msb_offset] |= maskOR_msb; + tmp[bsize-1] |= maskOR_lsb; + + /* read it in */ + if ((err = mp_read_unsigned_bin(a, tmp, bsize)) != MP_OKAY) { goto error; } + + /* is it prime? */ + if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; } + if (res == MP_NO) { + continue; + } + + if (flags & LTM_PRIME_SAFE) { + /* see if (a-1)/2 is prime */ + if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { goto error; } + if ((err = mp_div_2(a, a)) != MP_OKAY) { goto error; } + + /* is it prime? */ + if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; } + } + } while (res == MP_NO); + + if (flags & LTM_PRIME_SAFE) { + /* restore a to the original value */ + if ((err = mp_mul_2(a, a)) != MP_OKAY) { goto error; } + if ((err = mp_add_d(a, 1, a)) != MP_OKAY) { goto error; } + } + + err = MP_OKAY; +error: + XFREE(tmp); + return err; +} + + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_radix_size.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_radix_size.c new file mode 100644 index 0000000000..0c5a4391fe --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_radix_size.c @@ -0,0 +1,78 @@ +#include +#ifdef BN_MP_RADIX_SIZE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* returns size of ASCII reprensentation */ +int mp_radix_size (mp_int * a, int radix, int *size) +{ + int res, digs; + mp_int t; + mp_digit d; + + *size = 0; + + /* special case for binary */ + if (radix == 2) { + *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1; + return MP_OKAY; + } + + /* make sure the radix is in range */ + if (radix < 2 || radix > 64) { + return MP_VAL; + } + + if (mp_iszero(a) == MP_YES) { + *size = 2; + return MP_OKAY; + } + + /* digs is the digit count */ + digs = 0; + + /* if it's negative add one for the sign */ + if (a->sign == MP_NEG) { + ++digs; + } + + /* init a copy of the input */ + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + /* force temp to positive */ + t.sign = MP_ZPOS; + + /* fetch out all of the digits */ + while (mp_iszero (&t) == MP_NO) { + if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { + mp_clear (&t); + return res; + } + ++digs; + } + mp_clear (&t); + + /* return digs + 1, the 1 is for the NULL byte that would be required. */ + *size = digs + 1; + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_radix_smap.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_radix_smap.c new file mode 100644 index 0000000000..b3abd3ee7d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_radix_smap.c @@ -0,0 +1,24 @@ +#include +#ifdef BN_MP_RADIX_SMAP_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* chars used in radix conversions */ +const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_rand.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_rand.c new file mode 100644 index 0000000000..96e4e46307 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_rand.c @@ -0,0 +1,55 @@ +#include +#ifdef BN_MP_RAND_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* makes a pseudo-random int of a given size */ +int +mp_rand (mp_int * a, int digits) +{ + int res; + mp_digit d; + + mp_zero (a); + if (digits <= 0) { + return MP_OKAY; + } + + /* first place a random non-zero digit */ + do { + d = ((mp_digit) abs (rand ())) & MP_MASK; + } while (d == 0); + + if ((res = mp_add_d (a, d, a)) != MP_OKAY) { + return res; + } + + while (--digits > 0) { + if ((res = mp_lshd (a, 1)) != MP_OKAY) { + return res; + } + + if ((res = mp_add_d (a, ((mp_digit) abs (rand ())), a)) != MP_OKAY) { + return res; + } + } + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_read_radix.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_read_radix.c new file mode 100644 index 0000000000..68dd9f47c4 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_read_radix.c @@ -0,0 +1,85 @@ +#include +#ifdef BN_MP_READ_RADIX_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* read a string [ASCII] in a given radix */ +int mp_read_radix (mp_int * a, const char *str, int radix) +{ + int y, res, neg; + char ch; + + /* zero the digit bignum */ + mp_zero(a); + + /* make sure the radix is ok */ + if (radix < 2 || radix > 64) { + return MP_VAL; + } + + /* if the leading digit is a + * minus set the sign to negative. + */ + if (*str == '-') { + ++str; + neg = MP_NEG; + } else { + neg = MP_ZPOS; + } + + /* set the integer to the default of zero */ + mp_zero (a); + + /* process each digit of the string */ + while (*str) { + /* if the radix < 36 the conversion is case insensitive + * this allows numbers like 1AB and 1ab to represent the same value + * [e.g. in hex] + */ + ch = (char) ((radix < 36) ? toupper (*str) : *str); + for (y = 0; y < 64; y++) { + if (ch == mp_s_rmap[y]) { + break; + } + } + + /* if the char was found in the map + * and is less than the given radix add it + * to the number, otherwise exit the loop. + */ + if (y < radix) { + if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) { + return res; + } + if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) { + return res; + } + } else { + break; + } + ++str; + } + + /* set the sign only if a != 0 */ + if (mp_iszero(a) != 1) { + a->sign = neg; + } + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_read_signed_bin.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_read_signed_bin.c new file mode 100644 index 0000000000..92924e843d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_read_signed_bin.c @@ -0,0 +1,41 @@ +#include +#ifdef BN_MP_READ_SIGNED_BIN_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* read signed bin, big endian, first byte is 0==positive or 1==negative */ +int mp_read_signed_bin (mp_int * a, const unsigned char *b, int c) +{ + int res; + + /* read magnitude */ + if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) { + return res; + } + + /* first byte is 0 for positive, non-zero for negative */ + if (b[0] == 0) { + a->sign = MP_ZPOS; + } else { + a->sign = MP_NEG; + } + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_read_unsigned_bin.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_read_unsigned_bin.c new file mode 100644 index 0000000000..5a7fa91647 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_read_unsigned_bin.c @@ -0,0 +1,55 @@ +#include +#ifdef BN_MP_READ_UNSIGNED_BIN_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* reads a unsigned char array, assumes the msb is stored first [big endian] */ +int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c) +{ + int res; + + /* make sure there are at least two digits */ + if (a->alloc < 2) { + if ((res = mp_grow(a, 2)) != MP_OKAY) { + return res; + } + } + + /* zero the int */ + mp_zero (a); + + /* read the bytes in */ + while (c-- > 0) { + if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) { + return res; + } + +#ifndef MP_8BIT + a->dp[0] |= *b++; + a->used += 1; +#else + a->dp[0] = (*b & MP_MASK); + a->dp[1] |= ((*b++ >> 7U) & 1); + a->used += 2; +#endif + } + mp_clamp (a); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce.c new file mode 100644 index 0000000000..953b7c3db5 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce.c @@ -0,0 +1,100 @@ +#include +#ifdef BN_MP_REDUCE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* reduces x mod m, assumes 0 < x < m**2, mu is + * precomputed via mp_reduce_setup. + * From HAC pp.604 Algorithm 14.42 + */ +int mp_reduce (mp_int * x, mp_int * m, mp_int * mu) +{ + mp_int q; + int res, um = m->used; + + /* q = x */ + if ((res = mp_init_copy (&q, x)) != MP_OKAY) { + return res; + } + + /* q1 = x / b**(k-1) */ + mp_rshd (&q, um - 1); + + /* according to HAC this optimization is ok */ + if (((unsigned long) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) { + if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) { + goto CLEANUP; + } + } else { +#ifdef BN_S_MP_MUL_HIGH_DIGS_C + if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { + goto CLEANUP; + } +#elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) + if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { + goto CLEANUP; + } +#else + { + res = MP_VAL; + goto CLEANUP; + } +#endif + } + + /* q3 = q2 / b**(k+1) */ + mp_rshd (&q, um + 1); + + /* x = x mod b**(k+1), quick (no division) */ + if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) { + goto CLEANUP; + } + + /* q = q * m mod b**(k+1), quick (no division) */ + if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) { + goto CLEANUP; + } + + /* x = x - q */ + if ((res = mp_sub (x, &q, x)) != MP_OKAY) { + goto CLEANUP; + } + + /* If x < 0, add b**(k+1) to it */ + if (mp_cmp_d (x, 0) == MP_LT) { + mp_set (&q, 1); + if ((res = mp_lshd (&q, um + 1)) != MP_OKAY) + goto CLEANUP; + if ((res = mp_add (x, &q, x)) != MP_OKAY) + goto CLEANUP; + } + + /* Back off if it's too big */ + while (mp_cmp (x, m) != MP_LT) { + if ((res = s_mp_sub (x, m, x)) != MP_OKAY) { + goto CLEANUP; + } + } + +CLEANUP: + mp_clear (&q); + + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce_2k.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce_2k.c new file mode 100644 index 0000000000..63549e5838 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce_2k.c @@ -0,0 +1,61 @@ +#include +#ifdef BN_MP_REDUCE_2K_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* reduces a modulo n where n is of the form 2**p - d */ +int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d) +{ + mp_int q; + int p, res; + + if ((res = mp_init(&q)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(n); +top: + /* q = a/2**p, a = a mod 2**p */ + if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { + goto ERR; + } + + if (d != 1) { + /* q = q * d */ + if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) { + goto ERR; + } + } + + /* a = a + q */ + if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { + goto ERR; + } + + if (mp_cmp_mag(a, n) != MP_LT) { + s_mp_sub(a, n, a); + goto top; + } + +ERR: + mp_clear(&q); + return res; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce_2k_l.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce_2k_l.c new file mode 100644 index 0000000000..19489b4ee2 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce_2k_l.c @@ -0,0 +1,62 @@ +#include +#ifdef BN_MP_REDUCE_2K_L_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* reduces a modulo n where n is of the form 2**p - d + This differs from reduce_2k since "d" can be larger + than a single digit. +*/ +int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d) +{ + mp_int q; + int p, res; + + if ((res = mp_init(&q)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(n); +top: + /* q = a/2**p, a = a mod 2**p */ + if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { + goto ERR; + } + + /* q = q * d */ + if ((res = mp_mul(&q, d, &q)) != MP_OKAY) { + goto ERR; + } + + /* a = a + q */ + if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { + goto ERR; + } + + if (mp_cmp_mag(a, n) != MP_LT) { + s_mp_sub(a, n, a); + goto top; + } + +ERR: + mp_clear(&q); + return res; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce_2k_setup.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce_2k_setup.c new file mode 100644 index 0000000000..700e7bff05 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce_2k_setup.c @@ -0,0 +1,47 @@ +#include +#ifdef BN_MP_REDUCE_2K_SETUP_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* determines the setup value */ +int mp_reduce_2k_setup(mp_int *a, mp_digit *d) +{ + int res, p; + mp_int tmp; + + if ((res = mp_init(&tmp)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(a); + if ((res = mp_2expt(&tmp, p)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + *d = tmp.dp[0]; + mp_clear(&tmp); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce_2k_setup_l.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce_2k_setup_l.c new file mode 100644 index 0000000000..f53aa5461f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce_2k_setup_l.c @@ -0,0 +1,44 @@ +#include +#ifdef BN_MP_REDUCE_2K_SETUP_L_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* determines the setup value */ +int mp_reduce_2k_setup_l(mp_int *a, mp_int *d) +{ + int res; + mp_int tmp; + + if ((res = mp_init(&tmp)) != MP_OKAY) { + return res; + } + + if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) { + goto ERR; + } + + if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) { + goto ERR; + } + +ERR: + mp_clear(&tmp); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce_is_2k.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce_is_2k.c new file mode 100644 index 0000000000..22686831b9 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce_is_2k.c @@ -0,0 +1,52 @@ +#include +#ifdef BN_MP_REDUCE_IS_2K_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* determines if mp_reduce_2k can be used */ +int mp_reduce_is_2k(mp_int *a) +{ + int ix, iy, iw; + mp_digit iz; + + if (a->used == 0) { + return MP_NO; + } else if (a->used == 1) { + return MP_YES; + } else if (a->used > 1) { + iy = mp_count_bits(a); + iz = 1; + iw = 1; + + /* Test every bit from the second digit up, must be 1 */ + for (ix = DIGIT_BIT; ix < iy; ix++) { + if ((a->dp[iw] & iz) == 0) { + return MP_NO; + } + iz <<= 1; + if (iz > (mp_digit)MP_MASK) { + ++iw; + iz = 1; + } + } + } + return MP_YES; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce_is_2k_l.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce_is_2k_l.c new file mode 100644 index 0000000000..e7b064aa6f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce_is_2k_l.c @@ -0,0 +1,44 @@ +#include +#ifdef BN_MP_REDUCE_IS_2K_L_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* determines if reduce_2k_l can be used */ +int mp_reduce_is_2k_l(mp_int *a) +{ + int ix, iy; + + if (a->used == 0) { + return MP_NO; + } else if (a->used == 1) { + return MP_YES; + } else if (a->used > 1) { + /* if more than half of the digits are -1 we're sold */ + for (iy = ix = 0; ix < a->used; ix++) { + if (a->dp[ix] == MP_MASK) { + ++iy; + } + } + return (iy >= (a->used/2)) ? MP_YES : MP_NO; + + } + return MP_NO; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce_setup.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce_setup.c new file mode 100644 index 0000000000..a9c20aee10 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_reduce_setup.c @@ -0,0 +1,34 @@ +#include +#ifdef BN_MP_REDUCE_SETUP_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* pre-calculate the value required for Barrett reduction + * For a given modulus "b" it calulates the value required in "a" + */ +int mp_reduce_setup (mp_int * a, mp_int * b) +{ + int res; + + if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) { + return res; + } + return mp_div (a, b, a, NULL); +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_rshd.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_rshd.c new file mode 100644 index 0000000000..d859eb5036 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_rshd.c @@ -0,0 +1,72 @@ +#include +#ifdef BN_MP_RSHD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* shift right a certain amount of digits */ +void mp_rshd (mp_int * a, int b) +{ + int x; + + /* if b <= 0 then ignore it */ + if (b <= 0) { + return; + } + + /* if b > used then simply zero it and return */ + if (a->used <= b) { + mp_zero (a); + return; + } + + { + register mp_digit *bottom, *top; + + /* shift the digits down */ + + /* bottom */ + bottom = a->dp; + + /* top [offset into digits] */ + top = a->dp + b; + + /* this is implemented as a sliding window where + * the window is b-digits long and digits from + * the top of the window are copied to the bottom + * + * e.g. + + b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> + /\ | ----> + \-------------------/ ----> + */ + for (x = 0; x < (a->used - b); x++) { + *bottom++ = *top++; + } + + /* zero the top digits */ + for (; x < a->used; x++) { + *bottom++ = 0; + } + } + + /* remove excess digits */ + a->used -= b; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_set.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_set.c new file mode 100644 index 0000000000..412673abbe --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_set.c @@ -0,0 +1,29 @@ +#include +#ifdef BN_MP_SET_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* set to a digit */ +void mp_set (mp_int * a, mp_digit b) +{ + mp_zero (a); + a->dp[0] = b & MP_MASK; + a->used = (a->dp[0] != 0) ? 1 : 0; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_set_int.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_set_int.c new file mode 100644 index 0000000000..b8842e0823 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_set_int.c @@ -0,0 +1,48 @@ +#include +#ifdef BN_MP_SET_INT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* set a 32-bit const */ +int mp_set_int (mp_int * a, unsigned long b) +{ + int x, res; + + mp_zero (a); + + /* set four bits at a time */ + for (x = 0; x < 8; x++) { + /* shift the number up four bits */ + if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) { + return res; + } + + /* OR in the top four bits of the source */ + a->dp[0] |= (b >> 28) & 15; + + /* shift the source up to the next four bits */ + b <<= 4; + + /* ensure that digits are not clamped off */ + a->used += 1; + } + mp_clamp (a); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_shrink.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_shrink.c new file mode 100644 index 0000000000..4c45157100 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_shrink.c @@ -0,0 +1,40 @@ +#include +#ifdef BN_MP_SHRINK_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* shrink a bignum */ +int mp_shrink (mp_int * a) +{ + mp_digit *tmp; + int used = 1; + + if(a->used > 0) + used = a->used; + + if (a->alloc != used) { + if ((tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * used)) == NULL) { + return MP_MEM; + } + a->dp = tmp; + a->alloc = used; + } + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: v0.42.0 $ */ +/* $Date: 2010-06-02 15:09:36 +0200 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_signed_bin_size.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_signed_bin_size.c new file mode 100644 index 0000000000..b28d4027b0 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_signed_bin_size.c @@ -0,0 +1,27 @@ +#include +#ifdef BN_MP_SIGNED_BIN_SIZE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* get the size for an signed equivalent */ +int mp_signed_bin_size (mp_int * a) +{ + return 1 + mp_unsigned_bin_size (a); +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_sqr.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_sqr.c new file mode 100644 index 0000000000..590dc84713 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_sqr.c @@ -0,0 +1,58 @@ +#include +#ifdef BN_MP_SQR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* computes b = a*a */ +int +mp_sqr (mp_int * a, mp_int * b) +{ + int res; + +#ifdef BN_MP_TOOM_SQR_C + /* use Toom-Cook? */ + if (a->used >= TOOM_SQR_CUTOFF) { + res = mp_toom_sqr(a, b); + /* Karatsuba? */ + } else +#endif +#ifdef BN_MP_KARATSUBA_SQR_C +if (a->used >= KARATSUBA_SQR_CUTOFF) { + res = mp_karatsuba_sqr (a, b); + } else +#endif + { +#ifdef BN_FAST_S_MP_SQR_C + /* can we use the fast comba multiplier? */ + if ((a->used * 2 + 1) < MP_WARRAY && + a->used < + (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) { + res = fast_s_mp_sqr (a, b); + } else +#endif +#ifdef BN_S_MP_SQR_C + res = s_mp_sqr (a, b); +#else + res = MP_VAL; +#endif + } + b->sign = MP_ZPOS; + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_sqrmod.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_sqrmod.c new file mode 100644 index 0000000000..369028bd2f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_sqrmod.c @@ -0,0 +1,41 @@ +#include +#ifdef BN_MP_SQRMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* c = a * a (mod b) */ +int +mp_sqrmod (mp_int * a, mp_int * b, mp_int * c) +{ + int res; + mp_int t; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_sqr (a, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, b, c); + mp_clear (&t); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_sqrt.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_sqrt.c new file mode 100644 index 0000000000..d4fd58e29d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_sqrt.c @@ -0,0 +1,81 @@ +#include +#ifdef BN_MP_SQRT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* this function is less generic than mp_n_root, simpler and faster */ +int mp_sqrt(mp_int *arg, mp_int *ret) +{ + int res; + mp_int t1,t2; + + /* must be positive */ + if (arg->sign == MP_NEG) { + return MP_VAL; + } + + /* easy out */ + if (mp_iszero(arg) == MP_YES) { + mp_zero(ret); + return MP_OKAY; + } + + if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) { + return res; + } + + if ((res = mp_init(&t2)) != MP_OKAY) { + goto E2; + } + + /* First approx. (not very bad for large arg) */ + mp_rshd (&t1,t1.used/2); + + /* t1 > 0 */ + if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { + goto E1; + } + if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { + goto E1; + } + if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { + goto E1; + } + /* And now t1 > sqrt(arg) */ + do { + if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { + goto E1; + } + if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { + goto E1; + } + if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { + goto E1; + } + /* t1 >= sqrt(arg) >= t2 at this point */ + } while (mp_cmp_mag(&t1,&t2) == MP_GT); + + mp_exch(&t1,ret); + +E1: mp_clear(&t2); +E2: mp_clear(&t1); + return res; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_sub.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_sub.c new file mode 100644 index 0000000000..3c8e5d455f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_sub.c @@ -0,0 +1,59 @@ +#include +#ifdef BN_MP_SUB_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* high level subtraction (handles signs) */ +int +mp_sub (mp_int * a, mp_int * b, mp_int * c) +{ + int sa, sb, res; + + sa = a->sign; + sb = b->sign; + + if (sa != sb) { + /* subtract a negative from a positive, OR */ + /* subtract a positive from a negative. */ + /* In either case, ADD their magnitudes, */ + /* and use the sign of the first number. */ + c->sign = sa; + res = s_mp_add (a, b, c); + } else { + /* subtract a positive from a positive, OR */ + /* subtract a negative from a negative. */ + /* First, take the difference between their */ + /* magnitudes, then... */ + if (mp_cmp_mag (a, b) != MP_LT) { + /* Copy the sign from the first */ + c->sign = sa; + /* The first has a larger or equal magnitude */ + res = s_mp_sub (a, b, c); + } else { + /* The result has the *opposite* sign from */ + /* the first number. */ + c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS; + /* The second has a larger magnitude */ + res = s_mp_sub (b, a, c); + } + } + return res; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_sub_d.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_sub_d.c new file mode 100644 index 0000000000..13b49bcc53 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_sub_d.c @@ -0,0 +1,93 @@ +#include +#ifdef BN_MP_SUB_D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* single digit subtraction */ +int +mp_sub_d (mp_int * a, mp_digit b, mp_int * c) +{ + mp_digit *tmpa, *tmpc, mu; + int res, ix, oldused; + + /* grow c as required */ + if (c->alloc < a->used + 1) { + if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* if a is negative just do an unsigned + * addition [with fudged signs] + */ + if (a->sign == MP_NEG) { + a->sign = MP_ZPOS; + res = mp_add_d(a, b, c); + a->sign = c->sign = MP_NEG; + + /* clamp */ + mp_clamp(c); + + return res; + } + + /* setup regs */ + oldused = c->used; + tmpa = a->dp; + tmpc = c->dp; + + /* if a <= b simply fix the single digit */ + if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) { + if (a->used == 1) { + *tmpc++ = b - *tmpa; + } else { + *tmpc++ = b; + } + ix = 1; + + /* negative/1digit */ + c->sign = MP_NEG; + c->used = 1; + } else { + /* positive/size */ + c->sign = MP_ZPOS; + c->used = a->used; + + /* subtract first digit */ + *tmpc = *tmpa++ - b; + mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1); + *tmpc++ &= MP_MASK; + + /* handle rest of the digits */ + for (ix = 1; ix < a->used; ix++) { + *tmpc = *tmpa++ - mu; + mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1); + *tmpc++ &= MP_MASK; + } + } + + /* zero excess digits */ + while (ix++ < oldused) { + *tmpc++ = 0; + } + mp_clamp(c); + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_submod.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_submod.c new file mode 100644 index 0000000000..d919c17de9 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_submod.c @@ -0,0 +1,42 @@ +#include +#ifdef BN_MP_SUBMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* d = a - b (mod c) */ +int +mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + int res; + mp_int t; + + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_sub (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, c, d); + mp_clear (&t); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_to_signed_bin.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_to_signed_bin.c new file mode 100644 index 0000000000..dda9285556 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_to_signed_bin.c @@ -0,0 +1,33 @@ +#include +#ifdef BN_MP_TO_SIGNED_BIN_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* store in signed [big endian] format */ +int mp_to_signed_bin (mp_int * a, unsigned char *b) +{ + int res; + + if ((res = mp_to_unsigned_bin (a, b + 1)) != MP_OKAY) { + return res; + } + b[0] = (unsigned char) ((a->sign == MP_ZPOS) ? 0 : 1); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_to_signed_bin_n.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_to_signed_bin_n.c new file mode 100644 index 0000000000..9e3b011b52 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_to_signed_bin_n.c @@ -0,0 +1,31 @@ +#include +#ifdef BN_MP_TO_SIGNED_BIN_N_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* store in signed [big endian] format */ +int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen) +{ + if (*outlen < (unsigned long)mp_signed_bin_size(a)) { + return MP_VAL; + } + *outlen = mp_signed_bin_size(a); + return mp_to_signed_bin(a, b); +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_to_unsigned_bin.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_to_unsigned_bin.c new file mode 100644 index 0000000000..76072a99cf --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_to_unsigned_bin.c @@ -0,0 +1,48 @@ +#include +#ifdef BN_MP_TO_UNSIGNED_BIN_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* store in unsigned [big endian] format */ +int mp_to_unsigned_bin (mp_int * a, unsigned char *b) +{ + int x, res; + mp_int t; + + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + x = 0; + while (mp_iszero (&t) == 0) { +#ifndef MP_8BIT + b[x++] = (unsigned char) (t.dp[0] & 255); +#else + b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7)); +#endif + if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) { + mp_clear (&t); + return res; + } + } + bn_reverse (b, x); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_to_unsigned_bin_n.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_to_unsigned_bin_n.c new file mode 100644 index 0000000000..51028d8141 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_to_unsigned_bin_n.c @@ -0,0 +1,31 @@ +#include +#ifdef BN_MP_TO_UNSIGNED_BIN_N_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* store in unsigned [big endian] format */ +int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen) +{ + if (*outlen < (unsigned long)mp_unsigned_bin_size(a)) { + return MP_VAL; + } + *outlen = mp_unsigned_bin_size(a); + return mp_to_unsigned_bin(a, b); +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_toom_mul.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_toom_mul.c new file mode 100644 index 0000000000..847a554f2d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_toom_mul.c @@ -0,0 +1,284 @@ +#include +#ifdef BN_MP_TOOM_MUL_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* multiplication using the Toom-Cook 3-way algorithm + * + * Much more complicated than Karatsuba but has a lower + * asymptotic running time of O(N**1.464). This algorithm is + * only particularly useful on VERY large inputs + * (we're talking 1000s of digits here...). +*/ +int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c) +{ + mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2; + int res, B; + + /* init temps */ + if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, + &a0, &a1, &a2, &b0, &b1, + &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) { + return res; + } + + /* B */ + B = MIN(a->used, b->used) / 3; + + /* a = a2 * B**2 + a1 * B + a0 */ + if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(a, &a1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a1, B); + mp_mod_2d(&a1, DIGIT_BIT * B, &a1); + + if ((res = mp_copy(a, &a2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a2, B*2); + + /* b = b2 * B**2 + b1 * B + b0 */ + if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(b, &b1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&b1, B); + mp_mod_2d(&b1, DIGIT_BIT * B, &b1); + + if ((res = mp_copy(b, &b2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&b2, B*2); + + /* w0 = a0*b0 */ + if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) { + goto ERR; + } + + /* w4 = a2 * b2 */ + if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) { + goto ERR; + } + + /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */ + if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) { + goto ERR; + } + + /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */ + if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) { + goto ERR; + } + + + /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */ + if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) { + goto ERR; + } + + /* now solve the matrix + + 0 0 0 0 1 + 1 2 4 8 16 + 1 1 1 1 1 + 16 8 4 2 1 + 1 0 0 0 0 + + using 12 subtractions, 4 shifts, + 2 small divisions and 1 small multiplication + */ + + /* r1 - r4 */ + if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r0 */ + if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/2 */ + if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3/2 */ + if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { + goto ERR; + } + /* r2 - r0 - r4 */ + if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1 - 8r0 */ + if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - 8r4 */ + if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + /* 3r2 - r1 - r3 */ + if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/3 */ + if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { + goto ERR; + } + /* r3/3 */ + if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { + goto ERR; + } + + /* at this point shift W[n] by B*n */ + if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) { + goto ERR; + } + +ERR: + mp_clear_multi(&w0, &w1, &w2, &w3, &w4, + &a0, &a1, &a2, &b0, &b1, + &b2, &tmp1, &tmp2, NULL); + return res; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_toom_sqr.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_toom_sqr.c new file mode 100644 index 0000000000..9076e6f81b --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_toom_sqr.c @@ -0,0 +1,226 @@ +#include +#ifdef BN_MP_TOOM_SQR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* squaring using Toom-Cook 3-way algorithm */ +int +mp_toom_sqr(mp_int *a, mp_int *b) +{ + mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2; + int res, B; + + /* init temps */ + if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) { + return res; + } + + /* B */ + B = a->used / 3; + + /* a = a2 * B**2 + a1 * B + a0 */ + if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(a, &a1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a1, B); + mp_mod_2d(&a1, DIGIT_BIT * B, &a1); + + if ((res = mp_copy(a, &a2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a2, B*2); + + /* w0 = a0*a0 */ + if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) { + goto ERR; + } + + /* w4 = a2 * a2 */ + if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) { + goto ERR; + } + + /* w1 = (a2 + 2(a1 + 2a0))**2 */ + if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + + /* w3 = (a0 + 2(a1 + 2a2))**2 */ + if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + + + /* w2 = (a2 + a1 + a0)**2 */ + if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) { + goto ERR; + } + + /* now solve the matrix + + 0 0 0 0 1 + 1 2 4 8 16 + 1 1 1 1 1 + 16 8 4 2 1 + 1 0 0 0 0 + + using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication. + */ + + /* r1 - r4 */ + if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r0 */ + if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/2 */ + if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3/2 */ + if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { + goto ERR; + } + /* r2 - r0 - r4 */ + if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1 - 8r0 */ + if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - 8r4 */ + if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + /* 3r2 - r1 - r3 */ + if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/3 */ + if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { + goto ERR; + } + /* r3/3 */ + if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { + goto ERR; + } + + /* at this point shift W[n] by B*n */ + if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) { + goto ERR; + } + +ERR: + mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL); + return res; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_toradix.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_toradix.c new file mode 100644 index 0000000000..bb957833f5 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_toradix.c @@ -0,0 +1,75 @@ +#include +#ifdef BN_MP_TORADIX_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* stores a bignum as a ASCII string in a given radix (2..64) */ +int mp_toradix (mp_int * a, char *str, int radix) +{ + int res, digs; + mp_int t; + mp_digit d; + char *_s = str; + + /* check range of the radix */ + if (radix < 2 || radix > 64) { + return MP_VAL; + } + + /* quick out if its zero */ + if (mp_iszero(a) == 1) { + *str++ = '0'; + *str = '\0'; + return MP_OKAY; + } + + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + /* if it is negative output a - */ + if (t.sign == MP_NEG) { + ++_s; + *str++ = '-'; + t.sign = MP_ZPOS; + } + + digs = 0; + while (mp_iszero (&t) == 0) { + if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { + mp_clear (&t); + return res; + } + *str++ = mp_s_rmap[d]; + ++digs; + } + + /* reverse the digits of the string. In this case _s points + * to the first digit [exluding the sign] of the number] + */ + bn_reverse ((unsigned char *)_s, digs); + + /* append a NULL so the string is properly terminated */ + *str = '\0'; + + mp_clear (&t); + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_toradix_n.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_toradix_n.c new file mode 100644 index 0000000000..7bcfb928a5 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_toradix_n.c @@ -0,0 +1,88 @@ +#include +#ifdef BN_MP_TORADIX_N_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* stores a bignum as a ASCII string in a given radix (2..64) + * + * Stores upto maxlen-1 chars and always a NULL byte + */ +int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen) +{ + int res, digs; + mp_int t; + mp_digit d; + char *_s = str; + + /* check range of the maxlen, radix */ + if (maxlen < 2 || radix < 2 || radix > 64) { + return MP_VAL; + } + + /* quick out if its zero */ + if (mp_iszero(a) == MP_YES) { + *str++ = '0'; + *str = '\0'; + return MP_OKAY; + } + + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + /* if it is negative output a - */ + if (t.sign == MP_NEG) { + /* we have to reverse our digits later... but not the - sign!! */ + ++_s; + + /* store the flag and mark the number as positive */ + *str++ = '-'; + t.sign = MP_ZPOS; + + /* subtract a char */ + --maxlen; + } + + digs = 0; + while (mp_iszero (&t) == 0) { + if (--maxlen < 1) { + /* no more room */ + break; + } + if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { + mp_clear (&t); + return res; + } + *str++ = mp_s_rmap[d]; + ++digs; + } + + /* reverse the digits of the string. In this case _s points + * to the first digit [exluding the sign] of the number + */ + bn_reverse ((unsigned char *)_s, digs); + + /* append a NULL so the string is properly terminated */ + *str = '\0'; + + mp_clear (&t); + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_unsigned_bin_size.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_unsigned_bin_size.c new file mode 100644 index 0000000000..b16fdcd584 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_unsigned_bin_size.c @@ -0,0 +1,28 @@ +#include +#ifdef BN_MP_UNSIGNED_BIN_SIZE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* get the size for an unsigned equivalent */ +int mp_unsigned_bin_size (mp_int * a) +{ + int size = mp_count_bits (a); + return (size / 8 + ((size & 7) != 0 ? 1 : 0)); +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_xor.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_xor.c new file mode 100644 index 0000000000..5744556dae --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_xor.c @@ -0,0 +1,51 @@ +#include +#ifdef BN_MP_XOR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* XOR two ints together */ +int +mp_xor (mp_int * a, mp_int * b, mp_int * c) +{ + int res, ix, px; + mp_int t, *x; + + if (a->used > b->used) { + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + px = b->used; + x = b; + } else { + if ((res = mp_init_copy (&t, b)) != MP_OKAY) { + return res; + } + px = a->used; + x = a; + } + + for (ix = 0; ix < px; ix++) { + t.dp[ix] ^= x->dp[ix]; + } + mp_clamp (&t); + mp_exch (c, &t); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_mp_zero.c b/xmhf-64/xmhf/third-party/libtommath/bn_mp_zero.c new file mode 100644 index 0000000000..99e6df2114 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_mp_zero.c @@ -0,0 +1,36 @@ +#include +#ifdef BN_MP_ZERO_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* set to zero */ +void mp_zero (mp_int * a) +{ + int n; + mp_digit *tmp; + + a->sign = MP_ZPOS; + a->used = 0; + + tmp = a->dp; + for (n = 0; n < a->alloc; n++) { + *tmp++ = 0; + } +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_prime_tab.c b/xmhf-64/xmhf/third-party/libtommath/bn_prime_tab.c new file mode 100644 index 0000000000..fb5ad087fa --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_prime_tab.c @@ -0,0 +1,61 @@ +#include +#ifdef BN_PRIME_TAB_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +const mp_digit ltm_prime_tab[] = { + 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, + 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, + 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, + 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, +#ifndef MP_8BIT + 0x0083, + 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD, + 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF, + 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107, + 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137, + + 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167, + 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199, + 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9, + 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7, + 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239, + 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265, + 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293, + 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF, + + 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301, + 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B, + 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371, + 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD, + 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5, + 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419, + 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449, + 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B, + + 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7, + 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503, + 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529, + 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F, + 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3, + 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7, + 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623, + 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 +#endif +}; +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_reverse.c b/xmhf-64/xmhf/third-party/libtommath/bn_reverse.c new file mode 100644 index 0000000000..17cdcc1c5c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_reverse.c @@ -0,0 +1,39 @@ +#include +#ifdef BN_REVERSE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* reverse an array, used for radix code */ +void +bn_reverse (unsigned char *s, int len) +{ + int ix, iy; + unsigned char t; + + ix = 0; + iy = len - 1; + while (ix < iy) { + t = s[ix]; + s[ix] = s[iy]; + s[iy] = t; + ++ix; + --iy; + } +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_s_mp_add.c b/xmhf-64/xmhf/third-party/libtommath/bn_s_mp_add.c new file mode 100644 index 0000000000..4883dd5aac --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_s_mp_add.c @@ -0,0 +1,109 @@ +#include +#ifdef BN_S_MP_ADD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* low level addition, based on HAC pp.594, Algorithm 14.7 */ +int +s_mp_add (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int *x; + int olduse, res, min, max; + + /* find sizes, we let |a| <= |b| which means we have to sort + * them. "x" will point to the input with the most digits + */ + if (a->used > b->used) { + min = b->used; + max = a->used; + x = a; + } else { + min = a->used; + max = b->used; + x = b; + } + + /* init result */ + if (c->alloc < max + 1) { + if ((res = mp_grow (c, max + 1)) != MP_OKAY) { + return res; + } + } + + /* get old used digit count and set new one */ + olduse = c->used; + c->used = max + 1; + + { + register mp_digit u, *tmpa, *tmpb, *tmpc; + register int i; + + /* alias for digit pointers */ + + /* first input */ + tmpa = a->dp; + + /* second input */ + tmpb = b->dp; + + /* destination */ + tmpc = c->dp; + + /* zero the carry */ + u = 0; + for (i = 0; i < min; i++) { + /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */ + *tmpc = *tmpa++ + *tmpb++ + u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)DIGIT_BIT); + + /* take away carry bit from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* now copy higher words if any, that is in A+B + * if A or B has more digits add those in + */ + if (min != max) { + for (; i < max; i++) { + /* T[i] = X[i] + U */ + *tmpc = x->dp[i] + u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)DIGIT_BIT); + + /* take away carry bit from T[i] */ + *tmpc++ &= MP_MASK; + } + } + + /* add carry */ + *tmpc++ = u; + + /* clear digits above oldused */ + for (i = c->used; i < olduse; i++) { + *tmpc++ = 0; + } + } + + mp_clamp (c); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_s_mp_exptmod.c b/xmhf-64/xmhf/third-party/libtommath/bn_s_mp_exptmod.c new file mode 100644 index 0000000000..2bdc56ab07 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_s_mp_exptmod.c @@ -0,0 +1,252 @@ +#include +#ifdef BN_S_MP_EXPTMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#ifdef MP_LOW_MEM + #define TAB_SIZE 32 +#else + #define TAB_SIZE 256 +#endif + +int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) +{ + mp_int M[TAB_SIZE], res, mu; + mp_digit buf; + int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; + int (*redux)(mp_int*,mp_int*,mp_int*); + + /* find window size */ + x = mp_count_bits (X); + if (x <= 7) { + winsize = 2; + } else if (x <= 36) { + winsize = 3; + } else if (x <= 140) { + winsize = 4; + } else if (x <= 450) { + winsize = 5; + } else if (x <= 1303) { + winsize = 6; + } else if (x <= 3529) { + winsize = 7; + } else { + winsize = 8; + } + +#ifdef MP_LOW_MEM + if (winsize > 5) { + winsize = 5; + } +#endif + + /* init M array */ + /* init first cell */ + if ((err = mp_init(&M[1])) != MP_OKAY) { + return err; + } + + /* now init the second half of the array */ + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + if ((err = mp_init(&M[x])) != MP_OKAY) { + for (y = 1<<(winsize-1); y < x; y++) { + mp_clear (&M[y]); + } + mp_clear(&M[1]); + return err; + } + } + + /* create mu, used for Barrett reduction */ + if ((err = mp_init (&mu)) != MP_OKAY) { + goto LBL_M; + } + + if (redmode == 0) { + if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) { + goto LBL_MU; + } + redux = mp_reduce; + } else { + if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) { + goto LBL_MU; + } + redux = mp_reduce_2k_l; + } + + /* create M table + * + * The M table contains powers of the base, + * e.g. M[x] = G**x mod P + * + * The first half of the table is not + * computed though accept for M[0] and M[1] + */ + if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) { + goto LBL_MU; + } + + /* compute the value at M[1<<(winsize-1)] by squaring + * M[1] (winsize-1) times + */ + if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_MU; + } + + for (x = 0; x < (winsize - 1); x++) { + /* square it */ + if ((err = mp_sqr (&M[1 << (winsize - 1)], + &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_MU; + } + + /* reduce modulo P */ + if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) { + goto LBL_MU; + } + } + + /* create upper table, that is M[x] = M[x-1] * M[1] (mod P) + * for x = (2**(winsize - 1) + 1) to (2**winsize - 1) + */ + for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { + if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { + goto LBL_MU; + } + if ((err = redux (&M[x], P, &mu)) != MP_OKAY) { + goto LBL_MU; + } + } + + /* setup result */ + if ((err = mp_init (&res)) != MP_OKAY) { + goto LBL_MU; + } + mp_set (&res, 1); + + /* set initial mode and bit cnt */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = X->used - 1; + bitcpy = 0; + bitbuf = 0; + + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits */ + if (digidx == -1) { + break; + } + /* read next digit and reset the bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int) DIGIT_BIT; + } + + /* grab the next msb from the exponent */ + y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1; + buf <<= (mp_digit)1; + + /* if the bit is zero and mode == 0 then we ignore it + * These represent the leading zero bits before the first 1 bit + * in the exponent. Technically this opt is not required but it + * does lower the # of trivial squaring/reductions used + */ + if (mode == 0 && y == 0) { + continue; + } + + /* if the bit is zero and mode == 1 then we square */ + if (mode == 1 && y == 0) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + continue; + } + + /* else we add it to the window */ + bitbuf |= (y << (winsize - ++bitcpy)); + mode = 2; + + if (bitcpy == winsize) { + /* ok window is filled so square as required and multiply */ + /* square first */ + for (x = 0; x < winsize; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* then multiply */ + if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + + /* empty window and reset */ + bitcpy = 0; + bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then square/multiply */ + if (mode == 2 && bitcpy > 0) { + /* square then multiply if the bit is set */ + for (x = 0; x < bitcpy; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + + bitbuf <<= 1; + if ((bitbuf & (1 << winsize)) != 0) { + /* then multiply */ + if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + } + } + } + + mp_exch (&res, Y); + err = MP_OKAY; +LBL_RES:mp_clear (&res); +LBL_MU:mp_clear (&mu); +LBL_M: + mp_clear(&M[1]); + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + mp_clear (&M[x]); + } + return err; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_s_mp_mul_digs.c b/xmhf-64/xmhf/third-party/libtommath/bn_s_mp_mul_digs.c new file mode 100644 index 0000000000..ea911162fb --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_s_mp_mul_digs.c @@ -0,0 +1,90 @@ +#include +#ifdef BN_S_MP_MUL_DIGS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* multiplies |a| * |b| and only computes upto digs digits of result + * HAC pp. 595, Algorithm 14.12 Modified so you can control how + * many digits of output are created. + */ +int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + mp_int t; + int res, pa, pb, ix, iy; + mp_digit u; + mp_word r; + mp_digit tmpx, *tmpt, *tmpy; + + /* can we use the fast multiplier? */ + if (((digs) < MP_WARRAY) && + MIN (a->used, b->used) < + (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + return fast_s_mp_mul_digs (a, b, c, digs); + } + + if ((res = mp_init_size (&t, digs)) != MP_OKAY) { + return res; + } + t.used = digs; + + /* compute the digits of the product directly */ + pa = a->used; + for (ix = 0; ix < pa; ix++) { + /* set the carry to zero */ + u = 0; + + /* limit ourselves to making digs digits of output */ + pb = MIN (b->used, digs - ix); + + /* setup some aliases */ + /* copy of the digit from a used within the nested loop */ + tmpx = a->dp[ix]; + + /* an alias for the destination shifted ix places */ + tmpt = t.dp + ix; + + /* an alias for the digits of b */ + tmpy = b->dp; + + /* compute the columns of the output and propagate the carry */ + for (iy = 0; iy < pb; iy++) { + /* compute the column as a mp_word */ + r = ((mp_word)*tmpt) + + ((mp_word)tmpx) * ((mp_word)*tmpy++) + + ((mp_word) u); + + /* the new column is the lower part of the result */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get the carry word from the result */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + /* set carry if it is placed below digs */ + if (ix + iy < digs) { + *tmpt = u; + } + } + + mp_clamp (&t); + mp_exch (&t, c); + + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_s_mp_mul_high_digs.c b/xmhf-64/xmhf/third-party/libtommath/bn_s_mp_mul_high_digs.c new file mode 100644 index 0000000000..019014e71d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_s_mp_mul_high_digs.c @@ -0,0 +1,81 @@ +#include +#ifdef BN_S_MP_MUL_HIGH_DIGS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* multiplies |a| * |b| and does not compute the lower digs digits + * [meant to get the higher part of the product] + */ +int +s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + mp_int t; + int res, pa, pb, ix, iy; + mp_digit u; + mp_word r; + mp_digit tmpx, *tmpt, *tmpy; + + /* can we use the fast multiplier? */ +#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C + if (((a->used + b->used + 1) < MP_WARRAY) + && MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + return fast_s_mp_mul_high_digs (a, b, c, digs); + } +#endif + + if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) { + return res; + } + t.used = a->used + b->used + 1; + + pa = a->used; + pb = b->used; + for (ix = 0; ix < pa; ix++) { + /* clear the carry */ + u = 0; + + /* left hand side of A[ix] * B[iy] */ + tmpx = a->dp[ix]; + + /* alias to the address of where the digits will be stored */ + tmpt = &(t.dp[digs]); + + /* alias for where to read the right hand side from */ + tmpy = b->dp + (digs - ix); + + for (iy = digs - ix; iy < pb; iy++) { + /* calculate the double precision result */ + r = ((mp_word)*tmpt) + + ((mp_word)tmpx) * ((mp_word)*tmpy++) + + ((mp_word) u); + + /* get the lower part */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* carry the carry */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + *tmpt = u; + } + mp_clamp (&t); + mp_exch (&t, c); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_s_mp_sqr.c b/xmhf-64/xmhf/third-party/libtommath/bn_s_mp_sqr.c new file mode 100644 index 0000000000..716e79b348 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_s_mp_sqr.c @@ -0,0 +1,84 @@ +#include +#ifdef BN_S_MP_SQR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */ +int s_mp_sqr (mp_int * a, mp_int * b) +{ + mp_int t; + int res, ix, iy, pa; + mp_word r; + mp_digit u, tmpx, *tmpt; + + pa = a->used; + if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) { + return res; + } + + /* default used is maximum possible size */ + t.used = 2*pa + 1; + + for (ix = 0; ix < pa; ix++) { + /* first calculate the digit at 2*ix */ + /* calculate double precision result */ + r = ((mp_word) t.dp[2*ix]) + + ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]); + + /* store lower part in result */ + t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get the carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + + /* left hand side of A[ix] * A[iy] */ + tmpx = a->dp[ix]; + + /* alias for where to store the results */ + tmpt = t.dp + (2*ix + 1); + + for (iy = ix + 1; iy < pa; iy++) { + /* first calculate the product */ + r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]); + + /* now calculate the double precision result, note we use + * addition instead of *2 since it's easier to optimize + */ + r = ((mp_word) *tmpt) + r + r + ((mp_word) u); + + /* store lower part */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + } + /* propagate upwards */ + while (u != ((mp_digit) 0)) { + r = ((mp_word) *tmpt) + ((mp_word) u); + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + } + } + + mp_clamp (&t); + mp_exch (&t, b); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bn_s_mp_sub.c b/xmhf-64/xmhf/third-party/libtommath/bn_s_mp_sub.c new file mode 100644 index 0000000000..ccea6bd53b --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bn_s_mp_sub.c @@ -0,0 +1,89 @@ +#include +#ifdef BN_S_MP_SUB_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */ +int +s_mp_sub (mp_int * a, mp_int * b, mp_int * c) +{ + int olduse, res, min, max; + + /* find sizes */ + min = b->used; + max = a->used; + + /* init result */ + if (c->alloc < max) { + if ((res = mp_grow (c, max)) != MP_OKAY) { + return res; + } + } + olduse = c->used; + c->used = max; + + { + register mp_digit u, *tmpa, *tmpb, *tmpc; + register int i; + + /* alias for digit pointers */ + tmpa = a->dp; + tmpb = b->dp; + tmpc = c->dp; + + /* set carry to zero */ + u = 0; + for (i = 0; i < min; i++) { + /* T[i] = A[i] - B[i] - U */ + *tmpc = *tmpa++ - *tmpb++ - u; + + /* U = carry bit of T[i] + * Note this saves performing an AND operation since + * if a carry does occur it will propagate all the way to the + * MSB. As a result a single shift is enough to get the carry + */ + u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); + + /* Clear carry from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* now copy higher words if any, e.g. if A has more digits than B */ + for (; i < max; i++) { + /* T[i] = A[i] - U */ + *tmpc = *tmpa++ - u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); + + /* Clear carry from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* clear digits above used (since we may not have grown result above) */ + for (i = c->used; i < olduse; i++) { + *tmpc++ = 0; + } + } + + mp_clamp (c); + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/bncore.c b/xmhf-64/xmhf/third-party/libtommath/bncore.c new file mode 100644 index 0000000000..05df3eb4a7 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/bncore.c @@ -0,0 +1,36 @@ +#include +#ifdef BNCORE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Known optimal configurations + + CPU /Compiler /MUL CUTOFF/SQR CUTOFF +------------------------------------------------------------- + Intel P4 Northwood /GCC v3.4.1 / 88/ 128/LTM 0.32 ;-) + AMD Athlon64 /GCC v3.4.4 / 80/ 120/LTM 0.35 + +*/ + +int KARATSUBA_MUL_CUTOFF = 80, /* Min. number of digits before Karatsuba multiplication is used. */ + KARATSUBA_SQR_CUTOFF = 120, /* Min. number of digits before Karatsuba squaring is used. */ + + TOOM_MUL_CUTOFF = 350, /* no optimal values of these are known yet so set em high */ + TOOM_SQR_CUTOFF = 400; +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/booker.pl b/xmhf-64/xmhf/third-party/libtommath/booker.pl new file mode 100755 index 0000000000..49f1889d1b --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/booker.pl @@ -0,0 +1,265 @@ +#!/bin/perl +# +#Used to prepare the book "tommath.src" for LaTeX by pre-processing it into a .tex file +# +#Essentially you write the "tommath.src" as normal LaTex except where you want code snippets you put +# +#EXAM,file +# +#This preprocessor will then open "file" and insert it as a verbatim copy. +# +#Tom St Denis + +#get graphics type +if (shift =~ /PDF/) { + $graph = ""; +} else { + $graph = ".ps"; +} + +open(IN,"tommath.tex") or die "Can't open destination file"; + +print "Scanning for sections\n"; +$chapter = $section = $subsection = 0; +$x = 0; +while () { + print "."; + if (!(++$x % 80)) { print "\n"; } + #update the headings + if (~($_ =~ /\*/)) { + if ($_ =~ /\\chapter{.+}/) { + ++$chapter; + $section = $subsection = 0; + } elsif ($_ =~ /\\section{.+}/) { + ++$section; + $subsection = 0; + } elsif ($_ =~ /\\subsection{.+}/) { + ++$subsection; + } + } + + if ($_ =~ m/MARK/) { + @m = split(",",$_); + chomp(@m[1]); + $index1{@m[1]} = $chapter; + $index2{@m[1]} = $section; + $index3{@m[1]} = $subsection; + } +} +close(IN); + +open(IN,") { + ++$readline; + ++$srcline; + + if ($_ =~ m/MARK/) { + } elsif ($_ =~ m/EXAM/ || $_ =~ m/LIST/) { + if ($_ =~ m/EXAM/) { + $skipheader = 1; + } else { + $skipheader = 0; + } + + # EXAM,file + chomp($_); + @m = split(",",$_); + open(SRC,"<$m[1]") or die "Error:$srcline:Can't open source file $m[1]"; + + print "$srcline:Inserting $m[1]:"; + + $line = 0; + $tmp = $m[1]; + $tmp =~ s/_/"\\_"/ge; + print OUT "\\vspace{+3mm}\\begin{small}\n\\hspace{-5.1mm}{\\bf File}: $tmp\n\\vspace{-3mm}\n\\begin{alltt}\n"; + $wroteline += 5; + + if ($skipheader == 1) { + # scan till next end of comment, e.g. skip license + while () { + $text[$line++] = $_; + last if ($_ =~ /math\.libtomcrypt\.com/); + } + ; + } + + $inline = 0; + while () { + next if ($_ =~ /\$Source/); + next if ($_ =~ /\$Revision/); + next if ($_ =~ /\$Date/); + $text[$line++] = $_; + ++$inline; + chomp($_); + $_ =~ s/\t/" "/ge; + $_ =~ s/{/"^{"/ge; + $_ =~ s/}/"^}"/ge; + $_ =~ s/\\/'\symbol{92}'/ge; + $_ =~ s/\^/"\\"/ge; + + printf OUT ("%03d ", $line); + for ($x = 0; $x < length($_); $x++) { + print OUT chr(vec($_, $x, 8)); + if ($x == 75) { + print OUT "\n "; + ++$wroteline; + } + } + print OUT "\n"; + ++$wroteline; + } + $totlines = $line; + print OUT "\\end{alltt}\n\\end{small}\n"; + close(SRC); + print "$inline lines\n"; + $wroteline += 2; + } elsif ($_ =~ m/@\d+,.+@/) { + # line contains [number,text] + # e.g. @14,for (ix = 0)@ + $txt = $_; + while ($txt =~ m/@\d+,.+@/) { + @m = split("@",$txt); # splits into text, one, two + @parms = split(",",$m[1]); # splits one,two into two elements + + # now search from $parms[0] down for $parms[1] + $found1 = 0; + $found2 = 0; + for ($i = $parms[0]; $i < $totlines && $found1 == 0; $i++) { + if ($text[$i] =~ m/\Q$parms[1]\E/) { + $foundline1 = $i + 1; + $found1 = 1; + } + } + + # now search backwards + for ($i = $parms[0] - 1; $i >= 0 && $found2 == 0; $i--) { + if ($text[$i] =~ m/\Q$parms[1]\E/) { + $foundline2 = $i + 1; + $found2 = 1; + } + } + + # now use the closest match or the first if tied + if ($found1 == 1 && $found2 == 0) { + $found = 1; + $foundline = $foundline1; + } elsif ($found1 == 0 && $found2 == 1) { + $found = 1; + $foundline = $foundline2; + } elsif ($found1 == 1 && $found2 == 1) { + $found = 1; + if (($foundline1 - $parms[0]) <= ($parms[0] - $foundline2)) { + $foundline = $foundline1; + } else { + $foundline = $foundline2; + } + } else { + $found = 0; + } + + # if found replace + if ($found == 1) { + $delta = $parms[0] - $foundline; + print "Found replacement tag for \"$parms[1]\" on line $srcline which refers to line $foundline (delta $delta)\n"; + $_ =~ s/@\Q$m[1]\E@/$foundline/; + } else { + print "ERROR: The tag \"$parms[1]\" on line $srcline was not found in the most recently parsed source!\n"; + } + + # remake the rest of the line + $cnt = @m; + $txt = ""; + for ($i = 2; $i < $cnt; $i++) { + $txt = $txt . $m[$i] . "@"; + } + } + print OUT $_; + ++$wroteline; + } elsif ($_ =~ /~.+~/) { + # line contains a ~text~ pair used to refer to indexing :-) + $txt = $_; + while ($txt =~ /~.+~/) { + @m = split("~", $txt); + + # word is the second position + $word = @m[1]; + $a = $index1{$word}; + $b = $index2{$word}; + $c = $index3{$word}; + + # if chapter (a) is zero it wasn't found + if ($a == 0) { + print "ERROR: the tag \"$word\" on line $srcline was not found previously marked.\n"; + } else { + # format the tag as x, x.y or x.y.z depending on the values + $str = $a; + $str = $str . ".$b" if ($b != 0); + $str = $str . ".$c" if ($c != 0); + + if ($b == 0 && $c == 0) { + # its a chapter + if ($a <= 10) { + if ($a == 1) { + $str = "chapter one"; + } elsif ($a == 2) { + $str = "chapter two"; + } elsif ($a == 3) { + $str = "chapter three"; + } elsif ($a == 4) { + $str = "chapter four"; + } elsif ($a == 5) { + $str = "chapter five"; + } elsif ($a == 6) { + $str = "chapter six"; + } elsif ($a == 7) { + $str = "chapter seven"; + } elsif ($a == 8) { + $str = "chapter eight"; + } elsif ($a == 9) { + $str = "chapter nine"; + } elsif ($a == 10) { + $str = "chapter ten"; + } + } else { + $str = "chapter " . $str; + } + } else { + $str = "section " . $str if ($b != 0 && $c == 0); + $str = "sub-section " . $str if ($b != 0 && $c != 0); + } + + #substitute + $_ =~ s/~\Q$word\E~/$str/; + + print "Found replacement tag for marker \"$word\" on line $srcline which refers to $str\n"; + } + + # remake rest of the line + $cnt = @m; + $txt = ""; + for ($i = 2; $i < $cnt; $i++) { + $txt = $txt . $m[$i] . "~"; + } + } + print OUT $_; + ++$wroteline; + } elsif ($_ =~ m/FIGU/) { + # FIGU,file,caption + chomp($_); + @m = split(",", $_); + print OUT "\\begin{center}\n\\begin{figure}[here]\n\\includegraphics{pics/$m[1]$graph}\n"; + print OUT "\\caption{$m[2]}\n\\label{pic:$m[1]}\n\\end{figure}\n\\end{center}\n"; + $wroteline += 4; + } else { + print OUT $_; + ++$wroteline; + } +} +print "Read $readline lines, wrote $wroteline lines\n"; + +close (OUT); +close (IN); diff --git a/xmhf-64/xmhf/third-party/libtommath/callgraph.txt b/xmhf-64/xmhf/third-party/libtommath/callgraph.txt new file mode 100644 index 0000000000..2efcf245ba --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/callgraph.txt @@ -0,0 +1,11913 @@ +BN_PRIME_TAB_C + + +BN_MP_SQRT_C ++--->BN_MP_N_ROOT_C +| +--->BN_MP_INIT_C +| +--->BN_MP_SET_C +| | +--->BN_MP_ZERO_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_EXPT_D_C +| | +--->BN_MP_INIT_COPY_C +| | +--->BN_MP_SQR_C +| | | +--->BN_MP_TOOM_SQR_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_MUL_2_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_2_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_3_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_KARATSUBA_SQR_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLEAR_C +| | | +--->BN_FAST_S_MP_SQR_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SQR_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_CLEAR_C +| | +--->BN_MP_MUL_C +| | | +--->BN_MP_TOOM_MUL_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_MUL_2_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_2_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_3_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_KARATSUBA_MUL_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_MUL_DIGS_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| +--->BN_MP_MUL_C +| | +--->BN_MP_TOOM_MUL_C +| | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_MUL_2_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_2_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MUL_2D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MUL_D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_3_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLEAR_MULTI_C +| | | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_KARATSUBA_MUL_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_MUL_DIGS_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_C +| +--->BN_MP_SUB_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_MUL_D_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_DIV_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_COUNT_BITS_C +| | +--->BN_MP_ABS_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2D_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_INIT_COPY_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_CMP_C +| | +--->BN_MP_CMP_MAG_C +| +--->BN_MP_SUB_D_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_D_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_ZERO_C ++--->BN_MP_INIT_COPY_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C ++--->BN_MP_RSHD_C ++--->BN_MP_DIV_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_INIT_MULTI_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_SET_C +| +--->BN_MP_COUNT_BITS_C +| +--->BN_MP_ABS_C +| +--->BN_MP_MUL_2D_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_C +| +--->BN_MP_SUB_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_ADD_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_DIV_2D_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLEAR_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_MULTI_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_INIT_SIZE_C +| +--->BN_MP_LSHD_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_MUL_D_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_ADD_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_DIV_2_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_CMP_MAG_C ++--->BN_MP_EXCH_C ++--->BN_MP_CLEAR_C + + +BN_MP_CMP_D_C + + +BN_MP_EXCH_C + + +BN_MP_IS_SQUARE_C ++--->BN_MP_MOD_D_C +| +--->BN_MP_DIV_D_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_DIV_2D_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_INIT_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_DIV_3_C +| | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_INIT_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C ++--->BN_MP_INIT_SET_INT_C +| +--->BN_MP_INIT_C +| +--->BN_MP_SET_INT_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_MOD_C +| +--->BN_MP_INIT_C +| +--->BN_MP_DIV_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_SET_C +| | +--->BN_MP_COUNT_BITS_C +| | +--->BN_MP_ABS_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2D_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_INIT_COPY_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_CLEAR_C +| +--->BN_MP_ADD_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C ++--->BN_MP_GET_INT_C ++--->BN_MP_SQRT_C +| +--->BN_MP_N_ROOT_C +| | +--->BN_MP_INIT_C +| | +--->BN_MP_SET_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_EXPT_D_C +| | | +--->BN_MP_INIT_COPY_C +| | | +--->BN_MP_SQR_C +| | | | +--->BN_MP_TOOM_SQR_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | | +--->BN_MP_CLEAR_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_MUL_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_3_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | | +--->BN_MP_CLEAR_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_KARATSUBA_SQR_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_FAST_S_MP_SQR_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_SQR_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_MUL_C +| | | | +--->BN_MP_TOOM_MUL_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_MUL_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_3_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLEAR_MULTI_C +| | | | +--->BN_MP_KARATSUBA_MUL_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | +--->BN_MP_MUL_C +| | | +--->BN_MP_TOOM_MUL_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_MUL_2_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_2_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_3_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_KARATSUBA_MUL_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_CLEAR_C +| | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_MUL_DIGS_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_COUNT_BITS_C +| | | +--->BN_MP_ABS_C +| | | +--->BN_MP_MUL_2D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_2D_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_MULTI_C +| | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_COPY_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_CMP_C +| | | +--->BN_MP_CMP_MAG_C +| | +--->BN_MP_SUB_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ADD_D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_ZERO_C +| +--->BN_MP_INIT_COPY_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| +--->BN_MP_RSHD_C +| +--->BN_MP_DIV_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_SET_C +| | +--->BN_MP_COUNT_BITS_C +| | +--->BN_MP_ABS_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2D_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_ADD_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_DIV_2_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_SQR_C +| +--->BN_MP_TOOM_SQR_C +| | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_INIT_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_RSHD_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_MUL_2_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_3_C +| | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_INIT_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_CLEAR_C +| +--->BN_MP_KARATSUBA_SQR_C +| | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | +--->BN_MP_ADD_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_C +| +--->BN_FAST_S_MP_SQR_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_S_MP_SQR_C +| | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C ++--->BN_MP_CMP_MAG_C ++--->BN_MP_CLEAR_C + + +BN_MP_NEG_C ++--->BN_MP_COPY_C +| +--->BN_MP_GROW_C + + +BN_MP_EXPTMOD_C ++--->BN_MP_INIT_C ++--->BN_MP_INVMOD_C +| +--->BN_FAST_MP_INVMOD_C +| | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_MOD_C +| | | +--->BN_MP_DIV_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_SET_C +| | | | +--->BN_MP_COUNT_BITS_C +| | | | +--->BN_MP_ABS_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_2D_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CLEAR_C +| | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_INIT_COPY_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_SET_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_DIV_2_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_C +| | | +--->BN_MP_CMP_MAG_C +| | +--->BN_MP_CMP_D_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_CLEAR_C +| +--->BN_MP_INVMOD_SLOW_C +| | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_MOD_C +| | | +--->BN_MP_DIV_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_SET_C +| | | | +--->BN_MP_COUNT_BITS_C +| | | | +--->BN_MP_ABS_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_2D_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CLEAR_C +| | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_INIT_COPY_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_SET_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_DIV_2_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_C +| | | +--->BN_MP_CMP_MAG_C +| | +--->BN_MP_CMP_D_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_CLEAR_C ++--->BN_MP_CLEAR_C ++--->BN_MP_ABS_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C ++--->BN_MP_CLEAR_MULTI_C ++--->BN_MP_REDUCE_IS_2K_L_C ++--->BN_S_MP_EXPTMOD_C +| +--->BN_MP_COUNT_BITS_C +| +--->BN_MP_REDUCE_SETUP_C +| | +--->BN_MP_2EXPT_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_DIV_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_SET_C +| | | +--->BN_MP_MUL_2D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_2D_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_COPY_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_MUL_D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_REDUCE_C +| | +--->BN_MP_INIT_COPY_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_RSHD_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_MUL_C +| | | +--->BN_MP_TOOM_MUL_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_MUL_2_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_2_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_3_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_KARATSUBA_MUL_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_MUL_DIGS_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | +--->BN_S_MP_MUL_HIGH_DIGS_C +| | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_MUL_DIGS_C +| | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_D_C +| | +--->BN_MP_SET_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_C +| | | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_REDUCE_2K_SETUP_L_C +| | +--->BN_MP_2EXPT_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_GROW_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_REDUCE_2K_L_C +| | +--->BN_MP_DIV_2D_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_MUL_C +| | | +--->BN_MP_TOOM_MUL_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_MUL_2_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_2_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_3_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_KARATSUBA_MUL_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_MUL_DIGS_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_MOD_C +| | +--->BN_MP_DIV_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_SET_C +| | | +--->BN_MP_MUL_2D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_2D_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_COPY_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_MUL_D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_SQR_C +| | +--->BN_MP_TOOM_SQR_C +| | | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_MUL_2_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_2_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MUL_2D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MUL_D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_3_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_KARATSUBA_SQR_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | +--->BN_FAST_S_MP_SQR_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_SQR_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| +--->BN_MP_MUL_C +| | +--->BN_MP_TOOM_MUL_C +| | | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_MUL_2_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_2_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MUL_2D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MUL_D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_3_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_KARATSUBA_MUL_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_MUL_DIGS_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| +--->BN_MP_SET_C +| | +--->BN_MP_ZERO_C +| +--->BN_MP_EXCH_C ++--->BN_MP_DR_IS_MODULUS_C ++--->BN_MP_REDUCE_IS_2K_C +| +--->BN_MP_REDUCE_2K_C +| | +--->BN_MP_COUNT_BITS_C +| | +--->BN_MP_DIV_2D_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_COUNT_BITS_C ++--->BN_MP_EXPTMOD_FAST_C +| +--->BN_MP_COUNT_BITS_C +| +--->BN_MP_MONTGOMERY_SETUP_C +| +--->BN_FAST_MP_MONTGOMERY_REDUCE_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_RSHD_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| +--->BN_MP_MONTGOMERY_REDUCE_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_RSHD_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| +--->BN_MP_DR_SETUP_C +| +--->BN_MP_DR_REDUCE_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| +--->BN_MP_REDUCE_2K_SETUP_C +| | +--->BN_MP_2EXPT_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_GROW_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_REDUCE_2K_C +| | +--->BN_MP_DIV_2D_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C +| | +--->BN_MP_2EXPT_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_SET_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_MUL_2_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_MULMOD_C +| | +--->BN_MP_MUL_C +| | | +--->BN_MP_TOOM_MUL_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_MUL_2_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_2_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_3_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_KARATSUBA_MUL_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_MUL_DIGS_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | +--->BN_MP_MOD_C +| | | +--->BN_MP_DIV_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_SET_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_2D_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_INIT_COPY_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| +--->BN_MP_SET_C +| | +--->BN_MP_ZERO_C +| +--->BN_MP_MOD_C +| | +--->BN_MP_DIV_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_MUL_2D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_2D_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_COPY_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_MUL_D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_SQR_C +| | +--->BN_MP_TOOM_SQR_C +| | | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_MUL_2_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_2_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MUL_2D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MUL_D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_3_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_KARATSUBA_SQR_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | +--->BN_FAST_S_MP_SQR_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_SQR_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| +--->BN_MP_MUL_C +| | +--->BN_MP_TOOM_MUL_C +| | | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_MUL_2_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_2_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MUL_2D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MUL_D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_3_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_KARATSUBA_MUL_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_MUL_DIGS_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| +--->BN_MP_EXCH_C + + +BN_MP_OR_C ++--->BN_MP_INIT_COPY_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C ++--->BN_MP_CLAMP_C ++--->BN_MP_EXCH_C ++--->BN_MP_CLEAR_C + + +BN_MP_ZERO_C + + +BN_MP_GROW_C + + +BN_MP_COUNT_BITS_C + + +BN_MP_PRIME_FERMAT_C ++--->BN_MP_CMP_D_C ++--->BN_MP_INIT_C ++--->BN_MP_EXPTMOD_C +| +--->BN_MP_INVMOD_C +| | +--->BN_FAST_MP_INVMOD_C +| | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_MOD_C +| | | | +--->BN_MP_DIV_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_SET_C +| | | | | +--->BN_MP_COUNT_BITS_C +| | | | | +--->BN_MP_ABS_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_2D_C +| | | | | | +--->BN_MP_MOD_2D_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CLEAR_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | | +--->BN_MP_CLEAR_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_INIT_COPY_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_SET_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_DIV_2_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_MULTI_C +| | | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_INVMOD_SLOW_C +| | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_MOD_C +| | | | +--->BN_MP_DIV_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_SET_C +| | | | | +--->BN_MP_COUNT_BITS_C +| | | | | +--->BN_MP_ABS_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_2D_C +| | | | | | +--->BN_MP_MOD_2D_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CLEAR_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | | +--->BN_MP_CLEAR_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_INIT_COPY_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_SET_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_DIV_2_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_MULTI_C +| | | | +--->BN_MP_CLEAR_C +| +--->BN_MP_CLEAR_C +| +--->BN_MP_ABS_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| +--->BN_MP_CLEAR_MULTI_C +| +--->BN_MP_REDUCE_IS_2K_L_C +| +--->BN_S_MP_EXPTMOD_C +| | +--->BN_MP_COUNT_BITS_C +| | +--->BN_MP_REDUCE_SETUP_C +| | | +--->BN_MP_2EXPT_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_DIV_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_SET_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_2D_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_INIT_COPY_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_REDUCE_C +| | | +--->BN_MP_INIT_COPY_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_MUL_C +| | | | +--->BN_MP_TOOM_MUL_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_COPY_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_MUL_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_3_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_KARATSUBA_MUL_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | +--->BN_S_MP_MUL_HIGH_DIGS_C +| | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_MUL_DIGS_C +| | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SET_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_REDUCE_2K_SETUP_L_C +| | | +--->BN_MP_2EXPT_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_REDUCE_2K_L_C +| | | +--->BN_MP_DIV_2D_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_MUL_C +| | | | +--->BN_MP_TOOM_MUL_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_COPY_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_MUL_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_3_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_KARATSUBA_MUL_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MOD_C +| | | +--->BN_MP_DIV_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_SET_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_2D_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_INIT_COPY_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_SQR_C +| | | +--->BN_MP_TOOM_SQR_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_MUL_2_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_2_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_3_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_KARATSUBA_SQR_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | +--->BN_FAST_S_MP_SQR_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SQR_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | +--->BN_MP_MUL_C +| | | +--->BN_MP_TOOM_MUL_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_MUL_2_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_2_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_3_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_KARATSUBA_MUL_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_MUL_DIGS_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | +--->BN_MP_SET_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_DR_IS_MODULUS_C +| +--->BN_MP_REDUCE_IS_2K_C +| | +--->BN_MP_REDUCE_2K_C +| | | +--->BN_MP_COUNT_BITS_C +| | | +--->BN_MP_DIV_2D_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_MUL_D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_COUNT_BITS_C +| +--->BN_MP_EXPTMOD_FAST_C +| | +--->BN_MP_COUNT_BITS_C +| | +--->BN_MP_MONTGOMERY_SETUP_C +| | +--->BN_FAST_MP_MONTGOMERY_REDUCE_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | +--->BN_MP_MONTGOMERY_REDUCE_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | +--->BN_MP_DR_SETUP_C +| | +--->BN_MP_DR_REDUCE_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | +--->BN_MP_REDUCE_2K_SETUP_C +| | | +--->BN_MP_2EXPT_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_REDUCE_2K_C +| | | +--->BN_MP_DIV_2D_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_MUL_D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C +| | | +--->BN_MP_2EXPT_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_SET_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_MUL_2_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MULMOD_C +| | | +--->BN_MP_MUL_C +| | | | +--->BN_MP_TOOM_MUL_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_COPY_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_MUL_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_3_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_KARATSUBA_MUL_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_MOD_C +| | | | +--->BN_MP_DIV_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_SET_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_2D_C +| | | | | | +--->BN_MP_MOD_2D_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_INIT_COPY_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | +--->BN_MP_SET_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_MOD_C +| | | +--->BN_MP_DIV_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_2D_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_INIT_COPY_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_SQR_C +| | | +--->BN_MP_TOOM_SQR_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_MUL_2_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_2_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_3_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_KARATSUBA_SQR_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | +--->BN_FAST_S_MP_SQR_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SQR_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | +--->BN_MP_MUL_C +| | | +--->BN_MP_TOOM_MUL_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_MUL_2_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_2_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_3_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_KARATSUBA_MUL_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_MUL_DIGS_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | +--->BN_MP_EXCH_C ++--->BN_MP_CMP_C +| +--->BN_MP_CMP_MAG_C ++--->BN_MP_CLEAR_C + + +BN_MP_SUBMOD_C ++--->BN_MP_INIT_C ++--->BN_MP_SUB_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_CLEAR_C ++--->BN_MP_MOD_C +| +--->BN_MP_DIV_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_INIT_MULTI_C +| | +--->BN_MP_SET_C +| | +--->BN_MP_COUNT_BITS_C +| | +--->BN_MP_ABS_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2D_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_MULTI_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_INIT_COPY_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_ADD_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C + + +BN_MP_MOD_2D_C ++--->BN_MP_ZERO_C ++--->BN_MP_COPY_C +| +--->BN_MP_GROW_C ++--->BN_MP_CLAMP_C + + +BN_MP_TORADIX_N_C ++--->BN_MP_INIT_COPY_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C ++--->BN_MP_DIV_D_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_DIV_2D_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLEAR_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_DIV_3_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_INIT_SIZE_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_CLEAR_C + + +BN_MP_CMP_C ++--->BN_MP_CMP_MAG_C + + +BNCORE_C + + +BN_MP_TORADIX_C ++--->BN_MP_INIT_COPY_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C ++--->BN_MP_DIV_D_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_DIV_2D_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLEAR_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_DIV_3_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_INIT_SIZE_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_CLEAR_C + + +BN_MP_ADD_D_C ++--->BN_MP_GROW_C ++--->BN_MP_SUB_D_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_CLAMP_C + + +BN_MP_DIV_3_C ++--->BN_MP_INIT_SIZE_C +| +--->BN_MP_INIT_C ++--->BN_MP_CLAMP_C ++--->BN_MP_EXCH_C ++--->BN_MP_CLEAR_C + + +BN_FAST_S_MP_MUL_DIGS_C ++--->BN_MP_GROW_C ++--->BN_MP_CLAMP_C + + +BN_MP_SQRMOD_C ++--->BN_MP_INIT_C ++--->BN_MP_SQR_C +| +--->BN_MP_TOOM_SQR_C +| | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_RSHD_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_MUL_2_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_3_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_CLEAR_C +| +--->BN_MP_KARATSUBA_SQR_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | +--->BN_MP_ADD_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_C +| +--->BN_FAST_S_MP_SQR_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_S_MP_SQR_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C ++--->BN_MP_CLEAR_C ++--->BN_MP_MOD_C +| +--->BN_MP_DIV_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_INIT_MULTI_C +| | +--->BN_MP_SET_C +| | +--->BN_MP_COUNT_BITS_C +| | +--->BN_MP_ABS_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2D_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_MULTI_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_INIT_COPY_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_ADD_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C + + +BN_MP_INVMOD_C ++--->BN_FAST_MP_INVMOD_C +| +--->BN_MP_INIT_MULTI_C +| | +--->BN_MP_INIT_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_MOD_C +| | +--->BN_MP_INIT_C +| | +--->BN_MP_DIV_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_SET_C +| | | +--->BN_MP_COUNT_BITS_C +| | | +--->BN_MP_ABS_C +| | | +--->BN_MP_MUL_2D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_2D_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_MULTI_C +| | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_COPY_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_MUL_D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_CLEAR_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_SET_C +| | +--->BN_MP_ZERO_C +| +--->BN_MP_DIV_2_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_SUB_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_C +| | +--->BN_MP_CMP_MAG_C +| +--->BN_MP_CMP_D_C +| +--->BN_MP_ADD_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_MULTI_C +| | +--->BN_MP_CLEAR_C ++--->BN_MP_INVMOD_SLOW_C +| +--->BN_MP_INIT_MULTI_C +| | +--->BN_MP_INIT_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_MOD_C +| | +--->BN_MP_INIT_C +| | +--->BN_MP_DIV_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_SET_C +| | | +--->BN_MP_COUNT_BITS_C +| | | +--->BN_MP_ABS_C +| | | +--->BN_MP_MUL_2D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_2D_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_MULTI_C +| | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_COPY_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_MUL_D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_CLEAR_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_SET_C +| | +--->BN_MP_ZERO_C +| +--->BN_MP_DIV_2_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_ADD_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_SUB_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_C +| | +--->BN_MP_CMP_MAG_C +| +--->BN_MP_CMP_D_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_MULTI_C +| | +--->BN_MP_CLEAR_C + + +BN_MP_AND_C ++--->BN_MP_INIT_COPY_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C ++--->BN_MP_CLAMP_C ++--->BN_MP_EXCH_C ++--->BN_MP_CLEAR_C + + +BN_MP_MUL_D_C ++--->BN_MP_GROW_C ++--->BN_MP_CLAMP_C + + +BN_FAST_MP_INVMOD_C ++--->BN_MP_INIT_MULTI_C +| +--->BN_MP_INIT_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_COPY_C +| +--->BN_MP_GROW_C ++--->BN_MP_MOD_C +| +--->BN_MP_INIT_C +| +--->BN_MP_DIV_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_SET_C +| | +--->BN_MP_COUNT_BITS_C +| | +--->BN_MP_ABS_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2D_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_INIT_COPY_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_CLEAR_C +| +--->BN_MP_ADD_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C ++--->BN_MP_SET_C +| +--->BN_MP_ZERO_C ++--->BN_MP_DIV_2_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_SUB_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_CMP_C +| +--->BN_MP_CMP_MAG_C ++--->BN_MP_CMP_D_C ++--->BN_MP_ADD_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_EXCH_C ++--->BN_MP_CLEAR_MULTI_C +| +--->BN_MP_CLEAR_C + + +BN_MP_FWRITE_C ++--->BN_MP_RADIX_SIZE_C +| +--->BN_MP_COUNT_BITS_C +| +--->BN_MP_INIT_COPY_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| +--->BN_MP_DIV_D_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_DIV_2D_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_DIV_3_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_TORADIX_C +| +--->BN_MP_INIT_COPY_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| +--->BN_MP_DIV_D_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_DIV_2D_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_DIV_3_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_CLEAR_C + + +BN_S_MP_SQR_C ++--->BN_MP_INIT_SIZE_C +| +--->BN_MP_INIT_C ++--->BN_MP_CLAMP_C ++--->BN_MP_EXCH_C ++--->BN_MP_CLEAR_C + + +BN_MP_N_ROOT_C ++--->BN_MP_INIT_C ++--->BN_MP_SET_C +| +--->BN_MP_ZERO_C ++--->BN_MP_COPY_C +| +--->BN_MP_GROW_C ++--->BN_MP_EXPT_D_C +| +--->BN_MP_INIT_COPY_C +| +--->BN_MP_SQR_C +| | +--->BN_MP_TOOM_SQR_C +| | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_MUL_2_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_2_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MUL_2D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MUL_D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_3_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLEAR_MULTI_C +| | | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_KARATSUBA_SQR_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_FAST_S_MP_SQR_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_SQR_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_C +| +--->BN_MP_CLEAR_C +| +--->BN_MP_MUL_C +| | +--->BN_MP_TOOM_MUL_C +| | | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_MUL_2_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_2_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MUL_2D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MUL_D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_3_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLEAR_MULTI_C +| | +--->BN_MP_KARATSUBA_MUL_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_MUL_DIGS_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C ++--->BN_MP_MUL_C +| +--->BN_MP_TOOM_MUL_C +| | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_RSHD_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_MUL_2_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_3_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_CLEAR_C +| +--->BN_MP_KARATSUBA_MUL_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | +--->BN_MP_CLEAR_C +| +--->BN_FAST_S_MP_MUL_DIGS_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_S_MP_MUL_DIGS_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C ++--->BN_MP_SUB_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_MUL_D_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_DIV_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_MP_ZERO_C +| +--->BN_MP_INIT_MULTI_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_COUNT_BITS_C +| +--->BN_MP_ABS_C +| +--->BN_MP_MUL_2D_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_C +| +--->BN_MP_ADD_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_DIV_2D_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLEAR_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_MULTI_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_INIT_SIZE_C +| +--->BN_MP_INIT_COPY_C +| +--->BN_MP_LSHD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_RSHD_C +| +--->BN_MP_RSHD_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_CMP_C +| +--->BN_MP_CMP_MAG_C ++--->BN_MP_SUB_D_C +| +--->BN_MP_GROW_C +| +--->BN_MP_ADD_D_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_EXCH_C ++--->BN_MP_CLEAR_C + + +BN_MP_PRIME_RABIN_MILLER_TRIALS_C + + +BN_MP_RADIX_SIZE_C ++--->BN_MP_COUNT_BITS_C ++--->BN_MP_INIT_COPY_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C ++--->BN_MP_DIV_D_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_DIV_2D_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLEAR_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_DIV_3_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_INIT_SIZE_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_CLEAR_C + + +BN_MP_READ_SIGNED_BIN_C ++--->BN_MP_READ_UNSIGNED_BIN_C +| +--->BN_MP_GROW_C +| +--->BN_MP_ZERO_C +| +--->BN_MP_MUL_2D_C +| | +--->BN_MP_COPY_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLAMP_C + + +BN_MP_PRIME_RANDOM_EX_C ++--->BN_MP_READ_UNSIGNED_BIN_C +| +--->BN_MP_GROW_C +| +--->BN_MP_ZERO_C +| +--->BN_MP_MUL_2D_C +| | +--->BN_MP_COPY_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_PRIME_IS_PRIME_C +| +--->BN_MP_CMP_D_C +| +--->BN_MP_PRIME_IS_DIVISIBLE_C +| | +--->BN_MP_MOD_D_C +| | | +--->BN_MP_DIV_D_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_DIV_2D_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_INIT_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CLEAR_C +| | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_DIV_3_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_INIT_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_INIT_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_CLEAR_C +| +--->BN_MP_INIT_C +| +--->BN_MP_SET_C +| | +--->BN_MP_ZERO_C +| +--->BN_MP_PRIME_MILLER_RABIN_C +| | +--->BN_MP_INIT_COPY_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_SUB_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ADD_D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CNT_LSB_C +| | +--->BN_MP_DIV_2D_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_EXPTMOD_C +| | | +--->BN_MP_INVMOD_C +| | | | +--->BN_FAST_MP_INVMOD_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | | +--->BN_MP_CLEAR_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_MOD_C +| | | | | | +--->BN_MP_DIV_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | | | +--->BN_MP_COUNT_BITS_C +| | | | | | | +--->BN_MP_ABS_C +| | | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | | +--->BN_MP_RSHD_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_C +| | | | | | | +--->BN_MP_SUB_C +| | | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_ADD_C +| | | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_EXCH_C +| | | | | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | | | | +--->BN_MP_CLEAR_C +| | | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_MUL_D_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CLEAR_C +| | | | | | +--->BN_MP_CLEAR_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_DIV_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_INVMOD_SLOW_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | | +--->BN_MP_CLEAR_C +| | | | | +--->BN_MP_MOD_C +| | | | | | +--->BN_MP_DIV_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_MP_COPY_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | | | +--->BN_MP_COUNT_BITS_C +| | | | | | | +--->BN_MP_ABS_C +| | | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | | +--->BN_MP_RSHD_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_C +| | | | | | | +--->BN_MP_SUB_C +| | | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_ADD_C +| | | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_EXCH_C +| | | | | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | | | | +--->BN_MP_CLEAR_C +| | | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_MUL_D_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CLEAR_C +| | | | | | +--->BN_MP_CLEAR_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_DIV_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_ABS_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_REDUCE_IS_2K_L_C +| | | +--->BN_S_MP_EXPTMOD_C +| | | | +--->BN_MP_COUNT_BITS_C +| | | | +--->BN_MP_REDUCE_SETUP_C +| | | | | +--->BN_MP_2EXPT_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_DIV_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_MP_COPY_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_INIT_MULTI_C +| | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_MUL_D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_REDUCE_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_MUL_C +| | | | | | +--->BN_MP_TOOM_MUL_C +| | | | | | | +--->BN_MP_INIT_MULTI_C +| | | | | | | +--->BN_MP_MOD_2D_C +| | | | | | | | +--->BN_MP_ZERO_C +| | | | | | | | +--->BN_MP_COPY_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_COPY_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_MUL_2_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_ADD_C +| | | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_SUB_C +| | | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_DIV_2_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_MUL_D_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_DIV_3_C +| | | | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | | +--->BN_MP_EXCH_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_KARATSUBA_MUL_C +| | | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_SUB_C +| | | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_ADD_C +| | | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_S_MP_MUL_HIGH_DIGS_C +| | | | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_COPY_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_REDUCE_2K_SETUP_L_C +| | | | | +--->BN_MP_2EXPT_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_REDUCE_2K_L_C +| | | | | +--->BN_MP_MUL_C +| | | | | | +--->BN_MP_TOOM_MUL_C +| | | | | | | +--->BN_MP_INIT_MULTI_C +| | | | | | | +--->BN_MP_MOD_2D_C +| | | | | | | | +--->BN_MP_ZERO_C +| | | | | | | | +--->BN_MP_COPY_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_COPY_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | | | +--->BN_MP_ZERO_C +| | | | | | | +--->BN_MP_MUL_2_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_ADD_C +| | | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_SUB_C +| | | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_DIV_2_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_MUL_D_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_DIV_3_C +| | | | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | | +--->BN_MP_EXCH_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_KARATSUBA_MUL_C +| | | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_SUB_C +| | | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_ADD_C +| | | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_RSHD_C +| | | | | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MOD_C +| | | | | +--->BN_MP_DIV_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_MP_COPY_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_INIT_MULTI_C +| | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_MUL_D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_SQR_C +| | | | | +--->BN_MP_TOOM_SQR_C +| | | | | | +--->BN_MP_INIT_MULTI_C +| | | | | | +--->BN_MP_MOD_2D_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_MUL_2_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_DIV_2_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_MUL_D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_DIV_3_C +| | | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_EXCH_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_KARATSUBA_SQR_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_FAST_S_MP_SQR_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SQR_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_MUL_C +| | | | | +--->BN_MP_TOOM_MUL_C +| | | | | | +--->BN_MP_INIT_MULTI_C +| | | | | | +--->BN_MP_MOD_2D_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_MUL_2_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_DIV_2_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_MUL_D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_DIV_3_C +| | | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_EXCH_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_KARATSUBA_MUL_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_DR_IS_MODULUS_C +| | | +--->BN_MP_REDUCE_IS_2K_C +| | | | +--->BN_MP_REDUCE_2K_C +| | | | | +--->BN_MP_COUNT_BITS_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_COUNT_BITS_C +| | | +--->BN_MP_EXPTMOD_FAST_C +| | | | +--->BN_MP_COUNT_BITS_C +| | | | +--->BN_MP_MONTGOMERY_SETUP_C +| | | | +--->BN_FAST_MP_MONTGOMERY_REDUCE_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_MONTGOMERY_REDUCE_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_DR_SETUP_C +| | | | +--->BN_MP_DR_REDUCE_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_REDUCE_2K_SETUP_C +| | | | | +--->BN_MP_2EXPT_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_REDUCE_2K_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C +| | | | | +--->BN_MP_2EXPT_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_MUL_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MULMOD_C +| | | | | +--->BN_MP_MUL_C +| | | | | | +--->BN_MP_TOOM_MUL_C +| | | | | | | +--->BN_MP_INIT_MULTI_C +| | | | | | | +--->BN_MP_MOD_2D_C +| | | | | | | | +--->BN_MP_ZERO_C +| | | | | | | | +--->BN_MP_COPY_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_COPY_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | | | +--->BN_MP_ZERO_C +| | | | | | | +--->BN_MP_MUL_2_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_ADD_C +| | | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_SUB_C +| | | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_DIV_2_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_MUL_D_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_DIV_3_C +| | | | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | | +--->BN_MP_EXCH_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_KARATSUBA_MUL_C +| | | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_SUB_C +| | | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_ADD_C +| | | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_RSHD_C +| | | | | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_MOD_C +| | | | | | +--->BN_MP_DIV_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_MP_COPY_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | | | +--->BN_MP_INIT_MULTI_C +| | | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | | +--->BN_MP_RSHD_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_C +| | | | | | | +--->BN_MP_SUB_C +| | | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_ADD_C +| | | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_EXCH_C +| | | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_MUL_D_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_MOD_C +| | | | | +--->BN_MP_DIV_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_MP_COPY_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_INIT_MULTI_C +| | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_MUL_D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_SQR_C +| | | | | +--->BN_MP_TOOM_SQR_C +| | | | | | +--->BN_MP_INIT_MULTI_C +| | | | | | +--->BN_MP_MOD_2D_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_MUL_2_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_DIV_2_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_MUL_D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_DIV_3_C +| | | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_EXCH_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_KARATSUBA_SQR_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_FAST_S_MP_SQR_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SQR_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_MUL_C +| | | | | +--->BN_MP_TOOM_MUL_C +| | | | | | +--->BN_MP_INIT_MULTI_C +| | | | | | +--->BN_MP_MOD_2D_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_MUL_2_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_DIV_2_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_MUL_D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_DIV_3_C +| | | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_EXCH_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_KARATSUBA_MUL_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_EXCH_C +| | +--->BN_MP_CMP_C +| | | +--->BN_MP_CMP_MAG_C +| | +--->BN_MP_SQRMOD_C +| | | +--->BN_MP_SQR_C +| | | | +--->BN_MP_TOOM_SQR_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | | +--->BN_MP_CLEAR_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_COPY_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_MUL_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_3_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | | +--->BN_MP_CLEAR_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_KARATSUBA_SQR_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_FAST_S_MP_SQR_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_SQR_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_MOD_C +| | | | +--->BN_MP_DIV_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_COUNT_BITS_C +| | | | | +--->BN_MP_ABS_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_SUB_D_C +| +--->BN_MP_GROW_C +| +--->BN_MP_ADD_D_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_DIV_2_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_MUL_2_C +| +--->BN_MP_GROW_C ++--->BN_MP_ADD_D_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C + + +BN_MP_KARATSUBA_SQR_C ++--->BN_MP_INIT_SIZE_C +| +--->BN_MP_INIT_C ++--->BN_MP_CLAMP_C ++--->BN_MP_SQR_C +| +--->BN_MP_TOOM_SQR_C +| | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_INIT_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_RSHD_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_MUL_2_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_DIV_2_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_DIV_3_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_CLEAR_C +| +--->BN_FAST_S_MP_SQR_C +| | +--->BN_MP_GROW_C +| +--->BN_S_MP_SQR_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C ++--->BN_MP_SUB_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C ++--->BN_S_MP_ADD_C +| +--->BN_MP_GROW_C ++--->BN_MP_LSHD_C +| +--->BN_MP_GROW_C +| +--->BN_MP_RSHD_C +| | +--->BN_MP_ZERO_C ++--->BN_MP_ADD_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C ++--->BN_MP_CLEAR_C + + +BN_MP_INIT_COPY_C ++--->BN_MP_COPY_C +| +--->BN_MP_GROW_C + + +BN_MP_CLAMP_C + + +BN_MP_TOOM_SQR_C ++--->BN_MP_INIT_MULTI_C +| +--->BN_MP_INIT_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_MOD_2D_C +| +--->BN_MP_ZERO_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_COPY_C +| +--->BN_MP_GROW_C ++--->BN_MP_RSHD_C +| +--->BN_MP_ZERO_C ++--->BN_MP_SQR_C +| +--->BN_MP_KARATSUBA_SQR_C +| | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_C +| +--->BN_FAST_S_MP_SQR_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_S_MP_SQR_C +| | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C ++--->BN_MP_MUL_2_C +| +--->BN_MP_GROW_C ++--->BN_MP_ADD_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_SUB_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_DIV_2_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_MUL_2D_C +| +--->BN_MP_GROW_C +| +--->BN_MP_LSHD_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_MUL_D_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_DIV_3_C +| +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_INIT_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_LSHD_C +| +--->BN_MP_GROW_C ++--->BN_MP_CLEAR_MULTI_C +| +--->BN_MP_CLEAR_C + + +BN_MP_MOD_C ++--->BN_MP_INIT_C ++--->BN_MP_DIV_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_ZERO_C +| +--->BN_MP_INIT_MULTI_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_SET_C +| +--->BN_MP_COUNT_BITS_C +| +--->BN_MP_ABS_C +| +--->BN_MP_MUL_2D_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_C +| +--->BN_MP_SUB_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_ADD_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_DIV_2D_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLEAR_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_MULTI_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_INIT_SIZE_C +| +--->BN_MP_INIT_COPY_C +| +--->BN_MP_LSHD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_RSHD_C +| +--->BN_MP_RSHD_C +| +--->BN_MP_MUL_D_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_CLEAR_C ++--->BN_MP_ADD_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_EXCH_C + + +BN_MP_INIT_C + + +BN_MP_TOOM_MUL_C ++--->BN_MP_INIT_MULTI_C +| +--->BN_MP_INIT_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_MOD_2D_C +| +--->BN_MP_ZERO_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_COPY_C +| +--->BN_MP_GROW_C ++--->BN_MP_RSHD_C +| +--->BN_MP_ZERO_C ++--->BN_MP_MUL_C +| +--->BN_MP_KARATSUBA_MUL_C +| | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_C +| +--->BN_FAST_S_MP_MUL_DIGS_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_S_MP_MUL_DIGS_C +| | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C ++--->BN_MP_MUL_2_C +| +--->BN_MP_GROW_C ++--->BN_MP_ADD_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_SUB_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_DIV_2_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_MUL_2D_C +| +--->BN_MP_GROW_C +| +--->BN_MP_LSHD_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_MUL_D_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_DIV_3_C +| +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_INIT_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_LSHD_C +| +--->BN_MP_GROW_C ++--->BN_MP_CLEAR_MULTI_C +| +--->BN_MP_CLEAR_C + + +BN_MP_PRIME_IS_PRIME_C ++--->BN_MP_CMP_D_C ++--->BN_MP_PRIME_IS_DIVISIBLE_C +| +--->BN_MP_MOD_D_C +| | +--->BN_MP_DIV_D_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_DIV_2D_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_INIT_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_DIV_3_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_INIT_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_INIT_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_C ++--->BN_MP_INIT_C ++--->BN_MP_SET_C +| +--->BN_MP_ZERO_C ++--->BN_MP_PRIME_MILLER_RABIN_C +| +--->BN_MP_INIT_COPY_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| +--->BN_MP_SUB_D_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_D_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CNT_LSB_C +| +--->BN_MP_DIV_2D_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLEAR_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_EXPTMOD_C +| | +--->BN_MP_INVMOD_C +| | | +--->BN_FAST_MP_INVMOD_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_MOD_C +| | | | | +--->BN_MP_DIV_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_COUNT_BITS_C +| | | | | | +--->BN_MP_ABS_C +| | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | | | +--->BN_MP_CLEAR_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_MUL_D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CLEAR_C +| | | | | +--->BN_MP_CLEAR_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_DIV_2_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_INVMOD_SLOW_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_MOD_C +| | | | | +--->BN_MP_DIV_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_MP_COPY_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_COUNT_BITS_C +| | | | | | +--->BN_MP_ABS_C +| | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | | | +--->BN_MP_CLEAR_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_MUL_D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CLEAR_C +| | | | | +--->BN_MP_CLEAR_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_DIV_2_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_CLEAR_C +| | +--->BN_MP_ABS_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_MULTI_C +| | +--->BN_MP_REDUCE_IS_2K_L_C +| | +--->BN_S_MP_EXPTMOD_C +| | | +--->BN_MP_COUNT_BITS_C +| | | +--->BN_MP_REDUCE_SETUP_C +| | | | +--->BN_MP_2EXPT_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_DIV_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_REDUCE_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_MUL_C +| | | | | +--->BN_MP_TOOM_MUL_C +| | | | | | +--->BN_MP_INIT_MULTI_C +| | | | | | +--->BN_MP_MOD_2D_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | | | +--->BN_MP_COPY_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_COPY_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_MUL_2_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_DIV_2_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_MUL_D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_DIV_3_C +| | | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_EXCH_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_KARATSUBA_MUL_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_S_MP_MUL_HIGH_DIGS_C +| | | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_REDUCE_2K_SETUP_L_C +| | | | +--->BN_MP_2EXPT_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_REDUCE_2K_L_C +| | | | +--->BN_MP_MUL_C +| | | | | +--->BN_MP_TOOM_MUL_C +| | | | | | +--->BN_MP_INIT_MULTI_C +| | | | | | +--->BN_MP_MOD_2D_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | | | +--->BN_MP_COPY_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_COPY_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_MUL_2_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_DIV_2_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_MUL_D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_DIV_3_C +| | | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_EXCH_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_KARATSUBA_MUL_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MOD_C +| | | | +--->BN_MP_DIV_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_SQR_C +| | | | +--->BN_MP_TOOM_SQR_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_MUL_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_3_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_KARATSUBA_SQR_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_FAST_S_MP_SQR_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_SQR_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_MUL_C +| | | | +--->BN_MP_TOOM_MUL_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_MUL_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_3_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_KARATSUBA_MUL_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_DR_IS_MODULUS_C +| | +--->BN_MP_REDUCE_IS_2K_C +| | | +--->BN_MP_REDUCE_2K_C +| | | | +--->BN_MP_COUNT_BITS_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_COUNT_BITS_C +| | +--->BN_MP_EXPTMOD_FAST_C +| | | +--->BN_MP_COUNT_BITS_C +| | | +--->BN_MP_MONTGOMERY_SETUP_C +| | | +--->BN_FAST_MP_MONTGOMERY_REDUCE_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_MONTGOMERY_REDUCE_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_DR_SETUP_C +| | | +--->BN_MP_DR_REDUCE_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_REDUCE_2K_SETUP_C +| | | | +--->BN_MP_2EXPT_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_REDUCE_2K_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C +| | | | +--->BN_MP_2EXPT_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_MUL_2_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MULMOD_C +| | | | +--->BN_MP_MUL_C +| | | | | +--->BN_MP_TOOM_MUL_C +| | | | | | +--->BN_MP_INIT_MULTI_C +| | | | | | +--->BN_MP_MOD_2D_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | | | +--->BN_MP_COPY_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_COPY_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_MUL_2_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_DIV_2_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_MUL_D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_DIV_3_C +| | | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_EXCH_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_KARATSUBA_MUL_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_MOD_C +| | | | | +--->BN_MP_DIV_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_MP_COPY_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_INIT_MULTI_C +| | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_MUL_D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_MOD_C +| | | | +--->BN_MP_DIV_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_SQR_C +| | | | +--->BN_MP_TOOM_SQR_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_MUL_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_3_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_KARATSUBA_SQR_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_FAST_S_MP_SQR_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_SQR_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_MUL_C +| | | | +--->BN_MP_TOOM_MUL_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_MUL_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_3_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_KARATSUBA_MUL_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_EXCH_C +| +--->BN_MP_CMP_C +| | +--->BN_MP_CMP_MAG_C +| +--->BN_MP_SQRMOD_C +| | +--->BN_MP_SQR_C +| | | +--->BN_MP_TOOM_SQR_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_MUL_2_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_2_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_3_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_KARATSUBA_SQR_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLEAR_C +| | | +--->BN_FAST_S_MP_SQR_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SQR_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_CLEAR_C +| | +--->BN_MP_MOD_C +| | | +--->BN_MP_DIV_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_COUNT_BITS_C +| | | | +--->BN_MP_ABS_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_CLEAR_MULTI_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_CLEAR_C + + +BN_MP_COPY_C ++--->BN_MP_GROW_C + + +BN_S_MP_SUB_C ++--->BN_MP_GROW_C ++--->BN_MP_CLAMP_C + + +BN_MP_READ_UNSIGNED_BIN_C ++--->BN_MP_GROW_C ++--->BN_MP_ZERO_C ++--->BN_MP_MUL_2D_C +| +--->BN_MP_COPY_C +| +--->BN_MP_LSHD_C +| | +--->BN_MP_RSHD_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_CLAMP_C + + +BN_MP_EXPTMOD_FAST_C ++--->BN_MP_COUNT_BITS_C ++--->BN_MP_INIT_C ++--->BN_MP_CLEAR_C ++--->BN_MP_MONTGOMERY_SETUP_C ++--->BN_FAST_MP_MONTGOMERY_REDUCE_C +| +--->BN_MP_GROW_C +| +--->BN_MP_RSHD_C +| | +--->BN_MP_ZERO_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C ++--->BN_MP_MONTGOMERY_REDUCE_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_RSHD_C +| | +--->BN_MP_ZERO_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C ++--->BN_MP_DR_SETUP_C ++--->BN_MP_DR_REDUCE_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C ++--->BN_MP_REDUCE_2K_SETUP_C +| +--->BN_MP_2EXPT_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_GROW_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_REDUCE_2K_C +| +--->BN_MP_DIV_2D_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_MUL_D_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C +| +--->BN_MP_2EXPT_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_SET_C +| | +--->BN_MP_ZERO_C +| +--->BN_MP_MUL_2_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_MULMOD_C +| +--->BN_MP_MUL_C +| | +--->BN_MP_TOOM_MUL_C +| | | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_MUL_2_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_2_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MUL_2D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MUL_D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_3_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLEAR_MULTI_C +| | +--->BN_MP_KARATSUBA_MUL_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_MUL_DIGS_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| +--->BN_MP_MOD_C +| | +--->BN_MP_DIV_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_SET_C +| | | +--->BN_MP_ABS_C +| | | +--->BN_MP_MUL_2D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_2D_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_COPY_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_MUL_D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C ++--->BN_MP_SET_C +| +--->BN_MP_ZERO_C ++--->BN_MP_MOD_C +| +--->BN_MP_DIV_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_INIT_MULTI_C +| | +--->BN_MP_ABS_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2D_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_MULTI_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_INIT_COPY_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_ADD_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C ++--->BN_MP_COPY_C +| +--->BN_MP_GROW_C ++--->BN_MP_SQR_C +| +--->BN_MP_TOOM_SQR_C +| | +--->BN_MP_INIT_MULTI_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_RSHD_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_MUL_2_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_3_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_MULTI_C +| +--->BN_MP_KARATSUBA_SQR_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | +--->BN_MP_ADD_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| +--->BN_FAST_S_MP_SQR_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_S_MP_SQR_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C ++--->BN_MP_MUL_C +| +--->BN_MP_TOOM_MUL_C +| | +--->BN_MP_INIT_MULTI_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_RSHD_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_MUL_2_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_3_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_MULTI_C +| +--->BN_MP_KARATSUBA_MUL_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| +--->BN_FAST_S_MP_MUL_DIGS_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_S_MP_MUL_DIGS_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C ++--->BN_MP_EXCH_C + + +BN_MP_TO_UNSIGNED_BIN_C ++--->BN_MP_INIT_COPY_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C ++--->BN_MP_DIV_2D_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_ZERO_C +| +--->BN_MP_MOD_2D_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLEAR_C +| +--->BN_MP_RSHD_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C ++--->BN_MP_CLEAR_C + + +BN_MP_SET_INT_C ++--->BN_MP_ZERO_C ++--->BN_MP_MUL_2D_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_GROW_C +| +--->BN_MP_LSHD_C +| | +--->BN_MP_RSHD_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_CLAMP_C + + +BN_MP_MOD_D_C ++--->BN_MP_DIV_D_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_DIV_2D_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_INIT_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLEAR_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_DIV_3_C +| | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_INIT_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_C + + +BN_MP_SQR_C ++--->BN_MP_TOOM_SQR_C +| +--->BN_MP_INIT_MULTI_C +| | +--->BN_MP_INIT_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_MOD_2D_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_RSHD_C +| | +--->BN_MP_ZERO_C +| +--->BN_MP_MUL_2_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_ADD_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_SUB_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_DIV_2_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_MUL_2D_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_MUL_D_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_DIV_3_C +| | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_LSHD_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_CLEAR_MULTI_C +| | +--->BN_MP_CLEAR_C ++--->BN_MP_KARATSUBA_SQR_C +| +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_INIT_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_SUB_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_LSHD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_RSHD_C +| | | +--->BN_MP_ZERO_C +| +--->BN_MP_ADD_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| +--->BN_MP_CLEAR_C ++--->BN_FAST_S_MP_SQR_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_S_MP_SQR_C +| +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_INIT_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_C + + +BN_MP_MULMOD_C ++--->BN_MP_INIT_C ++--->BN_MP_MUL_C +| +--->BN_MP_TOOM_MUL_C +| | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_RSHD_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_MUL_2_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_3_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_CLEAR_C +| +--->BN_MP_KARATSUBA_MUL_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | +--->BN_MP_CLEAR_C +| +--->BN_FAST_S_MP_MUL_DIGS_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_S_MP_MUL_DIGS_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C ++--->BN_MP_CLEAR_C ++--->BN_MP_MOD_C +| +--->BN_MP_DIV_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_INIT_MULTI_C +| | +--->BN_MP_SET_C +| | +--->BN_MP_COUNT_BITS_C +| | +--->BN_MP_ABS_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2D_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_MULTI_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_INIT_COPY_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_ADD_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C + + +BN_MP_DIV_2D_C ++--->BN_MP_COPY_C +| +--->BN_MP_GROW_C ++--->BN_MP_ZERO_C ++--->BN_MP_INIT_C ++--->BN_MP_MOD_2D_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_CLEAR_C ++--->BN_MP_RSHD_C ++--->BN_MP_CLAMP_C ++--->BN_MP_EXCH_C + + +BN_S_MP_ADD_C ++--->BN_MP_GROW_C ++--->BN_MP_CLAMP_C + + +BN_FAST_S_MP_SQR_C ++--->BN_MP_GROW_C ++--->BN_MP_CLAMP_C + + +BN_S_MP_MUL_DIGS_C ++--->BN_FAST_S_MP_MUL_DIGS_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_INIT_SIZE_C +| +--->BN_MP_INIT_C ++--->BN_MP_CLAMP_C ++--->BN_MP_EXCH_C ++--->BN_MP_CLEAR_C + + +BN_MP_XOR_C ++--->BN_MP_INIT_COPY_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C ++--->BN_MP_CLAMP_C ++--->BN_MP_EXCH_C ++--->BN_MP_CLEAR_C + + +BN_MP_RADIX_SMAP_C + + +BN_MP_DR_IS_MODULUS_C + + +BN_MP_MONTGOMERY_CALC_NORMALIZATION_C ++--->BN_MP_COUNT_BITS_C ++--->BN_MP_2EXPT_C +| +--->BN_MP_ZERO_C +| +--->BN_MP_GROW_C ++--->BN_MP_SET_C +| +--->BN_MP_ZERO_C ++--->BN_MP_MUL_2_C +| +--->BN_MP_GROW_C ++--->BN_MP_CMP_MAG_C ++--->BN_S_MP_SUB_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C + + +BN_MP_SUB_C ++--->BN_S_MP_ADD_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_CMP_MAG_C ++--->BN_S_MP_SUB_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C + + +BN_MP_INIT_MULTI_C ++--->BN_MP_INIT_C ++--->BN_MP_CLEAR_C + + +BN_S_MP_MUL_HIGH_DIGS_C ++--->BN_FAST_S_MP_MUL_HIGH_DIGS_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_INIT_SIZE_C +| +--->BN_MP_INIT_C ++--->BN_MP_CLAMP_C ++--->BN_MP_EXCH_C ++--->BN_MP_CLEAR_C + + +BN_MP_PRIME_NEXT_PRIME_C ++--->BN_MP_CMP_D_C ++--->BN_MP_SET_C +| +--->BN_MP_ZERO_C ++--->BN_MP_SUB_D_C +| +--->BN_MP_GROW_C +| +--->BN_MP_ADD_D_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_MOD_D_C +| +--->BN_MP_DIV_D_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_DIV_2D_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_INIT_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_DIV_3_C +| | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_INIT_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C ++--->BN_MP_INIT_C ++--->BN_MP_ADD_D_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_PRIME_MILLER_RABIN_C +| +--->BN_MP_INIT_COPY_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| +--->BN_MP_CNT_LSB_C +| +--->BN_MP_DIV_2D_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLEAR_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_EXPTMOD_C +| | +--->BN_MP_INVMOD_C +| | | +--->BN_FAST_MP_INVMOD_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_MOD_C +| | | | | +--->BN_MP_DIV_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_COUNT_BITS_C +| | | | | | +--->BN_MP_ABS_C +| | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | | | +--->BN_MP_CLEAR_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_MUL_D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CLEAR_C +| | | | | +--->BN_MP_CLEAR_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_DIV_2_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_INVMOD_SLOW_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_MOD_C +| | | | | +--->BN_MP_DIV_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_MP_COPY_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_COUNT_BITS_C +| | | | | | +--->BN_MP_ABS_C +| | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | | | +--->BN_MP_CLEAR_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_MUL_D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CLEAR_C +| | | | | +--->BN_MP_CLEAR_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_DIV_2_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_CLEAR_C +| | +--->BN_MP_ABS_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_MULTI_C +| | +--->BN_MP_REDUCE_IS_2K_L_C +| | +--->BN_S_MP_EXPTMOD_C +| | | +--->BN_MP_COUNT_BITS_C +| | | +--->BN_MP_REDUCE_SETUP_C +| | | | +--->BN_MP_2EXPT_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_DIV_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_REDUCE_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_MUL_C +| | | | | +--->BN_MP_TOOM_MUL_C +| | | | | | +--->BN_MP_INIT_MULTI_C +| | | | | | +--->BN_MP_MOD_2D_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | | | +--->BN_MP_COPY_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_COPY_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_MUL_2_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_DIV_2_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_MUL_D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_DIV_3_C +| | | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_EXCH_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_KARATSUBA_MUL_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_S_MP_MUL_HIGH_DIGS_C +| | | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_REDUCE_2K_SETUP_L_C +| | | | +--->BN_MP_2EXPT_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_REDUCE_2K_L_C +| | | | +--->BN_MP_MUL_C +| | | | | +--->BN_MP_TOOM_MUL_C +| | | | | | +--->BN_MP_INIT_MULTI_C +| | | | | | +--->BN_MP_MOD_2D_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | | | +--->BN_MP_COPY_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_COPY_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_MUL_2_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_DIV_2_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_MUL_D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_DIV_3_C +| | | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_EXCH_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_KARATSUBA_MUL_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MOD_C +| | | | +--->BN_MP_DIV_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_SQR_C +| | | | +--->BN_MP_TOOM_SQR_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_MUL_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_3_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_KARATSUBA_SQR_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_FAST_S_MP_SQR_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_SQR_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_MUL_C +| | | | +--->BN_MP_TOOM_MUL_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_MUL_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_3_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_KARATSUBA_MUL_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_DR_IS_MODULUS_C +| | +--->BN_MP_REDUCE_IS_2K_C +| | | +--->BN_MP_REDUCE_2K_C +| | | | +--->BN_MP_COUNT_BITS_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_COUNT_BITS_C +| | +--->BN_MP_EXPTMOD_FAST_C +| | | +--->BN_MP_COUNT_BITS_C +| | | +--->BN_MP_MONTGOMERY_SETUP_C +| | | +--->BN_FAST_MP_MONTGOMERY_REDUCE_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_MONTGOMERY_REDUCE_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_DR_SETUP_C +| | | +--->BN_MP_DR_REDUCE_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_REDUCE_2K_SETUP_C +| | | | +--->BN_MP_2EXPT_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_REDUCE_2K_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C +| | | | +--->BN_MP_2EXPT_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_MUL_2_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MULMOD_C +| | | | +--->BN_MP_MUL_C +| | | | | +--->BN_MP_TOOM_MUL_C +| | | | | | +--->BN_MP_INIT_MULTI_C +| | | | | | +--->BN_MP_MOD_2D_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | | | +--->BN_MP_COPY_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_COPY_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_MUL_2_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_DIV_2_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_MUL_D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_DIV_3_C +| | | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_MP_EXCH_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_KARATSUBA_MUL_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_MOD_C +| | | | | +--->BN_MP_DIV_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_MP_COPY_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_INIT_MULTI_C +| | | | | | +--->BN_MP_MUL_2D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_LSHD_C +| | | | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_C +| | | | | | +--->BN_MP_SUB_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_ADD_C +| | | | | | | +--->BN_S_MP_ADD_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | | +--->BN_S_MP_SUB_C +| | | | | | | | +--->BN_MP_GROW_C +| | | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_MUL_D_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_MOD_C +| | | | +--->BN_MP_DIV_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_SQR_C +| | | | +--->BN_MP_TOOM_SQR_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_MUL_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_3_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_KARATSUBA_SQR_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_FAST_S_MP_SQR_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_SQR_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_MUL_C +| | | | +--->BN_MP_TOOM_MUL_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_MUL_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_3_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_KARATSUBA_MUL_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_EXCH_C +| +--->BN_MP_CMP_C +| | +--->BN_MP_CMP_MAG_C +| +--->BN_MP_SQRMOD_C +| | +--->BN_MP_SQR_C +| | | +--->BN_MP_TOOM_SQR_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_MUL_2_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_2_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_3_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_KARATSUBA_SQR_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLEAR_C +| | | +--->BN_FAST_S_MP_SQR_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SQR_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_CLEAR_C +| | +--->BN_MP_MOD_C +| | | +--->BN_MP_DIV_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_COUNT_BITS_C +| | | | +--->BN_MP_ABS_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_CLEAR_MULTI_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_CLEAR_C + + +BN_MP_SIGNED_BIN_SIZE_C ++--->BN_MP_UNSIGNED_BIN_SIZE_C +| +--->BN_MP_COUNT_BITS_C + + +BN_MP_INVMOD_SLOW_C ++--->BN_MP_INIT_MULTI_C +| +--->BN_MP_INIT_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_MOD_C +| +--->BN_MP_INIT_C +| +--->BN_MP_DIV_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_SET_C +| | +--->BN_MP_COUNT_BITS_C +| | +--->BN_MP_ABS_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2D_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_INIT_COPY_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_CLEAR_C +| +--->BN_MP_ADD_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C ++--->BN_MP_COPY_C +| +--->BN_MP_GROW_C ++--->BN_MP_SET_C +| +--->BN_MP_ZERO_C ++--->BN_MP_DIV_2_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_ADD_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_SUB_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_CMP_C +| +--->BN_MP_CMP_MAG_C ++--->BN_MP_CMP_D_C ++--->BN_MP_CMP_MAG_C ++--->BN_MP_EXCH_C ++--->BN_MP_CLEAR_MULTI_C +| +--->BN_MP_CLEAR_C + + +BN_MP_LCM_C ++--->BN_MP_INIT_MULTI_C +| +--->BN_MP_INIT_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_GCD_C +| +--->BN_MP_ABS_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| +--->BN_MP_ZERO_C +| +--->BN_MP_INIT_COPY_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| +--->BN_MP_CNT_LSB_C +| +--->BN_MP_DIV_2D_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLEAR_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_MP_EXCH_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_MUL_2D_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_CMP_MAG_C ++--->BN_MP_DIV_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_ZERO_C +| +--->BN_MP_SET_C +| +--->BN_MP_COUNT_BITS_C +| +--->BN_MP_ABS_C +| +--->BN_MP_MUL_2D_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_C +| +--->BN_MP_SUB_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_ADD_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_DIV_2D_C +| | +--->BN_MP_INIT_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLEAR_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_MULTI_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_INIT_C +| +--->BN_MP_INIT_C +| +--->BN_MP_INIT_COPY_C +| +--->BN_MP_LSHD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_RSHD_C +| +--->BN_MP_RSHD_C +| +--->BN_MP_MUL_D_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_MUL_C +| +--->BN_MP_TOOM_MUL_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_RSHD_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_MUL_2_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_3_C +| | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_INIT_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_CLEAR_C +| +--->BN_MP_KARATSUBA_MUL_C +| | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | +--->BN_MP_CLEAR_C +| +--->BN_FAST_S_MP_MUL_DIGS_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_S_MP_MUL_DIGS_C +| | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C ++--->BN_MP_CLEAR_MULTI_C +| +--->BN_MP_CLEAR_C + + +BN_MP_REDUCE_2K_L_C ++--->BN_MP_INIT_C ++--->BN_MP_COUNT_BITS_C ++--->BN_MP_DIV_2D_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_ZERO_C +| +--->BN_MP_MOD_2D_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLEAR_C +| +--->BN_MP_RSHD_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C ++--->BN_MP_MUL_C +| +--->BN_MP_TOOM_MUL_C +| | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_RSHD_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_MUL_2_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_3_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_CLEAR_C +| +--->BN_MP_KARATSUBA_MUL_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | +--->BN_MP_CLEAR_C +| +--->BN_FAST_S_MP_MUL_DIGS_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_S_MP_MUL_DIGS_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C ++--->BN_S_MP_ADD_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_CMP_MAG_C ++--->BN_S_MP_SUB_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_CLEAR_C + + +BN_REVERSE_C + + +BN_MP_PRIME_IS_DIVISIBLE_C ++--->BN_MP_MOD_D_C +| +--->BN_MP_DIV_D_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_DIV_2D_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_INIT_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_DIV_3_C +| | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_INIT_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C + + +BN_MP_SET_C ++--->BN_MP_ZERO_C + + +BN_MP_GCD_C ++--->BN_MP_ABS_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C ++--->BN_MP_ZERO_C ++--->BN_MP_INIT_COPY_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C ++--->BN_MP_CNT_LSB_C ++--->BN_MP_DIV_2D_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_MOD_2D_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLEAR_C +| +--->BN_MP_RSHD_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C ++--->BN_MP_CMP_MAG_C ++--->BN_MP_EXCH_C ++--->BN_S_MP_SUB_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_MUL_2D_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_GROW_C +| +--->BN_MP_LSHD_C +| | +--->BN_MP_RSHD_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_CLEAR_C + + +BN_MP_REDUCE_2K_SETUP_L_C ++--->BN_MP_INIT_C ++--->BN_MP_2EXPT_C +| +--->BN_MP_ZERO_C +| +--->BN_MP_GROW_C ++--->BN_MP_COUNT_BITS_C ++--->BN_S_MP_SUB_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_CLEAR_C + + +BN_MP_READ_RADIX_C ++--->BN_MP_ZERO_C ++--->BN_MP_MUL_D_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_ADD_D_C +| +--->BN_MP_GROW_C +| +--->BN_MP_SUB_D_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLAMP_C + + +BN_FAST_S_MP_MUL_HIGH_DIGS_C ++--->BN_MP_GROW_C ++--->BN_MP_CLAMP_C + + +BN_FAST_MP_MONTGOMERY_REDUCE_C ++--->BN_MP_GROW_C ++--->BN_MP_RSHD_C +| +--->BN_MP_ZERO_C ++--->BN_MP_CLAMP_C ++--->BN_MP_CMP_MAG_C ++--->BN_S_MP_SUB_C + + +BN_MP_DIV_D_C ++--->BN_MP_COPY_C +| +--->BN_MP_GROW_C ++--->BN_MP_DIV_2D_C +| +--->BN_MP_ZERO_C +| +--->BN_MP_INIT_C +| +--->BN_MP_MOD_2D_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLEAR_C +| +--->BN_MP_RSHD_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C ++--->BN_MP_DIV_3_C +| +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_INIT_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_INIT_SIZE_C +| +--->BN_MP_INIT_C ++--->BN_MP_CLAMP_C ++--->BN_MP_EXCH_C ++--->BN_MP_CLEAR_C + + +BN_MP_REDUCE_2K_SETUP_C ++--->BN_MP_INIT_C ++--->BN_MP_COUNT_BITS_C ++--->BN_MP_2EXPT_C +| +--->BN_MP_ZERO_C +| +--->BN_MP_GROW_C ++--->BN_MP_CLEAR_C ++--->BN_S_MP_SUB_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C + + +BN_MP_INIT_SET_C ++--->BN_MP_INIT_C ++--->BN_MP_SET_C +| +--->BN_MP_ZERO_C + + +BN_MP_REDUCE_2K_C ++--->BN_MP_INIT_C ++--->BN_MP_COUNT_BITS_C ++--->BN_MP_DIV_2D_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_ZERO_C +| +--->BN_MP_MOD_2D_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLEAR_C +| +--->BN_MP_RSHD_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C ++--->BN_MP_MUL_D_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_S_MP_ADD_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_CMP_MAG_C ++--->BN_S_MP_SUB_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_CLEAR_C + + +BN_ERROR_C + + +BN_MP_EXPT_D_C ++--->BN_MP_INIT_COPY_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C ++--->BN_MP_SET_C +| +--->BN_MP_ZERO_C ++--->BN_MP_SQR_C +| +--->BN_MP_TOOM_SQR_C +| | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_RSHD_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_MUL_2_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_3_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_CLEAR_C +| +--->BN_MP_KARATSUBA_SQR_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | +--->BN_MP_ADD_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_C +| +--->BN_FAST_S_MP_SQR_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_S_MP_SQR_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C ++--->BN_MP_CLEAR_C ++--->BN_MP_MUL_C +| +--->BN_MP_TOOM_MUL_C +| | +--->BN_MP_INIT_MULTI_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_RSHD_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_MUL_2_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_3_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_MULTI_C +| +--->BN_MP_KARATSUBA_MUL_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| +--->BN_FAST_S_MP_MUL_DIGS_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_S_MP_MUL_DIGS_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C + + +BN_S_MP_EXPTMOD_C ++--->BN_MP_COUNT_BITS_C ++--->BN_MP_INIT_C ++--->BN_MP_CLEAR_C ++--->BN_MP_REDUCE_SETUP_C +| +--->BN_MP_2EXPT_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_DIV_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_INIT_MULTI_C +| | +--->BN_MP_SET_C +| | +--->BN_MP_ABS_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2D_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_MULTI_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_INIT_COPY_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_REDUCE_C +| +--->BN_MP_INIT_COPY_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| +--->BN_MP_RSHD_C +| | +--->BN_MP_ZERO_C +| +--->BN_MP_MUL_C +| | +--->BN_MP_TOOM_MUL_C +| | | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_MUL_2_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_2_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MUL_2D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MUL_D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_3_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLEAR_MULTI_C +| | +--->BN_MP_KARATSUBA_MUL_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_MUL_DIGS_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| +--->BN_S_MP_MUL_HIGH_DIGS_C +| | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_MOD_2D_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_S_MP_MUL_DIGS_C +| | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_SUB_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_D_C +| +--->BN_MP_SET_C +| | +--->BN_MP_ZERO_C +| +--->BN_MP_LSHD_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_ADD_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_C +| | +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_REDUCE_2K_SETUP_L_C +| +--->BN_MP_2EXPT_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_GROW_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_REDUCE_2K_L_C +| +--->BN_MP_DIV_2D_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_MUL_C +| | +--->BN_MP_TOOM_MUL_C +| | | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_MUL_2_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_2_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MUL_2D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MUL_D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_3_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLEAR_MULTI_C +| | +--->BN_MP_KARATSUBA_MUL_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_MUL_DIGS_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_MOD_C +| +--->BN_MP_DIV_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_INIT_MULTI_C +| | +--->BN_MP_SET_C +| | +--->BN_MP_ABS_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2D_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_MULTI_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_INIT_COPY_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_ADD_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C ++--->BN_MP_COPY_C +| +--->BN_MP_GROW_C ++--->BN_MP_SQR_C +| +--->BN_MP_TOOM_SQR_C +| | +--->BN_MP_INIT_MULTI_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_RSHD_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_MUL_2_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_3_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_MULTI_C +| +--->BN_MP_KARATSUBA_SQR_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | +--->BN_MP_ADD_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| +--->BN_FAST_S_MP_SQR_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_S_MP_SQR_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C ++--->BN_MP_MUL_C +| +--->BN_MP_TOOM_MUL_C +| | +--->BN_MP_INIT_MULTI_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_RSHD_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_MUL_2_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_3_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_MULTI_C +| +--->BN_MP_KARATSUBA_MUL_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| +--->BN_FAST_S_MP_MUL_DIGS_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_S_MP_MUL_DIGS_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C ++--->BN_MP_SET_C +| +--->BN_MP_ZERO_C ++--->BN_MP_EXCH_C + + +BN_MP_ABS_C ++--->BN_MP_COPY_C +| +--->BN_MP_GROW_C + + +BN_MP_INIT_SET_INT_C ++--->BN_MP_INIT_C ++--->BN_MP_SET_INT_C +| +--->BN_MP_ZERO_C +| +--->BN_MP_MUL_2D_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLAMP_C + + +BN_MP_SUB_D_C ++--->BN_MP_GROW_C ++--->BN_MP_ADD_D_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_CLAMP_C + + +BN_MP_TO_SIGNED_BIN_C ++--->BN_MP_TO_UNSIGNED_BIN_C +| +--->BN_MP_INIT_COPY_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| +--->BN_MP_DIV_2D_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLEAR_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_C + + +BN_MP_DIV_2_C ++--->BN_MP_GROW_C ++--->BN_MP_CLAMP_C + + +BN_MP_REDUCE_IS_2K_C ++--->BN_MP_REDUCE_2K_C +| +--->BN_MP_INIT_C +| +--->BN_MP_COUNT_BITS_C +| +--->BN_MP_DIV_2D_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLEAR_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_MUL_D_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_COUNT_BITS_C + + +BN_MP_INIT_SIZE_C ++--->BN_MP_INIT_C + + +BN_MP_DIV_C ++--->BN_MP_CMP_MAG_C ++--->BN_MP_COPY_C +| +--->BN_MP_GROW_C ++--->BN_MP_ZERO_C ++--->BN_MP_INIT_MULTI_C +| +--->BN_MP_INIT_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_SET_C ++--->BN_MP_COUNT_BITS_C ++--->BN_MP_ABS_C ++--->BN_MP_MUL_2D_C +| +--->BN_MP_GROW_C +| +--->BN_MP_LSHD_C +| | +--->BN_MP_RSHD_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_CMP_C ++--->BN_MP_SUB_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_ADD_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_DIV_2D_C +| +--->BN_MP_INIT_C +| +--->BN_MP_MOD_2D_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLEAR_C +| +--->BN_MP_RSHD_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C ++--->BN_MP_EXCH_C ++--->BN_MP_CLEAR_MULTI_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_INIT_SIZE_C +| +--->BN_MP_INIT_C ++--->BN_MP_INIT_C ++--->BN_MP_INIT_COPY_C ++--->BN_MP_LSHD_C +| +--->BN_MP_GROW_C +| +--->BN_MP_RSHD_C ++--->BN_MP_RSHD_C ++--->BN_MP_MUL_D_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_CLAMP_C ++--->BN_MP_CLEAR_C + + +BN_MP_CLEAR_C + + +BN_MP_MONTGOMERY_REDUCE_C ++--->BN_FAST_MP_MONTGOMERY_REDUCE_C +| +--->BN_MP_GROW_C +| +--->BN_MP_RSHD_C +| | +--->BN_MP_ZERO_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C ++--->BN_MP_GROW_C ++--->BN_MP_CLAMP_C ++--->BN_MP_RSHD_C +| +--->BN_MP_ZERO_C ++--->BN_MP_CMP_MAG_C ++--->BN_S_MP_SUB_C + + +BN_MP_MUL_2_C ++--->BN_MP_GROW_C + + +BN_MP_UNSIGNED_BIN_SIZE_C ++--->BN_MP_COUNT_BITS_C + + +BN_MP_ADDMOD_C ++--->BN_MP_INIT_C ++--->BN_MP_ADD_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_CLEAR_C ++--->BN_MP_MOD_C +| +--->BN_MP_DIV_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_INIT_MULTI_C +| | +--->BN_MP_SET_C +| | +--->BN_MP_COUNT_BITS_C +| | +--->BN_MP_ABS_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2D_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_MULTI_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_INIT_COPY_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C + + +BN_MP_ADD_C ++--->BN_S_MP_ADD_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_CMP_MAG_C ++--->BN_S_MP_SUB_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C + + +BN_MP_TO_SIGNED_BIN_N_C ++--->BN_MP_SIGNED_BIN_SIZE_C +| +--->BN_MP_UNSIGNED_BIN_SIZE_C +| | +--->BN_MP_COUNT_BITS_C ++--->BN_MP_TO_SIGNED_BIN_C +| +--->BN_MP_TO_UNSIGNED_BIN_C +| | +--->BN_MP_INIT_COPY_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_DIV_2D_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C + + +BN_MP_REDUCE_IS_2K_L_C + + +BN_MP_RAND_C ++--->BN_MP_ZERO_C ++--->BN_MP_ADD_D_C +| +--->BN_MP_GROW_C +| +--->BN_MP_SUB_D_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_LSHD_C +| +--->BN_MP_GROW_C +| +--->BN_MP_RSHD_C + + +BN_MP_CNT_LSB_C + + +BN_MP_2EXPT_C ++--->BN_MP_ZERO_C ++--->BN_MP_GROW_C + + +BN_MP_RSHD_C ++--->BN_MP_ZERO_C + + +BN_MP_SHRINK_C + + +BN_MP_TO_UNSIGNED_BIN_N_C ++--->BN_MP_UNSIGNED_BIN_SIZE_C +| +--->BN_MP_COUNT_BITS_C ++--->BN_MP_TO_UNSIGNED_BIN_C +| +--->BN_MP_INIT_COPY_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| +--->BN_MP_DIV_2D_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLEAR_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_C + + +BN_MP_REDUCE_C ++--->BN_MP_REDUCE_SETUP_C +| +--->BN_MP_2EXPT_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_DIV_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_INIT_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_SET_C +| | +--->BN_MP_COUNT_BITS_C +| | +--->BN_MP_ABS_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2D_C +| | | +--->BN_MP_INIT_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_C +| | +--->BN_MP_INIT_C +| | +--->BN_MP_INIT_COPY_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLEAR_C ++--->BN_MP_INIT_COPY_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C ++--->BN_MP_RSHD_C +| +--->BN_MP_ZERO_C ++--->BN_MP_MUL_C +| +--->BN_MP_TOOM_MUL_C +| | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_MUL_2_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_3_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_CLEAR_C +| +--->BN_MP_KARATSUBA_MUL_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_C +| +--->BN_FAST_S_MP_MUL_DIGS_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_S_MP_MUL_DIGS_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C ++--->BN_S_MP_MUL_HIGH_DIGS_C +| +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_INIT_SIZE_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_C ++--->BN_FAST_S_MP_MUL_HIGH_DIGS_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_MOD_2D_C +| +--->BN_MP_ZERO_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_S_MP_MUL_DIGS_C +| +--->BN_FAST_S_MP_MUL_DIGS_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_INIT_SIZE_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_SUB_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_CMP_D_C ++--->BN_MP_SET_C +| +--->BN_MP_ZERO_C ++--->BN_MP_LSHD_C +| +--->BN_MP_GROW_C ++--->BN_MP_ADD_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_CMP_C +| +--->BN_MP_CMP_MAG_C ++--->BN_S_MP_SUB_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_CLEAR_C + + +BN_MP_MUL_2D_C ++--->BN_MP_COPY_C +| +--->BN_MP_GROW_C ++--->BN_MP_GROW_C ++--->BN_MP_LSHD_C +| +--->BN_MP_RSHD_C +| | +--->BN_MP_ZERO_C ++--->BN_MP_CLAMP_C + + +BN_MP_GET_INT_C + + +BN_MP_JACOBI_C ++--->BN_MP_CMP_D_C ++--->BN_MP_INIT_COPY_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C ++--->BN_MP_CNT_LSB_C ++--->BN_MP_DIV_2D_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_ZERO_C +| +--->BN_MP_MOD_2D_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLEAR_C +| +--->BN_MP_RSHD_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C ++--->BN_MP_MOD_C +| +--->BN_MP_DIV_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_SET_C +| | +--->BN_MP_COUNT_BITS_C +| | +--->BN_MP_ABS_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_CLEAR_C +| +--->BN_MP_ADD_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C ++--->BN_MP_CLEAR_C + + +BN_MP_CLEAR_MULTI_C ++--->BN_MP_CLEAR_C + + +BN_MP_MUL_C ++--->BN_MP_TOOM_MUL_C +| +--->BN_MP_INIT_MULTI_C +| | +--->BN_MP_INIT_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_MOD_2D_C +| | +--->BN_MP_ZERO_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_RSHD_C +| | +--->BN_MP_ZERO_C +| +--->BN_MP_MUL_2_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_ADD_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_SUB_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_DIV_2_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_MUL_2D_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_MUL_D_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_DIV_3_C +| | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_LSHD_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_CLEAR_MULTI_C +| | +--->BN_MP_CLEAR_C ++--->BN_MP_KARATSUBA_MUL_C +| +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_INIT_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_SUB_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| +--->BN_MP_ADD_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CMP_MAG_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| +--->BN_MP_LSHD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_RSHD_C +| | | +--->BN_MP_ZERO_C +| +--->BN_MP_CLEAR_C ++--->BN_FAST_S_MP_MUL_DIGS_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_S_MP_MUL_DIGS_C +| +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_INIT_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_C + + +BN_MP_EXTEUCLID_C ++--->BN_MP_INIT_MULTI_C +| +--->BN_MP_INIT_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_SET_C +| +--->BN_MP_ZERO_C ++--->BN_MP_COPY_C +| +--->BN_MP_GROW_C ++--->BN_MP_DIV_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_MP_ZERO_C +| +--->BN_MP_COUNT_BITS_C +| +--->BN_MP_ABS_C +| +--->BN_MP_MUL_2D_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_C +| +--->BN_MP_SUB_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_ADD_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_DIV_2D_C +| | +--->BN_MP_INIT_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLEAR_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_MULTI_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_INIT_C +| +--->BN_MP_INIT_C +| +--->BN_MP_INIT_COPY_C +| +--->BN_MP_LSHD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_RSHD_C +| +--->BN_MP_RSHD_C +| +--->BN_MP_MUL_D_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_CLEAR_C ++--->BN_MP_MUL_C +| +--->BN_MP_TOOM_MUL_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_RSHD_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_MUL_2_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_3_C +| | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_INIT_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_CLEAR_C +| +--->BN_MP_KARATSUBA_MUL_C +| | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | +--->BN_MP_CLEAR_C +| +--->BN_FAST_S_MP_MUL_DIGS_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_S_MP_MUL_DIGS_C +| | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C ++--->BN_MP_SUB_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C ++--->BN_MP_NEG_C ++--->BN_MP_EXCH_C ++--->BN_MP_CLEAR_MULTI_C +| +--->BN_MP_CLEAR_C + + +BN_MP_DR_REDUCE_C ++--->BN_MP_GROW_C ++--->BN_MP_CLAMP_C ++--->BN_MP_CMP_MAG_C ++--->BN_S_MP_SUB_C + + +BN_MP_FREAD_C ++--->BN_MP_ZERO_C ++--->BN_MP_MUL_D_C +| +--->BN_MP_GROW_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_ADD_D_C +| +--->BN_MP_GROW_C +| +--->BN_MP_SUB_D_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_CMP_D_C + + +BN_MP_REDUCE_SETUP_C ++--->BN_MP_2EXPT_C +| +--->BN_MP_ZERO_C +| +--->BN_MP_GROW_C ++--->BN_MP_DIV_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_ZERO_C +| +--->BN_MP_INIT_MULTI_C +| | +--->BN_MP_INIT_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_SET_C +| +--->BN_MP_COUNT_BITS_C +| +--->BN_MP_ABS_C +| +--->BN_MP_MUL_2D_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CMP_C +| +--->BN_MP_SUB_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_ADD_C +| | +--->BN_S_MP_ADD_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_SUB_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| +--->BN_MP_DIV_2D_C +| | +--->BN_MP_INIT_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_CLEAR_C +| | +--->BN_MP_RSHD_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_EXCH_C +| +--->BN_MP_CLEAR_MULTI_C +| | +--->BN_MP_CLEAR_C +| +--->BN_MP_INIT_SIZE_C +| | +--->BN_MP_INIT_C +| +--->BN_MP_INIT_C +| +--->BN_MP_INIT_COPY_C +| +--->BN_MP_LSHD_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_RSHD_C +| +--->BN_MP_RSHD_C +| +--->BN_MP_MUL_D_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_CLEAR_C + + +BN_MP_MONTGOMERY_SETUP_C + + +BN_MP_KARATSUBA_MUL_C ++--->BN_MP_MUL_C +| +--->BN_MP_TOOM_MUL_C +| | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_INIT_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_MOD_2D_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_RSHD_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_MUL_2_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_SUB_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_2_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_2D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MUL_D_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_DIV_3_C +| | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_INIT_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_LSHD_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_CLEAR_C +| +--->BN_FAST_S_MP_MUL_DIGS_C +| | +--->BN_MP_GROW_C +| | +--->BN_MP_CLAMP_C +| +--->BN_S_MP_MUL_DIGS_C +| | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_INIT_C +| | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C +| | +--->BN_MP_CLEAR_C ++--->BN_MP_INIT_SIZE_C +| +--->BN_MP_INIT_C ++--->BN_MP_CLAMP_C ++--->BN_MP_SUB_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C ++--->BN_MP_ADD_C +| +--->BN_S_MP_ADD_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_CMP_MAG_C +| +--->BN_S_MP_SUB_C +| | +--->BN_MP_GROW_C ++--->BN_MP_LSHD_C +| +--->BN_MP_GROW_C +| +--->BN_MP_RSHD_C +| | +--->BN_MP_ZERO_C ++--->BN_MP_CLEAR_C + + +BN_MP_LSHD_C ++--->BN_MP_GROW_C ++--->BN_MP_RSHD_C +| +--->BN_MP_ZERO_C + + +BN_MP_PRIME_MILLER_RABIN_C ++--->BN_MP_CMP_D_C ++--->BN_MP_INIT_COPY_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C ++--->BN_MP_SUB_D_C +| +--->BN_MP_GROW_C +| +--->BN_MP_ADD_D_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLAMP_C ++--->BN_MP_CNT_LSB_C ++--->BN_MP_DIV_2D_C +| +--->BN_MP_COPY_C +| | +--->BN_MP_GROW_C +| +--->BN_MP_ZERO_C +| +--->BN_MP_MOD_2D_C +| | +--->BN_MP_CLAMP_C +| +--->BN_MP_CLEAR_C +| +--->BN_MP_RSHD_C +| +--->BN_MP_CLAMP_C +| +--->BN_MP_EXCH_C ++--->BN_MP_EXPTMOD_C +| +--->BN_MP_INVMOD_C +| | +--->BN_FAST_MP_INVMOD_C +| | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_MOD_C +| | | | +--->BN_MP_DIV_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_SET_C +| | | | | +--->BN_MP_COUNT_BITS_C +| | | | | +--->BN_MP_ABS_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | | +--->BN_MP_CLEAR_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_SET_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_DIV_2_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_MULTI_C +| | | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_INVMOD_SLOW_C +| | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_MOD_C +| | | | +--->BN_MP_DIV_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_SET_C +| | | | | +--->BN_MP_COUNT_BITS_C +| | | | | +--->BN_MP_ABS_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_CLEAR_MULTI_C +| | | | | | +--->BN_MP_CLEAR_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_CLEAR_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_SET_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_DIV_2_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_MULTI_C +| | | | +--->BN_MP_CLEAR_C +| +--->BN_MP_CLEAR_C +| +--->BN_MP_ABS_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| +--->BN_MP_CLEAR_MULTI_C +| +--->BN_MP_REDUCE_IS_2K_L_C +| +--->BN_S_MP_EXPTMOD_C +| | +--->BN_MP_COUNT_BITS_C +| | +--->BN_MP_REDUCE_SETUP_C +| | | +--->BN_MP_2EXPT_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_DIV_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_SET_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_REDUCE_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_MUL_C +| | | | +--->BN_MP_TOOM_MUL_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_COPY_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_MUL_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_3_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_KARATSUBA_MUL_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | +--->BN_S_MP_MUL_HIGH_DIGS_C +| | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_MUL_DIGS_C +| | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SET_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_REDUCE_2K_SETUP_L_C +| | | +--->BN_MP_2EXPT_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_REDUCE_2K_L_C +| | | +--->BN_MP_MUL_C +| | | | +--->BN_MP_TOOM_MUL_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_COPY_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_MUL_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_3_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_KARATSUBA_MUL_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MOD_C +| | | +--->BN_MP_DIV_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_SET_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_SQR_C +| | | +--->BN_MP_TOOM_SQR_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_MUL_2_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_2_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_3_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_KARATSUBA_SQR_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | +--->BN_FAST_S_MP_SQR_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SQR_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | +--->BN_MP_MUL_C +| | | +--->BN_MP_TOOM_MUL_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_MUL_2_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_2_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_3_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_KARATSUBA_MUL_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_MUL_DIGS_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | +--->BN_MP_SET_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_EXCH_C +| +--->BN_MP_DR_IS_MODULUS_C +| +--->BN_MP_REDUCE_IS_2K_C +| | +--->BN_MP_REDUCE_2K_C +| | | +--->BN_MP_COUNT_BITS_C +| | | +--->BN_MP_MUL_D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_COUNT_BITS_C +| +--->BN_MP_EXPTMOD_FAST_C +| | +--->BN_MP_COUNT_BITS_C +| | +--->BN_MP_MONTGOMERY_SETUP_C +| | +--->BN_FAST_MP_MONTGOMERY_REDUCE_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | +--->BN_MP_MONTGOMERY_REDUCE_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | +--->BN_MP_DR_SETUP_C +| | +--->BN_MP_DR_REDUCE_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | +--->BN_MP_REDUCE_2K_SETUP_C +| | | +--->BN_MP_2EXPT_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_REDUCE_2K_C +| | | +--->BN_MP_MUL_D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C +| | | +--->BN_MP_2EXPT_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_SET_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_MUL_2_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_MULMOD_C +| | | +--->BN_MP_MUL_C +| | | | +--->BN_MP_TOOM_MUL_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_MOD_2D_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | | +--->BN_MP_COPY_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_MUL_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_2_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_DIV_3_C +| | | | | | +--->BN_MP_INIT_SIZE_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_KARATSUBA_MUL_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CMP_MAG_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_MUL_DIGS_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_MOD_C +| | | | +--->BN_MP_DIV_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_MP_COPY_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_INIT_MULTI_C +| | | | | +--->BN_MP_SET_C +| | | | | +--->BN_MP_MUL_2D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_LSHD_C +| | | | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_C +| | | | | +--->BN_MP_SUB_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_ADD_C +| | | | | | +--->BN_S_MP_ADD_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | | +--->BN_S_MP_SUB_C +| | | | | | | +--->BN_MP_GROW_C +| | | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_MUL_D_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | +--->BN_MP_SET_C +| | | +--->BN_MP_ZERO_C +| | +--->BN_MP_MOD_C +| | | +--->BN_MP_DIV_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | +--->BN_MP_COPY_C +| | | +--->BN_MP_GROW_C +| | +--->BN_MP_SQR_C +| | | +--->BN_MP_TOOM_SQR_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_MUL_2_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_2_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_3_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_KARATSUBA_SQR_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | +--->BN_FAST_S_MP_SQR_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_SQR_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | +--->BN_MP_MUL_C +| | | +--->BN_MP_TOOM_MUL_C +| | | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_MOD_2D_C +| | | | | +--->BN_MP_ZERO_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_MUL_2_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_2_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_2D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_MUL_D_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_DIV_3_C +| | | | | +--->BN_MP_INIT_SIZE_C +| | | | | +--->BN_MP_CLAMP_C +| | | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_KARATSUBA_MUL_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_SUB_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_ADD_C +| | | | | +--->BN_S_MP_ADD_C +| | | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CMP_MAG_C +| | | | | +--->BN_S_MP_SUB_C +| | | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_RSHD_C +| | | | | | +--->BN_MP_ZERO_C +| | | +--->BN_FAST_S_MP_MUL_DIGS_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_S_MP_MUL_DIGS_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | +--->BN_MP_EXCH_C ++--->BN_MP_CMP_C +| +--->BN_MP_CMP_MAG_C ++--->BN_MP_SQRMOD_C +| +--->BN_MP_SQR_C +| | +--->BN_MP_TOOM_SQR_C +| | | +--->BN_MP_INIT_MULTI_C +| | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_MOD_2D_C +| | | | +--->BN_MP_ZERO_C +| | | | +--->BN_MP_COPY_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_MUL_2_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_2_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MUL_2D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_MUL_D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_DIV_3_C +| | | | +--->BN_MP_INIT_SIZE_C +| | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_MP_EXCH_C +| | | | +--->BN_MP_CLEAR_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLEAR_MULTI_C +| | | | +--->BN_MP_CLEAR_C +| | +--->BN_MP_KARATSUBA_SQR_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_MP_CMP_MAG_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLEAR_C +| | +--->BN_FAST_S_MP_SQR_C +| | | +--->BN_MP_GROW_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_S_MP_SQR_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_C +| +--->BN_MP_CLEAR_C +| +--->BN_MP_MOD_C +| | +--->BN_MP_DIV_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_MP_COPY_C +| | | | +--->BN_MP_GROW_C +| | | +--->BN_MP_ZERO_C +| | | +--->BN_MP_INIT_MULTI_C +| | | +--->BN_MP_SET_C +| | | +--->BN_MP_COUNT_BITS_C +| | | +--->BN_MP_ABS_C +| | | +--->BN_MP_MUL_2D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_LSHD_C +| | | | | +--->BN_MP_RSHD_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_SUB_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_ADD_C +| | | | +--->BN_S_MP_ADD_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | | +--->BN_S_MP_SUB_C +| | | | | +--->BN_MP_GROW_C +| | | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_EXCH_C +| | | +--->BN_MP_CLEAR_MULTI_C +| | | +--->BN_MP_INIT_SIZE_C +| | | +--->BN_MP_LSHD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_RSHD_C +| | | +--->BN_MP_MUL_D_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_ADD_C +| | | +--->BN_S_MP_ADD_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | | +--->BN_MP_CMP_MAG_C +| | | +--->BN_S_MP_SUB_C +| | | | +--->BN_MP_GROW_C +| | | | +--->BN_MP_CLAMP_C +| | +--->BN_MP_EXCH_C ++--->BN_MP_CLEAR_C + + +BN_MP_DR_SETUP_C + + +BN_MP_CMP_MAG_C + + diff --git a/xmhf-64/xmhf/third-party/libtommath/changes.txt b/xmhf-64/xmhf/third-party/libtommath/changes.txt new file mode 100644 index 0000000000..4fc091353c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/changes.txt @@ -0,0 +1,403 @@ +July 23rd, 2010 +v0.42.0 + -- Fix for mp_prime_next_prime() bug when checking generated prime + -- allow mp_shrink to shrink initialized, but empty MPI's + -- Added project and solution files for Visual Studio 2005 and Visual Studio 2008. + +March 10th, 2007 +v0.41 -- Wolfgang Ehrhardt suggested a quick fix to mp_div_d() which makes the detection of powers of two quicker. + -- [CRI] Added libtommath.dsp for Visual C++ users. + +December 24th, 2006 +v0.40 -- Updated makefile to properly support LIBNAME + -- Fixed bug in fast_s_mp_mul_high_digs() which overflowed (line 83), thanks Valgrind! + +April 4th, 2006 +v0.39 -- Jim Wigginton pointed out my Montgomery examples in figures 6.4 and 6.6 were off by one, k should be 9 not 8 + -- Bruce Guenter suggested I use --tag=CC for libtool builds where the compiler may think it's C++. + -- "mm" from sci.crypt pointed out that my mp_gcd was sub-optimal (I also updated and corrected the book) + -- updated some of the @@ tags in tommath.src to reflect source changes. + -- updated email and url info in all source files + +Jan 26th, 2006 +v0.38 -- broken makefile.shared fixed + -- removed some carry stores that were not required [updated text] + +November 18th, 2005 +v0.37 -- [Don Porter] reported on a TCL list [HEY SEND ME BUGREPORTS ALREADY!!!] that mp_add_d() would compute -0 with some inputs. Fixed. + -- [rinick@gmail.com] reported the makefile.bcc was messed up. Fixed. + -- [Kevin Kenny] reported some issues with mp_toradix_n(). Now it doesn't require a min of 3 chars of output. + -- Made the make command renamable. Wee + +August 1st, 2005 +v0.36 -- LTM_PRIME_2MSB_ON was fixed and the "OFF" flag was removed. + -- [Peter LaDow] found a typo in the XREALLOC macro + -- [Peter LaDow] pointed out that mp_read_(un)signed_bin should have "const" on the input + -- Ported LTC patch to fix the prime_random_ex() function to get the bitsize correct [and the maskOR flags] + -- Kevin Kenny pointed out a stray // + -- David Hulton pointed out a typo in the textbook [mp_montgomery_setup() pseudo-code] + -- Neal Hamilton (Elliptic Semiconductor) pointed out that my Karatsuba notation was backwards and that I could use + unsigned operations in the routine. + -- Paul Schmidt pointed out a linking error in mp_exptmod() when BN_S_MP_EXPTMOD_C is undefined (and another for read_radix) + -- Updated makefiles to be way more flexible + +March 12th, 2005 +v0.35 -- Stupid XOR function missing line again... oops. + -- Fixed bug in invmod not handling negative inputs correctly [Wolfgang Ehrhardt] + -- Made exteuclid always give positive u3 output...[ Wolfgang Ehrhardt ] + -- [Wolfgang Ehrhardt] Suggested a fix for mp_reduce() which avoided underruns. ;-) + -- mp_rand() would emit one too many digits and it was possible to get a 0 out of it ... oops + -- Added montgomery to the testing to make sure it handles 1..10 digit moduli correctly + -- Fixed bug in comba that would lead to possible erroneous outputs when "pa < digs" + -- Fixed bug in mp_toradix_size for "0" [Kevin Kenny] + -- Updated chapters 1-5 of the textbook ;-) It now talks about the new comba code! + +February 12th, 2005 +v0.34 -- Fixed two more small errors in mp_prime_random_ex() + -- Fixed overflow in mp_mul_d() [Kevin Kenny] + -- Added mp_to_(un)signed_bin_n() functions which do bounds checking for ya [and report the size] + -- Added "large" diminished radix support. Speeds up things like DSA where the moduli is of the form 2^k - P for some P < 2^(k/2) or so + Actually is faster than Montgomery on my AMD64 (and probably much faster on a P4) + -- Updated the manual a bit + -- Ok so I haven't done the textbook work yet... My current freelance gig has landed me in France till the + end of Feb/05. Once I get back I'll have tons of free time and I plan to go to town on the book. + As of this release the API will freeze. At least until the book catches up with all the changes. I welcome + bug reports but new algorithms will have to wait. + +December 23rd, 2004 +v0.33 -- Fixed "small" variant for mp_div() which would munge with negative dividends... + -- Fixed bug in mp_prime_random_ex() which would set the most significant byte to zero when + no special flags were set + -- Fixed overflow [minor] bug in fast_s_mp_sqr() + -- Made the makefiles easier to configure the group/user that ltm will install as + -- Fixed "final carry" bug in comba multipliers. (Volkan Ceylan) + -- Matt Johnston pointed out a missing semi-colon in mp_exptmod + +October 29th, 2004 +v0.32 -- Added "makefile.shared" for shared object support + -- Added more to the build options/configs in the manual + -- Started the Depends framework, wrote dep.pl to scan deps and + produce "callgraph.txt" ;-) + -- Wrote SC_RSA_1 which will enable close to the minimum required to perform + RSA on 32-bit [or 64-bit] platforms with LibTomCrypt + -- Merged in the small/slower mp_div replacement. You can now toggle which + you want to use as your mp_div() at build time. Saves roughly 8KB or so. + -- Renamed a few files and changed some comments to make depends system work better. + (No changes to function names) + -- Merged in new Combas that perform 2 reads per inner loop instead of the older + 3reads/2writes per inner loop of the old code. Really though if you want speed + learn to use TomsFastMath ;-) + +August 9th, 2004 +v0.31 -- "profiled" builds now :-) new timings for Intel Northwoods + -- Added "pretty" build target + -- Update mp_init() to actually assign 0's instead of relying on calloc() + -- "Wolfgang Ehrhardt" found a bug in mp_mul() where if + you multiply a negative by zero you get negative zero as the result. Oops. + -- J Harper from PeerSec let me toy with his AMD64 and I got 60-bit digits working properly + [this also means that I fixed a bug where if sizeof(int) < sizeof(mp_digit) it would bug] + +April 11th, 2004 +v0.30 -- Added "mp_toradix_n" which stores upto "n-1" least significant digits of an mp_int + -- Johan Lindh sent a patch so MSVC wouldn't whine about redefining malloc [in weird dll modes] + -- Henrik Goldman spotted a missing OPT_CAST in mp_fwrite() + -- Tuned tommath.h so that when MP_LOW_MEM is defined MP_PREC shall be reduced. + [I also allow MP_PREC to be externally defined now] + -- Sped up mp_cnt_lsb() by using a 4x4 table [e.g. 4x speedup] + -- Added mp_prime_random_ex() which is a more versatile prime generator accurate to + exact bit lengths (unlike the deprecated but still available mp_prime_random() which + is only accurate to byte lengths). See the new LTM_PRIME_* flags ;-) + -- Alex Polushin contributed an optimized mp_sqrt() as well as mp_get_int() and mp_is_square(). + I've cleaned them all up to be a little more consistent [along with one bug fix] for this release. + -- Added mp_init_set and mp_init_set_int to initialize and set small constants with one function + call. + -- Removed /etclib directory [um LibTomPoly deprecates this]. + -- Fixed mp_mod() so the sign of the result agrees with the sign of the modulus. + ++ N.B. My semester is almost up so expect updates to the textbook to be posted to the libtomcrypt.org + website. + +Jan 25th, 2004 +v0.29 ++ Note: "Henrik" from the v0.28 changelog refers to Henrik Goldman ;-) + -- Added fix to mp_shrink to prevent a realloc when used == 0 [e.g. realloc zero bytes???] + -- Made the mp_prime_rabin_miller_trials() function internal table smaller and also + set the minimum number of tests to two (sounds a bit safer). + -- Added a mp_exteuclid() which computes the extended euclidean algorithm. + -- Fixed a memory leak in s_mp_exptmod() [called when Barrett reduction is to be used] which would arise + if a multiplication or subsequent reduction failed [would not free the temp result]. + -- Made an API change to mp_radix_size(). It now returns an error code and stores the required size + through an "int star" passed to it. + +Dec 24th, 2003 +v0.28 -- Henrik Goldman suggested I add casts to the montomgery code [stores into mu...] so compilers wouldn't + spew [erroneous] diagnostics... fixed. + -- Henrik Goldman also spotted two typos. One in mp_radix_size() and another in mp_toradix(). + -- Added fix to mp_shrink() to avoid a memory leak. + -- Added mp_prime_random() which requires a callback to make truly random primes of a given nature + (idea from chat with Niels Ferguson at Crypto'03) + -- Picked up a second wind. I'm filled with Gooo. Mission Gooo! + -- Removed divisions from mp_reduce_is_2k() + -- Sped up mp_div_d() [general case] to use only one division per digit instead of two. + -- Added the heap macros from LTC to LTM. Now you can easily [by editing four lines of tommath.h] + change the name of the heap functions used in LTM [also compatible with LTC via MPI mode] + -- Added bn_prime_rabin_miller_trials() which gives the number of Rabin-Miller trials to achieve + a failure rate of less than 2^-96 + -- fixed bug in fast_mp_invmod(). The initial testing logic was wrong. An invalid input is not when + "a" and "b" are even it's when "b" is even [the algo is for odd moduli only]. + -- Started a new manual [finally]. It is incomplete and will be finished as time goes on. I had to stop + adding full demos around half way in chapter three so I could at least get a good portion of the + manual done. If you really need help using the library you can always email me! + -- My Textbook is now included as part of the package [all Public Domain] + +Sept 19th, 2003 +v0.27 -- Removed changes.txt~ which was made by accident since "kate" decided it was + a good time to re-enable backups... [kde is fun!] + -- In mp_grow() "a->dp" is not overwritten by realloc call [re: memory leak] + Now if mp_grow() fails the mp_int is still valid and can be cleared via + mp_clear() to reclaim the memory. + -- Henrik Goldman found a buffer overflow bug in mp_add_d(). Fixed. + -- Cleaned up mp_mul_d() to be much easier to read and follow. + +Aug 29th, 2003 +v0.26 -- Fixed typo that caused warning with GCC 3.2 + -- Martin Marcel noticed a bug in mp_neg() that allowed negative zeroes. + Also, Martin is the fellow who noted the bugs in mp_gcd() of 0.24/0.25. + -- Martin Marcel noticed an optimization [and slight bug] in mp_lcm(). + -- Added fix to mp_read_unsigned_bin to prevent a buffer overflow. + -- Beefed up the comments in the baseline multipliers [and montgomery] + -- Added "mont" demo to the makefile.msvc in etc/ + -- Optimized sign compares in mp_cmp from 4 to 2 cases. + +Aug 4th, 2003 +v0.25 -- Fix to mp_gcd again... oops (0,-a) == (-a, 0) == a + -- Fix to mp_clear which didn't reset the sign [Greg Rose] + -- Added mp_error_to_string() to convert return codes to strings. [Greg Rose] + -- Optimized fast_mp_invmod() to do the test for invalid inputs [both even] + first so temps don't have to be initialized if it's going to fail. + -- Optimized mp_gcd() by removing mp_div_2d calls for when one of the inputs + is odd. + -- Tons of new comments, some indentation fixups, etc. + -- mp_jacobi() returns MP_VAL if the modulus is less than or equal to zero. + -- fixed two typos in the header of each file :-) + -- LibTomMath is officially Public Domain [see LICENSE] + +July 15th, 2003 +v0.24 -- Optimized mp_add_d and mp_sub_d to not allocate temporary variables + -- Fixed mp_gcd() so the gcd of 0,0 is 0. Allows the gcd operation to be chained + e.g. (0,0,a) == a [instead of 1] + -- Should be one of the last release for a while. Working on LibTomMath book now. + -- optimized the pprime demo [/etc/pprime.c] to first make a huge table of single + digit primes then it reads them randomly instead of randomly choosing/testing single + digit primes. + +July 12th, 2003 +v0.23 -- Optimized mp_prime_next_prime() to not use mp_mod [via is_divisible()] in each + iteration. Instead now a smaller table is kept of the residues which can be updated + without division. + -- Fixed a bug in next_prime() where an input of zero would be treated as odd and + have two added to it [to move to the next odd]. + -- fixed a bug in prime_fermat() and prime_miller_rabin() which allowed the base + to be negative, zero or one. Normally the test is only valid if the base is + greater than one. + -- changed the next_prime() prototype to accept a new parameter "bbs_style" which + will find the next prime congruent to 3 mod 4. The default [bbs_style==0] will + make primes which are either congruent to 1 or 3 mod 4. + -- fixed mp_read_unsigned_bin() so that it doesn't include both code for + the case DIGIT_BIT < 8 and >= 8 + -- optimized div_d() to easy out on division by 1 [or if a == 0] and use + logical shifts if the divisor is a power of two. + -- the default DIGIT_BIT type was not int for non-default builds. Fixed. + +July 2nd, 2003 +v0.22 -- Fixed up mp_invmod so the result is properly in range now [was always congruent to the inverse...] + -- Fixed up s_mp_exptmod and mp_exptmod_fast so the lower half of the pre-computed table isn't allocated + which makes the algorithm use half as much ram. + -- Fixed the install script not to make the book :-) [which isn't included anyways] + -- added mp_cnt_lsb() which counts how many of the lsbs are zero + -- optimized mp_gcd() to use the new mp_cnt_lsb() to replace multiple divisions by two by a single division. + -- applied similar optimization to mp_prime_miller_rabin(). + -- Fixed a bug in both mp_invmod() and fast_mp_invmod() which tested for odd + via "mp_iseven() == 0" which is not valid [since zero is not even either]. + +June 19th, 2003 +v0.21 -- Fixed bug in mp_mul_d which would not handle sign correctly [would not always forward it] + -- Removed the #line lines from gen.pl [was in violation of ISO C] + +June 8th, 2003 +v0.20 -- Removed the book from the package. Added the TDCAL license document. + -- This release is officially pure-bred TDCAL again [last officially TDCAL based release was v0.16] + +June 6th, 2003 +v0.19 -- Fixed a bug in mp_montgomery_reduce() which was introduced when I tweaked mp_rshd() in the previous release. + Essentially the digits were not trimmed before the compare which cause a subtraction to occur all the time. + -- Fixed up etc/tune.c a bit to stop testing new cutoffs after 16 failures [to find more optimal points]. + Brute force ho! + + +May 29th, 2003 +v0.18 -- Fixed a bug in s_mp_sqr which would handle carries properly just not very elegantly. + (e.g. correct result, just bad looking code) + -- Fixed bug in mp_sqr which still had a 512 constant instead of MP_WARRAY + -- Added Toom-Cook multipliers [needs tuning!] + -- Added efficient divide by 3 algorithm mp_div_3 + -- Re-wrote mp_div_d to be faster than calling mp_div + -- Added in a donated BCC makefile and a single page LTM poster (ahalhabsi@sbcglobal.net) + -- Added mp_reduce_2k which reduces an input modulo n = 2**p - k for any single digit k + -- Made the exptmod system be aware of the 2k reduction algorithms. + -- Rewrote mp_dr_reduce to be smaller, simpler and easier to understand. + +May 17th, 2003 +v0.17 -- Benjamin Goldberg submitted optimized mp_add and mp_sub routines. A new gen.pl as well + as several smaller suggestions. Thanks! + -- removed call to mp_cmp in inner loop of mp_div and put mp_cmp_mag in its place :-) + -- Fixed bug in mp_exptmod that would cause it to fail for odd moduli when DIGIT_BIT != 28 + -- mp_exptmod now also returns errors if the modulus is negative and will handle negative exponents + -- mp_prime_is_prime will now return true if the input is one of the primes in the prime table + -- Damian M Gryski (dgryski@uwaterloo.ca) found a index out of bounds error in the + mp_fast_s_mp_mul_high_digs function which didn't come up before. (fixed) + -- Refactored the DR reduction code so there is only one function per file. + -- Fixed bug in the mp_mul() which would erroneously avoid the faster multiplier [comba] when it was + allowed. The bug would not cause the incorrect value to be produced just less efficient (fixed) + -- Fixed similar bug in the Montgomery reduction code. + -- Added tons of (mp_digit) casts so the 7/15/28/31 bit digit code will work flawlessly out of the box. + Also added limited support for 64-bit machines with a 60-bit digit. Both thanks to Tom Wu (tom@arcot.com) + -- Added new comments here and there, cleaned up some code [style stuff] + -- Fixed a lingering typo in mp_exptmod* that would set bitcnt to zero then one. Very silly stuff :-) + -- Fixed up mp_exptmod_fast so it would set "redux" to the comba Montgomery reduction if allowed. This + saves quite a few calls and if statements. + -- Added etc/mont.c a test of the Montgomery reduction [assuming all else works :-| ] + -- Fixed up etc/tune.c to use a wider test range [more appropriate] also added a x86 based addition which + uses RDTSC for high precision timing. + -- Updated demo/demo.c to remove MPI stuff [won't work anyways], made the tests run for 2 seconds each so its + not so insanely slow. Also made the output space delimited [and fixed up various errors] + -- Added logs directory, logs/graph.dem which will use gnuplot to make a series of PNG files + that go with the pre-made index.html. You have to build [via make timing] and run ltmtest first in the + root of the package. + -- Fixed a bug in mp_sub and mp_add where "-a - -a" or "-a + a" would produce -0 as the result [obviously invalid]. + -- Fixed a bug in mp_rshd. If the count == a.used it should zero/return [instead of shifting] + -- Fixed a "off-by-one" bug in mp_mul2d. The initial size check on alloc would be off by one if the residue + shifting caused a carry. + -- Fixed a bug where s_mp_mul_digs() would not call the Comba based routine if allowed. This made Barrett reduction + slower than it had to be. + +Mar 29th, 2003 +v0.16 -- Sped up mp_div by making normalization one shift call + -- Sped up mp_mul_2d/mp_div_2d by aliasing pointers :-) + -- Cleaned up mp_gcd to use the macros for odd/even detection + -- Added comments here and there, mostly there but occasionally here too. + +Mar 22nd, 2003 +v0.15 -- Added series of prime testing routines to lib + -- Fixed up etc/tune.c + -- Added DR reduction algorithm + -- Beefed up the manual more. + -- Fixed up demo/demo.c so it doesn't have so many warnings and it does the full series of + tests + -- Added "pre-gen" directory which will hold a "gen.pl"'ed copy of the entire lib [done at + zipup time so its always the latest] + -- Added conditional casts for C++ users [boo!] + +Mar 15th, 2003 +v0.14 -- Tons of manual updates + -- cleaned up the directory + -- added MSVC makefiles + -- source changes [that I don't recall] + -- Fixed up the lshd/rshd code to use pointer aliasing + -- Fixed up the mul_2d and div_2d to not call rshd/lshd unless needed + -- Fixed up etc/tune.c a tad + -- fixed up demo/demo.c to output comma-delimited results of timing + also fixed up timing demo to use a finer granularity for various functions + -- fixed up demo/demo.c testing to pause during testing so my Duron won't catch on fire + [stays around 31-35C during testing :-)] + +Feb 13th, 2003 +v0.13 -- tons of minor speed-ups in low level add, sub, mul_2 and div_2 which propagate + to other functions like mp_invmod, mp_div, etc... + -- Sped up mp_exptmod_fast by using new code to find R mod m [e.g. B^n mod m] + -- minor fixes + +Jan 17th, 2003 +v0.12 -- re-wrote the majority of the makefile so its more portable and will + install via "make install" on most *nix platforms + -- Re-packaged all the source as seperate files. Means the library a single + file packagage any more. Instead of just adding "bn.c" you have to add + libtommath.a + -- Renamed "bn.h" to "tommath.h" + -- Changes to the manual to reflect all of this + -- Used GNU Indent to clean up the source + +Jan 15th, 2003 +v0.11 -- More subtle fixes + -- Moved to gentoo linux [hurrah!] so made *nix specific fixes to the make process + -- Sped up the montgomery reduction code quite a bit + -- fixed up demo so when building timing for the x86 it assumes ELF format now + +Jan 9th, 2003 +v0.10 -- Pekka Riikonen suggested fixes to the radix conversion code. + -- Added baseline montgomery and comba montgomery reductions, sped up exptmods + [to a point, see bn.h for MONTGOMERY_EXPT_CUTOFF] + +Jan 6th, 2003 +v0.09 -- Updated the manual to reflect recent changes. :-) + -- Added Jacobi function (mp_jacobi) to supplement the number theory side of the lib + -- Added a Mersenne prime finder demo in ./etc/mersenne.c + +Jan 2nd, 2003 +v0.08 -- Sped up the multipliers by moving the inner loop variables into a smaller scope + -- Corrected a bunch of small "warnings" + -- Added more comments + -- Made "mtest" be able to use /dev/random, /dev/urandom or stdin for RNG data + -- Corrected some bugs where error messages were potentially ignored + -- add etc/pprime.c program which makes numbers which are provably prime. + +Jan 1st, 2003 +v0.07 -- Removed alot of heap operations from core functions to speed them up + -- Added a root finding function [and mp_sqrt macro like from MPI] + -- Added more to manual + +Dec 31st, 2002 +v0.06 -- Sped up the s_mp_add, s_mp_sub which inturn sped up mp_invmod, mp_exptmod, etc... + -- Cleaned up the header a bit more + +Dec 30th, 2002 +v0.05 -- Builds with MSVC out of the box + -- Fixed a bug in mp_invmod w.r.t. even moduli + -- Made mp_toradix and mp_read_radix use char instead of unsigned char arrays + -- Fixed up exptmod to use fewer multiplications + -- Fixed up mp_init_size to use only one heap operation + -- Note there is a slight "off-by-one" bug in the library somewhere + without the padding (see the source for comment) the library + crashes in libtomcrypt. Anyways a reasonable workaround is to pad the + numbers which will always correct it since as the numbers grow the padding + will still be beyond the end of the number + -- Added more to the manual + +Dec 29th, 2002 +v0.04 -- Fixed a memory leak in mp_to_unsigned_bin + -- optimized invmod code + -- Fixed bug in mp_div + -- use exchange instead of copy for results + -- added a bit more to the manual + +Dec 27th, 2002 +v0.03 -- Sped up s_mp_mul_high_digs by not computing the carries of the lower digits + -- Fixed a bug where mp_set_int wouldn't zero the value first and set the used member. + -- fixed a bug in s_mp_mul_high_digs where the limit placed on the result digits was not calculated properly + -- fixed bugs in add/sub/mul/sqr_mod functions where if the modulus and dest were the same it wouldn't work + -- fixed a bug in mp_mod and mp_mod_d concerning negative inputs + -- mp_mul_d didn't preserve sign + -- Many many many many fixes + -- Works in LibTomCrypt now :-) + -- Added iterations to the timing demos... more accurate. + -- Tom needs a job. + +Dec 26th, 2002 +v0.02 -- Fixed a few "slips" in the manual. This is "LibTomMath" afterall :-) + -- Added mp_cmp_mag, mp_neg, mp_abs and mp_radix_size that were missing. + -- Sped up the fast [comba] multipliers more [yahoo!] + +Dec 25th,2002 +v0.01 -- Initial release. Gimme a break. + -- Todo list, + add details to manual [e.g. algorithms] + more comments in code + example programs diff --git a/xmhf-64/xmhf/third-party/libtommath/demo/demo.c b/xmhf-64/xmhf/third-party/libtommath/demo/demo.c new file mode 100644 index 0000000000..db77cbcd9a --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/demo/demo.c @@ -0,0 +1,740 @@ +#include + +#ifdef IOWNANATHLON +#include +#define SLEEP sleep(4) +#else +#define SLEEP +#endif + +#include "tommath.h" + +void ndraw(mp_int * a, char *name) +{ + char buf[16000]; + + printf("%s: ", name); + mp_toradix(a, buf, 10); + printf("%s\n", buf); +} + +static void draw(mp_int * a) +{ + ndraw(a, ""); +} + + +unsigned long lfsr = 0xAAAAAAAAUL; + +int lbit(void) +{ + if (lfsr & 0x80000000UL) { + lfsr = ((lfsr << 1) ^ 0x8000001BUL) & 0xFFFFFFFFUL; + return 1; + } else { + lfsr <<= 1; + return 0; + } +} + +int myrng(unsigned char *dst, int len, void *dat) +{ + int x; + + for (x = 0; x < len; x++) + dst[x] = rand() & 0xFF; + return len; +} + + + +char cmd[4096], buf[4096]; +int main(void) +{ + mp_int a, b, c, d, e, f; + unsigned long expt_n, add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n, + gcd_n, lcm_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n, t; + unsigned rr; + int i, n, err, cnt, ix, old_kara_m, old_kara_s; + mp_digit mp; + + + mp_init(&a); + mp_init(&b); + mp_init(&c); + mp_init(&d); + mp_init(&e); + mp_init(&f); + + srand(time(NULL)); + +#if 0 + // test montgomery + printf("Testing montgomery...\n"); + for (i = 1; i < 10; i++) { + printf("Testing digit size: %d\n", i); + for (n = 0; n < 1000; n++) { + mp_rand(&a, i); + a.dp[0] |= 1; + + // let's see if R is right + mp_montgomery_calc_normalization(&b, &a); + mp_montgomery_setup(&a, &mp); + + // now test a random reduction + for (ix = 0; ix < 100; ix++) { + mp_rand(&c, 1 + abs(rand()) % (2*i)); + mp_copy(&c, &d); + mp_copy(&c, &e); + + mp_mod(&d, &a, &d); + mp_montgomery_reduce(&c, &a, mp); + mp_mulmod(&c, &b, &a, &c); + + if (mp_cmp(&c, &d) != MP_EQ) { +printf("d = e mod a, c = e MOD a\n"); +mp_todecimal(&a, buf); printf("a = %s\n", buf); +mp_todecimal(&e, buf); printf("e = %s\n", buf); +mp_todecimal(&d, buf); printf("d = %s\n", buf); +mp_todecimal(&c, buf); printf("c = %s\n", buf); +printf("compare no compare!\n"); exit(EXIT_FAILURE); } + } + } + } + printf("done\n"); + + // test mp_get_int + printf("Testing: mp_get_int\n"); + for (i = 0; i < 1000; ++i) { + t = ((unsigned long) rand() * rand() + 1) & 0xFFFFFFFF; + mp_set_int(&a, t); + if (t != mp_get_int(&a)) { + printf("mp_get_int() bad result!\n"); + return 1; + } + } + mp_set_int(&a, 0); + if (mp_get_int(&a) != 0) { + printf("mp_get_int() bad result!\n"); + return 1; + } + mp_set_int(&a, 0xffffffff); + if (mp_get_int(&a) != 0xffffffff) { + printf("mp_get_int() bad result!\n"); + return 1; + } + // test mp_sqrt + printf("Testing: mp_sqrt\n"); + for (i = 0; i < 1000; ++i) { + printf("%6d\r", i); + fflush(stdout); + n = (rand() & 15) + 1; + mp_rand(&a, n); + if (mp_sqrt(&a, &b) != MP_OKAY) { + printf("mp_sqrt() error!\n"); + return 1; + } + mp_n_root(&a, 2, &a); + if (mp_cmp_mag(&b, &a) != MP_EQ) { + printf("mp_sqrt() bad result!\n"); + return 1; + } + } + + printf("\nTesting: mp_is_square\n"); + for (i = 0; i < 1000; ++i) { + printf("%6d\r", i); + fflush(stdout); + + /* test mp_is_square false negatives */ + n = (rand() & 7) + 1; + mp_rand(&a, n); + mp_sqr(&a, &a); + if (mp_is_square(&a, &n) != MP_OKAY) { + printf("fn:mp_is_square() error!\n"); + return 1; + } + if (n == 0) { + printf("fn:mp_is_square() bad result!\n"); + return 1; + } + + /* test for false positives */ + mp_add_d(&a, 1, &a); + if (mp_is_square(&a, &n) != MP_OKAY) { + printf("fp:mp_is_square() error!\n"); + return 1; + } + if (n == 1) { + printf("fp:mp_is_square() bad result!\n"); + return 1; + } + + } + printf("\n\n"); + + /* test for size */ + for (ix = 10; ix < 128; ix++) { + printf("Testing (not safe-prime): %9d bits \r", ix); + fflush(stdout); + err = + mp_prime_random_ex(&a, 8, ix, + (rand() & 1) ? LTM_PRIME_2MSB_OFF : + LTM_PRIME_2MSB_ON, myrng, NULL); + if (err != MP_OKAY) { + printf("failed with err code %d\n", err); + return EXIT_FAILURE; + } + if (mp_count_bits(&a) != ix) { + printf("Prime is %d not %d bits!!!\n", mp_count_bits(&a), ix); + return EXIT_FAILURE; + } + } + + for (ix = 16; ix < 128; ix++) { + printf("Testing ( safe-prime): %9d bits \r", ix); + fflush(stdout); + err = + mp_prime_random_ex(&a, 8, ix, + ((rand() & 1) ? LTM_PRIME_2MSB_OFF : + LTM_PRIME_2MSB_ON) | LTM_PRIME_SAFE, myrng, + NULL); + if (err != MP_OKAY) { + printf("failed with err code %d\n", err); + return EXIT_FAILURE; + } + if (mp_count_bits(&a) != ix) { + printf("Prime is %d not %d bits!!!\n", mp_count_bits(&a), ix); + return EXIT_FAILURE; + } + /* let's see if it's really a safe prime */ + mp_sub_d(&a, 1, &a); + mp_div_2(&a, &a); + mp_prime_is_prime(&a, 8, &cnt); + if (cnt != MP_YES) { + printf("sub is not prime!\n"); + return EXIT_FAILURE; + } + } + + printf("\n\n"); + + mp_read_radix(&a, "123456", 10); + mp_toradix_n(&a, buf, 10, 3); + printf("a == %s\n", buf); + mp_toradix_n(&a, buf, 10, 4); + printf("a == %s\n", buf); + mp_toradix_n(&a, buf, 10, 30); + printf("a == %s\n", buf); + + +#if 0 + for (;;) { + fgets(buf, sizeof(buf), stdin); + mp_read_radix(&a, buf, 10); + mp_prime_next_prime(&a, 5, 1); + mp_toradix(&a, buf, 10); + printf("%s, %lu\n", buf, a.dp[0] & 3); + } +#endif + + /* test mp_cnt_lsb */ + printf("testing mp_cnt_lsb...\n"); + mp_set(&a, 1); + for (ix = 0; ix < 1024; ix++) { + if (mp_cnt_lsb(&a) != ix) { + printf("Failed at %d, %d\n", ix, mp_cnt_lsb(&a)); + return 0; + } + mp_mul_2(&a, &a); + } + +/* test mp_reduce_2k */ + printf("Testing mp_reduce_2k...\n"); + for (cnt = 3; cnt <= 128; ++cnt) { + mp_digit tmp; + + mp_2expt(&a, cnt); + mp_sub_d(&a, 2, &a); /* a = 2**cnt - 2 */ + + + printf("\nTesting %4d bits", cnt); + printf("(%d)", mp_reduce_is_2k(&a)); + mp_reduce_2k_setup(&a, &tmp); + printf("(%d)", tmp); + for (ix = 0; ix < 1000; ix++) { + if (!(ix & 127)) { + printf("."); + fflush(stdout); + } + mp_rand(&b, (cnt / DIGIT_BIT + 1) * 2); + mp_copy(&c, &b); + mp_mod(&c, &a, &c); + mp_reduce_2k(&b, &a, 2); + if (mp_cmp(&c, &b)) { + printf("FAILED\n"); + exit(0); + } + } + } + +/* test mp_div_3 */ + printf("Testing mp_div_3...\n"); + mp_set(&d, 3); + for (cnt = 0; cnt < 10000;) { + mp_digit r1, r2; + + if (!(++cnt & 127)) + printf("%9d\r", cnt); + mp_rand(&a, abs(rand()) % 128 + 1); + mp_div(&a, &d, &b, &e); + mp_div_3(&a, &c, &r2); + + if (mp_cmp(&b, &c) || mp_cmp_d(&e, r2)) { + printf("\n\nmp_div_3 => Failure\n"); + } + } + printf("\n\nPassed div_3 testing\n"); + +/* test the DR reduction */ + printf("testing mp_dr_reduce...\n"); + for (cnt = 2; cnt < 32; cnt++) { + printf("%d digit modulus\n", cnt); + mp_grow(&a, cnt); + mp_zero(&a); + for (ix = 1; ix < cnt; ix++) { + a.dp[ix] = MP_MASK; + } + a.used = cnt; + a.dp[0] = 3; + + mp_rand(&b, cnt - 1); + mp_copy(&b, &c); + + rr = 0; + do { + if (!(rr & 127)) { + printf("%9lu\r", rr); + fflush(stdout); + } + mp_sqr(&b, &b); + mp_add_d(&b, 1, &b); + mp_copy(&b, &c); + + mp_mod(&b, &a, &b); + mp_dr_reduce(&c, &a, (((mp_digit) 1) << DIGIT_BIT) - a.dp[0]); + + if (mp_cmp(&b, &c) != MP_EQ) { + printf("Failed on trial %lu\n", rr); + exit(-1); + + } + } while (++rr < 500); + printf("Passed DR test for %d digits\n", cnt); + } + +#endif + +/* test the mp_reduce_2k_l code */ +#if 0 +#if 0 +/* first load P with 2^1024 - 0x2A434 B9FDEC95 D8F9D550 FFFFFFFF FFFFFFFF */ + mp_2expt(&a, 1024); + mp_read_radix(&b, "2A434B9FDEC95D8F9D550FFFFFFFFFFFFFFFF", 16); + mp_sub(&a, &b, &a); +#elif 1 +/* p = 2^2048 - 0x1 00000000 00000000 00000000 00000000 4945DDBF 8EA2A91D 5776399B B83E188F */ + mp_2expt(&a, 2048); + mp_read_radix(&b, + "1000000000000000000000000000000004945DDBF8EA2A91D5776399BB83E188F", + 16); + mp_sub(&a, &b, &a); +#endif + + mp_todecimal(&a, buf); + printf("p==%s\n", buf); +/* now mp_reduce_is_2k_l() should return */ + if (mp_reduce_is_2k_l(&a) != 1) { + printf("mp_reduce_is_2k_l() return 0, should be 1\n"); + return EXIT_FAILURE; + } + mp_reduce_2k_setup_l(&a, &d); + /* now do a million square+1 to see if it varies */ + mp_rand(&b, 64); + mp_mod(&b, &a, &b); + mp_copy(&b, &c); + printf("testing mp_reduce_2k_l..."); + fflush(stdout); + for (cnt = 0; cnt < (1UL << 20); cnt++) { + mp_sqr(&b, &b); + mp_add_d(&b, 1, &b); + mp_reduce_2k_l(&b, &a, &d); + mp_sqr(&c, &c); + mp_add_d(&c, 1, &c); + mp_mod(&c, &a, &c); + if (mp_cmp(&b, &c) != MP_EQ) { + printf("mp_reduce_2k_l() failed at step %lu\n", cnt); + mp_tohex(&b, buf); + printf("b == %s\n", buf); + mp_tohex(&c, buf); + printf("c == %s\n", buf); + return EXIT_FAILURE; + } + } + printf("...Passed\n"); +#endif + + div2_n = mul2_n = inv_n = expt_n = lcm_n = gcd_n = add_n = + sub_n = mul_n = div_n = sqr_n = mul2d_n = div2d_n = cnt = add_d_n = + sub_d_n = 0; + + /* force KARA and TOOM to enable despite cutoffs */ + KARATSUBA_SQR_CUTOFF = KARATSUBA_MUL_CUTOFF = 8; + TOOM_SQR_CUTOFF = TOOM_MUL_CUTOFF = 16; + + for (;;) { + /* randomly clear and re-init one variable, this has the affect of triming the alloc space */ + switch (abs(rand()) % 7) { + case 0: + mp_clear(&a); + mp_init(&a); + break; + case 1: + mp_clear(&b); + mp_init(&b); + break; + case 2: + mp_clear(&c); + mp_init(&c); + break; + case 3: + mp_clear(&d); + mp_init(&d); + break; + case 4: + mp_clear(&e); + mp_init(&e); + break; + case 5: + mp_clear(&f); + mp_init(&f); + break; + case 6: + break; /* don't clear any */ + } + + + printf + ("%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu ", + add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n, gcd_n, lcm_n, + expt_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n); + fgets(cmd, 4095, stdin); + cmd[strlen(cmd) - 1] = 0; + printf("%s ]\r", cmd); + fflush(stdout); + if (!strcmp(cmd, "mul2d")) { + ++mul2d_n; + fgets(buf, 4095, stdin); + mp_read_radix(&a, buf, 64); + fgets(buf, 4095, stdin); + sscanf(buf, "%d", &rr); + fgets(buf, 4095, stdin); + mp_read_radix(&b, buf, 64); + + mp_mul_2d(&a, rr, &a); + a.sign = b.sign; + if (mp_cmp(&a, &b) != MP_EQ) { + printf("mul2d failed, rr == %d\n", rr); + draw(&a); + draw(&b); + return 0; + } + } else if (!strcmp(cmd, "div2d")) { + ++div2d_n; + fgets(buf, 4095, stdin); + mp_read_radix(&a, buf, 64); + fgets(buf, 4095, stdin); + sscanf(buf, "%d", &rr); + fgets(buf, 4095, stdin); + mp_read_radix(&b, buf, 64); + + mp_div_2d(&a, rr, &a, &e); + a.sign = b.sign; + if (a.used == b.used && a.used == 0) { + a.sign = b.sign = MP_ZPOS; + } + if (mp_cmp(&a, &b) != MP_EQ) { + printf("div2d failed, rr == %d\n", rr); + draw(&a); + draw(&b); + return 0; + } + } else if (!strcmp(cmd, "add")) { + ++add_n; + fgets(buf, 4095, stdin); + mp_read_radix(&a, buf, 64); + fgets(buf, 4095, stdin); + mp_read_radix(&b, buf, 64); + fgets(buf, 4095, stdin); + mp_read_radix(&c, buf, 64); + mp_copy(&a, &d); + mp_add(&d, &b, &d); + if (mp_cmp(&c, &d) != MP_EQ) { + printf("add %lu failure!\n", add_n); + draw(&a); + draw(&b); + draw(&c); + draw(&d); + return 0; + } + + /* test the sign/unsigned storage functions */ + + rr = mp_signed_bin_size(&c); + mp_to_signed_bin(&c, (unsigned char *) cmd); + memset(cmd + rr, rand() & 255, sizeof(cmd) - rr); + mp_read_signed_bin(&d, (unsigned char *) cmd, rr); + if (mp_cmp(&c, &d) != MP_EQ) { + printf("mp_signed_bin failure!\n"); + draw(&c); + draw(&d); + return 0; + } + + + rr = mp_unsigned_bin_size(&c); + mp_to_unsigned_bin(&c, (unsigned char *) cmd); + memset(cmd + rr, rand() & 255, sizeof(cmd) - rr); + mp_read_unsigned_bin(&d, (unsigned char *) cmd, rr); + if (mp_cmp_mag(&c, &d) != MP_EQ) { + printf("mp_unsigned_bin failure!\n"); + draw(&c); + draw(&d); + return 0; + } + + } else if (!strcmp(cmd, "sub")) { + ++sub_n; + fgets(buf, 4095, stdin); + mp_read_radix(&a, buf, 64); + fgets(buf, 4095, stdin); + mp_read_radix(&b, buf, 64); + fgets(buf, 4095, stdin); + mp_read_radix(&c, buf, 64); + mp_copy(&a, &d); + mp_sub(&d, &b, &d); + if (mp_cmp(&c, &d) != MP_EQ) { + printf("sub %lu failure!\n", sub_n); + draw(&a); + draw(&b); + draw(&c); + draw(&d); + return 0; + } + } else if (!strcmp(cmd, "mul")) { + ++mul_n; + fgets(buf, 4095, stdin); + mp_read_radix(&a, buf, 64); + fgets(buf, 4095, stdin); + mp_read_radix(&b, buf, 64); + fgets(buf, 4095, stdin); + mp_read_radix(&c, buf, 64); + mp_copy(&a, &d); + mp_mul(&d, &b, &d); + if (mp_cmp(&c, &d) != MP_EQ) { + printf("mul %lu failure!\n", mul_n); + draw(&a); + draw(&b); + draw(&c); + draw(&d); + return 0; + } + } else if (!strcmp(cmd, "div")) { + ++div_n; + fgets(buf, 4095, stdin); + mp_read_radix(&a, buf, 64); + fgets(buf, 4095, stdin); + mp_read_radix(&b, buf, 64); + fgets(buf, 4095, stdin); + mp_read_radix(&c, buf, 64); + fgets(buf, 4095, stdin); + mp_read_radix(&d, buf, 64); + + mp_div(&a, &b, &e, &f); + if (mp_cmp(&c, &e) != MP_EQ || mp_cmp(&d, &f) != MP_EQ) { + printf("div %lu %d, %d, failure!\n", div_n, mp_cmp(&c, &e), + mp_cmp(&d, &f)); + draw(&a); + draw(&b); + draw(&c); + draw(&d); + draw(&e); + draw(&f); + return 0; + } + + } else if (!strcmp(cmd, "sqr")) { + ++sqr_n; + fgets(buf, 4095, stdin); + mp_read_radix(&a, buf, 64); + fgets(buf, 4095, stdin); + mp_read_radix(&b, buf, 64); + mp_copy(&a, &c); + mp_sqr(&c, &c); + if (mp_cmp(&b, &c) != MP_EQ) { + printf("sqr %lu failure!\n", sqr_n); + draw(&a); + draw(&b); + draw(&c); + return 0; + } + } else if (!strcmp(cmd, "gcd")) { + ++gcd_n; + fgets(buf, 4095, stdin); + mp_read_radix(&a, buf, 64); + fgets(buf, 4095, stdin); + mp_read_radix(&b, buf, 64); + fgets(buf, 4095, stdin); + mp_read_radix(&c, buf, 64); + mp_copy(&a, &d); + mp_gcd(&d, &b, &d); + d.sign = c.sign; + if (mp_cmp(&c, &d) != MP_EQ) { + printf("gcd %lu failure!\n", gcd_n); + draw(&a); + draw(&b); + draw(&c); + draw(&d); + return 0; + } + } else if (!strcmp(cmd, "lcm")) { + ++lcm_n; + fgets(buf, 4095, stdin); + mp_read_radix(&a, buf, 64); + fgets(buf, 4095, stdin); + mp_read_radix(&b, buf, 64); + fgets(buf, 4095, stdin); + mp_read_radix(&c, buf, 64); + mp_copy(&a, &d); + mp_lcm(&d, &b, &d); + d.sign = c.sign; + if (mp_cmp(&c, &d) != MP_EQ) { + printf("lcm %lu failure!\n", lcm_n); + draw(&a); + draw(&b); + draw(&c); + draw(&d); + return 0; + } + } else if (!strcmp(cmd, "expt")) { + ++expt_n; + fgets(buf, 4095, stdin); + mp_read_radix(&a, buf, 64); + fgets(buf, 4095, stdin); + mp_read_radix(&b, buf, 64); + fgets(buf, 4095, stdin); + mp_read_radix(&c, buf, 64); + fgets(buf, 4095, stdin); + mp_read_radix(&d, buf, 64); + mp_copy(&a, &e); + mp_exptmod(&e, &b, &c, &e); + if (mp_cmp(&d, &e) != MP_EQ) { + printf("expt %lu failure!\n", expt_n); + draw(&a); + draw(&b); + draw(&c); + draw(&d); + draw(&e); + return 0; + } + } else if (!strcmp(cmd, "invmod")) { + ++inv_n; + fgets(buf, 4095, stdin); + mp_read_radix(&a, buf, 64); + fgets(buf, 4095, stdin); + mp_read_radix(&b, buf, 64); + fgets(buf, 4095, stdin); + mp_read_radix(&c, buf, 64); + mp_invmod(&a, &b, &d); + mp_mulmod(&d, &a, &b, &e); + if (mp_cmp_d(&e, 1) != MP_EQ) { + printf("inv [wrong value from MPI?!] failure\n"); + draw(&a); + draw(&b); + draw(&c); + draw(&d); + mp_gcd(&a, &b, &e); + draw(&e); + return 0; + } + + } else if (!strcmp(cmd, "div2")) { + ++div2_n; + fgets(buf, 4095, stdin); + mp_read_radix(&a, buf, 64); + fgets(buf, 4095, stdin); + mp_read_radix(&b, buf, 64); + mp_div_2(&a, &c); + if (mp_cmp(&c, &b) != MP_EQ) { + printf("div_2 %lu failure\n", div2_n); + draw(&a); + draw(&b); + draw(&c); + return 0; + } + } else if (!strcmp(cmd, "mul2")) { + ++mul2_n; + fgets(buf, 4095, stdin); + mp_read_radix(&a, buf, 64); + fgets(buf, 4095, stdin); + mp_read_radix(&b, buf, 64); + mp_mul_2(&a, &c); + if (mp_cmp(&c, &b) != MP_EQ) { + printf("mul_2 %lu failure\n", mul2_n); + draw(&a); + draw(&b); + draw(&c); + return 0; + } + } else if (!strcmp(cmd, "add_d")) { + ++add_d_n; + fgets(buf, 4095, stdin); + mp_read_radix(&a, buf, 64); + fgets(buf, 4095, stdin); + sscanf(buf, "%d", &ix); + fgets(buf, 4095, stdin); + mp_read_radix(&b, buf, 64); + mp_add_d(&a, ix, &c); + if (mp_cmp(&b, &c) != MP_EQ) { + printf("add_d %lu failure\n", add_d_n); + draw(&a); + draw(&b); + draw(&c); + printf("d == %d\n", ix); + return 0; + } + } else if (!strcmp(cmd, "sub_d")) { + ++sub_d_n; + fgets(buf, 4095, stdin); + mp_read_radix(&a, buf, 64); + fgets(buf, 4095, stdin); + sscanf(buf, "%d", &ix); + fgets(buf, 4095, stdin); + mp_read_radix(&b, buf, 64); + mp_sub_d(&a, ix, &c); + if (mp_cmp(&b, &c) != MP_EQ) { + printf("sub_d %lu failure\n", sub_d_n); + draw(&a); + draw(&b); + draw(&c); + printf("d == %d\n", ix); + return 0; + } + } + } + return 0; +} + +/* $Source$ */ +/* $Revision: 0.36 $ */ +/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/demo/timing.c b/xmhf-64/xmhf/third-party/libtommath/demo/timing.c new file mode 100644 index 0000000000..57bb6d41f1 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/demo/timing.c @@ -0,0 +1,319 @@ +#include +#include + +ulong64 _tt; + +#ifdef IOWNANATHLON +#include +#define SLEEP sleep(4) +#else +#define SLEEP +#endif + + +void ndraw(mp_int * a, char *name) +{ + char buf[4096]; + + printf("%s: ", name); + mp_toradix(a, buf, 64); + printf("%s\n", buf); +} + +static void draw(mp_int * a) +{ + ndraw(a, ""); +} + + +unsigned long lfsr = 0xAAAAAAAAUL; + +int lbit(void) +{ + if (lfsr & 0x80000000UL) { + lfsr = ((lfsr << 1) ^ 0x8000001BUL) & 0xFFFFFFFFUL; + return 1; + } else { + lfsr <<= 1; + return 0; + } +} + +/* RDTSC from Scott Duplichan */ +static ulong64 TIMFUNC(void) +{ +#if defined __GNUC__ +#if defined(__i386__) || defined(__x86_64__) + unsigned long long a; + __asm__ __volatile__("rdtsc\nmovl %%eax,%0\nmovl %%edx,4+%0\n":: + "m"(a):"%eax", "%edx"); + return a; +#else /* gcc-IA64 version */ + unsigned long result; + __asm__ __volatile__("mov %0=ar.itc":"=r"(result)::"memory"); + + while (__builtin_expect((int) result == -1, 0)) + __asm__ __volatile__("mov %0=ar.itc":"=r"(result)::"memory"); + + return result; +#endif + + // Microsoft and Intel Windows compilers +#elif defined _M_IX86 + __asm rdtsc +#elif defined _M_AMD64 + return __rdtsc(); +#elif defined _M_IA64 +#if defined __INTEL_COMPILER +#include +#endif + return __getReg(3116); +#else +#error need rdtsc function for this build +#endif +} + +#define DO(x) x; x; +//#define DO4(x) DO2(x); DO2(x); +//#define DO8(x) DO4(x); DO4(x); +//#define DO(x) DO8(x); DO8(x); + +int main(void) +{ + ulong64 tt, gg, CLK_PER_SEC; + FILE *log, *logb, *logc, *logd; + mp_int a, b, c, d, e, f; + int n, cnt, ix, old_kara_m, old_kara_s; + unsigned rr; + + mp_init(&a); + mp_init(&b); + mp_init(&c); + mp_init(&d); + mp_init(&e); + mp_init(&f); + + srand(time(NULL)); + + + /* temp. turn off TOOM */ + TOOM_MUL_CUTOFF = TOOM_SQR_CUTOFF = 100000; + + CLK_PER_SEC = TIMFUNC(); + sleep(1); + CLK_PER_SEC = TIMFUNC() - CLK_PER_SEC; + + printf("CLK_PER_SEC == %llu\n", CLK_PER_SEC); + goto exptmod; + log = fopen("logs/add.log", "w"); + for (cnt = 8; cnt <= 128; cnt += 8) { + SLEEP; + mp_rand(&a, cnt); + mp_rand(&b, cnt); + rr = 0; + tt = -1; + do { + gg = TIMFUNC(); + DO(mp_add(&a, &b, &c)); + gg = (TIMFUNC() - gg) >> 1; + if (tt > gg) + tt = gg; + } while (++rr < 100000); + printf("Adding\t\t%4d-bit => %9llu/sec, %9llu cycles\n", + mp_count_bits(&a), CLK_PER_SEC / tt, tt); + fprintf(log, "%d %9llu\n", cnt * DIGIT_BIT, tt); + fflush(log); + } + fclose(log); + + log = fopen("logs/sub.log", "w"); + for (cnt = 8; cnt <= 128; cnt += 8) { + SLEEP; + mp_rand(&a, cnt); + mp_rand(&b, cnt); + rr = 0; + tt = -1; + do { + gg = TIMFUNC(); + DO(mp_sub(&a, &b, &c)); + gg = (TIMFUNC() - gg) >> 1; + if (tt > gg) + tt = gg; + } while (++rr < 100000); + + printf("Subtracting\t\t%4d-bit => %9llu/sec, %9llu cycles\n", + mp_count_bits(&a), CLK_PER_SEC / tt, tt); + fprintf(log, "%d %9llu\n", cnt * DIGIT_BIT, tt); + fflush(log); + } + fclose(log); + + /* do mult/square twice, first without karatsuba and second with */ + multtest: + old_kara_m = KARATSUBA_MUL_CUTOFF; + old_kara_s = KARATSUBA_SQR_CUTOFF; + for (ix = 0; ix < 2; ix++) { + printf("With%s Karatsuba\n", (ix == 0) ? "out" : ""); + + KARATSUBA_MUL_CUTOFF = (ix == 0) ? 9999 : old_kara_m; + KARATSUBA_SQR_CUTOFF = (ix == 0) ? 9999 : old_kara_s; + + log = fopen((ix == 0) ? "logs/mult.log" : "logs/mult_kara.log", "w"); + for (cnt = 4; cnt <= 10240 / DIGIT_BIT; cnt += 2) { + SLEEP; + mp_rand(&a, cnt); + mp_rand(&b, cnt); + rr = 0; + tt = -1; + do { + gg = TIMFUNC(); + DO(mp_mul(&a, &b, &c)); + gg = (TIMFUNC() - gg) >> 1; + if (tt > gg) + tt = gg; + } while (++rr < 100); + printf("Multiplying\t%4d-bit => %9llu/sec, %9llu cycles\n", + mp_count_bits(&a), CLK_PER_SEC / tt, tt); + fprintf(log, "%d %9llu\n", mp_count_bits(&a), tt); + fflush(log); + } + fclose(log); + + log = fopen((ix == 0) ? "logs/sqr.log" : "logs/sqr_kara.log", "w"); + for (cnt = 4; cnt <= 10240 / DIGIT_BIT; cnt += 2) { + SLEEP; + mp_rand(&a, cnt); + rr = 0; + tt = -1; + do { + gg = TIMFUNC(); + DO(mp_sqr(&a, &b)); + gg = (TIMFUNC() - gg) >> 1; + if (tt > gg) + tt = gg; + } while (++rr < 100); + printf("Squaring\t%4d-bit => %9llu/sec, %9llu cycles\n", + mp_count_bits(&a), CLK_PER_SEC / tt, tt); + fprintf(log, "%d %9llu\n", mp_count_bits(&a), tt); + fflush(log); + } + fclose(log); + + } + exptmod: + + { + char *primes[] = { + /* 2K large moduli */ + "179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586239334100047359817950870678242457666208137217", + "32317006071311007300714876688669951960444102669715484032130345427524655138867890893197201411522913463688717960921898019494119559150490921095088152386448283120630877367300996091750197750389652106796057638384067568276792218642619756161838094338476170470581645852036305042887575891541065808607552399123930385521914333389668342420684974786564569494856176035326322058077805659331026192708460314150258592864177116725943603718461857357598351152301645904403697613233287231227125684710820209725157101726931323469678542580656697935045997268352998638099733077152121140120031150424541696791951097529546801429027668869927491725169", + "1044388881413152506691752710716624382579964249047383780384233483283953907971557456848826811934997558340890106714439262837987573438185793607263236087851365277945956976543709998340361590134383718314428070011855946226376318839397712745672334684344586617496807908705803704071284048740118609114467977783598029006686938976881787785946905630190260940599579453432823469303026696443059025015972399867714215541693835559885291486318237914434496734087811872639496475100189041349008417061675093668333850551032972088269550769983616369411933015213796825837188091833656751221318492846368125550225998300412344784862595674492194617023806505913245610825731835380087608622102834270197698202313169017678006675195485079921636419370285375124784014907159135459982790513399611551794271106831134090584272884279791554849782954323534517065223269061394905987693002122963395687782878948440616007412945674919823050571642377154816321380631045902916136926708342856440730447899971901781465763473223850267253059899795996090799469201774624817718449867455659250178329070473119433165550807568221846571746373296884912819520317457002440926616910874148385078411929804522981857338977648103126085902995208257421855249796721729039744118165938433694823325696642096892124547425283", + /* 2K moduli mersenne primes */ + "6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151", + "531137992816767098689588206552468627329593117727031923199444138200403559860852242739162502265229285668889329486246501015346579337652707239409519978766587351943831270835393219031728127", + "10407932194664399081925240327364085538615262247266704805319112350403608059673360298012239441732324184842421613954281007791383566248323464908139906605677320762924129509389220345773183349661583550472959420547689811211693677147548478866962501384438260291732348885311160828538416585028255604666224831890918801847068222203140521026698435488732958028878050869736186900714720710555703168729087", + "1475979915214180235084898622737381736312066145333169775147771216478570297878078949377407337049389289382748507531496480477281264838760259191814463365330269540496961201113430156902396093989090226259326935025281409614983499388222831448598601834318536230923772641390209490231836446899608210795482963763094236630945410832793769905399982457186322944729636418890623372171723742105636440368218459649632948538696905872650486914434637457507280441823676813517852099348660847172579408422316678097670224011990280170474894487426924742108823536808485072502240519452587542875349976558572670229633962575212637477897785501552646522609988869914013540483809865681250419497686697771007", + "259117086013202627776246767922441530941818887553125427303974923161874019266586362086201209516800483406550695241733194177441689509238807017410377709597512042313066624082916353517952311186154862265604547691127595848775610568757931191017711408826252153849035830401185072116424747461823031471398340229288074545677907941037288235820705892351068433882986888616658650280927692080339605869308790500409503709875902119018371991620994002568935113136548829739112656797303241986517250116412703509705427773477972349821676443446668383119322540099648994051790241624056519054483690809616061625743042361721863339415852426431208737266591962061753535748892894599629195183082621860853400937932839420261866586142503251450773096274235376822938649407127700846077124211823080804139298087057504713825264571448379371125032081826126566649084251699453951887789613650248405739378594599444335231188280123660406262468609212150349937584782292237144339628858485938215738821232393687046160677362909315071", + "190797007524439073807468042969529173669356994749940177394741882673528979787005053706368049835514900244303495954950709725762186311224148828811920216904542206960744666169364221195289538436845390250168663932838805192055137154390912666527533007309292687539092257043362517857366624699975402375462954490293259233303137330643531556539739921926201438606439020075174723029056838272505051571967594608350063404495977660656269020823960825567012344189908927956646011998057988548630107637380993519826582389781888135705408653045219655801758081251164080554609057468028203308718724654081055323215860189611391296030471108443146745671967766308925858547271507311563765171008318248647110097614890313562856541784154881743146033909602737947385055355960331855614540900081456378659068370317267696980001187750995491090350108417050917991562167972281070161305972518044872048331306383715094854938415738549894606070722584737978176686422134354526989443028353644037187375385397838259511833166416134323695660367676897722287918773420968982326089026150031515424165462111337527431154890666327374921446276833564519776797633875503548665093914556482031482248883127023777039667707976559857333357013727342079099064400455741830654320379350833236245819348824064783585692924881021978332974949906122664421376034687815350484991", + + /* DR moduli */ + "14059105607947488696282932836518693308967803494693489478439861164411992439598399594747002144074658928593502845729752797260025831423419686528151609940203368612079", + "101745825697019260773923519755878567461315282017759829107608914364075275235254395622580447400994175578963163918967182013639660669771108475957692810857098847138903161308502419410142185759152435680068435915159402496058513611411688900243039", + "736335108039604595805923406147184530889923370574768772191969612422073040099331944991573923112581267542507986451953227192970402893063850485730703075899286013451337291468249027691733891486704001513279827771740183629161065194874727962517148100775228363421083691764065477590823919364012917984605619526140821797602431", + "38564998830736521417281865696453025806593491967131023221754800625044118265468851210705360385717536794615180260494208076605798671660719333199513807806252394423283413430106003596332513246682903994829528690198205120921557533726473585751382193953592127439965050261476810842071573684505878854588706623484573925925903505747545471088867712185004135201289273405614415899438276535626346098904241020877974002916168099951885406379295536200413493190419727789712076165162175783", + "542189391331696172661670440619180536749994166415993334151601745392193484590296600979602378676624808129613777993466242203025054573692562689251250471628358318743978285860720148446448885701001277560572526947619392551574490839286458454994488665744991822837769918095117129546414124448777033941223565831420390846864429504774477949153794689948747680362212954278693335653935890352619041936727463717926744868338358149568368643403037768649616778526013610493696186055899318268339432671541328195724261329606699831016666359440874843103020666106568222401047720269951530296879490444224546654729111504346660859907296364097126834834235287147", + "1487259134814709264092032648525971038895865645148901180585340454985524155135260217788758027400478312256339496385275012465661575576202252063145698732079880294664220579764848767704076761853197216563262660046602703973050798218246170835962005598561669706844469447435461092542265792444947706769615695252256130901271870341005768912974433684521436211263358097522726462083917939091760026658925757076733484173202927141441492573799914240222628795405623953109131594523623353044898339481494120112723445689647986475279242446083151413667587008191682564376412347964146113898565886683139407005941383669325997475076910488086663256335689181157957571445067490187939553165903773554290260531009121879044170766615232300936675369451260747671432073394867530820527479172464106442450727640226503746586340279816318821395210726268291535648506190714616083163403189943334431056876038286530365757187367147446004855912033137386225053275419626102417236133948503", + "1095121115716677802856811290392395128588168592409109494900178008967955253005183831872715423151551999734857184538199864469605657805519106717529655044054833197687459782636297255219742994736751541815269727940751860670268774903340296040006114013971309257028332849679096824800250742691718610670812374272414086863715763724622797509437062518082383056050144624962776302147890521249477060215148275163688301275847155316042279405557632639366066847442861422164832655874655824221577849928863023018366835675399949740429332468186340518172487073360822220449055340582568461568645259954873303616953776393853174845132081121976327462740354930744487429617202585015510744298530101547706821590188733515880733527449780963163909830077616357506845523215289297624086914545378511082534229620116563260168494523906566709418166011112754529766183554579321224940951177394088465596712620076240067370589036924024728375076210477267488679008016579588696191194060127319035195370137160936882402244399699172017835144537488486396906144217720028992863941288217185353914991583400421682751000603596655790990815525126154394344641336397793791497068253936771017031980867706707490224041075826337383538651825493679503771934836094655802776331664261631740148281763487765852746577808019633679", + + /* generic unrestricted moduli */ + "17933601194860113372237070562165128350027320072176844226673287945873370751245439587792371960615073855669274087805055507977323024886880985062002853331424203", + "2893527720709661239493896562339544088620375736490408468011883030469939904368086092336458298221245707898933583190713188177399401852627749210994595974791782790253946539043962213027074922559572312141181787434278708783207966459019479487", + "347743159439876626079252796797422223177535447388206607607181663903045907591201940478223621722118173270898487582987137708656414344685816179420855160986340457973820182883508387588163122354089264395604796675278966117567294812714812796820596564876450716066283126720010859041484786529056457896367683122960411136319", + "47266428956356393164697365098120418976400602706072312735924071745438532218237979333351774907308168340693326687317443721193266215155735814510792148768576498491199122744351399489453533553203833318691678263241941706256996197460424029012419012634671862283532342656309677173602509498417976091509154360039893165037637034737020327399910409885798185771003505320583967737293415979917317338985837385734747478364242020380416892056650841470869294527543597349250299539682430605173321029026555546832473048600327036845781970289288898317888427517364945316709081173840186150794397479045034008257793436817683392375274635794835245695887", + "436463808505957768574894870394349739623346440601945961161254440072143298152040105676491048248110146278752857839930515766167441407021501229924721335644557342265864606569000117714935185566842453630868849121480179691838399545644365571106757731317371758557990781880691336695584799313313687287468894148823761785582982549586183756806449017542622267874275103877481475534991201849912222670102069951687572917937634467778042874315463238062009202992087620963771759666448266532858079402669920025224220613419441069718482837399612644978839925207109870840278194042158748845445131729137117098529028886770063736487420613144045836803985635654192482395882603511950547826439092832800532152534003936926017612446606135655146445620623395788978726744728503058670046885876251527122350275750995227", + "11424167473351836398078306042624362277956429440521137061889702611766348760692206243140413411077394583180726863277012016602279290144126785129569474909173584789822341986742719230331946072730319555984484911716797058875905400999504305877245849119687509023232790273637466821052576859232452982061831009770786031785669030271542286603956118755585683996118896215213488875253101894663403069677745948305893849505434201763745232895780711972432011344857521691017896316861403206449421332243658855453435784006517202894181640562433575390821384210960117518650374602256601091379644034244332285065935413233557998331562749140202965844219336298970011513882564935538704289446968322281451907487362046511461221329799897350993370560697505809686438782036235372137015731304779072430260986460269894522159103008260495503005267165927542949439526272736586626709581721032189532726389643625590680105784844246152702670169304203783072275089194754889511973916207", + "1214855636816562637502584060163403830270705000634713483015101384881871978446801224798536155406895823305035467591632531067547890948695117172076954220727075688048751022421198712032848890056357845974246560748347918630050853933697792254955890439720297560693579400297062396904306270145886830719309296352765295712183040773146419022875165382778007040109957609739589875590885701126197906063620133954893216612678838507540777138437797705602453719559017633986486649523611975865005712371194067612263330335590526176087004421363598470302731349138773205901447704682181517904064735636518462452242791676541725292378925568296858010151852326316777511935037531017413910506921922450666933202278489024521263798482237150056835746454842662048692127173834433089016107854491097456725016327709663199738238442164843147132789153725513257167915555162094970853584447993125488607696008169807374736711297007473812256272245489405898470297178738029484459690836250560495461579533254473316340608217876781986188705928270735695752830825527963838355419762516246028680280988020401914551825487349990306976304093109384451438813251211051597392127491464898797406789175453067960072008590614886532333015881171367104445044718144312416815712216611576221546455968770801413440778423979", + NULL + }; + log = fopen("logs/expt.log", "w"); + logb = fopen("logs/expt_dr.log", "w"); + logc = fopen("logs/expt_2k.log", "w"); + logd = fopen("logs/expt_2kl.log", "w"); + for (n = 0; primes[n]; n++) { + SLEEP; + mp_read_radix(&a, primes[n], 10); + mp_zero(&b); + for (rr = 0; rr < (unsigned) mp_count_bits(&a); rr++) { + mp_mul_2(&b, &b); + b.dp[0] |= lbit(); + b.used += 1; + } + mp_sub_d(&a, 1, &c); + mp_mod(&b, &c, &b); + mp_set(&c, 3); + rr = 0; + tt = -1; + do { + gg = TIMFUNC(); + DO(mp_exptmod(&c, &b, &a, &d)); + gg = (TIMFUNC() - gg) >> 1; + if (tt > gg) + tt = gg; + } while (++rr < 10); + mp_sub_d(&a, 1, &e); + mp_sub(&e, &b, &b); + mp_exptmod(&c, &b, &a, &e); /* c^(p-1-b) mod a */ + mp_mulmod(&e, &d, &a, &d); /* c^b * c^(p-1-b) == c^p-1 == 1 */ + if (mp_cmp_d(&d, 1)) { + printf("Different (%d)!!!\n", mp_count_bits(&a)); + draw(&d); + exit(0); + } + printf("Exponentiating\t%4d-bit => %9llu/sec, %9llu cycles\n", + mp_count_bits(&a), CLK_PER_SEC / tt, tt); + fprintf(n < 4 ? logd : (n < 9) ? logc : (n < 16) ? logb : log, + "%d %9llu\n", mp_count_bits(&a), tt); + } + } + fclose(log); + fclose(logb); + fclose(logc); + fclose(logd); + + log = fopen("logs/invmod.log", "w"); + for (cnt = 4; cnt <= 128; cnt += 4) { + SLEEP; + mp_rand(&a, cnt); + mp_rand(&b, cnt); + + do { + mp_add_d(&b, 1, &b); + mp_gcd(&a, &b, &c); + } while (mp_cmp_d(&c, 1) != MP_EQ); + + rr = 0; + tt = -1; + do { + gg = TIMFUNC(); + DO(mp_invmod(&b, &a, &c)); + gg = (TIMFUNC() - gg) >> 1; + if (tt > gg) + tt = gg; + } while (++rr < 1000); + mp_mulmod(&b, &c, &a, &d); + if (mp_cmp_d(&d, 1) != MP_EQ) { + printf("Failed to invert\n"); + return 0; + } + printf("Inverting mod\t%4d-bit => %9llu/sec, %9llu cycles\n", + mp_count_bits(&a), CLK_PER_SEC / tt, tt); + fprintf(log, "%d %9llu\n", cnt * DIGIT_BIT, tt); + } + fclose(log); + + return 0; +} + +/* $Source$ */ +/* $Revision: 0.36 $ */ +/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/dep.pl b/xmhf-64/xmhf/third-party/libtommath/dep.pl new file mode 100755 index 0000000000..c39e27ea08 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/dep.pl @@ -0,0 +1,123 @@ +#!/usr/bin/perl +# +# Walk through source, add labels and make classes +# +#use strict; + +my %deplist; + +#open class file and write preamble +open(CLASS, ">tommath_class.h") or die "Couldn't open tommath_class.h for writing\n"; +print CLASS "#if !(defined(LTM1) && defined(LTM2) && defined(LTM3))\n#if defined(LTM2)\n#define LTM3\n#endif\n#if defined(LTM1)\n#define LTM2\n#endif\n#define LTM1\n\n#if defined(LTM_ALL)\n"; + +foreach my $filename (glob "bn*.c") { + my $define = $filename; + +print "Processing $filename\n"; + + # convert filename to upper case so we can use it as a define + $define =~ tr/[a-z]/[A-Z]/; + $define =~ tr/\./_/; + print CLASS "#define $define\n"; + + # now copy text and apply #ifdef as required + my $apply = 0; + open(SRC, "<$filename"); + open(OUT, ">tmp"); + + # first line will be the #ifdef + my $line = ; + if ($line =~ /include/) { + print OUT $line; + } else { + print OUT "#include \n#ifdef $define\n$line"; + $apply = 1; + } + while () { + if (!($_ =~ /tommath\.h/)) { + print OUT $_; + } + } + if ($apply == 1) { + print OUT "#endif\n"; + } + close SRC; + close OUT; + + unlink($filename); + rename("tmp", $filename); +} +print CLASS "#endif\n\n"; + +# now do classes + +foreach my $filename (glob "bn*.c") { + open(SRC, "<$filename") or die "Can't open source file!\n"; + + # convert filename to upper case so we can use it as a define + $filename =~ tr/[a-z]/[A-Z]/; + $filename =~ tr/\./_/; + + print CLASS "#if defined($filename)\n"; + my $list = $filename; + + # scan for mp_* and make classes + while () { + my $line = $_; + while ($line =~ m/(fast_)*(s_)*mp\_[a-z_0-9]*/) { + $line = $'; + # now $& is the match, we want to skip over LTM keywords like + # mp_int, mp_word, mp_digit + if (!($& eq "mp_digit") && !($& eq "mp_word") && !($& eq "mp_int")) { + my $a = $&; + $a =~ tr/[a-z]/[A-Z]/; + $a = "BN_" . $a . "_C"; + if (!($list =~ /$a/)) { + print CLASS " #define $a\n"; + } + $list = $list . "," . $a; + } + } + } + @deplist{$filename} = $list; + + print CLASS "#endif\n\n"; + close SRC; +} + +print CLASS "#ifdef LTM3\n#define LTM_LAST\n#endif\n#include \n#include \n#else\n#define LTM_LAST\n#endif\n"; +close CLASS; + +#now let's make a cool call graph... + +open(OUT,">callgraph.txt"); +$indent = 0; +foreach (keys %deplist) { + $list = ""; + draw_func(@deplist{$_}); + print OUT "\n\n"; +} +close(OUT); + +sub draw_func() +{ + my @funcs = split(",", $_[0]); + if ($list =~ /@funcs[0]/) { + return; + } else { + $list = $list . @funcs[0]; + } + if ($indent == 0) { } + elsif ($indent >= 1) { print OUT "| " x ($indent - 1) . "+--->"; } + print OUT @funcs[0] . "\n"; + shift @funcs; + my $temp = $list; + foreach my $i (@funcs) { + ++$indent; + draw_func(@deplist{$i}); + --$indent; + } + $list = $temp; +} + + diff --git a/xmhf-64/xmhf/third-party/libtommath/etc/2kprime.1 b/xmhf-64/xmhf/third-party/libtommath/etc/2kprime.1 new file mode 100644 index 0000000000..c41ded1f97 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/etc/2kprime.1 @@ -0,0 +1,2 @@ +256-bits (k = 36113) = 115792089237316195423570985008687907853269984665640564039457584007913129603823 +512-bits (k = 38117) = 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006045979 diff --git a/xmhf-64/xmhf/third-party/libtommath/etc/2kprime.c b/xmhf-64/xmhf/third-party/libtommath/etc/2kprime.c new file mode 100644 index 0000000000..fb9ae97c18 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/etc/2kprime.c @@ -0,0 +1,84 @@ +/* Makes safe primes of a 2k nature */ +#include +#include + +int sizes[] = {256, 512, 768, 1024, 1536, 2048, 3072, 4096}; + +int main(void) +{ + char buf[2000]; + int x, y; + mp_int q, p; + FILE *out; + clock_t t1; + mp_digit z; + + mp_init_multi(&q, &p, NULL); + + out = fopen("2kprime.1", "w"); + for (x = 0; x < (int)(sizeof(sizes) / sizeof(sizes[0])); x++) { + top: + mp_2expt(&q, sizes[x]); + mp_add_d(&q, 3, &q); + z = -3; + + t1 = clock(); + for(;;) { + mp_sub_d(&q, 4, &q); + z += 4; + + if (z > MP_MASK) { + printf("No primes of size %d found\n", sizes[x]); + break; + } + + if (clock() - t1 > CLOCKS_PER_SEC) { + printf("."); fflush(stdout); +// sleep((clock() - t1 + CLOCKS_PER_SEC/2)/CLOCKS_PER_SEC); + t1 = clock(); + } + + /* quick test on q */ + mp_prime_is_prime(&q, 1, &y); + if (y == 0) { + continue; + } + + /* find (q-1)/2 */ + mp_sub_d(&q, 1, &p); + mp_div_2(&p, &p); + mp_prime_is_prime(&p, 3, &y); + if (y == 0) { + continue; + } + + /* test on q */ + mp_prime_is_prime(&q, 3, &y); + if (y == 0) { + continue; + } + + break; + } + + if (y == 0) { + ++sizes[x]; + goto top; + } + + mp_toradix(&q, buf, 10); + printf("\n\n%d-bits (k = %lu) = %s\n", sizes[x], z, buf); + fprintf(out, "%d-bits (k = %lu) = %s\n", sizes[x], z, buf); fflush(out); + } + + return 0; +} + + + + + + +/* $Source$ */ +/* $Revision: 0.36 $ */ +/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/etc/drprime.c b/xmhf-64/xmhf/third-party/libtommath/etc/drprime.c new file mode 100644 index 0000000000..a93b8064c6 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/etc/drprime.c @@ -0,0 +1,64 @@ +/* Makes safe primes of a DR nature */ +#include + +int sizes[] = { 1+256/DIGIT_BIT, 1+512/DIGIT_BIT, 1+768/DIGIT_BIT, 1+1024/DIGIT_BIT, 1+2048/DIGIT_BIT, 1+4096/DIGIT_BIT }; +int main(void) +{ + int res, x, y; + char buf[4096]; + FILE *out; + mp_int a, b; + + mp_init(&a); + mp_init(&b); + + out = fopen("drprimes.txt", "w"); + for (x = 0; x < (int)(sizeof(sizes)/sizeof(sizes[0])); x++) { + top: + printf("Seeking a %d-bit safe prime\n", sizes[x] * DIGIT_BIT); + mp_grow(&a, sizes[x]); + mp_zero(&a); + for (y = 1; y < sizes[x]; y++) { + a.dp[y] = MP_MASK; + } + + /* make a DR modulus */ + a.dp[0] = -1; + a.used = sizes[x]; + + /* now loop */ + res = 0; + for (;;) { + a.dp[0] += 4; + if (a.dp[0] >= MP_MASK) break; + mp_prime_is_prime(&a, 1, &res); + if (res == 0) continue; + printf("."); fflush(stdout); + mp_sub_d(&a, 1, &b); + mp_div_2(&b, &b); + mp_prime_is_prime(&b, 3, &res); + if (res == 0) continue; + mp_prime_is_prime(&a, 3, &res); + if (res == 1) break; + } + + if (res != 1) { + printf("Error not DR modulus\n"); sizes[x] += 1; goto top; + } else { + mp_toradix(&a, buf, 10); + printf("\n\np == %s\n\n", buf); + fprintf(out, "%d-bit prime:\np == %s\n\n", mp_count_bits(&a), buf); fflush(out); + } + } + fclose(out); + + mp_clear(&a); + mp_clear(&b); + + return 0; +} + + +/* $Source$ */ +/* $Revision: 0.36 $ */ +/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/etc/drprimes.28 b/xmhf-64/xmhf/third-party/libtommath/etc/drprimes.28 new file mode 100644 index 0000000000..9d438ad1db --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/etc/drprimes.28 @@ -0,0 +1,25 @@ +DR safe primes for 28-bit digits. + +224-bit prime: +p == 26959946667150639794667015087019630673637144422540572481103341844143 + +532-bit prime: +p == 14059105607947488696282932836518693308967803494693489478439861164411992439598399594747002144074658928593502845729752797260025831423419686528151609940203368691747 + +784-bit prime: +p == 101745825697019260773923519755878567461315282017759829107608914364075275235254395622580447400994175578963163918967182013639660669771108475957692810857098847138903161308502419410142185759152435680068435915159402496058513611411688900243039 + +1036-bit prime: +p == 736335108039604595805923406147184530889923370574768772191969612422073040099331944991573923112581267542507986451953227192970402893063850485730703075899286013451337291468249027691733891486704001513279827771740183629161065194874727962517148100775228363421083691764065477590823919364012917984605619526140821798437127 + +1540-bit prime: +p == 38564998830736521417281865696453025806593491967131023221754800625044118265468851210705360385717536794615180260494208076605798671660719333199513807806252394423283413430106003596332513246682903994829528690198205120921557533726473585751382193953592127439965050261476810842071573684505878854588706623484573925925903505747545471088867712185004135201289273405614415899438276535626346098904241020877974002916168099951885406379295536200413493190419727789712076165162175783 + +2072-bit prime: +p == 542189391331696172661670440619180536749994166415993334151601745392193484590296600979602378676624808129613777993466242203025054573692562689251250471628358318743978285860720148446448885701001277560572526947619392551574490839286458454994488665744991822837769918095117129546414124448777033941223565831420390846864429504774477949153794689948747680362212954278693335653935890352619041936727463717926744868338358149568368643403037768649616778526013610493696186055899318268339432671541328195724261329606699831016666359440874843103020666106568222401047720269951530296879490444224546654729111504346660859907296364097126834834235287147 + +3080-bit prime: +p == 1487259134814709264092032648525971038895865645148901180585340454985524155135260217788758027400478312256339496385275012465661575576202252063145698732079880294664220579764848767704076761853197216563262660046602703973050798218246170835962005598561669706844469447435461092542265792444947706769615695252256130901271870341005768912974433684521436211263358097522726462083917939091760026658925757076733484173202927141441492573799914240222628795405623953109131594523623353044898339481494120112723445689647986475279242446083151413667587008191682564376412347964146113898565886683139407005941383669325997475076910488086663256335689181157957571445067490187939553165903773554290260531009121879044170766615232300936675369451260747671432073394867530820527479172464106442450727640226503746586340279816318821395210726268291535648506190714616083163403189943334431056876038286530365757187367147446004855912033137386225053275419626102417236133948503 + +4116-bit prime: +p == 1095121115716677802856811290392395128588168592409109494900178008967955253005183831872715423151551999734857184538199864469605657805519106717529655044054833197687459782636297255219742994736751541815269727940751860670268774903340296040006114013971309257028332849679096824800250742691718610670812374272414086863715763724622797509437062518082383056050144624962776302147890521249477060215148275163688301275847155316042279405557632639366066847442861422164832655874655824221577849928863023018366835675399949740429332468186340518172487073360822220449055340582568461568645259954873303616953776393853174845132081121976327462740354930744487429617202585015510744298530101547706821590188733515880733527449780963163909830077616357506845523215289297624086914545378511082534229620116563260168494523906566709418166011112754529766183554579321224940951177394088465596712620076240067370589036924024728375076210477267488679008016579588696191194060127319035195370137160936882402244399699172017835144537488486396906144217720028992863941288217185353914991583400421682751000603596655790990815525126154394344641336397793791497068253936771017031980867706707490224041075826337383538651825493679503771934836094655802776331664261631740148281763487765852746577808019633679 diff --git a/xmhf-64/xmhf/third-party/libtommath/etc/drprimes.txt b/xmhf-64/xmhf/third-party/libtommath/etc/drprimes.txt new file mode 100644 index 0000000000..7c97f67b9c --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/etc/drprimes.txt @@ -0,0 +1,9 @@ +300-bit prime: +p == 2037035976334486086268445688409378161051468393665936250636140449354381298610415201576637819 + +540-bit prime: +p == 3599131035634557106248430806148785487095757694641533306480604458089470064537190296255232548883112685719936728506816716098566612844395439751206810991770626477344739 + +780-bit prime: +p == 6359114106063703798370219984742410466332205126109989319225557147754704702203399726411277962562135973685197744935448875852478791860694279747355800678568677946181447581781401213133886609947027230004277244697462656003655947791725966271167 + diff --git a/xmhf-64/xmhf/third-party/libtommath/etc/makefile b/xmhf-64/xmhf/third-party/libtommath/etc/makefile new file mode 100644 index 0000000000..99154d864d --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/etc/makefile @@ -0,0 +1,50 @@ +CFLAGS += -Wall -W -Wshadow -O3 -fomit-frame-pointer -funroll-loops -I../ + +# default lib name (requires install with root) +# LIBNAME=-ltommath + +# libname when you can't install the lib with install +LIBNAME=../libtommath.a + +#provable primes +pprime: pprime.o + $(CC) pprime.o $(LIBNAME) -o pprime + +# portable [well requires clock()] tuning app +tune: tune.o + $(CC) tune.o $(LIBNAME) -o tune + +# same app but using RDTSC for higher precision [requires 80586+], coff based gcc installs [e.g. ming, cygwin, djgpp] +tune86: tune.c + nasm -f coff timer.asm + $(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o $(LIBNAME) -o tune86 + +# for cygwin +tune86c: tune.c + nasm -f gnuwin32 timer.asm + $(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o $(LIBNAME) -o tune86 + +#make tune86 for linux or any ELF format +tune86l: tune.c + nasm -f elf -DUSE_ELF timer.asm + $(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o $(LIBNAME) -o tune86l + +# spits out mersenne primes +mersenne: mersenne.o + $(CC) mersenne.o $(LIBNAME) -o mersenne + +# fines DR safe primes for the given config +drprime: drprime.o + $(CC) drprime.o $(LIBNAME) -o drprime + +# fines 2k safe primes for the given config +2kprime: 2kprime.o + $(CC) 2kprime.o $(LIBNAME) -o 2kprime + +mont: mont.o + $(CC) mont.o $(LIBNAME) -o mont + + +clean: + rm -f *.log *.o *.obj *.exe pprime tune mersenne drprime tune86 tune86l mont 2kprime pprime.dat \ + *.da *.dyn *.dpi *~ diff --git a/xmhf-64/xmhf/third-party/libtommath/etc/makefile.icc b/xmhf-64/xmhf/third-party/libtommath/etc/makefile.icc new file mode 100644 index 0000000000..8a1ffffd27 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/etc/makefile.icc @@ -0,0 +1,67 @@ +CC = icc + +CFLAGS += -I../ + +# optimize for SPEED +# +# -mcpu= can be pentium, pentiumpro (covers PII through PIII) or pentium4 +# -ax? specifies make code specifically for ? but compatible with IA-32 +# -x? specifies compile solely for ? [not specifically IA-32 compatible] +# +# where ? is +# K - PIII +# W - first P4 [Williamette] +# N - P4 Northwood +# P - P4 Prescott +# B - Blend of P4 and PM [mobile] +# +# Default to just generic max opts +CFLAGS += -O3 -xP -ip + +# default lib name (requires install with root) +# LIBNAME=-ltommath + +# libname when you can't install the lib with install +LIBNAME=../libtommath.a + +#provable primes +pprime: pprime.o + $(CC) pprime.o $(LIBNAME) -o pprime + +# portable [well requires clock()] tuning app +tune: tune.o + $(CC) tune.o $(LIBNAME) -o tune + +# same app but using RDTSC for higher precision [requires 80586+], coff based gcc installs [e.g. ming, cygwin, djgpp] +tune86: tune.c + nasm -f coff timer.asm + $(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o $(LIBNAME) -o tune86 + +# for cygwin +tune86c: tune.c + nasm -f gnuwin32 timer.asm + $(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o $(LIBNAME) -o tune86 + +#make tune86 for linux or any ELF format +tune86l: tune.c + nasm -f elf -DUSE_ELF timer.asm + $(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o $(LIBNAME) -o tune86l + +# spits out mersenne primes +mersenne: mersenne.o + $(CC) mersenne.o $(LIBNAME) -o mersenne + +# fines DR safe primes for the given config +drprime: drprime.o + $(CC) drprime.o $(LIBNAME) -o drprime + +# fines 2k safe primes for the given config +2kprime: 2kprime.o + $(CC) 2kprime.o $(LIBNAME) -o 2kprime + +mont: mont.o + $(CC) mont.o $(LIBNAME) -o mont + + +clean: + rm -f *.log *.o *.obj *.exe pprime tune mersenne drprime tune86 tune86l mont 2kprime pprime.dat *.il diff --git a/xmhf-64/xmhf/third-party/libtommath/etc/makefile.msvc b/xmhf-64/xmhf/third-party/libtommath/etc/makefile.msvc new file mode 100644 index 0000000000..2833372e00 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/etc/makefile.msvc @@ -0,0 +1,23 @@ +#MSVC Makefile +# +#Tom St Denis + +CFLAGS = /I../ /Ox /DWIN32 /W3 + +pprime: pprime.obj + cl pprime.obj ../tommath.lib + +mersenne: mersenne.obj + cl mersenne.obj ../tommath.lib + +tune: tune.obj + cl tune.obj ../tommath.lib + +mont: mont.obj + cl mont.obj ../tommath.lib + +drprime: drprime.obj + cl drprime.obj ../tommath.lib + +2kprime: 2kprime.obj + cl 2kprime.obj ../tommath.lib diff --git a/xmhf-64/xmhf/third-party/libtommath/etc/mersenne.c b/xmhf-64/xmhf/third-party/libtommath/etc/mersenne.c new file mode 100644 index 0000000000..5289631b01 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/etc/mersenne.c @@ -0,0 +1,144 @@ +/* Finds Mersenne primes using the Lucas-Lehmer test + * + * Tom St Denis, tomstdenis@gmail.com + */ +#include +#include + +int +is_mersenne (long s, int *pp) +{ + mp_int n, u; + int res, k; + + *pp = 0; + + if ((res = mp_init (&n)) != MP_OKAY) { + return res; + } + + if ((res = mp_init (&u)) != MP_OKAY) { + goto LBL_N; + } + + /* n = 2^s - 1 */ + if ((res = mp_2expt(&n, s)) != MP_OKAY) { + goto LBL_MU; + } + if ((res = mp_sub_d (&n, 1, &n)) != MP_OKAY) { + goto LBL_MU; + } + + /* set u=4 */ + mp_set (&u, 4); + + /* for k=1 to s-2 do */ + for (k = 1; k <= s - 2; k++) { + /* u = u^2 - 2 mod n */ + if ((res = mp_sqr (&u, &u)) != MP_OKAY) { + goto LBL_MU; + } + if ((res = mp_sub_d (&u, 2, &u)) != MP_OKAY) { + goto LBL_MU; + } + + /* make sure u is positive */ + while (u.sign == MP_NEG) { + if ((res = mp_add (&u, &n, &u)) != MP_OKAY) { + goto LBL_MU; + } + } + + /* reduce */ + if ((res = mp_reduce_2k (&u, &n, 1)) != MP_OKAY) { + goto LBL_MU; + } + } + + /* if u == 0 then its prime */ + if (mp_iszero (&u) == 1) { + mp_prime_is_prime(&n, 8, pp); + if (*pp != 1) printf("FAILURE\n"); + } + + res = MP_OKAY; +LBL_MU:mp_clear (&u); +LBL_N:mp_clear (&n); + return res; +} + +/* square root of a long < 65536 */ +long +i_sqrt (long x) +{ + long x1, x2; + + x2 = 16; + do { + x1 = x2; + x2 = x1 - ((x1 * x1) - x) / (2 * x1); + } while (x1 != x2); + + if (x1 * x1 > x) { + --x1; + } + + return x1; +} + +/* is the long prime by brute force */ +int +isprime (long k) +{ + long y, z; + + y = i_sqrt (k); + for (z = 2; z <= y; z++) { + if ((k % z) == 0) + return 0; + } + return 1; +} + + +int +main (void) +{ + int pp; + long k; + clock_t tt; + + k = 3; + + for (;;) { + /* start time */ + tt = clock (); + + /* test if 2^k - 1 is prime */ + if (is_mersenne (k, &pp) != MP_OKAY) { + printf ("Whoa error\n"); + return -1; + } + + if (pp == 1) { + /* count time */ + tt = clock () - tt; + + /* display if prime */ + printf ("2^%-5ld - 1 is prime, test took %ld ticks\n", k, tt); + } + + /* goto next odd exponent */ + k += 2; + + /* but make sure its prime */ + while (isprime (k) == 0) { + k += 2; + } + } + return 0; +} + +/* $Source$ */ +/* $Revision: 0.39 $ */ +/* $Date: 2006-04-06 19:49:59 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/etc/mont.c b/xmhf-64/xmhf/third-party/libtommath/etc/mont.c new file mode 100644 index 0000000000..a3271134e9 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/etc/mont.c @@ -0,0 +1,50 @@ +/* tests the montgomery routines */ +#include + +int main(void) +{ + mp_int modulus, R, p, pp; + mp_digit mp; + long x, y; + + srand(time(NULL)); + mp_init_multi(&modulus, &R, &p, &pp, NULL); + + /* loop through various sizes */ + for (x = 4; x < 256; x++) { + printf("DIGITS == %3ld...", x); fflush(stdout); + + /* make up the odd modulus */ + mp_rand(&modulus, x); + modulus.dp[0] |= 1; + + /* now find the R value */ + mp_montgomery_calc_normalization(&R, &modulus); + mp_montgomery_setup(&modulus, &mp); + + /* now run through a bunch tests */ + for (y = 0; y < 1000; y++) { + mp_rand(&p, x/2); /* p = random */ + mp_mul(&p, &R, &pp); /* pp = R * p */ + mp_montgomery_reduce(&pp, &modulus, mp); + + /* should be equal to p */ + if (mp_cmp(&pp, &p) != MP_EQ) { + printf("FAILURE!\n"); + exit(-1); + } + } + printf("PASSED\n"); + } + + return 0; +} + + + + + + +/* $Source$ */ +/* $Revision: 0.36 $ */ +/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/etc/pprime.c b/xmhf-64/xmhf/third-party/libtommath/etc/pprime.c new file mode 100644 index 0000000000..d2d3a32d7b --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/etc/pprime.c @@ -0,0 +1,400 @@ +/* Generates provable primes + * + * See http://gmail.com:8080/papers/pp.pdf for more info. + * + * Tom St Denis, tomstdenis@gmail.com, http://tom.gmail.com + */ +#include +#include "tommath.h" + +int n_prime; +FILE *primes; + +/* fast square root */ +static mp_digit +i_sqrt (mp_word x) +{ + mp_word x1, x2; + + x2 = x; + do { + x1 = x2; + x2 = x1 - ((x1 * x1) - x) / (2 * x1); + } while (x1 != x2); + + if (x1 * x1 > x) { + --x1; + } + + return x1; +} + + +/* generates a prime digit */ +static void gen_prime (void) +{ + mp_digit r, x, y, next; + FILE *out; + + out = fopen("pprime.dat", "wb"); + + /* write first set of primes */ + r = 3; fwrite(&r, 1, sizeof(mp_digit), out); + r = 5; fwrite(&r, 1, sizeof(mp_digit), out); + r = 7; fwrite(&r, 1, sizeof(mp_digit), out); + r = 11; fwrite(&r, 1, sizeof(mp_digit), out); + r = 13; fwrite(&r, 1, sizeof(mp_digit), out); + r = 17; fwrite(&r, 1, sizeof(mp_digit), out); + r = 19; fwrite(&r, 1, sizeof(mp_digit), out); + r = 23; fwrite(&r, 1, sizeof(mp_digit), out); + r = 29; fwrite(&r, 1, sizeof(mp_digit), out); + r = 31; fwrite(&r, 1, sizeof(mp_digit), out); + + /* get square root, since if 'r' is composite its factors must be < than this */ + y = i_sqrt (r); + next = (y + 1) * (y + 1); + + for (;;) { + do { + r += 2; /* next candidate */ + r &= MP_MASK; + if (r < 31) break; + + /* update sqrt ? */ + if (next <= r) { + ++y; + next = (y + 1) * (y + 1); + } + + /* loop if divisible by 3,5,7,11,13,17,19,23,29 */ + if ((r % 3) == 0) { + x = 0; + continue; + } + if ((r % 5) == 0) { + x = 0; + continue; + } + if ((r % 7) == 0) { + x = 0; + continue; + } + if ((r % 11) == 0) { + x = 0; + continue; + } + if ((r % 13) == 0) { + x = 0; + continue; + } + if ((r % 17) == 0) { + x = 0; + continue; + } + if ((r % 19) == 0) { + x = 0; + continue; + } + if ((r % 23) == 0) { + x = 0; + continue; + } + if ((r % 29) == 0) { + x = 0; + continue; + } + + /* now check if r is divisible by x + k={1,7,11,13,17,19,23,29} */ + for (x = 30; x <= y; x += 30) { + if ((r % (x + 1)) == 0) { + x = 0; + break; + } + if ((r % (x + 7)) == 0) { + x = 0; + break; + } + if ((r % (x + 11)) == 0) { + x = 0; + break; + } + if ((r % (x + 13)) == 0) { + x = 0; + break; + } + if ((r % (x + 17)) == 0) { + x = 0; + break; + } + if ((r % (x + 19)) == 0) { + x = 0; + break; + } + if ((r % (x + 23)) == 0) { + x = 0; + break; + } + if ((r % (x + 29)) == 0) { + x = 0; + break; + } + } + } while (x == 0); + if (r > 31) { fwrite(&r, 1, sizeof(mp_digit), out); printf("%9d\r", r); fflush(stdout); } + if (r < 31) break; + } + + fclose(out); +} + +void load_tab(void) +{ + primes = fopen("pprime.dat", "rb"); + if (primes == NULL) { + gen_prime(); + primes = fopen("pprime.dat", "rb"); + } + fseek(primes, 0, SEEK_END); + n_prime = ftell(primes) / sizeof(mp_digit); +} + +mp_digit prime_digit(void) +{ + int n; + mp_digit d; + + n = abs(rand()) % n_prime; + fseek(primes, n * sizeof(mp_digit), SEEK_SET); + fread(&d, 1, sizeof(mp_digit), primes); + return d; +} + + +/* makes a prime of at least k bits */ +int +pprime (int k, int li, mp_int * p, mp_int * q) +{ + mp_int a, b, c, n, x, y, z, v; + int res, ii; + static const mp_digit bases[] = { 2, 3, 5, 7, 11, 13, 17, 19 }; + + /* single digit ? */ + if (k <= (int) DIGIT_BIT) { + mp_set (p, prime_digit ()); + return MP_OKAY; + } + + if ((res = mp_init (&c)) != MP_OKAY) { + return res; + } + + if ((res = mp_init (&v)) != MP_OKAY) { + goto LBL_C; + } + + /* product of first 50 primes */ + if ((res = + mp_read_radix (&v, + "19078266889580195013601891820992757757219839668357012055907516904309700014933909014729740190", + 10)) != MP_OKAY) { + goto LBL_V; + } + + if ((res = mp_init (&a)) != MP_OKAY) { + goto LBL_V; + } + + /* set the prime */ + mp_set (&a, prime_digit ()); + + if ((res = mp_init (&b)) != MP_OKAY) { + goto LBL_A; + } + + if ((res = mp_init (&n)) != MP_OKAY) { + goto LBL_B; + } + + if ((res = mp_init (&x)) != MP_OKAY) { + goto LBL_N; + } + + if ((res = mp_init (&y)) != MP_OKAY) { + goto LBL_X; + } + + if ((res = mp_init (&z)) != MP_OKAY) { + goto LBL_Y; + } + + /* now loop making the single digit */ + while (mp_count_bits (&a) < k) { + fprintf (stderr, "prime has %4d bits left\r", k - mp_count_bits (&a)); + fflush (stderr); + top: + mp_set (&b, prime_digit ()); + + /* now compute z = a * b * 2 */ + if ((res = mp_mul (&a, &b, &z)) != MP_OKAY) { /* z = a * b */ + goto LBL_Z; + } + + if ((res = mp_copy (&z, &c)) != MP_OKAY) { /* c = a * b */ + goto LBL_Z; + } + + if ((res = mp_mul_2 (&z, &z)) != MP_OKAY) { /* z = 2 * a * b */ + goto LBL_Z; + } + + /* n = z + 1 */ + if ((res = mp_add_d (&z, 1, &n)) != MP_OKAY) { /* n = z + 1 */ + goto LBL_Z; + } + + /* check (n, v) == 1 */ + if ((res = mp_gcd (&n, &v, &y)) != MP_OKAY) { /* y = (n, v) */ + goto LBL_Z; + } + + if (mp_cmp_d (&y, 1) != MP_EQ) + goto top; + + /* now try base x=bases[ii] */ + for (ii = 0; ii < li; ii++) { + mp_set (&x, bases[ii]); + + /* compute x^a mod n */ + if ((res = mp_exptmod (&x, &a, &n, &y)) != MP_OKAY) { /* y = x^a mod n */ + goto LBL_Z; + } + + /* if y == 1 loop */ + if (mp_cmp_d (&y, 1) == MP_EQ) + continue; + + /* now x^2a mod n */ + if ((res = mp_sqrmod (&y, &n, &y)) != MP_OKAY) { /* y = x^2a mod n */ + goto LBL_Z; + } + + if (mp_cmp_d (&y, 1) == MP_EQ) + continue; + + /* compute x^b mod n */ + if ((res = mp_exptmod (&x, &b, &n, &y)) != MP_OKAY) { /* y = x^b mod n */ + goto LBL_Z; + } + + /* if y == 1 loop */ + if (mp_cmp_d (&y, 1) == MP_EQ) + continue; + + /* now x^2b mod n */ + if ((res = mp_sqrmod (&y, &n, &y)) != MP_OKAY) { /* y = x^2b mod n */ + goto LBL_Z; + } + + if (mp_cmp_d (&y, 1) == MP_EQ) + continue; + + /* compute x^c mod n == x^ab mod n */ + if ((res = mp_exptmod (&x, &c, &n, &y)) != MP_OKAY) { /* y = x^ab mod n */ + goto LBL_Z; + } + + /* if y == 1 loop */ + if (mp_cmp_d (&y, 1) == MP_EQ) + continue; + + /* now compute (x^c mod n)^2 */ + if ((res = mp_sqrmod (&y, &n, &y)) != MP_OKAY) { /* y = x^2ab mod n */ + goto LBL_Z; + } + + /* y should be 1 */ + if (mp_cmp_d (&y, 1) != MP_EQ) + continue; + break; + } + + /* no bases worked? */ + if (ii == li) + goto top; + +{ + char buf[4096]; + + mp_toradix(&n, buf, 10); + printf("Certificate of primality for:\n%s\n\n", buf); + mp_toradix(&a, buf, 10); + printf("A == \n%s\n\n", buf); + mp_toradix(&b, buf, 10); + printf("B == \n%s\n\nG == %d\n", buf, bases[ii]); + printf("----------------------------------------------------------------\n"); +} + + /* a = n */ + mp_copy (&n, &a); + } + + /* get q to be the order of the large prime subgroup */ + mp_sub_d (&n, 1, q); + mp_div_2 (q, q); + mp_div (q, &b, q, NULL); + + mp_exch (&n, p); + + res = MP_OKAY; +LBL_Z:mp_clear (&z); +LBL_Y:mp_clear (&y); +LBL_X:mp_clear (&x); +LBL_N:mp_clear (&n); +LBL_B:mp_clear (&b); +LBL_A:mp_clear (&a); +LBL_V:mp_clear (&v); +LBL_C:mp_clear (&c); + return res; +} + + +int +main (void) +{ + mp_int p, q; + char buf[4096]; + int k, li; + clock_t t1; + + srand (time (NULL)); + load_tab(); + + printf ("Enter # of bits: \n"); + fgets (buf, sizeof (buf), stdin); + sscanf (buf, "%d", &k); + + printf ("Enter number of bases to try (1 to 8):\n"); + fgets (buf, sizeof (buf), stdin); + sscanf (buf, "%d", &li); + + + mp_init (&p); + mp_init (&q); + + t1 = clock (); + pprime (k, li, &p, &q); + t1 = clock () - t1; + + printf ("\n\nTook %ld ticks, %d bits\n", t1, mp_count_bits (&p)); + + mp_toradix (&p, buf, 10); + printf ("P == %s\n", buf); + mp_toradix (&q, buf, 10); + printf ("Q == %s\n", buf); + + return 0; +} + +/* $Source$ */ +/* $Revision: 0.39 $ */ +/* $Date: 2006-04-06 19:49:59 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/etc/prime.1024 b/xmhf-64/xmhf/third-party/libtommath/etc/prime.1024 new file mode 100644 index 0000000000..5636e2da09 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/etc/prime.1024 @@ -0,0 +1,414 @@ +Enter # of bits: +Enter number of bases to try (1 to 8): +Certificate of primality for: +36360080703173363 + +A == +89963569 + +B == +202082249 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +4851595597739856136987139 + +A == +36360080703173363 + +B == +66715963 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +19550639734462621430325731591027 + +A == +4851595597739856136987139 + +B == +2014867 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +10409036141344317165691858509923818734539 + +A == +19550639734462621430325731591027 + +B == +266207047 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +1049829549988285012736475602118094726647504414203 + +A == +10409036141344317165691858509923818734539 + +B == +50428759 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +77194737385528288387712399596835459931920358844586615003 + +A == +1049829549988285012736475602118094726647504414203 + +B == +36765367 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +35663756695365208574443215955488689578374232732893628896541201763 + +A == +77194737385528288387712399596835459931920358844586615003 + +B == +230998627 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +16711831463502165169495622246023119698415848120292671294127567620396469803 + +A == +35663756695365208574443215955488689578374232732893628896541201763 + +B == +234297127 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +6163534781560285962890718925972249753147470953579266394395432475622345597103528739 + +A == +16711831463502165169495622246023119698415848120292671294127567620396469803 + +B == +184406323 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +814258256205243497704094951432575867360065658372158511036259934640748088306764553488803787 + +A == +6163534781560285962890718925972249753147470953579266394395432475622345597103528739 + +B == +66054487 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +176469695533271657902814176811660357049007467856432383037590673407330246967781451723764079581998187 + +A == +814258256205243497704094951432575867360065658372158511036259934640748088306764553488803787 + +B == +108362239 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +44924492859445516541759485198544012102424796403707253610035148063863073596051272171194806669756971406400419 + +A == +176469695533271657902814176811660357049007467856432383037590673407330246967781451723764079581998187 + +B == +127286707 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +20600996927219343383225424320134474929609459588323857796871086845924186191561749519858600696159932468024710985371059 + +A == +44924492859445516541759485198544012102424796403707253610035148063863073596051272171194806669756971406400419 + +B == +229284691 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +6295696427695493110141186605837397185848992307978456138112526915330347715236378041486547994708748840844217371233735072572979 + +A == +20600996927219343383225424320134474929609459588323857796871086845924186191561749519858600696159932468024710985371059 + +B == +152800771 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +3104984078042317488749073016454213579257792635142218294052134804187631661145261015102617582090263808696699966840735333252107678792123 + +A == +6295696427695493110141186605837397185848992307978456138112526915330347715236378041486547994708748840844217371233735072572979 + +B == +246595759 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +26405175827665701256325699315126705508919255051121452292124404943796947287968603975320562847910946802396632302209435206627913466015741799499 + +A == +3104984078042317488749073016454213579257792635142218294052134804187631661145261015102617582090263808696699966840735333252107678792123 + +B == +4252063 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +11122146237908413610034600609460545703591095894418599759742741406628055069007082998134905595800236452010905900391505454890446585211975124558601770163 + +A == +26405175827665701256325699315126705508919255051121452292124404943796947287968603975320562847910946802396632302209435206627913466015741799499 + +B == +210605419 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +1649861642047798890580354082088712649911849362201343649289384923147797960364736011515757482030049342943790127685185806092659832129486307035500638595572396187 + +A == +11122146237908413610034600609460545703591095894418599759742741406628055069007082998134905595800236452010905900391505454890446585211975124558601770163 + +B == +74170111 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +857983367126266717607389719637086684134462613006415859877666235955788392464081914127715967940968197765042399904117392707518175220864852816390004264107201177394565363 + +A == +1649861642047798890580354082088712649911849362201343649289384923147797960364736011515757482030049342943790127685185806092659832129486307035500638595572396187 + +B == +260016763 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +175995909353623703257072120479340610010337144085688850745292031336724691277374210929188442230237711063783727092685448718515661641054886101716698390145283196296702450566161283 + +A == +857983367126266717607389719637086684134462613006415859877666235955788392464081914127715967940968197765042399904117392707518175220864852816390004264107201177394565363 + +B == +102563707 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +48486002551155667224487059713350447239190772068092630563272168418880661006593537218144160068395218642353495339720640699721703003648144463556291315694787862009052641640656933232794283 + +A == +175995909353623703257072120479340610010337144085688850745292031336724691277374210929188442230237711063783727092685448718515661641054886101716698390145283196296702450566161283 + +B == +137747527 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +13156468011529105025061495011938518171328604045212410096476697450506055664012861932372156505805788068791146986282263016790631108386790291275939575123375304599622623328517354163964228279867403 + +A == +48486002551155667224487059713350447239190772068092630563272168418880661006593537218144160068395218642353495339720640699721703003648144463556291315694787862009052641640656933232794283 + +B == +135672847 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +6355194692790533601105154341731997464407930009404822926832136060319955058388106456084549316415200519472481147942263916585428906582726749131479465958107142228236909665306781538860053107680830113869123 + +A == +13156468011529105025061495011938518171328604045212410096476697450506055664012861932372156505805788068791146986282263016790631108386790291275939575123375304599622623328517354163964228279867403 + +B == +241523587 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +3157116676535430302794438027544146642863331358530722860333745617571010460905857862561870488000265751138954271040017454405707755458702044884023184574412221802502351503929935224995314581932097706874819348858083 + +A == +6355194692790533601105154341731997464407930009404822926832136060319955058388106456084549316415200519472481147942263916585428906582726749131479465958107142228236909665306781538860053107680830113869123 + +B == +248388667 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +390533129219992506725320633489467713907837370444962163378727819939092929448752905310115311180032249230394348337568973177802874166228132778126338883671958897238722734394783244237133367055422297736215754829839364158067 + +A == +3157116676535430302794438027544146642863331358530722860333745617571010460905857862561870488000265751138954271040017454405707755458702044884023184574412221802502351503929935224995314581932097706874819348858083 + +B == +61849651 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +48583654555070224891047847050732516652910250240135992225139515777200432486685999462997073444468380434359929499498804723793106565291183220444221080449740542884172281158126259373095216435009661050109711341419005972852770440739 + +A == +390533129219992506725320633489467713907837370444962163378727819939092929448752905310115311180032249230394348337568973177802874166228132778126338883671958897238722734394783244237133367055422297736215754829839364158067 + +B == +62201707 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +25733035251905120039135866524384525138869748427727001128764704499071378939227862068500633813538831598776578372709963673670934388213622433800015759585470542686333039614931682098922935087822950084908715298627996115185849260703525317419 + +A == +48583654555070224891047847050732516652910250240135992225139515777200432486685999462997073444468380434359929499498804723793106565291183220444221080449740542884172281158126259373095216435009661050109711341419005972852770440739 + +B == +264832231 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +2804594464939948901906623499531073917980499195397462605359913717827014360538186518540781517129548650937632008683280555602633122170458773895504894807182664540529077836857897972175530148107545939211339044386106111633510166695386323426241809387 + +A == +25733035251905120039135866524384525138869748427727001128764704499071378939227862068500633813538831598776578372709963673670934388213622433800015759585470542686333039614931682098922935087822950084908715298627996115185849260703525317419 + +B == +54494047 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +738136612083433720096707308165797114449914259256979340471077690416567237592465306112484843530074782721390528773594351482384711900456440808251196845265132086486672447136822046628407467459921823150600138073268385534588238548865012638209515923513516547 + +A == +2804594464939948901906623499531073917980499195397462605359913717827014360538186518540781517129548650937632008683280555602633122170458773895504894807182664540529077836857897972175530148107545939211339044386106111633510166695386323426241809387 + +B == +131594179 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +392847529056126766528615419937165193421166694172790666626558750047057558168124866940509180171236517681470100877687445134633784815352076138790217228749332398026714192707447855731679485746120589851992221508292976900578299504461333767437280988393026452846013683 + +A == +738136612083433720096707308165797114449914259256979340471077690416567237592465306112484843530074782721390528773594351482384711900456440808251196845265132086486672447136822046628407467459921823150600138073268385534588238548865012638209515923513516547 + +B == +266107603 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +168459393231883505975876919268398655632763956627405508859662408056221544310200546265681845397346956580604208064328814319465940958080244889692368602591598503944015835190587740756859842792554282496742843600573336023639256008687581291233481455395123454655488735304365627 + +A == +392847529056126766528615419937165193421166694172790666626558750047057558168124866940509180171236517681470100877687445134633784815352076138790217228749332398026714192707447855731679485746120589851992221508292976900578299504461333767437280988393026452846013683 + +B == +214408111 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +14865774288636941404884923981945833072113667565310054952177860608355263252462409554658728941191929400198053290113492910272458441655458514080123870132092365833472436407455910185221474386718838138135065780840839893113912689594815485706154461164071775481134379794909690501684643 + +A == +168459393231883505975876919268398655632763956627405508859662408056221544310200546265681845397346956580604208064328814319465940958080244889692368602591598503944015835190587740756859842792554282496742843600573336023639256008687581291233481455395123454655488735304365627 + +B == +44122723 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +1213301773203241614897109856134894783021668292000023984098824423682568173639394290886185366993108292039068940333907505157813934962357206131450244004178619265868614859794316361031904412926604138893775068853175215502104744339658944443630407632290152772487455298652998368296998719996019 + +A == +14865774288636941404884923981945833072113667565310054952177860608355263252462409554658728941191929400198053290113492910272458441655458514080123870132092365833472436407455910185221474386718838138135065780840839893113912689594815485706154461164071775481134379794909690501684643 + +B == +40808563 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +186935245989515158127969129347464851990429060640910951266513740972248428651109062997368144722015290092846666943896556191257222521203647606911446635194198213436423080005867489516421559330500722264446765608763224572386410155413161172707802334865729654109050873820610813855041667633843601286843 + +A == +1213301773203241614897109856134894783021668292000023984098824423682568173639394290886185366993108292039068940333907505157813934962357206131450244004178619265868614859794316361031904412926604138893775068853175215502104744339658944443630407632290152772487455298652998368296998719996019 + +B == +77035759 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +83142661079751490510739960019112406284111408348732592580459037404394946037094409915127399165633756159385609671956087845517678367844901424617866988187132480585966721962585586730693443536100138246516868613250009028187662080828012497191775172228832247706080044971423654632146928165751885302331924491683 + +A == +186935245989515158127969129347464851990429060640910951266513740972248428651109062997368144722015290092846666943896556191257222521203647606911446635194198213436423080005867489516421559330500722264446765608763224572386410155413161172707802334865729654109050873820610813855041667633843601286843 + +B == +222383587 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +3892354773803809855317742245039794448230625839512638747643814927766738642436392673485997449586432241626440927010641564064764336402368634186618250134234189066179771240232458249806850838490410473462391401438160528157981942499581634732706904411807195259620779379274017704050790865030808501633772117217899534443 + +A == +83142661079751490510739960019112406284111408348732592580459037404394946037094409915127399165633756159385609671956087845517678367844901424617866988187132480585966721962585586730693443536100138246516868613250009028187662080828012497191775172228832247706080044971423654632146928165751885302331924491683 + +B == +23407687 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +1663606652988091811284014366560171522582683318514519379924950390627250155440313691226744227787921928894551755219495501365555370027257568506349958010457682898612082048959464465369892842603765280317696116552850664773291371490339084156052244256635115997453399761029567033971998617303988376172539172702246575225837054723 + +A == +3892354773803809855317742245039794448230625839512638747643814927766738642436392673485997449586432241626440927010641564064764336402368634186618250134234189066179771240232458249806850838490410473462391401438160528157981942499581634732706904411807195259620779379274017704050790865030808501633772117217899534443 + +B == +213701827 + +G == 2 +---------------------------------------------------------------- + + +Took 33057 ticks, 1048 bits +P == 1663606652988091811284014366560171522582683318514519379924950390627250155440313691226744227787921928894551755219495501365555370027257568506349958010457682898612082048959464465369892842603765280317696116552850664773291371490339084156052244256635115997453399761029567033971998617303988376172539172702246575225837054723 +Q == 3892354773803809855317742245039794448230625839512638747643814927766738642436392673485997449586432241626440927010641564064764336402368634186618250134234189066179771240232458249806850838490410473462391401438160528157981942499581634732706904411807195259620779379274017704050790865030808501633772117217899534443 diff --git a/xmhf-64/xmhf/third-party/libtommath/etc/prime.512 b/xmhf-64/xmhf/third-party/libtommath/etc/prime.512 new file mode 100644 index 0000000000..cb6ec302fb --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/etc/prime.512 @@ -0,0 +1,205 @@ +Enter # of bits: +Enter number of bases to try (1 to 8): +Certificate of primality for: +85933926807634727 + +A == +253758023 + +B == +169322581 + +G == 5 +---------------------------------------------------------------- +Certificate of primality for: +23930198825086241462113799 + +A == +85933926807634727 + +B == +139236037 + +G == 11 +---------------------------------------------------------------- +Certificate of primality for: +6401844647261612602378676572510019 + +A == +23930198825086241462113799 + +B == +133760791 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +269731366027728777712034888684015329354259 + +A == +6401844647261612602378676572510019 + +B == +21066691 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +37942338209025571690075025099189467992329684223707 + +A == +269731366027728777712034888684015329354259 + +B == +70333567 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +15306904714258982484473490774101705363308327436988160248323 + +A == +37942338209025571690075025099189467992329684223707 + +B == +201712723 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +1616744757018513392810355191503853040357155275733333124624513530099 + +A == +15306904714258982484473490774101705363308327436988160248323 + +B == +52810963 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +464222094814208047161771036072622485188658077940154689939306386289983787983 + +A == +1616744757018513392810355191503853040357155275733333124624513530099 + +B == +143566909 + +G == 5 +---------------------------------------------------------------- +Certificate of primality for: +187429931674053784626487560729643601208757374994177258429930699354770049369025096447 + +A == +464222094814208047161771036072622485188658077940154689939306386289983787983 + +B == +201875281 + +G == 5 +---------------------------------------------------------------- +Certificate of primality for: +100579220846502621074093727119851331775052664444339632682598589456666938521976625305832917563 + +A == +187429931674053784626487560729643601208757374994177258429930699354770049369025096447 + +B == +268311523 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +1173616081309758475197022137833792133815753368965945885089720153370737965497134878651384030219765163 + +A == +100579220846502621074093727119851331775052664444339632682598589456666938521976625305832917563 + +B == +5834287 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +191456913489905913185935197655672585713573070349044195411728114905691721186574907738081340754373032735283623 + +A == +1173616081309758475197022137833792133815753368965945885089720153370737965497134878651384030219765163 + +B == +81567097 + +G == 5 +---------------------------------------------------------------- +Certificate of primality for: +57856530489201750164178576399448868489243874083056587683743345599898489554401618943240901541005080049321706789987519 + +A == +191456913489905913185935197655672585713573070349044195411728114905691721186574907738081340754373032735283623 + +B == +151095433 + +G == 7 +---------------------------------------------------------------- +Certificate of primality for: +13790529750452576698109671710773784949185621244122040804792403407272729038377767162233653248852099545134831722512085881814803 + +A == +57856530489201750164178576399448868489243874083056587683743345599898489554401618943240901541005080049321706789987519 + +B == +119178679 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +7075985989000817742677547821106534174334812111605018857703825637170140040509067704269696198231266351631132464035671858077052876058979 + +A == +13790529750452576698109671710773784949185621244122040804792403407272729038377767162233653248852099545134831722512085881814803 + +B == +256552363 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +1227273006232588072907488910282307435921226646895131225407452056677899411162892829564455154080310937471747140942360789623819327234258162420463 + +A == +7075985989000817742677547821106534174334812111605018857703825637170140040509067704269696198231266351631132464035671858077052876058979 + +B == +86720989 + +G == 5 +---------------------------------------------------------------- +Certificate of primality for: +446764896913554613686067036908702877942872355053329937790398156069936255759889884246832779737114032666318220500106499161852193765380831330106375235763 + +A == +1227273006232588072907488910282307435921226646895131225407452056677899411162892829564455154080310937471747140942360789623819327234258162420463 + +B == +182015287 + +G == 2 +---------------------------------------------------------------- +Certificate of primality for: +5290203010849586596974953717018896543907195901082056939587768479377028575911127944611236020459652034082251335583308070846379514569838984811187823420951275243 + +A == +446764896913554613686067036908702877942872355053329937790398156069936255759889884246832779737114032666318220500106499161852193765380831330106375235763 + +B == +5920567 + +G == 2 +---------------------------------------------------------------- + + +Took 3454 ticks, 521 bits +P == 5290203010849586596974953717018896543907195901082056939587768479377028575911127944611236020459652034082251335583308070846379514569838984811187823420951275243 +Q == 446764896913554613686067036908702877942872355053329937790398156069936255759889884246832779737114032666318220500106499161852193765380831330106375235763 diff --git a/xmhf-64/xmhf/third-party/libtommath/etc/timer.asm b/xmhf-64/xmhf/third-party/libtommath/etc/timer.asm new file mode 100644 index 0000000000..35890d9852 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/etc/timer.asm @@ -0,0 +1,37 @@ +; x86 timer in NASM +; +; Tom St Denis, tomstdenis@iahu.ca +[bits 32] +[section .data] +time dd 0, 0 + +[section .text] + +%ifdef USE_ELF +[global t_start] +t_start: +%else +[global _t_start] +_t_start: +%endif + push edx + push eax + rdtsc + mov [time+0],edx + mov [time+4],eax + pop eax + pop edx + ret + +%ifdef USE_ELF +[global t_read] +t_read: +%else +[global _t_read] +_t_read: +%endif + rdtsc + sub eax,[time+4] + sbb edx,[time+0] + ret + \ No newline at end of file diff --git a/xmhf-64/xmhf/third-party/libtommath/etc/tune.c b/xmhf-64/xmhf/third-party/libtommath/etc/tune.c new file mode 100644 index 0000000000..6a580ca931 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/etc/tune.c @@ -0,0 +1,142 @@ +/* Tune the Karatsuba parameters + * + * Tom St Denis, tomstdenis@gmail.com + */ +#include +#include + +/* how many times todo each size mult. Depends on your computer. For slow computers + * this can be low like 5 or 10. For fast [re: Athlon] should be 25 - 50 or so + */ +#define TIMES (1UL<<14UL) + +/* RDTSC from Scott Duplichan */ +static ulong64 TIMFUNC (void) + { + #if defined __GNUC__ + #if defined(__i386__) || defined(__x86_64__) + unsigned long long a; + __asm__ __volatile__ ("rdtsc\nmovl %%eax,%0\nmovl %%edx,4+%0\n"::"m"(a):"%eax","%edx"); + return a; + #else /* gcc-IA64 version */ + unsigned long result; + __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory"); + while (__builtin_expect ((int) result == -1, 0)) + __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory"); + return result; + #endif + + // Microsoft and Intel Windows compilers + #elif defined _M_IX86 + __asm rdtsc + #elif defined _M_AMD64 + return __rdtsc (); + #elif defined _M_IA64 + #if defined __INTEL_COMPILER + #include + #endif + return __getReg (3116); + #else + #error need rdtsc function for this build + #endif + } + + +#ifndef X86_TIMER + +/* generic ISO C timer */ +ulong64 LBL_T; +void t_start(void) { LBL_T = TIMFUNC(); } +ulong64 t_read(void) { return TIMFUNC() - LBL_T; } + +#else +extern void t_start(void); +extern ulong64 t_read(void); +#endif + +ulong64 time_mult(int size, int s) +{ + unsigned long x; + mp_int a, b, c; + ulong64 t1; + + mp_init (&a); + mp_init (&b); + mp_init (&c); + + mp_rand (&a, size); + mp_rand (&b, size); + + if (s == 1) { + KARATSUBA_MUL_CUTOFF = size; + } else { + KARATSUBA_MUL_CUTOFF = 100000; + } + + t_start(); + for (x = 0; x < TIMES; x++) { + mp_mul(&a,&b,&c); + } + t1 = t_read(); + mp_clear (&a); + mp_clear (&b); + mp_clear (&c); + return t1; +} + +ulong64 time_sqr(int size, int s) +{ + unsigned long x; + mp_int a, b; + ulong64 t1; + + mp_init (&a); + mp_init (&b); + + mp_rand (&a, size); + + if (s == 1) { + KARATSUBA_SQR_CUTOFF = size; + } else { + KARATSUBA_SQR_CUTOFF = 100000; + } + + t_start(); + for (x = 0; x < TIMES; x++) { + mp_sqr(&a,&b); + } + t1 = t_read(); + mp_clear (&a); + mp_clear (&b); + return t1; +} + +int +main (void) +{ + ulong64 t1, t2; + int x, y; + + for (x = 8; ; x += 2) { + t1 = time_mult(x, 0); + t2 = time_mult(x, 1); + printf("%d: %9llu %9llu, %9llu\n", x, t1, t2, t2 - t1); + if (t2 < t1) break; + } + y = x; + + for (x = 8; ; x += 2) { + t1 = time_sqr(x, 0); + t2 = time_sqr(x, 1); + printf("%d: %9llu %9llu, %9llu\n", x, t1, t2, t2 - t1); + if (t2 < t1) break; + } + printf("KARATSUBA_MUL_CUTOFF = %d\n", y); + printf("KARATSUBA_SQR_CUTOFF = %d\n", x); + + return 0; +} + +/* $Source$ */ +/* $Revision: 0.39 $ */ +/* $Date: 2006-04-06 19:49:59 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/gen.pl b/xmhf-64/xmhf/third-party/libtommath/gen.pl new file mode 100755 index 0000000000..72365912e1 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/gen.pl @@ -0,0 +1,17 @@ +#!/usr/bin/perl -w +# +# Generates a "single file" you can use to quickly +# add the whole source without any makefile troubles +# +use strict; + +open( OUT, ">mpi.c" ) or die "Couldn't open mpi.c for writing: $!"; +foreach my $filename (glob "bn*.c") { + open( SRC, "<$filename" ) or die "Couldn't open $filename for reading: $!"; + print OUT "/* Start: $filename */\n"; + print OUT while ; + print OUT "\n/* End: $filename */\n\n"; + close SRC or die "Error closing $filename after reading: $!"; +} +print OUT "\n/* EOF */\n"; +close OUT or die "Error closing mpi.c after writing: $!"; \ No newline at end of file diff --git a/xmhf-64/xmhf/third-party/libtommath/libtommath.dsp b/xmhf-64/xmhf/third-party/libtommath/libtommath.dsp new file mode 100644 index 0000000000..71ac2433eb --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/libtommath.dsp @@ -0,0 +1,572 @@ +# Microsoft Developer Studio Project File - Name="libtommath" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=libtommath - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "libtommath.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "libtommath.mak" CFG="libtommath - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "libtommath - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "libtommath - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "libtommath" +# PROP Scc_LocalPath "." +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "libtommath - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "." /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"Release\tommath.lib" + +!ELSEIF "$(CFG)" == "libtommath - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"Debug\tommath.lib" + +!ENDIF + +# Begin Target + +# Name "libtommath - Win32 Release" +# Name "libtommath - Win32 Debug" +# Begin Source File + +SOURCE=.\bn_error.c +# End Source File +# Begin Source File + +SOURCE=.\bn_fast_mp_invmod.c +# End Source File +# Begin Source File + +SOURCE=.\bn_fast_mp_montgomery_reduce.c +# End Source File +# Begin Source File + +SOURCE=.\bn_fast_s_mp_mul_digs.c +# End Source File +# Begin Source File + +SOURCE=.\bn_fast_s_mp_mul_high_digs.c +# End Source File +# Begin Source File + +SOURCE=.\bn_fast_s_mp_sqr.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_2expt.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_abs.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_add.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_add_d.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_addmod.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_and.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_clamp.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_clear.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_clear_multi.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_cmp.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_cmp_d.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_cmp_mag.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_cnt_lsb.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_copy.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_count_bits.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_div.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_div_2.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_div_2d.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_div_3.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_div_d.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_dr_is_modulus.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_dr_reduce.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_dr_setup.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_exch.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_expt_d.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_exptmod.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_exptmod_fast.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_exteuclid.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_fread.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_fwrite.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_gcd.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_get_int.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_grow.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_init.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_init_copy.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_init_multi.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_init_set.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_init_set_int.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_init_size.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_invmod.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_invmod_slow.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_is_square.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_jacobi.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_karatsuba_mul.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_karatsuba_sqr.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_lcm.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_lshd.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_mod.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_mod_2d.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_mod_d.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_montgomery_calc_normalization.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_montgomery_reduce.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_montgomery_setup.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_mul.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_mul_2.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_mul_2d.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_mul_d.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_mulmod.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_n_root.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_neg.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_or.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_prime_fermat.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_prime_is_divisible.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_prime_is_prime.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_prime_miller_rabin.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_prime_next_prime.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_prime_rabin_miller_trials.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_prime_random_ex.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_radix_size.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_radix_smap.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_rand.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_read_radix.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_read_signed_bin.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_read_unsigned_bin.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_reduce.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_reduce_2k.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_reduce_2k_l.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_reduce_2k_setup.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_reduce_2k_setup_l.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_reduce_is_2k.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_reduce_is_2k_l.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_reduce_setup.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_rshd.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_set.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_set_int.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_shrink.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_signed_bin_size.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_sqr.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_sqrmod.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_sqrt.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_sub.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_sub_d.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_submod.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_to_signed_bin.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_to_signed_bin_n.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_to_unsigned_bin.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_to_unsigned_bin_n.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_toom_mul.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_toom_sqr.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_toradix.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_toradix_n.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_unsigned_bin_size.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_xor.c +# End Source File +# Begin Source File + +SOURCE=.\bn_mp_zero.c +# End Source File +# Begin Source File + +SOURCE=.\bn_prime_tab.c +# End Source File +# Begin Source File + +SOURCE=.\bn_reverse.c +# End Source File +# Begin Source File + +SOURCE=.\bn_s_mp_add.c +# End Source File +# Begin Source File + +SOURCE=.\bn_s_mp_exptmod.c +# End Source File +# Begin Source File + +SOURCE=.\bn_s_mp_mul_digs.c +# End Source File +# Begin Source File + +SOURCE=.\bn_s_mp_mul_high_digs.c +# End Source File +# Begin Source File + +SOURCE=.\bn_s_mp_sqr.c +# End Source File +# Begin Source File + +SOURCE=.\bn_s_mp_sub.c +# End Source File +# Begin Source File + +SOURCE=.\bncore.c +# End Source File +# Begin Source File + +SOURCE=.\tommath.h +# End Source File +# Begin Source File + +SOURCE=.\tommath_class.h +# End Source File +# Begin Source File + +SOURCE=.\tommath_superclass.h +# End Source File +# End Target +# End Project diff --git a/xmhf-64/xmhf/third-party/libtommath/libtommath_VS2005.sln b/xmhf-64/xmhf/third-party/libtommath/libtommath_VS2005.sln new file mode 100644 index 0000000000..21bc915567 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/libtommath_VS2005.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libtommath", "libtommath_VS2005.vcproj", "{0272C9B2-D68B-4F24-B32D-C1FD552F7E51}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0272C9B2-D68B-4F24-B32D-C1FD552F7E51}.Debug|Win32.ActiveCfg = Debug|Win32 + {0272C9B2-D68B-4F24-B32D-C1FD552F7E51}.Debug|Win32.Build.0 = Debug|Win32 + {0272C9B2-D68B-4F24-B32D-C1FD552F7E51}.Release|Win32.ActiveCfg = Release|Win32 + {0272C9B2-D68B-4F24-B32D-C1FD552F7E51}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/xmhf-64/xmhf/third-party/libtommath/libtommath_VS2005.vcproj b/xmhf-64/xmhf/third-party/libtommath/libtommath_VS2005.vcproj new file mode 100644 index 0000000000..71621856cc --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/libtommath_VS2005.vcproj @@ -0,0 +1,2803 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmhf-64/xmhf/third-party/libtommath/libtommath_VS2008.sln b/xmhf-64/xmhf/third-party/libtommath/libtommath_VS2008.sln new file mode 100644 index 0000000000..1327ccf7a5 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/libtommath_VS2008.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libtommath", "libtommath_VS2008.vcproj", "{42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Debug|Win32.ActiveCfg = Debug|Win32 + {42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Debug|Win32.Build.0 = Debug|Win32 + {42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Release|Win32.ActiveCfg = Release|Win32 + {42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/xmhf-64/xmhf/third-party/libtommath/libtommath_VS2008.vcproj b/xmhf-64/xmhf/third-party/libtommath/libtommath_VS2008.vcproj new file mode 100644 index 0000000000..205aec13e6 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/libtommath_VS2008.vcproj @@ -0,0 +1,2805 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmhf-64/xmhf/third-party/libtommath/logs/README b/xmhf-64/xmhf/third-party/libtommath/logs/README new file mode 100644 index 0000000000..ea20c81379 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/logs/README @@ -0,0 +1,13 @@ +To use the pretty graphs you have to first build/run the ltmtest from the root directory of the package. +Todo this type + +make timing ; ltmtest + +in the root. It will run for a while [about ten minutes on most PCs] and produce a series of .log files in logs/. + +After doing that run "gnuplot graphs.dem" to make the PNGs. If you managed todo that all so far just open index.html to view +them all :-) + +Have fun + +Tom \ No newline at end of file diff --git a/xmhf-64/xmhf/third-party/libtommath/logs/addsub.png b/xmhf-64/xmhf/third-party/libtommath/logs/addsub.png new file mode 100644 index 0000000000..a5679ac563 Binary files /dev/null and b/xmhf-64/xmhf/third-party/libtommath/logs/addsub.png differ diff --git a/xmhf-64/xmhf/third-party/libtommath/logs/expt.png b/xmhf-64/xmhf/third-party/libtommath/logs/expt.png new file mode 100644 index 0000000000..9ee8bb769f Binary files /dev/null and b/xmhf-64/xmhf/third-party/libtommath/logs/expt.png differ diff --git a/xmhf-64/xmhf/third-party/libtommath/logs/graphs.dem b/xmhf-64/xmhf/third-party/libtommath/logs/graphs.dem new file mode 100644 index 0000000000..dfaf6138a1 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/logs/graphs.dem @@ -0,0 +1,17 @@ +set terminal png +set size 1.75 +set ylabel "Cycles per Operation" +set xlabel "Operand size (bits)" + +set output "addsub.png" +plot 'add.log' smooth bezier title "Addition", 'sub.log' smooth bezier title "Subtraction" + +set output "mult.png" +plot 'sqr.log' smooth bezier title "Squaring (without Karatsuba)", 'sqr_kara.log' smooth bezier title "Squaring (Karatsuba)", 'mult.log' smooth bezier title "Multiplication (without Karatsuba)", 'mult_kara.log' smooth bezier title "Multiplication (Karatsuba)" + +set output "expt.png" +plot 'expt.log' smooth bezier title "Exptmod (Montgomery)", 'expt_dr.log' smooth bezier title "Exptmod (Dimminished Radix)", 'expt_2k.log' smooth bezier title "Exptmod (2k Reduction)" + +set output "invmod.png" +plot 'invmod.log' smooth bezier title "Modular Inverse" + diff --git a/xmhf-64/xmhf/third-party/libtommath/logs/index.html b/xmhf-64/xmhf/third-party/libtommath/logs/index.html new file mode 100644 index 0000000000..4b68c25a51 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/logs/index.html @@ -0,0 +1,27 @@ + + +LibTomMath Log Plots + + + +

Addition and Subtraction

+
+
+ +

Multipliers

+
+
+ +

Exptmod

+
+
+ +

Modular Inverse

+
+
+ + + +/* $Source: /cvs/libtom/libtommath/logs/index.html,v $ */ +/* $Revision: 1.2 $ */ +/* $Date: 2005/05/05 14:38:47 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/logs/invmod.png b/xmhf-64/xmhf/third-party/libtommath/logs/invmod.png new file mode 100644 index 0000000000..0a8a4ad771 Binary files /dev/null and b/xmhf-64/xmhf/third-party/libtommath/logs/invmod.png differ diff --git a/xmhf-64/xmhf/third-party/libtommath/logs/mult.png b/xmhf-64/xmhf/third-party/libtommath/logs/mult.png new file mode 100644 index 0000000000..4f7a4eed7b Binary files /dev/null and b/xmhf-64/xmhf/third-party/libtommath/logs/mult.png differ diff --git a/xmhf-64/xmhf/third-party/libtommath/makefile b/xmhf-64/xmhf/third-party/libtommath/makefile new file mode 100644 index 0000000000..48cffc4799 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/makefile @@ -0,0 +1,199 @@ +#Makefile for GCC +# +#Tom St Denis + +srcdir := $(dir $(lastword $(MAKEFILE_LIST))) +vpath %.c $(srcdir) +vpath %.h $(srcdir) + +#version of library +VERSION=0.42.0 + +CFLAGS += -I$(srcdir) + +ifneq ($(CC), armcc) +CFLAGS += -Wall -W -Wshadow -Wsign-compare +endif + +ifndef MAKE + MAKE=make +endif + +ifndef IGNORE_SPEED + +#for speed +ifneq ($(CC), armcc) +CFLAGS += -O3 -funroll-loops +endif + +#for size +#CFLAGS += -Os + +#x86 optimizations [should be valid for any GCC install though] +ifneq ($(CC), armcc) +CFLAGS += -fomit-frame-pointer +endif + +#debug +#CFLAGS += -g3 + +endif + +#install as this user +ifndef INSTALL_GROUP + GROUP=wheel +else + GROUP=$(INSTALL_GROUP) +endif + +ifndef INSTALL_USER + USER=root +else + USER=$(INSTALL_USER) +endif + +#default files to install +ifndef LIBNAME + LIBNAME=libtommath.a +endif + +default: ${LIBNAME} + +HEADERS=tommath.h tommath_class.h tommath_superclass.h +HEADERS:=$(patsubst %, $(srcdir)/%, $(HEADERS)) + +#LIBPATH-The directory for libtommath to be installed to. +#INCPATH-The directory to install the header files for libtommath. +#DATAPATH-The directory to install the pdf docs. +DESTDIR= +LIBPATH=/usr/lib +INCPATH=/usr/include +DATAPATH=/usr/share/doc/libtommath/pdf + +OBJECTS=bncore.o bn_mp_init.o bn_mp_clear.o bn_mp_exch.o bn_mp_grow.o bn_mp_shrink.o \ +bn_mp_clamp.o bn_mp_zero.o bn_mp_set.o bn_mp_set_int.o bn_mp_init_size.o bn_mp_copy.o \ +bn_mp_init_copy.o bn_mp_abs.o bn_mp_neg.o bn_mp_cmp_mag.o bn_mp_cmp.o bn_mp_cmp_d.o \ +bn_mp_rshd.o bn_mp_lshd.o bn_mp_mod_2d.o bn_mp_div_2d.o bn_mp_mul_2d.o bn_mp_div_2.o \ +bn_mp_mul_2.o bn_s_mp_add.o bn_s_mp_sub.o bn_fast_s_mp_mul_digs.o bn_s_mp_mul_digs.o \ +bn_fast_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs.o bn_fast_s_mp_sqr.o bn_s_mp_sqr.o \ +bn_mp_add.o bn_mp_sub.o bn_mp_karatsuba_mul.o bn_mp_mul.o bn_mp_karatsuba_sqr.o \ +bn_mp_sqr.o bn_mp_div.o bn_mp_mod.o bn_mp_add_d.o bn_mp_sub_d.o bn_mp_mul_d.o \ +bn_mp_div_d.o bn_mp_mod_d.o bn_mp_expt_d.o bn_mp_addmod.o bn_mp_submod.o \ +bn_mp_mulmod.o bn_mp_sqrmod.o bn_mp_gcd.o bn_mp_lcm.o bn_fast_mp_invmod.o bn_mp_invmod.o \ +bn_mp_reduce.o bn_mp_montgomery_setup.o bn_fast_mp_montgomery_reduce.o bn_mp_montgomery_reduce.o \ +bn_mp_exptmod_fast.o bn_mp_exptmod.o bn_mp_2expt.o bn_mp_n_root.o bn_mp_jacobi.o bn_reverse.o \ +bn_mp_count_bits.o bn_mp_read_unsigned_bin.o bn_mp_read_signed_bin.o bn_mp_to_unsigned_bin.o \ +bn_mp_to_signed_bin.o bn_mp_unsigned_bin_size.o bn_mp_signed_bin_size.o \ +bn_mp_xor.o bn_mp_and.o bn_mp_or.o bn_mp_rand.o bn_mp_montgomery_calc_normalization.o \ +bn_mp_prime_is_divisible.o bn_prime_tab.o bn_mp_prime_fermat.o bn_mp_prime_miller_rabin.o \ +bn_mp_prime_is_prime.o bn_mp_prime_next_prime.o bn_mp_dr_reduce.o \ +bn_mp_dr_is_modulus.o bn_mp_dr_setup.o bn_mp_reduce_setup.o \ +bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_div_3.o bn_s_mp_exptmod.o \ +bn_mp_reduce_2k.o bn_mp_reduce_is_2k.o bn_mp_reduce_2k_setup.o \ +bn_mp_reduce_2k_l.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_2k_setup_l.o \ +bn_mp_radix_smap.o bn_mp_read_radix.o bn_mp_toradix.o bn_mp_radix_size.o \ +bn_mp_fread.o bn_mp_fwrite.o bn_mp_cnt_lsb.o bn_error.o \ +bn_mp_init_multi.o bn_mp_clear_multi.o bn_mp_exteuclid.o bn_mp_toradix_n.o \ +bn_mp_prime_random_ex.o bn_mp_get_int.o bn_mp_sqrt.o bn_mp_is_square.o bn_mp_init_set.o \ +bn_mp_init_set_int.o bn_mp_invmod_slow.o bn_mp_prime_rabin_miller_trials.o \ +bn_mp_to_signed_bin_n.o bn_mp_to_unsigned_bin_n.o + +$(LIBNAME): $(OBJECTS) + $(AR) $(ARFLAGS) $@ $(OBJECTS) + ranlib $@ + +#make a profiled library (takes a while!!!) +# +# This will build the library with profile generation +# then run the test demo and rebuild the library. +# +# So far I've seen improvements in the MP math +profiled: + make CFLAGS="$(CFLAGS) -fprofile-arcs -DTESTING" timing + ./ltmtest + rm -f *.a *.o ltmtest + make CFLAGS="$(CFLAGS) -fbranch-probabilities" + +#make a single object profiled library +profiled_single: + perl gen.pl + $(CC) $(CFLAGS) -fprofile-arcs -DTESTING -c mpi.c -o mpi.o + $(CC) $(CFLAGS) -DTESTING -DTIMER demo/timing.c mpi.o -o ltmtest + ./ltmtest + rm -f *.o ltmtest + $(CC) $(CFLAGS) -fbranch-probabilities -DTESTING -c mpi.c -o mpi.o + $(AR) $(ARFLAGS) $(LIBNAME) mpi.o + ranlib $(LIBNAME) + +install: $(LIBNAME) + install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) + install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) + install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH) + install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) + +test: $(LIBNAME) demo/demo.o + $(CC) $(CFLAGS) demo/demo.o $(LIBNAME) -o test + +mtest: test + cd mtest ; $(CC) $(CFLAGS) mtest.c -o mtest + +timing: $(LIBNAME) + $(CC) $(CFLAGS) -DTIMER demo/timing.c $(LIBNAME) -o ltmtest + +# makes the LTM book DVI file, requires tetex, perl and makeindex [part of tetex I think] +docdvi: tommath.src + cd pics ; MAKE=${MAKE} ${MAKE} + echo "hello" > tommath.ind + perl booker.pl + latex tommath > /dev/null + latex tommath > /dev/null + makeindex tommath + latex tommath > /dev/null + +# poster, makes the single page PDF poster +poster: poster.tex + pdflatex poster + rm -f poster.aux poster.log + +# makes the LTM book PDF file, requires tetex, cleans up the LaTeX temp files +docs: docdvi + dvipdf tommath + rm -f tommath.log tommath.aux tommath.dvi tommath.idx tommath.toc tommath.lof tommath.ind tommath.ilg + cd pics ; MAKE=${MAKE} ${MAKE} clean + +#LTM user manual +mandvi: bn.tex + echo "hello" > bn.ind + latex bn > /dev/null + latex bn > /dev/null + makeindex bn + latex bn > /dev/null + +#LTM user manual [pdf] +manual: mandvi + pdflatex bn >/dev/null + rm -f bn.aux bn.dvi bn.log bn.idx bn.lof bn.out bn.toc + +pretty: + perl pretty.build + +clean: + rm -f *.bat *.pdf *.o *.a *.obj *.lib *.exe *.dll etclib/*.o demo/demo.o test ltmtest mpitest mtest/mtest mtest/mtest.exe \ + *.idx *.toc *.log *.aux *.dvi *.lof *.ind *.ilg *.ps *.log *.s mpi.c *.da *.dyn *.dpi tommath.tex `find . -type f | grep [~] | xargs` *.lo *.la + rm -rf .libs + cd etc ; MAKE=${MAKE} ${MAKE} clean + cd pics ; MAKE=${MAKE} ${MAKE} clean + +#zipup the project (take that!) +no_oops: clean + cd .. ; cvs commit + echo Scanning for scratch/dirty files + find . -type f | grep -v CVS | xargs -n 1 bash mess.sh + +zipup: clean manual poster docs + perl gen.pl ; mv mpi.c pre_gen/ ; \ + cd .. ; rm -rf ltm* libtommath-$(VERSION) ; mkdir libtommath-$(VERSION) ; \ + cp -R ./libtommath/* ./libtommath-$(VERSION)/ ; \ + tar -c libtommath-$(VERSION)/* | bzip2 -9vvc > ltm-$(VERSION).tar.bz2 ; \ + zip -9 -r ltm-$(VERSION).zip libtommath-$(VERSION)/* ; \ + mv -f ltm* ~ ; rm -rf libtommath-$(VERSION) diff --git a/xmhf-64/xmhf/third-party/libtommath/makefile.bcc b/xmhf-64/xmhf/third-party/libtommath/makefile.bcc new file mode 100644 index 0000000000..67743d962f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/makefile.bcc @@ -0,0 +1,44 @@ +# +# Borland C++Builder Makefile (makefile.bcc) +# + + +LIB = tlib +CC = bcc32 +CFLAGS = -c -O2 -I. + +OBJECTS=bncore.obj bn_mp_init.obj bn_mp_clear.obj bn_mp_exch.obj bn_mp_grow.obj bn_mp_shrink.obj \ +bn_mp_clamp.obj bn_mp_zero.obj bn_mp_set.obj bn_mp_set_int.obj bn_mp_init_size.obj bn_mp_copy.obj \ +bn_mp_init_copy.obj bn_mp_abs.obj bn_mp_neg.obj bn_mp_cmp_mag.obj bn_mp_cmp.obj bn_mp_cmp_d.obj \ +bn_mp_rshd.obj bn_mp_lshd.obj bn_mp_mod_2d.obj bn_mp_div_2d.obj bn_mp_mul_2d.obj bn_mp_div_2.obj \ +bn_mp_mul_2.obj bn_s_mp_add.obj bn_s_mp_sub.obj bn_fast_s_mp_mul_digs.obj bn_s_mp_mul_digs.obj \ +bn_fast_s_mp_mul_high_digs.obj bn_s_mp_mul_high_digs.obj bn_fast_s_mp_sqr.obj bn_s_mp_sqr.obj \ +bn_mp_add.obj bn_mp_sub.obj bn_mp_karatsuba_mul.obj bn_mp_mul.obj bn_mp_karatsuba_sqr.obj \ +bn_mp_sqr.obj bn_mp_div.obj bn_mp_mod.obj bn_mp_add_d.obj bn_mp_sub_d.obj bn_mp_mul_d.obj \ +bn_mp_div_d.obj bn_mp_mod_d.obj bn_mp_expt_d.obj bn_mp_addmod.obj bn_mp_submod.obj \ +bn_mp_mulmod.obj bn_mp_sqrmod.obj bn_mp_gcd.obj bn_mp_lcm.obj bn_fast_mp_invmod.obj bn_mp_invmod.obj \ +bn_mp_reduce.obj bn_mp_montgomery_setup.obj bn_fast_mp_montgomery_reduce.obj bn_mp_montgomery_reduce.obj \ +bn_mp_exptmod_fast.obj bn_mp_exptmod.obj bn_mp_2expt.obj bn_mp_n_root.obj bn_mp_jacobi.obj bn_reverse.obj \ +bn_mp_count_bits.obj bn_mp_read_unsigned_bin.obj bn_mp_read_signed_bin.obj bn_mp_to_unsigned_bin.obj \ +bn_mp_to_signed_bin.obj bn_mp_unsigned_bin_size.obj bn_mp_signed_bin_size.obj \ +bn_mp_xor.obj bn_mp_and.obj bn_mp_or.obj bn_mp_rand.obj bn_mp_montgomery_calc_normalization.obj \ +bn_mp_prime_is_divisible.obj bn_prime_tab.obj bn_mp_prime_fermat.obj bn_mp_prime_miller_rabin.obj \ +bn_mp_prime_is_prime.obj bn_mp_prime_next_prime.obj bn_mp_dr_reduce.obj \ +bn_mp_dr_is_modulus.obj bn_mp_dr_setup.obj bn_mp_reduce_setup.obj \ +bn_mp_toom_mul.obj bn_mp_toom_sqr.obj bn_mp_div_3.obj bn_s_mp_exptmod.obj \ +bn_mp_reduce_2k.obj bn_mp_reduce_is_2k.obj bn_mp_reduce_2k_setup.obj \ +bn_mp_reduce_2k_l.obj bn_mp_reduce_is_2k_l.obj bn_mp_reduce_2k_setup_l.obj \ +bn_mp_radix_smap.obj bn_mp_read_radix.obj bn_mp_toradix.obj bn_mp_radix_size.obj \ +bn_mp_fread.obj bn_mp_fwrite.obj bn_mp_cnt_lsb.obj bn_error.obj \ +bn_mp_init_multi.obj bn_mp_clear_multi.obj bn_mp_exteuclid.obj bn_mp_toradix_n.obj \ +bn_mp_prime_random_ex.obj bn_mp_get_int.obj bn_mp_sqrt.obj bn_mp_is_square.obj \ +bn_mp_init_set.obj bn_mp_init_set_int.obj bn_mp_invmod_slow.obj bn_mp_prime_rabin_miller_trials.obj \ +bn_mp_to_signed_bin_n.obj bn_mp_to_unsigned_bin_n.obj + +TARGET = libtommath.lib + +$(TARGET): $(OBJECTS) + +.c.obj: + $(CC) $(CFLAGS) $< + $(LIB) $(TARGET) -+$@ diff --git a/xmhf-64/xmhf/third-party/libtommath/makefile.cygwin_dll b/xmhf-64/xmhf/third-party/libtommath/makefile.cygwin_dll new file mode 100644 index 0000000000..85a9b20533 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/makefile.cygwin_dll @@ -0,0 +1,55 @@ +#Makefile for Cygwin-GCC +# +#This makefile will build a Windows DLL [doesn't require cygwin to run] in the file +#libtommath.dll. The import library is in libtommath.dll.a. Remember to add +#"-Wl,--enable-auto-import" to your client build to avoid the auto-import warnings +# +#Tom St Denis +CFLAGS += -I./ -Wall -W -Wshadow -O3 -funroll-loops -mno-cygwin + +#x86 optimizations [should be valid for any GCC install though] +CFLAGS += -fomit-frame-pointer + +default: windll + +OBJECTS=bncore.o bn_mp_init.o bn_mp_clear.o bn_mp_exch.o bn_mp_grow.o bn_mp_shrink.o \ +bn_mp_clamp.o bn_mp_zero.o bn_mp_set.o bn_mp_set_int.o bn_mp_init_size.o bn_mp_copy.o \ +bn_mp_init_copy.o bn_mp_abs.o bn_mp_neg.o bn_mp_cmp_mag.o bn_mp_cmp.o bn_mp_cmp_d.o \ +bn_mp_rshd.o bn_mp_lshd.o bn_mp_mod_2d.o bn_mp_div_2d.o bn_mp_mul_2d.o bn_mp_div_2.o \ +bn_mp_mul_2.o bn_s_mp_add.o bn_s_mp_sub.o bn_fast_s_mp_mul_digs.o bn_s_mp_mul_digs.o \ +bn_fast_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs.o bn_fast_s_mp_sqr.o bn_s_mp_sqr.o \ +bn_mp_add.o bn_mp_sub.o bn_mp_karatsuba_mul.o bn_mp_mul.o bn_mp_karatsuba_sqr.o \ +bn_mp_sqr.o bn_mp_div.o bn_mp_mod.o bn_mp_add_d.o bn_mp_sub_d.o bn_mp_mul_d.o \ +bn_mp_div_d.o bn_mp_mod_d.o bn_mp_expt_d.o bn_mp_addmod.o bn_mp_submod.o \ +bn_mp_mulmod.o bn_mp_sqrmod.o bn_mp_gcd.o bn_mp_lcm.o bn_fast_mp_invmod.o bn_mp_invmod.o \ +bn_mp_reduce.o bn_mp_montgomery_setup.o bn_fast_mp_montgomery_reduce.o bn_mp_montgomery_reduce.o \ +bn_mp_exptmod_fast.o bn_mp_exptmod.o bn_mp_2expt.o bn_mp_n_root.o bn_mp_jacobi.o bn_reverse.o \ +bn_mp_count_bits.o bn_mp_read_unsigned_bin.o bn_mp_read_signed_bin.o bn_mp_to_unsigned_bin.o \ +bn_mp_to_signed_bin.o bn_mp_unsigned_bin_size.o bn_mp_signed_bin_size.o \ +bn_mp_xor.o bn_mp_and.o bn_mp_or.o bn_mp_rand.o bn_mp_montgomery_calc_normalization.o \ +bn_mp_prime_is_divisible.o bn_prime_tab.o bn_mp_prime_fermat.o bn_mp_prime_miller_rabin.o \ +bn_mp_prime_is_prime.o bn_mp_prime_next_prime.o bn_mp_dr_reduce.o \ +bn_mp_dr_is_modulus.o bn_mp_dr_setup.o bn_mp_reduce_setup.o \ +bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_div_3.o bn_s_mp_exptmod.o \ +bn_mp_reduce_2k.o bn_mp_reduce_is_2k.o bn_mp_reduce_2k_setup.o \ +bn_mp_reduce_2k_l.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_2k_setup_l.o \ +bn_mp_radix_smap.o bn_mp_read_radix.o bn_mp_toradix.o bn_mp_radix_size.o \ +bn_mp_fread.o bn_mp_fwrite.o bn_mp_cnt_lsb.o bn_error.o \ +bn_mp_init_multi.o bn_mp_clear_multi.o bn_mp_exteuclid.o bn_mp_toradix_n.o \ +bn_mp_prime_random_ex.o bn_mp_get_int.o bn_mp_sqrt.o bn_mp_is_square.o bn_mp_init_set.o \ +bn_mp_init_set_int.o bn_mp_invmod_slow.o bn_mp_prime_rabin_miller_trials.o \ +bn_mp_to_signed_bin_n.o bn_mp_to_unsigned_bin_n.o + +# make a Windows DLL via Cygwin +windll: $(OBJECTS) + gcc -mno-cygwin -mdll -o libtommath.dll -Wl,--out-implib=libtommath.dll.a -Wl,--export-all-symbols *.o + ranlib libtommath.dll.a + +# build the test program using the windows DLL +test: $(OBJECTS) windll + gcc $(CFLAGS) demo/demo.c libtommath.dll.a -Wl,--enable-auto-import -o test -s + cd mtest ; $(CC) -O3 -fomit-frame-pointer -funroll-loops mtest.c -o mtest -s + +/* $Source: /cvs/libtom/libtommath/makefile.cygwin_dll,v $ */ +/* $Revision: 1.2 $ */ +/* $Date: 2005/05/05 14:38:45 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/makefile.icc b/xmhf-64/xmhf/third-party/libtommath/makefile.icc new file mode 100644 index 0000000000..cf70ab0c2f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/makefile.icc @@ -0,0 +1,116 @@ +#Makefile for ICC +# +#Tom St Denis +CC=icc + +CFLAGS += -I./ + +# optimize for SPEED +# +# -mcpu= can be pentium, pentiumpro (covers PII through PIII) or pentium4 +# -ax? specifies make code specifically for ? but compatible with IA-32 +# -x? specifies compile solely for ? [not specifically IA-32 compatible] +# +# where ? is +# K - PIII +# W - first P4 [Williamette] +# N - P4 Northwood +# P - P4 Prescott +# B - Blend of P4 and PM [mobile] +# +# Default to just generic max opts +CFLAGS += -O3 -xP -ip + +#install as this user +USER=root +GROUP=root + +default: libtommath.a + +#default files to install +LIBNAME=libtommath.a +HEADERS=tommath.h + +#LIBPATH-The directory for libtomcrypt to be installed to. +#INCPATH-The directory to install the header files for libtommath. +#DATAPATH-The directory to install the pdf docs. +DESTDIR= +LIBPATH=/usr/lib +INCPATH=/usr/include +DATAPATH=/usr/share/doc/libtommath/pdf + +OBJECTS=bncore.o bn_mp_init.o bn_mp_clear.o bn_mp_exch.o bn_mp_grow.o bn_mp_shrink.o \ +bn_mp_clamp.o bn_mp_zero.o bn_mp_set.o bn_mp_set_int.o bn_mp_init_size.o bn_mp_copy.o \ +bn_mp_init_copy.o bn_mp_abs.o bn_mp_neg.o bn_mp_cmp_mag.o bn_mp_cmp.o bn_mp_cmp_d.o \ +bn_mp_rshd.o bn_mp_lshd.o bn_mp_mod_2d.o bn_mp_div_2d.o bn_mp_mul_2d.o bn_mp_div_2.o \ +bn_mp_mul_2.o bn_s_mp_add.o bn_s_mp_sub.o bn_fast_s_mp_mul_digs.o bn_s_mp_mul_digs.o \ +bn_fast_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs.o bn_fast_s_mp_sqr.o bn_s_mp_sqr.o \ +bn_mp_add.o bn_mp_sub.o bn_mp_karatsuba_mul.o bn_mp_mul.o bn_mp_karatsuba_sqr.o \ +bn_mp_sqr.o bn_mp_div.o bn_mp_mod.o bn_mp_add_d.o bn_mp_sub_d.o bn_mp_mul_d.o \ +bn_mp_div_d.o bn_mp_mod_d.o bn_mp_expt_d.o bn_mp_addmod.o bn_mp_submod.o \ +bn_mp_mulmod.o bn_mp_sqrmod.o bn_mp_gcd.o bn_mp_lcm.o bn_fast_mp_invmod.o bn_mp_invmod.o \ +bn_mp_reduce.o bn_mp_montgomery_setup.o bn_fast_mp_montgomery_reduce.o bn_mp_montgomery_reduce.o \ +bn_mp_exptmod_fast.o bn_mp_exptmod.o bn_mp_2expt.o bn_mp_n_root.o bn_mp_jacobi.o bn_reverse.o \ +bn_mp_count_bits.o bn_mp_read_unsigned_bin.o bn_mp_read_signed_bin.o bn_mp_to_unsigned_bin.o \ +bn_mp_to_signed_bin.o bn_mp_unsigned_bin_size.o bn_mp_signed_bin_size.o \ +bn_mp_xor.o bn_mp_and.o bn_mp_or.o bn_mp_rand.o bn_mp_montgomery_calc_normalization.o \ +bn_mp_prime_is_divisible.o bn_prime_tab.o bn_mp_prime_fermat.o bn_mp_prime_miller_rabin.o \ +bn_mp_prime_is_prime.o bn_mp_prime_next_prime.o bn_mp_dr_reduce.o \ +bn_mp_dr_is_modulus.o bn_mp_dr_setup.o bn_mp_reduce_setup.o \ +bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_div_3.o bn_s_mp_exptmod.o \ +bn_mp_reduce_2k.o bn_mp_reduce_is_2k.o bn_mp_reduce_2k_setup.o \ +bn_mp_reduce_2k_l.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_2k_setup_l.o \ +bn_mp_radix_smap.o bn_mp_read_radix.o bn_mp_toradix.o bn_mp_radix_size.o \ +bn_mp_fread.o bn_mp_fwrite.o bn_mp_cnt_lsb.o bn_error.o \ +bn_mp_init_multi.o bn_mp_clear_multi.o bn_mp_exteuclid.o bn_mp_toradix_n.o \ +bn_mp_prime_random_ex.o bn_mp_get_int.o bn_mp_sqrt.o bn_mp_is_square.o bn_mp_init_set.o \ +bn_mp_init_set_int.o bn_mp_invmod_slow.o bn_mp_prime_rabin_miller_trials.o \ +bn_mp_to_signed_bin_n.o bn_mp_to_unsigned_bin_n.o + +libtommath.a: $(OBJECTS) + $(AR) $(ARFLAGS) libtommath.a $(OBJECTS) + ranlib libtommath.a + +#make a profiled library (takes a while!!!) +# +# This will build the library with profile generation +# then run the test demo and rebuild the library. +# +# So far I've seen improvements in the MP math +profiled: + make -f makefile.icc CFLAGS="$(CFLAGS) -prof_gen -DTESTING" timing + ./ltmtest + rm -f *.a *.o ltmtest + make -f makefile.icc CFLAGS="$(CFLAGS) -prof_use" + +#make a single object profiled library +profiled_single: + perl gen.pl + $(CC) $(CFLAGS) -prof_gen -DTESTING -c mpi.c -o mpi.o + $(CC) $(CFLAGS) -DTESTING -DTIMER demo/demo.c mpi.o -o ltmtest + ./ltmtest + rm -f *.o ltmtest + $(CC) $(CFLAGS) -prof_use -ip -DTESTING -c mpi.c -o mpi.o + $(AR) $(ARFLAGS) libtommath.a mpi.o + ranlib libtommath.a + +install: libtommath.a + install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) + install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) + install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH) + install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) + +test: libtommath.a demo/demo.o + $(CC) demo/demo.o libtommath.a -o test + +mtest: test + cd mtest ; $(CC) $(CFLAGS) mtest.c -o mtest + +timing: libtommath.a + $(CC) $(CFLAGS) -DTIMER demo/timing.c libtommath.a -o ltmtest + +clean: + rm -f *.bat *.pdf *.o *.a *.obj *.lib *.exe *.dll etclib/*.o demo/demo.o test ltmtest mpitest mtest/mtest mtest/mtest.exe \ + *.idx *.toc *.log *.aux *.dvi *.lof *.ind *.ilg *.ps *.log *.s mpi.c *.il etc/*.il *.dyn + cd etc ; make clean + cd pics ; make clean diff --git a/xmhf-64/xmhf/third-party/libtommath/makefile.msvc b/xmhf-64/xmhf/third-party/libtommath/makefile.msvc new file mode 100644 index 0000000000..5edebec920 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/makefile.msvc @@ -0,0 +1,40 @@ +#MSVC Makefile +# +#Tom St Denis + +CFLAGS = /I. /Ox /DWIN32 /W3 /Fo$@ + +default: library + +OBJECTS=bncore.obj bn_mp_init.obj bn_mp_clear.obj bn_mp_exch.obj bn_mp_grow.obj bn_mp_shrink.obj \ +bn_mp_clamp.obj bn_mp_zero.obj bn_mp_set.obj bn_mp_set_int.obj bn_mp_init_size.obj bn_mp_copy.obj \ +bn_mp_init_copy.obj bn_mp_abs.obj bn_mp_neg.obj bn_mp_cmp_mag.obj bn_mp_cmp.obj bn_mp_cmp_d.obj \ +bn_mp_rshd.obj bn_mp_lshd.obj bn_mp_mod_2d.obj bn_mp_div_2d.obj bn_mp_mul_2d.obj bn_mp_div_2.obj \ +bn_mp_mul_2.obj bn_s_mp_add.obj bn_s_mp_sub.obj bn_fast_s_mp_mul_digs.obj bn_s_mp_mul_digs.obj \ +bn_fast_s_mp_mul_high_digs.obj bn_s_mp_mul_high_digs.obj bn_fast_s_mp_sqr.obj bn_s_mp_sqr.obj \ +bn_mp_add.obj bn_mp_sub.obj bn_mp_karatsuba_mul.obj bn_mp_mul.obj bn_mp_karatsuba_sqr.obj \ +bn_mp_sqr.obj bn_mp_div.obj bn_mp_mod.obj bn_mp_add_d.obj bn_mp_sub_d.obj bn_mp_mul_d.obj \ +bn_mp_div_d.obj bn_mp_mod_d.obj bn_mp_expt_d.obj bn_mp_addmod.obj bn_mp_submod.obj \ +bn_mp_mulmod.obj bn_mp_sqrmod.obj bn_mp_gcd.obj bn_mp_lcm.obj bn_fast_mp_invmod.obj bn_mp_invmod.obj \ +bn_mp_reduce.obj bn_mp_montgomery_setup.obj bn_fast_mp_montgomery_reduce.obj bn_mp_montgomery_reduce.obj \ +bn_mp_exptmod_fast.obj bn_mp_exptmod.obj bn_mp_2expt.obj bn_mp_n_root.obj bn_mp_jacobi.obj bn_reverse.obj \ +bn_mp_count_bits.obj bn_mp_read_unsigned_bin.obj bn_mp_read_signed_bin.obj bn_mp_to_unsigned_bin.obj \ +bn_mp_to_signed_bin.obj bn_mp_unsigned_bin_size.obj bn_mp_signed_bin_size.obj \ +bn_mp_xor.obj bn_mp_and.obj bn_mp_or.obj bn_mp_rand.obj bn_mp_montgomery_calc_normalization.obj \ +bn_mp_prime_is_divisible.obj bn_prime_tab.obj bn_mp_prime_fermat.obj bn_mp_prime_miller_rabin.obj \ +bn_mp_prime_is_prime.obj bn_mp_prime_next_prime.obj bn_mp_dr_reduce.obj \ +bn_mp_dr_is_modulus.obj bn_mp_dr_setup.obj bn_mp_reduce_setup.obj \ +bn_mp_toom_mul.obj bn_mp_toom_sqr.obj bn_mp_div_3.obj bn_s_mp_exptmod.obj \ +bn_mp_reduce_2k.obj bn_mp_reduce_is_2k.obj bn_mp_reduce_2k_setup.obj \ +bn_mp_reduce_2k_l.obj bn_mp_reduce_is_2k_l.obj bn_mp_reduce_2k_setup_l.obj \ +bn_mp_radix_smap.obj bn_mp_read_radix.obj bn_mp_toradix.obj bn_mp_radix_size.obj \ +bn_mp_fread.obj bn_mp_fwrite.obj bn_mp_cnt_lsb.obj bn_error.obj \ +bn_mp_init_multi.obj bn_mp_clear_multi.obj bn_mp_exteuclid.obj bn_mp_toradix_n.obj \ +bn_mp_prime_random_ex.obj bn_mp_get_int.obj bn_mp_sqrt.obj bn_mp_is_square.obj \ +bn_mp_init_set.obj bn_mp_init_set_int.obj bn_mp_invmod_slow.obj bn_mp_prime_rabin_miller_trials.obj \ +bn_mp_to_signed_bin_n.obj bn_mp_to_unsigned_bin_n.obj + +HEADERS=tommath.h tommath_class.h tommath_superclass.h + +library: $(OBJECTS) + lib /out:tommath.lib $(OBJECTS) diff --git a/xmhf-64/xmhf/third-party/libtommath/makefile.shared b/xmhf-64/xmhf/third-party/libtommath/makefile.shared new file mode 100644 index 0000000000..f17bbbd484 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/makefile.shared @@ -0,0 +1,102 @@ +#Makefile for GCC +# +#Tom St Denis +VERSION=0:41 + +CC = libtool --mode=compile --tag=CC gcc + +CFLAGS += -I./ -Wall -W -Wshadow -Wsign-compare + +ifndef IGNORE_SPEED + +#for speed +CFLAGS += -O3 -funroll-loops + +#for size +#CFLAGS += -Os + +#x86 optimizations [should be valid for any GCC install though] +CFLAGS += -fomit-frame-pointer + +endif + +#install as this user +ifndef INSTALL_GROUP + GROUP=wheel +else + GROUP=$(INSTALL_GROUP) +endif + +ifndef INSTALL_USER + USER=root +else + USER=$(INSTALL_USER) +endif + +default: libtommath.la + +#default files to install +ifndef LIBNAME + LIBNAME=libtommath.la +endif +ifndef LIBNAME_S + LIBNAME_S=libtommath.a +endif +HEADERS=tommath.h tommath_class.h tommath_superclass.h + +#LIBPATH-The directory for libtommath to be installed to. +#INCPATH-The directory to install the header files for libtommath. +#DATAPATH-The directory to install the pdf docs. +DESTDIR= +LIBPATH=/usr/lib +INCPATH=/usr/include +DATAPATH=/usr/share/doc/libtommath/pdf + +OBJECTS=bncore.o bn_mp_init.o bn_mp_clear.o bn_mp_exch.o bn_mp_grow.o bn_mp_shrink.o \ +bn_mp_clamp.o bn_mp_zero.o bn_mp_set.o bn_mp_set_int.o bn_mp_init_size.o bn_mp_copy.o \ +bn_mp_init_copy.o bn_mp_abs.o bn_mp_neg.o bn_mp_cmp_mag.o bn_mp_cmp.o bn_mp_cmp_d.o \ +bn_mp_rshd.o bn_mp_lshd.o bn_mp_mod_2d.o bn_mp_div_2d.o bn_mp_mul_2d.o bn_mp_div_2.o \ +bn_mp_mul_2.o bn_s_mp_add.o bn_s_mp_sub.o bn_fast_s_mp_mul_digs.o bn_s_mp_mul_digs.o \ +bn_fast_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs.o bn_fast_s_mp_sqr.o bn_s_mp_sqr.o \ +bn_mp_add.o bn_mp_sub.o bn_mp_karatsuba_mul.o bn_mp_mul.o bn_mp_karatsuba_sqr.o \ +bn_mp_sqr.o bn_mp_div.o bn_mp_mod.o bn_mp_add_d.o bn_mp_sub_d.o bn_mp_mul_d.o \ +bn_mp_div_d.o bn_mp_mod_d.o bn_mp_expt_d.o bn_mp_addmod.o bn_mp_submod.o \ +bn_mp_mulmod.o bn_mp_sqrmod.o bn_mp_gcd.o bn_mp_lcm.o bn_fast_mp_invmod.o bn_mp_invmod.o \ +bn_mp_reduce.o bn_mp_montgomery_setup.o bn_fast_mp_montgomery_reduce.o bn_mp_montgomery_reduce.o \ +bn_mp_exptmod_fast.o bn_mp_exptmod.o bn_mp_2expt.o bn_mp_n_root.o bn_mp_jacobi.o bn_reverse.o \ +bn_mp_count_bits.o bn_mp_read_unsigned_bin.o bn_mp_read_signed_bin.o bn_mp_to_unsigned_bin.o \ +bn_mp_to_signed_bin.o bn_mp_unsigned_bin_size.o bn_mp_signed_bin_size.o \ +bn_mp_xor.o bn_mp_and.o bn_mp_or.o bn_mp_rand.o bn_mp_montgomery_calc_normalization.o \ +bn_mp_prime_is_divisible.o bn_prime_tab.o bn_mp_prime_fermat.o bn_mp_prime_miller_rabin.o \ +bn_mp_prime_is_prime.o bn_mp_prime_next_prime.o bn_mp_dr_reduce.o \ +bn_mp_dr_is_modulus.o bn_mp_dr_setup.o bn_mp_reduce_setup.o \ +bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_div_3.o bn_s_mp_exptmod.o \ +bn_mp_reduce_2k.o bn_mp_reduce_is_2k.o bn_mp_reduce_2k_setup.o \ +bn_mp_reduce_2k_l.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_2k_setup_l.o \ +bn_mp_radix_smap.o bn_mp_read_radix.o bn_mp_toradix.o bn_mp_radix_size.o \ +bn_mp_fread.o bn_mp_fwrite.o bn_mp_cnt_lsb.o bn_error.o \ +bn_mp_init_multi.o bn_mp_clear_multi.o bn_mp_exteuclid.o bn_mp_toradix_n.o \ +bn_mp_prime_random_ex.o bn_mp_get_int.o bn_mp_sqrt.o bn_mp_is_square.o bn_mp_init_set.o \ +bn_mp_init_set_int.o bn_mp_invmod_slow.o bn_mp_prime_rabin_miller_trials.o \ +bn_mp_to_signed_bin_n.o bn_mp_to_unsigned_bin_n.o + +objs: $(OBJECTS) + +$(LIBNAME): $(OBJECTS) + libtool --mode=link gcc *.lo -o $(LIBNAME) -rpath $(LIBPATH) -version-info $(VERSION) + +install: $(LIBNAME) + install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) + libtool --mode=install install -c $(LIBNAME) $(DESTDIR)$(LIBPATH)/$(LIBNAME) + install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) + install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) + +test: $(LIBNAME) demo/demo.o + gcc $(CFLAGS) -c demo/demo.c -o demo/demo.o + libtool --mode=link gcc -o test demo/demo.o $(LIBNAME_S) + +mtest: test + cd mtest ; gcc $(CFLAGS) mtest.c -o mtest + +timing: $(LIBNAME) + gcc $(CFLAGS) -DTIMER demo/timing.c $(LIBNAME_S) -o ltmtest diff --git a/xmhf-64/xmhf/third-party/libtommath/mess.sh b/xmhf-64/xmhf/third-party/libtommath/mess.sh new file mode 100755 index 0000000000..bf639ce3b5 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/mess.sh @@ -0,0 +1,4 @@ +#!/bin/bash +if cvs log $1 >/dev/null 2>/dev/null; then exit 0; else echo "$1 shouldn't be here" ; exit 1; fi + + diff --git a/xmhf-64/xmhf/third-party/libtommath/mtest/logtab.h b/xmhf-64/xmhf/third-party/libtommath/mtest/logtab.h new file mode 100644 index 0000000000..04c1ad3e37 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/mtest/logtab.h @@ -0,0 +1,24 @@ +const float s_logv_2[] = { + 0.000000000, 0.000000000, 1.000000000, 0.630929754, /* 0 1 2 3 */ + 0.500000000, 0.430676558, 0.386852807, 0.356207187, /* 4 5 6 7 */ + 0.333333333, 0.315464877, 0.301029996, 0.289064826, /* 8 9 10 11 */ + 0.278942946, 0.270238154, 0.262649535, 0.255958025, /* 12 13 14 15 */ + 0.250000000, 0.244650542, 0.239812467, 0.235408913, /* 16 17 18 19 */ + 0.231378213, 0.227670249, 0.224243824, 0.221064729, /* 20 21 22 23 */ + 0.218104292, 0.215338279, 0.212746054, 0.210309918, /* 24 25 26 27 */ + 0.208014598, 0.205846832, 0.203795047, 0.201849087, /* 28 29 30 31 */ + 0.200000000, 0.198239863, 0.196561632, 0.194959022, /* 32 33 34 35 */ + 0.193426404, 0.191958720, 0.190551412, 0.189200360, /* 36 37 38 39 */ + 0.187901825, 0.186652411, 0.185449023, 0.184288833, /* 40 41 42 43 */ + 0.183169251, 0.182087900, 0.181042597, 0.180031327, /* 44 45 46 47 */ + 0.179052232, 0.178103594, 0.177183820, 0.176291434, /* 48 49 50 51 */ + 0.175425064, 0.174583430, 0.173765343, 0.172969690, /* 52 53 54 55 */ + 0.172195434, 0.171441601, 0.170707280, 0.169991616, /* 56 57 58 59 */ + 0.169293808, 0.168613099, 0.167948779, 0.167300179, /* 60 61 62 63 */ + 0.166666667 +}; + + +/* $Source$ */ +/* $Revision: 0.36 $ */ +/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/mtest/mpi-config.h b/xmhf-64/xmhf/third-party/libtommath/mtest/mpi-config.h new file mode 100644 index 0000000000..d946a8f31e --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/mtest/mpi-config.h @@ -0,0 +1,90 @@ +/* Default configuration for MPI library */ +/* $ID$ */ + +#ifndef MPI_CONFIG_H_ +#define MPI_CONFIG_H_ + +/* + For boolean options, + 0 = no + 1 = yes + + Other options are documented individually. + + */ + +#ifndef MP_IOFUNC +#define MP_IOFUNC 0 /* include mp_print() ? */ +#endif + +#ifndef MP_MODARITH +#define MP_MODARITH 1 /* include modular arithmetic ? */ +#endif + +#ifndef MP_NUMTH +#define MP_NUMTH 1 /* include number theoretic functions? */ +#endif + +#ifndef MP_LOGTAB +#define MP_LOGTAB 1 /* use table of logs instead of log()? */ +#endif + +#ifndef MP_MEMSET +#define MP_MEMSET 1 /* use memset() to zero buffers? */ +#endif + +#ifndef MP_MEMCPY +#define MP_MEMCPY 1 /* use memcpy() to copy buffers? */ +#endif + +#ifndef MP_CRYPTO +#define MP_CRYPTO 1 /* erase memory on free? */ +#endif + +#ifndef MP_ARGCHK +/* + 0 = no parameter checks + 1 = runtime checks, continue execution and return an error to caller + 2 = assertions; dump core on parameter errors + */ +#define MP_ARGCHK 2 /* how to check input arguments */ +#endif + +#ifndef MP_DEBUG +#define MP_DEBUG 0 /* print diagnostic output? */ +#endif + +#ifndef MP_DEFPREC +#define MP_DEFPREC 64 /* default precision, in digits */ +#endif + +#ifndef MP_MACRO +#define MP_MACRO 1 /* use macros for frequent calls? */ +#endif + +#ifndef MP_SQUARE +#define MP_SQUARE 1 /* use separate squaring code? */ +#endif + +#ifndef MP_PTAB_SIZE +/* + When building mpprime.c, we build in a table of small prime + values to use for primality testing. The more you include, + the more space they take up. See primes.c for the possible + values (currently 16, 32, 64, 128, 256, and 6542) + */ +#define MP_PTAB_SIZE 128 /* how many built-in primes? */ +#endif + +#ifndef MP_COMPAT_MACROS +#define MP_COMPAT_MACROS 1 /* define compatibility macros? */ +#endif + +#endif /* ifndef MPI_CONFIG_H_ */ + + +/* crc==3287762869, version==2, Sat Feb 02 06:43:53 2002 */ + +/* $Source$ */ +/* $Revision: 0.36 $ */ +/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/mtest/mpi-types.h b/xmhf-64/xmhf/third-party/libtommath/mtest/mpi-types.h new file mode 100644 index 0000000000..a90f11e7a5 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/mtest/mpi-types.h @@ -0,0 +1,20 @@ +/* Type definitions generated by 'types.pl' */ +typedef char mp_sign; +typedef unsigned short mp_digit; /* 2 byte type */ +typedef unsigned int mp_word; /* 4 byte type */ +typedef unsigned int mp_size; +typedef int mp_err; + +#define MP_DIGIT_BIT (CHAR_BIT*sizeof(mp_digit)) +#define MP_DIGIT_MAX USHRT_MAX +#define MP_WORD_BIT (CHAR_BIT*sizeof(mp_word)) +#define MP_WORD_MAX UINT_MAX + +#define MP_DIGIT_SIZE 2 +#define DIGIT_FMT "%04X" +#define RADIX (MP_DIGIT_MAX+1) + + +/* $Source$ */ +/* $Revision: 0.36 $ */ +/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/mtest/mpi.c b/xmhf-64/xmhf/third-party/libtommath/mtest/mpi.c new file mode 100644 index 0000000000..27c1a9e880 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/mtest/mpi.c @@ -0,0 +1,3985 @@ +/* + mpi.c + + by Michael J. Fromberger + Copyright (C) 1998 Michael J. Fromberger, All Rights Reserved + + Arbitrary precision integer arithmetic library + + $ID$ + */ + +#include "mpi.h" +#include +#include +#include + +#if MP_DEBUG +#include + +#define DIAG(T,V) {fprintf(stderr,T);mp_print(V,stderr);fputc('\n',stderr);} +#else +#define DIAG(T,V) +#endif + +/* + If MP_LOGTAB is not defined, use the math library to compute the + logarithms on the fly. Otherwise, use the static table below. + Pick which works best for your system. + */ +#if MP_LOGTAB + +/* {{{ s_logv_2[] - log table for 2 in various bases */ + +/* + A table of the logs of 2 for various bases (the 0 and 1 entries of + this table are meaningless and should not be referenced). + + This table is used to compute output lengths for the mp_toradix() + function. Since a number n in radix r takes up about log_r(n) + digits, we estimate the output size by taking the least integer + greater than log_r(n), where: + + log_r(n) = log_2(n) * log_r(2) + + This table, therefore, is a table of log_r(2) for 2 <= r <= 36, + which are the output bases supported. + */ + +#include "logtab.h" + +/* }}} */ +#define LOG_V_2(R) s_logv_2[(R)] + +#else + +#include +#define LOG_V_2(R) (log(2.0)/log(R)) + +#endif + +/* Default precision for newly created mp_int's */ +static unsigned int s_mp_defprec = MP_DEFPREC; + +/* {{{ Digit arithmetic macros */ + +/* + When adding and multiplying digits, the results can be larger than + can be contained in an mp_digit. Thus, an mp_word is used. These + macros mask off the upper and lower digits of the mp_word (the + mp_word may be more than 2 mp_digits wide, but we only concern + ourselves with the low-order 2 mp_digits) + + If your mp_word DOES have more than 2 mp_digits, you need to + uncomment the first line, and comment out the second. + */ + +/* #define CARRYOUT(W) (((W)>>DIGIT_BIT)&MP_DIGIT_MAX) */ +#define CARRYOUT(W) ((W)>>DIGIT_BIT) +#define ACCUM(W) ((W)&MP_DIGIT_MAX) + +/* }}} */ + +/* {{{ Comparison constants */ + +#define MP_LT -1 +#define MP_EQ 0 +#define MP_GT 1 + +/* }}} */ + +/* {{{ Constant strings */ + +/* Constant strings returned by mp_strerror() */ +static const char *mp_err_string[] = { + "unknown result code", /* say what? */ + "boolean true", /* MP_OKAY, MP_YES */ + "boolean false", /* MP_NO */ + "out of memory", /* MP_MEM */ + "argument out of range", /* MP_RANGE */ + "invalid input parameter", /* MP_BADARG */ + "result is undefined" /* MP_UNDEF */ +}; + +/* Value to digit maps for radix conversion */ + +/* s_dmap_1 - standard digits and letters */ +static const char *s_dmap_1 = + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; + +#if 0 +/* s_dmap_2 - base64 ordering for digits */ +static const char *s_dmap_2 = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +#endif + +/* }}} */ + +/* {{{ Static function declarations */ + +/* + If MP_MACRO is false, these will be defined as actual functions; + otherwise, suitable macro definitions will be used. This works + around the fact that ANSI C89 doesn't support an 'inline' keyword + (although I hear C9x will ... about bloody time). At present, the + macro definitions are identical to the function bodies, but they'll + expand in place, instead of generating a function call. + + I chose these particular functions to be made into macros because + some profiling showed they are called a lot on a typical workload, + and yet they are primarily housekeeping. + */ +#if MP_MACRO == 0 + void s_mp_setz(mp_digit *dp, mp_size count); /* zero digits */ + void s_mp_copy(mp_digit *sp, mp_digit *dp, mp_size count); /* copy */ + void *s_mp_alloc(size_t nb, size_t ni); /* general allocator */ + void s_mp_free(void *ptr); /* general free function */ +#else + + /* Even if these are defined as macros, we need to respect the settings + of the MP_MEMSET and MP_MEMCPY configuration options... + */ + #if MP_MEMSET == 0 + #define s_mp_setz(dp, count) \ + {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=0;} + #else + #define s_mp_setz(dp, count) memset(dp, 0, (count) * sizeof(mp_digit)) + #endif /* MP_MEMSET */ + + #if MP_MEMCPY == 0 + #define s_mp_copy(sp, dp, count) \ + {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=(sp)[ix];} + #else + #define s_mp_copy(sp, dp, count) memcpy(dp, sp, (count) * sizeof(mp_digit)) + #endif /* MP_MEMCPY */ + + #define s_mp_alloc(nb, ni) calloc(nb, ni) + #define s_mp_free(ptr) {if(ptr) free(ptr);} +#endif /* MP_MACRO */ + +mp_err s_mp_grow(mp_int *mp, mp_size min); /* increase allocated size */ +mp_err s_mp_pad(mp_int *mp, mp_size min); /* left pad with zeroes */ + +void s_mp_clamp(mp_int *mp); /* clip leading zeroes */ + +void s_mp_exch(mp_int *a, mp_int *b); /* swap a and b in place */ + +mp_err s_mp_lshd(mp_int *mp, mp_size p); /* left-shift by p digits */ +void s_mp_rshd(mp_int *mp, mp_size p); /* right-shift by p digits */ +void s_mp_div_2d(mp_int *mp, mp_digit d); /* divide by 2^d in place */ +void s_mp_mod_2d(mp_int *mp, mp_digit d); /* modulo 2^d in place */ +mp_err s_mp_mul_2d(mp_int *mp, mp_digit d); /* multiply by 2^d in place*/ +void s_mp_div_2(mp_int *mp); /* divide by 2 in place */ +mp_err s_mp_mul_2(mp_int *mp); /* multiply by 2 in place */ +mp_digit s_mp_norm(mp_int *a, mp_int *b); /* normalize for division */ +mp_err s_mp_add_d(mp_int *mp, mp_digit d); /* unsigned digit addition */ +mp_err s_mp_sub_d(mp_int *mp, mp_digit d); /* unsigned digit subtract */ +mp_err s_mp_mul_d(mp_int *mp, mp_digit d); /* unsigned digit multiply */ +mp_err s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r); + /* unsigned digit divide */ +mp_err s_mp_reduce(mp_int *x, mp_int *m, mp_int *mu); + /* Barrett reduction */ +mp_err s_mp_add(mp_int *a, mp_int *b); /* magnitude addition */ +mp_err s_mp_sub(mp_int *a, mp_int *b); /* magnitude subtract */ +mp_err s_mp_mul(mp_int *a, mp_int *b); /* magnitude multiply */ +#if 0 +void s_mp_kmul(mp_digit *a, mp_digit *b, mp_digit *out, mp_size len); + /* multiply buffers in place */ +#endif +#if MP_SQUARE +mp_err s_mp_sqr(mp_int *a); /* magnitude square */ +#else +#define s_mp_sqr(a) s_mp_mul(a, a) +#endif +mp_err s_mp_div(mp_int *a, mp_int *b); /* magnitude divide */ +mp_err s_mp_2expt(mp_int *a, mp_digit k); /* a = 2^k */ +int s_mp_cmp(mp_int *a, mp_int *b); /* magnitude comparison */ +int s_mp_cmp_d(mp_int *a, mp_digit d); /* magnitude digit compare */ +int s_mp_ispow2(mp_int *v); /* is v a power of 2? */ +int s_mp_ispow2d(mp_digit d); /* is d a power of 2? */ + +int s_mp_tovalue(char ch, int r); /* convert ch to value */ +char s_mp_todigit(int val, int r, int low); /* convert val to digit */ +int s_mp_outlen(int bits, int r); /* output length in bytes */ + +/* }}} */ + +/* {{{ Default precision manipulation */ + +unsigned int mp_get_prec(void) +{ + return s_mp_defprec; + +} /* end mp_get_prec() */ + +void mp_set_prec(unsigned int prec) +{ + if(prec == 0) + s_mp_defprec = MP_DEFPREC; + else + s_mp_defprec = prec; + +} /* end mp_set_prec() */ + +/* }}} */ + +/*------------------------------------------------------------------------*/ +/* {{{ mp_init(mp) */ + +/* + mp_init(mp) + + Initialize a new zero-valued mp_int. Returns MP_OKAY if successful, + MP_MEM if memory could not be allocated for the structure. + */ + +mp_err mp_init(mp_int *mp) +{ + return mp_init_size(mp, s_mp_defprec); + +} /* end mp_init() */ + +/* }}} */ + +/* {{{ mp_init_array(mp[], count) */ + +mp_err mp_init_array(mp_int mp[], int count) +{ + mp_err res; + int pos; + + ARGCHK(mp !=NULL && count > 0, MP_BADARG); + + for(pos = 0; pos < count; ++pos) { + if((res = mp_init(&mp[pos])) != MP_OKAY) + goto CLEANUP; + } + + return MP_OKAY; + + CLEANUP: + while(--pos >= 0) + mp_clear(&mp[pos]); + + return res; + +} /* end mp_init_array() */ + +/* }}} */ + +/* {{{ mp_init_size(mp, prec) */ + +/* + mp_init_size(mp, prec) + + Initialize a new zero-valued mp_int with at least the given + precision; returns MP_OKAY if successful, or MP_MEM if memory could + not be allocated for the structure. + */ + +mp_err mp_init_size(mp_int *mp, mp_size prec) +{ + ARGCHK(mp != NULL && prec > 0, MP_BADARG); + + if((DIGITS(mp) = s_mp_alloc(prec, sizeof(mp_digit))) == NULL) + return MP_MEM; + + SIGN(mp) = MP_ZPOS; + USED(mp) = 1; + ALLOC(mp) = prec; + + return MP_OKAY; + +} /* end mp_init_size() */ + +/* }}} */ + +/* {{{ mp_init_copy(mp, from) */ + +/* + mp_init_copy(mp, from) + + Initialize mp as an exact copy of from. Returns MP_OKAY if + successful, MP_MEM if memory could not be allocated for the new + structure. + */ + +mp_err mp_init_copy(mp_int *mp, mp_int *from) +{ + ARGCHK(mp != NULL && from != NULL, MP_BADARG); + + if(mp == from) + return MP_OKAY; + + if((DIGITS(mp) = s_mp_alloc(USED(from), sizeof(mp_digit))) == NULL) + return MP_MEM; + + s_mp_copy(DIGITS(from), DIGITS(mp), USED(from)); + USED(mp) = USED(from); + ALLOC(mp) = USED(from); + SIGN(mp) = SIGN(from); + + return MP_OKAY; + +} /* end mp_init_copy() */ + +/* }}} */ + +/* {{{ mp_copy(from, to) */ + +/* + mp_copy(from, to) + + Copies the mp_int 'from' to the mp_int 'to'. It is presumed that + 'to' has already been initialized (if not, use mp_init_copy() + instead). If 'from' and 'to' are identical, nothing happens. + */ + +mp_err mp_copy(mp_int *from, mp_int *to) +{ + ARGCHK(from != NULL && to != NULL, MP_BADARG); + + if(from == to) + return MP_OKAY; + + { /* copy */ + mp_digit *tmp; + + /* + If the allocated buffer in 'to' already has enough space to hold + all the used digits of 'from', we'll re-use it to avoid hitting + the memory allocater more than necessary; otherwise, we'd have + to grow anyway, so we just allocate a hunk and make the copy as + usual + */ + if(ALLOC(to) >= USED(from)) { + s_mp_setz(DIGITS(to) + USED(from), ALLOC(to) - USED(from)); + s_mp_copy(DIGITS(from), DIGITS(to), USED(from)); + + } else { + if((tmp = s_mp_alloc(USED(from), sizeof(mp_digit))) == NULL) + return MP_MEM; + + s_mp_copy(DIGITS(from), tmp, USED(from)); + + if(DIGITS(to) != NULL) { +#if MP_CRYPTO + s_mp_setz(DIGITS(to), ALLOC(to)); +#endif + s_mp_free(DIGITS(to)); + } + + DIGITS(to) = tmp; + ALLOC(to) = USED(from); + } + + /* Copy the precision and sign from the original */ + USED(to) = USED(from); + SIGN(to) = SIGN(from); + } /* end copy */ + + return MP_OKAY; + +} /* end mp_copy() */ + +/* }}} */ + +/* {{{ mp_exch(mp1, mp2) */ + +/* + mp_exch(mp1, mp2) + + Exchange mp1 and mp2 without allocating any intermediate memory + (well, unless you count the stack space needed for this call and the + locals it creates...). This cannot fail. + */ + +void mp_exch(mp_int *mp1, mp_int *mp2) +{ +#if MP_ARGCHK == 2 + assert(mp1 != NULL && mp2 != NULL); +#else + if(mp1 == NULL || mp2 == NULL) + return; +#endif + + s_mp_exch(mp1, mp2); + +} /* end mp_exch() */ + +/* }}} */ + +/* {{{ mp_clear(mp) */ + +/* + mp_clear(mp) + + Release the storage used by an mp_int, and void its fields so that + if someone calls mp_clear() again for the same int later, we won't + get tollchocked. + */ + +void mp_clear(mp_int *mp) +{ + if(mp == NULL) + return; + + if(DIGITS(mp) != NULL) { +#if MP_CRYPTO + s_mp_setz(DIGITS(mp), ALLOC(mp)); +#endif + s_mp_free(DIGITS(mp)); + DIGITS(mp) = NULL; + } + + USED(mp) = 0; + ALLOC(mp) = 0; + +} /* end mp_clear() */ + +/* }}} */ + +/* {{{ mp_clear_array(mp[], count) */ + +void mp_clear_array(mp_int mp[], int count) +{ + ARGCHK(mp != NULL && count > 0, MP_BADARG); + + while(--count >= 0) + mp_clear(&mp[count]); + +} /* end mp_clear_array() */ + +/* }}} */ + +/* {{{ mp_zero(mp) */ + +/* + mp_zero(mp) + + Set mp to zero. Does not change the allocated size of the structure, + and therefore cannot fail (except on a bad argument, which we ignore) + */ +void mp_zero(mp_int *mp) +{ + if(mp == NULL) + return; + + s_mp_setz(DIGITS(mp), ALLOC(mp)); + USED(mp) = 1; + SIGN(mp) = MP_ZPOS; + +} /* end mp_zero() */ + +/* }}} */ + +/* {{{ mp_set(mp, d) */ + +void mp_set(mp_int *mp, mp_digit d) +{ + if(mp == NULL) + return; + + mp_zero(mp); + DIGIT(mp, 0) = d; + +} /* end mp_set() */ + +/* }}} */ + +/* {{{ mp_set_int(mp, z) */ + +mp_err mp_set_int(mp_int *mp, long z) +{ + int ix; + unsigned long v = abs(z); + mp_err res; + + ARGCHK(mp != NULL, MP_BADARG); + + mp_zero(mp); + if(z == 0) + return MP_OKAY; /* shortcut for zero */ + + for(ix = sizeof(long) - 1; ix >= 0; ix--) { + + if((res = s_mp_mul_2d(mp, CHAR_BIT)) != MP_OKAY) + return res; + + res = s_mp_add_d(mp, + (mp_digit)((v >> (ix * CHAR_BIT)) & UCHAR_MAX)); + if(res != MP_OKAY) + return res; + + } + + if(z < 0) + SIGN(mp) = MP_NEG; + + return MP_OKAY; + +} /* end mp_set_int() */ + +/* }}} */ + +/*------------------------------------------------------------------------*/ +/* {{{ Digit arithmetic */ + +/* {{{ mp_add_d(a, d, b) */ + +/* + mp_add_d(a, d, b) + + Compute the sum b = a + d, for a single digit d. Respects the sign of + its primary addend (single digits are unsigned anyway). + */ + +mp_err mp_add_d(mp_int *a, mp_digit d, mp_int *b) +{ + mp_err res = MP_OKAY; + + ARGCHK(a != NULL && b != NULL, MP_BADARG); + + if((res = mp_copy(a, b)) != MP_OKAY) + return res; + + if(SIGN(b) == MP_ZPOS) { + res = s_mp_add_d(b, d); + } else if(s_mp_cmp_d(b, d) >= 0) { + res = s_mp_sub_d(b, d); + } else { + SIGN(b) = MP_ZPOS; + + DIGIT(b, 0) = d - DIGIT(b, 0); + } + + return res; + +} /* end mp_add_d() */ + +/* }}} */ + +/* {{{ mp_sub_d(a, d, b) */ + +/* + mp_sub_d(a, d, b) + + Compute the difference b = a - d, for a single digit d. Respects the + sign of its subtrahend (single digits are unsigned anyway). + */ + +mp_err mp_sub_d(mp_int *a, mp_digit d, mp_int *b) +{ + mp_err res; + + ARGCHK(a != NULL && b != NULL, MP_BADARG); + + if((res = mp_copy(a, b)) != MP_OKAY) + return res; + + if(SIGN(b) == MP_NEG) { + if((res = s_mp_add_d(b, d)) != MP_OKAY) + return res; + + } else if(s_mp_cmp_d(b, d) >= 0) { + if((res = s_mp_sub_d(b, d)) != MP_OKAY) + return res; + + } else { + mp_neg(b, b); + + DIGIT(b, 0) = d - DIGIT(b, 0); + SIGN(b) = MP_NEG; + } + + if(s_mp_cmp_d(b, 0) == 0) + SIGN(b) = MP_ZPOS; + + return MP_OKAY; + +} /* end mp_sub_d() */ + +/* }}} */ + +/* {{{ mp_mul_d(a, d, b) */ + +/* + mp_mul_d(a, d, b) + + Compute the product b = a * d, for a single digit d. Respects the sign + of its multiplicand (single digits are unsigned anyway) + */ + +mp_err mp_mul_d(mp_int *a, mp_digit d, mp_int *b) +{ + mp_err res; + + ARGCHK(a != NULL && b != NULL, MP_BADARG); + + if(d == 0) { + mp_zero(b); + return MP_OKAY; + } + + if((res = mp_copy(a, b)) != MP_OKAY) + return res; + + res = s_mp_mul_d(b, d); + + return res; + +} /* end mp_mul_d() */ + +/* }}} */ + +/* {{{ mp_mul_2(a, c) */ + +mp_err mp_mul_2(mp_int *a, mp_int *c) +{ + mp_err res; + + ARGCHK(a != NULL && c != NULL, MP_BADARG); + + if((res = mp_copy(a, c)) != MP_OKAY) + return res; + + return s_mp_mul_2(c); + +} /* end mp_mul_2() */ + +/* }}} */ + +/* {{{ mp_div_d(a, d, q, r) */ + +/* + mp_div_d(a, d, q, r) + + Compute the quotient q = a / d and remainder r = a mod d, for a + single digit d. Respects the sign of its divisor (single digits are + unsigned anyway). + */ + +mp_err mp_div_d(mp_int *a, mp_digit d, mp_int *q, mp_digit *r) +{ + mp_err res; + mp_digit rem; + int pow; + + ARGCHK(a != NULL, MP_BADARG); + + if(d == 0) + return MP_RANGE; + + /* Shortcut for powers of two ... */ + if((pow = s_mp_ispow2d(d)) >= 0) { + mp_digit mask; + + mask = (1 << pow) - 1; + rem = DIGIT(a, 0) & mask; + + if(q) { + mp_copy(a, q); + s_mp_div_2d(q, pow); + } + + if(r) + *r = rem; + + return MP_OKAY; + } + + /* + If the quotient is actually going to be returned, we'll try to + avoid hitting the memory allocator by copying the dividend into it + and doing the division there. This can't be any _worse_ than + always copying, and will sometimes be better (since it won't make + another copy) + + If it's not going to be returned, we need to allocate a temporary + to hold the quotient, which will just be discarded. + */ + if(q) { + if((res = mp_copy(a, q)) != MP_OKAY) + return res; + + res = s_mp_div_d(q, d, &rem); + if(s_mp_cmp_d(q, 0) == MP_EQ) + SIGN(q) = MP_ZPOS; + + } else { + mp_int qp; + + if((res = mp_init_copy(&qp, a)) != MP_OKAY) + return res; + + res = s_mp_div_d(&qp, d, &rem); + if(s_mp_cmp_d(&qp, 0) == 0) + SIGN(&qp) = MP_ZPOS; + + mp_clear(&qp); + } + + if(r) + *r = rem; + + return res; + +} /* end mp_div_d() */ + +/* }}} */ + +/* {{{ mp_div_2(a, c) */ + +/* + mp_div_2(a, c) + + Compute c = a / 2, disregarding the remainder. + */ + +mp_err mp_div_2(mp_int *a, mp_int *c) +{ + mp_err res; + + ARGCHK(a != NULL && c != NULL, MP_BADARG); + + if((res = mp_copy(a, c)) != MP_OKAY) + return res; + + s_mp_div_2(c); + + return MP_OKAY; + +} /* end mp_div_2() */ + +/* }}} */ + +/* {{{ mp_expt_d(a, d, b) */ + +mp_err mp_expt_d(mp_int *a, mp_digit d, mp_int *c) +{ + mp_int s, x; + mp_err res; + + ARGCHK(a != NULL && c != NULL, MP_BADARG); + + if((res = mp_init(&s)) != MP_OKAY) + return res; + if((res = mp_init_copy(&x, a)) != MP_OKAY) + goto X; + + DIGIT(&s, 0) = 1; + + while(d != 0) { + if(d & 1) { + if((res = s_mp_mul(&s, &x)) != MP_OKAY) + goto CLEANUP; + } + + d >>= 1; + + if((res = s_mp_sqr(&x)) != MP_OKAY) + goto CLEANUP; + } + + s_mp_exch(&s, c); + +CLEANUP: + mp_clear(&x); +X: + mp_clear(&s); + + return res; + +} /* end mp_expt_d() */ + +/* }}} */ + +/* }}} */ + +/*------------------------------------------------------------------------*/ +/* {{{ Full arithmetic */ + +/* {{{ mp_abs(a, b) */ + +/* + mp_abs(a, b) + + Compute b = |a|. 'a' and 'b' may be identical. + */ + +mp_err mp_abs(mp_int *a, mp_int *b) +{ + mp_err res; + + ARGCHK(a != NULL && b != NULL, MP_BADARG); + + if((res = mp_copy(a, b)) != MP_OKAY) + return res; + + SIGN(b) = MP_ZPOS; + + return MP_OKAY; + +} /* end mp_abs() */ + +/* }}} */ + +/* {{{ mp_neg(a, b) */ + +/* + mp_neg(a, b) + + Compute b = -a. 'a' and 'b' may be identical. + */ + +mp_err mp_neg(mp_int *a, mp_int *b) +{ + mp_err res; + + ARGCHK(a != NULL && b != NULL, MP_BADARG); + + if((res = mp_copy(a, b)) != MP_OKAY) + return res; + + if(s_mp_cmp_d(b, 0) == MP_EQ) + SIGN(b) = MP_ZPOS; + else + SIGN(b) = (SIGN(b) == MP_NEG) ? MP_ZPOS : MP_NEG; + + return MP_OKAY; + +} /* end mp_neg() */ + +/* }}} */ + +/* {{{ mp_add(a, b, c) */ + +/* + mp_add(a, b, c) + + Compute c = a + b. All parameters may be identical. + */ + +mp_err mp_add(mp_int *a, mp_int *b, mp_int *c) +{ + mp_err res; + int cmp; + + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + + if(SIGN(a) == SIGN(b)) { /* same sign: add values, keep sign */ + + /* Commutativity of addition lets us do this in either order, + so we avoid having to use a temporary even if the result + is supposed to replace the output + */ + if(c == b) { + if((res = s_mp_add(c, a)) != MP_OKAY) + return res; + } else { + if(c != a && (res = mp_copy(a, c)) != MP_OKAY) + return res; + + if((res = s_mp_add(c, b)) != MP_OKAY) + return res; + } + + } else if((cmp = s_mp_cmp(a, b)) > 0) { /* different sign: a > b */ + + /* If the output is going to be clobbered, we will use a temporary + variable; otherwise, we'll do it without touching the memory + allocator at all, if possible + */ + if(c == b) { + mp_int tmp; + + if((res = mp_init_copy(&tmp, a)) != MP_OKAY) + return res; + if((res = s_mp_sub(&tmp, b)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + s_mp_exch(&tmp, c); + mp_clear(&tmp); + + } else { + + if(c != a && (res = mp_copy(a, c)) != MP_OKAY) + return res; + if((res = s_mp_sub(c, b)) != MP_OKAY) + return res; + + } + + } else if(cmp == 0) { /* different sign, a == b */ + + mp_zero(c); + return MP_OKAY; + + } else { /* different sign: a < b */ + + /* See above... */ + if(c == a) { + mp_int tmp; + + if((res = mp_init_copy(&tmp, b)) != MP_OKAY) + return res; + if((res = s_mp_sub(&tmp, a)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + s_mp_exch(&tmp, c); + mp_clear(&tmp); + + } else { + + if(c != b && (res = mp_copy(b, c)) != MP_OKAY) + return res; + if((res = s_mp_sub(c, a)) != MP_OKAY) + return res; + + } + } + + if(USED(c) == 1 && DIGIT(c, 0) == 0) + SIGN(c) = MP_ZPOS; + + return MP_OKAY; + +} /* end mp_add() */ + +/* }}} */ + +/* {{{ mp_sub(a, b, c) */ + +/* + mp_sub(a, b, c) + + Compute c = a - b. All parameters may be identical. + */ + +mp_err mp_sub(mp_int *a, mp_int *b, mp_int *c) +{ + mp_err res; + int cmp; + + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + + if(SIGN(a) != SIGN(b)) { + if(c == a) { + if((res = s_mp_add(c, b)) != MP_OKAY) + return res; + } else { + if(c != b && ((res = mp_copy(b, c)) != MP_OKAY)) + return res; + if((res = s_mp_add(c, a)) != MP_OKAY) + return res; + SIGN(c) = SIGN(a); + } + + } else if((cmp = s_mp_cmp(a, b)) > 0) { /* Same sign, a > b */ + if(c == b) { + mp_int tmp; + + if((res = mp_init_copy(&tmp, a)) != MP_OKAY) + return res; + if((res = s_mp_sub(&tmp, b)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + s_mp_exch(&tmp, c); + mp_clear(&tmp); + + } else { + if(c != a && ((res = mp_copy(a, c)) != MP_OKAY)) + return res; + + if((res = s_mp_sub(c, b)) != MP_OKAY) + return res; + } + + } else if(cmp == 0) { /* Same sign, equal magnitude */ + mp_zero(c); + return MP_OKAY; + + } else { /* Same sign, b > a */ + if(c == a) { + mp_int tmp; + + if((res = mp_init_copy(&tmp, b)) != MP_OKAY) + return res; + + if((res = s_mp_sub(&tmp, a)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + s_mp_exch(&tmp, c); + mp_clear(&tmp); + + } else { + if(c != b && ((res = mp_copy(b, c)) != MP_OKAY)) + return res; + + if((res = s_mp_sub(c, a)) != MP_OKAY) + return res; + } + + SIGN(c) = !SIGN(b); + } + + if(USED(c) == 1 && DIGIT(c, 0) == 0) + SIGN(c) = MP_ZPOS; + + return MP_OKAY; + +} /* end mp_sub() */ + +/* }}} */ + +/* {{{ mp_mul(a, b, c) */ + +/* + mp_mul(a, b, c) + + Compute c = a * b. All parameters may be identical. + */ + +mp_err mp_mul(mp_int *a, mp_int *b, mp_int *c) +{ + mp_err res; + mp_sign sgn; + + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + + sgn = (SIGN(a) == SIGN(b)) ? MP_ZPOS : MP_NEG; + + if(c == b) { + if((res = s_mp_mul(c, a)) != MP_OKAY) + return res; + + } else { + if((res = mp_copy(a, c)) != MP_OKAY) + return res; + + if((res = s_mp_mul(c, b)) != MP_OKAY) + return res; + } + + if(sgn == MP_ZPOS || s_mp_cmp_d(c, 0) == MP_EQ) + SIGN(c) = MP_ZPOS; + else + SIGN(c) = sgn; + + return MP_OKAY; + +} /* end mp_mul() */ + +/* }}} */ + +/* {{{ mp_mul_2d(a, d, c) */ + +/* + mp_mul_2d(a, d, c) + + Compute c = a * 2^d. a may be the same as c. + */ + +mp_err mp_mul_2d(mp_int *a, mp_digit d, mp_int *c) +{ + mp_err res; + + ARGCHK(a != NULL && c != NULL, MP_BADARG); + + if((res = mp_copy(a, c)) != MP_OKAY) + return res; + + if(d == 0) + return MP_OKAY; + + return s_mp_mul_2d(c, d); + +} /* end mp_mul() */ + +/* }}} */ + +/* {{{ mp_sqr(a, b) */ + +#if MP_SQUARE +mp_err mp_sqr(mp_int *a, mp_int *b) +{ + mp_err res; + + ARGCHK(a != NULL && b != NULL, MP_BADARG); + + if((res = mp_copy(a, b)) != MP_OKAY) + return res; + + if((res = s_mp_sqr(b)) != MP_OKAY) + return res; + + SIGN(b) = MP_ZPOS; + + return MP_OKAY; + +} /* end mp_sqr() */ +#endif + +/* }}} */ + +/* {{{ mp_div(a, b, q, r) */ + +/* + mp_div(a, b, q, r) + + Compute q = a / b and r = a mod b. Input parameters may be re-used + as output parameters. If q or r is NULL, that portion of the + computation will be discarded (although it will still be computed) + + Pay no attention to the hacker behind the curtain. + */ + +mp_err mp_div(mp_int *a, mp_int *b, mp_int *q, mp_int *r) +{ + mp_err res; + mp_int qtmp, rtmp; + int cmp; + + ARGCHK(a != NULL && b != NULL, MP_BADARG); + + if(mp_cmp_z(b) == MP_EQ) + return MP_RANGE; + + /* If a <= b, we can compute the solution without division, and + avoid any memory allocation + */ + if((cmp = s_mp_cmp(a, b)) < 0) { + if(r) { + if((res = mp_copy(a, r)) != MP_OKAY) + return res; + } + + if(q) + mp_zero(q); + + return MP_OKAY; + + } else if(cmp == 0) { + + /* Set quotient to 1, with appropriate sign */ + if(q) { + int qneg = (SIGN(a) != SIGN(b)); + + mp_set(q, 1); + if(qneg) + SIGN(q) = MP_NEG; + } + + if(r) + mp_zero(r); + + return MP_OKAY; + } + + /* If we get here, it means we actually have to do some division */ + + /* Set up some temporaries... */ + if((res = mp_init_copy(&qtmp, a)) != MP_OKAY) + return res; + if((res = mp_init_copy(&rtmp, b)) != MP_OKAY) + goto CLEANUP; + + if((res = s_mp_div(&qtmp, &rtmp)) != MP_OKAY) + goto CLEANUP; + + /* Compute the signs for the output */ + SIGN(&rtmp) = SIGN(a); /* Sr = Sa */ + if(SIGN(a) == SIGN(b)) + SIGN(&qtmp) = MP_ZPOS; /* Sq = MP_ZPOS if Sa = Sb */ + else + SIGN(&qtmp) = MP_NEG; /* Sq = MP_NEG if Sa != Sb */ + + if(s_mp_cmp_d(&qtmp, 0) == MP_EQ) + SIGN(&qtmp) = MP_ZPOS; + if(s_mp_cmp_d(&rtmp, 0) == MP_EQ) + SIGN(&rtmp) = MP_ZPOS; + + /* Copy output, if it is needed */ + if(q) + s_mp_exch(&qtmp, q); + + if(r) + s_mp_exch(&rtmp, r); + +CLEANUP: + mp_clear(&rtmp); + mp_clear(&qtmp); + + return res; + +} /* end mp_div() */ + +/* }}} */ + +/* {{{ mp_div_2d(a, d, q, r) */ + +mp_err mp_div_2d(mp_int *a, mp_digit d, mp_int *q, mp_int *r) +{ + mp_err res; + + ARGCHK(a != NULL, MP_BADARG); + + if(q) { + if((res = mp_copy(a, q)) != MP_OKAY) + return res; + + s_mp_div_2d(q, d); + } + + if(r) { + if((res = mp_copy(a, r)) != MP_OKAY) + return res; + + s_mp_mod_2d(r, d); + } + + return MP_OKAY; + +} /* end mp_div_2d() */ + +/* }}} */ + +/* {{{ mp_expt(a, b, c) */ + +/* + mp_expt(a, b, c) + + Compute c = a ** b, that is, raise a to the b power. Uses a + standard iterative square-and-multiply technique. + */ + +mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c) +{ + mp_int s, x; + mp_err res; + mp_digit d; + int dig, bit; + + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + + if(mp_cmp_z(b) < 0) + return MP_RANGE; + + if((res = mp_init(&s)) != MP_OKAY) + return res; + + mp_set(&s, 1); + + if((res = mp_init_copy(&x, a)) != MP_OKAY) + goto X; + + /* Loop over low-order digits in ascending order */ + for(dig = 0; dig < (USED(b) - 1); dig++) { + d = DIGIT(b, dig); + + /* Loop over bits of each non-maximal digit */ + for(bit = 0; bit < DIGIT_BIT; bit++) { + if(d & 1) { + if((res = s_mp_mul(&s, &x)) != MP_OKAY) + goto CLEANUP; + } + + d >>= 1; + + if((res = s_mp_sqr(&x)) != MP_OKAY) + goto CLEANUP; + } + } + + /* Consider now the last digit... */ + d = DIGIT(b, dig); + + while(d) { + if(d & 1) { + if((res = s_mp_mul(&s, &x)) != MP_OKAY) + goto CLEANUP; + } + + d >>= 1; + + if((res = s_mp_sqr(&x)) != MP_OKAY) + goto CLEANUP; + } + + if(mp_iseven(b)) + SIGN(&s) = SIGN(a); + + res = mp_copy(&s, c); + +CLEANUP: + mp_clear(&x); +X: + mp_clear(&s); + + return res; + +} /* end mp_expt() */ + +/* }}} */ + +/* {{{ mp_2expt(a, k) */ + +/* Compute a = 2^k */ + +mp_err mp_2expt(mp_int *a, mp_digit k) +{ + ARGCHK(a != NULL, MP_BADARG); + + return s_mp_2expt(a, k); + +} /* end mp_2expt() */ + +/* }}} */ + +/* {{{ mp_mod(a, m, c) */ + +/* + mp_mod(a, m, c) + + Compute c = a (mod m). Result will always be 0 <= c < m. + */ + +mp_err mp_mod(mp_int *a, mp_int *m, mp_int *c) +{ + mp_err res; + int mag; + + ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG); + + if(SIGN(m) == MP_NEG) + return MP_RANGE; + + /* + If |a| > m, we need to divide to get the remainder and take the + absolute value. + + If |a| < m, we don't need to do any division, just copy and adjust + the sign (if a is negative). + + If |a| == m, we can simply set the result to zero. + + This order is intended to minimize the average path length of the + comparison chain on common workloads -- the most frequent cases are + that |a| != m, so we do those first. + */ + if((mag = s_mp_cmp(a, m)) > 0) { + if((res = mp_div(a, m, NULL, c)) != MP_OKAY) + return res; + + if(SIGN(c) == MP_NEG) { + if((res = mp_add(c, m, c)) != MP_OKAY) + return res; + } + + } else if(mag < 0) { + if((res = mp_copy(a, c)) != MP_OKAY) + return res; + + if(mp_cmp_z(a) < 0) { + if((res = mp_add(c, m, c)) != MP_OKAY) + return res; + + } + + } else { + mp_zero(c); + + } + + return MP_OKAY; + +} /* end mp_mod() */ + +/* }}} */ + +/* {{{ mp_mod_d(a, d, c) */ + +/* + mp_mod_d(a, d, c) + + Compute c = a (mod d). Result will always be 0 <= c < d + */ +mp_err mp_mod_d(mp_int *a, mp_digit d, mp_digit *c) +{ + mp_err res; + mp_digit rem; + + ARGCHK(a != NULL && c != NULL, MP_BADARG); + + if(s_mp_cmp_d(a, d) > 0) { + if((res = mp_div_d(a, d, NULL, &rem)) != MP_OKAY) + return res; + + } else { + if(SIGN(a) == MP_NEG) + rem = d - DIGIT(a, 0); + else + rem = DIGIT(a, 0); + } + + if(c) + *c = rem; + + return MP_OKAY; + +} /* end mp_mod_d() */ + +/* }}} */ + +/* {{{ mp_sqrt(a, b) */ + +/* + mp_sqrt(a, b) + + Compute the integer square root of a, and store the result in b. + Uses an integer-arithmetic version of Newton's iterative linear + approximation technique to determine this value; the result has the + following two properties: + + b^2 <= a + (b+1)^2 >= a + + It is a range error to pass a negative value. + */ +mp_err mp_sqrt(mp_int *a, mp_int *b) +{ + mp_int x, t; + mp_err res; + + ARGCHK(a != NULL && b != NULL, MP_BADARG); + + /* Cannot take square root of a negative value */ + if(SIGN(a) == MP_NEG) + return MP_RANGE; + + /* Special cases for zero and one, trivial */ + if(mp_cmp_d(a, 0) == MP_EQ || mp_cmp_d(a, 1) == MP_EQ) + return mp_copy(a, b); + + /* Initialize the temporaries we'll use below */ + if((res = mp_init_size(&t, USED(a))) != MP_OKAY) + return res; + + /* Compute an initial guess for the iteration as a itself */ + if((res = mp_init_copy(&x, a)) != MP_OKAY) + goto X; + +s_mp_rshd(&x, (USED(&x)/2)+1); +mp_add_d(&x, 1, &x); + + for(;;) { + /* t = (x * x) - a */ + mp_copy(&x, &t); /* can't fail, t is big enough for original x */ + if((res = mp_sqr(&t, &t)) != MP_OKAY || + (res = mp_sub(&t, a, &t)) != MP_OKAY) + goto CLEANUP; + + /* t = t / 2x */ + s_mp_mul_2(&x); + if((res = mp_div(&t, &x, &t, NULL)) != MP_OKAY) + goto CLEANUP; + s_mp_div_2(&x); + + /* Terminate the loop, if the quotient is zero */ + if(mp_cmp_z(&t) == MP_EQ) + break; + + /* x = x - t */ + if((res = mp_sub(&x, &t, &x)) != MP_OKAY) + goto CLEANUP; + + } + + /* Copy result to output parameter */ + mp_sub_d(&x, 1, &x); + s_mp_exch(&x, b); + + CLEANUP: + mp_clear(&x); + X: + mp_clear(&t); + + return res; + +} /* end mp_sqrt() */ + +/* }}} */ + +/* }}} */ + +/*------------------------------------------------------------------------*/ +/* {{{ Modular arithmetic */ + +#if MP_MODARITH +/* {{{ mp_addmod(a, b, m, c) */ + +/* + mp_addmod(a, b, m, c) + + Compute c = (a + b) mod m + */ + +mp_err mp_addmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c) +{ + mp_err res; + + ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG); + + if((res = mp_add(a, b, c)) != MP_OKAY) + return res; + if((res = mp_mod(c, m, c)) != MP_OKAY) + return res; + + return MP_OKAY; + +} + +/* }}} */ + +/* {{{ mp_submod(a, b, m, c) */ + +/* + mp_submod(a, b, m, c) + + Compute c = (a - b) mod m + */ + +mp_err mp_submod(mp_int *a, mp_int *b, mp_int *m, mp_int *c) +{ + mp_err res; + + ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG); + + if((res = mp_sub(a, b, c)) != MP_OKAY) + return res; + if((res = mp_mod(c, m, c)) != MP_OKAY) + return res; + + return MP_OKAY; + +} + +/* }}} */ + +/* {{{ mp_mulmod(a, b, m, c) */ + +/* + mp_mulmod(a, b, m, c) + + Compute c = (a * b) mod m + */ + +mp_err mp_mulmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c) +{ + mp_err res; + + ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG); + + if((res = mp_mul(a, b, c)) != MP_OKAY) + return res; + if((res = mp_mod(c, m, c)) != MP_OKAY) + return res; + + return MP_OKAY; + +} + +/* }}} */ + +/* {{{ mp_sqrmod(a, m, c) */ + +#if MP_SQUARE +mp_err mp_sqrmod(mp_int *a, mp_int *m, mp_int *c) +{ + mp_err res; + + ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG); + + if((res = mp_sqr(a, c)) != MP_OKAY) + return res; + if((res = mp_mod(c, m, c)) != MP_OKAY) + return res; + + return MP_OKAY; + +} /* end mp_sqrmod() */ +#endif + +/* }}} */ + +/* {{{ mp_exptmod(a, b, m, c) */ + +/* + mp_exptmod(a, b, m, c) + + Compute c = (a ** b) mod m. Uses a standard square-and-multiply + method with modular reductions at each step. (This is basically the + same code as mp_expt(), except for the addition of the reductions) + + The modular reductions are done using Barrett's algorithm (see + s_mp_reduce() below for details) + */ + +mp_err mp_exptmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c) +{ + mp_int s, x, mu; + mp_err res; + mp_digit d, *db = DIGITS(b); + mp_size ub = USED(b); + int dig, bit; + + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + + if(mp_cmp_z(b) < 0 || mp_cmp_z(m) <= 0) + return MP_RANGE; + + if((res = mp_init(&s)) != MP_OKAY) + return res; + if((res = mp_init_copy(&x, a)) != MP_OKAY) + goto X; + if((res = mp_mod(&x, m, &x)) != MP_OKAY || + (res = mp_init(&mu)) != MP_OKAY) + goto MU; + + mp_set(&s, 1); + + /* mu = b^2k / m */ + s_mp_add_d(&mu, 1); + s_mp_lshd(&mu, 2 * USED(m)); + if((res = mp_div(&mu, m, &mu, NULL)) != MP_OKAY) + goto CLEANUP; + + /* Loop over digits of b in ascending order, except highest order */ + for(dig = 0; dig < (ub - 1); dig++) { + d = *db++; + + /* Loop over the bits of the lower-order digits */ + for(bit = 0; bit < DIGIT_BIT; bit++) { + if(d & 1) { + if((res = s_mp_mul(&s, &x)) != MP_OKAY) + goto CLEANUP; + if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY) + goto CLEANUP; + } + + d >>= 1; + + if((res = s_mp_sqr(&x)) != MP_OKAY) + goto CLEANUP; + if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY) + goto CLEANUP; + } + } + + /* Now do the last digit... */ + d = *db; + + while(d) { + if(d & 1) { + if((res = s_mp_mul(&s, &x)) != MP_OKAY) + goto CLEANUP; + if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY) + goto CLEANUP; + } + + d >>= 1; + + if((res = s_mp_sqr(&x)) != MP_OKAY) + goto CLEANUP; + if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY) + goto CLEANUP; + } + + s_mp_exch(&s, c); + + CLEANUP: + mp_clear(&mu); + MU: + mp_clear(&x); + X: + mp_clear(&s); + + return res; + +} /* end mp_exptmod() */ + +/* }}} */ + +/* {{{ mp_exptmod_d(a, d, m, c) */ + +mp_err mp_exptmod_d(mp_int *a, mp_digit d, mp_int *m, mp_int *c) +{ + mp_int s, x; + mp_err res; + + ARGCHK(a != NULL && c != NULL, MP_BADARG); + + if((res = mp_init(&s)) != MP_OKAY) + return res; + if((res = mp_init_copy(&x, a)) != MP_OKAY) + goto X; + + mp_set(&s, 1); + + while(d != 0) { + if(d & 1) { + if((res = s_mp_mul(&s, &x)) != MP_OKAY || + (res = mp_mod(&s, m, &s)) != MP_OKAY) + goto CLEANUP; + } + + d /= 2; + + if((res = s_mp_sqr(&x)) != MP_OKAY || + (res = mp_mod(&x, m, &x)) != MP_OKAY) + goto CLEANUP; + } + + s_mp_exch(&s, c); + +CLEANUP: + mp_clear(&x); +X: + mp_clear(&s); + + return res; + +} /* end mp_exptmod_d() */ + +/* }}} */ +#endif /* if MP_MODARITH */ + +/* }}} */ + +/*------------------------------------------------------------------------*/ +/* {{{ Comparison functions */ + +/* {{{ mp_cmp_z(a) */ + +/* + mp_cmp_z(a) + + Compare a <=> 0. Returns <0 if a<0, 0 if a=0, >0 if a>0. + */ + +int mp_cmp_z(mp_int *a) +{ + if(SIGN(a) == MP_NEG) + return MP_LT; + else if(USED(a) == 1 && DIGIT(a, 0) == 0) + return MP_EQ; + else + return MP_GT; + +} /* end mp_cmp_z() */ + +/* }}} */ + +/* {{{ mp_cmp_d(a, d) */ + +/* + mp_cmp_d(a, d) + + Compare a <=> d. Returns <0 if a0 if a>d + */ + +int mp_cmp_d(mp_int *a, mp_digit d) +{ + ARGCHK(a != NULL, MP_EQ); + + if(SIGN(a) == MP_NEG) + return MP_LT; + + return s_mp_cmp_d(a, d); + +} /* end mp_cmp_d() */ + +/* }}} */ + +/* {{{ mp_cmp(a, b) */ + +int mp_cmp(mp_int *a, mp_int *b) +{ + ARGCHK(a != NULL && b != NULL, MP_EQ); + + if(SIGN(a) == SIGN(b)) { + int mag; + + if((mag = s_mp_cmp(a, b)) == MP_EQ) + return MP_EQ; + + if(SIGN(a) == MP_ZPOS) + return mag; + else + return -mag; + + } else if(SIGN(a) == MP_ZPOS) { + return MP_GT; + } else { + return MP_LT; + } + +} /* end mp_cmp() */ + +/* }}} */ + +/* {{{ mp_cmp_mag(a, b) */ + +/* + mp_cmp_mag(a, b) + + Compares |a| <=> |b|, and returns an appropriate comparison result + */ + +int mp_cmp_mag(mp_int *a, mp_int *b) +{ + ARGCHK(a != NULL && b != NULL, MP_EQ); + + return s_mp_cmp(a, b); + +} /* end mp_cmp_mag() */ + +/* }}} */ + +/* {{{ mp_cmp_int(a, z) */ + +/* + This just converts z to an mp_int, and uses the existing comparison + routines. This is sort of inefficient, but it's not clear to me how + frequently this wil get used anyway. For small positive constants, + you can always use mp_cmp_d(), and for zero, there is mp_cmp_z(). + */ +int mp_cmp_int(mp_int *a, long z) +{ + mp_int tmp; + int out; + + ARGCHK(a != NULL, MP_EQ); + + mp_init(&tmp); mp_set_int(&tmp, z); + out = mp_cmp(a, &tmp); + mp_clear(&tmp); + + return out; + +} /* end mp_cmp_int() */ + +/* }}} */ + +/* {{{ mp_isodd(a) */ + +/* + mp_isodd(a) + + Returns a true (non-zero) value if a is odd, false (zero) otherwise. + */ +int mp_isodd(mp_int *a) +{ + ARGCHK(a != NULL, 0); + + return (DIGIT(a, 0) & 1); + +} /* end mp_isodd() */ + +/* }}} */ + +/* {{{ mp_iseven(a) */ + +int mp_iseven(mp_int *a) +{ + return !mp_isodd(a); + +} /* end mp_iseven() */ + +/* }}} */ + +/* }}} */ + +/*------------------------------------------------------------------------*/ +/* {{{ Number theoretic functions */ + +#if MP_NUMTH +/* {{{ mp_gcd(a, b, c) */ + +/* + Like the old mp_gcd() function, except computes the GCD using the + binary algorithm due to Josef Stein in 1961 (via Knuth). + */ +mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c) +{ + mp_err res; + mp_int u, v, t; + mp_size k = 0; + + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + + if(mp_cmp_z(a) == MP_EQ && mp_cmp_z(b) == MP_EQ) + return MP_RANGE; + if(mp_cmp_z(a) == MP_EQ) { + return mp_copy(b, c); + } else if(mp_cmp_z(b) == MP_EQ) { + return mp_copy(a, c); + } + + if((res = mp_init(&t)) != MP_OKAY) + return res; + if((res = mp_init_copy(&u, a)) != MP_OKAY) + goto U; + if((res = mp_init_copy(&v, b)) != MP_OKAY) + goto V; + + SIGN(&u) = MP_ZPOS; + SIGN(&v) = MP_ZPOS; + + /* Divide out common factors of 2 until at least 1 of a, b is even */ + while(mp_iseven(&u) && mp_iseven(&v)) { + s_mp_div_2(&u); + s_mp_div_2(&v); + ++k; + } + + /* Initialize t */ + if(mp_isodd(&u)) { + if((res = mp_copy(&v, &t)) != MP_OKAY) + goto CLEANUP; + + /* t = -v */ + if(SIGN(&v) == MP_ZPOS) + SIGN(&t) = MP_NEG; + else + SIGN(&t) = MP_ZPOS; + + } else { + if((res = mp_copy(&u, &t)) != MP_OKAY) + goto CLEANUP; + + } + + for(;;) { + while(mp_iseven(&t)) { + s_mp_div_2(&t); + } + + if(mp_cmp_z(&t) == MP_GT) { + if((res = mp_copy(&t, &u)) != MP_OKAY) + goto CLEANUP; + + } else { + if((res = mp_copy(&t, &v)) != MP_OKAY) + goto CLEANUP; + + /* v = -t */ + if(SIGN(&t) == MP_ZPOS) + SIGN(&v) = MP_NEG; + else + SIGN(&v) = MP_ZPOS; + } + + if((res = mp_sub(&u, &v, &t)) != MP_OKAY) + goto CLEANUP; + + if(s_mp_cmp_d(&t, 0) == MP_EQ) + break; + } + + s_mp_2expt(&v, k); /* v = 2^k */ + res = mp_mul(&u, &v, c); /* c = u * v */ + + CLEANUP: + mp_clear(&v); + V: + mp_clear(&u); + U: + mp_clear(&t); + + return res; + +} /* end mp_bgcd() */ + +/* }}} */ + +/* {{{ mp_lcm(a, b, c) */ + +/* We compute the least common multiple using the rule: + + ab = [a, b](a, b) + + ... by computing the product, and dividing out the gcd. + */ + +mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c) +{ + mp_int gcd, prod; + mp_err res; + + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + + /* Set up temporaries */ + if((res = mp_init(&gcd)) != MP_OKAY) + return res; + if((res = mp_init(&prod)) != MP_OKAY) + goto GCD; + + if((res = mp_mul(a, b, &prod)) != MP_OKAY) + goto CLEANUP; + if((res = mp_gcd(a, b, &gcd)) != MP_OKAY) + goto CLEANUP; + + res = mp_div(&prod, &gcd, c, NULL); + + CLEANUP: + mp_clear(&prod); + GCD: + mp_clear(&gcd); + + return res; + +} /* end mp_lcm() */ + +/* }}} */ + +/* {{{ mp_xgcd(a, b, g, x, y) */ + +/* + mp_xgcd(a, b, g, x, y) + + Compute g = (a, b) and values x and y satisfying Bezout's identity + (that is, ax + by = g). This uses the extended binary GCD algorithm + based on the Stein algorithm used for mp_gcd() + */ + +mp_err mp_xgcd(mp_int *a, mp_int *b, mp_int *g, mp_int *x, mp_int *y) +{ + mp_int gx, xc, yc, u, v, A, B, C, D; + mp_int *clean[9]; + mp_err res; + int last = -1; + + if(mp_cmp_z(b) == 0) + return MP_RANGE; + + /* Initialize all these variables we need */ + if((res = mp_init(&u)) != MP_OKAY) goto CLEANUP; + clean[++last] = &u; + if((res = mp_init(&v)) != MP_OKAY) goto CLEANUP; + clean[++last] = &v; + if((res = mp_init(&gx)) != MP_OKAY) goto CLEANUP; + clean[++last] = &gx; + if((res = mp_init(&A)) != MP_OKAY) goto CLEANUP; + clean[++last] = &A; + if((res = mp_init(&B)) != MP_OKAY) goto CLEANUP; + clean[++last] = &B; + if((res = mp_init(&C)) != MP_OKAY) goto CLEANUP; + clean[++last] = &C; + if((res = mp_init(&D)) != MP_OKAY) goto CLEANUP; + clean[++last] = &D; + if((res = mp_init_copy(&xc, a)) != MP_OKAY) goto CLEANUP; + clean[++last] = &xc; + mp_abs(&xc, &xc); + if((res = mp_init_copy(&yc, b)) != MP_OKAY) goto CLEANUP; + clean[++last] = &yc; + mp_abs(&yc, &yc); + + mp_set(&gx, 1); + + /* Divide by two until at least one of them is even */ + while(mp_iseven(&xc) && mp_iseven(&yc)) { + s_mp_div_2(&xc); + s_mp_div_2(&yc); + if((res = s_mp_mul_2(&gx)) != MP_OKAY) + goto CLEANUP; + } + + mp_copy(&xc, &u); + mp_copy(&yc, &v); + mp_set(&A, 1); mp_set(&D, 1); + + /* Loop through binary GCD algorithm */ + for(;;) { + while(mp_iseven(&u)) { + s_mp_div_2(&u); + + if(mp_iseven(&A) && mp_iseven(&B)) { + s_mp_div_2(&A); s_mp_div_2(&B); + } else { + if((res = mp_add(&A, &yc, &A)) != MP_OKAY) goto CLEANUP; + s_mp_div_2(&A); + if((res = mp_sub(&B, &xc, &B)) != MP_OKAY) goto CLEANUP; + s_mp_div_2(&B); + } + } + + while(mp_iseven(&v)) { + s_mp_div_2(&v); + + if(mp_iseven(&C) && mp_iseven(&D)) { + s_mp_div_2(&C); s_mp_div_2(&D); + } else { + if((res = mp_add(&C, &yc, &C)) != MP_OKAY) goto CLEANUP; + s_mp_div_2(&C); + if((res = mp_sub(&D, &xc, &D)) != MP_OKAY) goto CLEANUP; + s_mp_div_2(&D); + } + } + + if(mp_cmp(&u, &v) >= 0) { + if((res = mp_sub(&u, &v, &u)) != MP_OKAY) goto CLEANUP; + if((res = mp_sub(&A, &C, &A)) != MP_OKAY) goto CLEANUP; + if((res = mp_sub(&B, &D, &B)) != MP_OKAY) goto CLEANUP; + + } else { + if((res = mp_sub(&v, &u, &v)) != MP_OKAY) goto CLEANUP; + if((res = mp_sub(&C, &A, &C)) != MP_OKAY) goto CLEANUP; + if((res = mp_sub(&D, &B, &D)) != MP_OKAY) goto CLEANUP; + + } + + /* If we're done, copy results to output */ + if(mp_cmp_z(&u) == 0) { + if(x) + if((res = mp_copy(&C, x)) != MP_OKAY) goto CLEANUP; + + if(y) + if((res = mp_copy(&D, y)) != MP_OKAY) goto CLEANUP; + + if(g) + if((res = mp_mul(&gx, &v, g)) != MP_OKAY) goto CLEANUP; + + break; + } + } + + CLEANUP: + while(last >= 0) + mp_clear(clean[last--]); + + return res; + +} /* end mp_xgcd() */ + +/* }}} */ + +/* {{{ mp_invmod(a, m, c) */ + +/* + mp_invmod(a, m, c) + + Compute c = a^-1 (mod m), if there is an inverse for a (mod m). + This is equivalent to the question of whether (a, m) = 1. If not, + MP_UNDEF is returned, and there is no inverse. + */ + +mp_err mp_invmod(mp_int *a, mp_int *m, mp_int *c) +{ + mp_int g, x; + mp_err res; + + ARGCHK(a && m && c, MP_BADARG); + + if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0) + return MP_RANGE; + + if((res = mp_init(&g)) != MP_OKAY) + return res; + if((res = mp_init(&x)) != MP_OKAY) + goto X; + + if((res = mp_xgcd(a, m, &g, &x, NULL)) != MP_OKAY) + goto CLEANUP; + + if(mp_cmp_d(&g, 1) != MP_EQ) { + res = MP_UNDEF; + goto CLEANUP; + } + + res = mp_mod(&x, m, c); + SIGN(c) = SIGN(a); + +CLEANUP: + mp_clear(&x); +X: + mp_clear(&g); + + return res; + +} /* end mp_invmod() */ + +/* }}} */ +#endif /* if MP_NUMTH */ + +/* }}} */ + +/*------------------------------------------------------------------------*/ +/* {{{ mp_print(mp, ofp) */ + +#if MP_IOFUNC +/* + mp_print(mp, ofp) + + Print a textual representation of the given mp_int on the output + stream 'ofp'. Output is generated using the internal radix. + */ + +void mp_print(mp_int *mp, FILE *ofp) +{ + int ix; + + if(mp == NULL || ofp == NULL) + return; + + fputc((SIGN(mp) == MP_NEG) ? '-' : '+', ofp); + + for(ix = USED(mp) - 1; ix >= 0; ix--) { + fprintf(ofp, DIGIT_FMT, DIGIT(mp, ix)); + } + +} /* end mp_print() */ + +#endif /* if MP_IOFUNC */ + +/* }}} */ + +/*------------------------------------------------------------------------*/ +/* {{{ More I/O Functions */ + +/* {{{ mp_read_signed_bin(mp, str, len) */ + +/* + mp_read_signed_bin(mp, str, len) + + Read in a raw value (base 256) into the given mp_int + */ + +mp_err mp_read_signed_bin(mp_int *mp, unsigned char *str, int len) +{ + mp_err res; + + ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG); + + if((res = mp_read_unsigned_bin(mp, str + 1, len - 1)) == MP_OKAY) { + /* Get sign from first byte */ + if(str[0]) + SIGN(mp) = MP_NEG; + else + SIGN(mp) = MP_ZPOS; + } + + return res; + +} /* end mp_read_signed_bin() */ + +/* }}} */ + +/* {{{ mp_signed_bin_size(mp) */ + +int mp_signed_bin_size(mp_int *mp) +{ + ARGCHK(mp != NULL, 0); + + return mp_unsigned_bin_size(mp) + 1; + +} /* end mp_signed_bin_size() */ + +/* }}} */ + +/* {{{ mp_to_signed_bin(mp, str) */ + +mp_err mp_to_signed_bin(mp_int *mp, unsigned char *str) +{ + ARGCHK(mp != NULL && str != NULL, MP_BADARG); + + /* Caller responsible for allocating enough memory (use mp_raw_size(mp)) */ + str[0] = (char)SIGN(mp); + + return mp_to_unsigned_bin(mp, str + 1); + +} /* end mp_to_signed_bin() */ + +/* }}} */ + +/* {{{ mp_read_unsigned_bin(mp, str, len) */ + +/* + mp_read_unsigned_bin(mp, str, len) + + Read in an unsigned value (base 256) into the given mp_int + */ + +mp_err mp_read_unsigned_bin(mp_int *mp, unsigned char *str, int len) +{ + int ix; + mp_err res; + + ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG); + + mp_zero(mp); + + for(ix = 0; ix < len; ix++) { + if((res = s_mp_mul_2d(mp, CHAR_BIT)) != MP_OKAY) + return res; + + if((res = mp_add_d(mp, str[ix], mp)) != MP_OKAY) + return res; + } + + return MP_OKAY; + +} /* end mp_read_unsigned_bin() */ + +/* }}} */ + +/* {{{ mp_unsigned_bin_size(mp) */ + +int mp_unsigned_bin_size(mp_int *mp) +{ + mp_digit topdig; + int count; + + ARGCHK(mp != NULL, 0); + + /* Special case for the value zero */ + if(USED(mp) == 1 && DIGIT(mp, 0) == 0) + return 1; + + count = (USED(mp) - 1) * sizeof(mp_digit); + topdig = DIGIT(mp, USED(mp) - 1); + + while(topdig != 0) { + ++count; + topdig >>= CHAR_BIT; + } + + return count; + +} /* end mp_unsigned_bin_size() */ + +/* }}} */ + +/* {{{ mp_to_unsigned_bin(mp, str) */ + +mp_err mp_to_unsigned_bin(mp_int *mp, unsigned char *str) +{ + mp_digit *dp, *end, d; + unsigned char *spos; + + ARGCHK(mp != NULL && str != NULL, MP_BADARG); + + dp = DIGITS(mp); + end = dp + USED(mp) - 1; + spos = str; + + /* Special case for zero, quick test */ + if(dp == end && *dp == 0) { + *str = '\0'; + return MP_OKAY; + } + + /* Generate digits in reverse order */ + while(dp < end) { + int ix; + + d = *dp; + for(ix = 0; ix < sizeof(mp_digit); ++ix) { + *spos = d & UCHAR_MAX; + d >>= CHAR_BIT; + ++spos; + } + + ++dp; + } + + /* Now handle last digit specially, high order zeroes are not written */ + d = *end; + while(d != 0) { + *spos = d & UCHAR_MAX; + d >>= CHAR_BIT; + ++spos; + } + + /* Reverse everything to get digits in the correct order */ + while(--spos > str) { + unsigned char t = *str; + *str = *spos; + *spos = t; + + ++str; + } + + return MP_OKAY; + +} /* end mp_to_unsigned_bin() */ + +/* }}} */ + +/* {{{ mp_count_bits(mp) */ + +int mp_count_bits(mp_int *mp) +{ + int len; + mp_digit d; + + ARGCHK(mp != NULL, MP_BADARG); + + len = DIGIT_BIT * (USED(mp) - 1); + d = DIGIT(mp, USED(mp) - 1); + + while(d != 0) { + ++len; + d >>= 1; + } + + return len; + +} /* end mp_count_bits() */ + +/* }}} */ + +/* {{{ mp_read_radix(mp, str, radix) */ + +/* + mp_read_radix(mp, str, radix) + + Read an integer from the given string, and set mp to the resulting + value. The input is presumed to be in base 10. Leading non-digit + characters are ignored, and the function reads until a non-digit + character or the end of the string. + */ + +mp_err mp_read_radix(mp_int *mp, unsigned char *str, int radix) +{ + int ix = 0, val = 0; + mp_err res; + mp_sign sig = MP_ZPOS; + + ARGCHK(mp != NULL && str != NULL && radix >= 2 && radix <= MAX_RADIX, + MP_BADARG); + + mp_zero(mp); + + /* Skip leading non-digit characters until a digit or '-' or '+' */ + while(str[ix] && + (s_mp_tovalue(str[ix], radix) < 0) && + str[ix] != '-' && + str[ix] != '+') { + ++ix; + } + + if(str[ix] == '-') { + sig = MP_NEG; + ++ix; + } else if(str[ix] == '+') { + sig = MP_ZPOS; /* this is the default anyway... */ + ++ix; + } + + while((val = s_mp_tovalue(str[ix], radix)) >= 0) { + if((res = s_mp_mul_d(mp, radix)) != MP_OKAY) + return res; + if((res = s_mp_add_d(mp, val)) != MP_OKAY) + return res; + ++ix; + } + + if(s_mp_cmp_d(mp, 0) == MP_EQ) + SIGN(mp) = MP_ZPOS; + else + SIGN(mp) = sig; + + return MP_OKAY; + +} /* end mp_read_radix() */ + +/* }}} */ + +/* {{{ mp_radix_size(mp, radix) */ + +int mp_radix_size(mp_int *mp, int radix) +{ + int len; + ARGCHK(mp != NULL, 0); + + len = s_mp_outlen(mp_count_bits(mp), radix) + 1; /* for NUL terminator */ + + if(mp_cmp_z(mp) < 0) + ++len; /* for sign */ + + return len; + +} /* end mp_radix_size() */ + +/* }}} */ + +/* {{{ mp_value_radix_size(num, qty, radix) */ + +/* num = number of digits + qty = number of bits per digit + radix = target base + + Return the number of digits in the specified radix that would be + needed to express 'num' digits of 'qty' bits each. + */ +int mp_value_radix_size(int num, int qty, int radix) +{ + ARGCHK(num >= 0 && qty > 0 && radix >= 2 && radix <= MAX_RADIX, 0); + + return s_mp_outlen(num * qty, radix); + +} /* end mp_value_radix_size() */ + +/* }}} */ + +/* {{{ mp_toradix(mp, str, radix) */ + +mp_err mp_toradix(mp_int *mp, unsigned char *str, int radix) +{ + int ix, pos = 0; + + ARGCHK(mp != NULL && str != NULL, MP_BADARG); + ARGCHK(radix > 1 && radix <= MAX_RADIX, MP_RANGE); + + if(mp_cmp_z(mp) == MP_EQ) { + str[0] = '0'; + str[1] = '\0'; + } else { + mp_err res; + mp_int tmp; + mp_sign sgn; + mp_digit rem, rdx = (mp_digit)radix; + char ch; + + if((res = mp_init_copy(&tmp, mp)) != MP_OKAY) + return res; + + /* Save sign for later, and take absolute value */ + sgn = SIGN(&tmp); SIGN(&tmp) = MP_ZPOS; + + /* Generate output digits in reverse order */ + while(mp_cmp_z(&tmp) != 0) { + if((res = s_mp_div_d(&tmp, rdx, &rem)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + /* Generate digits, use capital letters */ + ch = s_mp_todigit(rem, radix, 0); + + str[pos++] = ch; + } + + /* Add - sign if original value was negative */ + if(sgn == MP_NEG) + str[pos++] = '-'; + + /* Add trailing NUL to end the string */ + str[pos--] = '\0'; + + /* Reverse the digits and sign indicator */ + ix = 0; + while(ix < pos) { + char tmp = str[ix]; + + str[ix] = str[pos]; + str[pos] = tmp; + ++ix; + --pos; + } + + mp_clear(&tmp); + } + + return MP_OKAY; + +} /* end mp_toradix() */ + +/* }}} */ + +/* {{{ mp_char2value(ch, r) */ + +int mp_char2value(char ch, int r) +{ + return s_mp_tovalue(ch, r); + +} /* end mp_tovalue() */ + +/* }}} */ + +/* }}} */ + +/* {{{ mp_strerror(ec) */ + +/* + mp_strerror(ec) + + Return a string describing the meaning of error code 'ec'. The + string returned is allocated in static memory, so the caller should + not attempt to modify or free the memory associated with this + string. + */ +const char *mp_strerror(mp_err ec) +{ + int aec = (ec < 0) ? -ec : ec; + + /* Code values are negative, so the senses of these comparisons + are accurate */ + if(ec < MP_LAST_CODE || ec > MP_OKAY) { + return mp_err_string[0]; /* unknown error code */ + } else { + return mp_err_string[aec + 1]; + } + +} /* end mp_strerror() */ + +/* }}} */ + +/*========================================================================*/ +/*------------------------------------------------------------------------*/ +/* Static function definitions (internal use only) */ + +/* {{{ Memory management */ + +/* {{{ s_mp_grow(mp, min) */ + +/* Make sure there are at least 'min' digits allocated to mp */ +mp_err s_mp_grow(mp_int *mp, mp_size min) +{ + if(min > ALLOC(mp)) { + mp_digit *tmp; + + /* Set min to next nearest default precision block size */ + min = ((min + (s_mp_defprec - 1)) / s_mp_defprec) * s_mp_defprec; + + if((tmp = s_mp_alloc(min, sizeof(mp_digit))) == NULL) + return MP_MEM; + + s_mp_copy(DIGITS(mp), tmp, USED(mp)); + +#if MP_CRYPTO + s_mp_setz(DIGITS(mp), ALLOC(mp)); +#endif + s_mp_free(DIGITS(mp)); + DIGITS(mp) = tmp; + ALLOC(mp) = min; + } + + return MP_OKAY; + +} /* end s_mp_grow() */ + +/* }}} */ + +/* {{{ s_mp_pad(mp, min) */ + +/* Make sure the used size of mp is at least 'min', growing if needed */ +mp_err s_mp_pad(mp_int *mp, mp_size min) +{ + if(min > USED(mp)) { + mp_err res; + + /* Make sure there is room to increase precision */ + if(min > ALLOC(mp) && (res = s_mp_grow(mp, min)) != MP_OKAY) + return res; + + /* Increase precision; should already be 0-filled */ + USED(mp) = min; + } + + return MP_OKAY; + +} /* end s_mp_pad() */ + +/* }}} */ + +/* {{{ s_mp_setz(dp, count) */ + +#if MP_MACRO == 0 +/* Set 'count' digits pointed to by dp to be zeroes */ +void s_mp_setz(mp_digit *dp, mp_size count) +{ +#if MP_MEMSET == 0 + int ix; + + for(ix = 0; ix < count; ix++) + dp[ix] = 0; +#else + memset(dp, 0, count * sizeof(mp_digit)); +#endif + +} /* end s_mp_setz() */ +#endif + +/* }}} */ + +/* {{{ s_mp_copy(sp, dp, count) */ + +#if MP_MACRO == 0 +/* Copy 'count' digits from sp to dp */ +void s_mp_copy(mp_digit *sp, mp_digit *dp, mp_size count) +{ +#if MP_MEMCPY == 0 + int ix; + + for(ix = 0; ix < count; ix++) + dp[ix] = sp[ix]; +#else + memcpy(dp, sp, count * sizeof(mp_digit)); +#endif + +} /* end s_mp_copy() */ +#endif + +/* }}} */ + +/* {{{ s_mp_alloc(nb, ni) */ + +#if MP_MACRO == 0 +/* Allocate ni records of nb bytes each, and return a pointer to that */ +void *s_mp_alloc(size_t nb, size_t ni) +{ + return calloc(nb, ni); + +} /* end s_mp_alloc() */ +#endif + +/* }}} */ + +/* {{{ s_mp_free(ptr) */ + +#if MP_MACRO == 0 +/* Free the memory pointed to by ptr */ +void s_mp_free(void *ptr) +{ + if(ptr) + free(ptr); + +} /* end s_mp_free() */ +#endif + +/* }}} */ + +/* {{{ s_mp_clamp(mp) */ + +/* Remove leading zeroes from the given value */ +void s_mp_clamp(mp_int *mp) +{ + mp_size du = USED(mp); + mp_digit *zp = DIGITS(mp) + du - 1; + + while(du > 1 && !*zp--) + --du; + + USED(mp) = du; + +} /* end s_mp_clamp() */ + + +/* }}} */ + +/* {{{ s_mp_exch(a, b) */ + +/* Exchange the data for a and b; (b, a) = (a, b) */ +void s_mp_exch(mp_int *a, mp_int *b) +{ + mp_int tmp; + + tmp = *a; + *a = *b; + *b = tmp; + +} /* end s_mp_exch() */ + +/* }}} */ + +/* }}} */ + +/* {{{ Arithmetic helpers */ + +/* {{{ s_mp_lshd(mp, p) */ + +/* + Shift mp leftward by p digits, growing if needed, and zero-filling + the in-shifted digits at the right end. This is a convenient + alternative to multiplication by powers of the radix + */ + +mp_err s_mp_lshd(mp_int *mp, mp_size p) +{ + mp_err res; + mp_size pos; + mp_digit *dp; + int ix; + + if(p == 0) + return MP_OKAY; + + if((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY) + return res; + + pos = USED(mp) - 1; + dp = DIGITS(mp); + + /* Shift all the significant figures over as needed */ + for(ix = pos - p; ix >= 0; ix--) + dp[ix + p] = dp[ix]; + + /* Fill the bottom digits with zeroes */ + for(ix = 0; ix < p; ix++) + dp[ix] = 0; + + return MP_OKAY; + +} /* end s_mp_lshd() */ + +/* }}} */ + +/* {{{ s_mp_rshd(mp, p) */ + +/* + Shift mp rightward by p digits. Maintains the invariant that + digits above the precision are all zero. Digits shifted off the + end are lost. Cannot fail. + */ + +void s_mp_rshd(mp_int *mp, mp_size p) +{ + mp_size ix; + mp_digit *dp; + + if(p == 0) + return; + + /* Shortcut when all digits are to be shifted off */ + if(p >= USED(mp)) { + s_mp_setz(DIGITS(mp), ALLOC(mp)); + USED(mp) = 1; + SIGN(mp) = MP_ZPOS; + return; + } + + /* Shift all the significant figures over as needed */ + dp = DIGITS(mp); + for(ix = p; ix < USED(mp); ix++) + dp[ix - p] = dp[ix]; + + /* Fill the top digits with zeroes */ + ix -= p; + while(ix < USED(mp)) + dp[ix++] = 0; + + /* Strip off any leading zeroes */ + s_mp_clamp(mp); + +} /* end s_mp_rshd() */ + +/* }}} */ + +/* {{{ s_mp_div_2(mp) */ + +/* Divide by two -- take advantage of radix properties to do it fast */ +void s_mp_div_2(mp_int *mp) +{ + s_mp_div_2d(mp, 1); + +} /* end s_mp_div_2() */ + +/* }}} */ + +/* {{{ s_mp_mul_2(mp) */ + +mp_err s_mp_mul_2(mp_int *mp) +{ + int ix; + mp_digit kin = 0, kout, *dp = DIGITS(mp); + mp_err res; + + /* Shift digits leftward by 1 bit */ + for(ix = 0; ix < USED(mp); ix++) { + kout = (dp[ix] >> (DIGIT_BIT - 1)) & 1; + dp[ix] = (dp[ix] << 1) | kin; + + kin = kout; + } + + /* Deal with rollover from last digit */ + if(kin) { + if(ix >= ALLOC(mp)) { + if((res = s_mp_grow(mp, ALLOC(mp) + 1)) != MP_OKAY) + return res; + dp = DIGITS(mp); + } + + dp[ix] = kin; + USED(mp) += 1; + } + + return MP_OKAY; + +} /* end s_mp_mul_2() */ + +/* }}} */ + +/* {{{ s_mp_mod_2d(mp, d) */ + +/* + Remainder the integer by 2^d, where d is a number of bits. This + amounts to a bitwise AND of the value, and does not require the full + division code + */ +void s_mp_mod_2d(mp_int *mp, mp_digit d) +{ + unsigned int ndig = (d / DIGIT_BIT), nbit = (d % DIGIT_BIT); + unsigned int ix; + mp_digit dmask, *dp = DIGITS(mp); + + if(ndig >= USED(mp)) + return; + + /* Flush all the bits above 2^d in its digit */ + dmask = (1 << nbit) - 1; + dp[ndig] &= dmask; + + /* Flush all digits above the one with 2^d in it */ + for(ix = ndig + 1; ix < USED(mp); ix++) + dp[ix] = 0; + + s_mp_clamp(mp); + +} /* end s_mp_mod_2d() */ + +/* }}} */ + +/* {{{ s_mp_mul_2d(mp, d) */ + +/* + Multiply by the integer 2^d, where d is a number of bits. This + amounts to a bitwise shift of the value, and does not require the + full multiplication code. + */ +mp_err s_mp_mul_2d(mp_int *mp, mp_digit d) +{ + mp_err res; + mp_digit save, next, mask, *dp; + mp_size used; + int ix; + + if((res = s_mp_lshd(mp, d / DIGIT_BIT)) != MP_OKAY) + return res; + + dp = DIGITS(mp); used = USED(mp); + d %= DIGIT_BIT; + + mask = (1 << d) - 1; + + /* If the shift requires another digit, make sure we've got one to + work with */ + if((dp[used - 1] >> (DIGIT_BIT - d)) & mask) { + if((res = s_mp_grow(mp, used + 1)) != MP_OKAY) + return res; + dp = DIGITS(mp); + } + + /* Do the shifting... */ + save = 0; + for(ix = 0; ix < used; ix++) { + next = (dp[ix] >> (DIGIT_BIT - d)) & mask; + dp[ix] = (dp[ix] << d) | save; + save = next; + } + + /* If, at this point, we have a nonzero carryout into the next + digit, we'll increase the size by one digit, and store it... + */ + if(save) { + dp[used] = save; + USED(mp) += 1; + } + + s_mp_clamp(mp); + return MP_OKAY; + +} /* end s_mp_mul_2d() */ + +/* }}} */ + +/* {{{ s_mp_div_2d(mp, d) */ + +/* + Divide the integer by 2^d, where d is a number of bits. This + amounts to a bitwise shift of the value, and does not require the + full division code (used in Barrett reduction, see below) + */ +void s_mp_div_2d(mp_int *mp, mp_digit d) +{ + int ix; + mp_digit save, next, mask, *dp = DIGITS(mp); + + s_mp_rshd(mp, d / DIGIT_BIT); + d %= DIGIT_BIT; + + mask = (1 << d) - 1; + + save = 0; + for(ix = USED(mp) - 1; ix >= 0; ix--) { + next = dp[ix] & mask; + dp[ix] = (dp[ix] >> d) | (save << (DIGIT_BIT - d)); + save = next; + } + + s_mp_clamp(mp); + +} /* end s_mp_div_2d() */ + +/* }}} */ + +/* {{{ s_mp_norm(a, b) */ + +/* + s_mp_norm(a, b) + + Normalize a and b for division, where b is the divisor. In order + that we might make good guesses for quotient digits, we want the + leading digit of b to be at least half the radix, which we + accomplish by multiplying a and b by a constant. This constant is + returned (so that it can be divided back out of the remainder at the + end of the division process). + + We multiply by the smallest power of 2 that gives us a leading digit + at least half the radix. By choosing a power of 2, we simplify the + multiplication and division steps to simple shifts. + */ +mp_digit s_mp_norm(mp_int *a, mp_int *b) +{ + mp_digit t, d = 0; + + t = DIGIT(b, USED(b) - 1); + while(t < (RADIX / 2)) { + t <<= 1; + ++d; + } + + if(d != 0) { + s_mp_mul_2d(a, d); + s_mp_mul_2d(b, d); + } + + return d; + +} /* end s_mp_norm() */ + +/* }}} */ + +/* }}} */ + +/* {{{ Primitive digit arithmetic */ + +/* {{{ s_mp_add_d(mp, d) */ + +/* Add d to |mp| in place */ +mp_err s_mp_add_d(mp_int *mp, mp_digit d) /* unsigned digit addition */ +{ + mp_word w, k = 0; + mp_size ix = 1, used = USED(mp); + mp_digit *dp = DIGITS(mp); + + w = dp[0] + d; + dp[0] = ACCUM(w); + k = CARRYOUT(w); + + while(ix < used && k) { + w = dp[ix] + k; + dp[ix] = ACCUM(w); + k = CARRYOUT(w); + ++ix; + } + + if(k != 0) { + mp_err res; + + if((res = s_mp_pad(mp, USED(mp) + 1)) != MP_OKAY) + return res; + + DIGIT(mp, ix) = k; + } + + return MP_OKAY; + +} /* end s_mp_add_d() */ + +/* }}} */ + +/* {{{ s_mp_sub_d(mp, d) */ + +/* Subtract d from |mp| in place, assumes |mp| > d */ +mp_err s_mp_sub_d(mp_int *mp, mp_digit d) /* unsigned digit subtract */ +{ + mp_word w, b = 0; + mp_size ix = 1, used = USED(mp); + mp_digit *dp = DIGITS(mp); + + /* Compute initial subtraction */ + w = (RADIX + dp[0]) - d; + b = CARRYOUT(w) ? 0 : 1; + dp[0] = ACCUM(w); + + /* Propagate borrows leftward */ + while(b && ix < used) { + w = (RADIX + dp[ix]) - b; + b = CARRYOUT(w) ? 0 : 1; + dp[ix] = ACCUM(w); + ++ix; + } + + /* Remove leading zeroes */ + s_mp_clamp(mp); + + /* If we have a borrow out, it's a violation of the input invariant */ + if(b) + return MP_RANGE; + else + return MP_OKAY; + +} /* end s_mp_sub_d() */ + +/* }}} */ + +/* {{{ s_mp_mul_d(a, d) */ + +/* Compute a = a * d, single digit multiplication */ +mp_err s_mp_mul_d(mp_int *a, mp_digit d) +{ + mp_word w, k = 0; + mp_size ix, max; + mp_err res; + mp_digit *dp = DIGITS(a); + + /* + Single-digit multiplication will increase the precision of the + output by at most one digit. However, we can detect when this + will happen -- if the high-order digit of a, times d, gives a + two-digit result, then the precision of the result will increase; + otherwise it won't. We use this fact to avoid calling s_mp_pad() + unless absolutely necessary. + */ + max = USED(a); + w = dp[max - 1] * d; + if(CARRYOUT(w) != 0) { + if((res = s_mp_pad(a, max + 1)) != MP_OKAY) + return res; + dp = DIGITS(a); + } + + for(ix = 0; ix < max; ix++) { + w = (dp[ix] * d) + k; + dp[ix] = ACCUM(w); + k = CARRYOUT(w); + } + + /* If there is a precision increase, take care of it here; the above + test guarantees we have enough storage to do this safely. + */ + if(k) { + dp[max] = k; + USED(a) = max + 1; + } + + s_mp_clamp(a); + + return MP_OKAY; + +} /* end s_mp_mul_d() */ + +/* }}} */ + +/* {{{ s_mp_div_d(mp, d, r) */ + +/* + s_mp_div_d(mp, d, r) + + Compute the quotient mp = mp / d and remainder r = mp mod d, for a + single digit d. If r is null, the remainder will be discarded. + */ + +mp_err s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r) +{ + mp_word w = 0, t; + mp_int quot; + mp_err res; + mp_digit *dp = DIGITS(mp), *qp; + int ix; + + if(d == 0) + return MP_RANGE; + + /* Make room for the quotient */ + if((res = mp_init_size(", USED(mp))) != MP_OKAY) + return res; + + USED(") = USED(mp); /* so clamping will work below */ + qp = DIGITS("); + + /* Divide without subtraction */ + for(ix = USED(mp) - 1; ix >= 0; ix--) { + w = (w << DIGIT_BIT) | dp[ix]; + + if(w >= d) { + t = w / d; + w = w % d; + } else { + t = 0; + } + + qp[ix] = t; + } + + /* Deliver the remainder, if desired */ + if(r) + *r = w; + + s_mp_clamp("); + mp_exch(", mp); + mp_clear("); + + return MP_OKAY; + +} /* end s_mp_div_d() */ + +/* }}} */ + +/* }}} */ + +/* {{{ Primitive full arithmetic */ + +/* {{{ s_mp_add(a, b) */ + +/* Compute a = |a| + |b| */ +mp_err s_mp_add(mp_int *a, mp_int *b) /* magnitude addition */ +{ + mp_word w = 0; + mp_digit *pa, *pb; + mp_size ix, used = USED(b); + mp_err res; + + /* Make sure a has enough precision for the output value */ + if((used > USED(a)) && (res = s_mp_pad(a, used)) != MP_OKAY) + return res; + + /* + Add up all digits up to the precision of b. If b had initially + the same precision as a, or greater, we took care of it by the + padding step above, so there is no problem. If b had initially + less precision, we'll have to make sure the carry out is duly + propagated upward among the higher-order digits of the sum. + */ + pa = DIGITS(a); + pb = DIGITS(b); + for(ix = 0; ix < used; ++ix) { + w += *pa + *pb++; + *pa++ = ACCUM(w); + w = CARRYOUT(w); + } + + /* If we run out of 'b' digits before we're actually done, make + sure the carries get propagated upward... + */ + used = USED(a); + while(w && ix < used) { + w += *pa; + *pa++ = ACCUM(w); + w = CARRYOUT(w); + ++ix; + } + + /* If there's an overall carry out, increase precision and include + it. We could have done this initially, but why touch the memory + allocator unless we're sure we have to? + */ + if(w) { + if((res = s_mp_pad(a, used + 1)) != MP_OKAY) + return res; + + DIGIT(a, ix) = w; /* pa may not be valid after s_mp_pad() call */ + } + + return MP_OKAY; + +} /* end s_mp_add() */ + +/* }}} */ + +/* {{{ s_mp_sub(a, b) */ + +/* Compute a = |a| - |b|, assumes |a| >= |b| */ +mp_err s_mp_sub(mp_int *a, mp_int *b) /* magnitude subtract */ +{ + mp_word w = 0; + mp_digit *pa, *pb; + mp_size ix, used = USED(b); + + /* + Subtract and propagate borrow. Up to the precision of b, this + accounts for the digits of b; after that, we just make sure the + carries get to the right place. This saves having to pad b out to + the precision of a just to make the loops work right... + */ + pa = DIGITS(a); + pb = DIGITS(b); + + for(ix = 0; ix < used; ++ix) { + w = (RADIX + *pa) - w - *pb++; + *pa++ = ACCUM(w); + w = CARRYOUT(w) ? 0 : 1; + } + + used = USED(a); + while(ix < used) { + w = RADIX + *pa - w; + *pa++ = ACCUM(w); + w = CARRYOUT(w) ? 0 : 1; + ++ix; + } + + /* Clobber any leading zeroes we created */ + s_mp_clamp(a); + + /* + If there was a borrow out, then |b| > |a| in violation + of our input invariant. We've already done the work, + but we'll at least complain about it... + */ + if(w) + return MP_RANGE; + else + return MP_OKAY; + +} /* end s_mp_sub() */ + +/* }}} */ + +mp_err s_mp_reduce(mp_int *x, mp_int *m, mp_int *mu) +{ + mp_int q; + mp_err res; + mp_size um = USED(m); + + if((res = mp_init_copy(&q, x)) != MP_OKAY) + return res; + + s_mp_rshd(&q, um - 1); /* q1 = x / b^(k-1) */ + s_mp_mul(&q, mu); /* q2 = q1 * mu */ + s_mp_rshd(&q, um + 1); /* q3 = q2 / b^(k+1) */ + + /* x = x mod b^(k+1), quick (no division) */ + s_mp_mod_2d(x, (mp_digit)(DIGIT_BIT * (um + 1))); + + /* q = q * m mod b^(k+1), quick (no division), uses the short multiplier */ +#ifndef SHRT_MUL + s_mp_mul(&q, m); + s_mp_mod_2d(&q, (mp_digit)(DIGIT_BIT * (um + 1))); +#else + s_mp_mul_dig(&q, m, um + 1); +#endif + + /* x = x - q */ + if((res = mp_sub(x, &q, x)) != MP_OKAY) + goto CLEANUP; + + /* If x < 0, add b^(k+1) to it */ + if(mp_cmp_z(x) < 0) { + mp_set(&q, 1); + if((res = s_mp_lshd(&q, um + 1)) != MP_OKAY) + goto CLEANUP; + if((res = mp_add(x, &q, x)) != MP_OKAY) + goto CLEANUP; + } + + /* Back off if it's too big */ + while(mp_cmp(x, m) >= 0) { + if((res = s_mp_sub(x, m)) != MP_OKAY) + break; + } + + CLEANUP: + mp_clear(&q); + + return res; + +} /* end s_mp_reduce() */ + + + +/* {{{ s_mp_mul(a, b) */ + +/* Compute a = |a| * |b| */ +mp_err s_mp_mul(mp_int *a, mp_int *b) +{ + mp_word w, k = 0; + mp_int tmp; + mp_err res; + mp_size ix, jx, ua = USED(a), ub = USED(b); + mp_digit *pa, *pb, *pt, *pbt; + + if((res = mp_init_size(&tmp, ua + ub)) != MP_OKAY) + return res; + + /* This has the effect of left-padding with zeroes... */ + USED(&tmp) = ua + ub; + + /* We're going to need the base value each iteration */ + pbt = DIGITS(&tmp); + + /* Outer loop: Digits of b */ + + pb = DIGITS(b); + for(ix = 0; ix < ub; ++ix, ++pb) { + if(*pb == 0) + continue; + + /* Inner product: Digits of a */ + pa = DIGITS(a); + for(jx = 0; jx < ua; ++jx, ++pa) { + pt = pbt + ix + jx; + w = *pb * *pa + k + *pt; + *pt = ACCUM(w); + k = CARRYOUT(w); + } + + pbt[ix + jx] = k; + k = 0; + } + + s_mp_clamp(&tmp); + s_mp_exch(&tmp, a); + + mp_clear(&tmp); + + return MP_OKAY; + +} /* end s_mp_mul() */ + +/* }}} */ + +/* {{{ s_mp_kmul(a, b, out, len) */ + +#if 0 +void s_mp_kmul(mp_digit *a, mp_digit *b, mp_digit *out, mp_size len) +{ + mp_word w, k = 0; + mp_size ix, jx; + mp_digit *pa, *pt; + + for(ix = 0; ix < len; ++ix, ++b) { + if(*b == 0) + continue; + + pa = a; + for(jx = 0; jx < len; ++jx, ++pa) { + pt = out + ix + jx; + w = *b * *pa + k + *pt; + *pt = ACCUM(w); + k = CARRYOUT(w); + } + + out[ix + jx] = k; + k = 0; + } + +} /* end s_mp_kmul() */ +#endif + +/* }}} */ + +/* {{{ s_mp_sqr(a) */ + +/* + Computes the square of a, in place. This can be done more + efficiently than a general multiplication, because many of the + computation steps are redundant when squaring. The inner product + step is a bit more complicated, but we save a fair number of + iterations of the multiplication loop. + */ +#if MP_SQUARE +mp_err s_mp_sqr(mp_int *a) +{ + mp_word w, k = 0; + mp_int tmp; + mp_err res; + mp_size ix, jx, kx, used = USED(a); + mp_digit *pa1, *pa2, *pt, *pbt; + + if((res = mp_init_size(&tmp, 2 * used)) != MP_OKAY) + return res; + + /* Left-pad with zeroes */ + USED(&tmp) = 2 * used; + + /* We need the base value each time through the loop */ + pbt = DIGITS(&tmp); + + pa1 = DIGITS(a); + for(ix = 0; ix < used; ++ix, ++pa1) { + if(*pa1 == 0) + continue; + + w = DIGIT(&tmp, ix + ix) + (*pa1 * *pa1); + + pbt[ix + ix] = ACCUM(w); + k = CARRYOUT(w); + + /* + The inner product is computed as: + + (C, S) = t[i,j] + 2 a[i] a[j] + C + + This can overflow what can be represented in an mp_word, and + since C arithmetic does not provide any way to check for + overflow, we have to check explicitly for overflow conditions + before they happen. + */ + for(jx = ix + 1, pa2 = DIGITS(a) + jx; jx < used; ++jx, ++pa2) { + mp_word u = 0, v; + + /* Store this in a temporary to avoid indirections later */ + pt = pbt + ix + jx; + + /* Compute the multiplicative step */ + w = *pa1 * *pa2; + + /* If w is more than half MP_WORD_MAX, the doubling will + overflow, and we need to record a carry out into the next + word */ + u = (w >> (MP_WORD_BIT - 1)) & 1; + + /* Double what we've got, overflow will be ignored as defined + for C arithmetic (we've already noted if it is to occur) + */ + w *= 2; + + /* Compute the additive step */ + v = *pt + k; + + /* If we do not already have an overflow carry, check to see + if the addition will cause one, and set the carry out if so + */ + u |= ((MP_WORD_MAX - v) < w); + + /* Add in the rest, again ignoring overflow */ + w += v; + + /* Set the i,j digit of the output */ + *pt = ACCUM(w); + + /* Save carry information for the next iteration of the loop. + This is why k must be an mp_word, instead of an mp_digit */ + k = CARRYOUT(w) | (u << DIGIT_BIT); + + } /* for(jx ...) */ + + /* Set the last digit in the cycle and reset the carry */ + k = DIGIT(&tmp, ix + jx) + k; + pbt[ix + jx] = ACCUM(k); + k = CARRYOUT(k); + + /* If we are carrying out, propagate the carry to the next digit + in the output. This may cascade, so we have to be somewhat + circumspect -- but we will have enough precision in the output + that we won't overflow + */ + kx = 1; + while(k) { + k = pbt[ix + jx + kx] + 1; + pbt[ix + jx + kx] = ACCUM(k); + k = CARRYOUT(k); + ++kx; + } + } /* for(ix ...) */ + + s_mp_clamp(&tmp); + s_mp_exch(&tmp, a); + + mp_clear(&tmp); + + return MP_OKAY; + +} /* end s_mp_sqr() */ +#endif + +/* }}} */ + +/* {{{ s_mp_div(a, b) */ + +/* + s_mp_div(a, b) + + Compute a = a / b and b = a mod b. Assumes b > a. + */ + +mp_err s_mp_div(mp_int *a, mp_int *b) +{ + mp_int quot, rem, t; + mp_word q; + mp_err res; + mp_digit d; + int ix; + + if(mp_cmp_z(b) == 0) + return MP_RANGE; + + /* Shortcut if b is power of two */ + if((ix = s_mp_ispow2(b)) >= 0) { + mp_copy(a, b); /* need this for remainder */ + s_mp_div_2d(a, (mp_digit)ix); + s_mp_mod_2d(b, (mp_digit)ix); + + return MP_OKAY; + } + + /* Allocate space to store the quotient */ + if((res = mp_init_size(", USED(a))) != MP_OKAY) + return res; + + /* A working temporary for division */ + if((res = mp_init_size(&t, USED(a))) != MP_OKAY) + goto T; + + /* Allocate space for the remainder */ + if((res = mp_init_size(&rem, USED(a))) != MP_OKAY) + goto REM; + + /* Normalize to optimize guessing */ + d = s_mp_norm(a, b); + + /* Perform the division itself...woo! */ + ix = USED(a) - 1; + + while(ix >= 0) { + /* Find a partial substring of a which is at least b */ + while(s_mp_cmp(&rem, b) < 0 && ix >= 0) { + if((res = s_mp_lshd(&rem, 1)) != MP_OKAY) + goto CLEANUP; + + if((res = s_mp_lshd(", 1)) != MP_OKAY) + goto CLEANUP; + + DIGIT(&rem, 0) = DIGIT(a, ix); + s_mp_clamp(&rem); + --ix; + } + + /* If we didn't find one, we're finished dividing */ + if(s_mp_cmp(&rem, b) < 0) + break; + + /* Compute a guess for the next quotient digit */ + q = DIGIT(&rem, USED(&rem) - 1); + if(q <= DIGIT(b, USED(b) - 1) && USED(&rem) > 1) + q = (q << DIGIT_BIT) | DIGIT(&rem, USED(&rem) - 2); + + q /= DIGIT(b, USED(b) - 1); + + /* The guess can be as much as RADIX + 1 */ + if(q >= RADIX) + q = RADIX - 1; + + /* See what that multiplies out to */ + mp_copy(b, &t); + if((res = s_mp_mul_d(&t, q)) != MP_OKAY) + goto CLEANUP; + + /* + If it's too big, back it off. We should not have to do this + more than once, or, in rare cases, twice. Knuth describes a + method by which this could be reduced to a maximum of once, but + I didn't implement that here. + */ + while(s_mp_cmp(&t, &rem) > 0) { + --q; + s_mp_sub(&t, b); + } + + /* At this point, q should be the right next digit */ + if((res = s_mp_sub(&rem, &t)) != MP_OKAY) + goto CLEANUP; + + /* + Include the digit in the quotient. We allocated enough memory + for any quotient we could ever possibly get, so we should not + have to check for failures here + */ + DIGIT(", 0) = q; + } + + /* Denormalize remainder */ + if(d != 0) + s_mp_div_2d(&rem, d); + + s_mp_clamp("); + s_mp_clamp(&rem); + + /* Copy quotient back to output */ + s_mp_exch(", a); + + /* Copy remainder back to output */ + s_mp_exch(&rem, b); + +CLEANUP: + mp_clear(&rem); +REM: + mp_clear(&t); +T: + mp_clear("); + + return res; + +} /* end s_mp_div() */ + +/* }}} */ + +/* {{{ s_mp_2expt(a, k) */ + +mp_err s_mp_2expt(mp_int *a, mp_digit k) +{ + mp_err res; + mp_size dig, bit; + + dig = k / DIGIT_BIT; + bit = k % DIGIT_BIT; + + mp_zero(a); + if((res = s_mp_pad(a, dig + 1)) != MP_OKAY) + return res; + + DIGIT(a, dig) |= (1 << bit); + + return MP_OKAY; + +} /* end s_mp_2expt() */ + +/* }}} */ + + +/* }}} */ + +/* }}} */ + +/* {{{ Primitive comparisons */ + +/* {{{ s_mp_cmp(a, b) */ + +/* Compare |a| <=> |b|, return 0 if equal, <0 if a0 if a>b */ +int s_mp_cmp(mp_int *a, mp_int *b) +{ + mp_size ua = USED(a), ub = USED(b); + + if(ua > ub) + return MP_GT; + else if(ua < ub) + return MP_LT; + else { + int ix = ua - 1; + mp_digit *ap = DIGITS(a) + ix, *bp = DIGITS(b) + ix; + + while(ix >= 0) { + if(*ap > *bp) + return MP_GT; + else if(*ap < *bp) + return MP_LT; + + --ap; --bp; --ix; + } + + return MP_EQ; + } + +} /* end s_mp_cmp() */ + +/* }}} */ + +/* {{{ s_mp_cmp_d(a, d) */ + +/* Compare |a| <=> d, return 0 if equal, <0 if a0 if a>d */ +int s_mp_cmp_d(mp_int *a, mp_digit d) +{ + mp_size ua = USED(a); + mp_digit *ap = DIGITS(a); + + if(ua > 1) + return MP_GT; + + if(*ap < d) + return MP_LT; + else if(*ap > d) + return MP_GT; + else + return MP_EQ; + +} /* end s_mp_cmp_d() */ + +/* }}} */ + +/* {{{ s_mp_ispow2(v) */ + +/* + Returns -1 if the value is not a power of two; otherwise, it returns + k such that v = 2^k, i.e. lg(v). + */ +int s_mp_ispow2(mp_int *v) +{ + mp_digit d, *dp; + mp_size uv = USED(v); + int extra = 0, ix; + + d = DIGIT(v, uv - 1); /* most significant digit of v */ + + while(d && ((d & 1) == 0)) { + d >>= 1; + ++extra; + } + + if(d == 1) { + ix = uv - 2; + dp = DIGITS(v) + ix; + + while(ix >= 0) { + if(*dp) + return -1; /* not a power of two */ + + --dp; --ix; + } + + return ((uv - 1) * DIGIT_BIT) + extra; + } + + return -1; + +} /* end s_mp_ispow2() */ + +/* }}} */ + +/* {{{ s_mp_ispow2d(d) */ + +int s_mp_ispow2d(mp_digit d) +{ + int pow = 0; + + while((d & 1) == 0) { + ++pow; d >>= 1; + } + + if(d == 1) + return pow; + + return -1; + +} /* end s_mp_ispow2d() */ + +/* }}} */ + +/* }}} */ + +/* {{{ Primitive I/O helpers */ + +/* {{{ s_mp_tovalue(ch, r) */ + +/* + Convert the given character to its digit value, in the given radix. + If the given character is not understood in the given radix, -1 is + returned. Otherwise the digit's numeric value is returned. + + The results will be odd if you use a radix < 2 or > 62, you are + expected to know what you're up to. + */ +int s_mp_tovalue(char ch, int r) +{ + int val, xch; + + if(r > 36) + xch = ch; + else + xch = toupper(ch); + + if(isdigit(xch)) + val = xch - '0'; + else if(isupper(xch)) + val = xch - 'A' + 10; + else if(islower(xch)) + val = xch - 'a' + 36; + else if(xch == '+') + val = 62; + else if(xch == '/') + val = 63; + else + return -1; + + if(val < 0 || val >= r) + return -1; + + return val; + +} /* end s_mp_tovalue() */ + +/* }}} */ + +/* {{{ s_mp_todigit(val, r, low) */ + +/* + Convert val to a radix-r digit, if possible. If val is out of range + for r, returns zero. Otherwise, returns an ASCII character denoting + the value in the given radix. + + The results may be odd if you use a radix < 2 or > 64, you are + expected to know what you're doing. + */ + +char s_mp_todigit(int val, int r, int low) +{ + char ch; + + if(val < 0 || val >= r) + return 0; + + ch = s_dmap_1[val]; + + if(r <= 36 && low) + ch = tolower(ch); + + return ch; + +} /* end s_mp_todigit() */ + +/* }}} */ + +/* {{{ s_mp_outlen(bits, radix) */ + +/* + Return an estimate for how long a string is needed to hold a radix + r representation of a number with 'bits' significant bits. + + Does not include space for a sign or a NUL terminator. + */ +int s_mp_outlen(int bits, int r) +{ + return (int)((double)bits * LOG_V_2(r)); + +} /* end s_mp_outlen() */ + +/* }}} */ + +/* }}} */ + +/*------------------------------------------------------------------------*/ +/* HERE THERE BE DRAGONS */ +/* crc==4242132123, version==2, Sat Feb 02 06:43:52 2002 */ + +/* $Source$ */ +/* $Revision: 0.36 $ */ +/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/mtest/mpi.h b/xmhf-64/xmhf/third-party/libtommath/mtest/mpi.h new file mode 100644 index 0000000000..526c3fd1b7 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/mtest/mpi.h @@ -0,0 +1,231 @@ +/* + mpi.h + + by Michael J. Fromberger + Copyright (C) 1998 Michael J. Fromberger, All Rights Reserved + + Arbitrary precision integer arithmetic library + + $ID$ + */ + +#ifndef _H_MPI_ +#define _H_MPI_ + +#include "mpi-config.h" + +#define MP_LT -1 +#define MP_EQ 0 +#define MP_GT 1 + +#if MP_DEBUG +#undef MP_IOFUNC +#define MP_IOFUNC 1 +#endif + +#if MP_IOFUNC +#include +#include +#endif + +#include + +#define MP_NEG 1 +#define MP_ZPOS 0 + +/* Included for compatibility... */ +#define NEG MP_NEG +#define ZPOS MP_ZPOS + +#define MP_OKAY 0 /* no error, all is well */ +#define MP_YES 0 /* yes (boolean result) */ +#define MP_NO -1 /* no (boolean result) */ +#define MP_MEM -2 /* out of memory */ +#define MP_RANGE -3 /* argument out of range */ +#define MP_BADARG -4 /* invalid parameter */ +#define MP_UNDEF -5 /* answer is undefined */ +#define MP_LAST_CODE MP_UNDEF + +#include "mpi-types.h" + +/* Included for compatibility... */ +#define DIGIT_BIT MP_DIGIT_BIT +#define DIGIT_MAX MP_DIGIT_MAX + +/* Macros for accessing the mp_int internals */ +#define SIGN(MP) ((MP)->sign) +#define USED(MP) ((MP)->used) +#define ALLOC(MP) ((MP)->alloc) +#define DIGITS(MP) ((MP)->dp) +#define DIGIT(MP,N) (MP)->dp[(N)] + +#if MP_ARGCHK == 1 +#define ARGCHK(X,Y) {if(!(X)){return (Y);}} +#elif MP_ARGCHK == 2 +#include +#define ARGCHK(X,Y) assert(X) +#else +#define ARGCHK(X,Y) /* */ +#endif + +/* This defines the maximum I/O base (minimum is 2) */ +#define MAX_RADIX 64 + +typedef struct { + mp_sign sign; /* sign of this quantity */ + mp_size alloc; /* how many digits allocated */ + mp_size used; /* how many digits used */ + mp_digit *dp; /* the digits themselves */ +} mp_int; + +/*------------------------------------------------------------------------*/ +/* Default precision */ + +unsigned int mp_get_prec(void); +void mp_set_prec(unsigned int prec); + +/*------------------------------------------------------------------------*/ +/* Memory management */ + +mp_err mp_init(mp_int *mp); +mp_err mp_init_array(mp_int mp[], int count); +mp_err mp_init_size(mp_int *mp, mp_size prec); +mp_err mp_init_copy(mp_int *mp, mp_int *from); +mp_err mp_copy(mp_int *from, mp_int *to); +void mp_exch(mp_int *mp1, mp_int *mp2); +void mp_clear(mp_int *mp); +void mp_clear_array(mp_int mp[], int count); +void mp_zero(mp_int *mp); +void mp_set(mp_int *mp, mp_digit d); +mp_err mp_set_int(mp_int *mp, long z); +mp_err mp_shrink(mp_int *a); + + +/*------------------------------------------------------------------------*/ +/* Single digit arithmetic */ + +mp_err mp_add_d(mp_int *a, mp_digit d, mp_int *b); +mp_err mp_sub_d(mp_int *a, mp_digit d, mp_int *b); +mp_err mp_mul_d(mp_int *a, mp_digit d, mp_int *b); +mp_err mp_mul_2(mp_int *a, mp_int *c); +mp_err mp_div_d(mp_int *a, mp_digit d, mp_int *q, mp_digit *r); +mp_err mp_div_2(mp_int *a, mp_int *c); +mp_err mp_expt_d(mp_int *a, mp_digit d, mp_int *c); + +/*------------------------------------------------------------------------*/ +/* Sign manipulations */ + +mp_err mp_abs(mp_int *a, mp_int *b); +mp_err mp_neg(mp_int *a, mp_int *b); + +/*------------------------------------------------------------------------*/ +/* Full arithmetic */ + +mp_err mp_add(mp_int *a, mp_int *b, mp_int *c); +mp_err mp_sub(mp_int *a, mp_int *b, mp_int *c); +mp_err mp_mul(mp_int *a, mp_int *b, mp_int *c); +mp_err mp_mul_2d(mp_int *a, mp_digit d, mp_int *c); +#if MP_SQUARE +mp_err mp_sqr(mp_int *a, mp_int *b); +#else +#define mp_sqr(a, b) mp_mul(a, a, b) +#endif +mp_err mp_div(mp_int *a, mp_int *b, mp_int *q, mp_int *r); +mp_err mp_div_2d(mp_int *a, mp_digit d, mp_int *q, mp_int *r); +mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c); +mp_err mp_2expt(mp_int *a, mp_digit k); +mp_err mp_sqrt(mp_int *a, mp_int *b); + +/*------------------------------------------------------------------------*/ +/* Modular arithmetic */ + +#if MP_MODARITH +mp_err mp_mod(mp_int *a, mp_int *m, mp_int *c); +mp_err mp_mod_d(mp_int *a, mp_digit d, mp_digit *c); +mp_err mp_addmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c); +mp_err mp_submod(mp_int *a, mp_int *b, mp_int *m, mp_int *c); +mp_err mp_mulmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c); +#if MP_SQUARE +mp_err mp_sqrmod(mp_int *a, mp_int *m, mp_int *c); +#else +#define mp_sqrmod(a, m, c) mp_mulmod(a, a, m, c) +#endif +mp_err mp_exptmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c); +mp_err mp_exptmod_d(mp_int *a, mp_digit d, mp_int *m, mp_int *c); +#endif /* MP_MODARITH */ + +/*------------------------------------------------------------------------*/ +/* Comparisons */ + +int mp_cmp_z(mp_int *a); +int mp_cmp_d(mp_int *a, mp_digit d); +int mp_cmp(mp_int *a, mp_int *b); +int mp_cmp_mag(mp_int *a, mp_int *b); +int mp_cmp_int(mp_int *a, long z); +int mp_isodd(mp_int *a); +int mp_iseven(mp_int *a); + +/*------------------------------------------------------------------------*/ +/* Number theoretic */ + +#if MP_NUMTH +mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c); +mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c); +mp_err mp_xgcd(mp_int *a, mp_int *b, mp_int *g, mp_int *x, mp_int *y); +mp_err mp_invmod(mp_int *a, mp_int *m, mp_int *c); +#endif /* end MP_NUMTH */ + +/*------------------------------------------------------------------------*/ +/* Input and output */ + +#if MP_IOFUNC +void mp_print(mp_int *mp, FILE *ofp); +#endif /* end MP_IOFUNC */ + +/*------------------------------------------------------------------------*/ +/* Base conversion */ + +#define BITS 1 +#define BYTES CHAR_BIT + +mp_err mp_read_signed_bin(mp_int *mp, unsigned char *str, int len); +int mp_signed_bin_size(mp_int *mp); +mp_err mp_to_signed_bin(mp_int *mp, unsigned char *str); + +mp_err mp_read_unsigned_bin(mp_int *mp, unsigned char *str, int len); +int mp_unsigned_bin_size(mp_int *mp); +mp_err mp_to_unsigned_bin(mp_int *mp, unsigned char *str); + +int mp_count_bits(mp_int *mp); + +#if MP_COMPAT_MACROS +#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len)) +#define mp_raw_size(mp) mp_signed_bin_size(mp) +#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str)) +#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len)) +#define mp_mag_size(mp) mp_unsigned_bin_size(mp) +#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str)) +#endif + +mp_err mp_read_radix(mp_int *mp, unsigned char *str, int radix); +int mp_radix_size(mp_int *mp, int radix); +int mp_value_radix_size(int num, int qty, int radix); +mp_err mp_toradix(mp_int *mp, unsigned char *str, int radix); + +int mp_char2value(char ch, int r); + +#define mp_tobinary(M, S) mp_toradix((M), (S), 2) +#define mp_tooctal(M, S) mp_toradix((M), (S), 8) +#define mp_todecimal(M, S) mp_toradix((M), (S), 10) +#define mp_tohex(M, S) mp_toradix((M), (S), 16) + +/*------------------------------------------------------------------------*/ +/* Error strings */ + +const char *mp_strerror(mp_err ec); + +#endif /* end _H_MPI_ */ + +/* $Source$ */ +/* $Revision: 0.36 $ */ +/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/mtest/mtest.c b/xmhf-64/xmhf/third-party/libtommath/mtest/mtest.c new file mode 100644 index 0000000000..92f03adf6a --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/mtest/mtest.c @@ -0,0 +1,308 @@ +/* makes a bignum test harness with NUM tests per operation + * + * the output is made in the following format [one parameter per line] + +operation +operand1 +operand2 +[... operandN] +result1 +result2 +[... resultN] + +So for example "a * b mod n" would be + +mulmod +a +b +n +a*b mod n + +e.g. if a=3, b=4 n=11 then + +mulmod +3 +4 +11 +1 + + */ + +#ifdef MP_8BIT +#define THE_MASK 127 +#else +#define THE_MASK 32767 +#endif + +#include +#include +#include +#include "mpi.c" + +FILE *rng; + +void rand_num(mp_int *a) +{ + int n, size; + unsigned char buf[2048]; + + size = 1 + ((fgetc(rng)<<8) + fgetc(rng)) % 101; + buf[0] = (fgetc(rng)&1)?1:0; + fread(buf+1, 1, size, rng); + while (buf[1] == 0) buf[1] = fgetc(rng); + mp_read_raw(a, buf, 1+size); +} + +void rand_num2(mp_int *a) +{ + int n, size; + unsigned char buf[2048]; + + size = 10 + ((fgetc(rng)<<8) + fgetc(rng)) % 101; + buf[0] = (fgetc(rng)&1)?1:0; + fread(buf+1, 1, size, rng); + while (buf[1] == 0) buf[1] = fgetc(rng); + mp_read_raw(a, buf, 1+size); +} + +#define mp_to64(a, b) mp_toradix(a, b, 64) + +int main(void) +{ + int n, tmp; + mp_int a, b, c, d, e; + clock_t t1; + char buf[4096]; + + mp_init(&a); + mp_init(&b); + mp_init(&c); + mp_init(&d); + mp_init(&e); + + + /* initial (2^n - 1)^2 testing, makes sure the comba multiplier works [it has the new carry code] */ +/* + mp_set(&a, 1); + for (n = 1; n < 8192; n++) { + mp_mul(&a, &a, &c); + printf("mul\n"); + mp_to64(&a, buf); + printf("%s\n%s\n", buf, buf); + mp_to64(&c, buf); + printf("%s\n", buf); + + mp_add_d(&a, 1, &a); + mp_mul_2(&a, &a); + mp_sub_d(&a, 1, &a); + } +*/ + + rng = fopen("/dev/urandom", "rb"); + if (rng == NULL) { + rng = fopen("/dev/random", "rb"); + if (rng == NULL) { + fprintf(stderr, "\nWarning: stdin used as random source\n\n"); + rng = stdin; + } + } + + t1 = clock(); + for (;;) { +#if 0 + if (clock() - t1 > CLOCKS_PER_SEC) { + sleep(2); + t1 = clock(); + } +#endif + n = fgetc(rng) % 15; + + if (n == 0) { + /* add tests */ + rand_num(&a); + rand_num(&b); + mp_add(&a, &b, &c); + printf("add\n"); + mp_to64(&a, buf); + printf("%s\n", buf); + mp_to64(&b, buf); + printf("%s\n", buf); + mp_to64(&c, buf); + printf("%s\n", buf); + } else if (n == 1) { + /* sub tests */ + rand_num(&a); + rand_num(&b); + mp_sub(&a, &b, &c); + printf("sub\n"); + mp_to64(&a, buf); + printf("%s\n", buf); + mp_to64(&b, buf); + printf("%s\n", buf); + mp_to64(&c, buf); + printf("%s\n", buf); + } else if (n == 2) { + /* mul tests */ + rand_num(&a); + rand_num(&b); + mp_mul(&a, &b, &c); + printf("mul\n"); + mp_to64(&a, buf); + printf("%s\n", buf); + mp_to64(&b, buf); + printf("%s\n", buf); + mp_to64(&c, buf); + printf("%s\n", buf); + } else if (n == 3) { + /* div tests */ + rand_num(&a); + rand_num(&b); + mp_div(&a, &b, &c, &d); + printf("div\n"); + mp_to64(&a, buf); + printf("%s\n", buf); + mp_to64(&b, buf); + printf("%s\n", buf); + mp_to64(&c, buf); + printf("%s\n", buf); + mp_to64(&d, buf); + printf("%s\n", buf); + } else if (n == 4) { + /* sqr tests */ + rand_num(&a); + mp_sqr(&a, &b); + printf("sqr\n"); + mp_to64(&a, buf); + printf("%s\n", buf); + mp_to64(&b, buf); + printf("%s\n", buf); + } else if (n == 5) { + /* mul_2d test */ + rand_num(&a); + mp_copy(&a, &b); + n = fgetc(rng) & 63; + mp_mul_2d(&b, n, &b); + mp_to64(&a, buf); + printf("mul2d\n"); + printf("%s\n", buf); + printf("%d\n", n); + mp_to64(&b, buf); + printf("%s\n", buf); + } else if (n == 6) { + /* div_2d test */ + rand_num(&a); + mp_copy(&a, &b); + n = fgetc(rng) & 63; + mp_div_2d(&b, n, &b, NULL); + mp_to64(&a, buf); + printf("div2d\n"); + printf("%s\n", buf); + printf("%d\n", n); + mp_to64(&b, buf); + printf("%s\n", buf); + } else if (n == 7) { + /* gcd test */ + rand_num(&a); + rand_num(&b); + a.sign = MP_ZPOS; + b.sign = MP_ZPOS; + mp_gcd(&a, &b, &c); + printf("gcd\n"); + mp_to64(&a, buf); + printf("%s\n", buf); + mp_to64(&b, buf); + printf("%s\n", buf); + mp_to64(&c, buf); + printf("%s\n", buf); + } else if (n == 8) { + /* lcm test */ + rand_num(&a); + rand_num(&b); + a.sign = MP_ZPOS; + b.sign = MP_ZPOS; + mp_lcm(&a, &b, &c); + printf("lcm\n"); + mp_to64(&a, buf); + printf("%s\n", buf); + mp_to64(&b, buf); + printf("%s\n", buf); + mp_to64(&c, buf); + printf("%s\n", buf); + } else if (n == 9) { + /* exptmod test */ + rand_num2(&a); + rand_num2(&b); + rand_num2(&c); +// if (c.dp[0]&1) mp_add_d(&c, 1, &c); + a.sign = b.sign = c.sign = 0; + mp_exptmod(&a, &b, &c, &d); + printf("expt\n"); + mp_to64(&a, buf); + printf("%s\n", buf); + mp_to64(&b, buf); + printf("%s\n", buf); + mp_to64(&c, buf); + printf("%s\n", buf); + mp_to64(&d, buf); + printf("%s\n", buf); + } else if (n == 10) { + /* invmod test */ + rand_num2(&a); + rand_num2(&b); + b.sign = MP_ZPOS; + a.sign = MP_ZPOS; + mp_gcd(&a, &b, &c); + if (mp_cmp_d(&c, 1) != 0) continue; + if (mp_cmp_d(&b, 1) == 0) continue; + mp_invmod(&a, &b, &c); + printf("invmod\n"); + mp_to64(&a, buf); + printf("%s\n", buf); + mp_to64(&b, buf); + printf("%s\n", buf); + mp_to64(&c, buf); + printf("%s\n", buf); + } else if (n == 11) { + rand_num(&a); + mp_mul_2(&a, &a); + mp_div_2(&a, &b); + printf("div2\n"); + mp_to64(&a, buf); + printf("%s\n", buf); + mp_to64(&b, buf); + printf("%s\n", buf); + } else if (n == 12) { + rand_num2(&a); + mp_mul_2(&a, &b); + printf("mul2\n"); + mp_to64(&a, buf); + printf("%s\n", buf); + mp_to64(&b, buf); + printf("%s\n", buf); + } else if (n == 13) { + rand_num2(&a); + tmp = abs(rand()) & THE_MASK; + mp_add_d(&a, tmp, &b); + printf("add_d\n"); + mp_to64(&a, buf); + printf("%s\n%d\n", buf, tmp); + mp_to64(&b, buf); + printf("%s\n", buf); + } else if (n == 14) { + rand_num2(&a); + tmp = abs(rand()) & THE_MASK; + mp_sub_d(&a, tmp, &b); + printf("sub_d\n"); + mp_to64(&a, buf); + printf("%s\n%d\n", buf, tmp); + mp_to64(&b, buf); + printf("%s\n", buf); + } + } + fclose(rng); + return 0; +} + +/* $Source$ */ +/* $Revision: 0.36 $ */ +/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/pics/design_process.sxd b/xmhf-64/xmhf/third-party/libtommath/pics/design_process.sxd new file mode 100644 index 0000000000..7414dbb276 Binary files /dev/null and b/xmhf-64/xmhf/third-party/libtommath/pics/design_process.sxd differ diff --git a/xmhf-64/xmhf/third-party/libtommath/pics/design_process.tif b/xmhf-64/xmhf/third-party/libtommath/pics/design_process.tif new file mode 100644 index 0000000000..4a0c012d56 Binary files /dev/null and b/xmhf-64/xmhf/third-party/libtommath/pics/design_process.tif differ diff --git a/xmhf-64/xmhf/third-party/libtommath/pics/expt_state.sxd b/xmhf-64/xmhf/third-party/libtommath/pics/expt_state.sxd new file mode 100644 index 0000000000..6518404d5f Binary files /dev/null and b/xmhf-64/xmhf/third-party/libtommath/pics/expt_state.sxd differ diff --git a/xmhf-64/xmhf/third-party/libtommath/pics/expt_state.tif b/xmhf-64/xmhf/third-party/libtommath/pics/expt_state.tif new file mode 100644 index 0000000000..cb06e8edf1 Binary files /dev/null and b/xmhf-64/xmhf/third-party/libtommath/pics/expt_state.tif differ diff --git a/xmhf-64/xmhf/third-party/libtommath/pics/makefile b/xmhf-64/xmhf/third-party/libtommath/pics/makefile new file mode 100644 index 0000000000..3ecb02ff73 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/pics/makefile @@ -0,0 +1,35 @@ +# makes the images... yeah + +default: pses + +design_process.ps: design_process.tif + tiff2ps -s -e design_process.tif > design_process.ps + +sliding_window.ps: sliding_window.tif + tiff2ps -s -e sliding_window.tif > sliding_window.ps + +expt_state.ps: expt_state.tif + tiff2ps -s -e expt_state.tif > expt_state.ps + +primality.ps: primality.tif + tiff2ps -s -e primality.tif > primality.ps + +design_process.pdf: design_process.ps + epstopdf design_process.ps + +sliding_window.pdf: sliding_window.ps + epstopdf sliding_window.ps + +expt_state.pdf: expt_state.ps + epstopdf expt_state.ps + +primality.pdf: primality.ps + epstopdf primality.ps + + +pses: sliding_window.ps expt_state.ps primality.ps design_process.ps +pdfes: sliding_window.pdf expt_state.pdf primality.pdf design_process.pdf + +clean: + rm -rf *.ps *.pdf .xvpics + \ No newline at end of file diff --git a/xmhf-64/xmhf/third-party/libtommath/pics/primality.tif b/xmhf-64/xmhf/third-party/libtommath/pics/primality.tif new file mode 100644 index 0000000000..76d6be3fac Binary files /dev/null and b/xmhf-64/xmhf/third-party/libtommath/pics/primality.tif differ diff --git a/xmhf-64/xmhf/third-party/libtommath/pics/radix.sxd b/xmhf-64/xmhf/third-party/libtommath/pics/radix.sxd new file mode 100644 index 0000000000..b9eb9a032d Binary files /dev/null and b/xmhf-64/xmhf/third-party/libtommath/pics/radix.sxd differ diff --git a/xmhf-64/xmhf/third-party/libtommath/pics/sliding_window.sxd b/xmhf-64/xmhf/third-party/libtommath/pics/sliding_window.sxd new file mode 100644 index 0000000000..91e7c0d9f4 Binary files /dev/null and b/xmhf-64/xmhf/third-party/libtommath/pics/sliding_window.sxd differ diff --git a/xmhf-64/xmhf/third-party/libtommath/pics/sliding_window.tif b/xmhf-64/xmhf/third-party/libtommath/pics/sliding_window.tif new file mode 100644 index 0000000000..bb4cb96ebf Binary files /dev/null and b/xmhf-64/xmhf/third-party/libtommath/pics/sliding_window.tif differ diff --git a/xmhf-64/xmhf/third-party/libtommath/poster.out b/xmhf-64/xmhf/third-party/libtommath/poster.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/xmhf-64/xmhf/third-party/libtommath/poster.pdf b/xmhf-64/xmhf/third-party/libtommath/poster.pdf new file mode 100644 index 0000000000..dc80fbb902 Binary files /dev/null and b/xmhf-64/xmhf/third-party/libtommath/poster.pdf differ diff --git a/xmhf-64/xmhf/third-party/libtommath/poster.tex b/xmhf-64/xmhf/third-party/libtommath/poster.tex new file mode 100644 index 0000000000..e7388f44d0 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/poster.tex @@ -0,0 +1,35 @@ +\documentclass[landscape,11pt]{article} +\usepackage{amsmath, amssymb} +\usepackage{hyperref} +\begin{document} +\hspace*{-3in} +\begin{tabular}{llllll} +$c = a + b$ & {\tt mp\_add(\&a, \&b, \&c)} & $b = 2a$ & {\tt mp\_mul\_2(\&a, \&b)} & \\ +$c = a - b$ & {\tt mp\_sub(\&a, \&b, \&c)} & $b = a/2$ & {\tt mp\_div\_2(\&a, \&b)} & \\ +$c = ab $ & {\tt mp\_mul(\&a, \&b, \&c)} & $c = 2^ba$ & {\tt mp\_mul\_2d(\&a, b, \&c)} \\ +$b = a^2 $ & {\tt mp\_sqr(\&a, \&b)} & $c = a/2^b, d = a \mod 2^b$ & {\tt mp\_div\_2d(\&a, b, \&c, \&d)} \\ +$c = \lfloor a/b \rfloor, d = a \mod b$ & {\tt mp\_div(\&a, \&b, \&c, \&d)} & $c = a \mod 2^b $ & {\tt mp\_mod\_2d(\&a, b, \&c)} \\ + && \\ +$a = b $ & {\tt mp\_set\_int(\&a, b)} & $c = a \vee b$ & {\tt mp\_or(\&a, \&b, \&c)} \\ +$b = a $ & {\tt mp\_copy(\&a, \&b)} & $c = a \wedge b$ & {\tt mp\_and(\&a, \&b, \&c)} \\ + && $c = a \oplus b$ & {\tt mp\_xor(\&a, \&b, \&c)} \\ + & \\ +$b = -a $ & {\tt mp\_neg(\&a, \&b)} & $d = a + b \mod c$ & {\tt mp\_addmod(\&a, \&b, \&c, \&d)} \\ +$b = |a| $ & {\tt mp\_abs(\&a, \&b)} & $d = a - b \mod c$ & {\tt mp\_submod(\&a, \&b, \&c, \&d)} \\ + && $d = ab \mod c$ & {\tt mp\_mulmod(\&a, \&b, \&c, \&d)} \\ +Compare $a$ and $b$ & {\tt mp\_cmp(\&a, \&b)} & $c = a^2 \mod b$ & {\tt mp\_sqrmod(\&a, \&b, \&c)} \\ +Is Zero? & {\tt mp\_iszero(\&a)} & $c = a^{-1} \mod b$ & {\tt mp\_invmod(\&a, \&b, \&c)} \\ +Is Even? & {\tt mp\_iseven(\&a)} & $d = a^b \mod c$ & {\tt mp\_exptmod(\&a, \&b, \&c, \&d)} \\ +Is Odd ? & {\tt mp\_isodd(\&a)} \\ +&\\ +$\vert \vert a \vert \vert$ & {\tt mp\_unsigned\_bin\_size(\&a)} & $res$ = 1 if $a$ prime to $t$ rounds? & {\tt mp\_prime\_is\_prime(\&a, t, \&res)} \\ +$buf \leftarrow a$ & {\tt mp\_to\_unsigned\_bin(\&a, buf)} & Next prime after $a$ to $t$ rounds. & {\tt mp\_prime\_next\_prime(\&a, t, bbs\_style)} \\ +$a \leftarrow buf[0..len-1]$ & {\tt mp\_read\_unsigned\_bin(\&a, buf, len)} \\ +&\\ +$b = \sqrt{a}$ & {\tt mp\_sqrt(\&a, \&b)} & $c = \mbox{gcd}(a, b)$ & {\tt mp\_gcd(\&a, \&b, \&c)} \\ +$c = a^{1/b}$ & {\tt mp\_n\_root(\&a, b, \&c)} & $c = \mbox{lcm}(a, b)$ & {\tt mp\_lcm(\&a, \&b, \&c)} \\ +&\\ +Greater Than & MP\_GT & Equal To & MP\_EQ \\ +Less Than & MP\_LT & Bits per digit & DIGIT\_BIT \\ +\end{tabular} +\end{document} diff --git a/xmhf-64/xmhf/third-party/libtommath/pre_gen/mpi.c b/xmhf-64/xmhf/third-party/libtommath/pre_gen/mpi.c new file mode 100644 index 0000000000..3132a46a7f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/pre_gen/mpi.c @@ -0,0 +1,9524 @@ +/* Start: bn_error.c */ +#include +#ifdef BN_ERROR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +static const struct { + int code; + char *msg; +} msgs[] = { + { MP_OKAY, "Successful" }, + { MP_MEM, "Out of heap" }, + { MP_VAL, "Value out of range" } +}; + +/* return a char * string for a given code */ +char *mp_error_to_string(int code) +{ + int x; + + /* scan the lookup table for the given message */ + for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) { + if (msgs[x].code == code) { + return msgs[x].msg; + } + } + + /* generic reply for invalid code */ + return "Invalid error code"; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_error.c */ + +/* Start: bn_fast_mp_invmod.c */ +#include +#ifdef BN_FAST_MP_INVMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* computes the modular inverse via binary extended euclidean algorithm, + * that is c = 1/a mod b + * + * Based on slow invmod except this is optimized for the case where b is + * odd as per HAC Note 14.64 on pp. 610 + */ +int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int x, y, u, v, B, D; + int res, neg; + + /* 2. [modified] b must be odd */ + if (mp_iseven (b) == 1) { + return MP_VAL; + } + + /* init all our temps */ + if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) { + return res; + } + + /* x == modulus, y == value to invert */ + if ((res = mp_copy (b, &x)) != MP_OKAY) { + goto LBL_ERR; + } + + /* we need y = |a| */ + if ((res = mp_mod (a, b, &y)) != MP_OKAY) { + goto LBL_ERR; + } + + /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ + if ((res = mp_copy (&x, &u)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_copy (&y, &v)) != MP_OKAY) { + goto LBL_ERR; + } + mp_set (&D, 1); + +top: + /* 4. while u is even do */ + while (mp_iseven (&u) == 1) { + /* 4.1 u = u/2 */ + if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { + goto LBL_ERR; + } + /* 4.2 if B is odd then */ + if (mp_isodd (&B) == 1) { + if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* B = B/2 */ + if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 5. while v is even do */ + while (mp_iseven (&v) == 1) { + /* 5.1 v = v/2 */ + if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { + goto LBL_ERR; + } + /* 5.2 if D is odd then */ + if (mp_isodd (&D) == 1) { + /* D = (D-x)/2 */ + if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* D = D/2 */ + if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 6. if u >= v then */ + if (mp_cmp (&u, &v) != MP_LT) { + /* u = u - v, B = B - D */ + if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } else { + /* v - v - u, D = D - B */ + if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* if not zero goto step 4 */ + if (mp_iszero (&u) == 0) { + goto top; + } + + /* now a = C, b = D, gcd == g*v */ + + /* if v != 1 then there is no inverse */ + if (mp_cmp_d (&v, 1) != MP_EQ) { + res = MP_VAL; + goto LBL_ERR; + } + + /* b is now the inverse */ + neg = a->sign; + while (D.sign == MP_NEG) { + if ((res = mp_add (&D, b, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + mp_exch (&D, c); + c->sign = neg; + res = MP_OKAY; + +LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_fast_mp_invmod.c */ + +/* Start: bn_fast_mp_montgomery_reduce.c */ +#include +#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* computes xR**-1 == x (mod N) via Montgomery Reduction + * + * This is an optimized implementation of montgomery_reduce + * which uses the comba method to quickly calculate the columns of the + * reduction. + * + * Based on Algorithm 14.32 on pp.601 of HAC. +*/ +int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) +{ + int ix, res, olduse; + mp_word W[MP_WARRAY]; + + /* get old used count */ + olduse = x->used; + + /* grow a as required */ + if (x->alloc < n->used + 1) { + if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) { + return res; + } + } + + /* first we have to get the digits of the input into + * an array of double precision words W[...] + */ + { + register mp_word *_W; + register mp_digit *tmpx; + + /* alias for the W[] array */ + _W = W; + + /* alias for the digits of x*/ + tmpx = x->dp; + + /* copy the digits of a into W[0..a->used-1] */ + for (ix = 0; ix < x->used; ix++) { + *_W++ = *tmpx++; + } + + /* zero the high words of W[a->used..m->used*2] */ + for (; ix < n->used * 2 + 1; ix++) { + *_W++ = 0; + } + } + + /* now we proceed to zero successive digits + * from the least significant upwards + */ + for (ix = 0; ix < n->used; ix++) { + /* mu = ai * m' mod b + * + * We avoid a double precision multiplication (which isn't required) + * by casting the value down to a mp_digit. Note this requires + * that W[ix-1] have the carry cleared (see after the inner loop) + */ + register mp_digit mu; + mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK); + + /* a = a + mu * m * b**i + * + * This is computed in place and on the fly. The multiplication + * by b**i is handled by offseting which columns the results + * are added to. + * + * Note the comba method normally doesn't handle carries in the + * inner loop In this case we fix the carry from the previous + * column since the Montgomery reduction requires digits of the + * result (so far) [see above] to work. This is + * handled by fixing up one carry after the inner loop. The + * carry fixups are done in order so after these loops the + * first m->used words of W[] have the carries fixed + */ + { + register int iy; + register mp_digit *tmpn; + register mp_word *_W; + + /* alias for the digits of the modulus */ + tmpn = n->dp; + + /* Alias for the columns set by an offset of ix */ + _W = W + ix; + + /* inner loop */ + for (iy = 0; iy < n->used; iy++) { + *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++); + } + } + + /* now fix carry for next digit, W[ix+1] */ + W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT); + } + + /* now we have to propagate the carries and + * shift the words downward [all those least + * significant digits we zeroed]. + */ + { + register mp_digit *tmpx; + register mp_word *_W, *_W1; + + /* nox fix rest of carries */ + + /* alias for current word */ + _W1 = W + ix; + + /* alias for next word, where the carry goes */ + _W = W + ++ix; + + for (; ix <= n->used * 2 + 1; ix++) { + *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT); + } + + /* copy out, A = A/b**n + * + * The result is A/b**n but instead of converting from an + * array of mp_word to mp_digit than calling mp_rshd + * we just copy them in the right order + */ + + /* alias for destination word */ + tmpx = x->dp; + + /* alias for shifted double precision result */ + _W = W + n->used; + + for (ix = 0; ix < n->used + 1; ix++) { + *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK)); + } + + /* zero oldused digits, if the input a was larger than + * m->used+1 we'll have to clear the digits + */ + for (; ix < olduse; ix++) { + *tmpx++ = 0; + } + } + + /* set the max used and clamp */ + x->used = n->used + 1; + mp_clamp (x); + + /* if A >= m then A = A - m */ + if (mp_cmp_mag (x, n) != MP_LT) { + return s_mp_sub (x, n, x); + } + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_fast_mp_montgomery_reduce.c */ + +/* Start: bn_fast_s_mp_mul_digs.c */ +#include +#ifdef BN_FAST_S_MP_MUL_DIGS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Fast (comba) multiplier + * + * This is the fast column-array [comba] multiplier. It is + * designed to compute the columns of the product first + * then handle the carries afterwards. This has the effect + * of making the nested loops that compute the columns very + * simple and schedulable on super-scalar processors. + * + * This has been modified to produce a variable number of + * digits of output so if say only a half-product is required + * you don't have to compute the upper half (a feature + * required for fast Barrett reduction). + * + * Based on Algorithm 14.12 on pp.595 of HAC. + * + */ +int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + int olduse, res, pa, ix, iz; + mp_digit W[MP_WARRAY]; + register mp_word _W; + + /* grow the destination as required */ + if (c->alloc < digs) { + if ((res = mp_grow (c, digs)) != MP_OKAY) { + return res; + } + } + + /* number of output digits to produce */ + pa = MIN(digs, a->used + b->used); + + /* clear the carry */ + _W = 0; + for (ix = 0; ix < pa; ix++) { + int tx, ty; + int iy; + mp_digit *tmpx, *tmpy; + + /* get offsets into the two bignums */ + ty = MIN(b->used-1, ix); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = b->dp + ty; + + /* this is the number of times the loop will iterrate, essentially + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MIN(a->used-tx, ty+1); + + /* execute loop */ + for (iz = 0; iz < iy; ++iz) { + _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); + + } + + /* store term */ + W[ix] = ((mp_digit)_W) & MP_MASK; + + /* make next carry */ + _W = _W >> ((mp_word)DIGIT_BIT); + } + + /* setup dest */ + olduse = c->used; + c->used = pa; + + { + register mp_digit *tmpc; + tmpc = c->dp; + for (ix = 0; ix < pa+1; ix++) { + /* now extract the previous digit [below the carry] */ + *tmpc++ = W[ix]; + } + + /* clear unused digits [that existed in the old copy of c] */ + for (; ix < olduse; ix++) { + *tmpc++ = 0; + } + } + mp_clamp (c); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_fast_s_mp_mul_digs.c */ + +/* Start: bn_fast_s_mp_mul_high_digs.c */ +#include +#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* this is a modified version of fast_s_mul_digs that only produces + * output digits *above* digs. See the comments for fast_s_mul_digs + * to see how it works. + * + * This is used in the Barrett reduction since for one of the multiplications + * only the higher digits were needed. This essentially halves the work. + * + * Based on Algorithm 14.12 on pp.595 of HAC. + */ +int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + int olduse, res, pa, ix, iz; + mp_digit W[MP_WARRAY]; + mp_word _W; + + /* grow the destination as required */ + pa = a->used + b->used; + if (c->alloc < pa) { + if ((res = mp_grow (c, pa)) != MP_OKAY) { + return res; + } + } + + /* number of output digits to produce */ + pa = a->used + b->used; + _W = 0; + for (ix = digs; ix < pa; ix++) { + int tx, ty, iy; + mp_digit *tmpx, *tmpy; + + /* get offsets into the two bignums */ + ty = MIN(b->used-1, ix); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = b->dp + ty; + + /* this is the number of times the loop will iterrate, essentially its + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MIN(a->used-tx, ty+1); + + /* execute loop */ + for (iz = 0; iz < iy; iz++) { + _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); + } + + /* store term */ + W[ix] = ((mp_digit)_W) & MP_MASK; + + /* make next carry */ + _W = _W >> ((mp_word)DIGIT_BIT); + } + + /* setup dest */ + olduse = c->used; + c->used = pa; + + { + register mp_digit *tmpc; + + tmpc = c->dp + digs; + for (ix = digs; ix < pa; ix++) { + /* now extract the previous digit [below the carry] */ + *tmpc++ = W[ix]; + } + + /* clear unused digits [that existed in the old copy of c] */ + for (; ix < olduse; ix++) { + *tmpc++ = 0; + } + } + mp_clamp (c); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_fast_s_mp_mul_high_digs.c */ + +/* Start: bn_fast_s_mp_sqr.c */ +#include +#ifdef BN_FAST_S_MP_SQR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* the jist of squaring... + * you do like mult except the offset of the tmpx [one that + * starts closer to zero] can't equal the offset of tmpy. + * So basically you set up iy like before then you min it with + * (ty-tx) so that it never happens. You double all those + * you add in the inner loop + +After that loop you do the squares and add them in. +*/ + +int fast_s_mp_sqr (mp_int * a, mp_int * b) +{ + int olduse, res, pa, ix, iz; + mp_digit W[MP_WARRAY], *tmpx; + mp_word W1; + + /* grow the destination as required */ + pa = a->used + a->used; + if (b->alloc < pa) { + if ((res = mp_grow (b, pa)) != MP_OKAY) { + return res; + } + } + + /* number of output digits to produce */ + W1 = 0; + for (ix = 0; ix < pa; ix++) { + int tx, ty, iy; + mp_word _W; + mp_digit *tmpy; + + /* clear counter */ + _W = 0; + + /* get offsets into the two bignums */ + ty = MIN(a->used-1, ix); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = a->dp + ty; + + /* this is the number of times the loop will iterrate, essentially + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MIN(a->used-tx, ty+1); + + /* now for squaring tx can never equal ty + * we halve the distance since they approach at a rate of 2x + * and we have to round because odd cases need to be executed + */ + iy = MIN(iy, (ty-tx+1)>>1); + + /* execute loop */ + for (iz = 0; iz < iy; iz++) { + _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); + } + + /* double the inner product and add carry */ + _W = _W + _W + W1; + + /* even columns have the square term in them */ + if ((ix&1) == 0) { + _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]); + } + + /* store it */ + W[ix] = (mp_digit)(_W & MP_MASK); + + /* make next carry */ + W1 = _W >> ((mp_word)DIGIT_BIT); + } + + /* setup dest */ + olduse = b->used; + b->used = a->used+a->used; + + { + mp_digit *tmpb; + tmpb = b->dp; + for (ix = 0; ix < pa; ix++) { + *tmpb++ = W[ix] & MP_MASK; + } + + /* clear unused digits [that existed in the old copy of c] */ + for (; ix < olduse; ix++) { + *tmpb++ = 0; + } + } + mp_clamp (b); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_fast_s_mp_sqr.c */ + +/* Start: bn_mp_2expt.c */ +#include +#ifdef BN_MP_2EXPT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* computes a = 2**b + * + * Simple algorithm which zeroes the int, grows it then just sets one bit + * as required. + */ +int +mp_2expt (mp_int * a, int b) +{ + int res; + + /* zero a as per default */ + mp_zero (a); + + /* grow a to accomodate the single bit */ + if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) { + return res; + } + + /* set the used count of where the bit will go */ + a->used = b / DIGIT_BIT + 1; + + /* put the single bit in its place */ + a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT); + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_2expt.c */ + +/* Start: bn_mp_abs.c */ +#include +#ifdef BN_MP_ABS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* b = |a| + * + * Simple function copies the input and fixes the sign to positive + */ +int +mp_abs (mp_int * a, mp_int * b) +{ + int res; + + /* copy a to b */ + if (a != b) { + if ((res = mp_copy (a, b)) != MP_OKAY) { + return res; + } + } + + /* force the sign of b to positive */ + b->sign = MP_ZPOS; + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_abs.c */ + +/* Start: bn_mp_add.c */ +#include +#ifdef BN_MP_ADD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* high level addition (handles signs) */ +int mp_add (mp_int * a, mp_int * b, mp_int * c) +{ + int sa, sb, res; + + /* get sign of both inputs */ + sa = a->sign; + sb = b->sign; + + /* handle two cases, not four */ + if (sa == sb) { + /* both positive or both negative */ + /* add their magnitudes, copy the sign */ + c->sign = sa; + res = s_mp_add (a, b, c); + } else { + /* one positive, the other negative */ + /* subtract the one with the greater magnitude from */ + /* the one of the lesser magnitude. The result gets */ + /* the sign of the one with the greater magnitude. */ + if (mp_cmp_mag (a, b) == MP_LT) { + c->sign = sb; + res = s_mp_sub (b, a, c); + } else { + c->sign = sa; + res = s_mp_sub (a, b, c); + } + } + return res; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_add.c */ + +/* Start: bn_mp_add_d.c */ +#include +#ifdef BN_MP_ADD_D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* single digit addition */ +int +mp_add_d (mp_int * a, mp_digit b, mp_int * c) +{ + int res, ix, oldused; + mp_digit *tmpa, *tmpc, mu; + + /* grow c as required */ + if (c->alloc < a->used + 1) { + if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* if a is negative and |a| >= b, call c = |a| - b */ + if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) { + /* temporarily fix sign of a */ + a->sign = MP_ZPOS; + + /* c = |a| - b */ + res = mp_sub_d(a, b, c); + + /* fix sign */ + a->sign = c->sign = MP_NEG; + + /* clamp */ + mp_clamp(c); + + return res; + } + + /* old number of used digits in c */ + oldused = c->used; + + /* sign always positive */ + c->sign = MP_ZPOS; + + /* source alias */ + tmpa = a->dp; + + /* destination alias */ + tmpc = c->dp; + + /* if a is positive */ + if (a->sign == MP_ZPOS) { + /* add digit, after this we're propagating + * the carry. + */ + *tmpc = *tmpa++ + b; + mu = *tmpc >> DIGIT_BIT; + *tmpc++ &= MP_MASK; + + /* now handle rest of the digits */ + for (ix = 1; ix < a->used; ix++) { + *tmpc = *tmpa++ + mu; + mu = *tmpc >> DIGIT_BIT; + *tmpc++ &= MP_MASK; + } + /* set final carry */ + ix++; + *tmpc++ = mu; + + /* setup size */ + c->used = a->used + 1; + } else { + /* a was negative and |a| < b */ + c->used = 1; + + /* the result is a single digit */ + if (a->used == 1) { + *tmpc++ = b - a->dp[0]; + } else { + *tmpc++ = b; + } + + /* setup count so the clearing of oldused + * can fall through correctly + */ + ix = 1; + } + + /* now zero to oldused */ + while (ix++ < oldused) { + *tmpc++ = 0; + } + mp_clamp(c); + + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_add_d.c */ + +/* Start: bn_mp_addmod.c */ +#include +#ifdef BN_MP_ADDMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* d = a + b (mod c) */ +int +mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + int res; + mp_int t; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_add (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, c, d); + mp_clear (&t); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_addmod.c */ + +/* Start: bn_mp_and.c */ +#include +#ifdef BN_MP_AND_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* AND two ints together */ +int +mp_and (mp_int * a, mp_int * b, mp_int * c) +{ + int res, ix, px; + mp_int t, *x; + + if (a->used > b->used) { + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + px = b->used; + x = b; + } else { + if ((res = mp_init_copy (&t, b)) != MP_OKAY) { + return res; + } + px = a->used; + x = a; + } + + for (ix = 0; ix < px; ix++) { + t.dp[ix] &= x->dp[ix]; + } + + /* zero digits above the last from the smallest mp_int */ + for (; ix < t.used; ix++) { + t.dp[ix] = 0; + } + + mp_clamp (&t); + mp_exch (c, &t); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_and.c */ + +/* Start: bn_mp_clamp.c */ +#include +#ifdef BN_MP_CLAMP_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* trim unused digits + * + * This is used to ensure that leading zero digits are + * trimed and the leading "used" digit will be non-zero + * Typically very fast. Also fixes the sign if there + * are no more leading digits + */ +void +mp_clamp (mp_int * a) +{ + /* decrease used while the most significant digit is + * zero. + */ + while (a->used > 0 && a->dp[a->used - 1] == 0) { + --(a->used); + } + + /* reset the sign flag if used == 0 */ + if (a->used == 0) { + a->sign = MP_ZPOS; + } +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_clamp.c */ + +/* Start: bn_mp_clear.c */ +#include +#ifdef BN_MP_CLEAR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* clear one (frees) */ +void +mp_clear (mp_int * a) +{ + int i; + + /* only do anything if a hasn't been freed previously */ + if (a->dp != NULL) { + /* first zero the digits */ + for (i = 0; i < a->used; i++) { + a->dp[i] = 0; + } + + /* free ram */ + XFREE(a->dp); + + /* reset members to make debugging easier */ + a->dp = NULL; + a->alloc = a->used = 0; + a->sign = MP_ZPOS; + } +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_clear.c */ + +/* Start: bn_mp_clear_multi.c */ +#include +#ifdef BN_MP_CLEAR_MULTI_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include + +void mp_clear_multi(mp_int *mp, ...) +{ + mp_int* next_mp = mp; + va_list args; + va_start(args, mp); + while (next_mp != NULL) { + mp_clear(next_mp); + next_mp = va_arg(args, mp_int*); + } + va_end(args); +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_clear_multi.c */ + +/* Start: bn_mp_cmp.c */ +#include +#ifdef BN_MP_CMP_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* compare two ints (signed)*/ +int +mp_cmp (mp_int * a, mp_int * b) +{ + /* compare based on sign */ + if (a->sign != b->sign) { + if (a->sign == MP_NEG) { + return MP_LT; + } else { + return MP_GT; + } + } + + /* compare digits */ + if (a->sign == MP_NEG) { + /* if negative compare opposite direction */ + return mp_cmp_mag(b, a); + } else { + return mp_cmp_mag(a, b); + } +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_cmp.c */ + +/* Start: bn_mp_cmp_d.c */ +#include +#ifdef BN_MP_CMP_D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* compare a digit */ +int mp_cmp_d(mp_int * a, mp_digit b) +{ + /* compare based on sign */ + if (a->sign == MP_NEG) { + return MP_LT; + } + + /* compare based on magnitude */ + if (a->used > 1) { + return MP_GT; + } + + /* compare the only digit of a to b */ + if (a->dp[0] > b) { + return MP_GT; + } else if (a->dp[0] < b) { + return MP_LT; + } else { + return MP_EQ; + } +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_cmp_d.c */ + +/* Start: bn_mp_cmp_mag.c */ +#include +#ifdef BN_MP_CMP_MAG_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* compare maginitude of two ints (unsigned) */ +int mp_cmp_mag (mp_int * a, mp_int * b) +{ + int n; + mp_digit *tmpa, *tmpb; + + /* compare based on # of non-zero digits */ + if (a->used > b->used) { + return MP_GT; + } + + if (a->used < b->used) { + return MP_LT; + } + + /* alias for a */ + tmpa = a->dp + (a->used - 1); + + /* alias for b */ + tmpb = b->dp + (a->used - 1); + + /* compare based on digits */ + for (n = 0; n < a->used; ++n, --tmpa, --tmpb) { + if (*tmpa > *tmpb) { + return MP_GT; + } + + if (*tmpa < *tmpb) { + return MP_LT; + } + } + return MP_EQ; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_cmp_mag.c */ + +/* Start: bn_mp_cnt_lsb.c */ +#include +#ifdef BN_MP_CNT_LSB_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +static const int lnz[16] = { + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 +}; + +/* Counts the number of lsbs which are zero before the first zero bit */ +int mp_cnt_lsb(mp_int *a) +{ + int x; + mp_digit q, qq; + + /* easy out */ + if (mp_iszero(a) == 1) { + return 0; + } + + /* scan lower digits until non-zero */ + for (x = 0; x < a->used && a->dp[x] == 0; x++); + q = a->dp[x]; + x *= DIGIT_BIT; + + /* now scan this digit until a 1 is found */ + if ((q & 1) == 0) { + do { + qq = q & 15; + x += lnz[qq]; + q >>= 4; + } while (qq == 0); + } + return x; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_cnt_lsb.c */ + +/* Start: bn_mp_copy.c */ +#include +#ifdef BN_MP_COPY_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* copy, b = a */ +int +mp_copy (mp_int * a, mp_int * b) +{ + int res, n; + + /* if dst == src do nothing */ + if (a == b) { + return MP_OKAY; + } + + /* grow dest */ + if (b->alloc < a->used) { + if ((res = mp_grow (b, a->used)) != MP_OKAY) { + return res; + } + } + + /* zero b and copy the parameters over */ + { + register mp_digit *tmpa, *tmpb; + + /* pointer aliases */ + + /* source */ + tmpa = a->dp; + + /* destination */ + tmpb = b->dp; + + /* copy all the digits */ + for (n = 0; n < a->used; n++) { + *tmpb++ = *tmpa++; + } + + /* clear high digits */ + for (; n < b->used; n++) { + *tmpb++ = 0; + } + } + + /* copy used count and sign */ + b->used = a->used; + b->sign = a->sign; + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_copy.c */ + +/* Start: bn_mp_count_bits.c */ +#include +#ifdef BN_MP_COUNT_BITS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* returns the number of bits in an int */ +int +mp_count_bits (mp_int * a) +{ + int r; + mp_digit q; + + /* shortcut */ + if (a->used == 0) { + return 0; + } + + /* get number of digits and add that */ + r = (a->used - 1) * DIGIT_BIT; + + /* take the last digit and count the bits in it */ + q = a->dp[a->used - 1]; + while (q > ((mp_digit) 0)) { + ++r; + q >>= ((mp_digit) 1); + } + return r; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_count_bits.c */ + +/* Start: bn_mp_div.c */ +#include +#ifdef BN_MP_DIV_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +#ifdef BN_MP_DIV_SMALL + +/* slower bit-bang division... also smaller */ +int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + mp_int ta, tb, tq, q; + int res, n, n2; + + /* is divisor zero ? */ + if (mp_iszero (b) == 1) { + return MP_VAL; + } + + /* if a < b then q=0, r = a */ + if (mp_cmp_mag (a, b) == MP_LT) { + if (d != NULL) { + res = mp_copy (a, d); + } else { + res = MP_OKAY; + } + if (c != NULL) { + mp_zero (c); + } + return res; + } + + /* init our temps */ + if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL) != MP_OKAY)) { + return res; + } + + + mp_set(&tq, 1); + n = mp_count_bits(a) - mp_count_bits(b); + if (((res = mp_abs(a, &ta)) != MP_OKAY) || + ((res = mp_abs(b, &tb)) != MP_OKAY) || + ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) || + ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) { + goto LBL_ERR; + } + + while (n-- >= 0) { + if (mp_cmp(&tb, &ta) != MP_GT) { + if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) || + ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) { + goto LBL_ERR; + } + } + if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) || + ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) { + goto LBL_ERR; + } + } + + /* now q == quotient and ta == remainder */ + n = a->sign; + n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG); + if (c != NULL) { + mp_exch(c, &q); + c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2; + } + if (d != NULL) { + mp_exch(d, &ta); + d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n; + } +LBL_ERR: + mp_clear_multi(&ta, &tb, &tq, &q, NULL); + return res; +} + +#else + +/* integer signed division. + * c*b + d == a [e.g. a/b, c=quotient, d=remainder] + * HAC pp.598 Algorithm 14.20 + * + * Note that the description in HAC is horribly + * incomplete. For example, it doesn't consider + * the case where digits are removed from 'x' in + * the inner loop. It also doesn't consider the + * case that y has fewer than three digits, etc.. + * + * The overall algorithm is as described as + * 14.20 from HAC but fixed to treat these cases. +*/ +int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + mp_int q, x, y, t1, t2; + int res, n, t, i, norm, neg; + + /* is divisor zero ? */ + if (mp_iszero (b) == 1) { + return MP_VAL; + } + + /* if a < b then q=0, r = a */ + if (mp_cmp_mag (a, b) == MP_LT) { + if (d != NULL) { + res = mp_copy (a, d); + } else { + res = MP_OKAY; + } + if (c != NULL) { + mp_zero (c); + } + return res; + } + + if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) { + return res; + } + q.used = a->used + 2; + + if ((res = mp_init (&t1)) != MP_OKAY) { + goto LBL_Q; + } + + if ((res = mp_init (&t2)) != MP_OKAY) { + goto LBL_T1; + } + + if ((res = mp_init_copy (&x, a)) != MP_OKAY) { + goto LBL_T2; + } + + if ((res = mp_init_copy (&y, b)) != MP_OKAY) { + goto LBL_X; + } + + /* fix the sign */ + neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; + x.sign = y.sign = MP_ZPOS; + + /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */ + norm = mp_count_bits(&y) % DIGIT_BIT; + if (norm < (int)(DIGIT_BIT-1)) { + norm = (DIGIT_BIT-1) - norm; + if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) { + goto LBL_Y; + } + if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) { + goto LBL_Y; + } + } else { + norm = 0; + } + + /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */ + n = x.used - 1; + t = y.used - 1; + + /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */ + if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */ + goto LBL_Y; + } + + while (mp_cmp (&x, &y) != MP_LT) { + ++(q.dp[n - t]); + if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) { + goto LBL_Y; + } + } + + /* reset y by shifting it back down */ + mp_rshd (&y, n - t); + + /* step 3. for i from n down to (t + 1) */ + for (i = n; i >= (t + 1); i--) { + if (i > x.used) { + continue; + } + + /* step 3.1 if xi == yt then set q{i-t-1} to b-1, + * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ + if (x.dp[i] == y.dp[t]) { + q.dp[i - t - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1); + } else { + mp_word tmp; + tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT); + tmp |= ((mp_word) x.dp[i - 1]); + tmp /= ((mp_word) y.dp[t]); + if (tmp > (mp_word) MP_MASK) + tmp = MP_MASK; + q.dp[i - t - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK)); + } + + /* while (q{i-t-1} * (yt * b + y{t-1})) > + xi * b**2 + xi-1 * b + xi-2 + + do q{i-t-1} -= 1; + */ + q.dp[i - t - 1] = (q.dp[i - t - 1] + 1) & MP_MASK; + do { + q.dp[i - t - 1] = (q.dp[i - t - 1] - 1) & MP_MASK; + + /* find left hand */ + mp_zero (&t1); + t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1]; + t1.dp[1] = y.dp[t]; + t1.used = 2; + if ((res = mp_mul_d (&t1, q.dp[i - t - 1], &t1)) != MP_OKAY) { + goto LBL_Y; + } + + /* find right hand */ + t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2]; + t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1]; + t2.dp[2] = x.dp[i]; + t2.used = 3; + } while (mp_cmp_mag(&t1, &t2) == MP_GT); + + /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */ + if ((res = mp_mul_d (&y, q.dp[i - t - 1], &t1)) != MP_OKAY) { + goto LBL_Y; + } + + if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) { + goto LBL_Y; + } + + if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) { + goto LBL_Y; + } + + /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */ + if (x.sign == MP_NEG) { + if ((res = mp_copy (&y, &t1)) != MP_OKAY) { + goto LBL_Y; + } + if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) { + goto LBL_Y; + } + if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) { + goto LBL_Y; + } + + q.dp[i - t - 1] = (q.dp[i - t - 1] - 1UL) & MP_MASK; + } + } + + /* now q is the quotient and x is the remainder + * [which we have to normalize] + */ + + /* get sign before writing to c */ + x.sign = x.used == 0 ? MP_ZPOS : a->sign; + + if (c != NULL) { + mp_clamp (&q); + mp_exch (&q, c); + c->sign = neg; + } + + if (d != NULL) { + mp_div_2d (&x, norm, &x, NULL); + mp_exch (&x, d); + } + + res = MP_OKAY; + +LBL_Y:mp_clear (&y); +LBL_X:mp_clear (&x); +LBL_T2:mp_clear (&t2); +LBL_T1:mp_clear (&t1); +LBL_Q:mp_clear (&q); + return res; +} + +#endif + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_div.c */ + +/* Start: bn_mp_div_2.c */ +#include +#ifdef BN_MP_DIV_2_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* b = a/2 */ +int mp_div_2(mp_int * a, mp_int * b) +{ + int x, res, oldused; + + /* copy */ + if (b->alloc < a->used) { + if ((res = mp_grow (b, a->used)) != MP_OKAY) { + return res; + } + } + + oldused = b->used; + b->used = a->used; + { + register mp_digit r, rr, *tmpa, *tmpb; + + /* source alias */ + tmpa = a->dp + b->used - 1; + + /* dest alias */ + tmpb = b->dp + b->used - 1; + + /* carry */ + r = 0; + for (x = b->used - 1; x >= 0; x--) { + /* get the carry for the next iteration */ + rr = *tmpa & 1; + + /* shift the current digit, add in carry and store */ + *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); + + /* forward carry to next iteration */ + r = rr; + } + + /* zero excess digits */ + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } + } + b->sign = a->sign; + mp_clamp (b); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_div_2.c */ + +/* Start: bn_mp_div_2d.c */ +#include +#ifdef BN_MP_DIV_2D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* shift right by a certain bit count (store quotient in c, optional remainder in d) */ +int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) +{ + mp_digit D, r, rr; + int x, res; + mp_int t; + + + /* if the shift count is <= 0 then we do no work */ + if (b <= 0) { + res = mp_copy (a, c); + if (d != NULL) { + mp_zero (d); + } + return res; + } + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + /* get the remainder */ + if (d != NULL) { + if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + } + + /* copy */ + if ((res = mp_copy (a, c)) != MP_OKAY) { + mp_clear (&t); + return res; + } + + /* shift by as many digits in the bit count */ + if (b >= (int)DIGIT_BIT) { + mp_rshd (c, b / DIGIT_BIT); + } + + /* shift any bit count < DIGIT_BIT */ + D = (mp_digit) (b % DIGIT_BIT); + if (D != 0) { + register mp_digit *tmpc, mask, shift; + + /* mask */ + mask = (((mp_digit)1) << D) - 1; + + /* shift for lsb */ + shift = DIGIT_BIT - D; + + /* alias */ + tmpc = c->dp + (c->used - 1); + + /* carry */ + r = 0; + for (x = c->used - 1; x >= 0; x--) { + /* get the lower bits of this word in a temp */ + rr = *tmpc & mask; + + /* shift the current word and mix in the carry bits from the previous word */ + *tmpc = (*tmpc >> D) | (r << shift); + --tmpc; + + /* set the carry to the carry bits of the current word found above */ + r = rr; + } + } + mp_clamp (c); + if (d != NULL) { + mp_exch (&t, d); + } + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_div_2d.c */ + +/* Start: bn_mp_div_3.c */ +#include +#ifdef BN_MP_DIV_3_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* divide by three (based on routine from MPI and the GMP manual) */ +int +mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) +{ + mp_int q; + mp_word w, t; + mp_digit b; + int res, ix; + + /* b = 2**DIGIT_BIT / 3 */ + b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3); + + if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { + return res; + } + + q.used = a->used; + q.sign = a->sign; + w = 0; + for (ix = a->used - 1; ix >= 0; ix--) { + w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); + + if (w >= 3) { + /* multiply w by [1/3] */ + t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT); + + /* now subtract 3 * [w/3] from w, to get the remainder */ + w -= t+t+t; + + /* fixup the remainder as required since + * the optimization is not exact. + */ + while (w >= 3) { + t += 1; + w -= 3; + } + } else { + t = 0; + } + q.dp[ix] = (mp_digit)t; + } + + /* [optional] store the remainder */ + if (d != NULL) { + *d = (mp_digit)w; + } + + /* [optional] store the quotient */ + if (c != NULL) { + mp_clamp(&q); + mp_exch(&q, c); + } + mp_clear(&q); + + return res; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_div_3.c */ + +/* Start: bn_mp_div_d.c */ +#include +#ifdef BN_MP_DIV_D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +static int s_is_power_of_two(mp_digit b, int *p) +{ + int x; + + /* fast return if no power of two */ + if ((b==0) || (b & (b-1))) { + return 0; + } + + for (x = 0; x < DIGIT_BIT; x++) { + if (b == (((mp_digit)1)<dp[0] & ((((mp_digit)1)<used)) != MP_OKAY) { + return res; + } + + q.used = a->used; + q.sign = a->sign; + w = 0; + for (ix = a->used - 1; ix >= 0; ix--) { + w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); + + if (w >= b) { + t = (mp_digit)(w / b); + w -= ((mp_word)t) * ((mp_word)b); + } else { + t = 0; + } + q.dp[ix] = (mp_digit)t; + } + + if (d != NULL) { + *d = (mp_digit)w; + } + + if (c != NULL) { + mp_clamp(&q); + mp_exch(&q, c); + } + mp_clear(&q); + + return res; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_div_d.c */ + +/* Start: bn_mp_dr_is_modulus.c */ +#include +#ifdef BN_MP_DR_IS_MODULUS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* determines if a number is a valid DR modulus */ +int mp_dr_is_modulus(mp_int *a) +{ + int ix; + + /* must be at least two digits */ + if (a->used < 2) { + return 0; + } + + /* must be of the form b**k - a [a <= b] so all + * but the first digit must be equal to -1 (mod b). + */ + for (ix = 1; ix < a->used; ix++) { + if (a->dp[ix] != MP_MASK) { + return 0; + } + } + return 1; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_dr_is_modulus.c */ + +/* Start: bn_mp_dr_reduce.c */ +#include +#ifdef BN_MP_DR_REDUCE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* reduce "x" in place modulo "n" using the Diminished Radix algorithm. + * + * Based on algorithm from the paper + * + * "Generating Efficient Primes for Discrete Log Cryptosystems" + * Chae Hoon Lim, Pil Joong Lee, + * POSTECH Information Research Laboratories + * + * The modulus must be of a special format [see manual] + * + * Has been modified to use algorithm 7.10 from the LTM book instead + * + * Input x must be in the range 0 <= x <= (n-1)**2 + */ +int +mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k) +{ + int err, i, m; + mp_word r; + mp_digit mu, *tmpx1, *tmpx2; + + /* m = digits in modulus */ + m = n->used; + + /* ensure that "x" has at least 2m digits */ + if (x->alloc < m + m) { + if ((err = mp_grow (x, m + m)) != MP_OKAY) { + return err; + } + } + +/* top of loop, this is where the code resumes if + * another reduction pass is required. + */ +top: + /* aliases for digits */ + /* alias for lower half of x */ + tmpx1 = x->dp; + + /* alias for upper half of x, or x/B**m */ + tmpx2 = x->dp + m; + + /* set carry to zero */ + mu = 0; + + /* compute (x mod B**m) + k * [x/B**m] inline and inplace */ + for (i = 0; i < m; i++) { + r = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu; + *tmpx1++ = (mp_digit)(r & MP_MASK); + mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT)); + } + + /* set final carry */ + *tmpx1++ = mu; + + /* zero words above m */ + for (i = m + 1; i < x->used; i++) { + *tmpx1++ = 0; + } + + /* clamp, sub and return */ + mp_clamp (x); + + /* if x >= n then subtract and reduce again + * Each successive "recursion" makes the input smaller and smaller. + */ + if (mp_cmp_mag (x, n) != MP_LT) { + s_mp_sub(x, n, x); + goto top; + } + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_dr_reduce.c */ + +/* Start: bn_mp_dr_setup.c */ +#include +#ifdef BN_MP_DR_SETUP_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* determines the setup value */ +void mp_dr_setup(mp_int *a, mp_digit *d) +{ + /* the casts are required if DIGIT_BIT is one less than + * the number of bits in a mp_digit [e.g. DIGIT_BIT==31] + */ + *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - + ((mp_word)a->dp[0])); +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_dr_setup.c */ + +/* Start: bn_mp_exch.c */ +#include +#ifdef BN_MP_EXCH_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* swap the elements of two integers, for cases where you can't simply swap the + * mp_int pointers around + */ +void +mp_exch (mp_int * a, mp_int * b) +{ + mp_int t; + + t = *a; + *a = *b; + *b = t; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_exch.c */ + +/* Start: bn_mp_expt_d.c */ +#include +#ifdef BN_MP_EXPT_D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* calculate c = a**b using a square-multiply algorithm */ +int mp_expt_d (mp_int * a, mp_digit b, mp_int * c) +{ + int res, x; + mp_int g; + + if ((res = mp_init_copy (&g, a)) != MP_OKAY) { + return res; + } + + /* set initial result */ + mp_set (c, 1); + + for (x = 0; x < (int) DIGIT_BIT; x++) { + /* square */ + if ((res = mp_sqr (c, c)) != MP_OKAY) { + mp_clear (&g); + return res; + } + + /* if the bit is set multiply */ + if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) { + if ((res = mp_mul (c, &g, c)) != MP_OKAY) { + mp_clear (&g); + return res; + } + } + + /* shift to next bit */ + b <<= 1; + } + + mp_clear (&g); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_expt_d.c */ + +/* Start: bn_mp_exptmod.c */ +#include +#ifdef BN_MP_EXPTMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + + +/* this is a shell function that calls either the normal or Montgomery + * exptmod functions. Originally the call to the montgomery code was + * embedded in the normal function but that wasted alot of stack space + * for nothing (since 99% of the time the Montgomery code would be called) + */ +int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) +{ + int dr; + + /* modulus P must be positive */ + if (P->sign == MP_NEG) { + return MP_VAL; + } + + /* if exponent X is negative we have to recurse */ + if (X->sign == MP_NEG) { +#ifdef BN_MP_INVMOD_C + mp_int tmpG, tmpX; + int err; + + /* first compute 1/G mod P */ + if ((err = mp_init(&tmpG)) != MP_OKAY) { + return err; + } + if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) { + mp_clear(&tmpG); + return err; + } + + /* now get |X| */ + if ((err = mp_init(&tmpX)) != MP_OKAY) { + mp_clear(&tmpG); + return err; + } + if ((err = mp_abs(X, &tmpX)) != MP_OKAY) { + mp_clear_multi(&tmpG, &tmpX, NULL); + return err; + } + + /* and now compute (1/G)**|X| instead of G**X [X < 0] */ + err = mp_exptmod(&tmpG, &tmpX, P, Y); + mp_clear_multi(&tmpG, &tmpX, NULL); + return err; +#else + /* no invmod */ + return MP_VAL; +#endif + } + +/* modified diminished radix reduction */ +#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_C) + if (mp_reduce_is_2k_l(P) == MP_YES) { + return s_mp_exptmod(G, X, P, Y, 1); + } +#endif + +#ifdef BN_MP_DR_IS_MODULUS_C + /* is it a DR modulus? */ + dr = mp_dr_is_modulus(P); +#else + /* default to no */ + dr = 0; +#endif + +#ifdef BN_MP_REDUCE_IS_2K_C + /* if not, is it a unrestricted DR modulus? */ + if (dr == 0) { + dr = mp_reduce_is_2k(P) << 1; + } +#endif + + /* if the modulus is odd or dr != 0 use the montgomery method */ +#ifdef BN_MP_EXPTMOD_FAST_C + if (mp_isodd (P) == 1 || dr != 0) { + return mp_exptmod_fast (G, X, P, Y, dr); + } else { +#endif +#ifdef BN_S_MP_EXPTMOD_C + /* otherwise use the generic Barrett reduction technique */ + return s_mp_exptmod (G, X, P, Y, 0); +#else + /* no exptmod for evens */ + return MP_VAL; +#endif +#ifdef BN_MP_EXPTMOD_FAST_C + } +#endif +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_exptmod.c */ + +/* Start: bn_mp_exptmod_fast.c */ +#include +#ifdef BN_MP_EXPTMOD_FAST_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85 + * + * Uses a left-to-right k-ary sliding window to compute the modular exponentiation. + * The value of k changes based on the size of the exponent. + * + * Uses Montgomery or Diminished Radix reduction [whichever appropriate] + */ + +#ifdef MP_LOW_MEM + #define TAB_SIZE 32 +#else + #define TAB_SIZE 256 +#endif + +int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) +{ + mp_int M[TAB_SIZE], res; + mp_digit buf, mp; + int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; + + /* use a pointer to the reduction algorithm. This allows us to use + * one of many reduction algorithms without modding the guts of + * the code with if statements everywhere. + */ + int (*redux)(mp_int*,mp_int*,mp_digit); + + /* find window size */ + x = mp_count_bits (X); + if (x <= 7) { + winsize = 2; + } else if (x <= 36) { + winsize = 3; + } else if (x <= 140) { + winsize = 4; + } else if (x <= 450) { + winsize = 5; + } else if (x <= 1303) { + winsize = 6; + } else if (x <= 3529) { + winsize = 7; + } else { + winsize = 8; + } + +#ifdef MP_LOW_MEM + if (winsize > 5) { + winsize = 5; + } +#endif + + /* init M array */ + /* init first cell */ + if ((err = mp_init(&M[1])) != MP_OKAY) { + return err; + } + + /* now init the second half of the array */ + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + if ((err = mp_init(&M[x])) != MP_OKAY) { + for (y = 1<<(winsize-1); y < x; y++) { + mp_clear (&M[y]); + } + mp_clear(&M[1]); + return err; + } + } + + /* determine and setup reduction code */ + if (redmode == 0) { +#ifdef BN_MP_MONTGOMERY_SETUP_C + /* now setup montgomery */ + if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) { + goto LBL_M; + } +#else + err = MP_VAL; + goto LBL_M; +#endif + + /* automatically pick the comba one if available (saves quite a few calls/ifs) */ +#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C + if (((P->used * 2 + 1) < MP_WARRAY) && + P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + redux = fast_mp_montgomery_reduce; + } else +#endif + { +#ifdef BN_MP_MONTGOMERY_REDUCE_C + /* use slower baseline Montgomery method */ + redux = mp_montgomery_reduce; +#else + err = MP_VAL; + goto LBL_M; +#endif + } + } else if (redmode == 1) { +#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C) + /* setup DR reduction for moduli of the form B**k - b */ + mp_dr_setup(P, &mp); + redux = mp_dr_reduce; +#else + err = MP_VAL; + goto LBL_M; +#endif + } else { +#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C) + /* setup DR reduction for moduli of the form 2**k - b */ + if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) { + goto LBL_M; + } + redux = mp_reduce_2k; +#else + err = MP_VAL; + goto LBL_M; +#endif + } + + /* setup result */ + if ((err = mp_init (&res)) != MP_OKAY) { + goto LBL_M; + } + + /* create M table + * + + * + * The first half of the table is not computed though accept for M[0] and M[1] + */ + + if (redmode == 0) { +#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C + /* now we need R mod m */ + if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) { + goto LBL_RES; + } +#else + err = MP_VAL; + goto LBL_RES; +#endif + + /* now set M[1] to G * R mod m */ + if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) { + goto LBL_RES; + } + } else { + mp_set(&res, 1); + if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) { + goto LBL_RES; + } + } + + /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */ + if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_RES; + } + + for (x = 0; x < (winsize - 1); x++) { + if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* create upper table */ + for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { + if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&M[x], P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* set initial mode and bit cnt */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = X->used - 1; + bitcpy = 0; + bitbuf = 0; + + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits so break */ + if (digidx == -1) { + break; + } + /* read next digit and reset bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int)DIGIT_BIT; + } + + /* grab the next msb from the exponent */ + y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1; + buf <<= (mp_digit)1; + + /* if the bit is zero and mode == 0 then we ignore it + * These represent the leading zero bits before the first 1 bit + * in the exponent. Technically this opt is not required but it + * does lower the # of trivial squaring/reductions used + */ + if (mode == 0 && y == 0) { + continue; + } + + /* if the bit is zero and mode == 1 then we square */ + if (mode == 1 && y == 0) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + continue; + } + + /* else we add it to the window */ + bitbuf |= (y << (winsize - ++bitcpy)); + mode = 2; + + if (bitcpy == winsize) { + /* ok window is filled so square as required and multiply */ + /* square first */ + for (x = 0; x < winsize; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* then multiply */ + if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + + /* empty window and reset */ + bitcpy = 0; + bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then square/multiply */ + if (mode == 2 && bitcpy > 0) { + /* square then multiply if the bit is set */ + for (x = 0; x < bitcpy; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + + /* get next bit of the window */ + bitbuf <<= 1; + if ((bitbuf & (1 << winsize)) != 0) { + /* then multiply */ + if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + } + } + + if (redmode == 0) { + /* fixup result if Montgomery reduction is used + * recall that any value in a Montgomery system is + * actually multiplied by R mod n. So we have + * to reduce one more time to cancel out the factor + * of R. + */ + if ((err = redux(&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* swap res with Y */ + mp_exch (&res, Y); + err = MP_OKAY; +LBL_RES:mp_clear (&res); +LBL_M: + mp_clear(&M[1]); + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + mp_clear (&M[x]); + } + return err; +} +#endif + + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_exptmod_fast.c */ + +/* Start: bn_mp_exteuclid.c */ +#include +#ifdef BN_MP_EXTEUCLID_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Extended euclidean algorithm of (a, b) produces + a*u1 + b*u2 = u3 + */ +int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3) +{ + mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp; + int err; + + if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) { + return err; + } + + /* initialize, (u1,u2,u3) = (1,0,a) */ + mp_set(&u1, 1); + if ((err = mp_copy(a, &u3)) != MP_OKAY) { goto _ERR; } + + /* initialize, (v1,v2,v3) = (0,1,b) */ + mp_set(&v2, 1); + if ((err = mp_copy(b, &v3)) != MP_OKAY) { goto _ERR; } + + /* loop while v3 != 0 */ + while (mp_iszero(&v3) == MP_NO) { + /* q = u3/v3 */ + if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto _ERR; } + + /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */ + if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) { goto _ERR; } + if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto _ERR; } + if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) { goto _ERR; } + if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto _ERR; } + if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) { goto _ERR; } + if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto _ERR; } + + /* (u1,u2,u3) = (v1,v2,v3) */ + if ((err = mp_copy(&v1, &u1)) != MP_OKAY) { goto _ERR; } + if ((err = mp_copy(&v2, &u2)) != MP_OKAY) { goto _ERR; } + if ((err = mp_copy(&v3, &u3)) != MP_OKAY) { goto _ERR; } + + /* (v1,v2,v3) = (t1,t2,t3) */ + if ((err = mp_copy(&t1, &v1)) != MP_OKAY) { goto _ERR; } + if ((err = mp_copy(&t2, &v2)) != MP_OKAY) { goto _ERR; } + if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { goto _ERR; } + } + + /* make sure U3 >= 0 */ + if (u3.sign == MP_NEG) { + mp_neg(&u1, &u1); + mp_neg(&u2, &u2); + mp_neg(&u3, &u3); + } + + /* copy result out */ + if (U1 != NULL) { mp_exch(U1, &u1); } + if (U2 != NULL) { mp_exch(U2, &u2); } + if (U3 != NULL) { mp_exch(U3, &u3); } + + err = MP_OKAY; +_ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL); + return err; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_exteuclid.c */ + +/* Start: bn_mp_fread.c */ +#include +#ifdef BN_MP_FREAD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* read a bigint from a file stream in ASCII */ +int mp_fread(mp_int *a, int radix, FILE *stream) +{ + int err, ch, neg, y; + + /* clear a */ + mp_zero(a); + + /* if first digit is - then set negative */ + ch = fgetc(stream); + if (ch == '-') { + neg = MP_NEG; + ch = fgetc(stream); + } else { + neg = MP_ZPOS; + } + + for (;;) { + /* find y in the radix map */ + for (y = 0; y < radix; y++) { + if (mp_s_rmap[y] == ch) { + break; + } + } + if (y == radix) { + break; + } + + /* shift up and add */ + if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) { + return err; + } + if ((err = mp_add_d(a, y, a)) != MP_OKAY) { + return err; + } + + ch = fgetc(stream); + } + if (mp_cmp_d(a, 0) != MP_EQ) { + a->sign = neg; + } + + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_fread.c */ + +/* Start: bn_mp_fwrite.c */ +#include +#ifdef BN_MP_FWRITE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +int mp_fwrite(mp_int *a, int radix, FILE *stream) +{ + char *buf; + int err, len, x; + + if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) { + return err; + } + + buf = OPT_CAST(char) XMALLOC (len); + if (buf == NULL) { + return MP_MEM; + } + + if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) { + XFREE (buf); + return err; + } + + for (x = 0; x < len; x++) { + if (fputc(buf[x], stream) == EOF) { + XFREE (buf); + return MP_VAL; + } + } + + XFREE (buf); + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_fwrite.c */ + +/* Start: bn_mp_gcd.c */ +#include +#ifdef BN_MP_GCD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Greatest Common Divisor using the binary method */ +int mp_gcd (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int u, v; + int k, u_lsb, v_lsb, res; + + /* either zero than gcd is the largest */ + if (mp_iszero (a) == MP_YES) { + return mp_abs (b, c); + } + if (mp_iszero (b) == MP_YES) { + return mp_abs (a, c); + } + + /* get copies of a and b we can modify */ + if ((res = mp_init_copy (&u, a)) != MP_OKAY) { + return res; + } + + if ((res = mp_init_copy (&v, b)) != MP_OKAY) { + goto LBL_U; + } + + /* must be positive for the remainder of the algorithm */ + u.sign = v.sign = MP_ZPOS; + + /* B1. Find the common power of two for u and v */ + u_lsb = mp_cnt_lsb(&u); + v_lsb = mp_cnt_lsb(&v); + k = MIN(u_lsb, v_lsb); + + if (k > 0) { + /* divide the power of two out */ + if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) { + goto LBL_V; + } + + if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) { + goto LBL_V; + } + } + + /* divide any remaining factors of two out */ + if (u_lsb != k) { + if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) { + goto LBL_V; + } + } + + if (v_lsb != k) { + if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) { + goto LBL_V; + } + } + + while (mp_iszero(&v) == 0) { + /* make sure v is the largest */ + if (mp_cmp_mag(&u, &v) == MP_GT) { + /* swap u and v to make sure v is >= u */ + mp_exch(&u, &v); + } + + /* subtract smallest from largest */ + if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) { + goto LBL_V; + } + + /* Divide out all factors of two */ + if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) { + goto LBL_V; + } + } + + /* multiply by 2**k which we divided out at the beginning */ + if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) { + goto LBL_V; + } + c->sign = MP_ZPOS; + res = MP_OKAY; +LBL_V:mp_clear (&u); +LBL_U:mp_clear (&v); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_gcd.c */ + +/* Start: bn_mp_get_int.c */ +#include +#ifdef BN_MP_GET_INT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* get the lower 32-bits of an mp_int */ +unsigned long mp_get_int(mp_int * a) +{ + int i; + unsigned long res; + + if (a->used == 0) { + return 0; + } + + /* get number of digits of the lsb we have to read */ + i = MIN(a->used,(int)((sizeof(unsigned long)*CHAR_BIT+DIGIT_BIT-1)/DIGIT_BIT))-1; + + /* get most significant digit of result */ + res = DIGIT(a,i); + + while (--i >= 0) { + res = (res << DIGIT_BIT) | DIGIT(a,i); + } + + /* force result to 32-bits always so it is consistent on non 32-bit platforms */ + return res & 0xFFFFFFFFUL; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_get_int.c */ + +/* Start: bn_mp_grow.c */ +#include +#ifdef BN_MP_GROW_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* grow as required */ +int mp_grow (mp_int * a, int size) +{ + int i; + mp_digit *tmp; + + /* if the alloc size is smaller alloc more ram */ + if (a->alloc < size) { + /* ensure there are always at least MP_PREC digits extra on top */ + size += (MP_PREC * 2) - (size % MP_PREC); + + /* reallocate the array a->dp + * + * We store the return in a temporary variable + * in case the operation failed we don't want + * to overwrite the dp member of a. + */ + tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size); + if (tmp == NULL) { + /* reallocation failed but "a" is still valid [can be freed] */ + return MP_MEM; + } + + /* reallocation succeeded so set a->dp */ + a->dp = tmp; + + /* zero excess digits */ + i = a->alloc; + a->alloc = size; + for (; i < a->alloc; i++) { + a->dp[i] = 0; + } + } + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_grow.c */ + +/* Start: bn_mp_init.c */ +#include +#ifdef BN_MP_INIT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* init a new mp_int */ +int mp_init (mp_int * a) +{ + int i; + + /* allocate memory required and clear it */ + a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC); + if (a->dp == NULL) { + return MP_MEM; + } + + /* set the digits to zero */ + for (i = 0; i < MP_PREC; i++) { + a->dp[i] = 0; + } + + /* set the used to zero, allocated digits to the default precision + * and sign to positive */ + a->used = 0; + a->alloc = MP_PREC; + a->sign = MP_ZPOS; + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_init.c */ + +/* Start: bn_mp_init_copy.c */ +#include +#ifdef BN_MP_INIT_COPY_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* creates "a" then copies b into it */ +int mp_init_copy (mp_int * a, mp_int * b) +{ + int res; + + if ((res = mp_init (a)) != MP_OKAY) { + return res; + } + return mp_copy (b, a); +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_init_copy.c */ + +/* Start: bn_mp_init_multi.c */ +#include +#ifdef BN_MP_INIT_MULTI_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include + +int mp_init_multi(mp_int *mp, ...) +{ + mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ + int n = 0; /* Number of ok inits */ + mp_int* cur_arg = mp; + va_list args; + + va_start(args, mp); /* init args to next argument from caller */ + while (cur_arg != NULL) { + if (mp_init(cur_arg) != MP_OKAY) { + /* Oops - error! Back-track and mp_clear what we already + succeeded in init-ing, then return error. + */ + va_list clean_args; + + /* end the current list */ + va_end(args); + + /* now start cleaning up */ + cur_arg = mp; + va_start(clean_args, mp); + while (n--) { + mp_clear(cur_arg); + cur_arg = va_arg(clean_args, mp_int*); + } + va_end(clean_args); + res = MP_MEM; + break; + } + n++; + cur_arg = va_arg(args, mp_int*); + } + va_end(args); + return res; /* Assumed ok, if error flagged above. */ +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_init_multi.c */ + +/* Start: bn_mp_init_set.c */ +#include +#ifdef BN_MP_INIT_SET_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* initialize and set a digit */ +int mp_init_set (mp_int * a, mp_digit b) +{ + int err; + if ((err = mp_init(a)) != MP_OKAY) { + return err; + } + mp_set(a, b); + return err; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_init_set.c */ + +/* Start: bn_mp_init_set_int.c */ +#include +#ifdef BN_MP_INIT_SET_INT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* initialize and set a digit */ +int mp_init_set_int (mp_int * a, unsigned long b) +{ + int err; + if ((err = mp_init(a)) != MP_OKAY) { + return err; + } + return mp_set_int(a, b); +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_init_set_int.c */ + +/* Start: bn_mp_init_size.c */ +#include +#ifdef BN_MP_INIT_SIZE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* init an mp_init for a given size */ +int mp_init_size (mp_int * a, int size) +{ + int x; + + /* pad size so there are always extra digits */ + size += (MP_PREC * 2) - (size % MP_PREC); + + /* alloc mem */ + a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size); + if (a->dp == NULL) { + return MP_MEM; + } + + /* set the members */ + a->used = 0; + a->alloc = size; + a->sign = MP_ZPOS; + + /* zero the digits */ + for (x = 0; x < size; x++) { + a->dp[x] = 0; + } + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_init_size.c */ + +/* Start: bn_mp_invmod.c */ +#include +#ifdef BN_MP_INVMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* hac 14.61, pp608 */ +int mp_invmod (mp_int * a, mp_int * b, mp_int * c) +{ + /* b cannot be negative */ + if (b->sign == MP_NEG || mp_iszero(b) == 1) { + return MP_VAL; + } + +#ifdef BN_FAST_MP_INVMOD_C + /* if the modulus is odd we can use a faster routine instead */ + if (mp_isodd (b) == 1) { + return fast_mp_invmod (a, b, c); + } +#endif + +#ifdef BN_MP_INVMOD_SLOW_C + return mp_invmod_slow(a, b, c); +#endif + + return MP_VAL; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_invmod.c */ + +/* Start: bn_mp_invmod_slow.c */ +#include +#ifdef BN_MP_INVMOD_SLOW_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* hac 14.61, pp608 */ +int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int x, y, u, v, A, B, C, D; + int res; + + /* b cannot be negative */ + if (b->sign == MP_NEG || mp_iszero(b) == 1) { + return MP_VAL; + } + + /* init temps */ + if ((res = mp_init_multi(&x, &y, &u, &v, + &A, &B, &C, &D, NULL)) != MP_OKAY) { + return res; + } + + /* x = a, y = b */ + if ((res = mp_mod(a, b, &x)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_copy (b, &y)) != MP_OKAY) { + goto LBL_ERR; + } + + /* 2. [modified] if x,y are both even then return an error! */ + if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) { + res = MP_VAL; + goto LBL_ERR; + } + + /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ + if ((res = mp_copy (&x, &u)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_copy (&y, &v)) != MP_OKAY) { + goto LBL_ERR; + } + mp_set (&A, 1); + mp_set (&D, 1); + +top: + /* 4. while u is even do */ + while (mp_iseven (&u) == 1) { + /* 4.1 u = u/2 */ + if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { + goto LBL_ERR; + } + /* 4.2 if A or B is odd then */ + if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) { + /* A = (A+y)/2, B = (B-x)/2 */ + if ((res = mp_add (&A, &y, &A)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* A = A/2, B = B/2 */ + if ((res = mp_div_2 (&A, &A)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 5. while v is even do */ + while (mp_iseven (&v) == 1) { + /* 5.1 v = v/2 */ + if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { + goto LBL_ERR; + } + /* 5.2 if C or D is odd then */ + if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) { + /* C = (C+y)/2, D = (D-x)/2 */ + if ((res = mp_add (&C, &y, &C)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* C = C/2, D = D/2 */ + if ((res = mp_div_2 (&C, &C)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 6. if u >= v then */ + if (mp_cmp (&u, &v) != MP_LT) { + /* u = u - v, A = A - C, B = B - D */ + if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } else { + /* v - v - u, C = C - A, D = D - B */ + if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* if not zero goto step 4 */ + if (mp_iszero (&u) == 0) + goto top; + + /* now a = C, b = D, gcd == g*v */ + + /* if v != 1 then there is no inverse */ + if (mp_cmp_d (&v, 1) != MP_EQ) { + res = MP_VAL; + goto LBL_ERR; + } + + /* if its too low */ + while (mp_cmp_d(&C, 0) == MP_LT) { + if ((res = mp_add(&C, b, &C)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* too big */ + while (mp_cmp_mag(&C, b) != MP_LT) { + if ((res = mp_sub(&C, b, &C)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* C is now the inverse */ + mp_exch (&C, c); + res = MP_OKAY; +LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_invmod_slow.c */ + +/* Start: bn_mp_is_square.c */ +#include +#ifdef BN_MP_IS_SQUARE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Check if remainders are possible squares - fast exclude non-squares */ +static const char rem_128[128] = { + 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 +}; + +static const char rem_105[105] = { + 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 +}; + +/* Store non-zero to ret if arg is square, and zero if not */ +int mp_is_square(mp_int *arg,int *ret) +{ + int res; + mp_digit c; + mp_int t; + unsigned long r; + + /* Default to Non-square :) */ + *ret = MP_NO; + + if (arg->sign == MP_NEG) { + return MP_VAL; + } + + /* digits used? (TSD) */ + if (arg->used == 0) { + return MP_OKAY; + } + + /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */ + if (rem_128[127 & DIGIT(arg,0)] == 1) { + return MP_OKAY; + } + + /* Next check mod 105 (3*5*7) */ + if ((res = mp_mod_d(arg,105,&c)) != MP_OKAY) { + return res; + } + if (rem_105[c] == 1) { + return MP_OKAY; + } + + + if ((res = mp_init_set_int(&t,11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) { + return res; + } + if ((res = mp_mod(arg,&t,&t)) != MP_OKAY) { + goto ERR; + } + r = mp_get_int(&t); + /* Check for other prime modules, note it's not an ERROR but we must + * free "t" so the easiest way is to goto ERR. We know that res + * is already equal to MP_OKAY from the mp_mod call + */ + if ( (1L<<(r%11)) & 0x5C4L ) goto ERR; + if ( (1L<<(r%13)) & 0x9E4L ) goto ERR; + if ( (1L<<(r%17)) & 0x5CE8L ) goto ERR; + if ( (1L<<(r%19)) & 0x4F50CL ) goto ERR; + if ( (1L<<(r%23)) & 0x7ACCA0L ) goto ERR; + if ( (1L<<(r%29)) & 0xC2EDD0CL ) goto ERR; + if ( (1L<<(r%31)) & 0x6DE2B848L ) goto ERR; + + /* Final check - is sqr(sqrt(arg)) == arg ? */ + if ((res = mp_sqrt(arg,&t)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sqr(&t,&t)) != MP_OKAY) { + goto ERR; + } + + *ret = (mp_cmp_mag(&t,arg) == MP_EQ) ? MP_YES : MP_NO; +ERR:mp_clear(&t); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_is_square.c */ + +/* Start: bn_mp_jacobi.c */ +#include +#ifdef BN_MP_JACOBI_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* computes the jacobi c = (a | n) (or Legendre if n is prime) + * HAC pp. 73 Algorithm 2.149 + */ +int mp_jacobi (mp_int * a, mp_int * p, int *c) +{ + mp_int a1, p1; + int k, s, r, res; + mp_digit residue; + + /* if p <= 0 return MP_VAL */ + if (mp_cmp_d(p, 0) != MP_GT) { + return MP_VAL; + } + + /* step 1. if a == 0, return 0 */ + if (mp_iszero (a) == 1) { + *c = 0; + return MP_OKAY; + } + + /* step 2. if a == 1, return 1 */ + if (mp_cmp_d (a, 1) == MP_EQ) { + *c = 1; + return MP_OKAY; + } + + /* default */ + s = 0; + + /* step 3. write a = a1 * 2**k */ + if ((res = mp_init_copy (&a1, a)) != MP_OKAY) { + return res; + } + + if ((res = mp_init (&p1)) != MP_OKAY) { + goto LBL_A1; + } + + /* divide out larger power of two */ + k = mp_cnt_lsb(&a1); + if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) { + goto LBL_P1; + } + + /* step 4. if e is even set s=1 */ + if ((k & 1) == 0) { + s = 1; + } else { + /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */ + residue = p->dp[0] & 7; + + if (residue == 1 || residue == 7) { + s = 1; + } else if (residue == 3 || residue == 5) { + s = -1; + } + } + + /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */ + if ( ((p->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) { + s = -s; + } + + /* if a1 == 1 we're done */ + if (mp_cmp_d (&a1, 1) == MP_EQ) { + *c = s; + } else { + /* n1 = n mod a1 */ + if ((res = mp_mod (p, &a1, &p1)) != MP_OKAY) { + goto LBL_P1; + } + if ((res = mp_jacobi (&p1, &a1, &r)) != MP_OKAY) { + goto LBL_P1; + } + *c = s * r; + } + + /* done */ + res = MP_OKAY; +LBL_P1:mp_clear (&p1); +LBL_A1:mp_clear (&a1); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_jacobi.c */ + +/* Start: bn_mp_karatsuba_mul.c */ +#include +#ifdef BN_MP_KARATSUBA_MUL_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* c = |a| * |b| using Karatsuba Multiplication using + * three half size multiplications + * + * Let B represent the radix [e.g. 2**DIGIT_BIT] and + * let n represent half of the number of digits in + * the min(a,b) + * + * a = a1 * B**n + a0 + * b = b1 * B**n + b0 + * + * Then, a * b => + a1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0 + * + * Note that a1b1 and a0b0 are used twice and only need to be + * computed once. So in total three half size (half # of + * digit) multiplications are performed, a0b0, a1b1 and + * (a1+b1)(a0+b0) + * + * Note that a multiplication of half the digits requires + * 1/4th the number of single precision multiplications so in + * total after one call 25% of the single precision multiplications + * are saved. Note also that the call to mp_mul can end up back + * in this function if the a0, a1, b0, or b1 are above the threshold. + * This is known as divide-and-conquer and leads to the famous + * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than + * the standard O(N**2) that the baseline/comba methods use. + * Generally though the overhead of this method doesn't pay off + * until a certain size (N ~ 80) is reached. + */ +int mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int x0, x1, y0, y1, t1, x0y0, x1y1; + int B, err; + + /* default the return code to an error */ + err = MP_MEM; + + /* min # of digits */ + B = MIN (a->used, b->used); + + /* now divide in two */ + B = B >> 1; + + /* init copy all the temps */ + if (mp_init_size (&x0, B) != MP_OKAY) + goto ERR; + if (mp_init_size (&x1, a->used - B) != MP_OKAY) + goto X0; + if (mp_init_size (&y0, B) != MP_OKAY) + goto X1; + if (mp_init_size (&y1, b->used - B) != MP_OKAY) + goto Y0; + + /* init temps */ + if (mp_init_size (&t1, B * 2) != MP_OKAY) + goto Y1; + if (mp_init_size (&x0y0, B * 2) != MP_OKAY) + goto T1; + if (mp_init_size (&x1y1, B * 2) != MP_OKAY) + goto X0Y0; + + /* now shift the digits */ + x0.used = y0.used = B; + x1.used = a->used - B; + y1.used = b->used - B; + + { + register int x; + register mp_digit *tmpa, *tmpb, *tmpx, *tmpy; + + /* we copy the digits directly instead of using higher level functions + * since we also need to shift the digits + */ + tmpa = a->dp; + tmpb = b->dp; + + tmpx = x0.dp; + tmpy = y0.dp; + for (x = 0; x < B; x++) { + *tmpx++ = *tmpa++; + *tmpy++ = *tmpb++; + } + + tmpx = x1.dp; + for (x = B; x < a->used; x++) { + *tmpx++ = *tmpa++; + } + + tmpy = y1.dp; + for (x = B; x < b->used; x++) { + *tmpy++ = *tmpb++; + } + } + + /* only need to clamp the lower words since by definition the + * upper words x1/y1 must have a known number of digits + */ + mp_clamp (&x0); + mp_clamp (&y0); + + /* now calc the products x0y0 and x1y1 */ + /* after this x0 is no longer required, free temp [x0==t2]! */ + if (mp_mul (&x0, &y0, &x0y0) != MP_OKAY) + goto X1Y1; /* x0y0 = x0*y0 */ + if (mp_mul (&x1, &y1, &x1y1) != MP_OKAY) + goto X1Y1; /* x1y1 = x1*y1 */ + + /* now calc x1+x0 and y1+y0 */ + if (s_mp_add (&x1, &x0, &t1) != MP_OKAY) + goto X1Y1; /* t1 = x1 - x0 */ + if (s_mp_add (&y1, &y0, &x0) != MP_OKAY) + goto X1Y1; /* t2 = y1 - y0 */ + if (mp_mul (&t1, &x0, &t1) != MP_OKAY) + goto X1Y1; /* t1 = (x1 + x0) * (y1 + y0) */ + + /* add x0y0 */ + if (mp_add (&x0y0, &x1y1, &x0) != MP_OKAY) + goto X1Y1; /* t2 = x0y0 + x1y1 */ + if (s_mp_sub (&t1, &x0, &t1) != MP_OKAY) + goto X1Y1; /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */ + + /* shift by B */ + if (mp_lshd (&t1, B) != MP_OKAY) + goto X1Y1; /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))< +#ifdef BN_MP_KARATSUBA_SQR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Karatsuba squaring, computes b = a*a using three + * half size squarings + * + * See comments of karatsuba_mul for details. It + * is essentially the same algorithm but merely + * tuned to perform recursive squarings. + */ +int mp_karatsuba_sqr (mp_int * a, mp_int * b) +{ + mp_int x0, x1, t1, t2, x0x0, x1x1; + int B, err; + + err = MP_MEM; + + /* min # of digits */ + B = a->used; + + /* now divide in two */ + B = B >> 1; + + /* init copy all the temps */ + if (mp_init_size (&x0, B) != MP_OKAY) + goto ERR; + if (mp_init_size (&x1, a->used - B) != MP_OKAY) + goto X0; + + /* init temps */ + if (mp_init_size (&t1, a->used * 2) != MP_OKAY) + goto X1; + if (mp_init_size (&t2, a->used * 2) != MP_OKAY) + goto T1; + if (mp_init_size (&x0x0, B * 2) != MP_OKAY) + goto T2; + if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY) + goto X0X0; + + { + register int x; + register mp_digit *dst, *src; + + src = a->dp; + + /* now shift the digits */ + dst = x0.dp; + for (x = 0; x < B; x++) { + *dst++ = *src++; + } + + dst = x1.dp; + for (x = B; x < a->used; x++) { + *dst++ = *src++; + } + } + + x0.used = B; + x1.used = a->used - B; + + mp_clamp (&x0); + + /* now calc the products x0*x0 and x1*x1 */ + if (mp_sqr (&x0, &x0x0) != MP_OKAY) + goto X1X1; /* x0x0 = x0*x0 */ + if (mp_sqr (&x1, &x1x1) != MP_OKAY) + goto X1X1; /* x1x1 = x1*x1 */ + + /* now calc (x1+x0)**2 */ + if (s_mp_add (&x1, &x0, &t1) != MP_OKAY) + goto X1X1; /* t1 = x1 - x0 */ + if (mp_sqr (&t1, &t1) != MP_OKAY) + goto X1X1; /* t1 = (x1 - x0) * (x1 - x0) */ + + /* add x0y0 */ + if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY) + goto X1X1; /* t2 = x0x0 + x1x1 */ + if (s_mp_sub (&t1, &t2, &t1) != MP_OKAY) + goto X1X1; /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */ + + /* shift by B */ + if (mp_lshd (&t1, B) != MP_OKAY) + goto X1X1; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))< +#ifdef BN_MP_LCM_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* computes least common multiple as |a*b|/(a, b) */ +int mp_lcm (mp_int * a, mp_int * b, mp_int * c) +{ + int res; + mp_int t1, t2; + + + if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) { + return res; + } + + /* t1 = get the GCD of the two inputs */ + if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) { + goto LBL_T; + } + + /* divide the smallest by the GCD */ + if (mp_cmp_mag(a, b) == MP_LT) { + /* store quotient in t2 such that t2 * b is the LCM */ + if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) { + goto LBL_T; + } + res = mp_mul(b, &t2, c); + } else { + /* store quotient in t2 such that t2 * a is the LCM */ + if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) { + goto LBL_T; + } + res = mp_mul(a, &t2, c); + } + + /* fix the sign to positive */ + c->sign = MP_ZPOS; + +LBL_T: + mp_clear_multi (&t1, &t2, NULL); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_lcm.c */ + +/* Start: bn_mp_lshd.c */ +#include +#ifdef BN_MP_LSHD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* shift left a certain amount of digits */ +int mp_lshd (mp_int * a, int b) +{ + int x, res; + + /* if its less than zero return */ + if (b <= 0) { + return MP_OKAY; + } + + /* grow to fit the new digits */ + if (a->alloc < a->used + b) { + if ((res = mp_grow (a, a->used + b)) != MP_OKAY) { + return res; + } + } + + { + register mp_digit *top, *bottom; + + /* increment the used by the shift amount then copy upwards */ + a->used += b; + + /* top */ + top = a->dp + a->used - 1; + + /* base */ + bottom = a->dp + a->used - 1 - b; + + /* much like mp_rshd this is implemented using a sliding window + * except the window goes the otherway around. Copying from + * the bottom to the top. see bn_mp_rshd.c for more info. + */ + for (x = a->used - 1; x >= b; x--) { + *top-- = *bottom--; + } + + /* zero the lower digits */ + top = a->dp; + for (x = 0; x < b; x++) { + *top++ = 0; + } + } + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_lshd.c */ + +/* Start: bn_mp_mod.c */ +#include +#ifdef BN_MP_MOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* c = a mod b, 0 <= c < b */ +int +mp_mod (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int t; + int res; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + + if (t.sign != b->sign) { + res = mp_add (b, &t, c); + } else { + res = MP_OKAY; + mp_exch (&t, c); + } + + mp_clear (&t); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_mod.c */ + +/* Start: bn_mp_mod_2d.c */ +#include +#ifdef BN_MP_MOD_2D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* calc a value mod 2**b */ +int +mp_mod_2d (mp_int * a, int b, mp_int * c) +{ + int x, res; + + /* if b is <= 0 then zero the int */ + if (b <= 0) { + mp_zero (c); + return MP_OKAY; + } + + /* if the modulus is larger than the value than return */ + if (b >= (int) (a->used * DIGIT_BIT)) { + res = mp_copy (a, c); + return res; + } + + /* copy */ + if ((res = mp_copy (a, c)) != MP_OKAY) { + return res; + } + + /* zero digits above the last digit of the modulus */ + for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) { + c->dp[x] = 0; + } + /* clear the digit that is not completely outside/inside the modulus */ + c->dp[b / DIGIT_BIT] &= + (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1)); + mp_clamp (c); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_mod_2d.c */ + +/* Start: bn_mp_mod_d.c */ +#include +#ifdef BN_MP_MOD_D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +int +mp_mod_d (mp_int * a, mp_digit b, mp_digit * c) +{ + return mp_div_d(a, b, NULL, c); +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_mod_d.c */ + +/* Start: bn_mp_montgomery_calc_normalization.c */ +#include +#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* + * shifts with subtractions when the result is greater than b. + * + * The method is slightly modified to shift B unconditionally upto just under + * the leading bit of b. This saves alot of multiple precision shifting. + */ +int mp_montgomery_calc_normalization (mp_int * a, mp_int * b) +{ + int x, bits, res; + + /* how many bits of last digit does b use */ + bits = mp_count_bits (b) % DIGIT_BIT; + + if (b->used > 1) { + if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) { + return res; + } + } else { + mp_set(a, 1); + bits = 1; + } + + + /* now compute C = A * B mod b */ + for (x = bits - 1; x < (int)DIGIT_BIT; x++) { + if ((res = mp_mul_2 (a, a)) != MP_OKAY) { + return res; + } + if (mp_cmp_mag (a, b) != MP_LT) { + if ((res = s_mp_sub (a, b, a)) != MP_OKAY) { + return res; + } + } + } + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_montgomery_calc_normalization.c */ + +/* Start: bn_mp_montgomery_reduce.c */ +#include +#ifdef BN_MP_MONTGOMERY_REDUCE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* computes xR**-1 == x (mod N) via Montgomery Reduction */ +int +mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) +{ + int ix, res, digs; + mp_digit mu; + + /* can the fast reduction [comba] method be used? + * + * Note that unlike in mul you're safely allowed *less* + * than the available columns [255 per default] since carries + * are fixed up in the inner loop. + */ + digs = n->used * 2 + 1; + if ((digs < MP_WARRAY) && + n->used < + (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + return fast_mp_montgomery_reduce (x, n, rho); + } + + /* grow the input as required */ + if (x->alloc < digs) { + if ((res = mp_grow (x, digs)) != MP_OKAY) { + return res; + } + } + x->used = digs; + + for (ix = 0; ix < n->used; ix++) { + /* mu = ai * rho mod b + * + * The value of rho must be precalculated via + * montgomery_setup() such that + * it equals -1/n0 mod b this allows the + * following inner loop to reduce the + * input one digit at a time + */ + mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK); + + /* a = a + mu * m * b**i */ + { + register int iy; + register mp_digit *tmpn, *tmpx, u; + register mp_word r; + + /* alias for digits of the modulus */ + tmpn = n->dp; + + /* alias for the digits of x [the input] */ + tmpx = x->dp + ix; + + /* set the carry to zero */ + u = 0; + + /* Multiply and add in place */ + for (iy = 0; iy < n->used; iy++) { + /* compute product and sum */ + r = ((mp_word)mu) * ((mp_word)*tmpn++) + + ((mp_word) u) + ((mp_word) * tmpx); + + /* get carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + + /* fix digit */ + *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK)); + } + /* At this point the ix'th digit of x should be zero */ + + + /* propagate carries upwards as required*/ + while (u) { + *tmpx += u; + u = *tmpx >> DIGIT_BIT; + *tmpx++ &= MP_MASK; + } + } + } + + /* at this point the n.used'th least + * significant digits of x are all zero + * which means we can shift x to the + * right by n.used digits and the + * residue is unchanged. + */ + + /* x = x/b**n.used */ + mp_clamp(x); + mp_rshd (x, n->used); + + /* if x >= n then x = x - n */ + if (mp_cmp_mag (x, n) != MP_LT) { + return s_mp_sub (x, n, x); + } + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_montgomery_reduce.c */ + +/* Start: bn_mp_montgomery_setup.c */ +#include +#ifdef BN_MP_MONTGOMERY_SETUP_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* setups the montgomery reduction stuff */ +int +mp_montgomery_setup (mp_int * n, mp_digit * rho) +{ + mp_digit x, b; + +/* fast inversion mod 2**k + * + * Based on the fact that + * + * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n) + * => 2*X*A - X*X*A*A = 1 + * => 2*(1) - (1) = 1 + */ + b = n->dp[0]; + + if ((b & 1) == 0) { + return MP_VAL; + } + + x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ + x *= 2 - b * x; /* here x*a==1 mod 2**8 */ +#if !defined(MP_8BIT) + x *= 2 - b * x; /* here x*a==1 mod 2**16 */ +#endif +#if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT)) + x *= 2 - b * x; /* here x*a==1 mod 2**32 */ +#endif +#ifdef MP_64BIT + x *= 2 - b * x; /* here x*a==1 mod 2**64 */ +#endif + + /* rho = -1/m mod b */ + *rho = (unsigned long)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK; + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_montgomery_setup.c */ + +/* Start: bn_mp_mul.c */ +#include +#ifdef BN_MP_MUL_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* high level multiplication (handles sign) */ +int mp_mul (mp_int * a, mp_int * b, mp_int * c) +{ + int res, neg; + neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; + + /* use Toom-Cook? */ +#ifdef BN_MP_TOOM_MUL_C + if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) { + res = mp_toom_mul(a, b, c); + } else +#endif +#ifdef BN_MP_KARATSUBA_MUL_C + /* use Karatsuba? */ + if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) { + res = mp_karatsuba_mul (a, b, c); + } else +#endif + { + /* can we use the fast multiplier? + * + * The fast multiplier can be used if the output will + * have less than MP_WARRAY digits and the number of + * digits won't affect carry propagation + */ + int digs = a->used + b->used + 1; + +#ifdef BN_FAST_S_MP_MUL_DIGS_C + if ((digs < MP_WARRAY) && + MIN(a->used, b->used) <= + (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + res = fast_s_mp_mul_digs (a, b, c, digs); + } else +#endif +#ifdef BN_S_MP_MUL_DIGS_C + res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */ +#else + res = MP_VAL; +#endif + + } + c->sign = (c->used > 0) ? neg : MP_ZPOS; + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_mul.c */ + +/* Start: bn_mp_mul_2.c */ +#include +#ifdef BN_MP_MUL_2_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* b = a*2 */ +int mp_mul_2(mp_int * a, mp_int * b) +{ + int x, res, oldused; + + /* grow to accomodate result */ + if (b->alloc < a->used + 1) { + if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) { + return res; + } + } + + oldused = b->used; + b->used = a->used; + + { + register mp_digit r, rr, *tmpa, *tmpb; + + /* alias for source */ + tmpa = a->dp; + + /* alias for dest */ + tmpb = b->dp; + + /* carry */ + r = 0; + for (x = 0; x < a->used; x++) { + + /* get what will be the *next* carry bit from the + * MSB of the current digit + */ + rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1)); + + /* now shift up this digit, add in the carry [from the previous] */ + *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK; + + /* copy the carry that would be from the source + * digit into the next iteration + */ + r = rr; + } + + /* new leading digit? */ + if (r != 0) { + /* add a MSB which is always 1 at this point */ + *tmpb = 1; + ++(b->used); + } + + /* now zero any excess digits on the destination + * that we didn't write to + */ + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } + } + b->sign = a->sign; + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_mul_2.c */ + +/* Start: bn_mp_mul_2d.c */ +#include +#ifdef BN_MP_MUL_2D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* shift left by a certain bit count */ +int mp_mul_2d (mp_int * a, int b, mp_int * c) +{ + mp_digit d; + int res; + + /* copy */ + if (a != c) { + if ((res = mp_copy (a, c)) != MP_OKAY) { + return res; + } + } + + if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) { + if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) { + return res; + } + } + + /* shift by as many digits in the bit count */ + if (b >= (int)DIGIT_BIT) { + if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) { + return res; + } + } + + /* shift any bit count < DIGIT_BIT */ + d = (mp_digit) (b % DIGIT_BIT); + if (d != 0) { + register mp_digit *tmpc, shift, mask, r, rr; + register int x; + + /* bitmask for carries */ + mask = (((mp_digit)1) << d) - 1; + + /* shift for msbs */ + shift = DIGIT_BIT - d; + + /* alias */ + tmpc = c->dp; + + /* carry */ + r = 0; + for (x = 0; x < c->used; x++) { + /* get the higher bits of the current word */ + rr = (*tmpc >> shift) & mask; + + /* shift the current word and OR in the carry */ + *tmpc = ((*tmpc << d) | r) & MP_MASK; + ++tmpc; + + /* set the carry to the carry bits of the current word */ + r = rr; + } + + /* set final carry */ + if (r != 0) { + c->dp[(c->used)++] = r; + } + } + mp_clamp (c); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_mul_2d.c */ + +/* Start: bn_mp_mul_d.c */ +#include +#ifdef BN_MP_MUL_D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* multiply by a digit */ +int +mp_mul_d (mp_int * a, mp_digit b, mp_int * c) +{ + mp_digit u, *tmpa, *tmpc; + mp_word r; + int ix, res, olduse; + + /* make sure c is big enough to hold a*b */ + if (c->alloc < a->used + 1) { + if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* get the original destinations used count */ + olduse = c->used; + + /* set the sign */ + c->sign = a->sign; + + /* alias for a->dp [source] */ + tmpa = a->dp; + + /* alias for c->dp [dest] */ + tmpc = c->dp; + + /* zero carry */ + u = 0; + + /* compute columns */ + for (ix = 0; ix < a->used; ix++) { + /* compute product and carry sum for this term */ + r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b); + + /* mask off higher bits to get a single digit */ + *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* send carry into next iteration */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + + /* store final carry [if any] and increment ix offset */ + *tmpc++ = u; + ++ix; + + /* now zero digits above the top */ + while (ix++ < olduse) { + *tmpc++ = 0; + } + + /* set used count */ + c->used = a->used + 1; + mp_clamp(c); + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_mul_d.c */ + +/* Start: bn_mp_mulmod.c */ +#include +#ifdef BN_MP_MULMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* d = a * b (mod c) */ +int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + int res; + mp_int t; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_mul (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, c, d); + mp_clear (&t); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_mulmod.c */ + +/* Start: bn_mp_n_root.c */ +#include +#ifdef BN_MP_N_ROOT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* find the n'th root of an integer + * + * Result found such that (c)**b <= a and (c+1)**b > a + * + * This algorithm uses Newton's approximation + * x[i+1] = x[i] - f(x[i])/f'(x[i]) + * which will find the root in log(N) time where + * each step involves a fair bit. This is not meant to + * find huge roots [square and cube, etc]. + */ +int mp_n_root (mp_int * a, mp_digit b, mp_int * c) +{ + mp_int t1, t2, t3; + int res, neg; + + /* input must be positive if b is even */ + if ((b & 1) == 0 && a->sign == MP_NEG) { + return MP_VAL; + } + + if ((res = mp_init (&t1)) != MP_OKAY) { + return res; + } + + if ((res = mp_init (&t2)) != MP_OKAY) { + goto LBL_T1; + } + + if ((res = mp_init (&t3)) != MP_OKAY) { + goto LBL_T2; + } + + /* if a is negative fudge the sign but keep track */ + neg = a->sign; + a->sign = MP_ZPOS; + + /* t2 = 2 */ + mp_set (&t2, 2); + + do { + /* t1 = t2 */ + if ((res = mp_copy (&t2, &t1)) != MP_OKAY) { + goto LBL_T3; + } + + /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */ + + /* t3 = t1**(b-1) */ + if ((res = mp_expt_d (&t1, b - 1, &t3)) != MP_OKAY) { + goto LBL_T3; + } + + /* numerator */ + /* t2 = t1**b */ + if ((res = mp_mul (&t3, &t1, &t2)) != MP_OKAY) { + goto LBL_T3; + } + + /* t2 = t1**b - a */ + if ((res = mp_sub (&t2, a, &t2)) != MP_OKAY) { + goto LBL_T3; + } + + /* denominator */ + /* t3 = t1**(b-1) * b */ + if ((res = mp_mul_d (&t3, b, &t3)) != MP_OKAY) { + goto LBL_T3; + } + + /* t3 = (t1**b - a)/(b * t1**(b-1)) */ + if ((res = mp_div (&t2, &t3, &t3, NULL)) != MP_OKAY) { + goto LBL_T3; + } + + if ((res = mp_sub (&t1, &t3, &t2)) != MP_OKAY) { + goto LBL_T3; + } + } while (mp_cmp (&t1, &t2) != MP_EQ); + + /* result can be off by a few so check */ + for (;;) { + if ((res = mp_expt_d (&t1, b, &t2)) != MP_OKAY) { + goto LBL_T3; + } + + if (mp_cmp (&t2, a) == MP_GT) { + if ((res = mp_sub_d (&t1, 1, &t1)) != MP_OKAY) { + goto LBL_T3; + } + } else { + break; + } + } + + /* reset the sign of a first */ + a->sign = neg; + + /* set the result */ + mp_exch (&t1, c); + + /* set the sign of the result */ + c->sign = neg; + + res = MP_OKAY; + +LBL_T3:mp_clear (&t3); +LBL_T2:mp_clear (&t2); +LBL_T1:mp_clear (&t1); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_n_root.c */ + +/* Start: bn_mp_neg.c */ +#include +#ifdef BN_MP_NEG_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* b = -a */ +int mp_neg (mp_int * a, mp_int * b) +{ + int res; + if (a != b) { + if ((res = mp_copy (a, b)) != MP_OKAY) { + return res; + } + } + + if (mp_iszero(b) != MP_YES) { + b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS; + } else { + b->sign = MP_ZPOS; + } + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_neg.c */ + +/* Start: bn_mp_or.c */ +#include +#ifdef BN_MP_OR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* OR two ints together */ +int mp_or (mp_int * a, mp_int * b, mp_int * c) +{ + int res, ix, px; + mp_int t, *x; + + if (a->used > b->used) { + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + px = b->used; + x = b; + } else { + if ((res = mp_init_copy (&t, b)) != MP_OKAY) { + return res; + } + px = a->used; + x = a; + } + + for (ix = 0; ix < px; ix++) { + t.dp[ix] |= x->dp[ix]; + } + mp_clamp (&t); + mp_exch (c, &t); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_or.c */ + +/* Start: bn_mp_prime_fermat.c */ +#include +#ifdef BN_MP_PRIME_FERMAT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* performs one Fermat test. + * + * If "a" were prime then b**a == b (mod a) since the order of + * the multiplicative sub-group would be phi(a) = a-1. That means + * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a). + * + * Sets result to 1 if the congruence holds, or zero otherwise. + */ +int mp_prime_fermat (mp_int * a, mp_int * b, int *result) +{ + mp_int t; + int err; + + /* default to composite */ + *result = MP_NO; + + /* ensure b > 1 */ + if (mp_cmp_d(b, 1) != MP_GT) { + return MP_VAL; + } + + /* init t */ + if ((err = mp_init (&t)) != MP_OKAY) { + return err; + } + + /* compute t = b**a mod a */ + if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) { + goto LBL_T; + } + + /* is it equal to b? */ + if (mp_cmp (&t, b) == MP_EQ) { + *result = MP_YES; + } + + err = MP_OKAY; +LBL_T:mp_clear (&t); + return err; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_prime_fermat.c */ + +/* Start: bn_mp_prime_is_divisible.c */ +#include +#ifdef BN_MP_PRIME_IS_DIVISIBLE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* determines if an integers is divisible by one + * of the first PRIME_SIZE primes or not + * + * sets result to 0 if not, 1 if yes + */ +int mp_prime_is_divisible (mp_int * a, int *result) +{ + int err, ix; + mp_digit res; + + /* default to not */ + *result = MP_NO; + + for (ix = 0; ix < PRIME_SIZE; ix++) { + /* what is a mod LBL_prime_tab[ix] */ + if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) { + return err; + } + + /* is the residue zero? */ + if (res == 0) { + *result = MP_YES; + return MP_OKAY; + } + } + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_prime_is_divisible.c */ + +/* Start: bn_mp_prime_is_prime.c */ +#include +#ifdef BN_MP_PRIME_IS_PRIME_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* performs a variable number of rounds of Miller-Rabin + * + * Probability of error after t rounds is no more than + + * + * Sets result to 1 if probably prime, 0 otherwise + */ +int mp_prime_is_prime (mp_int * a, int t, int *result) +{ + mp_int b; + int ix, err, res; + + /* default to no */ + *result = MP_NO; + + /* valid value of t? */ + if (t <= 0 || t > PRIME_SIZE) { + return MP_VAL; + } + + /* is the input equal to one of the primes in the table? */ + for (ix = 0; ix < PRIME_SIZE; ix++) { + if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) { + *result = 1; + return MP_OKAY; + } + } + + /* first perform trial division */ + if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) { + return err; + } + + /* return if it was trivially divisible */ + if (res == MP_YES) { + return MP_OKAY; + } + + /* now perform the miller-rabin rounds */ + if ((err = mp_init (&b)) != MP_OKAY) { + return err; + } + + for (ix = 0; ix < t; ix++) { + /* set the prime */ + mp_set (&b, ltm_prime_tab[ix]); + + if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) { + goto LBL_B; + } + + if (res == MP_NO) { + goto LBL_B; + } + } + + /* passed the test */ + *result = MP_YES; +LBL_B:mp_clear (&b); + return err; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_prime_is_prime.c */ + +/* Start: bn_mp_prime_miller_rabin.c */ +#include +#ifdef BN_MP_PRIME_MILLER_RABIN_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Miller-Rabin test of "a" to the base of "b" as described in + * HAC pp. 139 Algorithm 4.24 + * + * Sets result to 0 if definitely composite or 1 if probably prime. + * Randomly the chance of error is no more than 1/4 and often + * very much lower. + */ +int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result) +{ + mp_int n1, y, r; + int s, j, err; + + /* default */ + *result = MP_NO; + + /* ensure b > 1 */ + if (mp_cmp_d(b, 1) != MP_GT) { + return MP_VAL; + } + + /* get n1 = a - 1 */ + if ((err = mp_init_copy (&n1, a)) != MP_OKAY) { + return err; + } + if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) { + goto LBL_N1; + } + + /* set 2**s * r = n1 */ + if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) { + goto LBL_N1; + } + + /* count the number of least significant bits + * which are zero + */ + s = mp_cnt_lsb(&r); + + /* now divide n - 1 by 2**s */ + if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) { + goto LBL_R; + } + + /* compute y = b**r mod a */ + if ((err = mp_init (&y)) != MP_OKAY) { + goto LBL_R; + } + if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) { + goto LBL_Y; + } + + /* if y != 1 and y != n1 do */ + if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) { + j = 1; + /* while j <= s-1 and y != n1 */ + while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) { + if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) { + goto LBL_Y; + } + + /* if y == 1 then composite */ + if (mp_cmp_d (&y, 1) == MP_EQ) { + goto LBL_Y; + } + + ++j; + } + + /* if y != n1 then composite */ + if (mp_cmp (&y, &n1) != MP_EQ) { + goto LBL_Y; + } + } + + /* probably prime now */ + *result = MP_YES; +LBL_Y:mp_clear (&y); +LBL_R:mp_clear (&r); +LBL_N1:mp_clear (&n1); + return err; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_prime_miller_rabin.c */ + +/* Start: bn_mp_prime_next_prime.c */ +#include +#ifdef BN_MP_PRIME_NEXT_PRIME_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* finds the next prime after the number "a" using "t" trials + * of Miller-Rabin. + * + * bbs_style = 1 means the prime must be congruent to 3 mod 4 + */ +int mp_prime_next_prime(mp_int *a, int t, int bbs_style) +{ + int err, res, x, y; + mp_digit res_tab[PRIME_SIZE], step, kstep; + mp_int b; + + /* ensure t is valid */ + if (t <= 0 || t > PRIME_SIZE) { + return MP_VAL; + } + + /* force positive */ + a->sign = MP_ZPOS; + + /* simple algo if a is less than the largest prime in the table */ + if (mp_cmp_d(a, ltm_prime_tab[PRIME_SIZE-1]) == MP_LT) { + /* find which prime it is bigger than */ + for (x = PRIME_SIZE - 2; x >= 0; x--) { + if (mp_cmp_d(a, ltm_prime_tab[x]) != MP_LT) { + if (bbs_style == 1) { + /* ok we found a prime smaller or + * equal [so the next is larger] + * + * however, the prime must be + * congruent to 3 mod 4 + */ + if ((ltm_prime_tab[x + 1] & 3) != 3) { + /* scan upwards for a prime congruent to 3 mod 4 */ + for (y = x + 1; y < PRIME_SIZE; y++) { + if ((ltm_prime_tab[y] & 3) == 3) { + mp_set(a, ltm_prime_tab[y]); + return MP_OKAY; + } + } + } + } else { + mp_set(a, ltm_prime_tab[x + 1]); + return MP_OKAY; + } + } + } + /* at this point a maybe 1 */ + if (mp_cmp_d(a, 1) == MP_EQ) { + mp_set(a, 2); + return MP_OKAY; + } + /* fall through to the sieve */ + } + + /* generate a prime congruent to 3 mod 4 or 1/3 mod 4? */ + if (bbs_style == 1) { + kstep = 4; + } else { + kstep = 2; + } + + /* at this point we will use a combination of a sieve and Miller-Rabin */ + + if (bbs_style == 1) { + /* if a mod 4 != 3 subtract the correct value to make it so */ + if ((a->dp[0] & 3) != 3) { + if ((err = mp_sub_d(a, (a->dp[0] & 3) + 1, a)) != MP_OKAY) { return err; }; + } + } else { + if (mp_iseven(a) == 1) { + /* force odd */ + if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { + return err; + } + } + } + + /* generate the restable */ + for (x = 1; x < PRIME_SIZE; x++) { + if ((err = mp_mod_d(a, ltm_prime_tab[x], res_tab + x)) != MP_OKAY) { + return err; + } + } + + /* init temp used for Miller-Rabin Testing */ + if ((err = mp_init(&b)) != MP_OKAY) { + return err; + } + + for (;;) { + /* skip to the next non-trivially divisible candidate */ + step = 0; + do { + /* y == 1 if any residue was zero [e.g. cannot be prime] */ + y = 0; + + /* increase step to next candidate */ + step += kstep; + + /* compute the new residue without using division */ + for (x = 1; x < PRIME_SIZE; x++) { + /* add the step to each residue */ + res_tab[x] += kstep; + + /* subtract the modulus [instead of using division] */ + if (res_tab[x] >= ltm_prime_tab[x]) { + res_tab[x] -= ltm_prime_tab[x]; + } + + /* set flag if zero */ + if (res_tab[x] == 0) { + y = 1; + } + } + } while (y == 1 && step < ((((mp_digit)1)<= ((((mp_digit)1)< +#ifdef BN_MP_PRIME_RABIN_MILLER_TRIALS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + + +static const struct { + int k, t; +} sizes[] = { +{ 128, 28 }, +{ 256, 16 }, +{ 384, 10 }, +{ 512, 7 }, +{ 640, 6 }, +{ 768, 5 }, +{ 896, 4 }, +{ 1024, 4 } +}; + +/* returns # of RM trials required for a given bit size */ +int mp_prime_rabin_miller_trials(int size) +{ + int x; + + for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) { + if (sizes[x].k == size) { + return sizes[x].t; + } else if (sizes[x].k > size) { + return (x == 0) ? sizes[0].t : sizes[x - 1].t; + } + } + return sizes[x-1].t + 1; +} + + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_prime_rabin_miller_trials.c */ + +/* Start: bn_mp_prime_random_ex.c */ +#include +#ifdef BN_MP_PRIME_RANDOM_EX_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* makes a truly random prime of a given size (bits), + * + * Flags are as follows: + * + * LTM_PRIME_BBS - make prime congruent to 3 mod 4 + * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS) + * LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero + * LTM_PRIME_2MSB_ON - make the 2nd highest bit one + * + * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can + * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself + * so it can be NULL + * + */ + +/* This is possibly the mother of all prime generation functions, muahahahahaha! */ +int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat) +{ + unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb; + int res, err, bsize, maskOR_msb_offset; + + /* sanity check the input */ + if (size <= 1 || t <= 0) { + return MP_VAL; + } + + /* LTM_PRIME_SAFE implies LTM_PRIME_BBS */ + if (flags & LTM_PRIME_SAFE) { + flags |= LTM_PRIME_BBS; + } + + /* calc the byte size */ + bsize = (size>>3) + ((size&7)?1:0); + + /* we need a buffer of bsize bytes */ + tmp = OPT_CAST(unsigned char) XMALLOC(bsize); + if (tmp == NULL) { + return MP_MEM; + } + + /* calc the maskAND value for the MSbyte*/ + maskAND = ((size&7) == 0) ? 0xFF : (0xFF >> (8 - (size & 7))); + + /* calc the maskOR_msb */ + maskOR_msb = 0; + maskOR_msb_offset = ((size & 7) == 1) ? 1 : 0; + if (flags & LTM_PRIME_2MSB_ON) { + maskOR_msb |= 0x80 >> ((9 - size) & 7); + } + + /* get the maskOR_lsb */ + maskOR_lsb = 1; + if (flags & LTM_PRIME_BBS) { + maskOR_lsb |= 3; + } + + do { + /* read the bytes */ + if (cb(tmp, bsize, dat) != bsize) { + err = MP_VAL; + goto error; + } + + /* work over the MSbyte */ + tmp[0] &= maskAND; + tmp[0] |= 1 << ((size - 1) & 7); + + /* mix in the maskORs */ + tmp[maskOR_msb_offset] |= maskOR_msb; + tmp[bsize-1] |= maskOR_lsb; + + /* read it in */ + if ((err = mp_read_unsigned_bin(a, tmp, bsize)) != MP_OKAY) { goto error; } + + /* is it prime? */ + if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; } + if (res == MP_NO) { + continue; + } + + if (flags & LTM_PRIME_SAFE) { + /* see if (a-1)/2 is prime */ + if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { goto error; } + if ((err = mp_div_2(a, a)) != MP_OKAY) { goto error; } + + /* is it prime? */ + if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; } + } + } while (res == MP_NO); + + if (flags & LTM_PRIME_SAFE) { + /* restore a to the original value */ + if ((err = mp_mul_2(a, a)) != MP_OKAY) { goto error; } + if ((err = mp_add_d(a, 1, a)) != MP_OKAY) { goto error; } + } + + err = MP_OKAY; +error: + XFREE(tmp); + return err; +} + + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_prime_random_ex.c */ + +/* Start: bn_mp_radix_size.c */ +#include +#ifdef BN_MP_RADIX_SIZE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* returns size of ASCII reprensentation */ +int mp_radix_size (mp_int * a, int radix, int *size) +{ + int res, digs; + mp_int t; + mp_digit d; + + *size = 0; + + /* special case for binary */ + if (radix == 2) { + *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1; + return MP_OKAY; + } + + /* make sure the radix is in range */ + if (radix < 2 || radix > 64) { + return MP_VAL; + } + + if (mp_iszero(a) == MP_YES) { + *size = 2; + return MP_OKAY; + } + + /* digs is the digit count */ + digs = 0; + + /* if it's negative add one for the sign */ + if (a->sign == MP_NEG) { + ++digs; + } + + /* init a copy of the input */ + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + /* force temp to positive */ + t.sign = MP_ZPOS; + + /* fetch out all of the digits */ + while (mp_iszero (&t) == MP_NO) { + if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { + mp_clear (&t); + return res; + } + ++digs; + } + mp_clear (&t); + + /* return digs + 1, the 1 is for the NULL byte that would be required. */ + *size = digs + 1; + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_radix_size.c */ + +/* Start: bn_mp_radix_smap.c */ +#include +#ifdef BN_MP_RADIX_SMAP_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* chars used in radix conversions */ +const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_radix_smap.c */ + +/* Start: bn_mp_rand.c */ +#include +#ifdef BN_MP_RAND_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* makes a pseudo-random int of a given size */ +int +mp_rand (mp_int * a, int digits) +{ + int res; + mp_digit d; + + mp_zero (a); + if (digits <= 0) { + return MP_OKAY; + } + + /* first place a random non-zero digit */ + do { + d = ((mp_digit) abs (rand ())) & MP_MASK; + } while (d == 0); + + if ((res = mp_add_d (a, d, a)) != MP_OKAY) { + return res; + } + + while (--digits > 0) { + if ((res = mp_lshd (a, 1)) != MP_OKAY) { + return res; + } + + if ((res = mp_add_d (a, ((mp_digit) abs (rand ())), a)) != MP_OKAY) { + return res; + } + } + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_rand.c */ + +/* Start: bn_mp_read_radix.c */ +#include +#ifdef BN_MP_READ_RADIX_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* read a string [ASCII] in a given radix */ +int mp_read_radix (mp_int * a, const char *str, int radix) +{ + int y, res, neg; + char ch; + + /* zero the digit bignum */ + mp_zero(a); + + /* make sure the radix is ok */ + if (radix < 2 || radix > 64) { + return MP_VAL; + } + + /* if the leading digit is a + * minus set the sign to negative. + */ + if (*str == '-') { + ++str; + neg = MP_NEG; + } else { + neg = MP_ZPOS; + } + + /* set the integer to the default of zero */ + mp_zero (a); + + /* process each digit of the string */ + while (*str) { + /* if the radix < 36 the conversion is case insensitive + * this allows numbers like 1AB and 1ab to represent the same value + * [e.g. in hex] + */ + ch = (char) ((radix < 36) ? toupper (*str) : *str); + for (y = 0; y < 64; y++) { + if (ch == mp_s_rmap[y]) { + break; + } + } + + /* if the char was found in the map + * and is less than the given radix add it + * to the number, otherwise exit the loop. + */ + if (y < radix) { + if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) { + return res; + } + if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) { + return res; + } + } else { + break; + } + ++str; + } + + /* set the sign only if a != 0 */ + if (mp_iszero(a) != 1) { + a->sign = neg; + } + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_read_radix.c */ + +/* Start: bn_mp_read_signed_bin.c */ +#include +#ifdef BN_MP_READ_SIGNED_BIN_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* read signed bin, big endian, first byte is 0==positive or 1==negative */ +int mp_read_signed_bin (mp_int * a, const unsigned char *b, int c) +{ + int res; + + /* read magnitude */ + if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) { + return res; + } + + /* first byte is 0 for positive, non-zero for negative */ + if (b[0] == 0) { + a->sign = MP_ZPOS; + } else { + a->sign = MP_NEG; + } + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_read_signed_bin.c */ + +/* Start: bn_mp_read_unsigned_bin.c */ +#include +#ifdef BN_MP_READ_UNSIGNED_BIN_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* reads a unsigned char array, assumes the msb is stored first [big endian] */ +int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c) +{ + int res; + + /* make sure there are at least two digits */ + if (a->alloc < 2) { + if ((res = mp_grow(a, 2)) != MP_OKAY) { + return res; + } + } + + /* zero the int */ + mp_zero (a); + + /* read the bytes in */ + while (c-- > 0) { + if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) { + return res; + } + +#ifndef MP_8BIT + a->dp[0] |= *b++; + a->used += 1; +#else + a->dp[0] = (*b & MP_MASK); + a->dp[1] |= ((*b++ >> 7U) & 1); + a->used += 2; +#endif + } + mp_clamp (a); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_read_unsigned_bin.c */ + +/* Start: bn_mp_reduce.c */ +#include +#ifdef BN_MP_REDUCE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* reduces x mod m, assumes 0 < x < m**2, mu is + * precomputed via mp_reduce_setup. + * From HAC pp.604 Algorithm 14.42 + */ +int mp_reduce (mp_int * x, mp_int * m, mp_int * mu) +{ + mp_int q; + int res, um = m->used; + + /* q = x */ + if ((res = mp_init_copy (&q, x)) != MP_OKAY) { + return res; + } + + /* q1 = x / b**(k-1) */ + mp_rshd (&q, um - 1); + + /* according to HAC this optimization is ok */ + if (((unsigned long) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) { + if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) { + goto CLEANUP; + } + } else { +#ifdef BN_S_MP_MUL_HIGH_DIGS_C + if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { + goto CLEANUP; + } +#elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) + if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { + goto CLEANUP; + } +#else + { + res = MP_VAL; + goto CLEANUP; + } +#endif + } + + /* q3 = q2 / b**(k+1) */ + mp_rshd (&q, um + 1); + + /* x = x mod b**(k+1), quick (no division) */ + if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) { + goto CLEANUP; + } + + /* q = q * m mod b**(k+1), quick (no division) */ + if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) { + goto CLEANUP; + } + + /* x = x - q */ + if ((res = mp_sub (x, &q, x)) != MP_OKAY) { + goto CLEANUP; + } + + /* If x < 0, add b**(k+1) to it */ + if (mp_cmp_d (x, 0) == MP_LT) { + mp_set (&q, 1); + if ((res = mp_lshd (&q, um + 1)) != MP_OKAY) + goto CLEANUP; + if ((res = mp_add (x, &q, x)) != MP_OKAY) + goto CLEANUP; + } + + /* Back off if it's too big */ + while (mp_cmp (x, m) != MP_LT) { + if ((res = s_mp_sub (x, m, x)) != MP_OKAY) { + goto CLEANUP; + } + } + +CLEANUP: + mp_clear (&q); + + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_reduce.c */ + +/* Start: bn_mp_reduce_2k.c */ +#include +#ifdef BN_MP_REDUCE_2K_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* reduces a modulo n where n is of the form 2**p - d */ +int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d) +{ + mp_int q; + int p, res; + + if ((res = mp_init(&q)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(n); +top: + /* q = a/2**p, a = a mod 2**p */ + if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { + goto ERR; + } + + if (d != 1) { + /* q = q * d */ + if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) { + goto ERR; + } + } + + /* a = a + q */ + if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { + goto ERR; + } + + if (mp_cmp_mag(a, n) != MP_LT) { + s_mp_sub(a, n, a); + goto top; + } + +ERR: + mp_clear(&q); + return res; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_reduce_2k.c */ + +/* Start: bn_mp_reduce_2k_l.c */ +#include +#ifdef BN_MP_REDUCE_2K_L_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* reduces a modulo n where n is of the form 2**p - d + This differs from reduce_2k since "d" can be larger + than a single digit. +*/ +int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d) +{ + mp_int q; + int p, res; + + if ((res = mp_init(&q)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(n); +top: + /* q = a/2**p, a = a mod 2**p */ + if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { + goto ERR; + } + + /* q = q * d */ + if ((res = mp_mul(&q, d, &q)) != MP_OKAY) { + goto ERR; + } + + /* a = a + q */ + if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { + goto ERR; + } + + if (mp_cmp_mag(a, n) != MP_LT) { + s_mp_sub(a, n, a); + goto top; + } + +ERR: + mp_clear(&q); + return res; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_reduce_2k_l.c */ + +/* Start: bn_mp_reduce_2k_setup.c */ +#include +#ifdef BN_MP_REDUCE_2K_SETUP_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* determines the setup value */ +int mp_reduce_2k_setup(mp_int *a, mp_digit *d) +{ + int res, p; + mp_int tmp; + + if ((res = mp_init(&tmp)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(a); + if ((res = mp_2expt(&tmp, p)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + *d = tmp.dp[0]; + mp_clear(&tmp); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_reduce_2k_setup.c */ + +/* Start: bn_mp_reduce_2k_setup_l.c */ +#include +#ifdef BN_MP_REDUCE_2K_SETUP_L_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* determines the setup value */ +int mp_reduce_2k_setup_l(mp_int *a, mp_int *d) +{ + int res; + mp_int tmp; + + if ((res = mp_init(&tmp)) != MP_OKAY) { + return res; + } + + if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) { + goto ERR; + } + + if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) { + goto ERR; + } + +ERR: + mp_clear(&tmp); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_reduce_2k_setup_l.c */ + +/* Start: bn_mp_reduce_is_2k.c */ +#include +#ifdef BN_MP_REDUCE_IS_2K_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* determines if mp_reduce_2k can be used */ +int mp_reduce_is_2k(mp_int *a) +{ + int ix, iy, iw; + mp_digit iz; + + if (a->used == 0) { + return MP_NO; + } else if (a->used == 1) { + return MP_YES; + } else if (a->used > 1) { + iy = mp_count_bits(a); + iz = 1; + iw = 1; + + /* Test every bit from the second digit up, must be 1 */ + for (ix = DIGIT_BIT; ix < iy; ix++) { + if ((a->dp[iw] & iz) == 0) { + return MP_NO; + } + iz <<= 1; + if (iz > (mp_digit)MP_MASK) { + ++iw; + iz = 1; + } + } + } + return MP_YES; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_reduce_is_2k.c */ + +/* Start: bn_mp_reduce_is_2k_l.c */ +#include +#ifdef BN_MP_REDUCE_IS_2K_L_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* determines if reduce_2k_l can be used */ +int mp_reduce_is_2k_l(mp_int *a) +{ + int ix, iy; + + if (a->used == 0) { + return MP_NO; + } else if (a->used == 1) { + return MP_YES; + } else if (a->used > 1) { + /* if more than half of the digits are -1 we're sold */ + for (iy = ix = 0; ix < a->used; ix++) { + if (a->dp[ix] == MP_MASK) { + ++iy; + } + } + return (iy >= (a->used/2)) ? MP_YES : MP_NO; + + } + return MP_NO; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_reduce_is_2k_l.c */ + +/* Start: bn_mp_reduce_setup.c */ +#include +#ifdef BN_MP_REDUCE_SETUP_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* pre-calculate the value required for Barrett reduction + * For a given modulus "b" it calulates the value required in "a" + */ +int mp_reduce_setup (mp_int * a, mp_int * b) +{ + int res; + + if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) { + return res; + } + return mp_div (a, b, a, NULL); +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_reduce_setup.c */ + +/* Start: bn_mp_rshd.c */ +#include +#ifdef BN_MP_RSHD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* shift right a certain amount of digits */ +void mp_rshd (mp_int * a, int b) +{ + int x; + + /* if b <= 0 then ignore it */ + if (b <= 0) { + return; + } + + /* if b > used then simply zero it and return */ + if (a->used <= b) { + mp_zero (a); + return; + } + + { + register mp_digit *bottom, *top; + + /* shift the digits down */ + + /* bottom */ + bottom = a->dp; + + /* top [offset into digits] */ + top = a->dp + b; + + /* this is implemented as a sliding window where + * the window is b-digits long and digits from + * the top of the window are copied to the bottom + * + * e.g. + + b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> + /\ | ----> + \-------------------/ ----> + */ + for (x = 0; x < (a->used - b); x++) { + *bottom++ = *top++; + } + + /* zero the top digits */ + for (; x < a->used; x++) { + *bottom++ = 0; + } + } + + /* remove excess digits */ + a->used -= b; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_rshd.c */ + +/* Start: bn_mp_set.c */ +#include +#ifdef BN_MP_SET_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* set to a digit */ +void mp_set (mp_int * a, mp_digit b) +{ + mp_zero (a); + a->dp[0] = b & MP_MASK; + a->used = (a->dp[0] != 0) ? 1 : 0; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_set.c */ + +/* Start: bn_mp_set_int.c */ +#include +#ifdef BN_MP_SET_INT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* set a 32-bit const */ +int mp_set_int (mp_int * a, unsigned long b) +{ + int x, res; + + mp_zero (a); + + /* set four bits at a time */ + for (x = 0; x < 8; x++) { + /* shift the number up four bits */ + if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) { + return res; + } + + /* OR in the top four bits of the source */ + a->dp[0] |= (b >> 28) & 15; + + /* shift the source up to the next four bits */ + b <<= 4; + + /* ensure that digits are not clamped off */ + a->used += 1; + } + mp_clamp (a); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_set_int.c */ + +/* Start: bn_mp_shrink.c */ +#include +#ifdef BN_MP_SHRINK_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* shrink a bignum */ +int mp_shrink (mp_int * a) +{ + mp_digit *tmp; + int used = 1; + + if(a->used > 0) + used = a->used; + + if (a->alloc != used) { + if ((tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * used)) == NULL) { + return MP_MEM; + } + a->dp = tmp; + a->alloc = used; + } + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: v0.42.0 $ */ +/* $Date: 2010-06-02 15:09:36 +0200 $ */ + +/* End: bn_mp_shrink.c */ + +/* Start: bn_mp_signed_bin_size.c */ +#include +#ifdef BN_MP_SIGNED_BIN_SIZE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* get the size for an signed equivalent */ +int mp_signed_bin_size (mp_int * a) +{ + return 1 + mp_unsigned_bin_size (a); +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_signed_bin_size.c */ + +/* Start: bn_mp_sqr.c */ +#include +#ifdef BN_MP_SQR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* computes b = a*a */ +int +mp_sqr (mp_int * a, mp_int * b) +{ + int res; + +#ifdef BN_MP_TOOM_SQR_C + /* use Toom-Cook? */ + if (a->used >= TOOM_SQR_CUTOFF) { + res = mp_toom_sqr(a, b); + /* Karatsuba? */ + } else +#endif +#ifdef BN_MP_KARATSUBA_SQR_C +if (a->used >= KARATSUBA_SQR_CUTOFF) { + res = mp_karatsuba_sqr (a, b); + } else +#endif + { +#ifdef BN_FAST_S_MP_SQR_C + /* can we use the fast comba multiplier? */ + if ((a->used * 2 + 1) < MP_WARRAY && + a->used < + (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) { + res = fast_s_mp_sqr (a, b); + } else +#endif +#ifdef BN_S_MP_SQR_C + res = s_mp_sqr (a, b); +#else + res = MP_VAL; +#endif + } + b->sign = MP_ZPOS; + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_sqr.c */ + +/* Start: bn_mp_sqrmod.c */ +#include +#ifdef BN_MP_SQRMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* c = a * a (mod b) */ +int +mp_sqrmod (mp_int * a, mp_int * b, mp_int * c) +{ + int res; + mp_int t; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_sqr (a, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, b, c); + mp_clear (&t); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_sqrmod.c */ + +/* Start: bn_mp_sqrt.c */ +#include +#ifdef BN_MP_SQRT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* this function is less generic than mp_n_root, simpler and faster */ +int mp_sqrt(mp_int *arg, mp_int *ret) +{ + int res; + mp_int t1,t2; + + /* must be positive */ + if (arg->sign == MP_NEG) { + return MP_VAL; + } + + /* easy out */ + if (mp_iszero(arg) == MP_YES) { + mp_zero(ret); + return MP_OKAY; + } + + if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) { + return res; + } + + if ((res = mp_init(&t2)) != MP_OKAY) { + goto E2; + } + + /* First approx. (not very bad for large arg) */ + mp_rshd (&t1,t1.used/2); + + /* t1 > 0 */ + if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { + goto E1; + } + if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { + goto E1; + } + if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { + goto E1; + } + /* And now t1 > sqrt(arg) */ + do { + if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { + goto E1; + } + if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { + goto E1; + } + if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { + goto E1; + } + /* t1 >= sqrt(arg) >= t2 at this point */ + } while (mp_cmp_mag(&t1,&t2) == MP_GT); + + mp_exch(&t1,ret); + +E1: mp_clear(&t2); +E2: mp_clear(&t1); + return res; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_sqrt.c */ + +/* Start: bn_mp_sub.c */ +#include +#ifdef BN_MP_SUB_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* high level subtraction (handles signs) */ +int +mp_sub (mp_int * a, mp_int * b, mp_int * c) +{ + int sa, sb, res; + + sa = a->sign; + sb = b->sign; + + if (sa != sb) { + /* subtract a negative from a positive, OR */ + /* subtract a positive from a negative. */ + /* In either case, ADD their magnitudes, */ + /* and use the sign of the first number. */ + c->sign = sa; + res = s_mp_add (a, b, c); + } else { + /* subtract a positive from a positive, OR */ + /* subtract a negative from a negative. */ + /* First, take the difference between their */ + /* magnitudes, then... */ + if (mp_cmp_mag (a, b) != MP_LT) { + /* Copy the sign from the first */ + c->sign = sa; + /* The first has a larger or equal magnitude */ + res = s_mp_sub (a, b, c); + } else { + /* The result has the *opposite* sign from */ + /* the first number. */ + c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS; + /* The second has a larger magnitude */ + res = s_mp_sub (b, a, c); + } + } + return res; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_sub.c */ + +/* Start: bn_mp_sub_d.c */ +#include +#ifdef BN_MP_SUB_D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* single digit subtraction */ +int +mp_sub_d (mp_int * a, mp_digit b, mp_int * c) +{ + mp_digit *tmpa, *tmpc, mu; + int res, ix, oldused; + + /* grow c as required */ + if (c->alloc < a->used + 1) { + if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* if a is negative just do an unsigned + * addition [with fudged signs] + */ + if (a->sign == MP_NEG) { + a->sign = MP_ZPOS; + res = mp_add_d(a, b, c); + a->sign = c->sign = MP_NEG; + + /* clamp */ + mp_clamp(c); + + return res; + } + + /* setup regs */ + oldused = c->used; + tmpa = a->dp; + tmpc = c->dp; + + /* if a <= b simply fix the single digit */ + if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) { + if (a->used == 1) { + *tmpc++ = b - *tmpa; + } else { + *tmpc++ = b; + } + ix = 1; + + /* negative/1digit */ + c->sign = MP_NEG; + c->used = 1; + } else { + /* positive/size */ + c->sign = MP_ZPOS; + c->used = a->used; + + /* subtract first digit */ + *tmpc = *tmpa++ - b; + mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1); + *tmpc++ &= MP_MASK; + + /* handle rest of the digits */ + for (ix = 1; ix < a->used; ix++) { + *tmpc = *tmpa++ - mu; + mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1); + *tmpc++ &= MP_MASK; + } + } + + /* zero excess digits */ + while (ix++ < oldused) { + *tmpc++ = 0; + } + mp_clamp(c); + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_sub_d.c */ + +/* Start: bn_mp_submod.c */ +#include +#ifdef BN_MP_SUBMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* d = a - b (mod c) */ +int +mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + int res; + mp_int t; + + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_sub (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, c, d); + mp_clear (&t); + return res; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_submod.c */ + +/* Start: bn_mp_to_signed_bin.c */ +#include +#ifdef BN_MP_TO_SIGNED_BIN_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* store in signed [big endian] format */ +int mp_to_signed_bin (mp_int * a, unsigned char *b) +{ + int res; + + if ((res = mp_to_unsigned_bin (a, b + 1)) != MP_OKAY) { + return res; + } + b[0] = (unsigned char) ((a->sign == MP_ZPOS) ? 0 : 1); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_to_signed_bin.c */ + +/* Start: bn_mp_to_signed_bin_n.c */ +#include +#ifdef BN_MP_TO_SIGNED_BIN_N_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* store in signed [big endian] format */ +int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen) +{ + if (*outlen < (unsigned long)mp_signed_bin_size(a)) { + return MP_VAL; + } + *outlen = mp_signed_bin_size(a); + return mp_to_signed_bin(a, b); +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_to_signed_bin_n.c */ + +/* Start: bn_mp_to_unsigned_bin.c */ +#include +#ifdef BN_MP_TO_UNSIGNED_BIN_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* store in unsigned [big endian] format */ +int mp_to_unsigned_bin (mp_int * a, unsigned char *b) +{ + int x, res; + mp_int t; + + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + x = 0; + while (mp_iszero (&t) == 0) { +#ifndef MP_8BIT + b[x++] = (unsigned char) (t.dp[0] & 255); +#else + b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7)); +#endif + if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) { + mp_clear (&t); + return res; + } + } + bn_reverse (b, x); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_to_unsigned_bin.c */ + +/* Start: bn_mp_to_unsigned_bin_n.c */ +#include +#ifdef BN_MP_TO_UNSIGNED_BIN_N_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* store in unsigned [big endian] format */ +int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen) +{ + if (*outlen < (unsigned long)mp_unsigned_bin_size(a)) { + return MP_VAL; + } + *outlen = mp_unsigned_bin_size(a); + return mp_to_unsigned_bin(a, b); +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_to_unsigned_bin_n.c */ + +/* Start: bn_mp_toom_mul.c */ +#include +#ifdef BN_MP_TOOM_MUL_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* multiplication using the Toom-Cook 3-way algorithm + * + * Much more complicated than Karatsuba but has a lower + * asymptotic running time of O(N**1.464). This algorithm is + * only particularly useful on VERY large inputs + * (we're talking 1000s of digits here...). +*/ +int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c) +{ + mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2; + int res, B; + + /* init temps */ + if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, + &a0, &a1, &a2, &b0, &b1, + &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) { + return res; + } + + /* B */ + B = MIN(a->used, b->used) / 3; + + /* a = a2 * B**2 + a1 * B + a0 */ + if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(a, &a1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a1, B); + mp_mod_2d(&a1, DIGIT_BIT * B, &a1); + + if ((res = mp_copy(a, &a2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a2, B*2); + + /* b = b2 * B**2 + b1 * B + b0 */ + if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(b, &b1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&b1, B); + mp_mod_2d(&b1, DIGIT_BIT * B, &b1); + + if ((res = mp_copy(b, &b2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&b2, B*2); + + /* w0 = a0*b0 */ + if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) { + goto ERR; + } + + /* w4 = a2 * b2 */ + if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) { + goto ERR; + } + + /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */ + if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) { + goto ERR; + } + + /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */ + if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) { + goto ERR; + } + + + /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */ + if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) { + goto ERR; + } + + /* now solve the matrix + + 0 0 0 0 1 + 1 2 4 8 16 + 1 1 1 1 1 + 16 8 4 2 1 + 1 0 0 0 0 + + using 12 subtractions, 4 shifts, + 2 small divisions and 1 small multiplication + */ + + /* r1 - r4 */ + if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r0 */ + if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/2 */ + if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3/2 */ + if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { + goto ERR; + } + /* r2 - r0 - r4 */ + if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1 - 8r0 */ + if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - 8r4 */ + if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + /* 3r2 - r1 - r3 */ + if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/3 */ + if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { + goto ERR; + } + /* r3/3 */ + if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { + goto ERR; + } + + /* at this point shift W[n] by B*n */ + if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) { + goto ERR; + } + +ERR: + mp_clear_multi(&w0, &w1, &w2, &w3, &w4, + &a0, &a1, &a2, &b0, &b1, + &b2, &tmp1, &tmp2, NULL); + return res; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_toom_mul.c */ + +/* Start: bn_mp_toom_sqr.c */ +#include +#ifdef BN_MP_TOOM_SQR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* squaring using Toom-Cook 3-way algorithm */ +int +mp_toom_sqr(mp_int *a, mp_int *b) +{ + mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2; + int res, B; + + /* init temps */ + if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) { + return res; + } + + /* B */ + B = a->used / 3; + + /* a = a2 * B**2 + a1 * B + a0 */ + if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(a, &a1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a1, B); + mp_mod_2d(&a1, DIGIT_BIT * B, &a1); + + if ((res = mp_copy(a, &a2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a2, B*2); + + /* w0 = a0*a0 */ + if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) { + goto ERR; + } + + /* w4 = a2 * a2 */ + if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) { + goto ERR; + } + + /* w1 = (a2 + 2(a1 + 2a0))**2 */ + if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + + /* w3 = (a0 + 2(a1 + 2a2))**2 */ + if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + + + /* w2 = (a2 + a1 + a0)**2 */ + if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) { + goto ERR; + } + + /* now solve the matrix + + 0 0 0 0 1 + 1 2 4 8 16 + 1 1 1 1 1 + 16 8 4 2 1 + 1 0 0 0 0 + + using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication. + */ + + /* r1 - r4 */ + if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r0 */ + if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/2 */ + if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3/2 */ + if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { + goto ERR; + } + /* r2 - r0 - r4 */ + if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1 - 8r0 */ + if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - 8r4 */ + if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + /* 3r2 - r1 - r3 */ + if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/3 */ + if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { + goto ERR; + } + /* r3/3 */ + if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { + goto ERR; + } + + /* at this point shift W[n] by B*n */ + if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) { + goto ERR; + } + +ERR: + mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL); + return res; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_toom_sqr.c */ + +/* Start: bn_mp_toradix.c */ +#include +#ifdef BN_MP_TORADIX_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* stores a bignum as a ASCII string in a given radix (2..64) */ +int mp_toradix (mp_int * a, char *str, int radix) +{ + int res, digs; + mp_int t; + mp_digit d; + char *_s = str; + + /* check range of the radix */ + if (radix < 2 || radix > 64) { + return MP_VAL; + } + + /* quick out if its zero */ + if (mp_iszero(a) == 1) { + *str++ = '0'; + *str = '\0'; + return MP_OKAY; + } + + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + /* if it is negative output a - */ + if (t.sign == MP_NEG) { + ++_s; + *str++ = '-'; + t.sign = MP_ZPOS; + } + + digs = 0; + while (mp_iszero (&t) == 0) { + if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { + mp_clear (&t); + return res; + } + *str++ = mp_s_rmap[d]; + ++digs; + } + + /* reverse the digits of the string. In this case _s points + * to the first digit [exluding the sign] of the number] + */ + bn_reverse ((unsigned char *)_s, digs); + + /* append a NULL so the string is properly terminated */ + *str = '\0'; + + mp_clear (&t); + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_toradix.c */ + +/* Start: bn_mp_toradix_n.c */ +#include +#ifdef BN_MP_TORADIX_N_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* stores a bignum as a ASCII string in a given radix (2..64) + * + * Stores upto maxlen-1 chars and always a NULL byte + */ +int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen) +{ + int res, digs; + mp_int t; + mp_digit d; + char *_s = str; + + /* check range of the maxlen, radix */ + if (maxlen < 2 || radix < 2 || radix > 64) { + return MP_VAL; + } + + /* quick out if its zero */ + if (mp_iszero(a) == MP_YES) { + *str++ = '0'; + *str = '\0'; + return MP_OKAY; + } + + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + /* if it is negative output a - */ + if (t.sign == MP_NEG) { + /* we have to reverse our digits later... but not the - sign!! */ + ++_s; + + /* store the flag and mark the number as positive */ + *str++ = '-'; + t.sign = MP_ZPOS; + + /* subtract a char */ + --maxlen; + } + + digs = 0; + while (mp_iszero (&t) == 0) { + if (--maxlen < 1) { + /* no more room */ + break; + } + if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { + mp_clear (&t); + return res; + } + *str++ = mp_s_rmap[d]; + ++digs; + } + + /* reverse the digits of the string. In this case _s points + * to the first digit [exluding the sign] of the number + */ + bn_reverse ((unsigned char *)_s, digs); + + /* append a NULL so the string is properly terminated */ + *str = '\0'; + + mp_clear (&t); + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_toradix_n.c */ + +/* Start: bn_mp_unsigned_bin_size.c */ +#include +#ifdef BN_MP_UNSIGNED_BIN_SIZE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* get the size for an unsigned equivalent */ +int mp_unsigned_bin_size (mp_int * a) +{ + int size = mp_count_bits (a); + return (size / 8 + ((size & 7) != 0 ? 1 : 0)); +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_unsigned_bin_size.c */ + +/* Start: bn_mp_xor.c */ +#include +#ifdef BN_MP_XOR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* XOR two ints together */ +int +mp_xor (mp_int * a, mp_int * b, mp_int * c) +{ + int res, ix, px; + mp_int t, *x; + + if (a->used > b->used) { + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + px = b->used; + x = b; + } else { + if ((res = mp_init_copy (&t, b)) != MP_OKAY) { + return res; + } + px = a->used; + x = a; + } + + for (ix = 0; ix < px; ix++) { + t.dp[ix] ^= x->dp[ix]; + } + mp_clamp (&t); + mp_exch (c, &t); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_xor.c */ + +/* Start: bn_mp_zero.c */ +#include +#ifdef BN_MP_ZERO_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* set to zero */ +void mp_zero (mp_int * a) +{ + int n; + mp_digit *tmp; + + a->sign = MP_ZPOS; + a->used = 0; + + tmp = a->dp; + for (n = 0; n < a->alloc; n++) { + *tmp++ = 0; + } +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_mp_zero.c */ + +/* Start: bn_prime_tab.c */ +#include +#ifdef BN_PRIME_TAB_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +const mp_digit ltm_prime_tab[] = { + 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, + 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, + 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, + 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, +#ifndef MP_8BIT + 0x0083, + 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD, + 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF, + 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107, + 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137, + + 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167, + 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199, + 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9, + 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7, + 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239, + 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265, + 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293, + 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF, + + 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301, + 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B, + 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371, + 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD, + 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5, + 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419, + 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449, + 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B, + + 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7, + 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503, + 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529, + 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F, + 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3, + 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7, + 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623, + 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 +#endif +}; +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_prime_tab.c */ + +/* Start: bn_reverse.c */ +#include +#ifdef BN_REVERSE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* reverse an array, used for radix code */ +void +bn_reverse (unsigned char *s, int len) +{ + int ix, iy; + unsigned char t; + + ix = 0; + iy = len - 1; + while (ix < iy) { + t = s[ix]; + s[ix] = s[iy]; + s[iy] = t; + ++ix; + --iy; + } +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_reverse.c */ + +/* Start: bn_s_mp_add.c */ +#include +#ifdef BN_S_MP_ADD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* low level addition, based on HAC pp.594, Algorithm 14.7 */ +int +s_mp_add (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int *x; + int olduse, res, min, max; + + /* find sizes, we let |a| <= |b| which means we have to sort + * them. "x" will point to the input with the most digits + */ + if (a->used > b->used) { + min = b->used; + max = a->used; + x = a; + } else { + min = a->used; + max = b->used; + x = b; + } + + /* init result */ + if (c->alloc < max + 1) { + if ((res = mp_grow (c, max + 1)) != MP_OKAY) { + return res; + } + } + + /* get old used digit count and set new one */ + olduse = c->used; + c->used = max + 1; + + { + register mp_digit u, *tmpa, *tmpb, *tmpc; + register int i; + + /* alias for digit pointers */ + + /* first input */ + tmpa = a->dp; + + /* second input */ + tmpb = b->dp; + + /* destination */ + tmpc = c->dp; + + /* zero the carry */ + u = 0; + for (i = 0; i < min; i++) { + /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */ + *tmpc = *tmpa++ + *tmpb++ + u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)DIGIT_BIT); + + /* take away carry bit from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* now copy higher words if any, that is in A+B + * if A or B has more digits add those in + */ + if (min != max) { + for (; i < max; i++) { + /* T[i] = X[i] + U */ + *tmpc = x->dp[i] + u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)DIGIT_BIT); + + /* take away carry bit from T[i] */ + *tmpc++ &= MP_MASK; + } + } + + /* add carry */ + *tmpc++ = u; + + /* clear digits above oldused */ + for (i = c->used; i < olduse; i++) { + *tmpc++ = 0; + } + } + + mp_clamp (c); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_s_mp_add.c */ + +/* Start: bn_s_mp_exptmod.c */ +#include +#ifdef BN_S_MP_EXPTMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#ifdef MP_LOW_MEM + #define TAB_SIZE 32 +#else + #define TAB_SIZE 256 +#endif + +int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) +{ + mp_int M[TAB_SIZE], res, mu; + mp_digit buf; + int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; + int (*redux)(mp_int*,mp_int*,mp_int*); + + /* find window size */ + x = mp_count_bits (X); + if (x <= 7) { + winsize = 2; + } else if (x <= 36) { + winsize = 3; + } else if (x <= 140) { + winsize = 4; + } else if (x <= 450) { + winsize = 5; + } else if (x <= 1303) { + winsize = 6; + } else if (x <= 3529) { + winsize = 7; + } else { + winsize = 8; + } + +#ifdef MP_LOW_MEM + if (winsize > 5) { + winsize = 5; + } +#endif + + /* init M array */ + /* init first cell */ + if ((err = mp_init(&M[1])) != MP_OKAY) { + return err; + } + + /* now init the second half of the array */ + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + if ((err = mp_init(&M[x])) != MP_OKAY) { + for (y = 1<<(winsize-1); y < x; y++) { + mp_clear (&M[y]); + } + mp_clear(&M[1]); + return err; + } + } + + /* create mu, used for Barrett reduction */ + if ((err = mp_init (&mu)) != MP_OKAY) { + goto LBL_M; + } + + if (redmode == 0) { + if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) { + goto LBL_MU; + } + redux = mp_reduce; + } else { + if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) { + goto LBL_MU; + } + redux = mp_reduce_2k_l; + } + + /* create M table + * + * The M table contains powers of the base, + * e.g. M[x] = G**x mod P + * + * The first half of the table is not + * computed though accept for M[0] and M[1] + */ + if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) { + goto LBL_MU; + } + + /* compute the value at M[1<<(winsize-1)] by squaring + * M[1] (winsize-1) times + */ + if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_MU; + } + + for (x = 0; x < (winsize - 1); x++) { + /* square it */ + if ((err = mp_sqr (&M[1 << (winsize - 1)], + &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_MU; + } + + /* reduce modulo P */ + if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) { + goto LBL_MU; + } + } + + /* create upper table, that is M[x] = M[x-1] * M[1] (mod P) + * for x = (2**(winsize - 1) + 1) to (2**winsize - 1) + */ + for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { + if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { + goto LBL_MU; + } + if ((err = redux (&M[x], P, &mu)) != MP_OKAY) { + goto LBL_MU; + } + } + + /* setup result */ + if ((err = mp_init (&res)) != MP_OKAY) { + goto LBL_MU; + } + mp_set (&res, 1); + + /* set initial mode and bit cnt */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = X->used - 1; + bitcpy = 0; + bitbuf = 0; + + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits */ + if (digidx == -1) { + break; + } + /* read next digit and reset the bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int) DIGIT_BIT; + } + + /* grab the next msb from the exponent */ + y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1; + buf <<= (mp_digit)1; + + /* if the bit is zero and mode == 0 then we ignore it + * These represent the leading zero bits before the first 1 bit + * in the exponent. Technically this opt is not required but it + * does lower the # of trivial squaring/reductions used + */ + if (mode == 0 && y == 0) { + continue; + } + + /* if the bit is zero and mode == 1 then we square */ + if (mode == 1 && y == 0) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + continue; + } + + /* else we add it to the window */ + bitbuf |= (y << (winsize - ++bitcpy)); + mode = 2; + + if (bitcpy == winsize) { + /* ok window is filled so square as required and multiply */ + /* square first */ + for (x = 0; x < winsize; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* then multiply */ + if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + + /* empty window and reset */ + bitcpy = 0; + bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then square/multiply */ + if (mode == 2 && bitcpy > 0) { + /* square then multiply if the bit is set */ + for (x = 0; x < bitcpy; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + + bitbuf <<= 1; + if ((bitbuf & (1 << winsize)) != 0) { + /* then multiply */ + if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + } + } + } + + mp_exch (&res, Y); + err = MP_OKAY; +LBL_RES:mp_clear (&res); +LBL_MU:mp_clear (&mu); +LBL_M: + mp_clear(&M[1]); + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + mp_clear (&M[x]); + } + return err; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_s_mp_exptmod.c */ + +/* Start: bn_s_mp_mul_digs.c */ +#include +#ifdef BN_S_MP_MUL_DIGS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* multiplies |a| * |b| and only computes upto digs digits of result + * HAC pp. 595, Algorithm 14.12 Modified so you can control how + * many digits of output are created. + */ +int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + mp_int t; + int res, pa, pb, ix, iy; + mp_digit u; + mp_word r; + mp_digit tmpx, *tmpt, *tmpy; + + /* can we use the fast multiplier? */ + if (((digs) < MP_WARRAY) && + MIN (a->used, b->used) < + (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + return fast_s_mp_mul_digs (a, b, c, digs); + } + + if ((res = mp_init_size (&t, digs)) != MP_OKAY) { + return res; + } + t.used = digs; + + /* compute the digits of the product directly */ + pa = a->used; + for (ix = 0; ix < pa; ix++) { + /* set the carry to zero */ + u = 0; + + /* limit ourselves to making digs digits of output */ + pb = MIN (b->used, digs - ix); + + /* setup some aliases */ + /* copy of the digit from a used within the nested loop */ + tmpx = a->dp[ix]; + + /* an alias for the destination shifted ix places */ + tmpt = t.dp + ix; + + /* an alias for the digits of b */ + tmpy = b->dp; + + /* compute the columns of the output and propagate the carry */ + for (iy = 0; iy < pb; iy++) { + /* compute the column as a mp_word */ + r = ((mp_word)*tmpt) + + ((mp_word)tmpx) * ((mp_word)*tmpy++) + + ((mp_word) u); + + /* the new column is the lower part of the result */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get the carry word from the result */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + /* set carry if it is placed below digs */ + if (ix + iy < digs) { + *tmpt = u; + } + } + + mp_clamp (&t); + mp_exch (&t, c); + + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_s_mp_mul_digs.c */ + +/* Start: bn_s_mp_mul_high_digs.c */ +#include +#ifdef BN_S_MP_MUL_HIGH_DIGS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* multiplies |a| * |b| and does not compute the lower digs digits + * [meant to get the higher part of the product] + */ +int +s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + mp_int t; + int res, pa, pb, ix, iy; + mp_digit u; + mp_word r; + mp_digit tmpx, *tmpt, *tmpy; + + /* can we use the fast multiplier? */ +#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C + if (((a->used + b->used + 1) < MP_WARRAY) + && MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + return fast_s_mp_mul_high_digs (a, b, c, digs); + } +#endif + + if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) { + return res; + } + t.used = a->used + b->used + 1; + + pa = a->used; + pb = b->used; + for (ix = 0; ix < pa; ix++) { + /* clear the carry */ + u = 0; + + /* left hand side of A[ix] * B[iy] */ + tmpx = a->dp[ix]; + + /* alias to the address of where the digits will be stored */ + tmpt = &(t.dp[digs]); + + /* alias for where to read the right hand side from */ + tmpy = b->dp + (digs - ix); + + for (iy = digs - ix; iy < pb; iy++) { + /* calculate the double precision result */ + r = ((mp_word)*tmpt) + + ((mp_word)tmpx) * ((mp_word)*tmpy++) + + ((mp_word) u); + + /* get the lower part */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* carry the carry */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + *tmpt = u; + } + mp_clamp (&t); + mp_exch (&t, c); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_s_mp_mul_high_digs.c */ + +/* Start: bn_s_mp_sqr.c */ +#include +#ifdef BN_S_MP_SQR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */ +int s_mp_sqr (mp_int * a, mp_int * b) +{ + mp_int t; + int res, ix, iy, pa; + mp_word r; + mp_digit u, tmpx, *tmpt; + + pa = a->used; + if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) { + return res; + } + + /* default used is maximum possible size */ + t.used = 2*pa + 1; + + for (ix = 0; ix < pa; ix++) { + /* first calculate the digit at 2*ix */ + /* calculate double precision result */ + r = ((mp_word) t.dp[2*ix]) + + ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]); + + /* store lower part in result */ + t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get the carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + + /* left hand side of A[ix] * A[iy] */ + tmpx = a->dp[ix]; + + /* alias for where to store the results */ + tmpt = t.dp + (2*ix + 1); + + for (iy = ix + 1; iy < pa; iy++) { + /* first calculate the product */ + r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]); + + /* now calculate the double precision result, note we use + * addition instead of *2 since it's easier to optimize + */ + r = ((mp_word) *tmpt) + r + r + ((mp_word) u); + + /* store lower part */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + } + /* propagate upwards */ + while (u != ((mp_digit) 0)) { + r = ((mp_word) *tmpt) + ((mp_word) u); + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + } + } + + mp_clamp (&t); + mp_exch (&t, b); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_s_mp_sqr.c */ + +/* Start: bn_s_mp_sub.c */ +#include +#ifdef BN_S_MP_SUB_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */ +int +s_mp_sub (mp_int * a, mp_int * b, mp_int * c) +{ + int olduse, res, min, max; + + /* find sizes */ + min = b->used; + max = a->used; + + /* init result */ + if (c->alloc < max) { + if ((res = mp_grow (c, max)) != MP_OKAY) { + return res; + } + } + olduse = c->used; + c->used = max; + + { + register mp_digit u, *tmpa, *tmpb, *tmpc; + register int i; + + /* alias for digit pointers */ + tmpa = a->dp; + tmpb = b->dp; + tmpc = c->dp; + + /* set carry to zero */ + u = 0; + for (i = 0; i < min; i++) { + /* T[i] = A[i] - B[i] - U */ + *tmpc = *tmpa++ - *tmpb++ - u; + + /* U = carry bit of T[i] + * Note this saves performing an AND operation since + * if a carry does occur it will propagate all the way to the + * MSB. As a result a single shift is enough to get the carry + */ + u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); + + /* Clear carry from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* now copy higher words if any, e.g. if A has more digits than B */ + for (; i < max; i++) { + /* T[i] = A[i] - U */ + *tmpc = *tmpa++ - u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); + + /* Clear carry from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* clear digits above used (since we may not have grown result above) */ + for (i = c->used; i < olduse; i++) { + *tmpc++ = 0; + } + } + + mp_clamp (c); + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bn_s_mp_sub.c */ + +/* Start: bncore.c */ +#include +#ifdef BNCORE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Known optimal configurations + + CPU /Compiler /MUL CUTOFF/SQR CUTOFF +------------------------------------------------------------- + Intel P4 Northwood /GCC v3.4.1 / 88/ 128/LTM 0.32 ;-) + AMD Athlon64 /GCC v3.4.4 / 80/ 120/LTM 0.35 + +*/ + +int KARATSUBA_MUL_CUTOFF = 80, /* Min. number of digits before Karatsuba multiplication is used. */ + KARATSUBA_SQR_CUTOFF = 120, /* Min. number of digits before Karatsuba squaring is used. */ + + TOOM_MUL_CUTOFF = 350, /* no optimal values of these are known yet so set em high */ + TOOM_SQR_CUTOFF = 400; +#endif + +/* $Source$ */ +/* $Revision: 0.41 $ */ +/* $Date: 2007-04-18 09:58:18 +0000 $ */ + +/* End: bncore.c */ + + +/* EOF */ diff --git a/xmhf-64/xmhf/third-party/libtommath/pretty.build b/xmhf-64/xmhf/third-party/libtommath/pretty.build new file mode 100755 index 0000000000..a708b8af22 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/pretty.build @@ -0,0 +1,66 @@ +#!/bin/perl -w +# +# Cute little builder for perl +# Total waste of development time... +# +# This will build all the object files and then the archive .a file +# requires GCC, GNU make and a sense of humour. +# +# Tom St Denis +use strict; + +my $count = 0; +my $starttime = time; +my $rate = 0; +print "Scanning for source files...\n"; +foreach my $filename (glob "*.c") { + ++$count; +} +print "Source files to build: $count\nBuilding...\n"; +my $i = 0; +my $lines = 0; +my $filesbuilt = 0; +foreach my $filename (glob "*.c") { + printf("Building %3.2f%%, ", (++$i/$count)*100.0); + if ($i % 4 == 0) { print "/, "; } + if ($i % 4 == 1) { print "-, "; } + if ($i % 4 == 2) { print "\\, "; } + if ($i % 4 == 3) { print "|, "; } + if ($rate > 0) { + my $tleft = ($count - $i) / $rate; + my $tsec = $tleft%60; + my $tmin = ($tleft/60)%60; + my $thour = ($tleft/3600)%60; + printf("%2d:%02d:%02d left, ", $thour, $tmin, $tsec); + } + my $cnt = ($i/$count)*30.0; + my $x = 0; + print "["; + for (; $x < $cnt; $x++) { print "#"; } + for (; $x < 30; $x++) { print " "; } + print "]\r"; + my $tmp = $filename; + $tmp =~ s/\.c/".o"/ge; + if (open(SRC, "<$tmp")) { + close SRC; + } else { + !system("make $tmp > /dev/null 2>/dev/null") or die "\nERROR: Failed to make $tmp!!!\n"; + open( SRC, "<$filename" ) or die "Couldn't open $filename for reading: $!"; + ++$lines while (); + close SRC or die "Error closing $filename after reading: $!"; + ++$filesbuilt; + } + + # update timer + if (time != $starttime) { + my $delay = time - $starttime; + $rate = $i/$delay; + } +} + +# finish building the library +printf("\nFinished building source (%d seconds, %3.2f files per second).\n", time - $starttime, $rate); +print "Compiled approximately $filesbuilt files and $lines lines of code.\n"; +print "Doing final make (building archive...)\n"; +!system("make > /dev/null 2>/dev/null") or die "\nERROR: Failed to perform last make command!!!\n"; +print "done.\n"; \ No newline at end of file diff --git a/xmhf-64/xmhf/third-party/libtommath/tombc/grammar.txt b/xmhf-64/xmhf/third-party/libtommath/tombc/grammar.txt new file mode 100644 index 0000000000..a780e759d6 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/tombc/grammar.txt @@ -0,0 +1,35 @@ +program := program statement | statement | empty +statement := { statement } | + identifier = numexpression; | + identifier[numexpression] = numexpression; | + function(expressionlist); | + for (identifer = numexpression; numexpression; identifier = numexpression) { statement } | + while (numexpression) { statement } | + if (numexpresion) { statement } elif | + break; | + continue; + +elif := else statement | empty +function := abs | countbits | exptmod | jacobi | print | isprime | nextprime | issquare | readinteger | exit +expressionlist := expressionlist, expression | expression + +// LR(1) !!!? +expression := string | numexpression +numexpression := cmpexpr && cmpexpr | cmpexpr \|\| cmpexpr | cmpexpr +cmpexpr := boolexpr < boolexpr | boolexpr > boolexpr | boolexpr == boolexpr | + boolexpr <= boolexpr | boolexpr >= boolexpr | boolexpr +boolexpr := shiftexpr & shiftexpr | shiftexpr ^ shiftexpr | shiftexpr \| shiftexpr | shiftexpr +shiftexpr := addsubexpr << addsubexpr | addsubexpr >> addsubexpr | addsubexpr +addsubexpr := mulexpr + mulexpr | mulexpr - mulexpr | mulexpr +mulexpr := expr * expr | expr / expr | expr % expr | expr +expr := -nexpr | nexpr +nexpr := integer | identifier | ( numexpression ) | identifier[numexpression] + +identifier := identifer digits | identifier alpha | alpha +alpha := a ... z | A ... Z +integer := hexnumber | digits +hexnumber := 0xhexdigits +hexdigits := hexdigits hexdigit | hexdigit +hexdigit := 0 ... 9 | a ... f | A ... F +digits := digits digit | digit +digit := 0 ... 9 diff --git a/xmhf-64/xmhf/third-party/libtommath/tommath.h b/xmhf-64/xmhf/third-party/libtommath/tommath.h new file mode 100644 index 0000000000..bb10f9dc7b --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/tommath.h @@ -0,0 +1,589 @@ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com + */ +#ifndef BN_H_ +#define BN_H_ + +#include +#include +#include +#include +#include + +#include + +#ifndef MIN + #define MIN(x,y) ((x)<(y)?(x):(y)) +#endif + +#ifndef MAX + #define MAX(x,y) ((x)>(y)?(x):(y)) +#endif + +#ifdef __cplusplus +extern "C" { + +/* C++ compilers don't like assigning void * to mp_digit * */ +#define OPT_CAST(x) (x *) + +#else + +/* C on the other hand doesn't care */ +#define OPT_CAST(x) + +#endif + + +/* detect 64-bit mode if possible */ +#if defined(__x86_64__) + #if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT)) + #define MP_64BIT + #endif +#endif + +/* some default configurations. + * + * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits + * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits + * + * At the very least a mp_digit must be able to hold 7 bits + * [any size beyond that is ok provided it doesn't overflow the data type] + */ +#ifdef MP_8BIT + typedef unsigned char mp_digit; + typedef unsigned short mp_word; +#elif defined(MP_16BIT) + typedef unsigned short mp_digit; + typedef unsigned long mp_word; +#elif defined(MP_64BIT) + /* for GCC only on supported platforms */ +#ifndef CRYPT + typedef unsigned long long ulong64; + typedef signed long long long64; +#endif + + typedef unsigned long mp_digit; + typedef unsigned long mp_word __attribute__ ((mode(TI))); + + #define DIGIT_BIT 60 +#else + /* this is the default case, 28-bit digits */ + + /* this is to make porting into LibTomCrypt easier :-) */ +#ifndef CRYPT + #if defined(_MSC_VER) || defined(__BORLANDC__) + typedef unsigned __int64 ulong64; + typedef signed __int64 long64; + #else + typedef unsigned long long ulong64; + typedef signed long long long64; + #endif +#endif + + typedef unsigned long mp_digit; + typedef ulong64 mp_word; + +#ifdef MP_31BIT + /* this is an extension that uses 31-bit digits */ + #define DIGIT_BIT 31 +#else + /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */ + #define DIGIT_BIT 28 + #define MP_28BIT +#endif +#endif + +/* define heap macros */ +#ifndef CRYPT + /* default to libc stuff */ + #ifndef XMALLOC + #define XMALLOC malloc + #define XFREE free + #define XREALLOC realloc + #define XCALLOC calloc + #else + /* prototypes for our heap functions */ + extern void *XMALLOC(size_t n); + extern void *XREALLOC(void *p, size_t n); + extern void *XCALLOC(size_t n, size_t s); + extern void XFREE(void *p); + #endif +#endif + + +/* otherwise the bits per digit is calculated automatically from the size of a mp_digit */ +#ifndef DIGIT_BIT + #define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1))) /* bits per digit */ +#endif + +#define MP_DIGIT_BIT DIGIT_BIT +#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1)) +#define MP_DIGIT_MAX MP_MASK + +/* equalities */ +#define MP_LT -1 /* less than */ +#define MP_EQ 0 /* equal to */ +#define MP_GT 1 /* greater than */ + +#define MP_ZPOS 0 /* positive integer */ +#define MP_NEG 1 /* negative */ + +#define MP_OKAY 0 /* ok result */ +#define MP_MEM -2 /* out of mem */ +#define MP_VAL -3 /* invalid input */ +#define MP_RANGE MP_VAL + +#define MP_YES 1 /* yes response */ +#define MP_NO 0 /* no response */ + +/* Primality generation flags */ +#define LTM_PRIME_BBS 0x0001 /* BBS style prime */ +#define LTM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */ +#define LTM_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */ + +typedef int mp_err; + +/* you'll have to tune these... */ +extern int KARATSUBA_MUL_CUTOFF, + KARATSUBA_SQR_CUTOFF, + TOOM_MUL_CUTOFF, + TOOM_SQR_CUTOFF; + +/* define this to use lower memory usage routines (exptmods mostly) */ +/* #define MP_LOW_MEM */ + +/* default precision */ +#ifndef MP_PREC + #ifndef MP_LOW_MEM + #define MP_PREC 32 /* default digits of precision */ + #else + #define MP_PREC 8 /* default digits of precision */ + #endif +#endif + +/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */ +#define MP_WARRAY (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1)) + +/* the infamous mp_int structure */ +typedef struct { + int used, alloc, sign; + mp_digit *dp; +} mp_int; + +/* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */ +typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat); + + +#define USED(m) ((m)->used) +#define DIGIT(m,k) ((m)->dp[(k)]) +#define SIGN(m) ((m)->sign) + +/* error code to char* string */ +char *mp_error_to_string(int code); + +/* ---> init and deinit bignum functions <--- */ +/* init a bignum */ +int mp_init(mp_int *a); + +/* free a bignum */ +void mp_clear(mp_int *a); + +/* init a null terminated series of arguments */ +int mp_init_multi(mp_int *mp, ...); + +/* clear a null terminated series of arguments */ +void mp_clear_multi(mp_int *mp, ...); + +/* exchange two ints */ +void mp_exch(mp_int *a, mp_int *b); + +/* shrink ram required for a bignum */ +int mp_shrink(mp_int *a); + +/* grow an int to a given size */ +int mp_grow(mp_int *a, int size); + +/* init to a given number of digits */ +int mp_init_size(mp_int *a, int size); + +/* ---> Basic Manipulations <--- */ +#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO) +#define mp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO) +#define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO) + +/* set to zero */ +void mp_zero(mp_int *a); + +/* set to a digit */ +void mp_set(mp_int *a, mp_digit b); + +/* set a 32-bit const */ +int mp_set_int(mp_int *a, unsigned long b); + +/* get a 32-bit value */ +unsigned long mp_get_int(mp_int * a); + +/* initialize and set a digit */ +int mp_init_set (mp_int * a, mp_digit b); + +/* initialize and set 32-bit value */ +int mp_init_set_int (mp_int * a, unsigned long b); + +/* copy, b = a */ +int mp_copy(mp_int *a, mp_int *b); + +/* inits and copies, a = b */ +int mp_init_copy(mp_int *a, mp_int *b); + +/* trim unused digits */ +void mp_clamp(mp_int *a); + +/* ---> digit manipulation <--- */ + +/* right shift by "b" digits */ +void mp_rshd(mp_int *a, int b); + +/* left shift by "b" digits */ +int mp_lshd(mp_int *a, int b); + +/* c = a / 2**b */ +int mp_div_2d(mp_int *a, int b, mp_int *c, mp_int *d); + +/* b = a/2 */ +int mp_div_2(mp_int *a, mp_int *b); + +/* c = a * 2**b */ +int mp_mul_2d(mp_int *a, int b, mp_int *c); + +/* b = a*2 */ +int mp_mul_2(mp_int *a, mp_int *b); + +/* c = a mod 2**d */ +int mp_mod_2d(mp_int *a, int b, mp_int *c); + +/* computes a = 2**b */ +int mp_2expt(mp_int *a, int b); + +/* Counts the number of lsbs which are zero before the first zero bit */ +int mp_cnt_lsb(mp_int *a); + +/* I Love Earth! */ + +/* makes a pseudo-random int of a given size */ +int mp_rand(mp_int *a, int digits); + +/* ---> binary operations <--- */ +/* c = a XOR b */ +int mp_xor(mp_int *a, mp_int *b, mp_int *c); + +/* c = a OR b */ +int mp_or(mp_int *a, mp_int *b, mp_int *c); + +/* c = a AND b */ +int mp_and(mp_int *a, mp_int *b, mp_int *c); + +/* ---> Basic arithmetic <--- */ + +/* b = -a */ +int mp_neg(mp_int *a, mp_int *b); + +/* b = |a| */ +int mp_abs(mp_int *a, mp_int *b); + +/* compare a to b */ +int mp_cmp(mp_int *a, mp_int *b); + +/* compare |a| to |b| */ +int mp_cmp_mag(mp_int *a, mp_int *b); + +/* c = a + b */ +int mp_add(mp_int *a, mp_int *b, mp_int *c); + +/* c = a - b */ +int mp_sub(mp_int *a, mp_int *b, mp_int *c); + +/* c = a * b */ +int mp_mul(mp_int *a, mp_int *b, mp_int *c); + +/* b = a*a */ +int mp_sqr(mp_int *a, mp_int *b); + +/* a/b => cb + d == a */ +int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* c = a mod b, 0 <= c < b */ +int mp_mod(mp_int *a, mp_int *b, mp_int *c); + +/* ---> single digit functions <--- */ + +/* compare against a single digit */ +int mp_cmp_d(mp_int *a, mp_digit b); + +/* c = a + b */ +int mp_add_d(mp_int *a, mp_digit b, mp_int *c); + +/* c = a - b */ +int mp_sub_d(mp_int *a, mp_digit b, mp_int *c); + +/* c = a * b */ +int mp_mul_d(mp_int *a, mp_digit b, mp_int *c); + +/* a/b => cb + d == a */ +int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d); + +/* a/3 => 3c + d == a */ +int mp_div_3(mp_int *a, mp_int *c, mp_digit *d); + +/* c = a**b */ +int mp_expt_d(mp_int *a, mp_digit b, mp_int *c); + +/* c = a mod b, 0 <= c < b */ +int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c); + +/* ---> number theory <--- */ + +/* d = a + b (mod c) */ +int mp_addmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* d = a - b (mod c) */ +int mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* d = a * b (mod c) */ +int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* c = a * a (mod b) */ +int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c); + +/* c = 1/a (mod b) */ +int mp_invmod(mp_int *a, mp_int *b, mp_int *c); + +/* c = (a, b) */ +int mp_gcd(mp_int *a, mp_int *b, mp_int *c); + +/* produces value such that U1*a + U2*b = U3 */ +int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3); + +/* c = [a, b] or (a*b)/(a, b) */ +int mp_lcm(mp_int *a, mp_int *b, mp_int *c); + +/* finds one of the b'th root of a, such that |c|**b <= |a| + * + * returns error if a < 0 and b is even + */ +int mp_n_root(mp_int *a, mp_digit b, mp_int *c); + +/* special sqrt algo */ +int mp_sqrt(mp_int *arg, mp_int *ret); + +/* is number a square? */ +int mp_is_square(mp_int *arg, int *ret); + +/* computes the jacobi c = (a | n) (or Legendre if b is prime) */ +int mp_jacobi(mp_int *a, mp_int *n, int *c); + +/* used to setup the Barrett reduction for a given modulus b */ +int mp_reduce_setup(mp_int *a, mp_int *b); + +/* Barrett Reduction, computes a (mod b) with a precomputed value c + * + * Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely + * compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code]. + */ +int mp_reduce(mp_int *a, mp_int *b, mp_int *c); + +/* setups the montgomery reduction */ +int mp_montgomery_setup(mp_int *a, mp_digit *mp); + +/* computes a = B**n mod b without division or multiplication useful for + * normalizing numbers in a Montgomery system. + */ +int mp_montgomery_calc_normalization(mp_int *a, mp_int *b); + +/* computes x/R == x (mod N) via Montgomery Reduction */ +int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp); + +/* returns 1 if a is a valid DR modulus */ +int mp_dr_is_modulus(mp_int *a); + +/* sets the value of "d" required for mp_dr_reduce */ +void mp_dr_setup(mp_int *a, mp_digit *d); + +/* reduces a modulo b using the Diminished Radix method */ +int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp); + +/* returns true if a can be reduced with mp_reduce_2k */ +int mp_reduce_is_2k(mp_int *a); + +/* determines k value for 2k reduction */ +int mp_reduce_2k_setup(mp_int *a, mp_digit *d); + +/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */ +int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d); + +/* returns true if a can be reduced with mp_reduce_2k_l */ +int mp_reduce_is_2k_l(mp_int *a); + +/* determines k value for 2k reduction */ +int mp_reduce_2k_setup_l(mp_int *a, mp_int *d); + +/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */ +int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d); + +/* d = a**b (mod c) */ +int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* ---> Primes <--- */ + +/* number of primes */ +#ifdef MP_8BIT + #define PRIME_SIZE 31 +#else + #define PRIME_SIZE 256 +#endif + +/* table of first PRIME_SIZE primes */ +extern const mp_digit ltm_prime_tab[]; + +/* result=1 if a is divisible by one of the first PRIME_SIZE primes */ +int mp_prime_is_divisible(mp_int *a, int *result); + +/* performs one Fermat test of "a" using base "b". + * Sets result to 0 if composite or 1 if probable prime + */ +int mp_prime_fermat(mp_int *a, mp_int *b, int *result); + +/* performs one Miller-Rabin test of "a" using base "b". + * Sets result to 0 if composite or 1 if probable prime + */ +int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result); + +/* This gives [for a given bit size] the number of trials required + * such that Miller-Rabin gives a prob of failure lower than 2^-96 + */ +int mp_prime_rabin_miller_trials(int size); + +/* performs t rounds of Miller-Rabin on "a" using the first + * t prime bases. Also performs an initial sieve of trial + * division. Determines if "a" is prime with probability + * of error no more than (1/4)**t. + * + * Sets result to 1 if probably prime, 0 otherwise + */ +int mp_prime_is_prime(mp_int *a, int t, int *result); + +/* finds the next prime after the number "a" using "t" trials + * of Miller-Rabin. + * + * bbs_style = 1 means the prime must be congruent to 3 mod 4 + */ +int mp_prime_next_prime(mp_int *a, int t, int bbs_style); + +/* makes a truly random prime of a given size (bytes), + * call with bbs = 1 if you want it to be congruent to 3 mod 4 + * + * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can + * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself + * so it can be NULL + * + * The prime generated will be larger than 2^(8*size). + */ +#define mp_prime_random(a, t, size, bbs, cb, dat) mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat) + +/* makes a truly random prime of a given size (bits), + * + * Flags are as follows: + * + * LTM_PRIME_BBS - make prime congruent to 3 mod 4 + * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS) + * LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero + * LTM_PRIME_2MSB_ON - make the 2nd highest bit one + * + * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can + * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself + * so it can be NULL + * + */ +int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat); + +/* ---> radix conversion <--- */ +int mp_count_bits(mp_int *a); + +int mp_unsigned_bin_size(mp_int *a); +int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c); +int mp_to_unsigned_bin(mp_int *a, unsigned char *b); +int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen); + +int mp_signed_bin_size(mp_int *a); +int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c); +int mp_to_signed_bin(mp_int *a, unsigned char *b); +int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen); + +int mp_read_radix(mp_int *a, const char *str, int radix); +int mp_toradix(mp_int *a, char *str, int radix); +int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen); +int mp_radix_size(mp_int *a, int radix, int *size); + +#ifdef BN_MP_FREAD_C +int mp_fread(mp_int *a, int radix, FILE *stream); +#endif + +#ifdef BN_MP_FWRITE_C +int mp_fwrite(mp_int *a, int radix, FILE *stream); +#endif + +#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len)) +#define mp_raw_size(mp) mp_signed_bin_size(mp) +#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str)) +#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len)) +#define mp_mag_size(mp) mp_unsigned_bin_size(mp) +#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str)) + +#define mp_tobinary(M, S) mp_toradix((M), (S), 2) +#define mp_tooctal(M, S) mp_toradix((M), (S), 8) +#define mp_todecimal(M, S) mp_toradix((M), (S), 10) +#define mp_tohex(M, S) mp_toradix((M), (S), 16) + +/* lowlevel functions, do not call! */ +int s_mp_add(mp_int *a, mp_int *b, mp_int *c); +int s_mp_sub(mp_int *a, mp_int *b, mp_int *c); +#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1) +int fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs); +int s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs); +int fast_s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs); +int s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs); +int fast_s_mp_sqr(mp_int *a, mp_int *b); +int s_mp_sqr(mp_int *a, mp_int *b); +int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c); +int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c); +int mp_karatsuba_sqr(mp_int *a, mp_int *b); +int mp_toom_sqr(mp_int *a, mp_int *b); +int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c); +int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c); +int fast_mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp); +int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int mode); +int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int mode); +void bn_reverse(unsigned char *s, int len); + +extern const char *mp_s_rmap; + +#ifdef __cplusplus + } +#endif + +#endif + + +/* $Source$ */ +/* $Revision: 0.39 $ */ +/* $Date: 2006-04-06 19:49:59 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/tommath.out b/xmhf-64/xmhf/third-party/libtommath/tommath.out new file mode 100644 index 0000000000..9f62617275 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/tommath.out @@ -0,0 +1,139 @@ +\BOOKMARK [0][-]{chapter.1}{Introduction}{} +\BOOKMARK [1][-]{section.1.1}{Multiple Precision Arithmetic}{chapter.1} +\BOOKMARK [2][-]{subsection.1.1.1}{What is Multiple Precision Arithmetic?}{section.1.1} +\BOOKMARK [2][-]{subsection.1.1.2}{The Need for Multiple Precision Arithmetic}{section.1.1} +\BOOKMARK [2][-]{subsection.1.1.3}{Benefits of Multiple Precision Arithmetic}{section.1.1} +\BOOKMARK [1][-]{section.1.2}{Purpose of This Text}{chapter.1} +\BOOKMARK [1][-]{section.1.3}{Discussion and Notation}{chapter.1} +\BOOKMARK [2][-]{subsection.1.3.1}{Notation}{section.1.3} +\BOOKMARK [2][-]{subsection.1.3.2}{Precision Notation}{section.1.3} +\BOOKMARK [2][-]{subsection.1.3.3}{Algorithm Inputs and Outputs}{section.1.3} +\BOOKMARK [2][-]{subsection.1.3.4}{Mathematical Expressions}{section.1.3} +\BOOKMARK [2][-]{subsection.1.3.5}{Work Effort}{section.1.3} +\BOOKMARK [1][-]{section.1.4}{Exercises}{chapter.1} +\BOOKMARK [1][-]{section.1.5}{Introduction to LibTomMath}{chapter.1} +\BOOKMARK [2][-]{subsection.1.5.1}{What is LibTomMath?}{section.1.5} +\BOOKMARK [2][-]{subsection.1.5.2}{Goals of LibTomMath}{section.1.5} +\BOOKMARK [1][-]{section.1.6}{Choice of LibTomMath}{chapter.1} +\BOOKMARK [2][-]{subsection.1.6.1}{Code Base}{section.1.6} +\BOOKMARK [2][-]{subsection.1.6.2}{API Simplicity}{section.1.6} +\BOOKMARK [2][-]{subsection.1.6.3}{Optimizations}{section.1.6} +\BOOKMARK [2][-]{subsection.1.6.4}{Portability and Stability}{section.1.6} +\BOOKMARK [2][-]{subsection.1.6.5}{Choice}{section.1.6} +\BOOKMARK [0][-]{chapter.2}{Getting Started}{} +\BOOKMARK [1][-]{section.2.1}{Library Basics}{chapter.2} +\BOOKMARK [1][-]{section.2.2}{What is a Multiple Precision Integer?}{chapter.2} +\BOOKMARK [2][-]{subsection.2.2.1}{The mp\137int Structure}{section.2.2} +\BOOKMARK [1][-]{section.2.3}{Argument Passing}{chapter.2} +\BOOKMARK [1][-]{section.2.4}{Return Values}{chapter.2} +\BOOKMARK [1][-]{section.2.5}{Initialization and Clearing}{chapter.2} +\BOOKMARK [2][-]{subsection.2.5.1}{Initializing an mp\137int}{section.2.5} +\BOOKMARK [2][-]{subsection.2.5.2}{Clearing an mp\137int}{section.2.5} +\BOOKMARK [1][-]{section.2.6}{Maintenance Algorithms}{chapter.2} +\BOOKMARK [2][-]{subsection.2.6.1}{Augmenting an mp\137int's Precision}{section.2.6} +\BOOKMARK [2][-]{subsection.2.6.2}{Initializing Variable Precision mp\137ints}{section.2.6} +\BOOKMARK [2][-]{subsection.2.6.3}{Multiple Integer Initializations and Clearings}{section.2.6} +\BOOKMARK [2][-]{subsection.2.6.4}{Clamping Excess Digits}{section.2.6} +\BOOKMARK [0][-]{chapter.3}{Basic Operations}{} +\BOOKMARK [1][-]{section.3.1}{Introduction}{chapter.3} +\BOOKMARK [1][-]{section.3.2}{Assigning Values to mp\137int Structures}{chapter.3} +\BOOKMARK [2][-]{subsection.3.2.1}{Copying an mp\137int}{section.3.2} +\BOOKMARK [2][-]{subsection.3.2.2}{Creating a Clone}{section.3.2} +\BOOKMARK [1][-]{section.3.3}{Zeroing an Integer}{chapter.3} +\BOOKMARK [1][-]{section.3.4}{Sign Manipulation}{chapter.3} +\BOOKMARK [2][-]{subsection.3.4.1}{Absolute Value}{section.3.4} +\BOOKMARK [2][-]{subsection.3.4.2}{Integer Negation}{section.3.4} +\BOOKMARK [1][-]{section.3.5}{Small Constants}{chapter.3} +\BOOKMARK [2][-]{subsection.3.5.1}{Setting Small Constants}{section.3.5} +\BOOKMARK [2][-]{subsection.3.5.2}{Setting Large Constants}{section.3.5} +\BOOKMARK [1][-]{section.3.6}{Comparisons}{chapter.3} +\BOOKMARK [2][-]{subsection.3.6.1}{Unsigned Comparisions}{section.3.6} +\BOOKMARK [2][-]{subsection.3.6.2}{Signed Comparisons}{section.3.6} +\BOOKMARK [0][-]{chapter.4}{Basic Arithmetic}{} +\BOOKMARK [1][-]{section.4.1}{Introduction}{chapter.4} +\BOOKMARK [1][-]{section.4.2}{Addition and Subtraction}{chapter.4} +\BOOKMARK [2][-]{subsection.4.2.1}{Low Level Addition}{section.4.2} +\BOOKMARK [2][-]{subsection.4.2.2}{Low Level Subtraction}{section.4.2} +\BOOKMARK [2][-]{subsection.4.2.3}{High Level Addition}{section.4.2} +\BOOKMARK [2][-]{subsection.4.2.4}{High Level Subtraction}{section.4.2} +\BOOKMARK [1][-]{section.4.3}{Bit and Digit Shifting}{chapter.4} +\BOOKMARK [2][-]{subsection.4.3.1}{Multiplication by Two}{section.4.3} +\BOOKMARK [2][-]{subsection.4.3.2}{Division by Two}{section.4.3} +\BOOKMARK [1][-]{section.4.4}{Polynomial Basis Operations}{chapter.4} +\BOOKMARK [2][-]{subsection.4.4.1}{Multiplication by x}{section.4.4} +\BOOKMARK [2][-]{subsection.4.4.2}{Division by x}{section.4.4} +\BOOKMARK [1][-]{section.4.5}{Powers of Two}{chapter.4} +\BOOKMARK [2][-]{subsection.4.5.1}{Multiplication by Power of Two}{section.4.5} +\BOOKMARK [2][-]{subsection.4.5.2}{Division by Power of Two}{section.4.5} +\BOOKMARK [2][-]{subsection.4.5.3}{Remainder of Division by Power of Two}{section.4.5} +\BOOKMARK [0][-]{chapter.5}{Multiplication and Squaring}{} +\BOOKMARK [1][-]{section.5.1}{The Multipliers}{chapter.5} +\BOOKMARK [1][-]{section.5.2}{Multiplication}{chapter.5} +\BOOKMARK [2][-]{subsection.5.2.1}{The Baseline Multiplication}{section.5.2} +\BOOKMARK [2][-]{subsection.5.2.2}{Faster Multiplication by the ``Comba'' Method}{section.5.2} +\BOOKMARK [2][-]{subsection.5.2.3}{Polynomial Basis Multiplication}{section.5.2} +\BOOKMARK [2][-]{subsection.5.2.4}{Karatsuba Multiplication}{section.5.2} +\BOOKMARK [2][-]{subsection.5.2.5}{Toom-Cook 3-Way Multiplication}{section.5.2} +\BOOKMARK [2][-]{subsection.5.2.6}{Signed Multiplication}{section.5.2} +\BOOKMARK [1][-]{section.5.3}{Squaring}{chapter.5} +\BOOKMARK [2][-]{subsection.5.3.1}{The Baseline Squaring Algorithm}{section.5.3} +\BOOKMARK [2][-]{subsection.5.3.2}{Faster Squaring by the ``Comba'' Method}{section.5.3} +\BOOKMARK [2][-]{subsection.5.3.3}{Polynomial Basis Squaring}{section.5.3} +\BOOKMARK [2][-]{subsection.5.3.4}{Karatsuba Squaring}{section.5.3} +\BOOKMARK [2][-]{subsection.5.3.5}{Toom-Cook Squaring}{section.5.3} +\BOOKMARK [2][-]{subsection.5.3.6}{High Level Squaring}{section.5.3} +\BOOKMARK [0][-]{chapter.6}{Modular Reduction}{} +\BOOKMARK [1][-]{section.6.1}{Basics of Modular Reduction}{chapter.6} +\BOOKMARK [1][-]{section.6.2}{The Barrett Reduction}{chapter.6} +\BOOKMARK [2][-]{subsection.6.2.1}{Fixed Point Arithmetic}{section.6.2} +\BOOKMARK [2][-]{subsection.6.2.2}{Choosing a Radix Point}{section.6.2} +\BOOKMARK [2][-]{subsection.6.2.3}{Trimming the Quotient}{section.6.2} +\BOOKMARK [2][-]{subsection.6.2.4}{Trimming the Residue}{section.6.2} +\BOOKMARK [2][-]{subsection.6.2.5}{The Barrett Algorithm}{section.6.2} +\BOOKMARK [2][-]{subsection.6.2.6}{The Barrett Setup Algorithm}{section.6.2} +\BOOKMARK [1][-]{section.6.3}{The Montgomery Reduction}{chapter.6} +\BOOKMARK [2][-]{subsection.6.3.1}{Digit Based Montgomery Reduction}{section.6.3} +\BOOKMARK [2][-]{subsection.6.3.2}{Baseline Montgomery Reduction}{section.6.3} +\BOOKMARK [2][-]{subsection.6.3.3}{Faster ``Comba'' Montgomery Reduction}{section.6.3} +\BOOKMARK [2][-]{subsection.6.3.4}{Montgomery Setup}{section.6.3} +\BOOKMARK [1][-]{section.6.4}{The Diminished Radix Algorithm}{chapter.6} +\BOOKMARK [2][-]{subsection.6.4.1}{Choice of Moduli}{section.6.4} +\BOOKMARK [2][-]{subsection.6.4.2}{Choice of k}{section.6.4} +\BOOKMARK [2][-]{subsection.6.4.3}{Restricted Diminished Radix Reduction}{section.6.4} +\BOOKMARK [2][-]{subsection.6.4.4}{Unrestricted Diminished Radix Reduction}{section.6.4} +\BOOKMARK [1][-]{section.6.5}{Algorithm Comparison}{chapter.6} +\BOOKMARK [0][-]{chapter.7}{Exponentiation}{} +\BOOKMARK [1][-]{section.7.1}{Exponentiation Basics}{chapter.7} +\BOOKMARK [2][-]{subsection.7.1.1}{Single Digit Exponentiation}{section.7.1} +\BOOKMARK [1][-]{section.7.2}{k-ary Exponentiation}{chapter.7} +\BOOKMARK [2][-]{subsection.7.2.1}{Optimal Values of k}{section.7.2} +\BOOKMARK [2][-]{subsection.7.2.2}{Sliding-Window Exponentiation}{section.7.2} +\BOOKMARK [1][-]{section.7.3}{Modular Exponentiation}{chapter.7} +\BOOKMARK [2][-]{subsection.7.3.1}{Barrett Modular Exponentiation}{section.7.3} +\BOOKMARK [1][-]{section.7.4}{Quick Power of Two}{chapter.7} +\BOOKMARK [0][-]{chapter.8}{Higher Level Algorithms}{} +\BOOKMARK [1][-]{section.8.1}{Integer Division with Remainder}{chapter.8} +\BOOKMARK [2][-]{subsection.8.1.1}{Quotient Estimation}{section.8.1} +\BOOKMARK [2][-]{subsection.8.1.2}{Normalized Integers}{section.8.1} +\BOOKMARK [2][-]{subsection.8.1.3}{Radix- Division with Remainder}{section.8.1} +\BOOKMARK [1][-]{section.8.2}{Single Digit Helpers}{chapter.8} +\BOOKMARK [2][-]{subsection.8.2.1}{Single Digit Addition and Subtraction}{section.8.2} +\BOOKMARK [2][-]{subsection.8.2.2}{Single Digit Multiplication}{section.8.2} +\BOOKMARK [2][-]{subsection.8.2.3}{Single Digit Division}{section.8.2} +\BOOKMARK [2][-]{subsection.8.2.4}{Single Digit Root Extraction}{section.8.2} +\BOOKMARK [1][-]{section.8.3}{Random Number Generation}{chapter.8} +\BOOKMARK [1][-]{section.8.4}{Formatted Representations}{chapter.8} +\BOOKMARK [2][-]{subsection.8.4.1}{Reading Radix-n Input}{section.8.4} +\BOOKMARK [2][-]{subsection.8.4.2}{Generating Radix-n Output}{section.8.4} +\BOOKMARK [0][-]{chapter.9}{Number Theoretic Algorithms}{} +\BOOKMARK [1][-]{section.9.1}{Greatest Common Divisor}{chapter.9} +\BOOKMARK [2][-]{subsection.9.1.1}{Complete Greatest Common Divisor}{section.9.1} +\BOOKMARK [1][-]{section.9.2}{Least Common Multiple}{chapter.9} +\BOOKMARK [1][-]{section.9.3}{Jacobi Symbol Computation}{chapter.9} +\BOOKMARK [2][-]{subsection.9.3.1}{Jacobi Symbol}{section.9.3} +\BOOKMARK [1][-]{section.9.4}{Modular Inverse}{chapter.9} +\BOOKMARK [2][-]{subsection.9.4.1}{General Case}{section.9.4} +\BOOKMARK [1][-]{section.9.5}{Primality Tests}{chapter.9} +\BOOKMARK [2][-]{subsection.9.5.1}{Trial Division}{section.9.5} +\BOOKMARK [2][-]{subsection.9.5.2}{The Fermat Test}{section.9.5} +\BOOKMARK [2][-]{subsection.9.5.3}{The Miller-Rabin Test}{section.9.5} diff --git a/xmhf-64/xmhf/third-party/libtommath/tommath.pdf b/xmhf-64/xmhf/third-party/libtommath/tommath.pdf new file mode 100644 index 0000000000..0b689419e9 Binary files /dev/null and b/xmhf-64/xmhf/third-party/libtommath/tommath.pdf differ diff --git a/xmhf-64/xmhf/third-party/libtommath/tommath.src b/xmhf-64/xmhf/third-party/libtommath/tommath.src new file mode 100644 index 0000000000..40658222c2 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/tommath.src @@ -0,0 +1,6350 @@ +\documentclass[b5paper]{book} +\usepackage{hyperref} +\usepackage{makeidx} +\usepackage{amssymb} +\usepackage{color} +\usepackage{alltt} +\usepackage{graphicx} +\usepackage{layout} +\def\union{\cup} +\def\intersect{\cap} +\def\getsrandom{\stackrel{\rm R}{\gets}} +\def\cross{\times} +\def\cat{\hspace{0.5em} \| \hspace{0.5em}} +\def\catn{$\|$} +\def\divides{\hspace{0.3em} | \hspace{0.3em}} +\def\nequiv{\not\equiv} +\def\approx{\raisebox{0.2ex}{\mbox{\small $\sim$}}} +\def\lcm{{\rm lcm}} +\def\gcd{{\rm gcd}} +\def\log{{\rm log}} +\def\ord{{\rm ord}} +\def\abs{{\mathit abs}} +\def\rep{{\mathit rep}} +\def\mod{{\mathit\ mod\ }} +\renewcommand{\pmod}[1]{\ ({\rm mod\ }{#1})} +\newcommand{\floor}[1]{\left\lfloor{#1}\right\rfloor} +\newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil} +\def\Or{{\rm\ or\ }} +\def\And{{\rm\ and\ }} +\def\iff{\hspace{1em}\Longleftrightarrow\hspace{1em}} +\def\implies{\Rightarrow} +\def\undefined{{\rm ``undefined"}} +\def\Proof{\vspace{1ex}\noindent {\bf Proof:}\hspace{1em}} +\let\oldphi\phi +\def\phi{\varphi} +\def\Pr{{\rm Pr}} +\newcommand{\str}[1]{{\mathbf{#1}}} +\def\F{{\mathbb F}} +\def\N{{\mathbb N}} +\def\Z{{\mathbb Z}} +\def\R{{\mathbb R}} +\def\C{{\mathbb C}} +\def\Q{{\mathbb Q}} +\definecolor{DGray}{gray}{0.5} +\newcommand{\emailaddr}[1]{\mbox{$<${#1}$>$}} +\def\twiddle{\raisebox{0.3ex}{\mbox{\tiny $\sim$}}} +\def\gap{\vspace{0.5ex}} +\makeindex +\begin{document} +\frontmatter +\pagestyle{empty} +\title{Multi--Precision Math} +\author{\mbox{ +%\begin{small} +\begin{tabular}{c} +Tom St Denis \\ +Algonquin College \\ +\\ +Mads Rasmussen \\ +Open Communications Security \\ +\\ +Greg Rose \\ +QUALCOMM Australia \\ +\end{tabular} +%\end{small} +} +} +\maketitle +This text has been placed in the public domain. This text corresponds to the v0.39 release of the +LibTomMath project. + +\begin{alltt} +Tom St Denis +111 Banning Rd +Ottawa, Ontario +K2L 1C3 +Canada + +Phone: 1-613-836-3160 +Email: tomstdenis@gmail.com +\end{alltt} + +This text is formatted to the international B5 paper size of 176mm wide by 250mm tall using the \LaTeX{} +{\em book} macro package and the Perl {\em booker} package. + +\tableofcontents +\listoffigures +\chapter*{Prefaces} +When I tell people about my LibTom projects and that I release them as public domain they are often puzzled. +They ask why I did it and especially why I continue to work on them for free. The best I can explain it is ``Because I can.'' +Which seems odd and perhaps too terse for adult conversation. I often qualify it with ``I am able, I am willing.'' which +perhaps explains it better. I am the first to admit there is not anything that special with what I have done. Perhaps +others can see that too and then we would have a society to be proud of. My LibTom projects are what I am doing to give +back to society in the form of tools and knowledge that can help others in their endeavours. + +I started writing this book because it was the most logical task to further my goal of open academia. The LibTomMath source +code itself was written to be easy to follow and learn from. There are times, however, where pure C source code does not +explain the algorithms properly. Hence this book. The book literally starts with the foundation of the library and works +itself outwards to the more complicated algorithms. The use of both pseudo--code and verbatim source code provides a duality +of ``theory'' and ``practice'' that the computer science students of the world shall appreciate. I never deviate too far +from relatively straightforward algebra and I hope that this book can be a valuable learning asset. + +This book and indeed much of the LibTom projects would not exist in their current form if it was not for a plethora +of kind people donating their time, resources and kind words to help support my work. Writing a text of significant +length (along with the source code) is a tiresome and lengthy process. Currently the LibTom project is four years old, +comprises of literally thousands of users and over 100,000 lines of source code, TeX and other material. People like Mads and Greg +were there at the beginning to encourage me to work well. It is amazing how timely validation from others can boost morale to +continue the project. Definitely my parents were there for me by providing room and board during the many months of work in 2003. + +To my many friends whom I have met through the years I thank you for the good times and the words of encouragement. I hope I +honour your kind gestures with this project. + +Open Source. Open Academia. Open Minds. + +\begin{flushright} Tom St Denis \end{flushright} + +\newpage +I found the opportunity to work with Tom appealing for several reasons, not only could I broaden my own horizons, but also +contribute to educate others facing the problem of having to handle big number mathematical calculations. + +This book is Tom's child and he has been caring and fostering the project ever since the beginning with a clear mind of +how he wanted the project to turn out. I have helped by proofreading the text and we have had several discussions about +the layout and language used. + +I hold a masters degree in cryptography from the University of Southern Denmark and have always been interested in the +practical aspects of cryptography. + +Having worked in the security consultancy business for several years in S\~{a}o Paulo, Brazil, I have been in touch with a +great deal of work in which multiple precision mathematics was needed. Understanding the possibilities for speeding up +multiple precision calculations is often very important since we deal with outdated machine architecture where modular +reductions, for example, become painfully slow. + +This text is for people who stop and wonder when first examining algorithms such as RSA for the first time and asks +themselves, ``You tell me this is only secure for large numbers, fine; but how do you implement these numbers?'' + +\begin{flushright} +Mads Rasmussen + +S\~{a}o Paulo - SP + +Brazil +\end{flushright} + +\newpage +It's all because I broke my leg. That just happened to be at about the same time that Tom asked for someone to review the section of the book about +Karatsuba multiplication. I was laid up, alone and immobile, and thought ``Why not?'' I vaguely knew what Karatsuba multiplication was, but not +really, so I thought I could help, learn, and stop myself from watching daytime cable TV, all at once. + +At the time of writing this, I've still not met Tom or Mads in meatspace. I've been following Tom's progress since his first splash on the +sci.crypt Usenet news group. I watched him go from a clueless newbie, to the cryptographic equivalent of a reformed smoker, to a real +contributor to the field, over a period of about two years. I've been impressed with his obvious intelligence, and astounded by his productivity. +Of course, he's young enough to be my own child, so he doesn't have my problems with staying awake. + +When I reviewed that single section of the book, in its very earliest form, I was very pleasantly surprised. So I decided to collaborate more fully, +and at least review all of it, and perhaps write some bits too. There's still a long way to go with it, and I have watched a number of close +friends go through the mill of publication, so I think that the way to go is longer than Tom thinks it is. Nevertheless, it's a good effort, +and I'm pleased to be involved with it. + +\begin{flushright} +Greg Rose, Sydney, Australia, June 2003. +\end{flushright} + +\mainmatter +\pagestyle{headings} +\chapter{Introduction} +\section{Multiple Precision Arithmetic} + +\subsection{What is Multiple Precision Arithmetic?} +When we think of long-hand arithmetic such as addition or multiplication we rarely consider the fact that we instinctively +raise or lower the precision of the numbers we are dealing with. For example, in decimal we almost immediate can +reason that $7$ times $6$ is $42$. However, $42$ has two digits of precision as opposed to one digit we started with. +Further multiplications of say $3$ result in a larger precision result $126$. In these few examples we have multiple +precisions for the numbers we are working with. Despite the various levels of precision a single subset\footnote{With the occasional optimization.} + of algorithms can be designed to accomodate them. + +By way of comparison a fixed or single precision operation would lose precision on various operations. For example, in +the decimal system with fixed precision $6 \cdot 7 = 2$. + +Essentially at the heart of computer based multiple precision arithmetic are the same long-hand algorithms taught in +schools to manually add, subtract, multiply and divide. + +\subsection{The Need for Multiple Precision Arithmetic} +The most prevalent need for multiple precision arithmetic, often referred to as ``bignum'' math, is within the implementation +of public-key cryptography algorithms. Algorithms such as RSA \cite{RSAREF} and Diffie-Hellman \cite{DHREF} require +integers of significant magnitude to resist known cryptanalytic attacks. For example, at the time of this writing a +typical RSA modulus would be at least greater than $10^{309}$. However, modern programming languages such as ISO C \cite{ISOC} and +Java \cite{JAVA} only provide instrinsic support for integers which are relatively small and single precision. + +\begin{figure}[!here] +\begin{center} +\begin{tabular}{|r|c|} +\hline \textbf{Data Type} & \textbf{Range} \\ +\hline char & $-128 \ldots 127$ \\ +\hline short & $-32768 \ldots 32767$ \\ +\hline long & $-2147483648 \ldots 2147483647$ \\ +\hline long long & $-9223372036854775808 \ldots 9223372036854775807$ \\ +\hline +\end{tabular} +\end{center} +\caption{Typical Data Types for the C Programming Language} +\label{fig:ISOC} +\end{figure} + +The largest data type guaranteed to be provided by the ISO C programming +language\footnote{As per the ISO C standard. However, each compiler vendor is allowed to augment the precision as they +see fit.} can only represent values up to $10^{19}$ as shown in figure \ref{fig:ISOC}. On its own the C language is +insufficient to accomodate the magnitude required for the problem at hand. An RSA modulus of magnitude $10^{19}$ could be +trivially factored\footnote{A Pollard-Rho factoring would take only $2^{16}$ time.} on the average desktop computer, +rendering any protocol based on the algorithm insecure. Multiple precision algorithms solve this very problem by +extending the range of representable integers while using single precision data types. + +Most advancements in fast multiple precision arithmetic stem from the need for faster and more efficient cryptographic +primitives. Faster modular reduction and exponentiation algorithms such as Barrett's algorithm, which have appeared in +various cryptographic journals, can render algorithms such as RSA and Diffie-Hellman more efficient. In fact, several +major companies such as RSA Security, Certicom and Entrust have built entire product lines on the implementation and +deployment of efficient algorithms. + +However, cryptography is not the only field of study that can benefit from fast multiple precision integer routines. +Another auxiliary use of multiple precision integers is high precision floating point data types. +The basic IEEE \cite{IEEE} standard floating point type is made up of an integer mantissa $q$, an exponent $e$ and a sign bit $s$. +Numbers are given in the form $n = q \cdot b^e \cdot -1^s$ where $b = 2$ is the most common base for IEEE. Since IEEE +floating point is meant to be implemented in hardware the precision of the mantissa is often fairly small +(\textit{23, 48 and 64 bits}). The mantissa is merely an integer and a multiple precision integer could be used to create +a mantissa of much larger precision than hardware alone can efficiently support. This approach could be useful where +scientific applications must minimize the total output error over long calculations. + +Yet another use for large integers is within arithmetic on polynomials of large characteristic (i.e. $GF(p)[x]$ for large $p$). +In fact the library discussed within this text has already been used to form a polynomial basis library\footnote{See \url{http://poly.libtomcrypt.org} for more details.}. + +\subsection{Benefits of Multiple Precision Arithmetic} +\index{precision} +The benefit of multiple precision representations over single or fixed precision representations is that +no precision is lost while representing the result of an operation which requires excess precision. For example, +the product of two $n$-bit integers requires at least $2n$ bits of precision to be represented faithfully. A multiple +precision algorithm would augment the precision of the destination to accomodate the result while a single precision system +would truncate excess bits to maintain a fixed level of precision. + +It is possible to implement algorithms which require large integers with fixed precision algorithms. For example, elliptic +curve cryptography (\textit{ECC}) is often implemented on smartcards by fixing the precision of the integers to the maximum +size the system will ever need. Such an approach can lead to vastly simpler algorithms which can accomodate the +integers required even if the host platform cannot natively accomodate them\footnote{For example, the average smartcard +processor has an 8 bit accumulator.}. However, as efficient as such an approach may be, the resulting source code is not +normally very flexible. It cannot, at runtime, accomodate inputs of higher magnitude than the designer anticipated. + +Multiple precision algorithms have the most overhead of any style of arithmetic. For the the most part the +overhead can be kept to a minimum with careful planning, but overall, it is not well suited for most memory starved +platforms. However, multiple precision algorithms do offer the most flexibility in terms of the magnitude of the +inputs. That is, the same algorithms based on multiple precision integers can accomodate any reasonable size input +without the designer's explicit forethought. This leads to lower cost of ownership for the code as it only has to +be written and tested once. + +\section{Purpose of This Text} +The purpose of this text is to instruct the reader regarding how to implement efficient multiple precision algorithms. +That is to not only explain a limited subset of the core theory behind the algorithms but also the various ``house keeping'' +elements that are neglected by authors of other texts on the subject. Several well reknowned texts \cite{TAOCPV2,HAC} +give considerably detailed explanations of the theoretical aspects of algorithms and often very little information +regarding the practical implementation aspects. + +In most cases how an algorithm is explained and how it is actually implemented are two very different concepts. For +example, the Handbook of Applied Cryptography (\textit{HAC}), algorithm 14.7 on page 594, gives a relatively simple +algorithm for performing multiple precision integer addition. However, the description lacks any discussion concerning +the fact that the two integer inputs may be of differing magnitudes. As a result the implementation is not as simple +as the text would lead people to believe. Similarly the division routine (\textit{algorithm 14.20, pp. 598}) does not +discuss how to handle sign or handle the dividend's decreasing magnitude in the main loop (\textit{step \#3}). + +Both texts also do not discuss several key optimal algorithms required such as ``Comba'' and Karatsuba multipliers +and fast modular inversion, which we consider practical oversights. These optimal algorithms are vital to achieve +any form of useful performance in non-trivial applications. + +To solve this problem the focus of this text is on the practical aspects of implementing a multiple precision integer +package. As a case study the ``LibTomMath''\footnote{Available at \url{http://math.libtomcrypt.com}} package is used +to demonstrate algorithms with real implementations\footnote{In the ISO C programming language.} that have been field +tested and work very well. The LibTomMath library is freely available on the Internet for all uses and this text +discusses a very large portion of the inner workings of the library. + +The algorithms that are presented will always include at least one ``pseudo-code'' description followed +by the actual C source code that implements the algorithm. The pseudo-code can be used to implement the same +algorithm in other programming languages as the reader sees fit. + +This text shall also serve as a walkthrough of the creation of multiple precision algorithms from scratch. Showing +the reader how the algorithms fit together as well as where to start on various taskings. + +\section{Discussion and Notation} +\subsection{Notation} +A multiple precision integer of $n$-digits shall be denoted as $x = (x_{n-1}, \ldots, x_1, x_0)_{ \beta }$ and represent +the integer $x \equiv \sum_{i=0}^{n-1} x_i\beta^i$. The elements of the array $x$ are said to be the radix $\beta$ digits +of the integer. For example, $x = (1,2,3)_{10}$ would represent the integer +$1\cdot 10^2 + 2\cdot10^1 + 3\cdot10^0 = 123$. + +\index{mp\_int} +The term ``mp\_int'' shall refer to a composite structure which contains the digits of the integer it represents, as well +as auxilary data required to manipulate the data. These additional members are discussed further in section +\ref{sec:MPINT}. For the purposes of this text a ``multiple precision integer'' and an ``mp\_int'' are assumed to be +synonymous. When an algorithm is specified to accept an mp\_int variable it is assumed the various auxliary data members +are present as well. An expression of the type \textit{variablename.item} implies that it should evaluate to the +member named ``item'' of the variable. For example, a string of characters may have a member ``length'' which would +evaluate to the number of characters in the string. If the string $a$ equals ``hello'' then it follows that +$a.length = 5$. + +For certain discussions more generic algorithms are presented to help the reader understand the final algorithm used +to solve a given problem. When an algorithm is described as accepting an integer input it is assumed the input is +a plain integer with no additional multiple-precision members. That is, algorithms that use integers as opposed to +mp\_ints as inputs do not concern themselves with the housekeeping operations required such as memory management. These +algorithms will be used to establish the relevant theory which will subsequently be used to describe a multiple +precision algorithm to solve the same problem. + +\subsection{Precision Notation} +The variable $\beta$ represents the radix of a single digit of a multiple precision integer and +must be of the form $q^p$ for $q, p \in \Z^+$. A single precision variable must be able to represent integers in +the range $0 \le x < q \beta$ while a double precision variable must be able to represent integers in the range +$0 \le x < q \beta^2$. The extra radix-$q$ factor allows additions and subtractions to proceed without truncation of the +carry. Since all modern computers are binary, it is assumed that $q$ is two. + +\index{mp\_digit} \index{mp\_word} +Within the source code that will be presented for each algorithm, the data type \textbf{mp\_digit} will represent +a single precision integer type, while, the data type \textbf{mp\_word} will represent a double precision integer type. In +several algorithms (notably the Comba routines) temporary results will be stored in arrays of double precision mp\_words. +For the purposes of this text $x_j$ will refer to the $j$'th digit of a single precision array and $\hat x_j$ will refer to +the $j$'th digit of a double precision array. Whenever an expression is to be assigned to a double precision +variable it is assumed that all single precision variables are promoted to double precision during the evaluation. +Expressions that are assigned to a single precision variable are truncated to fit within the precision of a single +precision data type. + +For example, if $\beta = 10^2$ a single precision data type may represent a value in the +range $0 \le x < 10^3$, while a double precision data type may represent a value in the range $0 \le x < 10^5$. Let +$a = 23$ and $b = 49$ represent two single precision variables. The single precision product shall be written +as $c \leftarrow a \cdot b$ while the double precision product shall be written as $\hat c \leftarrow a \cdot b$. +In this particular case, $\hat c = 1127$ and $c = 127$. The most significant digit of the product would not fit +in a single precision data type and as a result $c \ne \hat c$. + +\subsection{Algorithm Inputs and Outputs} +Within the algorithm descriptions all variables are assumed to be scalars of either single or double precision +as indicated. The only exception to this rule is when variables have been indicated to be of type mp\_int. This +distinction is important as scalars are often used as array indicies and various other counters. + +\subsection{Mathematical Expressions} +The $\lfloor \mbox{ } \rfloor$ brackets imply an expression truncated to an integer not greater than the expression +itself. For example, $\lfloor 5.7 \rfloor = 5$. Similarly the $\lceil \mbox{ } \rceil$ brackets imply an expression +rounded to an integer not less than the expression itself. For example, $\lceil 5.1 \rceil = 6$. Typically when +the $/$ division symbol is used the intention is to perform an integer division with truncation. For example, +$5/2 = 2$ which will often be written as $\lfloor 5/2 \rfloor = 2$ for clarity. When an expression is written as a +fraction a real value division is implied, for example ${5 \over 2} = 2.5$. + +The norm of a multiple precision integer, for example $\vert \vert x \vert \vert$, will be used to represent the number of digits in the representation +of the integer. For example, $\vert \vert 123 \vert \vert = 3$ and $\vert \vert 79452 \vert \vert = 5$. + +\subsection{Work Effort} +\index{big-Oh} +To measure the efficiency of the specified algorithms, a modified big-Oh notation is used. In this system all +single precision operations are considered to have the same cost\footnote{Except where explicitly noted.}. +That is a single precision addition, multiplication and division are assumed to take the same time to +complete. While this is generally not true in practice, it will simplify the discussions considerably. + +Some algorithms have slight advantages over others which is why some constants will not be removed in +the notation. For example, a normal baseline multiplication (section \ref{sec:basemult}) requires $O(n^2)$ work while a +baseline squaring (section \ref{sec:basesquare}) requires $O({{n^2 + n}\over 2})$ work. In standard big-Oh notation these +would both be said to be equivalent to $O(n^2)$. However, +in the context of the this text this is not the case as the magnitude of the inputs will typically be rather small. As a +result small constant factors in the work effort will make an observable difference in algorithm efficiency. + +All of the algorithms presented in this text have a polynomial time work level. That is, of the form +$O(n^k)$ for $n, k \in \Z^{+}$. This will help make useful comparisons in terms of the speed of the algorithms and how +various optimizations will help pay off in the long run. + +\section{Exercises} +Within the more advanced chapters a section will be set aside to give the reader some challenging exercises related to +the discussion at hand. These exercises are not designed to be prize winning problems, but instead to be thought +provoking. Wherever possible the problems are forward minded, stating problems that will be answered in subsequent +chapters. The reader is encouraged to finish the exercises as they appear to get a better understanding of the +subject material. + +That being said, the problems are designed to affirm knowledge of a particular subject matter. Students in particular +are encouraged to verify they can answer the problems correctly before moving on. + +Similar to the exercises of \cite[pp. ix]{TAOCPV2} these exercises are given a scoring system based on the difficulty of +the problem. However, unlike \cite{TAOCPV2} the problems do not get nearly as hard. The scoring of these +exercises ranges from one (the easiest) to five (the hardest). The following table sumarizes the +scoring system used. + +\begin{figure}[here] +\begin{center} +\begin{small} +\begin{tabular}{|c|l|} +\hline $\left [ 1 \right ]$ & An easy problem that should only take the reader a manner of \\ + & minutes to solve. Usually does not involve much computer time \\ + & to solve. \\ +\hline $\left [ 2 \right ]$ & An easy problem that involves a marginal amount of computer \\ + & time usage. Usually requires a program to be written to \\ + & solve the problem. \\ +\hline $\left [ 3 \right ]$ & A moderately hard problem that requires a non-trivial amount \\ + & of work. Usually involves trivial research and development of \\ + & new theory from the perspective of a student. \\ +\hline $\left [ 4 \right ]$ & A moderately hard problem that involves a non-trivial amount \\ + & of work and research, the solution to which will demonstrate \\ + & a higher mastery of the subject matter. \\ +\hline $\left [ 5 \right ]$ & A hard problem that involves concepts that are difficult for a \\ + & novice to solve. Solutions to these problems will demonstrate a \\ + & complete mastery of the given subject. \\ +\hline +\end{tabular} +\end{small} +\end{center} +\caption{Exercise Scoring System} +\end{figure} + +Problems at the first level are meant to be simple questions that the reader can answer quickly without programming a solution or +devising new theory. These problems are quick tests to see if the material is understood. Problems at the second level +are also designed to be easy but will require a program or algorithm to be implemented to arrive at the answer. These +two levels are essentially entry level questions. + +Problems at the third level are meant to be a bit more difficult than the first two levels. The answer is often +fairly obvious but arriving at an exacting solution requires some thought and skill. These problems will almost always +involve devising a new algorithm or implementing a variation of another algorithm previously presented. Readers who can +answer these questions will feel comfortable with the concepts behind the topic at hand. + +Problems at the fourth level are meant to be similar to those of the level three questions except they will require +additional research to be completed. The reader will most likely not know the answer right away, nor will the text provide +the exact details of the answer until a subsequent chapter. + +Problems at the fifth level are meant to be the hardest +problems relative to all the other problems in the chapter. People who can correctly answer fifth level problems have a +mastery of the subject matter at hand. + +Often problems will be tied together. The purpose of this is to start a chain of thought that will be discussed in future chapters. The reader +is encouraged to answer the follow-up problems and try to draw the relevance of problems. + +\section{Introduction to LibTomMath} + +\subsection{What is LibTomMath?} +LibTomMath is a free and open source multiple precision integer library written entirely in portable ISO C. By portable it +is meant that the library does not contain any code that is computer platform dependent or otherwise problematic to use on +any given platform. + +The library has been successfully tested under numerous operating systems including Unix\footnote{All of these +trademarks belong to their respective rightful owners.}, MacOS, Windows, Linux, PalmOS and on standalone hardware such +as the Gameboy Advance. The library is designed to contain enough functionality to be able to develop applications such +as public key cryptosystems and still maintain a relatively small footprint. + +\subsection{Goals of LibTomMath} + +Libraries which obtain the most efficiency are rarely written in a high level programming language such as C. However, +even though this library is written entirely in ISO C, considerable care has been taken to optimize the algorithm implementations within the +library. Specifically the code has been written to work well with the GNU C Compiler (\textit{GCC}) on both x86 and ARM +processors. Wherever possible, highly efficient algorithms, such as Karatsuba multiplication, sliding window +exponentiation and Montgomery reduction have been provided to make the library more efficient. + +Even with the nearly optimal and specialized algorithms that have been included the Application Programing Interface +(\textit{API}) has been kept as simple as possible. Often generic place holder routines will make use of specialized +algorithms automatically without the developer's specific attention. One such example is the generic multiplication +algorithm \textbf{mp\_mul()} which will automatically use Toom--Cook, Karatsuba, Comba or baseline multiplication +based on the magnitude of the inputs and the configuration of the library. + +Making LibTomMath as efficient as possible is not the only goal of the LibTomMath project. Ideally the library should +be source compatible with another popular library which makes it more attractive for developers to use. In this case the +MPI library was used as a API template for all the basic functions. MPI was chosen because it is another library that fits +in the same niche as LibTomMath. Even though LibTomMath uses MPI as the template for the function names and argument +passing conventions, it has been written from scratch by Tom St Denis. + +The project is also meant to act as a learning tool for students, the logic being that no easy-to-follow ``bignum'' +library exists which can be used to teach computer science students how to perform fast and reliable multiple precision +integer arithmetic. To this end the source code has been given quite a few comments and algorithm discussion points. + +\section{Choice of LibTomMath} +LibTomMath was chosen as the case study of this text not only because the author of both projects is one and the same but +for more worthy reasons. Other libraries such as GMP \cite{GMP}, MPI \cite{MPI}, LIP \cite{LIP} and OpenSSL +\cite{OPENSSL} have multiple precision integer arithmetic routines but would not be ideal for this text for +reasons that will be explained in the following sub-sections. + +\subsection{Code Base} +The LibTomMath code base is all portable ISO C source code. This means that there are no platform dependent conditional +segments of code littered throughout the source. This clean and uncluttered approach to the library means that a +developer can more readily discern the true intent of a given section of source code without trying to keep track of +what conditional code will be used. + +The code base of LibTomMath is well organized. Each function is in its own separate source code file +which allows the reader to find a given function very quickly. On average there are $76$ lines of code per source +file which makes the source very easily to follow. By comparison MPI and LIP are single file projects making code tracing +very hard. GMP has many conditional code segments which also hinder tracing. + +When compiled with GCC for the x86 processor and optimized for speed the entire library is approximately $100$KiB\footnote{The notation ``KiB'' means $2^{10}$ octets, similarly ``MiB'' means $2^{20}$ octets.} + which is fairly small compared to GMP (over $250$KiB). LibTomMath is slightly larger than MPI (which compiles to about +$50$KiB) but LibTomMath is also much faster and more complete than MPI. + +\subsection{API Simplicity} +LibTomMath is designed after the MPI library and shares the API design. Quite often programs that use MPI will build +with LibTomMath without change. The function names correlate directly to the action they perform. Almost all of the +functions share the same parameter passing convention. The learning curve is fairly shallow with the API provided +which is an extremely valuable benefit for the student and developer alike. + +The LIP library is an example of a library with an API that is awkward to work with. LIP uses function names that are often ``compressed'' to +illegible short hand. LibTomMath does not share this characteristic. + +The GMP library also does not return error codes. Instead it uses a POSIX.1 \cite{POSIX1} signal system where errors +are signaled to the host application. This happens to be the fastest approach but definitely not the most versatile. In +effect a math error (i.e. invalid input, heap error, etc) can cause a program to stop functioning which is definitely +undersireable in many situations. + +\subsection{Optimizations} +While LibTomMath is certainly not the fastest library (GMP often beats LibTomMath by a factor of two) it does +feature a set of optimal algorithms for tasks such as modular reduction, exponentiation, multiplication and squaring. GMP +and LIP also feature such optimizations while MPI only uses baseline algorithms with no optimizations. GMP lacks a few +of the additional modular reduction optimizations that LibTomMath features\footnote{At the time of this writing GMP +only had Barrett and Montgomery modular reduction algorithms.}. + +LibTomMath is almost always an order of magnitude faster than the MPI library at computationally expensive tasks such as modular +exponentiation. In the grand scheme of ``bignum'' libraries LibTomMath is faster than the average library and usually +slower than the best libraries such as GMP and OpenSSL by only a small factor. + +\subsection{Portability and Stability} +LibTomMath will build ``out of the box'' on any platform equipped with a modern version of the GNU C Compiler +(\textit{GCC}). This means that without changes the library will build without configuration or setting up any +variables. LIP and MPI will build ``out of the box'' as well but have numerous known bugs. Most notably the author of +MPI has recently stopped working on his library and LIP has long since been discontinued. + +GMP requires a configuration script to run and will not build out of the box. GMP and LibTomMath are still in active +development and are very stable across a variety of platforms. + +\subsection{Choice} +LibTomMath is a relatively compact, well documented, highly optimized and portable library which seems only natural for +the case study of this text. Various source files from the LibTomMath project will be included within the text. However, +the reader is encouraged to download their own copy of the library to actually be able to work with the library. + +\chapter{Getting Started} +\section{Library Basics} +The trick to writing any useful library of source code is to build a solid foundation and work outwards from it. First, +a problem along with allowable solution parameters should be identified and analyzed. In this particular case the +inability to accomodate multiple precision integers is the problem. Futhermore, the solution must be written +as portable source code that is reasonably efficient across several different computer platforms. + +After a foundation is formed the remainder of the library can be designed and implemented in a hierarchical fashion. +That is, to implement the lowest level dependencies first and work towards the most abstract functions last. For example, +before implementing a modular exponentiation algorithm one would implement a modular reduction algorithm. +By building outwards from a base foundation instead of using a parallel design methodology the resulting project is +highly modular. Being highly modular is a desirable property of any project as it often means the resulting product +has a small footprint and updates are easy to perform. + +Usually when I start a project I will begin with the header files. I define the data types I think I will need and +prototype the initial functions that are not dependent on other functions (within the library). After I +implement these base functions I prototype more dependent functions and implement them. The process repeats until +I implement all of the functions I require. For example, in the case of LibTomMath I implemented functions such as +mp\_init() well before I implemented mp\_mul() and even further before I implemented mp\_exptmod(). As an example as to +why this design works note that the Karatsuba and Toom-Cook multipliers were written \textit{after} the +dependent function mp\_exptmod() was written. Adding the new multiplication algorithms did not require changes to the +mp\_exptmod() function itself and lowered the total cost of ownership (\textit{so to speak}) and of development +for new algorithms. This methodology allows new algorithms to be tested in a complete framework with relative ease. + +FIGU,design_process,Design Flow of the First Few Original LibTomMath Functions. + +Only after the majority of the functions were in place did I pursue a less hierarchical approach to auditing and optimizing +the source code. For example, one day I may audit the multipliers and the next day the polynomial basis functions. + +It only makes sense to begin the text with the preliminary data types and support algorithms required as well. +This chapter discusses the core algorithms of the library which are the dependents for every other algorithm. + +\section{What is a Multiple Precision Integer?} +Recall that most programming languages, in particular ISO C \cite{ISOC}, only have fixed precision data types that on their own cannot +be used to represent values larger than their precision will allow. The purpose of multiple precision algorithms is +to use fixed precision data types to create and manipulate multiple precision integers which may represent values +that are very large. + +As a well known analogy, school children are taught how to form numbers larger than nine by prepending more radix ten digits. In the decimal system +the largest single digit value is $9$. However, by concatenating digits together larger numbers may be represented. Newly prepended digits +(\textit{to the left}) are said to be in a different power of ten column. That is, the number $123$ can be described as having a $1$ in the hundreds +column, $2$ in the tens column and $3$ in the ones column. Or more formally $123 = 1 \cdot 10^2 + 2 \cdot 10^1 + 3 \cdot 10^0$. Computer based +multiple precision arithmetic is essentially the same concept. Larger integers are represented by adjoining fixed +precision computer words with the exception that a different radix is used. + +What most people probably do not think about explicitly are the various other attributes that describe a multiple precision +integer. For example, the integer $154_{10}$ has two immediately obvious properties. First, the integer is positive, +that is the sign of this particular integer is positive as opposed to negative. Second, the integer has three digits in +its representation. There is an additional property that the integer posesses that does not concern pencil-and-paper +arithmetic. The third property is how many digits placeholders are available to hold the integer. + +The human analogy of this third property is ensuring there is enough space on the paper to write the integer. For example, +if one starts writing a large number too far to the right on a piece of paper they will have to erase it and move left. +Similarly, computer algorithms must maintain strict control over memory usage to ensure that the digits of an integer +will not exceed the allowed boundaries. These three properties make up what is known as a multiple precision +integer or mp\_int for short. + +\subsection{The mp\_int Structure} +\label{sec:MPINT} +The mp\_int structure is the ISO C based manifestation of what represents a multiple precision integer. The ISO C standard does not provide for +any such data type but it does provide for making composite data types known as structures. The following is the structure definition +used within LibTomMath. + +\index{mp\_int} +\begin{figure}[here] +\begin{center} +\begin{small} +%\begin{verbatim} +\begin{tabular}{|l|} +\hline +typedef struct \{ \\ +\hspace{3mm}int used, alloc, sign;\\ +\hspace{3mm}mp\_digit *dp;\\ +\} \textbf{mp\_int}; \\ +\hline +\end{tabular} +%\end{verbatim} +\end{small} +\caption{The mp\_int Structure} +\label{fig:mpint} +\end{center} +\end{figure} + +The mp\_int structure (fig. \ref{fig:mpint}) can be broken down as follows. + +\begin{enumerate} +\item The \textbf{used} parameter denotes how many digits of the array \textbf{dp} contain the digits used to represent +a given integer. The \textbf{used} count must be positive (or zero) and may not exceed the \textbf{alloc} count. + +\item The \textbf{alloc} parameter denotes how +many digits are available in the array to use by functions before it has to increase in size. When the \textbf{used} count +of a result would exceed the \textbf{alloc} count all of the algorithms will automatically increase the size of the +array to accommodate the precision of the result. + +\item The pointer \textbf{dp} points to a dynamically allocated array of digits that represent the given multiple +precision integer. It is padded with $(\textbf{alloc} - \textbf{used})$ zero digits. The array is maintained in a least +significant digit order. As a pencil and paper analogy the array is organized such that the right most digits are stored +first starting at the location indexed by zero\footnote{In C all arrays begin at zero.} in the array. For example, +if \textbf{dp} contains $\lbrace a, b, c, \ldots \rbrace$ where \textbf{dp}$_0 = a$, \textbf{dp}$_1 = b$, \textbf{dp}$_2 = c$, $\ldots$ then +it would represent the integer $a + b\beta + c\beta^2 + \ldots$ + +\index{MP\_ZPOS} \index{MP\_NEG} +\item The \textbf{sign} parameter denotes the sign as either zero/positive (\textbf{MP\_ZPOS}) or negative (\textbf{MP\_NEG}). +\end{enumerate} + +\subsubsection{Valid mp\_int Structures} +Several rules are placed on the state of an mp\_int structure and are assumed to be followed for reasons of efficiency. +The only exceptions are when the structure is passed to initialization functions such as mp\_init() and mp\_init\_copy(). + +\begin{enumerate} +\item The value of \textbf{alloc} may not be less than one. That is \textbf{dp} always points to a previously allocated +array of digits. +\item The value of \textbf{used} may not exceed \textbf{alloc} and must be greater than or equal to zero. +\item The value of \textbf{used} implies the digit at index $(used - 1)$ of the \textbf{dp} array is non-zero. That is, +leading zero digits in the most significant positions must be trimmed. + \begin{enumerate} + \item Digits in the \textbf{dp} array at and above the \textbf{used} location must be zero. + \end{enumerate} +\item The value of \textbf{sign} must be \textbf{MP\_ZPOS} if \textbf{used} is zero; +this represents the mp\_int value of zero. +\end{enumerate} + +\section{Argument Passing} +A convention of argument passing must be adopted early on in the development of any library. Making the function +prototypes consistent will help eliminate many headaches in the future as the library grows to significant complexity. +In LibTomMath the multiple precision integer functions accept parameters from left to right as pointers to mp\_int +structures. That means that the source (input) operands are placed on the left and the destination (output) on the right. +Consider the following examples. + +\begin{verbatim} + mp_mul(&a, &b, &c); /* c = a * b */ + mp_add(&a, &b, &a); /* a = a + b */ + mp_sqr(&a, &b); /* b = a * a */ +\end{verbatim} + +The left to right order is a fairly natural way to implement the functions since it lets the developer read aloud the +functions and make sense of them. For example, the first function would read ``multiply a and b and store in c''. + +Certain libraries (\textit{LIP by Lenstra for instance}) accept parameters the other way around, to mimic the order +of assignment expressions. That is, the destination (output) is on the left and arguments (inputs) are on the right. In +truth, it is entirely a matter of preference. In the case of LibTomMath the convention from the MPI library has been +adopted. + +Another very useful design consideration, provided for in LibTomMath, is whether to allow argument sources to also be a +destination. For example, the second example (\textit{mp\_add}) adds $a$ to $b$ and stores in $a$. This is an important +feature to implement since it allows the calling functions to cut down on the number of variables it must maintain. +However, to implement this feature specific care has to be given to ensure the destination is not modified before the +source is fully read. + +\section{Return Values} +A well implemented application, no matter what its purpose, should trap as many runtime errors as possible and return them +to the caller. By catching runtime errors a library can be guaranteed to prevent undefined behaviour. However, the end +developer can still manage to cause a library to crash. For example, by passing an invalid pointer an application may +fault by dereferencing memory not owned by the application. + +In the case of LibTomMath the only errors that are checked for are related to inappropriate inputs (division by zero for +instance) and memory allocation errors. It will not check that the mp\_int passed to any function is valid nor +will it check pointers for validity. Any function that can cause a runtime error will return an error code as an +\textbf{int} data type with one of the following values (fig \ref{fig:errcodes}). + +\index{MP\_OKAY} \index{MP\_VAL} \index{MP\_MEM} +\begin{figure}[here] +\begin{center} +\begin{tabular}{|l|l|} +\hline \textbf{Value} & \textbf{Meaning} \\ +\hline \textbf{MP\_OKAY} & The function was successful \\ +\hline \textbf{MP\_VAL} & One of the input value(s) was invalid \\ +\hline \textbf{MP\_MEM} & The function ran out of heap memory \\ +\hline +\end{tabular} +\end{center} +\caption{LibTomMath Error Codes} +\label{fig:errcodes} +\end{figure} + +When an error is detected within a function it should free any memory it allocated, often during the initialization of +temporary mp\_ints, and return as soon as possible. The goal is to leave the system in the same state it was when the +function was called. Error checking with this style of API is fairly simple. + +\begin{verbatim} + int err; + if ((err = mp_add(&a, &b, &c)) != MP_OKAY) { + printf("Error: %s\n", mp_error_to_string(err)); + exit(EXIT_FAILURE); + } +\end{verbatim} + +The GMP \cite{GMP} library uses C style \textit{signals} to flag errors which is of questionable use. Not all errors are fatal +and it was not deemed ideal by the author of LibTomMath to force developers to have signal handlers for such cases. + +\section{Initialization and Clearing} +The logical starting point when actually writing multiple precision integer functions is the initialization and +clearing of the mp\_int structures. These two algorithms will be used by the majority of the higher level algorithms. + +Given the basic mp\_int structure an initialization routine must first allocate memory to hold the digits of +the integer. Often it is optimal to allocate a sufficiently large pre-set number of digits even though +the initial integer will represent zero. If only a single digit were allocated quite a few subsequent re-allocations +would occur when operations are performed on the integers. There is a tradeoff between how many default digits to allocate +and how many re-allocations are tolerable. Obviously allocating an excessive amount of digits initially will waste +memory and become unmanageable. + +If the memory for the digits has been successfully allocated then the rest of the members of the structure must +be initialized. Since the initial state of an mp\_int is to represent the zero integer, the allocated digits must be set +to zero. The \textbf{used} count set to zero and \textbf{sign} set to \textbf{MP\_ZPOS}. + +\subsection{Initializing an mp\_int} +An mp\_int is said to be initialized if it is set to a valid, preferably default, state such that all of the members of the +structure are set to valid values. The mp\_init algorithm will perform such an action. + +\index{mp\_init} +\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_init}. \\ +\textbf{Input}. An mp\_int $a$ \\ +\textbf{Output}. Allocate memory and initialize $a$ to a known valid mp\_int state. \\ +\hline \\ +1. Allocate memory for \textbf{MP\_PREC} digits. \\ +2. If the allocation failed return(\textit{MP\_MEM}) \\ +3. for $n$ from $0$ to $MP\_PREC - 1$ do \\ +\hspace{3mm}3.1 $a_n \leftarrow 0$\\ +4. $a.sign \leftarrow MP\_ZPOS$\\ +5. $a.used \leftarrow 0$\\ +6. $a.alloc \leftarrow MP\_PREC$\\ +7. Return(\textit{MP\_OKAY})\\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_init} +\end{figure} + +\textbf{Algorithm mp\_init.} +The purpose of this function is to initialize an mp\_int structure so that the rest of the library can properly +manipulte it. It is assumed that the input may not have had any of its members previously initialized which is certainly +a valid assumption if the input resides on the stack. + +Before any of the members such as \textbf{sign}, \textbf{used} or \textbf{alloc} are initialized the memory for +the digits is allocated. If this fails the function returns before setting any of the other members. The \textbf{MP\_PREC} +name represents a constant\footnote{Defined in the ``tommath.h'' header file within LibTomMath.} +used to dictate the minimum precision of newly initialized mp\_int integers. Ideally, it is at least equal to the smallest +precision number you'll be working with. + +Allocating a block of digits at first instead of a single digit has the benefit of lowering the number of usually slow +heap operations later functions will have to perform in the future. If \textbf{MP\_PREC} is set correctly the slack +memory and the number of heap operations will be trivial. + +Once the allocation has been made the digits have to be set to zero as well as the \textbf{used}, \textbf{sign} and +\textbf{alloc} members initialized. This ensures that the mp\_int will always represent the default state of zero regardless +of the original condition of the input. + +\textbf{Remark.} +This function introduces the idiosyncrasy that all iterative loops, commonly initiated with the ``for'' keyword, iterate incrementally +when the ``to'' keyword is placed between two expressions. For example, ``for $a$ from $b$ to $c$ do'' means that +a subsequent expression (or body of expressions) are to be evaluated upto $c - b$ times so long as $b \le c$. In each +iteration the variable $a$ is substituted for a new integer that lies inclusively between $b$ and $c$. If $b > c$ occured +the loop would not iterate. By contrast if the ``downto'' keyword were used in place of ``to'' the loop would iterate +decrementally. + +EXAM,bn_mp_init.c + +One immediate observation of this initializtion function is that it does not return a pointer to a mp\_int structure. It +is assumed that the caller has already allocated memory for the mp\_int structure, typically on the application stack. The +call to mp\_init() is used only to initialize the members of the structure to a known default state. + +Here we see (line @23,XMALLOC@) the memory allocation is performed first. This allows us to exit cleanly and quickly +if there is an error. If the allocation fails the routine will return \textbf{MP\_MEM} to the caller to indicate there +was a memory error. The function XMALLOC is what actually allocates the memory. Technically XMALLOC is not a function +but a macro defined in ``tommath.h``. By default, XMALLOC will evaluate to malloc() which is the C library's built--in +memory allocation routine. + +In order to assure the mp\_int is in a known state the digits must be set to zero. On most platforms this could have been +accomplished by using calloc() instead of malloc(). However, to correctly initialize a integer type to a given value in a +portable fashion you have to actually assign the value. The for loop (line @28,for@) performs this required +operation. + +After the memory has been successfully initialized the remainder of the members are initialized +(lines @29,used@ through @31,sign@) to their respective default states. At this point the algorithm has succeeded and +a success code is returned to the calling function. If this function returns \textbf{MP\_OKAY} it is safe to assume the +mp\_int structure has been properly initialized and is safe to use with other functions within the library. + +\subsection{Clearing an mp\_int} +When an mp\_int is no longer required by the application, the memory that has been allocated for its digits must be +returned to the application's memory pool with the mp\_clear algorithm. + +\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_clear}. \\ +\textbf{Input}. An mp\_int $a$ \\ +\textbf{Output}. The memory for $a$ shall be deallocated. \\ +\hline \\ +1. If $a$ has been previously freed then return(\textit{MP\_OKAY}). \\ +2. for $n$ from 0 to $a.used - 1$ do \\ +\hspace{3mm}2.1 $a_n \leftarrow 0$ \\ +3. Free the memory allocated for the digits of $a$. \\ +4. $a.used \leftarrow 0$ \\ +5. $a.alloc \leftarrow 0$ \\ +6. $a.sign \leftarrow MP\_ZPOS$ \\ +7. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_clear} +\end{figure} + +\textbf{Algorithm mp\_clear.} +This algorithm accomplishes two goals. First, it clears the digits and the other mp\_int members. This ensures that +if a developer accidentally re-uses a cleared structure it is less likely to cause problems. The second goal +is to free the allocated memory. + +The logic behind the algorithm is extended by marking cleared mp\_int structures so that subsequent calls to this +algorithm will not try to free the memory multiple times. Cleared mp\_ints are detectable by having a pre-defined invalid +digit pointer \textbf{dp} setting. + +Once an mp\_int has been cleared the mp\_int structure is no longer in a valid state for any other algorithm +with the exception of algorithms mp\_init, mp\_init\_copy, mp\_init\_size and mp\_clear. + +EXAM,bn_mp_clear.c + +The algorithm only operates on the mp\_int if it hasn't been previously cleared. The if statement (line @23,a->dp != NULL@) +checks to see if the \textbf{dp} member is not \textbf{NULL}. If the mp\_int is a valid mp\_int then \textbf{dp} cannot be +\textbf{NULL} in which case the if statement will evaluate to true. + +The digits of the mp\_int are cleared by the for loop (line @25,for@) which assigns a zero to every digit. Similar to mp\_init() +the digits are assigned zero instead of using block memory operations (such as memset()) since this is more portable. + +The digits are deallocated off the heap via the XFREE macro. Similar to XMALLOC the XFREE macro actually evaluates to +a standard C library function. In this case the free() function. Since free() only deallocates the memory the pointer +still has to be reset to \textbf{NULL} manually (line @33,NULL@). + +Now that the digits have been cleared and deallocated the other members are set to their final values (lines @34,= 0@ and @35,ZPOS@). + +\section{Maintenance Algorithms} + +The previous sections describes how to initialize and clear an mp\_int structure. To further support operations +that are to be performed on mp\_int structures (such as addition and multiplication) the dependent algorithms must be +able to augment the precision of an mp\_int and +initialize mp\_ints with differing initial conditions. + +These algorithms complete the set of low level algorithms required to work with mp\_int structures in the higher level +algorithms such as addition, multiplication and modular exponentiation. + +\subsection{Augmenting an mp\_int's Precision} +When storing a value in an mp\_int structure, a sufficient number of digits must be available to accomodate the entire +result of an operation without loss of precision. Quite often the size of the array given by the \textbf{alloc} member +is large enough to simply increase the \textbf{used} digit count. However, when the size of the array is too small it +must be re-sized appropriately to accomodate the result. The mp\_grow algorithm will provide this functionality. + +\newpage\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_grow}. \\ +\textbf{Input}. An mp\_int $a$ and an integer $b$. \\ +\textbf{Output}. $a$ is expanded to accomodate $b$ digits. \\ +\hline \\ +1. if $a.alloc \ge b$ then return(\textit{MP\_OKAY}) \\ +2. $u \leftarrow b\mbox{ (mod }MP\_PREC\mbox{)}$ \\ +3. $v \leftarrow b + 2 \cdot MP\_PREC - u$ \\ +4. Re-allocate the array of digits $a$ to size $v$ \\ +5. If the allocation failed then return(\textit{MP\_MEM}). \\ +6. for n from a.alloc to $v - 1$ do \\ +\hspace{+3mm}6.1 $a_n \leftarrow 0$ \\ +7. $a.alloc \leftarrow v$ \\ +8. Return(\textit{MP\_OKAY}) \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_grow} +\end{figure} + +\textbf{Algorithm mp\_grow.} +It is ideal to prevent re-allocations from being performed if they are not required (step one). This is useful to +prevent mp\_ints from growing excessively in code that erroneously calls mp\_grow. + +The requested digit count is padded up to next multiple of \textbf{MP\_PREC} plus an additional \textbf{MP\_PREC} (steps two and three). +This helps prevent many trivial reallocations that would grow an mp\_int by trivially small values. + +It is assumed that the reallocation (step four) leaves the lower $a.alloc$ digits of the mp\_int intact. This is much +akin to how the \textit{realloc} function from the standard C library works. Since the newly allocated digits are +assumed to contain undefined values they are initially set to zero. + +EXAM,bn_mp_grow.c + +A quick optimization is to first determine if a memory re-allocation is required at all. The if statement (line @24,alloc@) checks +if the \textbf{alloc} member of the mp\_int is smaller than the requested digit count. If the count is not larger than \textbf{alloc} +the function skips the re-allocation part thus saving time. + +When a re-allocation is performed it is turned into an optimal request to save time in the future. The requested digit count is +padded upwards to 2nd multiple of \textbf{MP\_PREC} larger than \textbf{alloc} (line @25, size@). The XREALLOC function is used +to re-allocate the memory. As per the other functions XREALLOC is actually a macro which evaluates to realloc by default. The realloc +function leaves the base of the allocation intact which means the first \textbf{alloc} digits of the mp\_int are the same as before +the re-allocation. All that is left is to clear the newly allocated digits and return. + +Note that the re-allocation result is actually stored in a temporary pointer $tmp$. This is to allow this function to return +an error with a valid pointer. Earlier releases of the library stored the result of XREALLOC into the mp\_int $a$. That would +result in a memory leak if XREALLOC ever failed. + +\subsection{Initializing Variable Precision mp\_ints} +Occasionally the number of digits required will be known in advance of an initialization, based on, for example, the size +of input mp\_ints to a given algorithm. The purpose of algorithm mp\_init\_size is similar to mp\_init except that it +will allocate \textit{at least} a specified number of digits. + +\begin{figure}[here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_init\_size}. \\ +\textbf{Input}. An mp\_int $a$ and the requested number of digits $b$. \\ +\textbf{Output}. $a$ is initialized to hold at least $b$ digits. \\ +\hline \\ +1. $u \leftarrow b \mbox{ (mod }MP\_PREC\mbox{)}$ \\ +2. $v \leftarrow b + 2 \cdot MP\_PREC - u$ \\ +3. Allocate $v$ digits. \\ +4. for $n$ from $0$ to $v - 1$ do \\ +\hspace{3mm}4.1 $a_n \leftarrow 0$ \\ +5. $a.sign \leftarrow MP\_ZPOS$\\ +6. $a.used \leftarrow 0$\\ +7. $a.alloc \leftarrow v$\\ +8. Return(\textit{MP\_OKAY})\\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_init\_size} +\end{figure} + +\textbf{Algorithm mp\_init\_size.} +This algorithm will initialize an mp\_int structure $a$ like algorithm mp\_init with the exception that the number of +digits allocated can be controlled by the second input argument $b$. The input size is padded upwards so it is a +multiple of \textbf{MP\_PREC} plus an additional \textbf{MP\_PREC} digits. This padding is used to prevent trivial +allocations from becoming a bottleneck in the rest of the algorithms. + +Like algorithm mp\_init, the mp\_int structure is initialized to a default state representing the integer zero. This +particular algorithm is useful if it is known ahead of time the approximate size of the input. If the approximation is +correct no further memory re-allocations are required to work with the mp\_int. + +EXAM,bn_mp_init_size.c + +The number of digits $b$ requested is padded (line @22,MP_PREC@) by first augmenting it to the next multiple of +\textbf{MP\_PREC} and then adding \textbf{MP\_PREC} to the result. If the memory can be successfully allocated the +mp\_int is placed in a default state representing the integer zero. Otherwise, the error code \textbf{MP\_MEM} will be +returned (line @27,return@). + +The digits are allocated and set to zero at the same time with the calloc() function (line @25,XCALLOC@). The +\textbf{used} count is set to zero, the \textbf{alloc} count set to the padded digit count and the \textbf{sign} flag set +to \textbf{MP\_ZPOS} to achieve a default valid mp\_int state (lines @29,used@, @30,alloc@ and @31,sign@). If the function +returns succesfully then it is correct to assume that the mp\_int structure is in a valid state for the remainder of the +functions to work with. + +\subsection{Multiple Integer Initializations and Clearings} +Occasionally a function will require a series of mp\_int data types to be made available simultaneously. +The purpose of algorithm mp\_init\_multi is to initialize a variable length array of mp\_int structures in a single +statement. It is essentially a shortcut to multiple initializations. + +\newpage\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_init\_multi}. \\ +\textbf{Input}. Variable length array $V_k$ of mp\_int variables of length $k$. \\ +\textbf{Output}. The array is initialized such that each mp\_int of $V_k$ is ready to use. \\ +\hline \\ +1. for $n$ from 0 to $k - 1$ do \\ +\hspace{+3mm}1.1. Initialize the mp\_int $V_n$ (\textit{mp\_init}) \\ +\hspace{+3mm}1.2. If initialization failed then do \\ +\hspace{+6mm}1.2.1. for $j$ from $0$ to $n$ do \\ +\hspace{+9mm}1.2.1.1. Free the mp\_int $V_j$ (\textit{mp\_clear}) \\ +\hspace{+6mm}1.2.2. Return(\textit{MP\_MEM}) \\ +2. Return(\textit{MP\_OKAY}) \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_init\_multi} +\end{figure} + +\textbf{Algorithm mp\_init\_multi.} +The algorithm will initialize the array of mp\_int variables one at a time. If a runtime error has been detected +(\textit{step 1.2}) all of the previously initialized variables are cleared. The goal is an ``all or nothing'' +initialization which allows for quick recovery from runtime errors. + +EXAM,bn_mp_init_multi.c + +This function intializes a variable length list of mp\_int structure pointers. However, instead of having the mp\_int +structures in an actual C array they are simply passed as arguments to the function. This function makes use of the +``...'' argument syntax of the C programming language. The list is terminated with a final \textbf{NULL} argument +appended on the right. + +The function uses the ``stdarg.h'' \textit{va} functions to step portably through the arguments to the function. A count +$n$ of succesfully initialized mp\_int structures is maintained (line @47,n++@) such that if a failure does occur, +the algorithm can backtrack and free the previously initialized structures (lines @27,if@ to @46,}@). + + +\subsection{Clamping Excess Digits} +When a function anticipates a result will be $n$ digits it is simpler to assume this is true within the body of +the function instead of checking during the computation. For example, a multiplication of a $i$ digit number by a +$j$ digit produces a result of at most $i + j$ digits. It is entirely possible that the result is $i + j - 1$ +though, with no final carry into the last position. However, suppose the destination had to be first expanded +(\textit{via mp\_grow}) to accomodate $i + j - 1$ digits than further expanded to accomodate the final carry. +That would be a considerable waste of time since heap operations are relatively slow. + +The ideal solution is to always assume the result is $i + j$ and fix up the \textbf{used} count after the function +terminates. This way a single heap operation (\textit{at most}) is required. However, if the result was not checked +there would be an excess high order zero digit. + +For example, suppose the product of two integers was $x_n = (0x_{n-1}x_{n-2}...x_0)_{\beta}$. The leading zero digit +will not contribute to the precision of the result. In fact, through subsequent operations more leading zero digits would +accumulate to the point the size of the integer would be prohibitive. As a result even though the precision is very +low the representation is excessively large. + +The mp\_clamp algorithm is designed to solve this very problem. It will trim high-order zeros by decrementing the +\textbf{used} count until a non-zero most significant digit is found. Also in this system, zero is considered to be a +positive number which means that if the \textbf{used} count is decremented to zero, the sign must be set to +\textbf{MP\_ZPOS}. + +\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_clamp}. \\ +\textbf{Input}. An mp\_int $a$ \\ +\textbf{Output}. Any excess leading zero digits of $a$ are removed \\ +\hline \\ +1. while $a.used > 0$ and $a_{a.used - 1} = 0$ do \\ +\hspace{+3mm}1.1 $a.used \leftarrow a.used - 1$ \\ +2. if $a.used = 0$ then do \\ +\hspace{+3mm}2.1 $a.sign \leftarrow MP\_ZPOS$ \\ +\hline \\ +\end{tabular} +\end{center} +\caption{Algorithm mp\_clamp} +\end{figure} + +\textbf{Algorithm mp\_clamp.} +As can be expected this algorithm is very simple. The loop on step one is expected to iterate only once or twice at +the most. For example, this will happen in cases where there is not a carry to fill the last position. Step two fixes the sign for +when all of the digits are zero to ensure that the mp\_int is valid at all times. + +EXAM,bn_mp_clamp.c + +Note on line @27,while@ how to test for the \textbf{used} count is made on the left of the \&\& operator. In the C programming +language the terms to \&\& are evaluated left to right with a boolean short-circuit if any condition fails. This is +important since if the \textbf{used} is zero the test on the right would fetch below the array. That is obviously +undesirable. The parenthesis on line @28,a->used@ is used to make sure the \textbf{used} count is decremented and not +the pointer ``a''. + +\section*{Exercises} +\begin{tabular}{cl} +$\left [ 1 \right ]$ & Discuss the relevance of the \textbf{used} member of the mp\_int structure. \\ + & \\ +$\left [ 1 \right ]$ & Discuss the consequences of not using padding when performing allocations. \\ + & \\ +$\left [ 2 \right ]$ & Estimate an ideal value for \textbf{MP\_PREC} when performing 1024-bit RSA \\ + & encryption when $\beta = 2^{28}$. \\ + & \\ +$\left [ 1 \right ]$ & Discuss the relevance of the algorithm mp\_clamp. What does it prevent? \\ + & \\ +$\left [ 1 \right ]$ & Give an example of when the algorithm mp\_init\_copy might be useful. \\ + & \\ +\end{tabular} + + +%%% +% CHAPTER FOUR +%%% + +\chapter{Basic Operations} + +\section{Introduction} +In the previous chapter a series of low level algorithms were established that dealt with initializing and maintaining +mp\_int structures. This chapter will discuss another set of seemingly non-algebraic algorithms which will form the low +level basis of the entire library. While these algorithm are relatively trivial it is important to understand how they +work before proceeding since these algorithms will be used almost intrinsically in the following chapters. + +The algorithms in this chapter deal primarily with more ``programmer'' related tasks such as creating copies of +mp\_int structures, assigning small values to mp\_int structures and comparisons of the values mp\_int structures +represent. + +\section{Assigning Values to mp\_int Structures} +\subsection{Copying an mp\_int} +Assigning the value that a given mp\_int structure represents to another mp\_int structure shall be known as making +a copy for the purposes of this text. The copy of the mp\_int will be a separate entity that represents the same +value as the mp\_int it was copied from. The mp\_copy algorithm provides this functionality. + +\newpage\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_copy}. \\ +\textbf{Input}. An mp\_int $a$ and $b$. \\ +\textbf{Output}. Store a copy of $a$ in $b$. \\ +\hline \\ +1. If $b.alloc < a.used$ then grow $b$ to $a.used$ digits. (\textit{mp\_grow}) \\ +2. for $n$ from 0 to $a.used - 1$ do \\ +\hspace{3mm}2.1 $b_{n} \leftarrow a_{n}$ \\ +3. for $n$ from $a.used$ to $b.used - 1$ do \\ +\hspace{3mm}3.1 $b_{n} \leftarrow 0$ \\ +4. $b.used \leftarrow a.used$ \\ +5. $b.sign \leftarrow a.sign$ \\ +6. return(\textit{MP\_OKAY}) \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_copy} +\end{figure} + +\textbf{Algorithm mp\_copy.} +This algorithm copies the mp\_int $a$ such that upon succesful termination of the algorithm the mp\_int $b$ will +represent the same integer as the mp\_int $a$. The mp\_int $b$ shall be a complete and distinct copy of the +mp\_int $a$ meaing that the mp\_int $a$ can be modified and it shall not affect the value of the mp\_int $b$. + +If $b$ does not have enough room for the digits of $a$ it must first have its precision augmented via the mp\_grow +algorithm. The digits of $a$ are copied over the digits of $b$ and any excess digits of $b$ are set to zero (step two +and three). The \textbf{used} and \textbf{sign} members of $a$ are finally copied over the respective members of +$b$. + +\textbf{Remark.} This algorithm also introduces a new idiosyncrasy that will be used throughout the rest of the +text. The error return codes of other algorithms are not explicitly checked in the pseudo-code presented. For example, in +step one of the mp\_copy algorithm the return of mp\_grow is not explicitly checked to ensure it succeeded. Text space is +limited so it is assumed that if a algorithm fails it will clear all temporarily allocated mp\_ints and return +the error code itself. However, the C code presented will demonstrate all of the error handling logic required to +implement the pseudo-code. + +EXAM,bn_mp_copy.c + +Occasionally a dependent algorithm may copy an mp\_int effectively into itself such as when the input and output +mp\_int structures passed to a function are one and the same. For this case it is optimal to return immediately without +copying digits (line @24,a == b@). + +The mp\_int $b$ must have enough digits to accomodate the used digits of the mp\_int $a$. If $b.alloc$ is less than +$a.used$ the algorithm mp\_grow is used to augment the precision of $b$ (lines @29,alloc@ to @33,}@). In order to +simplify the inner loop that copies the digits from $a$ to $b$, two aliases $tmpa$ and $tmpb$ point directly at the digits +of the mp\_ints $a$ and $b$ respectively. These aliases (lines @42,tmpa@ and @45,tmpb@) allow the compiler to access the digits without first dereferencing the +mp\_int pointers and then subsequently the pointer to the digits. + +After the aliases are established the digits from $a$ are copied into $b$ (lines @48,for@ to @50,}@) and then the excess +digits of $b$ are set to zero (lines @53,for@ to @55,}@). Both ``for'' loops make use of the pointer aliases and in +fact the alias for $b$ is carried through into the second ``for'' loop to clear the excess digits. This optimization +allows the alias to stay in a machine register fairly easy between the two loops. + +\textbf{Remarks.} The use of pointer aliases is an implementation methodology first introduced in this function that will +be used considerably in other functions. Technically, a pointer alias is simply a short hand alias used to lower the +number of pointer dereferencing operations required to access data. For example, a for loop may resemble + +\begin{alltt} +for (x = 0; x < 100; x++) \{ + a->num[4]->dp[x] = 0; +\} +\end{alltt} + +This could be re-written using aliases as + +\begin{alltt} +mp_digit *tmpa; +a = a->num[4]->dp; +for (x = 0; x < 100; x++) \{ + *a++ = 0; +\} +\end{alltt} + +In this case an alias is used to access the +array of digits within an mp\_int structure directly. It may seem that a pointer alias is strictly not required +as a compiler may optimize out the redundant pointer operations. However, there are two dominant reasons to use aliases. + +The first reason is that most compilers will not effectively optimize pointer arithmetic. For example, some optimizations +may work for the Microsoft Visual C++ compiler (MSVC) and not for the GNU C Compiler (GCC). Also some optimizations may +work for GCC and not MSVC. As such it is ideal to find a common ground for as many compilers as possible. Pointer +aliases optimize the code considerably before the compiler even reads the source code which means the end compiled code +stands a better chance of being faster. + +The second reason is that pointer aliases often can make an algorithm simpler to read. Consider the first ``for'' +loop of the function mp\_copy() re-written to not use pointer aliases. + +\begin{alltt} + /* copy all the digits */ + for (n = 0; n < a->used; n++) \{ + b->dp[n] = a->dp[n]; + \} +\end{alltt} + +Whether this code is harder to read depends strongly on the individual. However, it is quantifiably slightly more +complicated as there are four variables within the statement instead of just two. + +\subsubsection{Nested Statements} +Another commonly used technique in the source routines is that certain sections of code are nested. This is used in +particular with the pointer aliases to highlight code phases. For example, a Comba multiplier (discussed in chapter six) +will typically have three different phases. First the temporaries are initialized, then the columns calculated and +finally the carries are propagated. In this example the middle column production phase will typically be nested as it +uses temporary variables and aliases the most. + +The nesting also simplies the source code as variables that are nested are only valid for their scope. As a result +the various temporary variables required do not propagate into other sections of code. + + +\subsection{Creating a Clone} +Another common operation is to make a local temporary copy of an mp\_int argument. To initialize an mp\_int +and then copy another existing mp\_int into the newly intialized mp\_int will be known as creating a clone. This is +useful within functions that need to modify an argument but do not wish to actually modify the original copy. The +mp\_init\_copy algorithm has been designed to help perform this task. + +\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_init\_copy}. \\ +\textbf{Input}. An mp\_int $a$ and $b$\\ +\textbf{Output}. $a$ is initialized to be a copy of $b$. \\ +\hline \\ +1. Init $a$. (\textit{mp\_init}) \\ +2. Copy $b$ to $a$. (\textit{mp\_copy}) \\ +3. Return the status of the copy operation. \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_init\_copy} +\end{figure} + +\textbf{Algorithm mp\_init\_copy.} +This algorithm will initialize an mp\_int variable and copy another previously initialized mp\_int variable into it. As +such this algorithm will perform two operations in one step. + +EXAM,bn_mp_init_copy.c + +This will initialize \textbf{a} and make it a verbatim copy of the contents of \textbf{b}. Note that +\textbf{a} will have its own memory allocated which means that \textbf{b} may be cleared after the call +and \textbf{a} will be left intact. + +\section{Zeroing an Integer} +Reseting an mp\_int to the default state is a common step in many algorithms. The mp\_zero algorithm will be the algorithm used to +perform this task. + +\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_zero}. \\ +\textbf{Input}. An mp\_int $a$ \\ +\textbf{Output}. Zero the contents of $a$ \\ +\hline \\ +1. $a.used \leftarrow 0$ \\ +2. $a.sign \leftarrow$ MP\_ZPOS \\ +3. for $n$ from 0 to $a.alloc - 1$ do \\ +\hspace{3mm}3.1 $a_n \leftarrow 0$ \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_zero} +\end{figure} + +\textbf{Algorithm mp\_zero.} +This algorithm simply resets a mp\_int to the default state. + +EXAM,bn_mp_zero.c + +After the function is completed, all of the digits are zeroed, the \textbf{used} count is zeroed and the +\textbf{sign} variable is set to \textbf{MP\_ZPOS}. + +\section{Sign Manipulation} +\subsection{Absolute Value} +With the mp\_int representation of an integer, calculating the absolute value is trivial. The mp\_abs algorithm will compute +the absolute value of an mp\_int. + +\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_abs}. \\ +\textbf{Input}. An mp\_int $a$ \\ +\textbf{Output}. Computes $b = \vert a \vert$ \\ +\hline \\ +1. Copy $a$ to $b$. (\textit{mp\_copy}) \\ +2. If the copy failed return(\textit{MP\_MEM}). \\ +3. $b.sign \leftarrow MP\_ZPOS$ \\ +4. Return(\textit{MP\_OKAY}) \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_abs} +\end{figure} + +\textbf{Algorithm mp\_abs.} +This algorithm computes the absolute of an mp\_int input. First it copies $a$ over $b$. This is an example of an +algorithm where the check in mp\_copy that determines if the source and destination are equal proves useful. This allows, +for instance, the developer to pass the same mp\_int as the source and destination to this function without addition +logic to handle it. + +EXAM,bn_mp_abs.c + +This fairly trivial algorithm first eliminates non--required duplications (line @27,a != b@) and then sets the +\textbf{sign} flag to \textbf{MP\_ZPOS}. + +\subsection{Integer Negation} +With the mp\_int representation of an integer, calculating the negation is also trivial. The mp\_neg algorithm will compute +the negative of an mp\_int input. + +\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_neg}. \\ +\textbf{Input}. An mp\_int $a$ \\ +\textbf{Output}. Computes $b = -a$ \\ +\hline \\ +1. Copy $a$ to $b$. (\textit{mp\_copy}) \\ +2. If the copy failed return(\textit{MP\_MEM}). \\ +3. If $a.used = 0$ then return(\textit{MP\_OKAY}). \\ +4. If $a.sign = MP\_ZPOS$ then do \\ +\hspace{3mm}4.1 $b.sign = MP\_NEG$. \\ +5. else do \\ +\hspace{3mm}5.1 $b.sign = MP\_ZPOS$. \\ +6. Return(\textit{MP\_OKAY}) \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_neg} +\end{figure} + +\textbf{Algorithm mp\_neg.} +This algorithm computes the negation of an input. First it copies $a$ over $b$. If $a$ has no used digits then +the algorithm returns immediately. Otherwise it flips the sign flag and stores the result in $b$. Note that if +$a$ had no digits then it must be positive by definition. Had step three been omitted then the algorithm would return +zero as negative. + +EXAM,bn_mp_neg.c + +Like mp\_abs() this function avoids non--required duplications (line @21,a != b@) and then sets the sign. We +have to make sure that only non--zero values get a \textbf{sign} of \textbf{MP\_NEG}. If the mp\_int is zero +than the \textbf{sign} is hard--coded to \textbf{MP\_ZPOS}. + +\section{Small Constants} +\subsection{Setting Small Constants} +Often a mp\_int must be set to a relatively small value such as $1$ or $2$. For these cases the mp\_set algorithm is useful. + +\newpage\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_set}. \\ +\textbf{Input}. An mp\_int $a$ and a digit $b$ \\ +\textbf{Output}. Make $a$ equivalent to $b$ \\ +\hline \\ +1. Zero $a$ (\textit{mp\_zero}). \\ +2. $a_0 \leftarrow b \mbox{ (mod }\beta\mbox{)}$ \\ +3. $a.used \leftarrow \left \lbrace \begin{array}{ll} + 1 & \mbox{if }a_0 > 0 \\ + 0 & \mbox{if }a_0 = 0 + \end{array} \right .$ \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_set} +\end{figure} + +\textbf{Algorithm mp\_set.} +This algorithm sets a mp\_int to a small single digit value. Step number 1 ensures that the integer is reset to the default state. The +single digit is set (\textit{modulo $\beta$}) and the \textbf{used} count is adjusted accordingly. + +EXAM,bn_mp_set.c + +First we zero (line @21,mp_zero@) the mp\_int to make sure that the other members are initialized for a +small positive constant. mp\_zero() ensures that the \textbf{sign} is positive and the \textbf{used} count +is zero. Next we set the digit and reduce it modulo $\beta$ (line @22,MP_MASK@). After this step we have to +check if the resulting digit is zero or not. If it is not then we set the \textbf{used} count to one, otherwise +to zero. + +We can quickly reduce modulo $\beta$ since it is of the form $2^k$ and a quick binary AND operation with +$2^k - 1$ will perform the same operation. + +One important limitation of this function is that it will only set one digit. The size of a digit is not fixed, meaning source that uses +this function should take that into account. Only trivially small constants can be set using this function. + +\subsection{Setting Large Constants} +To overcome the limitations of the mp\_set algorithm the mp\_set\_int algorithm is ideal. It accepts a ``long'' +data type as input and will always treat it as a 32-bit integer. + +\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_set\_int}. \\ +\textbf{Input}. An mp\_int $a$ and a ``long'' integer $b$ \\ +\textbf{Output}. Make $a$ equivalent to $b$ \\ +\hline \\ +1. Zero $a$ (\textit{mp\_zero}) \\ +2. for $n$ from 0 to 7 do \\ +\hspace{3mm}2.1 $a \leftarrow a \cdot 16$ (\textit{mp\_mul2d}) \\ +\hspace{3mm}2.2 $u \leftarrow \lfloor b / 2^{4(7 - n)} \rfloor \mbox{ (mod }16\mbox{)}$\\ +\hspace{3mm}2.3 $a_0 \leftarrow a_0 + u$ \\ +\hspace{3mm}2.4 $a.used \leftarrow a.used + 1$ \\ +3. Clamp excess used digits (\textit{mp\_clamp}) \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_set\_int} +\end{figure} + +\textbf{Algorithm mp\_set\_int.} +The algorithm performs eight iterations of a simple loop where in each iteration four bits from the source are added to the +mp\_int. Step 2.1 will multiply the current result by sixteen making room for four more bits in the less significant positions. In step 2.2 the +next four bits from the source are extracted and are added to the mp\_int. The \textbf{used} digit count is +incremented to reflect the addition. The \textbf{used} digit counter is incremented since if any of the leading digits were zero the mp\_int would have +zero digits used and the newly added four bits would be ignored. + +Excess zero digits are trimmed in steps 2.1 and 3 by using higher level algorithms mp\_mul2d and mp\_clamp. + +EXAM,bn_mp_set_int.c + +This function sets four bits of the number at a time to handle all practical \textbf{DIGIT\_BIT} sizes. The weird +addition on line @38,a->used@ ensures that the newly added in bits are added to the number of digits. While it may not +seem obvious as to why the digit counter does not grow exceedingly large it is because of the shift on line @27,mp_mul_2d@ +as well as the call to mp\_clamp() on line @40,mp_clamp@. Both functions will clamp excess leading digits which keeps +the number of used digits low. + +\section{Comparisons} +\subsection{Unsigned Comparisions} +Comparing a multiple precision integer is performed with the exact same algorithm used to compare two decimal numbers. For example, +to compare $1,234$ to $1,264$ the digits are extracted by their positions. That is we compare $1 \cdot 10^3 + 2 \cdot 10^2 + 3 \cdot 10^1 + 4 \cdot 10^0$ +to $1 \cdot 10^3 + 2 \cdot 10^2 + 6 \cdot 10^1 + 4 \cdot 10^0$ by comparing single digits at a time starting with the highest magnitude +positions. If any leading digit of one integer is greater than a digit in the same position of another integer then obviously it must be greater. + +The first comparision routine that will be developed is the unsigned magnitude compare which will perform a comparison based on the digits of two +mp\_int variables alone. It will ignore the sign of the two inputs. Such a function is useful when an absolute comparison is required or if the +signs are known to agree in advance. + +To facilitate working with the results of the comparison functions three constants are required. + +\begin{figure}[here] +\begin{center} +\begin{tabular}{|r|l|} +\hline \textbf{Constant} & \textbf{Meaning} \\ +\hline \textbf{MP\_GT} & Greater Than \\ +\hline \textbf{MP\_EQ} & Equal To \\ +\hline \textbf{MP\_LT} & Less Than \\ +\hline +\end{tabular} +\end{center} +\caption{Comparison Return Codes} +\end{figure} + +\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_cmp\_mag}. \\ +\textbf{Input}. Two mp\_ints $a$ and $b$. \\ +\textbf{Output}. Unsigned comparison results ($a$ to the left of $b$). \\ +\hline \\ +1. If $a.used > b.used$ then return(\textit{MP\_GT}) \\ +2. If $a.used < b.used$ then return(\textit{MP\_LT}) \\ +3. for n from $a.used - 1$ to 0 do \\ +\hspace{+3mm}3.1 if $a_n > b_n$ then return(\textit{MP\_GT}) \\ +\hspace{+3mm}3.2 if $a_n < b_n$ then return(\textit{MP\_LT}) \\ +4. Return(\textit{MP\_EQ}) \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_cmp\_mag} +\end{figure} + +\textbf{Algorithm mp\_cmp\_mag.} +By saying ``$a$ to the left of $b$'' it is meant that the comparison is with respect to $a$, that is if $a$ is greater than $b$ it will return +\textbf{MP\_GT} and similar with respect to when $a = b$ and $a < b$. The first two steps compare the number of digits used in both $a$ and $b$. +Obviously if the digit counts differ there would be an imaginary zero digit in the smaller number where the leading digit of the larger number is. +If both have the same number of digits than the actual digits themselves must be compared starting at the leading digit. + +By step three both inputs must have the same number of digits so its safe to start from either $a.used - 1$ or $b.used - 1$ and count down to +the zero'th digit. If after all of the digits have been compared, no difference is found, the algorithm returns \textbf{MP\_EQ}. + +EXAM,bn_mp_cmp_mag.c + +The two if statements (lines @24,if@ and @28,if@) compare the number of digits in the two inputs. These two are +performed before all of the digits are compared since it is a very cheap test to perform and can potentially save +considerable time. The implementation given is also not valid without those two statements. $b.alloc$ may be +smaller than $a.used$, meaning that undefined values will be read from $b$ past the end of the array of digits. + + + +\subsection{Signed Comparisons} +Comparing with sign considerations is also fairly critical in several routines (\textit{division for example}). Based on an unsigned magnitude +comparison a trivial signed comparison algorithm can be written. + +\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_cmp}. \\ +\textbf{Input}. Two mp\_ints $a$ and $b$ \\ +\textbf{Output}. Signed Comparison Results ($a$ to the left of $b$) \\ +\hline \\ +1. if $a.sign = MP\_NEG$ and $b.sign = MP\_ZPOS$ then return(\textit{MP\_LT}) \\ +2. if $a.sign = MP\_ZPOS$ and $b.sign = MP\_NEG$ then return(\textit{MP\_GT}) \\ +3. if $a.sign = MP\_NEG$ then \\ +\hspace{+3mm}3.1 Return the unsigned comparison of $b$ and $a$ (\textit{mp\_cmp\_mag}) \\ +4 Otherwise \\ +\hspace{+3mm}4.1 Return the unsigned comparison of $a$ and $b$ \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_cmp} +\end{figure} + +\textbf{Algorithm mp\_cmp.} +The first two steps compare the signs of the two inputs. If the signs do not agree then it can return right away with the appropriate +comparison code. When the signs are equal the digits of the inputs must be compared to determine the correct result. In step +three the unsigned comparision flips the order of the arguments since they are both negative. For instance, if $-a > -b$ then +$\vert a \vert < \vert b \vert$. Step number four will compare the two when they are both positive. + +EXAM,bn_mp_cmp.c + +The two if statements (lines @22,if@ and @26,if@) perform the initial sign comparison. If the signs are not the equal then which ever +has the positive sign is larger. The inputs are compared (line @30,if@) based on magnitudes. If the signs were both +negative then the unsigned comparison is performed in the opposite direction (line @31,mp_cmp_mag@). Otherwise, the signs are assumed to +be both positive and a forward direction unsigned comparison is performed. + +\section*{Exercises} +\begin{tabular}{cl} +$\left [ 2 \right ]$ & Modify algorithm mp\_set\_int to accept as input a variable length array of bits. \\ + & \\ +$\left [ 3 \right ]$ & Give the probability that algorithm mp\_cmp\_mag will have to compare $k$ digits \\ + & of two random digits (of equal magnitude) before a difference is found. \\ + & \\ +$\left [ 1 \right ]$ & Suggest a simple method to speed up the implementation of mp\_cmp\_mag based \\ + & on the observations made in the previous problem. \\ + & +\end{tabular} + +\chapter{Basic Arithmetic} +\section{Introduction} +At this point algorithms for initialization, clearing, zeroing, copying, comparing and setting small constants have been +established. The next logical set of algorithms to develop are addition, subtraction and digit shifting algorithms. These +algorithms make use of the lower level algorithms and are the cruicial building block for the multiplication algorithms. It is very important +that these algorithms are highly optimized. On their own they are simple $O(n)$ algorithms but they can be called from higher level algorithms +which easily places them at $O(n^2)$ or even $O(n^3)$ work levels. + +MARK,SHIFTS +All of the algorithms within this chapter make use of the logical bit shift operations denoted by $<<$ and $>>$ for left and right +logical shifts respectively. A logical shift is analogous to sliding the decimal point of radix-10 representations. For example, the real +number $0.9345$ is equivalent to $93.45\%$ which is found by sliding the the decimal two places to the right (\textit{multiplying by $\beta^2 = 10^2$}). +Algebraically a binary logical shift is equivalent to a division or multiplication by a power of two. +For example, $a << k = a \cdot 2^k$ while $a >> k = \lfloor a/2^k \rfloor$. + +One significant difference between a logical shift and the way decimals are shifted is that digits below the zero'th position are removed +from the number. For example, consider $1101_2 >> 1$ using decimal notation this would produce $110.1_2$. However, with a logical shift the +result is $110_2$. + +\section{Addition and Subtraction} +In common twos complement fixed precision arithmetic negative numbers are easily represented by subtraction from the modulus. For example, with 32-bit integers +$a - b\mbox{ (mod }2^{32}\mbox{)}$ is the same as $a + (2^{32} - b) \mbox{ (mod }2^{32}\mbox{)}$ since $2^{32} \equiv 0 \mbox{ (mod }2^{32}\mbox{)}$. +As a result subtraction can be performed with a trivial series of logical operations and an addition. + +However, in multiple precision arithmetic negative numbers are not represented in the same way. Instead a sign flag is used to keep track of the +sign of the integer. As a result signed addition and subtraction are actually implemented as conditional usage of lower level addition or +subtraction algorithms with the sign fixed up appropriately. + +The lower level algorithms will add or subtract integers without regard to the sign flag. That is they will add or subtract the magnitude of +the integers respectively. + +\subsection{Low Level Addition} +An unsigned addition of multiple precision integers is performed with the same long-hand algorithm used to add decimal numbers. That is to add the +trailing digits first and propagate the resulting carry upwards. Since this is a lower level algorithm the name will have a ``s\_'' prefix. +Historically that convention stems from the MPI library where ``s\_'' stood for static functions that were hidden from the developer entirely. + +\newpage +\begin{figure}[!here] +\begin{center} +\begin{small} +\begin{tabular}{l} +\hline Algorithm \textbf{s\_mp\_add}. \\ +\textbf{Input}. Two mp\_ints $a$ and $b$ \\ +\textbf{Output}. The unsigned addition $c = \vert a \vert + \vert b \vert$. \\ +\hline \\ +1. if $a.used > b.used$ then \\ +\hspace{+3mm}1.1 $min \leftarrow b.used$ \\ +\hspace{+3mm}1.2 $max \leftarrow a.used$ \\ +\hspace{+3mm}1.3 $x \leftarrow a$ \\ +2. else \\ +\hspace{+3mm}2.1 $min \leftarrow a.used$ \\ +\hspace{+3mm}2.2 $max \leftarrow b.used$ \\ +\hspace{+3mm}2.3 $x \leftarrow b$ \\ +3. If $c.alloc < max + 1$ then grow $c$ to hold at least $max + 1$ digits (\textit{mp\_grow}) \\ +4. $oldused \leftarrow c.used$ \\ +5. $c.used \leftarrow max + 1$ \\ +6. $u \leftarrow 0$ \\ +7. for $n$ from $0$ to $min - 1$ do \\ +\hspace{+3mm}7.1 $c_n \leftarrow a_n + b_n + u$ \\ +\hspace{+3mm}7.2 $u \leftarrow c_n >> lg(\beta)$ \\ +\hspace{+3mm}7.3 $c_n \leftarrow c_n \mbox{ (mod }\beta\mbox{)}$ \\ +8. if $min \ne max$ then do \\ +\hspace{+3mm}8.1 for $n$ from $min$ to $max - 1$ do \\ +\hspace{+6mm}8.1.1 $c_n \leftarrow x_n + u$ \\ +\hspace{+6mm}8.1.2 $u \leftarrow c_n >> lg(\beta)$ \\ +\hspace{+6mm}8.1.3 $c_n \leftarrow c_n \mbox{ (mod }\beta\mbox{)}$ \\ +9. $c_{max} \leftarrow u$ \\ +10. if $olduse > max$ then \\ +\hspace{+3mm}10.1 for $n$ from $max + 1$ to $oldused - 1$ do \\ +\hspace{+6mm}10.1.1 $c_n \leftarrow 0$ \\ +11. Clamp excess digits in $c$. (\textit{mp\_clamp}) \\ +12. Return(\textit{MP\_OKAY}) \\ +\hline +\end{tabular} +\end{small} +\end{center} +\caption{Algorithm s\_mp\_add} +\end{figure} + +\textbf{Algorithm s\_mp\_add.} +This algorithm is loosely based on algorithm 14.7 of HAC \cite[pp. 594]{HAC} but has been extended to allow the inputs to have different magnitudes. +Coincidentally the description of algorithm A in Knuth \cite[pp. 266]{TAOCPV2} shares the same deficiency as the algorithm from \cite{HAC}. Even the +MIX pseudo machine code presented by Knuth \cite[pp. 266-267]{TAOCPV2} is incapable of handling inputs which are of different magnitudes. + +The first thing that has to be accomplished is to sort out which of the two inputs is the largest. The addition logic +will simply add all of the smallest input to the largest input and store that first part of the result in the +destination. Then it will apply a simpler addition loop to excess digits of the larger input. + +The first two steps will handle sorting the inputs such that $min$ and $max$ hold the digit counts of the two +inputs. The variable $x$ will be an mp\_int alias for the largest input or the second input $b$ if they have the +same number of digits. After the inputs are sorted the destination $c$ is grown as required to accomodate the sum +of the two inputs. The original \textbf{used} count of $c$ is copied and set to the new used count. + +At this point the first addition loop will go through as many digit positions that both inputs have. The carry +variable $\mu$ is set to zero outside the loop. Inside the loop an ``addition'' step requires three statements to produce +one digit of the summand. First +two digits from $a$ and $b$ are added together along with the carry $\mu$. The carry of this step is extracted and stored +in $\mu$ and finally the digit of the result $c_n$ is truncated within the range $0 \le c_n < \beta$. + +Now all of the digit positions that both inputs have in common have been exhausted. If $min \ne max$ then $x$ is an alias +for one of the inputs that has more digits. A simplified addition loop is then used to essentially copy the remaining digits +and the carry to the destination. + +The final carry is stored in $c_{max}$ and digits above $max$ upto $oldused$ are zeroed which completes the addition. + + +EXAM,bn_s_mp_add.c + +We first sort (lines @27,if@ to @35,}@) the inputs based on magnitude and determine the $min$ and $max$ variables. +Note that $x$ is a pointer to an mp\_int assigned to the largest input, in effect it is a local alias. Next we +grow the destination (@37,init@ to @42,}@) ensure that it can accomodate the result of the addition. + +Similar to the implementation of mp\_copy this function uses the braced code and local aliases coding style. The three aliases that are on +lines @56,tmpa@, @59,tmpb@ and @62,tmpc@ represent the two inputs and destination variables respectively. These aliases are used to ensure the +compiler does not have to dereference $a$, $b$ or $c$ (respectively) to access the digits of the respective mp\_int. + +The initial carry $u$ will be cleared (line @65,u = 0@), note that $u$ is of type mp\_digit which ensures type +compatibility within the implementation. The initial addition (line @66,for@ to @75,}@) adds digits from +both inputs until the smallest input runs out of digits. Similarly the conditional addition loop +(line @81,for@ to @90,}@) adds the remaining digits from the larger of the two inputs. The addition is finished +with the final carry being stored in $tmpc$ (line @94,tmpc++@). Note the ``++'' operator within the same expression. +After line @94,tmpc++@, $tmpc$ will point to the $c.used$'th digit of the mp\_int $c$. This is useful +for the next loop (line @97,for@ to @99,}@) which set any old upper digits to zero. + +\subsection{Low Level Subtraction} +The low level unsigned subtraction algorithm is very similar to the low level unsigned addition algorithm. The principle difference is that the +unsigned subtraction algorithm requires the result to be positive. That is when computing $a - b$ the condition $\vert a \vert \ge \vert b\vert$ must +be met for this algorithm to function properly. Keep in mind this low level algorithm is not meant to be used in higher level algorithms directly. +This algorithm as will be shown can be used to create functional signed addition and subtraction algorithms. + +MARK,GAMMA + +For this algorithm a new variable is required to make the description simpler. Recall from section 1.3.1 that a mp\_digit must be able to represent +the range $0 \le x < 2\beta$ for the algorithms to work correctly. However, it is allowable that a mp\_digit represent a larger range of values. For +this algorithm we will assume that the variable $\gamma$ represents the number of bits available in a +mp\_digit (\textit{this implies $2^{\gamma} > \beta$}). + +For example, the default for LibTomMath is to use a ``unsigned long'' for the mp\_digit ``type'' while $\beta = 2^{28}$. In ISO C an ``unsigned long'' +data type must be able to represent $0 \le x < 2^{32}$ meaning that in this case $\gamma \ge 32$. + +\newpage\begin{figure}[!here] +\begin{center} +\begin{small} +\begin{tabular}{l} +\hline Algorithm \textbf{s\_mp\_sub}. \\ +\textbf{Input}. Two mp\_ints $a$ and $b$ ($\vert a \vert \ge \vert b \vert$) \\ +\textbf{Output}. The unsigned subtraction $c = \vert a \vert - \vert b \vert$. \\ +\hline \\ +1. $min \leftarrow b.used$ \\ +2. $max \leftarrow a.used$ \\ +3. If $c.alloc < max$ then grow $c$ to hold at least $max$ digits. (\textit{mp\_grow}) \\ +4. $oldused \leftarrow c.used$ \\ +5. $c.used \leftarrow max$ \\ +6. $u \leftarrow 0$ \\ +7. for $n$ from $0$ to $min - 1$ do \\ +\hspace{3mm}7.1 $c_n \leftarrow a_n - b_n - u$ \\ +\hspace{3mm}7.2 $u \leftarrow c_n >> (\gamma - 1)$ \\ +\hspace{3mm}7.3 $c_n \leftarrow c_n \mbox{ (mod }\beta\mbox{)}$ \\ +8. if $min < max$ then do \\ +\hspace{3mm}8.1 for $n$ from $min$ to $max - 1$ do \\ +\hspace{6mm}8.1.1 $c_n \leftarrow a_n - u$ \\ +\hspace{6mm}8.1.2 $u \leftarrow c_n >> (\gamma - 1)$ \\ +\hspace{6mm}8.1.3 $c_n \leftarrow c_n \mbox{ (mod }\beta\mbox{)}$ \\ +9. if $oldused > max$ then do \\ +\hspace{3mm}9.1 for $n$ from $max$ to $oldused - 1$ do \\ +\hspace{6mm}9.1.1 $c_n \leftarrow 0$ \\ +10. Clamp excess digits of $c$. (\textit{mp\_clamp}). \\ +11. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{small} +\end{center} +\caption{Algorithm s\_mp\_sub} +\end{figure} + +\textbf{Algorithm s\_mp\_sub.} +This algorithm performs the unsigned subtraction of two mp\_int variables under the restriction that the result must be positive. That is when +passing variables $a$ and $b$ the condition that $\vert a \vert \ge \vert b \vert$ must be met for the algorithm to function correctly. This +algorithm is loosely based on algorithm 14.9 \cite[pp. 595]{HAC} and is similar to algorithm S in \cite[pp. 267]{TAOCPV2} as well. As was the case +of the algorithm s\_mp\_add both other references lack discussion concerning various practical details such as when the inputs differ in magnitude. + +The initial sorting of the inputs is trivial in this algorithm since $a$ is guaranteed to have at least the same magnitude of $b$. Steps 1 and 2 +set the $min$ and $max$ variables. Unlike the addition routine there is guaranteed to be no carry which means that the final result can be at +most $max$ digits in length as opposed to $max + 1$. Similar to the addition algorithm the \textbf{used} count of $c$ is copied locally and +set to the maximal count for the operation. + +The subtraction loop that begins on step seven is essentially the same as the addition loop of algorithm s\_mp\_add except single precision +subtraction is used instead. Note the use of the $\gamma$ variable to extract the carry (\textit{also known as the borrow}) within the subtraction +loops. Under the assumption that two's complement single precision arithmetic is used this will successfully extract the desired carry. + +For example, consider subtracting $0101_2$ from $0100_2$ where $\gamma = 4$ and $\beta = 2$. The least significant bit will force a carry upwards to +the third bit which will be set to zero after the borrow. After the very first bit has been subtracted $4 - 1 \equiv 0011_2$ will remain, When the +third bit of $0101_2$ is subtracted from the result it will cause another carry. In this case though the carry will be forced to propagate all the +way to the most significant bit. + +Recall that $\beta < 2^{\gamma}$. This means that if a carry does occur just before the $lg(\beta)$'th bit it will propagate all the way to the most +significant bit. Thus, the high order bits of the mp\_digit that are not part of the actual digit will either be all zero, or all one. All that +is needed is a single zero or one bit for the carry. Therefore a single logical shift right by $\gamma - 1$ positions is sufficient to extract the +carry. This method of carry extraction may seem awkward but the reason for it becomes apparent when the implementation is discussed. + +If $b$ has a smaller magnitude than $a$ then step 9 will force the carry and copy operation to propagate through the larger input $a$ into $c$. Step +10 will ensure that any leading digits of $c$ above the $max$'th position are zeroed. + +EXAM,bn_s_mp_sub.c + +Like low level addition we ``sort'' the inputs. Except in this case the sorting is hardcoded +(lines @24,min@ and @25,max@). In reality the $min$ and $max$ variables are only aliases and are only +used to make the source code easier to read. Again the pointer alias optimization is used +within this algorithm. The aliases $tmpa$, $tmpb$ and $tmpc$ are initialized +(lines @42,tmpa@, @43,tmpb@ and @44,tmpc@) for $a$, $b$ and $c$ respectively. + +The first subtraction loop (lines @47,u = 0@ through @61,}@) subtract digits from both inputs until the smaller of +the two inputs has been exhausted. As remarked earlier there is an implementation reason for using the ``awkward'' +method of extracting the carry (line @57, >>@). The traditional method for extracting the carry would be to shift +by $lg(\beta)$ positions and logically AND the least significant bit. The AND operation is required because all of +the bits above the $\lg(\beta)$'th bit will be set to one after a carry occurs from subtraction. This carry +extraction requires two relatively cheap operations to extract the carry. The other method is to simply shift the +most significant bit to the least significant bit thus extracting the carry with a single cheap operation. This +optimization only works on twos compliment machines which is a safe assumption to make. + +If $a$ has a larger magnitude than $b$ an additional loop (lines @64,for@ through @73,}@) is required to propagate +the carry through $a$ and copy the result to $c$. + +\subsection{High Level Addition} +Now that both lower level addition and subtraction algorithms have been established an effective high level signed addition algorithm can be +established. This high level addition algorithm will be what other algorithms and developers will use to perform addition of mp\_int data +types. + +Recall from section 5.2 that an mp\_int represents an integer with an unsigned mantissa (\textit{the array of digits}) and a \textbf{sign} +flag. A high level addition is actually performed as a series of eight separate cases which can be optimized down to three unique cases. + +\begin{figure}[!here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_add}. \\ +\textbf{Input}. Two mp\_ints $a$ and $b$ \\ +\textbf{Output}. The signed addition $c = a + b$. \\ +\hline \\ +1. if $a.sign = b.sign$ then do \\ +\hspace{3mm}1.1 $c.sign \leftarrow a.sign$ \\ +\hspace{3mm}1.2 $c \leftarrow \vert a \vert + \vert b \vert$ (\textit{s\_mp\_add})\\ +2. else do \\ +\hspace{3mm}2.1 if $\vert a \vert < \vert b \vert$ then do (\textit{mp\_cmp\_mag}) \\ +\hspace{6mm}2.1.1 $c.sign \leftarrow b.sign$ \\ +\hspace{6mm}2.1.2 $c \leftarrow \vert b \vert - \vert a \vert$ (\textit{s\_mp\_sub}) \\ +\hspace{3mm}2.2 else do \\ +\hspace{6mm}2.2.1 $c.sign \leftarrow a.sign$ \\ +\hspace{6mm}2.2.2 $c \leftarrow \vert a \vert - \vert b \vert$ \\ +3. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_add} +\end{figure} + +\textbf{Algorithm mp\_add.} +This algorithm performs the signed addition of two mp\_int variables. There is no reference algorithm to draw upon from +either \cite{TAOCPV2} or \cite{HAC} since they both only provide unsigned operations. The algorithm is fairly +straightforward but restricted since subtraction can only produce positive results. + +\begin{figure}[here] +\begin{small} +\begin{center} +\begin{tabular}{|c|c|c|c|c|} +\hline \textbf{Sign of $a$} & \textbf{Sign of $b$} & \textbf{$\vert a \vert > \vert b \vert $} & \textbf{Unsigned Operation} & \textbf{Result Sign Flag} \\ +\hline $+$ & $+$ & Yes & $c = a + b$ & $a.sign$ \\ +\hline $+$ & $+$ & No & $c = a + b$ & $a.sign$ \\ +\hline $-$ & $-$ & Yes & $c = a + b$ & $a.sign$ \\ +\hline $-$ & $-$ & No & $c = a + b$ & $a.sign$ \\ +\hline &&&&\\ + +\hline $+$ & $-$ & No & $c = b - a$ & $b.sign$ \\ +\hline $-$ & $+$ & No & $c = b - a$ & $b.sign$ \\ + +\hline &&&&\\ + +\hline $+$ & $-$ & Yes & $c = a - b$ & $a.sign$ \\ +\hline $-$ & $+$ & Yes & $c = a - b$ & $a.sign$ \\ + +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Addition Guide Chart} +\label{fig:AddChart} +\end{figure} + +Figure~\ref{fig:AddChart} lists all of the eight possible input combinations and is sorted to show that only three +specific cases need to be handled. The return code of the unsigned operations at step 1.2, 2.1.2 and 2.2.2 are +forwarded to step three to check for errors. This simplifies the description of the algorithm considerably and best +follows how the implementation actually was achieved. + +Also note how the \textbf{sign} is set before the unsigned addition or subtraction is performed. Recall from the descriptions of algorithms +s\_mp\_add and s\_mp\_sub that the mp\_clamp function is used at the end to trim excess digits. The mp\_clamp algorithm will set the \textbf{sign} +to \textbf{MP\_ZPOS} when the \textbf{used} digit count reaches zero. + +For example, consider performing $-a + a$ with algorithm mp\_add. By the description of the algorithm the sign is set to \textbf{MP\_NEG} which would +produce a result of $-0$. However, since the sign is set first then the unsigned addition is performed the subsequent usage of algorithm mp\_clamp +within algorithm s\_mp\_add will force $-0$ to become $0$. + +EXAM,bn_mp_add.c + +The source code follows the algorithm fairly closely. The most notable new source code addition is the usage of the $res$ integer variable which +is used to pass result of the unsigned operations forward. Unlike in the algorithm, the variable $res$ is merely returned as is without +explicitly checking it and returning the constant \textbf{MP\_OKAY}. The observation is this algorithm will succeed or fail only if the lower +level functions do so. Returning their return code is sufficient. + +\subsection{High Level Subtraction} +The high level signed subtraction algorithm is essentially the same as the high level signed addition algorithm. + +\newpage\begin{figure}[!here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_sub}. \\ +\textbf{Input}. Two mp\_ints $a$ and $b$ \\ +\textbf{Output}. The signed subtraction $c = a - b$. \\ +\hline \\ +1. if $a.sign \ne b.sign$ then do \\ +\hspace{3mm}1.1 $c.sign \leftarrow a.sign$ \\ +\hspace{3mm}1.2 $c \leftarrow \vert a \vert + \vert b \vert$ (\textit{s\_mp\_add}) \\ +2. else do \\ +\hspace{3mm}2.1 if $\vert a \vert \ge \vert b \vert$ then do (\textit{mp\_cmp\_mag}) \\ +\hspace{6mm}2.1.1 $c.sign \leftarrow a.sign$ \\ +\hspace{6mm}2.1.2 $c \leftarrow \vert a \vert - \vert b \vert$ (\textit{s\_mp\_sub}) \\ +\hspace{3mm}2.2 else do \\ +\hspace{6mm}2.2.1 $c.sign \leftarrow \left \lbrace \begin{array}{ll} + MP\_ZPOS & \mbox{if }a.sign = MP\_NEG \\ + MP\_NEG & \mbox{otherwise} \\ + \end{array} \right .$ \\ +\hspace{6mm}2.2.2 $c \leftarrow \vert b \vert - \vert a \vert$ \\ +3. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_sub} +\end{figure} + +\textbf{Algorithm mp\_sub.} +This algorithm performs the signed subtraction of two inputs. Similar to algorithm mp\_add there is no reference in either \cite{TAOCPV2} or +\cite{HAC}. Also this algorithm is restricted by algorithm s\_mp\_sub. Chart \ref{fig:SubChart} lists the eight possible inputs and +the operations required. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{|c|c|c|c|c|} +\hline \textbf{Sign of $a$} & \textbf{Sign of $b$} & \textbf{$\vert a \vert \ge \vert b \vert $} & \textbf{Unsigned Operation} & \textbf{Result Sign Flag} \\ +\hline $+$ & $-$ & Yes & $c = a + b$ & $a.sign$ \\ +\hline $+$ & $-$ & No & $c = a + b$ & $a.sign$ \\ +\hline $-$ & $+$ & Yes & $c = a + b$ & $a.sign$ \\ +\hline $-$ & $+$ & No & $c = a + b$ & $a.sign$ \\ +\hline &&&& \\ +\hline $+$ & $+$ & Yes & $c = a - b$ & $a.sign$ \\ +\hline $-$ & $-$ & Yes & $c = a - b$ & $a.sign$ \\ +\hline &&&& \\ +\hline $+$ & $+$ & No & $c = b - a$ & $\mbox{opposite of }a.sign$ \\ +\hline $-$ & $-$ & No & $c = b - a$ & $\mbox{opposite of }a.sign$ \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Subtraction Guide Chart} +\label{fig:SubChart} +\end{figure} + +Similar to the case of algorithm mp\_add the \textbf{sign} is set first before the unsigned addition or subtraction. That is to prevent the +algorithm from producing $-a - -a = -0$ as a result. + +EXAM,bn_mp_sub.c + +Much like the implementation of algorithm mp\_add the variable $res$ is used to catch the return code of the unsigned addition or subtraction operations +and forward it to the end of the function. On line @38, != MP_LT@ the ``not equal to'' \textbf{MP\_LT} expression is used to emulate a +``greater than or equal to'' comparison. + +\section{Bit and Digit Shifting} +MARK,POLY +It is quite common to think of a multiple precision integer as a polynomial in $x$, that is $y = f(\beta)$ where $f(x) = \sum_{i=0}^{n-1} a_i x^i$. +This notation arises within discussion of Montgomery and Diminished Radix Reduction as well as Karatsuba multiplication and squaring. + +In order to facilitate operations on polynomials in $x$ as above a series of simple ``digit'' algorithms have to be established. That is to shift +the digits left or right as well to shift individual bits of the digits left and right. It is important to note that not all ``shift'' operations +are on radix-$\beta$ digits. + +\subsection{Multiplication by Two} + +In a binary system where the radix is a power of two multiplication by two not only arises often in other algorithms it is a fairly efficient +operation to perform. A single precision logical shift left is sufficient to multiply a single digit by two. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_mul\_2}. \\ +\textbf{Input}. One mp\_int $a$ \\ +\textbf{Output}. $b = 2a$. \\ +\hline \\ +1. If $b.alloc < a.used + 1$ then grow $b$ to hold $a.used + 1$ digits. (\textit{mp\_grow}) \\ +2. $oldused \leftarrow b.used$ \\ +3. $b.used \leftarrow a.used$ \\ +4. $r \leftarrow 0$ \\ +5. for $n$ from 0 to $a.used - 1$ do \\ +\hspace{3mm}5.1 $rr \leftarrow a_n >> (lg(\beta) - 1)$ \\ +\hspace{3mm}5.2 $b_n \leftarrow (a_n << 1) + r \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{3mm}5.3 $r \leftarrow rr$ \\ +6. If $r \ne 0$ then do \\ +\hspace{3mm}6.1 $b_{n + 1} \leftarrow r$ \\ +\hspace{3mm}6.2 $b.used \leftarrow b.used + 1$ \\ +7. If $b.used < oldused - 1$ then do \\ +\hspace{3mm}7.1 for $n$ from $b.used$ to $oldused - 1$ do \\ +\hspace{6mm}7.1.1 $b_n \leftarrow 0$ \\ +8. $b.sign \leftarrow a.sign$ \\ +9. Return(\textit{MP\_OKAY}).\\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_mul\_2} +\end{figure} + +\textbf{Algorithm mp\_mul\_2.} +This algorithm will quickly multiply a mp\_int by two provided $\beta$ is a power of two. Neither \cite{TAOCPV2} nor \cite{HAC} describe such +an algorithm despite the fact it arises often in other algorithms. The algorithm is setup much like the lower level algorithm s\_mp\_add since +it is for all intents and purposes equivalent to the operation $b = \vert a \vert + \vert a \vert$. + +Step 1 and 2 grow the input as required to accomodate the maximum number of \textbf{used} digits in the result. The initial \textbf{used} count +is set to $a.used$ at step 4. Only if there is a final carry will the \textbf{used} count require adjustment. + +Step 6 is an optimization implementation of the addition loop for this specific case. That is since the two values being added together +are the same there is no need to perform two reads from the digits of $a$. Step 6.1 performs a single precision shift on the current digit $a_n$ to +obtain what will be the carry for the next iteration. Step 6.2 calculates the $n$'th digit of the result as single precision shift of $a_n$ plus +the previous carry. Recall from ~SHIFTS~ that $a_n << 1$ is equivalent to $a_n \cdot 2$. An iteration of the addition loop is finished with +forwarding the carry to the next iteration. + +Step 7 takes care of any final carry by setting the $a.used$'th digit of the result to the carry and augmenting the \textbf{used} count of $b$. +Step 8 clears any leading digits of $b$ in case it originally had a larger magnitude than $a$. + +EXAM,bn_mp_mul_2.c + +This implementation is essentially an optimized implementation of s\_mp\_add for the case of doubling an input. The only noteworthy difference +is the use of the logical shift operator on line @52,<<@ to perform a single precision doubling. + +\subsection{Division by Two} +A division by two can just as easily be accomplished with a logical shift right as multiplication by two can be with a logical shift left. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_div\_2}. \\ +\textbf{Input}. One mp\_int $a$ \\ +\textbf{Output}. $b = a/2$. \\ +\hline \\ +1. If $b.alloc < a.used$ then grow $b$ to hold $a.used$ digits. (\textit{mp\_grow}) \\ +2. If the reallocation failed return(\textit{MP\_MEM}). \\ +3. $oldused \leftarrow b.used$ \\ +4. $b.used \leftarrow a.used$ \\ +5. $r \leftarrow 0$ \\ +6. for $n$ from $b.used - 1$ to $0$ do \\ +\hspace{3mm}6.1 $rr \leftarrow a_n \mbox{ (mod }2\mbox{)}$\\ +\hspace{3mm}6.2 $b_n \leftarrow (a_n >> 1) + (r << (lg(\beta) - 1)) \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{3mm}6.3 $r \leftarrow rr$ \\ +7. If $b.used < oldused - 1$ then do \\ +\hspace{3mm}7.1 for $n$ from $b.used$ to $oldused - 1$ do \\ +\hspace{6mm}7.1.1 $b_n \leftarrow 0$ \\ +8. $b.sign \leftarrow a.sign$ \\ +9. Clamp excess digits of $b$. (\textit{mp\_clamp}) \\ +10. Return(\textit{MP\_OKAY}).\\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_div\_2} +\end{figure} + +\textbf{Algorithm mp\_div\_2.} +This algorithm will divide an mp\_int by two using logical shifts to the right. Like mp\_mul\_2 it uses a modified low level addition +core as the basis of the algorithm. Unlike mp\_mul\_2 the shift operations work from the leading digit to the trailing digit. The algorithm +could be written to work from the trailing digit to the leading digit however, it would have to stop one short of $a.used - 1$ digits to prevent +reading past the end of the array of digits. + +Essentially the loop at step 6 is similar to that of mp\_mul\_2 except the logical shifts go in the opposite direction and the carry is at the +least significant bit not the most significant bit. + +EXAM,bn_mp_div_2.c + +\section{Polynomial Basis Operations} +Recall from ~POLY~ that any integer can be represented as a polynomial in $x$ as $y = f(\beta)$. Such a representation is also known as +the polynomial basis \cite[pp. 48]{ROSE}. Given such a notation a multiplication or division by $x$ amounts to shifting whole digits a single +place. The need for such operations arises in several other higher level algorithms such as Barrett and Montgomery reduction, integer +division and Karatsuba multiplication. + +Converting from an array of digits to polynomial basis is very simple. Consider the integer $y \equiv (a_2, a_1, a_0)_{\beta}$ and recall that +$y = \sum_{i=0}^{2} a_i \beta^i$. Simply replace $\beta$ with $x$ and the expression is in polynomial basis. For example, $f(x) = 8x + 9$ is the +polynomial basis representation for $89$ using radix ten. That is, $f(10) = 8(10) + 9 = 89$. + +\subsection{Multiplication by $x$} + +Given a polynomial in $x$ such as $f(x) = a_n x^n + a_{n-1} x^{n-1} + ... + a_0$ multiplying by $x$ amounts to shifting the coefficients up one +degree. In this case $f(x) \cdot x = a_n x^{n+1} + a_{n-1} x^n + ... + a_0 x$. From a scalar basis point of view multiplying by $x$ is equivalent to +multiplying by the integer $\beta$. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_lshd}. \\ +\textbf{Input}. One mp\_int $a$ and an integer $b$ \\ +\textbf{Output}. $a \leftarrow a \cdot \beta^b$ (equivalent to multiplication by $x^b$). \\ +\hline \\ +1. If $b \le 0$ then return(\textit{MP\_OKAY}). \\ +2. If $a.alloc < a.used + b$ then grow $a$ to at least $a.used + b$ digits. (\textit{mp\_grow}). \\ +3. If the reallocation failed return(\textit{MP\_MEM}). \\ +4. $a.used \leftarrow a.used + b$ \\ +5. $i \leftarrow a.used - 1$ \\ +6. $j \leftarrow a.used - 1 - b$ \\ +7. for $n$ from $a.used - 1$ to $b$ do \\ +\hspace{3mm}7.1 $a_{i} \leftarrow a_{j}$ \\ +\hspace{3mm}7.2 $i \leftarrow i - 1$ \\ +\hspace{3mm}7.3 $j \leftarrow j - 1$ \\ +8. for $n$ from 0 to $b - 1$ do \\ +\hspace{3mm}8.1 $a_n \leftarrow 0$ \\ +9. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_lshd} +\end{figure} + +\textbf{Algorithm mp\_lshd.} +This algorithm multiplies an mp\_int by the $b$'th power of $x$. This is equivalent to multiplying by $\beta^b$. The algorithm differs +from the other algorithms presented so far as it performs the operation in place instead storing the result in a separate location. The +motivation behind this change is due to the way this function is typically used. Algorithms such as mp\_add store the result in an optionally +different third mp\_int because the original inputs are often still required. Algorithm mp\_lshd (\textit{and similarly algorithm mp\_rshd}) is +typically used on values where the original value is no longer required. The algorithm will return success immediately if +$b \le 0$ since the rest of algorithm is only valid when $b > 0$. + +First the destination $a$ is grown as required to accomodate the result. The counters $i$ and $j$ are used to form a \textit{sliding window} over +the digits of $a$ of length $b$. The head of the sliding window is at $i$ (\textit{the leading digit}) and the tail at $j$ (\textit{the trailing digit}). +The loop on step 7 copies the digit from the tail to the head. In each iteration the window is moved down one digit. The last loop on +step 8 sets the lower $b$ digits to zero. + +\newpage +FIGU,sliding_window,Sliding Window Movement + +EXAM,bn_mp_lshd.c + +The if statement (line @24,if@) ensures that the $b$ variable is greater than zero since we do not interpret negative +shift counts properly. The \textbf{used} count is incremented by $b$ before the copy loop begins. This elminates +the need for an additional variable in the for loop. The variable $top$ (line @42,top@) is an alias +for the leading digit while $bottom$ (line @45,bottom@) is an alias for the trailing edge. The aliases form a +window of exactly $b$ digits over the input. + +\subsection{Division by $x$} + +Division by powers of $x$ is easily achieved by shifting the digits right and removing any that will end up to the right of the zero'th digit. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_rshd}. \\ +\textbf{Input}. One mp\_int $a$ and an integer $b$ \\ +\textbf{Output}. $a \leftarrow a / \beta^b$ (Divide by $x^b$). \\ +\hline \\ +1. If $b \le 0$ then return. \\ +2. If $a.used \le b$ then do \\ +\hspace{3mm}2.1 Zero $a$. (\textit{mp\_zero}). \\ +\hspace{3mm}2.2 Return. \\ +3. $i \leftarrow 0$ \\ +4. $j \leftarrow b$ \\ +5. for $n$ from 0 to $a.used - b - 1$ do \\ +\hspace{3mm}5.1 $a_i \leftarrow a_j$ \\ +\hspace{3mm}5.2 $i \leftarrow i + 1$ \\ +\hspace{3mm}5.3 $j \leftarrow j + 1$ \\ +6. for $n$ from $a.used - b$ to $a.used - 1$ do \\ +\hspace{3mm}6.1 $a_n \leftarrow 0$ \\ +7. $a.used \leftarrow a.used - b$ \\ +8. Return. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_rshd} +\end{figure} + +\textbf{Algorithm mp\_rshd.} +This algorithm divides the input in place by the $b$'th power of $x$. It is analogous to dividing by a $\beta^b$ but much quicker since +it does not require single precision division. This algorithm does not actually return an error code as it cannot fail. + +If the input $b$ is less than one the algorithm quickly returns without performing any work. If the \textbf{used} count is less than or equal +to the shift count $b$ then it will simply zero the input and return. + +After the trivial cases of inputs have been handled the sliding window is setup. Much like the case of algorithm mp\_lshd a sliding window that +is $b$ digits wide is used to copy the digits. Unlike mp\_lshd the window slides in the opposite direction from the trailing to the leading digit. +Also the digits are copied from the leading to the trailing edge. + +Once the window copy is complete the upper digits must be zeroed and the \textbf{used} count decremented. + +EXAM,bn_mp_rshd.c + +The only noteworthy element of this routine is the lack of a return type since it cannot fail. Like mp\_lshd() we +form a sliding window except we copy in the other direction. After the window (line @59,for (;@) we then zero +the upper digits of the input to make sure the result is correct. + +\section{Powers of Two} + +Now that algorithms for moving single bits as well as whole digits exist algorithms for moving the ``in between'' distances are required. For +example, to quickly multiply by $2^k$ for any $k$ without using a full multiplier algorithm would prove useful. Instead of performing single +shifts $k$ times to achieve a multiplication by $2^{\pm k}$ a mixture of whole digit shifting and partial digit shifting is employed. + +\subsection{Multiplication by Power of Two} + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_mul\_2d}. \\ +\textbf{Input}. One mp\_int $a$ and an integer $b$ \\ +\textbf{Output}. $c \leftarrow a \cdot 2^b$. \\ +\hline \\ +1. $c \leftarrow a$. (\textit{mp\_copy}) \\ +2. If $c.alloc < c.used + \lfloor b / lg(\beta) \rfloor + 2$ then grow $c$ accordingly. \\ +3. If the reallocation failed return(\textit{MP\_MEM}). \\ +4. If $b \ge lg(\beta)$ then \\ +\hspace{3mm}4.1 $c \leftarrow c \cdot \beta^{\lfloor b / lg(\beta) \rfloor}$ (\textit{mp\_lshd}). \\ +\hspace{3mm}4.2 If step 4.1 failed return(\textit{MP\_MEM}). \\ +5. $d \leftarrow b \mbox{ (mod }lg(\beta)\mbox{)}$ \\ +6. If $d \ne 0$ then do \\ +\hspace{3mm}6.1 $mask \leftarrow 2^d$ \\ +\hspace{3mm}6.2 $r \leftarrow 0$ \\ +\hspace{3mm}6.3 for $n$ from $0$ to $c.used - 1$ do \\ +\hspace{6mm}6.3.1 $rr \leftarrow c_n >> (lg(\beta) - d) \mbox{ (mod }mask\mbox{)}$ \\ +\hspace{6mm}6.3.2 $c_n \leftarrow (c_n << d) + r \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{6mm}6.3.3 $r \leftarrow rr$ \\ +\hspace{3mm}6.4 If $r > 0$ then do \\ +\hspace{6mm}6.4.1 $c_{c.used} \leftarrow r$ \\ +\hspace{6mm}6.4.2 $c.used \leftarrow c.used + 1$ \\ +7. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_mul\_2d} +\end{figure} + +\textbf{Algorithm mp\_mul\_2d.} +This algorithm multiplies $a$ by $2^b$ and stores the result in $c$. The algorithm uses algorithm mp\_lshd and a derivative of algorithm mp\_mul\_2 to +quickly compute the product. + +First the algorithm will multiply $a$ by $x^{\lfloor b / lg(\beta) \rfloor}$ which will ensure that the remainder multiplicand is less than +$\beta$. For example, if $b = 37$ and $\beta = 2^{28}$ then this step will multiply by $x$ leaving a multiplication by $2^{37 - 28} = 2^{9}$ +left. + +After the digits have been shifted appropriately at most $lg(\beta) - 1$ shifts are left to perform. Step 5 calculates the number of remaining shifts +required. If it is non-zero a modified shift loop is used to calculate the remaining product. +Essentially the loop is a generic version of algorithm mp\_mul\_2 designed to handle any shift count in the range $1 \le x < lg(\beta)$. The $mask$ +variable is used to extract the upper $d$ bits to form the carry for the next iteration. + +This algorithm is loosely measured as a $O(2n)$ algorithm which means that if the input is $n$-digits that it takes $2n$ ``time'' to +complete. It is possible to optimize this algorithm down to a $O(n)$ algorithm at a cost of making the algorithm slightly harder to follow. + +EXAM,bn_mp_mul_2d.c + +The shifting is performed in--place which means the first step (line @24,a != c@) is to copy the input to the +destination. We avoid calling mp\_copy() by making sure the mp\_ints are different. The destination then +has to be grown (line @31,grow@) to accomodate the result. + +If the shift count $b$ is larger than $lg(\beta)$ then a call to mp\_lshd() is used to handle all of the multiples +of $lg(\beta)$. Leaving only a remaining shift of $lg(\beta) - 1$ or fewer bits left. Inside the actual shift +loop (lines @45,if@ to @76,}@) we make use of pre--computed values $shift$ and $mask$. These are used to +extract the carry bit(s) to pass into the next iteration of the loop. The $r$ and $rr$ variables form a +chain between consecutive iterations to propagate the carry. + +\subsection{Division by Power of Two} + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_div\_2d}. \\ +\textbf{Input}. One mp\_int $a$ and an integer $b$ \\ +\textbf{Output}. $c \leftarrow \lfloor a / 2^b \rfloor, d \leftarrow a \mbox{ (mod }2^b\mbox{)}$. \\ +\hline \\ +1. If $b \le 0$ then do \\ +\hspace{3mm}1.1 $c \leftarrow a$ (\textit{mp\_copy}) \\ +\hspace{3mm}1.2 $d \leftarrow 0$ (\textit{mp\_zero}) \\ +\hspace{3mm}1.3 Return(\textit{MP\_OKAY}). \\ +2. $c \leftarrow a$ \\ +3. $d \leftarrow a \mbox{ (mod }2^b\mbox{)}$ (\textit{mp\_mod\_2d}) \\ +4. If $b \ge lg(\beta)$ then do \\ +\hspace{3mm}4.1 $c \leftarrow \lfloor c/\beta^{\lfloor b/lg(\beta) \rfloor} \rfloor$ (\textit{mp\_rshd}). \\ +5. $k \leftarrow b \mbox{ (mod }lg(\beta)\mbox{)}$ \\ +6. If $k \ne 0$ then do \\ +\hspace{3mm}6.1 $mask \leftarrow 2^k$ \\ +\hspace{3mm}6.2 $r \leftarrow 0$ \\ +\hspace{3mm}6.3 for $n$ from $c.used - 1$ to $0$ do \\ +\hspace{6mm}6.3.1 $rr \leftarrow c_n \mbox{ (mod }mask\mbox{)}$ \\ +\hspace{6mm}6.3.2 $c_n \leftarrow (c_n >> k) + (r << (lg(\beta) - k))$ \\ +\hspace{6mm}6.3.3 $r \leftarrow rr$ \\ +7. Clamp excess digits of $c$. (\textit{mp\_clamp}) \\ +8. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_div\_2d} +\end{figure} + +\textbf{Algorithm mp\_div\_2d.} +This algorithm will divide an input $a$ by $2^b$ and produce the quotient and remainder. The algorithm is designed much like algorithm +mp\_mul\_2d by first using whole digit shifts then single precision shifts. This algorithm will also produce the remainder of the division +by using algorithm mp\_mod\_2d. + +EXAM,bn_mp_div_2d.c + +The implementation of algorithm mp\_div\_2d is slightly different than the algorithm specifies. The remainder $d$ may be optionally +ignored by passing \textbf{NULL} as the pointer to the mp\_int variable. The temporary mp\_int variable $t$ is used to hold the +result of the remainder operation until the end. This allows $d$ and $a$ to represent the same mp\_int without modifying $a$ before +the quotient is obtained. + +The remainder of the source code is essentially the same as the source code for mp\_mul\_2d. The only significant difference is +the direction of the shifts. + +\subsection{Remainder of Division by Power of Two} + +The last algorithm in the series of polynomial basis power of two algorithms is calculating the remainder of division by $2^b$. This +algorithm benefits from the fact that in twos complement arithmetic $a \mbox{ (mod }2^b\mbox{)}$ is the same as $a$ AND $2^b - 1$. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_mod\_2d}. \\ +\textbf{Input}. One mp\_int $a$ and an integer $b$ \\ +\textbf{Output}. $c \leftarrow a \mbox{ (mod }2^b\mbox{)}$. \\ +\hline \\ +1. If $b \le 0$ then do \\ +\hspace{3mm}1.1 $c \leftarrow 0$ (\textit{mp\_zero}) \\ +\hspace{3mm}1.2 Return(\textit{MP\_OKAY}). \\ +2. If $b > a.used \cdot lg(\beta)$ then do \\ +\hspace{3mm}2.1 $c \leftarrow a$ (\textit{mp\_copy}) \\ +\hspace{3mm}2.2 Return the result of step 2.1. \\ +3. $c \leftarrow a$ \\ +4. If step 3 failed return(\textit{MP\_MEM}). \\ +5. for $n$ from $\lceil b / lg(\beta) \rceil$ to $c.used$ do \\ +\hspace{3mm}5.1 $c_n \leftarrow 0$ \\ +6. $k \leftarrow b \mbox{ (mod }lg(\beta)\mbox{)}$ \\ +7. $c_{\lfloor b / lg(\beta) \rfloor} \leftarrow c_{\lfloor b / lg(\beta) \rfloor} \mbox{ (mod }2^{k}\mbox{)}$. \\ +8. Clamp excess digits of $c$. (\textit{mp\_clamp}) \\ +9. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_mod\_2d} +\end{figure} + +\textbf{Algorithm mp\_mod\_2d.} +This algorithm will quickly calculate the value of $a \mbox{ (mod }2^b\mbox{)}$. First if $b$ is less than or equal to zero the +result is set to zero. If $b$ is greater than the number of bits in $a$ then it simply copies $a$ to $c$ and returns. Otherwise, $a$ +is copied to $b$, leading digits are removed and the remaining leading digit is trimed to the exact bit count. + +EXAM,bn_mp_mod_2d.c + +We first avoid cases of $b \le 0$ by simply mp\_zero()'ing the destination in such cases. Next if $2^b$ is larger +than the input we just mp\_copy() the input and return right away. After this point we know we must actually +perform some work to produce the remainder. + +Recalling that reducing modulo $2^k$ and a binary ``and'' with $2^k - 1$ are numerically equivalent we can quickly reduce +the number. First we zero any digits above the last digit in $2^b$ (line @41,for@). Next we reduce the +leading digit of both (line @45,&=@) and then mp\_clamp(). + +\section*{Exercises} +\begin{tabular}{cl} +$\left [ 3 \right ] $ & Devise an algorithm that performs $a \cdot 2^b$ for generic values of $b$ \\ + & in $O(n)$ time. \\ + &\\ +$\left [ 3 \right ] $ & Devise an efficient algorithm to multiply by small low hamming \\ + & weight values such as $3$, $5$ and $9$. Extend it to handle all values \\ + & upto $64$ with a hamming weight less than three. \\ + &\\ +$\left [ 2 \right ] $ & Modify the preceding algorithm to handle values of the form \\ + & $2^k - 1$ as well. \\ + &\\ +$\left [ 3 \right ] $ & Using only algorithms mp\_mul\_2, mp\_div\_2 and mp\_add create an \\ + & algorithm to multiply two integers in roughly $O(2n^2)$ time for \\ + & any $n$-bit input. Note that the time of addition is ignored in the \\ + & calculation. \\ + & \\ +$\left [ 5 \right ] $ & Improve the previous algorithm to have a working time of at most \\ + & $O \left (2^{(k-1)}n + \left ({2n^2 \over k} \right ) \right )$ for an appropriate choice of $k$. Again ignore \\ + & the cost of addition. \\ + & \\ +$\left [ 2 \right ] $ & Devise a chart to find optimal values of $k$ for the previous problem \\ + & for $n = 64 \ldots 1024$ in steps of $64$. \\ + & \\ +$\left [ 2 \right ] $ & Using only algorithms mp\_abs and mp\_sub devise another method for \\ + & calculating the result of a signed comparison. \\ + & +\end{tabular} + +\chapter{Multiplication and Squaring} +\section{The Multipliers} +For most number theoretic problems including certain public key cryptographic algorithms, the ``multipliers'' form the most important subset of +algorithms of any multiple precision integer package. The set of multiplier algorithms include integer multiplication, squaring and modular reduction +where in each of the algorithms single precision multiplication is the dominant operation performed. This chapter will discuss integer multiplication +and squaring, leaving modular reductions for the subsequent chapter. + +The importance of the multiplier algorithms is for the most part driven by the fact that certain popular public key algorithms are based on modular +exponentiation, that is computing $d \equiv a^b \mbox{ (mod }c\mbox{)}$ for some arbitrary choice of $a$, $b$, $c$ and $d$. During a modular +exponentiation the majority\footnote{Roughly speaking a modular exponentiation will spend about 40\% of the time performing modular reductions, +35\% of the time performing squaring and 25\% of the time performing multiplications.} of the processor time is spent performing single precision +multiplications. + +For centuries general purpose multiplication has required a lengthly $O(n^2)$ process, whereby each digit of one multiplicand has to be multiplied +against every digit of the other multiplicand. Traditional long-hand multiplication is based on this process; while the techniques can differ the +overall algorithm used is essentially the same. Only ``recently'' have faster algorithms been studied. First Karatsuba multiplication was discovered in +1962. This algorithm can multiply two numbers with considerably fewer single precision multiplications when compared to the long-hand approach. +This technique led to the discovery of polynomial basis algorithms (\textit{good reference?}) and subquently Fourier Transform based solutions. + +\section{Multiplication} +\subsection{The Baseline Multiplication} +\label{sec:basemult} +\index{baseline multiplication} +Computing the product of two integers in software can be achieved using a trivial adaptation of the standard $O(n^2)$ long-hand multiplication +algorithm that school children are taught. The algorithm is considered an $O(n^2)$ algorithm since for two $n$-digit inputs $n^2$ single precision +multiplications are required. More specifically for a $m$ and $n$ digit input $m \cdot n$ single precision multiplications are required. To +simplify most discussions, it will be assumed that the inputs have comparable number of digits. + +The ``baseline multiplication'' algorithm is designed to act as the ``catch-all'' algorithm, only to be used when the faster algorithms cannot be +used. This algorithm does not use any particularly interesting optimizations and should ideally be avoided if possible. One important +facet of this algorithm, is that it has been modified to only produce a certain amount of output digits as resolution. The importance of this +modification will become evident during the discussion of Barrett modular reduction. Recall that for a $n$ and $m$ digit input the product +will be at most $n + m$ digits. Therefore, this algorithm can be reduced to a full multiplier by having it produce $n + m$ digits of the product. + +Recall from ~GAMMA~ the definition of $\gamma$ as the number of bits in the type \textbf{mp\_digit}. We shall now extend the variable set to +include $\alpha$ which shall represent the number of bits in the type \textbf{mp\_word}. This implies that $2^{\alpha} > 2 \cdot \beta^2$. The +constant $\delta = 2^{\alpha - 2lg(\beta)}$ will represent the maximal weight of any column in a product (\textit{see ~COMBA~ for more information}). + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{s\_mp\_mul\_digs}. \\ +\textbf{Input}. mp\_int $a$, mp\_int $b$ and an integer $digs$ \\ +\textbf{Output}. $c \leftarrow \vert a \vert \cdot \vert b \vert \mbox{ (mod }\beta^{digs}\mbox{)}$. \\ +\hline \\ +1. If min$(a.used, b.used) < \delta$ then do \\ +\hspace{3mm}1.1 Calculate $c = \vert a \vert \cdot \vert b \vert$ by the Comba method (\textit{see algorithm~\ref{fig:COMBAMULT}}). \\ +\hspace{3mm}1.2 Return the result of step 1.1 \\ +\\ +Allocate and initialize a temporary mp\_int. \\ +2. Init $t$ to be of size $digs$ \\ +3. If step 2 failed return(\textit{MP\_MEM}). \\ +4. $t.used \leftarrow digs$ \\ +\\ +Compute the product. \\ +5. for $ix$ from $0$ to $a.used - 1$ do \\ +\hspace{3mm}5.1 $u \leftarrow 0$ \\ +\hspace{3mm}5.2 $pb \leftarrow \mbox{min}(b.used, digs - ix)$ \\ +\hspace{3mm}5.3 If $pb < 1$ then goto step 6. \\ +\hspace{3mm}5.4 for $iy$ from $0$ to $pb - 1$ do \\ +\hspace{6mm}5.4.1 $\hat r \leftarrow t_{iy + ix} + a_{ix} \cdot b_{iy} + u$ \\ +\hspace{6mm}5.4.2 $t_{iy + ix} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{6mm}5.4.3 $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\ +\hspace{3mm}5.5 if $ix + pb < digs$ then do \\ +\hspace{6mm}5.5.1 $t_{ix + pb} \leftarrow u$ \\ +6. Clamp excess digits of $t$. \\ +7. Swap $c$ with $t$ \\ +8. Clear $t$ \\ +9. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm s\_mp\_mul\_digs} +\end{figure} + +\textbf{Algorithm s\_mp\_mul\_digs.} +This algorithm computes the unsigned product of two inputs $a$ and $b$, limited to an output precision of $digs$ digits. While it may seem +a bit awkward to modify the function from its simple $O(n^2)$ description, the usefulness of partial multipliers will arise in a subsequent +algorithm. The algorithm is loosely based on algorithm 14.12 from \cite[pp. 595]{HAC} and is similar to Algorithm M of Knuth \cite[pp. 268]{TAOCPV2}. +Algorithm s\_mp\_mul\_digs differs from these cited references since it can produce a variable output precision regardless of the precision of the +inputs. + +The first thing this algorithm checks for is whether a Comba multiplier can be used instead. If the minimum digit count of either +input is less than $\delta$, then the Comba method may be used instead. After the Comba method is ruled out, the baseline algorithm begins. A +temporary mp\_int variable $t$ is used to hold the intermediate result of the product. This allows the algorithm to be used to +compute products when either $a = c$ or $b = c$ without overwriting the inputs. + +All of step 5 is the infamous $O(n^2)$ multiplication loop slightly modified to only produce upto $digs$ digits of output. The $pb$ variable +is given the count of digits to read from $b$ inside the nested loop. If $pb \le 1$ then no more output digits can be produced and the algorithm +will exit the loop. The best way to think of the loops are as a series of $pb \times 1$ multiplications. That is, in each pass of the +innermost loop $a_{ix}$ is multiplied against $b$ and the result is added (\textit{with an appropriate shift}) to $t$. + +For example, consider multiplying $576$ by $241$. That is equivalent to computing $10^0(1)(576) + 10^1(4)(576) + 10^2(2)(576)$ which is best +visualized in the following table. + +\begin{figure}[here] +\begin{center} +\begin{tabular}{|c|c|c|c|c|c|l|} +\hline && & 5 & 7 & 6 & \\ +\hline $\times$&& & 2 & 4 & 1 & \\ +\hline &&&&&&\\ + && & 5 & 7 & 6 & $10^0(1)(576)$ \\ + &2 & 3 & 6 & 1 & 6 & $10^1(4)(576) + 10^0(1)(576)$ \\ + 1 & 3 & 8 & 8 & 1 & 6 & $10^2(2)(576) + 10^1(4)(576) + 10^0(1)(576)$ \\ +\hline +\end{tabular} +\end{center} +\caption{Long-Hand Multiplication Diagram} +\end{figure} + +Each row of the product is added to the result after being shifted to the left (\textit{multiplied by a power of the radix}) by the appropriate +count. That is in pass $ix$ of the inner loop the product is added starting at the $ix$'th digit of the reult. + +Step 5.4.1 introduces the hat symbol (\textit{e.g. $\hat r$}) which represents a double precision variable. The multiplication on that step +is assumed to be a double wide output single precision multiplication. That is, two single precision variables are multiplied to produce a +double precision result. The step is somewhat optimized from a long-hand multiplication algorithm because the carry from the addition in step +5.4.1 is propagated through the nested loop. If the carry was not propagated immediately it would overflow the single precision digit +$t_{ix+iy}$ and the result would be lost. + +At step 5.5 the nested loop is finished and any carry that was left over should be forwarded. The carry does not have to be added to the $ix+pb$'th +digit since that digit is assumed to be zero at this point. However, if $ix + pb \ge digs$ the carry is not set as it would make the result +exceed the precision requested. + +EXAM,bn_s_mp_mul_digs.c + +First we determine (line @30,if@) if the Comba method can be used first since it's faster. The conditions for +sing the Comba routine are that min$(a.used, b.used) < \delta$ and the number of digits of output is less than +\textbf{MP\_WARRAY}. This new constant is used to control the stack usage in the Comba routines. By default it is +set to $\delta$ but can be reduced when memory is at a premium. + +If we cannot use the Comba method we proceed to setup the baseline routine. We allocate the the destination mp\_int +$t$ (line @36,init@) to the exact size of the output to avoid further re--allocations. At this point we now +begin the $O(n^2)$ loop. + +This implementation of multiplication has the caveat that it can be trimmed to only produce a variable number of +digits as output. In each iteration of the outer loop the $pb$ variable is set (line @48,MIN@) to the maximum +number of inner loop iterations. + +Inside the inner loop we calculate $\hat r$ as the mp\_word product of the two mp\_digits and the addition of the +carry from the previous iteration. A particularly important observation is that most modern optimizing +C compilers (GCC for instance) can recognize that a $N \times N \rightarrow 2N$ multiplication is all that +is required for the product. In x86 terms for example, this means using the MUL instruction. + +Each digit of the product is stored in turn (line @68,tmpt@) and the carry propagated (line @71,>>@) to the +next iteration. + +\subsection{Faster Multiplication by the ``Comba'' Method} +MARK,COMBA + +One of the huge drawbacks of the ``baseline'' algorithms is that at the $O(n^2)$ level the carry must be +computed and propagated upwards. This makes the nested loop very sequential and hard to unroll and implement +in parallel. The ``Comba'' \cite{COMBA} method is named after little known (\textit{in cryptographic venues}) Paul G. +Comba who described a method of implementing fast multipliers that do not require nested carry fixup operations. As an +interesting aside it seems that Paul Barrett describes a similar technique in his 1986 paper \cite{BARRETT} written +five years before. + +At the heart of the Comba technique is once again the long-hand algorithm. Except in this case a slight +twist is placed on how the columns of the result are produced. In the standard long-hand algorithm rows of products +are produced then added together to form the final result. In the baseline algorithm the columns are added together +after each iteration to get the result instantaneously. + +In the Comba algorithm the columns of the result are produced entirely independently of each other. That is at +the $O(n^2)$ level a simple multiplication and addition step is performed. The carries of the columns are propagated +after the nested loop to reduce the amount of work requiored. Succintly the first step of the algorithm is to compute +the product vector $\vec x$ as follows. + +\begin{equation} +\vec x_n = \sum_{i+j = n} a_ib_j, \forall n \in \lbrace 0, 1, 2, \ldots, i + j \rbrace +\end{equation} + +Where $\vec x_n$ is the $n'th$ column of the output vector. Consider the following example which computes the vector $\vec x$ for the multiplication +of $576$ and $241$. + +\newpage\begin{figure}[here] +\begin{small} +\begin{center} +\begin{tabular}{|c|c|c|c|c|c|} + \hline & & 5 & 7 & 6 & First Input\\ + \hline $\times$ & & 2 & 4 & 1 & Second Input\\ +\hline & & $1 \cdot 5 = 5$ & $1 \cdot 7 = 7$ & $1 \cdot 6 = 6$ & First pass \\ + & $4 \cdot 5 = 20$ & $4 \cdot 7+5=33$ & $4 \cdot 6+7=31$ & 6 & Second pass \\ + $2 \cdot 5 = 10$ & $2 \cdot 7 + 20 = 34$ & $2 \cdot 6+33=45$ & 31 & 6 & Third pass \\ +\hline 10 & 34 & 45 & 31 & 6 & Final Result \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Comba Multiplication Diagram} +\end{figure} + +At this point the vector $x = \left < 10, 34, 45, 31, 6 \right >$ is the result of the first step of the Comba multipler. +Now the columns must be fixed by propagating the carry upwards. The resultant vector will have one extra dimension over the input vector which is +congruent to adding a leading zero digit. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{Comba Fixup}. \\ +\textbf{Input}. Vector $\vec x$ of dimension $k$ \\ +\textbf{Output}. Vector $\vec x$ such that the carries have been propagated. \\ +\hline \\ +1. for $n$ from $0$ to $k - 1$ do \\ +\hspace{3mm}1.1 $\vec x_{n+1} \leftarrow \vec x_{n+1} + \lfloor \vec x_{n}/\beta \rfloor$ \\ +\hspace{3mm}1.2 $\vec x_{n} \leftarrow \vec x_{n} \mbox{ (mod }\beta\mbox{)}$ \\ +2. Return($\vec x$). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm Comba Fixup} +\end{figure} + +With that algorithm and $k = 5$ and $\beta = 10$ the following vector is produced $\vec x= \left < 1, 3, 8, 8, 1, 6 \right >$. In this case +$241 \cdot 576$ is in fact $138816$ and the procedure succeeded. If the algorithm is correct and as will be demonstrated shortly more +efficient than the baseline algorithm why not simply always use this algorithm? + +\subsubsection{Column Weight.} +At the nested $O(n^2)$ level the Comba method adds the product of two single precision variables to each column of the output +independently. A serious obstacle is if the carry is lost, due to lack of precision before the algorithm has a chance to fix +the carries. For example, in the multiplication of two three-digit numbers the third column of output will be the sum of +three single precision multiplications. If the precision of the accumulator for the output digits is less then $3 \cdot (\beta - 1)^2$ then +an overflow can occur and the carry information will be lost. For any $m$ and $n$ digit inputs the maximum weight of any column is +min$(m, n)$ which is fairly obvious. + +The maximum number of terms in any column of a product is known as the ``column weight'' and strictly governs when the algorithm can be used. Recall +from earlier that a double precision type has $\alpha$ bits of resolution and a single precision digit has $lg(\beta)$ bits of precision. Given these +two quantities we must not violate the following + +\begin{equation} +k \cdot \left (\beta - 1 \right )^2 < 2^{\alpha} +\end{equation} + +Which reduces to + +\begin{equation} +k \cdot \left ( \beta^2 - 2\beta + 1 \right ) < 2^{\alpha} +\end{equation} + +Let $\rho = lg(\beta)$ represent the number of bits in a single precision digit. By further re-arrangement of the equation the final solution is +found. + +\begin{equation} +k < {{2^{\alpha}} \over {\left (2^{2\rho} - 2^{\rho + 1} + 1 \right )}} +\end{equation} + +The defaults for LibTomMath are $\beta = 2^{28}$ and $\alpha = 2^{64}$ which means that $k$ is bounded by $k < 257$. In this configuration +the smaller input may not have more than $256$ digits if the Comba method is to be used. This is quite satisfactory for most applications since +$256$ digits would allow for numbers in the range of $0 \le x < 2^{7168}$ which, is much larger than most public key cryptographic algorithms require. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{fast\_s\_mp\_mul\_digs}. \\ +\textbf{Input}. mp\_int $a$, mp\_int $b$ and an integer $digs$ \\ +\textbf{Output}. $c \leftarrow \vert a \vert \cdot \vert b \vert \mbox{ (mod }\beta^{digs}\mbox{)}$. \\ +\hline \\ +Place an array of \textbf{MP\_WARRAY} single precision digits named $W$ on the stack. \\ +1. If $c.alloc < digs$ then grow $c$ to $digs$ digits. (\textit{mp\_grow}) \\ +2. If step 1 failed return(\textit{MP\_MEM}).\\ +\\ +3. $pa \leftarrow \mbox{MIN}(digs, a.used + b.used)$ \\ +\\ +4. $\_ \hat W \leftarrow 0$ \\ +5. for $ix$ from 0 to $pa - 1$ do \\ +\hspace{3mm}5.1 $ty \leftarrow \mbox{MIN}(b.used - 1, ix)$ \\ +\hspace{3mm}5.2 $tx \leftarrow ix - ty$ \\ +\hspace{3mm}5.3 $iy \leftarrow \mbox{MIN}(a.used - tx, ty + 1)$ \\ +\hspace{3mm}5.4 for $iz$ from 0 to $iy - 1$ do \\ +\hspace{6mm}5.4.1 $\_ \hat W \leftarrow \_ \hat W + a_{tx+iy}b_{ty-iy}$ \\ +\hspace{3mm}5.5 $W_{ix} \leftarrow \_ \hat W (\mbox{mod }\beta)$\\ +\hspace{3mm}5.6 $\_ \hat W \leftarrow \lfloor \_ \hat W / \beta \rfloor$ \\ +\\ +6. $oldused \leftarrow c.used$ \\ +7. $c.used \leftarrow digs$ \\ +8. for $ix$ from $0$ to $pa$ do \\ +\hspace{3mm}8.1 $c_{ix} \leftarrow W_{ix}$ \\ +9. for $ix$ from $pa + 1$ to $oldused - 1$ do \\ +\hspace{3mm}9.1 $c_{ix} \leftarrow 0$ \\ +\\ +10. Clamp $c$. \\ +11. Return MP\_OKAY. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm fast\_s\_mp\_mul\_digs} +\label{fig:COMBAMULT} +\end{figure} + +\textbf{Algorithm fast\_s\_mp\_mul\_digs.} +This algorithm performs the unsigned multiplication of $a$ and $b$ using the Comba method limited to $digs$ digits of precision. + +The outer loop of this algorithm is more complicated than that of the baseline multiplier. This is because on the inside of the +loop we want to produce one column per pass. This allows the accumulator $\_ \hat W$ to be placed in CPU registers and +reduce the memory bandwidth to two \textbf{mp\_digit} reads per iteration. + +The $ty$ variable is set to the minimum count of $ix$ or the number of digits in $b$. That way if $a$ has more digits than +$b$ this will be limited to $b.used - 1$. The $tx$ variable is set to the to the distance past $b.used$ the variable +$ix$ is. This is used for the immediately subsequent statement where we find $iy$. + +The variable $iy$ is the minimum digits we can read from either $a$ or $b$ before running out. Computing one column at a time +means we have to scan one integer upwards and the other downwards. $a$ starts at $tx$ and $b$ starts at $ty$. In each +pass we are producing the $ix$'th output column and we note that $tx + ty = ix$. As we move $tx$ upwards we have to +move $ty$ downards so the equality remains valid. The $iy$ variable is the number of iterations until +$tx \ge a.used$ or $ty < 0$ occurs. + +After every inner pass we store the lower half of the accumulator into $W_{ix}$ and then propagate the carry of the accumulator +into the next round by dividing $\_ \hat W$ by $\beta$. + +To measure the benefits of the Comba method over the baseline method consider the number of operations that are required. If the +cost in terms of time of a multiply and addition is $p$ and the cost of a carry propagation is $q$ then a baseline multiplication would require +$O \left ((p + q)n^2 \right )$ time to multiply two $n$-digit numbers. The Comba method requires only $O(pn^2 + qn)$ time, however in practice, +the speed increase is actually much more. With $O(n)$ space the algorithm can be reduced to $O(pn + qn)$ time by implementing the $n$ multiply +and addition operations in the nested loop in parallel. + +EXAM,bn_fast_s_mp_mul_digs.c + +As per the pseudo--code we first calculate $pa$ (line @47,MIN@) as the number of digits to output. Next we begin the outer loop +to produce the individual columns of the product. We use the two aliases $tmpx$ and $tmpy$ (lines @61,tmpx@, @62,tmpy@) to point +inside the two multiplicands quickly. + +The inner loop (lines @70,for@ to @72,}@) of this implementation is where the tradeoff come into play. Originally this comba +implementation was ``row--major'' which means it adds to each of the columns in each pass. After the outer loop it would then fix +the carries. This was very fast except it had an annoying drawback. You had to read a mp\_word and two mp\_digits and write +one mp\_word per iteration. On processors such as the Athlon XP and P4 this did not matter much since the cache bandwidth +is very high and it can keep the ALU fed with data. It did, however, matter on older and embedded cpus where cache is often +slower and also often doesn't exist. This new algorithm only performs two reads per iteration under the assumption that the +compiler has aliased $\_ \hat W$ to a CPU register. + +After the inner loop we store the current accumulator in $W$ and shift $\_ \hat W$ (lines @75,W[ix]@, @78,>>@) to forward it as +a carry for the next pass. After the outer loop we use the final carry (line @82,W[ix]@) as the last digit of the product. + +\subsection{Polynomial Basis Multiplication} +To break the $O(n^2)$ barrier in multiplication requires a completely different look at integer multiplication. In the following algorithms +the use of polynomial basis representation for two integers $a$ and $b$ as $f(x) = \sum_{i=0}^{n} a_i x^i$ and +$g(x) = \sum_{i=0}^{n} b_i x^i$ respectively, is required. In this system both $f(x)$ and $g(x)$ have $n + 1$ terms and are of the $n$'th degree. + +The product $a \cdot b \equiv f(x)g(x)$ is the polynomial $W(x) = \sum_{i=0}^{2n} w_i x^i$. The coefficients $w_i$ will +directly yield the desired product when $\beta$ is substituted for $x$. The direct solution to solve for the $2n + 1$ coefficients +requires $O(n^2)$ time and would in practice be slower than the Comba technique. + +However, numerical analysis theory indicates that only $2n + 1$ distinct points in $W(x)$ are required to determine the values of the $2n + 1$ unknown +coefficients. This means by finding $\zeta_y = W(y)$ for $2n + 1$ small values of $y$ the coefficients of $W(x)$ can be found with +Gaussian elimination. This technique is also occasionally refered to as the \textit{interpolation technique} (\textit{references please...}) since in +effect an interpolation based on $2n + 1$ points will yield a polynomial equivalent to $W(x)$. + +The coefficients of the polynomial $W(x)$ are unknown which makes finding $W(y)$ for any value of $y$ impossible. However, since +$W(x) = f(x)g(x)$ the equivalent $\zeta_y = f(y) g(y)$ can be used in its place. The benefit of this technique stems from the +fact that $f(y)$ and $g(y)$ are much smaller than either $a$ or $b$ respectively. As a result finding the $2n + 1$ relations required +by multiplying $f(y)g(y)$ involves multiplying integers that are much smaller than either of the inputs. + +When picking points to gather relations there are always three obvious points to choose, $y = 0, 1$ and $ \infty$. The $\zeta_0$ term +is simply the product $W(0) = w_0 = a_0 \cdot b_0$. The $\zeta_1$ term is the product +$W(1) = \left (\sum_{i = 0}^{n} a_i \right ) \left (\sum_{i = 0}^{n} b_i \right )$. The third point $\zeta_{\infty}$ is less obvious but rather +simple to explain. The $2n + 1$'th coefficient of $W(x)$ is numerically equivalent to the most significant column in an integer multiplication. +The point at $\infty$ is used symbolically to represent the most significant column, that is $W(\infty) = w_{2n} = a_nb_n$. Note that the +points at $y = 0$ and $\infty$ yield the coefficients $w_0$ and $w_{2n}$ directly. + +If more points are required they should be of small values and powers of two such as $2^q$ and the related \textit{mirror points} +$\left (2^q \right )^{2n} \cdot \zeta_{2^{-q}}$ for small values of $q$. The term ``mirror point'' stems from the fact that +$\left (2^q \right )^{2n} \cdot \zeta_{2^{-q}}$ can be calculated in the exact opposite fashion as $\zeta_{2^q}$. For +example, when $n = 2$ and $q = 1$ then following two equations are equivalent to the point $\zeta_{2}$ and its mirror. + +\begin{eqnarray} +\zeta_{2} = f(2)g(2) = (4a_2 + 2a_1 + a_0)(4b_2 + 2b_1 + b_0) \nonumber \\ +16 \cdot \zeta_{1 \over 2} = 4f({1\over 2}) \cdot 4g({1 \over 2}) = (a_2 + 2a_1 + 4a_0)(b_2 + 2b_1 + 4b_0) +\end{eqnarray} + +Using such points will allow the values of $f(y)$ and $g(y)$ to be independently calculated using only left shifts. For example, when $n = 2$ the +polynomial $f(2^q)$ is equal to $2^q((2^qa_2) + a_1) + a_0$. This technique of polynomial representation is known as Horner's method. + +As a general rule of the algorithm when the inputs are split into $n$ parts each there are $2n - 1$ multiplications. Each multiplication is of +multiplicands that have $n$ times fewer digits than the inputs. The asymptotic running time of this algorithm is +$O \left ( k^{lg_n(2n - 1)} \right )$ for $k$ digit inputs (\textit{assuming they have the same number of digits}). Figure~\ref{fig:exponent} +summarizes the exponents for various values of $n$. + +\begin{figure} +\begin{center} +\begin{tabular}{|c|c|c|} +\hline \textbf{Split into $n$ Parts} & \textbf{Exponent} & \textbf{Notes}\\ +\hline $2$ & $1.584962501$ & This is Karatsuba Multiplication. \\ +\hline $3$ & $1.464973520$ & This is Toom-Cook Multiplication. \\ +\hline $4$ & $1.403677461$ &\\ +\hline $5$ & $1.365212389$ &\\ +\hline $10$ & $1.278753601$ &\\ +\hline $100$ & $1.149426538$ &\\ +\hline $1000$ & $1.100270931$ &\\ +\hline $10000$ & $1.075252070$ &\\ +\hline +\end{tabular} +\end{center} +\caption{Asymptotic Running Time of Polynomial Basis Multiplication} +\label{fig:exponent} +\end{figure} + +At first it may seem like a good idea to choose $n = 1000$ since the exponent is approximately $1.1$. However, the overhead +of solving for the 2001 terms of $W(x)$ will certainly consume any savings the algorithm could offer for all but exceedingly large +numbers. + +\subsubsection{Cutoff Point} +The polynomial basis multiplication algorithms all require fewer single precision multiplications than a straight Comba approach. However, +the algorithms incur an overhead (\textit{at the $O(n)$ work level}) since they require a system of equations to be solved. This makes the +polynomial basis approach more costly to use with small inputs. + +Let $m$ represent the number of digits in the multiplicands (\textit{assume both multiplicands have the same number of digits}). There exists a +point $y$ such that when $m < y$ the polynomial basis algorithms are more costly than Comba, when $m = y$ they are roughly the same cost and +when $m > y$ the Comba methods are slower than the polynomial basis algorithms. + +The exact location of $y$ depends on several key architectural elements of the computer platform in question. + +\begin{enumerate} +\item The ratio of clock cycles for single precision multiplication versus other simpler operations such as addition, shifting, etc. For example +on the AMD Athlon the ratio is roughly $17 : 1$ while on the Intel P4 it is $29 : 1$. The higher the ratio in favour of multiplication the lower +the cutoff point $y$ will be. + +\item The complexity of the linear system of equations (\textit{for the coefficients of $W(x)$}) is. Generally speaking as the number of splits +grows the complexity grows substantially. Ideally solving the system will only involve addition, subtraction and shifting of integers. This +directly reflects on the ratio previous mentioned. + +\item To a lesser extent memory bandwidth and function call overheads. Provided the values are in the processor cache this is less of an +influence over the cutoff point. + +\end{enumerate} + +A clean cutoff point separation occurs when a point $y$ is found such that all of the cutoff point conditions are met. For example, if the point +is too low then there will be values of $m$ such that $m > y$ and the Comba method is still faster. Finding the cutoff points is fairly simple when +a high resolution timer is available. + +\subsection{Karatsuba Multiplication} +Karatsuba \cite{KARA} multiplication when originally proposed in 1962 was among the first set of algorithms to break the $O(n^2)$ barrier for +general purpose multiplication. Given two polynomial basis representations $f(x) = ax + b$ and $g(x) = cx + d$, Karatsuba proved with +light algebra \cite{KARAP} that the following polynomial is equivalent to multiplication of the two integers the polynomials represent. + +\begin{equation} +f(x) \cdot g(x) = acx^2 + ((a + b)(c + d) - (ac + bd))x + bd +\end{equation} + +Using the observation that $ac$ and $bd$ could be re-used only three half sized multiplications would be required to produce the product. Applying +this algorithm recursively, the work factor becomes $O(n^{lg(3)})$ which is substantially better than the work factor $O(n^2)$ of the Comba technique. It turns +out what Karatsuba did not know or at least did not publish was that this is simply polynomial basis multiplication with the points +$\zeta_0$, $\zeta_{\infty}$ and $\zeta_{1}$. Consider the resultant system of equations. + +\begin{center} +\begin{tabular}{rcrcrcrc} +$\zeta_{0}$ & $=$ & & & & & $w_0$ \\ +$\zeta_{1}$ & $=$ & $w_2$ & $+$ & $w_1$ & $+$ & $w_0$ \\ +$\zeta_{\infty}$ & $=$ & $w_2$ & & & & \\ +\end{tabular} +\end{center} + +By adding the first and last equation to the equation in the middle the term $w_1$ can be isolated and all three coefficients solved for. The simplicity +of this system of equations has made Karatsuba fairly popular. In fact the cutoff point is often fairly low\footnote{With LibTomMath 0.18 it is 70 and 109 digits for the Intel P4 and AMD Athlon respectively.} +making it an ideal algorithm to speed up certain public key cryptosystems such as RSA and Diffie-Hellman. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_karatsuba\_mul}. \\ +\textbf{Input}. mp\_int $a$ and mp\_int $b$ \\ +\textbf{Output}. $c \leftarrow \vert a \vert \cdot \vert b \vert$ \\ +\hline \\ +1. Init the following mp\_int variables: $x0$, $x1$, $y0$, $y1$, $t1$, $x0y0$, $x1y1$.\\ +2. If step 2 failed then return(\textit{MP\_MEM}). \\ +\\ +Split the input. e.g. $a = x1 \cdot \beta^B + x0$ \\ +3. $B \leftarrow \mbox{min}(a.used, b.used)/2$ \\ +4. $x0 \leftarrow a \mbox{ (mod }\beta^B\mbox{)}$ (\textit{mp\_mod\_2d}) \\ +5. $y0 \leftarrow b \mbox{ (mod }\beta^B\mbox{)}$ \\ +6. $x1 \leftarrow \lfloor a / \beta^B \rfloor$ (\textit{mp\_rshd}) \\ +7. $y1 \leftarrow \lfloor b / \beta^B \rfloor$ \\ +\\ +Calculate the three products. \\ +8. $x0y0 \leftarrow x0 \cdot y0$ (\textit{mp\_mul}) \\ +9. $x1y1 \leftarrow x1 \cdot y1$ \\ +10. $t1 \leftarrow x1 + x0$ (\textit{mp\_add}) \\ +11. $x0 \leftarrow y1 + y0$ \\ +12. $t1 \leftarrow t1 \cdot x0$ \\ +\\ +Calculate the middle term. \\ +13. $x0 \leftarrow x0y0 + x1y1$ \\ +14. $t1 \leftarrow t1 - x0$ (\textit{s\_mp\_sub}) \\ +\\ +Calculate the final product. \\ +15. $t1 \leftarrow t1 \cdot \beta^B$ (\textit{mp\_lshd}) \\ +16. $x1y1 \leftarrow x1y1 \cdot \beta^{2B}$ \\ +17. $t1 \leftarrow x0y0 + t1$ \\ +18. $c \leftarrow t1 + x1y1$ \\ +19. Clear all of the temporary variables. \\ +20. Return(\textit{MP\_OKAY}).\\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_karatsuba\_mul} +\end{figure} + +\textbf{Algorithm mp\_karatsuba\_mul.} +This algorithm computes the unsigned product of two inputs using the Karatsuba multiplication algorithm. It is loosely based on the description +from Knuth \cite[pp. 294-295]{TAOCPV2}. + +\index{radix point} +In order to split the two inputs into their respective halves, a suitable \textit{radix point} must be chosen. The radix point chosen must +be used for both of the inputs meaning that it must be smaller than the smallest input. Step 3 chooses the radix point $B$ as half of the +smallest input \textbf{used} count. After the radix point is chosen the inputs are split into lower and upper halves. Step 4 and 5 +compute the lower halves. Step 6 and 7 computer the upper halves. + +After the halves have been computed the three intermediate half-size products must be computed. Step 8 and 9 compute the trivial products +$x0 \cdot y0$ and $x1 \cdot y1$. The mp\_int $x0$ is used as a temporary variable after $x1 + x0$ has been computed. By using $x0$ instead +of an additional temporary variable, the algorithm can avoid an addition memory allocation operation. + +The remaining steps 13 through 18 compute the Karatsuba polynomial through a variety of digit shifting and addition operations. + +EXAM,bn_mp_karatsuba_mul.c + +The new coding element in this routine, not seen in previous routines, is the usage of goto statements. The conventional +wisdom is that goto statements should be avoided. This is generally true, however when every single function call can fail, it makes sense +to handle error recovery with a single piece of code. Lines @61,if@ to @75,if@ handle initializing all of the temporary variables +required. Note how each of the if statements goes to a different label in case of failure. This allows the routine to correctly free only +the temporaries that have been successfully allocated so far. + +The temporary variables are all initialized using the mp\_init\_size routine since they are expected to be large. This saves the +additional reallocation that would have been necessary. Also $x0$, $x1$, $y0$ and $y1$ have to be able to hold at least their respective +number of digits for the next section of code. + +The first algebraic portion of the algorithm is to split the two inputs into their halves. However, instead of using mp\_mod\_2d and mp\_rshd +to extract the halves, the respective code has been placed inline within the body of the function. To initialize the halves, the \textbf{used} and +\textbf{sign} members are copied first. The first for loop on line @98,for@ copies the lower halves. Since they are both the same magnitude it +is simpler to calculate both lower halves in a single loop. The for loop on lines @104,for@ and @109,for@ calculate the upper halves $x1$ and +$y1$ respectively. + +By inlining the calculation of the halves, the Karatsuba multiplier has a slightly lower overhead and can be used for smaller magnitude inputs. + +When line @152,err@ is reached, the algorithm has completed succesfully. The ``error status'' variable $err$ is set to \textbf{MP\_OKAY} so that +the same code that handles errors can be used to clear the temporary variables and return. + +\subsection{Toom-Cook $3$-Way Multiplication} +Toom-Cook $3$-Way \cite{TOOM} multiplication is essentially the polynomial basis algorithm for $n = 2$ except that the points are +chosen such that $\zeta$ is easy to compute and the resulting system of equations easy to reduce. Here, the points $\zeta_{0}$, +$16 \cdot \zeta_{1 \over 2}$, $\zeta_1$, $\zeta_2$ and $\zeta_{\infty}$ make up the five required points to solve for the coefficients +of the $W(x)$. + +With the five relations that Toom-Cook specifies, the following system of equations is formed. + +\begin{center} +\begin{tabular}{rcrcrcrcrcr} +$\zeta_0$ & $=$ & $0w_4$ & $+$ & $0w_3$ & $+$ & $0w_2$ & $+$ & $0w_1$ & $+$ & $1w_0$ \\ +$16 \cdot \zeta_{1 \over 2}$ & $=$ & $1w_4$ & $+$ & $2w_3$ & $+$ & $4w_2$ & $+$ & $8w_1$ & $+$ & $16w_0$ \\ +$\zeta_1$ & $=$ & $1w_4$ & $+$ & $1w_3$ & $+$ & $1w_2$ & $+$ & $1w_1$ & $+$ & $1w_0$ \\ +$\zeta_2$ & $=$ & $16w_4$ & $+$ & $8w_3$ & $+$ & $4w_2$ & $+$ & $2w_1$ & $+$ & $1w_0$ \\ +$\zeta_{\infty}$ & $=$ & $1w_4$ & $+$ & $0w_3$ & $+$ & $0w_2$ & $+$ & $0w_1$ & $+$ & $0w_0$ \\ +\end{tabular} +\end{center} + +A trivial solution to this matrix requires $12$ subtractions, two multiplications by a small power of two, two divisions by a small power +of two, two divisions by three and one multiplication by three. All of these $19$ sub-operations require less than quadratic time, meaning that +the algorithm can be faster than a baseline multiplication. However, the greater complexity of this algorithm places the cutoff point +(\textbf{TOOM\_MUL\_CUTOFF}) where Toom-Cook becomes more efficient much higher than the Karatsuba cutoff point. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_toom\_mul}. \\ +\textbf{Input}. mp\_int $a$ and mp\_int $b$ \\ +\textbf{Output}. $c \leftarrow a \cdot b $ \\ +\hline \\ +Split $a$ and $b$ into three pieces. E.g. $a = a_2 \beta^{2k} + a_1 \beta^{k} + a_0$ \\ +1. $k \leftarrow \lfloor \mbox{min}(a.used, b.used) / 3 \rfloor$ \\ +2. $a_0 \leftarrow a \mbox{ (mod }\beta^{k}\mbox{)}$ \\ +3. $a_1 \leftarrow \lfloor a / \beta^k \rfloor$, $a_1 \leftarrow a_1 \mbox{ (mod }\beta^{k}\mbox{)}$ \\ +4. $a_2 \leftarrow \lfloor a / \beta^{2k} \rfloor$, $a_2 \leftarrow a_2 \mbox{ (mod }\beta^{k}\mbox{)}$ \\ +5. $b_0 \leftarrow a \mbox{ (mod }\beta^{k}\mbox{)}$ \\ +6. $b_1 \leftarrow \lfloor a / \beta^k \rfloor$, $b_1 \leftarrow b_1 \mbox{ (mod }\beta^{k}\mbox{)}$ \\ +7. $b_2 \leftarrow \lfloor a / \beta^{2k} \rfloor$, $b_2 \leftarrow b_2 \mbox{ (mod }\beta^{k}\mbox{)}$ \\ +\\ +Find the five equations for $w_0, w_1, ..., w_4$. \\ +8. $w_0 \leftarrow a_0 \cdot b_0$ \\ +9. $w_4 \leftarrow a_2 \cdot b_2$ \\ +10. $tmp_1 \leftarrow 2 \cdot a_0$, $tmp_1 \leftarrow a_1 + tmp_1$, $tmp_1 \leftarrow 2 \cdot tmp_1$, $tmp_1 \leftarrow tmp_1 + a_2$ \\ +11. $tmp_2 \leftarrow 2 \cdot b_0$, $tmp_2 \leftarrow b_1 + tmp_2$, $tmp_2 \leftarrow 2 \cdot tmp_2$, $tmp_2 \leftarrow tmp_2 + b_2$ \\ +12. $w_1 \leftarrow tmp_1 \cdot tmp_2$ \\ +13. $tmp_1 \leftarrow 2 \cdot a_2$, $tmp_1 \leftarrow a_1 + tmp_1$, $tmp_1 \leftarrow 2 \cdot tmp_1$, $tmp_1 \leftarrow tmp_1 + a_0$ \\ +14. $tmp_2 \leftarrow 2 \cdot b_2$, $tmp_2 \leftarrow b_1 + tmp_2$, $tmp_2 \leftarrow 2 \cdot tmp_2$, $tmp_2 \leftarrow tmp_2 + b_0$ \\ +15. $w_3 \leftarrow tmp_1 \cdot tmp_2$ \\ +16. $tmp_1 \leftarrow a_0 + a_1$, $tmp_1 \leftarrow tmp_1 + a_2$, $tmp_2 \leftarrow b_0 + b_1$, $tmp_2 \leftarrow tmp_2 + b_2$ \\ +17. $w_2 \leftarrow tmp_1 \cdot tmp_2$ \\ +\\ +Continued on the next page.\\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_toom\_mul} +\end{figure} + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_toom\_mul} (continued). \\ +\textbf{Input}. mp\_int $a$ and mp\_int $b$ \\ +\textbf{Output}. $c \leftarrow a \cdot b $ \\ +\hline \\ +Now solve the system of equations. \\ +18. $w_1 \leftarrow w_4 - w_1$, $w_3 \leftarrow w_3 - w_0$ \\ +19. $w_1 \leftarrow \lfloor w_1 / 2 \rfloor$, $w_3 \leftarrow \lfloor w_3 / 2 \rfloor$ \\ +20. $w_2 \leftarrow w_2 - w_0$, $w_2 \leftarrow w_2 - w_4$ \\ +21. $w_1 \leftarrow w_1 - w_2$, $w_3 \leftarrow w_3 - w_2$ \\ +22. $tmp_1 \leftarrow 8 \cdot w_0$, $w_1 \leftarrow w_1 - tmp_1$, $tmp_1 \leftarrow 8 \cdot w_4$, $w_3 \leftarrow w_3 - tmp_1$ \\ +23. $w_2 \leftarrow 3 \cdot w_2$, $w_2 \leftarrow w_2 - w_1$, $w_2 \leftarrow w_2 - w_3$ \\ +24. $w_1 \leftarrow w_1 - w_2$, $w_3 \leftarrow w_3 - w_2$ \\ +25. $w_1 \leftarrow \lfloor w_1 / 3 \rfloor, w_3 \leftarrow \lfloor w_3 / 3 \rfloor$ \\ +\\ +Now substitute $\beta^k$ for $x$ by shifting $w_0, w_1, ..., w_4$. \\ +26. for $n$ from $1$ to $4$ do \\ +\hspace{3mm}26.1 $w_n \leftarrow w_n \cdot \beta^{nk}$ \\ +27. $c \leftarrow w_0 + w_1$, $c \leftarrow c + w_2$, $c \leftarrow c + w_3$, $c \leftarrow c + w_4$ \\ +28. Return(\textit{MP\_OKAY}) \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_toom\_mul (continued)} +\end{figure} + +\textbf{Algorithm mp\_toom\_mul.} +This algorithm computes the product of two mp\_int variables $a$ and $b$ using the Toom-Cook approach. Compared to the Karatsuba multiplication, this +algorithm has a lower asymptotic running time of approximately $O(n^{1.464})$ but at an obvious cost in overhead. In this +description, several statements have been compounded to save space. The intention is that the statements are executed from left to right across +any given step. + +The two inputs $a$ and $b$ are first split into three $k$-digit integers $a_0, a_1, a_2$ and $b_0, b_1, b_2$ respectively. From these smaller +integers the coefficients of the polynomial basis representations $f(x)$ and $g(x)$ are known and can be used to find the relations required. + +The first two relations $w_0$ and $w_4$ are the points $\zeta_{0}$ and $\zeta_{\infty}$ respectively. The relation $w_1, w_2$ and $w_3$ correspond +to the points $16 \cdot \zeta_{1 \over 2}, \zeta_{2}$ and $\zeta_{1}$ respectively. These are found using logical shifts to independently find +$f(y)$ and $g(y)$ which significantly speeds up the algorithm. + +After the five relations $w_0, w_1, \ldots, w_4$ have been computed, the system they represent must be solved in order for the unknown coefficients +$w_1, w_2$ and $w_3$ to be isolated. The steps 18 through 25 perform the system reduction required as previously described. Each step of +the reduction represents the comparable matrix operation that would be performed had this been performed by pencil. For example, step 18 indicates +that row $1$ must be subtracted from row $4$ and simultaneously row $0$ subtracted from row $3$. + +Once the coeffients have been isolated, the polynomial $W(x) = \sum_{i=0}^{2n} w_i x^i$ is known. By substituting $\beta^{k}$ for $x$, the integer +result $a \cdot b$ is produced. + +EXAM,bn_mp_toom_mul.c + +The first obvious thing to note is that this algorithm is complicated. The complexity is worth it if you are multiplying very +large numbers. For example, a 10,000 digit multiplication takes approximaly 99,282,205 fewer single precision multiplications with +Toom--Cook than a Comba or baseline approach (this is a savings of more than 99$\%$). For most ``crypto'' sized numbers this +algorithm is not practical as Karatsuba has a much lower cutoff point. + +First we split $a$ and $b$ into three roughly equal portions. This has been accomplished (lines @40,mod@ to @69,rshd@) with +combinations of mp\_rshd() and mp\_mod\_2d() function calls. At this point $a = a2 \cdot \beta^2 + a1 \cdot \beta + a0$ and similiarly +for $b$. + +Next we compute the five points $w0, w1, w2, w3$ and $w4$. Recall that $w0$ and $w4$ can be computed directly from the portions so +we get those out of the way first (lines @72,mul@ and @77,mul@). Next we compute $w1, w2$ and $w3$ using Horners method. + +After this point we solve for the actual values of $w1, w2$ and $w3$ by reducing the $5 \times 5$ system which is relatively +straight forward. + +\subsection{Signed Multiplication} +Now that algorithms to handle multiplications of every useful dimensions have been developed, a rather simple finishing touch is required. So far all +of the multiplication algorithms have been unsigned multiplications which leaves only a signed multiplication algorithm to be established. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_mul}. \\ +\textbf{Input}. mp\_int $a$ and mp\_int $b$ \\ +\textbf{Output}. $c \leftarrow a \cdot b$ \\ +\hline \\ +1. If $a.sign = b.sign$ then \\ +\hspace{3mm}1.1 $sign = MP\_ZPOS$ \\ +2. else \\ +\hspace{3mm}2.1 $sign = MP\_ZNEG$ \\ +3. If min$(a.used, b.used) \ge TOOM\_MUL\_CUTOFF$ then \\ +\hspace{3mm}3.1 $c \leftarrow a \cdot b$ using algorithm mp\_toom\_mul \\ +4. else if min$(a.used, b.used) \ge KARATSUBA\_MUL\_CUTOFF$ then \\ +\hspace{3mm}4.1 $c \leftarrow a \cdot b$ using algorithm mp\_karatsuba\_mul \\ +5. else \\ +\hspace{3mm}5.1 $digs \leftarrow a.used + b.used + 1$ \\ +\hspace{3mm}5.2 If $digs < MP\_ARRAY$ and min$(a.used, b.used) \le \delta$ then \\ +\hspace{6mm}5.2.1 $c \leftarrow a \cdot b \mbox{ (mod }\beta^{digs}\mbox{)}$ using algorithm fast\_s\_mp\_mul\_digs. \\ +\hspace{3mm}5.3 else \\ +\hspace{6mm}5.3.1 $c \leftarrow a \cdot b \mbox{ (mod }\beta^{digs}\mbox{)}$ using algorithm s\_mp\_mul\_digs. \\ +6. $c.sign \leftarrow sign$ \\ +7. Return the result of the unsigned multiplication performed. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_mul} +\end{figure} + +\textbf{Algorithm mp\_mul.} +This algorithm performs the signed multiplication of two inputs. It will make use of any of the three unsigned multiplication algorithms +available when the input is of appropriate size. The \textbf{sign} of the result is not set until the end of the algorithm since algorithm +s\_mp\_mul\_digs will clear it. + +EXAM,bn_mp_mul.c + +The implementation is rather simplistic and is not particularly noteworthy. Line @22,?@ computes the sign of the result using the ``?'' +operator from the C programming language. Line @37,<<@ computes $\delta$ using the fact that $1 << k$ is equal to $2^k$. + +\section{Squaring} +\label{sec:basesquare} + +Squaring is a special case of multiplication where both multiplicands are equal. At first it may seem like there is no significant optimization +available but in fact there is. Consider the multiplication of $576$ against $241$. In total there will be nine single precision multiplications +performed which are $1\cdot 6$, $1 \cdot 7$, $1 \cdot 5$, $4 \cdot 6$, $4 \cdot 7$, $4 \cdot 5$, $2 \cdot 6$, $2 \cdot 7$ and $2 \cdot 5$. Now consider +the multiplication of $123$ against $123$. The nine products are $3 \cdot 3$, $3 \cdot 2$, $3 \cdot 1$, $2 \cdot 3$, $2 \cdot 2$, $2 \cdot 1$, +$1 \cdot 3$, $1 \cdot 2$ and $1 \cdot 1$. On closer inspection some of the products are equivalent. For example, $3 \cdot 2 = 2 \cdot 3$ +and $3 \cdot 1 = 1 \cdot 3$. + +For any $n$-digit input, there are ${{\left (n^2 + n \right)}\over 2}$ possible unique single precision multiplications required compared to the $n^2$ +required for multiplication. The following diagram gives an example of the operations required. + +\begin{figure}[here] +\begin{center} +\begin{tabular}{ccccc|c} +&&1&2&3&\\ +$\times$ &&1&2&3&\\ +\hline && $3 \cdot 1$ & $3 \cdot 2$ & $3 \cdot 3$ & Row 0\\ + & $2 \cdot 1$ & $2 \cdot 2$ & $2 \cdot 3$ && Row 1 \\ + $1 \cdot 1$ & $1 \cdot 2$ & $1 \cdot 3$ &&& Row 2 \\ +\end{tabular} +\end{center} +\caption{Squaring Optimization Diagram} +\end{figure} + +MARK,SQUARE +Starting from zero and numbering the columns from right to left a very simple pattern becomes obvious. For the purposes of this discussion let $x$ +represent the number being squared. The first observation is that in row $k$ the $2k$'th column of the product has a $\left (x_k \right)^2$ term in it. + +The second observation is that every column $j$ in row $k$ where $j \ne 2k$ is part of a double product. Every non-square term of a column will +appear twice hence the name ``double product''. Every odd column is made up entirely of double products. In fact every column is made up of double +products and at most one square (\textit{see the exercise section}). + +The third and final observation is that for row $k$ the first unique non-square term, that is, one that hasn't already appeared in an earlier row, +occurs at column $2k + 1$. For example, on row $1$ of the previous squaring, column one is part of the double product with column one from row zero. +Column two of row one is a square and column three is the first unique column. + +\subsection{The Baseline Squaring Algorithm} +The baseline squaring algorithm is meant to be a catch-all squaring algorithm. It will handle any of the input sizes that the faster routines +will not handle. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{s\_mp\_sqr}. \\ +\textbf{Input}. mp\_int $a$ \\ +\textbf{Output}. $b \leftarrow a^2$ \\ +\hline \\ +1. Init a temporary mp\_int of at least $2 \cdot a.used +1$ digits. (\textit{mp\_init\_size}) \\ +2. If step 1 failed return(\textit{MP\_MEM}) \\ +3. $t.used \leftarrow 2 \cdot a.used + 1$ \\ +4. For $ix$ from 0 to $a.used - 1$ do \\ +\hspace{3mm}Calculate the square. \\ +\hspace{3mm}4.1 $\hat r \leftarrow t_{2ix} + \left (a_{ix} \right )^2$ \\ +\hspace{3mm}4.2 $t_{2ix} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{3mm}Calculate the double products after the square. \\ +\hspace{3mm}4.3 $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\ +\hspace{3mm}4.4 For $iy$ from $ix + 1$ to $a.used - 1$ do \\ +\hspace{6mm}4.4.1 $\hat r \leftarrow 2 \cdot a_{ix}a_{iy} + t_{ix + iy} + u$ \\ +\hspace{6mm}4.4.2 $t_{ix + iy} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{6mm}4.4.3 $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\ +\hspace{3mm}Set the last carry. \\ +\hspace{3mm}4.5 While $u > 0$ do \\ +\hspace{6mm}4.5.1 $iy \leftarrow iy + 1$ \\ +\hspace{6mm}4.5.2 $\hat r \leftarrow t_{ix + iy} + u$ \\ +\hspace{6mm}4.5.3 $t_{ix + iy} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{6mm}4.5.4 $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\ +5. Clamp excess digits of $t$. (\textit{mp\_clamp}) \\ +6. Exchange $b$ and $t$. \\ +7. Clear $t$ (\textit{mp\_clear}) \\ +8. Return(\textit{MP\_OKAY}) \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm s\_mp\_sqr} +\end{figure} + +\textbf{Algorithm s\_mp\_sqr.} +This algorithm computes the square of an input using the three observations on squaring. It is based fairly faithfully on algorithm 14.16 of HAC +\cite[pp.596-597]{HAC}. Similar to algorithm s\_mp\_mul\_digs, a temporary mp\_int is allocated to hold the result of the squaring. This allows the +destination mp\_int to be the same as the source mp\_int. + +The outer loop of this algorithm begins on step 4. It is best to think of the outer loop as walking down the rows of the partial results, while +the inner loop computes the columns of the partial result. Step 4.1 and 4.2 compute the square term for each row, and step 4.3 and 4.4 propagate +the carry and compute the double products. + +The requirement that a mp\_word be able to represent the range $0 \le x < 2 \beta^2$ arises from this +very algorithm. The product $a_{ix}a_{iy}$ will lie in the range $0 \le x \le \beta^2 - 2\beta + 1$ which is obviously less than $\beta^2$ meaning that +when it is multiplied by two, it can be properly represented by a mp\_word. + +Similar to algorithm s\_mp\_mul\_digs, after every pass of the inner loop, the destination is correctly set to the sum of all of the partial +results calculated so far. This involves expensive carry propagation which will be eliminated in the next algorithm. + +EXAM,bn_s_mp_sqr.c + +Inside the outer loop (line @32,for@) the square term is calculated on line @35,r =@. The carry (line @42,>>@) has been +extracted from the mp\_word accumulator using a right shift. Aliases for $a_{ix}$ and $t_{ix+iy}$ are initialized +(lines @45,tmpx@ and @48,tmpt@) to simplify the inner loop. The doubling is performed using two +additions (line @57,r + r@) since it is usually faster than shifting, if not at least as fast. + +The important observation is that the inner loop does not begin at $iy = 0$ like for multiplication. As such the inner loops +get progressively shorter as the algorithm proceeds. This is what leads to the savings compared to using a multiplication to +square a number. + +\subsection{Faster Squaring by the ``Comba'' Method} +A major drawback to the baseline method is the requirement for single precision shifting inside the $O(n^2)$ nested loop. Squaring has an additional +drawback that it must double the product inside the inner loop as well. As for multiplication, the Comba technique can be used to eliminate these +performance hazards. + +The first obvious solution is to make an array of mp\_words which will hold all of the columns. This will indeed eliminate all of the carry +propagation operations from the inner loop. However, the inner product must still be doubled $O(n^2)$ times. The solution stems from the simple fact +that $2a + 2b + 2c = 2(a + b + c)$. That is the sum of all of the double products is equal to double the sum of all the products. For example, +$ab + ba + ac + ca = 2ab + 2ac = 2(ab + ac)$. + +However, we cannot simply double all of the columns, since the squares appear only once per row. The most practical solution is to have two +mp\_word arrays. One array will hold the squares and the other array will hold the double products. With both arrays the doubling and +carry propagation can be moved to a $O(n)$ work level outside the $O(n^2)$ level. In this case, we have an even simpler solution in mind. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{fast\_s\_mp\_sqr}. \\ +\textbf{Input}. mp\_int $a$ \\ +\textbf{Output}. $b \leftarrow a^2$ \\ +\hline \\ +Place an array of \textbf{MP\_WARRAY} mp\_digits named $W$ on the stack. \\ +1. If $b.alloc < 2a.used + 1$ then grow $b$ to $2a.used + 1$ digits. (\textit{mp\_grow}). \\ +2. If step 1 failed return(\textit{MP\_MEM}). \\ +\\ +3. $pa \leftarrow 2 \cdot a.used$ \\ +4. $\hat W1 \leftarrow 0$ \\ +5. for $ix$ from $0$ to $pa - 1$ do \\ +\hspace{3mm}5.1 $\_ \hat W \leftarrow 0$ \\ +\hspace{3mm}5.2 $ty \leftarrow \mbox{MIN}(a.used - 1, ix)$ \\ +\hspace{3mm}5.3 $tx \leftarrow ix - ty$ \\ +\hspace{3mm}5.4 $iy \leftarrow \mbox{MIN}(a.used - tx, ty + 1)$ \\ +\hspace{3mm}5.5 $iy \leftarrow \mbox{MIN}(iy, \lfloor \left (ty - tx + 1 \right )/2 \rfloor)$ \\ +\hspace{3mm}5.6 for $iz$ from $0$ to $iz - 1$ do \\ +\hspace{6mm}5.6.1 $\_ \hat W \leftarrow \_ \hat W + a_{tx + iz}a_{ty - iz}$ \\ +\hspace{3mm}5.7 $\_ \hat W \leftarrow 2 \cdot \_ \hat W + \hat W1$ \\ +\hspace{3mm}5.8 if $ix$ is even then \\ +\hspace{6mm}5.8.1 $\_ \hat W \leftarrow \_ \hat W + \left ( a_{\lfloor ix/2 \rfloor}\right )^2$ \\ +\hspace{3mm}5.9 $W_{ix} \leftarrow \_ \hat W (\mbox{mod }\beta)$ \\ +\hspace{3mm}5.10 $\hat W1 \leftarrow \lfloor \_ \hat W / \beta \rfloor$ \\ +\\ +6. $oldused \leftarrow b.used$ \\ +7. $b.used \leftarrow 2 \cdot a.used$ \\ +8. for $ix$ from $0$ to $pa - 1$ do \\ +\hspace{3mm}8.1 $b_{ix} \leftarrow W_{ix}$ \\ +9. for $ix$ from $pa$ to $oldused - 1$ do \\ +\hspace{3mm}9.1 $b_{ix} \leftarrow 0$ \\ +10. Clamp excess digits from $b$. (\textit{mp\_clamp}) \\ +11. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm fast\_s\_mp\_sqr} +\end{figure} + +\textbf{Algorithm fast\_s\_mp\_sqr.} +This algorithm computes the square of an input using the Comba technique. It is designed to be a replacement for algorithm +s\_mp\_sqr when the number of input digits is less than \textbf{MP\_WARRAY} and less than $\delta \over 2$. +This algorithm is very similar to the Comba multiplier except with a few key differences we shall make note of. + +First, we have an accumulator and carry variables $\_ \hat W$ and $\hat W1$ respectively. This is because the inner loop +products are to be doubled. If we had added the previous carry in we would be doubling too much. Next we perform an +addition MIN condition on $iy$ (step 5.5) to prevent overlapping digits. For example, $a_3 \cdot a_5$ is equal +$a_5 \cdot a_3$. Whereas in the multiplication case we would have $5 < a.used$ and $3 \ge 0$ is maintained since we double the sum +of the products just outside the inner loop we have to avoid doing this. This is also a good thing since we perform +fewer multiplications and the routine ends up being faster. + +Finally the last difference is the addition of the ``square'' term outside the inner loop (step 5.8). We add in the square +only to even outputs and it is the square of the term at the $\lfloor ix / 2 \rfloor$ position. + +EXAM,bn_fast_s_mp_sqr.c + +This implementation is essentially a copy of Comba multiplication with the appropriate changes added to make it faster for +the special case of squaring. + +\subsection{Polynomial Basis Squaring} +The same algorithm that performs optimal polynomial basis multiplication can be used to perform polynomial basis squaring. The minor exception +is that $\zeta_y = f(y)g(y)$ is actually equivalent to $\zeta_y = f(y)^2$ since $f(y) = g(y)$. Instead of performing $2n + 1$ +multiplications to find the $\zeta$ relations, squaring operations are performed instead. + +\subsection{Karatsuba Squaring} +Let $f(x) = ax + b$ represent the polynomial basis representation of a number to square. +Let $h(x) = \left ( f(x) \right )^2$ represent the square of the polynomial. The Karatsuba equation can be modified to square a +number with the following equation. + +\begin{equation} +h(x) = a^2x^2 + \left ((a + b)^2 - (a^2 + b^2) \right )x + b^2 +\end{equation} + +Upon closer inspection this equation only requires the calculation of three half-sized squares: $a^2$, $b^2$ and $(a + b)^2$. As in +Karatsuba multiplication, this algorithm can be applied recursively on the input and will achieve an asymptotic running time of +$O \left ( n^{lg(3)} \right )$. + +If the asymptotic times of Karatsuba squaring and multiplication are the same, why not simply use the multiplication algorithm +instead? The answer to this arises from the cutoff point for squaring. As in multiplication there exists a cutoff point, at which the +time required for a Comba based squaring and a Karatsuba based squaring meet. Due to the overhead inherent in the Karatsuba method, the cutoff +point is fairly high. For example, on an AMD Athlon XP processor with $\beta = 2^{28}$, the cutoff point is around 127 digits. + +Consider squaring a 200 digit number with this technique. It will be split into two 100 digit halves which are subsequently squared. +The 100 digit halves will not be squared using Karatsuba, but instead using the faster Comba based squaring algorithm. If Karatsuba multiplication +were used instead, the 100 digit numbers would be squared with a slower Comba based multiplication. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_karatsuba\_sqr}. \\ +\textbf{Input}. mp\_int $a$ \\ +\textbf{Output}. $b \leftarrow a^2$ \\ +\hline \\ +1. Initialize the following temporary mp\_ints: $x0$, $x1$, $t1$, $t2$, $x0x0$ and $x1x1$. \\ +2. If any of the initializations on step 1 failed return(\textit{MP\_MEM}). \\ +\\ +Split the input. e.g. $a = x1\beta^B + x0$ \\ +3. $B \leftarrow \lfloor a.used / 2 \rfloor$ \\ +4. $x0 \leftarrow a \mbox{ (mod }\beta^B\mbox{)}$ (\textit{mp\_mod\_2d}) \\ +5. $x1 \leftarrow \lfloor a / \beta^B \rfloor$ (\textit{mp\_lshd}) \\ +\\ +Calculate the three squares. \\ +6. $x0x0 \leftarrow x0^2$ (\textit{mp\_sqr}) \\ +7. $x1x1 \leftarrow x1^2$ \\ +8. $t1 \leftarrow x1 + x0$ (\textit{s\_mp\_add}) \\ +9. $t1 \leftarrow t1^2$ \\ +\\ +Compute the middle term. \\ +10. $t2 \leftarrow x0x0 + x1x1$ (\textit{s\_mp\_add}) \\ +11. $t1 \leftarrow t1 - t2$ \\ +\\ +Compute final product. \\ +12. $t1 \leftarrow t1\beta^B$ (\textit{mp\_lshd}) \\ +13. $x1x1 \leftarrow x1x1\beta^{2B}$ \\ +14. $t1 \leftarrow t1 + x0x0$ \\ +15. $b \leftarrow t1 + x1x1$ \\ +16. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_karatsuba\_sqr} +\end{figure} + +\textbf{Algorithm mp\_karatsuba\_sqr.} +This algorithm computes the square of an input $a$ using the Karatsuba technique. This algorithm is very similar to the Karatsuba based +multiplication algorithm with the exception that the three half-size multiplications have been replaced with three half-size squarings. + +The radix point for squaring is simply placed exactly in the middle of the digits when the input has an odd number of digits, otherwise it is +placed just below the middle. Step 3, 4 and 5 compute the two halves required using $B$ +as the radix point. The first two squares in steps 6 and 7 are rather straightforward while the last square is of a more compact form. + +By expanding $\left (x1 + x0 \right )^2$, the $x1^2$ and $x0^2$ terms in the middle disappear, that is $(x0 - x1)^2 - (x1^2 + x0^2) = 2 \cdot x0 \cdot x1$. +Now if $5n$ single precision additions and a squaring of $n$-digits is faster than multiplying two $n$-digit numbers and doubling then +this method is faster. Assuming no further recursions occur, the difference can be estimated with the following inequality. + +Let $p$ represent the cost of a single precision addition and $q$ the cost of a single precision multiplication both in terms of time\footnote{Or +machine clock cycles.}. + +\begin{equation} +5pn +{{q(n^2 + n)} \over 2} \le pn + qn^2 +\end{equation} + +For example, on an AMD Athlon XP processor $p = {1 \over 3}$ and $q = 6$. This implies that the following inequality should hold. +\begin{center} +\begin{tabular}{rcl} +${5n \over 3} + 3n^2 + 3n$ & $<$ & ${n \over 3} + 6n^2$ \\ +${5 \over 3} + 3n + 3$ & $<$ & ${1 \over 3} + 6n$ \\ +${13 \over 9}$ & $<$ & $n$ \\ +\end{tabular} +\end{center} + +This results in a cutoff point around $n = 2$. As a consequence it is actually faster to compute the middle term the ``long way'' on processors +where multiplication is substantially slower\footnote{On the Athlon there is a 1:17 ratio between clock cycles for addition and multiplication. On +the Intel P4 processor this ratio is 1:29 making this method even more beneficial. The only common exception is the ARMv4 processor which has a +ratio of 1:7. } than simpler operations such as addition. + +EXAM,bn_mp_karatsuba_sqr.c + +This implementation is largely based on the implementation of algorithm mp\_karatsuba\_mul. It uses the same inline style to copy and +shift the input into the two halves. The loop from line @54,{@ to line @70,}@ has been modified since only one input exists. The \textbf{used} +count of both $x0$ and $x1$ is fixed up and $x0$ is clamped before the calculations begin. At this point $x1$ and $x0$ are valid equivalents +to the respective halves as if mp\_rshd and mp\_mod\_2d had been used. + +By inlining the copy and shift operations the cutoff point for Karatsuba multiplication can be lowered. On the Athlon the cutoff point +is exactly at the point where Comba squaring can no longer be used (\textit{128 digits}). On slower processors such as the Intel P4 +it is actually below the Comba limit (\textit{at 110 digits}). + +This routine uses the same error trap coding style as mp\_karatsuba\_sqr. As the temporary variables are initialized errors are +redirected to the error trap higher up. If the algorithm completes without error the error code is set to \textbf{MP\_OKAY} and +mp\_clears are executed normally. + +\subsection{Toom-Cook Squaring} +The Toom-Cook squaring algorithm mp\_toom\_sqr is heavily based on the algorithm mp\_toom\_mul with the exception that squarings are used +instead of multiplication to find the five relations. The reader is encouraged to read the description of the latter algorithm and try to +derive their own Toom-Cook squaring algorithm. + +\subsection{High Level Squaring} +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_sqr}. \\ +\textbf{Input}. mp\_int $a$ \\ +\textbf{Output}. $b \leftarrow a^2$ \\ +\hline \\ +1. If $a.used \ge TOOM\_SQR\_CUTOFF$ then \\ +\hspace{3mm}1.1 $b \leftarrow a^2$ using algorithm mp\_toom\_sqr \\ +2. else if $a.used \ge KARATSUBA\_SQR\_CUTOFF$ then \\ +\hspace{3mm}2.1 $b \leftarrow a^2$ using algorithm mp\_karatsuba\_sqr \\ +3. else \\ +\hspace{3mm}3.1 $digs \leftarrow a.used + b.used + 1$ \\ +\hspace{3mm}3.2 If $digs < MP\_ARRAY$ and $a.used \le \delta$ then \\ +\hspace{6mm}3.2.1 $b \leftarrow a^2$ using algorithm fast\_s\_mp\_sqr. \\ +\hspace{3mm}3.3 else \\ +\hspace{6mm}3.3.1 $b \leftarrow a^2$ using algorithm s\_mp\_sqr. \\ +4. $b.sign \leftarrow MP\_ZPOS$ \\ +5. Return the result of the unsigned squaring performed. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_sqr} +\end{figure} + +\textbf{Algorithm mp\_sqr.} +This algorithm computes the square of the input using one of four different algorithms. If the input is very large and has at least +\textbf{TOOM\_SQR\_CUTOFF} or \textbf{KARATSUBA\_SQR\_CUTOFF} digits then either the Toom-Cook or the Karatsuba Squaring algorithm is used. If +neither of the polynomial basis algorithms should be used then either the Comba or baseline algorithm is used. + +EXAM,bn_mp_sqr.c + +\section*{Exercises} +\begin{tabular}{cl} +$\left [ 3 \right ] $ & Devise an efficient algorithm for selection of the radix point to handle inputs \\ + & that have different number of digits in Karatsuba multiplication. \\ + & \\ +$\left [ 2 \right ] $ & In ~SQUARE~ the fact that every column of a squaring is made up \\ + & of double products and at most one square is stated. Prove this statement. \\ + & \\ +$\left [ 3 \right ] $ & Prove the equation for Karatsuba squaring. \\ + & \\ +$\left [ 1 \right ] $ & Prove that Karatsuba squaring requires $O \left (n^{lg(3)} \right )$ time. \\ + & \\ +$\left [ 2 \right ] $ & Determine the minimal ratio between addition and multiplication clock cycles \\ + & required for equation $6.7$ to be true. \\ + & \\ +$\left [ 3 \right ] $ & Implement a threaded version of Comba multiplication (and squaring) where you \\ + & compute subsets of the columns in each thread. Determine a cutoff point where \\ + & it is effective and add the logic to mp\_mul() and mp\_sqr(). \\ + &\\ +$\left [ 4 \right ] $ & Same as the previous but also modify the Karatsuba and Toom-Cook. You must \\ + & increase the throughput of mp\_exptmod() for random odd moduli in the range \\ + & $512 \ldots 4096$ bits significantly ($> 2x$) to complete this challenge. \\ + & \\ +\end{tabular} + +\chapter{Modular Reduction} +MARK,REDUCTION +\section{Basics of Modular Reduction} +\index{modular residue} +Modular reduction is an operation that arises quite often within public key cryptography algorithms and various number theoretic algorithms, +such as factoring. Modular reduction algorithms are the third class of algorithms of the ``multipliers'' set. A number $a$ is said to be \textit{reduced} +modulo another number $b$ by finding the remainder of the division $a/b$. Full integer division with remainder is a topic to be covered +in~\ref{sec:division}. + +Modular reduction is equivalent to solving for $r$ in the following equation. $a = bq + r$ where $q = \lfloor a/b \rfloor$. The result +$r$ is said to be ``congruent to $a$ modulo $b$'' which is also written as $r \equiv a \mbox{ (mod }b\mbox{)}$. In other vernacular $r$ is known as the +``modular residue'' which leads to ``quadratic residue''\footnote{That's fancy talk for $b \equiv a^2 \mbox{ (mod }p\mbox{)}$.} and +other forms of residues. + +Modular reductions are normally used to create either finite groups, rings or fields. The most common usage for performance driven modular reductions +is in modular exponentiation algorithms. That is to compute $d = a^b \mbox{ (mod }c\mbox{)}$ as fast as possible. This operation is used in the +RSA and Diffie-Hellman public key algorithms, for example. Modular multiplication and squaring also appears as a fundamental operation in +elliptic curve cryptographic algorithms. As will be discussed in the subsequent chapter there exist fast algorithms for computing modular +exponentiations without having to perform (\textit{in this example}) $b - 1$ multiplications. These algorithms will produce partial results in the +range $0 \le x < c^2$ which can be taken advantage of to create several efficient algorithms. They have also been used to create redundancy check +algorithms known as CRCs, error correction codes such as Reed-Solomon and solve a variety of number theoeretic problems. + +\section{The Barrett Reduction} +The Barrett reduction algorithm \cite{BARRETT} was inspired by fast division algorithms which multiply by the reciprocal to emulate +division. Barretts observation was that the residue $c$ of $a$ modulo $b$ is equal to + +\begin{equation} +c = a - b \cdot \lfloor a/b \rfloor +\end{equation} + +Since algorithms such as modular exponentiation would be using the same modulus extensively, typical DSP\footnote{It is worth noting that Barrett's paper +targeted the DSP56K processor.} intuition would indicate the next step would be to replace $a/b$ by a multiplication by the reciprocal. However, +DSP intuition on its own will not work as these numbers are considerably larger than the precision of common DSP floating point data types. +It would take another common optimization to optimize the algorithm. + +\subsection{Fixed Point Arithmetic} +The trick used to optimize the above equation is based on a technique of emulating floating point data types with fixed precision integers. Fixed +point arithmetic would become very popular as it greatly optimize the ``3d-shooter'' genre of games in the mid 1990s when floating point units were +fairly slow if not unavailable. The idea behind fixed point arithmetic is to take a normal $k$-bit integer data type and break it into $p$-bit +integer and a $q$-bit fraction part (\textit{where $p+q = k$}). + +In this system a $k$-bit integer $n$ would actually represent $n/2^q$. For example, with $q = 4$ the integer $n = 37$ would actually represent the +value $2.3125$. To multiply two fixed point numbers the integers are multiplied using traditional arithmetic and subsequently normalized by +moving the implied decimal point back to where it should be. For example, with $q = 4$ to multiply the integers $9$ and $5$ they must be converted +to fixed point first by multiplying by $2^q$. Let $a = 9(2^q)$ represent the fixed point representation of $9$ and $b = 5(2^q)$ represent the +fixed point representation of $5$. The product $ab$ is equal to $45(2^{2q})$ which when normalized by dividing by $2^q$ produces $45(2^q)$. + +This technique became popular since a normal integer multiplication and logical shift right are the only required operations to perform a multiplication +of two fixed point numbers. Using fixed point arithmetic, division can be easily approximated by multiplying by the reciprocal. If $2^q$ is +equivalent to one than $2^q/b$ is equivalent to the fixed point approximation of $1/b$ using real arithmetic. Using this fact dividing an integer +$a$ by another integer $b$ can be achieved with the following expression. + +\begin{equation} +\lfloor a / b \rfloor \mbox{ }\approx\mbox{ } \lfloor (a \cdot \lfloor 2^q / b \rfloor)/2^q \rfloor +\end{equation} + +The precision of the division is proportional to the value of $q$. If the divisor $b$ is used frequently as is the case with +modular exponentiation pre-computing $2^q/b$ will allow a division to be performed with a multiplication and a right shift. Both operations +are considerably faster than division on most processors. + +Consider dividing $19$ by $5$. The correct result is $\lfloor 19/5 \rfloor = 3$. With $q = 3$ the reciprocal is $\lfloor 2^q/5 \rfloor = 1$ which +leads to a product of $19$ which when divided by $2^q$ produces $2$. However, with $q = 4$ the reciprocal is $\lfloor 2^q/5 \rfloor = 3$ and +the result of the emulated division is $\lfloor 3 \cdot 19 / 2^q \rfloor = 3$ which is correct. The value of $2^q$ must be close to or ideally +larger than the dividend. In effect if $a$ is the dividend then $q$ should allow $0 \le \lfloor a/2^q \rfloor \le 1$ in order for this approach +to work correctly. Plugging this form of divison into the original equation the following modular residue equation arises. + +\begin{equation} +c = a - b \cdot \lfloor (a \cdot \lfloor 2^q / b \rfloor)/2^q \rfloor +\end{equation} + +Using the notation from \cite{BARRETT} the value of $\lfloor 2^q / b \rfloor$ will be represented by the $\mu$ symbol. Using the $\mu$ +variable also helps re-inforce the idea that it is meant to be computed once and re-used. + +\begin{equation} +c = a - b \cdot \lfloor (a \cdot \mu)/2^q \rfloor +\end{equation} + +Provided that $2^q \ge a$ this algorithm will produce a quotient that is either exactly correct or off by a value of one. In the context of Barrett +reduction the value of $a$ is bound by $0 \le a \le (b - 1)^2$ meaning that $2^q \ge b^2$ is sufficient to ensure the reciprocal will have enough +precision. + +Let $n$ represent the number of digits in $b$. This algorithm requires approximately $2n^2$ single precision multiplications to produce the quotient and +another $n^2$ single precision multiplications to find the residue. In total $3n^2$ single precision multiplications are required to +reduce the number. + +For example, if $b = 1179677$ and $q = 41$ ($2^q > b^2$), then the reciprocal $\mu$ is equal to $\lfloor 2^q / b \rfloor = 1864089$. Consider reducing +$a = 180388626447$ modulo $b$ using the above reduction equation. The quotient using the new formula is $\lfloor (a \cdot \mu) / 2^q \rfloor = 152913$. +By subtracting $152913b$ from $a$ the correct residue $a \equiv 677346 \mbox{ (mod }b\mbox{)}$ is found. + +\subsection{Choosing a Radix Point} +Using the fixed point representation a modular reduction can be performed with $3n^2$ single precision multiplications. If that were the best +that could be achieved a full division\footnote{A division requires approximately $O(2cn^2)$ single precision multiplications for a small value of $c$. +See~\ref{sec:division} for further details.} might as well be used in its place. The key to optimizing the reduction is to reduce the precision of +the initial multiplication that finds the quotient. + +Let $a$ represent the number of which the residue is sought. Let $b$ represent the modulus used to find the residue. Let $m$ represent +the number of digits in $b$. For the purposes of this discussion we will assume that the number of digits in $a$ is $2m$, which is generally true if +two $m$-digit numbers have been multiplied. Dividing $a$ by $b$ is the same as dividing a $2m$ digit integer by a $m$ digit integer. Digits below the +$m - 1$'th digit of $a$ will contribute at most a value of $1$ to the quotient because $\beta^k < b$ for any $0 \le k \le m - 1$. Another way to +express this is by re-writing $a$ as two parts. If $a' \equiv a \mbox{ (mod }b^m\mbox{)}$ and $a'' = a - a'$ then +${a \over b} \equiv {{a' + a''} \over b}$ which is equivalent to ${a' \over b} + {a'' \over b}$. Since $a'$ is bound to be less than $b$ the quotient +is bound by $0 \le {a' \over b} < 1$. + +Since the digits of $a'$ do not contribute much to the quotient the observation is that they might as well be zero. However, if the digits +``might as well be zero'' they might as well not be there in the first place. Let $q_0 = \lfloor a/\beta^{m-1} \rfloor$ represent the input +with the irrelevant digits trimmed. Now the modular reduction is trimmed to the almost equivalent equation + +\begin{equation} +c = a - b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor +\end{equation} + +Note that the original divisor $2^q$ has been replaced with $\beta^{m+1}$ where in this case $q$ is a multiple of $lg(\beta)$. Also note that the +exponent on the divisor when added to the amount $q_0$ was shifted by equals $2m$. If the optimization had not been performed the divisor +would have the exponent $2m$ so in the end the exponents do ``add up''. Using the above equation the quotient +$\lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor$ can be off from the true quotient by at most two. The original fixed point quotient can be off +by as much as one (\textit{provided the radix point is chosen suitably}) and now that the lower irrelevent digits have been trimmed the quotient +can be off by an additional value of one for a total of at most two. This implies that +$0 \le a - b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor < 3b$. By first subtracting $b$ times the quotient and then conditionally subtracting +$b$ once or twice the residue is found. + +The quotient is now found using $(m + 1)(m) = m^2 + m$ single precision multiplications and the residue with an additional $m^2$ single +precision multiplications, ignoring the subtractions required. In total $2m^2 + m$ single precision multiplications are required to find the residue. +This is considerably faster than the original attempt. + +For example, let $\beta = 10$ represent the radix of the digits. Let $b = 9999$ represent the modulus which implies $m = 4$. Let $a = 99929878$ +represent the value of which the residue is desired. In this case $q = 8$ since $10^7 < 9999^2$ meaning that $\mu = \lfloor \beta^{q}/b \rfloor = 10001$. +With the new observation the multiplicand for the quotient is equal to $q_0 = \lfloor a / \beta^{m - 1} \rfloor = 99929$. The quotient is then +$\lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor = 9993$. Subtracting $9993b$ from $a$ and the correct residue $a \equiv 9871 \mbox{ (mod }b\mbox{)}$ +is found. + +\subsection{Trimming the Quotient} +So far the reduction algorithm has been optimized from $3m^2$ single precision multiplications down to $2m^2 + m$ single precision multiplications. As +it stands now the algorithm is already fairly fast compared to a full integer division algorithm. However, there is still room for +optimization. + +After the first multiplication inside the quotient ($q_0 \cdot \mu$) the value is shifted right by $m + 1$ places effectively nullifying the lower +half of the product. It would be nice to be able to remove those digits from the product to effectively cut down the number of single precision +multiplications. If the number of digits in the modulus $m$ is far less than $\beta$ a full product is not required for the algorithm to work properly. +In fact the lower $m - 2$ digits will not affect the upper half of the product at all and do not need to be computed. + +The value of $\mu$ is a $m$-digit number and $q_0$ is a $m + 1$ digit number. Using a full multiplier $(m + 1)(m) = m^2 + m$ single precision +multiplications would be required. Using a multiplier that will only produce digits at and above the $m - 1$'th digit reduces the number +of single precision multiplications to ${m^2 + m} \over 2$ single precision multiplications. + +\subsection{Trimming the Residue} +After the quotient has been calculated it is used to reduce the input. As previously noted the algorithm is not exact and it can be off by a small +multiple of the modulus, that is $0 \le a - b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor < 3b$. If $b$ is $m$ digits than the +result of reduction equation is a value of at most $m + 1$ digits (\textit{provided $3 < \beta$}) implying that the upper $m - 1$ digits are +implicitly zero. + +The next optimization arises from this very fact. Instead of computing $b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor$ using a full +$O(m^2)$ multiplication algorithm only the lower $m+1$ digits of the product have to be computed. Similarly the value of $a$ can +be reduced modulo $\beta^{m+1}$ before the multiple of $b$ is subtracted which simplifes the subtraction as well. A multiplication that produces +only the lower $m+1$ digits requires ${m^2 + 3m - 2} \over 2$ single precision multiplications. + +With both optimizations in place the algorithm is the algorithm Barrett proposed. It requires $m^2 + 2m - 1$ single precision multiplications which +is considerably faster than the straightforward $3m^2$ method. + +\subsection{The Barrett Algorithm} +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_reduce}. \\ +\textbf{Input}. mp\_int $a$, mp\_int $b$ and $\mu = \lfloor \beta^{2m}/b \rfloor, m = \lceil lg_{\beta}(b) \rceil, (0 \le a < b^2, b > 1)$ \\ +\textbf{Output}. $a \mbox{ (mod }b\mbox{)}$ \\ +\hline \\ +Let $m$ represent the number of digits in $b$. \\ +1. Make a copy of $a$ and store it in $q$. (\textit{mp\_init\_copy}) \\ +2. $q \leftarrow \lfloor q / \beta^{m - 1} \rfloor$ (\textit{mp\_rshd}) \\ +\\ +Produce the quotient. \\ +3. $q \leftarrow q \cdot \mu$ (\textit{note: only produce digits at or above $m-1$}) \\ +4. $q \leftarrow \lfloor q / \beta^{m + 1} \rfloor$ \\ +\\ +Subtract the multiple of modulus from the input. \\ +5. $a \leftarrow a \mbox{ (mod }\beta^{m+1}\mbox{)}$ (\textit{mp\_mod\_2d}) \\ +6. $q \leftarrow q \cdot b \mbox{ (mod }\beta^{m+1}\mbox{)}$ (\textit{s\_mp\_mul\_digs}) \\ +7. $a \leftarrow a - q$ (\textit{mp\_sub}) \\ +\\ +Add $\beta^{m+1}$ if a carry occured. \\ +8. If $a < 0$ then (\textit{mp\_cmp\_d}) \\ +\hspace{3mm}8.1 $q \leftarrow 1$ (\textit{mp\_set}) \\ +\hspace{3mm}8.2 $q \leftarrow q \cdot \beta^{m+1}$ (\textit{mp\_lshd}) \\ +\hspace{3mm}8.3 $a \leftarrow a + q$ \\ +\\ +Now subtract the modulus if the residue is too large (e.g. quotient too small). \\ +9. While $a \ge b$ do (\textit{mp\_cmp}) \\ +\hspace{3mm}9.1 $c \leftarrow a - b$ \\ +10. Clear $q$. \\ +11. Return(\textit{MP\_OKAY}) \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_reduce} +\end{figure} + +\textbf{Algorithm mp\_reduce.} +This algorithm will reduce the input $a$ modulo $b$ in place using the Barrett algorithm. It is loosely based on algorithm 14.42 of HAC +\cite[pp. 602]{HAC} which is based on the paper from Paul Barrett \cite{BARRETT}. The algorithm has several restrictions and assumptions which must +be adhered to for the algorithm to work. + +First the modulus $b$ is assumed to be positive and greater than one. If the modulus were less than or equal to one than subtracting +a multiple of it would either accomplish nothing or actually enlarge the input. The input $a$ must be in the range $0 \le a < b^2$ in order +for the quotient to have enough precision. If $a$ is the product of two numbers that were already reduced modulo $b$, this will not be a problem. +Technically the algorithm will still work if $a \ge b^2$ but it will take much longer to finish. The value of $\mu$ is passed as an argument to this +algorithm and is assumed to be calculated and stored before the algorithm is used. + +Recall that the multiplication for the quotient on step 3 must only produce digits at or above the $m-1$'th position. An algorithm called +$s\_mp\_mul\_high\_digs$ which has not been presented is used to accomplish this task. The algorithm is based on $s\_mp\_mul\_digs$ except that +instead of stopping at a given level of precision it starts at a given level of precision. This optimal algorithm can only be used if the number +of digits in $b$ is very much smaller than $\beta$. + +While it is known that +$a \ge b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor$ only the lower $m+1$ digits are being used to compute the residue, so an implied +``borrow'' from the higher digits might leave a negative result. After the multiple of the modulus has been subtracted from $a$ the residue must be +fixed up in case it is negative. The invariant $\beta^{m+1}$ must be added to the residue to make it positive again. + +The while loop at step 9 will subtract $b$ until the residue is less than $b$. If the algorithm is performed correctly this step is +performed at most twice, and on average once. However, if $a \ge b^2$ than it will iterate substantially more times than it should. + +EXAM,bn_mp_reduce.c + +The first multiplication that determines the quotient can be performed by only producing the digits from $m - 1$ and up. This essentially halves +the number of single precision multiplications required. However, the optimization is only safe if $\beta$ is much larger than the number of digits +in the modulus. In the source code this is evaluated on lines @36,if@ to @44,}@ where algorithm s\_mp\_mul\_high\_digs is used when it is +safe to do so. + +\subsection{The Barrett Setup Algorithm} +In order to use algorithm mp\_reduce the value of $\mu$ must be calculated in advance. Ideally this value should be computed once and stored for +future use so that the Barrett algorithm can be used without delay. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_reduce\_setup}. \\ +\textbf{Input}. mp\_int $a$ ($a > 1$) \\ +\textbf{Output}. $\mu \leftarrow \lfloor \beta^{2m}/a \rfloor$ \\ +\hline \\ +1. $\mu \leftarrow 2^{2 \cdot lg(\beta) \cdot m}$ (\textit{mp\_2expt}) \\ +2. $\mu \leftarrow \lfloor \mu / b \rfloor$ (\textit{mp\_div}) \\ +3. Return(\textit{MP\_OKAY}) \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_reduce\_setup} +\end{figure} + +\textbf{Algorithm mp\_reduce\_setup.} +This algorithm computes the reciprocal $\mu$ required for Barrett reduction. First $\beta^{2m}$ is calculated as $2^{2 \cdot lg(\beta) \cdot m}$ which +is equivalent and much faster. The final value is computed by taking the integer quotient of $\lfloor \mu / b \rfloor$. + +EXAM,bn_mp_reduce_setup.c + +This simple routine calculates the reciprocal $\mu$ required by Barrett reduction. Note the extended usage of algorithm mp\_div where the variable +which would received the remainder is passed as NULL. As will be discussed in~\ref{sec:division} the division routine allows both the quotient and the +remainder to be passed as NULL meaning to ignore the value. + +\section{The Montgomery Reduction} +Montgomery reduction\footnote{Thanks to Niels Ferguson for his insightful explanation of the algorithm.} \cite{MONT} is by far the most interesting +form of reduction in common use. It computes a modular residue which is not actually equal to the residue of the input yet instead equal to a +residue times a constant. However, as perplexing as this may sound the algorithm is relatively simple and very efficient. + +Throughout this entire section the variable $n$ will represent the modulus used to form the residue. As will be discussed shortly the value of +$n$ must be odd. The variable $x$ will represent the quantity of which the residue is sought. Similar to the Barrett algorithm the input +is restricted to $0 \le x < n^2$. To begin the description some simple number theory facts must be established. + +\textbf{Fact 1.} Adding $n$ to $x$ does not change the residue since in effect it adds one to the quotient $\lfloor x / n \rfloor$. Another way +to explain this is that $n$ is (\textit{or multiples of $n$ are}) congruent to zero modulo $n$. Adding zero will not change the value of the residue. + +\textbf{Fact 2.} If $x$ is even then performing a division by two in $\Z$ is congruent to $x \cdot 2^{-1} \mbox{ (mod }n\mbox{)}$. Actually +this is an application of the fact that if $x$ is evenly divisible by any $k \in \Z$ then division in $\Z$ will be congruent to +multiplication by $k^{-1}$ modulo $n$. + +From these two simple facts the following simple algorithm can be derived. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{Montgomery Reduction}. \\ +\textbf{Input}. Integer $x$, $n$ and $k$ \\ +\textbf{Output}. $2^{-k}x \mbox{ (mod }n\mbox{)}$ \\ +\hline \\ +1. for $t$ from $1$ to $k$ do \\ +\hspace{3mm}1.1 If $x$ is odd then \\ +\hspace{6mm}1.1.1 $x \leftarrow x + n$ \\ +\hspace{3mm}1.2 $x \leftarrow x/2$ \\ +2. Return $x$. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm Montgomery Reduction} +\end{figure} + +The algorithm reduces the input one bit at a time using the two congruencies stated previously. Inside the loop $n$, which is odd, is +added to $x$ if $x$ is odd. This forces $x$ to be even which allows the division by two in $\Z$ to be congruent to a modular division by two. Since +$x$ is assumed to be initially much larger than $n$ the addition of $n$ will contribute an insignificant magnitude to $x$. Let $r$ represent the +final result of the Montgomery algorithm. If $k > lg(n)$ and $0 \le x < n^2$ then the final result is limited to +$0 \le r < \lfloor x/2^k \rfloor + n$. As a result at most a single subtraction is required to get the residue desired. + +\begin{figure}[here] +\begin{small} +\begin{center} +\begin{tabular}{|c|l|} +\hline \textbf{Step number ($t$)} & \textbf{Result ($x$)} \\ +\hline $1$ & $x + n = 5812$, $x/2 = 2906$ \\ +\hline $2$ & $x/2 = 1453$ \\ +\hline $3$ & $x + n = 1710$, $x/2 = 855$ \\ +\hline $4$ & $x + n = 1112$, $x/2 = 556$ \\ +\hline $5$ & $x/2 = 278$ \\ +\hline $6$ & $x/2 = 139$ \\ +\hline $7$ & $x + n = 396$, $x/2 = 198$ \\ +\hline $8$ & $x/2 = 99$ \\ +\hline $9$ & $x + n = 356$, $x/2 = 178$ \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Example of Montgomery Reduction (I)} +\label{fig:MONT1} +\end{figure} + +Consider the example in figure~\ref{fig:MONT1} which reduces $x = 5555$ modulo $n = 257$ when $k = 9$ (note $\beta^k = 512$ which is larger than $n$). The result of +the algorithm $r = 178$ is congruent to the value of $2^{-9} \cdot 5555 \mbox{ (mod }257\mbox{)}$. When $r$ is multiplied by $2^9$ modulo $257$ the correct residue +$r \equiv 158$ is produced. + +Let $k = \lfloor lg(n) \rfloor + 1$ represent the number of bits in $n$. The current algorithm requires $2k^2$ single precision shifts +and $k^2$ single precision additions. At this rate the algorithm is most certainly slower than Barrett reduction and not terribly useful. +Fortunately there exists an alternative representation of the algorithm. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{Montgomery Reduction} (modified I). \\ +\textbf{Input}. Integer $x$, $n$ and $k$ ($2^k > n$) \\ +\textbf{Output}. $2^{-k}x \mbox{ (mod }n\mbox{)}$ \\ +\hline \\ +1. for $t$ from $1$ to $k$ do \\ +\hspace{3mm}1.1 If the $t$'th bit of $x$ is one then \\ +\hspace{6mm}1.1.1 $x \leftarrow x + 2^tn$ \\ +2. Return $x/2^k$. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm Montgomery Reduction (modified I)} +\end{figure} + +This algorithm is equivalent since $2^tn$ is a multiple of $n$ and the lower $k$ bits of $x$ are zero by step 2. The number of single +precision shifts has now been reduced from $2k^2$ to $k^2 + k$ which is only a small improvement. + +\begin{figure}[here] +\begin{small} +\begin{center} +\begin{tabular}{|c|l|r|} +\hline \textbf{Step number ($t$)} & \textbf{Result ($x$)} & \textbf{Result ($x$) in Binary} \\ +\hline -- & $5555$ & $1010110110011$ \\ +\hline $1$ & $x + 2^{0}n = 5812$ & $1011010110100$ \\ +\hline $2$ & $5812$ & $1011010110100$ \\ +\hline $3$ & $x + 2^{2}n = 6840$ & $1101010111000$ \\ +\hline $4$ & $x + 2^{3}n = 8896$ & $10001011000000$ \\ +\hline $5$ & $8896$ & $10001011000000$ \\ +\hline $6$ & $8896$ & $10001011000000$ \\ +\hline $7$ & $x + 2^{6}n = 25344$ & $110001100000000$ \\ +\hline $8$ & $25344$ & $110001100000000$ \\ +\hline $9$ & $x + 2^{7}n = 91136$ & $10110010000000000$ \\ +\hline -- & $x/2^k = 178$ & \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Example of Montgomery Reduction (II)} +\label{fig:MONT2} +\end{figure} + +Figure~\ref{fig:MONT2} demonstrates the modified algorithm reducing $x = 5555$ modulo $n = 257$ with $k = 9$. +With this algorithm a single shift right at the end is the only right shift required to reduce the input instead of $k$ right shifts inside the +loop. Note that for the iterations $t = 2, 5, 6$ and $8$ where the result $x$ is not changed. In those iterations the $t$'th bit of $x$ is +zero and the appropriate multiple of $n$ does not need to be added to force the $t$'th bit of the result to zero. + +\subsection{Digit Based Montgomery Reduction} +Instead of computing the reduction on a bit-by-bit basis it is actually much faster to compute it on digit-by-digit basis. Consider the +previous algorithm re-written to compute the Montgomery reduction in this new fashion. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{Montgomery Reduction} (modified II). \\ +\textbf{Input}. Integer $x$, $n$ and $k$ ($\beta^k > n$) \\ +\textbf{Output}. $\beta^{-k}x \mbox{ (mod }n\mbox{)}$ \\ +\hline \\ +1. for $t$ from $0$ to $k - 1$ do \\ +\hspace{3mm}1.1 $x \leftarrow x + \mu n \beta^t$ \\ +2. Return $x/\beta^k$. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm Montgomery Reduction (modified II)} +\end{figure} + +The value $\mu n \beta^t$ is a multiple of the modulus $n$ meaning that it will not change the residue. If the first digit of +the value $\mu n \beta^t$ equals the negative (modulo $\beta$) of the $t$'th digit of $x$ then the addition will result in a zero digit. This +problem breaks down to solving the following congruency. + +\begin{center} +\begin{tabular}{rcl} +$x_t + \mu n_0$ & $\equiv$ & $0 \mbox{ (mod }\beta\mbox{)}$ \\ +$\mu n_0$ & $\equiv$ & $-x_t \mbox{ (mod }\beta\mbox{)}$ \\ +$\mu$ & $\equiv$ & $-x_t/n_0 \mbox{ (mod }\beta\mbox{)}$ \\ +\end{tabular} +\end{center} + +In each iteration of the loop on step 1 a new value of $\mu$ must be calculated. The value of $-1/n_0 \mbox{ (mod }\beta\mbox{)}$ is used +extensively in this algorithm and should be precomputed. Let $\rho$ represent the negative of the modular inverse of $n_0$ modulo $\beta$. + +For example, let $\beta = 10$ represent the radix. Let $n = 17$ represent the modulus which implies $k = 2$ and $\rho \equiv 7$. Let $x = 33$ +represent the value to reduce. + +\newpage\begin{figure} +\begin{center} +\begin{tabular}{|c|c|c|} +\hline \textbf{Step ($t$)} & \textbf{Value of $x$} & \textbf{Value of $\mu$} \\ +\hline -- & $33$ & --\\ +\hline $0$ & $33 + \mu n = 50$ & $1$ \\ +\hline $1$ & $50 + \mu n \beta = 900$ & $5$ \\ +\hline +\end{tabular} +\end{center} +\caption{Example of Montgomery Reduction} +\end{figure} + +The final result $900$ is then divided by $\beta^k$ to produce the final result $9$. The first observation is that $9 \nequiv x \mbox{ (mod }n\mbox{)}$ +which implies the result is not the modular residue of $x$ modulo $n$. However, recall that the residue is actually multiplied by $\beta^{-k}$ in +the algorithm. To get the true residue the value must be multiplied by $\beta^k$. In this case $\beta^k \equiv 15 \mbox{ (mod }n\mbox{)}$ and +the correct residue is $9 \cdot 15 \equiv 16 \mbox{ (mod }n\mbox{)}$. + +\subsection{Baseline Montgomery Reduction} +The baseline Montgomery reduction algorithm will produce the residue for any size input. It is designed to be a catch-all algororithm for +Montgomery reductions. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_montgomery\_reduce}. \\ +\textbf{Input}. mp\_int $x$, mp\_int $n$ and a digit $\rho \equiv -1/n_0 \mbox{ (mod }n\mbox{)}$. \\ +\hspace{11.5mm}($0 \le x < n^2, n > 1, (n, \beta) = 1, \beta^k > n$) \\ +\textbf{Output}. $\beta^{-k}x \mbox{ (mod }n\mbox{)}$ \\ +\hline \\ +1. $digs \leftarrow 2n.used + 1$ \\ +2. If $digs < MP\_ARRAY$ and $m.used < \delta$ then \\ +\hspace{3mm}2.1 Use algorithm fast\_mp\_montgomery\_reduce instead. \\ +\\ +Setup $x$ for the reduction. \\ +3. If $x.alloc < digs$ then grow $x$ to $digs$ digits. \\ +4. $x.used \leftarrow digs$ \\ +\\ +Eliminate the lower $k$ digits. \\ +5. For $ix$ from $0$ to $k - 1$ do \\ +\hspace{3mm}5.1 $\mu \leftarrow x_{ix} \cdot \rho \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{3mm}5.2 $u \leftarrow 0$ \\ +\hspace{3mm}5.3 For $iy$ from $0$ to $k - 1$ do \\ +\hspace{6mm}5.3.1 $\hat r \leftarrow \mu n_{iy} + x_{ix + iy} + u$ \\ +\hspace{6mm}5.3.2 $x_{ix + iy} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{6mm}5.3.3 $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\ +\hspace{3mm}5.4 While $u > 0$ do \\ +\hspace{6mm}5.4.1 $iy \leftarrow iy + 1$ \\ +\hspace{6mm}5.4.2 $x_{ix + iy} \leftarrow x_{ix + iy} + u$ \\ +\hspace{6mm}5.4.3 $u \leftarrow \lfloor x_{ix+iy} / \beta \rfloor$ \\ +\hspace{6mm}5.4.4 $x_{ix + iy} \leftarrow x_{ix+iy} \mbox{ (mod }\beta\mbox{)}$ \\ +\\ +Divide by $\beta^k$ and fix up as required. \\ +6. $x \leftarrow \lfloor x / \beta^k \rfloor$ \\ +7. If $x \ge n$ then \\ +\hspace{3mm}7.1 $x \leftarrow x - n$ \\ +8. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_montgomery\_reduce} +\end{figure} + +\textbf{Algorithm mp\_montgomery\_reduce.} +This algorithm reduces the input $x$ modulo $n$ in place using the Montgomery reduction algorithm. The algorithm is loosely based +on algorithm 14.32 of \cite[pp.601]{HAC} except it merges the multiplication of $\mu n \beta^t$ with the addition in the inner loop. The +restrictions on this algorithm are fairly easy to adapt to. First $0 \le x < n^2$ bounds the input to numbers in the same range as +for the Barrett algorithm. Additionally if $n > 1$ and $n$ is odd there will exist a modular inverse $\rho$. $\rho$ must be calculated in +advance of this algorithm. Finally the variable $k$ is fixed and a pseudonym for $n.used$. + +Step 2 decides whether a faster Montgomery algorithm can be used. It is based on the Comba technique meaning that there are limits on +the size of the input. This algorithm is discussed in ~COMBARED~. + +Step 5 is the main reduction loop of the algorithm. The value of $\mu$ is calculated once per iteration in the outer loop. The inner loop +calculates $x + \mu n \beta^{ix}$ by multiplying $\mu n$ and adding the result to $x$ shifted by $ix$ digits. Both the addition and +multiplication are performed in the same loop to save time and memory. Step 5.4 will handle any additional carries that escape the inner loop. + +Using a quick inspection this algorithm requires $n$ single precision multiplications for the outer loop and $n^2$ single precision multiplications +in the inner loop. In total $n^2 + n$ single precision multiplications which compares favourably to Barrett at $n^2 + 2n - 1$ single precision +multiplications. + +EXAM,bn_mp_montgomery_reduce.c + +This is the baseline implementation of the Montgomery reduction algorithm. Lines @30,digs@ to @35,}@ determine if the Comba based +routine can be used instead. Line @47,mu@ computes the value of $\mu$ for that particular iteration of the outer loop. + +The multiplication $\mu n \beta^{ix}$ is performed in one step in the inner loop. The alias $tmpx$ refers to the $ix$'th digit of $x$ and +the alias $tmpn$ refers to the modulus $n$. + +\subsection{Faster ``Comba'' Montgomery Reduction} +MARK,COMBARED + +The Montgomery reduction requires fewer single precision multiplications than a Barrett reduction, however it is much slower due to the serial +nature of the inner loop. The Barrett reduction algorithm requires two slightly modified multipliers which can be implemented with the Comba +technique. The Montgomery reduction algorithm cannot directly use the Comba technique to any significant advantage since the inner loop calculates +a $k \times 1$ product $k$ times. + +The biggest obstacle is that at the $ix$'th iteration of the outer loop the value of $x_{ix}$ is required to calculate $\mu$. This means the +carries from $0$ to $ix - 1$ must have been propagated upwards to form a valid $ix$'th digit. The solution as it turns out is very simple. +Perform a Comba like multiplier and inside the outer loop just after the inner loop fix up the $ix + 1$'th digit by forwarding the carry. + +With this change in place the Montgomery reduction algorithm can be performed with a Comba style multiplication loop which substantially increases +the speed of the algorithm. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{fast\_mp\_montgomery\_reduce}. \\ +\textbf{Input}. mp\_int $x$, mp\_int $n$ and a digit $\rho \equiv -1/n_0 \mbox{ (mod }n\mbox{)}$. \\ +\hspace{11.5mm}($0 \le x < n^2, n > 1, (n, \beta) = 1, \beta^k > n$) \\ +\textbf{Output}. $\beta^{-k}x \mbox{ (mod }n\mbox{)}$ \\ +\hline \\ +Place an array of \textbf{MP\_WARRAY} mp\_word variables called $\hat W$ on the stack. \\ +1. if $x.alloc < n.used + 1$ then grow $x$ to $n.used + 1$ digits. \\ +Copy the digits of $x$ into the array $\hat W$ \\ +2. For $ix$ from $0$ to $x.used - 1$ do \\ +\hspace{3mm}2.1 $\hat W_{ix} \leftarrow x_{ix}$ \\ +3. For $ix$ from $x.used$ to $2n.used - 1$ do \\ +\hspace{3mm}3.1 $\hat W_{ix} \leftarrow 0$ \\ +Elimiate the lower $k$ digits. \\ +4. for $ix$ from $0$ to $n.used - 1$ do \\ +\hspace{3mm}4.1 $\mu \leftarrow \hat W_{ix} \cdot \rho \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{3mm}4.2 For $iy$ from $0$ to $n.used - 1$ do \\ +\hspace{6mm}4.2.1 $\hat W_{iy + ix} \leftarrow \hat W_{iy + ix} + \mu \cdot n_{iy}$ \\ +\hspace{3mm}4.3 $\hat W_{ix + 1} \leftarrow \hat W_{ix + 1} + \lfloor \hat W_{ix} / \beta \rfloor$ \\ +Propagate carries upwards. \\ +5. for $ix$ from $n.used$ to $2n.used + 1$ do \\ +\hspace{3mm}5.1 $\hat W_{ix + 1} \leftarrow \hat W_{ix + 1} + \lfloor \hat W_{ix} / \beta \rfloor$ \\ +Shift right and reduce modulo $\beta$ simultaneously. \\ +6. for $ix$ from $0$ to $n.used + 1$ do \\ +\hspace{3mm}6.1 $x_{ix} \leftarrow \hat W_{ix + n.used} \mbox{ (mod }\beta\mbox{)}$ \\ +Zero excess digits and fixup $x$. \\ +7. if $x.used > n.used + 1$ then do \\ +\hspace{3mm}7.1 for $ix$ from $n.used + 1$ to $x.used - 1$ do \\ +\hspace{6mm}7.1.1 $x_{ix} \leftarrow 0$ \\ +8. $x.used \leftarrow n.used + 1$ \\ +9. Clamp excessive digits of $x$. \\ +10. If $x \ge n$ then \\ +\hspace{3mm}10.1 $x \leftarrow x - n$ \\ +11. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm fast\_mp\_montgomery\_reduce} +\end{figure} + +\textbf{Algorithm fast\_mp\_montgomery\_reduce.} +This algorithm will compute the Montgomery reduction of $x$ modulo $n$ using the Comba technique. It is on most computer platforms significantly +faster than algorithm mp\_montgomery\_reduce and algorithm mp\_reduce (\textit{Barrett reduction}). The algorithm has the same restrictions +on the input as the baseline reduction algorithm. An additional two restrictions are imposed on this algorithm. The number of digits $k$ in the +the modulus $n$ must not violate $MP\_WARRAY > 2k +1$ and $n < \delta$. When $\beta = 2^{28}$ this algorithm can be used to reduce modulo +a modulus of at most $3,556$ bits in length. + +As in the other Comba reduction algorithms there is a $\hat W$ array which stores the columns of the product. It is initially filled with the +contents of $x$ with the excess digits zeroed. The reduction loop is very similar the to the baseline loop at heart. The multiplication on step +4.1 can be single precision only since $ab \mbox{ (mod }\beta\mbox{)} \equiv (a \mbox{ mod }\beta)(b \mbox{ mod }\beta)$. Some multipliers such +as those on the ARM processors take a variable length time to complete depending on the number of bytes of result it must produce. By performing +a single precision multiplication instead half the amount of time is spent. + +Also note that digit $\hat W_{ix}$ must have the carry from the $ix - 1$'th digit propagated upwards in order for this to work. That is what step +4.3 will do. In effect over the $n.used$ iterations of the outer loop the $n.used$'th lower columns all have the their carries propagated forwards. Note +how the upper bits of those same words are not reduced modulo $\beta$. This is because those values will be discarded shortly and there is no +point. + +Step 5 will propagate the remainder of the carries upwards. On step 6 the columns are reduced modulo $\beta$ and shifted simultaneously as they are +stored in the destination $x$. + +EXAM,bn_fast_mp_montgomery_reduce.c + +The $\hat W$ array is first filled with digits of $x$ on line @49,for@ then the rest of the digits are zeroed on line @54,for@. Both loops share +the same alias variables to make the code easier to read. + +The value of $\mu$ is calculated in an interesting fashion. First the value $\hat W_{ix}$ is reduced modulo $\beta$ and cast to a mp\_digit. This +forces the compiler to use a single precision multiplication and prevents any concerns about loss of precision. Line @101,>>@ fixes the carry +for the next iteration of the loop by propagating the carry from $\hat W_{ix}$ to $\hat W_{ix+1}$. + +The for loop on line @113,for@ propagates the rest of the carries upwards through the columns. The for loop on line @126,for@ reduces the columns +modulo $\beta$ and shifts them $k$ places at the same time. The alias $\_ \hat W$ actually refers to the array $\hat W$ starting at the $n.used$'th +digit, that is $\_ \hat W_{t} = \hat W_{n.used + t}$. + +\subsection{Montgomery Setup} +To calculate the variable $\rho$ a relatively simple algorithm will be required. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_montgomery\_setup}. \\ +\textbf{Input}. mp\_int $n$ ($n > 1$ and $(n, 2) = 1$) \\ +\textbf{Output}. $\rho \equiv -1/n_0 \mbox{ (mod }\beta\mbox{)}$ \\ +\hline \\ +1. $b \leftarrow n_0$ \\ +2. If $b$ is even return(\textit{MP\_VAL}) \\ +3. $x \leftarrow (((b + 2) \mbox{ AND } 4) << 1) + b$ \\ +4. for $k$ from 0 to $\lceil lg(lg(\beta)) \rceil - 2$ do \\ +\hspace{3mm}4.1 $x \leftarrow x \cdot (2 - bx)$ \\ +5. $\rho \leftarrow \beta - x \mbox{ (mod }\beta\mbox{)}$ \\ +6. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_montgomery\_setup} +\end{figure} + +\textbf{Algorithm mp\_montgomery\_setup.} +This algorithm will calculate the value of $\rho$ required within the Montgomery reduction algorithms. It uses a very interesting trick +to calculate $1/n_0$ when $\beta$ is a power of two. + +EXAM,bn_mp_montgomery_setup.c + +This source code computes the value of $\rho$ required to perform Montgomery reduction. It has been modified to avoid performing excess +multiplications when $\beta$ is not the default 28-bits. + +\section{The Diminished Radix Algorithm} +The Diminished Radix method of modular reduction \cite{DRMET} is a fairly clever technique which can be more efficient than either the Barrett +or Montgomery methods for certain forms of moduli. The technique is based on the following simple congruence. + +\begin{equation} +(x \mbox{ mod } n) + k \lfloor x / n \rfloor \equiv x \mbox{ (mod }(n - k)\mbox{)} +\end{equation} + +This observation was used in the MMB \cite{MMB} block cipher to create a diffusion primitive. It used the fact that if $n = 2^{31}$ and $k=1$ that +then a x86 multiplier could produce the 62-bit product and use the ``shrd'' instruction to perform a double-precision right shift. The proof +of the above equation is very simple. First write $x$ in the product form. + +\begin{equation} +x = qn + r +\end{equation} + +Now reduce both sides modulo $(n - k)$. + +\begin{equation} +x \equiv qk + r \mbox{ (mod }(n-k)\mbox{)} +\end{equation} + +The variable $n$ reduces modulo $n - k$ to $k$. By putting $q = \lfloor x/n \rfloor$ and $r = x \mbox{ mod } n$ +into the equation the original congruence is reproduced, thus concluding the proof. The following algorithm is based on this observation. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{Diminished Radix Reduction}. \\ +\textbf{Input}. Integer $x$, $n$, $k$ \\ +\textbf{Output}. $x \mbox{ mod } (n - k)$ \\ +\hline \\ +1. $q \leftarrow \lfloor x / n \rfloor$ \\ +2. $q \leftarrow k \cdot q$ \\ +3. $x \leftarrow x \mbox{ (mod }n\mbox{)}$ \\ +4. $x \leftarrow x + q$ \\ +5. If $x \ge (n - k)$ then \\ +\hspace{3mm}5.1 $x \leftarrow x - (n - k)$ \\ +\hspace{3mm}5.2 Goto step 1. \\ +6. Return $x$ \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm Diminished Radix Reduction} +\label{fig:DR} +\end{figure} + +This algorithm will reduce $x$ modulo $n - k$ and return the residue. If $0 \le x < (n - k)^2$ then the algorithm will loop almost always +once or twice and occasionally three times. For simplicity sake the value of $x$ is bounded by the following simple polynomial. + +\begin{equation} +0 \le x < n^2 + k^2 - 2nk +\end{equation} + +The true bound is $0 \le x < (n - k - 1)^2$ but this has quite a few more terms. The value of $q$ after step 1 is bounded by the following. + +\begin{equation} +q < n - 2k - k^2/n +\end{equation} + +Since $k^2$ is going to be considerably smaller than $n$ that term will always be zero. The value of $x$ after step 3 is bounded trivially as +$0 \le x < n$. By step four the sum $x + q$ is bounded by + +\begin{equation} +0 \le q + x < (k + 1)n - 2k^2 - 1 +\end{equation} + +With a second pass $q$ will be loosely bounded by $0 \le q < k^2$ after step 2 while $x$ will still be loosely bounded by $0 \le x < n$ after step 3. After the second pass it is highly unlike that the +sum in step 4 will exceed $n - k$. In practice fewer than three passes of the algorithm are required to reduce virtually every input in the +range $0 \le x < (n - k - 1)^2$. + +\begin{figure} +\begin{small} +\begin{center} +\begin{tabular}{|l|} +\hline +$x = 123456789, n = 256, k = 3$ \\ +\hline $q \leftarrow \lfloor x/n \rfloor = 482253$ \\ +$q \leftarrow q*k = 1446759$ \\ +$x \leftarrow x \mbox{ mod } n = 21$ \\ +$x \leftarrow x + q = 1446780$ \\ +$x \leftarrow x - (n - k) = 1446527$ \\ +\hline +$q \leftarrow \lfloor x/n \rfloor = 5650$ \\ +$q \leftarrow q*k = 16950$ \\ +$x \leftarrow x \mbox{ mod } n = 127$ \\ +$x \leftarrow x + q = 17077$ \\ +$x \leftarrow x - (n - k) = 16824$ \\ +\hline +$q \leftarrow \lfloor x/n \rfloor = 65$ \\ +$q \leftarrow q*k = 195$ \\ +$x \leftarrow x \mbox{ mod } n = 184$ \\ +$x \leftarrow x + q = 379$ \\ +$x \leftarrow x - (n - k) = 126$ \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Example Diminished Radix Reduction} +\label{fig:EXDR} +\end{figure} + +Figure~\ref{fig:EXDR} demonstrates the reduction of $x = 123456789$ modulo $n - k = 253$ when $n = 256$ and $k = 3$. Note that even while $x$ +is considerably larger than $(n - k - 1)^2 = 63504$ the algorithm still converges on the modular residue exceedingly fast. In this case only +three passes were required to find the residue $x \equiv 126$. + + +\subsection{Choice of Moduli} +On the surface this algorithm looks like a very expensive algorithm. It requires a couple of subtractions followed by multiplication and other +modular reductions. The usefulness of this algorithm becomes exceedingly clear when an appropriate modulus is chosen. + +Division in general is a very expensive operation to perform. The one exception is when the division is by a power of the radix of representation used. +Division by ten for example is simple for pencil and paper mathematics since it amounts to shifting the decimal place to the right. Similarly division +by two (\textit{or powers of two}) is very simple for binary computers to perform. It would therefore seem logical to choose $n$ of the form $2^p$ +which would imply that $\lfloor x / n \rfloor$ is a simple shift of $x$ right $p$ bits. + +However, there is one operation related to division of power of twos that is even faster than this. If $n = \beta^p$ then the division may be +performed by moving whole digits to the right $p$ places. In practice division by $\beta^p$ is much faster than division by $2^p$ for any $p$. +Also with the choice of $n = \beta^p$ reducing $x$ modulo $n$ merely requires zeroing the digits above the $p-1$'th digit of $x$. + +Throughout the next section the term ``restricted modulus'' will refer to a modulus of the form $\beta^p - k$ whereas the term ``unrestricted +modulus'' will refer to a modulus of the form $2^p - k$. The word ``restricted'' in this case refers to the fact that it is based on the +$2^p$ logic except $p$ must be a multiple of $lg(\beta)$. + +\subsection{Choice of $k$} +Now that division and reduction (\textit{step 1 and 3 of figure~\ref{fig:DR}}) have been optimized to simple digit operations the multiplication by $k$ +in step 2 is the most expensive operation. Fortunately the choice of $k$ is not terribly limited. For all intents and purposes it might +as well be a single digit. The smaller the value of $k$ is the faster the algorithm will be. + +\subsection{Restricted Diminished Radix Reduction} +The restricted Diminished Radix algorithm can quickly reduce an input modulo a modulus of the form $n = \beta^p - k$. This algorithm can reduce +an input $x$ within the range $0 \le x < n^2$ using only a couple passes of the algorithm demonstrated in figure~\ref{fig:DR}. The implementation +of this algorithm has been optimized to avoid additional overhead associated with a division by $\beta^p$, the multiplication by $k$ or the addition +of $x$ and $q$. The resulting algorithm is very efficient and can lead to substantial improvements over Barrett and Montgomery reduction when modular +exponentiations are performed. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_dr\_reduce}. \\ +\textbf{Input}. mp\_int $x$, $n$ and a mp\_digit $k = \beta - n_0$ \\ +\hspace{11.5mm}($0 \le x < n^2$, $n > 1$, $0 < k < \beta$) \\ +\textbf{Output}. $x \mbox{ mod } n$ \\ +\hline \\ +1. $m \leftarrow n.used$ \\ +2. If $x.alloc < 2m$ then grow $x$ to $2m$ digits. \\ +3. $\mu \leftarrow 0$ \\ +4. for $i$ from $0$ to $m - 1$ do \\ +\hspace{3mm}4.1 $\hat r \leftarrow k \cdot x_{m+i} + x_{i} + \mu$ \\ +\hspace{3mm}4.2 $x_{i} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{3mm}4.3 $\mu \leftarrow \lfloor \hat r / \beta \rfloor$ \\ +5. $x_{m} \leftarrow \mu$ \\ +6. for $i$ from $m + 1$ to $x.used - 1$ do \\ +\hspace{3mm}6.1 $x_{i} \leftarrow 0$ \\ +7. Clamp excess digits of $x$. \\ +8. If $x \ge n$ then \\ +\hspace{3mm}8.1 $x \leftarrow x - n$ \\ +\hspace{3mm}8.2 Goto step 3. \\ +9. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_dr\_reduce} +\end{figure} + +\textbf{Algorithm mp\_dr\_reduce.} +This algorithm will perform the Dimished Radix reduction of $x$ modulo $n$. It has similar restrictions to that of the Barrett reduction +with the addition that $n$ must be of the form $n = \beta^m - k$ where $0 < k <\beta$. + +This algorithm essentially implements the pseudo-code in figure~\ref{fig:DR} except with a slight optimization. The division by $\beta^m$, multiplication by $k$ +and addition of $x \mbox{ mod }\beta^m$ are all performed simultaneously inside the loop on step 4. The division by $\beta^m$ is emulated by accessing +the term at the $m+i$'th position which is subsequently multiplied by $k$ and added to the term at the $i$'th position. After the loop the $m$'th +digit is set to the carry and the upper digits are zeroed. Steps 5 and 6 emulate the reduction modulo $\beta^m$ that should have happend to +$x$ before the addition of the multiple of the upper half. + +At step 8 if $x$ is still larger than $n$ another pass of the algorithm is required. First $n$ is subtracted from $x$ and then the algorithm resumes +at step 3. + +EXAM,bn_mp_dr_reduce.c + +The first step is to grow $x$ as required to $2m$ digits since the reduction is performed in place on $x$. The label on line @49,top:@ is where +the algorithm will resume if further reduction passes are required. In theory it could be placed at the top of the function however, the size of +the modulus and question of whether $x$ is large enough are invariant after the first pass meaning that it would be a waste of time. + +The aliases $tmpx1$ and $tmpx2$ refer to the digits of $x$ where the latter is offset by $m$ digits. By reading digits from $x$ offset by $m$ digits +a division by $\beta^m$ can be simulated virtually for free. The loop on line @61,for@ performs the bulk of the work (\textit{corresponds to step 4 of algorithm 7.11}) +in this algorithm. + +By line @68,mu@ the pointer $tmpx1$ points to the $m$'th digit of $x$ which is where the final carry will be placed. Similarly by line @71,for@ the +same pointer will point to the $m+1$'th digit where the zeroes will be placed. + +Since the algorithm is only valid if both $x$ and $n$ are greater than zero an unsigned comparison suffices to determine if another pass is required. +With the same logic at line @82,sub@ the value of $x$ is known to be greater than or equal to $n$ meaning that an unsigned subtraction can be used +as well. Since the destination of the subtraction is the larger of the inputs the call to algorithm s\_mp\_sub cannot fail and the return code +does not need to be checked. + +\subsubsection{Setup} +To setup the restricted Diminished Radix algorithm the value $k = \beta - n_0$ is required. This algorithm is not really complicated but provided for +completeness. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_dr\_setup}. \\ +\textbf{Input}. mp\_int $n$ \\ +\textbf{Output}. $k = \beta - n_0$ \\ +\hline \\ +1. $k \leftarrow \beta - n_0$ \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_dr\_setup} +\end{figure} + +EXAM,bn_mp_dr_setup.c + +\subsubsection{Modulus Detection} +Another algorithm which will be useful is the ability to detect a restricted Diminished Radix modulus. An integer is said to be +of restricted Diminished Radix form if all of the digits are equal to $\beta - 1$ except the trailing digit which may be any value. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_dr\_is\_modulus}. \\ +\textbf{Input}. mp\_int $n$ \\ +\textbf{Output}. $1$ if $n$ is in D.R form, $0$ otherwise \\ +\hline +1. If $n.used < 2$ then return($0$). \\ +2. for $ix$ from $1$ to $n.used - 1$ do \\ +\hspace{3mm}2.1 If $n_{ix} \ne \beta - 1$ return($0$). \\ +3. Return($1$). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_dr\_is\_modulus} +\end{figure} + +\textbf{Algorithm mp\_dr\_is\_modulus.} +This algorithm determines if a value is in Diminished Radix form. Step 1 rejects obvious cases where fewer than two digits are +in the mp\_int. Step 2 tests all but the first digit to see if they are equal to $\beta - 1$. If the algorithm manages to get to +step 3 then $n$ must be of Diminished Radix form. + +EXAM,bn_mp_dr_is_modulus.c + +\subsection{Unrestricted Diminished Radix Reduction} +The unrestricted Diminished Radix algorithm allows modular reductions to be performed when the modulus is of the form $2^p - k$. This algorithm +is a straightforward adaptation of algorithm~\ref{fig:DR}. + +In general the restricted Diminished Radix reduction algorithm is much faster since it has considerably lower overhead. However, this new +algorithm is much faster than either Montgomery or Barrett reduction when the moduli are of the appropriate form. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_reduce\_2k}. \\ +\textbf{Input}. mp\_int $a$ and $n$. mp\_digit $k$ \\ +\hspace{11.5mm}($a \ge 0$, $n > 1$, $0 < k < \beta$, $n + k$ is a power of two) \\ +\textbf{Output}. $a \mbox{ (mod }n\mbox{)}$ \\ +\hline +1. $p \leftarrow \lceil lg(n) \rceil$ (\textit{mp\_count\_bits}) \\ +2. While $a \ge n$ do \\ +\hspace{3mm}2.1 $q \leftarrow \lfloor a / 2^p \rfloor$ (\textit{mp\_div\_2d}) \\ +\hspace{3mm}2.2 $a \leftarrow a \mbox{ (mod }2^p\mbox{)}$ (\textit{mp\_mod\_2d}) \\ +\hspace{3mm}2.3 $q \leftarrow q \cdot k$ (\textit{mp\_mul\_d}) \\ +\hspace{3mm}2.4 $a \leftarrow a - q$ (\textit{s\_mp\_sub}) \\ +\hspace{3mm}2.5 If $a \ge n$ then do \\ +\hspace{6mm}2.5.1 $a \leftarrow a - n$ \\ +3. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_reduce\_2k} +\end{figure} + +\textbf{Algorithm mp\_reduce\_2k.} +This algorithm quickly reduces an input $a$ modulo an unrestricted Diminished Radix modulus $n$. Division by $2^p$ is emulated with a right +shift which makes the algorithm fairly inexpensive to use. + +EXAM,bn_mp_reduce_2k.c + +The algorithm mp\_count\_bits calculates the number of bits in an mp\_int which is used to find the initial value of $p$. The call to mp\_div\_2d +on line @31,mp_div_2d@ calculates both the quotient $q$ and the remainder $a$ required. By doing both in a single function call the code size +is kept fairly small. The multiplication by $k$ is only performed if $k > 1$. This allows reductions modulo $2^p - 1$ to be performed without +any multiplications. + +The unsigned s\_mp\_add, mp\_cmp\_mag and s\_mp\_sub are used in place of their full sign counterparts since the inputs are only valid if they are +positive. By using the unsigned versions the overhead is kept to a minimum. + +\subsubsection{Unrestricted Setup} +To setup this reduction algorithm the value of $k = 2^p - n$ is required. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_reduce\_2k\_setup}. \\ +\textbf{Input}. mp\_int $n$ \\ +\textbf{Output}. $k = 2^p - n$ \\ +\hline +1. $p \leftarrow \lceil lg(n) \rceil$ (\textit{mp\_count\_bits}) \\ +2. $x \leftarrow 2^p$ (\textit{mp\_2expt}) \\ +3. $x \leftarrow x - n$ (\textit{mp\_sub}) \\ +4. $k \leftarrow x_0$ \\ +5. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_reduce\_2k\_setup} +\end{figure} + +\textbf{Algorithm mp\_reduce\_2k\_setup.} +This algorithm computes the value of $k$ required for the algorithm mp\_reduce\_2k. By making a temporary variable $x$ equal to $2^p$ a subtraction +is sufficient to solve for $k$. Alternatively if $n$ has more than one digit the value of $k$ is simply $\beta - n_0$. + +EXAM,bn_mp_reduce_2k_setup.c + +\subsubsection{Unrestricted Detection} +An integer $n$ is a valid unrestricted Diminished Radix modulus if either of the following are true. + +\begin{enumerate} +\item The number has only one digit. +\item The number has more than one digit and every bit from the $\beta$'th to the most significant is one. +\end{enumerate} + +If either condition is true than there is a power of two $2^p$ such that $0 < 2^p - n < \beta$. If the input is only +one digit than it will always be of the correct form. Otherwise all of the bits above the first digit must be one. This arises from the fact +that there will be value of $k$ that when added to the modulus causes a carry in the first digit which propagates all the way to the most +significant bit. The resulting sum will be a power of two. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_reduce\_is\_2k}. \\ +\textbf{Input}. mp\_int $n$ \\ +\textbf{Output}. $1$ if of proper form, $0$ otherwise \\ +\hline +1. If $n.used = 0$ then return($0$). \\ +2. If $n.used = 1$ then return($1$). \\ +3. $p \leftarrow \lceil lg(n) \rceil$ (\textit{mp\_count\_bits}) \\ +4. for $x$ from $lg(\beta)$ to $p$ do \\ +\hspace{3mm}4.1 If the ($x \mbox{ mod }lg(\beta)$)'th bit of the $\lfloor x / lg(\beta) \rfloor$ of $n$ is zero then return($0$). \\ +5. Return($1$). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_reduce\_is\_2k} +\end{figure} + +\textbf{Algorithm mp\_reduce\_is\_2k.} +This algorithm quickly determines if a modulus is of the form required for algorithm mp\_reduce\_2k to function properly. + +EXAM,bn_mp_reduce_is_2k.c + + + +\section{Algorithm Comparison} +So far three very different algorithms for modular reduction have been discussed. Each of the algorithms have their own strengths and weaknesses +that makes having such a selection very useful. The following table sumarizes the three algorithms along with comparisons of work factors. Since +all three algorithms have the restriction that $0 \le x < n^2$ and $n > 1$ those limitations are not included in the table. + +\begin{center} +\begin{small} +\begin{tabular}{|c|c|c|c|c|c|} +\hline \textbf{Method} & \textbf{Work Required} & \textbf{Limitations} & \textbf{$m = 8$} & \textbf{$m = 32$} & \textbf{$m = 64$} \\ +\hline Barrett & $m^2 + 2m - 1$ & None & $79$ & $1087$ & $4223$ \\ +\hline Montgomery & $m^2 + m$ & $n$ must be odd & $72$ & $1056$ & $4160$ \\ +\hline D.R. & $2m$ & $n = \beta^m - k$ & $16$ & $64$ & $128$ \\ +\hline +\end{tabular} +\end{small} +\end{center} + +In theory Montgomery and Barrett reductions would require roughly the same amount of time to complete. However, in practice since Montgomery +reduction can be written as a single function with the Comba technique it is much faster. Barrett reduction suffers from the overhead of +calling the half precision multipliers, addition and division by $\beta$ algorithms. + +For almost every cryptographic algorithm Montgomery reduction is the algorithm of choice. The one set of algorithms where Diminished Radix reduction truly +shines are based on the discrete logarithm problem such as Diffie-Hellman \cite{DH} and ElGamal \cite{ELGAMAL}. In these algorithms +primes of the form $\beta^m - k$ can be found and shared amongst users. These primes will allow the Diminished Radix algorithm to be used in +modular exponentiation to greatly speed up the operation. + + + +\section*{Exercises} +\begin{tabular}{cl} +$\left [ 3 \right ]$ & Prove that the ``trick'' in algorithm mp\_montgomery\_setup actually \\ + & calculates the correct value of $\rho$. \\ + & \\ +$\left [ 2 \right ]$ & Devise an algorithm to reduce modulo $n + k$ for small $k$ quickly. \\ + & \\ +$\left [ 4 \right ]$ & Prove that the pseudo-code algorithm ``Diminished Radix Reduction'' \\ + & (\textit{figure~\ref{fig:DR}}) terminates. Also prove the probability that it will \\ + & terminate within $1 \le k \le 10$ iterations. \\ + & \\ +\end{tabular} + + +\chapter{Exponentiation} +Exponentiation is the operation of raising one variable to the power of another, for example, $a^b$. A variant of exponentiation, computed +in a finite field or ring, is called modular exponentiation. This latter style of operation is typically used in public key +cryptosystems such as RSA and Diffie-Hellman. The ability to quickly compute modular exponentiations is of great benefit to any +such cryptosystem and many methods have been sought to speed it up. + +\section{Exponentiation Basics} +A trivial algorithm would simply multiply $a$ against itself $b - 1$ times to compute the exponentiation desired. However, as $b$ grows in size +the number of multiplications becomes prohibitive. Imagine what would happen if $b$ $\approx$ $2^{1024}$ as is the case when computing an RSA signature +with a $1024$-bit key. Such a calculation could never be completed as it would take simply far too long. + +Fortunately there is a very simple algorithm based on the laws of exponents. Recall that $lg_a(a^b) = b$ and that $lg_a(a^ba^c) = b + c$ which +are two trivial relationships between the base and the exponent. Let $b_i$ represent the $i$'th bit of $b$ starting from the least +significant bit. If $b$ is a $k$-bit integer than the following equation is true. + +\begin{equation} +a^b = \prod_{i=0}^{k-1} a^{2^i \cdot b_i} +\end{equation} + +By taking the base $a$ logarithm of both sides of the equation the following equation is the result. + +\begin{equation} +b = \sum_{i=0}^{k-1}2^i \cdot b_i +\end{equation} + +The term $a^{2^i}$ can be found from the $i - 1$'th term by squaring the term since $\left ( a^{2^i} \right )^2$ is equal to +$a^{2^{i+1}}$. This observation forms the basis of essentially all fast exponentiation algorithms. It requires $k$ squarings and on average +$k \over 2$ multiplications to compute the result. This is indeed quite an improvement over simply multiplying by $a$ a total of $b-1$ times. + +While this current method is a considerable speed up there are further improvements to be made. For example, the $a^{2^i}$ term does not need to +be computed in an auxilary variable. Consider the following equivalent algorithm. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{Left to Right Exponentiation}. \\ +\textbf{Input}. Integer $a$, $b$ and $k$ \\ +\textbf{Output}. $c = a^b$ \\ +\hline \\ +1. $c \leftarrow 1$ \\ +2. for $i$ from $k - 1$ to $0$ do \\ +\hspace{3mm}2.1 $c \leftarrow c^2$ \\ +\hspace{3mm}2.2 $c \leftarrow c \cdot a^{b_i}$ \\ +3. Return $c$. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Left to Right Exponentiation} +\label{fig:LTOR} +\end{figure} + +This algorithm starts from the most significant bit and works towards the least significant bit. When the $i$'th bit of $b$ is set $a$ is +multiplied against the current product. In each iteration the product is squared which doubles the exponent of the individual terms of the +product. + +For example, let $b = 101100_2 \equiv 44_{10}$. The following chart demonstrates the actions of the algorithm. + +\newpage\begin{figure} +\begin{center} +\begin{tabular}{|c|c|} +\hline \textbf{Value of $i$} & \textbf{Value of $c$} \\ +\hline - & $1$ \\ +\hline $5$ & $a$ \\ +\hline $4$ & $a^2$ \\ +\hline $3$ & $a^4 \cdot a$ \\ +\hline $2$ & $a^8 \cdot a^2 \cdot a$ \\ +\hline $1$ & $a^{16} \cdot a^4 \cdot a^2$ \\ +\hline $0$ & $a^{32} \cdot a^8 \cdot a^4$ \\ +\hline +\end{tabular} +\end{center} +\caption{Example of Left to Right Exponentiation} +\end{figure} + +When the product $a^{32} \cdot a^8 \cdot a^4$ is simplified it is equal $a^{44}$ which is the desired exponentiation. This particular algorithm is +called ``Left to Right'' because it reads the exponent in that order. All of the exponentiation algorithms that will be presented are of this nature. + +\subsection{Single Digit Exponentiation} +The first algorithm in the series of exponentiation algorithms will be an unbounded algorithm where the exponent is a single digit. It is intended +to be used when a small power of an input is required (\textit{e.g. $a^5$}). It is faster than simply multiplying $b - 1$ times for all values of +$b$ that are greater than three. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_expt\_d}. \\ +\textbf{Input}. mp\_int $a$ and mp\_digit $b$ \\ +\textbf{Output}. $c = a^b$ \\ +\hline \\ +1. $g \leftarrow a$ (\textit{mp\_init\_copy}) \\ +2. $c \leftarrow 1$ (\textit{mp\_set}) \\ +3. for $x$ from 1 to $lg(\beta)$ do \\ +\hspace{3mm}3.1 $c \leftarrow c^2$ (\textit{mp\_sqr}) \\ +\hspace{3mm}3.2 If $b$ AND $2^{lg(\beta) - 1} \ne 0$ then \\ +\hspace{6mm}3.2.1 $c \leftarrow c \cdot g$ (\textit{mp\_mul}) \\ +\hspace{3mm}3.3 $b \leftarrow b << 1$ \\ +4. Clear $g$. \\ +5. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_expt\_d} +\end{figure} + +\textbf{Algorithm mp\_expt\_d.} +This algorithm computes the value of $a$ raised to the power of a single digit $b$. It uses the left to right exponentiation algorithm to +quickly compute the exponentiation. It is loosely based on algorithm 14.79 of HAC \cite[pp. 615]{HAC} with the difference that the +exponent is a fixed width. + +A copy of $a$ is made first to allow destination variable $c$ be the same as the source variable $a$. The result is set to the initial value of +$1$ in the subsequent step. + +Inside the loop the exponent is read from the most significant bit first down to the least significant bit. First $c$ is invariably squared +on step 3.1. In the following step if the most significant bit of $b$ is one the copy of $a$ is multiplied against $c$. The value +of $b$ is shifted left one bit to make the next bit down from the most signficant bit the new most significant bit. In effect each +iteration of the loop moves the bits of the exponent $b$ upwards to the most significant location. + +EXAM,bn_mp_expt_d.c + +Line @29,mp_set@ sets the initial value of the result to $1$. Next the loop on line @31,for@ steps through each bit of the exponent starting from +the most significant down towards the least significant. The invariant squaring operation placed on line @333,mp_sqr@ is performed first. After +the squaring the result $c$ is multiplied by the base $g$ if and only if the most significant bit of the exponent is set. The shift on line +@47,<<@ moves all of the bits of the exponent upwards towards the most significant location. + +\section{$k$-ary Exponentiation} +When calculating an exponentiation the most time consuming bottleneck is the multiplications which are in general a small factor +slower than squaring. Recall from the previous algorithm that $b_{i}$ refers to the $i$'th bit of the exponent $b$. Suppose instead it referred to +the $i$'th $k$-bit digit of the exponent of $b$. For $k = 1$ the definitions are synonymous and for $k > 1$ algorithm~\ref{fig:KARY} +computes the same exponentiation. A group of $k$ bits from the exponent is called a \textit{window}. That is it is a small window on only a +portion of the entire exponent. Consider the following modification to the basic left to right exponentiation algorithm. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{$k$-ary Exponentiation}. \\ +\textbf{Input}. Integer $a$, $b$, $k$ and $t$ \\ +\textbf{Output}. $c = a^b$ \\ +\hline \\ +1. $c \leftarrow 1$ \\ +2. for $i$ from $t - 1$ to $0$ do \\ +\hspace{3mm}2.1 $c \leftarrow c^{2^k} $ \\ +\hspace{3mm}2.2 Extract the $i$'th $k$-bit word from $b$ and store it in $g$. \\ +\hspace{3mm}2.3 $c \leftarrow c \cdot a^g$ \\ +3. Return $c$. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{$k$-ary Exponentiation} +\label{fig:KARY} +\end{figure} + +The squaring on step 2.1 can be calculated by squaring the value $c$ successively $k$ times. If the values of $a^g$ for $0 < g < 2^k$ have been +precomputed this algorithm requires only $t$ multiplications and $tk$ squarings. The table can be generated with $2^{k - 1} - 1$ squarings and +$2^{k - 1} + 1$ multiplications. This algorithm assumes that the number of bits in the exponent is evenly divisible by $k$. +However, when it is not the remaining $0 < x \le k - 1$ bits can be handled with algorithm~\ref{fig:LTOR}. + +Suppose $k = 4$ and $t = 100$. This modified algorithm will require $109$ multiplications and $408$ squarings to compute the exponentiation. The +original algorithm would on average have required $200$ multiplications and $400$ squrings to compute the same value. The total number of squarings +has increased slightly but the number of multiplications has nearly halved. + +\subsection{Optimal Values of $k$} +An optimal value of $k$ will minimize $2^{k} + \lceil n / k \rceil + n - 1$ for a fixed number of bits in the exponent $n$. The simplest +approach is to brute force search amongst the values $k = 2, 3, \ldots, 8$ for the lowest result. Table~\ref{fig:OPTK} lists optimal values of $k$ +for various exponent sizes and compares the number of multiplication and squarings required against algorithm~\ref{fig:LTOR}. + +\begin{figure}[here] +\begin{center} +\begin{small} +\begin{tabular}{|c|c|c|c|c|c|} +\hline \textbf{Exponent (bits)} & \textbf{Optimal $k$} & \textbf{Work at $k$} & \textbf{Work with ~\ref{fig:LTOR}} \\ +\hline $16$ & $2$ & $27$ & $24$ \\ +\hline $32$ & $3$ & $49$ & $48$ \\ +\hline $64$ & $3$ & $92$ & $96$ \\ +\hline $128$ & $4$ & $175$ & $192$ \\ +\hline $256$ & $4$ & $335$ & $384$ \\ +\hline $512$ & $5$ & $645$ & $768$ \\ +\hline $1024$ & $6$ & $1257$ & $1536$ \\ +\hline $2048$ & $6$ & $2452$ & $3072$ \\ +\hline $4096$ & $7$ & $4808$ & $6144$ \\ +\hline +\end{tabular} +\end{small} +\end{center} +\caption{Optimal Values of $k$ for $k$-ary Exponentiation} +\label{fig:OPTK} +\end{figure} + +\subsection{Sliding-Window Exponentiation} +A simple modification to the previous algorithm is only generate the upper half of the table in the range $2^{k-1} \le g < 2^k$. Essentially +this is a table for all values of $g$ where the most significant bit of $g$ is a one. However, in order for this to be allowed in the +algorithm values of $g$ in the range $0 \le g < 2^{k-1}$ must be avoided. + +Table~\ref{fig:OPTK2} lists optimal values of $k$ for various exponent sizes and compares the work required against algorithm~\ref{fig:KARY}. + +\begin{figure}[here] +\begin{center} +\begin{small} +\begin{tabular}{|c|c|c|c|c|c|} +\hline \textbf{Exponent (bits)} & \textbf{Optimal $k$} & \textbf{Work at $k$} & \textbf{Work with ~\ref{fig:KARY}} \\ +\hline $16$ & $3$ & $24$ & $27$ \\ +\hline $32$ & $3$ & $45$ & $49$ \\ +\hline $64$ & $4$ & $87$ & $92$ \\ +\hline $128$ & $4$ & $167$ & $175$ \\ +\hline $256$ & $5$ & $322$ & $335$ \\ +\hline $512$ & $6$ & $628$ & $645$ \\ +\hline $1024$ & $6$ & $1225$ & $1257$ \\ +\hline $2048$ & $7$ & $2403$ & $2452$ \\ +\hline $4096$ & $8$ & $4735$ & $4808$ \\ +\hline +\end{tabular} +\end{small} +\end{center} +\caption{Optimal Values of $k$ for Sliding Window Exponentiation} +\label{fig:OPTK2} +\end{figure} + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{Sliding Window $k$-ary Exponentiation}. \\ +\textbf{Input}. Integer $a$, $b$, $k$ and $t$ \\ +\textbf{Output}. $c = a^b$ \\ +\hline \\ +1. $c \leftarrow 1$ \\ +2. for $i$ from $t - 1$ to $0$ do \\ +\hspace{3mm}2.1 If the $i$'th bit of $b$ is a zero then \\ +\hspace{6mm}2.1.1 $c \leftarrow c^2$ \\ +\hspace{3mm}2.2 else do \\ +\hspace{6mm}2.2.1 $c \leftarrow c^{2^k}$ \\ +\hspace{6mm}2.2.2 Extract the $k$ bits from $(b_{i}b_{i-1}\ldots b_{i-(k-1)})$ and store it in $g$. \\ +\hspace{6mm}2.2.3 $c \leftarrow c \cdot a^g$ \\ +\hspace{6mm}2.2.4 $i \leftarrow i - k$ \\ +3. Return $c$. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Sliding Window $k$-ary Exponentiation} +\end{figure} + +Similar to the previous algorithm this algorithm must have a special handler when fewer than $k$ bits are left in the exponent. While this +algorithm requires the same number of squarings it can potentially have fewer multiplications. The pre-computed table $a^g$ is also half +the size as the previous table. + +Consider the exponent $b = 111101011001000_2 \equiv 31432_{10}$ with $k = 3$ using both algorithms. The first algorithm will divide the exponent up as +the following five $3$-bit words $b \equiv \left ( 111, 101, 011, 001, 000 \right )_{2}$. The second algorithm will break the +exponent as $b \equiv \left ( 111, 101, 0, 110, 0, 100, 0 \right )_{2}$. The single digit $0$ in the second representation are where +a single squaring took place instead of a squaring and multiplication. In total the first method requires $10$ multiplications and $18$ +squarings. The second method requires $8$ multiplications and $18$ squarings. + +In general the sliding window method is never slower than the generic $k$-ary method and often it is slightly faster. + +\section{Modular Exponentiation} + +Modular exponentiation is essentially computing the power of a base within a finite field or ring. For example, computing +$d \equiv a^b \mbox{ (mod }c\mbox{)}$ is a modular exponentiation. Instead of first computing $a^b$ and then reducing it +modulo $c$ the intermediate result is reduced modulo $c$ after every squaring or multiplication operation. + +This guarantees that any intermediate result is bounded by $0 \le d \le c^2 - 2c + 1$ and can be reduced modulo $c$ quickly using +one of the algorithms presented in ~REDUCTION~. + +Before the actual modular exponentiation algorithm can be written a wrapper algorithm must be written first. This algorithm +will allow the exponent $b$ to be negative which is computed as $c \equiv \left (1 / a \right )^{\vert b \vert} \mbox{(mod }d\mbox{)}$. The +value of $(1/a) \mbox{ mod }c$ is computed using the modular inverse (\textit{see \ref{sec;modinv}}). If no inverse exists the algorithm +terminates with an error. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_exptmod}. \\ +\textbf{Input}. mp\_int $a$, $b$ and $c$ \\ +\textbf{Output}. $y \equiv g^x \mbox{ (mod }p\mbox{)}$ \\ +\hline \\ +1. If $c.sign = MP\_NEG$ return(\textit{MP\_VAL}). \\ +2. If $b.sign = MP\_NEG$ then \\ +\hspace{3mm}2.1 $g' \leftarrow g^{-1} \mbox{ (mod }c\mbox{)}$ \\ +\hspace{3mm}2.2 $x' \leftarrow \vert x \vert$ \\ +\hspace{3mm}2.3 Compute $d \equiv g'^{x'} \mbox{ (mod }c\mbox{)}$ via recursion. \\ +3. if $p$ is odd \textbf{OR} $p$ is a D.R. modulus then \\ +\hspace{3mm}3.1 Compute $y \equiv g^{x} \mbox{ (mod }p\mbox{)}$ via algorithm mp\_exptmod\_fast. \\ +4. else \\ +\hspace{3mm}4.1 Compute $y \equiv g^{x} \mbox{ (mod }p\mbox{)}$ via algorithm s\_mp\_exptmod. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_exptmod} +\end{figure} + +\textbf{Algorithm mp\_exptmod.} +The first algorithm which actually performs modular exponentiation is algorithm s\_mp\_exptmod. It is a sliding window $k$-ary algorithm +which uses Barrett reduction to reduce the product modulo $p$. The second algorithm mp\_exptmod\_fast performs the same operation +except it uses either Montgomery or Diminished Radix reduction. The two latter reduction algorithms are clumped in the same exponentiation +algorithm since their arguments are essentially the same (\textit{two mp\_ints and one mp\_digit}). + +EXAM,bn_mp_exptmod.c + +In order to keep the algorithms in a known state the first step on line @29,if@ is to reject any negative modulus as input. If the exponent is +negative the algorithm tries to perform a modular exponentiation with the modular inverse of the base $G$. The temporary variable $tmpG$ is assigned +the modular inverse of $G$ and $tmpX$ is assigned the absolute value of $X$. The algorithm will recuse with these new values with a positive +exponent. + +If the exponent is positive the algorithm resumes the exponentiation. Line @63,dr_@ determines if the modulus is of the restricted Diminished Radix +form. If it is not line @65,reduce@ attempts to determine if it is of a unrestricted Diminished Radix form. The integer $dr$ will take on one +of three values. + +\begin{enumerate} +\item $dr = 0$ means that the modulus is not of either restricted or unrestricted Diminished Radix form. +\item $dr = 1$ means that the modulus is of restricted Diminished Radix form. +\item $dr = 2$ means that the modulus is of unrestricted Diminished Radix form. +\end{enumerate} + +Line @69,if@ determines if the fast modular exponentiation algorithm can be used. It is allowed if $dr \ne 0$ or if the modulus is odd. Otherwise, +the slower s\_mp\_exptmod algorithm is used which uses Barrett reduction. + +\subsection{Barrett Modular Exponentiation} + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{s\_mp\_exptmod}. \\ +\textbf{Input}. mp\_int $a$, $b$ and $c$ \\ +\textbf{Output}. $y \equiv g^x \mbox{ (mod }p\mbox{)}$ \\ +\hline \\ +1. $k \leftarrow lg(x)$ \\ +2. $winsize \leftarrow \left \lbrace \begin{array}{ll} + 2 & \mbox{if }k \le 7 \\ + 3 & \mbox{if }7 < k \le 36 \\ + 4 & \mbox{if }36 < k \le 140 \\ + 5 & \mbox{if }140 < k \le 450 \\ + 6 & \mbox{if }450 < k \le 1303 \\ + 7 & \mbox{if }1303 < k \le 3529 \\ + 8 & \mbox{if }3529 < k \\ + \end{array} \right .$ \\ +3. Initialize $2^{winsize}$ mp\_ints in an array named $M$ and one mp\_int named $\mu$ \\ +4. Calculate the $\mu$ required for Barrett Reduction (\textit{mp\_reduce\_setup}). \\ +5. $M_1 \leftarrow g \mbox{ (mod }p\mbox{)}$ \\ +\\ +Setup the table of small powers of $g$. First find $g^{2^{winsize}}$ and then all multiples of it. \\ +6. $k \leftarrow 2^{winsize - 1}$ \\ +7. $M_{k} \leftarrow M_1$ \\ +8. for $ix$ from 0 to $winsize - 2$ do \\ +\hspace{3mm}8.1 $M_k \leftarrow \left ( M_k \right )^2$ (\textit{mp\_sqr}) \\ +\hspace{3mm}8.2 $M_k \leftarrow M_k \mbox{ (mod }p\mbox{)}$ (\textit{mp\_reduce}) \\ +9. for $ix$ from $2^{winsize - 1} + 1$ to $2^{winsize} - 1$ do \\ +\hspace{3mm}9.1 $M_{ix} \leftarrow M_{ix - 1} \cdot M_{1}$ (\textit{mp\_mul}) \\ +\hspace{3mm}9.2 $M_{ix} \leftarrow M_{ix} \mbox{ (mod }p\mbox{)}$ (\textit{mp\_reduce}) \\ +10. $res \leftarrow 1$ \\ +\\ +Start Sliding Window. \\ +11. $mode \leftarrow 0, bitcnt \leftarrow 1, buf \leftarrow 0, digidx \leftarrow x.used - 1, bitcpy \leftarrow 0, bitbuf \leftarrow 0$ \\ +12. Loop \\ +\hspace{3mm}12.1 $bitcnt \leftarrow bitcnt - 1$ \\ +\hspace{3mm}12.2 If $bitcnt = 0$ then do \\ +\hspace{6mm}12.2.1 If $digidx = -1$ goto step 13. \\ +\hspace{6mm}12.2.2 $buf \leftarrow x_{digidx}$ \\ +\hspace{6mm}12.2.3 $digidx \leftarrow digidx - 1$ \\ +\hspace{6mm}12.2.4 $bitcnt \leftarrow lg(\beta)$ \\ +Continued on next page. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm s\_mp\_exptmod} +\end{figure} + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{s\_mp\_exptmod} (\textit{continued}). \\ +\textbf{Input}. mp\_int $a$, $b$ and $c$ \\ +\textbf{Output}. $y \equiv g^x \mbox{ (mod }p\mbox{)}$ \\ +\hline \\ +\hspace{3mm}12.3 $y \leftarrow (buf >> (lg(\beta) - 1))$ AND $1$ \\ +\hspace{3mm}12.4 $buf \leftarrow buf << 1$ \\ +\hspace{3mm}12.5 if $mode = 0$ and $y = 0$ then goto step 12. \\ +\hspace{3mm}12.6 if $mode = 1$ and $y = 0$ then do \\ +\hspace{6mm}12.6.1 $res \leftarrow res^2$ \\ +\hspace{6mm}12.6.2 $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\ +\hspace{6mm}12.6.3 Goto step 12. \\ +\hspace{3mm}12.7 $bitcpy \leftarrow bitcpy + 1$ \\ +\hspace{3mm}12.8 $bitbuf \leftarrow bitbuf + (y << (winsize - bitcpy))$ \\ +\hspace{3mm}12.9 $mode \leftarrow 2$ \\ +\hspace{3mm}12.10 If $bitcpy = winsize$ then do \\ +\hspace{6mm}Window is full so perform the squarings and single multiplication. \\ +\hspace{6mm}12.10.1 for $ix$ from $0$ to $winsize -1$ do \\ +\hspace{9mm}12.10.1.1 $res \leftarrow res^2$ \\ +\hspace{9mm}12.10.1.2 $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\ +\hspace{6mm}12.10.2 $res \leftarrow res \cdot M_{bitbuf}$ \\ +\hspace{6mm}12.10.3 $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\ +\hspace{6mm}Reset the window. \\ +\hspace{6mm}12.10.4 $bitcpy \leftarrow 0, bitbuf \leftarrow 0, mode \leftarrow 1$ \\ +\\ +No more windows left. Check for residual bits of exponent. \\ +13. If $mode = 2$ and $bitcpy > 0$ then do \\ +\hspace{3mm}13.1 for $ix$ form $0$ to $bitcpy - 1$ do \\ +\hspace{6mm}13.1.1 $res \leftarrow res^2$ \\ +\hspace{6mm}13.1.2 $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\ +\hspace{6mm}13.1.3 $bitbuf \leftarrow bitbuf << 1$ \\ +\hspace{6mm}13.1.4 If $bitbuf$ AND $2^{winsize} \ne 0$ then do \\ +\hspace{9mm}13.1.4.1 $res \leftarrow res \cdot M_{1}$ \\ +\hspace{9mm}13.1.4.2 $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\ +14. $y \leftarrow res$ \\ +15. Clear $res$, $mu$ and the $M$ array. \\ +16. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm s\_mp\_exptmod (continued)} +\end{figure} + +\textbf{Algorithm s\_mp\_exptmod.} +This algorithm computes the $x$'th power of $g$ modulo $p$ and stores the result in $y$. It takes advantage of the Barrett reduction +algorithm to keep the product small throughout the algorithm. + +The first two steps determine the optimal window size based on the number of bits in the exponent. The larger the exponent the +larger the window size becomes. After a window size $winsize$ has been chosen an array of $2^{winsize}$ mp\_int variables is allocated. This +table will hold the values of $g^x \mbox{ (mod }p\mbox{)}$ for $2^{winsize - 1} \le x < 2^{winsize}$. + +After the table is allocated the first power of $g$ is found. Since $g \ge p$ is allowed it must be first reduced modulo $p$ to make +the rest of the algorithm more efficient. The first element of the table at $2^{winsize - 1}$ is found by squaring $M_1$ successively $winsize - 2$ +times. The rest of the table elements are found by multiplying the previous element by $M_1$ modulo $p$. + +Now that the table is available the sliding window may begin. The following list describes the functions of all the variables in the window. +\begin{enumerate} +\item The variable $mode$ dictates how the bits of the exponent are interpreted. +\begin{enumerate} + \item When $mode = 0$ the bits are ignored since no non-zero bit of the exponent has been seen yet. For example, if the exponent were simply + $1$ then there would be $lg(\beta) - 1$ zero bits before the first non-zero bit. In this case bits are ignored until a non-zero bit is found. + \item When $mode = 1$ a non-zero bit has been seen before and a new $winsize$-bit window has not been formed yet. In this mode leading $0$ bits + are read and a single squaring is performed. If a non-zero bit is read a new window is created. + \item When $mode = 2$ the algorithm is in the middle of forming a window and new bits are appended to the window from the most significant bit + downwards. +\end{enumerate} +\item The variable $bitcnt$ indicates how many bits are left in the current digit of the exponent left to be read. When it reaches zero a new digit + is fetched from the exponent. +\item The variable $buf$ holds the currently read digit of the exponent. +\item The variable $digidx$ is an index into the exponents digits. It starts at the leading digit $x.used - 1$ and moves towards the trailing digit. +\item The variable $bitcpy$ indicates how many bits are in the currently formed window. When it reaches $winsize$ the window is flushed and + the appropriate operations performed. +\item The variable $bitbuf$ holds the current bits of the window being formed. +\end{enumerate} + +All of step 12 is the window processing loop. It will iterate while there are digits available form the exponent to read. The first step +inside this loop is to extract a new digit if no more bits are available in the current digit. If there are no bits left a new digit is +read and if there are no digits left than the loop terminates. + +After a digit is made available step 12.3 will extract the most significant bit of the current digit and move all other bits in the digit +upwards. In effect the digit is read from most significant bit to least significant bit and since the digits are read from leading to +trailing edges the entire exponent is read from most significant bit to least significant bit. + +At step 12.5 if the $mode$ and currently extracted bit $y$ are both zero the bit is ignored and the next bit is read. This prevents the +algorithm from having to perform trivial squaring and reduction operations before the first non-zero bit is read. Step 12.6 and 12.7-10 handle +the two cases of $mode = 1$ and $mode = 2$ respectively. + +FIGU,expt_state,Sliding Window State Diagram + +By step 13 there are no more digits left in the exponent. However, there may be partial bits in the window left. If $mode = 2$ then +a Left-to-Right algorithm is used to process the remaining few bits. + +EXAM,bn_s_mp_exptmod.c + +Lines @31,if@ through @45,}@ determine the optimal window size based on the length of the exponent in bits. The window divisions are sorted +from smallest to greatest so that in each \textbf{if} statement only one condition must be tested. For example, by the \textbf{if} statement +on line @37,if@ the value of $x$ is already known to be greater than $140$. + +The conditional piece of code beginning on line @42,ifdef@ allows the window size to be restricted to five bits. This logic is used to ensure +the table of precomputed powers of $G$ remains relatively small. + +The for loop on line @60,for@ initializes the $M$ array while lines @71,mp_init@ and @75,mp_reduce@ through @85,}@ initialize the reduction +function that will be used for this modulus. + +-- More later. + +\section{Quick Power of Two} +Calculating $b = 2^a$ can be performed much quicker than with any of the previous algorithms. Recall that a logical shift left $m << k$ is +equivalent to $m \cdot 2^k$. By this logic when $m = 1$ a quick power of two can be achieved. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_2expt}. \\ +\textbf{Input}. integer $b$ \\ +\textbf{Output}. $a \leftarrow 2^b$ \\ +\hline \\ +1. $a \leftarrow 0$ \\ +2. If $a.alloc < \lfloor b / lg(\beta) \rfloor + 1$ then grow $a$ appropriately. \\ +3. $a.used \leftarrow \lfloor b / lg(\beta) \rfloor + 1$ \\ +4. $a_{\lfloor b / lg(\beta) \rfloor} \leftarrow 1 << (b \mbox{ mod } lg(\beta))$ \\ +5. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_2expt} +\end{figure} + +\textbf{Algorithm mp\_2expt.} + +EXAM,bn_mp_2expt.c + +\chapter{Higher Level Algorithms} + +This chapter discusses the various higher level algorithms that are required to complete a well rounded multiple precision integer package. These +routines are less performance oriented than the algorithms of chapters five, six and seven but are no less important. + +The first section describes a method of integer division with remainder that is universally well known. It provides the signed division logic +for the package. The subsequent section discusses a set of algorithms which allow a single digit to be the 2nd operand for a variety of operations. +These algorithms serve mostly to simplify other algorithms where small constants are required. The last two sections discuss how to manipulate +various representations of integers. For example, converting from an mp\_int to a string of character. + +\section{Integer Division with Remainder} +\label{sec:division} + +Integer division aside from modular exponentiation is the most intensive algorithm to compute. Like addition, subtraction and multiplication +the basis of this algorithm is the long-hand division algorithm taught to school children. Throughout this discussion several common variables +will be used. Let $x$ represent the divisor and $y$ represent the dividend. Let $q$ represent the integer quotient $\lfloor y / x \rfloor$ and +let $r$ represent the remainder $r = y - x \lfloor y / x \rfloor$. The following simple algorithm will be used to start the discussion. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{Radix-$\beta$ Integer Division}. \\ +\textbf{Input}. integer $x$ and $y$ \\ +\textbf{Output}. $q = \lfloor y/x\rfloor, r = y - xq$ \\ +\hline \\ +1. $q \leftarrow 0$ \\ +2. $n \leftarrow \vert \vert y \vert \vert - \vert \vert x \vert \vert$ \\ +3. for $t$ from $n$ down to $0$ do \\ +\hspace{3mm}3.1 Maximize $k$ such that $kx\beta^t$ is less than or equal to $y$ and $(k + 1)x\beta^t$ is greater. \\ +\hspace{3mm}3.2 $q \leftarrow q + k\beta^t$ \\ +\hspace{3mm}3.3 $y \leftarrow y - kx\beta^t$ \\ +4. $r \leftarrow y$ \\ +5. Return($q, r$) \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm Radix-$\beta$ Integer Division} +\label{fig:raddiv} +\end{figure} + +As children we are taught this very simple algorithm for the case of $\beta = 10$. Almost instinctively several optimizations are taught for which +their reason of existing are never explained. For this example let $y = 5471$ represent the dividend and $x = 23$ represent the divisor. + +To find the first digit of the quotient the value of $k$ must be maximized such that $kx\beta^t$ is less than or equal to $y$ and +simultaneously $(k + 1)x\beta^t$ is greater than $y$. Implicitly $k$ is the maximum value the $t$'th digit of the quotient may have. The habitual method +used to find the maximum is to ``eyeball'' the two numbers, typically only the leading digits and quickly estimate a quotient. By only using leading +digits a much simpler division may be used to form an educated guess at what the value must be. In this case $k = \lfloor 54/23\rfloor = 2$ quickly +arises as a possible solution. Indeed $2x\beta^2 = 4600$ is less than $y = 5471$ and simultaneously $(k + 1)x\beta^2 = 6900$ is larger than $y$. +As a result $k\beta^2$ is added to the quotient which now equals $q = 200$ and $4600$ is subtracted from $y$ to give a remainder of $y = 841$. + +Again this process is repeated to produce the quotient digit $k = 3$ which makes the quotient $q = 200 + 3\beta = 230$ and the remainder +$y = 841 - 3x\beta = 181$. Finally the last iteration of the loop produces $k = 7$ which leads to the quotient $q = 230 + 7 = 237$ and the +remainder $y = 181 - 7x = 20$. The final quotient and remainder found are $q = 237$ and $r = y = 20$ which are indeed correct since +$237 \cdot 23 + 20 = 5471$ is true. + +\subsection{Quotient Estimation} +\label{sec:divest} +As alluded to earlier the quotient digit $k$ can be estimated from only the leading digits of both the divisor and dividend. When $p$ leading +digits are used from both the divisor and dividend to form an estimation the accuracy of the estimation rises as $p$ grows. Technically +speaking the estimation is based on assuming the lower $\vert \vert y \vert \vert - p$ and $\vert \vert x \vert \vert - p$ lower digits of the +dividend and divisor are zero. + +The value of the estimation may off by a few values in either direction and in general is fairly correct. A simplification \cite[pp. 271]{TAOCPV2} +of the estimation technique is to use $t + 1$ digits of the dividend and $t$ digits of the divisor, in particularly when $t = 1$. The estimate +using this technique is never too small. For the following proof let $t = \vert \vert y \vert \vert - 1$ and $s = \vert \vert x \vert \vert - 1$ +represent the most significant digits of the dividend and divisor respectively. + +\textbf{Proof.}\textit{ The quotient $\hat k = \lfloor (y_t\beta + y_{t-1}) / x_s \rfloor$ is greater than or equal to +$k = \lfloor y / (x \cdot \beta^{\vert \vert y \vert \vert - \vert \vert x \vert \vert - 1}) \rfloor$. } +The first obvious case is when $\hat k = \beta - 1$ in which case the proof is concluded since the real quotient cannot be larger. For all other +cases $\hat k = \lfloor (y_t\beta + y_{t-1}) / x_s \rfloor$ and $\hat k x_s \ge y_t\beta + y_{t-1} - x_s + 1$. The latter portion of the inequalility +$-x_s + 1$ arises from the fact that a truncated integer division will give the same quotient for at most $x_s - 1$ values. Next a series of +inequalities will prove the hypothesis. + +\begin{equation} +y - \hat k x \le y - \hat k x_s\beta^s +\end{equation} + +This is trivially true since $x \ge x_s\beta^s$. Next we replace $\hat kx_s\beta^s$ by the previous inequality for $\hat kx_s$. + +\begin{equation} +y - \hat k x \le y_t\beta^t + \ldots + y_0 - (y_t\beta^t + y_{t-1}\beta^{t-1} - x_s\beta^t + \beta^s) +\end{equation} + +By simplifying the previous inequality the following inequality is formed. + +\begin{equation} +y - \hat k x \le y_{t-2}\beta^{t-2} + \ldots + y_0 + x_s\beta^s - \beta^s +\end{equation} + +Subsequently, + +\begin{equation} +y_{t-2}\beta^{t-2} + \ldots + y_0 + x_s\beta^s - \beta^s < x_s\beta^s \le x +\end{equation} + +Which proves that $y - \hat kx \le x$ and by consequence $\hat k \ge k$ which concludes the proof. \textbf{QED} + + +\subsection{Normalized Integers} +For the purposes of division a normalized input is when the divisors leading digit $x_n$ is greater than or equal to $\beta / 2$. By multiplying both +$x$ and $y$ by $j = \lfloor (\beta / 2) / x_n \rfloor$ the quotient remains unchanged and the remainder is simply $j$ times the original +remainder. The purpose of normalization is to ensure the leading digit of the divisor is sufficiently large such that the estimated quotient will +lie in the domain of a single digit. Consider the maximum dividend $(\beta - 1) \cdot \beta + (\beta - 1)$ and the minimum divisor $\beta / 2$. + +\begin{equation} +{{\beta^2 - 1} \over { \beta / 2}} \le 2\beta - {2 \over \beta} +\end{equation} + +At most the quotient approaches $2\beta$, however, in practice this will not occur since that would imply the previous quotient digit was too small. + +\subsection{Radix-$\beta$ Division with Remainder} +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_div}. \\ +\textbf{Input}. mp\_int $a, b$ \\ +\textbf{Output}. $c = \lfloor a/b \rfloor$, $d = a - bc$ \\ +\hline \\ +1. If $b = 0$ return(\textit{MP\_VAL}). \\ +2. If $\vert a \vert < \vert b \vert$ then do \\ +\hspace{3mm}2.1 $d \leftarrow a$ \\ +\hspace{3mm}2.2 $c \leftarrow 0$ \\ +\hspace{3mm}2.3 Return(\textit{MP\_OKAY}). \\ +\\ +Setup the quotient to receive the digits. \\ +3. Grow $q$ to $a.used + 2$ digits. \\ +4. $q \leftarrow 0$ \\ +5. $x \leftarrow \vert a \vert , y \leftarrow \vert b \vert$ \\ +6. $sign \leftarrow \left \lbrace \begin{array}{ll} + MP\_ZPOS & \mbox{if }a.sign = b.sign \\ + MP\_NEG & \mbox{otherwise} \\ + \end{array} \right .$ \\ +\\ +Normalize the inputs such that the leading digit of $y$ is greater than or equal to $\beta / 2$. \\ +7. $norm \leftarrow (lg(\beta) - 1) - (\lceil lg(y) \rceil \mbox{ (mod }lg(\beta)\mbox{)})$ \\ +8. $x \leftarrow x \cdot 2^{norm}, y \leftarrow y \cdot 2^{norm}$ \\ +\\ +Find the leading digit of the quotient. \\ +9. $n \leftarrow x.used - 1, t \leftarrow y.used - 1$ \\ +10. $y \leftarrow y \cdot \beta^{n - t}$ \\ +11. While ($x \ge y$) do \\ +\hspace{3mm}11.1 $q_{n - t} \leftarrow q_{n - t} + 1$ \\ +\hspace{3mm}11.2 $x \leftarrow x - y$ \\ +12. $y \leftarrow \lfloor y / \beta^{n-t} \rfloor$ \\ +\\ +Continued on the next page. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_div} +\end{figure} + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_div} (continued). \\ +\textbf{Input}. mp\_int $a, b$ \\ +\textbf{Output}. $c = \lfloor a/b \rfloor$, $d = a - bc$ \\ +\hline \\ +Now find the remainder fo the digits. \\ +13. for $i$ from $n$ down to $(t + 1)$ do \\ +\hspace{3mm}13.1 If $i > x.used$ then jump to the next iteration of this loop. \\ +\hspace{3mm}13.2 If $x_{i} = y_{t}$ then \\ +\hspace{6mm}13.2.1 $q_{i - t - 1} \leftarrow \beta - 1$ \\ +\hspace{3mm}13.3 else \\ +\hspace{6mm}13.3.1 $\hat r \leftarrow x_{i} \cdot \beta + x_{i - 1}$ \\ +\hspace{6mm}13.3.2 $\hat r \leftarrow \lfloor \hat r / y_{t} \rfloor$ \\ +\hspace{6mm}13.3.3 $q_{i - t - 1} \leftarrow \hat r$ \\ +\hspace{3mm}13.4 $q_{i - t - 1} \leftarrow q_{i - t - 1} + 1$ \\ +\\ +Fixup quotient estimation. \\ +\hspace{3mm}13.5 Loop \\ +\hspace{6mm}13.5.1 $q_{i - t - 1} \leftarrow q_{i - t - 1} - 1$ \\ +\hspace{6mm}13.5.2 t$1 \leftarrow 0$ \\ +\hspace{6mm}13.5.3 t$1_0 \leftarrow y_{t - 1}, $ t$1_1 \leftarrow y_t,$ t$1.used \leftarrow 2$ \\ +\hspace{6mm}13.5.4 $t1 \leftarrow t1 \cdot q_{i - t - 1}$ \\ +\hspace{6mm}13.5.5 t$2_0 \leftarrow x_{i - 2}, $ t$2_1 \leftarrow x_{i - 1}, $ t$2_2 \leftarrow x_i, $ t$2.used \leftarrow 3$ \\ +\hspace{6mm}13.5.6 If $\vert t1 \vert > \vert t2 \vert$ then goto step 13.5. \\ +\hspace{3mm}13.6 t$1 \leftarrow y \cdot q_{i - t - 1}$ \\ +\hspace{3mm}13.7 t$1 \leftarrow $ t$1 \cdot \beta^{i - t - 1}$ \\ +\hspace{3mm}13.8 $x \leftarrow x - $ t$1$ \\ +\hspace{3mm}13.9 If $x.sign = MP\_NEG$ then \\ +\hspace{6mm}13.10 t$1 \leftarrow y$ \\ +\hspace{6mm}13.11 t$1 \leftarrow $ t$1 \cdot \beta^{i - t - 1}$ \\ +\hspace{6mm}13.12 $x \leftarrow x + $ t$1$ \\ +\hspace{6mm}13.13 $q_{i - t - 1} \leftarrow q_{i - t - 1} - 1$ \\ +\\ +Finalize the result. \\ +14. Clamp excess digits of $q$ \\ +15. $c \leftarrow q, c.sign \leftarrow sign$ \\ +16. $x.sign \leftarrow a.sign$ \\ +17. $d \leftarrow \lfloor x / 2^{norm} \rfloor$ \\ +18. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_div (continued)} +\end{figure} +\textbf{Algorithm mp\_div.} +This algorithm will calculate quotient and remainder from an integer division given a dividend and divisor. The algorithm is a signed +division and will produce a fully qualified quotient and remainder. + +First the divisor $b$ must be non-zero which is enforced in step one. If the divisor is larger than the dividend than the quotient is implicitly +zero and the remainder is the dividend. + +After the first two trivial cases of inputs are handled the variable $q$ is setup to receive the digits of the quotient. Two unsigned copies of the +divisor $y$ and dividend $x$ are made as well. The core of the division algorithm is an unsigned division and will only work if the values are +positive. Now the two values $x$ and $y$ must be normalized such that the leading digit of $y$ is greater than or equal to $\beta / 2$. +This is performed by shifting both to the left by enough bits to get the desired normalization. + +At this point the division algorithm can begin producing digits of the quotient. Recall that maximum value of the estimation used is +$2\beta - {2 \over \beta}$ which means that a digit of the quotient must be first produced by another means. In this case $y$ is shifted +to the left (\textit{step ten}) so that it has the same number of digits as $x$. The loop on step eleven will subtract multiples of the +shifted copy of $y$ until $x$ is smaller. Since the leading digit of $y$ is greater than or equal to $\beta/2$ this loop will iterate at most two +times to produce the desired leading digit of the quotient. + +Now the remainder of the digits can be produced. The equation $\hat q = \lfloor {{x_i \beta + x_{i-1}}\over y_t} \rfloor$ is used to fairly +accurately approximate the true quotient digit. The estimation can in theory produce an estimation as high as $2\beta - {2 \over \beta}$ but by +induction the upper quotient digit is correct (\textit{as established on step eleven}) and the estimate must be less than $\beta$. + +Recall from section~\ref{sec:divest} that the estimation is never too low but may be too high. The next step of the estimation process is +to refine the estimation. The loop on step 13.5 uses $x_i\beta^2 + x_{i-1}\beta + x_{i-2}$ and $q_{i - t - 1}(y_t\beta + y_{t-1})$ as a higher +order approximation to adjust the quotient digit. + +After both phases of estimation the quotient digit may still be off by a value of one\footnote{This is similar to the error introduced +by optimizing Barrett reduction.}. Steps 13.6 and 13.7 subtract the multiple of the divisor from the dividend (\textit{Similar to step 3.3 of +algorithm~\ref{fig:raddiv}} and then subsequently add a multiple of the divisor if the quotient was too large. + +Now that the quotient has been determine finializing the result is a matter of clamping the quotient, fixing the sizes and de-normalizing the +remainder. An important aspect of this algorithm seemingly overlooked in other descriptions such as that of Algorithm 14.20 HAC \cite[pp. 598]{HAC} +is that when the estimations are being made (\textit{inside the loop on step 13.5}) that the digits $y_{t-1}$, $x_{i-2}$ and $x_{i-1}$ may lie +outside their respective boundaries. For example, if $t = 0$ or $i \le 1$ then the digits would be undefined. In those cases the digits should +respectively be replaced with a zero. + +EXAM,bn_mp_div.c + +The implementation of this algorithm differs slightly from the pseudo code presented previously. In this algorithm either of the quotient $c$ or +remainder $d$ may be passed as a \textbf{NULL} pointer which indicates their value is not desired. For example, the C code to call the division +algorithm with only the quotient is + +\begin{verbatim} +mp_div(&a, &b, &c, NULL); /* c = [a/b] */ +\end{verbatim} + +Lines @108,if@ and @113,if@ handle the two trivial cases of inputs which are division by zero and dividend smaller than the divisor +respectively. After the two trivial cases all of the temporary variables are initialized. Line @147,neg@ determines the sign of +the quotient and line @148,sign@ ensures that both $x$ and $y$ are positive. + +The number of bits in the leading digit is calculated on line @151,norm@. Implictly an mp\_int with $r$ digits will require $lg(\beta)(r-1) + k$ bits +of precision which when reduced modulo $lg(\beta)$ produces the value of $k$. In this case $k$ is the number of bits in the leading digit which is +exactly what is required. For the algorithm to operate $k$ must equal $lg(\beta) - 1$ and when it does not the inputs must be normalized by shifting +them to the left by $lg(\beta) - 1 - k$ bits. + +Throughout the variables $n$ and $t$ will represent the highest digit of $x$ and $y$ respectively. These are first used to produce the +leading digit of the quotient. The loop beginning on line @184,for@ will produce the remainder of the quotient digits. + +The conditional ``continue'' on line @186,continue@ is used to prevent the algorithm from reading past the leading edge of $x$ which can occur when the +algorithm eliminates multiple non-zero digits in a single iteration. This ensures that $x_i$ is always non-zero since by definition the digits +above the $i$'th position $x$ must be zero in order for the quotient to be precise\footnote{Precise as far as integer division is concerned.}. + +Lines @214,t1@, @216,t1@ and @222,t2@ through @225,t2@ manually construct the high accuracy estimations by setting the digits of the two mp\_int +variables directly. + +\section{Single Digit Helpers} + +This section briefly describes a series of single digit helper algorithms which come in handy when working with small constants. All of +the helper functions assume the single digit input is positive and will treat them as such. + +\subsection{Single Digit Addition and Subtraction} + +Both addition and subtraction are performed by ``cheating'' and using mp\_set followed by the higher level addition or subtraction +algorithms. As a result these algorithms are subtantially simpler with a slight cost in performance. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_add\_d}. \\ +\textbf{Input}. mp\_int $a$ and a mp\_digit $b$ \\ +\textbf{Output}. $c = a + b$ \\ +\hline \\ +1. $t \leftarrow b$ (\textit{mp\_set}) \\ +2. $c \leftarrow a + t$ \\ +3. Return(\textit{MP\_OKAY}) \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_add\_d} +\end{figure} + +\textbf{Algorithm mp\_add\_d.} +This algorithm initiates a temporary mp\_int with the value of the single digit and uses algorithm mp\_add to add the two values together. + +EXAM,bn_mp_add_d.c + +Clever use of the letter 't'. + +\subsubsection{Subtraction} +The single digit subtraction algorithm mp\_sub\_d is essentially the same except it uses mp\_sub to subtract the digit from the mp\_int. + +\subsection{Single Digit Multiplication} +Single digit multiplication arises enough in division and radix conversion that it ought to be implement as a special case of the baseline +multiplication algorithm. Essentially this algorithm is a modified version of algorithm s\_mp\_mul\_digs where one of the multiplicands +only has one digit. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_mul\_d}. \\ +\textbf{Input}. mp\_int $a$ and a mp\_digit $b$ \\ +\textbf{Output}. $c = ab$ \\ +\hline \\ +1. $pa \leftarrow a.used$ \\ +2. Grow $c$ to at least $pa + 1$ digits. \\ +3. $oldused \leftarrow c.used$ \\ +4. $c.used \leftarrow pa + 1$ \\ +5. $c.sign \leftarrow a.sign$ \\ +6. $\mu \leftarrow 0$ \\ +7. for $ix$ from $0$ to $pa - 1$ do \\ +\hspace{3mm}7.1 $\hat r \leftarrow \mu + a_{ix}b$ \\ +\hspace{3mm}7.2 $c_{ix} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{3mm}7.3 $\mu \leftarrow \lfloor \hat r / \beta \rfloor$ \\ +8. $c_{pa} \leftarrow \mu$ \\ +9. for $ix$ from $pa + 1$ to $oldused$ do \\ +\hspace{3mm}9.1 $c_{ix} \leftarrow 0$ \\ +10. Clamp excess digits of $c$. \\ +11. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_mul\_d} +\end{figure} +\textbf{Algorithm mp\_mul\_d.} +This algorithm quickly multiplies an mp\_int by a small single digit value. It is specially tailored to the job and has a minimal of overhead. +Unlike the full multiplication algorithms this algorithm does not require any significnat temporary storage or memory allocations. + +EXAM,bn_mp_mul_d.c + +In this implementation the destination $c$ may point to the same mp\_int as the source $a$ since the result is written after the digit is +read from the source. This function uses pointer aliases $tmpa$ and $tmpc$ for the digits of $a$ and $c$ respectively. + +\subsection{Single Digit Division} +Like the single digit multiplication algorithm, single digit division is also a fairly common algorithm used in radix conversion. Since the +divisor is only a single digit a specialized variant of the division algorithm can be used to compute the quotient. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_div\_d}. \\ +\textbf{Input}. mp\_int $a$ and a mp\_digit $b$ \\ +\textbf{Output}. $c = \lfloor a / b \rfloor, d = a - cb$ \\ +\hline \\ +1. If $b = 0$ then return(\textit{MP\_VAL}).\\ +2. If $b = 3$ then use algorithm mp\_div\_3 instead. \\ +3. Init $q$ to $a.used$ digits. \\ +4. $q.used \leftarrow a.used$ \\ +5. $q.sign \leftarrow a.sign$ \\ +6. $\hat w \leftarrow 0$ \\ +7. for $ix$ from $a.used - 1$ down to $0$ do \\ +\hspace{3mm}7.1 $\hat w \leftarrow \hat w \beta + a_{ix}$ \\ +\hspace{3mm}7.2 If $\hat w \ge b$ then \\ +\hspace{6mm}7.2.1 $t \leftarrow \lfloor \hat w / b \rfloor$ \\ +\hspace{6mm}7.2.2 $\hat w \leftarrow \hat w \mbox{ (mod }b\mbox{)}$ \\ +\hspace{3mm}7.3 else\\ +\hspace{6mm}7.3.1 $t \leftarrow 0$ \\ +\hspace{3mm}7.4 $q_{ix} \leftarrow t$ \\ +8. $d \leftarrow \hat w$ \\ +9. Clamp excess digits of $q$. \\ +10. $c \leftarrow q$ \\ +11. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_div\_d} +\end{figure} +\textbf{Algorithm mp\_div\_d.} +This algorithm divides the mp\_int $a$ by the single mp\_digit $b$ using an optimized approach. Essentially in every iteration of the +algorithm another digit of the dividend is reduced and another digit of quotient produced. Provided $b < \beta$ the value of $\hat w$ +after step 7.1 will be limited such that $0 \le \lfloor \hat w / b \rfloor < \beta$. + +If the divisor $b$ is equal to three a variant of this algorithm is used which is called mp\_div\_3. It replaces the division by three with +a multiplication by $\lfloor \beta / 3 \rfloor$ and the appropriate shift and residual fixup. In essence it is much like the Barrett reduction +from chapter seven. + +EXAM,bn_mp_div_d.c + +Like the implementation of algorithm mp\_div this algorithm allows either of the quotient or remainder to be passed as a \textbf{NULL} pointer to +indicate the respective value is not required. This allows a trivial single digit modular reduction algorithm, mp\_mod\_d to be created. + +The division and remainder on lines @44,/@ and @45,%@ can be replaced often by a single division on most processors. For example, the 32-bit x86 based +processors can divide a 64-bit quantity by a 32-bit quantity and produce the quotient and remainder simultaneously. Unfortunately the GCC +compiler does not recognize that optimization and will actually produce two function calls to find the quotient and remainder respectively. + +\subsection{Single Digit Root Extraction} + +Finding the $n$'th root of an integer is fairly easy as far as numerical analysis is concerned. Algorithms such as the Newton-Raphson approximation +(\ref{eqn:newton}) series will converge very quickly to a root for any continuous function $f(x)$. + +\begin{equation} +x_{i+1} = x_i - {f(x_i) \over f'(x_i)} +\label{eqn:newton} +\end{equation} + +In this case the $n$'th root is desired and $f(x) = x^n - a$ where $a$ is the integer of which the root is desired. The derivative of $f(x)$ is +simply $f'(x) = nx^{n - 1}$. Of particular importance is that this algorithm will be used over the integers not over the a more continuous domain +such as the real numbers. As a result the root found can be above the true root by few and must be manually adjusted. Ideally at the end of the +algorithm the $n$'th root $b$ of an integer $a$ is desired such that $b^n \le a$. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_n\_root}. \\ +\textbf{Input}. mp\_int $a$ and a mp\_digit $b$ \\ +\textbf{Output}. $c^b \le a$ \\ +\hline \\ +1. If $b$ is even and $a.sign = MP\_NEG$ return(\textit{MP\_VAL}). \\ +2. $sign \leftarrow a.sign$ \\ +3. $a.sign \leftarrow MP\_ZPOS$ \\ +4. t$2 \leftarrow 2$ \\ +5. Loop \\ +\hspace{3mm}5.1 t$1 \leftarrow $ t$2$ \\ +\hspace{3mm}5.2 t$3 \leftarrow $ t$1^{b - 1}$ \\ +\hspace{3mm}5.3 t$2 \leftarrow $ t$3 $ $\cdot$ t$1$ \\ +\hspace{3mm}5.4 t$2 \leftarrow $ t$2 - a$ \\ +\hspace{3mm}5.5 t$3 \leftarrow $ t$3 \cdot b$ \\ +\hspace{3mm}5.6 t$3 \leftarrow \lfloor $t$2 / $t$3 \rfloor$ \\ +\hspace{3mm}5.7 t$2 \leftarrow $ t$1 - $ t$3$ \\ +\hspace{3mm}5.8 If t$1 \ne $ t$2$ then goto step 5. \\ +6. Loop \\ +\hspace{3mm}6.1 t$2 \leftarrow $ t$1^b$ \\ +\hspace{3mm}6.2 If t$2 > a$ then \\ +\hspace{6mm}6.2.1 t$1 \leftarrow $ t$1 - 1$ \\ +\hspace{6mm}6.2.2 Goto step 6. \\ +7. $a.sign \leftarrow sign$ \\ +8. $c \leftarrow $ t$1$ \\ +9. $c.sign \leftarrow sign$ \\ +10. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_n\_root} +\end{figure} +\textbf{Algorithm mp\_n\_root.} +This algorithm finds the integer $n$'th root of an input using the Newton-Raphson approach. It is partially optimized based on the observation +that the numerator of ${f(x) \over f'(x)}$ can be derived from a partial denominator. That is at first the denominator is calculated by finding +$x^{b - 1}$. This value can then be multiplied by $x$ and have $a$ subtracted from it to find the numerator. This saves a total of $b - 1$ +multiplications by t$1$ inside the loop. + +The initial value of the approximation is t$2 = 2$ which allows the algorithm to start with very small values and quickly converge on the +root. Ideally this algorithm is meant to find the $n$'th root of an input where $n$ is bounded by $2 \le n \le 5$. + +EXAM,bn_mp_n_root.c + +\section{Random Number Generation} + +Random numbers come up in a variety of activities from public key cryptography to simple simulations and various randomized algorithms. Pollard-Rho +factoring for example, can make use of random values as starting points to find factors of a composite integer. In this case the algorithm presented +is solely for simulations and not intended for cryptographic use. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_rand}. \\ +\textbf{Input}. An integer $b$ \\ +\textbf{Output}. A pseudo-random number of $b$ digits \\ +\hline \\ +1. $a \leftarrow 0$ \\ +2. If $b \le 0$ return(\textit{MP\_OKAY}) \\ +3. Pick a non-zero random digit $d$. \\ +4. $a \leftarrow a + d$ \\ +5. for $ix$ from 1 to $d - 1$ do \\ +\hspace{3mm}5.1 $a \leftarrow a \cdot \beta$ \\ +\hspace{3mm}5.2 Pick a random digit $d$. \\ +\hspace{3mm}5.3 $a \leftarrow a + d$ \\ +6. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_rand} +\end{figure} +\textbf{Algorithm mp\_rand.} +This algorithm produces a pseudo-random integer of $b$ digits. By ensuring that the first digit is non-zero the algorithm also guarantees that the +final result has at least $b$ digits. It relies heavily on a third-part random number generator which should ideally generate uniformly all of +the integers from $0$ to $\beta - 1$. + +EXAM,bn_mp_rand.c + +\section{Formatted Representations} +The ability to emit a radix-$n$ textual representation of an integer is useful for interacting with human parties. For example, the ability to +be given a string of characters such as ``114585'' and turn it into the radix-$\beta$ equivalent would make it easier to enter numbers +into a program. + +\subsection{Reading Radix-n Input} +For the purposes of this text we will assume that a simple lower ASCII map (\ref{fig:ASC}) is used for the values of from $0$ to $63$ to +printable characters. For example, when the character ``N'' is read it represents the integer $23$. The first $16$ characters of the +map are for the common representations up to hexadecimal. After that they match the ``base64'' encoding scheme which are suitable chosen +such that they are printable. While outputting as base64 may not be too helpful for human operators it does allow communication via non binary +mediums. + +\newpage\begin{figure}[here] +\begin{center} +\begin{tabular}{cc|cc|cc|cc} +\hline \textbf{Value} & \textbf{Char} & \textbf{Value} & \textbf{Char} & \textbf{Value} & \textbf{Char} & \textbf{Value} & \textbf{Char} \\ +\hline +0 & 0 & 1 & 1 & 2 & 2 & 3 & 3 \\ +4 & 4 & 5 & 5 & 6 & 6 & 7 & 7 \\ +8 & 8 & 9 & 9 & 10 & A & 11 & B \\ +12 & C & 13 & D & 14 & E & 15 & F \\ +16 & G & 17 & H & 18 & I & 19 & J \\ +20 & K & 21 & L & 22 & M & 23 & N \\ +24 & O & 25 & P & 26 & Q & 27 & R \\ +28 & S & 29 & T & 30 & U & 31 & V \\ +32 & W & 33 & X & 34 & Y & 35 & Z \\ +36 & a & 37 & b & 38 & c & 39 & d \\ +40 & e & 41 & f & 42 & g & 43 & h \\ +44 & i & 45 & j & 46 & k & 47 & l \\ +48 & m & 49 & n & 50 & o & 51 & p \\ +52 & q & 53 & r & 54 & s & 55 & t \\ +56 & u & 57 & v & 58 & w & 59 & x \\ +60 & y & 61 & z & 62 & $+$ & 63 & $/$ \\ +\hline +\end{tabular} +\end{center} +\caption{Lower ASCII Map} +\label{fig:ASC} +\end{figure} + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_read\_radix}. \\ +\textbf{Input}. A string $str$ of length $sn$ and radix $r$. \\ +\textbf{Output}. The radix-$\beta$ equivalent mp\_int. \\ +\hline \\ +1. If $r < 2$ or $r > 64$ return(\textit{MP\_VAL}). \\ +2. $ix \leftarrow 0$ \\ +3. If $str_0 =$ ``-'' then do \\ +\hspace{3mm}3.1 $ix \leftarrow ix + 1$ \\ +\hspace{3mm}3.2 $sign \leftarrow MP\_NEG$ \\ +4. else \\ +\hspace{3mm}4.1 $sign \leftarrow MP\_ZPOS$ \\ +5. $a \leftarrow 0$ \\ +6. for $iy$ from $ix$ to $sn - 1$ do \\ +\hspace{3mm}6.1 Let $y$ denote the position in the map of $str_{iy}$. \\ +\hspace{3mm}6.2 If $str_{iy}$ is not in the map or $y \ge r$ then goto step 7. \\ +\hspace{3mm}6.3 $a \leftarrow a \cdot r$ \\ +\hspace{3mm}6.4 $a \leftarrow a + y$ \\ +7. If $a \ne 0$ then $a.sign \leftarrow sign$ \\ +8. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_read\_radix} +\end{figure} +\textbf{Algorithm mp\_read\_radix.} +This algorithm will read an ASCII string and produce the radix-$\beta$ mp\_int representation of the same integer. A minus symbol ``-'' may precede the +string to indicate the value is negative, otherwise it is assumed to be positive. The algorithm will read up to $sn$ characters from the input +and will stop when it reads a character it cannot map the algorithm stops reading characters from the string. This allows numbers to be embedded +as part of larger input without any significant problem. + +EXAM,bn_mp_read_radix.c + +\subsection{Generating Radix-$n$ Output} +Generating radix-$n$ output is fairly trivial with a division and remainder algorithm. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_toradix}. \\ +\textbf{Input}. A mp\_int $a$ and an integer $r$\\ +\textbf{Output}. The radix-$r$ representation of $a$ \\ +\hline \\ +1. If $r < 2$ or $r > 64$ return(\textit{MP\_VAL}). \\ +2. If $a = 0$ then $str = $ ``$0$'' and return(\textit{MP\_OKAY}). \\ +3. $t \leftarrow a$ \\ +4. $str \leftarrow$ ``'' \\ +5. if $t.sign = MP\_NEG$ then \\ +\hspace{3mm}5.1 $str \leftarrow str + $ ``-'' \\ +\hspace{3mm}5.2 $t.sign = MP\_ZPOS$ \\ +6. While ($t \ne 0$) do \\ +\hspace{3mm}6.1 $d \leftarrow t \mbox{ (mod }r\mbox{)}$ \\ +\hspace{3mm}6.2 $t \leftarrow \lfloor t / r \rfloor$ \\ +\hspace{3mm}6.3 Look up $d$ in the map and store the equivalent character in $y$. \\ +\hspace{3mm}6.4 $str \leftarrow str + y$ \\ +7. If $str_0 = $``$-$'' then \\ +\hspace{3mm}7.1 Reverse the digits $str_1, str_2, \ldots str_n$. \\ +8. Otherwise \\ +\hspace{3mm}8.1 Reverse the digits $str_0, str_1, \ldots str_n$. \\ +9. Return(\textit{MP\_OKAY}).\\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_toradix} +\end{figure} +\textbf{Algorithm mp\_toradix.} +This algorithm computes the radix-$r$ representation of an mp\_int $a$. The ``digits'' of the representation are extracted by reducing +successive powers of $\lfloor a / r^k \rfloor$ the input modulo $r$ until $r^k > a$. Note that instead of actually dividing by $r^k$ in +each iteration the quotient $\lfloor a / r \rfloor$ is saved for the next iteration. As a result a series of trivial $n \times 1$ divisions +are required instead of a series of $n \times k$ divisions. One design flaw of this approach is that the digits are produced in the reverse order +(see~\ref{fig:mpradix}). To remedy this flaw the digits must be swapped or simply ``reversed''. + +\begin{figure} +\begin{center} +\begin{tabular}{|c|c|c|} +\hline \textbf{Value of $a$} & \textbf{Value of $d$} & \textbf{Value of $str$} \\ +\hline $1234$ & -- & -- \\ +\hline $123$ & $4$ & ``4'' \\ +\hline $12$ & $3$ & ``43'' \\ +\hline $1$ & $2$ & ``432'' \\ +\hline $0$ & $1$ & ``4321'' \\ +\hline +\end{tabular} +\end{center} +\caption{Example of Algorithm mp\_toradix.} +\label{fig:mpradix} +\end{figure} + +EXAM,bn_mp_toradix.c + +\chapter{Number Theoretic Algorithms} +This chapter discusses several fundamental number theoretic algorithms such as the greatest common divisor, least common multiple and Jacobi +symbol computation. These algorithms arise as essential components in several key cryptographic algorithms such as the RSA public key algorithm and +various Sieve based factoring algorithms. + +\section{Greatest Common Divisor} +The greatest common divisor of two integers $a$ and $b$, often denoted as $(a, b)$ is the largest integer $k$ that is a proper divisor of +both $a$ and $b$. That is, $k$ is the largest integer such that $0 \equiv a \mbox{ (mod }k\mbox{)}$ and $0 \equiv b \mbox{ (mod }k\mbox{)}$ occur +simultaneously. + +The most common approach (cite) is to reduce one input modulo another. That is if $a$ and $b$ are divisible by some integer $k$ and if $qa + r = b$ then +$r$ is also divisible by $k$. The reduction pattern follows $\left < a , b \right > \rightarrow \left < b, a \mbox{ mod } b \right >$. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{Greatest Common Divisor (I)}. \\ +\textbf{Input}. Two positive integers $a$ and $b$ greater than zero. \\ +\textbf{Output}. The greatest common divisor $(a, b)$. \\ +\hline \\ +1. While ($b > 0$) do \\ +\hspace{3mm}1.1 $r \leftarrow a \mbox{ (mod }b\mbox{)}$ \\ +\hspace{3mm}1.2 $a \leftarrow b$ \\ +\hspace{3mm}1.3 $b \leftarrow r$ \\ +2. Return($a$). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm Greatest Common Divisor (I)} +\label{fig:gcd1} +\end{figure} + +This algorithm will quickly converge on the greatest common divisor since the residue $r$ tends diminish rapidly. However, divisions are +relatively expensive operations to perform and should ideally be avoided. There is another approach based on a similar relationship of +greatest common divisors. The faster approach is based on the observation that if $k$ divides both $a$ and $b$ it will also divide $a - b$. +In particular, we would like $a - b$ to decrease in magnitude which implies that $b \ge a$. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{Greatest Common Divisor (II)}. \\ +\textbf{Input}. Two positive integers $a$ and $b$ greater than zero. \\ +\textbf{Output}. The greatest common divisor $(a, b)$. \\ +\hline \\ +1. While ($b > 0$) do \\ +\hspace{3mm}1.1 Swap $a$ and $b$ such that $a$ is the smallest of the two. \\ +\hspace{3mm}1.2 $b \leftarrow b - a$ \\ +2. Return($a$). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm Greatest Common Divisor (II)} +\label{fig:gcd2} +\end{figure} + +\textbf{Proof} \textit{Algorithm~\ref{fig:gcd2} will return the greatest common divisor of $a$ and $b$.} +The algorithm in figure~\ref{fig:gcd2} will eventually terminate since $b \ge a$ the subtraction in step 1.2 will be a value less than $b$. In other +words in every iteration that tuple $\left < a, b \right >$ decrease in magnitude until eventually $a = b$. Since both $a$ and $b$ are always +divisible by the greatest common divisor (\textit{until the last iteration}) and in the last iteration of the algorithm $b = 0$, therefore, in the +second to last iteration of the algorithm $b = a$ and clearly $(a, a) = a$ which concludes the proof. \textbf{QED}. + +As a matter of practicality algorithm \ref{fig:gcd1} decreases far too slowly to be useful. Specially if $b$ is much larger than $a$ such that +$b - a$ is still very much larger than $a$. A simple addition to the algorithm is to divide $b - a$ by a power of some integer $p$ which does +not divide the greatest common divisor but will divide $b - a$. In this case ${b - a} \over p$ is also an integer and still divisible by +the greatest common divisor. + +However, instead of factoring $b - a$ to find a suitable value of $p$ the powers of $p$ can be removed from $a$ and $b$ that are in common first. +Then inside the loop whenever $b - a$ is divisible by some power of $p$ it can be safely removed. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{Greatest Common Divisor (III)}. \\ +\textbf{Input}. Two positive integers $a$ and $b$ greater than zero. \\ +\textbf{Output}. The greatest common divisor $(a, b)$. \\ +\hline \\ +1. $k \leftarrow 0$ \\ +2. While $a$ and $b$ are both divisible by $p$ do \\ +\hspace{3mm}2.1 $a \leftarrow \lfloor a / p \rfloor$ \\ +\hspace{3mm}2.2 $b \leftarrow \lfloor b / p \rfloor$ \\ +\hspace{3mm}2.3 $k \leftarrow k + 1$ \\ +3. While $a$ is divisible by $p$ do \\ +\hspace{3mm}3.1 $a \leftarrow \lfloor a / p \rfloor$ \\ +4. While $b$ is divisible by $p$ do \\ +\hspace{3mm}4.1 $b \leftarrow \lfloor b / p \rfloor$ \\ +5. While ($b > 0$) do \\ +\hspace{3mm}5.1 Swap $a$ and $b$ such that $a$ is the smallest of the two. \\ +\hspace{3mm}5.2 $b \leftarrow b - a$ \\ +\hspace{3mm}5.3 While $b$ is divisible by $p$ do \\ +\hspace{6mm}5.3.1 $b \leftarrow \lfloor b / p \rfloor$ \\ +6. Return($a \cdot p^k$). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm Greatest Common Divisor (III)} +\label{fig:gcd3} +\end{figure} + +This algorithm is based on the first except it removes powers of $p$ first and inside the main loop to ensure the tuple $\left < a, b \right >$ +decreases more rapidly. The first loop on step two removes powers of $p$ that are in common. A count, $k$, is kept which will present a common +divisor of $p^k$. After step two the remaining common divisor of $a$ and $b$ cannot be divisible by $p$. This means that $p$ can be safely +divided out of the difference $b - a$ so long as the division leaves no remainder. + +In particular the value of $p$ should be chosen such that the division on step 5.3.1 occur often. It also helps that division by $p$ be easy +to compute. The ideal choice of $p$ is two since division by two amounts to a right logical shift. Another important observation is that by +step five both $a$ and $b$ are odd. Therefore, the diffrence $b - a$ must be even which means that each iteration removes one bit from the +largest of the pair. + +\subsection{Complete Greatest Common Divisor} +The algorithms presented so far cannot handle inputs which are zero or negative. The following algorithm can handle all input cases properly +and will produce the greatest common divisor. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_gcd}. \\ +\textbf{Input}. mp\_int $a$ and $b$ \\ +\textbf{Output}. The greatest common divisor $c = (a, b)$. \\ +\hline \\ +1. If $a = 0$ then \\ +\hspace{3mm}1.1 $c \leftarrow \vert b \vert $ \\ +\hspace{3mm}1.2 Return(\textit{MP\_OKAY}). \\ +2. If $b = 0$ then \\ +\hspace{3mm}2.1 $c \leftarrow \vert a \vert $ \\ +\hspace{3mm}2.2 Return(\textit{MP\_OKAY}). \\ +3. $u \leftarrow \vert a \vert, v \leftarrow \vert b \vert$ \\ +4. $k \leftarrow 0$ \\ +5. While $u.used > 0$ and $v.used > 0$ and $u_0 \equiv v_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ +\hspace{3mm}5.1 $k \leftarrow k + 1$ \\ +\hspace{3mm}5.2 $u \leftarrow \lfloor u / 2 \rfloor$ \\ +\hspace{3mm}5.3 $v \leftarrow \lfloor v / 2 \rfloor$ \\ +6. While $u.used > 0$ and $u_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ +\hspace{3mm}6.1 $u \leftarrow \lfloor u / 2 \rfloor$ \\ +7. While $v.used > 0$ and $v_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ +\hspace{3mm}7.1 $v \leftarrow \lfloor v / 2 \rfloor$ \\ +8. While $v.used > 0$ \\ +\hspace{3mm}8.1 If $\vert u \vert > \vert v \vert$ then \\ +\hspace{6mm}8.1.1 Swap $u$ and $v$. \\ +\hspace{3mm}8.2 $v \leftarrow \vert v \vert - \vert u \vert$ \\ +\hspace{3mm}8.3 While $v.used > 0$ and $v_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ +\hspace{6mm}8.3.1 $v \leftarrow \lfloor v / 2 \rfloor$ \\ +9. $c \leftarrow u \cdot 2^k$ \\ +10. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_gcd} +\end{figure} +\textbf{Algorithm mp\_gcd.} +This algorithm will produce the greatest common divisor of two mp\_ints $a$ and $b$. The algorithm was originally based on Algorithm B of +Knuth \cite[pp. 338]{TAOCPV2} but has been modified to be simpler to explain. In theory it achieves the same asymptotic working time as +Algorithm B and in practice this appears to be true. + +The first two steps handle the cases where either one of or both inputs are zero. If either input is zero the greatest common divisor is the +largest input or zero if they are both zero. If the inputs are not trivial than $u$ and $v$ are assigned the absolute values of +$a$ and $b$ respectively and the algorithm will proceed to reduce the pair. + +Step five will divide out any common factors of two and keep track of the count in the variable $k$. After this step, two is no longer a +factor of the remaining greatest common divisor between $u$ and $v$ and can be safely evenly divided out of either whenever they are even. Step +six and seven ensure that the $u$ and $v$ respectively have no more factors of two. At most only one of the while--loops will iterate since +they cannot both be even. + +By step eight both of $u$ and $v$ are odd which is required for the inner logic. First the pair are swapped such that $v$ is equal to +or greater than $u$. This ensures that the subtraction on step 8.2 will always produce a positive and even result. Step 8.3 removes any +factors of two from the difference $u$ to ensure that in the next iteration of the loop both are once again odd. + +After $v = 0$ occurs the variable $u$ has the greatest common divisor of the pair $\left < u, v \right >$ just after step six. The result +must be adjusted by multiplying by the common factors of two ($2^k$) removed earlier. + +EXAM,bn_mp_gcd.c + +This function makes use of the macros mp\_iszero and mp\_iseven. The former evaluates to $1$ if the input mp\_int is equivalent to the +integer zero otherwise it evaluates to $0$. The latter evaluates to $1$ if the input mp\_int represents a non-zero even integer otherwise +it evaluates to $0$. Note that just because mp\_iseven may evaluate to $0$ does not mean the input is odd, it could also be zero. The three +trivial cases of inputs are handled on lines @23,zero@ through @29,}@. After those lines the inputs are assumed to be non-zero. + +Lines @32,if@ and @36,if@ make local copies $u$ and $v$ of the inputs $a$ and $b$ respectively. At this point the common factors of two +must be divided out of the two inputs. The block starting at line @43,common@ removes common factors of two by first counting the number of trailing +zero bits in both. The local integer $k$ is used to keep track of how many factors of $2$ are pulled out of both values. It is assumed that +the number of factors will not exceed the maximum value of a C ``int'' data type\footnote{Strictly speaking no array in C may have more than +entries than are accessible by an ``int'' so this is not a limitation.}. + +At this point there are no more common factors of two in the two values. The divisions by a power of two on lines @60,div_2d@ and @67,div_2d@ remove +any independent factors of two such that both $u$ and $v$ are guaranteed to be an odd integer before hitting the main body of the algorithm. The while loop +on line @72, while@ performs the reduction of the pair until $v$ is equal to zero. The unsigned comparison and subtraction algorithms are used in +place of the full signed routines since both values are guaranteed to be positive and the result of the subtraction is guaranteed to be non-negative. + +\section{Least Common Multiple} +The least common multiple of a pair of integers is their product divided by their greatest common divisor. For two integers $a$ and $b$ the +least common multiple is normally denoted as $[ a, b ]$ and numerically equivalent to ${ab} \over {(a, b)}$. For example, if $a = 2 \cdot 2 \cdot 3 = 12$ +and $b = 2 \cdot 3 \cdot 3 \cdot 7 = 126$ the least common multiple is ${126 \over {(12, 126)}} = {126 \over 6} = 21$. + +The least common multiple arises often in coding theory as well as number theory. If two functions have periods of $a$ and $b$ respectively they will +collide, that is be in synchronous states, after only $[ a, b ]$ iterations. This is why, for example, random number generators based on +Linear Feedback Shift Registers (LFSR) tend to use registers with periods which are co-prime (\textit{e.g. the greatest common divisor is one.}). +Similarly in number theory if a composite $n$ has two prime factors $p$ and $q$ then maximal order of any unit of $\Z/n\Z$ will be $[ p - 1, q - 1] $. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_lcm}. \\ +\textbf{Input}. mp\_int $a$ and $b$ \\ +\textbf{Output}. The least common multiple $c = [a, b]$. \\ +\hline \\ +1. $c \leftarrow (a, b)$ \\ +2. $t \leftarrow a \cdot b$ \\ +3. $c \leftarrow \lfloor t / c \rfloor$ \\ +4. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_lcm} +\end{figure} +\textbf{Algorithm mp\_lcm.} +This algorithm computes the least common multiple of two mp\_int inputs $a$ and $b$. It computes the least common multiple directly by +dividing the product of the two inputs by their greatest common divisor. + +EXAM,bn_mp_lcm.c + +\section{Jacobi Symbol Computation} +To explain the Jacobi Symbol we shall first discuss the Legendre function\footnote{Arrg. What is the name of this?} off which the Jacobi symbol is +defined. The Legendre function computes whether or not an integer $a$ is a quadratic residue modulo an odd prime $p$. Numerically it is +equivalent to equation \ref{eqn:legendre}. + +\textit{-- Tom, don't be an ass, cite your source here...!} + +\begin{equation} +a^{(p-1)/2} \equiv \begin{array}{rl} + -1 & \mbox{if }a\mbox{ is a quadratic non-residue.} \\ + 0 & \mbox{if }a\mbox{ divides }p\mbox{.} \\ + 1 & \mbox{if }a\mbox{ is a quadratic residue}. + \end{array} \mbox{ (mod }p\mbox{)} +\label{eqn:legendre} +\end{equation} + +\textbf{Proof.} \textit{Equation \ref{eqn:legendre} correctly identifies the residue status of an integer $a$ modulo a prime $p$.} +An integer $a$ is a quadratic residue if the following equation has a solution. + +\begin{equation} +x^2 \equiv a \mbox{ (mod }p\mbox{)} +\label{eqn:root} +\end{equation} + +Consider the following equation. + +\begin{equation} +0 \equiv x^{p-1} - 1 \equiv \left \lbrace \left (x^2 \right )^{(p-1)/2} - a^{(p-1)/2} \right \rbrace + \left ( a^{(p-1)/2} - 1 \right ) \mbox{ (mod }p\mbox{)} +\label{eqn:rooti} +\end{equation} + +Whether equation \ref{eqn:root} has a solution or not equation \ref{eqn:rooti} is always true. If $a^{(p-1)/2} - 1 \equiv 0 \mbox{ (mod }p\mbox{)}$ +then the quantity in the braces must be zero. By reduction, + +\begin{eqnarray} +\left (x^2 \right )^{(p-1)/2} - a^{(p-1)/2} \equiv 0 \nonumber \\ +\left (x^2 \right )^{(p-1)/2} \equiv a^{(p-1)/2} \nonumber \\ +x^2 \equiv a \mbox{ (mod }p\mbox{)} +\end{eqnarray} + +As a result there must be a solution to the quadratic equation and in turn $a$ must be a quadratic residue. If $a$ does not divide $p$ and $a$ +is not a quadratic residue then the only other value $a^{(p-1)/2}$ may be congruent to is $-1$ since +\begin{equation} +0 \equiv a^{p - 1} - 1 \equiv (a^{(p-1)/2} + 1)(a^{(p-1)/2} - 1) \mbox{ (mod }p\mbox{)} +\end{equation} +One of the terms on the right hand side must be zero. \textbf{QED} + +\subsection{Jacobi Symbol} +The Jacobi symbol is a generalization of the Legendre function for any odd non prime moduli $p$ greater than 2. If $p = \prod_{i=0}^n p_i$ then +the Jacobi symbol $\left ( { a \over p } \right )$ is equal to the following equation. + +\begin{equation} +\left ( { a \over p } \right ) = \left ( { a \over p_0} \right ) \left ( { a \over p_1} \right ) \ldots \left ( { a \over p_n} \right ) +\end{equation} + +By inspection if $p$ is prime the Jacobi symbol is equivalent to the Legendre function. The following facts\footnote{See HAC \cite[pp. 72-74]{HAC} for +further details.} will be used to derive an efficient Jacobi symbol algorithm. Where $p$ is an odd integer greater than two and $a, b \in \Z$ the +following are true. + +\begin{enumerate} +\item $\left ( { a \over p} \right )$ equals $-1$, $0$ or $1$. +\item $\left ( { ab \over p} \right ) = \left ( { a \over p} \right )\left ( { b \over p} \right )$. +\item If $a \equiv b$ then $\left ( { a \over p} \right ) = \left ( { b \over p} \right )$. +\item $\left ( { 2 \over p} \right )$ equals $1$ if $p \equiv 1$ or $7 \mbox{ (mod }8\mbox{)}$. Otherwise, it equals $-1$. +\item $\left ( { a \over p} \right ) \equiv \left ( { p \over a} \right ) \cdot (-1)^{(p-1)(a-1)/4}$. More specifically +$\left ( { a \over p} \right ) = \left ( { p \over a} \right )$ if $p \equiv a \equiv 1 \mbox{ (mod }4\mbox{)}$. +\end{enumerate} + +Using these facts if $a = 2^k \cdot a'$ then + +\begin{eqnarray} +\left ( { a \over p } \right ) = \left ( {{2^k} \over p } \right ) \left ( {a' \over p} \right ) \nonumber \\ + = \left ( {2 \over p } \right )^k \left ( {a' \over p} \right ) +\label{eqn:jacobi} +\end{eqnarray} + +By fact five, + +\begin{equation} +\left ( { a \over p } \right ) = \left ( { p \over a } \right ) \cdot (-1)^{(p-1)(a-1)/4} +\end{equation} + +Subsequently by fact three since $p \equiv (p \mbox{ mod }a) \mbox{ (mod }a\mbox{)}$ then + +\begin{equation} +\left ( { a \over p } \right ) = \left ( { {p \mbox{ mod } a} \over a } \right ) \cdot (-1)^{(p-1)(a-1)/4} +\end{equation} + +By putting both observations into equation \ref{eqn:jacobi} the following simplified equation is formed. + +\begin{equation} +\left ( { a \over p } \right ) = \left ( {2 \over p } \right )^k \left ( {{p\mbox{ mod }a'} \over a'} \right ) \cdot (-1)^{(p-1)(a'-1)/4} +\end{equation} + +The value of $\left ( {{p \mbox{ mod }a'} \over a'} \right )$ can be found by using the same equation recursively. The value of +$\left ( {2 \over p } \right )^k$ equals $1$ if $k$ is even otherwise it equals $\left ( {2 \over p } \right )$. Using this approach the +factors of $p$ do not have to be known. Furthermore, if $(a, p) = 1$ then the algorithm will terminate when the recursion requests the +Jacobi symbol computation of $\left ( {1 \over a'} \right )$ which is simply $1$. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_jacobi}. \\ +\textbf{Input}. mp\_int $a$ and $p$, $a \ge 0$, $p \ge 3$, $p \equiv 1 \mbox{ (mod }2\mbox{)}$ \\ +\textbf{Output}. The Jacobi symbol $c = \left ( {a \over p } \right )$. \\ +\hline \\ +1. If $a = 0$ then \\ +\hspace{3mm}1.1 $c \leftarrow 0$ \\ +\hspace{3mm}1.2 Return(\textit{MP\_OKAY}). \\ +2. If $a = 1$ then \\ +\hspace{3mm}2.1 $c \leftarrow 1$ \\ +\hspace{3mm}2.2 Return(\textit{MP\_OKAY}). \\ +3. $a' \leftarrow a$ \\ +4. $k \leftarrow 0$ \\ +5. While $a'.used > 0$ and $a'_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ +\hspace{3mm}5.1 $k \leftarrow k + 1$ \\ +\hspace{3mm}5.2 $a' \leftarrow \lfloor a' / 2 \rfloor$ \\ +6. If $k \equiv 0 \mbox{ (mod }2\mbox{)}$ then \\ +\hspace{3mm}6.1 $s \leftarrow 1$ \\ +7. else \\ +\hspace{3mm}7.1 $r \leftarrow p_0 \mbox{ (mod }8\mbox{)}$ \\ +\hspace{3mm}7.2 If $r = 1$ or $r = 7$ then \\ +\hspace{6mm}7.2.1 $s \leftarrow 1$ \\ +\hspace{3mm}7.3 else \\ +\hspace{6mm}7.3.1 $s \leftarrow -1$ \\ +8. If $p_0 \equiv a'_0 \equiv 3 \mbox{ (mod }4\mbox{)}$ then \\ +\hspace{3mm}8.1 $s \leftarrow -s$ \\ +9. If $a' \ne 1$ then \\ +\hspace{3mm}9.1 $p' \leftarrow p \mbox{ (mod }a'\mbox{)}$ \\ +\hspace{3mm}9.2 $s \leftarrow s \cdot \mbox{mp\_jacobi}(p', a')$ \\ +10. $c \leftarrow s$ \\ +11. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_jacobi} +\end{figure} +\textbf{Algorithm mp\_jacobi.} +This algorithm computes the Jacobi symbol for an arbitrary positive integer $a$ with respect to an odd integer $p$ greater than three. The algorithm +is based on algorithm 2.149 of HAC \cite[pp. 73]{HAC}. + +Step numbers one and two handle the trivial cases of $a = 0$ and $a = 1$ respectively. Step five determines the number of two factors in the +input $a$. If $k$ is even than the term $\left ( { 2 \over p } \right )^k$ must always evaluate to one. If $k$ is odd than the term evaluates to one +if $p_0$ is congruent to one or seven modulo eight, otherwise it evaluates to $-1$. After the the $\left ( { 2 \over p } \right )^k$ term is handled +the $(-1)^{(p-1)(a'-1)/4}$ is computed and multiplied against the current product $s$. The latter term evaluates to one if both $p$ and $a'$ +are congruent to one modulo four, otherwise it evaluates to negative one. + +By step nine if $a'$ does not equal one a recursion is required. Step 9.1 computes $p' \equiv p \mbox{ (mod }a'\mbox{)}$ and will recurse to compute +$\left ( {p' \over a'} \right )$ which is multiplied against the current Jacobi product. + +EXAM,bn_mp_jacobi.c + +As a matter of practicality the variable $a'$ as per the pseudo-code is reprensented by the variable $a1$ since the $'$ symbol is not valid for a C +variable name character. + +The two simple cases of $a = 0$ and $a = 1$ are handled at the very beginning to simplify the algorithm. If the input is non-trivial the algorithm +has to proceed compute the Jacobi. The variable $s$ is used to hold the current Jacobi product. Note that $s$ is merely a C ``int'' data type since +the values it may obtain are merely $-1$, $0$ and $1$. + +After a local copy of $a$ is made all of the factors of two are divided out and the total stored in $k$. Technically only the least significant +bit of $k$ is required, however, it makes the algorithm simpler to follow to perform an addition. In practice an exclusive-or and addition have the same +processor requirements and neither is faster than the other. + +Line @59, if@ through @70, }@ determines the value of $\left ( { 2 \over p } \right )^k$. If the least significant bit of $k$ is zero than +$k$ is even and the value is one. Otherwise, the value of $s$ depends on which residue class $p$ belongs to modulo eight. The value of +$(-1)^{(p-1)(a'-1)/4}$ is compute and multiplied against $s$ on lines @73, if@ through @75, }@. + +Finally, if $a1$ does not equal one the algorithm must recurse and compute $\left ( {p' \over a'} \right )$. + +\textit{-- Comment about default $s$ and such...} + +\section{Modular Inverse} +\label{sec:modinv} +The modular inverse of a number actually refers to the modular multiplicative inverse. Essentially for any integer $a$ such that $(a, p) = 1$ there +exist another integer $b$ such that $ab \equiv 1 \mbox{ (mod }p\mbox{)}$. The integer $b$ is called the multiplicative inverse of $a$ which is +denoted as $b = a^{-1}$. Technically speaking modular inversion is a well defined operation for any finite ring or field not just for rings and +fields of integers. However, the former will be the matter of discussion. + +The simplest approach is to compute the algebraic inverse of the input. That is to compute $b \equiv a^{\Phi(p) - 1}$. If $\Phi(p)$ is the +order of the multiplicative subgroup modulo $p$ then $b$ must be the multiplicative inverse of $a$. The proof of which is trivial. + +\begin{equation} +ab \equiv a \left (a^{\Phi(p) - 1} \right ) \equiv a^{\Phi(p)} \equiv a^0 \equiv 1 \mbox{ (mod }p\mbox{)} +\end{equation} + +However, as simple as this approach may be it has two serious flaws. It requires that the value of $\Phi(p)$ be known which if $p$ is composite +requires all of the prime factors. This approach also is very slow as the size of $p$ grows. + +A simpler approach is based on the observation that solving for the multiplicative inverse is equivalent to solving the linear +Diophantine\footnote{See LeVeque \cite[pp. 40-43]{LeVeque} for more information.} equation. + +\begin{equation} +ab + pq = 1 +\end{equation} + +Where $a$, $b$, $p$ and $q$ are all integers. If such a pair of integers $ \left < b, q \right >$ exist than $b$ is the multiplicative inverse of +$a$ modulo $p$. The extended Euclidean algorithm (Knuth \cite[pp. 342]{TAOCPV2}) can be used to solve such equations provided $(a, p) = 1$. +However, instead of using that algorithm directly a variant known as the binary Extended Euclidean algorithm will be used in its place. The +binary approach is very similar to the binary greatest common divisor algorithm except it will produce a full solution to the Diophantine +equation. + +\subsection{General Case} +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_invmod}. \\ +\textbf{Input}. mp\_int $a$ and $b$, $(a, b) = 1$, $p \ge 2$, $0 < a < p$. \\ +\textbf{Output}. The modular inverse $c \equiv a^{-1} \mbox{ (mod }b\mbox{)}$. \\ +\hline \\ +1. If $b \le 0$ then return(\textit{MP\_VAL}). \\ +2. If $b_0 \equiv 1 \mbox{ (mod }2\mbox{)}$ then use algorithm fast\_mp\_invmod. \\ +3. $x \leftarrow \vert a \vert, y \leftarrow b$ \\ +4. If $x_0 \equiv y_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ then return(\textit{MP\_VAL}). \\ +5. $B \leftarrow 0, C \leftarrow 0, A \leftarrow 1, D \leftarrow 1$ \\ +6. While $u.used > 0$ and $u_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ +\hspace{3mm}6.1 $u \leftarrow \lfloor u / 2 \rfloor$ \\ +\hspace{3mm}6.2 If ($A.used > 0$ and $A_0 \equiv 1 \mbox{ (mod }2\mbox{)}$) or ($B.used > 0$ and $B_0 \equiv 1 \mbox{ (mod }2\mbox{)}$) then \\ +\hspace{6mm}6.2.1 $A \leftarrow A + y$ \\ +\hspace{6mm}6.2.2 $B \leftarrow B - x$ \\ +\hspace{3mm}6.3 $A \leftarrow \lfloor A / 2 \rfloor$ \\ +\hspace{3mm}6.4 $B \leftarrow \lfloor B / 2 \rfloor$ \\ +7. While $v.used > 0$ and $v_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ +\hspace{3mm}7.1 $v \leftarrow \lfloor v / 2 \rfloor$ \\ +\hspace{3mm}7.2 If ($C.used > 0$ and $C_0 \equiv 1 \mbox{ (mod }2\mbox{)}$) or ($D.used > 0$ and $D_0 \equiv 1 \mbox{ (mod }2\mbox{)}$) then \\ +\hspace{6mm}7.2.1 $C \leftarrow C + y$ \\ +\hspace{6mm}7.2.2 $D \leftarrow D - x$ \\ +\hspace{3mm}7.3 $C \leftarrow \lfloor C / 2 \rfloor$ \\ +\hspace{3mm}7.4 $D \leftarrow \lfloor D / 2 \rfloor$ \\ +8. If $u \ge v$ then \\ +\hspace{3mm}8.1 $u \leftarrow u - v$ \\ +\hspace{3mm}8.2 $A \leftarrow A - C$ \\ +\hspace{3mm}8.3 $B \leftarrow B - D$ \\ +9. else \\ +\hspace{3mm}9.1 $v \leftarrow v - u$ \\ +\hspace{3mm}9.2 $C \leftarrow C - A$ \\ +\hspace{3mm}9.3 $D \leftarrow D - B$ \\ +10. If $u \ne 0$ goto step 6. \\ +11. If $v \ne 1$ return(\textit{MP\_VAL}). \\ +12. While $C \le 0$ do \\ +\hspace{3mm}12.1 $C \leftarrow C + b$ \\ +13. While $C \ge b$ do \\ +\hspace{3mm}13.1 $C \leftarrow C - b$ \\ +14. $c \leftarrow C$ \\ +15. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\end{figure} +\textbf{Algorithm mp\_invmod.} +This algorithm computes the modular multiplicative inverse of an integer $a$ modulo an integer $b$. This algorithm is a variation of the +extended binary Euclidean algorithm from HAC \cite[pp. 608]{HAC}. It has been modified to only compute the modular inverse and not a complete +Diophantine solution. + +If $b \le 0$ than the modulus is invalid and MP\_VAL is returned. Similarly if both $a$ and $b$ are even then there cannot be a multiplicative +inverse for $a$ and the error is reported. + +The astute reader will observe that steps seven through nine are very similar to the binary greatest common divisor algorithm mp\_gcd. In this case +the other variables to the Diophantine equation are solved. The algorithm terminates when $u = 0$ in which case the solution is + +\begin{equation} +Ca + Db = v +\end{equation} + +If $v$, the greatest common divisor of $a$ and $b$ is not equal to one then the algorithm will report an error as no inverse exists. Otherwise, $C$ +is the modular inverse of $a$. The actual value of $C$ is congruent to, but not necessarily equal to, the ideal modular inverse which should lie +within $1 \le a^{-1} < b$. Step numbers twelve and thirteen adjust the inverse until it is in range. If the original input $a$ is within $0 < a < p$ +then only a couple of additions or subtractions will be required to adjust the inverse. + +EXAM,bn_mp_invmod.c + +\subsubsection{Odd Moduli} + +When the modulus $b$ is odd the variables $A$ and $C$ are fixed and are not required to compute the inverse. In particular by attempting to solve +the Diophantine $Cb + Da = 1$ only $B$ and $D$ are required to find the inverse of $a$. + +The algorithm fast\_mp\_invmod is a direct adaptation of algorithm mp\_invmod with all all steps involving either $A$ or $C$ removed. This +optimization will halve the time required to compute the modular inverse. + +\section{Primality Tests} + +A non-zero integer $a$ is said to be prime if it is not divisible by any other integer excluding one and itself. For example, $a = 7$ is prime +since the integers $2 \ldots 6$ do not evenly divide $a$. By contrast, $a = 6$ is not prime since $a = 6 = 2 \cdot 3$. + +Prime numbers arise in cryptography considerably as they allow finite fields to be formed. The ability to determine whether an integer is prime or +not quickly has been a viable subject in cryptography and number theory for considerable time. The algorithms that will be presented are all +probablistic algorithms in that when they report an integer is composite it must be composite. However, when the algorithms report an integer is +prime the algorithm may be incorrect. + +As will be discussed it is possible to limit the probability of error so well that for practical purposes the probablity of error might as +well be zero. For the purposes of these discussions let $n$ represent the candidate integer of which the primality is in question. + +\subsection{Trial Division} + +Trial division means to attempt to evenly divide a candidate integer by small prime integers. If the candidate can be evenly divided it obviously +cannot be prime. By dividing by all primes $1 < p \le \sqrt{n}$ this test can actually prove whether an integer is prime. However, such a test +would require a prohibitive amount of time as $n$ grows. + +Instead of dividing by every prime, a smaller, more mangeable set of primes may be used instead. By performing trial division with only a subset +of the primes less than $\sqrt{n} + 1$ the algorithm cannot prove if a candidate is prime. However, often it can prove a candidate is not prime. + +The benefit of this test is that trial division by small values is fairly efficient. Specially compared to the other algorithms that will be +discussed shortly. The probability that this approach correctly identifies a composite candidate when tested with all primes upto $q$ is given by +$1 - {1.12 \over ln(q)}$. The graph (\ref{pic:primality}, will be added later) demonstrates the probability of success for the range +$3 \le q \le 100$. + +At approximately $q = 30$ the gain of performing further tests diminishes fairly quickly. At $q = 90$ further testing is generally not going to +be of any practical use. In the case of LibTomMath the default limit $q = 256$ was chosen since it is not too high and will eliminate +approximately $80\%$ of all candidate integers. The constant \textbf{PRIME\_SIZE} is equal to the number of primes in the test base. The +array \_\_prime\_tab is an array of the first \textbf{PRIME\_SIZE} prime numbers. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_prime\_is\_divisible}. \\ +\textbf{Input}. mp\_int $a$ \\ +\textbf{Output}. $c = 1$ if $n$ is divisible by a small prime, otherwise $c = 0$. \\ +\hline \\ +1. for $ix$ from $0$ to $PRIME\_SIZE$ do \\ +\hspace{3mm}1.1 $d \leftarrow n \mbox{ (mod }\_\_prime\_tab_{ix}\mbox{)}$ \\ +\hspace{3mm}1.2 If $d = 0$ then \\ +\hspace{6mm}1.2.1 $c \leftarrow 1$ \\ +\hspace{6mm}1.2.2 Return(\textit{MP\_OKAY}). \\ +2. $c \leftarrow 0$ \\ +3. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_prime\_is\_divisible} +\end{figure} +\textbf{Algorithm mp\_prime\_is\_divisible.} +This algorithm attempts to determine if a candidate integer $n$ is composite by performing trial divisions. + +EXAM,bn_mp_prime_is_divisible.c + +The algorithm defaults to a return of $0$ in case an error occurs. The values in the prime table are all specified to be in the range of a +mp\_digit. The table \_\_prime\_tab is defined in the following file. + +EXAM,bn_prime_tab.c + +Note that there are two possible tables. When an mp\_digit is 7-bits long only the primes upto $127$ may be included, otherwise the primes +upto $1619$ are used. Note that the value of \textbf{PRIME\_SIZE} is a constant dependent on the size of a mp\_digit. + +\subsection{The Fermat Test} +The Fermat test is probably one the oldest tests to have a non-trivial probability of success. It is based on the fact that if $n$ is in +fact prime then $a^{n} \equiv a \mbox{ (mod }n\mbox{)}$ for all $0 < a < n$. The reason being that if $n$ is prime than the order of +the multiplicative sub group is $n - 1$. Any base $a$ must have an order which divides $n - 1$ and as such $a^n$ is equivalent to +$a^1 = a$. + +If $n$ is composite then any given base $a$ does not have to have a period which divides $n - 1$. In which case +it is possible that $a^n \nequiv a \mbox{ (mod }n\mbox{)}$. However, this test is not absolute as it is possible that the order +of a base will divide $n - 1$ which would then be reported as prime. Such a base yields what is known as a Fermat pseudo-prime. Several +integers known as Carmichael numbers will be a pseudo-prime to all valid bases. Fortunately such numbers are extremely rare as $n$ grows +in size. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_prime\_fermat}. \\ +\textbf{Input}. mp\_int $a$ and $b$, $a \ge 2$, $0 < b < a$. \\ +\textbf{Output}. $c = 1$ if $b^a \equiv b \mbox{ (mod }a\mbox{)}$, otherwise $c = 0$. \\ +\hline \\ +1. $t \leftarrow b^a \mbox{ (mod }a\mbox{)}$ \\ +2. If $t = b$ then \\ +\hspace{3mm}2.1 $c = 1$ \\ +3. else \\ +\hspace{3mm}3.1 $c = 0$ \\ +4. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_prime\_fermat} +\end{figure} +\textbf{Algorithm mp\_prime\_fermat.} +This algorithm determines whether an mp\_int $a$ is a Fermat prime to the base $b$ or not. It uses a single modular exponentiation to +determine the result. + +EXAM,bn_mp_prime_fermat.c + +\subsection{The Miller-Rabin Test} +The Miller-Rabin (citation) test is another primality test which has tighter error bounds than the Fermat test specifically with sequentially chosen +candidate integers. The algorithm is based on the observation that if $n - 1 = 2^kr$ and if $b^r \nequiv \pm 1$ then after upto $k - 1$ squarings the +value must be equal to $-1$. The squarings are stopped as soon as $-1$ is observed. If the value of $1$ is observed first it means that +some value not congruent to $\pm 1$ when squared equals one which cannot occur if $n$ is prime. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_prime\_miller\_rabin}. \\ +\textbf{Input}. mp\_int $a$ and $b$, $a \ge 2$, $0 < b < a$. \\ +\textbf{Output}. $c = 1$ if $a$ is a Miller-Rabin prime to the base $a$, otherwise $c = 0$. \\ +\hline +1. $a' \leftarrow a - 1$ \\ +2. $r \leftarrow n1$ \\ +3. $c \leftarrow 0, s \leftarrow 0$ \\ +4. While $r.used > 0$ and $r_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ +\hspace{3mm}4.1 $s \leftarrow s + 1$ \\ +\hspace{3mm}4.2 $r \leftarrow \lfloor r / 2 \rfloor$ \\ +5. $y \leftarrow b^r \mbox{ (mod }a\mbox{)}$ \\ +6. If $y \nequiv \pm 1$ then \\ +\hspace{3mm}6.1 $j \leftarrow 1$ \\ +\hspace{3mm}6.2 While $j \le (s - 1)$ and $y \nequiv a'$ \\ +\hspace{6mm}6.2.1 $y \leftarrow y^2 \mbox{ (mod }a\mbox{)}$ \\ +\hspace{6mm}6.2.2 If $y = 1$ then goto step 8. \\ +\hspace{6mm}6.2.3 $j \leftarrow j + 1$ \\ +\hspace{3mm}6.3 If $y \nequiv a'$ goto step 8. \\ +7. $c \leftarrow 1$\\ +8. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_prime\_miller\_rabin} +\end{figure} +\textbf{Algorithm mp\_prime\_miller\_rabin.} +This algorithm performs one trial round of the Miller-Rabin algorithm to the base $b$. It will set $c = 1$ if the algorithm cannot determine +if $b$ is composite or $c = 0$ if $b$ is provably composite. The values of $s$ and $r$ are computed such that $a' = a - 1 = 2^sr$. + +If the value $y \equiv b^r$ is congruent to $\pm 1$ then the algorithm cannot prove if $a$ is composite or not. Otherwise, the algorithm will +square $y$ upto $s - 1$ times stopping only when $y \equiv -1$. If $y^2 \equiv 1$ and $y \nequiv \pm 1$ then the algorithm can report that $a$ +is provably composite. If the algorithm performs $s - 1$ squarings and $y \nequiv -1$ then $a$ is provably composite. If $a$ is not provably +composite then it is \textit{probably} prime. + +EXAM,bn_mp_prime_miller_rabin.c + + + + +\backmatter +\appendix +\begin{thebibliography}{ABCDEF} +\bibitem[1]{TAOCPV2} +Donald Knuth, \textit{The Art of Computer Programming}, Third Edition, Volume Two, Seminumerical Algorithms, Addison-Wesley, 1998 + +\bibitem[2]{HAC} +A. Menezes, P. van Oorschot, S. Vanstone, \textit{Handbook of Applied Cryptography}, CRC Press, 1996 + +\bibitem[3]{ROSE} +Michael Rosing, \textit{Implementing Elliptic Curve Cryptography}, Manning Publications, 1999 + +\bibitem[4]{COMBA} +Paul G. Comba, \textit{Exponentiation Cryptosystems on the IBM PC}. IBM Systems Journal 29(4): 526-538 (1990) + +\bibitem[5]{KARA} +A. Karatsuba, Doklay Akad. Nauk SSSR 145 (1962), pp.293-294 + +\bibitem[6]{KARAP} +Andre Weimerskirch and Christof Paar, \textit{Generalizations of the Karatsuba Algorithm for Polynomial Multiplication}, Submitted to Design, Codes and Cryptography, March 2002 + +\bibitem[7]{BARRETT} +Paul Barrett, \textit{Implementing the Rivest Shamir and Adleman Public Key Encryption Algorithm on a Standard Digital Signal Processor}, Advances in Cryptology, Crypto '86, Springer-Verlag. + +\bibitem[8]{MONT} +P.L.Montgomery. \textit{Modular multiplication without trial division}. Mathematics of Computation, 44(170):519-521, April 1985. + +\bibitem[9]{DRMET} +Chae Hoon Lim and Pil Joong Lee, \textit{Generating Efficient Primes for Discrete Log Cryptosystems}, POSTECH Information Research Laboratories + +\bibitem[10]{MMB} +J. Daemen and R. Govaerts and J. Vandewalle, \textit{Block ciphers based on Modular Arithmetic}, State and {P}rogress in the {R}esearch of {C}ryptography, 1993, pp. 80-89 + +\bibitem[11]{RSAREF} +R.L. Rivest, A. Shamir, L. Adleman, \textit{A Method for Obtaining Digital Signatures and Public-Key Cryptosystems} + +\bibitem[12]{DHREF} +Whitfield Diffie, Martin E. Hellman, \textit{New Directions in Cryptography}, IEEE Transactions on Information Theory, 1976 + +\bibitem[13]{IEEE} +IEEE Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Std 754-1985) + +\bibitem[14]{GMP} +GNU Multiple Precision (GMP), \url{http://www.swox.com/gmp/} + +\bibitem[15]{MPI} +Multiple Precision Integer Library (MPI), Michael Fromberger, \url{http://thayer.dartmouth.edu/~sting/mpi/} + +\bibitem[16]{OPENSSL} +OpenSSL Cryptographic Toolkit, \url{http://openssl.org} + +\bibitem[17]{LIP} +Large Integer Package, \url{http://home.hetnet.nl/~ecstr/LIP.zip} + +\bibitem[18]{ISOC} +JTC1/SC22/WG14, ISO/IEC 9899:1999, ``A draft rationale for the C99 standard.'' + +\bibitem[19]{JAVA} +The Sun Java Website, \url{http://java.sun.com/} + +\end{thebibliography} + +\input{tommath.ind} + +\end{document} diff --git a/xmhf-64/xmhf/third-party/libtommath/tommath.tex b/xmhf-64/xmhf/third-party/libtommath/tommath.tex new file mode 100644 index 0000000000..c79a5370fb --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/tommath.tex @@ -0,0 +1,6691 @@ +\documentclass[b5paper]{book} +\usepackage{hyperref} +\usepackage{makeidx} +\usepackage{amssymb} +\usepackage{color} +\usepackage{alltt} +\usepackage{graphicx} +\usepackage{layout} +\def\union{\cup} +\def\intersect{\cap} +\def\getsrandom{\stackrel{\rm R}{\gets}} +\def\cross{\times} +\def\cat{\hspace{0.5em} \| \hspace{0.5em}} +\def\catn{$\|$} +\def\divides{\hspace{0.3em} | \hspace{0.3em}} +\def\nequiv{\not\equiv} +\def\approx{\raisebox{0.2ex}{\mbox{\small $\sim$}}} +\def\lcm{{\rm lcm}} +\def\gcd{{\rm gcd}} +\def\log{{\rm log}} +\def\ord{{\rm ord}} +\def\abs{{\mathit abs}} +\def\rep{{\mathit rep}} +\def\mod{{\mathit\ mod\ }} +\renewcommand{\pmod}[1]{\ ({\rm mod\ }{#1})} +\newcommand{\floor}[1]{\left\lfloor{#1}\right\rfloor} +\newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil} +\def\Or{{\rm\ or\ }} +\def\And{{\rm\ and\ }} +\def\iff{\hspace{1em}\Longleftrightarrow\hspace{1em}} +\def\implies{\Rightarrow} +\def\undefined{{\rm ``undefined"}} +\def\Proof{\vspace{1ex}\noindent {\bf Proof:}\hspace{1em}} +\let\oldphi\phi +\def\phi{\varphi} +\def\Pr{{\rm Pr}} +\newcommand{\str}[1]{{\mathbf{#1}}} +\def\F{{\mathbb F}} +\def\N{{\mathbb N}} +\def\Z{{\mathbb Z}} +\def\R{{\mathbb R}} +\def\C{{\mathbb C}} +\def\Q{{\mathbb Q}} +\definecolor{DGray}{gray}{0.5} +\newcommand{\emailaddr}[1]{\mbox{$<${#1}$>$}} +\def\twiddle{\raisebox{0.3ex}{\mbox{\tiny $\sim$}}} +\def\gap{\vspace{0.5ex}} +\makeindex +\begin{document} +\frontmatter +\pagestyle{empty} +\title{Multi--Precision Math} +\author{\mbox{ +%\begin{small} +\begin{tabular}{c} +Tom St Denis \\ +Algonquin College \\ +\\ +Mads Rasmussen \\ +Open Communications Security \\ +\\ +Greg Rose \\ +QUALCOMM Australia \\ +\end{tabular} +%\end{small} +} +} +\maketitle +This text has been placed in the public domain. This text corresponds to the v0.39 release of the +LibTomMath project. + +\begin{alltt} +Tom St Denis +111 Banning Rd +Ottawa, Ontario +K2L 1C3 +Canada + +Phone: 1-613-836-3160 +Email: tomstdenis@gmail.com +\end{alltt} + +This text is formatted to the international B5 paper size of 176mm wide by 250mm tall using the \LaTeX{} +{\em book} macro package and the Perl {\em booker} package. + +\tableofcontents +\listoffigures +\chapter*{Prefaces} +When I tell people about my LibTom projects and that I release them as public domain they are often puzzled. +They ask why I did it and especially why I continue to work on them for free. The best I can explain it is ``Because I can.'' +Which seems odd and perhaps too terse for adult conversation. I often qualify it with ``I am able, I am willing.'' which +perhaps explains it better. I am the first to admit there is not anything that special with what I have done. Perhaps +others can see that too and then we would have a society to be proud of. My LibTom projects are what I am doing to give +back to society in the form of tools and knowledge that can help others in their endeavours. + +I started writing this book because it was the most logical task to further my goal of open academia. The LibTomMath source +code itself was written to be easy to follow and learn from. There are times, however, where pure C source code does not +explain the algorithms properly. Hence this book. The book literally starts with the foundation of the library and works +itself outwards to the more complicated algorithms. The use of both pseudo--code and verbatim source code provides a duality +of ``theory'' and ``practice'' that the computer science students of the world shall appreciate. I never deviate too far +from relatively straightforward algebra and I hope that this book can be a valuable learning asset. + +This book and indeed much of the LibTom projects would not exist in their current form if it was not for a plethora +of kind people donating their time, resources and kind words to help support my work. Writing a text of significant +length (along with the source code) is a tiresome and lengthy process. Currently the LibTom project is four years old, +comprises of literally thousands of users and over 100,000 lines of source code, TeX and other material. People like Mads and Greg +were there at the beginning to encourage me to work well. It is amazing how timely validation from others can boost morale to +continue the project. Definitely my parents were there for me by providing room and board during the many months of work in 2003. + +To my many friends whom I have met through the years I thank you for the good times and the words of encouragement. I hope I +honour your kind gestures with this project. + +Open Source. Open Academia. Open Minds. + +\begin{flushright} Tom St Denis \end{flushright} + +\newpage +I found the opportunity to work with Tom appealing for several reasons, not only could I broaden my own horizons, but also +contribute to educate others facing the problem of having to handle big number mathematical calculations. + +This book is Tom's child and he has been caring and fostering the project ever since the beginning with a clear mind of +how he wanted the project to turn out. I have helped by proofreading the text and we have had several discussions about +the layout and language used. + +I hold a masters degree in cryptography from the University of Southern Denmark and have always been interested in the +practical aspects of cryptography. + +Having worked in the security consultancy business for several years in S\~{a}o Paulo, Brazil, I have been in touch with a +great deal of work in which multiple precision mathematics was needed. Understanding the possibilities for speeding up +multiple precision calculations is often very important since we deal with outdated machine architecture where modular +reductions, for example, become painfully slow. + +This text is for people who stop and wonder when first examining algorithms such as RSA for the first time and asks +themselves, ``You tell me this is only secure for large numbers, fine; but how do you implement these numbers?'' + +\begin{flushright} +Mads Rasmussen + +S\~{a}o Paulo - SP + +Brazil +\end{flushright} + +\newpage +It's all because I broke my leg. That just happened to be at about the same time that Tom asked for someone to review the section of the book about +Karatsuba multiplication. I was laid up, alone and immobile, and thought ``Why not?'' I vaguely knew what Karatsuba multiplication was, but not +really, so I thought I could help, learn, and stop myself from watching daytime cable TV, all at once. + +At the time of writing this, I've still not met Tom or Mads in meatspace. I've been following Tom's progress since his first splash on the +sci.crypt Usenet news group. I watched him go from a clueless newbie, to the cryptographic equivalent of a reformed smoker, to a real +contributor to the field, over a period of about two years. I've been impressed with his obvious intelligence, and astounded by his productivity. +Of course, he's young enough to be my own child, so he doesn't have my problems with staying awake. + +When I reviewed that single section of the book, in its very earliest form, I was very pleasantly surprised. So I decided to collaborate more fully, +and at least review all of it, and perhaps write some bits too. There's still a long way to go with it, and I have watched a number of close +friends go through the mill of publication, so I think that the way to go is longer than Tom thinks it is. Nevertheless, it's a good effort, +and I'm pleased to be involved with it. + +\begin{flushright} +Greg Rose, Sydney, Australia, June 2003. +\end{flushright} + +\mainmatter +\pagestyle{headings} +\chapter{Introduction} +\section{Multiple Precision Arithmetic} + +\subsection{What is Multiple Precision Arithmetic?} +When we think of long-hand arithmetic such as addition or multiplication we rarely consider the fact that we instinctively +raise or lower the precision of the numbers we are dealing with. For example, in decimal we almost immediate can +reason that $7$ times $6$ is $42$. However, $42$ has two digits of precision as opposed to one digit we started with. +Further multiplications of say $3$ result in a larger precision result $126$. In these few examples we have multiple +precisions for the numbers we are working with. Despite the various levels of precision a single subset\footnote{With the occasional optimization.} + of algorithms can be designed to accomodate them. + +By way of comparison a fixed or single precision operation would lose precision on various operations. For example, in +the decimal system with fixed precision $6 \cdot 7 = 2$. + +Essentially at the heart of computer based multiple precision arithmetic are the same long-hand algorithms taught in +schools to manually add, subtract, multiply and divide. + +\subsection{The Need for Multiple Precision Arithmetic} +The most prevalent need for multiple precision arithmetic, often referred to as ``bignum'' math, is within the implementation +of public-key cryptography algorithms. Algorithms such as RSA \cite{RSAREF} and Diffie-Hellman \cite{DHREF} require +integers of significant magnitude to resist known cryptanalytic attacks. For example, at the time of this writing a +typical RSA modulus would be at least greater than $10^{309}$. However, modern programming languages such as ISO C \cite{ISOC} and +Java \cite{JAVA} only provide instrinsic support for integers which are relatively small and single precision. + +\begin{figure}[!here] +\begin{center} +\begin{tabular}{|r|c|} +\hline \textbf{Data Type} & \textbf{Range} \\ +\hline char & $-128 \ldots 127$ \\ +\hline short & $-32768 \ldots 32767$ \\ +\hline long & $-2147483648 \ldots 2147483647$ \\ +\hline long long & $-9223372036854775808 \ldots 9223372036854775807$ \\ +\hline +\end{tabular} +\end{center} +\caption{Typical Data Types for the C Programming Language} +\label{fig:ISOC} +\end{figure} + +The largest data type guaranteed to be provided by the ISO C programming +language\footnote{As per the ISO C standard. However, each compiler vendor is allowed to augment the precision as they +see fit.} can only represent values up to $10^{19}$ as shown in figure \ref{fig:ISOC}. On its own the C language is +insufficient to accomodate the magnitude required for the problem at hand. An RSA modulus of magnitude $10^{19}$ could be +trivially factored\footnote{A Pollard-Rho factoring would take only $2^{16}$ time.} on the average desktop computer, +rendering any protocol based on the algorithm insecure. Multiple precision algorithms solve this very problem by +extending the range of representable integers while using single precision data types. + +Most advancements in fast multiple precision arithmetic stem from the need for faster and more efficient cryptographic +primitives. Faster modular reduction and exponentiation algorithms such as Barrett's algorithm, which have appeared in +various cryptographic journals, can render algorithms such as RSA and Diffie-Hellman more efficient. In fact, several +major companies such as RSA Security, Certicom and Entrust have built entire product lines on the implementation and +deployment of efficient algorithms. + +However, cryptography is not the only field of study that can benefit from fast multiple precision integer routines. +Another auxiliary use of multiple precision integers is high precision floating point data types. +The basic IEEE \cite{IEEE} standard floating point type is made up of an integer mantissa $q$, an exponent $e$ and a sign bit $s$. +Numbers are given in the form $n = q \cdot b^e \cdot -1^s$ where $b = 2$ is the most common base for IEEE. Since IEEE +floating point is meant to be implemented in hardware the precision of the mantissa is often fairly small +(\textit{23, 48 and 64 bits}). The mantissa is merely an integer and a multiple precision integer could be used to create +a mantissa of much larger precision than hardware alone can efficiently support. This approach could be useful where +scientific applications must minimize the total output error over long calculations. + +Yet another use for large integers is within arithmetic on polynomials of large characteristic (i.e. $GF(p)[x]$ for large $p$). +In fact the library discussed within this text has already been used to form a polynomial basis library\footnote{See \url{http://poly.libtomcrypt.org} for more details.}. + +\subsection{Benefits of Multiple Precision Arithmetic} +\index{precision} +The benefit of multiple precision representations over single or fixed precision representations is that +no precision is lost while representing the result of an operation which requires excess precision. For example, +the product of two $n$-bit integers requires at least $2n$ bits of precision to be represented faithfully. A multiple +precision algorithm would augment the precision of the destination to accomodate the result while a single precision system +would truncate excess bits to maintain a fixed level of precision. + +It is possible to implement algorithms which require large integers with fixed precision algorithms. For example, elliptic +curve cryptography (\textit{ECC}) is often implemented on smartcards by fixing the precision of the integers to the maximum +size the system will ever need. Such an approach can lead to vastly simpler algorithms which can accomodate the +integers required even if the host platform cannot natively accomodate them\footnote{For example, the average smartcard +processor has an 8 bit accumulator.}. However, as efficient as such an approach may be, the resulting source code is not +normally very flexible. It cannot, at runtime, accomodate inputs of higher magnitude than the designer anticipated. + +Multiple precision algorithms have the most overhead of any style of arithmetic. For the the most part the +overhead can be kept to a minimum with careful planning, but overall, it is not well suited for most memory starved +platforms. However, multiple precision algorithms do offer the most flexibility in terms of the magnitude of the +inputs. That is, the same algorithms based on multiple precision integers can accomodate any reasonable size input +without the designer's explicit forethought. This leads to lower cost of ownership for the code as it only has to +be written and tested once. + +\section{Purpose of This Text} +The purpose of this text is to instruct the reader regarding how to implement efficient multiple precision algorithms. +That is to not only explain a limited subset of the core theory behind the algorithms but also the various ``house keeping'' +elements that are neglected by authors of other texts on the subject. Several well reknowned texts \cite{TAOCPV2,HAC} +give considerably detailed explanations of the theoretical aspects of algorithms and often very little information +regarding the practical implementation aspects. + +In most cases how an algorithm is explained and how it is actually implemented are two very different concepts. For +example, the Handbook of Applied Cryptography (\textit{HAC}), algorithm 14.7 on page 594, gives a relatively simple +algorithm for performing multiple precision integer addition. However, the description lacks any discussion concerning +the fact that the two integer inputs may be of differing magnitudes. As a result the implementation is not as simple +as the text would lead people to believe. Similarly the division routine (\textit{algorithm 14.20, pp. 598}) does not +discuss how to handle sign or handle the dividend's decreasing magnitude in the main loop (\textit{step \#3}). + +Both texts also do not discuss several key optimal algorithms required such as ``Comba'' and Karatsuba multipliers +and fast modular inversion, which we consider practical oversights. These optimal algorithms are vital to achieve +any form of useful performance in non-trivial applications. + +To solve this problem the focus of this text is on the practical aspects of implementing a multiple precision integer +package. As a case study the ``LibTomMath''\footnote{Available at \url{http://math.libtomcrypt.com}} package is used +to demonstrate algorithms with real implementations\footnote{In the ISO C programming language.} that have been field +tested and work very well. The LibTomMath library is freely available on the Internet for all uses and this text +discusses a very large portion of the inner workings of the library. + +The algorithms that are presented will always include at least one ``pseudo-code'' description followed +by the actual C source code that implements the algorithm. The pseudo-code can be used to implement the same +algorithm in other programming languages as the reader sees fit. + +This text shall also serve as a walkthrough of the creation of multiple precision algorithms from scratch. Showing +the reader how the algorithms fit together as well as where to start on various taskings. + +\section{Discussion and Notation} +\subsection{Notation} +A multiple precision integer of $n$-digits shall be denoted as $x = (x_{n-1}, \ldots, x_1, x_0)_{ \beta }$ and represent +the integer $x \equiv \sum_{i=0}^{n-1} x_i\beta^i$. The elements of the array $x$ are said to be the radix $\beta$ digits +of the integer. For example, $x = (1,2,3)_{10}$ would represent the integer +$1\cdot 10^2 + 2\cdot10^1 + 3\cdot10^0 = 123$. + +\index{mp\_int} +The term ``mp\_int'' shall refer to a composite structure which contains the digits of the integer it represents, as well +as auxilary data required to manipulate the data. These additional members are discussed further in section +\ref{sec:MPINT}. For the purposes of this text a ``multiple precision integer'' and an ``mp\_int'' are assumed to be +synonymous. When an algorithm is specified to accept an mp\_int variable it is assumed the various auxliary data members +are present as well. An expression of the type \textit{variablename.item} implies that it should evaluate to the +member named ``item'' of the variable. For example, a string of characters may have a member ``length'' which would +evaluate to the number of characters in the string. If the string $a$ equals ``hello'' then it follows that +$a.length = 5$. + +For certain discussions more generic algorithms are presented to help the reader understand the final algorithm used +to solve a given problem. When an algorithm is described as accepting an integer input it is assumed the input is +a plain integer with no additional multiple-precision members. That is, algorithms that use integers as opposed to +mp\_ints as inputs do not concern themselves with the housekeeping operations required such as memory management. These +algorithms will be used to establish the relevant theory which will subsequently be used to describe a multiple +precision algorithm to solve the same problem. + +\subsection{Precision Notation} +The variable $\beta$ represents the radix of a single digit of a multiple precision integer and +must be of the form $q^p$ for $q, p \in \Z^+$. A single precision variable must be able to represent integers in +the range $0 \le x < q \beta$ while a double precision variable must be able to represent integers in the range +$0 \le x < q \beta^2$. The extra radix-$q$ factor allows additions and subtractions to proceed without truncation of the +carry. Since all modern computers are binary, it is assumed that $q$ is two. + +\index{mp\_digit} \index{mp\_word} +Within the source code that will be presented for each algorithm, the data type \textbf{mp\_digit} will represent +a single precision integer type, while, the data type \textbf{mp\_word} will represent a double precision integer type. In +several algorithms (notably the Comba routines) temporary results will be stored in arrays of double precision mp\_words. +For the purposes of this text $x_j$ will refer to the $j$'th digit of a single precision array and $\hat x_j$ will refer to +the $j$'th digit of a double precision array. Whenever an expression is to be assigned to a double precision +variable it is assumed that all single precision variables are promoted to double precision during the evaluation. +Expressions that are assigned to a single precision variable are truncated to fit within the precision of a single +precision data type. + +For example, if $\beta = 10^2$ a single precision data type may represent a value in the +range $0 \le x < 10^3$, while a double precision data type may represent a value in the range $0 \le x < 10^5$. Let +$a = 23$ and $b = 49$ represent two single precision variables. The single precision product shall be written +as $c \leftarrow a \cdot b$ while the double precision product shall be written as $\hat c \leftarrow a \cdot b$. +In this particular case, $\hat c = 1127$ and $c = 127$. The most significant digit of the product would not fit +in a single precision data type and as a result $c \ne \hat c$. + +\subsection{Algorithm Inputs and Outputs} +Within the algorithm descriptions all variables are assumed to be scalars of either single or double precision +as indicated. The only exception to this rule is when variables have been indicated to be of type mp\_int. This +distinction is important as scalars are often used as array indicies and various other counters. + +\subsection{Mathematical Expressions} +The $\lfloor \mbox{ } \rfloor$ brackets imply an expression truncated to an integer not greater than the expression +itself. For example, $\lfloor 5.7 \rfloor = 5$. Similarly the $\lceil \mbox{ } \rceil$ brackets imply an expression +rounded to an integer not less than the expression itself. For example, $\lceil 5.1 \rceil = 6$. Typically when +the $/$ division symbol is used the intention is to perform an integer division with truncation. For example, +$5/2 = 2$ which will often be written as $\lfloor 5/2 \rfloor = 2$ for clarity. When an expression is written as a +fraction a real value division is implied, for example ${5 \over 2} = 2.5$. + +The norm of a multiple precision integer, for example $\vert \vert x \vert \vert$, will be used to represent the number of digits in the representation +of the integer. For example, $\vert \vert 123 \vert \vert = 3$ and $\vert \vert 79452 \vert \vert = 5$. + +\subsection{Work Effort} +\index{big-Oh} +To measure the efficiency of the specified algorithms, a modified big-Oh notation is used. In this system all +single precision operations are considered to have the same cost\footnote{Except where explicitly noted.}. +That is a single precision addition, multiplication and division are assumed to take the same time to +complete. While this is generally not true in practice, it will simplify the discussions considerably. + +Some algorithms have slight advantages over others which is why some constants will not be removed in +the notation. For example, a normal baseline multiplication (section \ref{sec:basemult}) requires $O(n^2)$ work while a +baseline squaring (section \ref{sec:basesquare}) requires $O({{n^2 + n}\over 2})$ work. In standard big-Oh notation these +would both be said to be equivalent to $O(n^2)$. However, +in the context of the this text this is not the case as the magnitude of the inputs will typically be rather small. As a +result small constant factors in the work effort will make an observable difference in algorithm efficiency. + +All of the algorithms presented in this text have a polynomial time work level. That is, of the form +$O(n^k)$ for $n, k \in \Z^{+}$. This will help make useful comparisons in terms of the speed of the algorithms and how +various optimizations will help pay off in the long run. + +\section{Exercises} +Within the more advanced chapters a section will be set aside to give the reader some challenging exercises related to +the discussion at hand. These exercises are not designed to be prize winning problems, but instead to be thought +provoking. Wherever possible the problems are forward minded, stating problems that will be answered in subsequent +chapters. The reader is encouraged to finish the exercises as they appear to get a better understanding of the +subject material. + +That being said, the problems are designed to affirm knowledge of a particular subject matter. Students in particular +are encouraged to verify they can answer the problems correctly before moving on. + +Similar to the exercises of \cite[pp. ix]{TAOCPV2} these exercises are given a scoring system based on the difficulty of +the problem. However, unlike \cite{TAOCPV2} the problems do not get nearly as hard. The scoring of these +exercises ranges from one (the easiest) to five (the hardest). The following table sumarizes the +scoring system used. + +\begin{figure}[here] +\begin{center} +\begin{small} +\begin{tabular}{|c|l|} +\hline $\left [ 1 \right ]$ & An easy problem that should only take the reader a manner of \\ + & minutes to solve. Usually does not involve much computer time \\ + & to solve. \\ +\hline $\left [ 2 \right ]$ & An easy problem that involves a marginal amount of computer \\ + & time usage. Usually requires a program to be written to \\ + & solve the problem. \\ +\hline $\left [ 3 \right ]$ & A moderately hard problem that requires a non-trivial amount \\ + & of work. Usually involves trivial research and development of \\ + & new theory from the perspective of a student. \\ +\hline $\left [ 4 \right ]$ & A moderately hard problem that involves a non-trivial amount \\ + & of work and research, the solution to which will demonstrate \\ + & a higher mastery of the subject matter. \\ +\hline $\left [ 5 \right ]$ & A hard problem that involves concepts that are difficult for a \\ + & novice to solve. Solutions to these problems will demonstrate a \\ + & complete mastery of the given subject. \\ +\hline +\end{tabular} +\end{small} +\end{center} +\caption{Exercise Scoring System} +\end{figure} + +Problems at the first level are meant to be simple questions that the reader can answer quickly without programming a solution or +devising new theory. These problems are quick tests to see if the material is understood. Problems at the second level +are also designed to be easy but will require a program or algorithm to be implemented to arrive at the answer. These +two levels are essentially entry level questions. + +Problems at the third level are meant to be a bit more difficult than the first two levels. The answer is often +fairly obvious but arriving at an exacting solution requires some thought and skill. These problems will almost always +involve devising a new algorithm or implementing a variation of another algorithm previously presented. Readers who can +answer these questions will feel comfortable with the concepts behind the topic at hand. + +Problems at the fourth level are meant to be similar to those of the level three questions except they will require +additional research to be completed. The reader will most likely not know the answer right away, nor will the text provide +the exact details of the answer until a subsequent chapter. + +Problems at the fifth level are meant to be the hardest +problems relative to all the other problems in the chapter. People who can correctly answer fifth level problems have a +mastery of the subject matter at hand. + +Often problems will be tied together. The purpose of this is to start a chain of thought that will be discussed in future chapters. The reader +is encouraged to answer the follow-up problems and try to draw the relevance of problems. + +\section{Introduction to LibTomMath} + +\subsection{What is LibTomMath?} +LibTomMath is a free and open source multiple precision integer library written entirely in portable ISO C. By portable it +is meant that the library does not contain any code that is computer platform dependent or otherwise problematic to use on +any given platform. + +The library has been successfully tested under numerous operating systems including Unix\footnote{All of these +trademarks belong to their respective rightful owners.}, MacOS, Windows, Linux, PalmOS and on standalone hardware such +as the Gameboy Advance. The library is designed to contain enough functionality to be able to develop applications such +as public key cryptosystems and still maintain a relatively small footprint. + +\subsection{Goals of LibTomMath} + +Libraries which obtain the most efficiency are rarely written in a high level programming language such as C. However, +even though this library is written entirely in ISO C, considerable care has been taken to optimize the algorithm implementations within the +library. Specifically the code has been written to work well with the GNU C Compiler (\textit{GCC}) on both x86 and ARM +processors. Wherever possible, highly efficient algorithms, such as Karatsuba multiplication, sliding window +exponentiation and Montgomery reduction have been provided to make the library more efficient. + +Even with the nearly optimal and specialized algorithms that have been included the Application Programing Interface +(\textit{API}) has been kept as simple as possible. Often generic place holder routines will make use of specialized +algorithms automatically without the developer's specific attention. One such example is the generic multiplication +algorithm \textbf{mp\_mul()} which will automatically use Toom--Cook, Karatsuba, Comba or baseline multiplication +based on the magnitude of the inputs and the configuration of the library. + +Making LibTomMath as efficient as possible is not the only goal of the LibTomMath project. Ideally the library should +be source compatible with another popular library which makes it more attractive for developers to use. In this case the +MPI library was used as a API template for all the basic functions. MPI was chosen because it is another library that fits +in the same niche as LibTomMath. Even though LibTomMath uses MPI as the template for the function names and argument +passing conventions, it has been written from scratch by Tom St Denis. + +The project is also meant to act as a learning tool for students, the logic being that no easy-to-follow ``bignum'' +library exists which can be used to teach computer science students how to perform fast and reliable multiple precision +integer arithmetic. To this end the source code has been given quite a few comments and algorithm discussion points. + +\section{Choice of LibTomMath} +LibTomMath was chosen as the case study of this text not only because the author of both projects is one and the same but +for more worthy reasons. Other libraries such as GMP \cite{GMP}, MPI \cite{MPI}, LIP \cite{LIP} and OpenSSL +\cite{OPENSSL} have multiple precision integer arithmetic routines but would not be ideal for this text for +reasons that will be explained in the following sub-sections. + +\subsection{Code Base} +The LibTomMath code base is all portable ISO C source code. This means that there are no platform dependent conditional +segments of code littered throughout the source. This clean and uncluttered approach to the library means that a +developer can more readily discern the true intent of a given section of source code without trying to keep track of +what conditional code will be used. + +The code base of LibTomMath is well organized. Each function is in its own separate source code file +which allows the reader to find a given function very quickly. On average there are $76$ lines of code per source +file which makes the source very easily to follow. By comparison MPI and LIP are single file projects making code tracing +very hard. GMP has many conditional code segments which also hinder tracing. + +When compiled with GCC for the x86 processor and optimized for speed the entire library is approximately $100$KiB\footnote{The notation ``KiB'' means $2^{10}$ octets, similarly ``MiB'' means $2^{20}$ octets.} + which is fairly small compared to GMP (over $250$KiB). LibTomMath is slightly larger than MPI (which compiles to about +$50$KiB) but LibTomMath is also much faster and more complete than MPI. + +\subsection{API Simplicity} +LibTomMath is designed after the MPI library and shares the API design. Quite often programs that use MPI will build +with LibTomMath without change. The function names correlate directly to the action they perform. Almost all of the +functions share the same parameter passing convention. The learning curve is fairly shallow with the API provided +which is an extremely valuable benefit for the student and developer alike. + +The LIP library is an example of a library with an API that is awkward to work with. LIP uses function names that are often ``compressed'' to +illegible short hand. LibTomMath does not share this characteristic. + +The GMP library also does not return error codes. Instead it uses a POSIX.1 \cite{POSIX1} signal system where errors +are signaled to the host application. This happens to be the fastest approach but definitely not the most versatile. In +effect a math error (i.e. invalid input, heap error, etc) can cause a program to stop functioning which is definitely +undersireable in many situations. + +\subsection{Optimizations} +While LibTomMath is certainly not the fastest library (GMP often beats LibTomMath by a factor of two) it does +feature a set of optimal algorithms for tasks such as modular reduction, exponentiation, multiplication and squaring. GMP +and LIP also feature such optimizations while MPI only uses baseline algorithms with no optimizations. GMP lacks a few +of the additional modular reduction optimizations that LibTomMath features\footnote{At the time of this writing GMP +only had Barrett and Montgomery modular reduction algorithms.}. + +LibTomMath is almost always an order of magnitude faster than the MPI library at computationally expensive tasks such as modular +exponentiation. In the grand scheme of ``bignum'' libraries LibTomMath is faster than the average library and usually +slower than the best libraries such as GMP and OpenSSL by only a small factor. + +\subsection{Portability and Stability} +LibTomMath will build ``out of the box'' on any platform equipped with a modern version of the GNU C Compiler +(\textit{GCC}). This means that without changes the library will build without configuration or setting up any +variables. LIP and MPI will build ``out of the box'' as well but have numerous known bugs. Most notably the author of +MPI has recently stopped working on his library and LIP has long since been discontinued. + +GMP requires a configuration script to run and will not build out of the box. GMP and LibTomMath are still in active +development and are very stable across a variety of platforms. + +\subsection{Choice} +LibTomMath is a relatively compact, well documented, highly optimized and portable library which seems only natural for +the case study of this text. Various source files from the LibTomMath project will be included within the text. However, +the reader is encouraged to download their own copy of the library to actually be able to work with the library. + +\chapter{Getting Started} +\section{Library Basics} +The trick to writing any useful library of source code is to build a solid foundation and work outwards from it. First, +a problem along with allowable solution parameters should be identified and analyzed. In this particular case the +inability to accomodate multiple precision integers is the problem. Futhermore, the solution must be written +as portable source code that is reasonably efficient across several different computer platforms. + +After a foundation is formed the remainder of the library can be designed and implemented in a hierarchical fashion. +That is, to implement the lowest level dependencies first and work towards the most abstract functions last. For example, +before implementing a modular exponentiation algorithm one would implement a modular reduction algorithm. +By building outwards from a base foundation instead of using a parallel design methodology the resulting project is +highly modular. Being highly modular is a desirable property of any project as it often means the resulting product +has a small footprint and updates are easy to perform. + +Usually when I start a project I will begin with the header files. I define the data types I think I will need and +prototype the initial functions that are not dependent on other functions (within the library). After I +implement these base functions I prototype more dependent functions and implement them. The process repeats until +I implement all of the functions I require. For example, in the case of LibTomMath I implemented functions such as +mp\_init() well before I implemented mp\_mul() and even further before I implemented mp\_exptmod(). As an example as to +why this design works note that the Karatsuba and Toom-Cook multipliers were written \textit{after} the +dependent function mp\_exptmod() was written. Adding the new multiplication algorithms did not require changes to the +mp\_exptmod() function itself and lowered the total cost of ownership (\textit{so to speak}) and of development +for new algorithms. This methodology allows new algorithms to be tested in a complete framework with relative ease. + +\begin{center} +\begin{figure}[here] +\includegraphics{pics/design_process.ps} +\caption{Design Flow of the First Few Original LibTomMath Functions.} +\label{pic:design_process} +\end{figure} +\end{center} + +Only after the majority of the functions were in place did I pursue a less hierarchical approach to auditing and optimizing +the source code. For example, one day I may audit the multipliers and the next day the polynomial basis functions. + +It only makes sense to begin the text with the preliminary data types and support algorithms required as well. +This chapter discusses the core algorithms of the library which are the dependents for every other algorithm. + +\section{What is a Multiple Precision Integer?} +Recall that most programming languages, in particular ISO C \cite{ISOC}, only have fixed precision data types that on their own cannot +be used to represent values larger than their precision will allow. The purpose of multiple precision algorithms is +to use fixed precision data types to create and manipulate multiple precision integers which may represent values +that are very large. + +As a well known analogy, school children are taught how to form numbers larger than nine by prepending more radix ten digits. In the decimal system +the largest single digit value is $9$. However, by concatenating digits together larger numbers may be represented. Newly prepended digits +(\textit{to the left}) are said to be in a different power of ten column. That is, the number $123$ can be described as having a $1$ in the hundreds +column, $2$ in the tens column and $3$ in the ones column. Or more formally $123 = 1 \cdot 10^2 + 2 \cdot 10^1 + 3 \cdot 10^0$. Computer based +multiple precision arithmetic is essentially the same concept. Larger integers are represented by adjoining fixed +precision computer words with the exception that a different radix is used. + +What most people probably do not think about explicitly are the various other attributes that describe a multiple precision +integer. For example, the integer $154_{10}$ has two immediately obvious properties. First, the integer is positive, +that is the sign of this particular integer is positive as opposed to negative. Second, the integer has three digits in +its representation. There is an additional property that the integer posesses that does not concern pencil-and-paper +arithmetic. The third property is how many digits placeholders are available to hold the integer. + +The human analogy of this third property is ensuring there is enough space on the paper to write the integer. For example, +if one starts writing a large number too far to the right on a piece of paper they will have to erase it and move left. +Similarly, computer algorithms must maintain strict control over memory usage to ensure that the digits of an integer +will not exceed the allowed boundaries. These three properties make up what is known as a multiple precision +integer or mp\_int for short. + +\subsection{The mp\_int Structure} +\label{sec:MPINT} +The mp\_int structure is the ISO C based manifestation of what represents a multiple precision integer. The ISO C standard does not provide for +any such data type but it does provide for making composite data types known as structures. The following is the structure definition +used within LibTomMath. + +\index{mp\_int} +\begin{figure}[here] +\begin{center} +\begin{small} +%\begin{verbatim} +\begin{tabular}{|l|} +\hline +typedef struct \{ \\ +\hspace{3mm}int used, alloc, sign;\\ +\hspace{3mm}mp\_digit *dp;\\ +\} \textbf{mp\_int}; \\ +\hline +\end{tabular} +%\end{verbatim} +\end{small} +\caption{The mp\_int Structure} +\label{fig:mpint} +\end{center} +\end{figure} + +The mp\_int structure (fig. \ref{fig:mpint}) can be broken down as follows. + +\begin{enumerate} +\item The \textbf{used} parameter denotes how many digits of the array \textbf{dp} contain the digits used to represent +a given integer. The \textbf{used} count must be positive (or zero) and may not exceed the \textbf{alloc} count. + +\item The \textbf{alloc} parameter denotes how +many digits are available in the array to use by functions before it has to increase in size. When the \textbf{used} count +of a result would exceed the \textbf{alloc} count all of the algorithms will automatically increase the size of the +array to accommodate the precision of the result. + +\item The pointer \textbf{dp} points to a dynamically allocated array of digits that represent the given multiple +precision integer. It is padded with $(\textbf{alloc} - \textbf{used})$ zero digits. The array is maintained in a least +significant digit order. As a pencil and paper analogy the array is organized such that the right most digits are stored +first starting at the location indexed by zero\footnote{In C all arrays begin at zero.} in the array. For example, +if \textbf{dp} contains $\lbrace a, b, c, \ldots \rbrace$ where \textbf{dp}$_0 = a$, \textbf{dp}$_1 = b$, \textbf{dp}$_2 = c$, $\ldots$ then +it would represent the integer $a + b\beta + c\beta^2 + \ldots$ + +\index{MP\_ZPOS} \index{MP\_NEG} +\item The \textbf{sign} parameter denotes the sign as either zero/positive (\textbf{MP\_ZPOS}) or negative (\textbf{MP\_NEG}). +\end{enumerate} + +\subsubsection{Valid mp\_int Structures} +Several rules are placed on the state of an mp\_int structure and are assumed to be followed for reasons of efficiency. +The only exceptions are when the structure is passed to initialization functions such as mp\_init() and mp\_init\_copy(). + +\begin{enumerate} +\item The value of \textbf{alloc} may not be less than one. That is \textbf{dp} always points to a previously allocated +array of digits. +\item The value of \textbf{used} may not exceed \textbf{alloc} and must be greater than or equal to zero. +\item The value of \textbf{used} implies the digit at index $(used - 1)$ of the \textbf{dp} array is non-zero. That is, +leading zero digits in the most significant positions must be trimmed. + \begin{enumerate} + \item Digits in the \textbf{dp} array at and above the \textbf{used} location must be zero. + \end{enumerate} +\item The value of \textbf{sign} must be \textbf{MP\_ZPOS} if \textbf{used} is zero; +this represents the mp\_int value of zero. +\end{enumerate} + +\section{Argument Passing} +A convention of argument passing must be adopted early on in the development of any library. Making the function +prototypes consistent will help eliminate many headaches in the future as the library grows to significant complexity. +In LibTomMath the multiple precision integer functions accept parameters from left to right as pointers to mp\_int +structures. That means that the source (input) operands are placed on the left and the destination (output) on the right. +Consider the following examples. + +\begin{verbatim} + mp_mul(&a, &b, &c); /* c = a * b */ + mp_add(&a, &b, &a); /* a = a + b */ + mp_sqr(&a, &b); /* b = a * a */ +\end{verbatim} + +The left to right order is a fairly natural way to implement the functions since it lets the developer read aloud the +functions and make sense of them. For example, the first function would read ``multiply a and b and store in c''. + +Certain libraries (\textit{LIP by Lenstra for instance}) accept parameters the other way around, to mimic the order +of assignment expressions. That is, the destination (output) is on the left and arguments (inputs) are on the right. In +truth, it is entirely a matter of preference. In the case of LibTomMath the convention from the MPI library has been +adopted. + +Another very useful design consideration, provided for in LibTomMath, is whether to allow argument sources to also be a +destination. For example, the second example (\textit{mp\_add}) adds $a$ to $b$ and stores in $a$. This is an important +feature to implement since it allows the calling functions to cut down on the number of variables it must maintain. +However, to implement this feature specific care has to be given to ensure the destination is not modified before the +source is fully read. + +\section{Return Values} +A well implemented application, no matter what its purpose, should trap as many runtime errors as possible and return them +to the caller. By catching runtime errors a library can be guaranteed to prevent undefined behaviour. However, the end +developer can still manage to cause a library to crash. For example, by passing an invalid pointer an application may +fault by dereferencing memory not owned by the application. + +In the case of LibTomMath the only errors that are checked for are related to inappropriate inputs (division by zero for +instance) and memory allocation errors. It will not check that the mp\_int passed to any function is valid nor +will it check pointers for validity. Any function that can cause a runtime error will return an error code as an +\textbf{int} data type with one of the following values (fig \ref{fig:errcodes}). + +\index{MP\_OKAY} \index{MP\_VAL} \index{MP\_MEM} +\begin{figure}[here] +\begin{center} +\begin{tabular}{|l|l|} +\hline \textbf{Value} & \textbf{Meaning} \\ +\hline \textbf{MP\_OKAY} & The function was successful \\ +\hline \textbf{MP\_VAL} & One of the input value(s) was invalid \\ +\hline \textbf{MP\_MEM} & The function ran out of heap memory \\ +\hline +\end{tabular} +\end{center} +\caption{LibTomMath Error Codes} +\label{fig:errcodes} +\end{figure} + +When an error is detected within a function it should free any memory it allocated, often during the initialization of +temporary mp\_ints, and return as soon as possible. The goal is to leave the system in the same state it was when the +function was called. Error checking with this style of API is fairly simple. + +\begin{verbatim} + int err; + if ((err = mp_add(&a, &b, &c)) != MP_OKAY) { + printf("Error: %s\n", mp_error_to_string(err)); + exit(EXIT_FAILURE); + } +\end{verbatim} + +The GMP \cite{GMP} library uses C style \textit{signals} to flag errors which is of questionable use. Not all errors are fatal +and it was not deemed ideal by the author of LibTomMath to force developers to have signal handlers for such cases. + +\section{Initialization and Clearing} +The logical starting point when actually writing multiple precision integer functions is the initialization and +clearing of the mp\_int structures. These two algorithms will be used by the majority of the higher level algorithms. + +Given the basic mp\_int structure an initialization routine must first allocate memory to hold the digits of +the integer. Often it is optimal to allocate a sufficiently large pre-set number of digits even though +the initial integer will represent zero. If only a single digit were allocated quite a few subsequent re-allocations +would occur when operations are performed on the integers. There is a tradeoff between how many default digits to allocate +and how many re-allocations are tolerable. Obviously allocating an excessive amount of digits initially will waste +memory and become unmanageable. + +If the memory for the digits has been successfully allocated then the rest of the members of the structure must +be initialized. Since the initial state of an mp\_int is to represent the zero integer, the allocated digits must be set +to zero. The \textbf{used} count set to zero and \textbf{sign} set to \textbf{MP\_ZPOS}. + +\subsection{Initializing an mp\_int} +An mp\_int is said to be initialized if it is set to a valid, preferably default, state such that all of the members of the +structure are set to valid values. The mp\_init algorithm will perform such an action. + +\index{mp\_init} +\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_init}. \\ +\textbf{Input}. An mp\_int $a$ \\ +\textbf{Output}. Allocate memory and initialize $a$ to a known valid mp\_int state. \\ +\hline \\ +1. Allocate memory for \textbf{MP\_PREC} digits. \\ +2. If the allocation failed return(\textit{MP\_MEM}) \\ +3. for $n$ from $0$ to $MP\_PREC - 1$ do \\ +\hspace{3mm}3.1 $a_n \leftarrow 0$\\ +4. $a.sign \leftarrow MP\_ZPOS$\\ +5. $a.used \leftarrow 0$\\ +6. $a.alloc \leftarrow MP\_PREC$\\ +7. Return(\textit{MP\_OKAY})\\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_init} +\end{figure} + +\textbf{Algorithm mp\_init.} +The purpose of this function is to initialize an mp\_int structure so that the rest of the library can properly +manipulte it. It is assumed that the input may not have had any of its members previously initialized which is certainly +a valid assumption if the input resides on the stack. + +Before any of the members such as \textbf{sign}, \textbf{used} or \textbf{alloc} are initialized the memory for +the digits is allocated. If this fails the function returns before setting any of the other members. The \textbf{MP\_PREC} +name represents a constant\footnote{Defined in the ``tommath.h'' header file within LibTomMath.} +used to dictate the minimum precision of newly initialized mp\_int integers. Ideally, it is at least equal to the smallest +precision number you'll be working with. + +Allocating a block of digits at first instead of a single digit has the benefit of lowering the number of usually slow +heap operations later functions will have to perform in the future. If \textbf{MP\_PREC} is set correctly the slack +memory and the number of heap operations will be trivial. + +Once the allocation has been made the digits have to be set to zero as well as the \textbf{used}, \textbf{sign} and +\textbf{alloc} members initialized. This ensures that the mp\_int will always represent the default state of zero regardless +of the original condition of the input. + +\textbf{Remark.} +This function introduces the idiosyncrasy that all iterative loops, commonly initiated with the ``for'' keyword, iterate incrementally +when the ``to'' keyword is placed between two expressions. For example, ``for $a$ from $b$ to $c$ do'' means that +a subsequent expression (or body of expressions) are to be evaluated upto $c - b$ times so long as $b \le c$. In each +iteration the variable $a$ is substituted for a new integer that lies inclusively between $b$ and $c$. If $b > c$ occured +the loop would not iterate. By contrast if the ``downto'' keyword were used in place of ``to'' the loop would iterate +decrementally. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_init.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +One immediate observation of this initializtion function is that it does not return a pointer to a mp\_int structure. It +is assumed that the caller has already allocated memory for the mp\_int structure, typically on the application stack. The +call to mp\_init() is used only to initialize the members of the structure to a known default state. + +Here we see (line 24) the memory allocation is performed first. This allows us to exit cleanly and quickly +if there is an error. If the allocation fails the routine will return \textbf{MP\_MEM} to the caller to indicate there +was a memory error. The function XMALLOC is what actually allocates the memory. Technically XMALLOC is not a function +but a macro defined in ``tommath.h``. By default, XMALLOC will evaluate to malloc() which is the C library's built--in +memory allocation routine. + +In order to assure the mp\_int is in a known state the digits must be set to zero. On most platforms this could have been +accomplished by using calloc() instead of malloc(). However, to correctly initialize a integer type to a given value in a +portable fashion you have to actually assign the value. The for loop (line 30) performs this required +operation. + +After the memory has been successfully initialized the remainder of the members are initialized +(lines 34 through 35) to their respective default states. At this point the algorithm has succeeded and +a success code is returned to the calling function. If this function returns \textbf{MP\_OKAY} it is safe to assume the +mp\_int structure has been properly initialized and is safe to use with other functions within the library. + +\subsection{Clearing an mp\_int} +When an mp\_int is no longer required by the application, the memory that has been allocated for its digits must be +returned to the application's memory pool with the mp\_clear algorithm. + +\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_clear}. \\ +\textbf{Input}. An mp\_int $a$ \\ +\textbf{Output}. The memory for $a$ shall be deallocated. \\ +\hline \\ +1. If $a$ has been previously freed then return(\textit{MP\_OKAY}). \\ +2. for $n$ from 0 to $a.used - 1$ do \\ +\hspace{3mm}2.1 $a_n \leftarrow 0$ \\ +3. Free the memory allocated for the digits of $a$. \\ +4. $a.used \leftarrow 0$ \\ +5. $a.alloc \leftarrow 0$ \\ +6. $a.sign \leftarrow MP\_ZPOS$ \\ +7. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_clear} +\end{figure} + +\textbf{Algorithm mp\_clear.} +This algorithm accomplishes two goals. First, it clears the digits and the other mp\_int members. This ensures that +if a developer accidentally re-uses a cleared structure it is less likely to cause problems. The second goal +is to free the allocated memory. + +The logic behind the algorithm is extended by marking cleared mp\_int structures so that subsequent calls to this +algorithm will not try to free the memory multiple times. Cleared mp\_ints are detectable by having a pre-defined invalid +digit pointer \textbf{dp} setting. + +Once an mp\_int has been cleared the mp\_int structure is no longer in a valid state for any other algorithm +with the exception of algorithms mp\_init, mp\_init\_copy, mp\_init\_size and mp\_clear. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_clear.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +The algorithm only operates on the mp\_int if it hasn't been previously cleared. The if statement (line 25) +checks to see if the \textbf{dp} member is not \textbf{NULL}. If the mp\_int is a valid mp\_int then \textbf{dp} cannot be +\textbf{NULL} in which case the if statement will evaluate to true. + +The digits of the mp\_int are cleared by the for loop (line 27) which assigns a zero to every digit. Similar to mp\_init() +the digits are assigned zero instead of using block memory operations (such as memset()) since this is more portable. + +The digits are deallocated off the heap via the XFREE macro. Similar to XMALLOC the XFREE macro actually evaluates to +a standard C library function. In this case the free() function. Since free() only deallocates the memory the pointer +still has to be reset to \textbf{NULL} manually (line 35). + +Now that the digits have been cleared and deallocated the other members are set to their final values (lines 36 and 37). + +\section{Maintenance Algorithms} + +The previous sections describes how to initialize and clear an mp\_int structure. To further support operations +that are to be performed on mp\_int structures (such as addition and multiplication) the dependent algorithms must be +able to augment the precision of an mp\_int and +initialize mp\_ints with differing initial conditions. + +These algorithms complete the set of low level algorithms required to work with mp\_int structures in the higher level +algorithms such as addition, multiplication and modular exponentiation. + +\subsection{Augmenting an mp\_int's Precision} +When storing a value in an mp\_int structure, a sufficient number of digits must be available to accomodate the entire +result of an operation without loss of precision. Quite often the size of the array given by the \textbf{alloc} member +is large enough to simply increase the \textbf{used} digit count. However, when the size of the array is too small it +must be re-sized appropriately to accomodate the result. The mp\_grow algorithm will provide this functionality. + +\newpage\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_grow}. \\ +\textbf{Input}. An mp\_int $a$ and an integer $b$. \\ +\textbf{Output}. $a$ is expanded to accomodate $b$ digits. \\ +\hline \\ +1. if $a.alloc \ge b$ then return(\textit{MP\_OKAY}) \\ +2. $u \leftarrow b\mbox{ (mod }MP\_PREC\mbox{)}$ \\ +3. $v \leftarrow b + 2 \cdot MP\_PREC - u$ \\ +4. Re-allocate the array of digits $a$ to size $v$ \\ +5. If the allocation failed then return(\textit{MP\_MEM}). \\ +6. for n from a.alloc to $v - 1$ do \\ +\hspace{+3mm}6.1 $a_n \leftarrow 0$ \\ +7. $a.alloc \leftarrow v$ \\ +8. Return(\textit{MP\_OKAY}) \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_grow} +\end{figure} + +\textbf{Algorithm mp\_grow.} +It is ideal to prevent re-allocations from being performed if they are not required (step one). This is useful to +prevent mp\_ints from growing excessively in code that erroneously calls mp\_grow. + +The requested digit count is padded up to next multiple of \textbf{MP\_PREC} plus an additional \textbf{MP\_PREC} (steps two and three). +This helps prevent many trivial reallocations that would grow an mp\_int by trivially small values. + +It is assumed that the reallocation (step four) leaves the lower $a.alloc$ digits of the mp\_int intact. This is much +akin to how the \textit{realloc} function from the standard C library works. Since the newly allocated digits are +assumed to contain undefined values they are initially set to zero. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_grow.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +A quick optimization is to first determine if a memory re-allocation is required at all. The if statement (line 24) checks +if the \textbf{alloc} member of the mp\_int is smaller than the requested digit count. If the count is not larger than \textbf{alloc} +the function skips the re-allocation part thus saving time. + +When a re-allocation is performed it is turned into an optimal request to save time in the future. The requested digit count is +padded upwards to 2nd multiple of \textbf{MP\_PREC} larger than \textbf{alloc} (line 25). The XREALLOC function is used +to re-allocate the memory. As per the other functions XREALLOC is actually a macro which evaluates to realloc by default. The realloc +function leaves the base of the allocation intact which means the first \textbf{alloc} digits of the mp\_int are the same as before +the re-allocation. All that is left is to clear the newly allocated digits and return. + +Note that the re-allocation result is actually stored in a temporary pointer $tmp$. This is to allow this function to return +an error with a valid pointer. Earlier releases of the library stored the result of XREALLOC into the mp\_int $a$. That would +result in a memory leak if XREALLOC ever failed. + +\subsection{Initializing Variable Precision mp\_ints} +Occasionally the number of digits required will be known in advance of an initialization, based on, for example, the size +of input mp\_ints to a given algorithm. The purpose of algorithm mp\_init\_size is similar to mp\_init except that it +will allocate \textit{at least} a specified number of digits. + +\begin{figure}[here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_init\_size}. \\ +\textbf{Input}. An mp\_int $a$ and the requested number of digits $b$. \\ +\textbf{Output}. $a$ is initialized to hold at least $b$ digits. \\ +\hline \\ +1. $u \leftarrow b \mbox{ (mod }MP\_PREC\mbox{)}$ \\ +2. $v \leftarrow b + 2 \cdot MP\_PREC - u$ \\ +3. Allocate $v$ digits. \\ +4. for $n$ from $0$ to $v - 1$ do \\ +\hspace{3mm}4.1 $a_n \leftarrow 0$ \\ +5. $a.sign \leftarrow MP\_ZPOS$\\ +6. $a.used \leftarrow 0$\\ +7. $a.alloc \leftarrow v$\\ +8. Return(\textit{MP\_OKAY})\\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_init\_size} +\end{figure} + +\textbf{Algorithm mp\_init\_size.} +This algorithm will initialize an mp\_int structure $a$ like algorithm mp\_init with the exception that the number of +digits allocated can be controlled by the second input argument $b$. The input size is padded upwards so it is a +multiple of \textbf{MP\_PREC} plus an additional \textbf{MP\_PREC} digits. This padding is used to prevent trivial +allocations from becoming a bottleneck in the rest of the algorithms. + +Like algorithm mp\_init, the mp\_int structure is initialized to a default state representing the integer zero. This +particular algorithm is useful if it is known ahead of time the approximate size of the input. If the approximation is +correct no further memory re-allocations are required to work with the mp\_int. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_init\_size.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +The number of digits $b$ requested is padded (line 24) by first augmenting it to the next multiple of +\textbf{MP\_PREC} and then adding \textbf{MP\_PREC} to the result. If the memory can be successfully allocated the +mp\_int is placed in a default state representing the integer zero. Otherwise, the error code \textbf{MP\_MEM} will be +returned (line 29). + +The digits are allocated and set to zero at the same time with the calloc() function (line @25,XCALLOC@). The +\textbf{used} count is set to zero, the \textbf{alloc} count set to the padded digit count and the \textbf{sign} flag set +to \textbf{MP\_ZPOS} to achieve a default valid mp\_int state (lines 33, 34 and 35). If the function +returns succesfully then it is correct to assume that the mp\_int structure is in a valid state for the remainder of the +functions to work with. + +\subsection{Multiple Integer Initializations and Clearings} +Occasionally a function will require a series of mp\_int data types to be made available simultaneously. +The purpose of algorithm mp\_init\_multi is to initialize a variable length array of mp\_int structures in a single +statement. It is essentially a shortcut to multiple initializations. + +\newpage\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_init\_multi}. \\ +\textbf{Input}. Variable length array $V_k$ of mp\_int variables of length $k$. \\ +\textbf{Output}. The array is initialized such that each mp\_int of $V_k$ is ready to use. \\ +\hline \\ +1. for $n$ from 0 to $k - 1$ do \\ +\hspace{+3mm}1.1. Initialize the mp\_int $V_n$ (\textit{mp\_init}) \\ +\hspace{+3mm}1.2. If initialization failed then do \\ +\hspace{+6mm}1.2.1. for $j$ from $0$ to $n$ do \\ +\hspace{+9mm}1.2.1.1. Free the mp\_int $V_j$ (\textit{mp\_clear}) \\ +\hspace{+6mm}1.2.2. Return(\textit{MP\_MEM}) \\ +2. Return(\textit{MP\_OKAY}) \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_init\_multi} +\end{figure} + +\textbf{Algorithm mp\_init\_multi.} +The algorithm will initialize the array of mp\_int variables one at a time. If a runtime error has been detected +(\textit{step 1.2}) all of the previously initialized variables are cleared. The goal is an ``all or nothing'' +initialization which allows for quick recovery from runtime errors. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_init\_multi.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +This function intializes a variable length list of mp\_int structure pointers. However, instead of having the mp\_int +structures in an actual C array they are simply passed as arguments to the function. This function makes use of the +``...'' argument syntax of the C programming language. The list is terminated with a final \textbf{NULL} argument +appended on the right. + +The function uses the ``stdarg.h'' \textit{va} functions to step portably through the arguments to the function. A count +$n$ of succesfully initialized mp\_int structures is maintained (line 48) such that if a failure does occur, +the algorithm can backtrack and free the previously initialized structures (lines 28 to 47). + + +\subsection{Clamping Excess Digits} +When a function anticipates a result will be $n$ digits it is simpler to assume this is true within the body of +the function instead of checking during the computation. For example, a multiplication of a $i$ digit number by a +$j$ digit produces a result of at most $i + j$ digits. It is entirely possible that the result is $i + j - 1$ +though, with no final carry into the last position. However, suppose the destination had to be first expanded +(\textit{via mp\_grow}) to accomodate $i + j - 1$ digits than further expanded to accomodate the final carry. +That would be a considerable waste of time since heap operations are relatively slow. + +The ideal solution is to always assume the result is $i + j$ and fix up the \textbf{used} count after the function +terminates. This way a single heap operation (\textit{at most}) is required. However, if the result was not checked +there would be an excess high order zero digit. + +For example, suppose the product of two integers was $x_n = (0x_{n-1}x_{n-2}...x_0)_{\beta}$. The leading zero digit +will not contribute to the precision of the result. In fact, through subsequent operations more leading zero digits would +accumulate to the point the size of the integer would be prohibitive. As a result even though the precision is very +low the representation is excessively large. + +The mp\_clamp algorithm is designed to solve this very problem. It will trim high-order zeros by decrementing the +\textbf{used} count until a non-zero most significant digit is found. Also in this system, zero is considered to be a +positive number which means that if the \textbf{used} count is decremented to zero, the sign must be set to +\textbf{MP\_ZPOS}. + +\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_clamp}. \\ +\textbf{Input}. An mp\_int $a$ \\ +\textbf{Output}. Any excess leading zero digits of $a$ are removed \\ +\hline \\ +1. while $a.used > 0$ and $a_{a.used - 1} = 0$ do \\ +\hspace{+3mm}1.1 $a.used \leftarrow a.used - 1$ \\ +2. if $a.used = 0$ then do \\ +\hspace{+3mm}2.1 $a.sign \leftarrow MP\_ZPOS$ \\ +\hline \\ +\end{tabular} +\end{center} +\caption{Algorithm mp\_clamp} +\end{figure} + +\textbf{Algorithm mp\_clamp.} +As can be expected this algorithm is very simple. The loop on step one is expected to iterate only once or twice at +the most. For example, this will happen in cases where there is not a carry to fill the last position. Step two fixes the sign for +when all of the digits are zero to ensure that the mp\_int is valid at all times. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_clamp.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +Note on line 28 how to test for the \textbf{used} count is made on the left of the \&\& operator. In the C programming +language the terms to \&\& are evaluated left to right with a boolean short-circuit if any condition fails. This is +important since if the \textbf{used} is zero the test on the right would fetch below the array. That is obviously +undesirable. The parenthesis on line 31 is used to make sure the \textbf{used} count is decremented and not +the pointer ``a''. + +\section*{Exercises} +\begin{tabular}{cl} +$\left [ 1 \right ]$ & Discuss the relevance of the \textbf{used} member of the mp\_int structure. \\ + & \\ +$\left [ 1 \right ]$ & Discuss the consequences of not using padding when performing allocations. \\ + & \\ +$\left [ 2 \right ]$ & Estimate an ideal value for \textbf{MP\_PREC} when performing 1024-bit RSA \\ + & encryption when $\beta = 2^{28}$. \\ + & \\ +$\left [ 1 \right ]$ & Discuss the relevance of the algorithm mp\_clamp. What does it prevent? \\ + & \\ +$\left [ 1 \right ]$ & Give an example of when the algorithm mp\_init\_copy might be useful. \\ + & \\ +\end{tabular} + + +%%% +% CHAPTER FOUR +%%% + +\chapter{Basic Operations} + +\section{Introduction} +In the previous chapter a series of low level algorithms were established that dealt with initializing and maintaining +mp\_int structures. This chapter will discuss another set of seemingly non-algebraic algorithms which will form the low +level basis of the entire library. While these algorithm are relatively trivial it is important to understand how they +work before proceeding since these algorithms will be used almost intrinsically in the following chapters. + +The algorithms in this chapter deal primarily with more ``programmer'' related tasks such as creating copies of +mp\_int structures, assigning small values to mp\_int structures and comparisons of the values mp\_int structures +represent. + +\section{Assigning Values to mp\_int Structures} +\subsection{Copying an mp\_int} +Assigning the value that a given mp\_int structure represents to another mp\_int structure shall be known as making +a copy for the purposes of this text. The copy of the mp\_int will be a separate entity that represents the same +value as the mp\_int it was copied from. The mp\_copy algorithm provides this functionality. + +\newpage\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_copy}. \\ +\textbf{Input}. An mp\_int $a$ and $b$. \\ +\textbf{Output}. Store a copy of $a$ in $b$. \\ +\hline \\ +1. If $b.alloc < a.used$ then grow $b$ to $a.used$ digits. (\textit{mp\_grow}) \\ +2. for $n$ from 0 to $a.used - 1$ do \\ +\hspace{3mm}2.1 $b_{n} \leftarrow a_{n}$ \\ +3. for $n$ from $a.used$ to $b.used - 1$ do \\ +\hspace{3mm}3.1 $b_{n} \leftarrow 0$ \\ +4. $b.used \leftarrow a.used$ \\ +5. $b.sign \leftarrow a.sign$ \\ +6. return(\textit{MP\_OKAY}) \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_copy} +\end{figure} + +\textbf{Algorithm mp\_copy.} +This algorithm copies the mp\_int $a$ such that upon succesful termination of the algorithm the mp\_int $b$ will +represent the same integer as the mp\_int $a$. The mp\_int $b$ shall be a complete and distinct copy of the +mp\_int $a$ meaing that the mp\_int $a$ can be modified and it shall not affect the value of the mp\_int $b$. + +If $b$ does not have enough room for the digits of $a$ it must first have its precision augmented via the mp\_grow +algorithm. The digits of $a$ are copied over the digits of $b$ and any excess digits of $b$ are set to zero (step two +and three). The \textbf{used} and \textbf{sign} members of $a$ are finally copied over the respective members of +$b$. + +\textbf{Remark.} This algorithm also introduces a new idiosyncrasy that will be used throughout the rest of the +text. The error return codes of other algorithms are not explicitly checked in the pseudo-code presented. For example, in +step one of the mp\_copy algorithm the return of mp\_grow is not explicitly checked to ensure it succeeded. Text space is +limited so it is assumed that if a algorithm fails it will clear all temporarily allocated mp\_ints and return +the error code itself. However, the C code presented will demonstrate all of the error handling logic required to +implement the pseudo-code. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_copy.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +Occasionally a dependent algorithm may copy an mp\_int effectively into itself such as when the input and output +mp\_int structures passed to a function are one and the same. For this case it is optimal to return immediately without +copying digits (line 25). + +The mp\_int $b$ must have enough digits to accomodate the used digits of the mp\_int $a$. If $b.alloc$ is less than +$a.used$ the algorithm mp\_grow is used to augment the precision of $b$ (lines 30 to 33). In order to +simplify the inner loop that copies the digits from $a$ to $b$, two aliases $tmpa$ and $tmpb$ point directly at the digits +of the mp\_ints $a$ and $b$ respectively. These aliases (lines 43 and 46) allow the compiler to access the digits without first dereferencing the +mp\_int pointers and then subsequently the pointer to the digits. + +After the aliases are established the digits from $a$ are copied into $b$ (lines 49 to 51) and then the excess +digits of $b$ are set to zero (lines 54 to 56). Both ``for'' loops make use of the pointer aliases and in +fact the alias for $b$ is carried through into the second ``for'' loop to clear the excess digits. This optimization +allows the alias to stay in a machine register fairly easy between the two loops. + +\textbf{Remarks.} The use of pointer aliases is an implementation methodology first introduced in this function that will +be used considerably in other functions. Technically, a pointer alias is simply a short hand alias used to lower the +number of pointer dereferencing operations required to access data. For example, a for loop may resemble + +\begin{alltt} +for (x = 0; x < 100; x++) \{ + a->num[4]->dp[x] = 0; +\} +\end{alltt} + +This could be re-written using aliases as + +\begin{alltt} +mp_digit *tmpa; +a = a->num[4]->dp; +for (x = 0; x < 100; x++) \{ + *a++ = 0; +\} +\end{alltt} + +In this case an alias is used to access the +array of digits within an mp\_int structure directly. It may seem that a pointer alias is strictly not required +as a compiler may optimize out the redundant pointer operations. However, there are two dominant reasons to use aliases. + +The first reason is that most compilers will not effectively optimize pointer arithmetic. For example, some optimizations +may work for the Microsoft Visual C++ compiler (MSVC) and not for the GNU C Compiler (GCC). Also some optimizations may +work for GCC and not MSVC. As such it is ideal to find a common ground for as many compilers as possible. Pointer +aliases optimize the code considerably before the compiler even reads the source code which means the end compiled code +stands a better chance of being faster. + +The second reason is that pointer aliases often can make an algorithm simpler to read. Consider the first ``for'' +loop of the function mp\_copy() re-written to not use pointer aliases. + +\begin{alltt} + /* copy all the digits */ + for (n = 0; n < a->used; n++) \{ + b->dp[n] = a->dp[n]; + \} +\end{alltt} + +Whether this code is harder to read depends strongly on the individual. However, it is quantifiably slightly more +complicated as there are four variables within the statement instead of just two. + +\subsubsection{Nested Statements} +Another commonly used technique in the source routines is that certain sections of code are nested. This is used in +particular with the pointer aliases to highlight code phases. For example, a Comba multiplier (discussed in chapter six) +will typically have three different phases. First the temporaries are initialized, then the columns calculated and +finally the carries are propagated. In this example the middle column production phase will typically be nested as it +uses temporary variables and aliases the most. + +The nesting also simplies the source code as variables that are nested are only valid for their scope. As a result +the various temporary variables required do not propagate into other sections of code. + + +\subsection{Creating a Clone} +Another common operation is to make a local temporary copy of an mp\_int argument. To initialize an mp\_int +and then copy another existing mp\_int into the newly intialized mp\_int will be known as creating a clone. This is +useful within functions that need to modify an argument but do not wish to actually modify the original copy. The +mp\_init\_copy algorithm has been designed to help perform this task. + +\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_init\_copy}. \\ +\textbf{Input}. An mp\_int $a$ and $b$\\ +\textbf{Output}. $a$ is initialized to be a copy of $b$. \\ +\hline \\ +1. Init $a$. (\textit{mp\_init}) \\ +2. Copy $b$ to $a$. (\textit{mp\_copy}) \\ +3. Return the status of the copy operation. \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_init\_copy} +\end{figure} + +\textbf{Algorithm mp\_init\_copy.} +This algorithm will initialize an mp\_int variable and copy another previously initialized mp\_int variable into it. As +such this algorithm will perform two operations in one step. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_init\_copy.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +This will initialize \textbf{a} and make it a verbatim copy of the contents of \textbf{b}. Note that +\textbf{a} will have its own memory allocated which means that \textbf{b} may be cleared after the call +and \textbf{a} will be left intact. + +\section{Zeroing an Integer} +Reseting an mp\_int to the default state is a common step in many algorithms. The mp\_zero algorithm will be the algorithm used to +perform this task. + +\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_zero}. \\ +\textbf{Input}. An mp\_int $a$ \\ +\textbf{Output}. Zero the contents of $a$ \\ +\hline \\ +1. $a.used \leftarrow 0$ \\ +2. $a.sign \leftarrow$ MP\_ZPOS \\ +3. for $n$ from 0 to $a.alloc - 1$ do \\ +\hspace{3mm}3.1 $a_n \leftarrow 0$ \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_zero} +\end{figure} + +\textbf{Algorithm mp\_zero.} +This algorithm simply resets a mp\_int to the default state. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_zero.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +After the function is completed, all of the digits are zeroed, the \textbf{used} count is zeroed and the +\textbf{sign} variable is set to \textbf{MP\_ZPOS}. + +\section{Sign Manipulation} +\subsection{Absolute Value} +With the mp\_int representation of an integer, calculating the absolute value is trivial. The mp\_abs algorithm will compute +the absolute value of an mp\_int. + +\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_abs}. \\ +\textbf{Input}. An mp\_int $a$ \\ +\textbf{Output}. Computes $b = \vert a \vert$ \\ +\hline \\ +1. Copy $a$ to $b$. (\textit{mp\_copy}) \\ +2. If the copy failed return(\textit{MP\_MEM}). \\ +3. $b.sign \leftarrow MP\_ZPOS$ \\ +4. Return(\textit{MP\_OKAY}) \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_abs} +\end{figure} + +\textbf{Algorithm mp\_abs.} +This algorithm computes the absolute of an mp\_int input. First it copies $a$ over $b$. This is an example of an +algorithm where the check in mp\_copy that determines if the source and destination are equal proves useful. This allows, +for instance, the developer to pass the same mp\_int as the source and destination to this function without addition +logic to handle it. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_abs.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +This fairly trivial algorithm first eliminates non--required duplications (line 28) and then sets the +\textbf{sign} flag to \textbf{MP\_ZPOS}. + +\subsection{Integer Negation} +With the mp\_int representation of an integer, calculating the negation is also trivial. The mp\_neg algorithm will compute +the negative of an mp\_int input. + +\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_neg}. \\ +\textbf{Input}. An mp\_int $a$ \\ +\textbf{Output}. Computes $b = -a$ \\ +\hline \\ +1. Copy $a$ to $b$. (\textit{mp\_copy}) \\ +2. If the copy failed return(\textit{MP\_MEM}). \\ +3. If $a.used = 0$ then return(\textit{MP\_OKAY}). \\ +4. If $a.sign = MP\_ZPOS$ then do \\ +\hspace{3mm}4.1 $b.sign = MP\_NEG$. \\ +5. else do \\ +\hspace{3mm}5.1 $b.sign = MP\_ZPOS$. \\ +6. Return(\textit{MP\_OKAY}) \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_neg} +\end{figure} + +\textbf{Algorithm mp\_neg.} +This algorithm computes the negation of an input. First it copies $a$ over $b$. If $a$ has no used digits then +the algorithm returns immediately. Otherwise it flips the sign flag and stores the result in $b$. Note that if +$a$ had no digits then it must be positive by definition. Had step three been omitted then the algorithm would return +zero as negative. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_neg.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +Like mp\_abs() this function avoids non--required duplications (line 22) and then sets the sign. We +have to make sure that only non--zero values get a \textbf{sign} of \textbf{MP\_NEG}. If the mp\_int is zero +than the \textbf{sign} is hard--coded to \textbf{MP\_ZPOS}. + +\section{Small Constants} +\subsection{Setting Small Constants} +Often a mp\_int must be set to a relatively small value such as $1$ or $2$. For these cases the mp\_set algorithm is useful. + +\newpage\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_set}. \\ +\textbf{Input}. An mp\_int $a$ and a digit $b$ \\ +\textbf{Output}. Make $a$ equivalent to $b$ \\ +\hline \\ +1. Zero $a$ (\textit{mp\_zero}). \\ +2. $a_0 \leftarrow b \mbox{ (mod }\beta\mbox{)}$ \\ +3. $a.used \leftarrow \left \lbrace \begin{array}{ll} + 1 & \mbox{if }a_0 > 0 \\ + 0 & \mbox{if }a_0 = 0 + \end{array} \right .$ \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_set} +\end{figure} + +\textbf{Algorithm mp\_set.} +This algorithm sets a mp\_int to a small single digit value. Step number 1 ensures that the integer is reset to the default state. The +single digit is set (\textit{modulo $\beta$}) and the \textbf{used} count is adjusted accordingly. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_set.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +First we zero (line 21) the mp\_int to make sure that the other members are initialized for a +small positive constant. mp\_zero() ensures that the \textbf{sign} is positive and the \textbf{used} count +is zero. Next we set the digit and reduce it modulo $\beta$ (line 22). After this step we have to +check if the resulting digit is zero or not. If it is not then we set the \textbf{used} count to one, otherwise +to zero. + +We can quickly reduce modulo $\beta$ since it is of the form $2^k$ and a quick binary AND operation with +$2^k - 1$ will perform the same operation. + +One important limitation of this function is that it will only set one digit. The size of a digit is not fixed, meaning source that uses +this function should take that into account. Only trivially small constants can be set using this function. + +\subsection{Setting Large Constants} +To overcome the limitations of the mp\_set algorithm the mp\_set\_int algorithm is ideal. It accepts a ``long'' +data type as input and will always treat it as a 32-bit integer. + +\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_set\_int}. \\ +\textbf{Input}. An mp\_int $a$ and a ``long'' integer $b$ \\ +\textbf{Output}. Make $a$ equivalent to $b$ \\ +\hline \\ +1. Zero $a$ (\textit{mp\_zero}) \\ +2. for $n$ from 0 to 7 do \\ +\hspace{3mm}2.1 $a \leftarrow a \cdot 16$ (\textit{mp\_mul2d}) \\ +\hspace{3mm}2.2 $u \leftarrow \lfloor b / 2^{4(7 - n)} \rfloor \mbox{ (mod }16\mbox{)}$\\ +\hspace{3mm}2.3 $a_0 \leftarrow a_0 + u$ \\ +\hspace{3mm}2.4 $a.used \leftarrow a.used + 1$ \\ +3. Clamp excess used digits (\textit{mp\_clamp}) \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_set\_int} +\end{figure} + +\textbf{Algorithm mp\_set\_int.} +The algorithm performs eight iterations of a simple loop where in each iteration four bits from the source are added to the +mp\_int. Step 2.1 will multiply the current result by sixteen making room for four more bits in the less significant positions. In step 2.2 the +next four bits from the source are extracted and are added to the mp\_int. The \textbf{used} digit count is +incremented to reflect the addition. The \textbf{used} digit counter is incremented since if any of the leading digits were zero the mp\_int would have +zero digits used and the newly added four bits would be ignored. + +Excess zero digits are trimmed in steps 2.1 and 3 by using higher level algorithms mp\_mul2d and mp\_clamp. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_set\_int.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +This function sets four bits of the number at a time to handle all practical \textbf{DIGIT\_BIT} sizes. The weird +addition on line 39 ensures that the newly added in bits are added to the number of digits. While it may not +seem obvious as to why the digit counter does not grow exceedingly large it is because of the shift on line 28 +as well as the call to mp\_clamp() on line 41. Both functions will clamp excess leading digits which keeps +the number of used digits low. + +\section{Comparisons} +\subsection{Unsigned Comparisions} +Comparing a multiple precision integer is performed with the exact same algorithm used to compare two decimal numbers. For example, +to compare $1,234$ to $1,264$ the digits are extracted by their positions. That is we compare $1 \cdot 10^3 + 2 \cdot 10^2 + 3 \cdot 10^1 + 4 \cdot 10^0$ +to $1 \cdot 10^3 + 2 \cdot 10^2 + 6 \cdot 10^1 + 4 \cdot 10^0$ by comparing single digits at a time starting with the highest magnitude +positions. If any leading digit of one integer is greater than a digit in the same position of another integer then obviously it must be greater. + +The first comparision routine that will be developed is the unsigned magnitude compare which will perform a comparison based on the digits of two +mp\_int variables alone. It will ignore the sign of the two inputs. Such a function is useful when an absolute comparison is required or if the +signs are known to agree in advance. + +To facilitate working with the results of the comparison functions three constants are required. + +\begin{figure}[here] +\begin{center} +\begin{tabular}{|r|l|} +\hline \textbf{Constant} & \textbf{Meaning} \\ +\hline \textbf{MP\_GT} & Greater Than \\ +\hline \textbf{MP\_EQ} & Equal To \\ +\hline \textbf{MP\_LT} & Less Than \\ +\hline +\end{tabular} +\end{center} +\caption{Comparison Return Codes} +\end{figure} + +\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_cmp\_mag}. \\ +\textbf{Input}. Two mp\_ints $a$ and $b$. \\ +\textbf{Output}. Unsigned comparison results ($a$ to the left of $b$). \\ +\hline \\ +1. If $a.used > b.used$ then return(\textit{MP\_GT}) \\ +2. If $a.used < b.used$ then return(\textit{MP\_LT}) \\ +3. for n from $a.used - 1$ to 0 do \\ +\hspace{+3mm}3.1 if $a_n > b_n$ then return(\textit{MP\_GT}) \\ +\hspace{+3mm}3.2 if $a_n < b_n$ then return(\textit{MP\_LT}) \\ +4. Return(\textit{MP\_EQ}) \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_cmp\_mag} +\end{figure} + +\textbf{Algorithm mp\_cmp\_mag.} +By saying ``$a$ to the left of $b$'' it is meant that the comparison is with respect to $a$, that is if $a$ is greater than $b$ it will return +\textbf{MP\_GT} and similar with respect to when $a = b$ and $a < b$. The first two steps compare the number of digits used in both $a$ and $b$. +Obviously if the digit counts differ there would be an imaginary zero digit in the smaller number where the leading digit of the larger number is. +If both have the same number of digits than the actual digits themselves must be compared starting at the leading digit. + +By step three both inputs must have the same number of digits so its safe to start from either $a.used - 1$ or $b.used - 1$ and count down to +the zero'th digit. If after all of the digits have been compared, no difference is found, the algorithm returns \textbf{MP\_EQ}. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_cmp\_mag.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +The two if statements (lines 25 and 29) compare the number of digits in the two inputs. These two are +performed before all of the digits are compared since it is a very cheap test to perform and can potentially save +considerable time. The implementation given is also not valid without those two statements. $b.alloc$ may be +smaller than $a.used$, meaning that undefined values will be read from $b$ past the end of the array of digits. + + + +\subsection{Signed Comparisons} +Comparing with sign considerations is also fairly critical in several routines (\textit{division for example}). Based on an unsigned magnitude +comparison a trivial signed comparison algorithm can be written. + +\begin{figure}[here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_cmp}. \\ +\textbf{Input}. Two mp\_ints $a$ and $b$ \\ +\textbf{Output}. Signed Comparison Results ($a$ to the left of $b$) \\ +\hline \\ +1. if $a.sign = MP\_NEG$ and $b.sign = MP\_ZPOS$ then return(\textit{MP\_LT}) \\ +2. if $a.sign = MP\_ZPOS$ and $b.sign = MP\_NEG$ then return(\textit{MP\_GT}) \\ +3. if $a.sign = MP\_NEG$ then \\ +\hspace{+3mm}3.1 Return the unsigned comparison of $b$ and $a$ (\textit{mp\_cmp\_mag}) \\ +4 Otherwise \\ +\hspace{+3mm}4.1 Return the unsigned comparison of $a$ and $b$ \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_cmp} +\end{figure} + +\textbf{Algorithm mp\_cmp.} +The first two steps compare the signs of the two inputs. If the signs do not agree then it can return right away with the appropriate +comparison code. When the signs are equal the digits of the inputs must be compared to determine the correct result. In step +three the unsigned comparision flips the order of the arguments since they are both negative. For instance, if $-a > -b$ then +$\vert a \vert < \vert b \vert$. Step number four will compare the two when they are both positive. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_cmp.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +The two if statements (lines 23 and 24) perform the initial sign comparison. If the signs are not the equal then which ever +has the positive sign is larger. The inputs are compared (line 32) based on magnitudes. If the signs were both +negative then the unsigned comparison is performed in the opposite direction (line 34). Otherwise, the signs are assumed to +be both positive and a forward direction unsigned comparison is performed. + +\section*{Exercises} +\begin{tabular}{cl} +$\left [ 2 \right ]$ & Modify algorithm mp\_set\_int to accept as input a variable length array of bits. \\ + & \\ +$\left [ 3 \right ]$ & Give the probability that algorithm mp\_cmp\_mag will have to compare $k$ digits \\ + & of two random digits (of equal magnitude) before a difference is found. \\ + & \\ +$\left [ 1 \right ]$ & Suggest a simple method to speed up the implementation of mp\_cmp\_mag based \\ + & on the observations made in the previous problem. \\ + & +\end{tabular} + +\chapter{Basic Arithmetic} +\section{Introduction} +At this point algorithms for initialization, clearing, zeroing, copying, comparing and setting small constants have been +established. The next logical set of algorithms to develop are addition, subtraction and digit shifting algorithms. These +algorithms make use of the lower level algorithms and are the cruicial building block for the multiplication algorithms. It is very important +that these algorithms are highly optimized. On their own they are simple $O(n)$ algorithms but they can be called from higher level algorithms +which easily places them at $O(n^2)$ or even $O(n^3)$ work levels. + +All of the algorithms within this chapter make use of the logical bit shift operations denoted by $<<$ and $>>$ for left and right +logical shifts respectively. A logical shift is analogous to sliding the decimal point of radix-10 representations. For example, the real +number $0.9345$ is equivalent to $93.45\%$ which is found by sliding the the decimal two places to the right (\textit{multiplying by $\beta^2 = 10^2$}). +Algebraically a binary logical shift is equivalent to a division or multiplication by a power of two. +For example, $a << k = a \cdot 2^k$ while $a >> k = \lfloor a/2^k \rfloor$. + +One significant difference between a logical shift and the way decimals are shifted is that digits below the zero'th position are removed +from the number. For example, consider $1101_2 >> 1$ using decimal notation this would produce $110.1_2$. However, with a logical shift the +result is $110_2$. + +\section{Addition and Subtraction} +In common twos complement fixed precision arithmetic negative numbers are easily represented by subtraction from the modulus. For example, with 32-bit integers +$a - b\mbox{ (mod }2^{32}\mbox{)}$ is the same as $a + (2^{32} - b) \mbox{ (mod }2^{32}\mbox{)}$ since $2^{32} \equiv 0 \mbox{ (mod }2^{32}\mbox{)}$. +As a result subtraction can be performed with a trivial series of logical operations and an addition. + +However, in multiple precision arithmetic negative numbers are not represented in the same way. Instead a sign flag is used to keep track of the +sign of the integer. As a result signed addition and subtraction are actually implemented as conditional usage of lower level addition or +subtraction algorithms with the sign fixed up appropriately. + +The lower level algorithms will add or subtract integers without regard to the sign flag. That is they will add or subtract the magnitude of +the integers respectively. + +\subsection{Low Level Addition} +An unsigned addition of multiple precision integers is performed with the same long-hand algorithm used to add decimal numbers. That is to add the +trailing digits first and propagate the resulting carry upwards. Since this is a lower level algorithm the name will have a ``s\_'' prefix. +Historically that convention stems from the MPI library where ``s\_'' stood for static functions that were hidden from the developer entirely. + +\newpage +\begin{figure}[!here] +\begin{center} +\begin{small} +\begin{tabular}{l} +\hline Algorithm \textbf{s\_mp\_add}. \\ +\textbf{Input}. Two mp\_ints $a$ and $b$ \\ +\textbf{Output}. The unsigned addition $c = \vert a \vert + \vert b \vert$. \\ +\hline \\ +1. if $a.used > b.used$ then \\ +\hspace{+3mm}1.1 $min \leftarrow b.used$ \\ +\hspace{+3mm}1.2 $max \leftarrow a.used$ \\ +\hspace{+3mm}1.3 $x \leftarrow a$ \\ +2. else \\ +\hspace{+3mm}2.1 $min \leftarrow a.used$ \\ +\hspace{+3mm}2.2 $max \leftarrow b.used$ \\ +\hspace{+3mm}2.3 $x \leftarrow b$ \\ +3. If $c.alloc < max + 1$ then grow $c$ to hold at least $max + 1$ digits (\textit{mp\_grow}) \\ +4. $oldused \leftarrow c.used$ \\ +5. $c.used \leftarrow max + 1$ \\ +6. $u \leftarrow 0$ \\ +7. for $n$ from $0$ to $min - 1$ do \\ +\hspace{+3mm}7.1 $c_n \leftarrow a_n + b_n + u$ \\ +\hspace{+3mm}7.2 $u \leftarrow c_n >> lg(\beta)$ \\ +\hspace{+3mm}7.3 $c_n \leftarrow c_n \mbox{ (mod }\beta\mbox{)}$ \\ +8. if $min \ne max$ then do \\ +\hspace{+3mm}8.1 for $n$ from $min$ to $max - 1$ do \\ +\hspace{+6mm}8.1.1 $c_n \leftarrow x_n + u$ \\ +\hspace{+6mm}8.1.2 $u \leftarrow c_n >> lg(\beta)$ \\ +\hspace{+6mm}8.1.3 $c_n \leftarrow c_n \mbox{ (mod }\beta\mbox{)}$ \\ +9. $c_{max} \leftarrow u$ \\ +10. if $olduse > max$ then \\ +\hspace{+3mm}10.1 for $n$ from $max + 1$ to $oldused - 1$ do \\ +\hspace{+6mm}10.1.1 $c_n \leftarrow 0$ \\ +11. Clamp excess digits in $c$. (\textit{mp\_clamp}) \\ +12. Return(\textit{MP\_OKAY}) \\ +\hline +\end{tabular} +\end{small} +\end{center} +\caption{Algorithm s\_mp\_add} +\end{figure} + +\textbf{Algorithm s\_mp\_add.} +This algorithm is loosely based on algorithm 14.7 of HAC \cite[pp. 594]{HAC} but has been extended to allow the inputs to have different magnitudes. +Coincidentally the description of algorithm A in Knuth \cite[pp. 266]{TAOCPV2} shares the same deficiency as the algorithm from \cite{HAC}. Even the +MIX pseudo machine code presented by Knuth \cite[pp. 266-267]{TAOCPV2} is incapable of handling inputs which are of different magnitudes. + +The first thing that has to be accomplished is to sort out which of the two inputs is the largest. The addition logic +will simply add all of the smallest input to the largest input and store that first part of the result in the +destination. Then it will apply a simpler addition loop to excess digits of the larger input. + +The first two steps will handle sorting the inputs such that $min$ and $max$ hold the digit counts of the two +inputs. The variable $x$ will be an mp\_int alias for the largest input or the second input $b$ if they have the +same number of digits. After the inputs are sorted the destination $c$ is grown as required to accomodate the sum +of the two inputs. The original \textbf{used} count of $c$ is copied and set to the new used count. + +At this point the first addition loop will go through as many digit positions that both inputs have. The carry +variable $\mu$ is set to zero outside the loop. Inside the loop an ``addition'' step requires three statements to produce +one digit of the summand. First +two digits from $a$ and $b$ are added together along with the carry $\mu$. The carry of this step is extracted and stored +in $\mu$ and finally the digit of the result $c_n$ is truncated within the range $0 \le c_n < \beta$. + +Now all of the digit positions that both inputs have in common have been exhausted. If $min \ne max$ then $x$ is an alias +for one of the inputs that has more digits. A simplified addition loop is then used to essentially copy the remaining digits +and the carry to the destination. + +The final carry is stored in $c_{max}$ and digits above $max$ upto $oldused$ are zeroed which completes the addition. + + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_s\_mp\_add.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +We first sort (lines 28 to 36) the inputs based on magnitude and determine the $min$ and $max$ variables. +Note that $x$ is a pointer to an mp\_int assigned to the largest input, in effect it is a local alias. Next we +grow the destination (38 to 42) ensure that it can accomodate the result of the addition. + +Similar to the implementation of mp\_copy this function uses the braced code and local aliases coding style. The three aliases that are on +lines 56, 59 and 62 represent the two inputs and destination variables respectively. These aliases are used to ensure the +compiler does not have to dereference $a$, $b$ or $c$ (respectively) to access the digits of the respective mp\_int. + +The initial carry $u$ will be cleared (line 65), note that $u$ is of type mp\_digit which ensures type +compatibility within the implementation. The initial addition (line 66 to 75) adds digits from +both inputs until the smallest input runs out of digits. Similarly the conditional addition loop +(line 81 to 90) adds the remaining digits from the larger of the two inputs. The addition is finished +with the final carry being stored in $tmpc$ (line 94). Note the ``++'' operator within the same expression. +After line 94, $tmpc$ will point to the $c.used$'th digit of the mp\_int $c$. This is useful +for the next loop (line 97 to 99) which set any old upper digits to zero. + +\subsection{Low Level Subtraction} +The low level unsigned subtraction algorithm is very similar to the low level unsigned addition algorithm. The principle difference is that the +unsigned subtraction algorithm requires the result to be positive. That is when computing $a - b$ the condition $\vert a \vert \ge \vert b\vert$ must +be met for this algorithm to function properly. Keep in mind this low level algorithm is not meant to be used in higher level algorithms directly. +This algorithm as will be shown can be used to create functional signed addition and subtraction algorithms. + + +For this algorithm a new variable is required to make the description simpler. Recall from section 1.3.1 that a mp\_digit must be able to represent +the range $0 \le x < 2\beta$ for the algorithms to work correctly. However, it is allowable that a mp\_digit represent a larger range of values. For +this algorithm we will assume that the variable $\gamma$ represents the number of bits available in a +mp\_digit (\textit{this implies $2^{\gamma} > \beta$}). + +For example, the default for LibTomMath is to use a ``unsigned long'' for the mp\_digit ``type'' while $\beta = 2^{28}$. In ISO C an ``unsigned long'' +data type must be able to represent $0 \le x < 2^{32}$ meaning that in this case $\gamma \ge 32$. + +\newpage\begin{figure}[!here] +\begin{center} +\begin{small} +\begin{tabular}{l} +\hline Algorithm \textbf{s\_mp\_sub}. \\ +\textbf{Input}. Two mp\_ints $a$ and $b$ ($\vert a \vert \ge \vert b \vert$) \\ +\textbf{Output}. The unsigned subtraction $c = \vert a \vert - \vert b \vert$. \\ +\hline \\ +1. $min \leftarrow b.used$ \\ +2. $max \leftarrow a.used$ \\ +3. If $c.alloc < max$ then grow $c$ to hold at least $max$ digits. (\textit{mp\_grow}) \\ +4. $oldused \leftarrow c.used$ \\ +5. $c.used \leftarrow max$ \\ +6. $u \leftarrow 0$ \\ +7. for $n$ from $0$ to $min - 1$ do \\ +\hspace{3mm}7.1 $c_n \leftarrow a_n - b_n - u$ \\ +\hspace{3mm}7.2 $u \leftarrow c_n >> (\gamma - 1)$ \\ +\hspace{3mm}7.3 $c_n \leftarrow c_n \mbox{ (mod }\beta\mbox{)}$ \\ +8. if $min < max$ then do \\ +\hspace{3mm}8.1 for $n$ from $min$ to $max - 1$ do \\ +\hspace{6mm}8.1.1 $c_n \leftarrow a_n - u$ \\ +\hspace{6mm}8.1.2 $u \leftarrow c_n >> (\gamma - 1)$ \\ +\hspace{6mm}8.1.3 $c_n \leftarrow c_n \mbox{ (mod }\beta\mbox{)}$ \\ +9. if $oldused > max$ then do \\ +\hspace{3mm}9.1 for $n$ from $max$ to $oldused - 1$ do \\ +\hspace{6mm}9.1.1 $c_n \leftarrow 0$ \\ +10. Clamp excess digits of $c$. (\textit{mp\_clamp}). \\ +11. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{small} +\end{center} +\caption{Algorithm s\_mp\_sub} +\end{figure} + +\textbf{Algorithm s\_mp\_sub.} +This algorithm performs the unsigned subtraction of two mp\_int variables under the restriction that the result must be positive. That is when +passing variables $a$ and $b$ the condition that $\vert a \vert \ge \vert b \vert$ must be met for the algorithm to function correctly. This +algorithm is loosely based on algorithm 14.9 \cite[pp. 595]{HAC} and is similar to algorithm S in \cite[pp. 267]{TAOCPV2} as well. As was the case +of the algorithm s\_mp\_add both other references lack discussion concerning various practical details such as when the inputs differ in magnitude. + +The initial sorting of the inputs is trivial in this algorithm since $a$ is guaranteed to have at least the same magnitude of $b$. Steps 1 and 2 +set the $min$ and $max$ variables. Unlike the addition routine there is guaranteed to be no carry which means that the final result can be at +most $max$ digits in length as opposed to $max + 1$. Similar to the addition algorithm the \textbf{used} count of $c$ is copied locally and +set to the maximal count for the operation. + +The subtraction loop that begins on step seven is essentially the same as the addition loop of algorithm s\_mp\_add except single precision +subtraction is used instead. Note the use of the $\gamma$ variable to extract the carry (\textit{also known as the borrow}) within the subtraction +loops. Under the assumption that two's complement single precision arithmetic is used this will successfully extract the desired carry. + +For example, consider subtracting $0101_2$ from $0100_2$ where $\gamma = 4$ and $\beta = 2$. The least significant bit will force a carry upwards to +the third bit which will be set to zero after the borrow. After the very first bit has been subtracted $4 - 1 \equiv 0011_2$ will remain, When the +third bit of $0101_2$ is subtracted from the result it will cause another carry. In this case though the carry will be forced to propagate all the +way to the most significant bit. + +Recall that $\beta < 2^{\gamma}$. This means that if a carry does occur just before the $lg(\beta)$'th bit it will propagate all the way to the most +significant bit. Thus, the high order bits of the mp\_digit that are not part of the actual digit will either be all zero, or all one. All that +is needed is a single zero or one bit for the carry. Therefore a single logical shift right by $\gamma - 1$ positions is sufficient to extract the +carry. This method of carry extraction may seem awkward but the reason for it becomes apparent when the implementation is discussed. + +If $b$ has a smaller magnitude than $a$ then step 9 will force the carry and copy operation to propagate through the larger input $a$ into $c$. Step +10 will ensure that any leading digits of $c$ above the $max$'th position are zeroed. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_s\_mp\_sub.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +Like low level addition we ``sort'' the inputs. Except in this case the sorting is hardcoded +(lines 25 and 26). In reality the $min$ and $max$ variables are only aliases and are only +used to make the source code easier to read. Again the pointer alias optimization is used +within this algorithm. The aliases $tmpa$, $tmpb$ and $tmpc$ are initialized +(lines 42, 43 and 44) for $a$, $b$ and $c$ respectively. + +The first subtraction loop (lines 47 through 61) subtract digits from both inputs until the smaller of +the two inputs has been exhausted. As remarked earlier there is an implementation reason for using the ``awkward'' +method of extracting the carry (line 57). The traditional method for extracting the carry would be to shift +by $lg(\beta)$ positions and logically AND the least significant bit. The AND operation is required because all of +the bits above the $\lg(\beta)$'th bit will be set to one after a carry occurs from subtraction. This carry +extraction requires two relatively cheap operations to extract the carry. The other method is to simply shift the +most significant bit to the least significant bit thus extracting the carry with a single cheap operation. This +optimization only works on twos compliment machines which is a safe assumption to make. + +If $a$ has a larger magnitude than $b$ an additional loop (lines 64 through 73) is required to propagate +the carry through $a$ and copy the result to $c$. + +\subsection{High Level Addition} +Now that both lower level addition and subtraction algorithms have been established an effective high level signed addition algorithm can be +established. This high level addition algorithm will be what other algorithms and developers will use to perform addition of mp\_int data +types. + +Recall from section 5.2 that an mp\_int represents an integer with an unsigned mantissa (\textit{the array of digits}) and a \textbf{sign} +flag. A high level addition is actually performed as a series of eight separate cases which can be optimized down to three unique cases. + +\begin{figure}[!here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_add}. \\ +\textbf{Input}. Two mp\_ints $a$ and $b$ \\ +\textbf{Output}. The signed addition $c = a + b$. \\ +\hline \\ +1. if $a.sign = b.sign$ then do \\ +\hspace{3mm}1.1 $c.sign \leftarrow a.sign$ \\ +\hspace{3mm}1.2 $c \leftarrow \vert a \vert + \vert b \vert$ (\textit{s\_mp\_add})\\ +2. else do \\ +\hspace{3mm}2.1 if $\vert a \vert < \vert b \vert$ then do (\textit{mp\_cmp\_mag}) \\ +\hspace{6mm}2.1.1 $c.sign \leftarrow b.sign$ \\ +\hspace{6mm}2.1.2 $c \leftarrow \vert b \vert - \vert a \vert$ (\textit{s\_mp\_sub}) \\ +\hspace{3mm}2.2 else do \\ +\hspace{6mm}2.2.1 $c.sign \leftarrow a.sign$ \\ +\hspace{6mm}2.2.2 $c \leftarrow \vert a \vert - \vert b \vert$ \\ +3. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_add} +\end{figure} + +\textbf{Algorithm mp\_add.} +This algorithm performs the signed addition of two mp\_int variables. There is no reference algorithm to draw upon from +either \cite{TAOCPV2} or \cite{HAC} since they both only provide unsigned operations. The algorithm is fairly +straightforward but restricted since subtraction can only produce positive results. + +\begin{figure}[here] +\begin{small} +\begin{center} +\begin{tabular}{|c|c|c|c|c|} +\hline \textbf{Sign of $a$} & \textbf{Sign of $b$} & \textbf{$\vert a \vert > \vert b \vert $} & \textbf{Unsigned Operation} & \textbf{Result Sign Flag} \\ +\hline $+$ & $+$ & Yes & $c = a + b$ & $a.sign$ \\ +\hline $+$ & $+$ & No & $c = a + b$ & $a.sign$ \\ +\hline $-$ & $-$ & Yes & $c = a + b$ & $a.sign$ \\ +\hline $-$ & $-$ & No & $c = a + b$ & $a.sign$ \\ +\hline &&&&\\ + +\hline $+$ & $-$ & No & $c = b - a$ & $b.sign$ \\ +\hline $-$ & $+$ & No & $c = b - a$ & $b.sign$ \\ + +\hline &&&&\\ + +\hline $+$ & $-$ & Yes & $c = a - b$ & $a.sign$ \\ +\hline $-$ & $+$ & Yes & $c = a - b$ & $a.sign$ \\ + +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Addition Guide Chart} +\label{fig:AddChart} +\end{figure} + +Figure~\ref{fig:AddChart} lists all of the eight possible input combinations and is sorted to show that only three +specific cases need to be handled. The return code of the unsigned operations at step 1.2, 2.1.2 and 2.2.2 are +forwarded to step three to check for errors. This simplifies the description of the algorithm considerably and best +follows how the implementation actually was achieved. + +Also note how the \textbf{sign} is set before the unsigned addition or subtraction is performed. Recall from the descriptions of algorithms +s\_mp\_add and s\_mp\_sub that the mp\_clamp function is used at the end to trim excess digits. The mp\_clamp algorithm will set the \textbf{sign} +to \textbf{MP\_ZPOS} when the \textbf{used} digit count reaches zero. + +For example, consider performing $-a + a$ with algorithm mp\_add. By the description of the algorithm the sign is set to \textbf{MP\_NEG} which would +produce a result of $-0$. However, since the sign is set first then the unsigned addition is performed the subsequent usage of algorithm mp\_clamp +within algorithm s\_mp\_add will force $-0$ to become $0$. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_add.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +The source code follows the algorithm fairly closely. The most notable new source code addition is the usage of the $res$ integer variable which +is used to pass result of the unsigned operations forward. Unlike in the algorithm, the variable $res$ is merely returned as is without +explicitly checking it and returning the constant \textbf{MP\_OKAY}. The observation is this algorithm will succeed or fail only if the lower +level functions do so. Returning their return code is sufficient. + +\subsection{High Level Subtraction} +The high level signed subtraction algorithm is essentially the same as the high level signed addition algorithm. + +\newpage\begin{figure}[!here] +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_sub}. \\ +\textbf{Input}. Two mp\_ints $a$ and $b$ \\ +\textbf{Output}. The signed subtraction $c = a - b$. \\ +\hline \\ +1. if $a.sign \ne b.sign$ then do \\ +\hspace{3mm}1.1 $c.sign \leftarrow a.sign$ \\ +\hspace{3mm}1.2 $c \leftarrow \vert a \vert + \vert b \vert$ (\textit{s\_mp\_add}) \\ +2. else do \\ +\hspace{3mm}2.1 if $\vert a \vert \ge \vert b \vert$ then do (\textit{mp\_cmp\_mag}) \\ +\hspace{6mm}2.1.1 $c.sign \leftarrow a.sign$ \\ +\hspace{6mm}2.1.2 $c \leftarrow \vert a \vert - \vert b \vert$ (\textit{s\_mp\_sub}) \\ +\hspace{3mm}2.2 else do \\ +\hspace{6mm}2.2.1 $c.sign \leftarrow \left \lbrace \begin{array}{ll} + MP\_ZPOS & \mbox{if }a.sign = MP\_NEG \\ + MP\_NEG & \mbox{otherwise} \\ + \end{array} \right .$ \\ +\hspace{6mm}2.2.2 $c \leftarrow \vert b \vert - \vert a \vert$ \\ +3. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\caption{Algorithm mp\_sub} +\end{figure} + +\textbf{Algorithm mp\_sub.} +This algorithm performs the signed subtraction of two inputs. Similar to algorithm mp\_add there is no reference in either \cite{TAOCPV2} or +\cite{HAC}. Also this algorithm is restricted by algorithm s\_mp\_sub. Chart \ref{fig:SubChart} lists the eight possible inputs and +the operations required. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{|c|c|c|c|c|} +\hline \textbf{Sign of $a$} & \textbf{Sign of $b$} & \textbf{$\vert a \vert \ge \vert b \vert $} & \textbf{Unsigned Operation} & \textbf{Result Sign Flag} \\ +\hline $+$ & $-$ & Yes & $c = a + b$ & $a.sign$ \\ +\hline $+$ & $-$ & No & $c = a + b$ & $a.sign$ \\ +\hline $-$ & $+$ & Yes & $c = a + b$ & $a.sign$ \\ +\hline $-$ & $+$ & No & $c = a + b$ & $a.sign$ \\ +\hline &&&& \\ +\hline $+$ & $+$ & Yes & $c = a - b$ & $a.sign$ \\ +\hline $-$ & $-$ & Yes & $c = a - b$ & $a.sign$ \\ +\hline &&&& \\ +\hline $+$ & $+$ & No & $c = b - a$ & $\mbox{opposite of }a.sign$ \\ +\hline $-$ & $-$ & No & $c = b - a$ & $\mbox{opposite of }a.sign$ \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Subtraction Guide Chart} +\label{fig:SubChart} +\end{figure} + +Similar to the case of algorithm mp\_add the \textbf{sign} is set first before the unsigned addition or subtraction. That is to prevent the +algorithm from producing $-a - -a = -0$ as a result. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_sub.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +Much like the implementation of algorithm mp\_add the variable $res$ is used to catch the return code of the unsigned addition or subtraction operations +and forward it to the end of the function. On line 39 the ``not equal to'' \textbf{MP\_LT} expression is used to emulate a +``greater than or equal to'' comparison. + +\section{Bit and Digit Shifting} +It is quite common to think of a multiple precision integer as a polynomial in $x$, that is $y = f(\beta)$ where $f(x) = \sum_{i=0}^{n-1} a_i x^i$. +This notation arises within discussion of Montgomery and Diminished Radix Reduction as well as Karatsuba multiplication and squaring. + +In order to facilitate operations on polynomials in $x$ as above a series of simple ``digit'' algorithms have to be established. That is to shift +the digits left or right as well to shift individual bits of the digits left and right. It is important to note that not all ``shift'' operations +are on radix-$\beta$ digits. + +\subsection{Multiplication by Two} + +In a binary system where the radix is a power of two multiplication by two not only arises often in other algorithms it is a fairly efficient +operation to perform. A single precision logical shift left is sufficient to multiply a single digit by two. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_mul\_2}. \\ +\textbf{Input}. One mp\_int $a$ \\ +\textbf{Output}. $b = 2a$. \\ +\hline \\ +1. If $b.alloc < a.used + 1$ then grow $b$ to hold $a.used + 1$ digits. (\textit{mp\_grow}) \\ +2. $oldused \leftarrow b.used$ \\ +3. $b.used \leftarrow a.used$ \\ +4. $r \leftarrow 0$ \\ +5. for $n$ from 0 to $a.used - 1$ do \\ +\hspace{3mm}5.1 $rr \leftarrow a_n >> (lg(\beta) - 1)$ \\ +\hspace{3mm}5.2 $b_n \leftarrow (a_n << 1) + r \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{3mm}5.3 $r \leftarrow rr$ \\ +6. If $r \ne 0$ then do \\ +\hspace{3mm}6.1 $b_{n + 1} \leftarrow r$ \\ +\hspace{3mm}6.2 $b.used \leftarrow b.used + 1$ \\ +7. If $b.used < oldused - 1$ then do \\ +\hspace{3mm}7.1 for $n$ from $b.used$ to $oldused - 1$ do \\ +\hspace{6mm}7.1.1 $b_n \leftarrow 0$ \\ +8. $b.sign \leftarrow a.sign$ \\ +9. Return(\textit{MP\_OKAY}).\\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_mul\_2} +\end{figure} + +\textbf{Algorithm mp\_mul\_2.} +This algorithm will quickly multiply a mp\_int by two provided $\beta$ is a power of two. Neither \cite{TAOCPV2} nor \cite{HAC} describe such +an algorithm despite the fact it arises often in other algorithms. The algorithm is setup much like the lower level algorithm s\_mp\_add since +it is for all intents and purposes equivalent to the operation $b = \vert a \vert + \vert a \vert$. + +Step 1 and 2 grow the input as required to accomodate the maximum number of \textbf{used} digits in the result. The initial \textbf{used} count +is set to $a.used$ at step 4. Only if there is a final carry will the \textbf{used} count require adjustment. + +Step 6 is an optimization implementation of the addition loop for this specific case. That is since the two values being added together +are the same there is no need to perform two reads from the digits of $a$. Step 6.1 performs a single precision shift on the current digit $a_n$ to +obtain what will be the carry for the next iteration. Step 6.2 calculates the $n$'th digit of the result as single precision shift of $a_n$ plus +the previous carry. Recall from section 4.1 that $a_n << 1$ is equivalent to $a_n \cdot 2$. An iteration of the addition loop is finished with +forwarding the carry to the next iteration. + +Step 7 takes care of any final carry by setting the $a.used$'th digit of the result to the carry and augmenting the \textbf{used} count of $b$. +Step 8 clears any leading digits of $b$ in case it originally had a larger magnitude than $a$. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_mul\_2.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +This implementation is essentially an optimized implementation of s\_mp\_add for the case of doubling an input. The only noteworthy difference +is the use of the logical shift operator on line 52 to perform a single precision doubling. + +\subsection{Division by Two} +A division by two can just as easily be accomplished with a logical shift right as multiplication by two can be with a logical shift left. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_div\_2}. \\ +\textbf{Input}. One mp\_int $a$ \\ +\textbf{Output}. $b = a/2$. \\ +\hline \\ +1. If $b.alloc < a.used$ then grow $b$ to hold $a.used$ digits. (\textit{mp\_grow}) \\ +2. If the reallocation failed return(\textit{MP\_MEM}). \\ +3. $oldused \leftarrow b.used$ \\ +4. $b.used \leftarrow a.used$ \\ +5. $r \leftarrow 0$ \\ +6. for $n$ from $b.used - 1$ to $0$ do \\ +\hspace{3mm}6.1 $rr \leftarrow a_n \mbox{ (mod }2\mbox{)}$\\ +\hspace{3mm}6.2 $b_n \leftarrow (a_n >> 1) + (r << (lg(\beta) - 1)) \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{3mm}6.3 $r \leftarrow rr$ \\ +7. If $b.used < oldused - 1$ then do \\ +\hspace{3mm}7.1 for $n$ from $b.used$ to $oldused - 1$ do \\ +\hspace{6mm}7.1.1 $b_n \leftarrow 0$ \\ +8. $b.sign \leftarrow a.sign$ \\ +9. Clamp excess digits of $b$. (\textit{mp\_clamp}) \\ +10. Return(\textit{MP\_OKAY}).\\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_div\_2} +\end{figure} + +\textbf{Algorithm mp\_div\_2.} +This algorithm will divide an mp\_int by two using logical shifts to the right. Like mp\_mul\_2 it uses a modified low level addition +core as the basis of the algorithm. Unlike mp\_mul\_2 the shift operations work from the leading digit to the trailing digit. The algorithm +could be written to work from the trailing digit to the leading digit however, it would have to stop one short of $a.used - 1$ digits to prevent +reading past the end of the array of digits. + +Essentially the loop at step 6 is similar to that of mp\_mul\_2 except the logical shifts go in the opposite direction and the carry is at the +least significant bit not the most significant bit. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_div\_2.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +\section{Polynomial Basis Operations} +Recall from section 4.3 that any integer can be represented as a polynomial in $x$ as $y = f(\beta)$. Such a representation is also known as +the polynomial basis \cite[pp. 48]{ROSE}. Given such a notation a multiplication or division by $x$ amounts to shifting whole digits a single +place. The need for such operations arises in several other higher level algorithms such as Barrett and Montgomery reduction, integer +division and Karatsuba multiplication. + +Converting from an array of digits to polynomial basis is very simple. Consider the integer $y \equiv (a_2, a_1, a_0)_{\beta}$ and recall that +$y = \sum_{i=0}^{2} a_i \beta^i$. Simply replace $\beta$ with $x$ and the expression is in polynomial basis. For example, $f(x) = 8x + 9$ is the +polynomial basis representation for $89$ using radix ten. That is, $f(10) = 8(10) + 9 = 89$. + +\subsection{Multiplication by $x$} + +Given a polynomial in $x$ such as $f(x) = a_n x^n + a_{n-1} x^{n-1} + ... + a_0$ multiplying by $x$ amounts to shifting the coefficients up one +degree. In this case $f(x) \cdot x = a_n x^{n+1} + a_{n-1} x^n + ... + a_0 x$. From a scalar basis point of view multiplying by $x$ is equivalent to +multiplying by the integer $\beta$. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_lshd}. \\ +\textbf{Input}. One mp\_int $a$ and an integer $b$ \\ +\textbf{Output}. $a \leftarrow a \cdot \beta^b$ (equivalent to multiplication by $x^b$). \\ +\hline \\ +1. If $b \le 0$ then return(\textit{MP\_OKAY}). \\ +2. If $a.alloc < a.used + b$ then grow $a$ to at least $a.used + b$ digits. (\textit{mp\_grow}). \\ +3. If the reallocation failed return(\textit{MP\_MEM}). \\ +4. $a.used \leftarrow a.used + b$ \\ +5. $i \leftarrow a.used - 1$ \\ +6. $j \leftarrow a.used - 1 - b$ \\ +7. for $n$ from $a.used - 1$ to $b$ do \\ +\hspace{3mm}7.1 $a_{i} \leftarrow a_{j}$ \\ +\hspace{3mm}7.2 $i \leftarrow i - 1$ \\ +\hspace{3mm}7.3 $j \leftarrow j - 1$ \\ +8. for $n$ from 0 to $b - 1$ do \\ +\hspace{3mm}8.1 $a_n \leftarrow 0$ \\ +9. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_lshd} +\end{figure} + +\textbf{Algorithm mp\_lshd.} +This algorithm multiplies an mp\_int by the $b$'th power of $x$. This is equivalent to multiplying by $\beta^b$. The algorithm differs +from the other algorithms presented so far as it performs the operation in place instead storing the result in a separate location. The +motivation behind this change is due to the way this function is typically used. Algorithms such as mp\_add store the result in an optionally +different third mp\_int because the original inputs are often still required. Algorithm mp\_lshd (\textit{and similarly algorithm mp\_rshd}) is +typically used on values where the original value is no longer required. The algorithm will return success immediately if +$b \le 0$ since the rest of algorithm is only valid when $b > 0$. + +First the destination $a$ is grown as required to accomodate the result. The counters $i$ and $j$ are used to form a \textit{sliding window} over +the digits of $a$ of length $b$. The head of the sliding window is at $i$ (\textit{the leading digit}) and the tail at $j$ (\textit{the trailing digit}). +The loop on step 7 copies the digit from the tail to the head. In each iteration the window is moved down one digit. The last loop on +step 8 sets the lower $b$ digits to zero. + +\newpage +\begin{center} +\begin{figure}[here] +\includegraphics{pics/sliding_window.ps} +\caption{Sliding Window Movement} +\label{pic:sliding_window} +\end{figure} +\end{center} + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_lshd.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +The if statement (line 24) ensures that the $b$ variable is greater than zero since we do not interpret negative +shift counts properly. The \textbf{used} count is incremented by $b$ before the copy loop begins. This elminates +the need for an additional variable in the for loop. The variable $top$ (line 42) is an alias +for the leading digit while $bottom$ (line 45) is an alias for the trailing edge. The aliases form a +window of exactly $b$ digits over the input. + +\subsection{Division by $x$} + +Division by powers of $x$ is easily achieved by shifting the digits right and removing any that will end up to the right of the zero'th digit. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_rshd}. \\ +\textbf{Input}. One mp\_int $a$ and an integer $b$ \\ +\textbf{Output}. $a \leftarrow a / \beta^b$ (Divide by $x^b$). \\ +\hline \\ +1. If $b \le 0$ then return. \\ +2. If $a.used \le b$ then do \\ +\hspace{3mm}2.1 Zero $a$. (\textit{mp\_zero}). \\ +\hspace{3mm}2.2 Return. \\ +3. $i \leftarrow 0$ \\ +4. $j \leftarrow b$ \\ +5. for $n$ from 0 to $a.used - b - 1$ do \\ +\hspace{3mm}5.1 $a_i \leftarrow a_j$ \\ +\hspace{3mm}5.2 $i \leftarrow i + 1$ \\ +\hspace{3mm}5.3 $j \leftarrow j + 1$ \\ +6. for $n$ from $a.used - b$ to $a.used - 1$ do \\ +\hspace{3mm}6.1 $a_n \leftarrow 0$ \\ +7. $a.used \leftarrow a.used - b$ \\ +8. Return. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_rshd} +\end{figure} + +\textbf{Algorithm mp\_rshd.} +This algorithm divides the input in place by the $b$'th power of $x$. It is analogous to dividing by a $\beta^b$ but much quicker since +it does not require single precision division. This algorithm does not actually return an error code as it cannot fail. + +If the input $b$ is less than one the algorithm quickly returns without performing any work. If the \textbf{used} count is less than or equal +to the shift count $b$ then it will simply zero the input and return. + +After the trivial cases of inputs have been handled the sliding window is setup. Much like the case of algorithm mp\_lshd a sliding window that +is $b$ digits wide is used to copy the digits. Unlike mp\_lshd the window slides in the opposite direction from the trailing to the leading digit. +Also the digits are copied from the leading to the trailing edge. + +Once the window copy is complete the upper digits must be zeroed and the \textbf{used} count decremented. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_rshd.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +The only noteworthy element of this routine is the lack of a return type since it cannot fail. Like mp\_lshd() we +form a sliding window except we copy in the other direction. After the window (line 60) we then zero +the upper digits of the input to make sure the result is correct. + +\section{Powers of Two} + +Now that algorithms for moving single bits as well as whole digits exist algorithms for moving the ``in between'' distances are required. For +example, to quickly multiply by $2^k$ for any $k$ without using a full multiplier algorithm would prove useful. Instead of performing single +shifts $k$ times to achieve a multiplication by $2^{\pm k}$ a mixture of whole digit shifting and partial digit shifting is employed. + +\subsection{Multiplication by Power of Two} + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_mul\_2d}. \\ +\textbf{Input}. One mp\_int $a$ and an integer $b$ \\ +\textbf{Output}. $c \leftarrow a \cdot 2^b$. \\ +\hline \\ +1. $c \leftarrow a$. (\textit{mp\_copy}) \\ +2. If $c.alloc < c.used + \lfloor b / lg(\beta) \rfloor + 2$ then grow $c$ accordingly. \\ +3. If the reallocation failed return(\textit{MP\_MEM}). \\ +4. If $b \ge lg(\beta)$ then \\ +\hspace{3mm}4.1 $c \leftarrow c \cdot \beta^{\lfloor b / lg(\beta) \rfloor}$ (\textit{mp\_lshd}). \\ +\hspace{3mm}4.2 If step 4.1 failed return(\textit{MP\_MEM}). \\ +5. $d \leftarrow b \mbox{ (mod }lg(\beta)\mbox{)}$ \\ +6. If $d \ne 0$ then do \\ +\hspace{3mm}6.1 $mask \leftarrow 2^d$ \\ +\hspace{3mm}6.2 $r \leftarrow 0$ \\ +\hspace{3mm}6.3 for $n$ from $0$ to $c.used - 1$ do \\ +\hspace{6mm}6.3.1 $rr \leftarrow c_n >> (lg(\beta) - d) \mbox{ (mod }mask\mbox{)}$ \\ +\hspace{6mm}6.3.2 $c_n \leftarrow (c_n << d) + r \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{6mm}6.3.3 $r \leftarrow rr$ \\ +\hspace{3mm}6.4 If $r > 0$ then do \\ +\hspace{6mm}6.4.1 $c_{c.used} \leftarrow r$ \\ +\hspace{6mm}6.4.2 $c.used \leftarrow c.used + 1$ \\ +7. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_mul\_2d} +\end{figure} + +\textbf{Algorithm mp\_mul\_2d.} +This algorithm multiplies $a$ by $2^b$ and stores the result in $c$. The algorithm uses algorithm mp\_lshd and a derivative of algorithm mp\_mul\_2 to +quickly compute the product. + +First the algorithm will multiply $a$ by $x^{\lfloor b / lg(\beta) \rfloor}$ which will ensure that the remainder multiplicand is less than +$\beta$. For example, if $b = 37$ and $\beta = 2^{28}$ then this step will multiply by $x$ leaving a multiplication by $2^{37 - 28} = 2^{9}$ +left. + +After the digits have been shifted appropriately at most $lg(\beta) - 1$ shifts are left to perform. Step 5 calculates the number of remaining shifts +required. If it is non-zero a modified shift loop is used to calculate the remaining product. +Essentially the loop is a generic version of algorithm mp\_mul\_2 designed to handle any shift count in the range $1 \le x < lg(\beta)$. The $mask$ +variable is used to extract the upper $d$ bits to form the carry for the next iteration. + +This algorithm is loosely measured as a $O(2n)$ algorithm which means that if the input is $n$-digits that it takes $2n$ ``time'' to +complete. It is possible to optimize this algorithm down to a $O(n)$ algorithm at a cost of making the algorithm slightly harder to follow. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_mul\_2d.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +The shifting is performed in--place which means the first step (line 25) is to copy the input to the +destination. We avoid calling mp\_copy() by making sure the mp\_ints are different. The destination then +has to be grown (line 32) to accomodate the result. + +If the shift count $b$ is larger than $lg(\beta)$ then a call to mp\_lshd() is used to handle all of the multiples +of $lg(\beta)$. Leaving only a remaining shift of $lg(\beta) - 1$ or fewer bits left. Inside the actual shift +loop (lines 46 to 76) we make use of pre--computed values $shift$ and $mask$. These are used to +extract the carry bit(s) to pass into the next iteration of the loop. The $r$ and $rr$ variables form a +chain between consecutive iterations to propagate the carry. + +\subsection{Division by Power of Two} + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_div\_2d}. \\ +\textbf{Input}. One mp\_int $a$ and an integer $b$ \\ +\textbf{Output}. $c \leftarrow \lfloor a / 2^b \rfloor, d \leftarrow a \mbox{ (mod }2^b\mbox{)}$. \\ +\hline \\ +1. If $b \le 0$ then do \\ +\hspace{3mm}1.1 $c \leftarrow a$ (\textit{mp\_copy}) \\ +\hspace{3mm}1.2 $d \leftarrow 0$ (\textit{mp\_zero}) \\ +\hspace{3mm}1.3 Return(\textit{MP\_OKAY}). \\ +2. $c \leftarrow a$ \\ +3. $d \leftarrow a \mbox{ (mod }2^b\mbox{)}$ (\textit{mp\_mod\_2d}) \\ +4. If $b \ge lg(\beta)$ then do \\ +\hspace{3mm}4.1 $c \leftarrow \lfloor c/\beta^{\lfloor b/lg(\beta) \rfloor} \rfloor$ (\textit{mp\_rshd}). \\ +5. $k \leftarrow b \mbox{ (mod }lg(\beta)\mbox{)}$ \\ +6. If $k \ne 0$ then do \\ +\hspace{3mm}6.1 $mask \leftarrow 2^k$ \\ +\hspace{3mm}6.2 $r \leftarrow 0$ \\ +\hspace{3mm}6.3 for $n$ from $c.used - 1$ to $0$ do \\ +\hspace{6mm}6.3.1 $rr \leftarrow c_n \mbox{ (mod }mask\mbox{)}$ \\ +\hspace{6mm}6.3.2 $c_n \leftarrow (c_n >> k) + (r << (lg(\beta) - k))$ \\ +\hspace{6mm}6.3.3 $r \leftarrow rr$ \\ +7. Clamp excess digits of $c$. (\textit{mp\_clamp}) \\ +8. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_div\_2d} +\end{figure} + +\textbf{Algorithm mp\_div\_2d.} +This algorithm will divide an input $a$ by $2^b$ and produce the quotient and remainder. The algorithm is designed much like algorithm +mp\_mul\_2d by first using whole digit shifts then single precision shifts. This algorithm will also produce the remainder of the division +by using algorithm mp\_mod\_2d. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_div\_2d.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +The implementation of algorithm mp\_div\_2d is slightly different than the algorithm specifies. The remainder $d$ may be optionally +ignored by passing \textbf{NULL} as the pointer to the mp\_int variable. The temporary mp\_int variable $t$ is used to hold the +result of the remainder operation until the end. This allows $d$ and $a$ to represent the same mp\_int without modifying $a$ before +the quotient is obtained. + +The remainder of the source code is essentially the same as the source code for mp\_mul\_2d. The only significant difference is +the direction of the shifts. + +\subsection{Remainder of Division by Power of Two} + +The last algorithm in the series of polynomial basis power of two algorithms is calculating the remainder of division by $2^b$. This +algorithm benefits from the fact that in twos complement arithmetic $a \mbox{ (mod }2^b\mbox{)}$ is the same as $a$ AND $2^b - 1$. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_mod\_2d}. \\ +\textbf{Input}. One mp\_int $a$ and an integer $b$ \\ +\textbf{Output}. $c \leftarrow a \mbox{ (mod }2^b\mbox{)}$. \\ +\hline \\ +1. If $b \le 0$ then do \\ +\hspace{3mm}1.1 $c \leftarrow 0$ (\textit{mp\_zero}) \\ +\hspace{3mm}1.2 Return(\textit{MP\_OKAY}). \\ +2. If $b > a.used \cdot lg(\beta)$ then do \\ +\hspace{3mm}2.1 $c \leftarrow a$ (\textit{mp\_copy}) \\ +\hspace{3mm}2.2 Return the result of step 2.1. \\ +3. $c \leftarrow a$ \\ +4. If step 3 failed return(\textit{MP\_MEM}). \\ +5. for $n$ from $\lceil b / lg(\beta) \rceil$ to $c.used$ do \\ +\hspace{3mm}5.1 $c_n \leftarrow 0$ \\ +6. $k \leftarrow b \mbox{ (mod }lg(\beta)\mbox{)}$ \\ +7. $c_{\lfloor b / lg(\beta) \rfloor} \leftarrow c_{\lfloor b / lg(\beta) \rfloor} \mbox{ (mod }2^{k}\mbox{)}$. \\ +8. Clamp excess digits of $c$. (\textit{mp\_clamp}) \\ +9. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_mod\_2d} +\end{figure} + +\textbf{Algorithm mp\_mod\_2d.} +This algorithm will quickly calculate the value of $a \mbox{ (mod }2^b\mbox{)}$. First if $b$ is less than or equal to zero the +result is set to zero. If $b$ is greater than the number of bits in $a$ then it simply copies $a$ to $c$ and returns. Otherwise, $a$ +is copied to $b$, leading digits are removed and the remaining leading digit is trimed to the exact bit count. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_mod\_2d.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +We first avoid cases of $b \le 0$ by simply mp\_zero()'ing the destination in such cases. Next if $2^b$ is larger +than the input we just mp\_copy() the input and return right away. After this point we know we must actually +perform some work to produce the remainder. + +Recalling that reducing modulo $2^k$ and a binary ``and'' with $2^k - 1$ are numerically equivalent we can quickly reduce +the number. First we zero any digits above the last digit in $2^b$ (line 42). Next we reduce the +leading digit of both (line 46) and then mp\_clamp(). + +\section*{Exercises} +\begin{tabular}{cl} +$\left [ 3 \right ] $ & Devise an algorithm that performs $a \cdot 2^b$ for generic values of $b$ \\ + & in $O(n)$ time. \\ + &\\ +$\left [ 3 \right ] $ & Devise an efficient algorithm to multiply by small low hamming \\ + & weight values such as $3$, $5$ and $9$. Extend it to handle all values \\ + & upto $64$ with a hamming weight less than three. \\ + &\\ +$\left [ 2 \right ] $ & Modify the preceding algorithm to handle values of the form \\ + & $2^k - 1$ as well. \\ + &\\ +$\left [ 3 \right ] $ & Using only algorithms mp\_mul\_2, mp\_div\_2 and mp\_add create an \\ + & algorithm to multiply two integers in roughly $O(2n^2)$ time for \\ + & any $n$-bit input. Note that the time of addition is ignored in the \\ + & calculation. \\ + & \\ +$\left [ 5 \right ] $ & Improve the previous algorithm to have a working time of at most \\ + & $O \left (2^{(k-1)}n + \left ({2n^2 \over k} \right ) \right )$ for an appropriate choice of $k$. Again ignore \\ + & the cost of addition. \\ + & \\ +$\left [ 2 \right ] $ & Devise a chart to find optimal values of $k$ for the previous problem \\ + & for $n = 64 \ldots 1024$ in steps of $64$. \\ + & \\ +$\left [ 2 \right ] $ & Using only algorithms mp\_abs and mp\_sub devise another method for \\ + & calculating the result of a signed comparison. \\ + & +\end{tabular} + +\chapter{Multiplication and Squaring} +\section{The Multipliers} +For most number theoretic problems including certain public key cryptographic algorithms, the ``multipliers'' form the most important subset of +algorithms of any multiple precision integer package. The set of multiplier algorithms include integer multiplication, squaring and modular reduction +where in each of the algorithms single precision multiplication is the dominant operation performed. This chapter will discuss integer multiplication +and squaring, leaving modular reductions for the subsequent chapter. + +The importance of the multiplier algorithms is for the most part driven by the fact that certain popular public key algorithms are based on modular +exponentiation, that is computing $d \equiv a^b \mbox{ (mod }c\mbox{)}$ for some arbitrary choice of $a$, $b$, $c$ and $d$. During a modular +exponentiation the majority\footnote{Roughly speaking a modular exponentiation will spend about 40\% of the time performing modular reductions, +35\% of the time performing squaring and 25\% of the time performing multiplications.} of the processor time is spent performing single precision +multiplications. + +For centuries general purpose multiplication has required a lengthly $O(n^2)$ process, whereby each digit of one multiplicand has to be multiplied +against every digit of the other multiplicand. Traditional long-hand multiplication is based on this process; while the techniques can differ the +overall algorithm used is essentially the same. Only ``recently'' have faster algorithms been studied. First Karatsuba multiplication was discovered in +1962. This algorithm can multiply two numbers with considerably fewer single precision multiplications when compared to the long-hand approach. +This technique led to the discovery of polynomial basis algorithms (\textit{good reference?}) and subquently Fourier Transform based solutions. + +\section{Multiplication} +\subsection{The Baseline Multiplication} +\label{sec:basemult} +\index{baseline multiplication} +Computing the product of two integers in software can be achieved using a trivial adaptation of the standard $O(n^2)$ long-hand multiplication +algorithm that school children are taught. The algorithm is considered an $O(n^2)$ algorithm since for two $n$-digit inputs $n^2$ single precision +multiplications are required. More specifically for a $m$ and $n$ digit input $m \cdot n$ single precision multiplications are required. To +simplify most discussions, it will be assumed that the inputs have comparable number of digits. + +The ``baseline multiplication'' algorithm is designed to act as the ``catch-all'' algorithm, only to be used when the faster algorithms cannot be +used. This algorithm does not use any particularly interesting optimizations and should ideally be avoided if possible. One important +facet of this algorithm, is that it has been modified to only produce a certain amount of output digits as resolution. The importance of this +modification will become evident during the discussion of Barrett modular reduction. Recall that for a $n$ and $m$ digit input the product +will be at most $n + m$ digits. Therefore, this algorithm can be reduced to a full multiplier by having it produce $n + m$ digits of the product. + +Recall from sub-section 4.2.2 the definition of $\gamma$ as the number of bits in the type \textbf{mp\_digit}. We shall now extend the variable set to +include $\alpha$ which shall represent the number of bits in the type \textbf{mp\_word}. This implies that $2^{\alpha} > 2 \cdot \beta^2$. The +constant $\delta = 2^{\alpha - 2lg(\beta)}$ will represent the maximal weight of any column in a product (\textit{see sub-section 5.2.2 for more information}). + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{s\_mp\_mul\_digs}. \\ +\textbf{Input}. mp\_int $a$, mp\_int $b$ and an integer $digs$ \\ +\textbf{Output}. $c \leftarrow \vert a \vert \cdot \vert b \vert \mbox{ (mod }\beta^{digs}\mbox{)}$. \\ +\hline \\ +1. If min$(a.used, b.used) < \delta$ then do \\ +\hspace{3mm}1.1 Calculate $c = \vert a \vert \cdot \vert b \vert$ by the Comba method (\textit{see algorithm~\ref{fig:COMBAMULT}}). \\ +\hspace{3mm}1.2 Return the result of step 1.1 \\ +\\ +Allocate and initialize a temporary mp\_int. \\ +2. Init $t$ to be of size $digs$ \\ +3. If step 2 failed return(\textit{MP\_MEM}). \\ +4. $t.used \leftarrow digs$ \\ +\\ +Compute the product. \\ +5. for $ix$ from $0$ to $a.used - 1$ do \\ +\hspace{3mm}5.1 $u \leftarrow 0$ \\ +\hspace{3mm}5.2 $pb \leftarrow \mbox{min}(b.used, digs - ix)$ \\ +\hspace{3mm}5.3 If $pb < 1$ then goto step 6. \\ +\hspace{3mm}5.4 for $iy$ from $0$ to $pb - 1$ do \\ +\hspace{6mm}5.4.1 $\hat r \leftarrow t_{iy + ix} + a_{ix} \cdot b_{iy} + u$ \\ +\hspace{6mm}5.4.2 $t_{iy + ix} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{6mm}5.4.3 $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\ +\hspace{3mm}5.5 if $ix + pb < digs$ then do \\ +\hspace{6mm}5.5.1 $t_{ix + pb} \leftarrow u$ \\ +6. Clamp excess digits of $t$. \\ +7. Swap $c$ with $t$ \\ +8. Clear $t$ \\ +9. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm s\_mp\_mul\_digs} +\end{figure} + +\textbf{Algorithm s\_mp\_mul\_digs.} +This algorithm computes the unsigned product of two inputs $a$ and $b$, limited to an output precision of $digs$ digits. While it may seem +a bit awkward to modify the function from its simple $O(n^2)$ description, the usefulness of partial multipliers will arise in a subsequent +algorithm. The algorithm is loosely based on algorithm 14.12 from \cite[pp. 595]{HAC} and is similar to Algorithm M of Knuth \cite[pp. 268]{TAOCPV2}. +Algorithm s\_mp\_mul\_digs differs from these cited references since it can produce a variable output precision regardless of the precision of the +inputs. + +The first thing this algorithm checks for is whether a Comba multiplier can be used instead. If the minimum digit count of either +input is less than $\delta$, then the Comba method may be used instead. After the Comba method is ruled out, the baseline algorithm begins. A +temporary mp\_int variable $t$ is used to hold the intermediate result of the product. This allows the algorithm to be used to +compute products when either $a = c$ or $b = c$ without overwriting the inputs. + +All of step 5 is the infamous $O(n^2)$ multiplication loop slightly modified to only produce upto $digs$ digits of output. The $pb$ variable +is given the count of digits to read from $b$ inside the nested loop. If $pb \le 1$ then no more output digits can be produced and the algorithm +will exit the loop. The best way to think of the loops are as a series of $pb \times 1$ multiplications. That is, in each pass of the +innermost loop $a_{ix}$ is multiplied against $b$ and the result is added (\textit{with an appropriate shift}) to $t$. + +For example, consider multiplying $576$ by $241$. That is equivalent to computing $10^0(1)(576) + 10^1(4)(576) + 10^2(2)(576)$ which is best +visualized in the following table. + +\begin{figure}[here] +\begin{center} +\begin{tabular}{|c|c|c|c|c|c|l|} +\hline && & 5 & 7 & 6 & \\ +\hline $\times$&& & 2 & 4 & 1 & \\ +\hline &&&&&&\\ + && & 5 & 7 & 6 & $10^0(1)(576)$ \\ + &2 & 3 & 6 & 1 & 6 & $10^1(4)(576) + 10^0(1)(576)$ \\ + 1 & 3 & 8 & 8 & 1 & 6 & $10^2(2)(576) + 10^1(4)(576) + 10^0(1)(576)$ \\ +\hline +\end{tabular} +\end{center} +\caption{Long-Hand Multiplication Diagram} +\end{figure} + +Each row of the product is added to the result after being shifted to the left (\textit{multiplied by a power of the radix}) by the appropriate +count. That is in pass $ix$ of the inner loop the product is added starting at the $ix$'th digit of the reult. + +Step 5.4.1 introduces the hat symbol (\textit{e.g. $\hat r$}) which represents a double precision variable. The multiplication on that step +is assumed to be a double wide output single precision multiplication. That is, two single precision variables are multiplied to produce a +double precision result. The step is somewhat optimized from a long-hand multiplication algorithm because the carry from the addition in step +5.4.1 is propagated through the nested loop. If the carry was not propagated immediately it would overflow the single precision digit +$t_{ix+iy}$ and the result would be lost. + +At step 5.5 the nested loop is finished and any carry that was left over should be forwarded. The carry does not have to be added to the $ix+pb$'th +digit since that digit is assumed to be zero at this point. However, if $ix + pb \ge digs$ the carry is not set as it would make the result +exceed the precision requested. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_s\_mp\_mul\_digs.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +First we determine (line 31) if the Comba method can be used first since it's faster. The conditions for +sing the Comba routine are that min$(a.used, b.used) < \delta$ and the number of digits of output is less than +\textbf{MP\_WARRAY}. This new constant is used to control the stack usage in the Comba routines. By default it is +set to $\delta$ but can be reduced when memory is at a premium. + +If we cannot use the Comba method we proceed to setup the baseline routine. We allocate the the destination mp\_int +$t$ (line 37) to the exact size of the output to avoid further re--allocations. At this point we now +begin the $O(n^2)$ loop. + +This implementation of multiplication has the caveat that it can be trimmed to only produce a variable number of +digits as output. In each iteration of the outer loop the $pb$ variable is set (line 49) to the maximum +number of inner loop iterations. + +Inside the inner loop we calculate $\hat r$ as the mp\_word product of the two mp\_digits and the addition of the +carry from the previous iteration. A particularly important observation is that most modern optimizing +C compilers (GCC for instance) can recognize that a $N \times N \rightarrow 2N$ multiplication is all that +is required for the product. In x86 terms for example, this means using the MUL instruction. + +Each digit of the product is stored in turn (line 69) and the carry propagated (line 72) to the +next iteration. + +\subsection{Faster Multiplication by the ``Comba'' Method} + +One of the huge drawbacks of the ``baseline'' algorithms is that at the $O(n^2)$ level the carry must be +computed and propagated upwards. This makes the nested loop very sequential and hard to unroll and implement +in parallel. The ``Comba'' \cite{COMBA} method is named after little known (\textit{in cryptographic venues}) Paul G. +Comba who described a method of implementing fast multipliers that do not require nested carry fixup operations. As an +interesting aside it seems that Paul Barrett describes a similar technique in his 1986 paper \cite{BARRETT} written +five years before. + +At the heart of the Comba technique is once again the long-hand algorithm. Except in this case a slight +twist is placed on how the columns of the result are produced. In the standard long-hand algorithm rows of products +are produced then added together to form the final result. In the baseline algorithm the columns are added together +after each iteration to get the result instantaneously. + +In the Comba algorithm the columns of the result are produced entirely independently of each other. That is at +the $O(n^2)$ level a simple multiplication and addition step is performed. The carries of the columns are propagated +after the nested loop to reduce the amount of work requiored. Succintly the first step of the algorithm is to compute +the product vector $\vec x$ as follows. + +\begin{equation} +\vec x_n = \sum_{i+j = n} a_ib_j, \forall n \in \lbrace 0, 1, 2, \ldots, i + j \rbrace +\end{equation} + +Where $\vec x_n$ is the $n'th$ column of the output vector. Consider the following example which computes the vector $\vec x$ for the multiplication +of $576$ and $241$. + +\newpage\begin{figure}[here] +\begin{small} +\begin{center} +\begin{tabular}{|c|c|c|c|c|c|} + \hline & & 5 & 7 & 6 & First Input\\ + \hline $\times$ & & 2 & 4 & 1 & Second Input\\ +\hline & & $1 \cdot 5 = 5$ & $1 \cdot 7 = 7$ & $1 \cdot 6 = 6$ & First pass \\ + & $4 \cdot 5 = 20$ & $4 \cdot 7+5=33$ & $4 \cdot 6+7=31$ & 6 & Second pass \\ + $2 \cdot 5 = 10$ & $2 \cdot 7 + 20 = 34$ & $2 \cdot 6+33=45$ & 31 & 6 & Third pass \\ +\hline 10 & 34 & 45 & 31 & 6 & Final Result \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Comba Multiplication Diagram} +\end{figure} + +At this point the vector $x = \left < 10, 34, 45, 31, 6 \right >$ is the result of the first step of the Comba multipler. +Now the columns must be fixed by propagating the carry upwards. The resultant vector will have one extra dimension over the input vector which is +congruent to adding a leading zero digit. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{Comba Fixup}. \\ +\textbf{Input}. Vector $\vec x$ of dimension $k$ \\ +\textbf{Output}. Vector $\vec x$ such that the carries have been propagated. \\ +\hline \\ +1. for $n$ from $0$ to $k - 1$ do \\ +\hspace{3mm}1.1 $\vec x_{n+1} \leftarrow \vec x_{n+1} + \lfloor \vec x_{n}/\beta \rfloor$ \\ +\hspace{3mm}1.2 $\vec x_{n} \leftarrow \vec x_{n} \mbox{ (mod }\beta\mbox{)}$ \\ +2. Return($\vec x$). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm Comba Fixup} +\end{figure} + +With that algorithm and $k = 5$ and $\beta = 10$ the following vector is produced $\vec x= \left < 1, 3, 8, 8, 1, 6 \right >$. In this case +$241 \cdot 576$ is in fact $138816$ and the procedure succeeded. If the algorithm is correct and as will be demonstrated shortly more +efficient than the baseline algorithm why not simply always use this algorithm? + +\subsubsection{Column Weight.} +At the nested $O(n^2)$ level the Comba method adds the product of two single precision variables to each column of the output +independently. A serious obstacle is if the carry is lost, due to lack of precision before the algorithm has a chance to fix +the carries. For example, in the multiplication of two three-digit numbers the third column of output will be the sum of +three single precision multiplications. If the precision of the accumulator for the output digits is less then $3 \cdot (\beta - 1)^2$ then +an overflow can occur and the carry information will be lost. For any $m$ and $n$ digit inputs the maximum weight of any column is +min$(m, n)$ which is fairly obvious. + +The maximum number of terms in any column of a product is known as the ``column weight'' and strictly governs when the algorithm can be used. Recall +from earlier that a double precision type has $\alpha$ bits of resolution and a single precision digit has $lg(\beta)$ bits of precision. Given these +two quantities we must not violate the following + +\begin{equation} +k \cdot \left (\beta - 1 \right )^2 < 2^{\alpha} +\end{equation} + +Which reduces to + +\begin{equation} +k \cdot \left ( \beta^2 - 2\beta + 1 \right ) < 2^{\alpha} +\end{equation} + +Let $\rho = lg(\beta)$ represent the number of bits in a single precision digit. By further re-arrangement of the equation the final solution is +found. + +\begin{equation} +k < {{2^{\alpha}} \over {\left (2^{2\rho} - 2^{\rho + 1} + 1 \right )}} +\end{equation} + +The defaults for LibTomMath are $\beta = 2^{28}$ and $\alpha = 2^{64}$ which means that $k$ is bounded by $k < 257$. In this configuration +the smaller input may not have more than $256$ digits if the Comba method is to be used. This is quite satisfactory for most applications since +$256$ digits would allow for numbers in the range of $0 \le x < 2^{7168}$ which, is much larger than most public key cryptographic algorithms require. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{fast\_s\_mp\_mul\_digs}. \\ +\textbf{Input}. mp\_int $a$, mp\_int $b$ and an integer $digs$ \\ +\textbf{Output}. $c \leftarrow \vert a \vert \cdot \vert b \vert \mbox{ (mod }\beta^{digs}\mbox{)}$. \\ +\hline \\ +Place an array of \textbf{MP\_WARRAY} single precision digits named $W$ on the stack. \\ +1. If $c.alloc < digs$ then grow $c$ to $digs$ digits. (\textit{mp\_grow}) \\ +2. If step 1 failed return(\textit{MP\_MEM}).\\ +\\ +3. $pa \leftarrow \mbox{MIN}(digs, a.used + b.used)$ \\ +\\ +4. $\_ \hat W \leftarrow 0$ \\ +5. for $ix$ from 0 to $pa - 1$ do \\ +\hspace{3mm}5.1 $ty \leftarrow \mbox{MIN}(b.used - 1, ix)$ \\ +\hspace{3mm}5.2 $tx \leftarrow ix - ty$ \\ +\hspace{3mm}5.3 $iy \leftarrow \mbox{MIN}(a.used - tx, ty + 1)$ \\ +\hspace{3mm}5.4 for $iz$ from 0 to $iy - 1$ do \\ +\hspace{6mm}5.4.1 $\_ \hat W \leftarrow \_ \hat W + a_{tx+iy}b_{ty-iy}$ \\ +\hspace{3mm}5.5 $W_{ix} \leftarrow \_ \hat W (\mbox{mod }\beta)$\\ +\hspace{3mm}5.6 $\_ \hat W \leftarrow \lfloor \_ \hat W / \beta \rfloor$ \\ +\\ +6. $oldused \leftarrow c.used$ \\ +7. $c.used \leftarrow digs$ \\ +8. for $ix$ from $0$ to $pa$ do \\ +\hspace{3mm}8.1 $c_{ix} \leftarrow W_{ix}$ \\ +9. for $ix$ from $pa + 1$ to $oldused - 1$ do \\ +\hspace{3mm}9.1 $c_{ix} \leftarrow 0$ \\ +\\ +10. Clamp $c$. \\ +11. Return MP\_OKAY. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm fast\_s\_mp\_mul\_digs} +\label{fig:COMBAMULT} +\end{figure} + +\textbf{Algorithm fast\_s\_mp\_mul\_digs.} +This algorithm performs the unsigned multiplication of $a$ and $b$ using the Comba method limited to $digs$ digits of precision. + +The outer loop of this algorithm is more complicated than that of the baseline multiplier. This is because on the inside of the +loop we want to produce one column per pass. This allows the accumulator $\_ \hat W$ to be placed in CPU registers and +reduce the memory bandwidth to two \textbf{mp\_digit} reads per iteration. + +The $ty$ variable is set to the minimum count of $ix$ or the number of digits in $b$. That way if $a$ has more digits than +$b$ this will be limited to $b.used - 1$. The $tx$ variable is set to the to the distance past $b.used$ the variable +$ix$ is. This is used for the immediately subsequent statement where we find $iy$. + +The variable $iy$ is the minimum digits we can read from either $a$ or $b$ before running out. Computing one column at a time +means we have to scan one integer upwards and the other downwards. $a$ starts at $tx$ and $b$ starts at $ty$. In each +pass we are producing the $ix$'th output column and we note that $tx + ty = ix$. As we move $tx$ upwards we have to +move $ty$ downards so the equality remains valid. The $iy$ variable is the number of iterations until +$tx \ge a.used$ or $ty < 0$ occurs. + +After every inner pass we store the lower half of the accumulator into $W_{ix}$ and then propagate the carry of the accumulator +into the next round by dividing $\_ \hat W$ by $\beta$. + +To measure the benefits of the Comba method over the baseline method consider the number of operations that are required. If the +cost in terms of time of a multiply and addition is $p$ and the cost of a carry propagation is $q$ then a baseline multiplication would require +$O \left ((p + q)n^2 \right )$ time to multiply two $n$-digit numbers. The Comba method requires only $O(pn^2 + qn)$ time, however in practice, +the speed increase is actually much more. With $O(n)$ space the algorithm can be reduced to $O(pn + qn)$ time by implementing the $n$ multiply +and addition operations in the nested loop in parallel. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_fast\_s\_mp\_mul\_digs.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +As per the pseudo--code we first calculate $pa$ (line 48) as the number of digits to output. Next we begin the outer loop +to produce the individual columns of the product. We use the two aliases $tmpx$ and $tmpy$ (lines 62, 63) to point +inside the two multiplicands quickly. + +The inner loop (lines 71 to 74) of this implementation is where the tradeoff come into play. Originally this comba +implementation was ``row--major'' which means it adds to each of the columns in each pass. After the outer loop it would then fix +the carries. This was very fast except it had an annoying drawback. You had to read a mp\_word and two mp\_digits and write +one mp\_word per iteration. On processors such as the Athlon XP and P4 this did not matter much since the cache bandwidth +is very high and it can keep the ALU fed with data. It did, however, matter on older and embedded cpus where cache is often +slower and also often doesn't exist. This new algorithm only performs two reads per iteration under the assumption that the +compiler has aliased $\_ \hat W$ to a CPU register. + +After the inner loop we store the current accumulator in $W$ and shift $\_ \hat W$ (lines 77, 80) to forward it as +a carry for the next pass. After the outer loop we use the final carry (line 77) as the last digit of the product. + +\subsection{Polynomial Basis Multiplication} +To break the $O(n^2)$ barrier in multiplication requires a completely different look at integer multiplication. In the following algorithms +the use of polynomial basis representation for two integers $a$ and $b$ as $f(x) = \sum_{i=0}^{n} a_i x^i$ and +$g(x) = \sum_{i=0}^{n} b_i x^i$ respectively, is required. In this system both $f(x)$ and $g(x)$ have $n + 1$ terms and are of the $n$'th degree. + +The product $a \cdot b \equiv f(x)g(x)$ is the polynomial $W(x) = \sum_{i=0}^{2n} w_i x^i$. The coefficients $w_i$ will +directly yield the desired product when $\beta$ is substituted for $x$. The direct solution to solve for the $2n + 1$ coefficients +requires $O(n^2)$ time and would in practice be slower than the Comba technique. + +However, numerical analysis theory indicates that only $2n + 1$ distinct points in $W(x)$ are required to determine the values of the $2n + 1$ unknown +coefficients. This means by finding $\zeta_y = W(y)$ for $2n + 1$ small values of $y$ the coefficients of $W(x)$ can be found with +Gaussian elimination. This technique is also occasionally refered to as the \textit{interpolation technique} (\textit{references please...}) since in +effect an interpolation based on $2n + 1$ points will yield a polynomial equivalent to $W(x)$. + +The coefficients of the polynomial $W(x)$ are unknown which makes finding $W(y)$ for any value of $y$ impossible. However, since +$W(x) = f(x)g(x)$ the equivalent $\zeta_y = f(y) g(y)$ can be used in its place. The benefit of this technique stems from the +fact that $f(y)$ and $g(y)$ are much smaller than either $a$ or $b$ respectively. As a result finding the $2n + 1$ relations required +by multiplying $f(y)g(y)$ involves multiplying integers that are much smaller than either of the inputs. + +When picking points to gather relations there are always three obvious points to choose, $y = 0, 1$ and $ \infty$. The $\zeta_0$ term +is simply the product $W(0) = w_0 = a_0 \cdot b_0$. The $\zeta_1$ term is the product +$W(1) = \left (\sum_{i = 0}^{n} a_i \right ) \left (\sum_{i = 0}^{n} b_i \right )$. The third point $\zeta_{\infty}$ is less obvious but rather +simple to explain. The $2n + 1$'th coefficient of $W(x)$ is numerically equivalent to the most significant column in an integer multiplication. +The point at $\infty$ is used symbolically to represent the most significant column, that is $W(\infty) = w_{2n} = a_nb_n$. Note that the +points at $y = 0$ and $\infty$ yield the coefficients $w_0$ and $w_{2n}$ directly. + +If more points are required they should be of small values and powers of two such as $2^q$ and the related \textit{mirror points} +$\left (2^q \right )^{2n} \cdot \zeta_{2^{-q}}$ for small values of $q$. The term ``mirror point'' stems from the fact that +$\left (2^q \right )^{2n} \cdot \zeta_{2^{-q}}$ can be calculated in the exact opposite fashion as $\zeta_{2^q}$. For +example, when $n = 2$ and $q = 1$ then following two equations are equivalent to the point $\zeta_{2}$ and its mirror. + +\begin{eqnarray} +\zeta_{2} = f(2)g(2) = (4a_2 + 2a_1 + a_0)(4b_2 + 2b_1 + b_0) \nonumber \\ +16 \cdot \zeta_{1 \over 2} = 4f({1\over 2}) \cdot 4g({1 \over 2}) = (a_2 + 2a_1 + 4a_0)(b_2 + 2b_1 + 4b_0) +\end{eqnarray} + +Using such points will allow the values of $f(y)$ and $g(y)$ to be independently calculated using only left shifts. For example, when $n = 2$ the +polynomial $f(2^q)$ is equal to $2^q((2^qa_2) + a_1) + a_0$. This technique of polynomial representation is known as Horner's method. + +As a general rule of the algorithm when the inputs are split into $n$ parts each there are $2n - 1$ multiplications. Each multiplication is of +multiplicands that have $n$ times fewer digits than the inputs. The asymptotic running time of this algorithm is +$O \left ( k^{lg_n(2n - 1)} \right )$ for $k$ digit inputs (\textit{assuming they have the same number of digits}). Figure~\ref{fig:exponent} +summarizes the exponents for various values of $n$. + +\begin{figure} +\begin{center} +\begin{tabular}{|c|c|c|} +\hline \textbf{Split into $n$ Parts} & \textbf{Exponent} & \textbf{Notes}\\ +\hline $2$ & $1.584962501$ & This is Karatsuba Multiplication. \\ +\hline $3$ & $1.464973520$ & This is Toom-Cook Multiplication. \\ +\hline $4$ & $1.403677461$ &\\ +\hline $5$ & $1.365212389$ &\\ +\hline $10$ & $1.278753601$ &\\ +\hline $100$ & $1.149426538$ &\\ +\hline $1000$ & $1.100270931$ &\\ +\hline $10000$ & $1.075252070$ &\\ +\hline +\end{tabular} +\end{center} +\caption{Asymptotic Running Time of Polynomial Basis Multiplication} +\label{fig:exponent} +\end{figure} + +At first it may seem like a good idea to choose $n = 1000$ since the exponent is approximately $1.1$. However, the overhead +of solving for the 2001 terms of $W(x)$ will certainly consume any savings the algorithm could offer for all but exceedingly large +numbers. + +\subsubsection{Cutoff Point} +The polynomial basis multiplication algorithms all require fewer single precision multiplications than a straight Comba approach. However, +the algorithms incur an overhead (\textit{at the $O(n)$ work level}) since they require a system of equations to be solved. This makes the +polynomial basis approach more costly to use with small inputs. + +Let $m$ represent the number of digits in the multiplicands (\textit{assume both multiplicands have the same number of digits}). There exists a +point $y$ such that when $m < y$ the polynomial basis algorithms are more costly than Comba, when $m = y$ they are roughly the same cost and +when $m > y$ the Comba methods are slower than the polynomial basis algorithms. + +The exact location of $y$ depends on several key architectural elements of the computer platform in question. + +\begin{enumerate} +\item The ratio of clock cycles for single precision multiplication versus other simpler operations such as addition, shifting, etc. For example +on the AMD Athlon the ratio is roughly $17 : 1$ while on the Intel P4 it is $29 : 1$. The higher the ratio in favour of multiplication the lower +the cutoff point $y$ will be. + +\item The complexity of the linear system of equations (\textit{for the coefficients of $W(x)$}) is. Generally speaking as the number of splits +grows the complexity grows substantially. Ideally solving the system will only involve addition, subtraction and shifting of integers. This +directly reflects on the ratio previous mentioned. + +\item To a lesser extent memory bandwidth and function call overheads. Provided the values are in the processor cache this is less of an +influence over the cutoff point. + +\end{enumerate} + +A clean cutoff point separation occurs when a point $y$ is found such that all of the cutoff point conditions are met. For example, if the point +is too low then there will be values of $m$ such that $m > y$ and the Comba method is still faster. Finding the cutoff points is fairly simple when +a high resolution timer is available. + +\subsection{Karatsuba Multiplication} +Karatsuba \cite{KARA} multiplication when originally proposed in 1962 was among the first set of algorithms to break the $O(n^2)$ barrier for +general purpose multiplication. Given two polynomial basis representations $f(x) = ax + b$ and $g(x) = cx + d$, Karatsuba proved with +light algebra \cite{KARAP} that the following polynomial is equivalent to multiplication of the two integers the polynomials represent. + +\begin{equation} +f(x) \cdot g(x) = acx^2 + ((a + b)(c + d) - (ac + bd))x + bd +\end{equation} + +Using the observation that $ac$ and $bd$ could be re-used only three half sized multiplications would be required to produce the product. Applying +this algorithm recursively, the work factor becomes $O(n^{lg(3)})$ which is substantially better than the work factor $O(n^2)$ of the Comba technique. It turns +out what Karatsuba did not know or at least did not publish was that this is simply polynomial basis multiplication with the points +$\zeta_0$, $\zeta_{\infty}$ and $\zeta_{1}$. Consider the resultant system of equations. + +\begin{center} +\begin{tabular}{rcrcrcrc} +$\zeta_{0}$ & $=$ & & & & & $w_0$ \\ +$\zeta_{1}$ & $=$ & $w_2$ & $+$ & $w_1$ & $+$ & $w_0$ \\ +$\zeta_{\infty}$ & $=$ & $w_2$ & & & & \\ +\end{tabular} +\end{center} + +By adding the first and last equation to the equation in the middle the term $w_1$ can be isolated and all three coefficients solved for. The simplicity +of this system of equations has made Karatsuba fairly popular. In fact the cutoff point is often fairly low\footnote{With LibTomMath 0.18 it is 70 and 109 digits for the Intel P4 and AMD Athlon respectively.} +making it an ideal algorithm to speed up certain public key cryptosystems such as RSA and Diffie-Hellman. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_karatsuba\_mul}. \\ +\textbf{Input}. mp\_int $a$ and mp\_int $b$ \\ +\textbf{Output}. $c \leftarrow \vert a \vert \cdot \vert b \vert$ \\ +\hline \\ +1. Init the following mp\_int variables: $x0$, $x1$, $y0$, $y1$, $t1$, $x0y0$, $x1y1$.\\ +2. If step 2 failed then return(\textit{MP\_MEM}). \\ +\\ +Split the input. e.g. $a = x1 \cdot \beta^B + x0$ \\ +3. $B \leftarrow \mbox{min}(a.used, b.used)/2$ \\ +4. $x0 \leftarrow a \mbox{ (mod }\beta^B\mbox{)}$ (\textit{mp\_mod\_2d}) \\ +5. $y0 \leftarrow b \mbox{ (mod }\beta^B\mbox{)}$ \\ +6. $x1 \leftarrow \lfloor a / \beta^B \rfloor$ (\textit{mp\_rshd}) \\ +7. $y1 \leftarrow \lfloor b / \beta^B \rfloor$ \\ +\\ +Calculate the three products. \\ +8. $x0y0 \leftarrow x0 \cdot y0$ (\textit{mp\_mul}) \\ +9. $x1y1 \leftarrow x1 \cdot y1$ \\ +10. $t1 \leftarrow x1 + x0$ (\textit{mp\_add}) \\ +11. $x0 \leftarrow y1 + y0$ \\ +12. $t1 \leftarrow t1 \cdot x0$ \\ +\\ +Calculate the middle term. \\ +13. $x0 \leftarrow x0y0 + x1y1$ \\ +14. $t1 \leftarrow t1 - x0$ (\textit{s\_mp\_sub}) \\ +\\ +Calculate the final product. \\ +15. $t1 \leftarrow t1 \cdot \beta^B$ (\textit{mp\_lshd}) \\ +16. $x1y1 \leftarrow x1y1 \cdot \beta^{2B}$ \\ +17. $t1 \leftarrow x0y0 + t1$ \\ +18. $c \leftarrow t1 + x1y1$ \\ +19. Clear all of the temporary variables. \\ +20. Return(\textit{MP\_OKAY}).\\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_karatsuba\_mul} +\end{figure} + +\textbf{Algorithm mp\_karatsuba\_mul.} +This algorithm computes the unsigned product of two inputs using the Karatsuba multiplication algorithm. It is loosely based on the description +from Knuth \cite[pp. 294-295]{TAOCPV2}. + +\index{radix point} +In order to split the two inputs into their respective halves, a suitable \textit{radix point} must be chosen. The radix point chosen must +be used for both of the inputs meaning that it must be smaller than the smallest input. Step 3 chooses the radix point $B$ as half of the +smallest input \textbf{used} count. After the radix point is chosen the inputs are split into lower and upper halves. Step 4 and 5 +compute the lower halves. Step 6 and 7 computer the upper halves. + +After the halves have been computed the three intermediate half-size products must be computed. Step 8 and 9 compute the trivial products +$x0 \cdot y0$ and $x1 \cdot y1$. The mp\_int $x0$ is used as a temporary variable after $x1 + x0$ has been computed. By using $x0$ instead +of an additional temporary variable, the algorithm can avoid an addition memory allocation operation. + +The remaining steps 13 through 18 compute the Karatsuba polynomial through a variety of digit shifting and addition operations. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_karatsuba\_mul.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +The new coding element in this routine, not seen in previous routines, is the usage of goto statements. The conventional +wisdom is that goto statements should be avoided. This is generally true, however when every single function call can fail, it makes sense +to handle error recovery with a single piece of code. Lines 62 to 76 handle initializing all of the temporary variables +required. Note how each of the if statements goes to a different label in case of failure. This allows the routine to correctly free only +the temporaries that have been successfully allocated so far. + +The temporary variables are all initialized using the mp\_init\_size routine since they are expected to be large. This saves the +additional reallocation that would have been necessary. Also $x0$, $x1$, $y0$ and $y1$ have to be able to hold at least their respective +number of digits for the next section of code. + +The first algebraic portion of the algorithm is to split the two inputs into their halves. However, instead of using mp\_mod\_2d and mp\_rshd +to extract the halves, the respective code has been placed inline within the body of the function. To initialize the halves, the \textbf{used} and +\textbf{sign} members are copied first. The first for loop on line 96 copies the lower halves. Since they are both the same magnitude it +is simpler to calculate both lower halves in a single loop. The for loop on lines 102 and 107 calculate the upper halves $x1$ and +$y1$ respectively. + +By inlining the calculation of the halves, the Karatsuba multiplier has a slightly lower overhead and can be used for smaller magnitude inputs. + +When line 151 is reached, the algorithm has completed succesfully. The ``error status'' variable $err$ is set to \textbf{MP\_OKAY} so that +the same code that handles errors can be used to clear the temporary variables and return. + +\subsection{Toom-Cook $3$-Way Multiplication} +Toom-Cook $3$-Way \cite{TOOM} multiplication is essentially the polynomial basis algorithm for $n = 2$ except that the points are +chosen such that $\zeta$ is easy to compute and the resulting system of equations easy to reduce. Here, the points $\zeta_{0}$, +$16 \cdot \zeta_{1 \over 2}$, $\zeta_1$, $\zeta_2$ and $\zeta_{\infty}$ make up the five required points to solve for the coefficients +of the $W(x)$. + +With the five relations that Toom-Cook specifies, the following system of equations is formed. + +\begin{center} +\begin{tabular}{rcrcrcrcrcr} +$\zeta_0$ & $=$ & $0w_4$ & $+$ & $0w_3$ & $+$ & $0w_2$ & $+$ & $0w_1$ & $+$ & $1w_0$ \\ +$16 \cdot \zeta_{1 \over 2}$ & $=$ & $1w_4$ & $+$ & $2w_3$ & $+$ & $4w_2$ & $+$ & $8w_1$ & $+$ & $16w_0$ \\ +$\zeta_1$ & $=$ & $1w_4$ & $+$ & $1w_3$ & $+$ & $1w_2$ & $+$ & $1w_1$ & $+$ & $1w_0$ \\ +$\zeta_2$ & $=$ & $16w_4$ & $+$ & $8w_3$ & $+$ & $4w_2$ & $+$ & $2w_1$ & $+$ & $1w_0$ \\ +$\zeta_{\infty}$ & $=$ & $1w_4$ & $+$ & $0w_3$ & $+$ & $0w_2$ & $+$ & $0w_1$ & $+$ & $0w_0$ \\ +\end{tabular} +\end{center} + +A trivial solution to this matrix requires $12$ subtractions, two multiplications by a small power of two, two divisions by a small power +of two, two divisions by three and one multiplication by three. All of these $19$ sub-operations require less than quadratic time, meaning that +the algorithm can be faster than a baseline multiplication. However, the greater complexity of this algorithm places the cutoff point +(\textbf{TOOM\_MUL\_CUTOFF}) where Toom-Cook becomes more efficient much higher than the Karatsuba cutoff point. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_toom\_mul}. \\ +\textbf{Input}. mp\_int $a$ and mp\_int $b$ \\ +\textbf{Output}. $c \leftarrow a \cdot b $ \\ +\hline \\ +Split $a$ and $b$ into three pieces. E.g. $a = a_2 \beta^{2k} + a_1 \beta^{k} + a_0$ \\ +1. $k \leftarrow \lfloor \mbox{min}(a.used, b.used) / 3 \rfloor$ \\ +2. $a_0 \leftarrow a \mbox{ (mod }\beta^{k}\mbox{)}$ \\ +3. $a_1 \leftarrow \lfloor a / \beta^k \rfloor$, $a_1 \leftarrow a_1 \mbox{ (mod }\beta^{k}\mbox{)}$ \\ +4. $a_2 \leftarrow \lfloor a / \beta^{2k} \rfloor$, $a_2 \leftarrow a_2 \mbox{ (mod }\beta^{k}\mbox{)}$ \\ +5. $b_0 \leftarrow a \mbox{ (mod }\beta^{k}\mbox{)}$ \\ +6. $b_1 \leftarrow \lfloor a / \beta^k \rfloor$, $b_1 \leftarrow b_1 \mbox{ (mod }\beta^{k}\mbox{)}$ \\ +7. $b_2 \leftarrow \lfloor a / \beta^{2k} \rfloor$, $b_2 \leftarrow b_2 \mbox{ (mod }\beta^{k}\mbox{)}$ \\ +\\ +Find the five equations for $w_0, w_1, ..., w_4$. \\ +8. $w_0 \leftarrow a_0 \cdot b_0$ \\ +9. $w_4 \leftarrow a_2 \cdot b_2$ \\ +10. $tmp_1 \leftarrow 2 \cdot a_0$, $tmp_1 \leftarrow a_1 + tmp_1$, $tmp_1 \leftarrow 2 \cdot tmp_1$, $tmp_1 \leftarrow tmp_1 + a_2$ \\ +11. $tmp_2 \leftarrow 2 \cdot b_0$, $tmp_2 \leftarrow b_1 + tmp_2$, $tmp_2 \leftarrow 2 \cdot tmp_2$, $tmp_2 \leftarrow tmp_2 + b_2$ \\ +12. $w_1 \leftarrow tmp_1 \cdot tmp_2$ \\ +13. $tmp_1 \leftarrow 2 \cdot a_2$, $tmp_1 \leftarrow a_1 + tmp_1$, $tmp_1 \leftarrow 2 \cdot tmp_1$, $tmp_1 \leftarrow tmp_1 + a_0$ \\ +14. $tmp_2 \leftarrow 2 \cdot b_2$, $tmp_2 \leftarrow b_1 + tmp_2$, $tmp_2 \leftarrow 2 \cdot tmp_2$, $tmp_2 \leftarrow tmp_2 + b_0$ \\ +15. $w_3 \leftarrow tmp_1 \cdot tmp_2$ \\ +16. $tmp_1 \leftarrow a_0 + a_1$, $tmp_1 \leftarrow tmp_1 + a_2$, $tmp_2 \leftarrow b_0 + b_1$, $tmp_2 \leftarrow tmp_2 + b_2$ \\ +17. $w_2 \leftarrow tmp_1 \cdot tmp_2$ \\ +\\ +Continued on the next page.\\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_toom\_mul} +\end{figure} + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_toom\_mul} (continued). \\ +\textbf{Input}. mp\_int $a$ and mp\_int $b$ \\ +\textbf{Output}. $c \leftarrow a \cdot b $ \\ +\hline \\ +Now solve the system of equations. \\ +18. $w_1 \leftarrow w_4 - w_1$, $w_3 \leftarrow w_3 - w_0$ \\ +19. $w_1 \leftarrow \lfloor w_1 / 2 \rfloor$, $w_3 \leftarrow \lfloor w_3 / 2 \rfloor$ \\ +20. $w_2 \leftarrow w_2 - w_0$, $w_2 \leftarrow w_2 - w_4$ \\ +21. $w_1 \leftarrow w_1 - w_2$, $w_3 \leftarrow w_3 - w_2$ \\ +22. $tmp_1 \leftarrow 8 \cdot w_0$, $w_1 \leftarrow w_1 - tmp_1$, $tmp_1 \leftarrow 8 \cdot w_4$, $w_3 \leftarrow w_3 - tmp_1$ \\ +23. $w_2 \leftarrow 3 \cdot w_2$, $w_2 \leftarrow w_2 - w_1$, $w_2 \leftarrow w_2 - w_3$ \\ +24. $w_1 \leftarrow w_1 - w_2$, $w_3 \leftarrow w_3 - w_2$ \\ +25. $w_1 \leftarrow \lfloor w_1 / 3 \rfloor, w_3 \leftarrow \lfloor w_3 / 3 \rfloor$ \\ +\\ +Now substitute $\beta^k$ for $x$ by shifting $w_0, w_1, ..., w_4$. \\ +26. for $n$ from $1$ to $4$ do \\ +\hspace{3mm}26.1 $w_n \leftarrow w_n \cdot \beta^{nk}$ \\ +27. $c \leftarrow w_0 + w_1$, $c \leftarrow c + w_2$, $c \leftarrow c + w_3$, $c \leftarrow c + w_4$ \\ +28. Return(\textit{MP\_OKAY}) \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_toom\_mul (continued)} +\end{figure} + +\textbf{Algorithm mp\_toom\_mul.} +This algorithm computes the product of two mp\_int variables $a$ and $b$ using the Toom-Cook approach. Compared to the Karatsuba multiplication, this +algorithm has a lower asymptotic running time of approximately $O(n^{1.464})$ but at an obvious cost in overhead. In this +description, several statements have been compounded to save space. The intention is that the statements are executed from left to right across +any given step. + +The two inputs $a$ and $b$ are first split into three $k$-digit integers $a_0, a_1, a_2$ and $b_0, b_1, b_2$ respectively. From these smaller +integers the coefficients of the polynomial basis representations $f(x)$ and $g(x)$ are known and can be used to find the relations required. + +The first two relations $w_0$ and $w_4$ are the points $\zeta_{0}$ and $\zeta_{\infty}$ respectively. The relation $w_1, w_2$ and $w_3$ correspond +to the points $16 \cdot \zeta_{1 \over 2}, \zeta_{2}$ and $\zeta_{1}$ respectively. These are found using logical shifts to independently find +$f(y)$ and $g(y)$ which significantly speeds up the algorithm. + +After the five relations $w_0, w_1, \ldots, w_4$ have been computed, the system they represent must be solved in order for the unknown coefficients +$w_1, w_2$ and $w_3$ to be isolated. The steps 18 through 25 perform the system reduction required as previously described. Each step of +the reduction represents the comparable matrix operation that would be performed had this been performed by pencil. For example, step 18 indicates +that row $1$ must be subtracted from row $4$ and simultaneously row $0$ subtracted from row $3$. + +Once the coeffients have been isolated, the polynomial $W(x) = \sum_{i=0}^{2n} w_i x^i$ is known. By substituting $\beta^{k}$ for $x$, the integer +result $a \cdot b$ is produced. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_toom\_mul.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +The first obvious thing to note is that this algorithm is complicated. The complexity is worth it if you are multiplying very +large numbers. For example, a 10,000 digit multiplication takes approximaly 99,282,205 fewer single precision multiplications with +Toom--Cook than a Comba or baseline approach (this is a savings of more than 99$\%$). For most ``crypto'' sized numbers this +algorithm is not practical as Karatsuba has a much lower cutoff point. + +First we split $a$ and $b$ into three roughly equal portions. This has been accomplished (lines 41 to 70) with +combinations of mp\_rshd() and mp\_mod\_2d() function calls. At this point $a = a2 \cdot \beta^2 + a1 \cdot \beta + a0$ and similiarly +for $b$. + +Next we compute the five points $w0, w1, w2, w3$ and $w4$. Recall that $w0$ and $w4$ can be computed directly from the portions so +we get those out of the way first (lines 73 and 78). Next we compute $w1, w2$ and $w3$ using Horners method. + +After this point we solve for the actual values of $w1, w2$ and $w3$ by reducing the $5 \times 5$ system which is relatively +straight forward. + +\subsection{Signed Multiplication} +Now that algorithms to handle multiplications of every useful dimensions have been developed, a rather simple finishing touch is required. So far all +of the multiplication algorithms have been unsigned multiplications which leaves only a signed multiplication algorithm to be established. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_mul}. \\ +\textbf{Input}. mp\_int $a$ and mp\_int $b$ \\ +\textbf{Output}. $c \leftarrow a \cdot b$ \\ +\hline \\ +1. If $a.sign = b.sign$ then \\ +\hspace{3mm}1.1 $sign = MP\_ZPOS$ \\ +2. else \\ +\hspace{3mm}2.1 $sign = MP\_ZNEG$ \\ +3. If min$(a.used, b.used) \ge TOOM\_MUL\_CUTOFF$ then \\ +\hspace{3mm}3.1 $c \leftarrow a \cdot b$ using algorithm mp\_toom\_mul \\ +4. else if min$(a.used, b.used) \ge KARATSUBA\_MUL\_CUTOFF$ then \\ +\hspace{3mm}4.1 $c \leftarrow a \cdot b$ using algorithm mp\_karatsuba\_mul \\ +5. else \\ +\hspace{3mm}5.1 $digs \leftarrow a.used + b.used + 1$ \\ +\hspace{3mm}5.2 If $digs < MP\_ARRAY$ and min$(a.used, b.used) \le \delta$ then \\ +\hspace{6mm}5.2.1 $c \leftarrow a \cdot b \mbox{ (mod }\beta^{digs}\mbox{)}$ using algorithm fast\_s\_mp\_mul\_digs. \\ +\hspace{3mm}5.3 else \\ +\hspace{6mm}5.3.1 $c \leftarrow a \cdot b \mbox{ (mod }\beta^{digs}\mbox{)}$ using algorithm s\_mp\_mul\_digs. \\ +6. $c.sign \leftarrow sign$ \\ +7. Return the result of the unsigned multiplication performed. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_mul} +\end{figure} + +\textbf{Algorithm mp\_mul.} +This algorithm performs the signed multiplication of two inputs. It will make use of any of the three unsigned multiplication algorithms +available when the input is of appropriate size. The \textbf{sign} of the result is not set until the end of the algorithm since algorithm +s\_mp\_mul\_digs will clear it. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_mul.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +The implementation is rather simplistic and is not particularly noteworthy. Line 22 computes the sign of the result using the ``?'' +operator from the C programming language. Line 48 computes $\delta$ using the fact that $1 << k$ is equal to $2^k$. + +\section{Squaring} +\label{sec:basesquare} + +Squaring is a special case of multiplication where both multiplicands are equal. At first it may seem like there is no significant optimization +available but in fact there is. Consider the multiplication of $576$ against $241$. In total there will be nine single precision multiplications +performed which are $1\cdot 6$, $1 \cdot 7$, $1 \cdot 5$, $4 \cdot 6$, $4 \cdot 7$, $4 \cdot 5$, $2 \cdot 6$, $2 \cdot 7$ and $2 \cdot 5$. Now consider +the multiplication of $123$ against $123$. The nine products are $3 \cdot 3$, $3 \cdot 2$, $3 \cdot 1$, $2 \cdot 3$, $2 \cdot 2$, $2 \cdot 1$, +$1 \cdot 3$, $1 \cdot 2$ and $1 \cdot 1$. On closer inspection some of the products are equivalent. For example, $3 \cdot 2 = 2 \cdot 3$ +and $3 \cdot 1 = 1 \cdot 3$. + +For any $n$-digit input, there are ${{\left (n^2 + n \right)}\over 2}$ possible unique single precision multiplications required compared to the $n^2$ +required for multiplication. The following diagram gives an example of the operations required. + +\begin{figure}[here] +\begin{center} +\begin{tabular}{ccccc|c} +&&1&2&3&\\ +$\times$ &&1&2&3&\\ +\hline && $3 \cdot 1$ & $3 \cdot 2$ & $3 \cdot 3$ & Row 0\\ + & $2 \cdot 1$ & $2 \cdot 2$ & $2 \cdot 3$ && Row 1 \\ + $1 \cdot 1$ & $1 \cdot 2$ & $1 \cdot 3$ &&& Row 2 \\ +\end{tabular} +\end{center} +\caption{Squaring Optimization Diagram} +\end{figure} + +Starting from zero and numbering the columns from right to left a very simple pattern becomes obvious. For the purposes of this discussion let $x$ +represent the number being squared. The first observation is that in row $k$ the $2k$'th column of the product has a $\left (x_k \right)^2$ term in it. + +The second observation is that every column $j$ in row $k$ where $j \ne 2k$ is part of a double product. Every non-square term of a column will +appear twice hence the name ``double product''. Every odd column is made up entirely of double products. In fact every column is made up of double +products and at most one square (\textit{see the exercise section}). + +The third and final observation is that for row $k$ the first unique non-square term, that is, one that hasn't already appeared in an earlier row, +occurs at column $2k + 1$. For example, on row $1$ of the previous squaring, column one is part of the double product with column one from row zero. +Column two of row one is a square and column three is the first unique column. + +\subsection{The Baseline Squaring Algorithm} +The baseline squaring algorithm is meant to be a catch-all squaring algorithm. It will handle any of the input sizes that the faster routines +will not handle. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{s\_mp\_sqr}. \\ +\textbf{Input}. mp\_int $a$ \\ +\textbf{Output}. $b \leftarrow a^2$ \\ +\hline \\ +1. Init a temporary mp\_int of at least $2 \cdot a.used +1$ digits. (\textit{mp\_init\_size}) \\ +2. If step 1 failed return(\textit{MP\_MEM}) \\ +3. $t.used \leftarrow 2 \cdot a.used + 1$ \\ +4. For $ix$ from 0 to $a.used - 1$ do \\ +\hspace{3mm}Calculate the square. \\ +\hspace{3mm}4.1 $\hat r \leftarrow t_{2ix} + \left (a_{ix} \right )^2$ \\ +\hspace{3mm}4.2 $t_{2ix} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{3mm}Calculate the double products after the square. \\ +\hspace{3mm}4.3 $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\ +\hspace{3mm}4.4 For $iy$ from $ix + 1$ to $a.used - 1$ do \\ +\hspace{6mm}4.4.1 $\hat r \leftarrow 2 \cdot a_{ix}a_{iy} + t_{ix + iy} + u$ \\ +\hspace{6mm}4.4.2 $t_{ix + iy} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{6mm}4.4.3 $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\ +\hspace{3mm}Set the last carry. \\ +\hspace{3mm}4.5 While $u > 0$ do \\ +\hspace{6mm}4.5.1 $iy \leftarrow iy + 1$ \\ +\hspace{6mm}4.5.2 $\hat r \leftarrow t_{ix + iy} + u$ \\ +\hspace{6mm}4.5.3 $t_{ix + iy} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{6mm}4.5.4 $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\ +5. Clamp excess digits of $t$. (\textit{mp\_clamp}) \\ +6. Exchange $b$ and $t$. \\ +7. Clear $t$ (\textit{mp\_clear}) \\ +8. Return(\textit{MP\_OKAY}) \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm s\_mp\_sqr} +\end{figure} + +\textbf{Algorithm s\_mp\_sqr.} +This algorithm computes the square of an input using the three observations on squaring. It is based fairly faithfully on algorithm 14.16 of HAC +\cite[pp.596-597]{HAC}. Similar to algorithm s\_mp\_mul\_digs, a temporary mp\_int is allocated to hold the result of the squaring. This allows the +destination mp\_int to be the same as the source mp\_int. + +The outer loop of this algorithm begins on step 4. It is best to think of the outer loop as walking down the rows of the partial results, while +the inner loop computes the columns of the partial result. Step 4.1 and 4.2 compute the square term for each row, and step 4.3 and 4.4 propagate +the carry and compute the double products. + +The requirement that a mp\_word be able to represent the range $0 \le x < 2 \beta^2$ arises from this +very algorithm. The product $a_{ix}a_{iy}$ will lie in the range $0 \le x \le \beta^2 - 2\beta + 1$ which is obviously less than $\beta^2$ meaning that +when it is multiplied by two, it can be properly represented by a mp\_word. + +Similar to algorithm s\_mp\_mul\_digs, after every pass of the inner loop, the destination is correctly set to the sum of all of the partial +results calculated so far. This involves expensive carry propagation which will be eliminated in the next algorithm. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_s\_mp\_sqr.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +Inside the outer loop (line 34) the square term is calculated on line 37. The carry (line 44) has been +extracted from the mp\_word accumulator using a right shift. Aliases for $a_{ix}$ and $t_{ix+iy}$ are initialized +(lines 47 and 50) to simplify the inner loop. The doubling is performed using two +additions (line 59) since it is usually faster than shifting, if not at least as fast. + +The important observation is that the inner loop does not begin at $iy = 0$ like for multiplication. As such the inner loops +get progressively shorter as the algorithm proceeds. This is what leads to the savings compared to using a multiplication to +square a number. + +\subsection{Faster Squaring by the ``Comba'' Method} +A major drawback to the baseline method is the requirement for single precision shifting inside the $O(n^2)$ nested loop. Squaring has an additional +drawback that it must double the product inside the inner loop as well. As for multiplication, the Comba technique can be used to eliminate these +performance hazards. + +The first obvious solution is to make an array of mp\_words which will hold all of the columns. This will indeed eliminate all of the carry +propagation operations from the inner loop. However, the inner product must still be doubled $O(n^2)$ times. The solution stems from the simple fact +that $2a + 2b + 2c = 2(a + b + c)$. That is the sum of all of the double products is equal to double the sum of all the products. For example, +$ab + ba + ac + ca = 2ab + 2ac = 2(ab + ac)$. + +However, we cannot simply double all of the columns, since the squares appear only once per row. The most practical solution is to have two +mp\_word arrays. One array will hold the squares and the other array will hold the double products. With both arrays the doubling and +carry propagation can be moved to a $O(n)$ work level outside the $O(n^2)$ level. In this case, we have an even simpler solution in mind. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{fast\_s\_mp\_sqr}. \\ +\textbf{Input}. mp\_int $a$ \\ +\textbf{Output}. $b \leftarrow a^2$ \\ +\hline \\ +Place an array of \textbf{MP\_WARRAY} mp\_digits named $W$ on the stack. \\ +1. If $b.alloc < 2a.used + 1$ then grow $b$ to $2a.used + 1$ digits. (\textit{mp\_grow}). \\ +2. If step 1 failed return(\textit{MP\_MEM}). \\ +\\ +3. $pa \leftarrow 2 \cdot a.used$ \\ +4. $\hat W1 \leftarrow 0$ \\ +5. for $ix$ from $0$ to $pa - 1$ do \\ +\hspace{3mm}5.1 $\_ \hat W \leftarrow 0$ \\ +\hspace{3mm}5.2 $ty \leftarrow \mbox{MIN}(a.used - 1, ix)$ \\ +\hspace{3mm}5.3 $tx \leftarrow ix - ty$ \\ +\hspace{3mm}5.4 $iy \leftarrow \mbox{MIN}(a.used - tx, ty + 1)$ \\ +\hspace{3mm}5.5 $iy \leftarrow \mbox{MIN}(iy, \lfloor \left (ty - tx + 1 \right )/2 \rfloor)$ \\ +\hspace{3mm}5.6 for $iz$ from $0$ to $iz - 1$ do \\ +\hspace{6mm}5.6.1 $\_ \hat W \leftarrow \_ \hat W + a_{tx + iz}a_{ty - iz}$ \\ +\hspace{3mm}5.7 $\_ \hat W \leftarrow 2 \cdot \_ \hat W + \hat W1$ \\ +\hspace{3mm}5.8 if $ix$ is even then \\ +\hspace{6mm}5.8.1 $\_ \hat W \leftarrow \_ \hat W + \left ( a_{\lfloor ix/2 \rfloor}\right )^2$ \\ +\hspace{3mm}5.9 $W_{ix} \leftarrow \_ \hat W (\mbox{mod }\beta)$ \\ +\hspace{3mm}5.10 $\hat W1 \leftarrow \lfloor \_ \hat W / \beta \rfloor$ \\ +\\ +6. $oldused \leftarrow b.used$ \\ +7. $b.used \leftarrow 2 \cdot a.used$ \\ +8. for $ix$ from $0$ to $pa - 1$ do \\ +\hspace{3mm}8.1 $b_{ix} \leftarrow W_{ix}$ \\ +9. for $ix$ from $pa$ to $oldused - 1$ do \\ +\hspace{3mm}9.1 $b_{ix} \leftarrow 0$ \\ +10. Clamp excess digits from $b$. (\textit{mp\_clamp}) \\ +11. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm fast\_s\_mp\_sqr} +\end{figure} + +\textbf{Algorithm fast\_s\_mp\_sqr.} +This algorithm computes the square of an input using the Comba technique. It is designed to be a replacement for algorithm +s\_mp\_sqr when the number of input digits is less than \textbf{MP\_WARRAY} and less than $\delta \over 2$. +This algorithm is very similar to the Comba multiplier except with a few key differences we shall make note of. + +First, we have an accumulator and carry variables $\_ \hat W$ and $\hat W1$ respectively. This is because the inner loop +products are to be doubled. If we had added the previous carry in we would be doubling too much. Next we perform an +addition MIN condition on $iy$ (step 5.5) to prevent overlapping digits. For example, $a_3 \cdot a_5$ is equal +$a_5 \cdot a_3$. Whereas in the multiplication case we would have $5 < a.used$ and $3 \ge 0$ is maintained since we double the sum +of the products just outside the inner loop we have to avoid doing this. This is also a good thing since we perform +fewer multiplications and the routine ends up being faster. + +Finally the last difference is the addition of the ``square'' term outside the inner loop (step 5.8). We add in the square +only to even outputs and it is the square of the term at the $\lfloor ix / 2 \rfloor$ position. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_fast\_s\_mp\_sqr.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +This implementation is essentially a copy of Comba multiplication with the appropriate changes added to make it faster for +the special case of squaring. + +\subsection{Polynomial Basis Squaring} +The same algorithm that performs optimal polynomial basis multiplication can be used to perform polynomial basis squaring. The minor exception +is that $\zeta_y = f(y)g(y)$ is actually equivalent to $\zeta_y = f(y)^2$ since $f(y) = g(y)$. Instead of performing $2n + 1$ +multiplications to find the $\zeta$ relations, squaring operations are performed instead. + +\subsection{Karatsuba Squaring} +Let $f(x) = ax + b$ represent the polynomial basis representation of a number to square. +Let $h(x) = \left ( f(x) \right )^2$ represent the square of the polynomial. The Karatsuba equation can be modified to square a +number with the following equation. + +\begin{equation} +h(x) = a^2x^2 + \left ((a + b)^2 - (a^2 + b^2) \right )x + b^2 +\end{equation} + +Upon closer inspection this equation only requires the calculation of three half-sized squares: $a^2$, $b^2$ and $(a + b)^2$. As in +Karatsuba multiplication, this algorithm can be applied recursively on the input and will achieve an asymptotic running time of +$O \left ( n^{lg(3)} \right )$. + +If the asymptotic times of Karatsuba squaring and multiplication are the same, why not simply use the multiplication algorithm +instead? The answer to this arises from the cutoff point for squaring. As in multiplication there exists a cutoff point, at which the +time required for a Comba based squaring and a Karatsuba based squaring meet. Due to the overhead inherent in the Karatsuba method, the cutoff +point is fairly high. For example, on an AMD Athlon XP processor with $\beta = 2^{28}$, the cutoff point is around 127 digits. + +Consider squaring a 200 digit number with this technique. It will be split into two 100 digit halves which are subsequently squared. +The 100 digit halves will not be squared using Karatsuba, but instead using the faster Comba based squaring algorithm. If Karatsuba multiplication +were used instead, the 100 digit numbers would be squared with a slower Comba based multiplication. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_karatsuba\_sqr}. \\ +\textbf{Input}. mp\_int $a$ \\ +\textbf{Output}. $b \leftarrow a^2$ \\ +\hline \\ +1. Initialize the following temporary mp\_ints: $x0$, $x1$, $t1$, $t2$, $x0x0$ and $x1x1$. \\ +2. If any of the initializations on step 1 failed return(\textit{MP\_MEM}). \\ +\\ +Split the input. e.g. $a = x1\beta^B + x0$ \\ +3. $B \leftarrow \lfloor a.used / 2 \rfloor$ \\ +4. $x0 \leftarrow a \mbox{ (mod }\beta^B\mbox{)}$ (\textit{mp\_mod\_2d}) \\ +5. $x1 \leftarrow \lfloor a / \beta^B \rfloor$ (\textit{mp\_lshd}) \\ +\\ +Calculate the three squares. \\ +6. $x0x0 \leftarrow x0^2$ (\textit{mp\_sqr}) \\ +7. $x1x1 \leftarrow x1^2$ \\ +8. $t1 \leftarrow x1 + x0$ (\textit{s\_mp\_add}) \\ +9. $t1 \leftarrow t1^2$ \\ +\\ +Compute the middle term. \\ +10. $t2 \leftarrow x0x0 + x1x1$ (\textit{s\_mp\_add}) \\ +11. $t1 \leftarrow t1 - t2$ \\ +\\ +Compute final product. \\ +12. $t1 \leftarrow t1\beta^B$ (\textit{mp\_lshd}) \\ +13. $x1x1 \leftarrow x1x1\beta^{2B}$ \\ +14. $t1 \leftarrow t1 + x0x0$ \\ +15. $b \leftarrow t1 + x1x1$ \\ +16. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_karatsuba\_sqr} +\end{figure} + +\textbf{Algorithm mp\_karatsuba\_sqr.} +This algorithm computes the square of an input $a$ using the Karatsuba technique. This algorithm is very similar to the Karatsuba based +multiplication algorithm with the exception that the three half-size multiplications have been replaced with three half-size squarings. + +The radix point for squaring is simply placed exactly in the middle of the digits when the input has an odd number of digits, otherwise it is +placed just below the middle. Step 3, 4 and 5 compute the two halves required using $B$ +as the radix point. The first two squares in steps 6 and 7 are rather straightforward while the last square is of a more compact form. + +By expanding $\left (x1 + x0 \right )^2$, the $x1^2$ and $x0^2$ terms in the middle disappear, that is $(x0 - x1)^2 - (x1^2 + x0^2) = 2 \cdot x0 \cdot x1$. +Now if $5n$ single precision additions and a squaring of $n$-digits is faster than multiplying two $n$-digit numbers and doubling then +this method is faster. Assuming no further recursions occur, the difference can be estimated with the following inequality. + +Let $p$ represent the cost of a single precision addition and $q$ the cost of a single precision multiplication both in terms of time\footnote{Or +machine clock cycles.}. + +\begin{equation} +5pn +{{q(n^2 + n)} \over 2} \le pn + qn^2 +\end{equation} + +For example, on an AMD Athlon XP processor $p = {1 \over 3}$ and $q = 6$. This implies that the following inequality should hold. +\begin{center} +\begin{tabular}{rcl} +${5n \over 3} + 3n^2 + 3n$ & $<$ & ${n \over 3} + 6n^2$ \\ +${5 \over 3} + 3n + 3$ & $<$ & ${1 \over 3} + 6n$ \\ +${13 \over 9}$ & $<$ & $n$ \\ +\end{tabular} +\end{center} + +This results in a cutoff point around $n = 2$. As a consequence it is actually faster to compute the middle term the ``long way'' on processors +where multiplication is substantially slower\footnote{On the Athlon there is a 1:17 ratio between clock cycles for addition and multiplication. On +the Intel P4 processor this ratio is 1:29 making this method even more beneficial. The only common exception is the ARMv4 processor which has a +ratio of 1:7. } than simpler operations such as addition. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_karatsuba\_sqr.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +This implementation is largely based on the implementation of algorithm mp\_karatsuba\_mul. It uses the same inline style to copy and +shift the input into the two halves. The loop from line 54 to line 70 has been modified since only one input exists. The \textbf{used} +count of both $x0$ and $x1$ is fixed up and $x0$ is clamped before the calculations begin. At this point $x1$ and $x0$ are valid equivalents +to the respective halves as if mp\_rshd and mp\_mod\_2d had been used. + +By inlining the copy and shift operations the cutoff point for Karatsuba multiplication can be lowered. On the Athlon the cutoff point +is exactly at the point where Comba squaring can no longer be used (\textit{128 digits}). On slower processors such as the Intel P4 +it is actually below the Comba limit (\textit{at 110 digits}). + +This routine uses the same error trap coding style as mp\_karatsuba\_sqr. As the temporary variables are initialized errors are +redirected to the error trap higher up. If the algorithm completes without error the error code is set to \textbf{MP\_OKAY} and +mp\_clears are executed normally. + +\subsection{Toom-Cook Squaring} +The Toom-Cook squaring algorithm mp\_toom\_sqr is heavily based on the algorithm mp\_toom\_mul with the exception that squarings are used +instead of multiplication to find the five relations. The reader is encouraged to read the description of the latter algorithm and try to +derive their own Toom-Cook squaring algorithm. + +\subsection{High Level Squaring} +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_sqr}. \\ +\textbf{Input}. mp\_int $a$ \\ +\textbf{Output}. $b \leftarrow a^2$ \\ +\hline \\ +1. If $a.used \ge TOOM\_SQR\_CUTOFF$ then \\ +\hspace{3mm}1.1 $b \leftarrow a^2$ using algorithm mp\_toom\_sqr \\ +2. else if $a.used \ge KARATSUBA\_SQR\_CUTOFF$ then \\ +\hspace{3mm}2.1 $b \leftarrow a^2$ using algorithm mp\_karatsuba\_sqr \\ +3. else \\ +\hspace{3mm}3.1 $digs \leftarrow a.used + b.used + 1$ \\ +\hspace{3mm}3.2 If $digs < MP\_ARRAY$ and $a.used \le \delta$ then \\ +\hspace{6mm}3.2.1 $b \leftarrow a^2$ using algorithm fast\_s\_mp\_sqr. \\ +\hspace{3mm}3.3 else \\ +\hspace{6mm}3.3.1 $b \leftarrow a^2$ using algorithm s\_mp\_sqr. \\ +4. $b.sign \leftarrow MP\_ZPOS$ \\ +5. Return the result of the unsigned squaring performed. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_sqr} +\end{figure} + +\textbf{Algorithm mp\_sqr.} +This algorithm computes the square of the input using one of four different algorithms. If the input is very large and has at least +\textbf{TOOM\_SQR\_CUTOFF} or \textbf{KARATSUBA\_SQR\_CUTOFF} digits then either the Toom-Cook or the Karatsuba Squaring algorithm is used. If +neither of the polynomial basis algorithms should be used then either the Comba or baseline algorithm is used. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_sqr.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +\section*{Exercises} +\begin{tabular}{cl} +$\left [ 3 \right ] $ & Devise an efficient algorithm for selection of the radix point to handle inputs \\ + & that have different number of digits in Karatsuba multiplication. \\ + & \\ +$\left [ 2 \right ] $ & In section 5.3 the fact that every column of a squaring is made up \\ + & of double products and at most one square is stated. Prove this statement. \\ + & \\ +$\left [ 3 \right ] $ & Prove the equation for Karatsuba squaring. \\ + & \\ +$\left [ 1 \right ] $ & Prove that Karatsuba squaring requires $O \left (n^{lg(3)} \right )$ time. \\ + & \\ +$\left [ 2 \right ] $ & Determine the minimal ratio between addition and multiplication clock cycles \\ + & required for equation $6.7$ to be true. \\ + & \\ +$\left [ 3 \right ] $ & Implement a threaded version of Comba multiplication (and squaring) where you \\ + & compute subsets of the columns in each thread. Determine a cutoff point where \\ + & it is effective and add the logic to mp\_mul() and mp\_sqr(). \\ + &\\ +$\left [ 4 \right ] $ & Same as the previous but also modify the Karatsuba and Toom-Cook. You must \\ + & increase the throughput of mp\_exptmod() for random odd moduli in the range \\ + & $512 \ldots 4096$ bits significantly ($> 2x$) to complete this challenge. \\ + & \\ +\end{tabular} + +\chapter{Modular Reduction} +\section{Basics of Modular Reduction} +\index{modular residue} +Modular reduction is an operation that arises quite often within public key cryptography algorithms and various number theoretic algorithms, +such as factoring. Modular reduction algorithms are the third class of algorithms of the ``multipliers'' set. A number $a$ is said to be \textit{reduced} +modulo another number $b$ by finding the remainder of the division $a/b$. Full integer division with remainder is a topic to be covered +in~\ref{sec:division}. + +Modular reduction is equivalent to solving for $r$ in the following equation. $a = bq + r$ where $q = \lfloor a/b \rfloor$. The result +$r$ is said to be ``congruent to $a$ modulo $b$'' which is also written as $r \equiv a \mbox{ (mod }b\mbox{)}$. In other vernacular $r$ is known as the +``modular residue'' which leads to ``quadratic residue''\footnote{That's fancy talk for $b \equiv a^2 \mbox{ (mod }p\mbox{)}$.} and +other forms of residues. + +Modular reductions are normally used to create either finite groups, rings or fields. The most common usage for performance driven modular reductions +is in modular exponentiation algorithms. That is to compute $d = a^b \mbox{ (mod }c\mbox{)}$ as fast as possible. This operation is used in the +RSA and Diffie-Hellman public key algorithms, for example. Modular multiplication and squaring also appears as a fundamental operation in +elliptic curve cryptographic algorithms. As will be discussed in the subsequent chapter there exist fast algorithms for computing modular +exponentiations without having to perform (\textit{in this example}) $b - 1$ multiplications. These algorithms will produce partial results in the +range $0 \le x < c^2$ which can be taken advantage of to create several efficient algorithms. They have also been used to create redundancy check +algorithms known as CRCs, error correction codes such as Reed-Solomon and solve a variety of number theoeretic problems. + +\section{The Barrett Reduction} +The Barrett reduction algorithm \cite{BARRETT} was inspired by fast division algorithms which multiply by the reciprocal to emulate +division. Barretts observation was that the residue $c$ of $a$ modulo $b$ is equal to + +\begin{equation} +c = a - b \cdot \lfloor a/b \rfloor +\end{equation} + +Since algorithms such as modular exponentiation would be using the same modulus extensively, typical DSP\footnote{It is worth noting that Barrett's paper +targeted the DSP56K processor.} intuition would indicate the next step would be to replace $a/b$ by a multiplication by the reciprocal. However, +DSP intuition on its own will not work as these numbers are considerably larger than the precision of common DSP floating point data types. +It would take another common optimization to optimize the algorithm. + +\subsection{Fixed Point Arithmetic} +The trick used to optimize the above equation is based on a technique of emulating floating point data types with fixed precision integers. Fixed +point arithmetic would become very popular as it greatly optimize the ``3d-shooter'' genre of games in the mid 1990s when floating point units were +fairly slow if not unavailable. The idea behind fixed point arithmetic is to take a normal $k$-bit integer data type and break it into $p$-bit +integer and a $q$-bit fraction part (\textit{where $p+q = k$}). + +In this system a $k$-bit integer $n$ would actually represent $n/2^q$. For example, with $q = 4$ the integer $n = 37$ would actually represent the +value $2.3125$. To multiply two fixed point numbers the integers are multiplied using traditional arithmetic and subsequently normalized by +moving the implied decimal point back to where it should be. For example, with $q = 4$ to multiply the integers $9$ and $5$ they must be converted +to fixed point first by multiplying by $2^q$. Let $a = 9(2^q)$ represent the fixed point representation of $9$ and $b = 5(2^q)$ represent the +fixed point representation of $5$. The product $ab$ is equal to $45(2^{2q})$ which when normalized by dividing by $2^q$ produces $45(2^q)$. + +This technique became popular since a normal integer multiplication and logical shift right are the only required operations to perform a multiplication +of two fixed point numbers. Using fixed point arithmetic, division can be easily approximated by multiplying by the reciprocal. If $2^q$ is +equivalent to one than $2^q/b$ is equivalent to the fixed point approximation of $1/b$ using real arithmetic. Using this fact dividing an integer +$a$ by another integer $b$ can be achieved with the following expression. + +\begin{equation} +\lfloor a / b \rfloor \mbox{ }\approx\mbox{ } \lfloor (a \cdot \lfloor 2^q / b \rfloor)/2^q \rfloor +\end{equation} + +The precision of the division is proportional to the value of $q$. If the divisor $b$ is used frequently as is the case with +modular exponentiation pre-computing $2^q/b$ will allow a division to be performed with a multiplication and a right shift. Both operations +are considerably faster than division on most processors. + +Consider dividing $19$ by $5$. The correct result is $\lfloor 19/5 \rfloor = 3$. With $q = 3$ the reciprocal is $\lfloor 2^q/5 \rfloor = 1$ which +leads to a product of $19$ which when divided by $2^q$ produces $2$. However, with $q = 4$ the reciprocal is $\lfloor 2^q/5 \rfloor = 3$ and +the result of the emulated division is $\lfloor 3 \cdot 19 / 2^q \rfloor = 3$ which is correct. The value of $2^q$ must be close to or ideally +larger than the dividend. In effect if $a$ is the dividend then $q$ should allow $0 \le \lfloor a/2^q \rfloor \le 1$ in order for this approach +to work correctly. Plugging this form of divison into the original equation the following modular residue equation arises. + +\begin{equation} +c = a - b \cdot \lfloor (a \cdot \lfloor 2^q / b \rfloor)/2^q \rfloor +\end{equation} + +Using the notation from \cite{BARRETT} the value of $\lfloor 2^q / b \rfloor$ will be represented by the $\mu$ symbol. Using the $\mu$ +variable also helps re-inforce the idea that it is meant to be computed once and re-used. + +\begin{equation} +c = a - b \cdot \lfloor (a \cdot \mu)/2^q \rfloor +\end{equation} + +Provided that $2^q \ge a$ this algorithm will produce a quotient that is either exactly correct or off by a value of one. In the context of Barrett +reduction the value of $a$ is bound by $0 \le a \le (b - 1)^2$ meaning that $2^q \ge b^2$ is sufficient to ensure the reciprocal will have enough +precision. + +Let $n$ represent the number of digits in $b$. This algorithm requires approximately $2n^2$ single precision multiplications to produce the quotient and +another $n^2$ single precision multiplications to find the residue. In total $3n^2$ single precision multiplications are required to +reduce the number. + +For example, if $b = 1179677$ and $q = 41$ ($2^q > b^2$), then the reciprocal $\mu$ is equal to $\lfloor 2^q / b \rfloor = 1864089$. Consider reducing +$a = 180388626447$ modulo $b$ using the above reduction equation. The quotient using the new formula is $\lfloor (a \cdot \mu) / 2^q \rfloor = 152913$. +By subtracting $152913b$ from $a$ the correct residue $a \equiv 677346 \mbox{ (mod }b\mbox{)}$ is found. + +\subsection{Choosing a Radix Point} +Using the fixed point representation a modular reduction can be performed with $3n^2$ single precision multiplications. If that were the best +that could be achieved a full division\footnote{A division requires approximately $O(2cn^2)$ single precision multiplications for a small value of $c$. +See~\ref{sec:division} for further details.} might as well be used in its place. The key to optimizing the reduction is to reduce the precision of +the initial multiplication that finds the quotient. + +Let $a$ represent the number of which the residue is sought. Let $b$ represent the modulus used to find the residue. Let $m$ represent +the number of digits in $b$. For the purposes of this discussion we will assume that the number of digits in $a$ is $2m$, which is generally true if +two $m$-digit numbers have been multiplied. Dividing $a$ by $b$ is the same as dividing a $2m$ digit integer by a $m$ digit integer. Digits below the +$m - 1$'th digit of $a$ will contribute at most a value of $1$ to the quotient because $\beta^k < b$ for any $0 \le k \le m - 1$. Another way to +express this is by re-writing $a$ as two parts. If $a' \equiv a \mbox{ (mod }b^m\mbox{)}$ and $a'' = a - a'$ then +${a \over b} \equiv {{a' + a''} \over b}$ which is equivalent to ${a' \over b} + {a'' \over b}$. Since $a'$ is bound to be less than $b$ the quotient +is bound by $0 \le {a' \over b} < 1$. + +Since the digits of $a'$ do not contribute much to the quotient the observation is that they might as well be zero. However, if the digits +``might as well be zero'' they might as well not be there in the first place. Let $q_0 = \lfloor a/\beta^{m-1} \rfloor$ represent the input +with the irrelevant digits trimmed. Now the modular reduction is trimmed to the almost equivalent equation + +\begin{equation} +c = a - b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor +\end{equation} + +Note that the original divisor $2^q$ has been replaced with $\beta^{m+1}$ where in this case $q$ is a multiple of $lg(\beta)$. Also note that the +exponent on the divisor when added to the amount $q_0$ was shifted by equals $2m$. If the optimization had not been performed the divisor +would have the exponent $2m$ so in the end the exponents do ``add up''. Using the above equation the quotient +$\lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor$ can be off from the true quotient by at most two. The original fixed point quotient can be off +by as much as one (\textit{provided the radix point is chosen suitably}) and now that the lower irrelevent digits have been trimmed the quotient +can be off by an additional value of one for a total of at most two. This implies that +$0 \le a - b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor < 3b$. By first subtracting $b$ times the quotient and then conditionally subtracting +$b$ once or twice the residue is found. + +The quotient is now found using $(m + 1)(m) = m^2 + m$ single precision multiplications and the residue with an additional $m^2$ single +precision multiplications, ignoring the subtractions required. In total $2m^2 + m$ single precision multiplications are required to find the residue. +This is considerably faster than the original attempt. + +For example, let $\beta = 10$ represent the radix of the digits. Let $b = 9999$ represent the modulus which implies $m = 4$. Let $a = 99929878$ +represent the value of which the residue is desired. In this case $q = 8$ since $10^7 < 9999^2$ meaning that $\mu = \lfloor \beta^{q}/b \rfloor = 10001$. +With the new observation the multiplicand for the quotient is equal to $q_0 = \lfloor a / \beta^{m - 1} \rfloor = 99929$. The quotient is then +$\lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor = 9993$. Subtracting $9993b$ from $a$ and the correct residue $a \equiv 9871 \mbox{ (mod }b\mbox{)}$ +is found. + +\subsection{Trimming the Quotient} +So far the reduction algorithm has been optimized from $3m^2$ single precision multiplications down to $2m^2 + m$ single precision multiplications. As +it stands now the algorithm is already fairly fast compared to a full integer division algorithm. However, there is still room for +optimization. + +After the first multiplication inside the quotient ($q_0 \cdot \mu$) the value is shifted right by $m + 1$ places effectively nullifying the lower +half of the product. It would be nice to be able to remove those digits from the product to effectively cut down the number of single precision +multiplications. If the number of digits in the modulus $m$ is far less than $\beta$ a full product is not required for the algorithm to work properly. +In fact the lower $m - 2$ digits will not affect the upper half of the product at all and do not need to be computed. + +The value of $\mu$ is a $m$-digit number and $q_0$ is a $m + 1$ digit number. Using a full multiplier $(m + 1)(m) = m^2 + m$ single precision +multiplications would be required. Using a multiplier that will only produce digits at and above the $m - 1$'th digit reduces the number +of single precision multiplications to ${m^2 + m} \over 2$ single precision multiplications. + +\subsection{Trimming the Residue} +After the quotient has been calculated it is used to reduce the input. As previously noted the algorithm is not exact and it can be off by a small +multiple of the modulus, that is $0 \le a - b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor < 3b$. If $b$ is $m$ digits than the +result of reduction equation is a value of at most $m + 1$ digits (\textit{provided $3 < \beta$}) implying that the upper $m - 1$ digits are +implicitly zero. + +The next optimization arises from this very fact. Instead of computing $b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor$ using a full +$O(m^2)$ multiplication algorithm only the lower $m+1$ digits of the product have to be computed. Similarly the value of $a$ can +be reduced modulo $\beta^{m+1}$ before the multiple of $b$ is subtracted which simplifes the subtraction as well. A multiplication that produces +only the lower $m+1$ digits requires ${m^2 + 3m - 2} \over 2$ single precision multiplications. + +With both optimizations in place the algorithm is the algorithm Barrett proposed. It requires $m^2 + 2m - 1$ single precision multiplications which +is considerably faster than the straightforward $3m^2$ method. + +\subsection{The Barrett Algorithm} +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_reduce}. \\ +\textbf{Input}. mp\_int $a$, mp\_int $b$ and $\mu = \lfloor \beta^{2m}/b \rfloor, m = \lceil lg_{\beta}(b) \rceil, (0 \le a < b^2, b > 1)$ \\ +\textbf{Output}. $a \mbox{ (mod }b\mbox{)}$ \\ +\hline \\ +Let $m$ represent the number of digits in $b$. \\ +1. Make a copy of $a$ and store it in $q$. (\textit{mp\_init\_copy}) \\ +2. $q \leftarrow \lfloor q / \beta^{m - 1} \rfloor$ (\textit{mp\_rshd}) \\ +\\ +Produce the quotient. \\ +3. $q \leftarrow q \cdot \mu$ (\textit{note: only produce digits at or above $m-1$}) \\ +4. $q \leftarrow \lfloor q / \beta^{m + 1} \rfloor$ \\ +\\ +Subtract the multiple of modulus from the input. \\ +5. $a \leftarrow a \mbox{ (mod }\beta^{m+1}\mbox{)}$ (\textit{mp\_mod\_2d}) \\ +6. $q \leftarrow q \cdot b \mbox{ (mod }\beta^{m+1}\mbox{)}$ (\textit{s\_mp\_mul\_digs}) \\ +7. $a \leftarrow a - q$ (\textit{mp\_sub}) \\ +\\ +Add $\beta^{m+1}$ if a carry occured. \\ +8. If $a < 0$ then (\textit{mp\_cmp\_d}) \\ +\hspace{3mm}8.1 $q \leftarrow 1$ (\textit{mp\_set}) \\ +\hspace{3mm}8.2 $q \leftarrow q \cdot \beta^{m+1}$ (\textit{mp\_lshd}) \\ +\hspace{3mm}8.3 $a \leftarrow a + q$ \\ +\\ +Now subtract the modulus if the residue is too large (e.g. quotient too small). \\ +9. While $a \ge b$ do (\textit{mp\_cmp}) \\ +\hspace{3mm}9.1 $c \leftarrow a - b$ \\ +10. Clear $q$. \\ +11. Return(\textit{MP\_OKAY}) \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_reduce} +\end{figure} + +\textbf{Algorithm mp\_reduce.} +This algorithm will reduce the input $a$ modulo $b$ in place using the Barrett algorithm. It is loosely based on algorithm 14.42 of HAC +\cite[pp. 602]{HAC} which is based on the paper from Paul Barrett \cite{BARRETT}. The algorithm has several restrictions and assumptions which must +be adhered to for the algorithm to work. + +First the modulus $b$ is assumed to be positive and greater than one. If the modulus were less than or equal to one than subtracting +a multiple of it would either accomplish nothing or actually enlarge the input. The input $a$ must be in the range $0 \le a < b^2$ in order +for the quotient to have enough precision. If $a$ is the product of two numbers that were already reduced modulo $b$, this will not be a problem. +Technically the algorithm will still work if $a \ge b^2$ but it will take much longer to finish. The value of $\mu$ is passed as an argument to this +algorithm and is assumed to be calculated and stored before the algorithm is used. + +Recall that the multiplication for the quotient on step 3 must only produce digits at or above the $m-1$'th position. An algorithm called +$s\_mp\_mul\_high\_digs$ which has not been presented is used to accomplish this task. The algorithm is based on $s\_mp\_mul\_digs$ except that +instead of stopping at a given level of precision it starts at a given level of precision. This optimal algorithm can only be used if the number +of digits in $b$ is very much smaller than $\beta$. + +While it is known that +$a \ge b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor$ only the lower $m+1$ digits are being used to compute the residue, so an implied +``borrow'' from the higher digits might leave a negative result. After the multiple of the modulus has been subtracted from $a$ the residue must be +fixed up in case it is negative. The invariant $\beta^{m+1}$ must be added to the residue to make it positive again. + +The while loop at step 9 will subtract $b$ until the residue is less than $b$. If the algorithm is performed correctly this step is +performed at most twice, and on average once. However, if $a \ge b^2$ than it will iterate substantially more times than it should. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_reduce.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +The first multiplication that determines the quotient can be performed by only producing the digits from $m - 1$ and up. This essentially halves +the number of single precision multiplications required. However, the optimization is only safe if $\beta$ is much larger than the number of digits +in the modulus. In the source code this is evaluated on lines 36 to 44 where algorithm s\_mp\_mul\_high\_digs is used when it is +safe to do so. + +\subsection{The Barrett Setup Algorithm} +In order to use algorithm mp\_reduce the value of $\mu$ must be calculated in advance. Ideally this value should be computed once and stored for +future use so that the Barrett algorithm can be used without delay. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_reduce\_setup}. \\ +\textbf{Input}. mp\_int $a$ ($a > 1$) \\ +\textbf{Output}. $\mu \leftarrow \lfloor \beta^{2m}/a \rfloor$ \\ +\hline \\ +1. $\mu \leftarrow 2^{2 \cdot lg(\beta) \cdot m}$ (\textit{mp\_2expt}) \\ +2. $\mu \leftarrow \lfloor \mu / b \rfloor$ (\textit{mp\_div}) \\ +3. Return(\textit{MP\_OKAY}) \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_reduce\_setup} +\end{figure} + +\textbf{Algorithm mp\_reduce\_setup.} +This algorithm computes the reciprocal $\mu$ required for Barrett reduction. First $\beta^{2m}$ is calculated as $2^{2 \cdot lg(\beta) \cdot m}$ which +is equivalent and much faster. The final value is computed by taking the integer quotient of $\lfloor \mu / b \rfloor$. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_reduce\_setup.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +This simple routine calculates the reciprocal $\mu$ required by Barrett reduction. Note the extended usage of algorithm mp\_div where the variable +which would received the remainder is passed as NULL. As will be discussed in~\ref{sec:division} the division routine allows both the quotient and the +remainder to be passed as NULL meaning to ignore the value. + +\section{The Montgomery Reduction} +Montgomery reduction\footnote{Thanks to Niels Ferguson for his insightful explanation of the algorithm.} \cite{MONT} is by far the most interesting +form of reduction in common use. It computes a modular residue which is not actually equal to the residue of the input yet instead equal to a +residue times a constant. However, as perplexing as this may sound the algorithm is relatively simple and very efficient. + +Throughout this entire section the variable $n$ will represent the modulus used to form the residue. As will be discussed shortly the value of +$n$ must be odd. The variable $x$ will represent the quantity of which the residue is sought. Similar to the Barrett algorithm the input +is restricted to $0 \le x < n^2$. To begin the description some simple number theory facts must be established. + +\textbf{Fact 1.} Adding $n$ to $x$ does not change the residue since in effect it adds one to the quotient $\lfloor x / n \rfloor$. Another way +to explain this is that $n$ is (\textit{or multiples of $n$ are}) congruent to zero modulo $n$. Adding zero will not change the value of the residue. + +\textbf{Fact 2.} If $x$ is even then performing a division by two in $\Z$ is congruent to $x \cdot 2^{-1} \mbox{ (mod }n\mbox{)}$. Actually +this is an application of the fact that if $x$ is evenly divisible by any $k \in \Z$ then division in $\Z$ will be congruent to +multiplication by $k^{-1}$ modulo $n$. + +From these two simple facts the following simple algorithm can be derived. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{Montgomery Reduction}. \\ +\textbf{Input}. Integer $x$, $n$ and $k$ \\ +\textbf{Output}. $2^{-k}x \mbox{ (mod }n\mbox{)}$ \\ +\hline \\ +1. for $t$ from $1$ to $k$ do \\ +\hspace{3mm}1.1 If $x$ is odd then \\ +\hspace{6mm}1.1.1 $x \leftarrow x + n$ \\ +\hspace{3mm}1.2 $x \leftarrow x/2$ \\ +2. Return $x$. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm Montgomery Reduction} +\end{figure} + +The algorithm reduces the input one bit at a time using the two congruencies stated previously. Inside the loop $n$, which is odd, is +added to $x$ if $x$ is odd. This forces $x$ to be even which allows the division by two in $\Z$ to be congruent to a modular division by two. Since +$x$ is assumed to be initially much larger than $n$ the addition of $n$ will contribute an insignificant magnitude to $x$. Let $r$ represent the +final result of the Montgomery algorithm. If $k > lg(n)$ and $0 \le x < n^2$ then the final result is limited to +$0 \le r < \lfloor x/2^k \rfloor + n$. As a result at most a single subtraction is required to get the residue desired. + +\begin{figure}[here] +\begin{small} +\begin{center} +\begin{tabular}{|c|l|} +\hline \textbf{Step number ($t$)} & \textbf{Result ($x$)} \\ +\hline $1$ & $x + n = 5812$, $x/2 = 2906$ \\ +\hline $2$ & $x/2 = 1453$ \\ +\hline $3$ & $x + n = 1710$, $x/2 = 855$ \\ +\hline $4$ & $x + n = 1112$, $x/2 = 556$ \\ +\hline $5$ & $x/2 = 278$ \\ +\hline $6$ & $x/2 = 139$ \\ +\hline $7$ & $x + n = 396$, $x/2 = 198$ \\ +\hline $8$ & $x/2 = 99$ \\ +\hline $9$ & $x + n = 356$, $x/2 = 178$ \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Example of Montgomery Reduction (I)} +\label{fig:MONT1} +\end{figure} + +Consider the example in figure~\ref{fig:MONT1} which reduces $x = 5555$ modulo $n = 257$ when $k = 9$ (note $\beta^k = 512$ which is larger than $n$). The result of +the algorithm $r = 178$ is congruent to the value of $2^{-9} \cdot 5555 \mbox{ (mod }257\mbox{)}$. When $r$ is multiplied by $2^9$ modulo $257$ the correct residue +$r \equiv 158$ is produced. + +Let $k = \lfloor lg(n) \rfloor + 1$ represent the number of bits in $n$. The current algorithm requires $2k^2$ single precision shifts +and $k^2$ single precision additions. At this rate the algorithm is most certainly slower than Barrett reduction and not terribly useful. +Fortunately there exists an alternative representation of the algorithm. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{Montgomery Reduction} (modified I). \\ +\textbf{Input}. Integer $x$, $n$ and $k$ ($2^k > n$) \\ +\textbf{Output}. $2^{-k}x \mbox{ (mod }n\mbox{)}$ \\ +\hline \\ +1. for $t$ from $1$ to $k$ do \\ +\hspace{3mm}1.1 If the $t$'th bit of $x$ is one then \\ +\hspace{6mm}1.1.1 $x \leftarrow x + 2^tn$ \\ +2. Return $x/2^k$. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm Montgomery Reduction (modified I)} +\end{figure} + +This algorithm is equivalent since $2^tn$ is a multiple of $n$ and the lower $k$ bits of $x$ are zero by step 2. The number of single +precision shifts has now been reduced from $2k^2$ to $k^2 + k$ which is only a small improvement. + +\begin{figure}[here] +\begin{small} +\begin{center} +\begin{tabular}{|c|l|r|} +\hline \textbf{Step number ($t$)} & \textbf{Result ($x$)} & \textbf{Result ($x$) in Binary} \\ +\hline -- & $5555$ & $1010110110011$ \\ +\hline $1$ & $x + 2^{0}n = 5812$ & $1011010110100$ \\ +\hline $2$ & $5812$ & $1011010110100$ \\ +\hline $3$ & $x + 2^{2}n = 6840$ & $1101010111000$ \\ +\hline $4$ & $x + 2^{3}n = 8896$ & $10001011000000$ \\ +\hline $5$ & $8896$ & $10001011000000$ \\ +\hline $6$ & $8896$ & $10001011000000$ \\ +\hline $7$ & $x + 2^{6}n = 25344$ & $110001100000000$ \\ +\hline $8$ & $25344$ & $110001100000000$ \\ +\hline $9$ & $x + 2^{7}n = 91136$ & $10110010000000000$ \\ +\hline -- & $x/2^k = 178$ & \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Example of Montgomery Reduction (II)} +\label{fig:MONT2} +\end{figure} + +Figure~\ref{fig:MONT2} demonstrates the modified algorithm reducing $x = 5555$ modulo $n = 257$ with $k = 9$. +With this algorithm a single shift right at the end is the only right shift required to reduce the input instead of $k$ right shifts inside the +loop. Note that for the iterations $t = 2, 5, 6$ and $8$ where the result $x$ is not changed. In those iterations the $t$'th bit of $x$ is +zero and the appropriate multiple of $n$ does not need to be added to force the $t$'th bit of the result to zero. + +\subsection{Digit Based Montgomery Reduction} +Instead of computing the reduction on a bit-by-bit basis it is actually much faster to compute it on digit-by-digit basis. Consider the +previous algorithm re-written to compute the Montgomery reduction in this new fashion. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{Montgomery Reduction} (modified II). \\ +\textbf{Input}. Integer $x$, $n$ and $k$ ($\beta^k > n$) \\ +\textbf{Output}. $\beta^{-k}x \mbox{ (mod }n\mbox{)}$ \\ +\hline \\ +1. for $t$ from $0$ to $k - 1$ do \\ +\hspace{3mm}1.1 $x \leftarrow x + \mu n \beta^t$ \\ +2. Return $x/\beta^k$. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm Montgomery Reduction (modified II)} +\end{figure} + +The value $\mu n \beta^t$ is a multiple of the modulus $n$ meaning that it will not change the residue. If the first digit of +the value $\mu n \beta^t$ equals the negative (modulo $\beta$) of the $t$'th digit of $x$ then the addition will result in a zero digit. This +problem breaks down to solving the following congruency. + +\begin{center} +\begin{tabular}{rcl} +$x_t + \mu n_0$ & $\equiv$ & $0 \mbox{ (mod }\beta\mbox{)}$ \\ +$\mu n_0$ & $\equiv$ & $-x_t \mbox{ (mod }\beta\mbox{)}$ \\ +$\mu$ & $\equiv$ & $-x_t/n_0 \mbox{ (mod }\beta\mbox{)}$ \\ +\end{tabular} +\end{center} + +In each iteration of the loop on step 1 a new value of $\mu$ must be calculated. The value of $-1/n_0 \mbox{ (mod }\beta\mbox{)}$ is used +extensively in this algorithm and should be precomputed. Let $\rho$ represent the negative of the modular inverse of $n_0$ modulo $\beta$. + +For example, let $\beta = 10$ represent the radix. Let $n = 17$ represent the modulus which implies $k = 2$ and $\rho \equiv 7$. Let $x = 33$ +represent the value to reduce. + +\newpage\begin{figure} +\begin{center} +\begin{tabular}{|c|c|c|} +\hline \textbf{Step ($t$)} & \textbf{Value of $x$} & \textbf{Value of $\mu$} \\ +\hline -- & $33$ & --\\ +\hline $0$ & $33 + \mu n = 50$ & $1$ \\ +\hline $1$ & $50 + \mu n \beta = 900$ & $5$ \\ +\hline +\end{tabular} +\end{center} +\caption{Example of Montgomery Reduction} +\end{figure} + +The final result $900$ is then divided by $\beta^k$ to produce the final result $9$. The first observation is that $9 \nequiv x \mbox{ (mod }n\mbox{)}$ +which implies the result is not the modular residue of $x$ modulo $n$. However, recall that the residue is actually multiplied by $\beta^{-k}$ in +the algorithm. To get the true residue the value must be multiplied by $\beta^k$. In this case $\beta^k \equiv 15 \mbox{ (mod }n\mbox{)}$ and +the correct residue is $9 \cdot 15 \equiv 16 \mbox{ (mod }n\mbox{)}$. + +\subsection{Baseline Montgomery Reduction} +The baseline Montgomery reduction algorithm will produce the residue for any size input. It is designed to be a catch-all algororithm for +Montgomery reductions. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_montgomery\_reduce}. \\ +\textbf{Input}. mp\_int $x$, mp\_int $n$ and a digit $\rho \equiv -1/n_0 \mbox{ (mod }n\mbox{)}$. \\ +\hspace{11.5mm}($0 \le x < n^2, n > 1, (n, \beta) = 1, \beta^k > n$) \\ +\textbf{Output}. $\beta^{-k}x \mbox{ (mod }n\mbox{)}$ \\ +\hline \\ +1. $digs \leftarrow 2n.used + 1$ \\ +2. If $digs < MP\_ARRAY$ and $m.used < \delta$ then \\ +\hspace{3mm}2.1 Use algorithm fast\_mp\_montgomery\_reduce instead. \\ +\\ +Setup $x$ for the reduction. \\ +3. If $x.alloc < digs$ then grow $x$ to $digs$ digits. \\ +4. $x.used \leftarrow digs$ \\ +\\ +Eliminate the lower $k$ digits. \\ +5. For $ix$ from $0$ to $k - 1$ do \\ +\hspace{3mm}5.1 $\mu \leftarrow x_{ix} \cdot \rho \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{3mm}5.2 $u \leftarrow 0$ \\ +\hspace{3mm}5.3 For $iy$ from $0$ to $k - 1$ do \\ +\hspace{6mm}5.3.1 $\hat r \leftarrow \mu n_{iy} + x_{ix + iy} + u$ \\ +\hspace{6mm}5.3.2 $x_{ix + iy} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{6mm}5.3.3 $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\ +\hspace{3mm}5.4 While $u > 0$ do \\ +\hspace{6mm}5.4.1 $iy \leftarrow iy + 1$ \\ +\hspace{6mm}5.4.2 $x_{ix + iy} \leftarrow x_{ix + iy} + u$ \\ +\hspace{6mm}5.4.3 $u \leftarrow \lfloor x_{ix+iy} / \beta \rfloor$ \\ +\hspace{6mm}5.4.4 $x_{ix + iy} \leftarrow x_{ix+iy} \mbox{ (mod }\beta\mbox{)}$ \\ +\\ +Divide by $\beta^k$ and fix up as required. \\ +6. $x \leftarrow \lfloor x / \beta^k \rfloor$ \\ +7. If $x \ge n$ then \\ +\hspace{3mm}7.1 $x \leftarrow x - n$ \\ +8. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_montgomery\_reduce} +\end{figure} + +\textbf{Algorithm mp\_montgomery\_reduce.} +This algorithm reduces the input $x$ modulo $n$ in place using the Montgomery reduction algorithm. The algorithm is loosely based +on algorithm 14.32 of \cite[pp.601]{HAC} except it merges the multiplication of $\mu n \beta^t$ with the addition in the inner loop. The +restrictions on this algorithm are fairly easy to adapt to. First $0 \le x < n^2$ bounds the input to numbers in the same range as +for the Barrett algorithm. Additionally if $n > 1$ and $n$ is odd there will exist a modular inverse $\rho$. $\rho$ must be calculated in +advance of this algorithm. Finally the variable $k$ is fixed and a pseudonym for $n.used$. + +Step 2 decides whether a faster Montgomery algorithm can be used. It is based on the Comba technique meaning that there are limits on +the size of the input. This algorithm is discussed in sub-section 6.3.3. + +Step 5 is the main reduction loop of the algorithm. The value of $\mu$ is calculated once per iteration in the outer loop. The inner loop +calculates $x + \mu n \beta^{ix}$ by multiplying $\mu n$ and adding the result to $x$ shifted by $ix$ digits. Both the addition and +multiplication are performed in the same loop to save time and memory. Step 5.4 will handle any additional carries that escape the inner loop. + +Using a quick inspection this algorithm requires $n$ single precision multiplications for the outer loop and $n^2$ single precision multiplications +in the inner loop. In total $n^2 + n$ single precision multiplications which compares favourably to Barrett at $n^2 + 2n - 1$ single precision +multiplications. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_montgomery\_reduce.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +This is the baseline implementation of the Montgomery reduction algorithm. Lines 31 to 36 determine if the Comba based +routine can be used instead. Line 47 computes the value of $\mu$ for that particular iteration of the outer loop. + +The multiplication $\mu n \beta^{ix}$ is performed in one step in the inner loop. The alias $tmpx$ refers to the $ix$'th digit of $x$ and +the alias $tmpn$ refers to the modulus $n$. + +\subsection{Faster ``Comba'' Montgomery Reduction} + +The Montgomery reduction requires fewer single precision multiplications than a Barrett reduction, however it is much slower due to the serial +nature of the inner loop. The Barrett reduction algorithm requires two slightly modified multipliers which can be implemented with the Comba +technique. The Montgomery reduction algorithm cannot directly use the Comba technique to any significant advantage since the inner loop calculates +a $k \times 1$ product $k$ times. + +The biggest obstacle is that at the $ix$'th iteration of the outer loop the value of $x_{ix}$ is required to calculate $\mu$. This means the +carries from $0$ to $ix - 1$ must have been propagated upwards to form a valid $ix$'th digit. The solution as it turns out is very simple. +Perform a Comba like multiplier and inside the outer loop just after the inner loop fix up the $ix + 1$'th digit by forwarding the carry. + +With this change in place the Montgomery reduction algorithm can be performed with a Comba style multiplication loop which substantially increases +the speed of the algorithm. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{fast\_mp\_montgomery\_reduce}. \\ +\textbf{Input}. mp\_int $x$, mp\_int $n$ and a digit $\rho \equiv -1/n_0 \mbox{ (mod }n\mbox{)}$. \\ +\hspace{11.5mm}($0 \le x < n^2, n > 1, (n, \beta) = 1, \beta^k > n$) \\ +\textbf{Output}. $\beta^{-k}x \mbox{ (mod }n\mbox{)}$ \\ +\hline \\ +Place an array of \textbf{MP\_WARRAY} mp\_word variables called $\hat W$ on the stack. \\ +1. if $x.alloc < n.used + 1$ then grow $x$ to $n.used + 1$ digits. \\ +Copy the digits of $x$ into the array $\hat W$ \\ +2. For $ix$ from $0$ to $x.used - 1$ do \\ +\hspace{3mm}2.1 $\hat W_{ix} \leftarrow x_{ix}$ \\ +3. For $ix$ from $x.used$ to $2n.used - 1$ do \\ +\hspace{3mm}3.1 $\hat W_{ix} \leftarrow 0$ \\ +Elimiate the lower $k$ digits. \\ +4. for $ix$ from $0$ to $n.used - 1$ do \\ +\hspace{3mm}4.1 $\mu \leftarrow \hat W_{ix} \cdot \rho \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{3mm}4.2 For $iy$ from $0$ to $n.used - 1$ do \\ +\hspace{6mm}4.2.1 $\hat W_{iy + ix} \leftarrow \hat W_{iy + ix} + \mu \cdot n_{iy}$ \\ +\hspace{3mm}4.3 $\hat W_{ix + 1} \leftarrow \hat W_{ix + 1} + \lfloor \hat W_{ix} / \beta \rfloor$ \\ +Propagate carries upwards. \\ +5. for $ix$ from $n.used$ to $2n.used + 1$ do \\ +\hspace{3mm}5.1 $\hat W_{ix + 1} \leftarrow \hat W_{ix + 1} + \lfloor \hat W_{ix} / \beta \rfloor$ \\ +Shift right and reduce modulo $\beta$ simultaneously. \\ +6. for $ix$ from $0$ to $n.used + 1$ do \\ +\hspace{3mm}6.1 $x_{ix} \leftarrow \hat W_{ix + n.used} \mbox{ (mod }\beta\mbox{)}$ \\ +Zero excess digits and fixup $x$. \\ +7. if $x.used > n.used + 1$ then do \\ +\hspace{3mm}7.1 for $ix$ from $n.used + 1$ to $x.used - 1$ do \\ +\hspace{6mm}7.1.1 $x_{ix} \leftarrow 0$ \\ +8. $x.used \leftarrow n.used + 1$ \\ +9. Clamp excessive digits of $x$. \\ +10. If $x \ge n$ then \\ +\hspace{3mm}10.1 $x \leftarrow x - n$ \\ +11. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm fast\_mp\_montgomery\_reduce} +\end{figure} + +\textbf{Algorithm fast\_mp\_montgomery\_reduce.} +This algorithm will compute the Montgomery reduction of $x$ modulo $n$ using the Comba technique. It is on most computer platforms significantly +faster than algorithm mp\_montgomery\_reduce and algorithm mp\_reduce (\textit{Barrett reduction}). The algorithm has the same restrictions +on the input as the baseline reduction algorithm. An additional two restrictions are imposed on this algorithm. The number of digits $k$ in the +the modulus $n$ must not violate $MP\_WARRAY > 2k +1$ and $n < \delta$. When $\beta = 2^{28}$ this algorithm can be used to reduce modulo +a modulus of at most $3,556$ bits in length. + +As in the other Comba reduction algorithms there is a $\hat W$ array which stores the columns of the product. It is initially filled with the +contents of $x$ with the excess digits zeroed. The reduction loop is very similar the to the baseline loop at heart. The multiplication on step +4.1 can be single precision only since $ab \mbox{ (mod }\beta\mbox{)} \equiv (a \mbox{ mod }\beta)(b \mbox{ mod }\beta)$. Some multipliers such +as those on the ARM processors take a variable length time to complete depending on the number of bytes of result it must produce. By performing +a single precision multiplication instead half the amount of time is spent. + +Also note that digit $\hat W_{ix}$ must have the carry from the $ix - 1$'th digit propagated upwards in order for this to work. That is what step +4.3 will do. In effect over the $n.used$ iterations of the outer loop the $n.used$'th lower columns all have the their carries propagated forwards. Note +how the upper bits of those same words are not reduced modulo $\beta$. This is because those values will be discarded shortly and there is no +point. + +Step 5 will propagate the remainder of the carries upwards. On step 6 the columns are reduced modulo $\beta$ and shifted simultaneously as they are +stored in the destination $x$. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_fast\_mp\_montgomery\_reduce.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +The $\hat W$ array is first filled with digits of $x$ on line 48 then the rest of the digits are zeroed on line 55. Both loops share +the same alias variables to make the code easier to read. + +The value of $\mu$ is calculated in an interesting fashion. First the value $\hat W_{ix}$ is reduced modulo $\beta$ and cast to a mp\_digit. This +forces the compiler to use a single precision multiplication and prevents any concerns about loss of precision. Line 110 fixes the carry +for the next iteration of the loop by propagating the carry from $\hat W_{ix}$ to $\hat W_{ix+1}$. + +The for loop on line 109 propagates the rest of the carries upwards through the columns. The for loop on line 126 reduces the columns +modulo $\beta$ and shifts them $k$ places at the same time. The alias $\_ \hat W$ actually refers to the array $\hat W$ starting at the $n.used$'th +digit, that is $\_ \hat W_{t} = \hat W_{n.used + t}$. + +\subsection{Montgomery Setup} +To calculate the variable $\rho$ a relatively simple algorithm will be required. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_montgomery\_setup}. \\ +\textbf{Input}. mp\_int $n$ ($n > 1$ and $(n, 2) = 1$) \\ +\textbf{Output}. $\rho \equiv -1/n_0 \mbox{ (mod }\beta\mbox{)}$ \\ +\hline \\ +1. $b \leftarrow n_0$ \\ +2. If $b$ is even return(\textit{MP\_VAL}) \\ +3. $x \leftarrow (((b + 2) \mbox{ AND } 4) << 1) + b$ \\ +4. for $k$ from 0 to $\lceil lg(lg(\beta)) \rceil - 2$ do \\ +\hspace{3mm}4.1 $x \leftarrow x \cdot (2 - bx)$ \\ +5. $\rho \leftarrow \beta - x \mbox{ (mod }\beta\mbox{)}$ \\ +6. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_montgomery\_setup} +\end{figure} + +\textbf{Algorithm mp\_montgomery\_setup.} +This algorithm will calculate the value of $\rho$ required within the Montgomery reduction algorithms. It uses a very interesting trick +to calculate $1/n_0$ when $\beta$ is a power of two. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_montgomery\_setup.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +This source code computes the value of $\rho$ required to perform Montgomery reduction. It has been modified to avoid performing excess +multiplications when $\beta$ is not the default 28-bits. + +\section{The Diminished Radix Algorithm} +The Diminished Radix method of modular reduction \cite{DRMET} is a fairly clever technique which can be more efficient than either the Barrett +or Montgomery methods for certain forms of moduli. The technique is based on the following simple congruence. + +\begin{equation} +(x \mbox{ mod } n) + k \lfloor x / n \rfloor \equiv x \mbox{ (mod }(n - k)\mbox{)} +\end{equation} + +This observation was used in the MMB \cite{MMB} block cipher to create a diffusion primitive. It used the fact that if $n = 2^{31}$ and $k=1$ that +then a x86 multiplier could produce the 62-bit product and use the ``shrd'' instruction to perform a double-precision right shift. The proof +of the above equation is very simple. First write $x$ in the product form. + +\begin{equation} +x = qn + r +\end{equation} + +Now reduce both sides modulo $(n - k)$. + +\begin{equation} +x \equiv qk + r \mbox{ (mod }(n-k)\mbox{)} +\end{equation} + +The variable $n$ reduces modulo $n - k$ to $k$. By putting $q = \lfloor x/n \rfloor$ and $r = x \mbox{ mod } n$ +into the equation the original congruence is reproduced, thus concluding the proof. The following algorithm is based on this observation. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{Diminished Radix Reduction}. \\ +\textbf{Input}. Integer $x$, $n$, $k$ \\ +\textbf{Output}. $x \mbox{ mod } (n - k)$ \\ +\hline \\ +1. $q \leftarrow \lfloor x / n \rfloor$ \\ +2. $q \leftarrow k \cdot q$ \\ +3. $x \leftarrow x \mbox{ (mod }n\mbox{)}$ \\ +4. $x \leftarrow x + q$ \\ +5. If $x \ge (n - k)$ then \\ +\hspace{3mm}5.1 $x \leftarrow x - (n - k)$ \\ +\hspace{3mm}5.2 Goto step 1. \\ +6. Return $x$ \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm Diminished Radix Reduction} +\label{fig:DR} +\end{figure} + +This algorithm will reduce $x$ modulo $n - k$ and return the residue. If $0 \le x < (n - k)^2$ then the algorithm will loop almost always +once or twice and occasionally three times. For simplicity sake the value of $x$ is bounded by the following simple polynomial. + +\begin{equation} +0 \le x < n^2 + k^2 - 2nk +\end{equation} + +The true bound is $0 \le x < (n - k - 1)^2$ but this has quite a few more terms. The value of $q$ after step 1 is bounded by the following. + +\begin{equation} +q < n - 2k - k^2/n +\end{equation} + +Since $k^2$ is going to be considerably smaller than $n$ that term will always be zero. The value of $x$ after step 3 is bounded trivially as +$0 \le x < n$. By step four the sum $x + q$ is bounded by + +\begin{equation} +0 \le q + x < (k + 1)n - 2k^2 - 1 +\end{equation} + +With a second pass $q$ will be loosely bounded by $0 \le q < k^2$ after step 2 while $x$ will still be loosely bounded by $0 \le x < n$ after step 3. After the second pass it is highly unlike that the +sum in step 4 will exceed $n - k$. In practice fewer than three passes of the algorithm are required to reduce virtually every input in the +range $0 \le x < (n - k - 1)^2$. + +\begin{figure} +\begin{small} +\begin{center} +\begin{tabular}{|l|} +\hline +$x = 123456789, n = 256, k = 3$ \\ +\hline $q \leftarrow \lfloor x/n \rfloor = 482253$ \\ +$q \leftarrow q*k = 1446759$ \\ +$x \leftarrow x \mbox{ mod } n = 21$ \\ +$x \leftarrow x + q = 1446780$ \\ +$x \leftarrow x - (n - k) = 1446527$ \\ +\hline +$q \leftarrow \lfloor x/n \rfloor = 5650$ \\ +$q \leftarrow q*k = 16950$ \\ +$x \leftarrow x \mbox{ mod } n = 127$ \\ +$x \leftarrow x + q = 17077$ \\ +$x \leftarrow x - (n - k) = 16824$ \\ +\hline +$q \leftarrow \lfloor x/n \rfloor = 65$ \\ +$q \leftarrow q*k = 195$ \\ +$x \leftarrow x \mbox{ mod } n = 184$ \\ +$x \leftarrow x + q = 379$ \\ +$x \leftarrow x - (n - k) = 126$ \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Example Diminished Radix Reduction} +\label{fig:EXDR} +\end{figure} + +Figure~\ref{fig:EXDR} demonstrates the reduction of $x = 123456789$ modulo $n - k = 253$ when $n = 256$ and $k = 3$. Note that even while $x$ +is considerably larger than $(n - k - 1)^2 = 63504$ the algorithm still converges on the modular residue exceedingly fast. In this case only +three passes were required to find the residue $x \equiv 126$. + + +\subsection{Choice of Moduli} +On the surface this algorithm looks like a very expensive algorithm. It requires a couple of subtractions followed by multiplication and other +modular reductions. The usefulness of this algorithm becomes exceedingly clear when an appropriate modulus is chosen. + +Division in general is a very expensive operation to perform. The one exception is when the division is by a power of the radix of representation used. +Division by ten for example is simple for pencil and paper mathematics since it amounts to shifting the decimal place to the right. Similarly division +by two (\textit{or powers of two}) is very simple for binary computers to perform. It would therefore seem logical to choose $n$ of the form $2^p$ +which would imply that $\lfloor x / n \rfloor$ is a simple shift of $x$ right $p$ bits. + +However, there is one operation related to division of power of twos that is even faster than this. If $n = \beta^p$ then the division may be +performed by moving whole digits to the right $p$ places. In practice division by $\beta^p$ is much faster than division by $2^p$ for any $p$. +Also with the choice of $n = \beta^p$ reducing $x$ modulo $n$ merely requires zeroing the digits above the $p-1$'th digit of $x$. + +Throughout the next section the term ``restricted modulus'' will refer to a modulus of the form $\beta^p - k$ whereas the term ``unrestricted +modulus'' will refer to a modulus of the form $2^p - k$. The word ``restricted'' in this case refers to the fact that it is based on the +$2^p$ logic except $p$ must be a multiple of $lg(\beta)$. + +\subsection{Choice of $k$} +Now that division and reduction (\textit{step 1 and 3 of figure~\ref{fig:DR}}) have been optimized to simple digit operations the multiplication by $k$ +in step 2 is the most expensive operation. Fortunately the choice of $k$ is not terribly limited. For all intents and purposes it might +as well be a single digit. The smaller the value of $k$ is the faster the algorithm will be. + +\subsection{Restricted Diminished Radix Reduction} +The restricted Diminished Radix algorithm can quickly reduce an input modulo a modulus of the form $n = \beta^p - k$. This algorithm can reduce +an input $x$ within the range $0 \le x < n^2$ using only a couple passes of the algorithm demonstrated in figure~\ref{fig:DR}. The implementation +of this algorithm has been optimized to avoid additional overhead associated with a division by $\beta^p$, the multiplication by $k$ or the addition +of $x$ and $q$. The resulting algorithm is very efficient and can lead to substantial improvements over Barrett and Montgomery reduction when modular +exponentiations are performed. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_dr\_reduce}. \\ +\textbf{Input}. mp\_int $x$, $n$ and a mp\_digit $k = \beta - n_0$ \\ +\hspace{11.5mm}($0 \le x < n^2$, $n > 1$, $0 < k < \beta$) \\ +\textbf{Output}. $x \mbox{ mod } n$ \\ +\hline \\ +1. $m \leftarrow n.used$ \\ +2. If $x.alloc < 2m$ then grow $x$ to $2m$ digits. \\ +3. $\mu \leftarrow 0$ \\ +4. for $i$ from $0$ to $m - 1$ do \\ +\hspace{3mm}4.1 $\hat r \leftarrow k \cdot x_{m+i} + x_{i} + \mu$ \\ +\hspace{3mm}4.2 $x_{i} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{3mm}4.3 $\mu \leftarrow \lfloor \hat r / \beta \rfloor$ \\ +5. $x_{m} \leftarrow \mu$ \\ +6. for $i$ from $m + 1$ to $x.used - 1$ do \\ +\hspace{3mm}6.1 $x_{i} \leftarrow 0$ \\ +7. Clamp excess digits of $x$. \\ +8. If $x \ge n$ then \\ +\hspace{3mm}8.1 $x \leftarrow x - n$ \\ +\hspace{3mm}8.2 Goto step 3. \\ +9. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_dr\_reduce} +\end{figure} + +\textbf{Algorithm mp\_dr\_reduce.} +This algorithm will perform the Dimished Radix reduction of $x$ modulo $n$. It has similar restrictions to that of the Barrett reduction +with the addition that $n$ must be of the form $n = \beta^m - k$ where $0 < k <\beta$. + +This algorithm essentially implements the pseudo-code in figure~\ref{fig:DR} except with a slight optimization. The division by $\beta^m$, multiplication by $k$ +and addition of $x \mbox{ mod }\beta^m$ are all performed simultaneously inside the loop on step 4. The division by $\beta^m$ is emulated by accessing +the term at the $m+i$'th position which is subsequently multiplied by $k$ and added to the term at the $i$'th position. After the loop the $m$'th +digit is set to the carry and the upper digits are zeroed. Steps 5 and 6 emulate the reduction modulo $\beta^m$ that should have happend to +$x$ before the addition of the multiple of the upper half. + +At step 8 if $x$ is still larger than $n$ another pass of the algorithm is required. First $n$ is subtracted from $x$ and then the algorithm resumes +at step 3. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_dr\_reduce.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +The first step is to grow $x$ as required to $2m$ digits since the reduction is performed in place on $x$. The label on line 52 is where +the algorithm will resume if further reduction passes are required. In theory it could be placed at the top of the function however, the size of +the modulus and question of whether $x$ is large enough are invariant after the first pass meaning that it would be a waste of time. + +The aliases $tmpx1$ and $tmpx2$ refer to the digits of $x$ where the latter is offset by $m$ digits. By reading digits from $x$ offset by $m$ digits +a division by $\beta^m$ can be simulated virtually for free. The loop on line 64 performs the bulk of the work (\textit{corresponds to step 4 of algorithm 7.11}) +in this algorithm. + +By line 67 the pointer $tmpx1$ points to the $m$'th digit of $x$ which is where the final carry will be placed. Similarly by line 74 the +same pointer will point to the $m+1$'th digit where the zeroes will be placed. + +Since the algorithm is only valid if both $x$ and $n$ are greater than zero an unsigned comparison suffices to determine if another pass is required. +With the same logic at line 81 the value of $x$ is known to be greater than or equal to $n$ meaning that an unsigned subtraction can be used +as well. Since the destination of the subtraction is the larger of the inputs the call to algorithm s\_mp\_sub cannot fail and the return code +does not need to be checked. + +\subsubsection{Setup} +To setup the restricted Diminished Radix algorithm the value $k = \beta - n_0$ is required. This algorithm is not really complicated but provided for +completeness. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_dr\_setup}. \\ +\textbf{Input}. mp\_int $n$ \\ +\textbf{Output}. $k = \beta - n_0$ \\ +\hline \\ +1. $k \leftarrow \beta - n_0$ \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_dr\_setup} +\end{figure} + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_dr\_setup.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +\subsubsection{Modulus Detection} +Another algorithm which will be useful is the ability to detect a restricted Diminished Radix modulus. An integer is said to be +of restricted Diminished Radix form if all of the digits are equal to $\beta - 1$ except the trailing digit which may be any value. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_dr\_is\_modulus}. \\ +\textbf{Input}. mp\_int $n$ \\ +\textbf{Output}. $1$ if $n$ is in D.R form, $0$ otherwise \\ +\hline +1. If $n.used < 2$ then return($0$). \\ +2. for $ix$ from $1$ to $n.used - 1$ do \\ +\hspace{3mm}2.1 If $n_{ix} \ne \beta - 1$ return($0$). \\ +3. Return($1$). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_dr\_is\_modulus} +\end{figure} + +\textbf{Algorithm mp\_dr\_is\_modulus.} +This algorithm determines if a value is in Diminished Radix form. Step 1 rejects obvious cases where fewer than two digits are +in the mp\_int. Step 2 tests all but the first digit to see if they are equal to $\beta - 1$. If the algorithm manages to get to +step 3 then $n$ must be of Diminished Radix form. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_dr\_is\_modulus.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +\subsection{Unrestricted Diminished Radix Reduction} +The unrestricted Diminished Radix algorithm allows modular reductions to be performed when the modulus is of the form $2^p - k$. This algorithm +is a straightforward adaptation of algorithm~\ref{fig:DR}. + +In general the restricted Diminished Radix reduction algorithm is much faster since it has considerably lower overhead. However, this new +algorithm is much faster than either Montgomery or Barrett reduction when the moduli are of the appropriate form. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_reduce\_2k}. \\ +\textbf{Input}. mp\_int $a$ and $n$. mp\_digit $k$ \\ +\hspace{11.5mm}($a \ge 0$, $n > 1$, $0 < k < \beta$, $n + k$ is a power of two) \\ +\textbf{Output}. $a \mbox{ (mod }n\mbox{)}$ \\ +\hline +1. $p \leftarrow \lceil lg(n) \rceil$ (\textit{mp\_count\_bits}) \\ +2. While $a \ge n$ do \\ +\hspace{3mm}2.1 $q \leftarrow \lfloor a / 2^p \rfloor$ (\textit{mp\_div\_2d}) \\ +\hspace{3mm}2.2 $a \leftarrow a \mbox{ (mod }2^p\mbox{)}$ (\textit{mp\_mod\_2d}) \\ +\hspace{3mm}2.3 $q \leftarrow q \cdot k$ (\textit{mp\_mul\_d}) \\ +\hspace{3mm}2.4 $a \leftarrow a - q$ (\textit{s\_mp\_sub}) \\ +\hspace{3mm}2.5 If $a \ge n$ then do \\ +\hspace{6mm}2.5.1 $a \leftarrow a - n$ \\ +3. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_reduce\_2k} +\end{figure} + +\textbf{Algorithm mp\_reduce\_2k.} +This algorithm quickly reduces an input $a$ modulo an unrestricted Diminished Radix modulus $n$. Division by $2^p$ is emulated with a right +shift which makes the algorithm fairly inexpensive to use. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_reduce\_2k.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +The algorithm mp\_count\_bits calculates the number of bits in an mp\_int which is used to find the initial value of $p$. The call to mp\_div\_2d +on line 31 calculates both the quotient $q$ and the remainder $a$ required. By doing both in a single function call the code size +is kept fairly small. The multiplication by $k$ is only performed if $k > 1$. This allows reductions modulo $2^p - 1$ to be performed without +any multiplications. + +The unsigned s\_mp\_add, mp\_cmp\_mag and s\_mp\_sub are used in place of their full sign counterparts since the inputs are only valid if they are +positive. By using the unsigned versions the overhead is kept to a minimum. + +\subsubsection{Unrestricted Setup} +To setup this reduction algorithm the value of $k = 2^p - n$ is required. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_reduce\_2k\_setup}. \\ +\textbf{Input}. mp\_int $n$ \\ +\textbf{Output}. $k = 2^p - n$ \\ +\hline +1. $p \leftarrow \lceil lg(n) \rceil$ (\textit{mp\_count\_bits}) \\ +2. $x \leftarrow 2^p$ (\textit{mp\_2expt}) \\ +3. $x \leftarrow x - n$ (\textit{mp\_sub}) \\ +4. $k \leftarrow x_0$ \\ +5. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_reduce\_2k\_setup} +\end{figure} + +\textbf{Algorithm mp\_reduce\_2k\_setup.} +This algorithm computes the value of $k$ required for the algorithm mp\_reduce\_2k. By making a temporary variable $x$ equal to $2^p$ a subtraction +is sufficient to solve for $k$. Alternatively if $n$ has more than one digit the value of $k$ is simply $\beta - n_0$. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_reduce\_2k\_setup.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +\subsubsection{Unrestricted Detection} +An integer $n$ is a valid unrestricted Diminished Radix modulus if either of the following are true. + +\begin{enumerate} +\item The number has only one digit. +\item The number has more than one digit and every bit from the $\beta$'th to the most significant is one. +\end{enumerate} + +If either condition is true than there is a power of two $2^p$ such that $0 < 2^p - n < \beta$. If the input is only +one digit than it will always be of the correct form. Otherwise all of the bits above the first digit must be one. This arises from the fact +that there will be value of $k$ that when added to the modulus causes a carry in the first digit which propagates all the way to the most +significant bit. The resulting sum will be a power of two. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_reduce\_is\_2k}. \\ +\textbf{Input}. mp\_int $n$ \\ +\textbf{Output}. $1$ if of proper form, $0$ otherwise \\ +\hline +1. If $n.used = 0$ then return($0$). \\ +2. If $n.used = 1$ then return($1$). \\ +3. $p \leftarrow \lceil lg(n) \rceil$ (\textit{mp\_count\_bits}) \\ +4. for $x$ from $lg(\beta)$ to $p$ do \\ +\hspace{3mm}4.1 If the ($x \mbox{ mod }lg(\beta)$)'th bit of the $\lfloor x / lg(\beta) \rfloor$ of $n$ is zero then return($0$). \\ +5. Return($1$). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_reduce\_is\_2k} +\end{figure} + +\textbf{Algorithm mp\_reduce\_is\_2k.} +This algorithm quickly determines if a modulus is of the form required for algorithm mp\_reduce\_2k to function properly. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_reduce\_is\_2k.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + + + +\section{Algorithm Comparison} +So far three very different algorithms for modular reduction have been discussed. Each of the algorithms have their own strengths and weaknesses +that makes having such a selection very useful. The following table sumarizes the three algorithms along with comparisons of work factors. Since +all three algorithms have the restriction that $0 \le x < n^2$ and $n > 1$ those limitations are not included in the table. + +\begin{center} +\begin{small} +\begin{tabular}{|c|c|c|c|c|c|} +\hline \textbf{Method} & \textbf{Work Required} & \textbf{Limitations} & \textbf{$m = 8$} & \textbf{$m = 32$} & \textbf{$m = 64$} \\ +\hline Barrett & $m^2 + 2m - 1$ & None & $79$ & $1087$ & $4223$ \\ +\hline Montgomery & $m^2 + m$ & $n$ must be odd & $72$ & $1056$ & $4160$ \\ +\hline D.R. & $2m$ & $n = \beta^m - k$ & $16$ & $64$ & $128$ \\ +\hline +\end{tabular} +\end{small} +\end{center} + +In theory Montgomery and Barrett reductions would require roughly the same amount of time to complete. However, in practice since Montgomery +reduction can be written as a single function with the Comba technique it is much faster. Barrett reduction suffers from the overhead of +calling the half precision multipliers, addition and division by $\beta$ algorithms. + +For almost every cryptographic algorithm Montgomery reduction is the algorithm of choice. The one set of algorithms where Diminished Radix reduction truly +shines are based on the discrete logarithm problem such as Diffie-Hellman \cite{DH} and ElGamal \cite{ELGAMAL}. In these algorithms +primes of the form $\beta^m - k$ can be found and shared amongst users. These primes will allow the Diminished Radix algorithm to be used in +modular exponentiation to greatly speed up the operation. + + + +\section*{Exercises} +\begin{tabular}{cl} +$\left [ 3 \right ]$ & Prove that the ``trick'' in algorithm mp\_montgomery\_setup actually \\ + & calculates the correct value of $\rho$. \\ + & \\ +$\left [ 2 \right ]$ & Devise an algorithm to reduce modulo $n + k$ for small $k$ quickly. \\ + & \\ +$\left [ 4 \right ]$ & Prove that the pseudo-code algorithm ``Diminished Radix Reduction'' \\ + & (\textit{figure~\ref{fig:DR}}) terminates. Also prove the probability that it will \\ + & terminate within $1 \le k \le 10$ iterations. \\ + & \\ +\end{tabular} + + +\chapter{Exponentiation} +Exponentiation is the operation of raising one variable to the power of another, for example, $a^b$. A variant of exponentiation, computed +in a finite field or ring, is called modular exponentiation. This latter style of operation is typically used in public key +cryptosystems such as RSA and Diffie-Hellman. The ability to quickly compute modular exponentiations is of great benefit to any +such cryptosystem and many methods have been sought to speed it up. + +\section{Exponentiation Basics} +A trivial algorithm would simply multiply $a$ against itself $b - 1$ times to compute the exponentiation desired. However, as $b$ grows in size +the number of multiplications becomes prohibitive. Imagine what would happen if $b$ $\approx$ $2^{1024}$ as is the case when computing an RSA signature +with a $1024$-bit key. Such a calculation could never be completed as it would take simply far too long. + +Fortunately there is a very simple algorithm based on the laws of exponents. Recall that $lg_a(a^b) = b$ and that $lg_a(a^ba^c) = b + c$ which +are two trivial relationships between the base and the exponent. Let $b_i$ represent the $i$'th bit of $b$ starting from the least +significant bit. If $b$ is a $k$-bit integer than the following equation is true. + +\begin{equation} +a^b = \prod_{i=0}^{k-1} a^{2^i \cdot b_i} +\end{equation} + +By taking the base $a$ logarithm of both sides of the equation the following equation is the result. + +\begin{equation} +b = \sum_{i=0}^{k-1}2^i \cdot b_i +\end{equation} + +The term $a^{2^i}$ can be found from the $i - 1$'th term by squaring the term since $\left ( a^{2^i} \right )^2$ is equal to +$a^{2^{i+1}}$. This observation forms the basis of essentially all fast exponentiation algorithms. It requires $k$ squarings and on average +$k \over 2$ multiplications to compute the result. This is indeed quite an improvement over simply multiplying by $a$ a total of $b-1$ times. + +While this current method is a considerable speed up there are further improvements to be made. For example, the $a^{2^i}$ term does not need to +be computed in an auxilary variable. Consider the following equivalent algorithm. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{Left to Right Exponentiation}. \\ +\textbf{Input}. Integer $a$, $b$ and $k$ \\ +\textbf{Output}. $c = a^b$ \\ +\hline \\ +1. $c \leftarrow 1$ \\ +2. for $i$ from $k - 1$ to $0$ do \\ +\hspace{3mm}2.1 $c \leftarrow c^2$ \\ +\hspace{3mm}2.2 $c \leftarrow c \cdot a^{b_i}$ \\ +3. Return $c$. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Left to Right Exponentiation} +\label{fig:LTOR} +\end{figure} + +This algorithm starts from the most significant bit and works towards the least significant bit. When the $i$'th bit of $b$ is set $a$ is +multiplied against the current product. In each iteration the product is squared which doubles the exponent of the individual terms of the +product. + +For example, let $b = 101100_2 \equiv 44_{10}$. The following chart demonstrates the actions of the algorithm. + +\newpage\begin{figure} +\begin{center} +\begin{tabular}{|c|c|} +\hline \textbf{Value of $i$} & \textbf{Value of $c$} \\ +\hline - & $1$ \\ +\hline $5$ & $a$ \\ +\hline $4$ & $a^2$ \\ +\hline $3$ & $a^4 \cdot a$ \\ +\hline $2$ & $a^8 \cdot a^2 \cdot a$ \\ +\hline $1$ & $a^{16} \cdot a^4 \cdot a^2$ \\ +\hline $0$ & $a^{32} \cdot a^8 \cdot a^4$ \\ +\hline +\end{tabular} +\end{center} +\caption{Example of Left to Right Exponentiation} +\end{figure} + +When the product $a^{32} \cdot a^8 \cdot a^4$ is simplified it is equal $a^{44}$ which is the desired exponentiation. This particular algorithm is +called ``Left to Right'' because it reads the exponent in that order. All of the exponentiation algorithms that will be presented are of this nature. + +\subsection{Single Digit Exponentiation} +The first algorithm in the series of exponentiation algorithms will be an unbounded algorithm where the exponent is a single digit. It is intended +to be used when a small power of an input is required (\textit{e.g. $a^5$}). It is faster than simply multiplying $b - 1$ times for all values of +$b$ that are greater than three. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_expt\_d}. \\ +\textbf{Input}. mp\_int $a$ and mp\_digit $b$ \\ +\textbf{Output}. $c = a^b$ \\ +\hline \\ +1. $g \leftarrow a$ (\textit{mp\_init\_copy}) \\ +2. $c \leftarrow 1$ (\textit{mp\_set}) \\ +3. for $x$ from 1 to $lg(\beta)$ do \\ +\hspace{3mm}3.1 $c \leftarrow c^2$ (\textit{mp\_sqr}) \\ +\hspace{3mm}3.2 If $b$ AND $2^{lg(\beta) - 1} \ne 0$ then \\ +\hspace{6mm}3.2.1 $c \leftarrow c \cdot g$ (\textit{mp\_mul}) \\ +\hspace{3mm}3.3 $b \leftarrow b << 1$ \\ +4. Clear $g$. \\ +5. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_expt\_d} +\end{figure} + +\textbf{Algorithm mp\_expt\_d.} +This algorithm computes the value of $a$ raised to the power of a single digit $b$. It uses the left to right exponentiation algorithm to +quickly compute the exponentiation. It is loosely based on algorithm 14.79 of HAC \cite[pp. 615]{HAC} with the difference that the +exponent is a fixed width. + +A copy of $a$ is made first to allow destination variable $c$ be the same as the source variable $a$. The result is set to the initial value of +$1$ in the subsequent step. + +Inside the loop the exponent is read from the most significant bit first down to the least significant bit. First $c$ is invariably squared +on step 3.1. In the following step if the most significant bit of $b$ is one the copy of $a$ is multiplied against $c$. The value +of $b$ is shifted left one bit to make the next bit down from the most signficant bit the new most significant bit. In effect each +iteration of the loop moves the bits of the exponent $b$ upwards to the most significant location. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_expt\_d.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +Line 29 sets the initial value of the result to $1$. Next the loop on line 31 steps through each bit of the exponent starting from +the most significant down towards the least significant. The invariant squaring operation placed on line 33 is performed first. After +the squaring the result $c$ is multiplied by the base $g$ if and only if the most significant bit of the exponent is set. The shift on line +47 moves all of the bits of the exponent upwards towards the most significant location. + +\section{$k$-ary Exponentiation} +When calculating an exponentiation the most time consuming bottleneck is the multiplications which are in general a small factor +slower than squaring. Recall from the previous algorithm that $b_{i}$ refers to the $i$'th bit of the exponent $b$. Suppose instead it referred to +the $i$'th $k$-bit digit of the exponent of $b$. For $k = 1$ the definitions are synonymous and for $k > 1$ algorithm~\ref{fig:KARY} +computes the same exponentiation. A group of $k$ bits from the exponent is called a \textit{window}. That is it is a small window on only a +portion of the entire exponent. Consider the following modification to the basic left to right exponentiation algorithm. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{$k$-ary Exponentiation}. \\ +\textbf{Input}. Integer $a$, $b$, $k$ and $t$ \\ +\textbf{Output}. $c = a^b$ \\ +\hline \\ +1. $c \leftarrow 1$ \\ +2. for $i$ from $t - 1$ to $0$ do \\ +\hspace{3mm}2.1 $c \leftarrow c^{2^k} $ \\ +\hspace{3mm}2.2 Extract the $i$'th $k$-bit word from $b$ and store it in $g$. \\ +\hspace{3mm}2.3 $c \leftarrow c \cdot a^g$ \\ +3. Return $c$. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{$k$-ary Exponentiation} +\label{fig:KARY} +\end{figure} + +The squaring on step 2.1 can be calculated by squaring the value $c$ successively $k$ times. If the values of $a^g$ for $0 < g < 2^k$ have been +precomputed this algorithm requires only $t$ multiplications and $tk$ squarings. The table can be generated with $2^{k - 1} - 1$ squarings and +$2^{k - 1} + 1$ multiplications. This algorithm assumes that the number of bits in the exponent is evenly divisible by $k$. +However, when it is not the remaining $0 < x \le k - 1$ bits can be handled with algorithm~\ref{fig:LTOR}. + +Suppose $k = 4$ and $t = 100$. This modified algorithm will require $109$ multiplications and $408$ squarings to compute the exponentiation. The +original algorithm would on average have required $200$ multiplications and $400$ squrings to compute the same value. The total number of squarings +has increased slightly but the number of multiplications has nearly halved. + +\subsection{Optimal Values of $k$} +An optimal value of $k$ will minimize $2^{k} + \lceil n / k \rceil + n - 1$ for a fixed number of bits in the exponent $n$. The simplest +approach is to brute force search amongst the values $k = 2, 3, \ldots, 8$ for the lowest result. Table~\ref{fig:OPTK} lists optimal values of $k$ +for various exponent sizes and compares the number of multiplication and squarings required against algorithm~\ref{fig:LTOR}. + +\begin{figure}[here] +\begin{center} +\begin{small} +\begin{tabular}{|c|c|c|c|c|c|} +\hline \textbf{Exponent (bits)} & \textbf{Optimal $k$} & \textbf{Work at $k$} & \textbf{Work with ~\ref{fig:LTOR}} \\ +\hline $16$ & $2$ & $27$ & $24$ \\ +\hline $32$ & $3$ & $49$ & $48$ \\ +\hline $64$ & $3$ & $92$ & $96$ \\ +\hline $128$ & $4$ & $175$ & $192$ \\ +\hline $256$ & $4$ & $335$ & $384$ \\ +\hline $512$ & $5$ & $645$ & $768$ \\ +\hline $1024$ & $6$ & $1257$ & $1536$ \\ +\hline $2048$ & $6$ & $2452$ & $3072$ \\ +\hline $4096$ & $7$ & $4808$ & $6144$ \\ +\hline +\end{tabular} +\end{small} +\end{center} +\caption{Optimal Values of $k$ for $k$-ary Exponentiation} +\label{fig:OPTK} +\end{figure} + +\subsection{Sliding-Window Exponentiation} +A simple modification to the previous algorithm is only generate the upper half of the table in the range $2^{k-1} \le g < 2^k$. Essentially +this is a table for all values of $g$ where the most significant bit of $g$ is a one. However, in order for this to be allowed in the +algorithm values of $g$ in the range $0 \le g < 2^{k-1}$ must be avoided. + +Table~\ref{fig:OPTK2} lists optimal values of $k$ for various exponent sizes and compares the work required against algorithm~\ref{fig:KARY}. + +\begin{figure}[here] +\begin{center} +\begin{small} +\begin{tabular}{|c|c|c|c|c|c|} +\hline \textbf{Exponent (bits)} & \textbf{Optimal $k$} & \textbf{Work at $k$} & \textbf{Work with ~\ref{fig:KARY}} \\ +\hline $16$ & $3$ & $24$ & $27$ \\ +\hline $32$ & $3$ & $45$ & $49$ \\ +\hline $64$ & $4$ & $87$ & $92$ \\ +\hline $128$ & $4$ & $167$ & $175$ \\ +\hline $256$ & $5$ & $322$ & $335$ \\ +\hline $512$ & $6$ & $628$ & $645$ \\ +\hline $1024$ & $6$ & $1225$ & $1257$ \\ +\hline $2048$ & $7$ & $2403$ & $2452$ \\ +\hline $4096$ & $8$ & $4735$ & $4808$ \\ +\hline +\end{tabular} +\end{small} +\end{center} +\caption{Optimal Values of $k$ for Sliding Window Exponentiation} +\label{fig:OPTK2} +\end{figure} + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{Sliding Window $k$-ary Exponentiation}. \\ +\textbf{Input}. Integer $a$, $b$, $k$ and $t$ \\ +\textbf{Output}. $c = a^b$ \\ +\hline \\ +1. $c \leftarrow 1$ \\ +2. for $i$ from $t - 1$ to $0$ do \\ +\hspace{3mm}2.1 If the $i$'th bit of $b$ is a zero then \\ +\hspace{6mm}2.1.1 $c \leftarrow c^2$ \\ +\hspace{3mm}2.2 else do \\ +\hspace{6mm}2.2.1 $c \leftarrow c^{2^k}$ \\ +\hspace{6mm}2.2.2 Extract the $k$ bits from $(b_{i}b_{i-1}\ldots b_{i-(k-1)})$ and store it in $g$. \\ +\hspace{6mm}2.2.3 $c \leftarrow c \cdot a^g$ \\ +\hspace{6mm}2.2.4 $i \leftarrow i - k$ \\ +3. Return $c$. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Sliding Window $k$-ary Exponentiation} +\end{figure} + +Similar to the previous algorithm this algorithm must have a special handler when fewer than $k$ bits are left in the exponent. While this +algorithm requires the same number of squarings it can potentially have fewer multiplications. The pre-computed table $a^g$ is also half +the size as the previous table. + +Consider the exponent $b = 111101011001000_2 \equiv 31432_{10}$ with $k = 3$ using both algorithms. The first algorithm will divide the exponent up as +the following five $3$-bit words $b \equiv \left ( 111, 101, 011, 001, 000 \right )_{2}$. The second algorithm will break the +exponent as $b \equiv \left ( 111, 101, 0, 110, 0, 100, 0 \right )_{2}$. The single digit $0$ in the second representation are where +a single squaring took place instead of a squaring and multiplication. In total the first method requires $10$ multiplications and $18$ +squarings. The second method requires $8$ multiplications and $18$ squarings. + +In general the sliding window method is never slower than the generic $k$-ary method and often it is slightly faster. + +\section{Modular Exponentiation} + +Modular exponentiation is essentially computing the power of a base within a finite field or ring. For example, computing +$d \equiv a^b \mbox{ (mod }c\mbox{)}$ is a modular exponentiation. Instead of first computing $a^b$ and then reducing it +modulo $c$ the intermediate result is reduced modulo $c$ after every squaring or multiplication operation. + +This guarantees that any intermediate result is bounded by $0 \le d \le c^2 - 2c + 1$ and can be reduced modulo $c$ quickly using +one of the algorithms presented in chapter six. + +Before the actual modular exponentiation algorithm can be written a wrapper algorithm must be written first. This algorithm +will allow the exponent $b$ to be negative which is computed as $c \equiv \left (1 / a \right )^{\vert b \vert} \mbox{(mod }d\mbox{)}$. The +value of $(1/a) \mbox{ mod }c$ is computed using the modular inverse (\textit{see \ref{sec;modinv}}). If no inverse exists the algorithm +terminates with an error. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_exptmod}. \\ +\textbf{Input}. mp\_int $a$, $b$ and $c$ \\ +\textbf{Output}. $y \equiv g^x \mbox{ (mod }p\mbox{)}$ \\ +\hline \\ +1. If $c.sign = MP\_NEG$ return(\textit{MP\_VAL}). \\ +2. If $b.sign = MP\_NEG$ then \\ +\hspace{3mm}2.1 $g' \leftarrow g^{-1} \mbox{ (mod }c\mbox{)}$ \\ +\hspace{3mm}2.2 $x' \leftarrow \vert x \vert$ \\ +\hspace{3mm}2.3 Compute $d \equiv g'^{x'} \mbox{ (mod }c\mbox{)}$ via recursion. \\ +3. if $p$ is odd \textbf{OR} $p$ is a D.R. modulus then \\ +\hspace{3mm}3.1 Compute $y \equiv g^{x} \mbox{ (mod }p\mbox{)}$ via algorithm mp\_exptmod\_fast. \\ +4. else \\ +\hspace{3mm}4.1 Compute $y \equiv g^{x} \mbox{ (mod }p\mbox{)}$ via algorithm s\_mp\_exptmod. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_exptmod} +\end{figure} + +\textbf{Algorithm mp\_exptmod.} +The first algorithm which actually performs modular exponentiation is algorithm s\_mp\_exptmod. It is a sliding window $k$-ary algorithm +which uses Barrett reduction to reduce the product modulo $p$. The second algorithm mp\_exptmod\_fast performs the same operation +except it uses either Montgomery or Diminished Radix reduction. The two latter reduction algorithms are clumped in the same exponentiation +algorithm since their arguments are essentially the same (\textit{two mp\_ints and one mp\_digit}). + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_exptmod.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +In order to keep the algorithms in a known state the first step on line 29 is to reject any negative modulus as input. If the exponent is +negative the algorithm tries to perform a modular exponentiation with the modular inverse of the base $G$. The temporary variable $tmpG$ is assigned +the modular inverse of $G$ and $tmpX$ is assigned the absolute value of $X$. The algorithm will recuse with these new values with a positive +exponent. + +If the exponent is positive the algorithm resumes the exponentiation. Line 77 determines if the modulus is of the restricted Diminished Radix +form. If it is not line 70 attempts to determine if it is of a unrestricted Diminished Radix form. The integer $dr$ will take on one +of three values. + +\begin{enumerate} +\item $dr = 0$ means that the modulus is not of either restricted or unrestricted Diminished Radix form. +\item $dr = 1$ means that the modulus is of restricted Diminished Radix form. +\item $dr = 2$ means that the modulus is of unrestricted Diminished Radix form. +\end{enumerate} + +Line 69 determines if the fast modular exponentiation algorithm can be used. It is allowed if $dr \ne 0$ or if the modulus is odd. Otherwise, +the slower s\_mp\_exptmod algorithm is used which uses Barrett reduction. + +\subsection{Barrett Modular Exponentiation} + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{s\_mp\_exptmod}. \\ +\textbf{Input}. mp\_int $a$, $b$ and $c$ \\ +\textbf{Output}. $y \equiv g^x \mbox{ (mod }p\mbox{)}$ \\ +\hline \\ +1. $k \leftarrow lg(x)$ \\ +2. $winsize \leftarrow \left \lbrace \begin{array}{ll} + 2 & \mbox{if }k \le 7 \\ + 3 & \mbox{if }7 < k \le 36 \\ + 4 & \mbox{if }36 < k \le 140 \\ + 5 & \mbox{if }140 < k \le 450 \\ + 6 & \mbox{if }450 < k \le 1303 \\ + 7 & \mbox{if }1303 < k \le 3529 \\ + 8 & \mbox{if }3529 < k \\ + \end{array} \right .$ \\ +3. Initialize $2^{winsize}$ mp\_ints in an array named $M$ and one mp\_int named $\mu$ \\ +4. Calculate the $\mu$ required for Barrett Reduction (\textit{mp\_reduce\_setup}). \\ +5. $M_1 \leftarrow g \mbox{ (mod }p\mbox{)}$ \\ +\\ +Setup the table of small powers of $g$. First find $g^{2^{winsize}}$ and then all multiples of it. \\ +6. $k \leftarrow 2^{winsize - 1}$ \\ +7. $M_{k} \leftarrow M_1$ \\ +8. for $ix$ from 0 to $winsize - 2$ do \\ +\hspace{3mm}8.1 $M_k \leftarrow \left ( M_k \right )^2$ (\textit{mp\_sqr}) \\ +\hspace{3mm}8.2 $M_k \leftarrow M_k \mbox{ (mod }p\mbox{)}$ (\textit{mp\_reduce}) \\ +9. for $ix$ from $2^{winsize - 1} + 1$ to $2^{winsize} - 1$ do \\ +\hspace{3mm}9.1 $M_{ix} \leftarrow M_{ix - 1} \cdot M_{1}$ (\textit{mp\_mul}) \\ +\hspace{3mm}9.2 $M_{ix} \leftarrow M_{ix} \mbox{ (mod }p\mbox{)}$ (\textit{mp\_reduce}) \\ +10. $res \leftarrow 1$ \\ +\\ +Start Sliding Window. \\ +11. $mode \leftarrow 0, bitcnt \leftarrow 1, buf \leftarrow 0, digidx \leftarrow x.used - 1, bitcpy \leftarrow 0, bitbuf \leftarrow 0$ \\ +12. Loop \\ +\hspace{3mm}12.1 $bitcnt \leftarrow bitcnt - 1$ \\ +\hspace{3mm}12.2 If $bitcnt = 0$ then do \\ +\hspace{6mm}12.2.1 If $digidx = -1$ goto step 13. \\ +\hspace{6mm}12.2.2 $buf \leftarrow x_{digidx}$ \\ +\hspace{6mm}12.2.3 $digidx \leftarrow digidx - 1$ \\ +\hspace{6mm}12.2.4 $bitcnt \leftarrow lg(\beta)$ \\ +Continued on next page. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm s\_mp\_exptmod} +\end{figure} + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{s\_mp\_exptmod} (\textit{continued}). \\ +\textbf{Input}. mp\_int $a$, $b$ and $c$ \\ +\textbf{Output}. $y \equiv g^x \mbox{ (mod }p\mbox{)}$ \\ +\hline \\ +\hspace{3mm}12.3 $y \leftarrow (buf >> (lg(\beta) - 1))$ AND $1$ \\ +\hspace{3mm}12.4 $buf \leftarrow buf << 1$ \\ +\hspace{3mm}12.5 if $mode = 0$ and $y = 0$ then goto step 12. \\ +\hspace{3mm}12.6 if $mode = 1$ and $y = 0$ then do \\ +\hspace{6mm}12.6.1 $res \leftarrow res^2$ \\ +\hspace{6mm}12.6.2 $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\ +\hspace{6mm}12.6.3 Goto step 12. \\ +\hspace{3mm}12.7 $bitcpy \leftarrow bitcpy + 1$ \\ +\hspace{3mm}12.8 $bitbuf \leftarrow bitbuf + (y << (winsize - bitcpy))$ \\ +\hspace{3mm}12.9 $mode \leftarrow 2$ \\ +\hspace{3mm}12.10 If $bitcpy = winsize$ then do \\ +\hspace{6mm}Window is full so perform the squarings and single multiplication. \\ +\hspace{6mm}12.10.1 for $ix$ from $0$ to $winsize -1$ do \\ +\hspace{9mm}12.10.1.1 $res \leftarrow res^2$ \\ +\hspace{9mm}12.10.1.2 $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\ +\hspace{6mm}12.10.2 $res \leftarrow res \cdot M_{bitbuf}$ \\ +\hspace{6mm}12.10.3 $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\ +\hspace{6mm}Reset the window. \\ +\hspace{6mm}12.10.4 $bitcpy \leftarrow 0, bitbuf \leftarrow 0, mode \leftarrow 1$ \\ +\\ +No more windows left. Check for residual bits of exponent. \\ +13. If $mode = 2$ and $bitcpy > 0$ then do \\ +\hspace{3mm}13.1 for $ix$ form $0$ to $bitcpy - 1$ do \\ +\hspace{6mm}13.1.1 $res \leftarrow res^2$ \\ +\hspace{6mm}13.1.2 $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\ +\hspace{6mm}13.1.3 $bitbuf \leftarrow bitbuf << 1$ \\ +\hspace{6mm}13.1.4 If $bitbuf$ AND $2^{winsize} \ne 0$ then do \\ +\hspace{9mm}13.1.4.1 $res \leftarrow res \cdot M_{1}$ \\ +\hspace{9mm}13.1.4.2 $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\ +14. $y \leftarrow res$ \\ +15. Clear $res$, $mu$ and the $M$ array. \\ +16. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm s\_mp\_exptmod (continued)} +\end{figure} + +\textbf{Algorithm s\_mp\_exptmod.} +This algorithm computes the $x$'th power of $g$ modulo $p$ and stores the result in $y$. It takes advantage of the Barrett reduction +algorithm to keep the product small throughout the algorithm. + +The first two steps determine the optimal window size based on the number of bits in the exponent. The larger the exponent the +larger the window size becomes. After a window size $winsize$ has been chosen an array of $2^{winsize}$ mp\_int variables is allocated. This +table will hold the values of $g^x \mbox{ (mod }p\mbox{)}$ for $2^{winsize - 1} \le x < 2^{winsize}$. + +After the table is allocated the first power of $g$ is found. Since $g \ge p$ is allowed it must be first reduced modulo $p$ to make +the rest of the algorithm more efficient. The first element of the table at $2^{winsize - 1}$ is found by squaring $M_1$ successively $winsize - 2$ +times. The rest of the table elements are found by multiplying the previous element by $M_1$ modulo $p$. + +Now that the table is available the sliding window may begin. The following list describes the functions of all the variables in the window. +\begin{enumerate} +\item The variable $mode$ dictates how the bits of the exponent are interpreted. +\begin{enumerate} + \item When $mode = 0$ the bits are ignored since no non-zero bit of the exponent has been seen yet. For example, if the exponent were simply + $1$ then there would be $lg(\beta) - 1$ zero bits before the first non-zero bit. In this case bits are ignored until a non-zero bit is found. + \item When $mode = 1$ a non-zero bit has been seen before and a new $winsize$-bit window has not been formed yet. In this mode leading $0$ bits + are read and a single squaring is performed. If a non-zero bit is read a new window is created. + \item When $mode = 2$ the algorithm is in the middle of forming a window and new bits are appended to the window from the most significant bit + downwards. +\end{enumerate} +\item The variable $bitcnt$ indicates how many bits are left in the current digit of the exponent left to be read. When it reaches zero a new digit + is fetched from the exponent. +\item The variable $buf$ holds the currently read digit of the exponent. +\item The variable $digidx$ is an index into the exponents digits. It starts at the leading digit $x.used - 1$ and moves towards the trailing digit. +\item The variable $bitcpy$ indicates how many bits are in the currently formed window. When it reaches $winsize$ the window is flushed and + the appropriate operations performed. +\item The variable $bitbuf$ holds the current bits of the window being formed. +\end{enumerate} + +All of step 12 is the window processing loop. It will iterate while there are digits available form the exponent to read. The first step +inside this loop is to extract a new digit if no more bits are available in the current digit. If there are no bits left a new digit is +read and if there are no digits left than the loop terminates. + +After a digit is made available step 12.3 will extract the most significant bit of the current digit and move all other bits in the digit +upwards. In effect the digit is read from most significant bit to least significant bit and since the digits are read from leading to +trailing edges the entire exponent is read from most significant bit to least significant bit. + +At step 12.5 if the $mode$ and currently extracted bit $y$ are both zero the bit is ignored and the next bit is read. This prevents the +algorithm from having to perform trivial squaring and reduction operations before the first non-zero bit is read. Step 12.6 and 12.7-10 handle +the two cases of $mode = 1$ and $mode = 2$ respectively. + +\begin{center} +\begin{figure}[here] +\includegraphics{pics/expt_state.ps} +\caption{Sliding Window State Diagram} +\label{pic:expt_state} +\end{figure} +\end{center} + +By step 13 there are no more digits left in the exponent. However, there may be partial bits in the window left. If $mode = 2$ then +a Left-to-Right algorithm is used to process the remaining few bits. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_s\_mp\_exptmod.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +Lines 32 through 46 determine the optimal window size based on the length of the exponent in bits. The window divisions are sorted +from smallest to greatest so that in each \textbf{if} statement only one condition must be tested. For example, by the \textbf{if} statement +on line 38 the value of $x$ is already known to be greater than $140$. + +The conditional piece of code beginning on line 48 allows the window size to be restricted to five bits. This logic is used to ensure +the table of precomputed powers of $G$ remains relatively small. + +The for loop on line 61 initializes the $M$ array while lines 72 and 77 through 86 initialize the reduction +function that will be used for this modulus. + +-- More later. + +\section{Quick Power of Two} +Calculating $b = 2^a$ can be performed much quicker than with any of the previous algorithms. Recall that a logical shift left $m << k$ is +equivalent to $m \cdot 2^k$. By this logic when $m = 1$ a quick power of two can be achieved. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_2expt}. \\ +\textbf{Input}. integer $b$ \\ +\textbf{Output}. $a \leftarrow 2^b$ \\ +\hline \\ +1. $a \leftarrow 0$ \\ +2. If $a.alloc < \lfloor b / lg(\beta) \rfloor + 1$ then grow $a$ appropriately. \\ +3. $a.used \leftarrow \lfloor b / lg(\beta) \rfloor + 1$ \\ +4. $a_{\lfloor b / lg(\beta) \rfloor} \leftarrow 1 << (b \mbox{ mod } lg(\beta))$ \\ +5. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_2expt} +\end{figure} + +\textbf{Algorithm mp\_2expt.} + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_2expt.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +\chapter{Higher Level Algorithms} + +This chapter discusses the various higher level algorithms that are required to complete a well rounded multiple precision integer package. These +routines are less performance oriented than the algorithms of chapters five, six and seven but are no less important. + +The first section describes a method of integer division with remainder that is universally well known. It provides the signed division logic +for the package. The subsequent section discusses a set of algorithms which allow a single digit to be the 2nd operand for a variety of operations. +These algorithms serve mostly to simplify other algorithms where small constants are required. The last two sections discuss how to manipulate +various representations of integers. For example, converting from an mp\_int to a string of character. + +\section{Integer Division with Remainder} +\label{sec:division} + +Integer division aside from modular exponentiation is the most intensive algorithm to compute. Like addition, subtraction and multiplication +the basis of this algorithm is the long-hand division algorithm taught to school children. Throughout this discussion several common variables +will be used. Let $x$ represent the divisor and $y$ represent the dividend. Let $q$ represent the integer quotient $\lfloor y / x \rfloor$ and +let $r$ represent the remainder $r = y - x \lfloor y / x \rfloor$. The following simple algorithm will be used to start the discussion. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{Radix-$\beta$ Integer Division}. \\ +\textbf{Input}. integer $x$ and $y$ \\ +\textbf{Output}. $q = \lfloor y/x\rfloor, r = y - xq$ \\ +\hline \\ +1. $q \leftarrow 0$ \\ +2. $n \leftarrow \vert \vert y \vert \vert - \vert \vert x \vert \vert$ \\ +3. for $t$ from $n$ down to $0$ do \\ +\hspace{3mm}3.1 Maximize $k$ such that $kx\beta^t$ is less than or equal to $y$ and $(k + 1)x\beta^t$ is greater. \\ +\hspace{3mm}3.2 $q \leftarrow q + k\beta^t$ \\ +\hspace{3mm}3.3 $y \leftarrow y - kx\beta^t$ \\ +4. $r \leftarrow y$ \\ +5. Return($q, r$) \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm Radix-$\beta$ Integer Division} +\label{fig:raddiv} +\end{figure} + +As children we are taught this very simple algorithm for the case of $\beta = 10$. Almost instinctively several optimizations are taught for which +their reason of existing are never explained. For this example let $y = 5471$ represent the dividend and $x = 23$ represent the divisor. + +To find the first digit of the quotient the value of $k$ must be maximized such that $kx\beta^t$ is less than or equal to $y$ and +simultaneously $(k + 1)x\beta^t$ is greater than $y$. Implicitly $k$ is the maximum value the $t$'th digit of the quotient may have. The habitual method +used to find the maximum is to ``eyeball'' the two numbers, typically only the leading digits and quickly estimate a quotient. By only using leading +digits a much simpler division may be used to form an educated guess at what the value must be. In this case $k = \lfloor 54/23\rfloor = 2$ quickly +arises as a possible solution. Indeed $2x\beta^2 = 4600$ is less than $y = 5471$ and simultaneously $(k + 1)x\beta^2 = 6900$ is larger than $y$. +As a result $k\beta^2$ is added to the quotient which now equals $q = 200$ and $4600$ is subtracted from $y$ to give a remainder of $y = 841$. + +Again this process is repeated to produce the quotient digit $k = 3$ which makes the quotient $q = 200 + 3\beta = 230$ and the remainder +$y = 841 - 3x\beta = 181$. Finally the last iteration of the loop produces $k = 7$ which leads to the quotient $q = 230 + 7 = 237$ and the +remainder $y = 181 - 7x = 20$. The final quotient and remainder found are $q = 237$ and $r = y = 20$ which are indeed correct since +$237 \cdot 23 + 20 = 5471$ is true. + +\subsection{Quotient Estimation} +\label{sec:divest} +As alluded to earlier the quotient digit $k$ can be estimated from only the leading digits of both the divisor and dividend. When $p$ leading +digits are used from both the divisor and dividend to form an estimation the accuracy of the estimation rises as $p$ grows. Technically +speaking the estimation is based on assuming the lower $\vert \vert y \vert \vert - p$ and $\vert \vert x \vert \vert - p$ lower digits of the +dividend and divisor are zero. + +The value of the estimation may off by a few values in either direction and in general is fairly correct. A simplification \cite[pp. 271]{TAOCPV2} +of the estimation technique is to use $t + 1$ digits of the dividend and $t$ digits of the divisor, in particularly when $t = 1$. The estimate +using this technique is never too small. For the following proof let $t = \vert \vert y \vert \vert - 1$ and $s = \vert \vert x \vert \vert - 1$ +represent the most significant digits of the dividend and divisor respectively. + +\textbf{Proof.}\textit{ The quotient $\hat k = \lfloor (y_t\beta + y_{t-1}) / x_s \rfloor$ is greater than or equal to +$k = \lfloor y / (x \cdot \beta^{\vert \vert y \vert \vert - \vert \vert x \vert \vert - 1}) \rfloor$. } +The first obvious case is when $\hat k = \beta - 1$ in which case the proof is concluded since the real quotient cannot be larger. For all other +cases $\hat k = \lfloor (y_t\beta + y_{t-1}) / x_s \rfloor$ and $\hat k x_s \ge y_t\beta + y_{t-1} - x_s + 1$. The latter portion of the inequalility +$-x_s + 1$ arises from the fact that a truncated integer division will give the same quotient for at most $x_s - 1$ values. Next a series of +inequalities will prove the hypothesis. + +\begin{equation} +y - \hat k x \le y - \hat k x_s\beta^s +\end{equation} + +This is trivially true since $x \ge x_s\beta^s$. Next we replace $\hat kx_s\beta^s$ by the previous inequality for $\hat kx_s$. + +\begin{equation} +y - \hat k x \le y_t\beta^t + \ldots + y_0 - (y_t\beta^t + y_{t-1}\beta^{t-1} - x_s\beta^t + \beta^s) +\end{equation} + +By simplifying the previous inequality the following inequality is formed. + +\begin{equation} +y - \hat k x \le y_{t-2}\beta^{t-2} + \ldots + y_0 + x_s\beta^s - \beta^s +\end{equation} + +Subsequently, + +\begin{equation} +y_{t-2}\beta^{t-2} + \ldots + y_0 + x_s\beta^s - \beta^s < x_s\beta^s \le x +\end{equation} + +Which proves that $y - \hat kx \le x$ and by consequence $\hat k \ge k$ which concludes the proof. \textbf{QED} + + +\subsection{Normalized Integers} +For the purposes of division a normalized input is when the divisors leading digit $x_n$ is greater than or equal to $\beta / 2$. By multiplying both +$x$ and $y$ by $j = \lfloor (\beta / 2) / x_n \rfloor$ the quotient remains unchanged and the remainder is simply $j$ times the original +remainder. The purpose of normalization is to ensure the leading digit of the divisor is sufficiently large such that the estimated quotient will +lie in the domain of a single digit. Consider the maximum dividend $(\beta - 1) \cdot \beta + (\beta - 1)$ and the minimum divisor $\beta / 2$. + +\begin{equation} +{{\beta^2 - 1} \over { \beta / 2}} \le 2\beta - {2 \over \beta} +\end{equation} + +At most the quotient approaches $2\beta$, however, in practice this will not occur since that would imply the previous quotient digit was too small. + +\subsection{Radix-$\beta$ Division with Remainder} +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_div}. \\ +\textbf{Input}. mp\_int $a, b$ \\ +\textbf{Output}. $c = \lfloor a/b \rfloor$, $d = a - bc$ \\ +\hline \\ +1. If $b = 0$ return(\textit{MP\_VAL}). \\ +2. If $\vert a \vert < \vert b \vert$ then do \\ +\hspace{3mm}2.1 $d \leftarrow a$ \\ +\hspace{3mm}2.2 $c \leftarrow 0$ \\ +\hspace{3mm}2.3 Return(\textit{MP\_OKAY}). \\ +\\ +Setup the quotient to receive the digits. \\ +3. Grow $q$ to $a.used + 2$ digits. \\ +4. $q \leftarrow 0$ \\ +5. $x \leftarrow \vert a \vert , y \leftarrow \vert b \vert$ \\ +6. $sign \leftarrow \left \lbrace \begin{array}{ll} + MP\_ZPOS & \mbox{if }a.sign = b.sign \\ + MP\_NEG & \mbox{otherwise} \\ + \end{array} \right .$ \\ +\\ +Normalize the inputs such that the leading digit of $y$ is greater than or equal to $\beta / 2$. \\ +7. $norm \leftarrow (lg(\beta) - 1) - (\lceil lg(y) \rceil \mbox{ (mod }lg(\beta)\mbox{)})$ \\ +8. $x \leftarrow x \cdot 2^{norm}, y \leftarrow y \cdot 2^{norm}$ \\ +\\ +Find the leading digit of the quotient. \\ +9. $n \leftarrow x.used - 1, t \leftarrow y.used - 1$ \\ +10. $y \leftarrow y \cdot \beta^{n - t}$ \\ +11. While ($x \ge y$) do \\ +\hspace{3mm}11.1 $q_{n - t} \leftarrow q_{n - t} + 1$ \\ +\hspace{3mm}11.2 $x \leftarrow x - y$ \\ +12. $y \leftarrow \lfloor y / \beta^{n-t} \rfloor$ \\ +\\ +Continued on the next page. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_div} +\end{figure} + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_div} (continued). \\ +\textbf{Input}. mp\_int $a, b$ \\ +\textbf{Output}. $c = \lfloor a/b \rfloor$, $d = a - bc$ \\ +\hline \\ +Now find the remainder fo the digits. \\ +13. for $i$ from $n$ down to $(t + 1)$ do \\ +\hspace{3mm}13.1 If $i > x.used$ then jump to the next iteration of this loop. \\ +\hspace{3mm}13.2 If $x_{i} = y_{t}$ then \\ +\hspace{6mm}13.2.1 $q_{i - t - 1} \leftarrow \beta - 1$ \\ +\hspace{3mm}13.3 else \\ +\hspace{6mm}13.3.1 $\hat r \leftarrow x_{i} \cdot \beta + x_{i - 1}$ \\ +\hspace{6mm}13.3.2 $\hat r \leftarrow \lfloor \hat r / y_{t} \rfloor$ \\ +\hspace{6mm}13.3.3 $q_{i - t - 1} \leftarrow \hat r$ \\ +\hspace{3mm}13.4 $q_{i - t - 1} \leftarrow q_{i - t - 1} + 1$ \\ +\\ +Fixup quotient estimation. \\ +\hspace{3mm}13.5 Loop \\ +\hspace{6mm}13.5.1 $q_{i - t - 1} \leftarrow q_{i - t - 1} - 1$ \\ +\hspace{6mm}13.5.2 t$1 \leftarrow 0$ \\ +\hspace{6mm}13.5.3 t$1_0 \leftarrow y_{t - 1}, $ t$1_1 \leftarrow y_t,$ t$1.used \leftarrow 2$ \\ +\hspace{6mm}13.5.4 $t1 \leftarrow t1 \cdot q_{i - t - 1}$ \\ +\hspace{6mm}13.5.5 t$2_0 \leftarrow x_{i - 2}, $ t$2_1 \leftarrow x_{i - 1}, $ t$2_2 \leftarrow x_i, $ t$2.used \leftarrow 3$ \\ +\hspace{6mm}13.5.6 If $\vert t1 \vert > \vert t2 \vert$ then goto step 13.5. \\ +\hspace{3mm}13.6 t$1 \leftarrow y \cdot q_{i - t - 1}$ \\ +\hspace{3mm}13.7 t$1 \leftarrow $ t$1 \cdot \beta^{i - t - 1}$ \\ +\hspace{3mm}13.8 $x \leftarrow x - $ t$1$ \\ +\hspace{3mm}13.9 If $x.sign = MP\_NEG$ then \\ +\hspace{6mm}13.10 t$1 \leftarrow y$ \\ +\hspace{6mm}13.11 t$1 \leftarrow $ t$1 \cdot \beta^{i - t - 1}$ \\ +\hspace{6mm}13.12 $x \leftarrow x + $ t$1$ \\ +\hspace{6mm}13.13 $q_{i - t - 1} \leftarrow q_{i - t - 1} - 1$ \\ +\\ +Finalize the result. \\ +14. Clamp excess digits of $q$ \\ +15. $c \leftarrow q, c.sign \leftarrow sign$ \\ +16. $x.sign \leftarrow a.sign$ \\ +17. $d \leftarrow \lfloor x / 2^{norm} \rfloor$ \\ +18. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_div (continued)} +\end{figure} +\textbf{Algorithm mp\_div.} +This algorithm will calculate quotient and remainder from an integer division given a dividend and divisor. The algorithm is a signed +division and will produce a fully qualified quotient and remainder. + +First the divisor $b$ must be non-zero which is enforced in step one. If the divisor is larger than the dividend than the quotient is implicitly +zero and the remainder is the dividend. + +After the first two trivial cases of inputs are handled the variable $q$ is setup to receive the digits of the quotient. Two unsigned copies of the +divisor $y$ and dividend $x$ are made as well. The core of the division algorithm is an unsigned division and will only work if the values are +positive. Now the two values $x$ and $y$ must be normalized such that the leading digit of $y$ is greater than or equal to $\beta / 2$. +This is performed by shifting both to the left by enough bits to get the desired normalization. + +At this point the division algorithm can begin producing digits of the quotient. Recall that maximum value of the estimation used is +$2\beta - {2 \over \beta}$ which means that a digit of the quotient must be first produced by another means. In this case $y$ is shifted +to the left (\textit{step ten}) so that it has the same number of digits as $x$. The loop on step eleven will subtract multiples of the +shifted copy of $y$ until $x$ is smaller. Since the leading digit of $y$ is greater than or equal to $\beta/2$ this loop will iterate at most two +times to produce the desired leading digit of the quotient. + +Now the remainder of the digits can be produced. The equation $\hat q = \lfloor {{x_i \beta + x_{i-1}}\over y_t} \rfloor$ is used to fairly +accurately approximate the true quotient digit. The estimation can in theory produce an estimation as high as $2\beta - {2 \over \beta}$ but by +induction the upper quotient digit is correct (\textit{as established on step eleven}) and the estimate must be less than $\beta$. + +Recall from section~\ref{sec:divest} that the estimation is never too low but may be too high. The next step of the estimation process is +to refine the estimation. The loop on step 13.5 uses $x_i\beta^2 + x_{i-1}\beta + x_{i-2}$ and $q_{i - t - 1}(y_t\beta + y_{t-1})$ as a higher +order approximation to adjust the quotient digit. + +After both phases of estimation the quotient digit may still be off by a value of one\footnote{This is similar to the error introduced +by optimizing Barrett reduction.}. Steps 13.6 and 13.7 subtract the multiple of the divisor from the dividend (\textit{Similar to step 3.3 of +algorithm~\ref{fig:raddiv}} and then subsequently add a multiple of the divisor if the quotient was too large. + +Now that the quotient has been determine finializing the result is a matter of clamping the quotient, fixing the sizes and de-normalizing the +remainder. An important aspect of this algorithm seemingly overlooked in other descriptions such as that of Algorithm 14.20 HAC \cite[pp. 598]{HAC} +is that when the estimations are being made (\textit{inside the loop on step 13.5}) that the digits $y_{t-1}$, $x_{i-2}$ and $x_{i-1}$ may lie +outside their respective boundaries. For example, if $t = 0$ or $i \le 1$ then the digits would be undefined. In those cases the digits should +respectively be replaced with a zero. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_div.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +The implementation of this algorithm differs slightly from the pseudo code presented previously. In this algorithm either of the quotient $c$ or +remainder $d$ may be passed as a \textbf{NULL} pointer which indicates their value is not desired. For example, the C code to call the division +algorithm with only the quotient is + +\begin{verbatim} +mp_div(&a, &b, &c, NULL); /* c = [a/b] */ +\end{verbatim} + +Lines 109 and 113 handle the two trivial cases of inputs which are division by zero and dividend smaller than the divisor +respectively. After the two trivial cases all of the temporary variables are initialized. Line 148 determines the sign of +the quotient and line 148 ensures that both $x$ and $y$ are positive. + +The number of bits in the leading digit is calculated on line 151. Implictly an mp\_int with $r$ digits will require $lg(\beta)(r-1) + k$ bits +of precision which when reduced modulo $lg(\beta)$ produces the value of $k$. In this case $k$ is the number of bits in the leading digit which is +exactly what is required. For the algorithm to operate $k$ must equal $lg(\beta) - 1$ and when it does not the inputs must be normalized by shifting +them to the left by $lg(\beta) - 1 - k$ bits. + +Throughout the variables $n$ and $t$ will represent the highest digit of $x$ and $y$ respectively. These are first used to produce the +leading digit of the quotient. The loop beginning on line 184 will produce the remainder of the quotient digits. + +The conditional ``continue'' on line 187 is used to prevent the algorithm from reading past the leading edge of $x$ which can occur when the +algorithm eliminates multiple non-zero digits in a single iteration. This ensures that $x_i$ is always non-zero since by definition the digits +above the $i$'th position $x$ must be zero in order for the quotient to be precise\footnote{Precise as far as integer division is concerned.}. + +Lines 214, 216 and 223 through 225 manually construct the high accuracy estimations by setting the digits of the two mp\_int +variables directly. + +\section{Single Digit Helpers} + +This section briefly describes a series of single digit helper algorithms which come in handy when working with small constants. All of +the helper functions assume the single digit input is positive and will treat them as such. + +\subsection{Single Digit Addition and Subtraction} + +Both addition and subtraction are performed by ``cheating'' and using mp\_set followed by the higher level addition or subtraction +algorithms. As a result these algorithms are subtantially simpler with a slight cost in performance. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_add\_d}. \\ +\textbf{Input}. mp\_int $a$ and a mp\_digit $b$ \\ +\textbf{Output}. $c = a + b$ \\ +\hline \\ +1. $t \leftarrow b$ (\textit{mp\_set}) \\ +2. $c \leftarrow a + t$ \\ +3. Return(\textit{MP\_OKAY}) \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_add\_d} +\end{figure} + +\textbf{Algorithm mp\_add\_d.} +This algorithm initiates a temporary mp\_int with the value of the single digit and uses algorithm mp\_add to add the two values together. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_add\_d.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +Clever use of the letter 't'. + +\subsubsection{Subtraction} +The single digit subtraction algorithm mp\_sub\_d is essentially the same except it uses mp\_sub to subtract the digit from the mp\_int. + +\subsection{Single Digit Multiplication} +Single digit multiplication arises enough in division and radix conversion that it ought to be implement as a special case of the baseline +multiplication algorithm. Essentially this algorithm is a modified version of algorithm s\_mp\_mul\_digs where one of the multiplicands +only has one digit. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_mul\_d}. \\ +\textbf{Input}. mp\_int $a$ and a mp\_digit $b$ \\ +\textbf{Output}. $c = ab$ \\ +\hline \\ +1. $pa \leftarrow a.used$ \\ +2. Grow $c$ to at least $pa + 1$ digits. \\ +3. $oldused \leftarrow c.used$ \\ +4. $c.used \leftarrow pa + 1$ \\ +5. $c.sign \leftarrow a.sign$ \\ +6. $\mu \leftarrow 0$ \\ +7. for $ix$ from $0$ to $pa - 1$ do \\ +\hspace{3mm}7.1 $\hat r \leftarrow \mu + a_{ix}b$ \\ +\hspace{3mm}7.2 $c_{ix} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\ +\hspace{3mm}7.3 $\mu \leftarrow \lfloor \hat r / \beta \rfloor$ \\ +8. $c_{pa} \leftarrow \mu$ \\ +9. for $ix$ from $pa + 1$ to $oldused$ do \\ +\hspace{3mm}9.1 $c_{ix} \leftarrow 0$ \\ +10. Clamp excess digits of $c$. \\ +11. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_mul\_d} +\end{figure} +\textbf{Algorithm mp\_mul\_d.} +This algorithm quickly multiplies an mp\_int by a small single digit value. It is specially tailored to the job and has a minimal of overhead. +Unlike the full multiplication algorithms this algorithm does not require any significnat temporary storage or memory allocations. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_mul\_d.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +In this implementation the destination $c$ may point to the same mp\_int as the source $a$ since the result is written after the digit is +read from the source. This function uses pointer aliases $tmpa$ and $tmpc$ for the digits of $a$ and $c$ respectively. + +\subsection{Single Digit Division} +Like the single digit multiplication algorithm, single digit division is also a fairly common algorithm used in radix conversion. Since the +divisor is only a single digit a specialized variant of the division algorithm can be used to compute the quotient. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_div\_d}. \\ +\textbf{Input}. mp\_int $a$ and a mp\_digit $b$ \\ +\textbf{Output}. $c = \lfloor a / b \rfloor, d = a - cb$ \\ +\hline \\ +1. If $b = 0$ then return(\textit{MP\_VAL}).\\ +2. If $b = 3$ then use algorithm mp\_div\_3 instead. \\ +3. Init $q$ to $a.used$ digits. \\ +4. $q.used \leftarrow a.used$ \\ +5. $q.sign \leftarrow a.sign$ \\ +6. $\hat w \leftarrow 0$ \\ +7. for $ix$ from $a.used - 1$ down to $0$ do \\ +\hspace{3mm}7.1 $\hat w \leftarrow \hat w \beta + a_{ix}$ \\ +\hspace{3mm}7.2 If $\hat w \ge b$ then \\ +\hspace{6mm}7.2.1 $t \leftarrow \lfloor \hat w / b \rfloor$ \\ +\hspace{6mm}7.2.2 $\hat w \leftarrow \hat w \mbox{ (mod }b\mbox{)}$ \\ +\hspace{3mm}7.3 else\\ +\hspace{6mm}7.3.1 $t \leftarrow 0$ \\ +\hspace{3mm}7.4 $q_{ix} \leftarrow t$ \\ +8. $d \leftarrow \hat w$ \\ +9. Clamp excess digits of $q$. \\ +10. $c \leftarrow q$ \\ +11. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_div\_d} +\end{figure} +\textbf{Algorithm mp\_div\_d.} +This algorithm divides the mp\_int $a$ by the single mp\_digit $b$ using an optimized approach. Essentially in every iteration of the +algorithm another digit of the dividend is reduced and another digit of quotient produced. Provided $b < \beta$ the value of $\hat w$ +after step 7.1 will be limited such that $0 \le \lfloor \hat w / b \rfloor < \beta$. + +If the divisor $b$ is equal to three a variant of this algorithm is used which is called mp\_div\_3. It replaces the division by three with +a multiplication by $\lfloor \beta / 3 \rfloor$ and the appropriate shift and residual fixup. In essence it is much like the Barrett reduction +from chapter seven. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_div\_d.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +Like the implementation of algorithm mp\_div this algorithm allows either of the quotient or remainder to be passed as a \textbf{NULL} pointer to +indicate the respective value is not required. This allows a trivial single digit modular reduction algorithm, mp\_mod\_d to be created. + +The division and remainder on lines 44 and @45,%@ can be replaced often by a single division on most processors. For example, the 32-bit x86 based +processors can divide a 64-bit quantity by a 32-bit quantity and produce the quotient and remainder simultaneously. Unfortunately the GCC +compiler does not recognize that optimization and will actually produce two function calls to find the quotient and remainder respectively. + +\subsection{Single Digit Root Extraction} + +Finding the $n$'th root of an integer is fairly easy as far as numerical analysis is concerned. Algorithms such as the Newton-Raphson approximation +(\ref{eqn:newton}) series will converge very quickly to a root for any continuous function $f(x)$. + +\begin{equation} +x_{i+1} = x_i - {f(x_i) \over f'(x_i)} +\label{eqn:newton} +\end{equation} + +In this case the $n$'th root is desired and $f(x) = x^n - a$ where $a$ is the integer of which the root is desired. The derivative of $f(x)$ is +simply $f'(x) = nx^{n - 1}$. Of particular importance is that this algorithm will be used over the integers not over the a more continuous domain +such as the real numbers. As a result the root found can be above the true root by few and must be manually adjusted. Ideally at the end of the +algorithm the $n$'th root $b$ of an integer $a$ is desired such that $b^n \le a$. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_n\_root}. \\ +\textbf{Input}. mp\_int $a$ and a mp\_digit $b$ \\ +\textbf{Output}. $c^b \le a$ \\ +\hline \\ +1. If $b$ is even and $a.sign = MP\_NEG$ return(\textit{MP\_VAL}). \\ +2. $sign \leftarrow a.sign$ \\ +3. $a.sign \leftarrow MP\_ZPOS$ \\ +4. t$2 \leftarrow 2$ \\ +5. Loop \\ +\hspace{3mm}5.1 t$1 \leftarrow $ t$2$ \\ +\hspace{3mm}5.2 t$3 \leftarrow $ t$1^{b - 1}$ \\ +\hspace{3mm}5.3 t$2 \leftarrow $ t$3 $ $\cdot$ t$1$ \\ +\hspace{3mm}5.4 t$2 \leftarrow $ t$2 - a$ \\ +\hspace{3mm}5.5 t$3 \leftarrow $ t$3 \cdot b$ \\ +\hspace{3mm}5.6 t$3 \leftarrow \lfloor $t$2 / $t$3 \rfloor$ \\ +\hspace{3mm}5.7 t$2 \leftarrow $ t$1 - $ t$3$ \\ +\hspace{3mm}5.8 If t$1 \ne $ t$2$ then goto step 5. \\ +6. Loop \\ +\hspace{3mm}6.1 t$2 \leftarrow $ t$1^b$ \\ +\hspace{3mm}6.2 If t$2 > a$ then \\ +\hspace{6mm}6.2.1 t$1 \leftarrow $ t$1 - 1$ \\ +\hspace{6mm}6.2.2 Goto step 6. \\ +7. $a.sign \leftarrow sign$ \\ +8. $c \leftarrow $ t$1$ \\ +9. $c.sign \leftarrow sign$ \\ +10. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_n\_root} +\end{figure} +\textbf{Algorithm mp\_n\_root.} +This algorithm finds the integer $n$'th root of an input using the Newton-Raphson approach. It is partially optimized based on the observation +that the numerator of ${f(x) \over f'(x)}$ can be derived from a partial denominator. That is at first the denominator is calculated by finding +$x^{b - 1}$. This value can then be multiplied by $x$ and have $a$ subtracted from it to find the numerator. This saves a total of $b - 1$ +multiplications by t$1$ inside the loop. + +The initial value of the approximation is t$2 = 2$ which allows the algorithm to start with very small values and quickly converge on the +root. Ideally this algorithm is meant to find the $n$'th root of an input where $n$ is bounded by $2 \le n \le 5$. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_n\_root.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +\section{Random Number Generation} + +Random numbers come up in a variety of activities from public key cryptography to simple simulations and various randomized algorithms. Pollard-Rho +factoring for example, can make use of random values as starting points to find factors of a composite integer. In this case the algorithm presented +is solely for simulations and not intended for cryptographic use. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_rand}. \\ +\textbf{Input}. An integer $b$ \\ +\textbf{Output}. A pseudo-random number of $b$ digits \\ +\hline \\ +1. $a \leftarrow 0$ \\ +2. If $b \le 0$ return(\textit{MP\_OKAY}) \\ +3. Pick a non-zero random digit $d$. \\ +4. $a \leftarrow a + d$ \\ +5. for $ix$ from 1 to $d - 1$ do \\ +\hspace{3mm}5.1 $a \leftarrow a \cdot \beta$ \\ +\hspace{3mm}5.2 Pick a random digit $d$. \\ +\hspace{3mm}5.3 $a \leftarrow a + d$ \\ +6. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_rand} +\end{figure} +\textbf{Algorithm mp\_rand.} +This algorithm produces a pseudo-random integer of $b$ digits. By ensuring that the first digit is non-zero the algorithm also guarantees that the +final result has at least $b$ digits. It relies heavily on a third-part random number generator which should ideally generate uniformly all of +the integers from $0$ to $\beta - 1$. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_rand.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +\section{Formatted Representations} +The ability to emit a radix-$n$ textual representation of an integer is useful for interacting with human parties. For example, the ability to +be given a string of characters such as ``114585'' and turn it into the radix-$\beta$ equivalent would make it easier to enter numbers +into a program. + +\subsection{Reading Radix-n Input} +For the purposes of this text we will assume that a simple lower ASCII map (\ref{fig:ASC}) is used for the values of from $0$ to $63$ to +printable characters. For example, when the character ``N'' is read it represents the integer $23$. The first $16$ characters of the +map are for the common representations up to hexadecimal. After that they match the ``base64'' encoding scheme which are suitable chosen +such that they are printable. While outputting as base64 may not be too helpful for human operators it does allow communication via non binary +mediums. + +\newpage\begin{figure}[here] +\begin{center} +\begin{tabular}{cc|cc|cc|cc} +\hline \textbf{Value} & \textbf{Char} & \textbf{Value} & \textbf{Char} & \textbf{Value} & \textbf{Char} & \textbf{Value} & \textbf{Char} \\ +\hline +0 & 0 & 1 & 1 & 2 & 2 & 3 & 3 \\ +4 & 4 & 5 & 5 & 6 & 6 & 7 & 7 \\ +8 & 8 & 9 & 9 & 10 & A & 11 & B \\ +12 & C & 13 & D & 14 & E & 15 & F \\ +16 & G & 17 & H & 18 & I & 19 & J \\ +20 & K & 21 & L & 22 & M & 23 & N \\ +24 & O & 25 & P & 26 & Q & 27 & R \\ +28 & S & 29 & T & 30 & U & 31 & V \\ +32 & W & 33 & X & 34 & Y & 35 & Z \\ +36 & a & 37 & b & 38 & c & 39 & d \\ +40 & e & 41 & f & 42 & g & 43 & h \\ +44 & i & 45 & j & 46 & k & 47 & l \\ +48 & m & 49 & n & 50 & o & 51 & p \\ +52 & q & 53 & r & 54 & s & 55 & t \\ +56 & u & 57 & v & 58 & w & 59 & x \\ +60 & y & 61 & z & 62 & $+$ & 63 & $/$ \\ +\hline +\end{tabular} +\end{center} +\caption{Lower ASCII Map} +\label{fig:ASC} +\end{figure} + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_read\_radix}. \\ +\textbf{Input}. A string $str$ of length $sn$ and radix $r$. \\ +\textbf{Output}. The radix-$\beta$ equivalent mp\_int. \\ +\hline \\ +1. If $r < 2$ or $r > 64$ return(\textit{MP\_VAL}). \\ +2. $ix \leftarrow 0$ \\ +3. If $str_0 =$ ``-'' then do \\ +\hspace{3mm}3.1 $ix \leftarrow ix + 1$ \\ +\hspace{3mm}3.2 $sign \leftarrow MP\_NEG$ \\ +4. else \\ +\hspace{3mm}4.1 $sign \leftarrow MP\_ZPOS$ \\ +5. $a \leftarrow 0$ \\ +6. for $iy$ from $ix$ to $sn - 1$ do \\ +\hspace{3mm}6.1 Let $y$ denote the position in the map of $str_{iy}$. \\ +\hspace{3mm}6.2 If $str_{iy}$ is not in the map or $y \ge r$ then goto step 7. \\ +\hspace{3mm}6.3 $a \leftarrow a \cdot r$ \\ +\hspace{3mm}6.4 $a \leftarrow a + y$ \\ +7. If $a \ne 0$ then $a.sign \leftarrow sign$ \\ +8. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_read\_radix} +\end{figure} +\textbf{Algorithm mp\_read\_radix.} +This algorithm will read an ASCII string and produce the radix-$\beta$ mp\_int representation of the same integer. A minus symbol ``-'' may precede the +string to indicate the value is negative, otherwise it is assumed to be positive. The algorithm will read up to $sn$ characters from the input +and will stop when it reads a character it cannot map the algorithm stops reading characters from the string. This allows numbers to be embedded +as part of larger input without any significant problem. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_read\_radix.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +\subsection{Generating Radix-$n$ Output} +Generating radix-$n$ output is fairly trivial with a division and remainder algorithm. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_toradix}. \\ +\textbf{Input}. A mp\_int $a$ and an integer $r$\\ +\textbf{Output}. The radix-$r$ representation of $a$ \\ +\hline \\ +1. If $r < 2$ or $r > 64$ return(\textit{MP\_VAL}). \\ +2. If $a = 0$ then $str = $ ``$0$'' and return(\textit{MP\_OKAY}). \\ +3. $t \leftarrow a$ \\ +4. $str \leftarrow$ ``'' \\ +5. if $t.sign = MP\_NEG$ then \\ +\hspace{3mm}5.1 $str \leftarrow str + $ ``-'' \\ +\hspace{3mm}5.2 $t.sign = MP\_ZPOS$ \\ +6. While ($t \ne 0$) do \\ +\hspace{3mm}6.1 $d \leftarrow t \mbox{ (mod }r\mbox{)}$ \\ +\hspace{3mm}6.2 $t \leftarrow \lfloor t / r \rfloor$ \\ +\hspace{3mm}6.3 Look up $d$ in the map and store the equivalent character in $y$. \\ +\hspace{3mm}6.4 $str \leftarrow str + y$ \\ +7. If $str_0 = $``$-$'' then \\ +\hspace{3mm}7.1 Reverse the digits $str_1, str_2, \ldots str_n$. \\ +8. Otherwise \\ +\hspace{3mm}8.1 Reverse the digits $str_0, str_1, \ldots str_n$. \\ +9. Return(\textit{MP\_OKAY}).\\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_toradix} +\end{figure} +\textbf{Algorithm mp\_toradix.} +This algorithm computes the radix-$r$ representation of an mp\_int $a$. The ``digits'' of the representation are extracted by reducing +successive powers of $\lfloor a / r^k \rfloor$ the input modulo $r$ until $r^k > a$. Note that instead of actually dividing by $r^k$ in +each iteration the quotient $\lfloor a / r \rfloor$ is saved for the next iteration. As a result a series of trivial $n \times 1$ divisions +are required instead of a series of $n \times k$ divisions. One design flaw of this approach is that the digits are produced in the reverse order +(see~\ref{fig:mpradix}). To remedy this flaw the digits must be swapped or simply ``reversed''. + +\begin{figure} +\begin{center} +\begin{tabular}{|c|c|c|} +\hline \textbf{Value of $a$} & \textbf{Value of $d$} & \textbf{Value of $str$} \\ +\hline $1234$ & -- & -- \\ +\hline $123$ & $4$ & ``4'' \\ +\hline $12$ & $3$ & ``43'' \\ +\hline $1$ & $2$ & ``432'' \\ +\hline $0$ & $1$ & ``4321'' \\ +\hline +\end{tabular} +\end{center} +\caption{Example of Algorithm mp\_toradix.} +\label{fig:mpradix} +\end{figure} + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_toradix.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +\chapter{Number Theoretic Algorithms} +This chapter discusses several fundamental number theoretic algorithms such as the greatest common divisor, least common multiple and Jacobi +symbol computation. These algorithms arise as essential components in several key cryptographic algorithms such as the RSA public key algorithm and +various Sieve based factoring algorithms. + +\section{Greatest Common Divisor} +The greatest common divisor of two integers $a$ and $b$, often denoted as $(a, b)$ is the largest integer $k$ that is a proper divisor of +both $a$ and $b$. That is, $k$ is the largest integer such that $0 \equiv a \mbox{ (mod }k\mbox{)}$ and $0 \equiv b \mbox{ (mod }k\mbox{)}$ occur +simultaneously. + +The most common approach (cite) is to reduce one input modulo another. That is if $a$ and $b$ are divisible by some integer $k$ and if $qa + r = b$ then +$r$ is also divisible by $k$. The reduction pattern follows $\left < a , b \right > \rightarrow \left < b, a \mbox{ mod } b \right >$. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{Greatest Common Divisor (I)}. \\ +\textbf{Input}. Two positive integers $a$ and $b$ greater than zero. \\ +\textbf{Output}. The greatest common divisor $(a, b)$. \\ +\hline \\ +1. While ($b > 0$) do \\ +\hspace{3mm}1.1 $r \leftarrow a \mbox{ (mod }b\mbox{)}$ \\ +\hspace{3mm}1.2 $a \leftarrow b$ \\ +\hspace{3mm}1.3 $b \leftarrow r$ \\ +2. Return($a$). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm Greatest Common Divisor (I)} +\label{fig:gcd1} +\end{figure} + +This algorithm will quickly converge on the greatest common divisor since the residue $r$ tends diminish rapidly. However, divisions are +relatively expensive operations to perform and should ideally be avoided. There is another approach based on a similar relationship of +greatest common divisors. The faster approach is based on the observation that if $k$ divides both $a$ and $b$ it will also divide $a - b$. +In particular, we would like $a - b$ to decrease in magnitude which implies that $b \ge a$. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{Greatest Common Divisor (II)}. \\ +\textbf{Input}. Two positive integers $a$ and $b$ greater than zero. \\ +\textbf{Output}. The greatest common divisor $(a, b)$. \\ +\hline \\ +1. While ($b > 0$) do \\ +\hspace{3mm}1.1 Swap $a$ and $b$ such that $a$ is the smallest of the two. \\ +\hspace{3mm}1.2 $b \leftarrow b - a$ \\ +2. Return($a$). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm Greatest Common Divisor (II)} +\label{fig:gcd2} +\end{figure} + +\textbf{Proof} \textit{Algorithm~\ref{fig:gcd2} will return the greatest common divisor of $a$ and $b$.} +The algorithm in figure~\ref{fig:gcd2} will eventually terminate since $b \ge a$ the subtraction in step 1.2 will be a value less than $b$. In other +words in every iteration that tuple $\left < a, b \right >$ decrease in magnitude until eventually $a = b$. Since both $a$ and $b$ are always +divisible by the greatest common divisor (\textit{until the last iteration}) and in the last iteration of the algorithm $b = 0$, therefore, in the +second to last iteration of the algorithm $b = a$ and clearly $(a, a) = a$ which concludes the proof. \textbf{QED}. + +As a matter of practicality algorithm \ref{fig:gcd1} decreases far too slowly to be useful. Specially if $b$ is much larger than $a$ such that +$b - a$ is still very much larger than $a$. A simple addition to the algorithm is to divide $b - a$ by a power of some integer $p$ which does +not divide the greatest common divisor but will divide $b - a$. In this case ${b - a} \over p$ is also an integer and still divisible by +the greatest common divisor. + +However, instead of factoring $b - a$ to find a suitable value of $p$ the powers of $p$ can be removed from $a$ and $b$ that are in common first. +Then inside the loop whenever $b - a$ is divisible by some power of $p$ it can be safely removed. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{Greatest Common Divisor (III)}. \\ +\textbf{Input}. Two positive integers $a$ and $b$ greater than zero. \\ +\textbf{Output}. The greatest common divisor $(a, b)$. \\ +\hline \\ +1. $k \leftarrow 0$ \\ +2. While $a$ and $b$ are both divisible by $p$ do \\ +\hspace{3mm}2.1 $a \leftarrow \lfloor a / p \rfloor$ \\ +\hspace{3mm}2.2 $b \leftarrow \lfloor b / p \rfloor$ \\ +\hspace{3mm}2.3 $k \leftarrow k + 1$ \\ +3. While $a$ is divisible by $p$ do \\ +\hspace{3mm}3.1 $a \leftarrow \lfloor a / p \rfloor$ \\ +4. While $b$ is divisible by $p$ do \\ +\hspace{3mm}4.1 $b \leftarrow \lfloor b / p \rfloor$ \\ +5. While ($b > 0$) do \\ +\hspace{3mm}5.1 Swap $a$ and $b$ such that $a$ is the smallest of the two. \\ +\hspace{3mm}5.2 $b \leftarrow b - a$ \\ +\hspace{3mm}5.3 While $b$ is divisible by $p$ do \\ +\hspace{6mm}5.3.1 $b \leftarrow \lfloor b / p \rfloor$ \\ +6. Return($a \cdot p^k$). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm Greatest Common Divisor (III)} +\label{fig:gcd3} +\end{figure} + +This algorithm is based on the first except it removes powers of $p$ first and inside the main loop to ensure the tuple $\left < a, b \right >$ +decreases more rapidly. The first loop on step two removes powers of $p$ that are in common. A count, $k$, is kept which will present a common +divisor of $p^k$. After step two the remaining common divisor of $a$ and $b$ cannot be divisible by $p$. This means that $p$ can be safely +divided out of the difference $b - a$ so long as the division leaves no remainder. + +In particular the value of $p$ should be chosen such that the division on step 5.3.1 occur often. It also helps that division by $p$ be easy +to compute. The ideal choice of $p$ is two since division by two amounts to a right logical shift. Another important observation is that by +step five both $a$ and $b$ are odd. Therefore, the diffrence $b - a$ must be even which means that each iteration removes one bit from the +largest of the pair. + +\subsection{Complete Greatest Common Divisor} +The algorithms presented so far cannot handle inputs which are zero or negative. The following algorithm can handle all input cases properly +and will produce the greatest common divisor. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_gcd}. \\ +\textbf{Input}. mp\_int $a$ and $b$ \\ +\textbf{Output}. The greatest common divisor $c = (a, b)$. \\ +\hline \\ +1. If $a = 0$ then \\ +\hspace{3mm}1.1 $c \leftarrow \vert b \vert $ \\ +\hspace{3mm}1.2 Return(\textit{MP\_OKAY}). \\ +2. If $b = 0$ then \\ +\hspace{3mm}2.1 $c \leftarrow \vert a \vert $ \\ +\hspace{3mm}2.2 Return(\textit{MP\_OKAY}). \\ +3. $u \leftarrow \vert a \vert, v \leftarrow \vert b \vert$ \\ +4. $k \leftarrow 0$ \\ +5. While $u.used > 0$ and $v.used > 0$ and $u_0 \equiv v_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ +\hspace{3mm}5.1 $k \leftarrow k + 1$ \\ +\hspace{3mm}5.2 $u \leftarrow \lfloor u / 2 \rfloor$ \\ +\hspace{3mm}5.3 $v \leftarrow \lfloor v / 2 \rfloor$ \\ +6. While $u.used > 0$ and $u_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ +\hspace{3mm}6.1 $u \leftarrow \lfloor u / 2 \rfloor$ \\ +7. While $v.used > 0$ and $v_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ +\hspace{3mm}7.1 $v \leftarrow \lfloor v / 2 \rfloor$ \\ +8. While $v.used > 0$ \\ +\hspace{3mm}8.1 If $\vert u \vert > \vert v \vert$ then \\ +\hspace{6mm}8.1.1 Swap $u$ and $v$. \\ +\hspace{3mm}8.2 $v \leftarrow \vert v \vert - \vert u \vert$ \\ +\hspace{3mm}8.3 While $v.used > 0$ and $v_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ +\hspace{6mm}8.3.1 $v \leftarrow \lfloor v / 2 \rfloor$ \\ +9. $c \leftarrow u \cdot 2^k$ \\ +10. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_gcd} +\end{figure} +\textbf{Algorithm mp\_gcd.} +This algorithm will produce the greatest common divisor of two mp\_ints $a$ and $b$. The algorithm was originally based on Algorithm B of +Knuth \cite[pp. 338]{TAOCPV2} but has been modified to be simpler to explain. In theory it achieves the same asymptotic working time as +Algorithm B and in practice this appears to be true. + +The first two steps handle the cases where either one of or both inputs are zero. If either input is zero the greatest common divisor is the +largest input or zero if they are both zero. If the inputs are not trivial than $u$ and $v$ are assigned the absolute values of +$a$ and $b$ respectively and the algorithm will proceed to reduce the pair. + +Step five will divide out any common factors of two and keep track of the count in the variable $k$. After this step, two is no longer a +factor of the remaining greatest common divisor between $u$ and $v$ and can be safely evenly divided out of either whenever they are even. Step +six and seven ensure that the $u$ and $v$ respectively have no more factors of two. At most only one of the while--loops will iterate since +they cannot both be even. + +By step eight both of $u$ and $v$ are odd which is required for the inner logic. First the pair are swapped such that $v$ is equal to +or greater than $u$. This ensures that the subtraction on step 8.2 will always produce a positive and even result. Step 8.3 removes any +factors of two from the difference $u$ to ensure that in the next iteration of the loop both are once again odd. + +After $v = 0$ occurs the variable $u$ has the greatest common divisor of the pair $\left < u, v \right >$ just after step six. The result +must be adjusted by multiplying by the common factors of two ($2^k$) removed earlier. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_gcd.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +This function makes use of the macros mp\_iszero and mp\_iseven. The former evaluates to $1$ if the input mp\_int is equivalent to the +integer zero otherwise it evaluates to $0$. The latter evaluates to $1$ if the input mp\_int represents a non-zero even integer otherwise +it evaluates to $0$. Note that just because mp\_iseven may evaluate to $0$ does not mean the input is odd, it could also be zero. The three +trivial cases of inputs are handled on lines 24 through 30. After those lines the inputs are assumed to be non-zero. + +Lines 32 and 37 make local copies $u$ and $v$ of the inputs $a$ and $b$ respectively. At this point the common factors of two +must be divided out of the two inputs. The block starting at line 44 removes common factors of two by first counting the number of trailing +zero bits in both. The local integer $k$ is used to keep track of how many factors of $2$ are pulled out of both values. It is assumed that +the number of factors will not exceed the maximum value of a C ``int'' data type\footnote{Strictly speaking no array in C may have more than +entries than are accessible by an ``int'' so this is not a limitation.}. + +At this point there are no more common factors of two in the two values. The divisions by a power of two on lines 62 and 68 remove +any independent factors of two such that both $u$ and $v$ are guaranteed to be an odd integer before hitting the main body of the algorithm. The while loop +on line 73 performs the reduction of the pair until $v$ is equal to zero. The unsigned comparison and subtraction algorithms are used in +place of the full signed routines since both values are guaranteed to be positive and the result of the subtraction is guaranteed to be non-negative. + +\section{Least Common Multiple} +The least common multiple of a pair of integers is their product divided by their greatest common divisor. For two integers $a$ and $b$ the +least common multiple is normally denoted as $[ a, b ]$ and numerically equivalent to ${ab} \over {(a, b)}$. For example, if $a = 2 \cdot 2 \cdot 3 = 12$ +and $b = 2 \cdot 3 \cdot 3 \cdot 7 = 126$ the least common multiple is ${126 \over {(12, 126)}} = {126 \over 6} = 21$. + +The least common multiple arises often in coding theory as well as number theory. If two functions have periods of $a$ and $b$ respectively they will +collide, that is be in synchronous states, after only $[ a, b ]$ iterations. This is why, for example, random number generators based on +Linear Feedback Shift Registers (LFSR) tend to use registers with periods which are co-prime (\textit{e.g. the greatest common divisor is one.}). +Similarly in number theory if a composite $n$ has two prime factors $p$ and $q$ then maximal order of any unit of $\Z/n\Z$ will be $[ p - 1, q - 1] $. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_lcm}. \\ +\textbf{Input}. mp\_int $a$ and $b$ \\ +\textbf{Output}. The least common multiple $c = [a, b]$. \\ +\hline \\ +1. $c \leftarrow (a, b)$ \\ +2. $t \leftarrow a \cdot b$ \\ +3. $c \leftarrow \lfloor t / c \rfloor$ \\ +4. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_lcm} +\end{figure} +\textbf{Algorithm mp\_lcm.} +This algorithm computes the least common multiple of two mp\_int inputs $a$ and $b$. It computes the least common multiple directly by +dividing the product of the two inputs by their greatest common divisor. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_lcm.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +\section{Jacobi Symbol Computation} +To explain the Jacobi Symbol we shall first discuss the Legendre function\footnote{Arrg. What is the name of this?} off which the Jacobi symbol is +defined. The Legendre function computes whether or not an integer $a$ is a quadratic residue modulo an odd prime $p$. Numerically it is +equivalent to equation \ref{eqn:legendre}. + +\textit{-- Tom, don't be an ass, cite your source here...!} + +\begin{equation} +a^{(p-1)/2} \equiv \begin{array}{rl} + -1 & \mbox{if }a\mbox{ is a quadratic non-residue.} \\ + 0 & \mbox{if }a\mbox{ divides }p\mbox{.} \\ + 1 & \mbox{if }a\mbox{ is a quadratic residue}. + \end{array} \mbox{ (mod }p\mbox{)} +\label{eqn:legendre} +\end{equation} + +\textbf{Proof.} \textit{Equation \ref{eqn:legendre} correctly identifies the residue status of an integer $a$ modulo a prime $p$.} +An integer $a$ is a quadratic residue if the following equation has a solution. + +\begin{equation} +x^2 \equiv a \mbox{ (mod }p\mbox{)} +\label{eqn:root} +\end{equation} + +Consider the following equation. + +\begin{equation} +0 \equiv x^{p-1} - 1 \equiv \left \lbrace \left (x^2 \right )^{(p-1)/2} - a^{(p-1)/2} \right \rbrace + \left ( a^{(p-1)/2} - 1 \right ) \mbox{ (mod }p\mbox{)} +\label{eqn:rooti} +\end{equation} + +Whether equation \ref{eqn:root} has a solution or not equation \ref{eqn:rooti} is always true. If $a^{(p-1)/2} - 1 \equiv 0 \mbox{ (mod }p\mbox{)}$ +then the quantity in the braces must be zero. By reduction, + +\begin{eqnarray} +\left (x^2 \right )^{(p-1)/2} - a^{(p-1)/2} \equiv 0 \nonumber \\ +\left (x^2 \right )^{(p-1)/2} \equiv a^{(p-1)/2} \nonumber \\ +x^2 \equiv a \mbox{ (mod }p\mbox{)} +\end{eqnarray} + +As a result there must be a solution to the quadratic equation and in turn $a$ must be a quadratic residue. If $a$ does not divide $p$ and $a$ +is not a quadratic residue then the only other value $a^{(p-1)/2}$ may be congruent to is $-1$ since +\begin{equation} +0 \equiv a^{p - 1} - 1 \equiv (a^{(p-1)/2} + 1)(a^{(p-1)/2} - 1) \mbox{ (mod }p\mbox{)} +\end{equation} +One of the terms on the right hand side must be zero. \textbf{QED} + +\subsection{Jacobi Symbol} +The Jacobi symbol is a generalization of the Legendre function for any odd non prime moduli $p$ greater than 2. If $p = \prod_{i=0}^n p_i$ then +the Jacobi symbol $\left ( { a \over p } \right )$ is equal to the following equation. + +\begin{equation} +\left ( { a \over p } \right ) = \left ( { a \over p_0} \right ) \left ( { a \over p_1} \right ) \ldots \left ( { a \over p_n} \right ) +\end{equation} + +By inspection if $p$ is prime the Jacobi symbol is equivalent to the Legendre function. The following facts\footnote{See HAC \cite[pp. 72-74]{HAC} for +further details.} will be used to derive an efficient Jacobi symbol algorithm. Where $p$ is an odd integer greater than two and $a, b \in \Z$ the +following are true. + +\begin{enumerate} +\item $\left ( { a \over p} \right )$ equals $-1$, $0$ or $1$. +\item $\left ( { ab \over p} \right ) = \left ( { a \over p} \right )\left ( { b \over p} \right )$. +\item If $a \equiv b$ then $\left ( { a \over p} \right ) = \left ( { b \over p} \right )$. +\item $\left ( { 2 \over p} \right )$ equals $1$ if $p \equiv 1$ or $7 \mbox{ (mod }8\mbox{)}$. Otherwise, it equals $-1$. +\item $\left ( { a \over p} \right ) \equiv \left ( { p \over a} \right ) \cdot (-1)^{(p-1)(a-1)/4}$. More specifically +$\left ( { a \over p} \right ) = \left ( { p \over a} \right )$ if $p \equiv a \equiv 1 \mbox{ (mod }4\mbox{)}$. +\end{enumerate} + +Using these facts if $a = 2^k \cdot a'$ then + +\begin{eqnarray} +\left ( { a \over p } \right ) = \left ( {{2^k} \over p } \right ) \left ( {a' \over p} \right ) \nonumber \\ + = \left ( {2 \over p } \right )^k \left ( {a' \over p} \right ) +\label{eqn:jacobi} +\end{eqnarray} + +By fact five, + +\begin{equation} +\left ( { a \over p } \right ) = \left ( { p \over a } \right ) \cdot (-1)^{(p-1)(a-1)/4} +\end{equation} + +Subsequently by fact three since $p \equiv (p \mbox{ mod }a) \mbox{ (mod }a\mbox{)}$ then + +\begin{equation} +\left ( { a \over p } \right ) = \left ( { {p \mbox{ mod } a} \over a } \right ) \cdot (-1)^{(p-1)(a-1)/4} +\end{equation} + +By putting both observations into equation \ref{eqn:jacobi} the following simplified equation is formed. + +\begin{equation} +\left ( { a \over p } \right ) = \left ( {2 \over p } \right )^k \left ( {{p\mbox{ mod }a'} \over a'} \right ) \cdot (-1)^{(p-1)(a'-1)/4} +\end{equation} + +The value of $\left ( {{p \mbox{ mod }a'} \over a'} \right )$ can be found by using the same equation recursively. The value of +$\left ( {2 \over p } \right )^k$ equals $1$ if $k$ is even otherwise it equals $\left ( {2 \over p } \right )$. Using this approach the +factors of $p$ do not have to be known. Furthermore, if $(a, p) = 1$ then the algorithm will terminate when the recursion requests the +Jacobi symbol computation of $\left ( {1 \over a'} \right )$ which is simply $1$. + +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_jacobi}. \\ +\textbf{Input}. mp\_int $a$ and $p$, $a \ge 0$, $p \ge 3$, $p \equiv 1 \mbox{ (mod }2\mbox{)}$ \\ +\textbf{Output}. The Jacobi symbol $c = \left ( {a \over p } \right )$. \\ +\hline \\ +1. If $a = 0$ then \\ +\hspace{3mm}1.1 $c \leftarrow 0$ \\ +\hspace{3mm}1.2 Return(\textit{MP\_OKAY}). \\ +2. If $a = 1$ then \\ +\hspace{3mm}2.1 $c \leftarrow 1$ \\ +\hspace{3mm}2.2 Return(\textit{MP\_OKAY}). \\ +3. $a' \leftarrow a$ \\ +4. $k \leftarrow 0$ \\ +5. While $a'.used > 0$ and $a'_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ +\hspace{3mm}5.1 $k \leftarrow k + 1$ \\ +\hspace{3mm}5.2 $a' \leftarrow \lfloor a' / 2 \rfloor$ \\ +6. If $k \equiv 0 \mbox{ (mod }2\mbox{)}$ then \\ +\hspace{3mm}6.1 $s \leftarrow 1$ \\ +7. else \\ +\hspace{3mm}7.1 $r \leftarrow p_0 \mbox{ (mod }8\mbox{)}$ \\ +\hspace{3mm}7.2 If $r = 1$ or $r = 7$ then \\ +\hspace{6mm}7.2.1 $s \leftarrow 1$ \\ +\hspace{3mm}7.3 else \\ +\hspace{6mm}7.3.1 $s \leftarrow -1$ \\ +8. If $p_0 \equiv a'_0 \equiv 3 \mbox{ (mod }4\mbox{)}$ then \\ +\hspace{3mm}8.1 $s \leftarrow -s$ \\ +9. If $a' \ne 1$ then \\ +\hspace{3mm}9.1 $p' \leftarrow p \mbox{ (mod }a'\mbox{)}$ \\ +\hspace{3mm}9.2 $s \leftarrow s \cdot \mbox{mp\_jacobi}(p', a')$ \\ +10. $c \leftarrow s$ \\ +11. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_jacobi} +\end{figure} +\textbf{Algorithm mp\_jacobi.} +This algorithm computes the Jacobi symbol for an arbitrary positive integer $a$ with respect to an odd integer $p$ greater than three. The algorithm +is based on algorithm 2.149 of HAC \cite[pp. 73]{HAC}. + +Step numbers one and two handle the trivial cases of $a = 0$ and $a = 1$ respectively. Step five determines the number of two factors in the +input $a$. If $k$ is even than the term $\left ( { 2 \over p } \right )^k$ must always evaluate to one. If $k$ is odd than the term evaluates to one +if $p_0$ is congruent to one or seven modulo eight, otherwise it evaluates to $-1$. After the the $\left ( { 2 \over p } \right )^k$ term is handled +the $(-1)^{(p-1)(a'-1)/4}$ is computed and multiplied against the current product $s$. The latter term evaluates to one if both $p$ and $a'$ +are congruent to one modulo four, otherwise it evaluates to negative one. + +By step nine if $a'$ does not equal one a recursion is required. Step 9.1 computes $p' \equiv p \mbox{ (mod }a'\mbox{)}$ and will recurse to compute +$\left ( {p' \over a'} \right )$ which is multiplied against the current Jacobi product. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_jacobi.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +As a matter of practicality the variable $a'$ as per the pseudo-code is reprensented by the variable $a1$ since the $'$ symbol is not valid for a C +variable name character. + +The two simple cases of $a = 0$ and $a = 1$ are handled at the very beginning to simplify the algorithm. If the input is non-trivial the algorithm +has to proceed compute the Jacobi. The variable $s$ is used to hold the current Jacobi product. Note that $s$ is merely a C ``int'' data type since +the values it may obtain are merely $-1$, $0$ and $1$. + +After a local copy of $a$ is made all of the factors of two are divided out and the total stored in $k$. Technically only the least significant +bit of $k$ is required, however, it makes the algorithm simpler to follow to perform an addition. In practice an exclusive-or and addition have the same +processor requirements and neither is faster than the other. + +Line 58 through 71 determines the value of $\left ( { 2 \over p } \right )^k$. If the least significant bit of $k$ is zero than +$k$ is even and the value is one. Otherwise, the value of $s$ depends on which residue class $p$ belongs to modulo eight. The value of +$(-1)^{(p-1)(a'-1)/4}$ is compute and multiplied against $s$ on lines 71 through 74. + +Finally, if $a1$ does not equal one the algorithm must recurse and compute $\left ( {p' \over a'} \right )$. + +\textit{-- Comment about default $s$ and such...} + +\section{Modular Inverse} +\label{sec:modinv} +The modular inverse of a number actually refers to the modular multiplicative inverse. Essentially for any integer $a$ such that $(a, p) = 1$ there +exist another integer $b$ such that $ab \equiv 1 \mbox{ (mod }p\mbox{)}$. The integer $b$ is called the multiplicative inverse of $a$ which is +denoted as $b = a^{-1}$. Technically speaking modular inversion is a well defined operation for any finite ring or field not just for rings and +fields of integers. However, the former will be the matter of discussion. + +The simplest approach is to compute the algebraic inverse of the input. That is to compute $b \equiv a^{\Phi(p) - 1}$. If $\Phi(p)$ is the +order of the multiplicative subgroup modulo $p$ then $b$ must be the multiplicative inverse of $a$. The proof of which is trivial. + +\begin{equation} +ab \equiv a \left (a^{\Phi(p) - 1} \right ) \equiv a^{\Phi(p)} \equiv a^0 \equiv 1 \mbox{ (mod }p\mbox{)} +\end{equation} + +However, as simple as this approach may be it has two serious flaws. It requires that the value of $\Phi(p)$ be known which if $p$ is composite +requires all of the prime factors. This approach also is very slow as the size of $p$ grows. + +A simpler approach is based on the observation that solving for the multiplicative inverse is equivalent to solving the linear +Diophantine\footnote{See LeVeque \cite[pp. 40-43]{LeVeque} for more information.} equation. + +\begin{equation} +ab + pq = 1 +\end{equation} + +Where $a$, $b$, $p$ and $q$ are all integers. If such a pair of integers $ \left < b, q \right >$ exist than $b$ is the multiplicative inverse of +$a$ modulo $p$. The extended Euclidean algorithm (Knuth \cite[pp. 342]{TAOCPV2}) can be used to solve such equations provided $(a, p) = 1$. +However, instead of using that algorithm directly a variant known as the binary Extended Euclidean algorithm will be used in its place. The +binary approach is very similar to the binary greatest common divisor algorithm except it will produce a full solution to the Diophantine +equation. + +\subsection{General Case} +\newpage\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_invmod}. \\ +\textbf{Input}. mp\_int $a$ and $b$, $(a, b) = 1$, $p \ge 2$, $0 < a < p$. \\ +\textbf{Output}. The modular inverse $c \equiv a^{-1} \mbox{ (mod }b\mbox{)}$. \\ +\hline \\ +1. If $b \le 0$ then return(\textit{MP\_VAL}). \\ +2. If $b_0 \equiv 1 \mbox{ (mod }2\mbox{)}$ then use algorithm fast\_mp\_invmod. \\ +3. $x \leftarrow \vert a \vert, y \leftarrow b$ \\ +4. If $x_0 \equiv y_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ then return(\textit{MP\_VAL}). \\ +5. $B \leftarrow 0, C \leftarrow 0, A \leftarrow 1, D \leftarrow 1$ \\ +6. While $u.used > 0$ and $u_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ +\hspace{3mm}6.1 $u \leftarrow \lfloor u / 2 \rfloor$ \\ +\hspace{3mm}6.2 If ($A.used > 0$ and $A_0 \equiv 1 \mbox{ (mod }2\mbox{)}$) or ($B.used > 0$ and $B_0 \equiv 1 \mbox{ (mod }2\mbox{)}$) then \\ +\hspace{6mm}6.2.1 $A \leftarrow A + y$ \\ +\hspace{6mm}6.2.2 $B \leftarrow B - x$ \\ +\hspace{3mm}6.3 $A \leftarrow \lfloor A / 2 \rfloor$ \\ +\hspace{3mm}6.4 $B \leftarrow \lfloor B / 2 \rfloor$ \\ +7. While $v.used > 0$ and $v_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ +\hspace{3mm}7.1 $v \leftarrow \lfloor v / 2 \rfloor$ \\ +\hspace{3mm}7.2 If ($C.used > 0$ and $C_0 \equiv 1 \mbox{ (mod }2\mbox{)}$) or ($D.used > 0$ and $D_0 \equiv 1 \mbox{ (mod }2\mbox{)}$) then \\ +\hspace{6mm}7.2.1 $C \leftarrow C + y$ \\ +\hspace{6mm}7.2.2 $D \leftarrow D - x$ \\ +\hspace{3mm}7.3 $C \leftarrow \lfloor C / 2 \rfloor$ \\ +\hspace{3mm}7.4 $D \leftarrow \lfloor D / 2 \rfloor$ \\ +8. If $u \ge v$ then \\ +\hspace{3mm}8.1 $u \leftarrow u - v$ \\ +\hspace{3mm}8.2 $A \leftarrow A - C$ \\ +\hspace{3mm}8.3 $B \leftarrow B - D$ \\ +9. else \\ +\hspace{3mm}9.1 $v \leftarrow v - u$ \\ +\hspace{3mm}9.2 $C \leftarrow C - A$ \\ +\hspace{3mm}9.3 $D \leftarrow D - B$ \\ +10. If $u \ne 0$ goto step 6. \\ +11. If $v \ne 1$ return(\textit{MP\_VAL}). \\ +12. While $C \le 0$ do \\ +\hspace{3mm}12.1 $C \leftarrow C + b$ \\ +13. While $C \ge b$ do \\ +\hspace{3mm}13.1 $C \leftarrow C - b$ \\ +14. $c \leftarrow C$ \\ +15. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\end{figure} +\textbf{Algorithm mp\_invmod.} +This algorithm computes the modular multiplicative inverse of an integer $a$ modulo an integer $b$. This algorithm is a variation of the +extended binary Euclidean algorithm from HAC \cite[pp. 608]{HAC}. It has been modified to only compute the modular inverse and not a complete +Diophantine solution. + +If $b \le 0$ than the modulus is invalid and MP\_VAL is returned. Similarly if both $a$ and $b$ are even then there cannot be a multiplicative +inverse for $a$ and the error is reported. + +The astute reader will observe that steps seven through nine are very similar to the binary greatest common divisor algorithm mp\_gcd. In this case +the other variables to the Diophantine equation are solved. The algorithm terminates when $u = 0$ in which case the solution is + +\begin{equation} +Ca + Db = v +\end{equation} + +If $v$, the greatest common divisor of $a$ and $b$ is not equal to one then the algorithm will report an error as no inverse exists. Otherwise, $C$ +is the modular inverse of $a$. The actual value of $C$ is congruent to, but not necessarily equal to, the ideal modular inverse which should lie +within $1 \le a^{-1} < b$. Step numbers twelve and thirteen adjust the inverse until it is in range. If the original input $a$ is within $0 < a < p$ +then only a couple of additions or subtractions will be required to adjust the inverse. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_invmod.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +\subsubsection{Odd Moduli} + +When the modulus $b$ is odd the variables $A$ and $C$ are fixed and are not required to compute the inverse. In particular by attempting to solve +the Diophantine $Cb + Da = 1$ only $B$ and $D$ are required to find the inverse of $a$. + +The algorithm fast\_mp\_invmod is a direct adaptation of algorithm mp\_invmod with all all steps involving either $A$ or $C$ removed. This +optimization will halve the time required to compute the modular inverse. + +\section{Primality Tests} + +A non-zero integer $a$ is said to be prime if it is not divisible by any other integer excluding one and itself. For example, $a = 7$ is prime +since the integers $2 \ldots 6$ do not evenly divide $a$. By contrast, $a = 6$ is not prime since $a = 6 = 2 \cdot 3$. + +Prime numbers arise in cryptography considerably as they allow finite fields to be formed. The ability to determine whether an integer is prime or +not quickly has been a viable subject in cryptography and number theory for considerable time. The algorithms that will be presented are all +probablistic algorithms in that when they report an integer is composite it must be composite. However, when the algorithms report an integer is +prime the algorithm may be incorrect. + +As will be discussed it is possible to limit the probability of error so well that for practical purposes the probablity of error might as +well be zero. For the purposes of these discussions let $n$ represent the candidate integer of which the primality is in question. + +\subsection{Trial Division} + +Trial division means to attempt to evenly divide a candidate integer by small prime integers. If the candidate can be evenly divided it obviously +cannot be prime. By dividing by all primes $1 < p \le \sqrt{n}$ this test can actually prove whether an integer is prime. However, such a test +would require a prohibitive amount of time as $n$ grows. + +Instead of dividing by every prime, a smaller, more mangeable set of primes may be used instead. By performing trial division with only a subset +of the primes less than $\sqrt{n} + 1$ the algorithm cannot prove if a candidate is prime. However, often it can prove a candidate is not prime. + +The benefit of this test is that trial division by small values is fairly efficient. Specially compared to the other algorithms that will be +discussed shortly. The probability that this approach correctly identifies a composite candidate when tested with all primes upto $q$ is given by +$1 - {1.12 \over ln(q)}$. The graph (\ref{pic:primality}, will be added later) demonstrates the probability of success for the range +$3 \le q \le 100$. + +At approximately $q = 30$ the gain of performing further tests diminishes fairly quickly. At $q = 90$ further testing is generally not going to +be of any practical use. In the case of LibTomMath the default limit $q = 256$ was chosen since it is not too high and will eliminate +approximately $80\%$ of all candidate integers. The constant \textbf{PRIME\_SIZE} is equal to the number of primes in the test base. The +array \_\_prime\_tab is an array of the first \textbf{PRIME\_SIZE} prime numbers. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_prime\_is\_divisible}. \\ +\textbf{Input}. mp\_int $a$ \\ +\textbf{Output}. $c = 1$ if $n$ is divisible by a small prime, otherwise $c = 0$. \\ +\hline \\ +1. for $ix$ from $0$ to $PRIME\_SIZE$ do \\ +\hspace{3mm}1.1 $d \leftarrow n \mbox{ (mod }\_\_prime\_tab_{ix}\mbox{)}$ \\ +\hspace{3mm}1.2 If $d = 0$ then \\ +\hspace{6mm}1.2.1 $c \leftarrow 1$ \\ +\hspace{6mm}1.2.2 Return(\textit{MP\_OKAY}). \\ +2. $c \leftarrow 0$ \\ +3. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_prime\_is\_divisible} +\end{figure} +\textbf{Algorithm mp\_prime\_is\_divisible.} +This algorithm attempts to determine if a candidate integer $n$ is composite by performing trial divisions. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_prime\_is\_divisible.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +The algorithm defaults to a return of $0$ in case an error occurs. The values in the prime table are all specified to be in the range of a +mp\_digit. The table \_\_prime\_tab is defined in the following file. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_prime\_tab.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +Note that there are two possible tables. When an mp\_digit is 7-bits long only the primes upto $127$ may be included, otherwise the primes +upto $1619$ are used. Note that the value of \textbf{PRIME\_SIZE} is a constant dependent on the size of a mp\_digit. + +\subsection{The Fermat Test} +The Fermat test is probably one the oldest tests to have a non-trivial probability of success. It is based on the fact that if $n$ is in +fact prime then $a^{n} \equiv a \mbox{ (mod }n\mbox{)}$ for all $0 < a < n$. The reason being that if $n$ is prime than the order of +the multiplicative sub group is $n - 1$. Any base $a$ must have an order which divides $n - 1$ and as such $a^n$ is equivalent to +$a^1 = a$. + +If $n$ is composite then any given base $a$ does not have to have a period which divides $n - 1$. In which case +it is possible that $a^n \nequiv a \mbox{ (mod }n\mbox{)}$. However, this test is not absolute as it is possible that the order +of a base will divide $n - 1$ which would then be reported as prime. Such a base yields what is known as a Fermat pseudo-prime. Several +integers known as Carmichael numbers will be a pseudo-prime to all valid bases. Fortunately such numbers are extremely rare as $n$ grows +in size. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_prime\_fermat}. \\ +\textbf{Input}. mp\_int $a$ and $b$, $a \ge 2$, $0 < b < a$. \\ +\textbf{Output}. $c = 1$ if $b^a \equiv b \mbox{ (mod }a\mbox{)}$, otherwise $c = 0$. \\ +\hline \\ +1. $t \leftarrow b^a \mbox{ (mod }a\mbox{)}$ \\ +2. If $t = b$ then \\ +\hspace{3mm}2.1 $c = 1$ \\ +3. else \\ +\hspace{3mm}3.1 $c = 0$ \\ +4. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_prime\_fermat} +\end{figure} +\textbf{Algorithm mp\_prime\_fermat.} +This algorithm determines whether an mp\_int $a$ is a Fermat prime to the base $b$ or not. It uses a single modular exponentiation to +determine the result. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_prime\_fermat.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + +\subsection{The Miller-Rabin Test} +The Miller-Rabin (citation) test is another primality test which has tighter error bounds than the Fermat test specifically with sequentially chosen +candidate integers. The algorithm is based on the observation that if $n - 1 = 2^kr$ and if $b^r \nequiv \pm 1$ then after upto $k - 1$ squarings the +value must be equal to $-1$. The squarings are stopped as soon as $-1$ is observed. If the value of $1$ is observed first it means that +some value not congruent to $\pm 1$ when squared equals one which cannot occur if $n$ is prime. + +\begin{figure}[!here] +\begin{small} +\begin{center} +\begin{tabular}{l} +\hline Algorithm \textbf{mp\_prime\_miller\_rabin}. \\ +\textbf{Input}. mp\_int $a$ and $b$, $a \ge 2$, $0 < b < a$. \\ +\textbf{Output}. $c = 1$ if $a$ is a Miller-Rabin prime to the base $a$, otherwise $c = 0$. \\ +\hline +1. $a' \leftarrow a - 1$ \\ +2. $r \leftarrow n1$ \\ +3. $c \leftarrow 0, s \leftarrow 0$ \\ +4. While $r.used > 0$ and $r_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ +\hspace{3mm}4.1 $s \leftarrow s + 1$ \\ +\hspace{3mm}4.2 $r \leftarrow \lfloor r / 2 \rfloor$ \\ +5. $y \leftarrow b^r \mbox{ (mod }a\mbox{)}$ \\ +6. If $y \nequiv \pm 1$ then \\ +\hspace{3mm}6.1 $j \leftarrow 1$ \\ +\hspace{3mm}6.2 While $j \le (s - 1)$ and $y \nequiv a'$ \\ +\hspace{6mm}6.2.1 $y \leftarrow y^2 \mbox{ (mod }a\mbox{)}$ \\ +\hspace{6mm}6.2.2 If $y = 1$ then goto step 8. \\ +\hspace{6mm}6.2.3 $j \leftarrow j + 1$ \\ +\hspace{3mm}6.3 If $y \nequiv a'$ goto step 8. \\ +7. $c \leftarrow 1$\\ +8. Return(\textit{MP\_OKAY}). \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Algorithm mp\_prime\_miller\_rabin} +\end{figure} +\textbf{Algorithm mp\_prime\_miller\_rabin.} +This algorithm performs one trial round of the Miller-Rabin algorithm to the base $b$. It will set $c = 1$ if the algorithm cannot determine +if $b$ is composite or $c = 0$ if $b$ is provably composite. The values of $s$ and $r$ are computed such that $a' = a - 1 = 2^sr$. + +If the value $y \equiv b^r$ is congruent to $\pm 1$ then the algorithm cannot prove if $a$ is composite or not. Otherwise, the algorithm will +square $y$ upto $s - 1$ times stopping only when $y \equiv -1$. If $y^2 \equiv 1$ and $y \nequiv \pm 1$ then the algorithm can report that $a$ +is provably composite. If the algorithm performs $s - 1$ squarings and $y \nequiv -1$ then $a$ is provably composite. If $a$ is not provably +composite then it is \textit{probably} prime. + +\vspace{+3mm}\begin{small} +\hspace{-5.1mm}{\bf File}: bn\_mp\_prime\_miller\_rabin.c +\vspace{-3mm} +\begin{alltt} +\end{alltt} +\end{small} + + + + +\backmatter +\appendix +\begin{thebibliography}{ABCDEF} +\bibitem[1]{TAOCPV2} +Donald Knuth, \textit{The Art of Computer Programming}, Third Edition, Volume Two, Seminumerical Algorithms, Addison-Wesley, 1998 + +\bibitem[2]{HAC} +A. Menezes, P. van Oorschot, S. Vanstone, \textit{Handbook of Applied Cryptography}, CRC Press, 1996 + +\bibitem[3]{ROSE} +Michael Rosing, \textit{Implementing Elliptic Curve Cryptography}, Manning Publications, 1999 + +\bibitem[4]{COMBA} +Paul G. Comba, \textit{Exponentiation Cryptosystems on the IBM PC}. IBM Systems Journal 29(4): 526-538 (1990) + +\bibitem[5]{KARA} +A. Karatsuba, Doklay Akad. Nauk SSSR 145 (1962), pp.293-294 + +\bibitem[6]{KARAP} +Andre Weimerskirch and Christof Paar, \textit{Generalizations of the Karatsuba Algorithm for Polynomial Multiplication}, Submitted to Design, Codes and Cryptography, March 2002 + +\bibitem[7]{BARRETT} +Paul Barrett, \textit{Implementing the Rivest Shamir and Adleman Public Key Encryption Algorithm on a Standard Digital Signal Processor}, Advances in Cryptology, Crypto '86, Springer-Verlag. + +\bibitem[8]{MONT} +P.L.Montgomery. \textit{Modular multiplication without trial division}. Mathematics of Computation, 44(170):519-521, April 1985. + +\bibitem[9]{DRMET} +Chae Hoon Lim and Pil Joong Lee, \textit{Generating Efficient Primes for Discrete Log Cryptosystems}, POSTECH Information Research Laboratories + +\bibitem[10]{MMB} +J. Daemen and R. Govaerts and J. Vandewalle, \textit{Block ciphers based on Modular Arithmetic}, State and {P}rogress in the {R}esearch of {C}ryptography, 1993, pp. 80-89 + +\bibitem[11]{RSAREF} +R.L. Rivest, A. Shamir, L. Adleman, \textit{A Method for Obtaining Digital Signatures and Public-Key Cryptosystems} + +\bibitem[12]{DHREF} +Whitfield Diffie, Martin E. Hellman, \textit{New Directions in Cryptography}, IEEE Transactions on Information Theory, 1976 + +\bibitem[13]{IEEE} +IEEE Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Std 754-1985) + +\bibitem[14]{GMP} +GNU Multiple Precision (GMP), \url{http://www.swox.com/gmp/} + +\bibitem[15]{MPI} +Multiple Precision Integer Library (MPI), Michael Fromberger, \url{http://thayer.dartmouth.edu/~sting/mpi/} + +\bibitem[16]{OPENSSL} +OpenSSL Cryptographic Toolkit, \url{http://openssl.org} + +\bibitem[17]{LIP} +Large Integer Package, \url{http://home.hetnet.nl/~ecstr/LIP.zip} + +\bibitem[18]{ISOC} +JTC1/SC22/WG14, ISO/IEC 9899:1999, ``A draft rationale for the C99 standard.'' + +\bibitem[19]{JAVA} +The Sun Java Website, \url{http://java.sun.com/} + +\end{thebibliography} + +\input{tommath.ind} + +\end{document} diff --git a/xmhf-64/xmhf/third-party/libtommath/tommath_class.h b/xmhf-64/xmhf/third-party/libtommath/tommath_class.h new file mode 100644 index 0000000000..da30aaa840 --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/tommath_class.h @@ -0,0 +1,1002 @@ +#if !(defined(LTM1) && defined(LTM2) && defined(LTM3)) +#if defined(LTM2) +#define LTM3 +#endif +#if defined(LTM1) +#define LTM2 +#endif +#define LTM1 + +#if defined(LTM_ALL) +#define BN_ERROR_C +#define BN_FAST_MP_INVMOD_C +#define BN_FAST_MP_MONTGOMERY_REDUCE_C +#define BN_FAST_S_MP_MUL_DIGS_C +#define BN_FAST_S_MP_MUL_HIGH_DIGS_C +#define BN_FAST_S_MP_SQR_C +#define BN_MP_2EXPT_C +#define BN_MP_ABS_C +#define BN_MP_ADD_C +#define BN_MP_ADD_D_C +#define BN_MP_ADDMOD_C +#define BN_MP_AND_C +#define BN_MP_CLAMP_C +#define BN_MP_CLEAR_C +#define BN_MP_CLEAR_MULTI_C +#define BN_MP_CMP_C +#define BN_MP_CMP_D_C +#define BN_MP_CMP_MAG_C +#define BN_MP_CNT_LSB_C +#define BN_MP_COPY_C +#define BN_MP_COUNT_BITS_C +#define BN_MP_DIV_C +#define BN_MP_DIV_2_C +#define BN_MP_DIV_2D_C +#define BN_MP_DIV_3_C +#define BN_MP_DIV_D_C +#define BN_MP_DR_IS_MODULUS_C +#define BN_MP_DR_REDUCE_C +#define BN_MP_DR_SETUP_C +#define BN_MP_EXCH_C +#define BN_MP_EXPT_D_C +#define BN_MP_EXPTMOD_C +#define BN_MP_EXPTMOD_FAST_C +#define BN_MP_EXTEUCLID_C +#if !defined(LTM_NO_FILE) +#define BN_MP_FREAD_C +#define BN_MP_FWRITE_C +#endif +#define BN_MP_GCD_C +#define BN_MP_GET_INT_C +#define BN_MP_GROW_C +#define BN_MP_INIT_C +#define BN_MP_INIT_COPY_C +#define BN_MP_INIT_MULTI_C +#define BN_MP_INIT_SET_C +#define BN_MP_INIT_SET_INT_C +#define BN_MP_INIT_SIZE_C +#define BN_MP_INVMOD_C +#define BN_MP_INVMOD_SLOW_C +#define BN_MP_IS_SQUARE_C +#define BN_MP_JACOBI_C +#define BN_MP_KARATSUBA_MUL_C +#define BN_MP_KARATSUBA_SQR_C +#define BN_MP_LCM_C +#define BN_MP_LSHD_C +#define BN_MP_MOD_C +#define BN_MP_MOD_2D_C +#define BN_MP_MOD_D_C +#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C +#define BN_MP_MONTGOMERY_REDUCE_C +#define BN_MP_MONTGOMERY_SETUP_C +#define BN_MP_MUL_C +#define BN_MP_MUL_2_C +#define BN_MP_MUL_2D_C +#define BN_MP_MUL_D_C +#define BN_MP_MULMOD_C +#define BN_MP_N_ROOT_C +#define BN_MP_NEG_C +#define BN_MP_OR_C +#define BN_MP_PRIME_FERMAT_C +#define BN_MP_PRIME_IS_DIVISIBLE_C +#define BN_MP_PRIME_IS_PRIME_C +#define BN_MP_PRIME_MILLER_RABIN_C +#define BN_MP_PRIME_NEXT_PRIME_C +#define BN_MP_PRIME_RABIN_MILLER_TRIALS_C +#define BN_MP_PRIME_RANDOM_EX_C +#define BN_MP_RADIX_SIZE_C +#define BN_MP_RADIX_SMAP_C +#define BN_MP_RAND_C +#define BN_MP_READ_RADIX_C +#define BN_MP_READ_SIGNED_BIN_C +#define BN_MP_READ_UNSIGNED_BIN_C +#define BN_MP_REDUCE_C +#define BN_MP_REDUCE_2K_C +#define BN_MP_REDUCE_2K_L_C +#define BN_MP_REDUCE_2K_SETUP_C +#define BN_MP_REDUCE_2K_SETUP_L_C +#define BN_MP_REDUCE_IS_2K_C +#define BN_MP_REDUCE_IS_2K_L_C +#define BN_MP_REDUCE_SETUP_C +#define BN_MP_RSHD_C +#define BN_MP_SET_C +#define BN_MP_SET_INT_C +#define BN_MP_SHRINK_C +#define BN_MP_SIGNED_BIN_SIZE_C +#define BN_MP_SQR_C +#define BN_MP_SQRMOD_C +#define BN_MP_SQRT_C +#define BN_MP_SUB_C +#define BN_MP_SUB_D_C +#define BN_MP_SUBMOD_C +#define BN_MP_TO_SIGNED_BIN_C +#define BN_MP_TO_SIGNED_BIN_N_C +#define BN_MP_TO_UNSIGNED_BIN_C +#define BN_MP_TO_UNSIGNED_BIN_N_C +#define BN_MP_TOOM_MUL_C +#define BN_MP_TOOM_SQR_C +#define BN_MP_TORADIX_C +#define BN_MP_TORADIX_N_C +#define BN_MP_UNSIGNED_BIN_SIZE_C +#define BN_MP_XOR_C +#define BN_MP_ZERO_C +#define BN_PRIME_TAB_C +#define BN_REVERSE_C +#define BN_S_MP_ADD_C +#define BN_S_MP_EXPTMOD_C +#define BN_S_MP_MUL_DIGS_C +#define BN_S_MP_MUL_HIGH_DIGS_C +#define BN_S_MP_SQR_C +#define BN_S_MP_SUB_C +#define BNCORE_C +#endif + +#if defined(BN_ERROR_C) + #define BN_MP_ERROR_TO_STRING_C +#endif + +#if defined(BN_FAST_MP_INVMOD_C) + #define BN_MP_ISEVEN_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_COPY_C + #define BN_MP_MOD_C + #define BN_MP_SET_C + #define BN_MP_DIV_2_C + #define BN_MP_ISODD_C + #define BN_MP_SUB_C + #define BN_MP_CMP_C + #define BN_MP_ISZERO_C + #define BN_MP_CMP_D_C + #define BN_MP_ADD_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_FAST_MP_MONTGOMERY_REDUCE_C) + #define BN_MP_GROW_C + #define BN_MP_RSHD_C + #define BN_MP_CLAMP_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_FAST_S_MP_MUL_DIGS_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_FAST_S_MP_SQR_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_2EXPT_C) + #define BN_MP_ZERO_C + #define BN_MP_GROW_C +#endif + +#if defined(BN_MP_ABS_C) + #define BN_MP_COPY_C +#endif + +#if defined(BN_MP_ADD_C) + #define BN_S_MP_ADD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_ADD_D_C) + #define BN_MP_GROW_C + #define BN_MP_SUB_D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_ADDMOD_C) + #define BN_MP_INIT_C + #define BN_MP_ADD_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_AND_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_CLAMP_C) +#endif + +#if defined(BN_MP_CLEAR_C) +#endif + +#if defined(BN_MP_CLEAR_MULTI_C) + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_CMP_C) + #define BN_MP_CMP_MAG_C +#endif + +#if defined(BN_MP_CMP_D_C) +#endif + +#if defined(BN_MP_CMP_MAG_C) +#endif + +#if defined(BN_MP_CNT_LSB_C) + #define BN_MP_ISZERO_C +#endif + +#if defined(BN_MP_COPY_C) + #define BN_MP_GROW_C +#endif + +#if defined(BN_MP_COUNT_BITS_C) +#endif + +#if defined(BN_MP_DIV_C) + #define BN_MP_ISZERO_C + #define BN_MP_CMP_MAG_C + #define BN_MP_COPY_C + #define BN_MP_ZERO_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_SET_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_ABS_C + #define BN_MP_MUL_2D_C + #define BN_MP_CMP_C + #define BN_MP_SUB_C + #define BN_MP_ADD_C + #define BN_MP_DIV_2D_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_INIT_C + #define BN_MP_INIT_COPY_C + #define BN_MP_LSHD_C + #define BN_MP_RSHD_C + #define BN_MP_MUL_D_C + #define BN_MP_CLAMP_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_DIV_2_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_DIV_2D_C) + #define BN_MP_COPY_C + #define BN_MP_ZERO_C + #define BN_MP_INIT_C + #define BN_MP_MOD_2D_C + #define BN_MP_CLEAR_C + #define BN_MP_RSHD_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C +#endif + +#if defined(BN_MP_DIV_3_C) + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_DIV_D_C) + #define BN_MP_ISZERO_C + #define BN_MP_COPY_C + #define BN_MP_DIV_2D_C + #define BN_MP_DIV_3_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_DR_IS_MODULUS_C) +#endif + +#if defined(BN_MP_DR_REDUCE_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_DR_SETUP_C) +#endif + +#if defined(BN_MP_EXCH_C) +#endif + +#if defined(BN_MP_EXPT_D_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_SET_C + #define BN_MP_SQR_C + #define BN_MP_CLEAR_C + #define BN_MP_MUL_C +#endif + +#if defined(BN_MP_EXPTMOD_C) + #define BN_MP_INIT_C + #define BN_MP_INVMOD_C + #define BN_MP_CLEAR_C + #define BN_MP_ABS_C + #define BN_MP_CLEAR_MULTI_C + #define BN_MP_REDUCE_IS_2K_L_C + #define BN_S_MP_EXPTMOD_C + #define BN_MP_DR_IS_MODULUS_C + #define BN_MP_REDUCE_IS_2K_C + #define BN_MP_ISODD_C + #define BN_MP_EXPTMOD_FAST_C +#endif + +#if defined(BN_MP_EXPTMOD_FAST_C) + #define BN_MP_COUNT_BITS_C + #define BN_MP_INIT_C + #define BN_MP_CLEAR_C + #define BN_MP_MONTGOMERY_SETUP_C + #define BN_FAST_MP_MONTGOMERY_REDUCE_C + #define BN_MP_MONTGOMERY_REDUCE_C + #define BN_MP_DR_SETUP_C + #define BN_MP_DR_REDUCE_C + #define BN_MP_REDUCE_2K_SETUP_C + #define BN_MP_REDUCE_2K_C + #define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C + #define BN_MP_MULMOD_C + #define BN_MP_SET_C + #define BN_MP_MOD_C + #define BN_MP_COPY_C + #define BN_MP_SQR_C + #define BN_MP_MUL_C + #define BN_MP_EXCH_C +#endif + +#if defined(BN_MP_EXTEUCLID_C) + #define BN_MP_INIT_MULTI_C + #define BN_MP_SET_C + #define BN_MP_COPY_C + #define BN_MP_ISZERO_C + #define BN_MP_DIV_C + #define BN_MP_MUL_C + #define BN_MP_SUB_C + #define BN_MP_NEG_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_FREAD_C) + #define BN_MP_ZERO_C + #define BN_MP_S_RMAP_C + #define BN_MP_MUL_D_C + #define BN_MP_ADD_D_C + #define BN_MP_CMP_D_C +#endif + +#if defined(BN_MP_FWRITE_C) + #define BN_MP_RADIX_SIZE_C + #define BN_MP_TORADIX_C +#endif + +#if defined(BN_MP_GCD_C) + #define BN_MP_ISZERO_C + #define BN_MP_ABS_C + #define BN_MP_ZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_CNT_LSB_C + #define BN_MP_DIV_2D_C + #define BN_MP_CMP_MAG_C + #define BN_MP_EXCH_C + #define BN_S_MP_SUB_C + #define BN_MP_MUL_2D_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_GET_INT_C) +#endif + +#if defined(BN_MP_GROW_C) +#endif + +#if defined(BN_MP_INIT_C) +#endif + +#if defined(BN_MP_INIT_COPY_C) + #define BN_MP_COPY_C +#endif + +#if defined(BN_MP_INIT_MULTI_C) + #define BN_MP_ERR_C + #define BN_MP_INIT_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_INIT_SET_C) + #define BN_MP_INIT_C + #define BN_MP_SET_C +#endif + +#if defined(BN_MP_INIT_SET_INT_C) + #define BN_MP_INIT_C + #define BN_MP_SET_INT_C +#endif + +#if defined(BN_MP_INIT_SIZE_C) + #define BN_MP_INIT_C +#endif + +#if defined(BN_MP_INVMOD_C) + #define BN_MP_ISZERO_C + #define BN_MP_ISODD_C + #define BN_FAST_MP_INVMOD_C + #define BN_MP_INVMOD_SLOW_C +#endif + +#if defined(BN_MP_INVMOD_SLOW_C) + #define BN_MP_ISZERO_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_MOD_C + #define BN_MP_COPY_C + #define BN_MP_ISEVEN_C + #define BN_MP_SET_C + #define BN_MP_DIV_2_C + #define BN_MP_ISODD_C + #define BN_MP_ADD_C + #define BN_MP_SUB_C + #define BN_MP_CMP_C + #define BN_MP_CMP_D_C + #define BN_MP_CMP_MAG_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_IS_SQUARE_C) + #define BN_MP_MOD_D_C + #define BN_MP_INIT_SET_INT_C + #define BN_MP_MOD_C + #define BN_MP_GET_INT_C + #define BN_MP_SQRT_C + #define BN_MP_SQR_C + #define BN_MP_CMP_MAG_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_JACOBI_C) + #define BN_MP_CMP_D_C + #define BN_MP_ISZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_CNT_LSB_C + #define BN_MP_DIV_2D_C + #define BN_MP_MOD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_KARATSUBA_MUL_C) + #define BN_MP_MUL_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_SUB_C + #define BN_MP_ADD_C + #define BN_MP_LSHD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_KARATSUBA_SQR_C) + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_SQR_C + #define BN_MP_SUB_C + #define BN_S_MP_ADD_C + #define BN_MP_LSHD_C + #define BN_MP_ADD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_LCM_C) + #define BN_MP_INIT_MULTI_C + #define BN_MP_GCD_C + #define BN_MP_CMP_MAG_C + #define BN_MP_DIV_C + #define BN_MP_MUL_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_LSHD_C) + #define BN_MP_GROW_C + #define BN_MP_RSHD_C +#endif + +#if defined(BN_MP_MOD_C) + #define BN_MP_INIT_C + #define BN_MP_DIV_C + #define BN_MP_CLEAR_C + #define BN_MP_ADD_C + #define BN_MP_EXCH_C +#endif + +#if defined(BN_MP_MOD_2D_C) + #define BN_MP_ZERO_C + #define BN_MP_COPY_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_MOD_D_C) + #define BN_MP_DIV_D_C +#endif + +#if defined(BN_MP_MONTGOMERY_CALC_NORMALIZATION_C) + #define BN_MP_COUNT_BITS_C + #define BN_MP_2EXPT_C + #define BN_MP_SET_C + #define BN_MP_MUL_2_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_MONTGOMERY_REDUCE_C) + #define BN_FAST_MP_MONTGOMERY_REDUCE_C + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C + #define BN_MP_RSHD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_MONTGOMERY_SETUP_C) +#endif + +#if defined(BN_MP_MUL_C) + #define BN_MP_TOOM_MUL_C + #define BN_MP_KARATSUBA_MUL_C + #define BN_FAST_S_MP_MUL_DIGS_C + #define BN_S_MP_MUL_C + #define BN_S_MP_MUL_DIGS_C +#endif + +#if defined(BN_MP_MUL_2_C) + #define BN_MP_GROW_C +#endif + +#if defined(BN_MP_MUL_2D_C) + #define BN_MP_COPY_C + #define BN_MP_GROW_C + #define BN_MP_LSHD_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_MUL_D_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_MULMOD_C) + #define BN_MP_INIT_C + #define BN_MP_MUL_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_N_ROOT_C) + #define BN_MP_INIT_C + #define BN_MP_SET_C + #define BN_MP_COPY_C + #define BN_MP_EXPT_D_C + #define BN_MP_MUL_C + #define BN_MP_SUB_C + #define BN_MP_MUL_D_C + #define BN_MP_DIV_C + #define BN_MP_CMP_C + #define BN_MP_SUB_D_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_NEG_C) + #define BN_MP_COPY_C + #define BN_MP_ISZERO_C +#endif + +#if defined(BN_MP_OR_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_FERMAT_C) + #define BN_MP_CMP_D_C + #define BN_MP_INIT_C + #define BN_MP_EXPTMOD_C + #define BN_MP_CMP_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_IS_DIVISIBLE_C) + #define BN_MP_MOD_D_C +#endif + +#if defined(BN_MP_PRIME_IS_PRIME_C) + #define BN_MP_CMP_D_C + #define BN_MP_PRIME_IS_DIVISIBLE_C + #define BN_MP_INIT_C + #define BN_MP_SET_C + #define BN_MP_PRIME_MILLER_RABIN_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_MILLER_RABIN_C) + #define BN_MP_CMP_D_C + #define BN_MP_INIT_COPY_C + #define BN_MP_SUB_D_C + #define BN_MP_CNT_LSB_C + #define BN_MP_DIV_2D_C + #define BN_MP_EXPTMOD_C + #define BN_MP_CMP_C + #define BN_MP_SQRMOD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_NEXT_PRIME_C) + #define BN_MP_CMP_D_C + #define BN_MP_SET_C + #define BN_MP_SUB_D_C + #define BN_MP_ISEVEN_C + #define BN_MP_MOD_D_C + #define BN_MP_INIT_C + #define BN_MP_ADD_D_C + #define BN_MP_PRIME_MILLER_RABIN_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_RABIN_MILLER_TRIALS_C) +#endif + +#if defined(BN_MP_PRIME_RANDOM_EX_C) + #define BN_MP_READ_UNSIGNED_BIN_C + #define BN_MP_PRIME_IS_PRIME_C + #define BN_MP_SUB_D_C + #define BN_MP_DIV_2_C + #define BN_MP_MUL_2_C + #define BN_MP_ADD_D_C +#endif + +#if defined(BN_MP_RADIX_SIZE_C) + #define BN_MP_COUNT_BITS_C + #define BN_MP_INIT_COPY_C + #define BN_MP_ISZERO_C + #define BN_MP_DIV_D_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_RADIX_SMAP_C) + #define BN_MP_S_RMAP_C +#endif + +#if defined(BN_MP_RAND_C) + #define BN_MP_ZERO_C + #define BN_MP_ADD_D_C + #define BN_MP_LSHD_C +#endif + +#if defined(BN_MP_READ_RADIX_C) + #define BN_MP_ZERO_C + #define BN_MP_S_RMAP_C + #define BN_MP_RADIX_SMAP_C + #define BN_MP_MUL_D_C + #define BN_MP_ADD_D_C + #define BN_MP_ISZERO_C +#endif + +#if defined(BN_MP_READ_SIGNED_BIN_C) + #define BN_MP_READ_UNSIGNED_BIN_C +#endif + +#if defined(BN_MP_READ_UNSIGNED_BIN_C) + #define BN_MP_GROW_C + #define BN_MP_ZERO_C + #define BN_MP_MUL_2D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_REDUCE_C) + #define BN_MP_REDUCE_SETUP_C + #define BN_MP_INIT_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_MUL_C + #define BN_S_MP_MUL_HIGH_DIGS_C + #define BN_FAST_S_MP_MUL_HIGH_DIGS_C + #define BN_MP_MOD_2D_C + #define BN_S_MP_MUL_DIGS_C + #define BN_MP_SUB_C + #define BN_MP_CMP_D_C + #define BN_MP_SET_C + #define BN_MP_LSHD_C + #define BN_MP_ADD_C + #define BN_MP_CMP_C + #define BN_S_MP_SUB_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_REDUCE_2K_C) + #define BN_MP_INIT_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_DIV_2D_C + #define BN_MP_MUL_D_C + #define BN_S_MP_ADD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_REDUCE_2K_L_C) + #define BN_MP_INIT_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_DIV_2D_C + #define BN_MP_MUL_C + #define BN_S_MP_ADD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_REDUCE_2K_SETUP_C) + #define BN_MP_INIT_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_2EXPT_C + #define BN_MP_CLEAR_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_REDUCE_2K_SETUP_L_C) + #define BN_MP_INIT_C + #define BN_MP_2EXPT_C + #define BN_MP_COUNT_BITS_C + #define BN_S_MP_SUB_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_REDUCE_IS_2K_C) + #define BN_MP_REDUCE_2K_C + #define BN_MP_COUNT_BITS_C +#endif + +#if defined(BN_MP_REDUCE_IS_2K_L_C) +#endif + +#if defined(BN_MP_REDUCE_SETUP_C) + #define BN_MP_2EXPT_C + #define BN_MP_DIV_C +#endif + +#if defined(BN_MP_RSHD_C) + #define BN_MP_ZERO_C +#endif + +#if defined(BN_MP_SET_C) + #define BN_MP_ZERO_C +#endif + +#if defined(BN_MP_SET_INT_C) + #define BN_MP_ZERO_C + #define BN_MP_MUL_2D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_SHRINK_C) +#endif + +#if defined(BN_MP_SIGNED_BIN_SIZE_C) + #define BN_MP_UNSIGNED_BIN_SIZE_C +#endif + +#if defined(BN_MP_SQR_C) + #define BN_MP_TOOM_SQR_C + #define BN_MP_KARATSUBA_SQR_C + #define BN_FAST_S_MP_SQR_C + #define BN_S_MP_SQR_C +#endif + +#if defined(BN_MP_SQRMOD_C) + #define BN_MP_INIT_C + #define BN_MP_SQR_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_SQRT_C) + #define BN_MP_N_ROOT_C + #define BN_MP_ISZERO_C + #define BN_MP_ZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_DIV_C + #define BN_MP_ADD_C + #define BN_MP_DIV_2_C + #define BN_MP_CMP_MAG_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_SUB_C) + #define BN_S_MP_ADD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_SUB_D_C) + #define BN_MP_GROW_C + #define BN_MP_ADD_D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_SUBMOD_C) + #define BN_MP_INIT_C + #define BN_MP_SUB_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_TO_SIGNED_BIN_C) + #define BN_MP_TO_UNSIGNED_BIN_C +#endif + +#if defined(BN_MP_TO_SIGNED_BIN_N_C) + #define BN_MP_SIGNED_BIN_SIZE_C + #define BN_MP_TO_SIGNED_BIN_C +#endif + +#if defined(BN_MP_TO_UNSIGNED_BIN_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_ISZERO_C + #define BN_MP_DIV_2D_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_TO_UNSIGNED_BIN_N_C) + #define BN_MP_UNSIGNED_BIN_SIZE_C + #define BN_MP_TO_UNSIGNED_BIN_C +#endif + +#if defined(BN_MP_TOOM_MUL_C) + #define BN_MP_INIT_MULTI_C + #define BN_MP_MOD_2D_C + #define BN_MP_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_MUL_C + #define BN_MP_MUL_2_C + #define BN_MP_ADD_C + #define BN_MP_SUB_C + #define BN_MP_DIV_2_C + #define BN_MP_MUL_2D_C + #define BN_MP_MUL_D_C + #define BN_MP_DIV_3_C + #define BN_MP_LSHD_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_TOOM_SQR_C) + #define BN_MP_INIT_MULTI_C + #define BN_MP_MOD_2D_C + #define BN_MP_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_SQR_C + #define BN_MP_MUL_2_C + #define BN_MP_ADD_C + #define BN_MP_SUB_C + #define BN_MP_DIV_2_C + #define BN_MP_MUL_2D_C + #define BN_MP_MUL_D_C + #define BN_MP_DIV_3_C + #define BN_MP_LSHD_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_TORADIX_C) + #define BN_MP_ISZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_DIV_D_C + #define BN_MP_CLEAR_C + #define BN_MP_S_RMAP_C +#endif + +#if defined(BN_MP_TORADIX_N_C) + #define BN_MP_ISZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_DIV_D_C + #define BN_MP_CLEAR_C + #define BN_MP_S_RMAP_C +#endif + +#if defined(BN_MP_UNSIGNED_BIN_SIZE_C) + #define BN_MP_COUNT_BITS_C +#endif + +#if defined(BN_MP_XOR_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_ZERO_C) +#endif + +#if defined(BN_PRIME_TAB_C) +#endif + +#if defined(BN_REVERSE_C) +#endif + +#if defined(BN_S_MP_ADD_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_S_MP_EXPTMOD_C) + #define BN_MP_COUNT_BITS_C + #define BN_MP_INIT_C + #define BN_MP_CLEAR_C + #define BN_MP_REDUCE_SETUP_C + #define BN_MP_REDUCE_C + #define BN_MP_REDUCE_2K_SETUP_L_C + #define BN_MP_REDUCE_2K_L_C + #define BN_MP_MOD_C + #define BN_MP_COPY_C + #define BN_MP_SQR_C + #define BN_MP_MUL_C + #define BN_MP_SET_C + #define BN_MP_EXCH_C +#endif + +#if defined(BN_S_MP_MUL_DIGS_C) + #define BN_FAST_S_MP_MUL_DIGS_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_S_MP_MUL_HIGH_DIGS_C) + #define BN_FAST_S_MP_MUL_HIGH_DIGS_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_S_MP_SQR_C) + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_S_MP_SUB_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BNCORE_C) +#endif + +#ifdef LTM3 +#define LTM_LAST +#endif +#include +#include +#else +#define LTM_LAST + +#endif + +/* $Source$ */ +/* $Revision: 0.36 $ */ +/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/xmhf-64/xmhf/third-party/libtommath/tommath_superclass.h b/xmhf-64/xmhf/third-party/libtommath/tommath_superclass.h new file mode 100644 index 0000000000..b35b77d75f --- /dev/null +++ b/xmhf-64/xmhf/third-party/libtommath/tommath_superclass.h @@ -0,0 +1,76 @@ +/* super class file for PK algos */ + +/* default ... include all MPI */ +#define LTM_ALL + +/* RSA only (does not support DH/DSA/ECC) */ +/* #define SC_RSA_1 */ + +/* For reference.... On an Athlon64 optimizing for speed... + + LTM's mpi.o with all functions [striped] is 142KiB in size. + +*/ + +/* Works for RSA only, mpi.o is 68KiB */ +#ifdef SC_RSA_1 + #define BN_MP_SHRINK_C + #define BN_MP_LCM_C + #define BN_MP_PRIME_RANDOM_EX_C + #define BN_MP_INVMOD_C + #define BN_MP_GCD_C + #define BN_MP_MOD_C + #define BN_MP_MULMOD_C + #define BN_MP_ADDMOD_C + #define BN_MP_EXPTMOD_C + #define BN_MP_SET_INT_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_CLEAR_MULTI_C + #define BN_MP_UNSIGNED_BIN_SIZE_C + #define BN_MP_TO_UNSIGNED_BIN_C + #define BN_MP_MOD_D_C + #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C + #define BN_REVERSE_C + #define BN_PRIME_TAB_C + + /* other modifiers */ + #define BN_MP_DIV_SMALL /* Slower division, not critical */ + + /* here we are on the last pass so we turn things off. The functions classes are still there + * but we remove them specifically from the build. This also invokes tweaks in functions + * like removing support for even moduli, etc... + */ +#ifdef LTM_LAST + #undef BN_MP_TOOM_MUL_C + #undef BN_MP_TOOM_SQR_C + #undef BN_MP_KARATSUBA_MUL_C + #undef BN_MP_KARATSUBA_SQR_C + #undef BN_MP_REDUCE_C + #undef BN_MP_REDUCE_SETUP_C + #undef BN_MP_DR_IS_MODULUS_C + #undef BN_MP_DR_SETUP_C + #undef BN_MP_DR_REDUCE_C + #undef BN_MP_REDUCE_IS_2K_C + #undef BN_MP_REDUCE_2K_SETUP_C + #undef BN_MP_REDUCE_2K_C + #undef BN_S_MP_EXPTMOD_C + #undef BN_MP_DIV_3_C + #undef BN_S_MP_MUL_HIGH_DIGS_C + #undef BN_FAST_S_MP_MUL_HIGH_DIGS_C + #undef BN_FAST_MP_INVMOD_C + + /* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold + * which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines] + * which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without + * trouble. + */ + #undef BN_S_MP_MUL_DIGS_C + #undef BN_S_MP_SQR_C + #undef BN_MP_MONTGOMERY_REDUCE_C +#endif + +#endif + +/* $Source$ */ +/* $Revision: 0.36 $ */ +/* $Date: 2005-08-01 16:37:28 +0000 $ */