diff --git a/sys/hashes/sha256.c b/sys/hashes/sha256.c
index aef002c73a60c298a8749b18d6ef62d07ec0ede3..51d8cab73f4c51450d2a73e29e271e33d9e6bc57 100644
--- a/sys/hashes/sha256.c
+++ b/sys/hashes/sha256.c
@@ -1,6 +1,7 @@
 /*-
  * Copyright 2005 Colin Percival
  * Copyright 2013 Christian Mehlis & René Kijewski
+ * Copyright 2016 Martin Landsmann <martin.landsmann@haw-hamburg.de>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -37,11 +38,13 @@
  * @author      Colin Percival
  * @author      Christian Mehlis
  * @author      Rene Kijewski
+ * @author      Martin Landsmann
  *
  * @}
  */
 
 #include <string.h>
+#include <assert.h>
 
 #include "hashes/sha256.h"
 #include "board.h"
@@ -318,3 +321,140 @@ const unsigned char *hmac_sha256(const unsigned char *key,
 
     return result;
 }
+
+/**
+ * @brief helper to compute sha256 inplace for the given buffer
+ *
+ * @param[in, out] element the buffer to compute a sha256 and store it back to it
+ *
+ */
+static inline void sha256_inplace(unsigned char element[SHA256_DIGEST_LENGTH])
+{
+    sha256_context_t ctx;
+    sha256_init(&ctx);
+    sha256_update(&ctx, element, SHA256_DIGEST_LENGTH);
+    sha256_final(element, &ctx);
+}
+
+unsigned char *sha256_chain(const unsigned char *seed, size_t seed_length,
+                            size_t elements, unsigned char *tail_element)
+{
+    unsigned char tmp_element[SHA256_DIGEST_LENGTH];
+
+    /* assert if no sha256-chain can be created */
+    assert(elements >= 2);
+
+    /* 1st iteration */
+    sha256(seed, seed_length, tmp_element);
+
+    /* perform consecutive iterations minus the first one */
+    for (size_t i = 0; i < (elements - 1); ++i) {
+        sha256_inplace(tmp_element);
+    }
+
+    /* store the result */
+    memcpy(tail_element, tmp_element, SHA256_DIGEST_LENGTH);
+
+    return tail_element;
+}
+
+unsigned char *sha256_chain_with_waypoints(const unsigned char *seed,
+                                           size_t seed_length,
+                                           size_t elements,
+                                           unsigned char *tail_element,
+                                           sha256_chain_idx_elm_t *waypoints,
+                                           size_t *waypoints_length)
+{
+    /* assert if no sha256-chain can be created */
+    assert(elements >= 2);
+
+    /* assert to prevent division by 0 */
+    assert(*waypoints_length > 0);
+
+    /* assert if no waypoints can be created */
+    assert(*waypoints_length > 1);
+
+    /* if we have enough space we store the whole chain */
+    if (*waypoints_length >= elements) {
+        /* 1st iteration */
+        sha256(seed, seed_length, waypoints[0].element);
+        waypoints[0].index = 0;
+
+        /* perform consecutive iterations starting at index 1*/
+        for (size_t i = 1; i < elements; ++i) {
+            sha256_context_t ctx;
+            sha256_init(&ctx);
+            sha256_update(&ctx, waypoints[(i - 1)].element, SHA256_DIGEST_LENGTH);
+            sha256_final(waypoints[i].element, &ctx);
+            waypoints[i].index = i;
+        }
+
+        /* store the result */
+        memcpy(tail_element, waypoints[(elements - 1)].element, SHA256_DIGEST_LENGTH);
+        *waypoints_length = (elements - 1);
+
+        return tail_element;
+    }
+    else {
+        unsigned char tmp_element[SHA256_DIGEST_LENGTH];
+        size_t waypoint_streak = (elements / *waypoints_length);
+
+        /* 1st waypoint iteration */
+        sha256(seed, seed_length, tmp_element);
+        for (size_t i = 1; i < waypoint_streak; ++i) {
+                sha256_inplace(tmp_element);
+        }
+        memcpy(waypoints[0].element, tmp_element, SHA256_DIGEST_LENGTH);
+        waypoints[0].index = (waypoint_streak - 1);
+
+        /* index of the current computed element in the chain */
+        size_t index = (waypoint_streak - 1);
+
+        /* consecutive waypoint iterations */
+        size_t j = 1;
+        for (; j < *waypoints_length; ++j) {
+            for (size_t i = 0; i < waypoint_streak; ++i) {
+                sha256_inplace(tmp_element);
+                index++;
+            }
+            memcpy(waypoints[j].element, tmp_element, SHA256_DIGEST_LENGTH);
+            waypoints[j].index = index;
+        }
+
+        /* store/pass the last used index in the waypoint array */
+        *waypoints_length = (j - 1);
+
+        /* remaining iterations down to elements */
+        for (size_t i = index; i < (elements - 1); ++i) {
+            sha256_inplace(tmp_element);
+        }
+
+        /* store the result */
+        memcpy(tail_element, tmp_element, SHA256_DIGEST_LENGTH);
+
+        return tail_element;
+    }
+}
+
+int sha256_chain_verify_element(unsigned char *element,
+                                 size_t element_index,
+                                 unsigned char *tail_element,
+                                 size_t chain_length)
+{
+    unsigned char tmp_element[SHA256_DIGEST_LENGTH];
+
+    int delta_count = (chain_length - element_index);
+
+    /* assert if we have an index mismatch */
+    assert(delta_count >= 1);
+
+    memcpy((void*)tmp_element, (void*)element, SHA256_DIGEST_LENGTH);
+
+    /* perform all consecutive iterations down to tail_element */
+    for (int i = 0; i < (delta_count - 1); ++i) {
+        sha256_inplace(tmp_element);
+    }
+
+    /* return if the computed element equals the tail_element */
+    return (memcmp(tmp_element, tail_element, SHA256_DIGEST_LENGTH) != 0);
+}
diff --git a/sys/include/hashes/sha256.h b/sys/include/hashes/sha256.h
index 7d2d71246455a3a6a11597640ec5689ef936b9b9..c4eb80ed0283c0497c01cc9e19339065ae8cc692 100644
--- a/sys/include/hashes/sha256.h
+++ b/sys/include/hashes/sha256.h
@@ -1,6 +1,7 @@
 /*-
  * Copyright 2005 Colin Percival
  * Copyright 2013 Christian Mehlis & René Kijewski
+ * Copyright 2016 Martin Landsmann <martin.landsmann@haw-hamburg.de>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -68,6 +69,16 @@ typedef struct {
     unsigned char buf[64];
 } sha256_context_t;
 
+/**
+ * @brief sha256-chain indexed element
+ */
+typedef struct {
+    /** the position of this element in its chain */
+    size_t index;
+    /** the element */
+    unsigned char element[SHA256_DIGEST_LENGTH];
+} sha256_chain_idx_elm_t;
+
 /**
  * @brief SHA-256 initialization.  Begins a SHA-256 operation.
  *
@@ -124,6 +135,74 @@ const unsigned char *hmac_sha256(const unsigned char *key,
                                  size_t message_length,
                                  unsigned char *result);
 
+/**
+ * @brief function to produce a hash chain statring with a given seed element.
+ *        The chain is computed by taking the sha256 from the seed,
+ *        hash the resulting sha256 and continuing taking sha256
+ *        from each result consecutively.
+ *
+ * @param[in] seed the seed of the sha256-chain, i.e. the first element
+ * @param[in] seed_length the size of seed in bytes
+ * @param[in] elements the number of chained elements,
+ *            i.e. the index of the last element is (elements-1)
+ * @param[out] tail_element the final element of the sha256-chain
+ *
+ * @returns pointer to tail_element
+ */
+unsigned char *sha256_chain(const unsigned char *seed, size_t seed_length,
+                            size_t elements, unsigned char *tail_element);
+
+/**
+ * @brief function to produce a hash chain statring with a given seed element.
+ *        The chain is computed the same way as done with sha256_chain().
+ *        Additionally intermediate elements are saved while computing the chain.
+ *        This slows down computation, but provides the caller with indexed
+ *        "waypoint"-elements.
+ *        They are supposed to shortcut computing verification elements,
+ *        this comes in handy when using long chains,
+ *        e.g. a chain with 2<sup>32</sup> elements.
+ *
+ * @param[in] seed the seed of the sha256-chain, i.e. the first element
+ * @param[in] seed_length the size of seed in bytes
+ * @param[in] elements the number of chained elements,
+ *            i.e. the index of the last element is (elements-1)
+ * @param[out] tail_element the final element of the sha256-chain
+ * @param[out] waypoints intermediate elements are stored there.
+ * @param[in, out] waypoints_length the size of the waypoints array.
+ *                 If the given size is equal or greater elements, the complete
+ *                 chain will be stored.
+ *                 Otherwise every n-th element is stored where:
+ *                 n = floor(elements / waypoints_length);
+ *                 floor is implicitly used since we perform unsigned integer division.
+ *                 The last used waypoint index is stored in the variable after call.
+ *                 That is (elements - 1) if the complete chain is stored,
+ *                 and (*waypoints_length - 1) if we only store some waypoints.
+ *
+ * @returns pointer to tail_element
+ */
+unsigned char *sha256_chain_with_waypoints(const unsigned char *seed,
+                                           size_t seed_length,
+                                           size_t elements,
+                                           unsigned char *tail_element,
+                                           sha256_chain_idx_elm_t *waypoints,
+                                           size_t *waypoints_length);
+
+/**
+ * @brief function to verify if a given chain element is part of the chain.
+ *
+ * @param[in] element the chain element to be verified
+ * @param[in] element_index the position in the chain
+ * @param[in] tail_element the last element of the sha256-chain
+ * @param[in] chain_length the number of elements in the chain
+ *
+ * @returns 0 if element is verified to be part of the chain at element_index
+ *          1 if the element cannot be verified as part of the chain
+ */
+int sha256_chain_verify_element(unsigned char *element,
+                                size_t element_index,
+                                unsigned char *tail_element,
+                                size_t chain_length);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/tests/unittests/tests-hashes/tests-hashes-sha256-chain.c b/tests/unittests/tests-hashes/tests-hashes-sha256-chain.c
new file mode 100644
index 0000000000000000000000000000000000000000..98afbb68500d69b2b5d094f4c8df3aec08605396
--- /dev/null
+++ b/tests/unittests/tests-hashes/tests-hashes-sha256-chain.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2016 Martin Landsmann <martin.landsmann@haw-hamburg.de>
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License v2.1. See the file LICENSE in the top level
+ * directory for more details.
+ */
+
+ /**
+ * @ingroup     unittests
+ * @{
+ *
+ * @file
+ * @brief       testcases for the sha256-chain implementation
+ *
+ * @author      Martin Landsmann <martin.landsmann@haw-hamburg.de>
+ *
+ * @}
+ */
+
+#include <limits.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "embUnit/embUnit.h"
+
+#include "hashes/sha256.h"
+
+#include "tests-hashes.h"
+
+static void test_sha256_hash_chain(void)
+{
+    const char strSeed[] = "My cool secret seed, you'll never guess it ;) 12345";
+    static unsigned char tail_hash_chain_element[SHA256_DIGEST_LENGTH];
+
+    /* we produce a sha256-chain of 257 elements */
+    size_t elements = 257;
+
+    memset(tail_hash_chain_element, 0, SHA256_DIGEST_LENGTH);
+    TEST_ASSERT(sha256_chain((unsigned char*)strSeed, strlen(strSeed),
+                             elements, tail_hash_chain_element) != NULL);
+
+    /* we check if the first element is part of the chain */
+    unsigned char element_one[SHA256_DIGEST_LENGTH];
+    sha256((unsigned char*)strSeed, strlen(strSeed), element_one);
+    TEST_ASSERT(sha256_chain_verify_element(element_one, 0,
+                                            tail_hash_chain_element, elements) == 0);
+
+    /* now we check if the test fails if the index is wrong */
+    TEST_ASSERT(sha256_chain_verify_element(element_one, 2,
+                                            tail_hash_chain_element, elements) == 1);
+
+    /* now we check if other elements are also part of the chain */
+    unsigned char tmp_element[SHA256_DIGEST_LENGTH];
+    memcpy((void*)tmp_element, (void*)element_one, SHA256_DIGEST_LENGTH);
+
+    /* since we know the seed we build every element and test if its in the chain */
+    for (size_t i = 1; i < elements; ++i) {
+        sha256_context_t ctx;
+        sha256_init(&ctx);
+        sha256_update(&ctx, tmp_element, SHA256_DIGEST_LENGTH);
+        sha256_final(tmp_element, &ctx);
+
+        TEST_ASSERT(sha256_chain_verify_element(tmp_element, i,
+                                                tail_hash_chain_element, elements) == 0);
+    }
+}
+
+static void test_sha256_hash_chain_with_waypoints(void)
+{
+    const char strSeed[] = "My cool secret seed, you'll never guess it ;P 123456!";
+    static unsigned char tail_hash_chain_element[SHA256_DIGEST_LENGTH];
+
+    /* we produce a sha256-chain of 257 elements */
+    size_t elements = 257;
+
+    /* the first element of the hash chain */
+    unsigned char element_one[SHA256_DIGEST_LENGTH];
+    sha256((unsigned char*)strSeed, strlen(strSeed), element_one);
+
+    /* now we check storing some waypoints, lets say 10 */
+    size_t waypoints_length = 10;
+    sha256_chain_idx_elm_t waypoints[waypoints_length];
+    memset(tail_hash_chain_element, 0, SHA256_DIGEST_LENGTH);
+
+    sha256_chain_with_waypoints((unsigned char*)strSeed,
+                                strlen(strSeed),
+                                elements,
+                                tail_hash_chain_element,
+                                waypoints,
+                                &waypoints_length);
+
+    /* we test if the chain has been computed properly */
+    TEST_ASSERT(sha256_chain_verify_element(element_one, 0,
+                                            tail_hash_chain_element, elements) == 0);
+
+    /* and we check if our waypoints are properly stored */
+    for (size_t i = 0; i < (waypoints_length + 1); ++i) {
+        TEST_ASSERT(sha256_chain_verify_element(waypoints[i].element,
+                                                waypoints[i].index,
+                                                tail_hash_chain_element, elements) == 0);
+    }
+}
+
+static void test_sha256_hash_chain_store_whole(void)
+{
+    const char strSeed[] = "My cool secret seed, you'll never guess it ;P 123456!";
+    static unsigned char tail_hash_chain_element[SHA256_DIGEST_LENGTH];
+
+    /* now we check storing the whole chain
+     * not a too large one though to remain inside the stack bounds
+     */
+    size_t elements = 17;
+
+    /* the first element of the hash chain */
+    unsigned char element_one[SHA256_DIGEST_LENGTH];
+    sha256((unsigned char*)strSeed, strlen(strSeed), element_one);
+
+    size_t whole_chain_length = elements;
+    sha256_chain_idx_elm_t waypoints_whole_chain[whole_chain_length];
+
+    memset(tail_hash_chain_element, 0, SHA256_DIGEST_LENGTH);
+
+    sha256_chain_with_waypoints((unsigned char*)strSeed,
+                                strlen(strSeed),
+                                whole_chain_length,
+                                tail_hash_chain_element,
+                                waypoints_whole_chain,
+                                &whole_chain_length);
+
+    /* we test again if the chain has been computed properly */
+    TEST_ASSERT(sha256_chain_verify_element(element_one, 0,
+                                            tail_hash_chain_element, elements) == 0);
+
+    /* and we check if our complete chain has been properly stored */
+    TEST_ASSERT( (whole_chain_length + 1) == elements );
+
+    for (size_t i = 0; i < (whole_chain_length + 1); ++i) {
+        TEST_ASSERT(sha256_chain_verify_element(waypoints_whole_chain[i].element,
+                                                waypoints_whole_chain[i].index,
+                                                tail_hash_chain_element, elements) == 0);
+    }
+}
+
+Test *tests_hashes_sha256_chain_tests(void)
+{
+    EMB_UNIT_TESTFIXTURES(fixtures) {
+        new_TestFixture(test_sha256_hash_chain),
+        new_TestFixture(test_sha256_hash_chain_with_waypoints),
+        new_TestFixture(test_sha256_hash_chain_store_whole),
+    };
+
+    EMB_UNIT_TESTCALLER(hashes_sha256_tests, NULL, NULL,
+                        fixtures);
+
+    return (Test *)&hashes_sha256_tests;
+}
diff --git a/tests/unittests/tests-hashes/tests-hashes-sha256.c b/tests/unittests/tests-hashes/tests-hashes-sha256.c
index cb71d81f11fe1643cf5b58207ad015e839ef5cd7..865562b18136ece5feaf2cbb90bd28ff08ca1b84 100644
--- a/tests/unittests/tests-hashes/tests-hashes-sha256.c
+++ b/tests/unittests/tests-hashes/tests-hashes-sha256.c
@@ -8,6 +8,20 @@
  * directory for more details.
  */
 
