diff --git a/cryptolib/selftest-heap/.gitignore b/cryptolib/selftest-heap/.gitignore
new file mode 100644
index 00000000..e9e7c568
--- /dev/null
+++ b/cryptolib/selftest-heap/.gitignore
@@ -0,0 +1,3 @@
+bin/
+*.swp
+main
diff --git a/cryptolib/selftest-heap/Makefile b/cryptolib/selftest-heap/Makefile
new file mode 100644
index 00000000..e3384ec4
--- /dev/null
+++ b/cryptolib/selftest-heap/Makefile
@@ -0,0 +1,76 @@
+#-------------------------------------------------------------------------
+# NMAKE-Makefile
+#-------------------------------------------------------------------------
+PROJ=dynamic memory tracking example programs
+UTIL1=dmt-utils
+PROG1=dmt-realloc
+PROG2=dmt-access
+
+#-------------------------------------------------------------------------
+# Compiler-Flags General
+#-------------------------------------------------------------------------
+CC := gcc
+CFLAGS := -g -O0 -Wall -Werror
+LDD := ldd
+LIBS :=
+INCLUDE := -I.
+ifeq ($(MAKECMDGOALS),debug)
+ CFLAGS += -DDEBUG
+endif
+
+#-------------------------------------------------------------------------
+# Objects and Output
+#-------------------------------------------------------------------------
+DIR_OUTPUT := bin
+DIR_UTILS := $(DIR_OUTPUT)/utils
+DIR_PROGS := $(DIR_OUTPUT)/programs
+UTILS := $(DIR_UTILS)/$(UTIL1)
+UTILS_OBJ := $(patsubst %, %.o, $(UTILS))
+PROGRAMS := $(DIR_PROGS)/$(PROG1) $(DIR_PROGS)/$(PROG2)
+
+#-------------------------------------------------------------------------
+# Main-Targets
+#-------------------------------------------------------------------------
+.PHONY: all help
+
+all: output $(UTILS) $(PROGRAMS)
+debug: all
+
+output:
+ @if [ -d $(DIR_OUTPUT) ]; then \
+ echo "dir $(DIR_OUTPUT) already exists."; \
+ else \
+ mkdir -p $(DIR_UTILS); \
+ mkdir -p $(DIR_PROGS); \
+ fi
+
+clean:
+ -$(RM) -r $(DIR_OUTPUT)
+
+help:
+ @echo
+ @echo "$(PROJ)"
+ @echo
+ @echo "make [all]"
+ @echo "make [help|clean]"
+ @echo
+ @echo "Targets : help - Shows this text."
+ @echo " all - Compiles the project."
+ @echo " debug - Enable debug output."
+ @echo " clean - Cleans up output files."
+ @echo
+
+#-------------------------------------------------------------------------
+# Sub-Targets
+#-------------------------------------------------------------------------
+
+# build utils
+$(DIR_UTILS)/%: %.c
+ $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@.o
+
+# build programs
+$(DIR_PROGS)/%: %.c
+ $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@.o
+ $(CC) $(INCLUDE) -o $@ $@.o $(UTILS_OBJ) $(LIBS)
+ $(LDD) $@
+
diff --git a/cryptolib/selftest-heap/data_run.sh b/cryptolib/selftest-heap/data_run.sh
new file mode 100755
index 00000000..9fee801f
--- /dev/null
+++ b/cryptolib/selftest-heap/data_run.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+set -e
+
+OPTIONS="--phase1 --phase2 --export --parallel"
+export RESULTDIR=results
+
+pushd ${BASH_SOURCE%/*}
+./framework.sh ${OPTIONS} basic 8
+popd
diff --git a/cryptolib/selftest-heap/dmt-access.c b/cryptolib/selftest-heap/dmt-access.c
new file mode 100644
index 00000000..c4000d0b
--- /dev/null
+++ b/cryptolib/selftest-heap/dmt-access.c
@@ -0,0 +1,149 @@
+/************************************************************************
+ * Copyright (C) 2017-2018 IAIK TU Graz and Fraunhofer AISEC
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ ***********************************************************************/
+
+/**
+ * @file dmt-access.c
+ * @brief Dynamic memory tracking simple access selftest.
+ * @license This project is released under the GNU GPLv3+ License.
+ * @author See AUTHORS file.
+ * @version 0.3
+ */
+
+/***********************************************************************/
+
+#include
+#include
+#include
+#include
+#include "dmt-utils.h"
+
+/***********************************************************************/
+
+#define LARGE_INIT 524288
+
+/***********************************************************************/
+
+void help();
+
+/***********************************************************************/
+
+uint16_t ALLOC_TYPE = 0;
+uint16_t USE_ALTERNATIVE = 0;
+
+/***********************************************************************/
+
+/***
+ * Main function.
+ *
+ * @param argc number of command line arguments
+ * @param argv command line arguments
+ * @return 0=success, else=error
+ */
+int main(int argc, char **argv)
+{
+ /* init */
+ int err = 1;
+ uint8_t key = 0;
+ FILE *kfile = NULL;
+ unsigned char str[2];
+ void *obj = NULL;
+ size_t objsize = 0;
+ char lookup = 0;
+
+ /* check args */
+ if (argc != 4) {
+ help();
+ return (1);
+ }
+
+ /* get cmdline args */
+ sscanf(argv[1], "%hu", &ALLOC_TYPE);
+ sscanf(argv[2], "%hu", &USE_ALTERNATIVE);
+
+ /* read key */
+ kfile = fopen(argv[3], "r");
+ if (!kfile) {
+ printf("[Error] Unable to open key file!\n");
+ return (1);
+ }
+ if (fread(&str, 1, 2, kfile) != 2) {
+ printf("[Error] Unable to read key file!\n");
+ return (1);
+ }
+ key = (str[0] % 32 + 9) % 25;
+ fclose(kfile);
+
+ /* ini rnd */
+ srand(getpid() + time(NULL));
+
+ /* allocate object */
+ objsize = LARGE_INIT;
+ obj = dmt_allocate(objsize, ALLOC_TYPE, USE_ALTERNATIVE);
+ if (INVALIDPTR(obj)) {
+ printf("[Error] Unable to allocate object!\n");
+ return (1);
+ }
+
+ /* debug info */
+#ifdef DEBUG
+ printf("Max rand() value: %u\n", RAND_MAX);
+ printf("Allocate type: %s\n", (ALLOC_TYPE ? "mmap" : "malloc"));
+ printf("Use alternative: %s\n", (USE_ALTERNATIVE ? "yes" : "no"));
+ printf("Key nibble: %x\n", key);
+ printf("Object size: %zu\n", objsize);
+ printf("Object address: %0*"PRIxPTR"\n", (int)(sizeof(void*) * 2), (uintptr_t)obj);
+#endif
+
+ /* key-dependent data access */
+ /* triggers H_pos(b), H_addr */
+ /* expected leak stats: */
+ /* difference: 1 */
+ /* data leak generic: 1 */
+ /* data leak specific: 1 (key byte nibble high) */
+ lookup = ((uint8_t*)obj)[key];
+ fprintf(stdin, "%d\n", lookup);
+
+ /* key-independent data access */
+ /* expected leak stats: */
+ /* difference = 1 */
+ /* data leak generic = 0 */
+ /* data leak specific = 0 */
+ key = rand() % 16;
+ lookup = ((uint8_t*)obj)[key];
+ fprintf(stdin, "%d\n", lookup);
+
+ /* deallocate */
+ err = dmt_deallocate(obj, objsize, ALLOC_TYPE);
+
+ /* done */
+ return (err);
+}
+
+/***********************************************************************/
+
+/***
+ * Print help text.
+ */
+void help()
+{
+ printf("Usage:\n");
+ printf(" dmt-access \n\n");
+ printf(" ....... 0: malloc & co, else: mmap & co\n");
+ printf(" ........ 0: standard (malloc,mmap private), else: alternative (calloc,mmap shared)\n");
+ printf(" ... file containing secret key byte as hex string\n");
+}
+
diff --git a/cryptolib/selftest-heap/dmt-realloc.c b/cryptolib/selftest-heap/dmt-realloc.c
new file mode 100644
index 00000000..537565d4
--- /dev/null
+++ b/cryptolib/selftest-heap/dmt-realloc.c
@@ -0,0 +1,598 @@
+/************************************************************************
+ * Copyright (C) 2017-2018 IAIK TU Graz and Fraunhofer AISEC
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ ***********************************************************************/
+
+/**
+ * @file dmt-realloc.c
+ * @brief Dynamic memory tracking re-allocation selftest.
+ * @license This project is released under the GNU GPLv3+ License.
+ * @author See AUTHORS file.
+ * @version 0.3
+ */
+
+/***********************************************************************/
+
+#define _GNU_SOURCE
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "dmt-utils.h"
+
+/***********************************************************************/
+
+#define MIN_OBJ_NUMBER 13
+#define SMALL_INIT 512
+#define MEDIUM_INIT 49152
+#define LARGE_INIT 524288
+#define HUGE_INIT 5242880
+
+/***********************************************************************/
+
+void help();
+void* allocate(size_t size, int id);
+void* reallocate(void* obj, size_t oldsize, size_t newsize, int id);
+int deallocate(void* obj, size_t size, int id);
+int fill(uint16_t number, void** obj);
+int change(uint16_t number, void** obj);
+int readaddr(void** addr, uint16_t number);
+int test(uint16_t number, uint8_t key);
+#ifdef DEBUG
+void printstats(uint16_t number, void** obj);
+void printaddr(uint16_t number, void** addr);
+#endif
+
+/***********************************************************************/
+
+uint16_t ALLOC_TYPE = 0;
+uint16_t USE_ALTERNATIVE = 0;
+uint16_t LEAKAGE_POINTS = 0;
+size_t* ALLOC_SIZES = NULL;
+uint8_t* ALLOC_CHANGED = NULL;
+
+/***********************************************************************/
+
+uint8_t DUMMY_OBJ = 0;
+
+/***********************************************************************/
+
+/***
+ * Main function.
+ *
+ * @param argc number of command line arguments
+ * @param argv command line arguments
+ * @return 0=success, else=error
+ */
+int main(int argc, char **argv)
+{
+ /* init */
+ int err;
+ uint16_t number;
+ uint8_t key;
+ unsigned char str[2];
+ FILE *kfile = NULL;
+
+ /* check args */
+ if (argc != 6) {
+ help();
+ return (1);
+ }
+
+ /* get cmdline args */
+ sscanf(argv[1], "%hu", &ALLOC_TYPE);
+ sscanf(argv[2], "%hu", &USE_ALTERNATIVE);
+ sscanf(argv[3], "%hu", &LEAKAGE_POINTS);
+ sscanf(argv[4], "%hu", &number);
+
+ /* read key */
+ kfile = fopen(argv[5], "r");
+ if (!kfile) {
+ printf("[Error] Unable to open key file!\n");
+ return (1);
+ }
+ if (fread(&str, 1, 2, kfile) != 2) {
+ printf("[Error] Unable to read key file!\n");
+ return (1);
+ }
+ key = (str[0] % 32 + 9) % 25;
+ fclose(kfile);
+
+ /* ini rnd */
+ srand(getpid() + time(NULL));
+#ifdef DEBUG
+ printf("Max rand() value: %u\n", RAND_MAX);
+ printf("Allocate type: %s\n", (ALLOC_TYPE ? "mmap" : "malloc"));
+ printf("Use alternative: %s\n", (USE_ALTERNATIVE ? "yes" : "no"));
+ printf("Leakage points: %s\n", (LEAKAGE_POINTS ? "2" : "1"));
+ printf("Number of objects: %u\n", number);
+ printf("Key nibble: %x\n", key);
+#endif
+
+ /* sanity check */
+ if (number < MIN_OBJ_NUMBER) {
+ printf("[Error] Number of objects too small. Please use %u or above.\n", MIN_OBJ_NUMBER);
+ return (1);
+ }
+
+ /* test */
+ err = test(number, key);
+
+ /* done */
+ return (err);
+}
+
+/***********************************************************************/
+
+/***
+ * Allocate a new object with bytes.
+ * If is non-zero, the
+ * alternative will be used (e.g. calloc or
+ * mmap shared).
+ *
+ * @param size number of bytes to allocate
+ * @param id object id
+ * @return allocated object pointer
+ */
+void* allocate(size_t size, int id)
+{
+ /* init */
+ void* obj = NULL;
+
+ /* allocate */
+ obj = dmt_allocate(size, ALLOC_TYPE, USE_ALTERNATIVE);
+ if (INVALIDPTR(obj)) { return(obj); }
+
+ /* keep record */
+ if (id >= 0) {
+ ALLOC_SIZES[id] = size;
+ ALLOC_CHANGED[id] = 0;
+ }
+
+ /* done */
+ return (obj);
+}
+
+/***
+ * Re-allocate an object to bytes.
+ *
+ * @param obj object to reallocate
+ * @param oldsize previous object size
+ * @param newsize new number of bytes to allocate
+ * @param id object id
+ * @return allocated object pointer
+ */
+void* reallocate(void* obj, size_t oldsize, size_t newsize, int id)
+{
+ /* init */
+ void* objnew = NULL;
+
+ /* re-allocate */
+ objnew = dmt_reallocate(obj, oldsize, newsize, ALLOC_TYPE);
+ if (INVALIDPTR(objnew)) { return(objnew); }
+
+ /* keep record */
+ if (id >= 0) {
+ ALLOC_SIZES[id] = newsize;
+ if (objnew != obj) {
+ ALLOC_CHANGED[id] = 1;
+ }
+ }
+
+ /* done */
+ return (objnew);
+}
+
+/***
+ * Free resources of an object.
+ *
+ * @param obj object to free
+ * @param size allocation size in bytes
+ * @param id object id
+ * @return 0: success, else: error
+ */
+int deallocate(void* obj, size_t size, int id)
+{
+ /* init */
+ int res = 0;
+
+ /* free */
+ res = dmt_deallocate(obj, size, ALLOC_TYPE);
+
+ /* clear record */
+ if (id >= 0) {
+ ALLOC_SIZES[id] = 0;
+ ALLOC_CHANGED[id] = 0;
+ }
+
+ /* done */
+ return (res);
+}
+
+/***********************************************************************/
+
+/***
+ * Fill an array with objects of different sizes:
+ * 50% ... < 1kB
+ * 20% ... < 100kB
+ * 22% ... < 1MB
+ * 8% ... < 10MB
+ *
+ * @param number number of objects to create
+ * @param obj array to store objects in
+ * @return 0: success, else: error
+ */
+int fill(uint16_t number, void** obj)
+{
+ /* init */
+ int i;
+ int huge = number * 0.08;
+ int large = number * 0.22;
+ int medium = number * 0.20;
+ int small = (number - huge - large - medium);
+
+ /* debug */
+#ifdef DEBUG
+ printf("*******************************\n");
+ printf("Allocating:\n");
+ printf(" Small: %d\n", small);
+ printf(" Medium: %d\n", medium);
+ printf(" Large: %d\n", large);
+ printf(" Huge: %d\n", huge);
+#endif
+
+ /* fill */
+ for (i = 0; i < small; i++) {
+ obj[i] = allocate(SMALL_INIT, i);
+ if (INVALIDPTR(obj[i])) {
+ printf("[Error] Could not allocate small object #%d!\n", i);
+ return (1);
+ }
+ }
+ for (; i < (small+medium); i++) {
+ obj[i] = allocate(MEDIUM_INIT, i);
+ if (INVALIDPTR(obj[i])) {
+ printf("[Error] Could not allocate medium object #%d!\n", i-small);
+ return (1);
+ }
+ }
+ for (; i < (small+medium+large); i++) {
+ obj[i] = allocate(LARGE_INIT, i);
+ if (INVALIDPTR(obj[i])) {
+ printf("[Error] Could not allocate large object #%d!\n", i-small-medium);
+ return (1);
+ }
+ }
+ for (; i < (small+medium+large+huge); i++) {
+ obj[i] = allocate(HUGE_INIT, i);
+ if (INVALIDPTR(obj[i])) {
+ printf("[Error] Could not allocate huge object #%d!\n", i-small-medium-large);
+ return (1);
+ }
+ }
+
+ /* done */
+ return (0);
+}
+
+/***********************************************************************/
+
+/***
+ * Change the size of objects within an array:
+ * 50% ... < 1kB
+ * 20% ... < 100kB
+ * 22% ... < 1MB
+ * 8% ... < 10MB
+ *
+ * @param number number of objects to change
+ * @param obj array containing objects
+ * @return 0: success, else: error
+ */
+int change(uint16_t number, void** obj)
+{
+ /* init */
+ int i,c,p;
+ int huge = number * 0.08;
+ int large = number * 0.22;
+ int medium = number * 0.20;
+ int small = (number - huge - large - medium);
+
+ /* change */
+ for (i = 0; i < number;) {
+ c = rand() % 4;
+ p = 0;
+ switch (c) {
+ case 0:
+ if (small > 0) {
+ small--;
+ obj[i] = reallocate(obj[i], ALLOC_SIZES[i], SMALL, i);
+ p = 1;
+ }
+ break;
+ case 1:
+ if (medium > 0) {
+ medium--;
+ obj[i] = reallocate(obj[i], ALLOC_SIZES[i], MEDIUM, i);
+ p = 1;
+ }
+ break;
+ case 2:
+ if (large > 0) {
+ large--;
+ obj[i] = reallocate(obj[i], ALLOC_SIZES[i], LARGE, i);
+ p = 1;
+ }
+ break;
+ case 3:
+ if (huge > 0) {
+ huge--;
+ obj[i] = reallocate(obj[i], ALLOC_SIZES[i], HUGE, i);
+ p = 1;
+ }
+ break;
+ }
+ if (INVALIDPTR(obj[i])) {
+ printf("[Error] Could not reallocate object #%d!\n", i);
+ return (1);
+ }
+ if (p) {i++;}
+ }
+
+ /* done */
+ return (0);
+}
+
+/***********************************************************************/
+
+/***
+ * Read from the addresses in the array.
+ *
+ * @param addr array containing addresses
+ * @param number number of addresses
+ * @return helper variable
+ */
+int readaddr(void** addr, uint16_t number)
+{
+ int i,tmp;
+ tmp = 1;
+ for (i = 0; i < number; i++) {
+ tmp ^= ((uint8_t*)addr[i])[0];
+ }
+ return (tmp);
+}
+
+/***********************************************************************/
+
+#ifdef DEBUG
+/***
+ * Print statistics of malloc and the objects
+ * contained in the given array.
+ *
+ * @param number number of objects
+ * @param obj array containing objects
+ */
+void printstats(uint16_t number, void** obj)
+{
+ /* total memory */
+ struct mallinfo mi = mallinfo();
+ printf("*******************************\n");
+ printf("Allocated bytes: %d\n", mi.arena);
+
+ /* objects entries */
+ int i;
+ for (i = 0; i < number; i++) {
+ printf(" %*d: %*zu -- %s\n", 5, i, 10, ALLOC_SIZES[i], (ALLOC_CHANGED[i] ? "changed" : "_"));
+ }
+}
+#endif
+
+/***********************************************************************/
+
+#ifdef DEBUG
+/***
+ * Print the addresses contained in
+ * the given array.
+ *
+ * @param number number of objects
+ * @param addr array containing addresses
+ */
+void printaddr(uint16_t number, void** addr)
+{
+ printf("*******************************\n");
+ printf("Addresses:\n");
+ int i;
+ for (i = 0; i < number; i++) {
+ printf(" %0*"PRIxPTR"\n", (int)(sizeof(void*) * 2), (uintptr_t)addr[i]);
+ }
+}
+#endif
+
+/***********************************************************************/
+
+/***
+ * Creates memory objects of sizes between
+ * few bytes to several megabytes. The objects will
+ * be resized once.
+ *
+ * @param number number of memory objects
+ * @param key secret key byte
+ * @return 0: success, else: error
+ */
+int test(uint16_t number, uint8_t key)
+{
+ /* init */
+ int i,j;
+ int err = 1;
+ void** objects = NULL;
+ void** addr_before = NULL;
+ void** addr_after = NULL;
+ void** addr_current = NULL;
+
+ /* create helper structures */
+ ALLOC_SIZES = allocate(number * sizeof(size_t), -1);
+ if (INVALIDPTR(ALLOC_SIZES)) {
+ printf("[Error] Could not allocate size array!\n");
+ goto cleanup;
+ }
+ ALLOC_CHANGED = allocate(number * sizeof(uint8_t), -1);
+ if (INVALIDPTR(ALLOC_CHANGED)) {
+ printf("[Error] Could not allocate change array!\n");
+ goto cleanup;
+ }
+ addr_before = allocate(number * sizeof(void*), -1);
+ if (INVALIDPTR(addr_before)) {
+ printf("[Error] Could not allocate address array 'before'!\n");
+ goto cleanup;
+ }
+ addr_after = allocate(number * sizeof(void*), -1);
+ if (INVALIDPTR(addr_after)) {
+ printf("[Error] Could not allocate address array 'after'!\n");
+ goto cleanup;
+ }
+
+ /* create objects */
+ objects = allocate(number * sizeof(void*), -1);
+ if (INVALIDPTR(objects)) {
+ printf("[Error] Could not allocate object array!\n");
+ goto cleanup;
+ }
+ if (fill(number, objects)) {
+ printf("[Error] Could not fill object array!\n");
+ goto cleanup;
+ }
+#ifdef DEBUG
+ printstats(number, objects);
+#endif
+
+ /* fill address array */
+ for (i = 0; i < number; i++) {
+ if (rand() & 0x1) {
+ addr_before[i] = (void*)&DUMMY_OBJ;
+ } else {
+ addr_before[i] = (void*)((uint8_t*)(objects[i]) + key);
+ }
+ }
+#ifdef DEBUG
+ printaddr(number, addr_before);
+#endif
+
+ /* two leakage points */
+ if (LEAKAGE_POINTS) {
+ /* access objects */
+ fprintf(stdin, "%d\n", readaddr(addr_before, number));
+
+ /* realloc objects */
+ if (change(number, objects)) {
+ printf("[Error] Could not re-allocate objects!\n");
+ goto cleanup;
+ }
+#ifdef DEBUG
+ printstats(number, objects);
+#endif
+
+ /* fill address array */
+ for (i = 0; i < number; i++) {
+ if (addr_before[i] != (void*)&DUMMY_OBJ) {
+ addr_after[i] = (void*)&DUMMY_OBJ;
+ } else {
+ addr_after[i] = (void*)((uint8_t*)(objects[i]) + key);
+ }
+ }
+#ifdef DEBUG
+ printaddr(number, addr_after);
+#endif
+
+ /* access objects */
+ fprintf(stdin, "%d\n", readaddr(addr_after, number));
+ }
+ /* one leakage point */
+ else {
+ addr_current = addr_before;
+ for (j = 0; j < 2; j++) {
+ /* access objects */
+ fprintf(stdin, "%d\n", readaddr(addr_current, number));
+ if (j == 1) { break; }
+
+ /* realloc objects */
+ if (change(number, objects)) {
+ printf("[Error] Could not re-allocate objects!\n");
+ goto cleanup;
+ }
+#ifdef DEBUG
+ printstats(number, objects);
+#endif
+
+ /* fill address array */
+ for (i = 0; i < number; i++) {
+ if (addr_before[i] != (void*)&DUMMY_OBJ) {
+ addr_after[i] = (void*)&DUMMY_OBJ;
+ } else {
+ addr_after[i] = (void*)((uint8_t*)(objects[i]) + key);
+ }
+ }
+#ifdef DEBUG
+ printaddr(number, addr_after);
+#endif
+ addr_current = addr_after;
+ }
+ addr_current = NULL;
+ }
+
+ /* done */
+ err = 0;
+cleanup:
+ if (!INVALIDPTR(objects)) {
+ for (i = 0; i < number; i++) {
+ if (!INVALIDPTR(objects[i])) {
+ deallocate(objects[i], ALLOC_SIZES[i], i);
+ objects[i] = NULL;
+ }
+ }
+ deallocate(objects, number * sizeof(void*), -1);
+ }
+ if (!INVALIDPTR(ALLOC_SIZES)) {
+ deallocate(ALLOC_SIZES, number * sizeof(size_t), -1);
+ }
+ if (!INVALIDPTR(ALLOC_CHANGED)) {
+ deallocate(ALLOC_CHANGED, number * sizeof(uint8_t), -1);
+ }
+ if (!INVALIDPTR(addr_before)) {
+ deallocate(addr_before, number * sizeof(void*), -1);
+ }
+ if (!INVALIDPTR(addr_after)) {
+ deallocate(addr_after, number * sizeof(void*), -1);
+ }
+ return (err);
+}
+
+/***********************************************************************/
+
+/***
+ * Print help text.
+ */
+void help()
+{
+ printf("Usage:\n");
+ printf(" dmt-realloc \n\n");
+ printf(" ....... 0: malloc & co, else: mmap & co\n");
+ printf(" ........ 0: standard (malloc,mmap private), else: alternative (calloc,mmap shared)\n");
+ printf(" ..... 0: one leakage point, else: two leakage points\n");
+ printf(" ..... # of objects to create, 16-bit uint\n");
+ printf(" ... file containing secret key byte as hex string\n");
+}
+
diff --git a/cryptolib/selftest-heap/dmt-utils.c b/cryptolib/selftest-heap/dmt-utils.c
new file mode 100644
index 00000000..a3fa1f24
--- /dev/null
+++ b/cryptolib/selftest-heap/dmt-utils.c
@@ -0,0 +1,137 @@
+/************************************************************************
+ * Copyright (C) 2017-2018 IAIK TU Graz and Fraunhofer AISEC
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ ***********************************************************************/
+
+/**
+ * @file dmt-utils.c
+ * @brief Dynamic memory tracking helper functions.
+ * @license This project is released under the GNU GPLv3+ License.
+ * @author See AUTHORS file.
+ * @version 0.3
+ */
+
+/***********************************************************************/
+
+#define _GNU_SOURCE
+#include
+#include
+#include "dmt-utils.h"
+
+/***********************************************************************/
+
+/***
+ * Allocate a new object with bytes.
+ * If is zero, malloc is used. Otherwise,
+ * mmap is used. If is non-zero, a slight
+ * variant of the allocation call is used.
+ *
+ * @param size number of bytes to allocate
+ * @param type 0: malloc, else: mmap
+ * @param alt 0: standard call, else: alternative call
+ * @return allocated object pointer
+ */
+void* dmt_allocate(size_t size, int type, int alt)
+{
+ /* init */
+ void* obj = NULL;
+
+ /* mmap */
+ if (type) {
+ if (alt) {
+ obj = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+ } else {
+ obj = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ }
+ if (INVALIDPTR(obj)) { return(obj); }
+ memset(obj, 0, size);
+ }
+ /* malloc */
+ else {
+ if (alt) {
+ obj = calloc(1, size);
+ } else {
+ obj = malloc(size);
+ if (INVALIDPTR(obj)) { return(obj); }
+ memset(obj, 0, size);
+ }
+ }
+
+ /* done */
+ return (obj);
+}
+
+/***********************************************************************/
+
+/***
+ * Re-allocate an object to bytes.
+ * If is zero, realloc is used. Otherwise,
+ * mremap is used.
+ *
+ * @param obj object to reallocate
+ * @param oldsize previous object size
+ * @param newsize new number of bytes to allocate
+ * @param type 0: realloc, else: mremap
+ * @return re-allocated object pointer
+ */
+void* dmt_reallocate(void* obj, size_t oldsize, size_t newsize, int type)
+{
+ /* init */
+ void* objnew;
+
+ /* mremap */
+ if (type) {
+ objnew = mremap(obj, oldsize, newsize, MREMAP_MAYMOVE);
+ }
+ /* realloc */
+ else {
+ objnew = realloc(obj, newsize);
+ }
+ if (INVALIDPTR(objnew)) { return(objnew); }
+
+ /* done */
+ return (objnew);
+}
+
+/***********************************************************************/
+
+/***
+ * Free resources of an object.
+ * If is zero, free is used. Otherwise,
+ * munmap is used.
+ *
+ * @param obj object to free
+ * @param size allocation size in bytes
+ * @param type 0: free, else: munmap
+ * @return 0: success, else: error
+ */
+int dmt_deallocate(void* obj, size_t size, int type)
+{
+ /* init */
+ int res = 0;
+
+ /* munmap */
+ if (type) {
+ res = munmap(obj, size);
+ }
+ /* free */
+ else {
+ free(obj);
+ }
+
+ /* done */
+ return (res);
+}
+
diff --git a/cryptolib/selftest-heap/dmt-utils.h b/cryptolib/selftest-heap/dmt-utils.h
new file mode 100644
index 00000000..1878e4ce
--- /dev/null
+++ b/cryptolib/selftest-heap/dmt-utils.h
@@ -0,0 +1,86 @@
+/************************************************************************
+ * Copyright (C) 2017-2018 IAIK TU Graz and Fraunhofer AISEC
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ ***********************************************************************/
+
+/**
+ * @file dmt-utils.h
+ * @brief Dynamic memory tracking helper functions.
+ * @license This project is released under the GNU GPLv3+ License.
+ * @author See AUTHORS file.
+ * @version 0.3
+ */
+
+/***********************************************************************/
+
+#include
+#include
+
+/***********************************************************************/
+
+#define RANDRANGE(M,N) (M + (N - M) * (float)rand() / (float)RAND_MAX)
+#define INVALIDPTR(p) (p == NULL || p == (void*)-1)
+
+/***********************************************************************/
+
+#define SMALL RANDRANGE(16,1024)
+#define MEDIUM RANDRANGE(1024,100*1024)
+#define LARGE RANDRANGE(100*1024,1*1024*1024)
+#define HUGE RANDRANGE(1*1024*1024,10*1024*1024)
+
+/***********************************************************************/
+
+/***
+ * Allocate a new object with bytes.
+ * If is zero, malloc is used. Otherwise,
+ * mmap is used. If is non-zero, a slight
+ * variant of the allocation call is used.
+ *
+ * @param size number of bytes to allocate
+ * @param type 0: malloc, else: mmap
+ * @param alt 0: standard call, else: alternative call
+ * @return allocated object pointer
+ */
+void* dmt_allocate(size_t size, int type, int alt);
+
+/***********************************************************************/
+
+/***
+ * Re-allocate an object to bytes.
+ * If is zero, realloc is used. Otherwise,
+ * mremap is used.
+ *
+ * @param obj object to reallocate
+ * @param oldsize previous object size
+ * @param newsize new number of bytes to allocate
+ * @param type 0: realloc, else: mremap
+ * @return re-allocated object pointer
+ */
+void* dmt_reallocate(void* obj, size_t oldsize, size_t newsize, int type);
+
+/***********************************************************************/
+
+/***
+ * Free resources of an object.
+ * If is zero, free is used. Otherwise,
+ * munmap is used.
+ *
+ * @param obj object to free
+ * @param size allocation size in bytes
+ * @param type 0: free, else: munmap
+ * @return 0: success, else: error
+ */
+int dmt_deallocate(void* obj, size_t size, int type);
+
diff --git a/cryptolib/selftest-heap/framework.sh b/cryptolib/selftest-heap/framework.sh
new file mode 100755
index 00000000..057e301c
--- /dev/null
+++ b/cryptolib/selftest-heap/framework.sh
@@ -0,0 +1,135 @@
+#!/bin/bash
+
+#########################################################################
+# DO NOT CHANGE: Preparing DATA
+#------------------------------------------------------------------------
+source "${DATA_COMMON}/DATA_init.sh" || { echo "source data.sh first!" && exit 1; }
+#########################################################################
+
+#------------------------------------------------------------------------
+# Specify your framework settings used by DATA
+#------------------------------------------------------------------------
+
+# The name of the framework. Do not use spaces or special characters.
+export FRAMEWORK=selftest-heap
+
+# The file containing all supported algorithms
+export TARGETFILE=targets.txt
+
+# The number of measurements for difference detection (phase1)
+export PHASE1_TRACES=3
+
+# The number of constant keys for generic tests (phase2)
+# Make sure that PHASE2_FIXEDKEYS <= PHASE1_TRACES
+export PHASE2_FIXEDKEYS=3
+
+# The number of measurements per constant key for generic tests (phase2)
+export PHASE2_TRACES=100
+
+# The number of measurements for specific tests (phase3)
+export PHASE3_TRACES=300
+
+# (Optional) Additional flags for the pintool. Supported flags are:
+# -main Start recording at function . Note that the
+# symbol must exist, otherwise this will yield empty traces!
+# -heap Trace heap allocations and replace heap addresses with
+# relative offset
+export PINTOOL_ARGS="-heap"
+
+#------------------------------------------------------------------------
+# Implement your framework-specific callbacks
+#------------------------------------------------------------------------
+#
+# Globally available environment variables:
+# $FRAMEWORK The framework name
+# $BASEDIR The absolute directory path of this script
+# $DATA_COMMON The absolute directory for common DATA scripts
+# $DATA_LEAKAGE_MODELS The absolute directory for DATA leakage models
+#
+# Available for cb_genkey, cb_pre_run, cb_run_command, cb_post_run
+# $ALGO The currently tested algo
+#
+# Available for cb_pre_run, cb_run_command, cb_post_run
+# $ENVFILE
+
+export BINARY=${PWD}/bin/programs/dmt-realloc
+
+# The leakage model of phase 3.
+# See ${DATA_LEAKAGE_MODELS} for all options.
+export SPECIFIC_LEAKAGE_CALLBACK=${DATA_LEAKAGE_MODELS}/sym_nibble_high.py
+
+# DATA callback for setting up the framework to analyze. This callback
+# is invoked once inside the current directory before analysis starts.
+# Implement framework-specific tasks here like framework compilation.
+function cb_prepare_framework {
+ make -s
+}
+
+# DATA callback for generating keys. This callback is invoked every
+# time a new key is needed. Implement key generation according to
+# your algorithm and store the generated key inside a file named $2.
+#
+# $1 ... key file name
+function cb_genkey {
+ "${DATA_COMMON}"/genkey.py "${KEYBYTES}" > "$1"
+ RES=$((RES + $?))
+}
+
+# DATA callback for custom commands that are executed immediately before
+# the algorithm is profiled. It is executed in a temporary directory
+# which contains the keyfile $1 and ${ENVFILE}.
+#
+# If 'cb_run_command' needs any other files, copy them to ${PWD}.
+#
+# $1 ... key file name
+function cb_pre_run {
+ log_verbose "running with key $1"
+}
+
+# DATA callback for the main invocation of the tested algorithm.
+# It shall return the bash command to execute as string. It is
+# executed inside a temporary directory with a clean environment.
+# If you need special files or environment variables set, specify
+# them in cb_pre_run.
+#
+# $1 ... key file name
+function cb_run_command {
+ echo "${BINARY} 0 0 0 16 $1"
+}
+
+# DATA callback for custom commands that are executed immediately after
+# the algorithm is profiled. It is executed in a temporary directory.
+# You can cleanup any custom files generated by your algorithm.
+#
+# $1 ... key file name
+function cb_post_run {
+ :
+}
+
+# DATA callback for preparing an individual algorithm. It shall:
+# 1. Parse the next algorithm from the commandline string of all algorithms
+# and set up anything necessary for analyzing this algorithm.
+# If the algorithm needs additional parameters (like key sizes),
+# increase $SHIFT accordingly.
+# 2. Configure $WORKDIR, which will create a subdirectory holding all
+# intermediate files generated by the algorithm and the results.
+# Do not use an absolute path!
+#
+# $* ... algorithm string from the commandline
+function cb_prepare_algo {
+ ALGO=$1
+ # key bits
+ PARAM=$2
+ SHIFT=$((SHIFT+1))
+ KEYBYTES=$(( PARAM / 8 ))
+
+ WORKDIR="$FRAMEWORK/$ALGO/$PARAM"
+}
+
+#########################################################################
+# DO NOT CHANGE: Running DATA's commandline parser
+#------------------------------------------------------------------------
+DATA_parse "$@"
+#------------------------------------------------------------------------
+# DO NOT ADD CODE AFTER THIS LINE
+#########################################################################
diff --git a/cryptolib/selftest-heap/targets.txt b/cryptolib/selftest-heap/targets.txt
new file mode 100644
index 00000000..338a62e4
--- /dev/null
+++ b/cryptolib/selftest-heap/targets.txt
@@ -0,0 +1 @@
+basic 8