Blame view

RIOT/sys/include/hashes/sha256.h 8.86 KB
a752c7ab   elopes   add first test an...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
  /*-
   * Copyright 2005 Colin Percival
   * Copyright 2013 Christian Mehlis & René Kijewski
   * Copyright 2016 Martin Landsmann <martin.landsmann@haw-hamburg.de>
   * Copyright 2016 OTA keys S.A.
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in the
   *    documentation and/or other materials provided with the distribution.
   *
   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
   * $FreeBSD: src/lib/libmd/sha256.h,v 1.1.2.1 2005/06/24 13:32:25 cperciva Exp $
   */
  
  
  /**
   * @ingroup     sys_hashes
   * @{
   *
   * @file
   * @brief       Header definitions for the SHA256 hash function
   *
   * @author      Colin Percival
   * @author      Christian Mehlis
   * @author      Rene Kijewski
   * @author      Hermann Lelong
   */
  
  #ifndef HASHES_SHA256_H
  #define HASHES_SHA256_H
  
  #include <inttypes.h>
  
  #ifdef __cplusplus
  extern "C" {
  #endif
  
  #define SHA256_DIGEST_LENGTH 32
  
  /**
   * @brief 512 Bit (64 Byte) internally used block size for sha256
   */
  #define SHA256_INTERNAL_BLOCK_SIZE (64)
  
  /**
   * @brief Context for ciper operations based on sha256
   */
  typedef struct {
      /** global state */
      uint32_t state[8];
      /** processed bytes counter */
      uint32_t count[2];
      /** data buffer */
      unsigned char buf[64];
  } sha256_context_t;
  
  /**
   * @brief Context for HMAC operations based on sha256
   */
  typedef struct {
      /** Context for inner hash calculation */
      sha256_context_t c_in;
      /** Context for outer hash calculation */
      sha256_context_t c_out;
  } hmac_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.
   *
   * @param ctx  sha256_context_t handle to init
   */
  void sha256_init(sha256_context_t *ctx);
  
  /**
   * @brief Add bytes into the hash
   *
   * @param ctx      sha256_context_t handle to use
   * @param[in] data Input data
   * @param[in] len  Length of @p data
   */
  void sha256_update(sha256_context_t *ctx, const void *data, size_t len);
  
  /**
   * @brief SHA-256 finalization.  Pads the input data, exports the hash value,
   * and clears the context state.
   *
   * @param ctx    sha256_context_t handle to use
   * @param digest resulting digest, this is the hash of all the bytes
   */
  void sha256_final(sha256_context_t *ctx, void *digest);
  
  /**
   * @brief A wrapper function to simplify the generation of a hash, this is
   * usefull for generating sha256 for one buffer
   *
   * @param[in] data   pointer to the buffer to generate hash from
   * @param[in] len    length of the buffer
   * @param[out] digest optional pointer to an array for the result, length must
   *                    be SHA256_DIGEST_LENGTH
   *                    if digest == NULL, one static buffer is used
   */
  void *sha256(const void *data, size_t len, void *digest);
  
  /**
   * @brief hmac_sha256_init HMAC SHA-256 calculation. Initiate calculation of a HMAC
   * @param[in] ctx hmac_context_t handle to use
   * @param[in] key key used in the hmac-sha256 computation
   * @param[in] key_length the size in bytes of the key
   */
  void hmac_sha256_init(hmac_context_t *ctx, const void *key, size_t key_length);
  
  /**
   * @brief hmac_sha256_update Add data bytes for HMAC calculation
   * @param[in] ctx hmac_context_t handle to use
   * @param[in] data pointer to the buffer to generate hash from
   * @param[in] len length of the buffer
   */
  void hmac_sha256_update(hmac_context_t *ctx, const void *data, size_t len);
  
  /**
   * @brief hmac_sha256_final HMAC SHA-256 finalization. Finish HMAC calculation and export the value
   * @param[in] ctx hmac_context_t handle to use
   * @param[out] digest the computed hmac-sha256,
   *             length MUST be SHA256_DIGEST_LENGTH
   *             if digest == NULL, a static buffer is used
   */
  void hmac_sha256_final(hmac_context_t *ctx, void *digest);
  
  /**
   * @brief function to compute a hmac-sha256 from a given message
   *
   * @param[in] key key used in the hmac-sha256 computation
   * @param[in] key_length the size in bytes of the key
   * @param[in] data pointer to the buffer to generate the hmac-sha256
   * @param[in] len the length of the message in bytes
   * @param[out] digest the computed hmac-sha256,
   *             length MUST be SHA256_DIGEST_LENGTH
   *             if digest == NULL, a static buffer is used
   * @returns pointer to the resulting digest.
   *          if result == NULL the pointer points to the static buffer
   */
  const void *hmac_sha256(const void *key, size_t key_length,
                          const void *data, size_t len, void *digest);
  
  /**
   * @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
   */
  void *sha256_chain(const void *seed, size_t seed_length,
                     size_t elements, void *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
   */
  void *sha256_chain_with_waypoints(const void *seed, size_t seed_length,
                                    size_t elements, void *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(void *element,
                                  size_t element_index,
                                  void *tail_element,
                                  size_t chain_length);
  
  #ifdef __cplusplus
  }
  #endif
  
  /** @} */
  #endif /* HASHES_SHA256_H */