├── .gitignore ├── .gitlab-ci.yml ├── .travis.yml ├── LICENSE ├── Makefile ├── README.md ├── build_bitfiles_fpl_optimized.py ├── build_bitfiles_fpl_paper.py ├── build_bitfiles_meas_journal.py ├── examples └── full_memenc_bd.tcl ├── flow ├── binary_directory_defines.mk ├── default.mk ├── ghdl.mk ├── ghdl │ ├── project.sh │ └── run_simulation.sh ├── global_defines.mk ├── vivado.mk └── vivado │ ├── add_HDL_sources.frag │ ├── add_SIM_sources.frag │ ├── configure_implementation.frag │ ├── configure_simulation.frag │ ├── configure_synthesis.frag │ ├── finalize_recipe.frag │ ├── generate_base_project.frag │ ├── generate_block_design.frag │ ├── package_ip.sh │ ├── package_ip.tcl │ ├── project.sh │ ├── run_implementation.sh │ ├── run_implementation.tcl │ ├── run_simulation.sh │ ├── run_simulation.tcl │ ├── run_synthesis.sh │ └── run_synthesis.tcl ├── hdl ├── crypto │ ├── aes │ │ └── aes128_hs.vhdl │ ├── ascon │ │ ├── LICENSE │ │ ├── README.md │ │ ├── ascon_fast_core.vhdl │ │ └── ascon_mac.vhdl │ ├── keccak │ │ ├── keccak_package.vhd │ │ ├── keccak_parallel.vhd │ │ ├── keccak_parallel_control.vhd │ │ ├── keccak_parallel_datapath.vhd │ │ ├── keccak_register.vhd │ │ ├── keccak_round_counter.vhd │ │ ├── keccak_round_iota.vhd │ │ ├── keccak_round_parallel.vhd │ │ ├── keccak_round_parallel_chi.vhd │ │ ├── keccak_round_parallel_pi.vhd │ │ ├── keccak_round_parallel_rho.vhd │ │ ├── keccak_round_parallel_theta.vhd │ │ └── keccak_state.vhd │ ├── prince.vhd │ ├── qarma.vhd │ ├── xts_tweak_generator.vhd │ └── xts_tweak_mul.vhd ├── framework │ ├── axi │ │ ├── axi_deserialization.vhd │ │ ├── cpu_read_responder.vhd │ │ ├── cpu_request_modifier.vhd │ │ ├── cpu_write_data.vhd │ │ ├── memory_read_fetcher.vhd │ │ ├── memory_read_issuer.vhd │ │ ├── memory_to_cpu_write_responder.vhd │ │ ├── memory_write_data.vhd │ │ └── memory_write_issuer.vhd │ ├── metadata │ │ ├── key_updater.vhd │ │ ├── node_cache.vhd │ │ ├── node_cache_read_fetcher.vhd │ │ ├── node_cache_read_issuer.vhd │ │ ├── node_cache_writer.vhd │ │ ├── nonce_increment.vhd │ │ ├── secure_root.vhd │ │ ├── stream_metadata_injector.vhd │ │ ├── stream_metadata_modifier.vhd │ │ ├── stream_nonce_incrementer.vhd │ │ └── stream_treedata_modifier.vhd │ ├── stream │ │ ├── crypto │ │ │ ├── stream_aes_cbc_decrypt.vhd │ │ │ ├── stream_aes_cbc_encrypt.vhd │ │ │ ├── stream_aes_ecb.vhd │ │ │ ├── stream_aes_xts.vhd │ │ │ ├── stream_ascon.vhd │ │ │ ├── stream_lrae_ascon_prince_delay.vhd │ │ │ ├── stream_lrae_ascon_prince_ecb.vhd │ │ │ ├── stream_prince_cbc_decrypt.vhd │ │ │ ├── stream_prince_cbc_encrypt.vhd │ │ │ ├── stream_prince_ecb.vhd │ │ │ └── stream_prince_xts.vhd │ │ ├── request_modification │ │ │ ├── stream_crypto_request_modifier.vhd │ │ │ ├── stream_request_extractor.vhd │ │ │ ├── stream_request_splitter.vhd │ │ │ └── stream_tree_request_generator.vhd │ │ ├── stream_axi_wrap_burst_cache.vhd │ │ ├── stream_beat_remover.vhd │ │ ├── stream_data_block_filter.vhd │ │ ├── stream_data_filter_to_stdlogic.vhd │ │ ├── stream_data_modifier.vhd │ │ ├── stream_fifo.vhd │ │ ├── stream_multi_register_stage.vhd │ │ ├── stream_ready_synchronizer.vhd │ │ ├── stream_register_stage.vhd │ │ ├── stream_register_stage_fifo.vhd │ │ ├── stream_request_zero_initializer.vhd │ │ └── stream_scheduler.vhd │ └── util │ │ ├── data_dispatcher.vhd │ │ ├── deserialization.vhd │ │ ├── fifo.vhd │ │ ├── pipeline_guard.vhd │ │ ├── prng.vhd │ │ ├── rate_converter.vhd │ │ ├── ready_synchronizer.vhd │ │ ├── register_stage.vhd │ │ ├── register_stage_fifo.vhd │ │ ├── serialization.vhd │ │ ├── valid_dispatcher.vhd │ │ ├── xilinx_TDP_RAM.vhd │ │ └── xilinx_TDP_RAM_synchronized.vhd ├── memsec_config.vhd ├── memsec_functions.vhd ├── memsec_pkg.vhd └── top │ ├── memsec.vhd │ ├── memsec_ascon.vhd │ ├── memsec_block_encryption.vhd │ ├── memsec_meas.vhd │ └── memsec_tectree_ascon.vhd ├── python └── memsec │ └── __init__.py ├── run_tests.py └── tb ├── axi_block_memory ├── .gitignore └── axi_block_memory.xci ├── tb_aes.vhd ├── tb_ascon.vhd ├── tb_prince.vhd ├── tb_qarma.vhd ├── tb_rw_blockram.vhd └── tb_utils_pkg.vhd /.gitignore: -------------------------------------------------------------------------------- 1 | # files from packaging 2 | component.xml 3 | xgui 4 | _*/ 5 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | vivado: 2 | image: vivado:2016.2 3 | tags: 4 | - vivado 5 | before_script: 6 | - apt-get update && apt-get install -y gettext-base 7 | script: 8 | - python3 run_tests.py 9 | 10 | ghdl: 11 | image: nioshd/ghdl:latest 12 | tags: 13 | - gitlabci 14 | script: 15 | - python3 run_tests.py 16 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | 3 | services: 4 | - docker 5 | 6 | script: 7 | - docker run --rm -ti -v "$TRAVIS_BUILD_DIR:/builds" nioshd/ghdl:latest bash -c "cd /builds;./run_tests.py" 8 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | # Copyright (C) 2017-2018 Graz University of Technology, IAIK 4 | # 5 | # This file is part of MEMSEC. 6 | # 7 | # MEMSEC is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # MEMSEC is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with MEMSEC. If not, see . 19 | # 20 | 21 | # determine the source directory and the default script directory based on the Makefile 22 | override FLOW_SOURCE_SCRIPT := $(realpath $(firstword $(MAKEFILE_LIST))) 23 | override FLOW_SOURCE_DIR := $(shell dirname $(FLOW_SOURCE_SCRIPT)) 24 | FLOW_DIR ?= ${FLOW_SOURCE_DIR}/flow 25 | 26 | FLOW_MODULE ?= memsec 27 | 28 | # The used test benches write the result into a file inside the simulation 29 | # directory where 1 means success and 0 means failure. 30 | ${FLOW_MODULE}FLOW_SIM_RESULT_FILE ?= ${${FLOW_MODULE}FLOW_SIM_TOP}_log.txt 31 | ${FLOW_MODULE}FLOW_SIM_RESULT_REGEX ?= ^1 32 | ${FLOW_MODULE}FLOW_SIM_RESULT_RULE ?= file-success 33 | 34 | include $(FLOW_DIR)/binary_directory_defines.mk 35 | ############################################################################### 36 | # memsec IP module 37 | ############################################################################### 38 | FLOW_MODULES += memsec 39 | memsecFLOW_HDL_FILES ?= $(shell find ${FLOW_SOURCE_DIR}/hdl -iname *.vhd | xargs) $(shell find ${FLOW_SOURCE_DIR}/hdl -iname *.vhdl | xargs) 40 | memsecFLOW_SIM_HDL_FILES ?= $(shell find ${FLOW_SOURCE_DIR}/tb -maxdepth 1 -iname *.vhd | xargs) 41 | memsecFLOW_VIVADO_SIM_IP_FILES ?= $(shell find ${FLOW_SOURCE_DIR}/tb -iname *.xci | xargs) 42 | memsecFLOW_HDL_TOP ?= memsec 43 | memsecFLOW_SIM_TOP ?= tb_rw_blockram 44 | 45 | ############################################################################### 46 | # integration module which embeds the memsec IP core into a block design 47 | ############################################################################### 48 | FLOW_MODULES += full_memenc 49 | full_memencFLOW_VIVADO_IP_DEPENDENCIES ?= memsec 50 | full_memencFLOW_VIVADO_IP_REPO_PATHS ?= ${FLOW_SOURCE_DIR} 51 | full_memencFLOW_VIVADO_BD_TCL_FILE ?= ${FLOW_SOURCE_DIR}/examples/full_memenc_bd.tcl 52 | 53 | full_memencFLOW_VIVADO_BD_GENERIC_PCW_FPGA0_PERIPHERAL_FREQMHZ_AT_processing_system7_0 ?= 50 54 | full_memencFLOW_VIVADO_BD_GENERIC_PCW_FCLK0_PERIPHERAL_CLKSRC_AT_processing_system7_0 ?= IO PLL 55 | 56 | default: help 57 | 58 | include $(FLOW_DIR)/global_defines.mk 59 | include $(FLOW_DIR)/ghdl.mk 60 | include $(FLOW_DIR)/vivado.mk 61 | include $(FLOW_DIR)/default.mk 62 | -------------------------------------------------------------------------------- /build_bitfiles_fpl_optimized.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # MEMSEC - Framework for building transparent memory encryption and authentication solutions. 4 | # Copyright (C) 2017 Graz University of Technology, IAIK 5 | # 6 | # This file is part of MEMSEC. 7 | # 8 | # MEMSEC is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # MEMSEC is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with MEMSEC. If not, see . 20 | 21 | import os 22 | import sys 23 | 24 | sys.path.append(os.path.join(os.path.dirname(__file__), "python")) 25 | from memsec import * 26 | 27 | module = 'full_memenc' 28 | res = [] 29 | 30 | # package the IP core 31 | run('memsec',['info', 'vivado_package', 'distclean']) 32 | 33 | # PCW_FPGA0_PERIPHERAL_FREQMHZ, PCW_FCLK0_PERIPHERAL_CLKSRC, ... 34 | globalBdGenerics = {'PCW_FPGA0_PERIPHERAL_FREQMHZ': 100} 35 | 36 | globalOptionDictList = [ {}, 37 | {'FLOW_VIVADO_IMPL_STRATEGY': 'Performance_NetDelay_high'}, 38 | {'FLOW_VIVADO_IMPL_STRATEGY': 'Performance_NetDelay_low'}, 39 | {'FLOW_VIVADO_IMPL_STRATEGY': 'Flow_RunPostRoutePhysOpt'} ] 40 | 41 | # PLAIN 42 | localBdGenerics = merge_dicts(globalBdGenerics, {'CRYPTO_CONFIG': 0,'BLOCKS_PER_SECTOR': 4}) 43 | for optionsDict in globalOptionDictList: 44 | res += buildBitStream(module,localBdGenerics,optionsDict) 45 | 46 | # ASCON 47 | localBdGenerics = merge_dicts(globalBdGenerics, {'CRYPTO_CONFIG': 1, 'DATA_BLOCK_SIZE': 32}) 48 | for optionsDict in globalOptionDictList: 49 | res += buildBitStream(module,localBdGenerics,optionsDict) 50 | 51 | # ASCON TREE 52 | localBdGenerics = merge_dicts(globalBdGenerics, {'CRYPTO_CONFIG': 2,'TREE_ROOTS': 1024, 'TREE_ARITY': 8,'DATA_BLOCK_SIZE': 64}) 53 | for optionsDict in globalOptionDictList: 54 | res += buildBitStream(module,localBdGenerics,optionsDict) 55 | 56 | # Prince ECB 57 | localBdGenerics = merge_dicts(globalBdGenerics, {'CRYPTO_CONFIG': 3,'BLOCKS_PER_SECTOR': 4}) 58 | for optionsDict in globalOptionDictList: 59 | res += buildBitStream(module,localBdGenerics,optionsDict) 60 | 61 | # AES ECB 62 | localBdGenerics = merge_dicts(globalBdGenerics, {'CRYPTO_CONFIG': 4,'BLOCKS_PER_SECTOR': 2}) 63 | for optionsDict in globalOptionDictList: 64 | res += buildBitStream(module,localBdGenerics,optionsDict) 65 | 66 | # Prince CBC 67 | localBdGenerics = merge_dicts(globalBdGenerics, {'CRYPTO_CONFIG': 5,'BLOCKS_PER_SECTOR': 4}) 68 | for optionsDict in globalOptionDictList: 69 | res += buildBitStream(module,localBdGenerics,optionsDict) 70 | 71 | # AES CBC 72 | localBdGenerics = merge_dicts(globalBdGenerics, {'CRYPTO_CONFIG': 6,'BLOCKS_PER_SECTOR': 2}) 73 | for optionsDict in globalOptionDictList: 74 | res += buildBitStream(module,localBdGenerics,optionsDict) 75 | 76 | # Prince XTS 77 | localBdGenerics = merge_dicts(globalBdGenerics, {'CRYPTO_CONFIG': 7,'BLOCKS_PER_SECTOR': 4}) 78 | for optionsDict in globalOptionDictList: 79 | res += buildBitStream(module,localBdGenerics,optionsDict) 80 | 81 | # AES XTS 82 | localBdGenerics = merge_dicts(globalBdGenerics, {'CRYPTO_CONFIG': 8,'BLOCKS_PER_SECTOR': 2}) 83 | for optionsDict in globalOptionDictList: 84 | res += buildBitStream(module,localBdGenerics,optionsDict) 85 | 86 | sys.exit(printSummary(res)) 87 | -------------------------------------------------------------------------------- /build_bitfiles_fpl_paper.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # MEMSEC - Framework for building transparent memory encryption and authentication solutions. 4 | # Copyright (C) 2017 Graz University of Technology, IAIK 5 | # 6 | # This file is part of MEMSEC. 7 | # 8 | # MEMSEC is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # MEMSEC is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with MEMSEC. If not, see . 20 | 21 | import os 22 | import sys 23 | 24 | sys.path.append(os.path.join(os.path.dirname(__file__), "python")) 25 | from memsec import * 26 | 27 | module ='full_memenc' 28 | res = [] 29 | 30 | # package the IP core 31 | run('memsec',['info', 'vivado_package', 'distclean']) 32 | 33 | globalBdGenerics = {'PCW_FPGA0_PERIPHERAL_FREQMHZ': 50} 34 | 35 | # PLAIN 36 | #localBdGenerics = merge_dicts(globalBdGenerics, {'CRYPTO_CONFIG': 0}) 37 | #res += buildBitStream(module,merge_dicts(localBdGenerics, {'BLOCKS_PER_SECTOR': 4})) 38 | 39 | # ASCON 40 | localBdGenerics = merge_dicts(globalBdGenerics, {'CRYPTO_CONFIG': 1}) 41 | res += buildBitStream(module,merge_dicts(localBdGenerics, {'DATA_BLOCK_SIZE': 32})) 42 | 43 | # ASCON TREE 44 | localBdGenerics = merge_dicts(globalBdGenerics, {'CRYPTO_CONFIG': 2}) 45 | res += buildBitStream(module,merge_dicts(localBdGenerics, {'TREE_ROOTS': 1024,'TREE_ARITY': 8,'DATA_BLOCK_SIZE': 64})) 46 | 47 | # Prince ECB 48 | localBdGenerics = merge_dicts(globalBdGenerics, {'CRYPTO_CONFIG': 3}) 49 | res += buildBitStream(module,merge_dicts(localBdGenerics, {'BLOCKS_PER_SECTOR': 4})) 50 | res += buildBitStream(module,merge_dicts(localBdGenerics, {'BLOCKS_PER_SECTOR': 8})) 51 | 52 | # AES ECB 53 | localBdGenerics = merge_dicts(globalBdGenerics, {'CRYPTO_CONFIG': 4}) 54 | res += buildBitStream(module,merge_dicts(localBdGenerics, {'BLOCKS_PER_SECTOR': 2})) 55 | 56 | # Prince CBC 57 | localBdGenerics = merge_dicts(globalBdGenerics, {'CRYPTO_CONFIG': 5}) 58 | res += buildBitStream(module,merge_dicts(localBdGenerics, {'BLOCKS_PER_SECTOR': 1})) 59 | res += buildBitStream(module,merge_dicts(localBdGenerics, {'BLOCKS_PER_SECTOR': 2})) 60 | res += buildBitStream(module,merge_dicts(localBdGenerics, {'BLOCKS_PER_SECTOR': 4})) 61 | res += buildBitStream(module,merge_dicts(localBdGenerics, {'BLOCKS_PER_SECTOR': 8})) 62 | res += buildBitStream(module,merge_dicts(localBdGenerics, {'BLOCKS_PER_SECTOR': 16})) 63 | res += buildBitStream(module,merge_dicts(localBdGenerics, {'BLOCKS_PER_SECTOR': 32})) 64 | 65 | # AES CBC 66 | localBdGenerics = merge_dicts(globalBdGenerics, {'CRYPTO_CONFIG': 6}) 67 | res += buildBitStream(module,merge_dicts(localBdGenerics, {'BLOCKS_PER_SECTOR': 2})) 68 | 69 | # Prince XTS 70 | localBdGenerics = merge_dicts(globalBdGenerics, {'CRYPTO_CONFIG': 7}) 71 | res += buildBitStream(module,merge_dicts(localBdGenerics, {'BLOCKS_PER_SECTOR': 4})) 72 | 73 | # AES XTS 74 | localBdGenerics = merge_dicts(globalBdGenerics, {'CRYPTO_CONFIG': 8}) 75 | res += buildBitStream(module,merge_dicts(localBdGenerics, {'BLOCKS_PER_SECTOR': 2})) 76 | 77 | sys.exit(printSummary(res)) 78 | -------------------------------------------------------------------------------- /build_bitfiles_meas_journal.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # MEMSEC - Framework for building transparent memory encryption and authentication solutions. 4 | # Copyright (C) 2017 Graz University of Technology, IAIK 5 | # 6 | # This file is part of MEMSEC. 7 | # 8 | # MEMSEC is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # MEMSEC is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with MEMSEC. If not, see . 20 | 21 | import os 22 | import sys 23 | 24 | sys.path.append(os.path.join(os.path.dirname(__file__), "python")) 25 | from memsec import * 26 | 27 | module ='full_memenc' 28 | res = [] 29 | 30 | # package the IP core 31 | run('memsec',['info', 'vivado_package', 'distclean']) 32 | 33 | globalBdGenerics = {'PCW_FPGA0_PERIPHERAL_FREQMHZ': 50} 34 | 35 | globalOptionDict = {'FLOW_VIVADO_IMPL_STRATEGY': 'Flow_RunPostRoutePhysOpt'} 36 | 37 | ## MEAS 38 | localBdGenerics = merge_dicts(globalBdGenerics, {'CRYPTO_CONFIG': 9,'TREE_ROOTS': 1024,'DATA_BLOCK_SIZE': 64}) 39 | #res += buildBitStream(module,merge_dicts(localBdGenerics, {'TREE_ARITY': 2}),merge_dicts(globalOptionDict,{'DATASTREAM_DATA_WIDTH': 64})) 40 | #res += buildBitStream(module,merge_dicts(localBdGenerics, {'TREE_ARITY': 4}),merge_dicts(globalOptionDict,{'DATASTREAM_DATA_WIDTH': 64})) 41 | #res += buildBitStream(module,merge_dicts(localBdGenerics, {'TREE_ARITY': 8}),merge_dicts(globalOptionDict,{'DATASTREAM_DATA_WIDTH': 64})) 42 | #res += buildBitStream(module,merge_dicts(localBdGenerics, {'TREE_ARITY': 2}),merge_dicts(globalOptionDict,{'DATASTREAM_DATA_WIDTH': 128})) 43 | #res += buildBitStream(module,merge_dicts(localBdGenerics, {'TREE_ARITY': 4}),merge_dicts(globalOptionDict,{'DATASTREAM_DATA_WIDTH': 128})) 44 | #res += buildBitStream(module,merge_dicts(localBdGenerics, {'TREE_ARITY': 8}),merge_dicts(globalOptionDict,{'DATASTREAM_DATA_WIDTH': 128})) 45 | 46 | ## MEAS ECB 47 | localBdGenerics = merge_dicts(globalBdGenerics, {'CRYPTO_CONFIG': 10,'TREE_ROOTS': 1024,'DATA_BLOCK_SIZE': 64}) 48 | #res += buildBitStream(module,merge_dicts(localBdGenerics, {'TREE_ARITY': 2}),merge_dicts(globalOptionDict,{'DATASTREAM_DATA_WIDTH': 64})) 49 | #res += buildBitStream(module,merge_dicts(localBdGenerics, {'TREE_ARITY': 4}),merge_dicts(globalOptionDict,{'DATASTREAM_DATA_WIDTH': 64})) 50 | #res += buildBitStream(module,merge_dicts(localBdGenerics, {'TREE_ARITY': 8}),merge_dicts(globalOptionDict,{'DATASTREAM_DATA_WIDTH': 64})) 51 | #res += buildBitStream(module,merge_dicts(localBdGenerics, {'TREE_ARITY': 2}),merge_dicts(globalOptionDict,{'DATASTREAM_DATA_WIDTH': 128})) 52 | #res += buildBitStream(module,merge_dicts(localBdGenerics, {'TREE_ARITY': 4}),merge_dicts(globalOptionDict,{'DATASTREAM_DATA_WIDTH': 128})) 53 | #res += buildBitStream(module,merge_dicts(localBdGenerics, {'TREE_ARITY': 8}),merge_dicts(globalOptionDict,{'DATASTREAM_DATA_WIDTH': 128})) 54 | 55 | # build MEAS (ECB) with different optimizer settings 56 | synthOptionDictList = [{'FLOW_VIVADO_SYNTH_STRATEGY': 'Flow_AlternateRoutability'}, 57 | {'FLOW_VIVADO_SYNTH_STRATEGY': 'Flow_PerfOptimized_high'}, 58 | {'FLOW_VIVADO_SYNTH_STRATEGY': 'Flow_PerfThresholdCarry'}] 59 | 60 | implOptionDictList = [{'FLOW_VIVADO_IMPL_STRATEGY': 'Flow_RunPostRoutePhysOpt'}] 61 | 62 | localBdGenerics = merge_dicts(globalBdGenerics, {'TREE_ARITY': 4,'TREE_ROOTS': 1024,'DATA_BLOCK_SIZE': 64}) 63 | for synthOptionsDict in synthOptionDictList: 64 | for implOptionsDict in implOptionDictList: 65 | optionsDict = merge_dicts(implOptionsDict,synthOptionsDict,{'DATASTREAM_DATA_WIDTH': 128}) 66 | res += buildBitStream(module,merge_dicts(localBdGenerics, {'CRYPTO_CONFIG': 9}),optionsDict) 67 | res += buildBitStream(module,merge_dicts(localBdGenerics, {'CRYPTO_CONFIG': 10}),optionsDict) 68 | 69 | sys.exit(printSummary(res)) 70 | -------------------------------------------------------------------------------- /flow/ghdl.mk: -------------------------------------------------------------------------------- 1 | # 2 | # MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | # Copyright (C) 2017-2018 Graz University of Technology, IAIK 4 | # 5 | # This file is part of MEMSEC. 6 | # 7 | # MEMSEC is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # MEMSEC is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with MEMSEC. If not, see . 19 | # 20 | 21 | # check if ghdl is available 22 | FLOW_GHDL_BINARY ?= $(shell which ghdl) 23 | ifneq (${FLOW_GHDL_BINARY},) 24 | FLOW_BACKEND ?= ghdl 25 | FLOW_BACKENDS += ghdl 26 | 27 | ifeq (${FLOW_BACKEND},ghdl) 28 | ############################################################################### 29 | # Backend specific variables 30 | ############################################################################### 31 | FLOW_GTKWAVE_BINARY ?= $(shell which gtkwave) 32 | FLOW_LCOV_BINARY ?= $(shell which lcov) 33 | FLOW_GENHTML_BINARY ?= $(shell which genhtml) 34 | 35 | FLOW_GHDL_GCC ?= $(shell ! ${FLOW_GHDL_BINARY} -v | grep -q "GCC back-end code generator"; echo $$?) 36 | 37 | # Additional flags that are passed to ghdl during project generation 38 | # (i.e., in the analysis and elaboration phase). 39 | ifeq (${FLOW_GHDL_GCC},1) 40 | FLOW_GHDL_CFLAGS += -Wc,-ftest-coverage -Wc,-fprofile-arcs -Wl,--coverage 41 | endif 42 | 43 | # Additional flags that are passed to ghdl during simulation 44 | # (i.e., in the run phase). 45 | # FLOW_GHDL_RFLAGS ?= 46 | 47 | # define which variables should be shown on the info screen 48 | BACKEND_INFO_VARS += $(filter FLOW_GHDL_%,$(.VARIABLES)) FLOW_GTKWAVE_BINARY FLOW_LCOV_BINARY FLOW_GENHTML_BINARY 49 | 50 | ############################################################################### 51 | # Backend specific targets 52 | ############################################################################### 53 | 54 | .PHONY: ghdl_project ghdl_subproject 55 | GHDL_PROJECT := ${FLOW_BINARY_DIR}/${FLOW_MODULE}-${FLOW_SIM_TOP}.stamp 56 | ${GHDL_PROJECT}: ${FLOW_HDL_FILES} ${FLOW_SIM_HDL_FILES} 57 | @mkdir -p ${FLOW_BINARY_DIR} 58 | @cd ${FLOW_BINARY_DIR}; FLOW_LOG_FILE="${FLOW_BINARY_ROOT_DIR}/${FLOW_MODULE}_${FLOW_SIM_TOP}_project.log" bash ${FLOW_DIR}/ghdl/project.sh 59 | @touch $@ 60 | 61 | ghdl_project: 62 | @$(call printStep,"### ${FLOW_MODULE}: processing dependencies") 63 | @$(foreach entry,$(FLOW_SIM_FILES),mkdir -p $(dir $(lastword $(subst :, ,$(entry)))) && cp $(firstword $(subst :, ,$(entry))) $(lastword $(subst :, ,$(entry)));) 64 | @$(foreach module,$(FLOW_FULL_DEPENDENCIES),$(call makeTarget,FLOW_MODULE=$(module) ghdl_subproject);) 65 | @$(call printStep,"### ${FLOW_MODULE}: configuring as top-level project") 66 | @$(call makeTarget,$(GHDL_PROJECT)) 67 | @$(call printStep,"") 68 | 69 | ghdl_subproject: 70 | @$(call printStep,"### ${FLOW_MODULE}: configuring as sub project") 71 | @$(call makeTarget,$(GHDL_PROJECT)) 72 | @$(call printStep,"") 73 | 74 | .PHONY: ghdl_hdlsb 75 | ghdl_hdlsb: ghdl_project 76 | @$(call printStep,"### ${FLOW_MODULE}: simulating in batch mode") 77 | @cd ${FLOW_BINARY_DIR}; FLOW_LOG_FILE="${FLOW_BINARY_ROOT_DIR}/${FLOW_MODULE}_${FLOW_SIM_TOP}_simulation.log" bash ${FLOW_DIR}/ghdl/run_simulation.sh 78 | @$(call printStep,"") 79 | 80 | .PHONY: ghdl_hdlsg 81 | ghdl_hdlsg: ghdl_project 82 | @$(call printStep,"### ${FLOW_MODULE}: simulating in graphical mode") 83 | @cd ${FLOW_BINARY_DIR}; FLOW_LOG_FILE="${FLOW_BINARY_ROOT_DIR}/${FLOW_MODULE}_${FLOW_SIM_TOP}_simulation.log" FLOW_GTKWAVE_GUI=1 bash ${FLOW_DIR}/ghdl/run_simulation.sh 84 | @$(call printStep,"") 85 | 86 | .PHONY: ghdl_synthcb 87 | ghdl_synthcb: 88 | @echo "Synthesis is not supported by GHDL!" 89 | @exit 1 90 | 91 | .PHONY: ghdl_implcb 92 | ghdl_implcb: 93 | @echo "Implementation is not supported by GHDL!" 94 | @exit 1 95 | 96 | ifeq (${FLOW_GHDL_GCC},1) 97 | BACKEND_HELP_TEXT += $(subst ${space},+,"ghdl_covReset.....Reset the coverage counters.") 98 | BACKEND_HELP_TEXT += $(subst ${space},+,"ghdl_covGenerate..Generate coverage report.") 99 | .PHONY: ghdl_covReset ghdl_covGenerate 100 | ghdl_covReset: 101 | @${FLOW_LCOV_BINARY} -z -d ${FLOW_BINARY_DIR} 102 | 103 | ghdl_covGenerate: 104 | @${FLOW_LCOV_BINARY} -c -d ${FLOW_BINARY_DIR} -o ${FLOW_BINARY_DIR}/coverage.info 105 | @${FLOW_LCOV_BINARY} --remove ${FLOW_BINARY_DIR}/coverage.info '${FLOW_BINARY_DIR}/e~*' -o ${FLOW_BINARY_DIR}/coverage.info 106 | @cd ${FLOW_BINARY_DIR}; ${FLOW_GENHTML_BINARY} coverage.info -o html 107 | endif 108 | 109 | endif # FLOW_BACKEND is ghdl 110 | endif # FLOW_GHDL_BINARY not empty 111 | -------------------------------------------------------------------------------- /flow/ghdl/project.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # MEMSEC - Framework for building transparent memory encryption and authentication solutions. 4 | # Copyright (C) 2017-2018 Graz University of Technology, IAIK 5 | # 6 | # This file is part of MEMSEC. 7 | # 8 | # MEMSEC is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # MEMSEC is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with MEMSEC. If not, see . 20 | # 21 | shopt -s expand_aliases 22 | PWD=$(pwd) 23 | DATE=$(date) 24 | 25 | # define the log command which writes to the logfile and possibly to stdout 26 | if [ ${FLOW_VERBOSITY} -ge 2 ]; then 27 | alias log='tee -a "${FLOW_LOG_FILE}"' 28 | else 29 | alias log='cat >> "${FLOW_LOG_FILE}"' 30 | fi 31 | 32 | echo "" >> "${FLOW_LOG_FILE}" 33 | echo "###############################################################################" >> "${FLOW_LOG_FILE}" 34 | echo "# ${DATE}" >> "${FLOW_LOG_FILE}" 35 | echo "###############################################################################" >> "${FLOW_LOG_FILE}" 36 | echo "\$ cd ${PWD}" 2>&1 | log 37 | 38 | # generate the ghdl command line flags 39 | GHDL_COMPILE_OPTIONS="" 40 | if [ -n "${FLOW_LIBRARY_NAME}" ]; then 41 | GHDL_COMPILE_OPTIONS="${GHDL_COMPILE_OPTIONS} --work=${FLOW_LIBRARY_NAME}" 42 | fi 43 | 44 | # add the directories of all dependencies to the compile options 45 | for I in ${FLOW_FULL_DEPENDENCY_DIRS} 46 | do 47 | GHDL_COMPILE_OPTIONS="${GHDL_COMPILE_OPTIONS} -P${I}" 48 | done 49 | 50 | echo "\$ ${FLOW_GHDL_BINARY} -i ${GHDL_COMPILE_OPTIONS} ${FLOW_HDL_FILES} ${FLOW_SIM_HDL_FILES}" 2>&1 | log 51 | ${FLOW_GHDL_BINARY} -i ${GHDL_COMPILE_OPTIONS} ${FLOW_HDL_FILES} ${FLOW_SIM_HDL_FILES} 2>&1 | log 52 | RETURN_VALUE=${PIPESTATUS[0]} 53 | 54 | exit $RETURN_VALUE 55 | -------------------------------------------------------------------------------- /flow/global_defines.mk: -------------------------------------------------------------------------------- 1 | # 2 | # MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | # Copyright (C) 2017-2018 Graz University of Technology, IAIK 4 | # 5 | # This file is part of MEMSEC. 6 | # 7 | # MEMSEC is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # MEMSEC is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with MEMSEC. If not, see . 19 | # 20 | 21 | # helpers for escaping spaces (used in the BACKEND_HELP_TEXT) 22 | empty := 23 | space := $(empty) $(empty) 24 | 25 | ${FLOW_MODULE}FLOW_SIM_TOP ?= ${${FLOW_MODULE}FLOW_HDL_TOP} 26 | ${FLOW_MODULE}FLOW_SIM_TIME ?= 500us 27 | ${FLOW_MODULE}FLOW_BINARY_DIR ?= ${FLOW_BINARY_ROOT_DIR}/${FLOW_MODULE} 28 | ${FLOW_MODULE}FLOW_SIM_RESULT_RULE ?= sim-return 29 | $(foreach prop,${STANDARD_PROPERTIES},$(eval ${FLOW_MODULE}${prop} ?= )) 30 | 31 | # Overwrite variables by version which are prefixed with the module name, 32 | # Note that we override FLOW_BINARY_DIR first such that it is already usable 33 | # in other expansions, 34 | # e.g.: GENERIC_foobar := ${${FLOW_MODULE}GENERIC_foobar} 35 | NAMES := ${FLOW_MODULE}FLOW_BINARY_DIR 36 | $(foreach var,${NAMES},$(eval $(subst ${FLOW_MODULE},,${var}) := ${${var}})) 37 | NAMES := $(filter ${FLOW_MODULE}%,$(.VARIABLES)) 38 | $(foreach var,${NAMES},$(eval $(subst ${FLOW_MODULE},,${var}) := ${${var}})) 39 | 40 | # Configure a verbosity level for the output 41 | # 0 ..... no output 42 | # 1 ..... output only the performed steps 43 | # 2 ..... (default) tool output in adition to the output of level 1 44 | # 3 ..... include all dependent modules in info and output of level 2 45 | FLOW_VERBOSITY ?= 2 46 | 47 | # if VERBOSITY is 0, steps are not printed and make is quiet 48 | define printStep 49 | endef 50 | define makeTarget 51 | $(MAKE) --quiet --no-print-directory -f ${FLOW_SOURCE_SCRIPT} $1 52 | endef 53 | 54 | # otherwise steps get printed and make is less quiet 55 | ifneq (${FLOW_VERBOSITY},0) 56 | define printStep 57 | echo $1 58 | endef 59 | define makeTarget 60 | $(MAKE) --no-print-directory -f ${FLOW_SOURCE_SCRIPT} $1 61 | endef 62 | endif 63 | 64 | # calculate dependencies 65 | DEPENDENCIES_HIER1 := ${FLOW_DEPENDENCIES} ${FLOW_SIM_DEPENDENCIES} 66 | DEPENDENCIES_HIER2 := $(foreach m,$(DEPENDENCIES_HIER1),$($(m)FLOW_DEPENDENCIES)) 67 | DEPENDENCIES_HIER3 := $(foreach m,$(DEPENDENCIES_HIER2),$($(m)FLOW_DEPENDENCIES)) 68 | DEPENDENCIES_HIER4 := $(foreach m,$(DEPENDENCIES_HIER3),$($(m)FLOW_DEPENDENCIES)) 69 | DEPENDENCIES_HIER5 := $(foreach m,$(DEPENDENCIES_HIER4),$($(m)FLOW_DEPENDENCIES)) 70 | DEPENDENCIES_HIER6 := $(foreach m,$(DEPENDENCIES_HIER5),$($(m)FLOW_DEPENDENCIES)) 71 | DEPENDENCIES_HIER7 := $(foreach m,$(DEPENDENCIES_HIER6),$($(m)FLOW_DEPENDENCIES)) 72 | DEPENDENCIES_HIER8 := $(foreach m,$(DEPENDENCIES_HIER7),$($(m)FLOW_DEPENDENCIES)) 73 | DEPENDENCIES_HIER9 := $(foreach m,$(DEPENDENCIES_HIER8),$($(m)FLOW_DEPENDENCIES)) 74 | 75 | define uniq 76 | $(eval seen :=) 77 | $(foreach _,$1,$(if $(filter $_,${seen}),,$(eval seen += $_))) 78 | ${seen} 79 | endef 80 | 81 | FLOW_FULL_DEPENDENCIES := $(strip $(call uniq,$(foreach m,9 8 7 6 5 4 3 2 1,$(DEPENDENCIES_HIER$(m))))) 82 | FLOW_FULL_DEPENDENCY_DIRS := $(strip $(call uniq,$(foreach module, $(FLOW_FULL_DEPENDENCIES),$(if $($(module)FLOW_BINARY_DIR),$($(module)FLOW_BINARY_DIR),$(FLOW_BINARY_ROOT_DIR)/$(module))))) 83 | 84 | # normalize SIM_FILES format into the : format from either 85 | # * 86 | # * : 87 | # * : 88 | par2Func = $(lastword $(subst :, ,$1)) 89 | 90 | srcFunc = $(firstword $(subst :, ,$1)) 91 | srcFileNameFunc = $(notdir $(call srcFunc,$1)) 92 | destFunc = $(if $(findstring :,$1),$(if $(notdir $(call par2Func,$1)),$(call par2Func,$1),$(call par2Func,$1)$(call srcFileNameFunc,$1)),$(FLOW_BINARY_DIR)/$(call srcFileNameFunc,$1)) 93 | FLOW_SIM_FILES := $(foreach entry,$(FLOW_SIM_FILES),$(call srcFunc,$(entry)):$(call destFunc,$(entry))) 94 | -------------------------------------------------------------------------------- /flow/vivado/add_HDL_sources.frag: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # adding HDL sources for module ${FLOW_MODULE} 3 | ############################################################################### 4 | if {"${FLOW_HDL_FILES}" ne ""} { 5 | add_files -fileset sources_1 -norecurse ${FLOW_HDL_FILES} 6 | if {"${FLOW_LIBRARY_NAME}" ne ""} { 7 | foreach path [list ${FLOW_HDL_FILES}] { 8 | set_property library ${FLOW_LIBRARY_NAME} [get_files $path] 9 | } 10 | } 11 | } 12 | 13 | if {"${FLOW_FILES}" ne ""} { 14 | add_files -fileset constrs_1 -norecurse ${FLOW_FILES} 15 | } 16 | 17 | -------------------------------------------------------------------------------- /flow/vivado/add_SIM_sources.frag: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # adding simulation sources for module ${FLOW_MODULE} 3 | ############################################################################### 4 | if {"${FLOW_SIM_HDL_FILES} ${FLOW_SIM_FILES}" ne " "} { 5 | add_files -fileset sim_1 -norecurse ${FLOW_SIM_HDL_FILES} ${FLOW_SIM_FILES} 6 | } 7 | 8 | if { [info exists env(FLOW_VIVADO_SIM_IP_FILES)] == 1 } { 9 | add_files -fileset sim_1 -norecurse $env(FLOW_VIVADO_SIM_IP_FILES) 10 | generate_target Simulation [get_files $env(FLOW_VIVADO_SIM_IP_FILES)] 11 | export_ip_user_files -of_objects [get_files $env(FLOW_VIVADO_SIM_IP_FILES)] -no_script -force -quiet 12 | } 13 | -------------------------------------------------------------------------------- /flow/vivado/configure_implementation.frag: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # generate and/or configure implementation run 3 | ############################################################################### 4 | if {[string equal [get_runs -quiet impl_1] ""]} { 5 | create_run -name impl_1 -part $env(FLOW_VIVADO_PARTNAME) -flow {$env(FLOW_VIVADO_IMPL_FLOW)} -strategy "$env(FLOW_VIVADO_IMPL_STRATEGY)" -constrset constrs_1 -parent_run synth_1 6 | } else { 7 | set_property strategy "$env(FLOW_VIVADO_IMPL_STRATEGY)" [get_runs impl_1] 8 | set_property flow "$env(FLOW_VIVADO_IMPL_FLOW)" [get_runs impl_1] 9 | } 10 | current_run -implementation [get_runs impl_1] 11 | 12 | -------------------------------------------------------------------------------- /flow/vivado/configure_simulation.frag: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # configure simulation for module ${FLOW_MODULE} 3 | ############################################################################### 4 | set_property -name top -value $env(FLOW_SIM_TOP) -objects [get_filesets sim_1] 5 | set_property -name {xsim.simulate.runtime} -value {0s} -objects [get_filesets sim_1] 6 | update_compile_order -fileset sim_1 7 | 8 | # Extend the generic property with values from the environment 9 | # Every variable which starts with GENERIC_* is added to the property without 10 | # the prefix. 11 | set generics "" 12 | foreach index [array names env] { 13 | if {[string match "GENERIC_*" "$index"] == 0} { 14 | continue 15 | } 16 | set generic_name [string range "$index" [string length "GENERIC_"] [string length "$index"]] 17 | set generics "$generics $generic_name=$env($index)" 18 | puts "$generic_name=$env($index)" 19 | } 20 | set generics [string trim $generics] 21 | set_property -name generic -value $generics -objects [get_filesets sim_1] 22 | 23 | -------------------------------------------------------------------------------- /flow/vivado/configure_synthesis.frag: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # generate and/or configure synthesis run 3 | ############################################################################### 4 | if { [info exists env(FLOW_HDL_TOP)] == 1 } { 5 | set_property "top" $env(FLOW_HDL_TOP) [get_filesets sources_1] 6 | } 7 | if {[string equal [get_runs -quiet synth_1] ""]} { 8 | create_run -name synth_1 -part $env(FLOW_VIVADO_PARTNAME) -flow {$env(FLOW_VIVADO_SYNTH_FLOW)} -strategy "$env(FLOW_VIVADO_SYNTH_STRATEGY)" -constrset constrs_1 9 | } else { 10 | set_property strategy "$env(FLOW_VIVADO_SYNTH_STRATEGY)" [get_runs synth_1] 11 | set_property flow "$env(FLOW_VIVADO_SYNTH_FLOW)" [get_runs synth_1] 12 | } 13 | current_run -synthesis [get_runs synth_1] 14 | 15 | -------------------------------------------------------------------------------- /flow/vivado/finalize_recipe.frag: -------------------------------------------------------------------------------- 1 | close_project 2 | exit 3 | -------------------------------------------------------------------------------- /flow/vivado/generate_base_project.frag: -------------------------------------------------------------------------------- 1 | # 2 | # MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | # Copyright (C) 2017-2018 Graz University of Technology, IAIK 4 | # 5 | # This file is part of MEMSEC. 6 | # 7 | # MEMSEC is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # MEMSEC is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with MEMSEC. If not, see . 19 | # 20 | 21 | # generating project for module ${FLOW_MODULE} 22 | create_project -force -part ${FLOW_VIVADO_PARTNAME} ${FLOW_MODULE} . 23 | if {"${FLOW_VIVADO_BOARD}" ne ""} { 24 | set_property board_part ${FLOW_VIVADO_BOARD} [current_project] 25 | } 26 | 27 | # generate filesets for sources, constraints, and simulation 28 | if {[string equal [get_filesets -quiet sources_1] ""]} { 29 | create_fileset -srcset sources_1 30 | } 31 | if {[string equal [get_filesets -quiet constrs_1] ""]} { 32 | create_fileset -constrset constrs_1 33 | } 34 | if {[string equal [get_filesets -quiet sim_1] ""]} { 35 | create_fileset -simset sim_1 36 | } 37 | 38 | -------------------------------------------------------------------------------- /flow/vivado/generate_block_design.frag: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # generate block design for module ${FLOW_MODULE} if specified 3 | ############################################################################### 4 | if { [info exists env(FLOW_VIVADO_IP_REPO_PATHS)] == 1 } { 5 | set_property ip_repo_paths "$env(FLOW_VIVADO_IP_REPO_PATHS)" [current_project] 6 | update_ip_catalog 7 | } 8 | 9 | if { [info exists env(FLOW_VIVADO_BD_TCL_FILE)] == 1 } { 10 | source $env(FLOW_VIVADO_BD_TCL_FILE) 11 | set wrapper [make_wrapper [get_files *.bd] -top] 12 | add_files -norecurse $wrapper 13 | update_compile_order -fileset sources_1 14 | update_compile_order -fileset sim_1 15 | 16 | # Update the config of cells in the block diagram with values from the environment 17 | # Every variable of the form FLOW_VIVADO_BD_GENERIC__AT_= gets 18 | # applied to the open block design. 19 | foreach index [array names env] { 20 | if {[string match "FLOW_VIVADO_BD_GENERIC_*" "$index"] == 0} { 21 | continue 22 | } 23 | set generic_name_and_cell [string range "$index" [string length "FLOW_VIVADO_BD_GENERIC_"] [string length "$index"]] 24 | set generic_name [string range "$generic_name_and_cell" 0 [expr {[string first "_AT_" "$generic_name_and_cell"]-1}]] 25 | set generic_cell [string range "$generic_name_and_cell" [expr {[string first "_AT_" "$generic_name_and_cell"]+4}] [string length "$generic_name_and_cell"]] 26 | puts "$generic_name@$generic_cell=$env($index)" 27 | set_property -dict [list CONFIG.$generic_name "$env($index)"] [get_bd_cells $generic_cell] 28 | } 29 | 30 | save_bd_design 31 | generate_target all [get_files *.bd] 32 | } 33 | 34 | -------------------------------------------------------------------------------- /flow/vivado/package_ip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # MEMSEC - Framework for building transparent memory encryption and authentication solutions. 4 | # Copyright (C) 2018 Graz University of Technology, IAIK 5 | # 6 | # This file is part of MEMSEC. 7 | # 8 | # MEMSEC is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # MEMSEC is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with MEMSEC. If not, see . 20 | # 21 | PWD=$(pwd) 22 | DATE=$(date) 23 | LATEST_PACKAGE_LOG_FILE=${FLOW_MODULE}_latest_package.log 24 | 25 | # define the log command which writes to the logfile and possibly to stdout 26 | if [ ${FLOW_VERBOSITY} -ge 2 ]; then 27 | alias log='tee -a "${FLOW_LOG_FILE}"' 28 | else 29 | alias log='cat >> "${FLOW_LOG_FILE}"' 30 | fi 31 | 32 | echo "" >> "${FLOW_LOG_FILE}" 33 | echo "###############################################################################" >> "${FLOW_LOG_FILE}" 34 | echo "# ${DATE}" >> "${FLOW_LOG_FILE}" 35 | echo "###############################################################################" >> "${FLOW_LOG_FILE}" 36 | echo "\$ cd ${PWD}" 2>&1 | log 37 | 38 | # run the implementation 39 | echo "\$ ${FLOW_VIVADO_BINARY} -nojournal -nolog -mode batch -source ${FLOW_DIR}/vivado/package_ip.tcl" 2>&1 | log 40 | ${FLOW_VIVADO_BINARY} -nojournal -nolog -mode batch -source ${FLOW_DIR}/vivado/package_ip.tcl 2>&1 | tee "${LATEST_PACKAGE_LOG_FILE}" | log 41 | 42 | # # unfortunately, vivado does not return errors -> grep for error message 43 | # LAUNCH_FAIL=$(cat "${LATEST_PACKAGE_LOG_FILE}" | grep -Eq "^ERROR: implementation failed"; echo $?) 44 | # if [ ${LAUNCH_FAIL} -eq "0" ]; then 45 | # echo "RESULT: Implementation failed." 2>&1 | log 46 | # exit 1 47 | # fi 48 | # 49 | # TIMING_FAIL=$(cat "${LATEST_PACKAGE_LOG_FILE}" | grep -Eq "^Timing constraints are not met."; echo $?) 50 | # if [ ${TIMING_FAIL} -eq "0" ]; then 51 | # echo "RESULT: Timing constraints are not met." 2>&1 | log 52 | # exit 2 53 | # fi 54 | -------------------------------------------------------------------------------- /flow/vivado/package_ip.tcl: -------------------------------------------------------------------------------- 1 | # 2 | # MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | # Copyright (C) 2017-2018 Graz University of Technology, IAIK 4 | # 5 | # This file is part of MEMSEC. 6 | # 7 | # MEMSEC is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # MEMSEC is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with MEMSEC. If not, see . 19 | # 20 | open_project $env(FLOW_MODULE).xpr 21 | 22 | set package_file "$env(FLOW_VIVADO_PACKAGE_XML)" 23 | set package_dir [file dirname $package_file] 24 | if { [file exists "$package_file"] == 1 } { 25 | ipx::open_core $package_file 26 | set revision [get_property core_revision [ipx::current_core]] 27 | puts "REVISION: $revision" 28 | set revision [expr {$revision + 1}] 29 | set_property core_revision "$revision" [ipx::current_core] 30 | ipx::merge_project_changes files [ipx::current_core] 31 | ipx::merge_project_changes ports [ipx::current_core] 32 | } else { 33 | ipx::package_project -root_dir $package_dir -vendor IAIK -library IAIK -taxonomy /UserIP -force 34 | set_property core_revision 1 [ipx::current_core] 35 | set_property supported_families {zynq Beta} [ipx::current_core] 36 | } 37 | ipx::create_xgui_files [ipx::current_core] 38 | ipx::update_checksums [ipx::current_core] 39 | ipx::save_core [ipx::current_core] 40 | update_ip_catalog 41 | ipx::unload_core [ipx::current_core] 42 | 43 | close_project 44 | exit 45 | -------------------------------------------------------------------------------- /flow/vivado/project.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # MEMSEC - Framework for building transparent memory encryption and authentication solutions. 4 | # Copyright (C) 2017-2018 Graz University of Technology, IAIK 5 | # 6 | # This file is part of MEMSEC. 7 | # 8 | # MEMSEC is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # MEMSEC is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with MEMSEC. If not, see . 20 | # 21 | PWD=$(pwd) 22 | DATE=$(date) 23 | 24 | # define the log command which writes to the logfile and possibly to stdout 25 | if [ ${FLOW_VERBOSITY} -ge 2 ]; then 26 | alias log='tee -a "${FLOW_LOG_FILE}"' 27 | else 28 | alias log='cat >> "${FLOW_LOG_FILE}"' 29 | fi 30 | 31 | # check if we need to generate a new project 32 | if [ -f "${FLOW_VIVADO_PROJECT_STAMP}" ]; then 33 | RETVAL=$(diff "${FLOW_VIVADO_PROJECT_RECIPE}" "${FLOW_VIVADO_PROJECT_STAMP}" > /dev/null; echo $?) 34 | if [ "${RETVAL}" -eq "0" ]; then 35 | echo "Project is uptodate." 36 | exit 0 37 | fi 38 | fi 39 | 40 | echo "" >> "${FLOW_LOG_FILE}" 41 | echo "###############################################################################" >> "${FLOW_LOG_FILE}" 42 | echo "# ${DATE}" >> "${FLOW_LOG_FILE}" 43 | echo "###############################################################################" >> "${FLOW_LOG_FILE}" 44 | echo "\$ cd ${PWD}" 2>&1 | log 45 | 46 | # delete the vivado project if it exists already 47 | echo "\$ rm -rf \"${FLOW_VIVADO_PROJECT}\" \"${FLOW_MODULE}.cache\" \"${FLOW_MODULE}.hw\" \"${FLOW_MODULE}.ip_user_files\" \"${FLOW_MODULE}.sim\"" 2>&1 | log 48 | rm -rf "${FLOW_VIVADO_PROJECT}" "${FLOW_MODULE}.cache" "${FLOW_MODULE}.hw" "${FLOW_MODULE}.ip_user_files" "${FLOW_MODULE}.sim" 2>&1 | log 49 | 50 | echo "\$ ${FLOW_VIVADO_BINARY} -nojournal -nolog -mode batch -source ${FLOW_VIVADO_PROJECT_RECIPE}" 2>&1 | log 51 | ${FLOW_VIVADO_BINARY} -nojournal -nolog -mode batch -source ${FLOW_VIVADO_PROJECT_RECIPE} 2>&1 | log 52 | -------------------------------------------------------------------------------- /flow/vivado/run_implementation.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # MEMSEC - Framework for building transparent memory encryption and authentication solutions. 4 | # Copyright (C) 2017-2018 Graz University of Technology, IAIK 5 | # 6 | # This file is part of MEMSEC. 7 | # 8 | # MEMSEC is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # MEMSEC is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with MEMSEC. If not, see . 20 | # 21 | PWD=$(pwd) 22 | DATE=$(date) 23 | LATEST_IMPL_LOG_FILE=${FLOW_MODULE}_latest_implementation.log 24 | 25 | # define the log command which writes to the logfile and possibly to stdout 26 | if [ ${FLOW_VERBOSITY} -ge 2 ]; then 27 | alias log='tee -a "${FLOW_LOG_FILE}"' 28 | else 29 | alias log='cat >> "${FLOW_LOG_FILE}"' 30 | fi 31 | 32 | echo "" >> "${FLOW_LOG_FILE}" 33 | echo "###############################################################################" >> "${FLOW_LOG_FILE}" 34 | echo "# ${DATE}" >> "${FLOW_LOG_FILE}" 35 | echo "###############################################################################" >> "${FLOW_LOG_FILE}" 36 | echo "\$ cd ${PWD}" 2>&1 | log 37 | 38 | # run the implementation 39 | echo "\$ ${FLOW_VIVADO_BINARY} -nojournal -nolog -mode batch -source ${FLOW_DIR}/vivado/run_implementation.tcl" 2>&1 | log 40 | ${FLOW_VIVADO_BINARY} -nojournal -nolog -mode batch -source ${FLOW_DIR}/vivado/run_implementation.tcl 2>&1 | tee "${LATEST_IMPL_LOG_FILE}" | log 41 | 42 | # unfortunately, vivado does not return errors -> grep for error message 43 | LAUNCH_FAIL=$(cat "${LATEST_IMPL_LOG_FILE}" | grep -Eq "^ERROR: implementation failed"; echo $?) 44 | if [ ${LAUNCH_FAIL} -eq "0" ]; then 45 | echo "RESULT: Implementation failed." 2>&1 | log 46 | exit 1 47 | fi 48 | 49 | TIMING_FAIL=$(cat "${LATEST_IMPL_LOG_FILE}" | grep -Eq "^Timing constraints are not met."; echo $?) 50 | if [ ${TIMING_FAIL} -eq "0" ]; then 51 | echo "RESULT: Timing constraints are not met." 2>&1 | log 52 | exit 2 53 | fi 54 | -------------------------------------------------------------------------------- /flow/vivado/run_implementation.tcl: -------------------------------------------------------------------------------- 1 | # 2 | # MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | # Copyright (C) 2017 Graz University of Technology, IAIK 4 | # 5 | # This file is part of MEMSEC. 6 | # 7 | # MEMSEC is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # MEMSEC is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with MEMSEC. If not, see . 19 | # 20 | open_project $env(FLOW_MODULE).xpr 21 | 22 | if { [info exists env(FLOW_VIVADO_GUI)] == 1 } { 23 | start_gui 24 | } 25 | 26 | # change the strategy when requested or reset incomplete or out of date run 27 | if {[get_property strategy [get_runs impl_1]] != "$env(FLOW_VIVADO_IMPL_STRATEGY)" } { 28 | puts "Switching synthesis strategy to $env(FLOW_VIVADO_IMPL_STRATEGY)" 29 | set_property strategy "$env(FLOW_VIVADO_IMPL_STRATEGY)" [get_runs impl_1] 30 | reset_run impl_1 31 | } elseif {[get_property PROGRESS [get_runs impl_1]] != "100%" || [get_property NEEDS_REFRESH [get_runs impl_1]] != 0 } { 32 | reset_run impl_1 33 | } 34 | 35 | if {[get_property PROGRESS [get_runs impl_1]] != "100%" } { 36 | launch_runs impl_1 -to_step write_bitstream 37 | wait_on_run impl_1 38 | } 39 | 40 | if {[get_property PROGRESS [get_runs impl_1]] != "100%"} { 41 | error "ERROR: implementation failed" 42 | close_project 43 | exit -1 44 | } else { 45 | open_run impl_1 46 | write_checkpoint -force "$env(FLOW_BINARY_ROOT_DIR)/$env(FLOW_MODULE)-impl.dcp" 47 | report_timing_summary -file "$env(FLOW_BINARY_ROOT_DIR)/$env(FLOW_MODULE)-impl_timing_summary.txt" -delay_type min_max -report_unconstrained -check_timing_verbose -max_paths 10 -input_pins 48 | report_utilization -hierarchical -file "$env(FLOW_BINARY_ROOT_DIR)/$env(FLOW_MODULE)-impl_utilization.txt" 49 | 50 | set exit_code 0 51 | if {[get_property STATS.WNS [get_runs impl_1]] < 0 } { 52 | puts "Timing constraints are not met." 53 | set exit_code -2 54 | } 55 | 56 | if { [info exists env(FLOW_VIVADO_GUI)] == 0 } { 57 | close_project 58 | exit $exit_code 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /flow/vivado/run_simulation.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # MEMSEC - Framework for building transparent memory encryption and authentication solutions. 4 | # Copyright (C) 2017-2018 Graz University of Technology, IAIK 5 | # 6 | # This file is part of MEMSEC. 7 | # 8 | # MEMSEC is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # MEMSEC is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with MEMSEC. If not, see . 20 | # 21 | PWD=$(pwd) 22 | DATE=$(date) 23 | LATEST_SIM_LOG_FILE=${FLOW_MODULE}_${FLOW_SIM_TOP}_latest_simulation.log 24 | 25 | # define the log command which writes to the logfile and possibly to stdout 26 | if [ ${FLOW_VERBOSITY} -ge 2 ]; then 27 | alias log='tee -a "${FLOW_LOG_FILE}"' 28 | else 29 | alias log='cat >> "${FLOW_LOG_FILE}"' 30 | fi 31 | 32 | echo "" >> "${FLOW_LOG_FILE}" 33 | echo "###############################################################################" >> "${FLOW_LOG_FILE}" 34 | echo "# ${DATE}" >> "${FLOW_LOG_FILE}" 35 | echo "###############################################################################" >> "${FLOW_LOG_FILE}" 36 | echo "\$ cd ${PWD}" 2>&1 | log 37 | 38 | if [ -z "${FLOW_SIM_TOP}" ]; then 39 | echo "No top module defined. Simulation not possible!" 40 | exit 1 41 | fi 42 | 43 | # delete result files if used 44 | case ${FLOW_SIM_RESULT_RULE} in 45 | file-*) 46 | # set the result file to the log file if it is undefined 47 | if [ -z "${FLOW_SIM_RESULT_FILE}" ]; then 48 | FLOW_SIM_RESULT_FILE="${LATEST_SIM_LOG_FILE}" 49 | fi 50 | # delete the result file if it is used and already exists 51 | if [ -f ${FLOW_SIM_RESULT_FILE} ]; then 52 | echo "\$ rm ${FLOW_SIM_RESULT_FILE}" 2>&1 | log 53 | rm ${FLOW_SIM_RESULT_FILE} 2>&1 | log 54 | fi 55 | ;; 56 | esac 57 | 58 | # run the simulation 59 | echo "\$ ${FLOW_VIVADO_BINARY} -nojournal -nolog -mode batch -source ${FLOW_DIR}/vivado/run_simulation.tcl" 2>&1 | log 60 | ${FLOW_VIVADO_BINARY} -nojournal -nolog -mode batch -source ${FLOW_DIR}/vivado/run_simulation.tcl 2>&1 | tee "${LATEST_SIM_LOG_FILE}" | log 61 | 62 | # unfortunately, vivado does not return errors -> grep for simulation launch error message 63 | LAUNCH_FAIL=$(cat "${LATEST_SIM_LOG_FILE}" | grep -Eq "^Launching the simulation failed!"; echo $?) 64 | if [ ${LAUNCH_FAIL} -eq "0" ] && [ "sim-return" = "${FLOW_SIM_RESULT_RULE}" ]; then 65 | echo "RESULT: Simulation failed." 2>&1 | log 66 | exit 1 67 | fi 68 | 69 | # determine the exit code of the simulation 70 | case ${FLOW_SIM_RESULT_RULE} in 71 | file-success) 72 | EXIT_CODE=1 73 | # check if the result file exists and check its contents 74 | if [ -f ${FLOW_SIM_RESULT_FILE} ]; then 75 | COMP=$(cat "${FLOW_SIM_RESULT_FILE}" | grep -Eq "${FLOW_SIM_RESULT_REGEX}"; echo $?) 76 | if [ ${COMP} -eq "0" ]; then 77 | echo "RESULT: Simulation succeeded" 2>&1 | log 78 | EXIT_CODE=0 79 | else 80 | echo "RESULT: Simulation failed." 2>&1 | log 81 | fi 82 | else 83 | echo "RESULT: Timeout. Result file \"${FLOW_SIM_RESULT_FILE}\" not found." 2>&1 | log 84 | EXIT_CODE=2 85 | fi 86 | ;; 87 | 88 | file-failure) 89 | EXIT_CODE=0 90 | # check if the result file exists and check its contents 91 | if [ -f ${FLOW_SIM_RESULT_FILE} ]; then 92 | COMP=$(cat "${FLOW_SIM_RESULT_FILE}" | grep -Eq "${FLOW_SIM_RESULT_REGEX}"; echo $?) 93 | if [ ${COMP} -eq "0" ]; then 94 | echo "RESULT: Simulation failed." 2>&1 | log 95 | EXIT_CODE=1 96 | else 97 | echo "RESULT: Simulation succeeded" 2>&1 | log 98 | fi 99 | else 100 | echo "RESULT: Timeout. Result file \"${FLOW_SIM_RESULT_FILE}\" not found." 2>&1 | log 101 | EXIT_CODE=2 102 | fi 103 | ;; 104 | 105 | sim-return) 106 | ;; 107 | 108 | *) 109 | echo "ERROR: unsupported RESULT_RULE '${FLOW_SIM_RESULT_RULE}' used" 2>&1 | log 110 | EXIT_CODE=1 111 | ;; 112 | esac 113 | 114 | exit ${EXIT_CODE} 115 | -------------------------------------------------------------------------------- /flow/vivado/run_simulation.tcl: -------------------------------------------------------------------------------- 1 | # 2 | # MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | # Copyright (C) 2017-2018 Graz University of Technology, IAIK 4 | # 5 | # This file is part of MEMSEC. 6 | # 7 | # MEMSEC is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # MEMSEC is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with MEMSEC. If not, see . 19 | # 20 | open_project $env(FLOW_MODULE).xpr 21 | 22 | source [file join [file dirname [info script]] "configure_simulation.frag"] 23 | 24 | launch_simulation -quiet 25 | 26 | # check for simulation launching errors and display log files if possible 27 | set simulation_dir "$env(FLOW_MODULE).sim/sim_1/behav" 28 | if { {} == [current_sim] } { 29 | puts "Launching the simulation failed!" 30 | set log_file_name "" 31 | set elaborate_log_file_name "$simulation_dir/elaborate.log" 32 | set xvhdl_log_file_name "$simulation_dir/xvhdl.log" 33 | if { [file exists $elaborate_log_file_name] == 1 } { 34 | puts "Elaborate Log:" 35 | set log_file_name $elaborate_log_file_name 36 | } elseif { [file exists $xvhdl_log_file_name] == 1 } { 37 | puts "XVHDL Log:" 38 | set log_file_name $xvhdl_log_file_name 39 | } else { 40 | puts "No log file found!" 41 | close_project 42 | exit 3 43 | } 44 | set fd [open "$log_file_name" "r"] 45 | puts [read $fd [file size $log_file_name]] 46 | close $fd 47 | close_project 48 | exit 3 49 | } 50 | 51 | if { [info exists env(FLOW_VIVADO_GUI)] == 1 } { 52 | start_gui 53 | } 54 | 55 | run $env(FLOW_SIM_TIME) 56 | 57 | set time [current_time] 58 | puts "Execution stopped after $time" 59 | 60 | if { [info exists env(FLOW_VIVADO_GUI)] == 0 } { 61 | close_project 62 | } 63 | -------------------------------------------------------------------------------- /flow/vivado/run_synthesis.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # MEMSEC - Framework for building transparent memory encryption and authentication solutions. 4 | # Copyright (C) 2018 Graz University of Technology, IAIK 5 | # 6 | # This file is part of MEMSEC. 7 | # 8 | # MEMSEC is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # MEMSEC is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with MEMSEC. If not, see . 20 | # 21 | PWD=$(pwd) 22 | DATE=$(date) 23 | LATEST_SYNTH_LOG_FILE=${FLOW_MODULE}_latest_synthesis.log 24 | 25 | # define the log command which writes to the logfile and possibly to stdout 26 | if [ ${FLOW_VERBOSITY} -ge 2 ]; then 27 | alias log='tee -a "${FLOW_LOG_FILE}"' 28 | else 29 | alias log='cat >> "${FLOW_LOG_FILE}"' 30 | fi 31 | 32 | echo "" >> "${FLOW_LOG_FILE}" 33 | echo "###############################################################################" >> "${FLOW_LOG_FILE}" 34 | echo "# ${DATE}" >> "${FLOW_LOG_FILE}" 35 | echo "###############################################################################" >> "${FLOW_LOG_FILE}" 36 | echo "\$ cd ${PWD}" 2>&1 | log 37 | 38 | # run the synthesis 39 | echo "\$ ${FLOW_VIVADO_BINARY} -nojournal -nolog -mode batch -source ${FLOW_DIR}/vivado/run_synthesis.tcl" 2>&1 | log 40 | ${FLOW_VIVADO_BINARY} -nojournal -nolog -mode batch -source ${FLOW_DIR}/vivado/run_synthesis.tcl 2>&1 | tee "${LATEST_SYNTH_LOG_FILE}" | log 41 | 42 | # unfortunately, vivado does not return errors -> grep for simulation launch error message 43 | LAUNCH_FAIL=$(cat "${LATEST_SYNTH_LOG_FILE}" | grep -Eq "^ERROR: synthesis failed"; echo $?) 44 | if [ ${LAUNCH_FAIL} -eq "0" ]; then 45 | echo "RESULT: Syntesis failed." 2>&1 | log 46 | exit 1 47 | fi 48 | -------------------------------------------------------------------------------- /flow/vivado/run_synthesis.tcl: -------------------------------------------------------------------------------- 1 | # 2 | # MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | # Copyright (C) 2017 Graz University of Technology, IAIK 4 | # 5 | # This file is part of MEMSEC. 6 | # 7 | # MEMSEC is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # MEMSEC is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with MEMSEC. If not, see . 19 | # 20 | open_project $env(FLOW_MODULE).xpr 21 | 22 | ############################################################################### 23 | # apply generics 24 | ############################################################################### 25 | set generics "" 26 | foreach index [array names env] { 27 | if {[string match "GENERIC_*" "$index"] == 0} { 28 | continue 29 | } 30 | set generic_name [string range "$index" [string length "GENERIC_"] [string length "$index"]] 31 | set generics "$generics $generic_name=$env($index)" 32 | puts "$generic_name=$env($index)" 33 | } 34 | set generics [string trim $generics] 35 | set_property -name generic -value $generics -objects [get_filesets sources_1] 36 | 37 | ############################################################################### 38 | # apply block design specific generics 39 | ############################################################################### 40 | if { [info exists env(FLOW_VIVADO_BD_TCL_FILE)] == 1 } { 41 | # Update the config of cells in the block diagram with values from the environment 42 | # Every variable of the form FLOW_VIVADO_BD_GENERIC__AT_= gets 43 | # applied to the open block design. 44 | foreach index [array names env] { 45 | if {[string match "FLOW_VIVADO_BD_GENERIC_*" "$index"] == 0} { 46 | continue 47 | } 48 | set generic_name_and_cell [string range "$index" [string length "FLOW_VIVADO_BD_GENERIC_"] [string length "$index"]] 49 | set generic_name [string range "$generic_name_and_cell" 0 [expr {[string first "_AT_" "$generic_name_and_cell"]-1}]] 50 | set generic_cell [string range "$generic_name_and_cell" [expr {[string first "_AT_" "$generic_name_and_cell"]+4}] [string length "$generic_name_and_cell"]] 51 | puts "$generic_name@$generic_cell=$env($index)" 52 | set_property -dict [list CONFIG.$generic_name "$env($index)"] [get_bd_cells $generic_cell] 53 | } 54 | 55 | save_bd_design 56 | generate_target all [get_files *.bd] 57 | } 58 | 59 | if { [info exists env(FLOW_VIVADO_GUI)] == 1 } { 60 | start_gui 61 | } 62 | 63 | # change the strategy when requested or reset incomplete or out of date run 64 | if {[get_property strategy [get_runs synth_1]] != "$env(FLOW_VIVADO_SYNTH_STRATEGY)" } { 65 | puts "Switching synthesis strategy to $env(FLOW_VIVADO_SYNTH_STRATEGY)" 66 | set_property strategy "$env(FLOW_VIVADO_SYNTH_STRATEGY)" [get_runs synth_1] 67 | reset_run synth_1 68 | } elseif {[get_property PROGRESS [get_runs synth_1]] != "100%" || [get_property NEEDS_REFRESH [get_runs synth_1]] != 0 } { 69 | reset_run synth_1 70 | } 71 | 72 | if {[get_property PROGRESS [get_runs synth_1]] != "100%" } { 73 | launch_runs synth_1 74 | wait_on_run synth_1 75 | } 76 | 77 | if {[get_property PROGRESS [get_runs synth_1]] != "100%"} { 78 | error "ERROR: synthesis failed" 79 | close_project 80 | exit -1 81 | } else { 82 | open_run synth_1 83 | write_checkpoint -force "$env(FLOW_BINARY_ROOT_DIR)/$env(FLOW_MODULE)-synth.dcp" 84 | report_timing_summary -file "$env(FLOW_BINARY_ROOT_DIR)/$env(FLOW_MODULE)-synth_timing_summary.txt" -delay_type min_max -report_unconstrained -check_timing_verbose -max_paths 10 -input_pins 85 | report_utilization -hierarchical -file "$env(FLOW_BINARY_ROOT_DIR)/$env(FLOW_MODULE)-synth_utilization.txt" 86 | 87 | if { [info exists env(FLOW_VIVADO_GUI)] == 0 } { 88 | close_project 89 | exit 0 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /hdl/crypto/aes/aes128_hs.vhdl: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | 24 | entity aes128_hs is 25 | port( 26 | ClkxCI : in std_logic; 27 | RstxRBI : in std_logic; 28 | KeyxDI : in std_logic_vector(127 downto 0); 29 | DataxDI : in std_logic_vector(127 downto 0); 30 | DataxDO : out std_logic_vector(127 downto 0); 31 | EncryptxSI : in std_logic; 32 | 33 | in_ready : out std_logic; 34 | in_valid : in std_logic; 35 | out_ready : in std_logic; 36 | out_valid : out std_logic 37 | ); 38 | end aes128_hs; 39 | 40 | --! @FIXME replace with real implementation for aes128_hs 41 | architecture nop of aes128_hs is 42 | begin 43 | data_reg : entity work.register_stage 44 | generic map( 45 | WIDTH => 128, 46 | REGISTERED => true 47 | ) 48 | port map ( 49 | clk => ClkxCI, 50 | resetn => RstxRBI, 51 | 52 | in_data => DataxDI, 53 | in_valid => in_valid, 54 | in_ready => in_ready, 55 | 56 | out_data => DataxDO, 57 | out_valid => out_valid, 58 | out_ready => out_ready 59 | ); 60 | end nop; 61 | -------------------------------------------------------------------------------- /hdl/crypto/ascon/README.md: -------------------------------------------------------------------------------- 1 | Generic Ascon VHDL implementation from . 2 | 3 | * `ascon_fast_core.vhdl` modified version of the original upstream implementation by Hannes Groß. 4 | * `ascon_spongewrap.vhdl` Ascon in a MAC mode. 5 | -------------------------------------------------------------------------------- /hdl/crypto/keccak/keccak_package.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | 25 | package keccak_package is 26 | constant LANE_BITWIDTH : integer := 16; 27 | 28 | subtype Lane is std_logic_vector(LANE_BITWIDTH-1 downto 0); 29 | type LaneArray is array (24 downto 0) of Lane; 30 | type Plane is array (4 downto 0) of Lane; 31 | 32 | type ParallelCtoD is record -- Interface from controller to datapath 33 | loadState : std_logic; 34 | enableStateRate : std_logic; 35 | enableStateCapacity : std_logic; 36 | selectXoredBlock : std_logic; 37 | enableRoundCounter : std_logic; 38 | end record; 39 | 40 | type ParallelDtoC is record -- Interface from datapath to controller 41 | permutate_done : std_logic; -- all permutation rounds are done 42 | end record; 43 | 44 | function log2Ceil(i : natural) return integer; 45 | end keccak_package; 46 | 47 | package body keccak_package is 48 | function log2Ceil(i : natural) return integer is 49 | variable temp : integer := i; 50 | variable ret_val : integer := 0; 51 | variable prev : integer; 52 | variable ceil : integer := 0; 53 | begin 54 | while temp > 1 loop 55 | ret_val := ret_val + 1; 56 | prev := temp; 57 | temp := temp / 2; 58 | 59 | if temp*2 /= prev then 60 | ceil := 1; 61 | end if; 62 | end loop; 63 | ret_val := ret_val + ceil; 64 | 65 | return ret_val; 66 | end function; 67 | end package body; 68 | -------------------------------------------------------------------------------- /hdl/crypto/keccak/keccak_parallel.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.keccak_package.all; 25 | 26 | entity keccak_parallel is 27 | generic( 28 | UNROLLED_ROUNDS : integer := 1; 29 | ROUNDS : integer := 18; 30 | RATE : integer := 80); 31 | port ( 32 | ClkxCI : in std_logic; -- system clock 33 | RstxRBI : in std_logic; -- synchronous reset (active low) 34 | -- Data signals 35 | BlockxDO : out std_logic_vector(RATE-1 downto 0); -- output block 36 | BlockxDI : in std_logic_vector(RATE-1 downto 0); -- input block 37 | IVxDI : in std_logic_vector(25*LANE_BITWIDTH-1 downto 0); -- initial vector 38 | -- Control signals 39 | StartInitxSI : in std_logic; -- load IV into current state 40 | StartAbsorbxSI : in std_logic; -- absorb the input block 41 | StartSqueezexSI : in std_logic; -- absorb the input block 42 | PermutateDonexSO : out std_logic); -- calculation is in progress 43 | end keccak_parallel; 44 | 45 | architecture impl of keccak_parallel is 46 | signal CtoD : ParallelCtoD; 47 | signal DtoC : ParallelDtoC; 48 | 49 | signal StatexS : LaneArray; 50 | 51 | function Vec2LaneArray(vec : std_logic_vector) return LaneArray is 52 | variable result : LaneArray; 53 | begin 54 | for i in 0 to 24 loop 55 | result(i) := vec((i+1)*LANE_BITWIDTH-1 downto i*LANE_BITWIDTH); 56 | end loop; 57 | return result; 58 | end function; 59 | 60 | begin 61 | datapath : entity work.keccak_parallel_datapath 62 | generic map( 63 | UNROLLED_ROUNDS => UNROLLED_ROUNDS, 64 | RATE => RATE, 65 | ROUNDS => ROUNDS 66 | ) 67 | port map ( 68 | ClkxCI => ClkxCI, 69 | RstxRBI => RstxRBI, 70 | -- Data signals 71 | BlockxDO => BlockxDO, 72 | BlockxDI => BlockxDI, 73 | IVxDI => Vec2LaneArray(IVxDI), 74 | -- Internal control signals 75 | ControlxSI => CtoD, 76 | StatusxSO => DtoC); 77 | 78 | controller : entity work.keccak_parallel_control 79 | port map ( 80 | ClkxCI => ClkxCI, 81 | RstxRBI => RstxRBI, 82 | -- External control signals 83 | StartInitxSI => StartInitxSI, 84 | StartAbsorbxSI => StartAbsorbxSI, 85 | StartSqueezexSI => StartSqueezexSI, 86 | PermutateDonexSO => PermutateDonexSO, 87 | -- Internal control signals 88 | ControlxSO => CtoD, 89 | StatusxSI => DtoC); 90 | end impl; 91 | -------------------------------------------------------------------------------- /hdl/crypto/keccak/keccak_parallel_control.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use work.keccak_package.all; 24 | use ieee.numeric_std.all; 25 | 26 | entity keccak_parallel_control is 27 | port ( 28 | ClkxCI : in std_logic; 29 | RstxRBI : in std_logic; 30 | -- External control signals 31 | StartInitxSI : in std_logic; 32 | StartAbsorbxSI : in std_logic; 33 | StartSqueezexSI : in std_logic; 34 | PermutateDonexSO : out std_logic; 35 | -- Internal control signals 36 | ControlxSO : out ParallelCtoD; 37 | StatusxSI : in ParallelDtoC 38 | ); 39 | end keccak_parallel_control; 40 | 41 | architecture behavior of keccak_parallel_control is 42 | type STATE_TYPE is (IDLE, PERMUTATE); 43 | signal CurrentStatexS, NextStatexS : STATE_TYPE; 44 | signal PermutateDonexSP, PermutateDonexSN : std_logic; 45 | begin 46 | comb : process(CurrentStatexS, StartInitxSI, StartAbsorbxSI, 47 | StartSqueezexSI, StatusxSI.permutate_done, PermutateDonexSP) 48 | begin 49 | NextStatexS <= CurrentStatexS; 50 | ControlxSO.selectXoredBlock <= '0'; 51 | ControlxSO.loadState <= '0'; 52 | ControlxSO.enableStateRate <= '0'; 53 | ControlxSO.enableStateCapacity <= '0'; 54 | ControlxSO.enableRoundCounter <= '0'; 55 | PermutateDonexSN <= PermutateDonexSP; 56 | PermutateDonexSO <= PermutateDonexSP; 57 | 58 | case CurrentStatexS is 59 | when IDLE => 60 | PermutateDonexSN <= '0'; 61 | if StartInitxSI = '1' then 62 | ControlxSO.selectXoredBlock <= '0'; 63 | ControlxSO.loadState <= '1'; 64 | ControlxSO.enableStateRate <= '1'; 65 | ControlxSO.enableStateCapacity <= '1'; 66 | NextStatexS <= PERMUTATE; 67 | elsif StartAbsorbxSI = '1' then 68 | ControlxSO.selectXoredBlock <= '1'; 69 | ControlxSO.loadState <= '0'; 70 | ControlxSO.enableStateRate <= '1'; 71 | ControlxSO.enableStateCapacity <= '0'; 72 | NextStatexS <= PERMUTATE; 73 | elsif StartSqueezexSI = '1' then 74 | ControlxSO.selectXoredBlock <= '0'; 75 | ControlxSO.loadState <= '0'; 76 | ControlxSO.enableStateRate <= '0'; 77 | ControlxSO.enableStateCapacity <= '0'; 78 | NextStatexS <= PERMUTATE; 79 | else 80 | NextStatexS <= IDLE; 81 | end if; 82 | 83 | when PERMUTATE => 84 | ControlxSO.selectXoredBlock <= '0'; 85 | ControlxSO.loadState <= '0'; 86 | ControlxSO.enableStateRate <= '1'; 87 | ControlxSO.enableStateCapacity <= '1'; 88 | ControlxSO.enableRoundCounter <= '1'; 89 | NextStatexS <= PERMUTATE; 90 | if StatusxSI.permutate_done = '1' then 91 | ControlxSO.enableRoundCounter <= '0'; 92 | PermutateDonexSN <= '1'; 93 | NextStatexS <= IDLE; 94 | end if; 95 | 96 | end case; 97 | end process; 98 | 99 | sync : process 100 | begin 101 | wait until rising_edge(ClkxCI); 102 | if RstxRBI = '0' then 103 | CurrentStatexS <= IDLE; 104 | PermutateDonexSP <= '0'; 105 | else 106 | CurrentStatexS <= NextStatexS; 107 | PermutateDonexSP <= PermutateDonexSN; 108 | end if; 109 | end process; 110 | end behavior; 111 | -------------------------------------------------------------------------------- /hdl/crypto/keccak/keccak_parallel_datapath.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.keccak_package.all; 25 | 26 | entity keccak_parallel_datapath is 27 | generic( 28 | UNROLLED_ROUNDS : integer := 1; 29 | RATE : integer := 80; 30 | ROUNDS : integer := 18 31 | ); 32 | port ( 33 | ClkxCI : in std_logic; -- system clock 34 | RstxRBI : in std_logic; -- synchronous reset (active low) 35 | -- Data signals 36 | BlockxDO : out std_logic_vector(RATE-1 downto 0); -- output block 37 | BlockxDI : in std_logic_vector(RATE-1 downto 0); -- input block 38 | IVxDI : in LaneArray; -- initial state 39 | -- Control signals 40 | ControlxSI : in ParallelCtoD; -- control signals from the controller to the datapath 41 | StatusxSO : out ParallelDtoC); -- status signals from the datapath to the controller 42 | end keccak_parallel_datapath; 43 | 44 | architecture impl of keccak_parallel_datapath is 45 | signal StatexDP : LaneArray; 46 | signal StatexDN : LaneArray; 47 | signal RoundCountxD : std_logic_vector(log2Ceil(ROUNDS)-1 downto 0); 48 | signal SyncCounterReset : std_logic; 49 | 50 | type PermutationStatesType is array (0 to UNROLLED_ROUNDS) of LaneArray; 51 | type RoundCountType is array (0 to UNROLLED_ROUNDS-1) of std_logic_vector(log2Ceil(ROUNDS)-1 downto 0); 52 | 53 | signal PermutationStatexD : PermutationStatesType; 54 | signal RoundCountsxD : RoundCountType; 55 | begin 56 | state1 : entity work.keccak_state 57 | generic map ( 58 | RATE => RATE, 59 | BITWIDTH => LANE_BITWIDTH) 60 | port map ( 61 | ClkxCI => ClkxCI, 62 | DxDI => StatexDN, 63 | Enable_RatexSI => ControlxSI.enableStateRate, 64 | Enable_CapacityxSI => ControlxSI.enableStateCapacity, 65 | RstxRBI => RstxRBI, 66 | QxDO => StatexDP); 67 | 68 | keccak_round_counter_1 : entity work.keccak_round_counter 69 | generic map ( 70 | BITWIDTH => log2Ceil(ROUNDS), 71 | SUBTRAHEND => UNROLLED_ROUNDS 72 | ) 73 | port map ( 74 | ClkxCI => ClkxCI, 75 | EnableCounterxSI => ControlxSI.enableRoundCounter, 76 | RstxRBI => RstxRBI, 77 | CounterZeroxSO => StatusxSO.permutate_done, 78 | CounterValuexDO => RoundCountxD, 79 | SyncResetxSI => SyncCounterReset, 80 | ResetValuexDI => std_logic_vector(to_unsigned(ROUNDS-UNROLLED_ROUNDS, log2Ceil(ROUNDS))) 81 | ); 82 | 83 | SyncCounterReset <= not ControlxSI.enableRoundCounter; 84 | 85 | next_state : process (StatexDP, ControlxSI.selectXoredBlock, IVxDI, 86 | ControlxSI.loadState, BlockxDI, PermutationStatexD(UNROLLED_ROUNDS)) 87 | variable nextState : LaneArray; 88 | begin 89 | nextState := PermutationStatexD(UNROLLED_ROUNDS); 90 | 91 | if ControlxSI.loadState = '1' then 92 | nextState := IVxDI; 93 | end if; 94 | 95 | if ControlxSI.selectXoredBlock = '1' then 96 | -- xor rate 97 | for N in RATE/LANE_BITWIDTH - 1 downto 0 loop 98 | nextState(N) := StatexDP(N) xor BlockxDI((N+1)*LANE_BITWIDTH-1 downto N*LANE_BITWIDTH); 99 | end loop; 100 | end if; 101 | 102 | StatexDN <= nextState; 103 | end process next_state; 104 | 105 | outBlock : process (StatexDP) 106 | variable v_rate : std_logic_vector(RATE-1 downto 0); 107 | begin 108 | v_rate := (others => '0'); 109 | for i in RATE/LANE_BITWIDTH -1 downto 0 loop 110 | v_rate((i+1)*LANE_BITWIDTH-1 downto i*LANE_BITWIDTH) := StatexDP(i); 111 | end loop; 112 | BlockxDO <= v_rate; 113 | end process outBlock; 114 | 115 | PermutationStatexD(0) <= StatexDP; 116 | round_instances : 117 | for i in 0 to UNROLLED_ROUNDS-1 generate 118 | round : entity work.keccak_round_parallel 119 | generic map(BITWIDTH => log2Ceil(ROUNDS)) 120 | port map(StatexDI => PermutationStatexD(i), 121 | StatexDO => PermutationStatexD(i+1), 122 | CfgRoundsxDI => std_logic_vector(to_unsigned(ROUNDS, log2Ceil(ROUNDS))), 123 | RoundNrxDI => RoundCountsxD(i)); 124 | 125 | RoundCountsxD(i) <= std_logic_vector(unsigned(RoundCountxD)+UNROLLED_ROUNDS-1-i); 126 | end generate round_instances; 127 | end impl; 128 | -------------------------------------------------------------------------------- /hdl/crypto/keccak/keccak_register.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | 25 | entity keccak_register is 26 | generic ( 27 | BITWIDTH : integer := 16); 28 | port ( 29 | ClkxCI : in std_logic; 30 | DxDI : in std_logic_vector(BITWIDTH-1 downto 0); 31 | EnablexSI : in std_logic; 32 | RstxRBI : in std_logic; 33 | QxDO : out std_logic_vector(BITWIDTH-1 downto 0) 34 | ); 35 | 36 | end keccak_register; 37 | 38 | architecture arch_reg of keccak_register is 39 | signal Q_tmp : std_logic_vector(BITWIDTH-1 downto 0) := (others => '0'); 40 | begin 41 | SequProc : process 42 | begin -- process SequProc 43 | wait until rising_edge(ClkxCI); 44 | if RstxRBI = '0' then -- synchronous reset (active low) 45 | Q_tmp <= (others => '0'); 46 | elsif EnablexSI = '1' then 47 | Q_tmp <= DxDI; 48 | end if; 49 | end process SequProc; 50 | 51 | QxDO <= Q_tmp; 52 | 53 | end arch_reg; 54 | -------------------------------------------------------------------------------- /hdl/crypto/keccak/keccak_round_counter.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | 25 | entity keccak_round_counter is 26 | generic ( 27 | SUBTRAHEND : integer := 1; 28 | BITWIDTH : integer := 5); 29 | port ( 30 | ClkxCI : in std_logic; 31 | EnableCounterxSI : in std_logic; 32 | RstxRBI : in std_logic; 33 | CounterZeroxSO : out std_logic; 34 | CounterValuexDO : out std_logic_vector(BITWIDTH-1 downto 0); 35 | ResetValuexDI : in std_logic_vector(BITWIDTH-1 downto 0); 36 | SyncResetxSI : in std_logic 37 | ); 38 | end keccak_round_counter; 39 | 40 | architecture arch_reg of keccak_round_counter is 41 | signal QxDP, QxDN : std_logic_vector(BITWIDTH-1 downto 0) := (others => '0'); 42 | begin 43 | SequProc : process(RstxRBI, ClkxCI) 44 | begin -- process SequProc 45 | if RstxRBI = '0' then -- asynchronous reset (active low) 46 | QxDP <= (others => '0'); 47 | elsif rising_edge(ClkxCI) then 48 | QxDP <= QxDN; 49 | end if; 50 | end process SequProc; 51 | CounterValuexDO <= QxDP; 52 | 53 | CombProc : process (QxDP, SyncResetxSI, EnableCounterxSI, ResetValuexDI) 54 | variable new_value : std_logic_vector(BITWIDTH -1 downto 0); 55 | begin -- process CombProc 56 | new_value := std_logic_vector(unsigned(QxDP) - SUBTRAHEND); 57 | 58 | QxDN <= QxDP; 59 | if EnableCounterxSI = '1' then 60 | QxDN <= new_value; 61 | end if; 62 | if SyncResetxSI = '1' then 63 | QxDN <= ResetValuexDI; 64 | end if; 65 | 66 | if unsigned(QxDP) = 0 then 67 | CounterZeroxSO <= '1'; 68 | else 69 | CounterZeroxSO <= '0'; 70 | end if; 71 | end process CombProc; 72 | end arch_reg; 73 | -------------------------------------------------------------------------------- /hdl/crypto/keccak/keccak_round_iota.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.keccak_package.all; 25 | 26 | entity keccak_round_iota is 27 | port ( 28 | StatexDI : in Lane; 29 | StatexDO : out Lane; 30 | RoundNrxDI : in std_logic_vector(4 downto 0); 31 | CfgRoundsxDI : in std_logic_vector(4 downto 0) 32 | ); 33 | end keccak_round_iota; 34 | 35 | architecture impl of keccak_round_iota is 36 | begin 37 | iota : process (StatexDI, RoundNrxDI, CfgRoundsxDI) 38 | variable currentLane : Lane; 39 | variable roundAsInt : integer; 40 | variable iota_index : integer range 0 to 19; 41 | type lut_type is array (0 to 19) of std_logic_vector(4 downto 0); 42 | constant lut : lut_type := ( 43 | 0 => "00001", 1 => "11010", 2 => "11110", 3 => "10000", 4 => "11111", 44 | 5 => "00001", 6 => "11001", 7 => "10101", 8 => "01110", 9 => "01100", 45 | 10 => "10101", 11 => "00110", 12 => "11111", 13 => "01111", 14 => "11101", 46 | 15 => "10011", 16 => "10010", 17 => "01000", 18 => "10110", 19 => "00110"); 47 | begin 48 | roundAsInt := to_integer(unsigned(RoundNrxDI)); 49 | if roundAsInt > (to_integer(unsigned(CfgRoundsxDI))-1) then 50 | iota_index := 0; 51 | else 52 | iota_index := to_integer(unsigned(CfgRoundsxDI))-1-roundAsInt; 53 | end if; 54 | 55 | currentLane := StatexDI; 56 | 57 | currentLane(1 downto 0) := currentLane(1 downto 0) xor lut(iota_index)(1 downto 0); 58 | currentLane(3) := currentLane(3) xor lut(iota_index)(2); 59 | if log2Ceil(LANE_BITWIDTH) > 2 then 60 | currentLane(7) := currentLane(7) xor lut(iota_index)(3); 61 | end if; 62 | if log2Ceil(LANE_BITWIDTH) > 3 then 63 | currentLane(15) := currentLane(15) xor lut(iota_index)(4); 64 | end if; 65 | 66 | StatexDO <= currentLane; 67 | end process iota; 68 | end impl; 69 | -------------------------------------------------------------------------------- /hdl/crypto/keccak/keccak_round_parallel.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.keccak_package.all; 25 | 26 | entity keccak_round_parallel is 27 | generic ( 28 | BITWIDTH : integer := 5); 29 | port ( 30 | StatexDI : in LaneArray; 31 | StatexDO : out LaneArray; 32 | CfgRoundsxDI : in std_logic_vector(BITWIDTH-1 downto 0); 33 | RoundNrxDI : in std_logic_vector(BITWIDTH-1 downto 0)); 34 | end keccak_round_parallel; 35 | 36 | architecture impl of keccak_round_parallel is 37 | signal StateAfterTheta : LaneArray; 38 | signal StateAfterRho : LaneArray; 39 | signal StateAfterPi : LaneArray; 40 | signal StateAfterChi : LaneArray; 41 | signal StateAfterIota : LaneArray; 42 | begin 43 | theta : entity work.keccak_round_parallel_theta 44 | port map ( 45 | StatexDI => StatexDI, 46 | StatexDO => StateAfterTheta); 47 | 48 | rho : entity work.keccak_round_parallel_rho 49 | port map ( 50 | StatexDI => StateAfterTheta, 51 | StatexDO => StateAfterRho); 52 | 53 | pi : entity work.keccak_round_parallel_pi 54 | port map ( 55 | StatexDI => StateAfterRho, 56 | StatexDO => StateAfterPi); 57 | 58 | chi : entity work.keccak_round_parallel_chi 59 | port map ( 60 | StatexDI => StateAfterPi, 61 | StatexDO => StateAfterChi); 62 | 63 | iota : entity work.keccak_round_iota 64 | port map ( 65 | StatexDI => StateAfterChi(0), 66 | StatexDO => StateAfterIota(0), 67 | RoundNrxDI => RoundNrxDI, 68 | CfgRoundsxDI => CfgRoundsxDI); 69 | StateAfterIota(24 downto 1) <= StateAfterChi(24 downto 1); 70 | 71 | StatexDO <= StateAfterIota; 72 | end impl; 73 | -------------------------------------------------------------------------------- /hdl/crypto/keccak/keccak_round_parallel_chi.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.keccak_package.all; 25 | 26 | entity keccak_round_parallel_chi is 27 | port ( 28 | StatexDI : in LaneArray; 29 | StatexDO : out LaneArray); 30 | end keccak_round_parallel_chi; 31 | 32 | architecture impl of keccak_round_parallel_chi is 33 | begin 34 | chi : process (StatexDI) 35 | variable currentState : LaneArray; 36 | variable tempState : LaneArray; 37 | begin 38 | currentState := StatexDI; 39 | 40 | for y in 0 to 4 loop 41 | for x in 0 to 4 loop 42 | tempState(x + y*5) := currentState(x + y*5) xor ((not (currentState((x+1) mod 5 + 5*y))) and currentState((x+2) mod 5 + 5*y)); 43 | end loop; 44 | end loop; 45 | 46 | StatexDO <= tempState; 47 | end process chi; 48 | end impl; 49 | -------------------------------------------------------------------------------- /hdl/crypto/keccak/keccak_round_parallel_pi.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.keccak_package.all; 25 | 26 | entity keccak_round_parallel_pi is 27 | port ( 28 | StatexDI : in LaneArray; 29 | StatexDO : out LaneArray); 30 | end keccak_round_parallel_pi; 31 | 32 | architecture impl of keccak_round_parallel_pi is 33 | begin 34 | pi : process (StatexDI) 35 | variable currentState : LaneArray; 36 | variable tempState : LaneArray; 37 | variable pi_index : integer := 0; 38 | begin 39 | currentState := StatexDI; 40 | 41 | for y in 0 to 4 loop 42 | for x in 0 to 4 loop 43 | pi_index := ((2*x+3*y) mod 5)*5 + y; 44 | tempState(pi_index) := currentState(x+5*y); 45 | end loop; 46 | end loop; 47 | 48 | StatexDO <= tempState; 49 | end process pi; 50 | end impl; 51 | -------------------------------------------------------------------------------- /hdl/crypto/keccak/keccak_round_parallel_rho.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.keccak_package.all; 25 | 26 | entity keccak_round_parallel_rho is 27 | port ( 28 | StatexDI : in LaneArray; 29 | StatexDO : out LaneArray); 30 | end keccak_round_parallel_rho; 31 | 32 | architecture impl of keccak_round_parallel_rho is 33 | begin 34 | rho : process (StatexDI) 35 | type offset_array is array (0 to 24) of integer; 36 | variable offset : offset_array; 37 | variable currentState : LaneArray; 38 | begin 39 | offset(0) := 0 mod LANE_BITWIDTH; 40 | offset(1) := 1 mod LANE_BITWIDTH; 41 | offset(2) := 14 mod LANE_BITWIDTH; 42 | offset(3) := 12 mod LANE_BITWIDTH; 43 | offset(4) := 11 mod LANE_BITWIDTH; 44 | offset(5) := 4 mod LANE_BITWIDTH; 45 | offset(6) := 12 mod LANE_BITWIDTH; 46 | offset(7) := 6 mod LANE_BITWIDTH; 47 | offset(8) := 7 mod LANE_BITWIDTH; 48 | offset(9) := 4 mod LANE_BITWIDTH; 49 | offset(10) := 3 mod LANE_BITWIDTH; 50 | offset(11) := 10 mod LANE_BITWIDTH; 51 | offset(12) := 11 mod LANE_BITWIDTH; 52 | offset(13) := 9 mod LANE_BITWIDTH; 53 | offset(14) := 7 mod LANE_BITWIDTH; 54 | offset(15) := 9 mod LANE_BITWIDTH; 55 | offset(16) := 13 mod LANE_BITWIDTH; 56 | offset(17) := 15 mod LANE_BITWIDTH; 57 | offset(18) := 5 mod LANE_BITWIDTH; 58 | offset(19) := 8 mod LANE_BITWIDTH; 59 | offset(20) := 2 mod LANE_BITWIDTH; 60 | offset(21) := 2 mod LANE_BITWIDTH; 61 | offset(22) := 13 mod LANE_BITWIDTH; 62 | offset(23) := 8 mod LANE_BITWIDTH; 63 | offset(24) := 14 mod LANE_BITWIDTH; 64 | 65 | currentState := StatexDI; 66 | 67 | for N in 1 to 24 loop 68 | currentState(N) := currentState(N)((LANE_BITWIDTH-1-offset(N)) downto 0) & currentState(N)(LANE_BITWIDTH-1 downto (LANE_BITWIDTH-1 - offset(N)+1)); 69 | end loop; 70 | 71 | StatexDO <= currentState; 72 | end process rho; 73 | end impl; 74 | -------------------------------------------------------------------------------- /hdl/crypto/keccak/keccak_round_parallel_theta.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.keccak_package.all; 25 | 26 | entity keccak_round_parallel_theta is 27 | port ( 28 | StatexDI : in LaneArray; 29 | StatexDO : out LaneArray); 30 | end keccak_round_parallel_theta; 31 | 32 | architecture impl of keccak_round_parallel_theta is 33 | begin 34 | theta : process (StatexDI) 35 | variable thetaXorxD : Plane; 36 | variable thetaXorShiftedxD : Plane; 37 | variable currentState : LaneArray; 38 | begin 39 | currentState := StatexDI; 40 | 41 | --THETA 42 | --xoring planes and shifting help plane 43 | for i in 0 to 4 loop 44 | thetaXorxD(i) := currentState(i) xor currentState(i+5) xor currentState(i+10) xor currentState(i+15) xor currentState(i+20); 45 | thetaXorShiftedxD(i) := thetaXorxD(i)(LANE_BITWIDTH-2 downto 0) & thetaXorxD(i)(LANE_BITWIDTH-1); 46 | end loop; 47 | --xoring with actual state 48 | for i in 0 to 24 loop 49 | currentState(i) := thetaXorxD((i-1) mod 5) xor thetaXorShiftedxD((i+1) mod 5) xor currentState(i); 50 | end loop; -- i 51 | 52 | StatexDO <= currentState; 53 | end process theta; 54 | end impl; 55 | -------------------------------------------------------------------------------- /hdl/crypto/keccak/keccak_state.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.keccak_package.all; 25 | 26 | entity keccak_state is 27 | generic ( 28 | RATE : integer := 80; 29 | BITWIDTH : integer := 16); 30 | port ( 31 | ClkxCI : in std_logic; 32 | DxDI : in LaneArray; 33 | Enable_RatexSI : in std_logic; 34 | Enable_CapacityxSI : in std_logic; 35 | RstxRBI : in std_logic; 36 | QxDO : out LaneArray); 37 | end keccak_state; 38 | 39 | architecture gen of keccak_state is 40 | begin 41 | G1 : for i in 24 downto 0 generate 42 | reg_rate : if i < RATE/BITWIDTH generate 43 | keccak_rate : entity work.keccak_register 44 | generic map ( 45 | BITWIDTH => BITWIDTH) 46 | port map ( 47 | ClkxCI => ClkxCI, 48 | DxDI => DxDI(i), 49 | EnablexSI => Enable_RatexSI, 50 | RstxRBI => RstxRBI, 51 | QxDO => QxDO(i)); 52 | end generate reg_rate; 53 | 54 | reg_capacity : if i >= RATE/BITWIDTH generate 55 | keccak_capacity : entity work.keccak_register 56 | generic map ( 57 | BITWIDTH => BITWIDTH) 58 | port map ( 59 | ClkxCI => ClkxCI, 60 | DxDI => DxDI(i), 61 | EnablexSI => Enable_CapacityxSI, 62 | RstxRBI => RstxRBI, 63 | QxDO => QxDO(i)); 64 | end generate reg_capacity; 65 | end generate G1; 66 | end gen; 67 | -------------------------------------------------------------------------------- /hdl/crypto/xts_tweak_generator.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | 25 | entity xts_tweak_generator is 26 | generic( 27 | WIDTH : integer := 64; 28 | BLOCK_INDEX_WIDTH : integer := 2 29 | ); 30 | port( 31 | clk : in std_logic; 32 | resetn : in std_logic; 33 | 34 | in_tweak : in std_logic_vector(WIDTH - 1 downto 0); 35 | in_blockNr : in std_logic_vector(BLOCK_INDEX_WIDTH - 1 downto 0); -- the index of the in block 36 | in_mulNr : in std_logic_vector(BLOCK_INDEX_WIDTH - 1 downto 0); -- the number of initial multiplications 37 | in_valid : in std_logic; -- new tweak and block index are valid and should be used 38 | in_ready : out std_logic; 39 | 40 | out_tweak : out std_logic_vector(WIDTH - 1 downto 0); 41 | out_valid : out std_logic; 42 | out_ready : in std_logic -- the outputed tweak has been processed and the next one can be computed 43 | ); 44 | end xts_tweak_generator; 45 | 46 | architecture Behavioral of xts_tweak_generator is 47 | constant BLOCK_INDEX_MAX : integer := 2**BLOCK_INDEX_WIDTH-1; 48 | 49 | signal tweakxDP, tweakxDN : std_logic_vector(WIDTH - 1 downto 0); 50 | signal mulxDP, mulxDN : std_logic_vector(BLOCK_INDEX_WIDTH - 1 downto 0); -- number of multiplications till valid 51 | signal blockTotalxDP, blockTotalxDN : std_logic_vector(BLOCK_INDEX_WIDTH - 1 downto 0); 52 | signal validxDP, validxDN : std_logic; 53 | 54 | -- helper signals 55 | signal tweak_calc_in, tweak_calc_out : std_logic_vector(WIDTH - 1 downto 0); 56 | signal in_readyxS : std_logic; 57 | signal out_validxS : std_logic; 58 | 59 | begin 60 | 61 | tweak_mul : entity work.xts_tweak_mul 62 | generic map( 63 | WIDTH => WIDTH 64 | ) 65 | port map ( 66 | in_tweak => tweak_calc_in, 67 | out_tweak => tweak_calc_out 68 | ); 69 | 70 | regs : process(clk) is 71 | begin 72 | if rising_edge(clk) then 73 | if resetn = '0' then 74 | tweakxDP <= (others => '0'); 75 | mulxDP <= (others => '0'); 76 | blockTotalxDP <= (others => '0'); 77 | validxDP <= '0'; 78 | else 79 | tweakxDP <= tweakxDN; 80 | mulxDP <= mulxDN; 81 | blockTotalxDP <= blockTotalxDN; 82 | validxDP <= validxDN; 83 | end if; 84 | end if; 85 | end process regs; 86 | 87 | control : process(mulxDP, in_blockNr, in_tweak, in_valid, out_ready, validxDP, 88 | tweak_calc_out, tweakxDP, blockTotalxDP, in_blockNr, in_mulNr) is 89 | begin 90 | -- hold the values in the registers by default 91 | tweakxDN <= tweakxDP; 92 | mulxDN <= mulxDP; 93 | blockTotalxDN <= blockTotalxDP; 94 | validxDN <= validxDP; 95 | 96 | in_readyxS <= '0'; 97 | 98 | -- calculate the next tweak from the register and output it by default 99 | tweak_calc_in <= tweakxDP; 100 | out_tweak <= tweakxDP; 101 | 102 | -- start a new tweak calculation by loading the input data into the registers 103 | if in_valid = '1' then 104 | tweakxDN <= in_tweak; 105 | mulxDN <= in_mulNr; 106 | in_readyxS <= '1'; 107 | blockTotalxDN <= in_blockNr; 108 | validxDN <= '0'; 109 | if to_integer(unsigned(in_mulNr)) = 0 then 110 | validxDN <= '1'; 111 | end if; 112 | end if; 113 | 114 | -- loop until the first tweak is generated 115 | if to_integer(unsigned(mulxDP)) /= 0 then 116 | tweakxDN <= tweak_calc_out; 117 | mulxDN <= std_logic_vector(unsigned(mulxDP) - 1); 118 | blockTotalxDN <= std_logic_vector(unsigned(blockTotalxDP) + 1); 119 | if to_integer(unsigned(mulxDP)) = 1 then 120 | validxDN <= '1'; 121 | end if; 122 | end if; 123 | 124 | -- update the tweak when it has been in_read 125 | if validxDP = '1' and out_ready = '1' then 126 | tweakxDN <= tweak_calc_out; 127 | blockTotalxDN <= std_logic_vector(unsigned(blockTotalxDP) + 1); 128 | if to_integer(unsigned(blockTotalxDP)) = BLOCK_INDEX_MAX then 129 | validxDN <= '0'; 130 | end if; 131 | end if; 132 | end process control; 133 | 134 | out_valid <= validxDP; 135 | in_ready <= in_readyxS; 136 | 137 | end Behavioral; 138 | 139 | -------------------------------------------------------------------------------- /hdl/crypto/xts_tweak_mul.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | 25 | entity xts_tweak_mul is 26 | generic( 27 | WIDTH : integer := 64 28 | ); 29 | port( 30 | in_tweak : in std_logic_vector(WIDTH - 1 downto 0); 31 | out_tweak : out std_logic_vector(WIDTH - 1 downto 0) 32 | ); 33 | end xts_tweak_mul; 34 | 35 | architecture Behavioral of xts_tweak_mul is 36 | -- GCM polynomials: (http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf) 37 | -- 38 | -- 128-bit: 1 + a + a^2 + a^7 + a^128 => x"87" 39 | -- 64-bit: 1 + a + a^3 + a^4 + a^64 => x"1B" 40 | -- 41 | signal multiplied : std_logic_vector(WIDTH - 1 downto 0); 42 | 43 | function polynomial ( 44 | constant SIZE : natural) 45 | return std_logic_vector is 46 | variable res : std_logic_vector(WIDTH - 1 downto 0); 47 | begin -- polynomial 48 | res := (others => '0'); 49 | case SIZE is 50 | when 64 => res(7 downto 0) := x"1B"; 51 | when 128 => res(7 downto 0) := x"87"; 52 | when others => assert false report "WIDTH is not supported" severity error; 53 | end case; 54 | return res; 55 | end polynomial; 56 | begin 57 | multiplied <= in_tweak(WIDTH - 2 downto 0) & '0'; 58 | out_tweak <= multiplied xor polynomial(WIDTH) when in_tweak(WIDTH-1) = '1' else multiplied; 59 | end Behavioral; 60 | -------------------------------------------------------------------------------- /hdl/framework/axi/cpu_write_data.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | 26 | --! [Slave] Merges data received via the AXI write channel into the internal data stream. 27 | entity cpu_write_data is 28 | generic( 29 | C_S_AXI_DATA_WIDTH : integer := 32; 30 | C_S_AXI_WUSER_WIDTH : integer := 0 31 | ); 32 | port( 33 | clk : in std_logic; 34 | resetn : in std_logic; 35 | 36 | s_axi_wdata : in std_logic_vector(C_S_AXI_DATA_WIDTH - 1 downto 0); 37 | s_axi_wstrb : in std_logic_vector((C_S_AXI_DATA_WIDTH / 8) - 1 downto 0); 38 | s_axi_wlast : in std_logic; 39 | s_axi_wuser : in std_logic_vector(C_S_AXI_WUSER_WIDTH - 1 downto 0); 40 | s_axi_wvalid : in std_logic; 41 | s_axi_wready : out std_logic; 42 | 43 | s_request : in StreamType; 44 | s_request_ready : out std_logic; 45 | 46 | m_request : out StreamType; 47 | m_request_ready : in std_logic 48 | ); 49 | end cpu_write_data; 50 | 51 | architecture arch_imp of cpu_write_data is 52 | signal to_extractor, to_axideser, to_modifier : StreamType; 53 | signal to_extractor_ready, to_axideser_ready, to_modifier_ready : std_logic; 54 | 55 | signal data : BlockStreamType; 56 | signal data_address : AddressType; 57 | signal data_ready : std_logic; 58 | begin 59 | synchronizer : entity work.stream_ready_synchronizer 60 | generic map( 61 | OUT_WIDTH => 2, 62 | REGISTERS => 0 63 | ) 64 | port map ( 65 | clk => clk, 66 | resetn => resetn, 67 | 68 | s_request => s_request, 69 | s_request_ready => s_request_ready, 70 | 71 | m_requests_ready(0) => to_extractor_ready, 72 | m_requests_ready(1) => to_modifier_ready, 73 | 74 | m_requests_active(0) => '1', 75 | m_requests_active(1) => '1', 76 | 77 | m_requests(0) => to_extractor, 78 | m_requests(1) => to_modifier 79 | ); 80 | 81 | -- extract the original request from the internal data stream by dropping 82 | -- all the data beats 83 | extractor : entity work.stream_request_extractor 84 | port map ( 85 | clk => clk, 86 | resetn => resetn, 87 | 88 | s_request => to_extractor, 89 | s_request_ready => to_extractor_ready, 90 | 91 | m_request => to_axideser, 92 | m_request_ready => to_axideser_ready 93 | ); 94 | 95 | -- decode AXI write channel into stream of aligned data blocks incl. strobes 96 | -- and address but without narrow transfer support 97 | deserialization : entity work.axi_deserialization 98 | generic map( 99 | ADDR_WIDTH => ADDRESS_WIDTH, 100 | IN_DATA_WIDTH => C_S_AXI_DATA_WIDTH, 101 | OUT_DATA_WIDTH => DATASTREAM_DATA_WIDTH 102 | ) 103 | port map ( 104 | clk => clk, 105 | resetn => resetn, 106 | 107 | wdata => s_axi_wdata, 108 | wstrb => s_axi_wstrb, 109 | wlast => s_axi_wlast, 110 | wvalid => s_axi_wvalid, 111 | wready => s_axi_wready, 112 | 113 | s_request => to_axideser, 114 | s_request_ready => to_axideser_ready, 115 | 116 | m_data => data, 117 | m_data_address => data_address, 118 | m_data_ready => data_ready 119 | ); 120 | 121 | -- perform the actual modification of the internal data stream 122 | modifier : entity work.stream_data_modifier 123 | generic map( 124 | MATCH_TYPE => 0, -- virtual addresses should be matched 125 | IGNORE_METADATA => true, -- don't touch metadata 126 | IGNORE_TREE_REQ => true, -- don't touch tree requests 127 | IGNORE_DATA_REQ => false -- modify real data 128 | ) 129 | port map ( 130 | clk => clk, 131 | resetn => resetn, 132 | 133 | s_data => data, 134 | s_data_address => data_address, 135 | s_data_address_valid => data.valid, 136 | s_data_ready => data_ready, 137 | 138 | s_request => to_modifier, 139 | s_request_ready => to_modifier_ready, 140 | 141 | m_request => m_request, 142 | m_request_ready => m_request_ready 143 | ); 144 | 145 | end arch_imp; 146 | -------------------------------------------------------------------------------- /hdl/framework/metadata/key_updater.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | 26 | --! Updates keys/nonces by replacing s_request through random data. 27 | entity key_updater is 28 | generic( 29 | KEY_WIDTH : integer := DATASTREAM_DATA_WIDTH; 30 | REGISTERED : boolean := false 31 | ); 32 | port( 33 | clk : in std_logic; 34 | resetn : in std_logic; 35 | 36 | s_request : in std_logic_vector(KEY_WIDTH-1 downto 0); 37 | s_request_address : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); 38 | s_request_valid : in std_logic; 39 | s_request_ready : out std_logic; 40 | 41 | m_request : out std_logic_vector(KEY_WIDTH-1 downto 0); 42 | m_request_address : out std_logic_vector(ADDRESS_WIDTH-1 downto 0); 43 | m_request_valid : out std_logic; 44 | m_request_ready : in std_logic; 45 | 46 | random : in std_logic_vector(KEY_WIDTH-1 downto 0); 47 | random_valid : in std_logic; 48 | random_ready : out std_logic; 49 | random_request : out std_logic 50 | ); 51 | end key_updater; 52 | 53 | architecture structural of key_updater is 54 | signal request : std_logic_vector(KEY_WIDTH-1 downto 0); 55 | signal request_address : std_logic_vector(ADDRESS_WIDTH-1 downto 0); 56 | signal request_valid : std_logic; 57 | signal request_ready : std_logic; 58 | begin 59 | request <= random; 60 | request_address <= s_request_address; 61 | request_valid <= s_request_valid and random_valid; 62 | 63 | s_request_ready <= request_ready; 64 | random_ready <= request_ready; 65 | random_request <= s_request_valid; 66 | 67 | 68 | register_stage : entity work.register_stage 69 | generic map( 70 | WIDTH => KEY_WIDTH+ADDRESS_WIDTH, 71 | REGISTERED => REGISTERED 72 | ) 73 | port map ( 74 | clk => clk, 75 | resetn => resetn, 76 | 77 | in_data(KEY_WIDTH-1 downto 0) => request, 78 | in_data(KEY_WIDTH+ADDRESS_WIDTH-1 downto KEY_WIDTH) => request_address, 79 | in_valid => request_valid, 80 | in_ready => request_ready, 81 | 82 | out_data(KEY_WIDTH-1 downto 0) => m_request, 83 | out_data(KEY_WIDTH+ADDRESS_WIDTH-1 downto KEY_WIDTH) => m_request_address, 84 | out_valid => m_request_valid, 85 | out_ready => m_request_ready 86 | ); 87 | end structural; 88 | -------------------------------------------------------------------------------- /hdl/framework/metadata/node_cache_read_fetcher.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | 26 | --! Reads data from the cache into the internal stream. 27 | --! 28 | --! For every tree node a response from the cache is expected. If the cache 29 | --! request is a hit, the result is stored in the internal stream as metadata. 30 | entity node_cache_read_fetcher is 31 | generic( 32 | CACHE_DATA_WIDTH : integer := 64 33 | ); 34 | port( 35 | clk : in std_logic; 36 | resetn : in std_logic; 37 | 38 | rdata : in std_logic_vector(CACHE_DATA_WIDTH - 1 downto 0); 39 | rhit : in std_logic; 40 | rvalid : in std_logic; 41 | rready : out std_logic; 42 | 43 | s_request : in StreamType; 44 | s_request_ready : out std_logic; 45 | 46 | m_request : out StreamType; 47 | m_request_ready : in std_logic 48 | ); 49 | end node_cache_read_fetcher; 50 | 51 | architecture arch_imp of node_cache_read_fetcher is 52 | signal cdata : std_logic_vector(DATASTREAM_DATA_WIDTH-1 downto 0); 53 | signal clast, cvalid, cready : std_logic; 54 | 55 | signal hit, miss : std_logic; 56 | signal rvalid_hit, rvalid_miss : std_logic; 57 | signal rready_hit, rready_miss : std_logic; 58 | 59 | begin 60 | 61 | hit <= rhit and s_request.read; 62 | miss <= not(hit); 63 | 64 | synchronizer : entity work.ready_synchronizer 65 | generic map( 66 | OUT_WIDTH => 2 67 | ) 68 | port map ( 69 | clk => clk, 70 | resetn => resetn, 71 | 72 | in_valid => rvalid, 73 | in_ready => rready, 74 | 75 | out_valid(0) => rvalid_hit, 76 | out_valid(1) => rvalid_miss, 77 | out_active(0) => hit, 78 | out_active(1) => miss, 79 | out_ready(0) => rready_hit, 80 | out_ready(1) => rready_miss 81 | ); 82 | 83 | cache_rate_converter : entity work.rate_converter 84 | generic map( 85 | IN_DATA_WIDTH => CACHE_DATA_WIDTH, 86 | OUT_DATA_WIDTH => DATASTREAM_DATA_WIDTH, 87 | REGISTERED => false 88 | ) 89 | port map ( 90 | clk => clk, 91 | resetn => resetn, 92 | 93 | in_field_offset => (others => '0'), 94 | in_field_len => (others => '1'), 95 | 96 | in_last => '1', 97 | in_data => rdata, 98 | in_valid => rvalid_hit, 99 | in_ready => rready_hit, 100 | 101 | out_data => cdata, 102 | out_last => clast, 103 | out_field_offset => open, 104 | out_field_len => open, 105 | out_valid => cvalid, 106 | out_ready => cready 107 | ); 108 | 109 | output : process(m_request_ready, rvalid_miss, s_request, rhit, cvalid, cdata, clast) is 110 | begin 111 | m_request <= StreamType_default; 112 | s_request_ready <= '0'; 113 | cready <= '0'; 114 | rready_miss <= '0'; 115 | 116 | if s_request.valid = '1' then 117 | if s_request.request_type /= REQ_TYPE_TREE and s_request.request_type /= REQ_TYPE_TREE_ROOT then 118 | m_request <= s_request; 119 | s_request_ready <= m_request_ready; 120 | elsif rvalid_miss = '1' then 121 | m_request <= s_request; 122 | rready_miss <= m_request_ready; 123 | s_request_ready <= m_request_ready; 124 | elsif cvalid = '1' then 125 | m_request <= s_request; 126 | m_request.block_len <= (others => '1'); 127 | m_request.data <= cdata; 128 | m_request.metadata <= '1'; 129 | 130 | cready <= m_request_ready; 131 | s_request_ready <= m_request_ready and clast; 132 | end if; 133 | end if; 134 | end process output; 135 | 136 | end arch_imp; 137 | -------------------------------------------------------------------------------- /hdl/framework/metadata/node_cache_read_issuer.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | use work.memsec_functions.all; 26 | 27 | --! Requests data from the cache for every tree node. 28 | --! 29 | --! If the request is a write, the cache entry is also deleted. 30 | entity node_cache_read_issuer is 31 | generic( 32 | CACHE_ADDR_WIDTH : integer := 32; 33 | DATA_MEMORY_SIZE : integer := 512; -- Data memory size in byte 34 | CACHE_DATA_WIDTH : integer := 64 35 | ); 36 | port( 37 | clk : in std_logic; 38 | resetn : in std_logic; 39 | 40 | araddr : out std_logic_vector(CACHE_ADDR_WIDTH - 1 downto 0); 41 | ardelete : out std_logic; 42 | arvalid : out std_logic; 43 | arready : in std_logic; 44 | 45 | s_request : in StreamType; 46 | s_request_ready : out std_logic; 47 | 48 | m_request : out StreamType; 49 | m_request_ready : in std_logic 50 | ); 51 | end node_cache_read_issuer; 52 | 53 | architecture arch_imp of node_cache_read_issuer is 54 | signal m_request_valid : std_logic; 55 | 56 | signal tree_request : std_logic; 57 | begin 58 | 59 | synchronizer : entity work.ready_synchronizer 60 | generic map( 61 | OUT_WIDTH => 2 62 | ) 63 | port map ( 64 | clk => clk, 65 | resetn => resetn, 66 | 67 | in_valid => s_request.valid, 68 | in_ready => s_request_ready, 69 | 70 | out_valid(0) => m_request_valid, 71 | out_valid(1) => arvalid, 72 | out_active(0) => '1', 73 | out_active(1) => tree_request, 74 | out_ready(0) => m_request_ready, 75 | out_ready(1) => arready 76 | ); 77 | 78 | tree_request <= '1' when s_request.valid = '1' and (s_request.request_type = REQ_TYPE_TREE or s_request.request_type = REQ_TYPE_TREE_ROOT) 79 | else '0'; 80 | 81 | output_cache_lookup : process(s_request.address, s_request.request_type, s_request.valid, s_request.read, tree_request) is 82 | constant ALIGNMENT_WIDTH : integer := log2_ceil(CACHE_DATA_WIDTH/8); 83 | variable addr : unsigned(ADDRESS_WIDTH-1 downto 0); 84 | begin 85 | araddr <= (others => '0'); 86 | ardelete <= '0'; 87 | if tree_request = '1' then 88 | addr := unsigned(s_request.address) - to_unsigned(DATA_MEMORY_SIZE, ADDRESS_WIDTH); 89 | araddr <= std_logic_vector(addr(CACHE_ADDR_WIDTH+ALIGNMENT_WIDTH-1 downto ALIGNMENT_WIDTH)); 90 | ardelete <= not(s_request.read); 91 | end if; 92 | end process output_cache_lookup; 93 | 94 | output_stream : process(m_request_valid, s_request) is 95 | begin 96 | m_request <= s_request; 97 | m_request.valid <= m_request_valid; 98 | end process output_stream; 99 | 100 | end arch_imp; 101 | -------------------------------------------------------------------------------- /hdl/framework/metadata/node_cache_writer.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | use work.memsec_functions.all; 26 | 27 | --! Writes data (from one of two ports) into the cache. 28 | --! 29 | --! The new port writes data unconditionally when it is valid. On the other 30 | --! hand, the old port writes data only when no request from the new port is 31 | --! pending and when the request is a read. 32 | entity node_cache_writer is 33 | generic( 34 | CACHE_ADDR_WIDTH : integer := 32; 35 | DATA_MEMORY_SIZE : integer := 512; -- Data memory size in byte 36 | CACHE_DATA_WIDTH : integer := 64 37 | ); 38 | port( 39 | clk : in std_logic; 40 | resetn : in std_logic; 41 | 42 | waddr : out std_logic_vector(CACHE_ADDR_WIDTH - 1 downto 0); 43 | wdata : out std_logic_vector(CACHE_DATA_WIDTH - 1 downto 0); 44 | wvalid : out std_logic; 45 | wready : in std_logic; 46 | 47 | s_old_entry : in std_logic_vector(CACHE_DATA_WIDTH - 1 downto 0); 48 | s_old_address : in AddressType; 49 | s_old_is_read : in std_logic; 50 | s_old_valid : in std_logic; 51 | s_old_ready : out std_logic; 52 | 53 | s_new_entry : in std_logic_vector(CACHE_DATA_WIDTH - 1 downto 0); 54 | s_new_address : in AddressType; 55 | s_new_valid : in std_logic; 56 | s_new_ready : out std_logic 57 | ); 58 | end node_cache_writer; 59 | 60 | architecture arch_imp of node_cache_writer is 61 | begin 62 | 63 | work : process(s_new_address, s_new_entry, s_new_valid, s_old_address, 64 | s_old_entry, s_old_is_read, s_old_valid, wready) is 65 | constant ALIGNMENT_WIDTH : integer := log2_ceil(CACHE_DATA_WIDTH/8); 66 | variable address : unsigned(ADDRESS_WIDTH-1 downto 0); 67 | begin 68 | waddr <= (others => '0'); 69 | wdata <= (others => '0'); 70 | wvalid <= '0'; 71 | 72 | s_old_ready <= '0'; 73 | s_new_ready <= '0'; 74 | 75 | address := (others => '0'); 76 | if s_new_valid = '1' then 77 | address := unsigned(s_new_address) - to_unsigned(DATA_MEMORY_SIZE, ADDRESS_WIDTH); 78 | wdata <= s_new_entry; 79 | wvalid <= '1'; 80 | s_new_ready <= wready; 81 | elsif s_old_valid = '1' and s_old_is_read = '1' then 82 | address := unsigned(s_old_address) - to_unsigned(DATA_MEMORY_SIZE, ADDRESS_WIDTH); 83 | wdata <= s_old_entry; 84 | wvalid <= '1'; 85 | s_old_ready <= wready; 86 | end if; 87 | 88 | if s_old_valid = '1' and s_old_is_read = '0' then 89 | s_old_ready <= '1'; 90 | end if; 91 | 92 | waddr <= std_logic_vector(address(CACHE_ADDR_WIDTH+ALIGNMENT_WIDTH-1 downto ALIGNMENT_WIDTH)); 93 | end process work; 94 | 95 | end arch_imp; 96 | -------------------------------------------------------------------------------- /hdl/framework/metadata/nonce_increment.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | 26 | --! Increments the nonce from the s_request input and returns it on m_request. 27 | --! 28 | --! If the nonce wraps to zero, one is returned instead. This is necessary to 29 | --! ensure that the zero nonce is reserved for identifiying uninitialized memory. 30 | entity nonce_increment is 31 | generic( 32 | NONCE_WIDTH : integer := DATASTREAM_DATA_WIDTH 33 | ); 34 | port( 35 | clk : in std_logic; 36 | resetn : in std_logic; 37 | 38 | s_request : in std_logic_vector(NONCE_WIDTH-1 downto 0); 39 | s_request_address : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); 40 | s_request_valid : in std_logic; 41 | s_request_ready : out std_logic; 42 | 43 | m_request : out std_logic_vector(NONCE_WIDTH-1 downto 0); 44 | m_request_address : out std_logic_vector(ADDRESS_WIDTH-1 downto 0); 45 | m_request_valid : out std_logic; 46 | m_request_ready : in std_logic 47 | ); 48 | end nonce_increment; 49 | 50 | architecture structural of nonce_increment is 51 | begin 52 | m_request_valid <= s_request_valid; 53 | s_request_ready <= m_request_ready; 54 | 55 | work : process(s_request, s_request_address) is 56 | variable res : unsigned(NONCE_WIDTH-1 downto 0); 57 | begin 58 | res := unsigned(s_request) + 1; 59 | if res = 0 then 60 | res := to_unsigned(1, NONCE_WIDTH); 61 | end if; 62 | m_request <= std_logic_vector(res); 63 | m_request_address <= s_request_address; 64 | end process work; 65 | 66 | end structural; 67 | -------------------------------------------------------------------------------- /hdl/framework/metadata/stream_nonce_incrementer.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | 26 | --! Increments the metadata block in front of a memory transaction. 27 | entity stream_nonce_incrementer is 28 | port( 29 | clk : in std_logic; 30 | resetn : in std_logic; 31 | 32 | s_request : in StreamType; 33 | s_request_ready : out std_logic; 34 | 35 | m_request : out StreamType; 36 | m_request_ready : in std_logic 37 | ); 38 | end stream_nonce_incrementer; 39 | 40 | architecture arch_imp of stream_nonce_incrementer is 41 | signal data : BlockStreamType; 42 | 43 | signal inc_nonce : std_logic_vector(DATASTREAM_DATA_WIDTH-1 downto 0); 44 | signal inc_nonce_valid, inc_nonce_ready : std_logic; 45 | begin 46 | 47 | modifier : entity work.stream_data_modifier 48 | generic map( 49 | MATCH_TYPE => 2, -- block numbers should be matched 50 | IGNORE_METADATA => false, 51 | IGNORE_TREE_REQ => false, 52 | IGNORE_DATA_REQ => false 53 | ) 54 | port map ( 55 | clk => clk, 56 | resetn => resetn, 57 | 58 | s_data => data, 59 | s_data_address => (others => '0'), 60 | s_data_address_valid => '1', 61 | s_data_ready => open, 62 | 63 | s_request => s_request, 64 | s_request_ready => s_request_ready, 65 | 66 | m_request => m_request, 67 | m_request_ready => m_request_ready 68 | ); 69 | 70 | 71 | work : process(s_request.data, s_request.valid) is 72 | variable res : unsigned(DATASTREAM_DATA_WIDTH-1 downto 0); 73 | begin 74 | data <= BlockStreamType_default; 75 | res := (others => '0'); 76 | 77 | if s_request.valid = '1' then 78 | data.strobes <= (others => '1'); 79 | data.last <= '1'; 80 | data.valid <= '1'; 81 | 82 | res := unsigned(s_request.data) + 1; 83 | if res = 0 then 84 | res := to_unsigned(1, DATASTREAM_DATA_WIDTH); 85 | end if; 86 | 87 | data.data <= std_logic_vector(res); 88 | end if; 89 | end process work; 90 | 91 | end arch_imp; 92 | -------------------------------------------------------------------------------- /hdl/framework/metadata/stream_treedata_modifier.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | use work.memsec_functions.all; 26 | 27 | --! Replaces a data block within a tree memory transaction. 28 | --! 29 | --! Used to update nonces/keys within the data part of the inner tree nodes. 30 | entity stream_treedata_modifier is 31 | generic( 32 | METADATA_WIDTH : integer := DATASTREAM_DATA_WIDTH 33 | ); 34 | port( 35 | clk : in std_logic; 36 | resetn : in std_logic; 37 | 38 | metadata : in std_logic_vector(METADATA_WIDTH-1 downto 0); 39 | metadata_valid : in std_logic; 40 | metadata_ready : out std_logic; 41 | 42 | s_request : in StreamType; 43 | s_request_ready : out std_logic; 44 | 45 | m_request : out StreamType; 46 | m_request_ready : in std_logic 47 | ); 48 | end stream_treedata_modifier; 49 | 50 | architecture arch_imp of stream_treedata_modifier is 51 | signal data : BlockStreamType; 52 | signal data_address : AddressType; 53 | signal data_address_valid : std_logic; 54 | signal data_ready : std_logic; 55 | 56 | signal metadata_out : std_logic_vector(DATASTREAM_DATA_WIDTH-1 downto 0); 57 | signal metadata_out_offset : std_logic_vector(offset_width(DATASTREAM_DATA_WIDTH, METADATA_WIDTH)-1 downto 0); 58 | signal metadata_out_last, metadata_out_valid, metadata_out_ready : std_logic; 59 | begin 60 | 61 | metadata_rate_converter : entity work.rate_converter 62 | generic map( 63 | IN_DATA_WIDTH => METADATA_WIDTH, 64 | OUT_DATA_WIDTH => DATASTREAM_DATA_WIDTH, 65 | REGISTERED => false 66 | ) 67 | port map ( 68 | clk => clk, 69 | resetn => resetn, 70 | 71 | in_field_offset => (others => '0'), 72 | in_field_len => (others => '1'), 73 | 74 | in_last => '1', 75 | in_data => metadata, 76 | in_valid => metadata_valid, 77 | in_ready => metadata_ready, 78 | 79 | out_data => metadata_out, 80 | out_last => metadata_out_last, 81 | out_field_offset => metadata_out_offset, 82 | out_field_len => open, 83 | out_valid => metadata_out_valid, 84 | out_ready => metadata_out_ready 85 | ); 86 | 87 | modifier : entity work.stream_data_modifier 88 | generic map( 89 | MATCH_TYPE => 0, -- virtual addresses should be matched 90 | IGNORE_METADATA => true, 91 | IGNORE_TREE_REQ => false, 92 | IGNORE_DATA_REQ => true 93 | ) 94 | port map ( 95 | clk => clk, 96 | resetn => resetn, 97 | 98 | s_data => data, 99 | s_data_address => data_address, 100 | s_data_address_valid => data_address_valid, 101 | s_data_ready => data_ready, 102 | 103 | s_request => s_request, 104 | s_request_ready => s_request_ready, 105 | 106 | m_request => m_request, 107 | m_request_ready => m_request_ready 108 | ); 109 | 110 | work : process(data_ready, metadata_out, metadata_out_valid, metadata_out_last, 111 | s_request.address, s_request.request_type, s_request.valid, 112 | metadata_out_offset) is 113 | begin 114 | data <= BlockStreamType_default; 115 | metadata_out_ready <= '0'; 116 | data_address <= (others => '0'); 117 | data_address_valid <= '0'; 118 | 119 | if s_request.valid = '1' and (s_request.request_type = REQ_TYPE_TREE_ROOT or s_request.request_type = REQ_TYPE_TREE) then 120 | data_address_valid <= '1'; 121 | data_address <= set_bits(s_request.address, metadata_out_offset, DATASTREAM_DATA_WIDTH/8, METADATA_WIDTH/8); 122 | data.strobes <= (others => '1'); 123 | data.last <= metadata_out_last; 124 | data.valid <= metadata_out_valid; 125 | data.data <= metadata_out; 126 | metadata_out_ready <= data_ready; 127 | end if; 128 | end process work; 129 | 130 | end arch_imp; 131 | -------------------------------------------------------------------------------- /hdl/framework/stream/request_modification/stream_request_extractor.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | 26 | --! Extracts the original request from the stream. 27 | --! 28 | --! The data beats as well as all metadata of all data and tree requests are 29 | --! discarded such that every data transaction is reported only once. 30 | entity stream_request_extractor is 31 | port( 32 | clk : in std_logic; 33 | resetn : in std_logic; 34 | 35 | s_request : in StreamType; 36 | s_request_ready : out std_logic; 37 | 38 | m_request : out StreamType; 39 | m_request_ready : in std_logic 40 | ); 41 | end stream_request_extractor; 42 | 43 | architecture arch_imp of stream_request_extractor is 44 | signal reqxDP, reqxDN : StreamType; 45 | signal output_ackxDBP, output_ackxDBN : std_logic; 46 | signal input_ackxDBP, input_ackxDBN : std_logic; 47 | 48 | signal request_ready : std_logic; 49 | signal output_req : StreamType; 50 | begin 51 | 52 | regs : process(clk) is 53 | begin 54 | if rising_edge(clk) then 55 | if resetn = '0' then 56 | reqxDP <= StreamType_default; 57 | input_ackxDBP <= '0'; 58 | output_ackxDBP <= '0'; 59 | else 60 | reqxDP <= reqxDN; 61 | input_ackxDBP <= input_ackxDBN; 62 | output_ackxDBP <= output_ackxDBN; 63 | end if; 64 | end if; 65 | end process regs; 66 | 67 | work : process(input_ackxDBP, m_request_ready, output_ackxDBP, 68 | output_req.valid, request_ready, reqxDP, s_request) is 69 | begin 70 | reqxDN <= reqxDP; 71 | input_ackxDBN <= input_ackxDBP; 72 | output_ackxDBN <= output_ackxDBP; 73 | 74 | output_req <= StreamType_default; 75 | request_ready <= '0'; 76 | 77 | if reqxDP.valid = '1' and output_ackxDBP = '1' then 78 | output_req <= reqxDP; 79 | end if; 80 | 81 | -- Register is empty. 82 | -- Write the new data into the register and forward the new request 83 | -- directly from the input. 84 | if s_request.valid = '1' and s_request.request_type = REQ_TYPE_DATA and input_ackxDBP = '0' and output_ackxDBP = '0' then 85 | reqxDN <= s_request; 86 | output_req <= s_request; 87 | request_ready <= '1'; 88 | output_ackxDBN <= '1'; 89 | input_ackxDBN <= '1'; 90 | elsif s_request.valid = '1' and s_request.request_type /= REQ_TYPE_DATA then 91 | request_ready <= '1'; 92 | end if; 93 | 94 | -- remember if the output request has been acknowledged 95 | if output_req.valid = '1' and m_request_ready = '1' then 96 | output_ackxDBN <= '0'; 97 | end if; 98 | 99 | -- remember if the input request has been acknowledged 100 | if s_request.valid = '1' and request_ready = '1' and to_integer(unsigned(s_request.block_len)) = 0 and s_request.last_request = '1' then 101 | input_ackxDBN <= '0'; 102 | end if; 103 | 104 | -- acknowledged all requests at the input until the end has been reached 105 | if s_request.valid = '1' and reqxDP.valid = '1' and input_ackxDBP = '1' then 106 | request_ready <= '1'; 107 | end if; 108 | end process work; 109 | 110 | s_request_ready <= request_ready; 111 | 112 | sanitize : process(output_req) is 113 | begin 114 | m_request <= output_req; 115 | m_request.virt_address <= (others => '0'); 116 | m_request.block_address <= (others => '0'); 117 | m_request.block_len <= (others => '0'); 118 | m_request.data <= (others => '0'); 119 | m_request.len <= (others => '0'); -- the request splitter cuts the original len and it is not used 120 | m_request.metadata <= '0'; 121 | end process sanitize; 122 | 123 | end arch_imp; 124 | -------------------------------------------------------------------------------- /hdl/framework/stream/stream_beat_remover.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | 26 | --! Drops a configurable amount of beats in each transaction. 27 | entity stream_beat_remover is 28 | generic( 29 | DROP_POSITION : integer := 0; 30 | DROP_COUNT : integer := 1 31 | ); 32 | port( 33 | clk : in std_logic; 34 | resetn : in std_logic; 35 | 36 | s_request : in StreamType; 37 | s_request_ready : out std_logic; 38 | 39 | m_request : out StreamType; 40 | m_request_ready : in std_logic 41 | ); 42 | end stream_beat_remover; 43 | 44 | architecture behavioral of stream_beat_remover is 45 | signal BlockCounterxDP, BlockCounterxDN : std_logic_vector(s_request.len'length-1 downto 0); 46 | signal request_ready : std_logic; 47 | begin 48 | 49 | regs : process(clk) is 50 | begin 51 | if rising_edge(clk) then 52 | if resetn = '0' then 53 | BlockCounterxDP <= (others => '0'); 54 | else 55 | BlockCounterxDP <= BlockCounterxDN; 56 | end if; 57 | end if; 58 | end process regs; 59 | 60 | comb : process(s_request, m_request_ready, request_ready, BlockCounterxDP) is 61 | variable vBlockCounter : integer; 62 | begin 63 | BlockCounterxDN <= BlockCounterxDP; 64 | 65 | -- forward request by default 66 | m_request <= s_request; 67 | request_ready <= m_request_ready; 68 | 69 | vBlockCounter := to_integer(unsigned(BlockCounterxDP)); 70 | -- drop the input block if the drop position is reached 71 | if vBlockCounter >= DROP_POSITION and vBlockCounter <= (DROP_POSITION+DROP_COUNT-1) then 72 | m_request <= StreamType_default; 73 | request_ready <= '1'; 74 | end if; 75 | 76 | if s_request.valid = '1' and request_ready = '1' then 77 | if unsigned(s_request.block_len) = 0 then 78 | BlockCounterxDN <= (others => '0'); 79 | else 80 | BlockCounterxDN <= std_logic_vector(unsigned(BlockCounterxDP) + 1); 81 | end if; 82 | end if; 83 | end process comb; 84 | 85 | s_request_ready <= request_ready; 86 | 87 | end behavioral; 88 | -------------------------------------------------------------------------------- /hdl/framework/stream/stream_data_filter_to_stdlogic.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | use work.memsec_functions.all; 26 | 27 | --! Filters the internal stream according to the original request. 28 | --! 29 | --! Only blocks which are necessary to answer the original request get 30 | --! forwarded. All other data beats are simply dropped. 31 | entity stream_data_filter_to_stdlogic is 32 | generic( 33 | DATASTREAM_OUT_WIDTH : integer := 64; 34 | TREE_FILTER : boolean := false; 35 | DATA_LEAF_FILTER : boolean := false 36 | ); 37 | port( 38 | -- Ports of Axi Slave Bus Interface S_AXI 39 | clk : in std_logic; 40 | resetn : in std_logic; 41 | 42 | s_request : in StreamType; 43 | s_request_ready : out std_logic; 44 | 45 | m_request : out std_logic_vector(DATASTREAM_OUT_WIDTH-1 downto 0); 46 | m_request_address : out std_logic_vector(ADDRESS_WIDTH-1 downto 0); 47 | m_request_is_read : out std_logic; 48 | m_request_read_valid : out std_logic; 49 | m_request_read_ready : in std_logic; 50 | m_request_write_valid : out std_logic; 51 | m_request_write_ready : in std_logic; 52 | m_request_cache_valid : out std_logic; 53 | m_request_cache_ready : in std_logic 54 | ); 55 | end stream_data_filter_to_stdlogic; 56 | 57 | architecture structural of stream_data_filter_to_stdlogic is 58 | signal request : StreamType; 59 | 60 | signal m_request_valid, m_request_ready, req_write_active : std_logic; 61 | signal request_ready : std_logic; 62 | 63 | signal request_field_offset : std_logic_vector(offset_width(DATASTREAM_DATA_WIDTH, DATASTREAM_OUT_WIDTH)-1 downto 0); 64 | signal output_field_offset : std_logic_vector(offset_width(DATASTREAM_DATA_WIDTH, DATASTREAM_OUT_WIDTH)-1 downto 0); 65 | signal last_input : std_logic; 66 | begin 67 | 68 | data_filter : entity work.stream_data_block_filter 69 | generic map ( 70 | DATASTREAM_OUT_WIDTH => DATASTREAM_DATA_WIDTH, 71 | TREE_FILTER => TREE_FILTER, 72 | DATA_LEAF_FILTER => DATA_LEAF_FILTER 73 | ) 74 | port map ( 75 | clk => clk, 76 | resetn => resetn, 77 | 78 | s_request => s_request, 79 | s_request_ready => s_request_ready, 80 | 81 | m_request => request, 82 | m_request_ready => request_ready 83 | ); 84 | 85 | request_field_offset <= slice_bits(request.virt_address, DATASTREAM_DATA_WIDTH/8, DATASTREAM_OUT_WIDTH/8); 86 | last_input <= '1' when request_field_offset = ones(request_field_offset'length) else '0'; 87 | 88 | rate_conversion : entity work.rate_converter 89 | generic map( 90 | IN_DATA_WIDTH => DATASTREAM_DATA_WIDTH, 91 | OUT_DATA_WIDTH => DATASTREAM_OUT_WIDTH, 92 | REGISTERED => false 93 | ) 94 | port map ( 95 | clk => clk, 96 | resetn => resetn, 97 | 98 | in_field_offset => request_field_offset, 99 | in_field_len => (others => '1'), 100 | 101 | in_last => last_input, 102 | in_data => request.data, 103 | in_valid => request.valid, 104 | in_ready => request_ready, 105 | 106 | out_data => m_request, 107 | out_last => open, 108 | out_field_offset => output_field_offset, 109 | out_field_len => open, 110 | out_valid => m_request_valid, 111 | out_ready => m_request_ready 112 | ); 113 | 114 | m_request_address <= set_bits(request.address, output_field_offset, DATASTREAM_DATA_WIDTH/8, DATASTREAM_OUT_WIDTH/8); 115 | m_request_is_read <= request.read; 116 | 117 | synchronizer : entity work.ready_synchronizer 118 | generic map( 119 | OUT_WIDTH => 3 120 | ) 121 | port map ( 122 | clk => clk, 123 | resetn => resetn, 124 | 125 | in_valid => m_request_valid, 126 | in_ready => m_request_ready, 127 | 128 | out_valid(0) => m_request_read_valid, 129 | out_valid(1) => m_request_write_valid, 130 | out_valid(2) => m_request_cache_valid, 131 | out_active(0) => '1', 132 | out_active(1) => req_write_active, 133 | out_active(2) => '1', 134 | out_ready(0) => m_request_read_ready, 135 | out_ready(1) => m_request_write_ready, 136 | out_ready(2) => m_request_cache_ready 137 | ); 138 | 139 | req_write_active <= not(request.read); 140 | 141 | end structural; 142 | -------------------------------------------------------------------------------- /hdl/framework/stream/stream_fifo.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | use work.memsec_functions.all; 26 | 27 | --! FIFO for the internal stream type. 28 | entity stream_fifo is 29 | generic( 30 | WIDTH : integer := 32; 31 | ELEMENTS : integer := 1 32 | ); 33 | port( 34 | clk : in std_logic; 35 | resetn : in std_logic; 36 | 37 | in_data : in StreamType; 38 | in_valid : in std_logic; 39 | in_ready : out std_logic; 40 | 41 | out_data : out StreamType; 42 | out_valid : out std_logic; 43 | out_ready : in std_logic 44 | ); 45 | end stream_fifo; 46 | 47 | architecture arch_imp of stream_fifo is 48 | type FifoArray is array(integer range <>) of StreamType; 49 | signal FifoxDP, FifoxDN : FifoArray(ELEMENTS-1 downto 0); 50 | 51 | signal IndexxDP, IndexxDN : std_logic_vector(log2_ceil(ELEMENTS) downto 0); 52 | 53 | begin 54 | regs : process(clk) is 55 | begin 56 | if rising_edge(clk) then 57 | if resetn = '0' then 58 | FifoxDP <= (others => StreamType_default); 59 | IndexxDP <= (others => '0'); 60 | else 61 | FifoxDP <= FifoxDN; 62 | IndexxDP <= IndexxDN; 63 | end if; 64 | end if; 65 | end process regs; 66 | 67 | comb : process(in_data, in_valid, out_ready, FifoxDP, IndexxDP) is 68 | variable vIndex : integer range 0 to ELEMENTS; 69 | begin 70 | FifoxDN <= FifoxDP; 71 | IndexxDN <= IndexxDP; 72 | 73 | in_ready <= '0'; 74 | out_valid <= '0'; 75 | out_data <= FifoxDP(0); 76 | 77 | vIndex := to_integer(unsigned(IndexxDP)); 78 | -- output 79 | if vIndex > 0 then 80 | out_valid <= '1'; 81 | 82 | if out_ready = '1' then 83 | vIndex := vIndex - 1; 84 | FifoxDN(ELEMENTS-2 downto 0) <= FifoxDP(ELEMENTS-1 downto 1); 85 | FifoxDN(ELEMENTS-1) <= StreamType_default; 86 | end if; 87 | end if; 88 | 89 | if in_valid = '1' and vIndex < ELEMENTS then 90 | FifoxDN(vIndex) <= in_data; 91 | vIndex := vIndex + 1; 92 | in_ready <= '1'; 93 | end if; 94 | 95 | IndexxDN <= std_logic_vector(to_unsigned(vIndex, IndexxDP'length)); 96 | end process comb; 97 | end arch_imp; 98 | -------------------------------------------------------------------------------- /hdl/framework/stream/stream_multi_register_stage.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | 26 | --! Simple register stage for the internal stream type with configurable register count. 27 | entity stream_multi_register_stage is 28 | generic( 29 | REGISTERS : integer := 1 30 | ); 31 | port( 32 | clk : in std_logic; 33 | resetn : in std_logic; 34 | 35 | in_data : in StreamType; 36 | in_valid : in std_logic; 37 | in_ready : out std_logic; 38 | 39 | out_data : out StreamType; 40 | out_valid : out std_logic; 41 | out_ready : in std_logic 42 | ); 43 | end stream_multi_register_stage; 44 | 45 | architecture arch_imp of stream_multi_register_stage is 46 | type HandshakeArrayType is array (REGISTERS downto 0) of std_logic; 47 | 48 | signal streams : StreamArrayType(REGISTERS downto 0); 49 | signal readys, valids : HandshakeArrayType; 50 | begin 51 | streams(0) <= in_data; 52 | valids(0) <= in_valid; 53 | in_ready <= readys(0); 54 | 55 | regs : for I in 0 to REGISTERS-1 generate 56 | r : entity work.stream_register_stage 57 | port map ( 58 | clk => clk, 59 | resetn => resetn, 60 | 61 | in_data => streams(I), 62 | in_valid => valids(I), 63 | in_ready => readys(I), 64 | 65 | out_data => streams(I+1), 66 | out_valid => valids(I+1), 67 | out_ready => readys(I+1) 68 | ); 69 | end generate regs; 70 | 71 | out_data <= streams(REGISTERS); 72 | out_valid <= valids(REGISTERS); 73 | readys(REGISTERS) <= out_ready; 74 | end arch_imp; 75 | -------------------------------------------------------------------------------- /hdl/framework/stream/stream_ready_synchronizer.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | 26 | --! Synchronization block for the internal stream type. 27 | --! 28 | --! This block ensures that all consumers have acknowledged the reception of the 29 | --! block before the next one is accepted. 30 | entity stream_ready_synchronizer is 31 | generic( 32 | OUT_WIDTH : integer := 2; 33 | REGISTERS : integer := 0 34 | ); 35 | port( 36 | clk : in std_logic; 37 | resetn : in std_logic; 38 | 39 | s_request : in StreamType; 40 | s_request_ready : out std_logic; 41 | 42 | m_requests : out StreamArrayType(OUT_WIDTH-1 downto 0); 43 | m_requests_active : in std_logic_vector(OUT_WIDTH-1 downto 0); 44 | m_requests_ready : in std_logic_vector(OUT_WIDTH-1 downto 0) 45 | ); 46 | end stream_ready_synchronizer; 47 | 48 | architecture arch_imp of stream_ready_synchronizer is 49 | signal reg_stream : StreamType; 50 | signal reg_ready : std_logic; 51 | signal readys, valids : std_logic_vector(OUT_WIDTH-1 downto 0); 52 | begin 53 | 54 | reg_stage : entity work.stream_multi_register_stage 55 | generic map( 56 | REGISTERS => REGISTERS 57 | ) 58 | port map ( 59 | clk => clk, 60 | resetn => resetn, 61 | 62 | in_data => s_request, 63 | in_valid => s_request.valid, 64 | in_ready => s_request_ready, 65 | 66 | out_data => reg_stream, 67 | out_valid => open, 68 | out_ready => reg_ready 69 | ); 70 | 71 | synchronization : entity work.ready_synchronizer 72 | generic map( 73 | OUT_WIDTH => OUT_WIDTH 74 | ) 75 | port map( 76 | clk => clk, 77 | resetn => resetn, 78 | 79 | in_ready => reg_ready, 80 | in_valid => reg_stream.valid, 81 | 82 | out_ready => readys, 83 | out_active => m_requests_active, 84 | out_valid => valids 85 | ); 86 | 87 | io : process(reg_stream, valids, m_requests_ready) is 88 | begin 89 | for I in 0 to OUT_WIDTH-1 loop 90 | m_requests(I) <= reg_stream; 91 | m_requests(I).valid <= valids(I); 92 | readys(I) <= m_requests_ready(I); 93 | end loop; 94 | end process io; 95 | 96 | end arch_imp; 97 | -------------------------------------------------------------------------------- /hdl/framework/stream/stream_register_stage.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | 26 | --! Simple register stage for the internal stream type. 27 | --! 28 | --! Enabling the READY_BYPASS permits to operate the register without 29 | --! introducing idle cycles. However, as a consequence, a critical path across 30 | --! the ready line is not prevented. 31 | entity stream_register_stage is 32 | generic( 33 | READY_BYPASS : boolean := true; --! permit to directly write the register when the output is read 34 | REGISTERED : boolean := true 35 | ); 36 | port( 37 | clk : in std_logic; 38 | resetn : in std_logic; 39 | 40 | in_data : in StreamType; 41 | in_valid : in std_logic; 42 | in_ready : out std_logic; 43 | 44 | out_data : out StreamType; 45 | out_valid : out std_logic; 46 | out_ready : in std_logic 47 | ); 48 | end stream_register_stage; 49 | 50 | architecture arch_imp of stream_register_stage is 51 | signal dataxDP, dataxDN : StreamType; 52 | signal validxDP, validxDN : std_logic; 53 | 54 | begin 55 | regs : process(clk) is 56 | begin 57 | if rising_edge(clk) then 58 | if resetn = '0' then 59 | dataxDP <= StreamType_default; 60 | validxDP <= '0'; 61 | else 62 | dataxDP <= dataxDN; 63 | validxDP <= validxDN; 64 | end if; 65 | end if; 66 | end process regs; 67 | 68 | control : process(dataxDP, in_data, in_valid, out_ready, validxDP) is 69 | begin 70 | dataxDN <= dataxDP; 71 | validxDN <= validxDP; 72 | 73 | in_ready <= out_ready; 74 | out_valid <= in_valid; 75 | out_data <= in_data; 76 | 77 | if REGISTERED then 78 | in_ready <= '0'; 79 | 80 | -- reset the register when it was read 81 | if validxDP = '1' and out_ready = '1' then 82 | dataxDN <= StreamType_default; 83 | validxDN <= '0'; 84 | end if; 85 | 86 | -- set the register when it was empty or when it is currently read 87 | if in_valid = '1' and (validxDP = '0' or (READY_BYPASS and out_ready = '1')) then 88 | dataxDN <= in_data; 89 | validxDN <= '1'; 90 | in_ready <= '1'; 91 | end if; 92 | 93 | out_valid <= validxDP; 94 | out_data <= dataxDP; 95 | end if; 96 | end process control; 97 | end arch_imp; 98 | -------------------------------------------------------------------------------- /hdl/framework/stream/stream_register_stage_fifo.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | 26 | --! FIFO for the internal stream type with two elements. 27 | --! 28 | --! The primary purpose of this two element FIFO is to provide an alternative 29 | --! two the register stage which cuts the critical path in forward and backward 30 | --! direction without loosing a cycle. 31 | entity stream_register_stage_fifo is 32 | port( 33 | clk : in std_logic; 34 | resetn : in std_logic; 35 | 36 | in_data : in StreamType; 37 | in_valid : in std_logic; 38 | in_ready : out std_logic; 39 | 40 | out_data : out StreamType; 41 | out_valid : out std_logic; 42 | out_ready : in std_logic 43 | ); 44 | end stream_register_stage_fifo; 45 | 46 | architecture arch_imp of stream_register_stage_fifo is 47 | signal left_input, left_output, right_input, right_output : StreamType; 48 | signal left_input_valid, right_input_valid, left_output_valid, right_output_valid : std_logic; 49 | signal left_input_ready, right_input_ready, left_output_ready, right_output_ready : std_logic; 50 | 51 | signal leftInputxDP, leftInputxDN, leftOutputxDP, leftOutputxDN : std_logic; 52 | begin 53 | 54 | regs : process(clk) is 55 | begin 56 | if rising_edge(clk) then 57 | if resetn = '0' then 58 | leftInputxDP <= '0'; 59 | leftOutputxDP <= '0'; 60 | else 61 | leftInputxDP <= leftInputxDN; 62 | leftOutputxDP <= leftOutputxDN; 63 | end if; 64 | end if; 65 | end process regs; 66 | 67 | comb : process(in_data, in_valid, out_ready, leftInputxDP, leftOutputxDP, 68 | right_output, right_output_valid, left_output, left_output_valid, 69 | left_input_ready, right_input_ready) is 70 | begin 71 | leftInputxDN <= leftInputxDP; 72 | leftOutputxDN <= leftOutputxDP; 73 | 74 | right_output_ready <= '0'; 75 | left_output_ready <= '0'; 76 | 77 | -- output 78 | if leftOutputxDP = '1' then 79 | out_data <= left_output; 80 | out_data.valid <= left_output_valid; 81 | out_valid <= left_output_valid; 82 | left_output_ready <= out_ready; 83 | if out_ready = '1' and left_output_valid = '1' then 84 | leftOutputxDN <= '0'; 85 | end if; 86 | else 87 | out_data <= right_output; 88 | out_data.valid <= right_output_valid; 89 | out_valid <= right_output_valid; 90 | right_output_ready <= out_ready; 91 | if out_ready = '1' and right_output_valid = '1' then 92 | leftOutputxDN <= '1'; 93 | end if; 94 | end if; 95 | 96 | -- input 97 | left_input <= StreamType_default; 98 | right_input <= StreamType_default; 99 | left_input_valid <= '0'; 100 | right_input_valid <= '0'; 101 | 102 | if leftInputxDP = '1' then 103 | left_input <= in_data; 104 | left_input_valid <= in_valid; 105 | in_ready <= left_input_ready; 106 | if left_input_ready = '1' then 107 | leftInputxDN <= '0'; 108 | end if; 109 | else 110 | right_input <= in_data; 111 | right_input_valid <= in_valid; 112 | in_ready <= right_input_ready; 113 | if right_input_ready = '1' then 114 | leftInputxDN <= '1'; 115 | end if; 116 | end if; 117 | end process comb; 118 | 119 | 120 | left : entity work.stream_register_stage 121 | generic map ( 122 | REGISTERED => true, 123 | READY_BYPASS => false 124 | ) 125 | port map ( 126 | clk => clk, 127 | resetn => resetn, 128 | 129 | in_data => left_input, 130 | in_valid => left_input_valid, 131 | in_ready => left_input_ready, 132 | 133 | out_data => left_output, 134 | out_valid => left_output_valid, 135 | out_ready => left_output_ready 136 | ); 137 | 138 | right : entity work.stream_register_stage 139 | generic map ( 140 | REGISTERED => true, 141 | READY_BYPASS => false 142 | ) 143 | port map ( 144 | clk => clk, 145 | resetn => resetn, 146 | 147 | in_data => right_input, 148 | in_valid => right_input_valid, 149 | in_ready => right_input_ready, 150 | 151 | out_data => right_output, 152 | out_valid => right_output_valid, 153 | out_ready => right_output_ready 154 | ); 155 | end arch_imp; 156 | -------------------------------------------------------------------------------- /hdl/framework/stream/stream_request_zero_initializer.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | use work.memsec_functions.all; 26 | 27 | --! Clears the full transaction when the first nonce/key block is zero. 28 | --! 29 | --! Using a zero nonce to identify uninitialized memory permits to lazily 30 | --! bootstrap the AE modes. 31 | entity stream_request_zero_initializer is 32 | port( 33 | clk : in std_logic; 34 | resetn : in std_logic; 35 | 36 | s_request : in StreamType; 37 | s_request_ready : out std_logic; 38 | 39 | m_request : out StreamType; 40 | m_request_ready : in std_logic 41 | ); 42 | end stream_request_zero_initializer; 43 | 44 | architecture behavioral of stream_request_zero_initializer is 45 | signal initRequestxDP, initRequestxDN : std_logic; 46 | signal inRequestxDP, inRequestxDN : std_logic; 47 | signal request_ready : std_logic; 48 | begin 49 | 50 | regs : process(clk) is 51 | begin 52 | if rising_edge(clk) then 53 | if resetn = '0' then 54 | initRequestxDP <= '0'; 55 | inRequestxDP <= '0'; 56 | else 57 | initRequestxDP <= initRequestxDN; 58 | inRequestxDP <= inRequestxDN; 59 | end if; 60 | end if; 61 | end process regs; 62 | 63 | comb : process(s_request, m_request_ready, request_ready, initRequestxDP, inRequestxDP) is 64 | begin 65 | initRequestxDN <= initRequestxDP; 66 | inRequestxDN <= inRequestxDP; 67 | 68 | m_request <= StreamType_default; 69 | request_ready <= '0'; 70 | 71 | if s_request.valid = '1' then 72 | m_request <= s_request; 73 | request_ready <= m_request_ready; 74 | 75 | if inRequestxDP = '0' then 76 | inRequestxDN <= '1'; 77 | initRequestxDN <= to_std_logic(unsigned(s_request.data) = 0); 78 | end if; 79 | 80 | if request_ready = '1' and unsigned(s_request.block_len) = 0 then 81 | inRequestxDN <= '0'; 82 | end if; 83 | 84 | if inRequestxDP = '1' and initRequestxDP = '1' then 85 | m_request.data <= (others => '0'); 86 | m_request.error <= '0'; 87 | end if; 88 | end if; 89 | end process comb; 90 | 91 | s_request_ready <= request_ready; 92 | 93 | end behavioral; 94 | -------------------------------------------------------------------------------- /hdl/framework/stream/stream_scheduler.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | 26 | --! Simple scheduler which forwards the slave ports to the master in a round robin manner. 27 | entity stream_scheduler is 28 | port( 29 | clk : in std_logic; 30 | resetn : in std_logic; 31 | 32 | s_request_1 : in StreamType; 33 | s_request_1_ready : out std_logic; 34 | 35 | s_request_2 : in StreamType; 36 | s_request_2_ready : out std_logic; 37 | 38 | m_request : out StreamType; 39 | m_request_ready : in std_logic 40 | ); 41 | end stream_scheduler; 42 | 43 | architecture arch_imp of stream_scheduler is 44 | signal last_1xDP, last_1xDN : std_logic; 45 | 46 | begin 47 | 48 | regs : process(clk) is 49 | begin 50 | if rising_edge(clk) then 51 | if resetn = '0' then 52 | last_1xDP <= '0'; 53 | else 54 | last_1xDP <= last_1xDN; 55 | end if; 56 | end if; 57 | end process regs; 58 | 59 | work : process(s_request_1, s_request_2, m_request_ready, last_1xDP) is 60 | variable request_1 : std_logic; 61 | begin 62 | m_request <= StreamType_default; 63 | s_request_1_ready <= '0'; 64 | s_request_2_ready <= '0'; 65 | 66 | last_1xDN <= last_1xDP; 67 | 68 | request_1 := '0'; 69 | 70 | -- by default, requests 1 is always forwarded when valid 71 | if s_request_1.valid = '1' then 72 | m_request <= s_request_1; 73 | s_request_1_ready <= m_request_ready; 74 | if s_request_1.last_request = '1' then 75 | request_1 := '1'; 76 | end if; 77 | end if; 78 | 79 | -- requests 2 is forwarded when it is valid and no request 1 should 80 | -- be performed, or when the last request was already a request 1 81 | if s_request_2.valid = '1' and 82 | (s_request_1.valid = '0' or last_1xDP = '1') then 83 | m_request <= s_request_2; 84 | s_request_2_ready <= m_request_ready; 85 | s_request_1_ready <= '0'; 86 | request_1 := '0'; 87 | end if; 88 | 89 | if m_request_ready = '1' then 90 | last_1xDN <= request_1; 91 | end if; 92 | end process work; 93 | 94 | end arch_imp; 95 | -------------------------------------------------------------------------------- /hdl/framework/util/data_dispatcher.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | use work.memsec_functions.all; 26 | 27 | --! Synchronization block which dispatches an input block to one of the available outputs. 28 | entity data_dispatcher is 29 | generic ( 30 | DISPATCH_WIDTH : integer := 2; 31 | DATA_WIDTH : integer := 128; 32 | REGISTERED : boolean := false 33 | ); 34 | port ( 35 | clk : in std_logic; 36 | resetn : in std_logic; 37 | 38 | in_data : in std_logic_vector(DATA_WIDTH-1 downto 0); 39 | in_valid : in std_logic; 40 | in_ready : out std_logic; 41 | 42 | out_data : out std_logic_vector(DATA_WIDTH*DISPATCH_WIDTH-1 downto 0); 43 | out_request : in std_logic_vector(DISPATCH_WIDTH-1 downto 0); 44 | out_valid : out std_logic_vector(DISPATCH_WIDTH-1 downto 0); 45 | out_ready : in std_logic_vector(DISPATCH_WIDTH-1 downto 0) 46 | ); 47 | end data_dispatcher; 48 | 49 | architecture Behavioral of data_dispatcher is 50 | signal valid_reg : std_logic_vector(DISPATCH_WIDTH-1 downto 0); 51 | signal ready_reg : std_logic_vector(DISPATCH_WIDTH-1 downto 0); 52 | signal request_reg : std_logic_vector(DISPATCH_WIDTH-1 downto 0); 53 | signal valid_out : std_logic_vector(DISPATCH_WIDTH-1 downto 0); 54 | begin 55 | 56 | valid_dispatch : entity work.valid_dispatcher 57 | generic map( 58 | WIDTH => DISPATCH_WIDTH 59 | ) 60 | port map( 61 | clk => clk, 62 | resetn => resetn, 63 | 64 | in_valid => in_valid, 65 | in_ready => in_ready, 66 | 67 | out_request => request_reg, 68 | out_valid => valid_reg, 69 | out_ready => ready_reg 70 | ); 71 | 72 | registers : for i in 0 to DISPATCH_WIDTH-1 generate 73 | reg : entity work.register_stage 74 | generic map( 75 | WIDTH => DATA_WIDTH, 76 | READY_BYPASS => true, 77 | REGISTERED => REGISTERED 78 | ) 79 | port map( 80 | clk => clk, 81 | resetn => resetn, 82 | 83 | in_data => in_data, 84 | in_valid => valid_reg(i), 85 | in_ready => ready_reg(i), 86 | 87 | out_data => out_data((i+1)*DATA_WIDTH-1 downto i*DATA_WIDTH), 88 | out_valid => valid_out(i), 89 | out_ready => out_ready(i) 90 | ); 91 | end generate registers; 92 | 93 | comb_reg : if REGISTERED generate 94 | request_reg <= not(valid_out); 95 | out_valid <= valid_out; 96 | end generate comb_reg; 97 | 98 | comb_noreg : if not(REGISTERED) generate 99 | request_reg <= out_request; 100 | out_valid <= valid_out; 101 | end generate comb_noreg; 102 | 103 | end Behavioral; 104 | -------------------------------------------------------------------------------- /hdl/framework/util/fifo.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | use work.memsec_functions.all; 26 | 27 | --! FIFO for standard logic vectors. 28 | entity fifo is 29 | generic( 30 | WIDTH : integer := 32; 31 | ELEMENTS : integer := 1 32 | ); 33 | port( 34 | clk : in std_logic; 35 | resetn : in std_logic; 36 | 37 | in_data : in std_logic_vector(WIDTH - 1 downto 0); 38 | in_valid : in std_logic; 39 | in_ready : out std_logic; 40 | in_full : out std_logic; 41 | 42 | out_data : out std_logic_vector(WIDTH - 1 downto 0); 43 | out_valid : out std_logic; 44 | out_ready : in std_logic 45 | ); 46 | end fifo; 47 | 48 | architecture arch_imp of fifo is 49 | type FifoArray is array(integer range <>) of std_logic_vector(WIDTH-1 downto 0); 50 | signal FifoxDP, FifoxDN : FifoArray(ELEMENTS-1 downto 0); 51 | 52 | signal IndexxDP, IndexxDN : std_logic_vector(log2_ceil(ELEMENTS) downto 0); 53 | 54 | begin 55 | regs : process(clk) is 56 | begin 57 | if rising_edge(clk) then 58 | if resetn = '0' then 59 | FifoxDP <= (others => (others => '0')); 60 | IndexxDP <= (others => '0'); 61 | else 62 | FifoxDP <= FifoxDN; 63 | IndexxDP <= IndexxDN; 64 | end if; 65 | end if; 66 | end process regs; 67 | 68 | comb : process(in_data, in_valid, out_ready, FifoxDP, IndexxDP) is 69 | variable vIndex : integer range 0 to ELEMENTS; 70 | begin 71 | FifoxDN <= FifoxDP; 72 | IndexxDN <= IndexxDP; 73 | 74 | in_ready <= '0'; 75 | out_valid <= '0'; 76 | out_data <= FifoxDP(0); 77 | 78 | vIndex := to_integer(unsigned(IndexxDP)); 79 | 80 | in_full <= '0'; 81 | if vIndex = ELEMENTS then 82 | in_full <= '1'; 83 | end if; 84 | 85 | -- output 86 | if vIndex > 0 then 87 | out_valid <= '1'; 88 | 89 | if out_ready = '1' then 90 | vIndex := vIndex - 1; 91 | FifoxDN(ELEMENTS-2 downto 0) <= FifoxDP(ELEMENTS-1 downto 1); 92 | FifoxDN(ELEMENTS-1) <= (others => '0'); 93 | end if; 94 | end if; 95 | 96 | if in_valid = '1' and vIndex < ELEMENTS then 97 | FifoxDN(vIndex) <= in_data; 98 | vIndex := vIndex + 1; 99 | in_ready <= '1'; 100 | end if; 101 | 102 | IndexxDN <= std_logic_vector(to_unsigned(vIndex, IndexxDP'length)); 103 | end process comb; 104 | end arch_imp; 105 | -------------------------------------------------------------------------------- /hdl/framework/util/prng.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | use work.memsec_functions.all; 26 | use work.keccak_package.all; 27 | 28 | --! Simple PRNG based on the Keccak permutation. 29 | entity prng is 30 | generic ( 31 | WIDTH : integer := 128 32 | ); 33 | port ( 34 | clk : in std_logic; 35 | resetn : in std_logic; 36 | 37 | random : out std_logic_vector(WIDTH-1 downto 0); 38 | random_valid : out std_logic; 39 | random_ready : in std_logic; 40 | 41 | random_init : in std_logic_vector(LANE_BITWIDTH*25-1 downto 0) 42 | ); 43 | end prng; 44 | 45 | architecture Behavioral of prng is 46 | constant RATE : integer := (8*LANE_BITWIDTH)*(LANE_BITWIDTH/8); 47 | constant STATE_INIT : std_logic_vector(1 downto 0) := "00"; 48 | constant STATE_PERMUTE : std_logic_vector(1 downto 0) := "01"; 49 | constant STATE_VALID : std_logic_vector(1 downto 0) := "11"; 50 | 51 | signal StatexDP, StatexDN : std_logic_vector(1 downto 0); 52 | 53 | signal KeccakOutxD : std_logic_vector(RATE-1 downto 0); 54 | signal KeccakInitxS, KeccakSqueezexS, KeccakFinishedxS : std_logic; 55 | signal KeccakZeroxS : std_logic; 56 | 57 | signal random_internal : std_logic_vector(RATE-1 downto 0); 58 | signal random_internal_valid, random_internal_ready : std_logic; 59 | begin 60 | 61 | keccak : entity work.keccak_parallel 62 | generic map ( 63 | UNROLLED_ROUNDS => 16/LANE_BITWIDTH, 64 | RATE => RATE, 65 | ROUNDS => 2*log2ceil(LANE_BITWIDTH)+12 66 | ) 67 | port map ( 68 | ClkxCI => clk, 69 | RstxRBI => resetn, 70 | BlockxDO => KeccakOutxD, 71 | BlockxDI => (others => '0'), 72 | IVxDI => random_init, 73 | 74 | StartInitxSI => KeccakInitxS, 75 | StartAbsorbxSI => '0', 76 | StartSqueezexSI => KeccakSqueezexS, 77 | PermutateDonexSO => KeccakFinishedxS 78 | ); 79 | 80 | random_internal <= KeccakOutxD; 81 | KeccakZeroxS <= '1' when KeccakOutxD = zeros(KeccakOutxD'length) else '0'; 82 | 83 | comb : process(KeccakFinishedxS, random_internal_ready, StatexDP, KeccakZeroxS) 84 | begin 85 | StatexDN <= StatexDP; 86 | 87 | KeccakInitxS <= '0'; 88 | KeccakSqueezexS <= '0'; 89 | 90 | random_internal_valid <= '0'; 91 | 92 | case StatexDP is 93 | when STATE_INIT => 94 | KeccakInitxS <= '1'; 95 | StatexDN <= STATE_PERMUTE; 96 | when STATE_PERMUTE => 97 | random_internal_valid <= KeccakFinishedxS and not(KeccakZeroxS); 98 | KeccakSqueezexS <= random_internal_ready; 99 | if KeccakFinishedxS = '1' then 100 | if random_internal_ready = '1' or KeccakZeroxS = '1' then 101 | KeccakSqueezexS <= '1'; 102 | else 103 | StatexDN <= STATE_VALID; 104 | end if; 105 | end if; 106 | when STATE_VALID => 107 | random_internal_valid <= '1'; 108 | if random_internal_ready = '1' then 109 | StatexDN <= STATE_PERMUTE; 110 | KeccakSqueezexS <= '1'; 111 | end if; 112 | when others => 113 | end case; 114 | 115 | end process comb; 116 | 117 | output_conversion : entity work.rate_converter 118 | generic map( 119 | IN_DATA_WIDTH => RATE, 120 | OUT_DATA_WIDTH => WIDTH, 121 | REGISTERED => false 122 | ) 123 | port map ( 124 | clk => clk, 125 | resetn => resetn, 126 | 127 | in_field_offset => (others => '0'), 128 | in_field_len => (others => '1'), 129 | 130 | in_last => '0', 131 | in_data => random_internal, 132 | in_valid => random_internal_valid, 133 | in_ready => random_internal_ready, 134 | 135 | out_data => random, 136 | out_last => open, 137 | out_field_offset => open, 138 | out_field_len => open, 139 | out_valid => random_valid, 140 | out_ready => random_ready 141 | ); 142 | 143 | regs : process(clk) is 144 | begin 145 | if rising_edge(clk) then 146 | if resetn = '0' then 147 | StatexDP <= STATE_INIT; 148 | else 149 | StatexDP <= StatexDN; 150 | end if; 151 | end if; 152 | end process regs; 153 | end Behavioral; 154 | -------------------------------------------------------------------------------- /hdl/framework/util/ready_synchronizer.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | use work.memsec_functions.all; 26 | 27 | --! Synchronization block for the standard valid and ready handshake signals. 28 | --! 29 | --! This block ensures that all consumers have acknowledged the reception of the 30 | --! block before the next one is accepted. 31 | entity ready_synchronizer is 32 | generic( 33 | OUT_WIDTH : integer := 1 34 | ); 35 | port( 36 | clk : in std_logic; 37 | resetn : in std_logic; 38 | 39 | in_valid : in std_logic; 40 | in_ready : out std_logic; 41 | 42 | out_valid : out std_logic_vector(OUT_WIDTH-1 downto 0); 43 | out_active : in std_logic_vector(OUT_WIDTH-1 downto 0); 44 | out_ready : in std_logic_vector(OUT_WIDTH-1 downto 0) 45 | ); 46 | end ready_synchronizer; 47 | 48 | architecture arch_imp of ready_synchronizer is 49 | signal ackxDP, ackxDN : std_logic_vector(OUT_WIDTH-1 downto 0); 50 | signal out_activexSP, out_activexSN : std_logic_vector(OUT_WIDTH-1 downto 0); 51 | 52 | signal in_readyxS : std_logic; 53 | signal out_validxS : std_logic_vector(OUT_WIDTH-1 downto 0); 54 | signal out_readyxS : std_logic_vector(OUT_WIDTH-1 downto 0); 55 | begin 56 | regs : process(clk) is 57 | begin 58 | if rising_edge(clk) then 59 | if resetn = '0' then 60 | out_activexSP <= (others => '0'); 61 | ackxDP <= (others => '0'); 62 | else 63 | out_activexSP <= out_activexSN; 64 | ackxDP <= ackxDN; 65 | end if; 66 | end if; 67 | end process regs; 68 | 69 | control : process(ackxDP, in_valid, out_validxS, out_readyxS, out_activexSP, out_active) is 70 | variable out_ack : std_logic_vector(OUT_WIDTH-1 downto 0); 71 | 72 | variable ackxV : std_logic_vector(OUT_WIDTH-1 downto 0); 73 | begin 74 | ackxV := ackxDP; 75 | 76 | if out_active /= out_activexSP then 77 | --ackxV := (others => '0'); 78 | ackxV := ackxV and out_active and out_activexSP; 79 | end if; 80 | 81 | in_readyxS <= '0'; 82 | out_validxS <= (others => '0'); 83 | 84 | -- helper signals 85 | out_ack := out_validxS and out_readyxS; 86 | 87 | -- generate the valid outputs 88 | if in_valid = '1' then 89 | out_validxS <= not(ackxV); 90 | end if; 91 | 92 | -- process ack signals from the output 93 | for I in 0 to OUT_WIDTH - 1 loop 94 | if out_ack(I) = '1' then 95 | ackxV(I) := '1'; 96 | end if; 97 | end loop; 98 | 99 | -- send ack to the input when all outputs have been acknowledged 100 | if ackxV = ones(OUT_WIDTH) then 101 | in_readyxS <= '1'; 102 | ackxV := (others => '0'); 103 | end if; 104 | 105 | ackxDN <= ackxV; 106 | out_activexSN <= out_active; 107 | end process control; 108 | 109 | in_ready <= in_readyxS; 110 | out_valid <= out_active and out_validxS; 111 | out_readyxS <= not(out_active) or out_ready; 112 | end arch_imp; 113 | -------------------------------------------------------------------------------- /hdl/framework/util/register_stage.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | 26 | --! Simple register stage for a standard logic vector. 27 | --! 28 | --! Enabling the READY_BYPASS permits to operate the register without 29 | --! introducing idle cycles. However, as a consequence, a critical path across 30 | --! the ready line is not prevented. 31 | entity register_stage is 32 | generic( 33 | WIDTH : integer := 32; 34 | READY_BYPASS : boolean := true; --! permit to directly write the register when the output is read 35 | REGISTERED : boolean := true 36 | ); 37 | port( 38 | clk : in std_logic; 39 | resetn : in std_logic; 40 | 41 | in_data : in std_logic_vector(WIDTH - 1 downto 0); 42 | in_valid : in std_logic; 43 | in_ready : out std_logic; 44 | 45 | out_data : out std_logic_vector(WIDTH - 1 downto 0); 46 | out_valid : out std_logic; 47 | out_ready : in std_logic 48 | ); 49 | end register_stage; 50 | 51 | architecture arch_imp of register_stage is 52 | signal dataxDP, dataxDN : std_logic_vector(WIDTH - 1 downto 0); 53 | signal validxDP, validxDN : std_logic; 54 | 55 | begin 56 | regs : process(clk) is 57 | begin 58 | if rising_edge(clk) then 59 | if resetn = '0' then 60 | dataxDP <= (others => '0'); 61 | validxDP <= '0'; 62 | else 63 | dataxDP <= dataxDN; 64 | validxDP <= validxDN; 65 | end if; 66 | end if; 67 | end process regs; 68 | 69 | control : process(dataxDP, in_data, in_valid, out_ready, validxDP) is 70 | begin 71 | dataxDN <= dataxDP; 72 | validxDN <= validxDP; 73 | 74 | in_ready <= out_ready; 75 | out_valid <= in_valid; 76 | out_data <= in_data; 77 | 78 | if REGISTERED then 79 | in_ready <= '0'; 80 | 81 | -- reset the register when it was read 82 | if validxDP = '1' and out_ready = '1' then 83 | dataxDN <= (others => '0'); 84 | validxDN <= '0'; 85 | end if; 86 | 87 | -- set the register when it was empty or when it is currently read 88 | if in_valid = '1' and (validxDP = '0' or (READY_BYPASS and out_ready = '1')) then 89 | dataxDN <= in_data; 90 | validxDN <= '1'; 91 | in_ready <= '1'; 92 | end if; 93 | 94 | out_valid <= validxDP; 95 | out_data <= dataxDP; 96 | end if; 97 | end process control; 98 | end arch_imp; 99 | -------------------------------------------------------------------------------- /hdl/framework/util/valid_dispatcher.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | use work.memsec_functions.all; 26 | 27 | --! Synchronization block which dispatches an input to one of the available outputs. 28 | entity valid_dispatcher is 29 | generic ( 30 | WIDTH : integer := 2 31 | ); 32 | port ( 33 | clk : in std_logic; 34 | resetn : in std_logic; 35 | 36 | in_valid : in std_logic; 37 | in_ready : out std_logic; 38 | 39 | out_request : in std_logic_vector(WIDTH-1 downto 0); 40 | out_valid : out std_logic_vector(WIDTH-1 downto 0); 41 | out_ready : in std_logic_vector(WIDTH-1 downto 0) 42 | ); 43 | end valid_dispatcher; 44 | 45 | architecture Behavioral of valid_dispatcher is 46 | signal ActiveSignalxDP, ActiveSignalxDN : std_logic_vector(log2_ceil(WIDTH)-1 downto 0); 47 | begin 48 | 49 | comb : process(out_request, out_ready, in_valid, ActiveSignalxDP) 50 | variable vRequest : std_logic; 51 | variable vRequestNo : integer; 52 | variable vActiveRequest : integer; 53 | variable i : integer; 54 | variable vOutRequests : std_logic_vector(out_request'range); 55 | begin 56 | ActiveSignalxDN <= ActiveSignalxDP; 57 | 58 | in_ready <= '0'; 59 | out_valid <= (others => '0'); 60 | 61 | vActiveRequest := to_integer(unsigned(ActiveSignalxDP)); 62 | vOutRequests := std_logic_vector(unsigned(out_request) rol vActiveRequest); 63 | vRequest := '0'; 64 | vRequestNo := 0; 65 | for i in 0 to WIDTH-1 loop 66 | if vOutRequests(i) = '1' then 67 | vRequest := '1'; 68 | vRequestNo := i; 69 | end if; 70 | end loop; 71 | vRequestNo := vRequestNo + vActiveRequest; 72 | if vRequestNo >= WIDTH then 73 | vRequestNo := vRequestNo-WIDTH; 74 | end if; 75 | 76 | if vRequest = '1' then 77 | out_valid(vRequestNo) <= in_valid; 78 | in_ready <= out_ready(vRequestNo); 79 | if out_ready(vRequestNo) = '1' then 80 | if vRequestNo = WIDTH-1 then 81 | ActiveSignalxDN <= (others => '0'); 82 | else 83 | ActiveSignalxDN <= std_logic_vector(to_unsigned(vRequestNo+1, log2_ceil(WIDTH))); 84 | end if; 85 | end if; 86 | end if; 87 | 88 | end process comb; 89 | 90 | regs : process(clk) is 91 | begin 92 | if rising_edge(clk) then 93 | if resetn = '0' then 94 | ActiveSignalxDP <= (others => '0'); 95 | else 96 | ActiveSignalxDP <= ActiveSignalxDN; 97 | end if; 98 | end if; 99 | end process regs; 100 | 101 | end Behavioral; 102 | -------------------------------------------------------------------------------- /hdl/framework/util/xilinx_TDP_RAM.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | use work.memsec_pkg.all; 25 | 26 | --! Dual port RAM for Xilinx FPGAs. 27 | entity xilinx_TDP_RAM is 28 | generic( 29 | ADDR_WIDTH : integer := 32; 30 | DATA_WIDTH : integer := 64; 31 | ENTRIES : integer := 32 -- number of entries (should be a power of 2) 32 | ); 33 | port( 34 | clk : in std_logic; -- clock 35 | 36 | addra : in std_logic_vector(ADDR_WIDTH-1 downto 0); -- Port A Address bus, width determined from RAM_DEPTH 37 | addrb : in std_logic_vector(ADDR_WIDTH-1 downto 0); -- Port B Address bus, width determined from RAM_DEPTH 38 | dina : in std_logic_vector(DATA_WIDTH-1 downto 0); -- Port A RAM input data 39 | dinb : in std_logic_vector(DATA_WIDTH-1 downto 0); -- Port B RAM input data 40 | 41 | wea : in std_logic; -- Port A Write enable 42 | web : in std_logic; -- Port B Write enable 43 | ena : in std_logic; -- Port A RAM Enable, for additional power savings, disable port when not in use 44 | enb : in std_logic; -- Port B RAM Enable, for additional power savings, disable port when not in use 45 | 46 | douta : out std_logic_vector(DATA_WIDTH-1 downto 0); -- Port A RAM output data 47 | doutb : out std_logic_vector(DATA_WIDTH-1 downto 0) -- Port B RAM output data 48 | ); 49 | end xilinx_TDP_RAM; 50 | 51 | architecture arch_imp of xilinx_TDP_RAM is 52 | type ram_type is array (ENTRIES-1 downto 0) of std_logic_vector (DATA_WIDTH-1 downto 0); -- 2D Array Declaration for RAM signal 53 | signal ram_data_a : std_logic_vector(DATA_WIDTH-1 downto 0); 54 | signal ram_data_b : std_logic_vector(DATA_WIDTH-1 downto 0); 55 | 56 | shared variable ram : ram_type := (others => (others => '0')); 57 | begin 58 | 59 | process(clk) 60 | begin 61 | if(clk'event and clk = '1') then 62 | if(ena = '1') then 63 | ram_data_a <= ram(to_integer(unsigned(addra))); 64 | if(wea = '1') then 65 | ram(to_integer(unsigned(addra))) := dina; 66 | end if; 67 | end if; 68 | end if; 69 | end process; 70 | 71 | process(clk) 72 | begin 73 | if(clk'event and clk = '1') then 74 | if(enb = '1') then 75 | ram_data_b <= ram(to_integer(unsigned(addrb))); 76 | if(web = '1') then 77 | ram(to_integer(unsigned(addrb))) := dinb; 78 | end if; 79 | end if; 80 | end if; 81 | end process; 82 | 83 | douta <= ram_data_a; 84 | doutb <= ram_data_b; 85 | 86 | end arch_imp; 87 | -------------------------------------------------------------------------------- /hdl/memsec_config.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | package memsec_config is 22 | constant DATASTREAM_DATA_WIDTH : integer := 64; 23 | end package; 24 | -------------------------------------------------------------------------------- /run_tests.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # MEMSEC - Framework for building transparent memory encryption and authentication solutions. 4 | # Copyright (C) 2017-2018 Graz University of Technology, IAIK 5 | # 6 | # This file is part of MEMSEC. 7 | # 8 | # MEMSEC is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # MEMSEC is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with MEMSEC. If not, see . 20 | 21 | import os 22 | import re 23 | import sys 24 | 25 | sys.path.append(os.path.join(os.path.dirname(__file__), "python")) 26 | from memsec import * 27 | 28 | module ='memsec' 29 | res = [] 30 | 31 | # determine the default backend which will be used for the tests 32 | infoOutput = subprocess.check_output(["make", "info"]).decode() 33 | backend = re.search('FLOW_BACKEND:\s+(\w+)', infoOutput).group(1) 34 | 35 | # Test the cryptographic primitives alone 36 | for r in [5,6,7]: 37 | res += runTest(module, {'ROUNDS': r}, {'FLOW_SIM_TOP': 'tb_qarma'}) 38 | res += runTest(module, {}, {'FLOW_SIM_TOP': 'tb_prince'}) 39 | res += runTest(module, {}, {'FLOW_SIM_TOP': 'tb_aes'}) 40 | res[-1]['ERROR'] = not res[-1]['ERROR'] # the AES test is currently expected to fail 41 | for r in [1,2,3,6]: 42 | res += runTest(module, {'UNROLED_ROUNDS': r}, {'FLOW_SIM_TOP': 'tb_ascon'}) 43 | 44 | # Test the different pipelines 45 | # ghdl is currently not supported 46 | if backend != "ghdl": 47 | generics = {'SIMULATION_ITERATIONS': 50} 48 | 49 | # PLAIN 50 | res += runTest(module,merge_dicts(generics, {'CRYPTO_CONFIG': 0,'BLOCKS_PER_SECTOR': 1})) 51 | 52 | # ASCON 53 | res += runTest(module,merge_dicts(generics, {'CRYPTO_CONFIG': 1,'DATA_BLOCK_SIZE': 32})) 54 | 55 | # ASCON TREE 56 | res += runTest(module,merge_dicts(generics, {'CRYPTO_CONFIG': 2,'TREE_ROOTS': 1,'TREE_ARITY': 8,'DATA_BLOCK_SIZE': 64})) 57 | 58 | # Prince ECB 59 | res += runTest(module,merge_dicts(generics, {'CRYPTO_CONFIG': 3,'BLOCKS_PER_SECTOR': 4})) 60 | 61 | # AES ECB 62 | res += runTest(module,merge_dicts(generics, {'CRYPTO_CONFIG': 4,'BLOCKS_PER_SECTOR': 2})) 63 | 64 | # Prince CBC 65 | res += runTest(module,merge_dicts(generics, {'CRYPTO_CONFIG': 5,'BLOCKS_PER_SECTOR': 4})) 66 | 67 | # AES CBC 68 | res += runTest(module,merge_dicts(generics, {'CRYPTO_CONFIG': 6,'BLOCKS_PER_SECTOR': 2})) 69 | 70 | # Prince XTS 71 | res += runTest(module,merge_dicts(generics, {'CRYPTO_CONFIG': 7,'BLOCKS_PER_SECTOR': 4})) 72 | 73 | # AES XTS 74 | res += runTest(module,merge_dicts(generics, {'CRYPTO_CONFIG': 8,'BLOCKS_PER_SECTOR': 2})) 75 | 76 | # MEAS 77 | localGenerics = merge_dicts(generics, {'CRYPTO_CONFIG': 9,'TREE_ROOTS': 1,'TREE_ARITY': 4,'DATA_BLOCK_SIZE': 64}) 78 | res += runTest(module,localGenerics) 79 | res += runTest(module,localGenerics,{'DATASTREAM_DATA_WIDTH': 128}) 80 | 81 | # MEAS ECB 82 | localGenerics = merge_dicts(generics, {'CRYPTO_CONFIG': 10,'TREE_ROOTS': 1,'TREE_ARITY': 4,'DATA_BLOCK_SIZE': 64}) 83 | res += runTest(module,localGenerics) 84 | res += runTest(module,localGenerics,{'DATASTREAM_DATA_WIDTH': 128}) 85 | 86 | sys.exit(printSummary(res)) 87 | -------------------------------------------------------------------------------- /tb/axi_block_memory/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !*.xci 4 | -------------------------------------------------------------------------------- /tb/tb_aes.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library IEEE; 22 | use IEEE.STD_LOGIC_1164.all; 23 | use work.tb_utils_pkg.all; 24 | 25 | entity tb_aes is 26 | generic( 27 | ENTITY_NAME : string := "tb_aes"; 28 | CLK_PERIOD : time := 5.0 ns 29 | ); 30 | end tb_aes; 31 | 32 | architecture Behavioral of tb_aes is 33 | signal ClkxC : std_logic := '0'; 34 | signal RstxRB : std_logic; 35 | 36 | signal KeyxD, KeyInvxD : std_logic_vector(127 downto 0); 37 | signal MessagexD : std_logic_vector(127 downto 0); 38 | signal MessageVerifyxD : std_logic_vector(127 downto 0); 39 | signal CiphertextxD : std_logic_vector(127 downto 0); 40 | signal ExpCiphertextxD : std_logic_vector(127 downto 0); 41 | 42 | signal PlainValidxS, PlainReadyxS : std_logic; 43 | signal EncryptionValidxS, EncryptionReadyxS : std_logic; 44 | signal DecryptionValidxS, DecryptionReadyxS : std_logic; 45 | begin 46 | -- Generate clock and reset 47 | ClkxC <= not ClkxC after CLK_PERIOD; 48 | RstxRB <= '0', '1' after 20 ns; 49 | 50 | inst_enc_aes : entity work.aes128_hs 51 | port map( 52 | ClkxCI => ClkxC, 53 | RstxRBI => RstxRB, 54 | KeyxDI => KeyxD, 55 | DataxDI => MessagexD, 56 | DataxDO => CiphertextxD, 57 | EncryptxSI => '1', 58 | in_ready => PlainReadyxS, 59 | in_valid => PlainValidxS, 60 | out_ready => EncryptionReadyxS, 61 | out_valid => EncryptionValidxS 62 | ); 63 | 64 | inst_dec_aes : entity work.aes128_hs 65 | port map( 66 | ClkxCI => ClkxC, 67 | RstxRBI => RstxRB, 68 | KeyxDI => KeyInvxD, 69 | DataxDI => CiphertextxD, 70 | DataxDO => MessageVerifyxD, 71 | EncryptxSI => '0', 72 | in_ready => EncryptionReadyxS, 73 | in_valid => EncryptionValidxS, 74 | out_ready => DecryptionReadyxS, 75 | out_valid => DecryptionValidxS 76 | ); 77 | 78 | rw_testcase : process 79 | variable error_occured : boolean := false; 80 | type testvector_t is array (0 to 3) of std_logic_vector(127 downto 0); 81 | variable message_v : testvector_t := (x"80000000000000000000000000000000", x"ffffffffffffffffffffffffffffffff", x"00000000000000000000000000000000", x"00000000000000000000000000000000"); 82 | variable key_v : testvector_t := (x"00000000000000000000000000000000", x"00000000000000000000000000000000", x"80000000000000000000000000000000", x"ffffffffffffffffffffffffffffffff"); 83 | variable keyInv_v : testvector_t := (x"b4ef5bcb3e92e21123e951cf6f8f188e", x"b4ef5bcb3e92e21123e951cf6f8f188e", x"b5b125173ecce2cd22e951136f8f1852", x"d60a3588e472f07b82d2d7858cd7c326"); 84 | variable cipher_v : testvector_t := (x"3ad78e726c1ec02b7ebfe92b23d9ec34", x"3f5b8cc9ea855a0afa7347d23e8d664e", x"0edd33d3c621e546455bd8ba1418bec8", x"a1f6258c877d5fcd8964484538bfc92c"); 85 | begin 86 | wait until rising_edge(RstxRB); 87 | DecryptionReadyxS <= '0'; 88 | for I in 0 to message_v'length-1 loop 89 | KeyxD <= key_v(I); 90 | KeyInvxD <= keyInv_v(I); 91 | MessagexD <= message_v(I); 92 | ExpCiphertextxD <= cipher_v(I); 93 | PlainValidxS <= '1'; 94 | 95 | wait until PlainReadyxS = '1' and rising_edge(ClkxC); 96 | PlainValidxS <= '0'; 97 | 98 | wait until EncryptionValidxS = '1' and falling_edge(ClkxC); 99 | if CiphertextxD /= ExpCiphertextxD then 100 | report "ERROR: Encryption failed. Ciphertext mismatch."; 101 | error_occured := true; 102 | end if; 103 | 104 | wait until DecryptionValidxS = '1' and falling_edge(ClkxC); 105 | if MessageVerifyxD /= MessagexD then 106 | report "ERROR: Decryption failed. Plaintext mismatch."; 107 | error_occured := true; 108 | end if; 109 | DecryptionReadyxS <= '1'; 110 | 111 | wait until DecryptionValidxS = '0' and falling_edge(ClkxC); 112 | DecryptionReadyxS <= '0'; 113 | end loop; 114 | 115 | if error_occured then 116 | write_tb_fail(ENTITY_NAME); 117 | report "Simulation failed" severity failure; 118 | else 119 | write_tb_success(ENTITY_NAME); 120 | report "Simulation succeeded" severity failure; 121 | end if; 122 | end process; 123 | end Behavioral; 124 | -------------------------------------------------------------------------------- /tb/tb_prince.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library IEEE; 22 | use IEEE.STD_LOGIC_1164.all; 23 | use work.tb_utils_pkg.all; 24 | 25 | entity tb_prince is 26 | generic( 27 | ENTITY_NAME : string := "tb_prince"; 28 | CLK_PERIOD : time := 5.0 ns 29 | ); 30 | end tb_prince; 31 | 32 | architecture Behavioral of tb_prince is 33 | signal ClkxC : std_logic := '0'; 34 | signal RstxRB : std_logic; 35 | 36 | signal Key0xD, Key1xD : std_logic_vector(63 downto 0); 37 | signal MessagexD : std_logic_vector(63 downto 0); 38 | signal MessageVerifyxD : std_logic_vector(63 downto 0); 39 | signal CiphertextxD : std_logic_vector(63 downto 0); 40 | signal ExpCiphertextxD : std_logic_vector(63 downto 0); 41 | 42 | signal PlainValidxS, PlainReadyxS : std_logic; 43 | signal EncryptionValidxS, EncryptionReadyxS : std_logic; 44 | signal DecryptionValidxS, DecryptionReadyxS : std_logic; 45 | begin 46 | -- Generate clock and reset 47 | ClkxC <= not ClkxC after CLK_PERIOD; 48 | RstxRB <= '0', '1' after 20 ns; 49 | 50 | inst_enc_prince : entity work.prince 51 | generic map( 52 | DECRYPTION => false 53 | ) 54 | port map( 55 | ClkxCI => ClkxC, 56 | RstxRBI => RstxRB, 57 | Key0xDI => Key0xD, 58 | Key1xDI => Key1xD, 59 | MessagexDI => MessagexD, 60 | CiphertextxDO => CiphertextxD, 61 | in_ready => PlainReadyxS, 62 | in_valid => PlainValidxS, 63 | out_ready => EncryptionReadyxS, 64 | out_valid => EncryptionValidxS 65 | ); 66 | 67 | inst_dec_prince : entity work.prince 68 | generic map( 69 | DECRYPTION => true 70 | ) 71 | port map( 72 | ClkxCI => ClkxC, 73 | RstxRBI => RstxRB, 74 | Key0xDI => Key0xD, 75 | Key1xDI => Key1xD, 76 | MessagexDI => CiphertextxD, 77 | CiphertextxDO => MessageVerifyxD, 78 | in_ready => EncryptionReadyxS, 79 | in_valid => EncryptionValidxS, 80 | out_ready => DecryptionReadyxS, 81 | out_valid => DecryptionValidxS 82 | ); 83 | 84 | rw_testcase : process 85 | variable error_occured : boolean := false; 86 | type testvector_t is array (0 to 4) of std_logic_vector(63 downto 0); 87 | variable message_v : testvector_t := (x"0000000000000000", x"ffffffffffffffff", x"0000000000000000", x"0000000000000000", x"0123456789abcdef"); 88 | variable key0_v : testvector_t := (x"0000000000000000", x"0000000000000000", x"ffffffffffffffff", x"0000000000000000", x"0000000000000000"); 89 | variable key1_v : testvector_t := (x"0000000000000000", x"0000000000000000", x"0000000000000000", x"ffffffffffffffff", x"fedcba9876543210"); 90 | variable cipher_v : testvector_t := (x"818665aa0d02dfda", x"604ae6ca03c20ada", x"9fb51935fc3df524", x"78a54cbe737bb7ef", x"ae25ad3ca8fa9ccf"); 91 | begin 92 | wait until rising_edge(RstxRB); 93 | DecryptionReadyxS <= '0'; 94 | for I in 0 to message_v'length-1 loop 95 | Key0xD <= key0_v(I); 96 | Key1xD <= key1_v(I); 97 | MessagexD <= message_v(I); 98 | ExpCiphertextxD <= cipher_v(I); 99 | PlainValidxS <= '1'; 100 | 101 | wait until PlainReadyxS = '1' and rising_edge(ClkxC); 102 | PlainValidxS <= '0'; 103 | 104 | wait until EncryptionValidxS = '1' and falling_edge(ClkxC); 105 | if CiphertextxD /= ExpCiphertextxD then 106 | report "ERROR: Encryption failed. Ciphertext mismatch."; 107 | error_occured := true; 108 | end if; 109 | 110 | wait until DecryptionValidxS = '1' and falling_edge(ClkxC); 111 | if MessageVerifyxD /= MessagexD then 112 | report "ERROR: Decryption failed. Plaintext mismatch."; 113 | error_occured := true; 114 | end if; 115 | DecryptionReadyxS <= '1'; 116 | 117 | wait until DecryptionValidxS = '0' and falling_edge(ClkxC); 118 | DecryptionReadyxS <= '0'; 119 | end loop; 120 | 121 | if error_occured then 122 | write_tb_fail(ENTITY_NAME); 123 | report "Simulation failed" severity failure; 124 | else 125 | write_tb_success(ENTITY_NAME); 126 | report "Simulation succeeded" severity failure; 127 | end if; 128 | end process; 129 | end Behavioral; 130 | -------------------------------------------------------------------------------- /tb/tb_qarma.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library IEEE; 22 | use IEEE.STD_LOGIC_1164.all; 23 | use work.tb_utils_pkg.all; 24 | 25 | entity tb_qarma is 26 | generic( 27 | ENTITY_NAME : string := "tb_qarma"; 28 | CLK_PERIOD : time := 5.0 ns; 29 | ROUNDS : integer := 6 30 | ); 31 | end tb_qarma; 32 | 33 | architecture Behavioral of tb_qarma is 34 | signal ClkxC : std_logic := '0'; 35 | signal RstxRB : std_logic; 36 | 37 | signal KeyxD : std_logic_vector(127 downto 0); 38 | signal TweakxD : std_logic_vector(63 downto 0); 39 | signal MessagexD : std_logic_vector(63 downto 0); 40 | signal MessageVerifyxD : std_logic_vector(63 downto 0); 41 | signal CiphertextxD : std_logic_vector(63 downto 0); 42 | signal ExpCiphertextxD : std_logic_vector(63 downto 0); 43 | 44 | signal EnryptionValidxS, EnryptionReadyxS : std_logic; 45 | signal DecryptionValidxS : std_logic; 46 | begin 47 | -- Generate clock and reset 48 | ClkxC <= not ClkxC after CLK_PERIOD; 49 | RstxRB <= '0', '1' after 20 ns; 50 | 51 | inst_enc_qarma : entity work.qarma 52 | generic map( 53 | DECRYPTION => false, 54 | ROUNDS => ROUNDS 55 | ) 56 | port map( 57 | ClkxCI => ClkxC, 58 | RstxRBI => RstxRB, 59 | KeyxDI => KeyxD, 60 | TweakxDI => TweakxD, 61 | MessagexDI => MessagexD, 62 | CiphertextxDO => CiphertextxD, 63 | 64 | in_ready => open, 65 | in_valid => '1', 66 | out_ready => EnryptionReadyxS, 67 | out_valid => EnryptionValidxS 68 | ); 69 | 70 | 71 | inst_dec_qarma : entity work.qarma 72 | generic map( 73 | DECRYPTION => true, 74 | ROUNDS => ROUNDS 75 | ) 76 | port map( 77 | ClkxCI => ClkxC, 78 | RstxRBI => RstxRB, 79 | KeyxDI => KeyxD, 80 | TweakxDI => TweakxD, 81 | MessagexDI => CiphertextxD, 82 | CiphertextxDO => MessageVerifyxD, 83 | 84 | in_ready => EnryptionReadyxS, 85 | in_valid => EnryptionValidxS, 86 | out_ready => '1', 87 | out_valid => DecryptionValidxS 88 | ); 89 | 90 | rw_testcase : process 91 | variable error_occured : boolean := false; 92 | begin 93 | wait until rising_edge(RstxRB); 94 | 95 | KeyxD <= x"84be85ce9804e94bec2802d4e0a488e9"; 96 | MessagexD <= x"fb623599da6e8127"; 97 | TweakxD <= x"477d469dec0b8762"; 98 | 99 | case ROUNDS is 100 | when 5 => ExpCiphertextxD <= x"544b0ab95bda7c3a"; 101 | when 6 => ExpCiphertextxD <= x"a512dd1e4e3ec582"; 102 | when 7 => ExpCiphertextxD <= x"edf67ff370a483f2"; 103 | when others => 104 | write_tb_fail(ENTITY_NAME); 105 | report "Test Vector is unknown" severity failure; 106 | end case; 107 | 108 | wait until EnryptionValidxS = '1' and falling_edge(ClkxC); 109 | if CiphertextxD /= ExpCiphertextxD then 110 | report "ERROR: Encryption failed. Ciphertext mismatch."; 111 | error_occured := true; 112 | end if; 113 | 114 | wait until DecryptionValidxS = '1' and falling_edge(ClkxC); 115 | if MessageVerifyxD /= MessagexD then 116 | report "ERROR: Decryption failed. Plaintext mismatch."; 117 | error_occured := true; 118 | end if; 119 | 120 | if error_occured then 121 | write_tb_fail(ENTITY_NAME); 122 | report "Simulation failed" severity failure; 123 | else 124 | write_tb_success(ENTITY_NAME); 125 | report "Simulation succeeded" severity failure; 126 | end if; 127 | end process; 128 | end Behavioral; 129 | -------------------------------------------------------------------------------- /tb/tb_utils_pkg.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- MEMSEC - Framework for building transparent memory encryption and authentication solutions. 3 | -- Copyright (C) 2017 Graz University of Technology, IAIK 4 | -- 5 | -- This file is part of MEMSEC. 6 | -- 7 | -- MEMSEC is free software: you can redistribute it and/or modify 8 | -- it under the terms of the GNU General Public License as published by 9 | -- the Free Software Foundation, either version 3 of the License, or 10 | -- (at your option) any later version. 11 | -- 12 | -- MEMSEC is distributed in the hope that it will be useful, 13 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | -- GNU General Public License for more details. 16 | -- 17 | -- You should have received a copy of the GNU General Public License 18 | -- along with MEMSEC. If not, see . 19 | -- 20 | 21 | library ieee; 22 | use ieee.std_logic_1164.all; 23 | use ieee.numeric_std.all; 24 | 25 | library std; 26 | use std.textio.all; 27 | 28 | 29 | package tb_utils_pkg is 30 | type AxiMemoryType is array (0 to 511) of std_logic_vector(32-1 downto 0); 31 | -- Converts std_logic_vector to hex string 32 | function to_hstring (value : std_logic_vector) return string; 33 | -- Writes success message that testbench succeeds 34 | procedure write_tb_success(filename : in string); 35 | -- Writes error message that testbench failed 36 | procedure write_tb_fail(filename : in string); 37 | end package; 38 | 39 | package body tb_utils_pkg is 40 | 41 | function to_hstring (value : std_logic_vector) return string is 42 | constant ne : integer := (value'length+3)/4; 43 | variable pad : std_logic_vector(0 to (ne*4 - value'length) - 1); 44 | variable ivalue : std_logic_vector(0 to ne*4 - 1); 45 | variable result : string(1 to ne); 46 | variable quad : std_logic_vector(0 to 3); 47 | begin 48 | if value'length < 1 then 49 | return "Error"; 50 | else 51 | if value (value'left) = 'Z' then 52 | pad := (others => 'Z'); 53 | else 54 | pad := (others => '0'); 55 | end if; 56 | ivalue := pad & value; 57 | for i in 0 to ne-1 loop 58 | quad := To_X01Z(ivalue(4*i to 4*i+3)); 59 | case quad is 60 | when x"0" => result(i+1) := '0'; 61 | when x"1" => result(i+1) := '1'; 62 | when x"2" => result(i+1) := '2'; 63 | when x"3" => result(i+1) := '3'; 64 | when x"4" => result(i+1) := '4'; 65 | when x"5" => result(i+1) := '5'; 66 | when x"6" => result(i+1) := '6'; 67 | when x"7" => result(i+1) := '7'; 68 | when x"8" => result(i+1) := '8'; 69 | when x"9" => result(i+1) := '9'; 70 | when x"A" => result(i+1) := 'A'; 71 | when x"B" => result(i+1) := 'B'; 72 | when x"C" => result(i+1) := 'C'; 73 | when x"D" => result(i+1) := 'D'; 74 | when x"E" => result(i+1) := 'E'; 75 | when x"F" => result(i+1) := 'F'; 76 | when "ZZZZ" => result(i+1) := 'Z'; 77 | when others => result(i+1) := 'X'; 78 | end case; 79 | end loop; 80 | return result; 81 | end if; 82 | end function to_hstring; 83 | 84 | 85 | procedure write_tb_success(filename : in string) is 86 | file outfile : text is out filename & "_log.txt"; 87 | variable outline : line; 88 | begin 89 | write(outline, 1); 90 | writeline(outfile, outline); 91 | end procedure; 92 | 93 | 94 | procedure write_tb_fail(filename : in string) is 95 | file outfile : text is out filename & "_log.txt"; 96 | variable outline : line; 97 | begin 98 | write(outline, 0); 99 | writeline(outfile, outline); 100 | end procedure; 101 | 102 | end package body; 103 | --------------------------------------------------------------------------------