├── .github └── workflows │ └── ci.yml ├── .gitmodules ├── LICENSE ├── Makefile ├── README.md ├── default.nix ├── document ├── device_driver_tutorial.md └── tsrc │ └── intro.tex ├── hardware ├── fpga │ ├── Makefile │ ├── minicom_dma_test.txt │ ├── minicom_test1.txt │ ├── quartus │ │ ├── CYCLONEV-GT-DK │ │ │ ├── fw_jump.bin │ │ │ ├── iob_soc.dtb │ │ │ ├── iob_soc_opencryptolinux_fpga_wrapper.v │ │ │ ├── iob_soc_opencryptolinux_fpga_wrapper_dev.sdc │ │ │ └── linux_build_macros.txt │ │ ├── build.mk │ │ ├── build.tcl │ │ └── timing.tcl │ └── vivado │ │ ├── AES-KU040-DB-G │ │ ├── fw_jump.bin │ │ ├── iob_soc.dtb │ │ ├── iob_soc_opencryptolinux_fpga_wrapper.v │ │ ├── iob_soc_opencryptolinux_fpga_wrapper_dev.sdc │ │ └── linux_build_macros.txt │ │ ├── build.tcl │ │ └── iob_soc_opencryptolinux_fpga_wrapper_tool.sdc ├── simulation │ ├── fw_jump.bin │ ├── iob_soc.dtb │ ├── linux_build_macros.txt │ ├── sim_build.mk │ └── src │ │ ├── bsp.vh │ │ └── iob_soc_opencryptolinux_sim_wrapper.v └── src │ ├── axi_interconnect.v │ ├── axi_ram.v │ ├── eth_example.txt │ ├── iob2axil.v │ ├── iob_soc_opencryptolinux.v │ ├── iob_soc_opencryptolinux_boot_ctr.v │ └── units │ ├── Mux4.v │ ├── RSBox.v │ ├── SBox.v │ ├── xunitF.v │ └── xunitM.v ├── iob_soc_opencryptolinux.py ├── scripts ├── check_if_run_linux.py └── iob_soc_opencryptolinux_create_periphs_tmp.py └── software ├── KAT ├── AESECB256.rsp ├── McElieceRound4kat_kem.rsp ├── McElieceRound4kat_kem_short.rsp └── SHA256ShortMsg.rsp ├── Makefile ├── buildroot └── board │ └── IObundle │ └── iob-soc │ └── rootfs-overlay │ ├── etc │ ├── init.d │ │ ├── S10mdev │ │ └── S99IObundleVerification │ └── mdev.conf │ └── root │ └── dma_demo │ ├── dma_demo.c │ ├── iob-axistream-in-user.c │ ├── iob-axistream-in-user.h │ ├── iob-axistream-out-user.c │ ├── iob-axistream-out-user.h │ ├── iob-dma-user.c │ ├── iob-dma-user.h │ ├── iob-sysfs-common.c │ ├── iob-sysfs-common.h │ ├── iob-timer-user.c │ ├── iob-timer-user.h │ ├── iob-uart16550.c │ └── iob-uart16550.h ├── iob_soc_dma_demo.dts ├── linux_config ├── src ├── Image ├── clint.h ├── crypto │ ├── McEliece │ │ ├── LICENSE │ │ ├── Makefile │ │ ├── Makefile.Microsoft_nmake │ │ ├── aes256ctr.c │ │ ├── aes256ctr.h │ │ ├── api.h │ │ ├── arena.c │ │ ├── arena.h │ │ ├── benes.c │ │ ├── benes.h │ │ ├── bm.c │ │ ├── bm.h │ │ ├── common │ │ │ ├── aes.c │ │ │ ├── aes.h │ │ │ ├── compat.h │ │ │ ├── crypto_declassify.h │ │ │ ├── fips202.c │ │ │ ├── fips202.h │ │ │ ├── nistkatrng.c │ │ │ ├── nistkatrng.h │ │ │ ├── nistseedexpander.c │ │ │ ├── nistseedexpander.h │ │ │ ├── randombytes.c │ │ │ ├── randombytes.h │ │ │ ├── sha2.c │ │ │ ├── sha2.h │ │ │ ├── sp800-185.c │ │ │ └── sp800-185.h │ │ ├── controlbits.c │ │ ├── controlbits.h │ │ ├── crypto_hash.h │ │ ├── crypto_int16.c │ │ ├── crypto_int16.h │ │ ├── crypto_int32.c │ │ ├── crypto_int32.h │ │ ├── crypto_kem.h │ │ ├── crypto_uint16.c │ │ ├── crypto_uint16.h │ │ ├── crypto_uint32.c │ │ ├── crypto_uint32.h │ │ ├── crypto_uint64.c │ │ ├── crypto_uint64.h │ │ ├── decrypt.c │ │ ├── decrypt.h │ │ ├── encrypt.c │ │ ├── encrypt.h │ │ ├── gf.c │ │ ├── gf.h │ │ ├── int32_sort.h │ │ ├── namespace.h │ │ ├── operations.c │ │ ├── operations.h │ │ ├── params.h │ │ ├── pk_gen.c │ │ ├── pk_gen.h │ │ ├── root.c │ │ ├── root.h │ │ ├── sk_gen.c │ │ ├── sk_gen.h │ │ ├── synd.c │ │ ├── synd.h │ │ ├── transpose.c │ │ ├── transpose.h │ │ ├── uint64_sort.h │ │ ├── util.c │ │ └── util.h │ ├── README.md │ ├── aes.c │ ├── aes.h │ ├── sha2.h │ └── sha2_old.c ├── io.h ├── iob_soc_opencryptolinux_boot.S ├── iob_soc_opencryptolinux_boot.c ├── iob_soc_opencryptolinux_boot.lds ├── iob_soc_opencryptolinux_firmware.S ├── iob_soc_opencryptolinux_firmware.c ├── iob_soc_opencryptolinux_firmware.lds ├── linux │ ├── crypto.c │ ├── unitConfiguration.h │ ├── versat.h │ ├── versatCrypto.c │ ├── versatCrypto.h │ └── versat_accel.h ├── plic.h ├── riscv-csr.h ├── riscv-interrupts.h ├── rootfs.cpio.gz ├── soc.h ├── type.h ├── unitConfiguration.h ├── versat_crypto.c ├── versat_crypto.h ├── versat_crypto_common_tests.c ├── versat_crypto_tests.c ├── versat_crypto_tests.h ├── versat_mceliece.c └── versat_simple_crypto_tests.c ├── sw_build.mk ├── tests ├── exampleTransfer.sh ├── opensslValues.sh ├── setupTest.sh └── test.sh └── versat ├── module ├── Makefile ├── versat.c └── versat.ko └── versatSpec.txt /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | # Set default shell as interactive (source ~/.bashrc) 4 | defaults: 5 | run: 6 | shell: bash -ieo pipefail {0} 7 | 8 | # Run only one instance of this workflow at a time 9 | # cancel-in-progress: stop running workflow and run latest instead 10 | concurrency: 11 | group: ${{ github.workflow }}-${{ github.ref }} 12 | cancel-in-progress: true 13 | 14 | on: 15 | push: 16 | branches: 17 | - master 18 | # Don't forget to require approval for all outside collaborators 19 | pull_request: 20 | branches: '*' 21 | # Allow manual workflow runs 22 | workflow_dispatch: 23 | 24 | jobs: 25 | 26 | spi: 27 | runs-on: self-hosted 28 | timeout-minutes: 20 29 | # run even if previous job failed 30 | if: ${{ !cancelled() }} 31 | 32 | steps: 33 | - uses: actions/checkout@v4 34 | with: 35 | submodules: 'recursive' 36 | - name: run spi test 37 | run: nix-shell --run "make -C submodules/SPI/ clean build-setup && make -C submodules/iob_spi_master_V0.10/ sim-run" 38 | 39 | uart16550: 40 | runs-on: self-hosted 41 | timeout-minutes: 5 42 | # run even if previous job failed 43 | if: ${{ !cancelled() }} 44 | 45 | steps: 46 | - uses: actions/checkout@v4 47 | with: 48 | submodules: 'recursive' 49 | - name: run uart16550 test 50 | run: nix-shell --run "make -C submodules/UART16550/ clean build-setup && make -C submodules/iob_uart16550_V0.10/ sim-run" 51 | 52 | iverilog-baremetal: 53 | runs-on: self-hosted 54 | timeout-minutes: 120 55 | # run even if previous job failed 56 | if: ${{ !cancelled() }} 57 | 58 | steps: 59 | - uses: actions/checkout@v4 60 | with: 61 | submodules: 'recursive' 62 | - name: clean 63 | run: nix-shell --run "make clean" 64 | - name: setup init_mem ext_mem 65 | run: nix-shell --run "make setup INIT_MEM=1 RUN_LINUX=0" 66 | - name: icarus test 67 | run: nix-shell --run "make -C ../iob_soc_o* sim-run" 68 | 69 | verilator-baremetal: 70 | runs-on: self-hosted 71 | timeout-minutes: 90 72 | # run even if previous job failed 73 | if: ${{ !cancelled() }} 74 | 75 | steps: 76 | - uses: actions/checkout@v4 77 | with: 78 | submodules: 'recursive' 79 | - name: clean 80 | run: nix-shell --run "make clean" 81 | - name: setup no_init_mem ext_mem 82 | run: nix-shell --run "make setup INIT_MEM=0 RUN_LINUX=0" 83 | - name: verilator test 84 | run: nix-shell --run "make -C ../iob_soc_o* sim-run SIMULATOR=verilator" 85 | 86 | 87 | cyclonev: 88 | runs-on: self-hosted 89 | timeout-minutes: 90 90 | # run even if previous job failed 91 | if: ${{ !cancelled() }} 92 | # run after indicated job 93 | needs: [ iverilog-baremetal ] 94 | 95 | steps: 96 | - uses: actions/checkout@v4 97 | with: 98 | submodules: 'recursive' 99 | - name: test baremetal 100 | run: make fpga-run RUN_LINUX=0 BOARD=CYCLONEV-GT-DK 101 | - name: test linux 102 | run: make test-linux-fpga-connect BOARD=CYCLONEV-GT-DK 103 | 104 | aes-ku040: 105 | runs-on: self-hosted 106 | timeout-minutes: 90 107 | # run even if previous job failed 108 | if: ${{ !cancelled() }} 109 | # run after indicated job 110 | needs: [ iverilog-baremetal ] 111 | 112 | steps: 113 | - uses: actions/checkout@v4 114 | with: 115 | submodules: 'recursive' 116 | - name: test baremetal 117 | run: make fpga-run RUN_LINUX=0 BOARD=AES-KU040-DB-G 118 | - name: test linux 119 | run: make test-linux-fpga-connect BOARD=AES-KU040-DB-G 120 | 121 | dma_demo: 122 | runs-on: self-hosted 123 | timeout-minutes: 90 124 | # run even if previous job failed 125 | if: ${{ !cancelled() }} 126 | # run after indicated job 127 | needs: [ aes-ku040 ] 128 | 129 | steps: 130 | - uses: actions/checkout@v4 131 | with: 132 | submodules: 'recursive' 133 | - name: test dma 134 | run: make dma-demo 135 | 136 | ## doc: 137 | ## runs-on: self-hosted 138 | ## timeout-minutes: 60 139 | ## if: ${{ !cancelled() }} 140 | ## needs: [ cyclonev, aes-ku040 ] 141 | ## 142 | ## steps: 143 | ## - uses: actions/checkout@v4 144 | ## with: 145 | ## submodules: 'recursive' 146 | ## - name: clean 147 | ## run: nix-shell --run "make clean" 148 | ## - name: setup 149 | ## run: nix-shell --run "make setup" 150 | ## - name: doc test 151 | ## run: nix-shell --run "make -C ../iob_soc_o* doc-test" 152 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "submodules/VEXRISCV"] 2 | path = submodules/VEXRISCV 3 | url = git@github.com:IObundle/iob-vexriscv.git 4 | [submodule "submodules/UART16550"] 5 | path = submodules/UART16550 6 | url = git@github.com:IObundle/iob-uart16550.git 7 | [submodule "submodules/OS"] 8 | path = submodules/OS 9 | url = git@github.com:IObundle/iob-linux.git 10 | [submodule "submodules/IOBSOC"] 11 | path = submodules/IOBSOC 12 | url = git@github.com:IObundle/iob-soc.git 13 | [submodule "submodules/SPI"] 14 | path = submodules/SPI 15 | url = git@github.com:IObundle/iob-spi.git 16 | [submodule "submodules/VERSAT"] 17 | path = submodules/VERSAT 18 | url = git@github.com:IObundle/iob-versat.git 19 | [submodule "submodules/ETHERNET"] 20 | path = submodules/ETHERNET 21 | url = git@github.com:IObundle/iob-eth.git 22 | [submodule "submodules/AXISTREAM"] 23 | path = submodules/AXISTREAM 24 | url = git@github.com:IObundle/iob-axis.git 25 | [submodule "submodules/DMA"] 26 | path = submodules/DMA 27 | url = git@github.com:IObundle/iob-dma.git 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020-2024 IObundle, Lda. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? import (builtins.fetchTarball { 2 | # Descriptive name to make the store path easier to identify 3 | name = "nixos-22.11"; 4 | # Commit hash for nixos-22.11 5 | url = "https://github.com/NixOS/nixpkgs/archive/refs/tags/22.11.tar.gz"; 6 | # Hash obtained using `nix-prefetch-url --unpack ` 7 | sha256 = "11w3wn2yjhaa5pv20gbfbirvjq6i3m7pqrq2msf0g7cv44vijwgw"; 8 | }) {}}: 9 | let 10 | # Import the original iob-soc default.nix and get its attributes 11 | origShell = import ./submodules/IOBSOC/submodules/LIB/scripts/default.nix { inherit pkgs; }; 12 | in 13 | pkgs.mkShell { 14 | # Include the original packages 15 | buildInputs = with pkgs; origShell.buildInputs ++ [ 16 | (callPackage ./submodules/VERSAT/versat.nix {}) 17 | (callPackage ./submodules/OS/scripts/riscv-gnu-toolchain.nix {}) 18 | ]; 19 | } 20 | -------------------------------------------------------------------------------- /document/tsrc/intro.tex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IObundle/iob-soc-opencryptolinux/dec99d3afd50e8a53ca2a4e01fdc8f3b873746fa/document/tsrc/intro.tex -------------------------------------------------------------------------------- /hardware/fpga/Makefile: -------------------------------------------------------------------------------- 1 | # This file becomes the fpga makefile when copied to the build 2 | # directory 3 | 4 | SHELL:=bash 5 | 6 | include ../../config_build.mk 7 | 8 | #include local fpga build segment 9 | ifneq ($(wildcard fpga_build.mk),) 10 | include fpga_build.mk 11 | endif 12 | 13 | REMOTE_BUILD_DIR=$(USER)/$(BUILD_DIR_NAME) 14 | REMOTE_FPGA_DIR=$(REMOTE_BUILD_DIR)/hardware/fpga 15 | EMB_DIR = ../../software 16 | PYTHON_DIR = ../../scripts 17 | 18 | #default board 19 | BOARD ?= CYCLONEV-GT-DK 20 | 21 | #fpga toolchain 22 | FPGA_TOOL:=$(shell find . -name $(BOARD) | cut -d"/" -f2) 23 | 24 | FPGA_TOP ?=$(NAME)_fpga_wrapper 25 | 26 | ifeq ($(FPGA_TOOL),) 27 | $(error Cannot find FPGA toolchain for board $(BOARD). Please make sure that the board name is correct and that the board is supported by the FPGA toolchain) 28 | endif 29 | 30 | N_INTERCONNECT_SLAVES ?=1 31 | 32 | include $(FPGA_TOOL)/$(BOARD)/board.mk 33 | include $(FPGA_TOOL)/build.mk 34 | 35 | #include the module's headers and sources 36 | VHDR += $(wildcard ../src/*.vh) $(wildcard ./src/*.vh) 37 | VSRC += $(wildcard ../src/*.v) $(wildcard ./src/*.v) 38 | 39 | ifneq ($(wildcard $(FPGA_TOOL)/$(BOARD)/$(NAME)_fpga_wrapper.v),) 40 | VSRC+=$(FPGA_TOOL)/$(BOARD)/$(NAME)_fpga_wrapper.v 41 | endif 42 | 43 | UFLAGS+=FPGA_TOP=$(FPGA_TOP) 44 | UFLAGS+=IS_FPGA=$(IS_FPGA) 45 | UFLAGS+=USE_QUARTUS_PRO=$(USE_QUARTUS_PRO) 46 | 47 | #build fpga image or netlist 48 | build: $(VHDR) $(VSRC) $(BUILD_DEPS) 49 | ifeq ($(FPGA_SERVER),) 50 | make $(FPGA_OBJ) 51 | else 52 | ssh $(FPGA_SSH_FLAGS) $(FPGA_USER)@$(FPGA_SERVER) "if [ ! -d $(REMOTE_BUILD_DIR) ]; then mkdir -p $(REMOTE_BUILD_DIR); fi" 53 | rsync $(FPGA_SYNC_FLAGS) -avz --delete --force ../.. $(FPGA_USER)@$(FPGA_SERVER):$(REMOTE_BUILD_DIR) 54 | ssh -t $(FPGA_SSH_FLAGS) $(FPGA_USER)@$(FPGA_SERVER) 'if [ -f quartus_env ]; then source quartus_env $(USE_QUARTUS_PRO); fi; make -C $(REMOTE_FPGA_DIR) $@ BOARD=$(BOARD) $(UFLAGS)' 55 | scp $(FPGA_SCP_FLAGS) $(FPGA_USER)@$(FPGA_SERVER):$(REMOTE_FPGA_DIR)/$(FPGA_OBJ) . 56 | scp -r $(FPGA_SCP_FLAGS) $(FPGA_USER)@$(FPGA_SERVER):$(REMOTE_FPGA_DIR)/reports . 57 | ifneq ($(FPGA_STUB),) 58 | scp $(FPGA_SCP_FLAGS) $(FPGA_USER)@$(FPGA_SERVER):$(REMOTE_FPGA_DIR)/$(FPGA_STUB) . 59 | endif 60 | endif 61 | 62 | #console start command 63 | CONSOLE_CMD ?=$(PYTHON_DIR)/console.py -s /dev/usb-uart 64 | 65 | #board client command 66 | GRAB_TIMEOUT ?= 900 67 | BOARD_GRAB_CMD=../../scripts/board_client.py grab $(GRAB_TIMEOUT) 68 | 69 | #run fpga image 70 | run: build $(RUN_DEPS) 71 | ifneq ($(NORUN),1) 72 | ifeq ($(BOARD_SERVER),) 73 | cp $(EMB_DIR)/$(NAME)_firmware.bin . 74 | $(BOARD_GRAB_CMD) -p '$(FPGA_PROG)' -c '$(CONSOLE_CMD)' && echo "Checking test log..." && test "$$(cat test.log)" = "Test passed!" 75 | else 76 | ssh $(BOARD_USER)@$(BOARD_SERVER) "if [ ! -d $(REMOTE_BUILD_DIR) ]; then mkdir -p $(REMOTE_BUILD_DIR); fi" 77 | rsync $(BOARD_SYNC_FLAGS) -avz --delete --force ../.. $(BOARD_USER)@$(BOARD_SERVER):$(REMOTE_BUILD_DIR) 78 | ssh -t $(BOARD_USER)@$(BOARD_SERVER) 'if [ -f quartus_env ]; then source quartus_env $(USE_QUARTUS_PRO); fi; make -C $(REMOTE_FPGA_DIR) $@ BOARD=$(BOARD) GRAB_TIMEOUT=$(GRAB_TIMEOUT) $(UFLAGS)' 79 | scp $(BOARD_USER)@$(BOARD_SERVER):$(REMOTE_FPGA_DIR)/*.log . 2> /dev/null | true 80 | endif 81 | endif 82 | 83 | # clean 84 | clean: $(FPGA_TOOL)-clean 85 | find . -maxdepth 1 -type f -not \( -name "Makefile" -o -name "fpga_build.mk" -o -name "uut_build.mk" \) -delete 86 | @rm -rf resynthesis *.hex 87 | ifneq ($(FPGA_SERVER),) 88 | ssh $(FPGA_SSH_FLAGS) $(FPGA_USER)@$(FPGA_SERVER) 'rm -rf $(REMOTE_BUILD_DIR)' 89 | ifneq ($(BOARD_SERVER),) 90 | ssh $(BOARD_SSH_FLAGS) $(BOARD_USER)@$(BOARD_SERVER) 'rm -rf $(REMOTE_BUILD_DIR)' 91 | endif 92 | endif 93 | 94 | test: $(TEST_LIST) 95 | 96 | debug: 97 | @echo SIMULATOR=$(SIMULATOR) 98 | @echo BOARD=$(BOARD) 99 | @echo VHDR=$(VHDR) 100 | @echo VSRC=$(VSRC) 101 | @echo FPGA_SERVER=$(FPGA_SERVER) 102 | @echo FPGA_OBJ=$(FPGA_OBJ) 103 | 104 | .PRECIOUS: $(FPGA_OBJ) test.log s_fw.bin 105 | 106 | .PHONY: run build clean debug test $(TEST_LIST) 107 | -------------------------------------------------------------------------------- /hardware/fpga/minicom_dma_test.txt: -------------------------------------------------------------------------------- 1 | # Script for "runscript" program of minicom, to test linux functionality 2 | 3 | # Set 15min timeout 4 | # runscript has 2min timeout by default: 5 | # check `timeout` in: https://linux.die.net/man/1/runscript 6 | timeout 900 7 | 8 | # Wait for the "buildroot login:" message 9 | print "\n[minicom] Waiting for buildroot login..." 10 | expect { 11 | "buildroot login:" 12 | timeout 300 13 | } 14 | 15 | send "root" 16 | 17 | expect { 18 | "#" 19 | timeout 10 20 | } 21 | 22 | send "./dma_demo/dma_demo" 23 | 24 | expect { 25 | "#" 26 | timeout 100 27 | } 28 | 29 | send "echo 'Test passed!' > test.log" 30 | send "sz -e test.log" 31 | ! rz --overwrite 32 | 33 | print "\n[minicom] Done Test" 34 | 35 | # Exit minicom 36 | ! kill `cut -f4 -d' ' /proc/$PPID/stat` 37 | -------------------------------------------------------------------------------- /hardware/fpga/minicom_test1.txt: -------------------------------------------------------------------------------- 1 | # Script for "runscript" program of minicom, to test linux functionality 2 | 3 | # Set 15min timeout 4 | # runscript has 2min timeout by default: 5 | # check `timeout` in: https://linux.die.net/man/1/runscript 6 | timeout 900 7 | 8 | # Wait for the "buildroot login:" message 9 | print "\n[minicom] Waiting for buildroot login..." 10 | expect { 11 | "buildroot login:" 12 | timeout 300 13 | } 14 | 15 | send "root" 16 | 17 | expect { 18 | "#" 19 | timeout 10 20 | } 21 | 22 | send "rz" 23 | ! sz ../../software/crypto ../../software/versat.ko ../../software/exampleTransfer.sh ../../software/setupTest.sh ../../software/test.sh 24 | 25 | expect { 26 | "#" 27 | timeout 100 28 | } 29 | 30 | send "./setupTest.sh" 31 | 32 | expect { 33 | "#" 34 | timeout 100 35 | } 36 | 37 | send "./test.sh && ./exampleTransfer.sh" 38 | 39 | expect { 40 | "#" 41 | timeout 900 42 | } 43 | 44 | send "echo 'Test passed!' > test.log" 45 | send "sz -e test.log" 46 | ! rz --overwrite 47 | 48 | print "\n[minicom] Done Test" 49 | 50 | # Exit minicom 51 | ! kill `cut -f4 -d' ' /proc/$PPID/stat` 52 | -------------------------------------------------------------------------------- /hardware/fpga/quartus/CYCLONEV-GT-DK/fw_jump.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IObundle/iob-soc-opencryptolinux/dec99d3afd50e8a53ca2a4e01fdc8f3b873746fa/hardware/fpga/quartus/CYCLONEV-GT-DK/fw_jump.bin -------------------------------------------------------------------------------- /hardware/fpga/quartus/CYCLONEV-GT-DK/iob_soc.dtb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IObundle/iob-soc-opencryptolinux/dec99d3afd50e8a53ca2a4e01fdc8f3b873746fa/hardware/fpga/quartus/CYCLONEV-GT-DK/iob_soc.dtb -------------------------------------------------------------------------------- /hardware/fpga/quartus/CYCLONEV-GT-DK/iob_soc_opencryptolinux_fpga_wrapper_dev.sdc: -------------------------------------------------------------------------------- 1 | create_clock -name "clk" -period 20.0 [get_ports {clk}] 2 | create_clock -period 40 [get_ports {ENET_RX_CLK}] 3 | -------------------------------------------------------------------------------- /hardware/fpga/quartus/CYCLONEV-GT-DK/linux_build_macros.txt: -------------------------------------------------------------------------------- 1 | TIMER0_ADDR f2000000 2 | UART0_ADDR f4000000 3 | SPI0_ADDR f6000000 4 | VERSAT0_ADDR f8000000 5 | ETH0_ADDR fa000000 6 | CLINT0_ADDR fc000000 7 | PLIC0_ADDR fe000000 8 | FREQ 50000000 9 | BAUD 115200 10 | -------------------------------------------------------------------------------- /hardware/fpga/quartus/build.mk: -------------------------------------------------------------------------------- 1 | ../../../submodules/IOBSOC/submodules/LIB/hardware/fpga/quartus/build.mk -------------------------------------------------------------------------------- /hardware/fpga/quartus/build.tcl: -------------------------------------------------------------------------------- 1 | ../../../submodules/IOBSOC/submodules/LIB/hardware/fpga/quartus/build.tcl -------------------------------------------------------------------------------- /hardware/fpga/quartus/timing.tcl: -------------------------------------------------------------------------------- 1 | ../../../submodules/IOBSOC/submodules/LIB/hardware/fpga/quartus/timing.tcl -------------------------------------------------------------------------------- /hardware/fpga/vivado/AES-KU040-DB-G/fw_jump.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IObundle/iob-soc-opencryptolinux/dec99d3afd50e8a53ca2a4e01fdc8f3b873746fa/hardware/fpga/vivado/AES-KU040-DB-G/fw_jump.bin -------------------------------------------------------------------------------- /hardware/fpga/vivado/AES-KU040-DB-G/iob_soc.dtb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IObundle/iob-soc-opencryptolinux/dec99d3afd50e8a53ca2a4e01fdc8f3b873746fa/hardware/fpga/vivado/AES-KU040-DB-G/iob_soc.dtb -------------------------------------------------------------------------------- /hardware/fpga/vivado/AES-KU040-DB-G/linux_build_macros.txt: -------------------------------------------------------------------------------- 1 | TIMER0_ADDR f2000000 2 | UART0_ADDR f4000000 3 | SPI0_ADDR f6000000 4 | VERSAT0_ADDR f8000000 5 | ETH0_ADDR fa000000 6 | CLINT0_ADDR fc000000 7 | PLIC0_ADDR fe000000 8 | FREQ 100000000 9 | BAUD 115200 10 | -------------------------------------------------------------------------------- /hardware/fpga/vivado/build.tcl: -------------------------------------------------------------------------------- 1 | #extract cli args 2 | set NAME [lindex $argv 0] 3 | set CSR_IF [lindex $argv 1] 4 | set BOARD [lindex $argv 2] 5 | set VSRC [lindex $argv 3] 6 | set IS_FPGA [lindex $argv 4] 7 | set USE_EXTMEM [lindex $argv 5] 8 | set N_INTERCONNECT_SLAVES [lindex $argv 6] 9 | 10 | #verilog sources, vivado IPs, use file extension 11 | foreach file [split $VSRC \ ] { 12 | puts $file 13 | if { [ file extension $file ] == ".edif" } { 14 | read_edif $file 15 | } elseif {$file != "" && $file != " " && $file != "\n"} { 16 | read_verilog -sv $file 17 | } 18 | } 19 | 20 | #read board propreties 21 | source vivado/$BOARD/board.tcl 22 | 23 | #set FPGA device 24 | set_property part $PART [current_project] 25 | 26 | 27 | #set pre-map custom assignments 28 | if {[file exists "vivado/premap.tcl"]} { 29 | source "vivado/premap.tcl" 30 | } 31 | 32 | 33 | #read design constraints and synthesize design 34 | if { $IS_FPGA == "1" } { 35 | puts "Synthesizing for FPGA" 36 | read_xdc vivado/$BOARD/$NAME\_dev.sdc 37 | if {[file exists "src/$NAME.sdc"]} { 38 | read_xdc src/$NAME.sdc 39 | } 40 | if {[file exists "../src/$NAME\_$CSR_IF.sdc"]} { 41 | read_xdc ../src/$NAME\_$CSR_IF.sdc 42 | } 43 | if {[file exists "vivado/$NAME\_tool.sdc"]} { 44 | read_xdc vivado/$NAME\_tool.sdc 45 | } 46 | synth_design -include_dirs ../src -include_dirs ./src -include_dirs ./vivado/$BOARD -part $PART -top $NAME -verbose 47 | } else { 48 | #read design constraints 49 | puts "Out of context synthesis" 50 | read_xdc -mode out_of_context vivado/$BOARD/$NAME\_dev.sdc 51 | read_xdc -mode out_of_context src/$NAME.sdc 52 | if {[file exists "vivado/$NAME\_tool.sdc"]} { 53 | read_xdc -mode out_of_context vivado/$NAME\_tool.sdc 54 | } 55 | synth_design -include_dirs ../src -include_dirs ./src -include_dirs ./vivado/$BOARD -part $PART -top $NAME -mode out_of_context -flatten_hierarchy full -verbose 56 | } 57 | 58 | #set post-map custom assignments 59 | if {[file exists "vivado/postmap.tcl"]} { 60 | source "vivado/postmap.tcl" 61 | } 62 | 63 | opt_design 64 | 65 | place_design 66 | 67 | route_design -timing 68 | 69 | report_clocks 70 | report_clock_interaction 71 | report_cdc -details 72 | report_bus_skew 73 | 74 | report_clocks -file reports/$NAME\_$PART\_clocks.rpt 75 | report_clock_interaction -file reports/$NAME\_$PART\_clock_interaction.rpt 76 | report_cdc -details -file reports/$NAME\_$PART\_cdc.rpt 77 | report_synchronizer_mtbf -file reports/$NAME\_$PART\_synchronizer_mtbf.rpt 78 | report_utilization -file reports/$NAME\_$PART\_utilization.rpt 79 | report_utilization -hierarchical -file reports/$NAME\_$PART\_utilization_hierarchical.rpt 80 | report_timing -file reports/$NAME\_$PART\_timing.rpt 81 | report_timing_summary -file reports/$NAME\_$PART\_timing_summary.rpt 82 | report_timing -file reports/$NAME\_$PART\_timing_paths.rpt -max_paths 30 83 | report_bus_skew -file reports/$NAME\_$PART\_bus_skew.rpt 84 | 85 | if { $IS_FPGA == "1" } { 86 | write_bitstream -force $NAME.bit 87 | } else { 88 | write_verilog -force $NAME\_netlist.v 89 | write_verilog -force -mode synth_stub ${NAME}_stub.v 90 | } 91 | -------------------------------------------------------------------------------- /hardware/fpga/vivado/iob_soc_opencryptolinux_fpga_wrapper_tool.sdc: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ## Synchronizers 3 | ################################################################################ 4 | set_property ASYNC_REG TRUE [get_cells -hier {*iob_r_data_o*[*]}] 5 | 6 | ################################################################################ 7 | ## Clock groups 8 | ################################################################################# 9 | set_clock_groups -asynchronous -group {c0_sys_clk_clk_p} -group {enet_clk} 10 | -------------------------------------------------------------------------------- /hardware/simulation/fw_jump.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IObundle/iob-soc-opencryptolinux/dec99d3afd50e8a53ca2a4e01fdc8f3b873746fa/hardware/simulation/fw_jump.bin -------------------------------------------------------------------------------- /hardware/simulation/iob_soc.dtb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IObundle/iob-soc-opencryptolinux/dec99d3afd50e8a53ca2a4e01fdc8f3b873746fa/hardware/simulation/iob_soc.dtb -------------------------------------------------------------------------------- /hardware/simulation/linux_build_macros.txt: -------------------------------------------------------------------------------- 1 | TIMER0_ADDR f2000000 2 | UART0_ADDR f4000000 3 | SPI0_ADDR f6000000 4 | VERSAT0_ADDR f8000000 5 | ETH0_ADDR fa000000 6 | CLINT0_ADDR fc000000 7 | PLIC0_ADDR fe000000 8 | FREQ 100000000 9 | BAUD 3000000 10 | -------------------------------------------------------------------------------- /hardware/simulation/sim_build.mk: -------------------------------------------------------------------------------- 1 | # Add iob_soc_opencryptolinux software as a build dependency 2 | HEX+=iob_soc_opencryptolinux_boot.hex iob_soc_opencryptolinux_firmware.hex 3 | HEX+=boot_flow 4 | 5 | ROOT_DIR :=../.. 6 | include $(ROOT_DIR)/software/sw_build.mk 7 | 8 | VTOP:=iob_soc_opencryptolinux_tb 9 | 10 | # SOURCES 11 | ifeq ($(SIMULATOR),verilator) 12 | 13 | VSRC+=./src/iob_tasks.cpp 14 | 15 | ifeq ($(USE_ETHERNET),1) 16 | VSRC+=./src/iob_eth_swreg_emb_verilator.c ./src/iob_eth_driver_tb.cpp 17 | endif 18 | 19 | # verilator top module 20 | VTOP:=iob_soc_opencryptolinux_sim_wrapper 21 | 22 | VSRC_TMP:=$(filter-out ./src/N25Qxxx.v,$(VSRC)) 23 | VSRC=$(VSRC_TMP) 24 | endif 25 | 26 | CONSOLE_CMD ?=../../scripts/console.py -L 27 | 28 | GRAB_TIMEOUT ?= 7200 29 | 30 | TEST_LIST+=test1 31 | test1: 32 | make -C ../../ fw-clean SIMULATOR=$(SIMULATOR) && make -C ../../ sim-clean SIMULATOR=$(SIMULATOR) && make run SIMULATOR=$(SIMULATOR) 33 | 34 | .PHONY: boot_flow 35 | -------------------------------------------------------------------------------- /hardware/simulation/src/bsp.vh: -------------------------------------------------------------------------------- 1 | `define BAUD 3000000 2 | `define FREQ 100000000 3 | `define DDR_DATA_W 32 4 | `define DDR_ADDR_W 26 5 | `define SIMULATION 1 6 | -------------------------------------------------------------------------------- /hardware/src/eth_example.txt: -------------------------------------------------------------------------------- 1 | ---------------------------------------- 2 | This is an example text file transferred 3 | from the console via ethernet. 4 | 0123456789 5 | ---------------------------------------- 6 | -------------------------------------------------------------------------------- /hardware/src/iob2axil.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | 4 | 5 | module iob2axil #( 6 | parameter AXIL_ADDR_W = 21, // AXI Lite address bus width in bits 7 | parameter AXIL_DATA_W = 21, // AXI Lite data bus width in bits 8 | parameter ADDR_W = AXIL_ADDR_W, // IOb address bus width in bits 9 | parameter DATA_W = AXIL_DATA_W // IOb data bus width in bits 10 | ) ( 11 | // AXI4 Lite master interface 12 | output wire axil_awvalid_o, 13 | input wire axil_awready_i, 14 | output wire [ AXIL_ADDR_W-1:0] axil_awaddr_o, 15 | output wire [ 2:0] axil_awprot_o, 16 | output wire axil_wvalid_o, 17 | input wire axil_wready_i, 18 | output wire [ AXIL_DATA_W-1:0] axil_wdata_o, 19 | output wire [AXIL_DATA_W/8-1:0] axil_wstrb_o, 20 | input wire axil_bvalid_i, 21 | output wire axil_bready_o, 22 | input wire [ 1:0] axil_bresp_i, 23 | output wire axil_arvalid_o, 24 | input wire axil_arready_i, 25 | output wire [ AXIL_ADDR_W-1:0] axil_araddr_o, 26 | output wire [ 2:0] axil_arprot_o, 27 | input wire axil_rvalid_i, 28 | output wire axil_rready_o, 29 | input wire [ AXIL_DATA_W-1:0] axil_rdata_i, 30 | input wire [ 1:0] axil_rresp_i, 31 | 32 | // IOb slave interface 33 | input wire iob_valid_i, 34 | input wire [ ADDR_W-1:0] iob_addr_i, 35 | input wire [ DATA_W-1:0] iob_wdata_i, 36 | input wire [DATA_W/8-1:0] iob_wstrb_i, 37 | output wire iob_rvalid_o, 38 | output wire [ DATA_W-1:0] iob_rdata_o, 39 | output wire iob_ready_o 40 | ); 41 | 42 | // 43 | // COMPUTE IOb OUTPUTS 44 | // 45 | assign iob_rvalid_o = axil_rvalid_i; 46 | assign iob_rdata_o = axil_rdata_i; 47 | assign iob_ready_o = (|iob_wstrb_i) ? axil_wready_i : axil_arready_i; 48 | 49 | // 50 | // COMPUTE AXIL OUTPUTS 51 | // 52 | 53 | // write address 54 | assign axil_awvalid_o = iob_valid_i & |iob_wstrb_i; 55 | assign axil_awaddr_o = iob_addr_i; 56 | assign axil_awprot_o = 3'd2; 57 | 58 | // write 59 | assign axil_wvalid_o = iob_valid_i & |iob_wstrb_i; 60 | assign axil_wdata_o = iob_wdata_i; 61 | assign axil_wstrb_o = iob_wstrb_i; 62 | 63 | // write response 64 | assign axil_bready_o = 1'b1; 65 | 66 | // read address 67 | assign axil_arvalid_o = iob_valid_i & ~|iob_wstrb_i; 68 | assign axil_araddr_o = iob_addr_i; 69 | assign axil_arprot_o = 3'd2; 70 | 71 | // read 72 | assign axil_rready_o = 1'b1; 73 | 74 | endmodule 75 | -------------------------------------------------------------------------------- /hardware/src/iob_soc_opencryptolinux_boot_ctr.v: -------------------------------------------------------------------------------- 1 | `timescale 1 ns / 1 ps 2 | 3 | module iob_soc_opencryptolinux_boot_ctr #( 4 | parameter ADDR_W = 0, 5 | parameter DATA_W = 0, 6 | parameter STRB_W = (DATA_W / 8) 7 | ) ( 8 | output wire boot, 9 | output wire cpu_reset, 10 | 11 | input wire [ 1-1:0] iob_valid_i, 12 | input wire [ADDR_W-1:0] iob_addr_i, 13 | input wire [DATA_W-1:0] iob_wdata_i, 14 | input wire [STRB_W-1:0] iob_wstrb_i, 15 | output wire [ 1-1:0] iob_rvalid_o, 16 | output wire [DATA_W-1:0] iob_rdata_o, 17 | output wire [ 1-1:0] iob_ready_o, 18 | 19 | `include "clk_en_rst_s_port.vs" 20 | ); 21 | 22 | //boot register: (1) load bootloader to sram and run it: (0) run program 23 | wire boot_wr; 24 | reg boot_nxt; 25 | //create CPU reset pulse 26 | wire cpu_reset_req; 27 | wire rst_sync; 28 | 29 | assign boot_wr = iob_valid_i & (|iob_wstrb_i); 30 | assign cpu_reset_req = (iob_valid_i & (|iob_wstrb_i) & iob_wdata_i[1]) | rst_sync; 31 | 32 | // IOb-Bus 33 | assign iob_rvalid_o = 1'b0; // has no read registers 34 | assign iob_rdata_o = {DATA_W{1'b0}}; 35 | assign iob_ready_o = 1'b1; 36 | 37 | iob_reg_re #( 38 | .DATA_W (1), 39 | .RST_VAL(1) 40 | ) bootnxt ( 41 | .clk_i (clk_i), 42 | .arst_i(arst_i), 43 | .cke_i (cke_i), 44 | .rst_i (1'b0), 45 | .en_i (boot_wr), 46 | .data_i(iob_wdata_i[0]), 47 | .data_o(boot_nxt) 48 | ); 49 | iob_reg_r #( 50 | .DATA_W (1), 51 | .RST_VAL(1) 52 | ) bootreg ( 53 | .clk_i (clk_i), 54 | .arst_i(arst_i), 55 | .cke_i (cke_i), 56 | .rst_i (1'b0), 57 | .data_i(boot_nxt), 58 | .data_o(boot) 59 | ); 60 | iob_reset_sync sync_reset ( 61 | .clk_i (clk_i), 62 | .arst_i(arst_i), 63 | .arst_o(rst_sync) 64 | ); 65 | iob_pulse_gen #( 66 | .START (0), 67 | .DURATION(100) 68 | ) reset_pulse ( 69 | .clk_i (clk_i), 70 | .arst_i (arst_i), 71 | .cke_i (cke_i), 72 | .start_i(cpu_reset_req), 73 | .pulse_o(cpu_reset) 74 | ); 75 | 76 | endmodule 77 | -------------------------------------------------------------------------------- /hardware/src/units/Mux4.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | module Mux4 #( 4 | parameter DATA_W = 32 5 | ) 6 | ( 7 | //control 8 | input clk, 9 | input rst, 10 | input running, 11 | 12 | input run, 13 | 14 | //input / output data 15 | input [DATA_W-1:0] in0, 16 | input [DATA_W-1:0] in1, 17 | input [DATA_W-1:0] in2, 18 | input [DATA_W-1:0] in3, 19 | 20 | (* versat_latency = 1 *) output reg [DATA_W-1:0] out0, 21 | 22 | input [1:0] sel 23 | 24 | ); 25 | 26 | 27 | always @(posedge clk,posedge rst) 28 | begin 29 | if(rst) begin 30 | out0 <= 0; 31 | end else begin 32 | case(sel) 33 | 2'b00: out0 <= in0; 34 | 2'b01: out0 <= in1; 35 | 2'b10: out0 <= in2; 36 | 2'b11: out0 <= in3; 37 | endcase 38 | end 39 | end 40 | 41 | endmodule 42 | -------------------------------------------------------------------------------- /hardware/src/units/xunitF.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | module xunitF #( 4 | parameter DELAY_W = 7, 5 | parameter DATA_W = 32 6 | ) 7 | ( 8 | //control 9 | input clk, 10 | input rst, 11 | 12 | input running, 13 | input run, 14 | output done, 15 | 16 | //input / output data 17 | input [DATA_W-1:0] in0, 18 | input [DATA_W-1:0] in1, 19 | input [DATA_W-1:0] in2, 20 | input [DATA_W-1:0] in3, 21 | input [DATA_W-1:0] in4, 22 | input [DATA_W-1:0] in5, 23 | input [DATA_W-1:0] in6, 24 | input [DATA_W-1:0] in7, 25 | 26 | input [DATA_W-1:0] in8, 27 | input [DATA_W-1:0] in9, 28 | 29 | (* versat_latency = 16 *) output [DATA_W-1:0] out0, 30 | (* versat_latency = 16 *) output [DATA_W-1:0] out1, 31 | (* versat_latency = 16 *) output [DATA_W-1:0] out2, 32 | (* versat_latency = 16 *) output [DATA_W-1:0] out3, 33 | (* versat_latency = 16 *) output [DATA_W-1:0] out4, 34 | (* versat_latency = 16 *) output [DATA_W-1:0] out5, 35 | (* versat_latency = 16 *) output [DATA_W-1:0] out6, 36 | (* versat_latency = 16 *) output [DATA_W-1:0] out7, 37 | 38 | //configurations 39 | input [DELAY_W-1:0] delay0 // Encodes delay 40 | ); 41 | 42 | reg [DELAY_W-1:0] delay; 43 | reg [31:0] a,b,c,d,e,f,g,h; 44 | 45 | assign out0 = a; 46 | assign out1 = b; 47 | assign out2 = c; 48 | assign out3 = d; 49 | assign out4 = e; 50 | assign out5 = f; 51 | assign out6 = g; 52 | assign out7 = h; 53 | 54 | assign done = (delay == 0); 55 | 56 | wire [31:0] w = in8; 57 | wire [31:0] k = in9; 58 | 59 | function [31:0] ROTR_32(input [31:0] x,input [4:0] c); 60 | begin 61 | ROTR_32 = (((x) >> (c)) | ((x) << (32 - (c)))); 62 | end 63 | endfunction 64 | 65 | function [31:0] SHR(input [31:0] x,input [4:0] c); 66 | begin 67 | SHR = ((x) >> (c)); 68 | end 69 | endfunction 70 | 71 | function [31:0] Ch(input [31:0] x,y,z); 72 | begin 73 | Ch = (((x) & (y)) ^ (~(x) & (z))); 74 | end 75 | endfunction 76 | 77 | function [31:0] Maj(input [31:0] x,y,z); 78 | begin 79 | Maj = (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))); 80 | end 81 | endfunction 82 | 83 | function [31:0] Sigma0_32(input [31:0] x); 84 | begin 85 | Sigma0_32 = (ROTR_32(x, 2) ^ ROTR_32(x,13) ^ ROTR_32(x,22)); 86 | end 87 | endfunction 88 | 89 | function [31:0] Sigma1_32(input [31:0] x); 90 | begin 91 | Sigma1_32 = (ROTR_32(x, 6) ^ ROTR_32(x,11) ^ ROTR_32(x,25)); 92 | end 93 | endfunction 94 | 95 | wire [31:0] T1 = h + Sigma1_32(e) + Ch(e,f,g) + k + w; 96 | wire [31:0] T2 = Sigma0_32(a) + Maj(a,b,c); 97 | 98 | wire [31:0] T1_init = in7 + Sigma1_32(in4) + Ch(in4,in5,in6) + k + w; 99 | wire [31:0] T2_init = Sigma0_32(in0) + Maj(in0,in1,in2); 100 | 101 | reg working; 102 | 103 | always @(posedge clk,posedge rst) 104 | begin 105 | if(rst) begin 106 | delay <= 0; 107 | working <= 0; 108 | a <= 0; 109 | b <= 0; 110 | c <= 0; 111 | d <= 0; 112 | e <= 0; 113 | f <= 0; 114 | g <= 0; 115 | h <= 0; 116 | end else if(run) begin 117 | delay <= delay0; 118 | working <= 0; 119 | end else if(!working) begin 120 | if(delay == 0) begin 121 | a <= T1_init + T2_init; 122 | b <= in0; 123 | c <= in1; 124 | d <= in2; 125 | e <= in3 + T1_init; 126 | f <= in4; 127 | g <= in5; 128 | h <= in6; 129 | working <= 1'b1; 130 | end else begin 131 | delay <= delay - 1; 132 | end 133 | end else begin 134 | a <= T1 + T2; 135 | b <= a; 136 | c <= b; 137 | d <= c; 138 | e <= d + T1; 139 | f <= e; 140 | g <= f; 141 | h <= g; 142 | end 143 | end 144 | 145 | endmodule 146 | -------------------------------------------------------------------------------- /hardware/src/units/xunitM.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | module xunitM #( 4 | parameter DELAY_W = 7, 5 | parameter DATA_W = 32 6 | ) 7 | ( 8 | //control 9 | input clk, 10 | input rst, 11 | 12 | input running, 13 | input run, 14 | output done, 15 | 16 | //input / output data 17 | input [DATA_W-1:0] in0, 18 | 19 | (* versat_latency = 17 *) output reg [DATA_W-1:0] out0, 20 | 21 | //configurations 22 | input [DELAY_W-1:0] delay0 // Encodes delay 23 | ); 24 | 25 | assign done = 1'b1; 26 | 27 | reg [DELAY_W-1:0] delay; 28 | reg [4:0] latency; 29 | reg [31:0] w[15:0]; 30 | 31 | // Extract from array to view on gtkwave 32 | wire [31:0] w0 = w[0]; 33 | wire [31:0] w1 = w[1]; 34 | wire [31:0] w2 = w[2]; 35 | wire [31:0] w3 = w[3]; 36 | wire [31:0] w4 = w[4]; 37 | wire [31:0] w5 = w[5]; 38 | wire [31:0] w6 = w[6]; 39 | wire [31:0] w7 = w[7]; 40 | wire [31:0] w8 = w[8]; 41 | wire [31:0] w9 = w[9]; 42 | wire [31:0] w10 = w[10]; 43 | wire [31:0] w11 = w[11]; 44 | wire [31:0] w12 = w[12]; 45 | wire [31:0] w13 = w[13]; 46 | wire [31:0] w14 = w[14]; 47 | wire [31:0] w15 = w[15]; 48 | 49 | function [31:0] ROTR_32(input [31:0] x,input [4:0] c); 50 | begin 51 | ROTR_32 = (((x) >> (c)) | ((x) << (32 - (c)))); 52 | end 53 | endfunction 54 | 55 | function [31:0] SHR(input [31:0] x,input [4:0] c); 56 | begin 57 | SHR = ((x) >> (c)); 58 | end 59 | endfunction 60 | 61 | function [31:0] sigma0_32(input [31:0] x); 62 | begin 63 | sigma0_32 = (ROTR_32(x, 7) ^ ROTR_32(x,18) ^ SHR(x, 3)); 64 | end 65 | endfunction 66 | 67 | function [31:0] sigma1_32(input [31:0] x); 68 | begin 69 | sigma1_32 = (ROTR_32(x,17) ^ ROTR_32(x,19) ^ SHR(x,10)); 70 | end 71 | endfunction 72 | 73 | wire [31:0] val = (sigma1_32(w[14]) + (w[9]) + sigma0_32(w[1]) + (w[0])); 74 | 75 | integer i; 76 | always @(posedge clk,posedge rst) 77 | begin 78 | if(rst) begin 79 | delay <= 0; 80 | for(i = 0; i < 16; i = i + 1) 81 | w[i] <= 0; 82 | end else if(run) begin 83 | delay <= delay0; // wait delay0 cycles for valid input data 84 | latency <= 5'h11; // cycles from valid input to valid output 85 | end else if (|delay) begin 86 | delay <= delay - 1; 87 | end else begin 88 | if(|latency) begin 89 | latency <= latency - 1; 90 | end 91 | 92 | out0 <= w[0]; 93 | 94 | for(i = 0; i < 15; i = i + 1) begin 95 | w[i] <= w[i+1]; 96 | end 97 | 98 | if(latency[4:1] != 0) begin // latency > 1 99 | w[15] <= in0; 100 | end else begin 101 | w[15] <= val; 102 | end 103 | 104 | out0 <= val; 105 | end 106 | end 107 | 108 | endmodule 109 | -------------------------------------------------------------------------------- /scripts/check_if_run_linux.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys 4 | 5 | ROOT_DIR = sys.argv[1] 6 | SOC_NAME = sys.argv[2] 7 | if len(sys.argv) > 3: 8 | RUN_LINUX = sys.argv[3] 9 | else: 10 | RUN_LINUX = "0" 11 | 12 | 13 | # If line contains "line_content", replace entire line with "new_line_content" 14 | # If "line_content" is empty, append "new_line_content" to end of file 15 | def replace_line(filename, line_content, new_line_content): 16 | with open(filename, "r") as file: 17 | lines = file.readlines() 18 | if line_content: 19 | for i in range(len(lines)): 20 | if line_content in lines[i]: 21 | lines[i] = new_line_content 22 | else: 23 | lines.append(new_line_content) 24 | 25 | with open(filename, "w") as file: 26 | file.writelines(lines) 27 | 28 | 29 | # Generate "iob_mem.config" according to which binary firmware the SoC should load to RAM 30 | 31 | iob_mem_file = f"{ROOT_DIR}/hardware/{SOC_NAME}_mem.config" 32 | with open(iob_mem_file, "w") as file: 33 | if RUN_LINUX == "1": 34 | file.write( 35 | "fw_jump.bin 0\nImage 400000\niob_soc.dtb F80000\nrootfs.cpio.gz 1000000" 36 | ) 37 | else: 38 | file.write(f"{SOC_NAME}_firmware.bin 0") 39 | 40 | 41 | # Fixes existing bsp.h and bsp.vh for Simulation 42 | 43 | bsp_file = f"{ROOT_DIR}/software/src/bsp.h" 44 | with open(bsp_file, "r") as file: 45 | content = file.read() 46 | 47 | if "define SIMULATION 1" in content: 48 | if RUN_LINUX == "1": 49 | # bsp_file = f"{ROOT_DIR}/hardware/simulation/src/bsp.vh" 50 | # replace_line(bsp_file, "`define BAUD", "`define BAUD 115200\n") 51 | 52 | # bsp_file = f"{ROOT_DIR}/software/src/bsp.h" 53 | # replace_line(bsp_file, "#define BAUD", "#define BAUD 115200\n") 54 | 55 | conf_file = f"{ROOT_DIR}/hardware/src/{SOC_NAME}_conf.vh" 56 | replace_line(conf_file, "", "`define {SOC_NAME.upper()}_RUN_LINUX 1\n") 57 | 58 | conf_file = f"{ROOT_DIR}/software/src/{SOC_NAME}_conf.h" 59 | replace_line( 60 | conf_file, 61 | "#define H_{SOC_NAME.upper()}_CONF_H", 62 | "#define H_{SOC_NAME.upper()}_CONF_H\n#define {SOC_NAME.upper()}_RUN_LINUX 1\n", 63 | ) 64 | else: 65 | # bsp_file = f"{ROOT_DIR}/hardware/simulation/src/bsp.vh" 66 | # replace_line(bsp_file, "`define BAUD", "`define BAUD 3000000\n") 67 | 68 | # bsp_file = f"{ROOT_DIR}/software/src/bsp.h" 69 | # replace_line(bsp_file, "#define BAUD", "#define BAUD 3000000\n") 70 | 71 | conf_file = f"{ROOT_DIR}/hardware/src/{SOC_NAME}_conf.vh" 72 | replace_line(conf_file, "`define {SOC_NAME.upper()}_RUN_LINUX", "") 73 | 74 | conf_file = f"{ROOT_DIR}/software/src/{SOC_NAME}_conf.h" 75 | replace_line(conf_file, "#define {SOC_NAME.upper()}_RUN_LINUX", "") 76 | -------------------------------------------------------------------------------- /software/KAT/AESECB256.rsp: -------------------------------------------------------------------------------- 1 | # CAVS 11.1 2 | # CONFIG INFO FOR AES_VALUES 3 | # AESVS MCT TEST DATA FOR ECB 4 | # STATE : ENCRYPT 5 | # KEY LENGTH : 256 6 | # GENERATED FROM EDITED VERSION OF AESVS MCT TEST DATA FOR ECB 7 | # ALL TESTS WITH 256BIT PLAINTEXT SIZE 8 | 9 | [ENCRYPT] 10 | 11 | COUNT = 0 12 | KEY = CC22DA787F375711C76302BEF0979D8EDDF842829C2B99EF3DD04E23E54CC24B 13 | PLAINTEXT = CCC62C6B0A09A671D64456818DB29A4D 14 | CIPHERTEXT = DF8634CA02B13A125B786E1DCE90658B 15 | 16 | COUNT = 1 17 | KEY = 7A52E4D342AA07255A7E7C34266CF7302ABE2D4DD7EC4468A46187EE61825FFA 18 | PLAINTEXT = 7E771C6EE4B26DB89050E982BA7E9803 19 | CIPHERTEXT = A91D8B2DDF37520BC469470AD0DD6394 20 | 21 | COUNT = 2 22 | KEY = 605C4139C961B496CA5148F1BDB1BB1901F2101943A0EC10FCDC403D3B0C285A 23 | PLAINTEXT = 68C9885BA2BE03181F65F1E04E83D6BA 24 | CIPHERTEXT = A7603D29BBBA4C77208BF2F3DF9F5EC8 25 | 26 | COUNT = 3 27 | KEY = F984B0F534FC0AE2C0A8593E16AB8365F25FCC9C5947F9A2DB45B588160D35C3 28 | PLAINTEXT = 351FEE099122E371C4830F409C6C4411 29 | CIPHERTEXT = 8B9C9E692C16E7059818E285E85D8FA5 30 | 31 | COUNT = 4 32 | KEY = BA42B760BB5A5DE21ACB9ABA214C9783CD71EA841ADA018580ABC4E1BE3B76DD 33 | PLAINTEXT = 4B4B12D6EE6FC0BF987EAAFE2634AAD4 34 | CIPHERTEXT = FA18D25E37EA0CE94F0949EFC0EDECC6 35 | 36 | COUNT = 5 37 | KEY = 1D29079CC34AB5A3BC713F416A129F9D26ADA15FCA458CC2731404EA857D2F79 38 | PLAINTEXT = B36809198132518D815AA37F32F40DD7 39 | CIPHERTEXT = 7AE803B14914D156439F580C02C592BF 40 | 41 | COUNT = 6 42 | KEY = 2E39C585CE4900D323CE29713BEBE73A1BE08A0CB22E9F1310FCC14AD4B9B23E 43 | PLAINTEXT = E199899E1E12CFFCB28909AEC51B36C2 44 | CIPHERTEXT = 2C4998428E72F6D96E982A316F73BF2A 45 | 46 | COUNT = 7 47 | KEY = 85405C4F0EBBE8F29228F02F1FF184E2F5E7857E8933C2A1D08F61ECB9B68111 48 | PLAINTEXT = 0F5321DB6FD9D816D88E28183A739D90 49 | CIPHERTEXT = 2AC6DE212DA0434BEA9CDD7332637307 50 | 51 | COUNT = 8 52 | KEY = F157285DB00E64C2791668A54493966E3039A19426605056B95B7EAC5106667D 53 | PLAINTEXT = 3637F71F60A430322980349AD414FCFD 54 | CIPHERTEXT = CA0A683E759C1312928FE01198F625BB 55 | 56 | COUNT = 9 57 | KEY = 44A2B5A7453E49F38261904F21AC797641D1BCD8DDEDD293F319449FE63B2948 58 | PLAINTEXT = C91B8A7B9C511784B6A37F73B290516B 59 | CIPHERTEXT = 05D51AF0E2B61E2C06CB1E843FEE3172 60 | -------------------------------------------------------------------------------- /software/Makefile: -------------------------------------------------------------------------------- 1 | # (c) 2022-Present IObundle, Lda, all rights reserved 2 | # 3 | # This makefile is used at build-time in $(BUILD_DIR)/software/Makefile 4 | # 5 | 6 | include ../config_build.mk 7 | 8 | ######################################### 9 | # General settings # 10 | ######################################### 11 | 12 | PYTHON_DIR = ../scripts 13 | 14 | # include local build segment 15 | # all previously defined variables can be overwritten in this file 16 | ifneq ($(wildcard sw_build.mk),) 17 | include sw_build.mk 18 | endif 19 | 20 | ######################################### 21 | # Embedded settings # 22 | ######################################### 23 | 24 | TEMPLATE_LDS ?=template.lds 25 | 26 | MFLAGS=$(MFLAGS_BASE)$(MFLAG_M)$(MFLAG_C) 27 | MFLAGS_BASE:=rv32i 28 | ifeq ($(USE_MUL_DIV),1) 29 | MFLAG_M=m 30 | endif 31 | ifeq ($(USE_COMPRESSED),1) 32 | MFLAG_C=c 33 | endif 34 | 35 | #default compiler settings 36 | TOOLCHAIN_PREFIX ?=riscv64-unknown-elf- 37 | CFLAGS ?=-Os -nostdlib -march=$(MFLAGS) -mabi=ilp32 --specs=nano.specs -Wcast-align=strict $(USER_CFLAGS) 38 | LFLAGS ?= -Wl,-Bstatic,-T,$(TEMPLATE_LDS),--strip-debug 39 | LLIBS ?=-lgcc -lc -lnosys 40 | INCLUDES ?=-I. -Isrc 41 | 42 | ######################################### 43 | # PC emulation settings # 44 | ######################################### 45 | 46 | # compiler flags 47 | EMUL_CFLAGS ?=-Os -std=gnu99 -Wl,--strip-debug 48 | 49 | CONSOLE_CMD ?=rm -f soc2cnsl cnsl2soc; ../scripts/console.py -L 50 | 51 | EMUL_INCLUDES ?=-I. -Isrc 52 | 53 | EMUL_HDR+=$(wildcard src/*_emul.h) 54 | 55 | EMUL_SRC+=$(wildcard src/*_emul.c) 56 | 57 | ######################################### 58 | # Embedded targets # 59 | ######################################### 60 | 61 | CRYPTO_SRC := src/iob-versat.c $(wildcard src/linux/*.c) $(wildcard src/crypto/McEliece/*.c) $(wildcard src/crypto/McEliece/common/*.c) 62 | CRYPTO_HDR := $(wildcard src/linux/*.h) $(wildcard src/crypto/McEliece/*.h) 63 | 64 | crypto: 65 | riscv64-unknown-linux-gnu-gcc -std=gnu99 -march=rv32imac -mabi=ilp32 -Wcast-align=strict -Os -s -ffunction-sections $(CRYPTO_SRC) -o crypto -Isrc/crypto/McEliece -Isrc/crypto/McEliece/common -Isrc/linux -Wl,-gc-sections -Wl,--strip-all 66 | 67 | build: $(UTARGETS) crypto 68 | %.elf: $(TEMPLATE_LDS) $(HDR) $(SRC) 69 | $(TOOLCHAIN_PREFIX)gcc -o $@ $(CFLAGS) $(LFLAGS) $(INCLUDES) $(SRC) $(LLIBS) 70 | $(TOOLCHAIN_PREFIX)objcopy -O binary $@ $(*F).bin 71 | 72 | ifneq ($(BOARD),) 73 | FPGA_TOOL:=$(shell find ../hardware/fpga -name $(BOARD) | cut -d"/" -f5) 74 | endif 75 | 76 | debug: 77 | @echo $(TEMPLATE_LDS) 78 | @echo $(FW_SRC) 79 | @echo $(BOOT_SRC) 80 | @echo $(HDR) 81 | 82 | .PHONY: build debug 83 | 84 | ######################################### 85 | # PC emulation targets # 86 | ######################################### 87 | 88 | fw_emul: $(EMUL_HDR) $(EMUL_SRC) 89 | gcc -o $@ $(EMUL_CFLAGS) $(EMUL_INCLUDES) $(EMUL_SRC) -lgcc -lc 90 | 91 | build_emul: fw_emul 92 | @echo "build" 93 | 94 | #board client command 95 | BOARD_GRAB_CMD ?=../scripts/board_client.py grab 300 96 | 97 | test.log: build_emul 98 | $(BOARD_GRAB_CMD) -s './fw_emul' -c '$(CONSOLE_CMD)' 99 | 100 | run_emul: test.log 101 | test "$$(cat test.log)" = "Test passed!" 102 | 103 | .PHONY: build_emul run_emul 104 | 105 | ######################################### 106 | # General targets # 107 | ######################################### 108 | 109 | clean: 110 | @rm -rf *.bin *.elf *.map *.hex 111 | @rm -rf fw_emul test.log soc2cnsl cnsl2soc 112 | @rm -rf *.txt iob_soc_conf.h 113 | 114 | .PHONY: clean 115 | -------------------------------------------------------------------------------- /software/buildroot/board/IObundle/iob-soc/rootfs-overlay/etc/init.d/S10mdev: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Run the mdev daemon 4 | # 5 | 6 | DAEMON="mdev" 7 | PIDFILE="/var/run/$DAEMON.pid" 8 | 9 | 10 | start() { 11 | echo -n "Starting $DAEMON... " 12 | start-stop-daemon -S -b -m -p $PIDFILE -x /sbin/mdev -- -df 13 | [ $? -eq 0 ] && echo "OK" || echo "ERROR" 14 | 15 | # coldplug modules 16 | find /sys/ -name modalias -print0 | \ 17 | xargs -0 sort -u | \ 18 | tr '\n' '\0' | \ 19 | xargs -0 modprobe -abq 20 | } 21 | 22 | stop() { 23 | echo -n "Stopping $DAEMON... " 24 | start-stop-daemon -K -p $PIDFILE 25 | [ $? -eq 0 ] && echo "OK" || echo "ERROR" 26 | } 27 | 28 | restart() { 29 | stop 30 | start 31 | } 32 | 33 | case "$1" in 34 | start|stop|restart) 35 | "$1" 36 | ;; 37 | *) 38 | echo "Usage: $0 {start|stop|restart}" 39 | exit 1 40 | esac 41 | 42 | exit $? 43 | -------------------------------------------------------------------------------- /software/buildroot/board/IObundle/iob-soc/rootfs-overlay/etc/init.d/S99IObundleVerification: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Load Linux Kernel Modules 4 | for i in /drivers/*.ko; do 5 | insmod $i; 6 | done 7 | -------------------------------------------------------------------------------- /software/buildroot/board/IObundle/iob-soc/rootfs-overlay/etc/mdev.conf: -------------------------------------------------------------------------------- 1 | # null may already exist; therefore ownership has to be changed with command 2 | null root:root 666 @chmod 666 $MDEV 3 | zero root:root 666 4 | full root:root 666 5 | random root:root 444 6 | urandom root:root 444 7 | hwrandom root:root 444 8 | grsec root:root 660 9 | 10 | kmem root:root 640 11 | mem root:root 640 12 | port root:root 640 13 | # console may already exist; therefore ownership has to be changed with command 14 | console root:tty 600 @chmod 600 $MDEV 15 | ptmx root:tty 666 16 | pty.* root:tty 660 17 | 18 | # Typical devices 19 | tty root:tty 666 20 | tty[0-9]* root:tty 660 21 | vcsa*[0-9]* root:tty 660 22 | ttyS[0-9]* root:root 660 23 | ttyUSB[0-9]* root:root 660 24 | 25 | # alsa sound devices 26 | snd/pcm.* root:audio 660 27 | snd/control.* root:audio 660 28 | snd/midi.* root:audio 660 29 | snd/seq root:audio 660 30 | snd/timer root:audio 660 31 | 32 | # input stuff 33 | input/event[0-9]+ root:root 640 34 | input/mice root:root 640 35 | input/mouse[0-9] root:root 640 36 | input/ts[0-9] root:root 600 37 | 38 | # load modules 39 | $MODALIAS=.* root:root 660 @modprobe "$MODALIAS" 40 | -------------------------------------------------------------------------------- /software/buildroot/board/IObundle/iob-soc/rootfs-overlay/root/dma_demo/dma_demo.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * DMA demo Program * 3 | *********************************************************/ 4 | 5 | // #include "bsp.h" 6 | #include "iob-axistream-in-user.h" 7 | #include "iob-axistream-out-user.h" 8 | #include "iob-dma-user.h" 9 | 10 | #include 11 | #include 12 | 13 | // We should ideally receive the INIT_MEM information from the PC 14 | // However, since most of the time we run linux on the FPGA, 15 | // the INIT_MEM will be 0, therefore we hardcode it for now. 16 | #undef IOB_SOC_OPENCRYPTOLINUX_INIT_MEM 17 | 18 | void send_axistream(); 19 | void receive_axistream(); 20 | 21 | int main() { 22 | // init axistream 23 | iob_sysfs_write_file(IOB_AXISTREAM_IN_SYSFILE_ENABLE, 1); 24 | iob_sysfs_write_file(IOB_AXISTREAM_OUT_SYSFILE_ENABLE, 1); 25 | 26 | // Send byte stream via AXI stream 27 | send_axistream(); 28 | // Read byte stream via AXI stream 29 | receive_axistream(); 30 | } 31 | 32 | 33 | void send_axistream() { 34 | uint8_t i; 35 | uint8_t words_in_byte_stream = 4; 36 | // Allocate memory for byte stream 37 | uint32_t *byte_stream = (uint32_t *)malloc(words_in_byte_stream*sizeof(uint32_t)); 38 | // Fill byte stream to send 39 | byte_stream[0] = 0x03020100; 40 | byte_stream[1] = 0x07060504; 41 | byte_stream[2] = 0xbbaa0908; 42 | byte_stream[3] = 0xffeeddcc; 43 | 44 | // Print byte stream to send 45 | printf("Sending AXI stream bytes: "); 46 | for (i = 0; i < words_in_byte_stream; i++) 47 | printf("0x%08x ", byte_stream[i]); 48 | printf("\n"); 49 | 50 | // Send bytes to AXI stream output via DMA 51 | printf("Loading AXI words via DMA...\n\n"); 52 | iob_axis_out_reset(); 53 | iob_sysfs_write_file(IOB_AXISTREAM_OUT_SYSFILE_ENABLE, 1); 54 | iob_sysfs_write_file(IOB_AXISTREAM_OUT_SYSFILE_MODE, 1); 55 | iob_sysfs_write_file(IOB_AXISTREAM_OUT_SYSFILE_NWORDS, words_in_byte_stream); 56 | dma_start_transfer(byte_stream, words_in_byte_stream, 0, 0); 57 | 58 | free(byte_stream); 59 | } 60 | 61 | void receive_axistream() { 62 | uint8_t i; 63 | uint32_t n_received_words = 0; 64 | iob_sysfs_read_file(IOB_AXISTREAM_IN_SYSFILE_NWORDS, &n_received_words); 65 | 66 | // Allocate memory for byte stream 67 | volatile uint32_t *byte_stream = (volatile uint32_t *)malloc((n_received_words)*sizeof(uint32_t)); 68 | for (i = 0; i < n_received_words; i++) 69 | byte_stream[i] = 0; 70 | 71 | // Transfer bytes from AXI stream input via DMA 72 | printf("Storing AXI words via DMA...\n"); 73 | iob_sysfs_write_file(IOB_AXISTREAM_IN_SYSFILE_MODE, 1); 74 | dma_start_transfer((uint32_t *)byte_stream, n_received_words, 1, 0); 75 | 76 | // clear_cache(); 77 | 78 | // Print byte stream received 79 | printf("Received AXI stream %d bytes: ", n_received_words*4); 80 | for (i = 0; i < n_received_words; i++) 81 | printf("0x%08x ", byte_stream[i]); 82 | printf("\n\n"); 83 | 84 | free((uint32_t *)byte_stream); 85 | } 86 | -------------------------------------------------------------------------------- /software/buildroot/board/IObundle/iob-soc/rootfs-overlay/root/dma_demo/iob-axistream-in-user.c: -------------------------------------------------------------------------------- 1 | #include "iob-axistream-in-user.h" 2 | 3 | int iob_axis_in_reset() { 4 | if (iob_sysfs_write_file(IOB_AXISTREAM_IN_SYSFILE_SOFT_RESET, 1) == -1) { 5 | return -1; 6 | } 7 | if (iob_sysfs_write_file(IOB_AXISTREAM_IN_SYSFILE_SOFT_RESET, 0) == -1) { 8 | return -1; 9 | } 10 | return 0; 11 | } 12 | 13 | uint32_t iob_axis_read(uint32_t *value) { 14 | int ret = 0; 15 | uint32_t empty = 0; 16 | 17 | ret = iob_sysfs_read_file(IOB_AXISTREAM_IN_SYSFILE_FIFO_EMPTY, &empty); 18 | if ((ret == -1) || (empty == 1)) { 19 | return 0; 20 | } else { 21 | ret = iob_sysfs_read_file(IOB_AXISTREAM_IN_SYSFILE_DATA, value); 22 | if (ret == -1) { 23 | return 0; 24 | } 25 | } 26 | return 1; 27 | } 28 | -------------------------------------------------------------------------------- /software/buildroot/board/IObundle/iob-soc/rootfs-overlay/root/dma_demo/iob-axistream-in-user.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "iob-sysfs-common.h" 5 | /* IOb-axistream-in header automatically generated from: 6 | * /path/to/iob-linux/scripts/drivers.py iob_axistream_in 7 | * contains: 8 | * - sysfs file paths 9 | * - Register address and width definitions 10 | */ 11 | #include "iob_axistream_in.h" 12 | 13 | int iob_axis_in_reset(); 14 | uint32_t iob_axis_read(uint32_t *value); 15 | -------------------------------------------------------------------------------- /software/buildroot/board/IObundle/iob-soc/rootfs-overlay/root/dma_demo/iob-axistream-out-user.c: -------------------------------------------------------------------------------- 1 | #include "iob-axistream-out-user.h" 2 | 3 | int iob_axis_out_reset() { 4 | if (iob_sysfs_write_file(IOB_AXISTREAM_OUT_SYSFILE_SOFT_RESET, 1) == -1) { 5 | return -1; 6 | } 7 | if (iob_sysfs_write_file(IOB_AXISTREAM_OUT_SYSFILE_SOFT_RESET, 0) == -1) { 8 | return -1; 9 | } 10 | return 0; 11 | } 12 | 13 | uint32_t iob_axis_write(uint32_t value) { 14 | int ret = 0; 15 | uint32_t full = 0; 16 | 17 | ret = iob_sysfs_read_file(IOB_AXISTREAM_OUT_SYSFILE_FIFO_FULL, &full); 18 | if ((ret == -1) || (full == 1)) { 19 | return 0; 20 | } else { 21 | if (iob_sysfs_write_file(IOB_AXISTREAM_OUT_SYSFILE_DATA, value) == -1) { 22 | return 0; 23 | } 24 | } 25 | return 1; 26 | } 27 | -------------------------------------------------------------------------------- /software/buildroot/board/IObundle/iob-soc/rootfs-overlay/root/dma_demo/iob-axistream-out-user.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "iob-sysfs-common.h" 5 | /* IOb-axistream-out header automatically generated from: 6 | * /path/to/iob-linux/scripts/drivers.py iob_axistream_out 7 | * contains: 8 | * - sysfs file paths 9 | * - Register address and width definitions 10 | */ 11 | #include "iob_axistream_out.h" 12 | 13 | int iob_axis_out_reset(); 14 | uint32_t iob_axis_write(uint32_t value); 15 | -------------------------------------------------------------------------------- /software/buildroot/board/IObundle/iob-soc/rootfs-overlay/root/dma_demo/iob-dma-user.c: -------------------------------------------------------------------------------- 1 | #include "iob-dma-user.h" 2 | 3 | #define IOB_DMA_PAGE_SIZE 4096 4 | /* Calculate memory map length 5 | * - size: number of 32-bit words to transfer 6 | * 7 | */ 8 | static size_t mmap_length(uint32_t size) { 9 | size_t mmap_length = 0; 10 | uint32_t page_mult = 11 | ((size << 2) + IOB_DMA_PAGE_SIZE - 1) / IOB_DMA_PAGE_SIZE; 12 | mmap_length = page_mult * IOB_DMA_PAGE_SIZE; 13 | return mmap_length; 14 | } 15 | 16 | /* DMA transfer: 17 | * - data_ptr: pointer to data for read or write according to [direction]. 18 | * - size: ammount of 32-bit words to transfer 19 | * - direction: 0 = read from memory, 1 = write to memory 20 | * - interface_number: which AXI Stream interface to use 21 | * 22 | * returns 0 on success, -1 on error 23 | */ 24 | int dma_start_transfer(uint32_t *data_ptr, uint32_t size, int direction, 25 | uint16_t interface_number) { 26 | int fd = 0; 27 | void *virt_addr = NULL; 28 | 29 | // open the device file 30 | fd = open(IOB_DMA_DEVICE_FILE, O_RDWR); 31 | if (fd < 0) { 32 | printf("Error opening device file: %s\n", IOB_DMA_DEVICE_FILE); 33 | return -1; 34 | } 35 | 36 | // NOTE: driver call to mmap() sets DMA physical base address 37 | // iob_sysfs_write_file(IOB_DMA_SYSFILE_BASE_ADDR, base_addr); 38 | virt_addr = 39 | mmap(NULL, mmap_length(size), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 40 | if (virt_addr == MAP_FAILED) { 41 | printf("Error mapping memory\n"); 42 | close(fd); 43 | return -1; 44 | } 45 | 46 | iob_sysfs_write_file(IOB_DMA_SYSFILE_DIRECTION, direction); 47 | iob_sysfs_write_file(IOB_DMA_SYSFILE_INTERFACE_NUM, interface_number); 48 | 49 | // MEM -> DEVICE transfers: copy user buffer to DMA memory 50 | if (direction == 0) { 51 | memcpy(virt_addr, data_ptr, size << 2); 52 | } 53 | 54 | // Setting the transfer size will begin the transfer 55 | iob_sysfs_write_file(IOB_DMA_SYSFILE_TRANSFER_SIZE, size); 56 | 57 | while (dma_transfer_ready() == 0) { 58 | // wait for transfer to complete 59 | } 60 | 61 | // DEVICE -> MEM transfers: copy DMA memory to user buffer 62 | if (direction == 1) { 63 | memcpy(data_ptr, virt_addr, size << 2); 64 | } 65 | 66 | close(fd); 67 | return 0; 68 | } 69 | 70 | // Check if DMA is ready for new transfer 71 | uint8_t dma_transfer_ready() { 72 | uint32_t ready_r = 0; 73 | uint32_t ready_w = 0; 74 | iob_sysfs_read_file(IOB_DMA_SYSFILE_READY_R, &ready_r); 75 | iob_sysfs_read_file(IOB_DMA_SYSFILE_READY_W, &ready_w); 76 | return (ready_w && ready_r); 77 | } 78 | -------------------------------------------------------------------------------- /software/buildroot/board/IObundle/iob-soc/rootfs-overlay/root/dma_demo/iob-dma-user.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "iob-sysfs-common.h" 9 | /* IOb-DMA header automatically generated from: 10 | * /path/to/iob-linux/scripts/drivers.py iob_dma 11 | * contains: 12 | * - sysfs file paths 13 | * - Register address and width definitions 14 | */ 15 | #include "iob_dma.h" 16 | 17 | int dma_start_transfer(uint32_t *base_addr, uint32_t size, int direction, uint16_t interface_number); 18 | uint8_t dma_transfer_ready(); 19 | -------------------------------------------------------------------------------- /software/buildroot/board/IObundle/iob-soc/rootfs-overlay/root/dma_demo/iob-sysfs-common.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "iob-sysfs-common.h" 4 | 5 | int iob_sysfs_read_file(const char *filename, uint32_t *read_value) { 6 | // Open file for read 7 | FILE *file = fopen(filename, "r"); 8 | if (file == NULL) { 9 | perror("[User] Failed to open the file"); 10 | return -1; 11 | } 12 | 13 | // Read uint32_t value from file in ASCII 14 | ssize_t ret = fscanf(file, "%u", read_value); 15 | if (ret == -1) { 16 | perror("[User] Failed to read from file"); 17 | fclose(file); 18 | return -1; 19 | } 20 | 21 | fclose(file); 22 | 23 | return ret; 24 | } 25 | 26 | int iob_sysfs_write_file(const char *filename, uint32_t write_value) { 27 | // Open file for write 28 | FILE *file = fopen(filename, "w"); 29 | if (file == NULL) { 30 | perror("[User] Failed to open the file"); 31 | return -1; 32 | } 33 | 34 | // Write uint32_t value to file in ASCII 35 | ssize_t ret = fprintf(file, "%u", write_value); 36 | if (ret == -1) { 37 | perror("[User] Failed to write to file"); 38 | fclose(file); 39 | return -1; 40 | } 41 | 42 | fclose(file); 43 | 44 | return ret; 45 | } 46 | 47 | int iob_sysfs_print_version(const char *filename) { 48 | uint32_t ret = -1; 49 | uint32_t version = 0; 50 | 51 | ret = iob_sysfs_read_file(filename, &version); 52 | if (ret == -1) { 53 | return ret; 54 | } 55 | 56 | printf("[User] Version: 0x%x\n", version); 57 | return 0; 58 | } 59 | 60 | char *iob_sysfs_gen_fname(char *filename, char *class_path, int minor, 61 | char *reg) { 62 | sprintf(filename, "%s%d/%s", class_path, minor, reg); 63 | return filename; 64 | } 65 | -------------------------------------------------------------------------------- /software/buildroot/board/IObundle/iob-soc/rootfs-overlay/root/dma_demo/iob-sysfs-common.h: -------------------------------------------------------------------------------- 1 | /* iob-sysfs-common.h: common functions for SysFS access */ 2 | 3 | int iob_sysfs_read_file(const char *filename, uint32_t *read_value); 4 | int iob_sysfs_write_file(const char *filename, uint32_t write_value); 5 | int iob_sysfs_print_version(const char *filename); 6 | char *iob_sysfs_gen_fname(char *filename, char *class_path, int minor, 7 | char *reg); 8 | -------------------------------------------------------------------------------- /software/buildroot/board/IObundle/iob-soc/rootfs-overlay/root/dma_demo/iob-timer-user.c: -------------------------------------------------------------------------------- 1 | #include "iob-timer-user.h" 2 | 3 | int iob_timer_reset() { 4 | if (iob_sysfs_write_file(IOB_TIMER_SYSFILE_RESET, 1) == -1) { 5 | return -1; 6 | } 7 | if (iob_sysfs_write_file(IOB_TIMER_SYSFILE_RESET, 0) == -1) { 8 | return -1; 9 | } 10 | 11 | return 0; 12 | } 13 | 14 | int iob_timer_init() { 15 | if (iob_timer_reset()) { 16 | return -1; 17 | } 18 | 19 | if (iob_sysfs_write_file(IOB_TIMER_SYSFILE_ENABLE, 1) == -1) { 20 | return -1; 21 | } 22 | 23 | return 0; 24 | } 25 | 26 | int iob_timer_get_count(uint64_t *count) { 27 | uint32_t ret = -1; 28 | uint32_t data = 0; 29 | 30 | // Sample timer counter 31 | if (iob_sysfs_write_file(IOB_TIMER_SYSFILE_SAMPLE, 1) == -1) { 32 | return -1; 33 | } 34 | if (iob_sysfs_write_file(IOB_TIMER_SYSFILE_SAMPLE, 0) == -1) { 35 | return -1; 36 | } 37 | 38 | // Read sampled timer counter 39 | ret = iob_sysfs_read_file(IOB_TIMER_SYSFILE_DATA_HIGH, &data); 40 | if (ret == -1) { 41 | return -1; 42 | } 43 | *count = ((uint64_t)data) << IOB_TIMER_DATA_LOW_W; 44 | ret = iob_sysfs_read_file(IOB_TIMER_SYSFILE_DATA_LOW, &data); 45 | if (ret == -1) { 46 | return -1; 47 | } 48 | (*count) = (*count) | (uint64_t)data; 49 | 50 | return 0; 51 | } 52 | 53 | int iob_timer_test() { 54 | printf("[Tester|User] IOb-Timer test\n"); 55 | 56 | if (iob_timer_init() == -1) { 57 | perror("[Tester|User] Failed to initialize timer"); 58 | return -1; 59 | } 60 | 61 | if (iob_sysfs_print_version(IOB_TIMER_SYSFILE_VERSION) == -1) { 62 | perror("[Tester|User] Failed to print version"); 63 | return -1; 64 | } 65 | 66 | // read current timer count 67 | uint64_t elapsed = 0; 68 | if (iob_timer_get_count(&elapsed)){ 69 | perror("[Tester|User] Failed to get count"); 70 | } 71 | printf("\nExecution time: %llu clock cycles\n", elapsed); 72 | 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /software/buildroot/board/IObundle/iob-soc/rootfs-overlay/root/dma_demo/iob-timer-user.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "iob-sysfs-common.h" 5 | /* IOb-Timer header automatically generated from: 6 | * /path/to/iob-linux/scripts/drivers.py iob_timer 7 | * contains: 8 | * - sysfs file paths 9 | * - Register address and width definitions 10 | */ 11 | #include "iob_timer.h" 12 | 13 | int iob_timer_reset(); 14 | int iob_timer_init(); 15 | int iob_timer_get_count(uint64_t *count); 16 | int iob_timer_test(); 17 | -------------------------------------------------------------------------------- /software/buildroot/board/IObundle/iob-soc/rootfs-overlay/root/dma_demo/iob-uart16550.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "iob-uart16550.h" 8 | 9 | static int serial_port; 10 | 11 | //TX FUNCTIONS 12 | void uart16550_putc(char c) { 13 | write(serial_port, &c, 1); 14 | } 15 | 16 | //RX FUNCTIONS 17 | char uart16550_getc() { 18 | char c; 19 | read(serial_port, &c, 1); 20 | return c; 21 | } 22 | 23 | // Change UART base 24 | void uart16550_init(char device_path[]) { 25 | serial_port = open(device_path, O_RDWR); 26 | if (serial_port < 0) { 27 | printf("Error %i from open: %s\n", errno, strerror(errno)); 28 | } 29 | } 30 | 31 | void uart16550_finish() { 32 | uart16550_putc(EOT); 33 | close(serial_port); 34 | } 35 | 36 | //Print string, excluding end of string (0) 37 | void uart16550_puts(const char *s) { 38 | while (*s) uart16550_putc(*s++); 39 | } 40 | 41 | //Sends the name of the file to use, including end of string (0) 42 | void uart16550_sendstr (char* name) { 43 | int i=0; 44 | do 45 | uart16550_putc(name[i]); 46 | while (name[i++]); 47 | } 48 | 49 | //Receives file into mem 50 | int uart16550_recvfile(char* file_name, char *mem) { 51 | 52 | uart16550_puts(UART_PROGNAME); 53 | uart16550_puts (": requesting to receive file\n"); 54 | 55 | //send file receive request 56 | uart16550_putc (FRX); 57 | 58 | //clear input buffer 59 | //while(uart16550_rxready()) uart16550_getc(); 60 | 61 | //send file name 62 | uart16550_sendstr(file_name); 63 | 64 | 65 | //receive file size 66 | int file_size = (unsigned int) uart16550_getc(); 67 | file_size |= ((unsigned int) uart16550_getc()) << 8; 68 | file_size |= ((unsigned int) uart16550_getc()) << 16; 69 | file_size |= ((unsigned int) uart16550_getc()) << 24; 70 | 71 | //allocate space for file if file pointer not initialized 72 | if(mem == NULL) { 73 | mem = (char *) malloc(file_size); 74 | if (mem == NULL) { 75 | uart16550_puts(UART_PROGNAME); 76 | uart16550_puts("Error: malloc failed"); 77 | } 78 | } 79 | 80 | //send ACK before receiving file 81 | uart16550_putc(ACK); 82 | 83 | //write file to memory 84 | for (int i = 0; i < file_size; i++) { 85 | mem[i] = uart16550_getc(); 86 | } 87 | 88 | uart16550_puts(UART_PROGNAME); 89 | uart16550_puts(": file received\n"); 90 | 91 | return file_size; 92 | } 93 | 94 | //Sends mem contents to a file 95 | void uart16550_sendfile(char *file_name, int file_size, char *mem) { 96 | 97 | uart16550_puts(UART_PROGNAME); 98 | uart16550_puts(": requesting to send file\n"); 99 | 100 | //send file transmit command 101 | uart16550_putc(FTX); 102 | 103 | //send file name 104 | uart16550_sendstr(file_name); 105 | 106 | // send file size 107 | uart16550_putc((char)(file_size & 0x0ff)); 108 | uart16550_putc((char)((file_size & 0x0ff00) >> 8)); 109 | uart16550_putc((char)((file_size & 0x0ff0000) >> 16)); 110 | uart16550_putc((char)((file_size & 0x0ff000000) >> 24)); 111 | 112 | // send file contents 113 | for (int i = 0; i < file_size; i++) 114 | uart16550_putc(mem[i]); 115 | 116 | uart16550_puts(UART_PROGNAME); 117 | uart16550_puts(": file sent\n"); 118 | } 119 | -------------------------------------------------------------------------------- /software/buildroot/board/IObundle/iob-soc/rootfs-overlay/root/dma_demo/iob-uart16550.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define UART_PROGNAME "IOb-UART" 6 | 7 | //UART commands 8 | #define STX 2 //start text 9 | #define ETX 3 //end text 10 | #define EOT 4 //end of transission 11 | #define ENQ 5 //enquiry 12 | #define ACK 6 //acklowledge 13 | #define FTX 7 //transmit file 14 | #define FRX 8 //receive file 15 | 16 | //UART functions 17 | 18 | // Init UART 19 | void uart16550_init(char device_path[]); 20 | 21 | //Close transmission 22 | void uart16550_finish(); 23 | 24 | //Print char 25 | void uart16550_putc(char c); 26 | 27 | //Print string 28 | void uart16550_puts(const char *s); 29 | 30 | //Send file 31 | void uart16550_sendfile(char* file_name, int file_size, char *mem); 32 | 33 | //Get char 34 | char uart16550_getc(); 35 | 36 | //Receive file 37 | int uart16550_recvfile(char* file_name, char *mem); 38 | -------------------------------------------------------------------------------- /software/iob_soc_dma_demo.dts: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: (GPL-2.0 OR MIT) 2 | /* Copyright (c) 2023 Pedro Antunes */ 3 | // Device tree for base IOb-SoC-Opencryptolinux system 4 | 5 | /dts-v1/; 6 | 7 | / { 8 | #address-cells = <1>; 9 | #size-cells = <1>; 10 | model = "IOb-SoC, VexRiscv"; 11 | compatible = "IOb-SoC, VexRiscv"; 12 | cpus { 13 | #address-cells = <0x1>; 14 | #size-cells = <0x0>; 15 | timebase-frequency = ; 16 | CPU0: cpu@0 { 17 | clock-frequency = ; 18 | device_type = "cpu"; 19 | reg = <0x0>; 20 | status = "okay"; 21 | compatible = "riscv"; 22 | riscv,isa = "rv32imac"; 23 | mmu-type = "riscv,sv32"; 24 | d-cache-block-size = <0x40>; 25 | d-cache-sets = <0x40>; 26 | d-cache-size = <0x8000>; 27 | d-tlb-sets = <0x1>; 28 | d-tlb-size = <0x20>; 29 | i-cache-block-size = <0x40>; 30 | i-cache-sets = <0x40>; 31 | i-cache-size = <0x8000>; 32 | i-tlb-sets = <0x1>; 33 | i-tlb-size = <0x20>; 34 | tlb-split; 35 | CPU0_intc: interrupt-controller { 36 | #address-cells = <0>; 37 | #interrupt-cells = <1>; 38 | interrupt-controller; 39 | compatible = "riscv,cpu-intc"; 40 | }; 41 | }; 42 | }; 43 | memory@80000000 { 44 | device_type = "memory"; 45 | reg = <0x80000000 0x02000000>; // 26 bits (size of external memory) 46 | }; 47 | chosen { 48 | bootargs = "rootwait console=hvc0 earlycon=sbi root=/dev/ram0 init=/sbin/init swiotlb=32 loglevel=8"; 49 | linux,initrd-start = <0x81000000>; 50 | linux,initrd-end = <0x81800000>; // max 8MB ramdisk image 51 | }; 52 | soc { 53 | #address-cells = <1>; 54 | #size-cells = <1>; 55 | compatible = "iobundle,iob-soc", "simple-bus"; 56 | ranges; 57 | // Don't launch driver of UART0 because it's already used by OpenSBI 58 | //uart0: uart@/*UART0_ADDR_MACRO*/ { 59 | // compatible = "ns16550a"; 60 | // reg = <0x/*UART0_ADDR_MACRO*/ 0x1000>; 61 | // clock-frequency = ; 62 | // current-speed = ; 63 | //// interrupt-parent = < &PLIC0 >; 64 | //// interrupts = <1>; 65 | //// reg-shift = <2>; // regs are spaced on 32 bit boundary 66 | //// reg-io-width = <4>; // only 32-bit access are supported 67 | //}; 68 | 69 | // Do we need CLINT0 here? OpenSBI already uses it. 70 | CLINT0: clint@/*CLINT0_ADDR_MACRO*/ { 71 | compatible = "riscv,clint0"; 72 | interrupts-extended = < &CPU0_intc 3 73 | &CPU0_intc 7 >; 74 | reg = <0x/*CLINT0_ADDR_MACRO*/ 0xc0000>; 75 | reg-names = "control"; 76 | }; 77 | 78 | DMA0: dma@/*DMA0_ADDR_MACRO*/ { 79 | compatible = "iobundle,dma0"; 80 | reg = <0x/*DMA0_ADDR_MACRO*/ 0x10>; 81 | }; 82 | 83 | AXISTREAMIN0: axistream_in@/*AXISTREAMIN0_ADDR_MACRO*/ { 84 | compatible = "iobundle,axistream_in0"; 85 | reg = <0x/*AXISTREAMIN0_ADDR_MACRO*/ 0x20>; 86 | }; 87 | 88 | AXISTREAMOUT0: axistream_out@/*AXISTREAMOUT0_ADDR_MACRO*/ { 89 | compatible = "iobundle,axistream_out0"; 90 | reg = <0x/*AXISTREAMOUT0_ADDR_MACRO*/ 0x20>; 91 | }; 92 | 93 | // Do we need PLIC0 here? OpenSBI already uses it. 94 | //PLIC0: plic@/*PLIC0_ADDR_MACRO*/ { 95 | // #address-cells = <0>; 96 | // #interrupt-cells = <1>; 97 | // compatible = "riscv,plic0"; 98 | // interrupt-controller; 99 | // interrupts-extended = < &CPU0_intc 11 100 | // &CPU0_intc 9 >; 101 | // reg = <0x/*PLIC0_ADDR_MACRO*/ 0x4000000>; 102 | // reg-names = "control"; 103 | // riscv,max-priority = <7>; 104 | // riscv,ndev = <31>; 105 | //}; 106 | }; 107 | }; 108 | -------------------------------------------------------------------------------- /software/linux_config: -------------------------------------------------------------------------------- 1 | CONFIG_SECTION_MISMATCH_WARN_ONLY=y 2 | 3 | # Architecture 4 | CONFIG_ARCH_DEFCONFIG="arch/riscv/configs/defconfig" 5 | CONFIG_NONPORTABLE=y 6 | CONFIG_ARCH_RV32I=y 7 | CONFIG_RISCV_ISA_M=y 8 | CONFIG_RISCV_ISA_A=y 9 | CONFIG_RISCV_ISA_C=y 10 | CONFIG_SIFIVE_PLIC=y 11 | CONFIG_FPU=n 12 | CONFIG_SMP=y 13 | CONFIG_STRICT_KERNEL_RWX=n 14 | CONFIG_EFI=n 15 | CONFIG_HVC_RISCV_SBI=y 16 | CONFIG_HOTPLUG_CPU=y 17 | 18 | CONFIG_BLK_DEV_INITRD=y 19 | CONFIG_INITRAMFS_SOURCE="" 20 | CONFIG_RD_GZIP=y 21 | CONFIG_RD_BZIP2=y 22 | CONFIG_RD_LZMA=y 23 | CONFIG_RD_XZ=y 24 | CONFIG_RD_LZO=y 25 | CONFIG_RD_LZ4=y 26 | 27 | # FPGA / SoC 28 | CONFIG_FPGA=y 29 | 30 | # Time 31 | CONFIG_PRINTK_TIME=y 32 | 33 | # Clocking 34 | CONFIG_COMMON_CLK=y 35 | CONFIG_COMMON_CLK_LITEX=y 36 | 37 | # Interrupts 38 | CONFIG_IRQCHIP=y 39 | CONFIG_OF_IRQ=y 40 | CONFIG_HANDLE_DOMAIN_IRQ=y 41 | 42 | # Modules 43 | CONFIG_MODULES=y 44 | CONFIG_MODULE_UNLOAD=y 45 | 46 | # Ethernet 47 | CONFIG_NET=y 48 | CONFIG_PACKET=y 49 | CONFIG_PACKET_DIAG=y 50 | CONFIG_INET=y 51 | CONFIG_NETDEVICES=n 52 | CONFIG_ETHOC=n 53 | 54 | ## Serial 55 | CONFIG_SERIAL_EARLYCON_RISCV_SBI=y 56 | # Enable UART16550 module and probe them from device tree 57 | CONFIG_SERIAL_8250=y 58 | #CONFIG_SERIAL_8250_CONSOLE=y 59 | CONFIG_SERIAL_OF_PLATFORM=y 60 | 61 | CONFIG_EXT2_FS=y 62 | CONFIG_EXT3_FS=y 63 | CONFIG_EXT4_FS=y 64 | 65 | ## .config in kernel 66 | CONFIG_IKCONFIG=y 67 | CONFIG_IKCONFIG_PROC=y 68 | 69 | ## Filesystem 70 | CONFIG_FAT_FS=y 71 | CONFIG_MSDOS_FS=y 72 | CONFIG_MSDOS_PARTITION=y 73 | CONFIG_VFAT_FS=y 74 | CONFIG_FAT_DEFAULT_CODEPAGE=437 75 | CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" 76 | CONFIG_NCPFS_SMALLDOS=y 77 | CONFIG_NLS=y 78 | CONFIG_NLS_CODEPAGE_437=y 79 | CONFIG_NLS_ASCII=y 80 | CONFIG_NLS_ISO8859_1=y 81 | CONFIG_TMPFS=y 82 | CONFIG_DEVTMPFS=y 83 | CONFIG_DEVTMPFS_MOUNT=y 84 | CONFIG_UEVENT_HELPER=y 85 | -------------------------------------------------------------------------------- /software/src/Image: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IObundle/iob-soc-opencryptolinux/dec99d3afd50e8a53ca2a4e01fdc8f3b873746fa/software/src/Image -------------------------------------------------------------------------------- /software/src/clint.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "io.h" 4 | #include "type.h" 5 | 6 | #define CLINT_IPI_ADDR 0x0000 7 | #define CLINT_CMP_ADDR 0x4000 8 | #define CLINT_TIME_ADDR 0xBFF8 9 | 10 | readReg_u32(clint_getTimeLow, CLINT_TIME_ADDR) 11 | readReg_u32(clint_getTimeHigh, CLINT_TIME_ADDR + 4) 12 | 13 | static void clint_setCmp(u32 p, u64 cmp, u32 hart_id) { 14 | p += CLINT_CMP_ADDR + hart_id * 8; 15 | write_u32(0xFFFFFFFF, p + 4); 16 | write_u32(cmp, p + 0); 17 | write_u32(cmp >> 32, p + 4); 18 | } 19 | 20 | static u64 clint_getTime(u32 p) { 21 | u32 lo, hi; 22 | 23 | /* Likewise, must guard against rollover when reading */ 24 | do { 25 | hi = clint_getTimeHigh(p); 26 | lo = clint_getTimeLow(p); 27 | } while (clint_getTimeHigh(p) != hi); 28 | 29 | return (((u64)hi) << 32) | lo; 30 | } 31 | 32 | static void clint_uDelay(u32 usec, u32 hz, u32 reg) { 33 | u32 mTimePerUsec = hz / 1000000; 34 | u32 limit = clint_getTimeLow(reg) + usec * mTimePerUsec; 35 | while ((int32_t)(limit - (clint_getTimeLow(reg))) >= 0) 36 | ; 37 | } -------------------------------------------------------------------------------- /software/src/crypto/McEliece/LICENSE: -------------------------------------------------------------------------------- 1 | Public domain 2 | 3 | "The official Classic McEliece software is in the public domain." 4 | https://classic.mceliece.org/impl.html 5 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/Makefile: -------------------------------------------------------------------------------- 1 | # This Makefile can be used with GNU Make or BSD Make 2 | 3 | LIB = libmceliece348864_clean.a 4 | 5 | SOURCES = aes256ctr.c benes.c bm.c controlbits.c crypto_int16.c crypto_int32.c \ 6 | crypto_uint16.c crypto_uint32.c crypto_uint64.c decrypt.c encrypt.c gf.c \ 7 | operations.c pk_gen.c root.c sk_gen.c synd.c transpose.c util.c 8 | 9 | HEADERS = aes256ctr.h api.h api.h benes.h bm.h controlbits.h crypto_hash.h crypto_hash.h \ 10 | crypto_int16.h crypto_int32.h crypto_kem.h crypto_uint16.h crypto_uint32.h \ 11 | crypto_uint64.h decrypt.h encrypt.h gf.h int32_sort.h int32_sort.h namespace.h \ 12 | operations.h params.h pk_gen.h root.h sk_gen.h synd.h transpose.h uint64_sort.h \ 13 | util.h 14 | 15 | OBJECTS = aes256ctr.o benes.o bm.o controlbits.o crypto_int16.o crypto_int32.o \ 16 | crypto_uint16.o crypto_uint32.o crypto_uint64.o decrypt.o encrypt.o gf.o \ 17 | operations.o pk_gen.o root.o sk_gen.o synd.o transpose.o util.o 18 | 19 | CFLAGS = -O3 -std=c99 -Wall -Wextra -pedantic -Werror -Wpedantic \ 20 | -Wredundant-decls -Wcast-align -Wmissing-prototypes \ 21 | -I../../../common/ $(EXTRAFLAGS) 22 | 23 | all: $(LIB) 24 | 25 | %.o: %.c $(HEADERS) 26 | $(CC) $(CFLAGS) -c -o $@ $< 27 | 28 | $(LIB): $(OBJECTS) 29 | $(AR) -r $@ $(OBJECTS) 30 | 31 | clean: 32 | $(RM) $(OBJECTS) 33 | $(RM) $(LIB) -------------------------------------------------------------------------------- /software/src/crypto/McEliece/Makefile.Microsoft_nmake: -------------------------------------------------------------------------------- 1 | # This Makefile can be used with GNU Make or BSD Make 2 | 3 | LIBRARY = libmceliece348864_clean.lib 4 | 5 | OBJECTS = aes256ctr.obj benes.obj bm.obj controlbits.obj crypto_int16.obj \ 6 | crypto_int32.obj crypto_uint16.obj crypto_uint32.obj crypto_uint64.obj \ 7 | decrypt.obj encrypt.obj gf.obj operations.obj pk_gen.obj root.obj sk_gen.obj \ 8 | synd.obj transpose.obj util.obj 9 | 10 | # Warning C4146 is raised when a unary minus operator is applied to an 11 | # unsigned type; this has nonetheless been standard and portable for as 12 | # long as there has been a C standard, and we do that a lot, especially 13 | # for constant-time computations. Thus, we disable that spurious warning. 14 | CFLAGS=/nologo /O2 /I ..\..\..\common /W4 /wd4146 /WX 15 | 16 | all: $(LIBRARY) 17 | 18 | # Make sure objects are recompiled if headers change. 19 | $(OBJECTS): *.h 20 | 21 | $(LIBRARY): $(OBJECTS) 22 | LIB.EXE /NOLOGO /WX /OUT:$@ $** 23 | 24 | clean: 25 | -DEL $(OBJECTS) 26 | -DEL $(LIBRARY) -------------------------------------------------------------------------------- /software/src/crypto/McEliece/aes256ctr.c: -------------------------------------------------------------------------------- 1 | #include "aes256ctr.h" 2 | 3 | void aes256ctr( 4 | uint8_t *out, 5 | size_t outlen, 6 | const uint8_t nonce[AESCTR_NONCEBYTES], 7 | const uint8_t key[AES256_KEYBYTES]) { 8 | 9 | aes256ctx state; 10 | aes256_ctr_keyexp(&state, key); 11 | aes256_ctr(out, outlen, nonce, &state); 12 | aes256_ctx_release(&state); 13 | } 14 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/aes256ctr.h: -------------------------------------------------------------------------------- 1 | #ifndef PQCLEAN_MCELIECE348864_CLEAN_AES256CTR_H 2 | #define PQCLEAN_MCELIECE348864_CLEAN_AES256CTR_H 3 | 4 | #include 5 | #include 6 | 7 | #include "aes.h" 8 | 9 | #include "namespace.h" 10 | 11 | #define aes256ctr CRYPTO_NAMESPACE(aes256ctr) 12 | 13 | void aes256ctr( 14 | uint8_t *out, 15 | size_t outlen, 16 | const uint8_t nonce[AESCTR_NONCEBYTES], 17 | const uint8_t key[AES256_KEYBYTES] 18 | ); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/api.h: -------------------------------------------------------------------------------- 1 | #ifndef PQCLEAN_MCELIECE348864_CLEAN_API_H 2 | #define PQCLEAN_MCELIECE348864_CLEAN_API_H 3 | 4 | #include 5 | 6 | #define PQCLEAN_MCELIECE348864_CLEAN_CRYPTO_ALGNAME "Classic McEliece 348864" 7 | #define PQCLEAN_MCELIECE348864_CLEAN_CRYPTO_PUBLICKEYBYTES 261120 8 | #define PQCLEAN_MCELIECE348864_CLEAN_CRYPTO_SECRETKEYBYTES 6492 9 | #define PQCLEAN_MCELIECE348864_CLEAN_CRYPTO_CIPHERTEXTBYTES 96 10 | #define PQCLEAN_MCELIECE348864_CLEAN_CRYPTO_BYTES 32 11 | 12 | int PQCLEAN_MCELIECE348864_CLEAN_crypto_kem_enc( 13 | uint8_t *c, 14 | uint8_t *key, 15 | const uint8_t *pk 16 | ); 17 | 18 | int PQCLEAN_MCELIECE348864_CLEAN_crypto_kem_dec( 19 | uint8_t *key, 20 | const uint8_t *c, 21 | const uint8_t *sk 22 | ); 23 | 24 | int PQCLEAN_MCELIECE348864_CLEAN_crypto_kem_keypair 25 | ( 26 | uint8_t *pk, 27 | uint8_t *sk 28 | ); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/arena.c: -------------------------------------------------------------------------------- 1 | #include "arena.h" 2 | 3 | #include 4 | 5 | #include 6 | 7 | //Arena globalArenaInst = {}; 8 | Arena* globalArena = NULL; 9 | 10 | Arena InitArena(int size){ 11 | Arena arena = {}; 12 | arena.ptr = (char*) malloc(size * sizeof(char)); 13 | arena.allocated = size; 14 | 15 | return arena; 16 | } 17 | 18 | void* PushBytes(Arena* arena,int size){ 19 | char* ptr = &arena->ptr[arena->used]; 20 | 21 | size = (size + 3) & (~3); // Align to 4 byte boundary 22 | arena->used += size; 23 | 24 | if(arena->used > arena->allocated){ 25 | printf("Arena overflow\n"); 26 | printf("Size: %d,Used: %d, Allocated: %d\n",size,arena->used,arena->allocated); 27 | } 28 | 29 | return ptr; 30 | } 31 | 32 | void* PushAndZeroBytes(Arena* arena,int size){ 33 | char* ptr = PushBytes(arena,size); 34 | 35 | for (int i = 0; i < size; i++) { 36 | ptr[i] = 0; 37 | } 38 | 39 | return ptr; 40 | } 41 | 42 | int MarkArena(Arena* arena){ 43 | return arena->used; 44 | } 45 | 46 | void PopArena(Arena* arena,int mark){ 47 | arena->used = mark; 48 | } 49 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/arena.h: -------------------------------------------------------------------------------- 1 | #ifndef H_ARENA_H 2 | #define H_ARENA_H 3 | #include 4 | 5 | typedef struct{ 6 | char* ptr; 7 | int used; 8 | int allocated; 9 | } Arena; 10 | 11 | extern Arena* globalArena; 12 | 13 | Arena InitArena(int size); 14 | void* PushBytes(Arena* arena,int size); 15 | void* PushAndZeroBytes(Arena* arena,int size); 16 | int MarkArena(Arena* arena); 17 | void PopArena(Arena* arena,int mark); 18 | 19 | #define PushArray(ARENA,N_ELEM,TYPE) (TYPE*) PushBytes(ARENA,(N_ELEM) * sizeof(TYPE)) 20 | 21 | #endif // H_MEMORY_POOL_H 22 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/benes.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is for Benes network related functions 3 | 4 | For the implementation strategy, see 5 | https://eprint.iacr.org/2017/793.pdf 6 | */ 7 | 8 | #include "util.h" 9 | #include "benes.h" 10 | #include "params.h" 11 | #include "transpose.h" 12 | 13 | /* one layer of the benes network */ 14 | static void layer(uint64_t *data, uint64_t *bits, int lgs) { 15 | int i, j, s; 16 | 17 | uint64_t d; 18 | 19 | s = 1 << lgs; 20 | 21 | for (i = 0; i < 64; i += s * 2) { 22 | for (j = i; j < i + s; j++) { 23 | 24 | d = (data[j + 0] ^ data[j + s]); 25 | d &= (*bits++); 26 | data[j + 0] ^= d; 27 | data[j + s] ^= d; 28 | } 29 | } 30 | } 31 | 32 | /* input: r, sequence of bits to be permuted */ 33 | /* bits, condition bits of the Benes network */ 34 | /* rev, 0 for normal application; !0 for inverse */ 35 | /* output: r, permuted bits */ 36 | void apply_benes(unsigned char *r, const unsigned char *bits, int rev) { 37 | int i; 38 | 39 | const unsigned char *cond_ptr; 40 | int inc, low; 41 | 42 | uint64_t bs[64]; 43 | uint64_t cond[64]; 44 | 45 | // 46 | 47 | for (i = 0; i < 64; i++) { 48 | bs[i] = load8(r + i * 8); 49 | } 50 | 51 | if (rev == 0) { 52 | inc = 256; 53 | cond_ptr = bits; 54 | } else { 55 | inc = -256; 56 | cond_ptr = bits + (2 * GFBITS - 2) * 256; 57 | } 58 | 59 | // 60 | 61 | transpose_64x64(bs, bs); 62 | 63 | for (low = 0; low <= 5; low++) { 64 | for (i = 0; i < 64; i++) { 65 | cond[i] = load4(cond_ptr + i * 4); 66 | } 67 | transpose_64x64(cond, cond); 68 | layer(bs, cond, low); 69 | cond_ptr += inc; 70 | } 71 | 72 | transpose_64x64(bs, bs); 73 | 74 | for (low = 0; low <= 5; low++) { 75 | for (i = 0; i < 32; i++) { 76 | cond[i] = load8(cond_ptr + i * 8); 77 | } 78 | layer(bs, cond, low); 79 | cond_ptr += inc; 80 | } 81 | for (low = 4; low >= 0; low--) { 82 | for (i = 0; i < 32; i++) { 83 | cond[i] = load8(cond_ptr + i * 8); 84 | } 85 | layer(bs, cond, low); 86 | cond_ptr += inc; 87 | } 88 | 89 | transpose_64x64(bs, bs); 90 | 91 | for (low = 5; low >= 0; low--) { 92 | for (i = 0; i < 64; i++) { 93 | cond[i] = load4(cond_ptr + i * 4); 94 | } 95 | transpose_64x64(cond, cond); 96 | layer(bs, cond, low); 97 | cond_ptr += inc; 98 | } 99 | 100 | transpose_64x64(bs, bs); 101 | 102 | // 103 | 104 | for (i = 0; i < 64; i++) { 105 | store8(r + i * 8, bs[i]); 106 | } 107 | } 108 | 109 | /* input: condition bits c */ 110 | /* output: support s */ 111 | void support_gen(gf *s, const unsigned char *c) { 112 | gf a; 113 | int i, j; 114 | unsigned char L[ GFBITS ][ (1 << GFBITS) / 8 ]; 115 | 116 | for (i = 0; i < GFBITS; i++) { 117 | for (j = 0; j < (1 << GFBITS) / 8; j++) { 118 | L[i][j] = 0; 119 | } 120 | } 121 | 122 | for (i = 0; i < (1 << GFBITS); i++) { 123 | a = bitrev((gf) i); 124 | 125 | for (j = 0; j < GFBITS; j++) { 126 | L[j][ i / 8 ] |= ((a >> j) & 1) << (i % 8); 127 | } 128 | } 129 | 130 | for (j = 0; j < GFBITS; j++) { 131 | apply_benes(L[j], c, 0); 132 | } 133 | 134 | for (i = 0; i < SYS_N; i++) { 135 | s[i] = 0; 136 | for (j = GFBITS - 1; j >= 0; j--) { 137 | s[i] <<= 1; 138 | s[i] |= (L[j][i / 8] >> (i % 8)) & 1; 139 | } 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/benes.h: -------------------------------------------------------------------------------- 1 | #ifndef BENES_H 2 | #define BENES_H 3 | /* 4 | This file is for Benes network related functions 5 | */ 6 | 7 | #include "namespace.h" 8 | 9 | #define apply_benes CRYPTO_NAMESPACE(apply_benes) 10 | #define support_gen CRYPTO_NAMESPACE(support_gen) 11 | 12 | #include "gf.h" 13 | 14 | void apply_benes(unsigned char *r, const unsigned char *bits, int rev); 15 | void support_gen(gf *s, const unsigned char *c); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/bm.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is for the Berlekamp-Massey algorithm 3 | see http://crypto.stanford.edu/~mironov/cs359/massey.pdf 4 | */ 5 | 6 | #include "bm.h" 7 | #include "params.h" 8 | 9 | #define min(a, b) (((a) < (b)) ? (a) : (b)) 10 | 11 | /* the Berlekamp-Massey algorithm */ 12 | /* input: s, sequence of field elements */ 13 | /* output: out, minimal polynomial of s */ 14 | void bm(gf *out, gf *s) { 15 | int i; 16 | 17 | uint16_t N = 0; 18 | uint16_t L = 0; 19 | uint16_t mle; 20 | uint16_t mne; 21 | 22 | gf T[ SYS_T + 1 ]; 23 | gf C[ SYS_T + 1 ]; 24 | gf B[ SYS_T + 1 ]; 25 | 26 | gf b = 1, d, f; 27 | 28 | // 29 | 30 | for (i = 0; i < SYS_T + 1; i++) { 31 | C[i] = B[i] = 0; 32 | } 33 | 34 | B[1] = C[0] = 1; 35 | 36 | // 37 | 38 | for (N = 0; N < 2 * SYS_T; N++) { 39 | d = 0; 40 | 41 | for (i = 0; i <= min(N, SYS_T); i++) { 42 | d ^= gf_mul(C[i], s[ N - i]); 43 | } 44 | 45 | mne = d; 46 | mne -= 1; 47 | mne >>= 15; 48 | mne -= 1; 49 | mle = N; 50 | mle -= 2 * L; 51 | mle >>= 15; 52 | mle -= 1; 53 | mle &= mne; 54 | 55 | for (i = 0; i <= SYS_T; i++) { 56 | T[i] = C[i]; 57 | } 58 | 59 | f = gf_frac(b, d); 60 | 61 | for (i = 0; i <= SYS_T; i++) { 62 | C[i] ^= gf_mul(f, B[i]) & mne; 63 | } 64 | 65 | L = (L & ~mle) | ((N + 1 - L) & mle); 66 | 67 | for (i = 0; i <= SYS_T; i++) { 68 | B[i] = (B[i] & ~mle) | (T[i] & mle); 69 | } 70 | 71 | b = (b & ~mle) | (d & mle); 72 | 73 | for (i = SYS_T; i >= 1; i--) { 74 | B[i] = B[i - 1]; 75 | } 76 | B[0] = 0; 77 | } 78 | 79 | for (i = 0; i <= SYS_T; i++) { 80 | out[i] = C[ SYS_T - i ]; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/bm.h: -------------------------------------------------------------------------------- 1 | #ifndef BM_H 2 | #define BM_H 3 | /* 4 | This file is for the Berlekamp-Massey algorithm 5 | see http://crypto.stanford.edu/~mironov/cs359/massey.pdf 6 | */ 7 | 8 | #include "gf.h" 9 | #include "namespace.h" 10 | 11 | #define bm CRYPTO_NAMESPACE(bm) 12 | 13 | void bm(gf *out, gf *s); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/common/aes.h: -------------------------------------------------------------------------------- 1 | #ifndef AES_H 2 | #define AES_H 3 | 4 | #include 5 | #include 6 | 7 | #define AES128_KEYBYTES 16 8 | #define AES192_KEYBYTES 24 9 | #define AES256_KEYBYTES 32 10 | #define AESCTR_NONCEBYTES 12 11 | #define AES_BLOCKBYTES 16 12 | 13 | // We've put these states on the heap to make sure ctx_release is used. 14 | #define PQC_AES128_STATESIZE 88 15 | typedef struct { 16 | uint64_t *sk_exp; 17 | } aes128ctx; 18 | 19 | #define PQC_AES192_STATESIZE 104 20 | typedef struct { 21 | uint64_t *sk_exp; 22 | } aes192ctx; 23 | 24 | #define PQC_AES256_STATESIZE 120 25 | typedef struct { 26 | uint64_t *sk_exp; 27 | } aes256ctx; 28 | 29 | /** Initializes the context **/ 30 | void aes128_ecb_keyexp(aes128ctx *r, const unsigned char *key); 31 | 32 | void aes128_ctr_keyexp(aes128ctx *r, const unsigned char *key); 33 | 34 | void aes128_ecb(unsigned char *out, const unsigned char *in, size_t nblocks, const aes128ctx *ctx); 35 | 36 | void aes128_ctr(unsigned char *out, size_t outlen, const unsigned char *iv, const aes128ctx *ctx); 37 | 38 | /** Frees the context **/ 39 | void aes128_ctx_release(aes128ctx *r); 40 | 41 | /** Initializes the context **/ 42 | void aes192_ecb_keyexp(aes192ctx *r, const unsigned char *key); 43 | 44 | void aes192_ctr_keyexp(aes192ctx *r, const unsigned char *key); 45 | 46 | void aes192_ecb(unsigned char *out, const unsigned char *in, size_t nblocks, const aes192ctx *ctx); 47 | 48 | void aes192_ctr(unsigned char *out, size_t outlen, const unsigned char *iv, const aes192ctx *ctx); 49 | 50 | void aes192_ctx_release(aes192ctx *r); 51 | 52 | /** Initializes the context **/ 53 | void aes256_ecb_keyexp(aes256ctx *r, const unsigned char *key); 54 | 55 | void aes256_ctr_keyexp(aes256ctx *r, const unsigned char *key); 56 | 57 | void aes256_ecb(unsigned char *out, const unsigned char *in, size_t nblocks, const aes256ctx *ctx); 58 | 59 | void aes256_ctr(unsigned char *out, size_t outlen, const unsigned char *iv, const aes256ctx *ctx); 60 | 61 | /** Frees the context **/ 62 | void aes256_ctx_release(aes256ctx *r); 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/common/compat.h: -------------------------------------------------------------------------------- 1 | #ifndef PQCLEAN_COMMON_COMPAT_H 2 | #define PQCLEAN_COMMON_COMPAT_H 3 | 4 | /* This file serves to solve compatibility issues between different 5 | * versions of compilers. 6 | * 7 | * This file is allowed to use #ifdefs and toggle things by compiler versions. 8 | */ 9 | 10 | // From https://github.com/gcc-mirror/gcc/blob/af73a8b2027d9ab64944d7dbbb48e207d7790ce6/gcc/config/i386/avxintrin.h#L62-L71 11 | /* Unaligned versions of the vector types */ 12 | #define UNALIGNED_VECTOR_POLYFILL_GCC \ 13 | typedef float __m256_u __attribute__ ((__vector_size__ (32), __may_alias__, __aligned__ (1))); \ 14 | typedef double __m256d_u __attribute__ ((__vector_size__ (32), __may_alias__, __aligned__ (1))); \ 15 | typedef long long __m256i_u __attribute__ ((__vector_size__ (32), __may_alias__, __aligned__ (1))); 16 | 17 | #if defined(__GNUC__) && !defined(__clang__) 18 | #include 19 | 20 | # if !__GNUC_PREREQ(7, 1) // at least GCC 7.1 21 | /* Versions of the GCC pre-7.1 don't have __m256*_u types */ 22 | UNALIGNED_VECTOR_POLYFILL_GCC 23 | # endif // __GNUC_PREREQ(7,1) 24 | 25 | #elif defined(__GNUC__) && defined(__clang__) 26 | 27 | # if __clang__major__ < 9 28 | /* Versions of Clang pre-9.0 don't have __m256*_u types */ 29 | UNALIGNED_VECTOR_POLYFILL_GCC 30 | # endif 31 | 32 | #elif defined(_MSC_VER) 33 | // MSVC simply doesn't have these types 34 | #define __m256_u __m256 35 | #define __m256d_u __m256d 36 | #define __m256i_u __m256i 37 | 38 | #else 39 | #error UNSUPPORTED COMPILER!?!? 40 | #endif // compiler selector 41 | 42 | /************************ 43 | * Portable VLA support * 44 | ************************/ 45 | 46 | /* To support MSVC use alloca() instead of VLAs. */ 47 | #ifdef _MSC_VER 48 | /* MSVC defines _alloca in malloc.h */ 49 | # include 50 | /* Note: _malloca(), which is recommended over deprecated _alloca, 51 | requires that you call _freea(). So we stick with _alloca */ 52 | # define PQCLEAN_VLA(__t,__x,__s) __t *__x = (__t*)_alloca((__s)*sizeof(__t)) 53 | #else 54 | # define PQCLEAN_VLA(__t,__x,__s) __t __x[__s] 55 | #endif 56 | 57 | #endif // PQCLEAN_COMMON_COMPAT_H 58 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/common/crypto_declassify.h: -------------------------------------------------------------------------------- 1 | #ifndef PQCLEAN_CRYPTO_DECLASSIFY 2 | #define PQCLEAN_CRYPTO_DECLASSIFY 3 | 4 | /* EMPTY MACRO DEFINITION */ 5 | #define crypto_declassify(x, y) 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/common/nistkatrng.c: -------------------------------------------------------------------------------- 1 | // 2 | // rng.c 3 | // 4 | // Created by Bassham, Lawrence E (Fed) on 8/29/17. 5 | // Copyright © 2017 Bassham, Lawrence E (Fed). All rights reserved. 6 | // Modified for liboqs by Douglas Stebila 7 | // 8 | 9 | #include 10 | #include 11 | 12 | #include "aes.h" 13 | #include "randombytes.h" 14 | 15 | typedef struct { 16 | uint8_t Key[32]; 17 | uint8_t V[16]; 18 | int reseed_counter; 19 | } AES256_CTR_DRBG_struct; 20 | 21 | static AES256_CTR_DRBG_struct DRBG_ctx; 22 | static void AES256_CTR_DRBG_Update(const uint8_t *provided_data, uint8_t *Key, uint8_t *V); 23 | 24 | // Use whatever AES implementation you have. This uses AES from openSSL library 25 | // key - 256-bit AES key 26 | // ctr - a 128-bit plaintext value 27 | // buffer - a 128-bit ciphertext value 28 | static void AES256_ECB(uint8_t *key, uint8_t *ctr, uint8_t *buffer) { 29 | aes256ctx ctx; 30 | aes256_ecb_keyexp(&ctx, key); 31 | aes256_ecb(buffer, ctr, 1, &ctx); 32 | aes256_ctx_release(&ctx); 33 | } 34 | 35 | void nist_kat_init(uint8_t *entropy_input, const uint8_t *personalization_string, int security_strength); 36 | void nist_kat_init(uint8_t *entropy_input, const uint8_t *personalization_string, int security_strength) { 37 | uint8_t seed_material[48]; 38 | 39 | assert(security_strength == 256); 40 | memcpy(seed_material, entropy_input, 48); 41 | if (personalization_string) { 42 | for (int i = 0; i < 48; i++) { 43 | seed_material[i] ^= personalization_string[i]; 44 | } 45 | } 46 | memset(DRBG_ctx.Key, 0x00, 32); 47 | memset(DRBG_ctx.V, 0x00, 16); 48 | AES256_CTR_DRBG_Update(seed_material, DRBG_ctx.Key, DRBG_ctx.V); 49 | DRBG_ctx.reseed_counter = 1; 50 | } 51 | 52 | #if 1 53 | int randombytes(uint8_t *buf, size_t n) { 54 | uint8_t block[16]; 55 | int i = 0; 56 | 57 | while (n > 0) { 58 | //increment V 59 | for (int j = 15; j >= 0; j--) { 60 | if (DRBG_ctx.V[j] == 0xff) { 61 | DRBG_ctx.V[j] = 0x00; 62 | } else { 63 | DRBG_ctx.V[j]++; 64 | break; 65 | } 66 | } 67 | AES256_ECB(DRBG_ctx.Key, DRBG_ctx.V, block); 68 | if (n > 15) { 69 | memcpy(buf + i, block, 16); 70 | i += 16; 71 | n -= 16; 72 | } else { 73 | memcpy(buf + i, block, n); 74 | n = 0; 75 | } 76 | } 77 | AES256_CTR_DRBG_Update(NULL, DRBG_ctx.Key, DRBG_ctx.V); 78 | DRBG_ctx.reseed_counter++; 79 | return 0; 80 | } 81 | #endif 82 | 83 | static void AES256_CTR_DRBG_Update(const uint8_t *provided_data, uint8_t *Key, uint8_t *V) { 84 | uint8_t temp[48]; 85 | 86 | for (int i = 0; i < 3; i++) { 87 | //increment V 88 | for (int j = 15; j >= 0; j--) { 89 | if (V[j] == 0xff) { 90 | V[j] = 0x00; 91 | } else { 92 | V[j]++; 93 | break; 94 | } 95 | } 96 | 97 | AES256_ECB(Key, V, temp + 16 * i); 98 | } 99 | if (provided_data != NULL) { 100 | for (int i = 0; i < 48; i++) { 101 | temp[i] ^= provided_data[i]; 102 | } 103 | } 104 | memcpy(Key, temp, 32); 105 | memcpy(V, temp + 32, 16); 106 | } 107 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/common/nistkatrng.h: -------------------------------------------------------------------------------- 1 | #ifndef NIST_KAT_RNG_H 2 | #define NIST_KAT_RNG_H 3 | 4 | void nist_kat_init(uint8_t *entropy_input, const uint8_t *personalization_string, int security_strength); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/common/nistseedexpander.c: -------------------------------------------------------------------------------- 1 | // 2 | // rng.c 3 | // 4 | // Created by Bassham, Lawrence E (Fed) on 8/29/17. 5 | // Copyright © 2017 Bassham, Lawrence E (Fed). All rights reserved. 6 | // Modified for PQClean by Sebastian Verschoor 7 | // 8 | 9 | #include "nistseedexpander.h" 10 | #include "aes.h" 11 | #include 12 | 13 | /* 14 | seedexpander_init() 15 | ctx - stores the current state of an instance of the seed expander 16 | seed - a 32 byte random value 17 | diversifier - an 8 byte diversifier 18 | maxlen - maximum number of bytes (less than 2**32) generated under this seed and diversifier 19 | */ 20 | int 21 | seedexpander_init(AES_XOF_struct *ctx, 22 | const uint8_t *seed, 23 | const uint8_t *diversifier, 24 | size_t maxlen) { 25 | ctx->length_remaining = maxlen; 26 | 27 | memcpy(ctx->key, seed, 32); 28 | memcpy(ctx->ctr, diversifier, 8); 29 | 30 | ctx->ctr[11] = maxlen % 256; 31 | maxlen >>= 8; 32 | ctx->ctr[10] = maxlen % 256; 33 | maxlen >>= 8; 34 | ctx->ctr[9] = maxlen % 256; 35 | maxlen >>= 8; 36 | ctx->ctr[8] = maxlen % 256; 37 | memset(ctx->ctr + 12, 0x00, 4); 38 | 39 | ctx->buffer_pos = 16; 40 | memset(ctx->buffer, 0x00, 16); 41 | 42 | return RNG_SUCCESS; 43 | } 44 | 45 | static void AES256_ECB(uint8_t *key, uint8_t *ctr, uint8_t *buffer) { 46 | aes256ctx ctx; 47 | aes256_ecb_keyexp(&ctx, key); 48 | aes256_ecb(buffer, ctr, 1, &ctx); 49 | aes256_ctx_release(&ctx); 50 | } 51 | 52 | /* 53 | seedexpander() 54 | ctx - stores the current state of an instance of the seed expander 55 | x - returns the XOF data 56 | xlen - number of bytes to return 57 | */ 58 | int 59 | seedexpander(AES_XOF_struct *ctx, uint8_t *x, size_t xlen) { 60 | size_t offset; 61 | 62 | if ( x == NULL ) { 63 | return RNG_BAD_OUTBUF; 64 | } 65 | if ( xlen >= ctx->length_remaining ) { 66 | return RNG_BAD_REQ_LEN; 67 | } 68 | 69 | ctx->length_remaining -= xlen; 70 | 71 | offset = 0; 72 | while ( xlen > 0 ) { 73 | if ( xlen <= (16 - ctx->buffer_pos) ) { // buffer has what we need 74 | memcpy(x + offset, ctx->buffer + ctx->buffer_pos, xlen); 75 | ctx->buffer_pos += xlen; 76 | 77 | return RNG_SUCCESS; 78 | } 79 | 80 | // take what's in the buffer 81 | memcpy(x + offset, ctx->buffer + ctx->buffer_pos, 16 - ctx->buffer_pos); 82 | xlen -= 16 - ctx->buffer_pos; 83 | offset += 16 - ctx->buffer_pos; 84 | 85 | AES256_ECB(ctx->key, ctx->ctr, ctx->buffer); 86 | ctx->buffer_pos = 0; 87 | 88 | //increment the counter 89 | for (size_t i = 15; i >= 12; i--) { 90 | if ( ctx->ctr[i] == 0xff ) { 91 | ctx->ctr[i] = 0x00; 92 | } else { 93 | ctx->ctr[i]++; 94 | break; 95 | } 96 | } 97 | 98 | } 99 | 100 | return RNG_SUCCESS; 101 | } 102 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/common/nistseedexpander.h: -------------------------------------------------------------------------------- 1 | #ifndef NISTSEEDEXPANDER_H 2 | #define NISTSEEDEXPANDER_H 3 | 4 | // 5 | // rng.h 6 | // 7 | // Created by Bassham, Lawrence E (Fed) on 8/29/17. 8 | // Copyright © 2017 Bassham, Lawrence E (Fed). All rights reserved. 9 | // Modified for PQClean by Sebastian Verschoor 10 | // 11 | 12 | #include 13 | #include 14 | 15 | #define NISTSEEDEXPANDER_SEED_LEN 32 16 | 17 | #define RNG_SUCCESS ( 0) 18 | #define RNG_BAD_MAXLEN (-1) 19 | #define RNG_BAD_OUTBUF (-2) 20 | #define RNG_BAD_REQ_LEN (-3) 21 | 22 | typedef struct { 23 | uint8_t buffer[16]; 24 | size_t buffer_pos; 25 | size_t length_remaining; 26 | uint8_t key[NISTSEEDEXPANDER_SEED_LEN]; 27 | uint8_t ctr[16]; 28 | } AES_XOF_struct; 29 | 30 | int 31 | seedexpander_init(AES_XOF_struct *ctx, 32 | const uint8_t *seed, 33 | const uint8_t *diversifier, 34 | size_t maxlen); 35 | 36 | int 37 | seedexpander(AES_XOF_struct *ctx, uint8_t *x, size_t xlen); 38 | 39 | #endif /* NISTSEEDEXPANDER_H */ 40 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/common/randombytes.h: -------------------------------------------------------------------------------- 1 | #ifndef PQCLEAN_RANDOMBYTES_H 2 | #define PQCLEAN_RANDOMBYTES_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | 10 | #ifdef _WIN32 11 | /* Load size_t on windows */ 12 | #include 13 | #else 14 | #include 15 | #endif /* _WIN32 */ 16 | 17 | /* 18 | * Write `n` bytes of high quality random bytes to `buf` 19 | */ 20 | #define randombytes PQCLEAN_randombytes 21 | int randombytes(uint8_t *output, size_t n); 22 | 23 | #ifdef __cplusplus 24 | } 25 | #endif 26 | 27 | #endif /* PQCLEAN_RANDOMBYTES_H */ 28 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/common/sha2.h: -------------------------------------------------------------------------------- 1 | #ifndef SHA2_H 2 | #define SHA2_H 3 | 4 | #include 5 | #include 6 | 7 | /* The incremental API allows hashing of individual input blocks; these blocks 8 | must be exactly 64 bytes each. 9 | Use the 'finalize' functions for any remaining bytes (possibly over 64). */ 10 | 11 | #define PQC_SHA256CTX_BYTES 40 12 | /* Structure for the incremental API */ 13 | typedef struct { 14 | uint8_t *ctx; 15 | } sha224ctx; 16 | 17 | /* Structure for the incremental API */ 18 | typedef struct { 19 | uint8_t *ctx; 20 | } sha256ctx; 21 | 22 | #define PQC_SHA512CTX_BYTES 72 23 | /* Structure for the incremental API */ 24 | typedef struct { 25 | uint8_t *ctx; 26 | } sha384ctx; 27 | 28 | /* Structure for the incremental API */ 29 | typedef struct { 30 | uint8_t *ctx; 31 | } sha512ctx; 32 | 33 | /* ====== SHA224 API ==== */ 34 | 35 | /** 36 | * Initialize the incremental hashing API. 37 | * 38 | * Can't be called multiple times. 39 | */ 40 | void sha224_inc_init(sha224ctx *state); 41 | 42 | /** 43 | * Copy the hashing state 44 | */ 45 | void sha224_inc_ctx_clone(sha224ctx *stateout, const sha224ctx *statein); 46 | 47 | /** 48 | * Absorb blocks 49 | */ 50 | void sha224_inc_blocks(sha224ctx *state, const uint8_t *in, size_t inblocks); 51 | 52 | /** 53 | * Finalize and obtain the digest 54 | * 55 | * If applicable, this function will free the memory associated with the sha224ctx. 56 | * 57 | * If not calling this function, call `sha224_inc_ctx_release` 58 | */ 59 | void sha224_inc_finalize(uint8_t *out, sha224ctx *state, const uint8_t *in, size_t inlen); 60 | 61 | /** 62 | * Destroy the state. Make sure to use this, as this API may not always be stack-based. 63 | */ 64 | void sha224_inc_ctx_release(sha224ctx *state); 65 | 66 | /** 67 | * All-in-one sha224 function 68 | */ 69 | void sha224(uint8_t *out, const uint8_t *in, size_t inlen); 70 | 71 | /* ====== SHA256 API ==== */ 72 | 73 | /** 74 | * Initialize the incremental hashing API 75 | */ 76 | void sha256_inc_init(sha256ctx *state); 77 | 78 | /** 79 | * Copy the hashing state 80 | */ 81 | void sha256_inc_ctx_clone(sha256ctx *stateout, const sha256ctx *statein); 82 | 83 | /** 84 | * Absorb blocks 85 | */ 86 | void sha256_inc_blocks(sha256ctx *state, const uint8_t *in, size_t inblocks); 87 | 88 | /** 89 | * Finalize and obtain the digest 90 | * 91 | * If applicable, this function will free the memory associated with the sha256ctx. 92 | */ 93 | void sha256_inc_finalize(uint8_t *out, sha256ctx *state, const uint8_t *in, size_t inlen); 94 | 95 | /** 96 | * Destroy the state. Make sure to use this, as this API may not always be stack-based. 97 | */ 98 | void sha256_inc_ctx_release(sha256ctx *state); 99 | 100 | /** 101 | * All-in-one sha256 function 102 | */ 103 | void sha256(uint8_t *out, const uint8_t *in, size_t inlen); 104 | 105 | /* ====== SHA384 API ==== */ 106 | 107 | /** 108 | * Initialize the incremental hashing API 109 | */ 110 | void sha384_inc_init(sha384ctx *state); 111 | 112 | /** 113 | * Copy the hashing state 114 | */ 115 | void sha384_inc_ctx_clone(sha384ctx *stateout, const sha384ctx *statein); 116 | 117 | /** 118 | * Absorb blocks 119 | */ 120 | void sha384_inc_blocks(sha384ctx *state, const uint8_t *in, size_t inblocks); 121 | 122 | /** 123 | * Finalize and obtain the digest. 124 | * 125 | * If applicable, this function will free the memory associated with the sha384ctx. 126 | */ 127 | void sha384_inc_finalize(uint8_t *out, sha384ctx *state, const uint8_t *in, size_t inlen); 128 | 129 | /** 130 | * Destroy the state. Make sure to use this if not calling finalize, as this API may not always be stack-based. 131 | */ 132 | void sha384_inc_ctx_release(sha384ctx *state); 133 | 134 | /** 135 | * All-in-one sha384 function 136 | */ 137 | void sha384(uint8_t *out, const uint8_t *in, size_t inlen); 138 | 139 | /* ====== SHA512 API ==== */ 140 | 141 | /** 142 | * Initialize the incremental hashing API 143 | */ 144 | void sha512_inc_init(sha512ctx *state); 145 | 146 | /** 147 | * Copy the hashing state 148 | */ 149 | void sha512_inc_ctx_clone(sha512ctx *stateout, const sha512ctx *statein); 150 | 151 | /** 152 | * Absorb blocks 153 | */ 154 | void sha512_inc_blocks(sha512ctx *state, const uint8_t *in, size_t inblocks); 155 | 156 | /** 157 | * Finalize and obtain the digest 158 | * 159 | * If applicable, this function will free the memory associated with the sha512ctx. 160 | */ 161 | void sha512_inc_finalize(uint8_t *out, sha512ctx *state, const uint8_t *in, size_t inlen); 162 | 163 | /** 164 | * Destroy the state. Make sure to use this if not calling finalize, as this API may not always be stack-based. 165 | */ 166 | void sha512_inc_ctx_release(sha512ctx *state); 167 | 168 | /** 169 | * All-in-one sha512 function 170 | */ 171 | void sha512(uint8_t *out, const uint8_t *in, size_t inlen); 172 | 173 | #endif 174 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/common/sp800-185.h: -------------------------------------------------------------------------------- 1 | #ifndef SP800_185_H 2 | #define SP800_185_H 3 | 4 | #include 5 | #include 6 | 7 | #include "fips202.h" 8 | 9 | void cshake128_inc_init(shake128incctx *state, const uint8_t *name, size_t namelen, const uint8_t *cstm, size_t cstmlen); 10 | void cshake128_inc_absorb(shake128incctx *state, const uint8_t *input, size_t inlen); 11 | void cshake128_inc_finalize(shake128incctx *state); 12 | void cshake128_inc_squeeze(uint8_t *output, size_t outlen, shake128incctx *state); 13 | void cshake128_inc_ctx_release(shake128incctx *state); 14 | void cshake128_inc_ctx_clone(shake128incctx *dest, const shake128incctx *src); 15 | 16 | void cshake128(uint8_t *output, size_t outlen, const uint8_t *name, size_t namelen, const uint8_t *cstm, size_t cstmlen, const uint8_t *input, size_t inlen); 17 | 18 | void cshake256_inc_init(shake256incctx *state, const uint8_t *name, size_t namelen, const uint8_t *cstm, size_t cstmlen); 19 | void cshake256_inc_absorb(shake256incctx *state, const uint8_t *input, size_t inlen); 20 | void cshake256_inc_finalize(shake256incctx *state); 21 | void cshake256_inc_squeeze(uint8_t *output, size_t outlen, shake256incctx *state); 22 | void cshake256_inc_ctx_release(shake256incctx *state); 23 | void cshake256_inc_ctx_clone(shake256incctx *dest, const shake256incctx *src); 24 | 25 | void cshake256(uint8_t *output, size_t outlen, const uint8_t *name, size_t namelen, const uint8_t *cstm, size_t cstmlen, const uint8_t *input, size_t inlen); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/controlbits.h: -------------------------------------------------------------------------------- 1 | #ifndef CONTROLBITS_H 2 | #define CONTROLBITS_H 3 | /* This file is for implementing the Nassimi-Sahni algorithm */ 4 | /* See David Nassimi, Sartaj Sahni "Parallel algorithms to set up the Benes permutationnetwork" */ 5 | /* See also https://cr.yp.to/papers/controlbits-20200923.pdf */ 6 | 7 | #include "namespace.h" 8 | 9 | #define controlbitsfrompermutation CRYPTO_NAMESPACE(controlbitsfrompermutation) 10 | 11 | #include 12 | 13 | extern void controlbitsfrompermutation(unsigned char *out, const int16_t *pi, long long w, long long n); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/crypto_hash.h: -------------------------------------------------------------------------------- 1 | #ifndef PQCLEAN_MCELIECE348864_CLEAN_CRYPTO_HASH_H 2 | #define PQCLEAN_MCELIECE348864_CLEAN_CRYPTO_HASH_H 3 | 4 | #include "fips202.h" 5 | 6 | #define crypto_hash_32b(out, in, inlen) \ 7 | shake256(out, 32, in, inlen) 8 | 9 | #define shake(out,outlen,in,inlen) \ 10 | shake256(out, outlen, in, inlen) 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/crypto_int16.c: -------------------------------------------------------------------------------- 1 | #include "crypto_int16.h" 2 | 3 | crypto_int16 crypto_int16_negative_mask(crypto_int16 crypto_int16_x) { 4 | return crypto_int16_x >> 15; 5 | } 6 | 7 | crypto_int16 crypto_int16_nonzero_mask(crypto_int16 crypto_int16_x) { 8 | return crypto_int16_negative_mask(crypto_int16_x) | crypto_int16_negative_mask(-crypto_int16_x); 9 | } 10 | 11 | crypto_int16 crypto_int16_zero_mask(crypto_int16 crypto_int16_x) { 12 | return ~crypto_int16_nonzero_mask(crypto_int16_x); 13 | } 14 | 15 | crypto_int16 crypto_int16_positive_mask(crypto_int16 crypto_int16_x) { 16 | crypto_int16 crypto_int16_z = -crypto_int16_x; 17 | crypto_int16_z ^= crypto_int16_x & crypto_int16_z; 18 | return crypto_int16_negative_mask(crypto_int16_z); 19 | } 20 | 21 | crypto_int16 crypto_int16_unequal_mask(crypto_int16 crypto_int16_x, crypto_int16 crypto_int16_y) { 22 | crypto_int16 crypto_int16_xy = crypto_int16_x ^ crypto_int16_y; 23 | return crypto_int16_nonzero_mask(crypto_int16_xy); 24 | } 25 | 26 | crypto_int16 crypto_int16_equal_mask(crypto_int16 crypto_int16_x, crypto_int16 crypto_int16_y) { 27 | return ~crypto_int16_unequal_mask(crypto_int16_x, crypto_int16_y); 28 | } 29 | 30 | crypto_int16 crypto_int16_smaller_mask(crypto_int16 crypto_int16_x, crypto_int16 crypto_int16_y) { 31 | crypto_int16 crypto_int16_xy = crypto_int16_x ^ crypto_int16_y; 32 | crypto_int16 crypto_int16_z = crypto_int16_x - crypto_int16_y; 33 | crypto_int16_z ^= crypto_int16_xy & (crypto_int16_z ^ crypto_int16_x); 34 | return crypto_int16_negative_mask(crypto_int16_z); 35 | } 36 | 37 | crypto_int16 crypto_int16_min(crypto_int16 crypto_int16_x, crypto_int16 crypto_int16_y) { 38 | crypto_int16 crypto_int16_xy = crypto_int16_y ^ crypto_int16_x; 39 | crypto_int16 crypto_int16_z = crypto_int16_y - crypto_int16_x; 40 | crypto_int16_z ^= crypto_int16_xy & (crypto_int16_z ^ crypto_int16_y); 41 | crypto_int16_z = crypto_int16_negative_mask(crypto_int16_z); 42 | crypto_int16_z &= crypto_int16_xy; 43 | return crypto_int16_x ^ crypto_int16_z; 44 | } 45 | 46 | crypto_int16 crypto_int16_max(crypto_int16 crypto_int16_x, crypto_int16 crypto_int16_y) { 47 | crypto_int16 crypto_int16_xy = crypto_int16_y ^ crypto_int16_x; 48 | crypto_int16 crypto_int16_z = crypto_int16_y - crypto_int16_x; 49 | crypto_int16_z ^= crypto_int16_xy & (crypto_int16_z ^ crypto_int16_y); 50 | crypto_int16_z = crypto_int16_negative_mask(crypto_int16_z); 51 | crypto_int16_z &= crypto_int16_xy; 52 | return crypto_int16_y ^ crypto_int16_z; 53 | } 54 | 55 | void crypto_int16_minmax(crypto_int16 *crypto_int16_a, crypto_int16 *crypto_int16_b) { 56 | crypto_int16 crypto_int16_x = *crypto_int16_a; 57 | crypto_int16 crypto_int16_y = *crypto_int16_b; 58 | crypto_int16 crypto_int16_xy = crypto_int16_y ^ crypto_int16_x; 59 | crypto_int16 crypto_int16_z = crypto_int16_y - crypto_int16_x; 60 | crypto_int16_z ^= crypto_int16_xy & (crypto_int16_z ^ crypto_int16_y); 61 | crypto_int16_z = crypto_int16_negative_mask(crypto_int16_z); 62 | crypto_int16_z &= crypto_int16_xy; 63 | *crypto_int16_a = crypto_int16_x ^ crypto_int16_z; 64 | *crypto_int16_b = crypto_int16_y ^ crypto_int16_z; 65 | } 66 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/crypto_int16.h: -------------------------------------------------------------------------------- 1 | #ifndef PQCLEAN_MCELIECE348864_CLEAN_crypto_int16_h 2 | #define PQCLEAN_MCELIECE348864_CLEAN_crypto_int16_h 3 | 4 | #include 5 | 6 | #include "namespace.h" 7 | 8 | typedef int16_t crypto_int16; 9 | 10 | #define crypto_int16_negative_mask CRYPTO_NAMESPACE(crypto_int16_negative_mask) 11 | crypto_int16 crypto_int16_negative_mask(crypto_int16 crypto_int16_x); 12 | #define crypto_int16_nonzero_mask CRYPTO_NAMESPACE(crypto_int16_nonzero_mask) 13 | crypto_int16 crypto_int16_nonzero_mask(crypto_int16 crypto_int16_x); 14 | #define crypto_int16_zero_mask CRYPTO_NAMESPACE(crypto_int16_zero_mask) 15 | crypto_int16 crypto_int16_zero_mask(crypto_int16 crypto_int16_x); 16 | #define crypto_int16_positive_mask CRYPTO_NAMESPACE(crypto_int16_positive_mask) 17 | crypto_int16 crypto_int16_positive_mask(crypto_int16 crypto_int16_x); 18 | #define crypto_int16_unequal_mask CRYPTO_NAMESPACE(crypto_int16_unequal_mask) 19 | crypto_int16 crypto_int16_unequal_mask(crypto_int16 crypto_int16_x, crypto_int16 crypto_int16_y); 20 | #define crypto_int16_equal_mask CRYPTO_NAMESPACE(crypto_int16_equal_mask) 21 | crypto_int16 crypto_int16_equal_mask(crypto_int16 crypto_int16_x, crypto_int16 crypto_int16_y); 22 | #define crypto_int16_smaller_mask CRYPTO_NAMESPACE(crypto_int16_smaller_mask) 23 | crypto_int16 crypto_int16_smaller_mask(crypto_int16 crypto_int16_x, crypto_int16 crypto_int16_y); 24 | #define crypto_int16_min CRYPTO_NAMESPACE(crypto_int16_min) 25 | crypto_int16 crypto_int16_min(crypto_int16 crypto_int16_x, crypto_int16 crypto_int16_y); 26 | #define crypto_int16_max CRYPTO_NAMESPACE(crypto_int16_max) 27 | crypto_int16 crypto_int16_max(crypto_int16 crypto_int16_x, crypto_int16 crypto_int16_y); 28 | #define crypto_int16_minmax CRYPTO_NAMESPACE(crypto_int16_minmax) 29 | void crypto_int16_minmax(crypto_int16 *crypto_int16_a, crypto_int16 *crypto_int16_b); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/crypto_int32.c: -------------------------------------------------------------------------------- 1 | #include "crypto_int32.h" 2 | 3 | crypto_int32 crypto_int32_negative_mask(crypto_int32 crypto_int32_x) { 4 | return crypto_int32_x >> 31; 5 | } 6 | 7 | crypto_int32 crypto_int32_nonzero_mask(crypto_int32 crypto_int32_x) { 8 | return crypto_int32_negative_mask(crypto_int32_x) | crypto_int32_negative_mask(-crypto_int32_x); 9 | } 10 | 11 | crypto_int32 crypto_int32_zero_mask(crypto_int32 crypto_int32_x) { 12 | return ~crypto_int32_nonzero_mask(crypto_int32_x); 13 | } 14 | 15 | crypto_int32 crypto_int32_positive_mask(crypto_int32 crypto_int32_x) { 16 | crypto_int32 crypto_int32_z = -crypto_int32_x; 17 | crypto_int32_z ^= crypto_int32_x & crypto_int32_z; 18 | return crypto_int32_negative_mask(crypto_int32_z); 19 | } 20 | 21 | crypto_int32 crypto_int32_unequal_mask(crypto_int32 crypto_int32_x, crypto_int32 crypto_int32_y) { 22 | crypto_int32 crypto_int32_xy = crypto_int32_x ^ crypto_int32_y; 23 | return crypto_int32_nonzero_mask(crypto_int32_xy); 24 | } 25 | 26 | crypto_int32 crypto_int32_equal_mask(crypto_int32 crypto_int32_x, crypto_int32 crypto_int32_y) { 27 | return ~crypto_int32_unequal_mask(crypto_int32_x, crypto_int32_y); 28 | } 29 | 30 | crypto_int32 crypto_int32_smaller_mask(crypto_int32 crypto_int32_x, crypto_int32 crypto_int32_y) { 31 | crypto_int32 crypto_int32_xy = crypto_int32_x ^ crypto_int32_y; 32 | crypto_int32 crypto_int32_z = crypto_int32_x - crypto_int32_y; 33 | crypto_int32_z ^= crypto_int32_xy & (crypto_int32_z ^ crypto_int32_x); 34 | return crypto_int32_negative_mask(crypto_int32_z); 35 | } 36 | 37 | crypto_int32 crypto_int32_min(crypto_int32 crypto_int32_x, crypto_int32 crypto_int32_y) { 38 | crypto_int32 crypto_int32_xy = crypto_int32_y ^ crypto_int32_x; 39 | crypto_int32 crypto_int32_z = crypto_int32_y - crypto_int32_x; 40 | crypto_int32_z ^= crypto_int32_xy & (crypto_int32_z ^ crypto_int32_y); 41 | crypto_int32_z = crypto_int32_negative_mask(crypto_int32_z); 42 | crypto_int32_z &= crypto_int32_xy; 43 | return crypto_int32_x ^ crypto_int32_z; 44 | } 45 | 46 | crypto_int32 crypto_int32_max(crypto_int32 crypto_int32_x, crypto_int32 crypto_int32_y) { 47 | crypto_int32 crypto_int32_xy = crypto_int32_y ^ crypto_int32_x; 48 | crypto_int32 crypto_int32_z = crypto_int32_y - crypto_int32_x; 49 | crypto_int32_z ^= crypto_int32_xy & (crypto_int32_z ^ crypto_int32_y); 50 | crypto_int32_z = crypto_int32_negative_mask(crypto_int32_z); 51 | crypto_int32_z &= crypto_int32_xy; 52 | return crypto_int32_y ^ crypto_int32_z; 53 | } 54 | 55 | void crypto_int32_minmax(crypto_int32 *crypto_int32_a, crypto_int32 *crypto_int32_b) { 56 | crypto_int32 crypto_int32_x = *crypto_int32_a; 57 | crypto_int32 crypto_int32_y = *crypto_int32_b; 58 | crypto_int32 crypto_int32_xy = crypto_int32_y ^ crypto_int32_x; 59 | crypto_int32 crypto_int32_z = crypto_int32_y - crypto_int32_x; 60 | crypto_int32_z ^= crypto_int32_xy & (crypto_int32_z ^ crypto_int32_y); 61 | crypto_int32_z = crypto_int32_negative_mask(crypto_int32_z); 62 | crypto_int32_z &= crypto_int32_xy; 63 | *crypto_int32_a = crypto_int32_x ^ crypto_int32_z; 64 | *crypto_int32_b = crypto_int32_y ^ crypto_int32_z; 65 | } 66 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/crypto_int32.h: -------------------------------------------------------------------------------- 1 | #ifndef PQCLEAN_MCELIECE348864_CLEAN_crypto_int32_h 2 | #define PQCLEAN_MCELIECE348864_CLEAN_crypto_int32_h 3 | 4 | #include 5 | typedef int32_t crypto_int32; 6 | 7 | #include "namespace.h" 8 | 9 | #define crypto_int32_negative_mask CRYPTO_NAMESPACE(crypto_int32_negative_mask) 10 | crypto_int32 crypto_int32_negative_mask(crypto_int32 crypto_int32_x); 11 | #define crypto_int32_nonzero_mask CRYPTO_NAMESPACE(crypto_int32_nonzero_mask) 12 | crypto_int32 crypto_int32_nonzero_mask(crypto_int32 crypto_int32_x); 13 | #define crypto_int32_zero_mask CRYPTO_NAMESPACE(crypto_int32_zero_mask) 14 | crypto_int32 crypto_int32_zero_mask(crypto_int32 crypto_int32_x); 15 | #define crypto_int32_positive_mask CRYPTO_NAMESPACE(crypto_int32_positive_mask) 16 | crypto_int32 crypto_int32_positive_mask(crypto_int32 crypto_int32_x); 17 | #define crypto_int32_unequal_mask CRYPTO_NAMESPACE(crypto_int32_unequal_mask) 18 | crypto_int32 crypto_int32_unequal_mask(crypto_int32 crypto_int32_x, crypto_int32 crypto_int32_y); 19 | #define crypto_int32_equal_mask CRYPTO_NAMESPACE(crypto_int32_equal_mask) 20 | crypto_int32 crypto_int32_equal_mask(crypto_int32 crypto_int32_x, crypto_int32 crypto_int32_y); 21 | #define crypto_int32_smaller_mask CRYPTO_NAMESPACE(crypto_int32_smaller_mask) 22 | crypto_int32 crypto_int32_smaller_mask(crypto_int32 crypto_int32_x, crypto_int32 crypto_int32_y); 23 | #define crypto_int32_min CRYPTO_NAMESPACE(crypto_int32_min) 24 | crypto_int32 crypto_int32_min(crypto_int32 crypto_int32_x, crypto_int32 crypto_int32_y); 25 | #define crypto_int32_max CRYPTO_NAMESPACE(crypto_int32_max) 26 | crypto_int32 crypto_int32_max(crypto_int32 crypto_int32_x, crypto_int32 crypto_int32_y); 27 | #define crypto_int32_minmax CRYPTO_NAMESPACE(crypto_int32_minmax) 28 | void crypto_int32_minmax(crypto_int32 *crypto_int32_a, crypto_int32 *crypto_int32_b); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/crypto_kem.h: -------------------------------------------------------------------------------- 1 | #ifndef PQCLEAN_MCELIECE348864_CLEAN_CRYPTO_KEM_H 2 | #define PQCLEAN_MCELIECE348864_CLEAN_CRYPTO_KEM_H 3 | 4 | #define crypto_kem_keypair CRYPTO_NAMESPACE(crypto_kem_keypair) 5 | #define crypto_kem_enc CRYPTO_NAMESPACE(crypto_kem_enc) 6 | #define crypto_kem_dec CRYPTO_NAMESPACE(crypto_kem_dec) 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/crypto_uint16.c: -------------------------------------------------------------------------------- 1 | #include "crypto_uint16.h" 2 | 3 | crypto_uint16_signed crypto_uint16_signed_negative_mask(crypto_uint16_signed crypto_uint16_signed_x) { 4 | return crypto_uint16_signed_x >> 15; 5 | } 6 | 7 | crypto_uint16 crypto_uint16_nonzero_mask(crypto_uint16 crypto_uint16_x) { 8 | return crypto_uint16_signed_negative_mask(crypto_uint16_x) | crypto_uint16_signed_negative_mask(-crypto_uint16_x); 9 | } 10 | 11 | crypto_uint16 crypto_uint16_zero_mask(crypto_uint16 crypto_uint16_x) { 12 | return ~crypto_uint16_nonzero_mask(crypto_uint16_x); 13 | } 14 | 15 | crypto_uint16 crypto_uint16_unequal_mask(crypto_uint16 crypto_uint16_x, crypto_uint16 crypto_uint16_y) { 16 | crypto_uint16 crypto_uint16_xy = crypto_uint16_x ^ crypto_uint16_y; 17 | return crypto_uint16_nonzero_mask(crypto_uint16_xy); 18 | } 19 | 20 | crypto_uint16 crypto_uint16_equal_mask(crypto_uint16 crypto_uint16_x, crypto_uint16 crypto_uint16_y) { 21 | return ~crypto_uint16_unequal_mask(crypto_uint16_x, crypto_uint16_y); 22 | } 23 | 24 | crypto_uint16 crypto_uint16_smaller_mask(crypto_uint16 crypto_uint16_x, crypto_uint16 crypto_uint16_y) { 25 | crypto_uint16 crypto_uint16_xy = crypto_uint16_x ^ crypto_uint16_y; 26 | crypto_uint16 crypto_uint16_z = crypto_uint16_x - crypto_uint16_y; 27 | crypto_uint16_z ^= crypto_uint16_xy & (crypto_uint16_z ^ crypto_uint16_x ^ (((crypto_uint16) 1) << 15)); 28 | return crypto_uint16_signed_negative_mask(crypto_uint16_z); 29 | } 30 | 31 | crypto_uint16 crypto_uint16_min(crypto_uint16 crypto_uint16_x, crypto_uint16 crypto_uint16_y) { 32 | crypto_uint16 crypto_uint16_xy = crypto_uint16_y ^ crypto_uint16_x; 33 | crypto_uint16 crypto_uint16_z = crypto_uint16_y - crypto_uint16_x; 34 | crypto_uint16_z ^= crypto_uint16_xy & (crypto_uint16_z ^ crypto_uint16_y ^ (((crypto_uint16) 1) << 15)); 35 | crypto_uint16_z = crypto_uint16_signed_negative_mask(crypto_uint16_z); 36 | crypto_uint16_z &= crypto_uint16_xy; 37 | return crypto_uint16_x ^ crypto_uint16_z; 38 | } 39 | 40 | crypto_uint16 crypto_uint16_max(crypto_uint16 crypto_uint16_x, crypto_uint16 crypto_uint16_y) { 41 | crypto_uint16 crypto_uint16_xy = crypto_uint16_y ^ crypto_uint16_x; 42 | crypto_uint16 crypto_uint16_z = crypto_uint16_y - crypto_uint16_x; 43 | crypto_uint16_z ^= crypto_uint16_xy & (crypto_uint16_z ^ crypto_uint16_y ^ (((crypto_uint16) 1) << 15)); 44 | crypto_uint16_z = crypto_uint16_signed_negative_mask(crypto_uint16_z); 45 | crypto_uint16_z &= crypto_uint16_xy; 46 | return crypto_uint16_y ^ crypto_uint16_z; 47 | } 48 | 49 | void crypto_uint16_minmax(crypto_uint16 *crypto_uint16_a, crypto_uint16 *crypto_uint16_b) { 50 | crypto_uint16 crypto_uint16_x = *crypto_uint16_a; 51 | crypto_uint16 crypto_uint16_y = *crypto_uint16_b; 52 | crypto_uint16 crypto_uint16_xy = crypto_uint16_y ^ crypto_uint16_x; 53 | crypto_uint16 crypto_uint16_z = crypto_uint16_y - crypto_uint16_x; 54 | crypto_uint16_z ^= crypto_uint16_xy & (crypto_uint16_z ^ crypto_uint16_y ^ (((crypto_uint16) 1) << 15)); 55 | crypto_uint16_z = crypto_uint16_signed_negative_mask(crypto_uint16_z); 56 | crypto_uint16_z &= crypto_uint16_xy; 57 | *crypto_uint16_a = crypto_uint16_x ^ crypto_uint16_z; 58 | *crypto_uint16_b = crypto_uint16_y ^ crypto_uint16_z; 59 | } 60 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/crypto_uint16.h: -------------------------------------------------------------------------------- 1 | #ifndef PQCLEAN_MCELIECE348864_CLEAN_crypto_uint16_h 2 | #define PQCLEAN_MCELIECE348864_CLEAN_crypto_uint16_h 3 | 4 | #include 5 | typedef uint16_t crypto_uint16; 6 | 7 | typedef int16_t crypto_uint16_signed; 8 | 9 | #include "namespace.h" 10 | 11 | #define crypto_uint16_signed_negative_mask CRYPTO_NAMESPACE(crypto_uint16_signed_negative_mask) 12 | crypto_uint16_signed crypto_uint16_signed_negative_mask(crypto_uint16_signed crypto_uint16_signed_x); 13 | #define crypto_uint16_nonzero_mask CRYPTO_NAMESPACE(crypto_uint16_nonzero_mask) 14 | crypto_uint16 crypto_uint16_nonzero_mask(crypto_uint16 crypto_uint16_x); 15 | #define crypto_uint16_zero_mask CRYPTO_NAMESPACE(crypto_uint16_zero_mask) 16 | crypto_uint16 crypto_uint16_zero_mask(crypto_uint16 crypto_uint16_x); 17 | #define crypto_uint16_unequal_mask CRYPTO_NAMESPACE(crypto_uint16_unequal_mask) 18 | crypto_uint16 crypto_uint16_unequal_mask(crypto_uint16 crypto_uint16_x, crypto_uint16 crypto_uint16_y); 19 | #define crypto_uint16_equal_mask CRYPTO_NAMESPACE(crypto_uint16_equal_mask) 20 | crypto_uint16 crypto_uint16_equal_mask(crypto_uint16 crypto_uint16_x, crypto_uint16 crypto_uint16_y); 21 | #define crypto_uint16_smaller_mask CRYPTO_NAMESPACE(crypto_uint16_smaller_mask) 22 | crypto_uint16 crypto_uint16_smaller_mask(crypto_uint16 crypto_uint16_x, crypto_uint16 crypto_uint16_y); 23 | #define crypto_uint16_min CRYPTO_NAMESPACE(crypto_uint16_min) 24 | crypto_uint16 crypto_uint16_min(crypto_uint16 crypto_uint16_x, crypto_uint16 crypto_uint16_y); 25 | #define crypto_uint16_max CRYPTO_NAMESPACE(crypto_uint16_max) 26 | crypto_uint16 crypto_uint16_max(crypto_uint16 crypto_uint16_x, crypto_uint16 crypto_uint16_y); 27 | #define crypto_uint16_minmax CRYPTO_NAMESPACE(crypto_uint16_minmax) 28 | void crypto_uint16_minmax(crypto_uint16 *crypto_uint16_a, crypto_uint16 *crypto_uint16_b); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/crypto_uint32.c: -------------------------------------------------------------------------------- 1 | #include "crypto_uint32.h" 2 | 3 | crypto_uint32_signed crypto_uint32_signed_negative_mask(crypto_uint32_signed crypto_uint32_signed_x) { 4 | return crypto_uint32_signed_x >> 31; 5 | } 6 | 7 | crypto_uint32 crypto_uint32_nonzero_mask(crypto_uint32 crypto_uint32_x) { 8 | return crypto_uint32_signed_negative_mask(crypto_uint32_x) | crypto_uint32_signed_negative_mask(-crypto_uint32_x); 9 | } 10 | 11 | crypto_uint32 crypto_uint32_zero_mask(crypto_uint32 crypto_uint32_x) { 12 | return ~crypto_uint32_nonzero_mask(crypto_uint32_x); 13 | } 14 | 15 | crypto_uint32 crypto_uint32_unequal_mask(crypto_uint32 crypto_uint32_x, crypto_uint32 crypto_uint32_y) { 16 | crypto_uint32 crypto_uint32_xy = crypto_uint32_x ^ crypto_uint32_y; 17 | return crypto_uint32_nonzero_mask(crypto_uint32_xy); 18 | } 19 | 20 | crypto_uint32 crypto_uint32_equal_mask(crypto_uint32 crypto_uint32_x, crypto_uint32 crypto_uint32_y) { 21 | return ~crypto_uint32_unequal_mask(crypto_uint32_x, crypto_uint32_y); 22 | } 23 | 24 | crypto_uint32 crypto_uint32_smaller_mask(crypto_uint32 crypto_uint32_x, crypto_uint32 crypto_uint32_y) { 25 | crypto_uint32 crypto_uint32_xy = crypto_uint32_x ^ crypto_uint32_y; 26 | crypto_uint32 crypto_uint32_z = crypto_uint32_x - crypto_uint32_y; 27 | crypto_uint32_z ^= crypto_uint32_xy & (crypto_uint32_z ^ crypto_uint32_x ^ (((crypto_uint32) 1) << 31)); 28 | return crypto_uint32_signed_negative_mask(crypto_uint32_z); 29 | } 30 | 31 | crypto_uint32 crypto_uint32_min(crypto_uint32 crypto_uint32_x, crypto_uint32 crypto_uint32_y) { 32 | crypto_uint32 crypto_uint32_xy = crypto_uint32_y ^ crypto_uint32_x; 33 | crypto_uint32 crypto_uint32_z = crypto_uint32_y - crypto_uint32_x; 34 | crypto_uint32_z ^= crypto_uint32_xy & (crypto_uint32_z ^ crypto_uint32_y ^ (((crypto_uint32) 1) << 31)); 35 | crypto_uint32_z = crypto_uint32_signed_negative_mask(crypto_uint32_z); 36 | crypto_uint32_z &= crypto_uint32_xy; 37 | return crypto_uint32_x ^ crypto_uint32_z; 38 | } 39 | 40 | crypto_uint32 crypto_uint32_max(crypto_uint32 crypto_uint32_x, crypto_uint32 crypto_uint32_y) { 41 | crypto_uint32 crypto_uint32_xy = crypto_uint32_y ^ crypto_uint32_x; 42 | crypto_uint32 crypto_uint32_z = crypto_uint32_y - crypto_uint32_x; 43 | crypto_uint32_z ^= crypto_uint32_xy & (crypto_uint32_z ^ crypto_uint32_y ^ (((crypto_uint32) 1) << 31)); 44 | crypto_uint32_z = crypto_uint32_signed_negative_mask(crypto_uint32_z); 45 | crypto_uint32_z &= crypto_uint32_xy; 46 | return crypto_uint32_y ^ crypto_uint32_z; 47 | } 48 | 49 | void crypto_uint32_minmax(crypto_uint32 *crypto_uint32_a, crypto_uint32 *crypto_uint32_b) { 50 | crypto_uint32 crypto_uint32_x = *crypto_uint32_a; 51 | crypto_uint32 crypto_uint32_y = *crypto_uint32_b; 52 | crypto_uint32 crypto_uint32_xy = crypto_uint32_y ^ crypto_uint32_x; 53 | crypto_uint32 crypto_uint32_z = crypto_uint32_y - crypto_uint32_x; 54 | crypto_uint32_z ^= crypto_uint32_xy & (crypto_uint32_z ^ crypto_uint32_y ^ (((crypto_uint32) 1) << 31)); 55 | crypto_uint32_z = crypto_uint32_signed_negative_mask(crypto_uint32_z); 56 | crypto_uint32_z &= crypto_uint32_xy; 57 | *crypto_uint32_a = crypto_uint32_x ^ crypto_uint32_z; 58 | *crypto_uint32_b = crypto_uint32_y ^ crypto_uint32_z; 59 | } 60 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/crypto_uint32.h: -------------------------------------------------------------------------------- 1 | #ifndef PQCLEAN_MCELIECE348864_CLEAN_crypto_uint32_h 2 | #define PQCLEAN_MCELIECE348864_CLEAN_crypto_uint32_h 3 | 4 | #include 5 | typedef uint32_t crypto_uint32; 6 | 7 | typedef int32_t crypto_uint32_signed; 8 | 9 | #include "namespace.h" 10 | 11 | #define crypto_uint32_signed_negative_mask CRYPTO_NAMESPACE(crypto_uint32_signed_negative_mask) 12 | crypto_uint32_signed crypto_uint32_signed_negative_mask(crypto_uint32_signed crypto_uint32_signed_x); 13 | #define crypto_uint32_nonzero_mask CRYPTO_NAMESPACE(crypto_uint32_nonzero_mask) 14 | crypto_uint32 crypto_uint32_nonzero_mask(crypto_uint32 crypto_uint32_x); 15 | #define crypto_uint32_zero_mask CRYPTO_NAMESPACE(crypto_uint32_zero_mask) 16 | crypto_uint32 crypto_uint32_zero_mask(crypto_uint32 crypto_uint32_x); 17 | #define crypto_uint32_unequal_mask CRYPTO_NAMESPACE(crypto_uint32_unequal_mask) 18 | crypto_uint32 crypto_uint32_unequal_mask(crypto_uint32 crypto_uint32_x, crypto_uint32 crypto_uint32_y); 19 | #define crypto_uint32_equal_mask CRYPTO_NAMESPACE(crypto_uint32_equal_mask) 20 | crypto_uint32 crypto_uint32_equal_mask(crypto_uint32 crypto_uint32_x, crypto_uint32 crypto_uint32_y); 21 | #define crypto_uint32_smaller_mask CRYPTO_NAMESPACE(crypto_uint32_smaller_mask) 22 | crypto_uint32 crypto_uint32_smaller_mask(crypto_uint32 crypto_uint32_x, crypto_uint32 crypto_uint32_y); 23 | #define crypto_uint32_min CRYPTO_NAMESPACE(crypto_uint32_min) 24 | crypto_uint32 crypto_uint32_min(crypto_uint32 crypto_uint32_x, crypto_uint32 crypto_uint32_y); 25 | #define crypto_uint32_max CRYPTO_NAMESPACE(crypto_uint32_max) 26 | crypto_uint32 crypto_uint32_max(crypto_uint32 crypto_uint32_x, crypto_uint32 crypto_uint32_y); 27 | #define crypto_uint32_minmax CRYPTO_NAMESPACE(crypto_uint32_minmax) 28 | void crypto_uint32_minmax(crypto_uint32 *crypto_uint32_a, crypto_uint32 *crypto_uint32_b); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/crypto_uint64.c: -------------------------------------------------------------------------------- 1 | #include "crypto_uint64.h" 2 | 3 | crypto_uint64_signed crypto_uint64_signed_negative_mask(crypto_uint64_signed crypto_uint64_signed_x) { 4 | return crypto_uint64_signed_x >> 63; 5 | } 6 | 7 | crypto_uint64 crypto_uint64_nonzero_mask(crypto_uint64 crypto_uint64_x) { 8 | return crypto_uint64_signed_negative_mask(crypto_uint64_x) | crypto_uint64_signed_negative_mask(-crypto_uint64_x); 9 | } 10 | 11 | crypto_uint64 crypto_uint64_zero_mask(crypto_uint64 crypto_uint64_x) { 12 | return ~crypto_uint64_nonzero_mask(crypto_uint64_x); 13 | } 14 | 15 | crypto_uint64 crypto_uint64_unequal_mask(crypto_uint64 crypto_uint64_x, crypto_uint64 crypto_uint64_y) { 16 | crypto_uint64 crypto_uint64_xy = crypto_uint64_x ^ crypto_uint64_y; 17 | return crypto_uint64_nonzero_mask(crypto_uint64_xy); 18 | } 19 | 20 | crypto_uint64 crypto_uint64_equal_mask(crypto_uint64 crypto_uint64_x, crypto_uint64 crypto_uint64_y) { 21 | return ~crypto_uint64_unequal_mask(crypto_uint64_x, crypto_uint64_y); 22 | } 23 | 24 | crypto_uint64 crypto_uint64_smaller_mask(crypto_uint64 crypto_uint64_x, crypto_uint64 crypto_uint64_y) { 25 | crypto_uint64 crypto_uint64_xy = crypto_uint64_x ^ crypto_uint64_y; 26 | crypto_uint64 crypto_uint64_z = crypto_uint64_x - crypto_uint64_y; 27 | crypto_uint64_z ^= crypto_uint64_xy & (crypto_uint64_z ^ crypto_uint64_x ^ (((crypto_uint64) 1) << 63)); 28 | return crypto_uint64_signed_negative_mask(crypto_uint64_z); 29 | } 30 | 31 | crypto_uint64 crypto_uint64_min(crypto_uint64 crypto_uint64_x, crypto_uint64 crypto_uint64_y) { 32 | crypto_uint64 crypto_uint64_xy = crypto_uint64_y ^ crypto_uint64_x; 33 | crypto_uint64 crypto_uint64_z = crypto_uint64_y - crypto_uint64_x; 34 | crypto_uint64_z ^= crypto_uint64_xy & (crypto_uint64_z ^ crypto_uint64_y ^ (((crypto_uint64) 1) << 63)); 35 | crypto_uint64_z = crypto_uint64_signed_negative_mask(crypto_uint64_z); 36 | crypto_uint64_z &= crypto_uint64_xy; 37 | return crypto_uint64_x ^ crypto_uint64_z; 38 | } 39 | 40 | crypto_uint64 crypto_uint64_max(crypto_uint64 crypto_uint64_x, crypto_uint64 crypto_uint64_y) { 41 | crypto_uint64 crypto_uint64_xy = crypto_uint64_y ^ crypto_uint64_x; 42 | crypto_uint64 crypto_uint64_z = crypto_uint64_y - crypto_uint64_x; 43 | crypto_uint64_z ^= crypto_uint64_xy & (crypto_uint64_z ^ crypto_uint64_y ^ (((crypto_uint64) 1) << 63)); 44 | crypto_uint64_z = crypto_uint64_signed_negative_mask(crypto_uint64_z); 45 | crypto_uint64_z &= crypto_uint64_xy; 46 | return crypto_uint64_y ^ crypto_uint64_z; 47 | } 48 | 49 | void crypto_uint64_minmax(crypto_uint64 *crypto_uint64_a, crypto_uint64 *crypto_uint64_b) { 50 | crypto_uint64 crypto_uint64_x = *crypto_uint64_a; 51 | crypto_uint64 crypto_uint64_y = *crypto_uint64_b; 52 | crypto_uint64 crypto_uint64_xy = crypto_uint64_y ^ crypto_uint64_x; 53 | crypto_uint64 crypto_uint64_z = crypto_uint64_y - crypto_uint64_x; 54 | crypto_uint64_z ^= crypto_uint64_xy & (crypto_uint64_z ^ crypto_uint64_y ^ (((crypto_uint64) 1) << 63)); 55 | crypto_uint64_z = crypto_uint64_signed_negative_mask(crypto_uint64_z); 56 | crypto_uint64_z &= crypto_uint64_xy; 57 | *crypto_uint64_a = crypto_uint64_x ^ crypto_uint64_z; 58 | *crypto_uint64_b = crypto_uint64_y ^ crypto_uint64_z; 59 | } 60 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/crypto_uint64.h: -------------------------------------------------------------------------------- 1 | #ifndef PQCLEAN_MCELIECE348864_CLEAN_crypto_uint64_h 2 | #define PQCLEAN_MCELIECE348864_CLEAN_crypto_uint64_h 3 | 4 | #include 5 | typedef uint64_t crypto_uint64; 6 | 7 | typedef int64_t crypto_uint64_signed; 8 | 9 | #include "namespace.h" 10 | 11 | #define crypto_uint64_signed_negative_mask CRYPTO_NAMESPACE(crypto_uint64_signed_negative_mask) 12 | crypto_uint64_signed crypto_uint64_signed_negative_mask(crypto_uint64_signed crypto_uint64_signed_x); 13 | #define crypto_uint64_nonzero_mask CRYPTO_NAMESPACE(crypto_uint64_nonzero_mask) 14 | crypto_uint64 crypto_uint64_nonzero_mask(crypto_uint64 crypto_uint64_x); 15 | #define crypto_uint64_zero_mask CRYPTO_NAMESPACE(crypto_uint64_zero_mask) 16 | crypto_uint64 crypto_uint64_zero_mask(crypto_uint64 crypto_uint64_x); 17 | #define crypto_uint64_unequal_mask CRYPTO_NAMESPACE(crypto_uint64_unequal_mask) 18 | crypto_uint64 crypto_uint64_unequal_mask(crypto_uint64 crypto_uint64_x, crypto_uint64 crypto_uint64_y); 19 | #define crypto_uint64_equal_mask CRYPTO_NAMESPACE(crypto_uint64_equal_mask) 20 | crypto_uint64 crypto_uint64_equal_mask(crypto_uint64 crypto_uint64_x, crypto_uint64 crypto_uint64_y); 21 | #define crypto_uint64_smaller_mask CRYPTO_NAMESPACE(crypto_uint64_smaller_mask) 22 | crypto_uint64 crypto_uint64_smaller_mask(crypto_uint64 crypto_uint64_x, crypto_uint64 crypto_uint64_y); 23 | #define crypto_uint64_min CRYPTO_NAMESPACE(crypto_uint64_min) 24 | crypto_uint64 crypto_uint64_min(crypto_uint64 crypto_uint64_x, crypto_uint64 crypto_uint64_y); 25 | #define crypto_uint64_max CRYPTO_NAMESPACE(crypto_uint64_max) 26 | crypto_uint64 crypto_uint64_max(crypto_uint64 crypto_uint64_x, crypto_uint64 crypto_uint64_y); 27 | #define crypto_uint64_minmax CRYPTO_NAMESPACE(crypto_uint64_minmax) 28 | void crypto_uint64_minmax(crypto_uint64 *crypto_uint64_a, crypto_uint64 *crypto_uint64_b); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/decrypt.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is for Niederreiter decryption 3 | */ 4 | 5 | #include "decrypt.h" 6 | 7 | #include "benes.h" 8 | #include "bm.h" 9 | #include "gf.h" 10 | #include "params.h" 11 | #include "root.h" 12 | #include "synd.h" 13 | #include "util.h" 14 | 15 | /* Niederreiter decryption with the Berlekamp decoder */ 16 | /* intput: sk, secret key */ 17 | /* c, ciphertext */ 18 | /* output: e, error vector */ 19 | /* return: 0 for success; 1 for failure */ 20 | int decrypt(unsigned char *e, const unsigned char *sk, const unsigned char *c) { 21 | int i, w = 0; 22 | uint16_t check; 23 | 24 | unsigned char r[ SYS_N / 8 ]; 25 | 26 | gf g[ SYS_T + 1 ]; 27 | gf L[ SYS_N ]; 28 | 29 | gf s[ SYS_T * 2 ]; 30 | gf s_cmp[ SYS_T * 2 ]; 31 | gf locator[ SYS_T + 1 ]; 32 | gf images[ SYS_N ]; 33 | 34 | gf t; 35 | 36 | // 37 | 38 | for (i = 0; i < SYND_BYTES; i++) { 39 | r[i] = c[i]; 40 | } 41 | for (i = SYND_BYTES; i < SYS_N / 8; i++) { 42 | r[i] = 0; 43 | } 44 | 45 | for (i = 0; i < SYS_T; i++) { 46 | g[i] = load_gf(sk); 47 | sk += 2; 48 | } 49 | g[ SYS_T ] = 1; 50 | 51 | support_gen(L, sk); 52 | 53 | synd(s, g, L, r); 54 | 55 | bm(locator, s); 56 | 57 | root(images, locator, L); 58 | 59 | // 60 | 61 | for (i = 0; i < SYS_N / 8; i++) { 62 | e[i] = 0; 63 | } 64 | 65 | for (i = 0; i < SYS_N; i++) { 66 | t = gf_iszero(images[i]) & 1; 67 | 68 | e[ i / 8 ] |= t << (i % 8); 69 | w += t; 70 | 71 | } 72 | 73 | synd(s_cmp, g, L, e); 74 | 75 | // 76 | 77 | check = (uint16_t)w; 78 | check ^= SYS_T; 79 | 80 | for (i = 0; i < SYS_T * 2; i++) { 81 | check |= s[i] ^ s_cmp[i]; 82 | } 83 | 84 | check -= 1; 85 | check >>= 15; 86 | 87 | return check ^ 1; 88 | } 89 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/decrypt.h: -------------------------------------------------------------------------------- 1 | #ifndef DECRYPT_H 2 | #define DECRYPT_H 3 | /* 4 | This file is for Nieddereiter decryption 5 | */ 6 | 7 | #include "namespace.h" 8 | 9 | #define decrypt CRYPTO_NAMESPACE(decrypt) 10 | 11 | int decrypt(unsigned char *e, const unsigned char *sk, const unsigned char *c); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/encrypt.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is for Niederreiter encryption 3 | */ 4 | 5 | #include "util.h" 6 | #include "params.h" 7 | #include "randombytes.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "crypto_declassify.h" 14 | #include "crypto_uint16.h" 15 | #include "crypto_uint32.h" 16 | #include "gf.h" 17 | 18 | /* include last because of conflict with unistd.h encrypt function */ 19 | #include "encrypt.h" 20 | 21 | static inline crypto_uint16 uint16_is_smaller_declassify(uint16_t t, uint16_t u) { 22 | crypto_uint16 mask = crypto_uint16_smaller_mask(t, u); 23 | crypto_declassify(&mask, sizeof mask); 24 | return mask; 25 | } 26 | 27 | static inline crypto_uint32 uint32_is_equal_declassify(uint32_t t, uint32_t u) { 28 | crypto_uint32 mask = crypto_uint32_equal_mask(t, u); 29 | crypto_declassify(&mask, sizeof mask); 30 | return mask; 31 | } 32 | 33 | static inline unsigned char same_mask(uint16_t x, uint16_t y) { 34 | uint32_t mask; 35 | 36 | mask = x ^ y; 37 | mask -= 1; 38 | mask >>= 31; 39 | mask = -mask; 40 | 41 | return mask & 0xFF; 42 | } 43 | 44 | /* output: e, an error vector of weight t */ 45 | static void gen_e(unsigned char *e) { 46 | int i, j, eq, count; 47 | 48 | union { 49 | uint16_t nums[ SYS_T * 2 ]; 50 | unsigned char bytes[ SYS_T * 2 * sizeof(uint16_t) ]; 51 | } buf; 52 | 53 | uint16_t ind[ SYS_T ]; 54 | unsigned char mask; 55 | unsigned char val[ SYS_T ]; 56 | 57 | while (1) { 58 | randombytes(buf.bytes, sizeof(buf)); 59 | 60 | for (i = 0; i < SYS_T * 2; i++) { 61 | buf.nums[i] = load_gf(buf.bytes + i * 2); 62 | } 63 | 64 | // moving and counting indices in the correct range 65 | 66 | count = 0; 67 | for (i = 0; i < SYS_T * 2 && count < SYS_T; i++) { 68 | if (uint16_is_smaller_declassify(buf.nums[i], SYS_N)) { 69 | ind[ count++ ] = buf.nums[i]; 70 | } 71 | } 72 | 73 | if (count < SYS_T) { 74 | continue; 75 | } 76 | 77 | // check for repetition 78 | 79 | eq = 0; 80 | 81 | for (i = 1; i < SYS_T; i++) { 82 | for (j = 0; j < i; j++) { 83 | if (uint32_is_equal_declassify(ind[i], ind[j])) { 84 | eq = 1; 85 | } 86 | } 87 | } 88 | 89 | if (eq == 0) { 90 | break; 91 | } 92 | } 93 | 94 | for (j = 0; j < SYS_T; j++) { 95 | val[j] = 1 << (ind[j] & 7); 96 | } 97 | 98 | for (i = 0; i < SYS_N / 8; i++) { 99 | e[i] = 0; 100 | 101 | for (j = 0; j < SYS_T; j++) { 102 | mask = same_mask((uint16_t)i, ind[j] >> 3); 103 | 104 | e[i] |= val[j] & mask; 105 | } 106 | } 107 | } 108 | 109 | /* input: public key pk, error vector e */ 110 | /* output: syndrome s */ 111 | static void syndrome(unsigned char *s, const unsigned char *pk, const unsigned char *e) { 112 | unsigned char b, row[SYS_N / 8]; 113 | const unsigned char *pk_ptr = pk; 114 | 115 | int i, j; 116 | 117 | for (i = 0; i < SYND_BYTES; i++) { 118 | s[i] = 0; 119 | } 120 | 121 | for (i = 0; i < PK_NROWS; i++) { 122 | for (j = 0; j < SYS_N / 8; j++) { 123 | row[j] = 0; 124 | } 125 | 126 | for (j = 0; j < PK_ROW_BYTES; j++) { 127 | row[ SYS_N / 8 - PK_ROW_BYTES + j ] = pk_ptr[j]; 128 | } 129 | 130 | row[i / 8] |= 1 << (i % 8); 131 | 132 | b = 0; 133 | for (j = 0; j < SYS_N / 8; j++) { 134 | b ^= row[j] & e[j]; 135 | } 136 | 137 | b ^= b >> 4; 138 | b ^= b >> 2; 139 | b ^= b >> 1; 140 | b &= 1; 141 | 142 | s[ i / 8 ] |= (b << (i % 8)); 143 | 144 | pk_ptr += PK_ROW_BYTES; 145 | } 146 | } 147 | 148 | void encrypt(unsigned char *s, const unsigned char *pk, unsigned char *e) { 149 | gen_e(e); 150 | 151 | syndrome(s, pk, e); 152 | } 153 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/encrypt.h: -------------------------------------------------------------------------------- 1 | #ifndef ENCRYPT_H 2 | #define ENCRYPT_H 3 | /* 4 | This file is for Niederreiter encryption 5 | */ 6 | 7 | #include "namespace.h" 8 | 9 | #define encrypt CRYPTO_NAMESPACE(encrypt) 10 | 11 | void encrypt(unsigned char *s, const unsigned char *pk, unsigned char *e); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/gf.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is for functions for field arithmetic 3 | */ 4 | 5 | #include "gf.h" 6 | 7 | #include "params.h" 8 | 9 | #include "arena.h" 10 | 11 | gf gf_iszero(gf a) { 12 | uint32_t t = a; 13 | 14 | t -= 1; 15 | t >>= 19; 16 | 17 | return (gf) t; 18 | } 19 | 20 | gf gf_add(gf in0, gf in1) { 21 | return in0 ^ in1; 22 | } 23 | 24 | gf gf_mul(gf in0, gf in1) { 25 | int i; 26 | 27 | uint32_t tmp; 28 | uint32_t t0; 29 | uint32_t t1; 30 | uint32_t t; 31 | 32 | t0 = in0; 33 | t1 = in1; 34 | 35 | tmp = t0 * (t1 & 1); 36 | 37 | for (i = 1; i < GFBITS; i++) { 38 | tmp ^= (t0 * (t1 & (1 << i))); 39 | } 40 | 41 | t = tmp & 0x7FC000; 42 | tmp ^= t >> 9; 43 | tmp ^= t >> 12; 44 | 45 | t = tmp & 0x3000; 46 | tmp ^= t >> 9; 47 | tmp ^= t >> 12; 48 | 49 | return tmp & ((1 << GFBITS) - 1); 50 | } 51 | 52 | /* input: field element in */ 53 | /* return: in^2 */ 54 | static inline gf gf_sq(gf in) { 55 | const uint32_t B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF}; 56 | 57 | uint32_t x = in; 58 | uint32_t t; 59 | 60 | x = (x | (x << 8)) & B[3]; 61 | x = (x | (x << 4)) & B[2]; 62 | x = (x | (x << 2)) & B[1]; 63 | x = (x | (x << 1)) & B[0]; 64 | 65 | t = x & 0x7FC000; 66 | x ^= t >> 9; 67 | x ^= t >> 12; 68 | 69 | t = x & 0x3000; 70 | x ^= t >> 9; 71 | x ^= t >> 12; 72 | 73 | return x & ((1 << GFBITS) - 1); 74 | } 75 | 76 | gf gf_inv(gf in) { 77 | gf tmp_11; 78 | gf tmp_1111; 79 | 80 | gf out = in; 81 | 82 | out = gf_sq(out); 83 | tmp_11 = gf_mul(out, in); // 11 84 | 85 | out = gf_sq(tmp_11); 86 | out = gf_sq(out); 87 | tmp_1111 = gf_mul(out, tmp_11); // 1111 88 | 89 | out = gf_sq(tmp_1111); 90 | out = gf_sq(out); 91 | out = gf_sq(out); 92 | out = gf_sq(out); 93 | out = gf_mul(out, tmp_1111); // 11111111 94 | 95 | out = gf_sq(out); 96 | out = gf_sq(out); 97 | out = gf_mul(out, tmp_11); // 1111111111 98 | 99 | out = gf_sq(out); 100 | out = gf_mul(out, in); // 11111111111 101 | 102 | return gf_sq(out); // 111111111110 103 | } 104 | 105 | /* input: field element den, num */ 106 | /* return: (num/den) */ 107 | gf gf_frac(gf den, gf num) { 108 | return gf_mul(gf_inv(den), num); 109 | } 110 | 111 | /* input: in0, in1 in GF((2^m)^t)*/ 112 | /* output: out = in0*in1 */ 113 | void GF_mul(gf *out, gf *in0, gf *in1) { 114 | int i, j; 115 | 116 | int mark = MarkArena(globalArena); 117 | 118 | //gf prod[ SYS_T * 2 - 1 ]; 119 | gf* prod = PushArray(globalArena,SYS_T * 2 - 1,gf); 120 | 121 | for (i = 0; i < SYS_T * 2 - 1; i++) { 122 | prod[i] = 0; 123 | } 124 | 125 | for (i = 0; i < SYS_T; i++) { 126 | for (j = 0; j < SYS_T; j++) { 127 | prod[i + j] ^= gf_mul(in0[i], in1[j]); 128 | } 129 | } 130 | 131 | // 132 | 133 | for (i = (SYS_T - 1) * 2; i >= SYS_T; i--) { 134 | prod[i - SYS_T + 3] ^= prod[i]; 135 | prod[i - SYS_T + 1] ^= prod[i]; 136 | prod[i - SYS_T + 0] ^= gf_mul(prod[i], (gf) 2); 137 | } 138 | 139 | for (i = 0; i < SYS_T; i++) { 140 | out[i] = prod[i]; 141 | } 142 | 143 | PopArena(globalArena,mark); 144 | } 145 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/gf.h: -------------------------------------------------------------------------------- 1 | #ifndef GF_H 2 | #define GF_H 3 | /* 4 | This file is for functions for field arithmetic 5 | */ 6 | 7 | #include "namespace.h" 8 | 9 | #define gf_add CRYPTO_NAMESPACE(gf_add) 10 | #define gf_frac CRYPTO_NAMESPACE(gf_frac) 11 | #define gf_inv CRYPTO_NAMESPACE(gf_inv) 12 | #define gf_iszero CRYPTO_NAMESPACE(gf_iszero) 13 | #define gf_mul CRYPTO_NAMESPACE(gf_mul) 14 | #define GF_mul CRYPTO_NAMESPACE(GF_mul) 15 | 16 | #include 17 | 18 | typedef uint16_t gf; 19 | 20 | gf gf_iszero(gf a); 21 | gf gf_add(gf in0, gf in1); 22 | gf gf_mul(gf in0, gf in1); 23 | gf gf_frac(gf den, gf num); 24 | gf gf_inv(gf in); 25 | 26 | void GF_mul(gf *out, gf *in0, gf *in1); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/int32_sort.h: -------------------------------------------------------------------------------- 1 | #ifndef PQCLEAN_MCELIECE348864_CLEAN_int32_sort_h 2 | #define PQCLEAN_MCELIECE348864_CLEAN_int32_sort_h 3 | 4 | #include "namespace.h" 5 | 6 | #define int32_sort CRYPTO_NAMESPACE(int32_sort) 7 | 8 | #include 9 | 10 | #define int32_MINMAX(a,b) \ 11 | do { \ 12 | int32_t ab = (b) ^ (a); \ 13 | int32_t c = (b) - (a); \ 14 | c ^= ab & ((c) ^ (b)); \ 15 | c >>= 31; \ 16 | c &= ab; \ 17 | (a) ^= c; \ 18 | (b) ^= c; \ 19 | } while(0) 20 | 21 | static void int32_sort(int32_t *x, long long n) { 22 | long long top, p, q, r, i; 23 | 24 | if (n < 2) { 25 | return; 26 | } 27 | top = 1; 28 | while (top < n - top) { 29 | top += top; 30 | } 31 | 32 | for (p = top; p > 0; p >>= 1) { 33 | for (i = 0; i < n - p; ++i) { 34 | if (!(i & p)) { 35 | int32_MINMAX(x[i], x[i + p]); 36 | } 37 | } 38 | i = 0; 39 | for (q = top; q > p; q >>= 1) { 40 | for (; i < n - q; ++i) { 41 | if (!(i & p)) { 42 | int32_t a = x[i + p]; 43 | for (r = q; r > p; r >>= 1) { 44 | int32_MINMAX(a, x[i + r]); 45 | } 46 | x[i + p] = a; 47 | } 48 | } 49 | } 50 | } 51 | } 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/namespace.h: -------------------------------------------------------------------------------- 1 | #ifndef PQCLEAN_MCELIECE348864_CLEAN_NAMESPACE_H 2 | #define PQCLEAN_MCELIECE348864_CLEAN_NAMESPACE_H 3 | 4 | #define CRYPTO_NAMESPACE(fun) PQCLEAN_MCELIECE348864_CLEAN_ ## fun 5 | #define _CRYPTO_NAMESPACE(fun) _PQCLEAN_MCELIECE348864_CLEAN_ ## fun 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/operations.c: -------------------------------------------------------------------------------- 1 | #include "operations.h" 2 | 3 | #include "controlbits.h" 4 | #include "crypto_hash.h" 5 | #include "decrypt.h" 6 | #include "params.h" 7 | #include "pk_gen.h" 8 | #include "randombytes.h" 9 | #include "sk_gen.h" 10 | #include "util.h" 11 | 12 | #include 13 | #include 14 | 15 | /* Include last because of issues with unistd.h's encrypt definition */ 16 | #include "encrypt.h" 17 | 18 | #include "printf.h" 19 | 20 | int crypto_kem_enc( 21 | unsigned char *c, 22 | unsigned char *key, 23 | const unsigned char *pk 24 | ) { 25 | unsigned char e[ SYS_N / 8 ]; 26 | unsigned char one_ec[ 1 + SYS_N / 8 + SYND_BYTES ] = {1}; 27 | 28 | encrypt(c, pk, e); 29 | 30 | memcpy(one_ec + 1, e, SYS_N / 8); 31 | memcpy(one_ec + 1 + SYS_N / 8, c, SYND_BYTES); 32 | 33 | crypto_hash_32b(key, one_ec, sizeof(one_ec)); 34 | 35 | return 0; 36 | } 37 | 38 | int crypto_kem_dec( 39 | unsigned char *key, 40 | const unsigned char *c, 41 | const unsigned char *sk 42 | ) { 43 | int i; 44 | 45 | unsigned char ret_decrypt = 0; 46 | 47 | uint16_t m; 48 | 49 | unsigned char e[ SYS_N / 8 ]; 50 | unsigned char preimage[ 1 + SYS_N / 8 + SYND_BYTES ]; 51 | unsigned char *x = preimage; 52 | const unsigned char *s = sk + 40 + IRR_BYTES + COND_BYTES; 53 | 54 | // 55 | 56 | ret_decrypt = (unsigned char)decrypt(e, sk + 40, c); 57 | 58 | m = ret_decrypt; 59 | m -= 1; 60 | m >>= 8; 61 | 62 | *x++ = m & 1; 63 | for (i = 0; i < SYS_N / 8; i++) { 64 | *x++ = (~m & s[i]) | (m & e[i]); 65 | } 66 | 67 | for (i = 0; i < SYND_BYTES; i++) { 68 | *x++ = c[i]; 69 | } 70 | 71 | crypto_hash_32b(key, preimage, sizeof(preimage)); 72 | 73 | return 0; 74 | } 75 | 76 | int crypto_kem_keypair 77 | ( 78 | unsigned char *pk, 79 | unsigned char *sk 80 | ) { 81 | int i; 82 | unsigned char seed[ 33 ] = {64}; 83 | unsigned char r[ SYS_N / 8 + (1 << GFBITS)*sizeof(uint32_t) + SYS_T * 2 + 32 ]; 84 | unsigned char *rp, *skp; 85 | 86 | gf f[ SYS_T ]; // element in GF(2^mt) 87 | gf irr[ SYS_T ]; // Goppa polynomial 88 | uint32_t perm[ 1 << GFBITS ]; // random permutation as 32-bit integers 89 | int16_t pi[ 1 << GFBITS ]; // random permutation 90 | 91 | randombytes(seed + 1, 32); 92 | 93 | while (1) { 94 | rp = &r[ sizeof(r) - 32 ]; 95 | skp = sk; 96 | 97 | // expanding and updating the seed 98 | shake(r, sizeof(r), seed, 33); 99 | memcpy(skp, seed + 1, 32); 100 | skp += 32 + 8; 101 | memcpy(seed + 1, &r[ sizeof(r) - 32 ], 32); 102 | 103 | // generating irreducible polynomial 104 | rp -= sizeof(f); 105 | 106 | for (i = 0; i < SYS_T; i++) { 107 | f[i] = load_gf(rp + i * 2); 108 | } 109 | 110 | if (genpoly_gen(irr, f)) { 111 | continue; 112 | } 113 | 114 | for (i = 0; i < SYS_T; i++) { 115 | store_gf(skp + i * 2, irr[i]); 116 | } 117 | 118 | skp += IRR_BYTES; 119 | 120 | // generating permutation 121 | rp -= sizeof(perm); 122 | 123 | for (i = 0; i < (1 << GFBITS); i++) { 124 | perm[i] = load4(rp + i * 4); 125 | } 126 | 127 | if (pk_gen(pk, skp - IRR_BYTES, perm, pi)) { 128 | continue; 129 | } 130 | 131 | controlbitsfrompermutation(skp, pi, GFBITS, 1 << GFBITS); 132 | skp += COND_BYTES; 133 | 134 | // storing the random string s 135 | rp -= SYS_N / 8; 136 | memcpy(skp, rp, SYS_N / 8); 137 | 138 | // storing positions of the 32 pivots 139 | store8(sk + 32, 0xFFFFFFFF); 140 | 141 | break; 142 | } 143 | 144 | return 0; 145 | } 146 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/operations.h: -------------------------------------------------------------------------------- 1 | #ifndef OPERATIONS_H 2 | #define OPERATIONS_H 3 | 4 | #include "namespace.h" 5 | 6 | #include "crypto_kem.h" 7 | 8 | int crypto_kem_enc( 9 | unsigned char *c, 10 | unsigned char *key, 11 | const unsigned char *pk 12 | ); 13 | 14 | int crypto_kem_dec( 15 | unsigned char *key, 16 | const unsigned char *c, 17 | const unsigned char *sk 18 | ); 19 | 20 | int crypto_kem_keypair 21 | ( 22 | unsigned char *pk, 23 | unsigned char *sk 24 | ); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/params.h: -------------------------------------------------------------------------------- 1 | #ifndef PARAMS_H 2 | #define PARAMS_H 3 | 4 | #include "namespace.h" 5 | 6 | #define GFBITS 12 7 | #define SYS_N 3488 8 | #define SYS_T 64 9 | 10 | #define COND_BYTES ((1 << (GFBITS-4))*(2*GFBITS - 1)) 11 | #define IRR_BYTES (SYS_T * 2) 12 | 13 | #define PK_NROWS (SYS_T*GFBITS) 14 | #define PK_NCOLS (SYS_N - PK_NROWS) 15 | #define PK_ROW_BYTES ((PK_NCOLS + 7)/8) 16 | 17 | #define SYND_BYTES ((PK_NROWS + 7)/8) 18 | 19 | #define GFMASK ((1 << GFBITS) - 1) 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/pk_gen.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is for public-key generation 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include "controlbits.h" 10 | #include "benes.h" 11 | #include "crypto_declassify.h" 12 | #include "crypto_uint64.h" 13 | #include "params.h" 14 | #include "pk_gen.h" 15 | #include "root.h" 16 | #include "uint64_sort.h" 17 | #include "util.h" 18 | 19 | #include "versat_accel.h" 20 | #include "unitConfiguration.h" 21 | #include "printf.h" 22 | #include "arena.h" 23 | 24 | static crypto_uint64 uint64_is_equal_declassify(uint64_t t, uint64_t u) { 25 | crypto_uint64 mask = crypto_uint64_equal_mask(t, u); 26 | crypto_declassify(&mask, sizeof mask); 27 | return mask; 28 | } 29 | 30 | static crypto_uint64 uint64_is_zero_declassify(uint64_t t) { 31 | crypto_uint64 mask = crypto_uint64_zero_mask(t); 32 | crypto_declassify(&mask, sizeof mask); 33 | return mask; 34 | } 35 | 36 | /* input: secret key sk */ 37 | /* output: public key pk */ 38 | int pk_gen(unsigned char *pk, unsigned char *sk, const uint32_t *perm, int16_t *pi) { 39 | int i, j, k; 40 | int row, c; 41 | 42 | int mark = MarkArena(globalArena); 43 | 44 | uint64_t buf[ 1 << GFBITS ]; 45 | 46 | unsigned char** mat = PushArray(globalArena,PK_NROWS,unsigned char*); 47 | for(int i = 0; i < PK_NROWS; i++){ 48 | mat[i] = PushArray(globalArena,SYS_N / 8,unsigned char); 49 | } 50 | 51 | unsigned char mask; 52 | unsigned char b; 53 | 54 | gf* g = PushArray(globalArena,SYS_T + 1,gf); 55 | gf* L = PushArray(globalArena,SYS_N,gf); // support 56 | gf* inv = PushArray(globalArena,SYS_N,gf); 57 | 58 | // 59 | 60 | g[ SYS_T ] = 1; 61 | 62 | for (i = 0; i < SYS_T; i++) { 63 | g[i] = load_gf(sk); 64 | sk += 2; 65 | } 66 | 67 | for (i = 0; i < (1 << GFBITS); i++) { 68 | buf[i] = perm[i]; 69 | buf[i] <<= 31; 70 | buf[i] |= i; 71 | } 72 | 73 | uint64_sort(buf, 1 << GFBITS); 74 | 75 | for (i = 1; i < (1 << GFBITS); i++) { 76 | if (uint64_is_equal_declassify(buf[i - 1] >> 31, buf[i] >> 31)) { 77 | PopArena(globalArena,mark); 78 | return -1; 79 | } 80 | } 81 | 82 | for (i = 0; i < (1 << GFBITS); i++) { 83 | pi[i] = buf[i] & GFMASK; 84 | } 85 | for (i = 0; i < SYS_N; i++) { 86 | L[i] = bitrev(pi[i]); 87 | } 88 | 89 | // filling the matrix 90 | 91 | root(inv, g, L); 92 | 93 | for (i = 0; i < SYS_N; i++) { 94 | inv[i] = gf_inv(inv[i]); 95 | } 96 | 97 | for (i = 0; i < PK_NROWS; i++) { 98 | for (j = 0; j < SYS_N / 8; j++) { 99 | mat[i][j] = 0; 100 | } 101 | } 102 | 103 | for (i = 0; i < SYS_T; i++) { 104 | for (j = 0; j < SYS_N; j += 8) { 105 | for (k = 0; k < GFBITS; k++) { 106 | b = (inv[j + 7] >> k) & 1; 107 | b <<= 1; 108 | b |= (inv[j + 6] >> k) & 1; 109 | b <<= 1; 110 | b |= (inv[j + 5] >> k) & 1; 111 | b <<= 1; 112 | b |= (inv[j + 4] >> k) & 1; 113 | b <<= 1; 114 | b |= (inv[j + 3] >> k) & 1; 115 | b <<= 1; 116 | b |= (inv[j + 2] >> k) & 1; 117 | b <<= 1; 118 | b |= (inv[j + 1] >> k) & 1; 119 | b <<= 1; 120 | b |= (inv[j + 0] >> k) & 1; 121 | 122 | mat[ i * GFBITS + k ][ j / 8 ] = b; 123 | } 124 | } 125 | 126 | for (j = 0; j < SYS_N; j++) { 127 | inv[j] = gf_mul(inv[j], L[j]); 128 | } 129 | } 130 | 131 | // gaussian elimination 132 | for (i = 0; i < (PK_NROWS + 7) / 8; i++) { 133 | for (j = 0; j < 8; j++) { 134 | row = i * 8 + j; 135 | 136 | if (row >= PK_NROWS) { 137 | break; 138 | } 139 | 140 | for (k = row + 1; k < PK_NROWS; k++) { 141 | mask = mat[ row ][ i ] ^ mat[ k ][ i ]; 142 | mask >>= j; 143 | mask &= 1; 144 | mask = -mask; 145 | 146 | for (c = 0; c < SYS_N / 8; c++) { 147 | mat[ row ][ c ] ^= mat[ k ][ c ] & mask; 148 | } 149 | } 150 | 151 | if ( uint64_is_zero_declassify((mat[ row ][ i ] >> j) & 1) ) { // return if not systematic 152 | PopArena(globalArena,mark); 153 | return -1; 154 | } 155 | 156 | for (k = 0; k < PK_NROWS; k++) { 157 | if (k != row) { 158 | mask = mat[ k ][ i ] >> j; 159 | mask &= 1; 160 | mask = -mask; 161 | 162 | for (c = 0; c < SYS_N / 8; c++) { 163 | mat[ k ][ c ] ^= mat[ row ][ c ] & mask; 164 | } 165 | } 166 | } 167 | } 168 | } 169 | 170 | for (i = 0; i < PK_NROWS; i++) { 171 | memcpy(pk + i * PK_ROW_BYTES, mat[i] + PK_NROWS / 8, PK_ROW_BYTES); 172 | } 173 | 174 | PopArena(globalArena,mark); 175 | return 0; 176 | } 177 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/pk_gen.h: -------------------------------------------------------------------------------- 1 | #ifndef PK_GEN_H 2 | #define PK_GEN_H 3 | /* 4 | This file is for public-key generation 5 | */ 6 | 7 | #include "namespace.h" 8 | 9 | #define pk_gen CRYPTO_NAMESPACE(pk_gen) 10 | 11 | #include "gf.h" 12 | 13 | int pk_gen(unsigned char *pk, unsigned char *sk, const uint32_t *perm, int16_t *pi); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/root.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is for evaluating a polynomial at one or more field elements 3 | */ 4 | 5 | #include "root.h" 6 | #include "gf.h" 7 | #include "params.h" 8 | 9 | /* input: polynomial f and field element a */ 10 | /* return f(a) */ 11 | gf eval(gf *f, gf a) { 12 | int i; 13 | gf r; 14 | 15 | r = f[ SYS_T ]; 16 | 17 | for (i = SYS_T - 1; i >= 0; i--) { 18 | r = gf_mul(r, a); 19 | r = gf_add(r, f[i]); 20 | } 21 | 22 | return r; 23 | } 24 | 25 | /* input: polynomial f and list of field elements L */ 26 | /* output: out = [ f(a) for a in L ] */ 27 | void root(gf *out, gf *f, gf *L) { 28 | int i; 29 | 30 | for (i = 0; i < SYS_N; i++) { 31 | out[i] = eval(f, L[i]); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/root.h: -------------------------------------------------------------------------------- 1 | #ifndef ROOT_H 2 | #define ROOT_H 3 | /* 4 | This file is for evaluating a polynomial at one or more field elements 5 | */ 6 | 7 | #include "namespace.h" 8 | 9 | #define eval CRYPTO_NAMESPACE(eval) 10 | #define root CRYPTO_NAMESPACE(root) 11 | 12 | #include "gf.h" 13 | 14 | gf eval(gf *f, gf a); 15 | void root(gf *out, gf *f, gf *L); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/sk_gen.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is for secret-key generation 3 | */ 4 | 5 | #include "sk_gen.h" 6 | 7 | #include "controlbits.h" 8 | #include "crypto_declassify.h" 9 | #include "crypto_uint16.h" 10 | #include "gf.h" 11 | #include "params.h" 12 | #include "randombytes.h" 13 | #include "util.h" 14 | 15 | #include "printf.h" 16 | #include "arena.h" 17 | 18 | static inline crypto_uint16 gf_is_zero_declassify(gf t) { 19 | crypto_uint16 mask = crypto_uint16_zero_mask(t); 20 | crypto_declassify(&mask, sizeof mask); 21 | return mask; 22 | } 23 | 24 | // Matrix Allocate 25 | #define MA(Y,X,TYPE) PushBytes(globalArena,sizeof(TYPE) * (X) * (Y)) 26 | // Matrix Index 27 | 28 | #define MI(Y,X,ROWSIZE) ((Y) * (ROWSIZE) + (X)) 29 | //#define MI(Y,X,ROWSIZE) Y ][ X 30 | 31 | /* input: f, element in GF((2^m)^t) */ 32 | /* output: out, minimal polynomial of f */ 33 | /* return: 0 for success and -1 for failure */ 34 | int genpoly_gen(gf *out, gf *f) { 35 | int i, j, k, c; 36 | 37 | int mark = MarkArena(globalArena); 38 | 39 | gf* mat = MA(SYS_T + 1,SYS_T,gf); 40 | //gf mat[ SYS_T + 1 ][ SYS_T ]; 41 | 42 | gf mask, inv, t; 43 | 44 | // fill matrix 45 | mat[MI(0,0,SYS_T)] = 1; 46 | 47 | for (i = 1; i < SYS_T; i++) { 48 | mat[MI(0,i,SYS_T)] = 0; 49 | } 50 | 51 | for (i = 0; i < SYS_T; i++) { 52 | mat[MI(1,i,SYS_T)] = f[i]; 53 | } 54 | 55 | for (j = 2; j <= SYS_T; j++) { 56 | //GF_mul(mat[j], mat[(j - 1)], f); 57 | GF_mul(&mat[j * SYS_T], &mat[(j - 1) * SYS_T], f); 58 | } 59 | 60 | // TODO: Potential place to accelerate using Versat 61 | for (j = 0; j < SYS_T; j++) { 62 | for (k = j + 1; k < SYS_T; k++) { 63 | mask = gf_iszero(mat[MI(j,j,SYS_T)]); 64 | 65 | for (c = j; c < SYS_T + 1; c++) { 66 | mat[MI(c,j,SYS_T)] ^= mat[MI(c,k,SYS_T)] & mask; 67 | } 68 | 69 | } 70 | 71 | if ( gf_is_zero_declassify(mat[MI(j,j,SYS_T)]) ) { // return if not systematic 72 | PopArena(globalArena,mark); 73 | return -1; 74 | } 75 | 76 | inv = gf_inv(mat[MI(j,j,SYS_T)]); 77 | 78 | for (c = j; c < SYS_T + 1; c++) { 79 | mat[MI(c,j,SYS_T) ] = gf_mul(mat[MI(c,j,SYS_T)], inv) ; 80 | } 81 | 82 | for (k = 0; k < SYS_T; k++) { 83 | if (k != j) { 84 | t = mat[MI(j,k,SYS_T)]; 85 | 86 | for (c = j; c < SYS_T + 1; c++) { 87 | mat[MI(c,k,SYS_T)] ^= gf_mul(mat[MI(c,j,SYS_T)], t); 88 | } 89 | } 90 | } 91 | } 92 | 93 | for (i = 0; i < SYS_T; i++) { 94 | out[i] = mat[MI(SYS_T,i,SYS_T)]; 95 | } 96 | 97 | PopArena(globalArena,mark); 98 | 99 | return 0; 100 | } 101 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/sk_gen.h: -------------------------------------------------------------------------------- 1 | #ifndef SK_GEN_H 2 | #define SK_GEN_H 3 | /* 4 | This file is for secret-key generation 5 | */ 6 | 7 | #include "namespace.h" 8 | 9 | #define genpoly_gen CRYPTO_NAMESPACE(genpoly_gen) 10 | 11 | #include "gf.h" 12 | 13 | #include 14 | 15 | int genpoly_gen(gf *out, gf *f); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/synd.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is for syndrome computation 3 | */ 4 | 5 | #include "synd.h" 6 | 7 | #include "params.h" 8 | #include "root.h" 9 | 10 | /* input: Goppa polynomial f, support L, received word r */ 11 | /* output: out, the syndrome of length 2t */ 12 | void synd(gf *out, gf *f, gf *L, const unsigned char *r) { 13 | int i, j; 14 | gf e, e_inv, c; 15 | 16 | for (j = 0; j < 2 * SYS_T; j++) { 17 | out[j] = 0; 18 | } 19 | 20 | for (i = 0; i < SYS_N; i++) { 21 | c = (r[i / 8] >> (i % 8)) & 1; 22 | 23 | e = eval(f, L[i]); 24 | e_inv = gf_inv(gf_mul(e, e)); 25 | 26 | for (j = 0; j < 2 * SYS_T; j++) { 27 | out[j] = gf_add(out[j], gf_mul(e_inv, c)); 28 | e_inv = gf_mul(e_inv, L[i]); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/synd.h: -------------------------------------------------------------------------------- 1 | #ifndef SYND_H 2 | #define SYND_H 3 | /* 4 | This file is for syndrome computation 5 | */ 6 | 7 | #include "namespace.h" 8 | 9 | #define synd CRYPTO_NAMESPACE(synd) 10 | 11 | #include "gf.h" 12 | 13 | void synd(gf *out, gf *f, gf *L, const unsigned char *r); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/transpose.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is for matrix transposition 3 | */ 4 | 5 | #include "transpose.h" 6 | 7 | #include 8 | 9 | /* input: in, a 64x64 matrix over GF(2) */ 10 | /* output: out, transpose of in */ 11 | void transpose_64x64(uint64_t *out, const uint64_t *in) { 12 | int i, j, s, d; 13 | 14 | uint64_t x, y; 15 | uint64_t masks[6][2] = { 16 | {0x5555555555555555, 0xAAAAAAAAAAAAAAAA}, 17 | {0x3333333333333333, 0xCCCCCCCCCCCCCCCC}, 18 | {0x0F0F0F0F0F0F0F0F, 0xF0F0F0F0F0F0F0F0}, 19 | {0x00FF00FF00FF00FF, 0xFF00FF00FF00FF00}, 20 | {0x0000FFFF0000FFFF, 0xFFFF0000FFFF0000}, 21 | {0x00000000FFFFFFFF, 0xFFFFFFFF00000000} 22 | }; 23 | 24 | for (i = 0; i < 64; i++) { 25 | out[i] = in[i]; 26 | } 27 | 28 | for (d = 5; d >= 0; d--) { 29 | s = 1 << d; 30 | 31 | for (i = 0; i < 64; i += s * 2) { 32 | for (j = i; j < i + s; j++) { 33 | x = (out[j] & masks[d][0]) | ((out[j + s] & masks[d][0]) << s); 34 | y = ((out[j] & masks[d][1]) >> s) | (out[j + s] & masks[d][1]); 35 | 36 | out[j + 0] = x; 37 | out[j + s] = y; 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/transpose.h: -------------------------------------------------------------------------------- 1 | #ifndef TRANSPOSE_H 2 | #define TRANSPOSE_H 3 | /* 4 | This file is for matrix transposition 5 | */ 6 | 7 | #include "namespace.h" 8 | 9 | #define transpose_64x64 CRYPTO_NAMESPACE(transpose_64x64) 10 | 11 | #include 12 | 13 | void transpose_64x64(uint64_t *out, const uint64_t *in); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/uint64_sort.h: -------------------------------------------------------------------------------- 1 | #ifndef uint64_sort_h 2 | #define uint64_sort_h 3 | 4 | #include "namespace.h" 5 | 6 | #define int64_sort CRYPTO_NAMESPACE(int64_sort) 7 | 8 | #include 9 | 10 | #define uint64_MINMAX(a,b) \ 11 | do { \ 12 | uint64_t c = (b) - (a); \ 13 | c >>= 63; \ 14 | c = -c; \ 15 | c &= (a) ^ (b); \ 16 | (a) ^= c; \ 17 | (b) ^= c; \ 18 | } while(0) 19 | 20 | static void uint64_sort(uint64_t *x, long long n) { 21 | long long top, p, q, r, i; 22 | 23 | if (n < 2) { 24 | return; 25 | } 26 | top = 1; 27 | while (top < n - top) { 28 | top += top; 29 | } 30 | 31 | for (p = top; p > 0; p >>= 1) { 32 | for (i = 0; i < n - p; ++i) { 33 | if (!(i & p)) { 34 | uint64_MINMAX(x[i], x[i + p]); 35 | } 36 | } 37 | i = 0; 38 | for (q = top; q > p; q >>= 1) { 39 | for (; i < n - q; ++i) { 40 | if (!(i & p)) { 41 | uint64_t a = x[i + p]; 42 | for (r = q; r > p; r >>= 1) { 43 | uint64_MINMAX(a, x[i + r]); 44 | } 45 | x[i + p] = a; 46 | } 47 | } 48 | } 49 | } 50 | } 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/util.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is for loading/storing data in a little-endian fashion 3 | */ 4 | 5 | #include "util.h" 6 | 7 | #include "params.h" 8 | 9 | void store_gf(unsigned char *dest, gf a) { 10 | dest[0] = a & 0xFF; 11 | dest[1] = a >> 8; 12 | } 13 | 14 | uint16_t load_gf(const unsigned char *src) { 15 | uint16_t a; 16 | 17 | a = src[1]; 18 | a <<= 8; 19 | a |= src[0]; 20 | 21 | return a & GFMASK; 22 | } 23 | 24 | uint32_t load4(const unsigned char *in) { 25 | int i; 26 | uint32_t ret = in[3]; 27 | 28 | for (i = 2; i >= 0; i--) { 29 | ret <<= 8; 30 | ret |= in[i]; 31 | } 32 | 33 | return ret; 34 | } 35 | 36 | void store8(unsigned char *out, uint64_t in) { 37 | out[0] = (in >> 0x00) & 0xFF; 38 | out[1] = (in >> 0x08) & 0xFF; 39 | out[2] = (in >> 0x10) & 0xFF; 40 | out[3] = (in >> 0x18) & 0xFF; 41 | out[4] = (in >> 0x20) & 0xFF; 42 | out[5] = (in >> 0x28) & 0xFF; 43 | out[6] = (in >> 0x30) & 0xFF; 44 | out[7] = (in >> 0x38) & 0xFF; 45 | } 46 | 47 | uint64_t load8(const unsigned char *in) { 48 | int i; 49 | uint64_t ret = in[7]; 50 | 51 | for (i = 6; i >= 0; i--) { 52 | ret <<= 8; 53 | ret |= in[i]; 54 | } 55 | 56 | return ret; 57 | } 58 | 59 | gf bitrev(gf a) { 60 | a = ((a & 0x00FF) << 8) | ((a & 0xFF00) >> 8); 61 | a = ((a & 0x0F0F) << 4) | ((a & 0xF0F0) >> 4); 62 | a = ((a & 0x3333) << 2) | ((a & 0xCCCC) >> 2); 63 | a = ((a & 0x5555) << 1) | ((a & 0xAAAA) >> 1); 64 | 65 | return a >> 4; 66 | } 67 | -------------------------------------------------------------------------------- /software/src/crypto/McEliece/util.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_H 2 | #define UTIL_H 3 | /* 4 | This file is for loading/storing data in a little-endian fashion 5 | */ 6 | 7 | #include "namespace.h" 8 | 9 | #define bitrev CRYPTO_NAMESPACE(bitrev) 10 | #define load4 CRYPTO_NAMESPACE(load4) 11 | #define load8 CRYPTO_NAMESPACE(load8) 12 | #define load_gf CRYPTO_NAMESPACE(load_gf) 13 | #define store8 CRYPTO_NAMESPACE(store8) 14 | #define store_gf CRYPTO_NAMESPACE(store_gf) 15 | 16 | #include "gf.h" 17 | #include 18 | 19 | void store_gf(unsigned char *dest, gf a); 20 | uint16_t load_gf(const unsigned char *src); 21 | 22 | uint32_t load4(const unsigned char *in); 23 | 24 | void store8(unsigned char *out, uint64_t in); 25 | uint64_t load8(const unsigned char *in); 26 | 27 | gf bitrev(gf a); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /software/src/crypto/README.md: -------------------------------------------------------------------------------- 1 | Clean implementation of crypto algorithms. 2 | 3 | Taken from opensource projects: 4 | 5 | * sha2 - Public domain, from [PQClean/Common/](https://github.com/PQClean/PQClean/tree/master/common) repository 6 | 7 | * aes - Public domain, from [tiny-aes-c](https://github.com/kokke/tiny-AES-c) repository -------------------------------------------------------------------------------- /software/src/crypto/aes.h: -------------------------------------------------------------------------------- 1 | #ifndef _AES_H_ 2 | #define _AES_H_ 3 | 4 | #include 5 | #include 6 | 7 | // #define the macros below to 1/0 to enable/disable the mode of operation. 8 | // 9 | // CBC enables AES encryption in CBC-mode of operation. 10 | // CTR enables encryption in counter-mode. 11 | // ECB enables the basic ECB 16-byte block algorithm. All can be enabled simultaneously. 12 | 13 | // The #ifndef-guard allows it to be configured before #include'ing or at compile time. 14 | #ifndef CBC 15 | #define CBC 1 16 | #endif 17 | 18 | #ifndef ECB 19 | #define ECB 1 20 | #endif 21 | 22 | #ifndef CTR 23 | #define CTR 1 24 | #endif 25 | 26 | 27 | //#define AES128 1 28 | //#define AES192 1 29 | #define AES256 1 30 | 31 | #define AES_BLOCKLEN 16 // Block length in bytes - AES is 128b block only 32 | 33 | #if defined(AES256) && (AES256 == 1) 34 | #define AES_KEYLEN 32 35 | #define AES_keyExpSize 240 36 | #elif defined(AES192) && (AES192 == 1) 37 | #define AES_KEYLEN 24 38 | #define AES_keyExpSize 208 39 | #else 40 | #define AES_KEYLEN 16 // Key length in bytes 41 | #define AES_keyExpSize 176 42 | #endif 43 | 44 | struct AES_ctx 45 | { 46 | uint8_t RoundKey[AES_keyExpSize]; 47 | #if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1)) 48 | uint8_t Iv[AES_BLOCKLEN]; 49 | #endif 50 | }; 51 | 52 | void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key); 53 | #if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1)) 54 | void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv); 55 | void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv); 56 | #endif 57 | 58 | #if defined(ECB) && (ECB == 1) 59 | // buffer size is exactly AES_BLOCKLEN bytes; 60 | // you need only AES_init_ctx as IV is not used in ECB 61 | // NB: ECB is considered insecure for most uses 62 | void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf); 63 | void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf); 64 | 65 | #endif // #if defined(ECB) && (ECB == !) 66 | 67 | 68 | #if defined(CBC) && (CBC == 1) 69 | // buffer size MUST be mutile of AES_BLOCKLEN; 70 | // Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme 71 | // NOTES: you need to set IV in ctx via AES_init_ctx_iv() or AES_ctx_set_iv() 72 | // no IV should ever be reused with the same key 73 | void AES_CBC_encrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length); 74 | void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length); 75 | 76 | #endif // #if defined(CBC) && (CBC == 1) 77 | 78 | 79 | #if defined(CTR) && (CTR == 1) 80 | 81 | // Same function for encrypting as for decrypting. 82 | // IV is incremented for every block, and used after encryption as XOR-compliment for output 83 | // Suggesting https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme 84 | // NOTES: you need to set IV in ctx with AES_init_ctx_iv() or AES_ctx_set_iv() 85 | // no IV should ever be reused with the same key 86 | void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length); 87 | 88 | #endif // #if defined(CTR) && (CTR == 1) 89 | 90 | 91 | #endif // _AES_H_ 92 | -------------------------------------------------------------------------------- /software/src/crypto/sha2.h: -------------------------------------------------------------------------------- 1 | #ifndef SHA2_H 2 | #define SHA2_H 3 | 4 | #include 5 | #include 6 | 7 | #ifdef PROFILE 8 | #include "profile.h" 9 | #endif 10 | 11 | /* The incremental API allows hashing of individual input blocks; these blocks 12 | must be exactly 64 bytes each. 13 | Use the 'finalize' functions for any remaining bytes (possibly over 64). */ 14 | 15 | #define PQC_SHA256CTX_BYTES 40 16 | /* Structure for the incremental API */ 17 | typedef struct { 18 | uint8_t *ctx; 19 | } sha224ctx; 20 | 21 | /* Structure for the incremental API */ 22 | typedef struct { 23 | uint8_t *ctx; 24 | } sha256ctx; 25 | 26 | #define PQC_SHA512CTX_BYTES 72 27 | /* Structure for the incremental API */ 28 | typedef struct { 29 | uint8_t *ctx; 30 | } sha384ctx; 31 | 32 | /* Structure for the incremental API */ 33 | typedef struct { 34 | uint8_t *ctx; 35 | } sha512ctx; 36 | 37 | /* ====== SHA224 API ==== */ 38 | 39 | /** 40 | * Initialize the incremental hashing API. 41 | * 42 | * Can't be called multiple times. 43 | */ 44 | void sha224_inc_init(sha224ctx *state); 45 | 46 | /** 47 | * Copy the hashing state 48 | */ 49 | void sha224_inc_ctx_clone(sha224ctx *stateout, const sha224ctx *statein); 50 | 51 | /** 52 | * Absorb blocks 53 | */ 54 | void sha224_inc_blocks(sha224ctx *state, const uint8_t *in, size_t inblocks); 55 | 56 | /** 57 | * Finalize and obtain the digest 58 | * 59 | * If applicable, this function will free the memory associated with the sha224ctx. 60 | * 61 | * If not calling this function, call `sha224_inc_ctx_release` 62 | */ 63 | void sha224_inc_finalize(uint8_t *out, sha224ctx *state, const uint8_t *in, size_t inlen); 64 | 65 | /** 66 | * Destroy the state. Make sure to use this, as this API may not always be stack-based. 67 | */ 68 | void sha224_inc_ctx_release(sha224ctx *state); 69 | 70 | /** 71 | * All-in-one sha224 function 72 | */ 73 | void sha224(uint8_t *out, const uint8_t *in, size_t inlen); 74 | 75 | /* ====== SHA256 API ==== */ 76 | 77 | /** 78 | * Initialize the incremental hashing API 79 | */ 80 | void sha256_inc_init(sha256ctx *state); 81 | 82 | /** 83 | * Copy the hashing state 84 | */ 85 | void sha256_inc_ctx_clone(sha256ctx *stateout, const sha256ctx *statein); 86 | 87 | /** 88 | * Absorb blocks 89 | */ 90 | void sha256_inc_blocks(sha256ctx *state, const uint8_t *in, size_t inblocks); 91 | 92 | /** 93 | * Finalize and obtain the digest 94 | * 95 | * If applicable, this function will free the memory associated with the sha256ctx. 96 | */ 97 | void sha256_inc_finalize(uint8_t *out, sha256ctx *state, const uint8_t *in, size_t inlen); 98 | 99 | /** 100 | * Destroy the state. Make sure to use this, as this API may not always be stack-based. 101 | */ 102 | void sha256_inc_ctx_release(sha256ctx *state); 103 | 104 | /** 105 | * All-in-one sha256 function 106 | */ 107 | void sha256(uint8_t *out, const uint8_t *in, size_t inlen); 108 | 109 | /* ====== SHA384 API ==== */ 110 | 111 | /** 112 | * Initialize the incremental hashing API 113 | */ 114 | void sha384_inc_init(sha384ctx *state); 115 | 116 | /** 117 | * Copy the hashing state 118 | */ 119 | void sha384_inc_ctx_clone(sha384ctx *stateout, const sha384ctx *statein); 120 | 121 | /** 122 | * Absorb blocks 123 | */ 124 | void sha384_inc_blocks(sha384ctx *state, const uint8_t *in, size_t inblocks); 125 | 126 | /** 127 | * Finalize and obtain the digest. 128 | * 129 | * If applicable, this function will free the memory associated with the sha384ctx. 130 | */ 131 | void sha384_inc_finalize(uint8_t *out, sha384ctx *state, const uint8_t *in, size_t inlen); 132 | 133 | /** 134 | * Destroy the state. Make sure to use this if not calling finalize, as this API may not always be stack-based. 135 | */ 136 | void sha384_inc_ctx_release(sha384ctx *state); 137 | 138 | /** 139 | * All-in-one sha384 function 140 | */ 141 | void sha384(uint8_t *out, const uint8_t *in, size_t inlen); 142 | 143 | 144 | /* ====== SHA512 API ==== */ 145 | 146 | /** 147 | * Initialize the incremental hashing API 148 | */ 149 | void sha512_inc_init(sha512ctx *state); 150 | 151 | /** 152 | * Copy the hashing state 153 | */ 154 | void sha512_inc_ctx_clone(sha512ctx *stateout, const sha512ctx *statein); 155 | 156 | /** 157 | * Absorb blocks 158 | */ 159 | void sha512_inc_blocks(sha512ctx *state, const uint8_t *in, size_t inblocks); 160 | 161 | /** 162 | * Finalize and obtain the digest 163 | * 164 | * If applicable, this function will free the memory associated with the sha512ctx. 165 | */ 166 | void sha512_inc_finalize(uint8_t *out, sha512ctx *state, const uint8_t *in, size_t inlen); 167 | 168 | /** 169 | * Destroy the state. Make sure to use this if not calling finalize, as this API may not always be stack-based. 170 | */ 171 | void sha512_inc_ctx_release(sha512ctx *state); 172 | 173 | /** 174 | * All-in-one sha512 function 175 | */ 176 | void sha512(uint8_t *out, const uint8_t *in, size_t inlen); 177 | 178 | #endif 179 | 180 | -------------------------------------------------------------------------------- /software/src/io.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "soc.h" 4 | #include "type.h" 5 | 6 | static inline u32 read_u32(u32 address) { return *((volatile u32 *)address); } 7 | 8 | static inline void write_u32(u32 data, u32 address) { 9 | *((volatile u32 *)address) = data; 10 | } 11 | 12 | static inline u16 read_u16(u32 address) { return *((volatile u16 *)address); } 13 | 14 | static inline void write_u16(u16 data, u32 address) { 15 | *((volatile u16 *)address) = data; 16 | } 17 | 18 | static inline u8 read_u8(u32 address) { return *((volatile u8 *)address); } 19 | 20 | static inline void write_u8(u8 data, u32 address) { 21 | *((volatile u8 *)address) = data; 22 | } 23 | 24 | static inline void write_u32_ad(u32 address, u32 data) { 25 | *((volatile u32 *)address) = data; 26 | } 27 | 28 | #define writeReg_u32(name, offset) \ 29 | static inline void name(u32 reg, u32 value) { \ 30 | write_u32(value, reg + offset); \ 31 | } 32 | 33 | #define readReg_u32(name, offset) \ 34 | static inline u32 name(u32 reg) { return read_u32(reg + offset); } 35 | -------------------------------------------------------------------------------- /software/src/iob_soc_opencryptolinux_boot.S: -------------------------------------------------------------------------------- 1 | #include "iob_soc_opencryptolinux_system.h" 2 | #include "iob_soc_opencryptolinux_conf.h" 3 | 4 | .section .init 5 | .global main 6 | 7 | //set stack pointer 8 | lui sp, %hi(1<incrA = 1; 22 | inst->pingPong = 1; 23 | 24 | // B - versat side 25 | inst->iterB = 1; 26 | inst->incrB = 1; 27 | inst->dutyB = 1; 28 | } 29 | 30 | static void ConfigureSimpleVReadShallow(VReadConfig* inst, int numberItems,int* memory){ 31 | inst->enableRead = 1; 32 | 33 | // Memory side 34 | inst->perA = numberItems; 35 | inst->ext_addr = (iptr) memory; 36 | inst->length = numberItems * sizeof(int); 37 | 38 | // B - versat side 39 | inst->perB = numberItems; 40 | } 41 | 42 | static void ConfigureSimpleVRead(VReadConfig* inst, int numberItems,int* memory){ 43 | ConfigureSimpleVReadBare(inst); 44 | ConfigureSimpleVReadShallow(inst,numberItems,memory); 45 | } 46 | #endif 47 | 48 | #ifdef VERSAT_DEFINED_VWrite 49 | static void ConfigureSimpleVWriteBare(VWriteConfig* inst){ 50 | IntSet(inst,0,sizeof(VWriteConfig)); 51 | 52 | // Write side 53 | inst->incrA = 1; 54 | inst->pingPong = 1; 55 | 56 | // Memory side 57 | inst->iterB = 1; 58 | inst->dutyB = 1; 59 | inst->incrB = 1; 60 | } 61 | 62 | static void ConfigureSimpleVWriteShallow(VWriteConfig* inst, int numberItems,int* memory){ 63 | inst->enableWrite = 1; 64 | 65 | // Write side 66 | inst->perA = numberItems; 67 | inst->length = numberItems * sizeof(int); 68 | inst->ext_addr = (iptr) memory; 69 | 70 | // Memory side 71 | inst->perB = numberItems; 72 | } 73 | 74 | static void ConfigureSimpleVWrite(VWriteConfig* inst, int numberItems,int* memory){ 75 | ConfigureSimpleVWriteBare(inst); 76 | ConfigureSimpleVWriteShallow(inst,numberItems,memory); 77 | } 78 | #endif 79 | 80 | #ifdef VERSAT_DEFINED_Mem 81 | static void ConfigureMemoryOutputAndStart(MemConfig* inst, int amountOfData, int start){ 82 | IntSet(inst,0,sizeof(MemConfig)); 83 | 84 | inst->iterA = 1; 85 | inst->perA = amountOfData; 86 | inst->dutyA = amountOfData; 87 | inst->incrA = 1; 88 | inst->startA = start; 89 | } 90 | 91 | static void ConfigureMemoryOutputAndLoad(MemConfig* inst, int amountOfData, int start,MemAddr addr,int* data){ 92 | ConfigureMemoryOutputAndStart(inst,amountOfData,start); 93 | VersatMemoryCopy(addr.addr,data,amountOfData * sizeof(int)); 94 | } 95 | 96 | static void ConfigureMemoryOutput(MemConfig* inst, int amountOfData){ 97 | IntSet(inst,0,sizeof(MemConfig)); 98 | 99 | inst->iterA = 1; 100 | inst->perA = amountOfData; 101 | inst->dutyA = amountOfData; 102 | inst->incrA = 1; 103 | } 104 | 105 | static void ConfigureMemoryReceive(MemConfig* inst, int amountOfData){ 106 | IntSet(inst,0,sizeof(MemConfig)); 107 | 108 | inst->iterA = 1; 109 | inst->perA = amountOfData; 110 | inst->dutyA = amountOfData; 111 | inst->incrA = 1; 112 | inst->in0_wr = 1; 113 | } 114 | #endif 115 | 116 | #endif // INCLUDED_UNIT_CONFIGURATION -------------------------------------------------------------------------------- /software/src/linux/versat.h: -------------------------------------------------------------------------------- 1 | #define VERSAT_ADDRESS 0xf8000000 -------------------------------------------------------------------------------- /software/src/linux/versatCrypto.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | // These buffers are needed to load data into and from the versat accelerator. 7 | // In order to avoid unneaded copies, we expose their interface to the programmer. 8 | // Each time a buffer is returned by a function, that buffer is the next valid buffer 9 | // that the programmer is allowed to use while the previous buffer is invalid. 10 | 11 | typedef struct{ 12 | uint8_t* mem; // Not guaranteed to be byte aligned. It's intended to store bytes 13 | int size; 14 | int maxSize; 15 | } VersatBuffer; 16 | 17 | // Each Begin/End represents a pair of functions that need to be called before calling other functions 18 | // related to the crypto algorithm being used. 19 | // Must call End before calling another Begin, unless calling Begin for the first time. 20 | 21 | // SHA 22 | bool InitVersat(int maxBlockSize); // There is a minimum size of 64 bytes 23 | 24 | // To optimize performance try to send multiple buffers instead of a single buffer even if data fits into a single buffer. 25 | // Versat can process data while CPU is filling the next buffer. 26 | 27 | VersatBuffer* BeginSHA(); // Returns one buffer that can be used to load data. 28 | 29 | // If buffer is not disivible by 64 bytes, prints an error. 30 | VersatBuffer* ProcessSHA(VersatBuffer* input); // Returns a valid buffer that can be used by program to load more data 31 | void EndSHA(VersatBuffer* input,uint8_t digest[32]); // Fills digest 32 | 33 | #define AES_KEY_SIZE 16 34 | #define AES_256_KEY_SIZE 32 35 | #define AES_MAX_KEY_SIZE 32 36 | 37 | #define AES_BLK_SIZE 16 38 | #define AES_256_BLK_SIZE 16 39 | #define AES_MAX_BLK_SIZE 16 40 | 41 | #define AES_IV_SIZE 16 42 | #define AES_256_IV_SIZE 16 43 | #define AES_MAX_IV_SIZE 16 44 | 45 | VersatBuffer* BeginAES_ECB(uint8_t* key,bool is256,bool isDecryption); 46 | VersatBuffer* BeginAES_CBC(uint8_t* key,uint8_t* iv,bool is256,bool isDecryption); 47 | VersatBuffer* BeginAES_CTR(uint8_t* key,uint8_t* initialCounter,bool is256); // Encryption and decryption are the same 48 | 49 | VersatBuffer* ProcessAES(VersatBuffer* input,uint8_t* output,/* out */ int* outputOffset); // Must make sure that output is capable of storing data 50 | 51 | // Returns total size of processed file. Important for decryption. 52 | // For decryption outputOffset returns the actual amount of data removing the padding. 53 | int EndAES(VersatBuffer* input,uint8_t* output,/* out */ int* outputOffset); // Must make sure that output is capable of storing data 54 | -------------------------------------------------------------------------------- /software/src/plic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "io.h" 4 | #include "type.h" 5 | 6 | #define PLIC_PRIORITY_BASE 0x0000 7 | #define PLIC_PENDING_BASE 0x1000 8 | #define PLIC_ENABLE_BASE 0x2000 9 | #define PLIC_THRESHOLD_BASE 0x200000 10 | #define PLIC_CLAIM_BASE 0x200004 11 | 12 | #define PLIC_ENABLE_PER_HART 0x80 13 | #define PLIC_CONTEXT_PER_HART 0x1000 14 | 15 | static void plic_set_priority(u32 plic, u32 gateway, u32 priority) { 16 | write_u32(priority, plic + PLIC_PRIORITY_BASE + gateway * 4); 17 | } 18 | 19 | static void plic_set_enable(u32 plic, u32 target, u32 gateway, u32 enable) { 20 | u32 word = plic + PLIC_ENABLE_BASE + target * PLIC_ENABLE_PER_HART + 21 | (gateway / 32 * 4); 22 | u32 mask = 1 << (gateway % 32); 23 | if (enable) 24 | write_u32(read_u32(word) | mask, word); 25 | else 26 | write_u32(read_u32(word) & ~mask, word); 27 | } 28 | 29 | static void plic_set_threshold(u32 plic, u32 target, u32 threshold) { 30 | write_u32(threshold, 31 | plic + PLIC_THRESHOLD_BASE + target * PLIC_CONTEXT_PER_HART); 32 | } 33 | 34 | static u32 plic_claim(u32 plic, u32 target) { 35 | return read_u32(plic + PLIC_CLAIM_BASE + target * PLIC_CONTEXT_PER_HART); 36 | } 37 | 38 | static void plic_release(u32 plic, u32 target, u32 gateway) { 39 | write_u32(gateway, plic + PLIC_CLAIM_BASE + target * PLIC_CONTEXT_PER_HART); 40 | } -------------------------------------------------------------------------------- /software/src/riscv-interrupts.h: -------------------------------------------------------------------------------- 1 | /* 2 | RISC-V machine interrupts. 3 | SPDX-License-Identifier: Unlicense 4 | 5 | https://five-embeddev.com/ 6 | 7 | */ 8 | 9 | #ifndef RISCV_INTERRUPTS_H 10 | #define RISCV_INTERRUPTS_H 11 | 12 | enum { 13 | RISCV_INT_POS_MSI = 3, 14 | RISCV_INT_POS_MTI = 7, 15 | RISCV_INT_POS_MEI = 11, 16 | RISCV_INT_POS_SSI = 1, 17 | RISCV_INT_POS_STI = 5, 18 | RISCV_INT_POS_SEI = 9, 19 | RISCV_INT_POS_USI = 0, 20 | RISCV_INT_POS_UTI = 4, 21 | RISCV_INT_POS_UEI = 8, 22 | }; 23 | 24 | enum { 25 | RISCV_INT_MASK_MSI = (1UL< 5 | 6 | typedef uint64_t u64; 7 | typedef int64_t s64; 8 | 9 | typedef uint32_t u32; 10 | typedef int32_t s32; 11 | 12 | typedef uint16_t u16; 13 | typedef int16_t s16; 14 | 15 | typedef uint8_t u8; 16 | typedef int8_t s8; 17 | 18 | #define BIT_0 (1 << 0) 19 | #define BIT_1 (1 << 1) 20 | #define BIT_2 (1 << 2) 21 | #define BIT_3 (1 << 3) 22 | #define BIT_4 (1 << 4) 23 | #define BIT_5 (1 << 5) 24 | #define BIT_6 (1 << 6) 25 | #define BIT_7 (1 << 7) 26 | #define BIT_8 (1 << 8) 27 | #define BIT_9 (1 << 9) 28 | #define BIT_10 (1 << 10) 29 | #define BIT_11 (1 << 11) 30 | #define BIT_12 (1 << 12) 31 | #define BIT_13 (1 << 13) 32 | #define BIT_14 (1 << 14) 33 | #define BIT_15 (1 << 15) 34 | #define BIT_16 (1 << 16) 35 | #define BIT_17 (1 << 17) 36 | #define BIT_18 (1 << 18) 37 | #define BIT_19 (1 << 19) 38 | #define BIT_20 (1 << 20) 39 | #define BIT_21 (1 << 21) 40 | #define BIT_22 (1 << 22) 41 | #define BIT_23 (1 << 23) 42 | #define BIT_24 (1 << 24) 43 | #define BIT_25 (1 << 25) 44 | #define BIT_26 (1 << 26) 45 | #define BIT_27 (1 << 27) 46 | #define BIT_28 (1 << 28) 47 | #define BIT_29 (1 << 29) 48 | #define BIT_30 (1 << 30) 49 | #define BIT_31 (1 << 31) 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /software/src/unitConfiguration.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDED_UNIT_CONFIGURATION 2 | #define INCLUDED_UNIT_CONFIGURATION 3 | 4 | #include "printf.h" 5 | 6 | static void IntSet(volatile void* buffer,int value,int byteSize){ 7 | volatile int* asInt = (int*) buffer; 8 | 9 | int nInts = byteSize / 4; 10 | 11 | for(int i = 0; i < nInts; i++){ 12 | asInt[i] = value; 13 | } 14 | } 15 | 16 | #ifdef VERSAT_DEFINED_VRead 17 | static void ConfigureSimpleVReadBare(VReadConfig* inst){ 18 | IntSet(inst,0,sizeof(VReadConfig)); 19 | 20 | // Memory side 21 | inst->incrA = 1; 22 | inst->pingPong = 1; 23 | 24 | // B - versat side 25 | inst->iterB = 1; 26 | inst->incrB = 1; 27 | inst->dutyB = 1; 28 | } 29 | 30 | static void ConfigureSimpleVReadShallow(VReadConfig* inst, int numberItems,int* memory){ 31 | inst->enableRead = 1; 32 | 33 | // Memory side 34 | inst->perA = numberItems; 35 | inst->ext_addr = (iptr) memory; 36 | inst->length = numberItems * sizeof(int); 37 | 38 | // B - versat side 39 | inst->perB = numberItems; 40 | } 41 | 42 | static void ConfigureSimpleVRead(VReadConfig* inst, int numberItems,int* memory){ 43 | ConfigureSimpleVReadBare(inst); 44 | ConfigureSimpleVReadShallow(inst,numberItems,memory); 45 | } 46 | #endif 47 | 48 | #ifdef VERSAT_DEFINED_VWrite 49 | static void ConfigureSimpleVWriteBare(VWriteConfig* inst){ 50 | IntSet(inst,0,sizeof(VWriteConfig)); 51 | 52 | // Write side 53 | inst->incrA = 1; 54 | inst->pingPong = 1; 55 | 56 | // Memory side 57 | inst->iterB = 1; 58 | inst->dutyB = 1; 59 | inst->incrB = 1; 60 | } 61 | 62 | static void ConfigureSimpleVWriteShallow(VWriteConfig* inst, int numberItems,int* memory){ 63 | inst->enableWrite = 1; 64 | 65 | // Write side 66 | inst->perA = numberItems; 67 | inst->length = numberItems * sizeof(int); 68 | inst->ext_addr = (iptr) memory; 69 | 70 | // Memory side 71 | inst->perB = numberItems; 72 | } 73 | 74 | static void ConfigureSimpleVWrite(VWriteConfig* inst, int numberItems,int* memory){ 75 | ConfigureSimpleVWriteBare(inst); 76 | ConfigureSimpleVWriteShallow(inst,numberItems,memory); 77 | } 78 | #endif 79 | 80 | #ifdef VERSAT_DEFINED_Mem 81 | static void ConfigureMemoryOutputAndStart(MemConfig* inst, int amountOfData, int start){ 82 | IntSet(inst,0,sizeof(MemConfig)); 83 | 84 | inst->iterA = 1; 85 | inst->perA = amountOfData; 86 | inst->dutyA = amountOfData; 87 | inst->incrA = 1; 88 | inst->startA = start; 89 | } 90 | 91 | static void ConfigureMemoryOutputAndLoad(MemConfig* inst, int amountOfData, int start,MemAddr addr,int* data){ 92 | ConfigureMemoryOutputAndStart(inst,amountOfData,start); 93 | VersatMemoryCopy(addr.addr,data,amountOfData * sizeof(int)); 94 | } 95 | 96 | static void ConfigureMemoryOutput(MemConfig* inst, int amountOfData){ 97 | IntSet(inst,0,sizeof(MemConfig)); 98 | 99 | inst->iterA = 1; 100 | inst->perA = amountOfData; 101 | inst->dutyA = amountOfData; 102 | inst->incrA = 1; 103 | } 104 | 105 | static void ConfigureMemoryReceive(MemConfig* inst, int amountOfData){ 106 | IntSet(inst,0,sizeof(MemConfig)); 107 | 108 | inst->iterA = 1; 109 | inst->perA = amountOfData; 110 | inst->dutyA = amountOfData; 111 | inst->incrA = 1; 112 | inst->in0_wr = 1; 113 | } 114 | #endif 115 | 116 | #endif // INCLUDED_UNIT_CONFIGURATION -------------------------------------------------------------------------------- /software/src/versat_crypto.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDED_SHA_AES 2 | #define INCLUDED_SHA_AES 3 | 4 | #include "stdint.h" 5 | #include "stddef.h" 6 | 7 | // Must call versat_init before calling any function from here 8 | 9 | // Each Init... function must be called before calling the corresponding Versat* function. 10 | // This function prepares the accelerator for the specific algorithm 11 | // Only need to call init once per multiple calls of Versat*. 12 | // When changing algorithms, need to call the init function again even if called previously. 13 | 14 | void InitVersatSHA(); 15 | void VersatSHA(uint8_t *out, const uint8_t *in, size_t inlen); 16 | 17 | // AES Sizes (bytes) 18 | #define AES_BLK_SIZE (16) 19 | #define AES_KEY_SIZE (32) 20 | 21 | void InitVersatAES(); 22 | void VersatAES(); 23 | void InitAES(); 24 | 25 | // McEliece 26 | int VersatMcEliece(unsigned char *pk,unsigned char *sk); 27 | 28 | // Simple function to convert result into plain text hexadecimal number and vice versa. Useful for testing 29 | char* GetHexadecimal(const char* text,char* buffer,int str_size); 30 | int HexStringToHex(char* buffer,const char* str); 31 | 32 | 33 | 34 | #endif // INCLUDED_SHA_AES -------------------------------------------------------------------------------- /software/src/versat_crypto_tests.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | typedef struct{ 7 | char* str; 8 | int size; 9 | } String; 10 | 11 | #define STRING(str) (String){str,strlen(str)} 12 | 13 | typedef struct { 14 | int initTime; 15 | int tests; 16 | int goodTests; 17 | int versatTimeAccum; 18 | int softwareTimeAccum; 19 | int earlyExit; 20 | } TestState; 21 | 22 | // Functions needed by crypto side but implemented elsewhere 23 | // Somewhere someone must implement such functions so that we can time the algorithms relative performance and receive the testcases by ethernet 24 | int GetTime(); 25 | uint32_t uart_recvfile_ethernet(const char *file_name); 26 | 27 | // Misc Functions used by tests to parse KAT file 28 | char* SearchAndAdvance(char* ptr,String str); 29 | int ParseNumber(char* ptr); 30 | 31 | void InitializeCryptoSide(int versatAddress); 32 | 33 | // Returns zero if pass, nonzero otherwise 34 | int VersatSimpleSHATests(); 35 | int VersatSimpleAESTests(); 36 | 37 | int VersatSHATests(); 38 | int VersatAESTests(); 39 | int VersatMcElieceTests(); 40 | 41 | TestState VersatCommonSHATests(String content); 42 | TestState VersatCommonAESTests(String content); 43 | -------------------------------------------------------------------------------- /software/src/versat_simple_crypto_tests.c: -------------------------------------------------------------------------------- 1 | #include "versat_crypto_tests.h" 2 | 3 | #include "iob-uart16550.h" 4 | #include "printf.h" 5 | 6 | int VersatSimpleSHATests(){ 7 | String content = STRING("LEN = 0\n" 8 | "MSG = 00\n" 9 | "MD = E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855\n" 10 | "LEN = 256\n" 11 | "MSG = 09FC1ACCC230A205E4A208E64A8F204291F581A12756392DA4B8C0CF5EF02B95\n" 12 | "MD = 4F44C1C7FBEBB6F9601829F3897BFD650C56FA07844BE76489076356AC1886A4\n" 13 | "LEN = 512\n" 14 | "MSG = 5A86B737EAEA8EE976A0A24DA63E7ED7EEFAD18A101C1211E2B3650C5187C2A8A650547208251F6D4237E661C7BF4C77F335390394C37FA1A9F9BE836AC28509\n" 15 | "MD = 42E61E174FBB3897D6DD6CEF3DD2802FE67B331953B06114A65C772859DFC1AA\n"); 16 | 17 | TestState result = VersatCommonSHATests(content); 18 | 19 | if(result.earlyExit){ 20 | printf("SHA early exit.\n"); 21 | return 1; 22 | } 23 | 24 | printf("SHA: Passing:%d Total:%d\n",result.goodTests,result.tests); 25 | 26 | return (result.goodTests == result.tests) ? 0 : 1; 27 | } 28 | 29 | int VersatSimpleAESTests(){ 30 | String content = STRING("COUNT = 7\n" 31 | "KEY = 85405C4F0EBBE8F29228F02F1FF184E2F5E7857E8933C2A1D08F61ECB9B68111\n" 32 | "PLAINTEXT = 0F5321DB6FD9D816D88E28183A739D90\n" 33 | "CIPHERTEXT = 2AC6DE212DA0434BEA9CDD7332637307\n" 34 | "COUNT = 8\n" 35 | "KEY = F157285DB00E64C2791668A54493966E3039A19426605056B95B7EAC5106667D\n" 36 | "PLAINTEXT = 3637F71F60A430322980349AD414FCFD\n" 37 | "CIPHERTEXT = CA0A683E759C1312928FE01198F625BB\n" 38 | "COUNT = 9\n" 39 | "KEY = 44A2B5A7453E49F38261904F21AC797641D1BCD8DDEDD293F319449FE63B2948\n" 40 | "PLAINTEXT = C91B8A7B9C511784B6A37F73B290516B\n" 41 | "CIPHERTEXT = 05D51AF0E2B61E2C06CB1E843FEE3172\n"); 42 | 43 | TestState result = VersatCommonAESTests(content); 44 | 45 | if(result.earlyExit){ 46 | printf("AES early exit.\n"); 47 | return 1; 48 | } 49 | 50 | printf("AES: Passing:%d Total:%d\n",result.goodTests,result.tests); 51 | 52 | return (result.goodTests == result.tests) ? 0 : 1; 53 | } 54 | -------------------------------------------------------------------------------- /software/tests/exampleTransfer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Values choosen as random 4 | IV="10987654321098765432109876543210" 5 | SEED="000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008" # Fast seed, only one iteration 6 | 7 | # Values expected to see. Obtained by comparing to a clean implementation (openssl). A small script to generate these values can be found in software/versat/generateTest 8 | EXPECTED_SHA="574874084239233FD9FF32BC890242F07E83357BE1A1237CE1C6BAC8AEE1B54F" 9 | EXPECTED_AES="4355375130f93dab841058524143602f295e1d8e7bdb76feb94134b06ef4\n7a4c3092a3990ae84a96522c0fb22cdf5dd4cba061f1d5372f70034f317f\nb1c36a5a08f28c7c808d6a0f579ebea2e5e17f95cd2780107d35dc9bd9ae\n7c7c1b2ef9b4\n" 10 | 11 | echo -e -n $EXPECTED_AES > aesExpected.txt 12 | 13 | # Alice generates a pair of private and public keys using McEliece. She storages the private key and publishes the public key 14 | echo "Generating private and public keys. Takes around half a minute." 15 | echo "" 16 | ./crypto -P priv.txt -p pub.txt -s $SEED McEliece 17 | 18 | # Bob wants to send this message to Alice encrypted 19 | echo -n "Test string, contains multiple characters in order to test the block stream properly" > in.txt 20 | 21 | echo "Going to encrypt the following content:" 22 | cat in.txt 23 | echo "" 24 | 25 | # He calculates an hash of the content of the message 26 | echo "" 27 | echo "SHA result:" 28 | FirstSHA=$(./crypto -i in.txt SHA256) 29 | echo $FirstSHA 30 | echo "" 31 | echo "Expected:" 32 | echo $EXPECTED_SHA 33 | echo "" 34 | 35 | # Bob uses the public key to generate a session key as well as the chipertext that encapsulates that session key 36 | BobSessionKey=$(./crypto -p pub.txt -o chiperText.txt -s $SEED McEliece) 37 | 38 | # Alice receives the chipertext and decapsulates it to generate the same exact session key that Bob has 39 | AliceSessionKey=$(./crypto -P priv.txt -i chiperText.txt -s $SEED McEliece) 40 | 41 | echo "Session key from encoding side:" 42 | echo $BobSessionKey 43 | echo "" 44 | echo "Session key from decoding side:" 45 | echo $AliceSessionKey 46 | echo "" 47 | 48 | # Bob uses the session key to encrypt the data using AES-256. He uses CBC mode since it's more secure. 49 | ./crypto -i in.txt -o out_256_cbc.txt -k $BobSessionKey -v $IV -e AES-256-CBC 50 | 51 | xxd -p out_256_cbc.txt > aesGot.txt 52 | 53 | echo "AES result:" 54 | cat aesGot.txt 55 | echo "" 56 | echo "Expected:" 57 | echo -e $EXPECTED_AES 58 | echo "" 59 | 60 | # Alice receives the encrypted message and uses her own key to decrypt it 61 | ./crypto -i out_256_cbc.txt -o decryptedMessage.txt -k $AliceSessionKey -v $IV -d AES-256-CBC 62 | 63 | # Alice calculates an hash of the content of the message. Since the hash matches, we know the file was properly encrypted and decrypted 64 | echo "SHA of decrypted result:" 65 | SecondSHA=$(./crypto -i decryptedMessage.txt SHA256) 66 | echo $SecondSHA 67 | echo "" 68 | 69 | test $FirstSHA = $EXPECTED_SHA || { echo "Failed SHA" && echo "Example transfer failed!" > test.log && exit 1 ; } 70 | test $SecondSHA = $EXPECTED_SHA || { echo "Failed SHA" && echo "Example transfer failed!" > test.log && exit 1 ; } 71 | 72 | cmp -s aesGot.txt aesExpected.txt || { echo "Failed AES" && echo "Example transfer failed!" > test.log && exit 1 ; } 73 | 74 | test $BobSessionKey = $AliceSessionKey || { echo "Failed McEliece" && echo "Example transfer failed!" > test.log && exit 1 ; } 75 | echo "Example transfer passed!" | tee test.log 76 | -------------------------------------------------------------------------------- /software/tests/opensslValues.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #set -x 3 | 4 | # Simple script to generate testcases using a well known implementation (openssl). 5 | # This script is the source of the values used when comparing the result of crypto. 6 | 7 | KEY128="01234567890123456789012345678901" # 128 is not being used right now so key is not important 8 | KEY256="732FE849725D6FB098B5CB8BA0D4812AC44F83A63F3A23CA41C0B2B941F84488" # Key generated by McEliece given the seed used in exampleTransfer.sh 9 | IV="10987654321098765432109876543210" # Can be anything but needs to be equal to the one used in exampleTransfer.sh in order to give the same results 10 | 11 | echo -n "Test string, contains multiple characters in order to test the block stream properly" > in.txt 12 | 13 | echo "" 14 | openssl sha256 in.txt 15 | 16 | openssl aes-128-ecb -in in.txt -K $KEY128 -e > out_128_ecb.txt 17 | echo "" 18 | echo "ECB 128" 19 | echo "" 20 | xxd -p out_128_ecb.txt 21 | openssl aes-128-ecb -in out_128_ecb.txt -K $KEY128 -d > out_128_ecb_decrypt.txt 22 | 23 | openssl aes-256-ecb -in in.txt -K $KEY256 -e > out_256_ecb.txt 24 | echo "" 25 | echo "ECB 256" 26 | echo "" 27 | xxd -p out_256_ecb.txt 28 | openssl aes-256-ecb -in out_256_ecb.txt -K $KEY256 -d > out_256_ecb_decrypt.txt 29 | 30 | openssl aes-128-cbc -in in.txt -K $KEY128 -iv $IV -e > out_128_cbc.txt 31 | echo "" 32 | echo "CBC 128" 33 | echo "" 34 | xxd -p out_128_cbc.txt 35 | openssl aes-128-cbc -in out_128_cbc.txt -K $KEY128 -iv $IV -d > out_128_cbc_decrypt.txt 36 | 37 | openssl aes-256-cbc -in in.txt -K $KEY256 -iv $IV -e > out_256_cbc.txt 38 | echo "" 39 | echo "CBC 256" 40 | echo "" 41 | xxd -p out_256_cbc.txt 42 | openssl aes-256-cbc -in out_256_cbc.txt -K $KEY256 -iv $IV -d > out_256_cbc_decrypt.txt 43 | 44 | echo "" 45 | echo "Just to visually check if everything is correct:" 46 | echo "" 47 | 48 | xxd -p -l 25 in.txt 49 | xxd -p -l 25 out_128_ecb_decrypt.txt 50 | xxd -p -l 25 out_256_ecb_decrypt.txt 51 | xxd -p -l 25 out_128_cbc_decrypt.txt 52 | xxd -p -l 25 out_256_cbc_decrypt.txt 53 | 54 | echo "" 55 | 56 | xxd -p -l 25 -seek 25 in.txt 57 | xxd -p -l 25 -seek 25 out_128_ecb_decrypt.txt 58 | xxd -p -l 25 -seek 25 out_256_ecb_decrypt.txt 59 | xxd -p -l 25 -seek 25 out_128_cbc_decrypt.txt 60 | xxd -p -l 25 -seek 25 out_256_cbc_decrypt.txt 61 | 62 | echo "" 63 | 64 | xxd -p -l 25 -seek 50 in.txt 65 | xxd -p -l 25 -seek 50 out_128_ecb_decrypt.txt 66 | xxd -p -l 25 -seek 50 out_256_ecb_decrypt.txt 67 | xxd -p -l 25 -seek 50 out_128_cbc_decrypt.txt 68 | xxd -p -l 25 -seek 50 out_256_cbc_decrypt.txt 69 | 70 | rm *.txt 71 | -------------------------------------------------------------------------------- /software/tests/setupTest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | insmod versat.ko 4 | 5 | # 3000 per block, 12000 total 6 | dd if=/dev/zero bs=750 count=1 2> /dev/null | tr "\000" "\060" > small.txt 7 | dd if=/dev/zero bs=750 count=1 2> /dev/null | tr "\000" "\061" >> small.txt 8 | dd if=/dev/zero bs=750 count=1 2> /dev/null | tr "\000" "\062" >> small.txt 9 | dd if=/dev/zero bs=750 count=1 2> /dev/null | tr "\000" "\063" >> small.txt 10 | 11 | dd if=/dev/zero bs=750 count=1 2> /dev/null | tr "\000" "\064" >> small.txt 12 | dd if=/dev/zero bs=750 count=1 2> /dev/null | tr "\000" "\065" >> small.txt 13 | dd if=/dev/zero bs=750 count=1 2> /dev/null | tr "\000" "\066" >> small.txt 14 | dd if=/dev/zero bs=750 count=1 2> /dev/null | tr "\000" "\067" >> small.txt 15 | 16 | dd if=/dev/zero bs=750 count=1 2> /dev/null | tr "\000" "\067" >> small.txt 17 | dd if=/dev/zero bs=750 count=1 2> /dev/null | tr "\000" "\070" >> small.txt 18 | dd if=/dev/zero bs=750 count=1 2> /dev/null | tr "\000" "\071" >> small.txt 19 | dd if=/dev/zero bs=750 count=1 2> /dev/null | tr "\000" "\072" >> small.txt 20 | 21 | dd if=/dev/zero bs=750 count=1 2> /dev/null | tr "\000" "\073" >> small.txt 22 | dd if=/dev/zero bs=750 count=1 2> /dev/null | tr "\000" "\074" >> small.txt 23 | dd if=/dev/zero bs=750 count=1 2> /dev/null | tr "\000" "\075" >> small.txt 24 | dd if=/dev/zero bs=750 count=1 2> /dev/null | tr "\000" "\076" >> small.txt 25 | 26 | # 12000 * 8 = 96000 27 | cat small.txt > medium.txt 28 | cat small.txt >> medium.txt 29 | cat small.txt >> medium.txt 30 | cat small.txt >> medium.txt 31 | cat small.txt >> medium.txt 32 | cat small.txt >> medium.txt 33 | cat small.txt >> medium.txt 34 | cat small.txt >> medium.txt 35 | 36 | # 96000 * 8 = 768000 37 | cat medium.txt > large.txt 38 | cat medium.txt >> large.txt 39 | cat medium.txt >> large.txt 40 | cat medium.txt >> large.txt 41 | cat medium.txt >> large.txt 42 | cat medium.txt >> large.txt 43 | cat medium.txt >> large.txt 44 | cat medium.txt >> large.txt 45 | 46 | -------------------------------------------------------------------------------- /software/tests/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | KEY="0123456789012345678901234567890123456789012345678901234567890123" 4 | SEED="000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008" # Guarantees one iteration, needed because software only is slow 5 | 6 | # 7 | # Testing correctness 8 | # 9 | 10 | # Buffer is the maximum amount of data that is read and written at a time and that the algorithms are allowed to process at a time 11 | 12 | echo "Testing SHA with different buffer sizes" 13 | ./crypto -b 101 -i large.txt SHA256 | tee sha1_1.txt 14 | ./crypto -b 167 -i large.txt SHA256 | tee sha1_2.txt 15 | ./crypto -b 397 -i large.txt SHA256 | tee sha1_3.txt 16 | ./crypto -i large.txt SHA256 | tee sha1_4.txt 17 | 18 | echo -e "\n" 19 | 20 | echo "Testing AES with different buffer sizes" 21 | ./crypto -b 101 -i large.txt -o AES_101.txt -k $KEY -e AES-256-ECB 22 | ./crypto -b 167 -i large.txt -o AES_167.txt -k $KEY -e AES-256-ECB 23 | ./crypto -b 397 -i large.txt -o AES_397.txt -k $KEY -e AES-256-ECB 24 | ./crypto -i large.txt -o AES_DEFAULT.txt -k $KEY -e AES-256-ECB 25 | 26 | xxd -p AES_101.txt | head -c 64 | tee aes1_1.txt 27 | echo "" 28 | xxd -p AES_167.txt | head -c 64 | tee aes1_2.txt 29 | echo "" 30 | xxd -p AES_397.txt | head -c 64 | tee aes1_3.txt 31 | echo "" 32 | xxd -p AES_DEFAULT.txt | head -c 64 | tee aes1_4.txt 33 | echo "" 34 | 35 | echo -e "\n" 36 | 37 | # 38 | # Testing performance compared to software only 39 | # 40 | 41 | # Testing performance 42 | echo "SHA Versat time" 43 | time ./crypto -i large.txt SHA256 44 | 45 | echo -e "\n" 46 | 47 | echo "SHA Software time" 48 | time ./crypto -t -i large.txt SHA256 49 | 50 | echo -e "\n" 51 | 52 | echo "AES Versat time and result" 53 | time ./crypto -i large.txt -o AES1.txt -k $KEY -e AES-256-ECB 54 | echo "" 55 | xxd -p AES1.txt | head -c 64 | tee aes2_1.txt 56 | echo "" 57 | 58 | echo -e "\n" 59 | 60 | echo "AES software time and result" 61 | time ./crypto -t -i large.txt -o AES2.txt -k $KEY -e AES-256-ECB 62 | echo "" 63 | xxd -p AES2.txt | head -c 64 | tee aes2_2.txt 64 | 65 | echo -e "\n" 66 | 67 | echo "McEliece Versat time and result" 68 | time ./crypto -P priv1.txt -p pub1.txt -s $SEED McEliece 69 | echo "" 70 | xxd -p priv1.txt | head -c 256 | tee mc1_1.txt 71 | echo "" 72 | xxd -p priv1.txt | tail -c 256 | tee mc2_1.txt 73 | echo "" 74 | xxd -p pub1.txt | head -c 256 | tee mc3_1.txt 75 | echo "" 76 | 77 | echo -e "\n" 78 | 79 | echo -e "McEliece software time and result" 80 | time ./crypto -t -P priv2.txt -p pub2.txt -s $SEED McEliece 81 | echo "" 82 | xxd -p priv2.txt | head -c 256 | tee mc1_2.txt 83 | echo "" 84 | xxd -p priv2.txt | tail -c 256 | tee mc2_2.txt 85 | echo "" 86 | xxd -p pub2.txt | head -c 256 | tee mc3_2.txt 87 | echo "" 88 | 89 | echo -e "\n" 90 | 91 | cmp -s sha1_4.txt sha1_1.txt || { echo "Failed SHA" && echo "Test failed!" > test.log && exit 1 ; } 92 | cmp -s sha1_4.txt sha1_2.txt || { echo "Failed SHA" && echo "Test failed!" > test.log && exit 1 ; } 93 | cmp -s sha1_4.txt sha1_3.txt || { echo "Failed SHA" && echo "Test failed!" > test.log && exit 1 ; } 94 | 95 | cmp -s aes1_4.txt aes1_1.txt || { echo "Failed AES" && echo "Test failed!" > test.log && exit 1 ; } 96 | cmp -s aes1_4.txt aes1_2.txt || { echo "Failed AES" && echo "Test failed!" > test.log && exit 1 ; } 97 | cmp -s aes1_4.txt aes1_3.txt || { echo "Failed AES" && echo "Test failed!" > test.log && exit 1 ; } 98 | 99 | cmp -s aes2_1.txt aes2_2.txt || { echo "Failed AES" && echo "Test failed!" > test.log && exit 1 ; } 100 | 101 | cmp -s mc1_1.txt mc1_2.txt || { echo "Failed McEliece" && echo "Test failed!" > test.log && exit 1 ; } 102 | cmp -s mc2_1.txt mc2_2.txt || { echo "Failed McEliece" && echo "Test failed!" > test.log && exit 1 ; } 103 | cmp -s mc3_1.txt mc3_2.txt || { echo "Failed McEliece" && echo "Test failed!" > test.log && exit 1 ; } 104 | 105 | echo "Test passed!" | tee test.log 106 | -------------------------------------------------------------------------------- /software/versat/module/Makefile: -------------------------------------------------------------------------------- 1 | LINUX_DIR := ../../../submodules/OS/submodules/linux-5.15.98 2 | PWD:=$(shell pwd) 3 | obj-m += versat.o 4 | 5 | # In order to compile the versat linux module, need to go to the submodules/OS folder, enter the nix-shell and do "make build-linux-kernel". 6 | # Afterwards, while inside the same nix-shell, cd to this directory and do "make". The result is a module called versat.ko 7 | # This module is included as well in order to simplify the build process, because compiling the module requires building the entire linux-kernel. 8 | 9 | all: module 10 | 11 | module: 12 | $(MAKE) ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- -C $(LINUX_DIR) M=$(PWD) modules 13 | 14 | clean: 15 | find . ! -name 'Makefile' -and ! -name '*.c' -and ! -name '*.h' -and ! -name '*.sh' -and ! -name '*.ko' -type f -exec rm -f {} + 16 | rm -f versat.mod.c 17 | -------------------------------------------------------------------------------- /software/versat/module/versat.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | // Disable all prints 15 | #undef printk 16 | #define printk(...) ((void)0) 17 | 18 | // TODO: Do not know if this module supports concurrent access. I believe it does because no use of shared memory but have not tested it. 19 | 20 | static struct class* class; 21 | static struct device* device; 22 | 23 | static void* last_physical; 24 | 25 | static int major; 26 | 27 | #define DEVICE_NAME "versat" 28 | #define CLASS_NAME "versat_class" 29 | 30 | static int module_release(struct inode* inodep, struct file* filp){ 31 | printk(KERN_INFO "Device closed\n"); 32 | 33 | return 0; 34 | } 35 | 36 | static int module_open(struct inode* inodep, struct file* filp){ 37 | printk(KERN_INFO "Device opened\n"); 38 | 39 | return 0; 40 | } 41 | 42 | static unsigned int numberToNextOrder(int val){ 43 | unsigned int order = 0; 44 | while((1 << order) < val){ 45 | order += 1; 46 | } 47 | return order; 48 | } 49 | 50 | void module_vma_close(struct vm_area_struct *vma){ 51 | int pageSize; 52 | void* virtual_mem; 53 | int order; 54 | uintptr_t data = (uintptr_t) vma->vm_private_data; 55 | 56 | pageSize = 1 << PAGE_SHIFT; 57 | virtual_mem = (void*) (data & ~(pageSize - 1)); 58 | order = (int) (data & (pageSize - 1)); 59 | 60 | printk(KERN_NOTICE "Simple VMA close, virt %lx, Priv: %px Virt: %px Ord: %d\n ",vma->vm_start,vma->vm_private_data,virtual_mem,order); 61 | 62 | free_pages((unsigned long) virtual_mem,order); 63 | } 64 | 65 | static struct vm_operations_struct simple_remap_vm_ops = { 66 | .close = module_vma_close, 67 | }; 68 | 69 | static int module_mmap(struct file* file, struct vm_area_struct* vma){ 70 | unsigned long size; 71 | struct page* page; 72 | void* virtual_mem; 73 | unsigned long pageStart; 74 | int res; 75 | unsigned int order; 76 | int amountPages; 77 | int pageSize; 78 | 79 | size = (unsigned long)(vma->vm_end - vma->vm_start); 80 | pageSize = 1 << PAGE_SHIFT; 81 | printk(KERN_INFO "PageSize %d\n",pageSize); 82 | printk(KERN_INFO "Size %lu",size); 83 | 84 | // Only support page aligned sizes 85 | if((size & (pageSize - 1)) != 0){ 86 | return -EIO; 87 | } 88 | 89 | amountPages = (size + pageSize - 1) / pageSize; 90 | order = numberToNextOrder(amountPages); 91 | 92 | printk(KERN_INFO "Size %lu %d %u\n",size,amountPages,order); 93 | page = alloc_pages(GFP_KERNEL,order); 94 | if(page == NULL){ 95 | printk(KERN_INFO "Error allocating page\n"); 96 | return -EIO; 97 | } 98 | 99 | // TODO: Zero out the pages. 100 | virtual_mem = page_address(page); //alloc_mapable_pages(pages); 101 | printk(KERN_INFO "Virtual Address %px\n",virtual_mem); 102 | 103 | last_physical = (void*) virt_to_phys(virtual_mem); 104 | printk(KERN_INFO "Physical Address %px\n",last_physical); 105 | 106 | if(virtual_mem == NULL){ 107 | pr_err("Failed to allocate memory\n"); 108 | return -EIO; 109 | } 110 | 111 | pageStart = page_to_pfn(page); 112 | printk(KERN_INFO "PageStart %lx\n",pageStart); 113 | 114 | res = remap_pfn_range(vma,vma->vm_start,pageStart,size,vma->vm_page_prot); 115 | printk(KERN_INFO "VM Start %lx\n",vma->vm_start); 116 | if(res != 0){ 117 | pr_err("Failed to remap\n"); 118 | return -EIO; 119 | } 120 | 121 | vma->vm_private_data = (void*) ((uintptr_t)virtual_mem | (uintptr_t)order); // Store order in the lower bits that are guaranteed to be zero because virtual_mem is page aligned 122 | vma->vm_ops = &simple_remap_vm_ops; 123 | 124 | return 0; 125 | } 126 | 127 | long int module_ioctl(struct file *file,unsigned int cmd,unsigned long arg){ 128 | switch(cmd){ 129 | case 0:{ 130 | if(copy_to_user((int*) arg,&last_physical,sizeof(void*))){ 131 | printk(KERN_INFO "Error copying data\n"); 132 | } 133 | } break; 134 | default:{ 135 | printk(KERN_INFO "IOCTL not implemented %d\n",cmd); 136 | } break; 137 | } 138 | 139 | return 0; 140 | } 141 | 142 | static const struct file_operations fops = { 143 | .open = module_open, 144 | .release = module_release, 145 | .mmap = module_mmap, 146 | .unlocked_ioctl = module_ioctl, 147 | .owner = THIS_MODULE, 148 | }; 149 | 150 | int versat_init(void){ 151 | int ret = -1; 152 | 153 | major = register_chrdev(0, DEVICE_NAME, &fops); 154 | if (major < 0){ 155 | printk(KERN_INFO "Failed to register major\n"); 156 | ret = major; 157 | goto failed_major_register; 158 | } 159 | 160 | class = class_create(THIS_MODULE, CLASS_NAME); 161 | if (IS_ERR(class)){ 162 | printk(KERN_INFO "Failed to register class\n"); 163 | ret = PTR_ERR(class); 164 | goto failed_class_create; 165 | } 166 | 167 | device = device_create(class, NULL, MKDEV(major, 0), NULL, DEVICE_NAME); 168 | if (IS_ERR(device)) { 169 | printk(KERN_INFO "Failed to create device\n"); 170 | ret = PTR_ERR(device); 171 | goto failed_device_create; 172 | } 173 | 174 | printk(KERN_INFO "Successfully loaded versat\n"); 175 | 176 | return 0; 177 | 178 | // if device successes and we add more code that can fail 179 | device_destroy(class, MKDEV(major, 0)); 180 | failed_device_create: 181 | class_unregister(class); 182 | class_destroy(class); 183 | failed_class_create: 184 | unregister_chrdev(major, DEVICE_NAME); 185 | failed_major_register: 186 | return ret; 187 | } 188 | 189 | void versat_exit(void) 190 | { 191 | // This portion should reflect the error handling of this_module_init 192 | device_destroy(class, MKDEV(major, 0)); 193 | class_unregister(class); 194 | class_destroy(class); 195 | unregister_chrdev(major, DEVICE_NAME); 196 | 197 | printk(KERN_INFO "versat unregistered!\n"); 198 | } 199 | 200 | module_init(versat_init); 201 | module_exit(versat_exit); 202 | MODULE_LICENSE("GPL"); -------------------------------------------------------------------------------- /software/versat/module/versat.ko: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IObundle/iob-soc-opencryptolinux/dec99d3afd50e8a53ca2a4e01fdc8f3b873746fa/software/versat/module/versat.ko --------------------------------------------------------------------------------