+ /**
+ * @ingroup     unittests
+ * @{
+ *
+ * @file
+ * @brief       testcases for the sha256 implementation
+ *
+ * @author      Christian Mehlis <mehlis@inf.fu-berlin.de>
+ * @author      Philipp Rosenkranz <philipp.rosenkranz@fu-berlin.de>
+ * @author      Martin Landsmann <martin.landsmann@haw-hamburg.de>
+ *
+ * @}
+ */
+
 #include <limits.h>
 #include <string.h>
 #include <stdio.h>
diff --git a/tests/unittests/tests-hashes/tests-hashes.c b/tests/unittests/tests-hashes/tests-hashes.c
index 1e9e79983c5307d7efba2c204769b0ac5dde8c64..c66911e61a2839e98dc0ea3b952a79e0ca5c9f89 100644
--- a/tests/unittests/tests-hashes/tests-hashes.c
+++ b/tests/unittests/tests-hashes/tests-hashes.c
@@ -26,4 +26,5 @@ void tests_hashes(void)
     TESTS_RUN(tests_hashes_sha1_tests());
     TESTS_RUN(tests_hashes_sha256_tests());
     TESTS_RUN(tests_hashes_sha256_hmac_tests());
+    TESTS_RUN(tests_hashes_sha256_chain_tests());
 }
diff --git a/tests/unittests/tests-hashes/tests-hashes.h b/tests/unittests/tests-hashes/tests-hashes.h
index a533c45fdd9920702faca2582c0158a71c5bf981..c6dc6a2dc3dc751bf75a010a45c50710f6cfa125 100644
--- a/tests/unittests/tests-hashes/tests-hashes.h
+++ b/tests/unittests/tests-hashes/tests-hashes.h
@@ -58,6 +58,13 @@ Test *tests_hashes_sha256_tests(void);
  */
 Test *tests_hashes_sha256_hmac_tests(void);
 
+/**
+ * @brief   Generates tests for hashes/sha256.h - sha256-chain
+ *
+ * @return  embUnit tests if successful, NULL if not.
+ */
+Test *tests_hashes_sha256_chain_tests(void);
+
 #ifdef __cplusplus
 }
 #endif