Noise-C
 All Data Structures Files Functions Variables Typedefs Macros Groups Pages
hashstate.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016 Southern Storm Software, Pty Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22 
23 #include "internal.h"
24 #include <string.h>
25 
74 {
75  /* The "state" argument must be non-NULL */
76  if (!state)
78 
79  /* Create the HashState object for the "id" */
80  *state = 0;
81  switch (id) {
82  case NOISE_HASH_BLAKE2s:
83  *state = noise_blake2s_new();
84  break;
85 
86  case NOISE_HASH_BLAKE2b:
87  *state = noise_blake2b_new();
88  break;
89 
90  case NOISE_HASH_SHA256:
91  *state = noise_sha256_new();
92  break;
93 
94  case NOISE_HASH_SHA512:
95  *state = noise_sha512_new();
96  break;
97 
98  default:
100  }
101 
102  /* Bail out if insufficient memory */
103  if (!(*state))
104  return NOISE_ERROR_NO_MEMORY;
105 
106  /* Ready to go */
107  return NOISE_ERROR_NONE;
108 }
109 
126 int noise_hashstate_new_by_name(NoiseHashState **state, const char *name)
127 {
128  int id;
129 
130  /* The "state" and "name" arguments must be non-NULL */
131  if (!state)
133  *state = 0;
134  if (!name)
136 
137  /* Map the name and create the corresponding object */
138  id = noise_name_to_id(NOISE_HASH_CATEGORY, name, strlen(name));
139  if (id)
140  return noise_hashstate_new_by_id(state, id);
141 
142  /* We don't know what this is */
144 }
145 
157 {
158  /* Bail out if no hash state */
159  if (!state)
161 
162  /* Call the backend-specific destroy function if necessary */
163  if (state->destroy)
164  (*(state->destroy))(state);
165 
166  /* Clean and free the memory */
167  noise_free(state, state->size);
168  return NOISE_ERROR_NONE;
169 }
170 
179 {
180  return state ? state->hash_id : NOISE_HASH_NONE;
181 }
182 
193 {
194  return state ? state->hash_len : 0;
195 }
196 
207 {
208  return state ? state->block_len : 0;
209 }
210 
222 {
223  /* Validate the parameter */
224  if (!state)
226 
227  /* Reset the hash state */
228  (*(state->reset))(state);
229  return NOISE_ERROR_NONE;
230 }
231 
245  (NoiseHashState *state, const uint8_t *data, size_t data_len)
246 {
247  /* Validate the parameters */
248  if (!state || !data)
250 
251  /* Update the hash state */
252  (*(state->update))(state, data, data_len);
253  return NOISE_ERROR_NONE;
254 }
255 
272  (NoiseHashState *state, uint8_t *hash, size_t hash_len)
273 {
274  /* Validate the parameters */
275  if (!state || !hash)
277  if (hash_len != state->hash_len)
279 
280  /* Finalize the hash state */
281  (*(state->finalize))(state, hash);
282  return NOISE_ERROR_NONE;
283 }
284 
309  (NoiseHashState *state, const uint8_t *data, size_t data_len,
310  uint8_t *hash, size_t hash_len)
311 {
312  /* Validate the parameters */
313  if (!state || !data || !hash)
315  if (hash_len != state->hash_len)
317 
318  /* Hash the data */
319  (*(state->reset))(state);
320  (*(state->update))(state, data, data_len);
321  (*(state->finalize))(state, hash);
322  return NOISE_ERROR_NONE;
323 }
324 
352  (NoiseHashState *state, const uint8_t *data1, size_t data1_len,
353  const uint8_t *data2, size_t data2_len, uint8_t *hash, size_t hash_len)
354 {
355  /* Validate the parameters */
356  if (!state || !data1 || !data2 || !hash)
358  if (hash_len != state->hash_len)
360 
361  /* Hash the data */
362  (*(state->reset))(state);
363  (*(state->update))(state, data1, data1_len);
364  (*(state->update))(state, data2, data2_len);
365  (*(state->finalize))(state, hash);
366  return NOISE_ERROR_NONE;
367 }
368 
370 #define HMAC_IPAD 0x36
371 #define HMAC_OPAD 0x5C
381 static void noise_hashstate_xor_key(uint8_t *key, size_t key_len, uint8_t value)
382 {
383  while (key_len > 0) {
384  *key++ ^= value;
385  --key_len;
386  }
387 }
388 
406 static void noise_hashstate_hmac
407  (NoiseHashState *state, const uint8_t *key, size_t key_len,
408  const uint8_t *data1, size_t data1_len,
409  const uint8_t *data2, size_t data2_len, uint8_t *hash)
410 {
411  size_t hash_len = state->hash_len;
412  size_t block_len = state->block_len;
413  uint8_t *key_block;
414 
415  /* Allocate temporary stack space for the key block */
416  key_block = alloca(block_len);
417 
418  /* Format the key for the inner hashing context */
419  if (key_len <= block_len) {
420  memcpy(key_block, key, key_len);
421  memset(key_block + key_len, 0, block_len - key_len);
422  } else {
423  (*(state->reset))(state);
424  (*(state->update))(state, key, key_len);
425  (*(state->finalize))(state, key_block);
426  memset(key_block + hash_len, 0, block_len - hash_len);
427  }
428  noise_hashstate_xor_key(key_block, block_len, HMAC_IPAD);
429 
430  /* Calculate the inner hash */
431  (*(state->reset))(state);
432  (*(state->update))(state, key_block, block_len);
433  (*(state->update))(state, data1, data1_len);
434  if (data2)
435  (*(state->update))(state, data2, data2_len);
436  (*(state->finalize))(state, hash);
437 
438  /* Format the key for the outer hashing context */
439  noise_hashstate_xor_key(key_block, block_len, HMAC_IPAD ^ HMAC_OPAD);
440 
441  /* Calculate the outer hash */
442  (*(state->reset))(state);
443  (*(state->update))(state, key_block, block_len);
444  (*(state->update))(state, hash, hash_len);
445  (*(state->finalize))(state, hash);
446 
447  /* Clean up and exit */
448  noise_clean(key_block, state->block_len);
449 }
450 
477  (NoiseHashState *state, const uint8_t *key, size_t key_len,
478  const uint8_t *data, size_t data_len,
479  uint8_t *output1, size_t output1_len,
480  uint8_t *output2, size_t output2_len)
481 {
482  size_t hash_len;
483  uint8_t *temp_key;
484  uint8_t *temp_hash;
485 
486  /* Validate the parameters */
487  if (!state || !key || !data || !output1 || !output2)
489  hash_len = state->hash_len;
490  if (output1_len > hash_len || output2_len > hash_len)
492 
493  /* Allocate local stack space for the temporary hash values */
494  temp_key = alloca(hash_len);
495  temp_hash = alloca(hash_len + 1);
496 
497  /* Generate the temporary hashing key */
498  noise_hashstate_hmac(state, key, key_len, data, data_len, 0, 0, temp_key);
499 
500  /* Generate the first output */
501  temp_hash[0] = 0x01;
502  noise_hashstate_hmac
503  (state, temp_key, hash_len, temp_hash, 1, 0, 0, temp_hash);
504  memcpy(output1, temp_hash, output1_len);
505 
506  /* Generate the second output */
507  temp_hash[hash_len] = 0x02;
508  noise_hashstate_hmac
509  (state, temp_key, hash_len, temp_hash, hash_len + 1, 0, 0, temp_hash);
510  memcpy(output2, temp_hash, output2_len);
511 
512  /* Clean up and exit */
513  noise_clean(temp_key, hash_len);
514  noise_clean(temp_hash, hash_len + 1);
515  return NOISE_ERROR_NONE;
516 }
517 
542  (NoiseHashState *state, const uint8_t *passphrase, size_t passphrase_len,
543  const uint8_t *salt, size_t salt_len, size_t iterations,
544  uint8_t *output, size_t output_len)
545 {
546  size_t hash_len;
547  uint64_t max_size;
548  uint8_t T[NOISE_MAX_HASHLEN];
549  uint8_t U[NOISE_MAX_HASHLEN];
550  uint8_t ibuf[4];
551  size_t i, index, index2;
552 
553  /* Validate the parameters */
554  if (!state || !passphrase || !salt || !output)
556  hash_len = state->hash_len;
557  max_size = ((uint64_t)0xFFFFFFFFU) * hash_len;
558  if (output_len > max_size)
560 
561  /* Generate the required output blocks */
562  i = 1;
563  while (output_len > 0) {
564  /* Generate the next block of output */
565  ibuf[0] = (uint8_t)(i >> 24);
566  ibuf[1] = (uint8_t)(i >> 16);
567  ibuf[2] = (uint8_t)(i >> 8);
568  ibuf[3] = (uint8_t)i;
569  ++i;
570  noise_hashstate_hmac
571  (state, passphrase, passphrase_len, salt, salt_len,
572  ibuf, sizeof(ibuf), T);
573  memcpy(U, T, hash_len);
574  for (index = 1; index < iterations; ++index) {
575  noise_hashstate_hmac
576  (state, passphrase, passphrase_len, U, hash_len, 0, 0, U);
577  for (index2 = 0; index2 < hash_len; ++index2)
578  T[index2] ^= U[index2];
579  }
580 
581  /* Copy the generated data into the output buffer */
582  if (output_len >= hash_len) {
583  memcpy(output, T, hash_len);
584  output += hash_len;
585  output_len -= hash_len;
586  } else {
587  memcpy(output, T, output_len);
588  output_len = 0;
589  }
590  }
591 
592  /* Clean up and exit */
593  noise_clean(T, sizeof(T));
594  noise_clean(U, sizeof(U));
595  return NOISE_ERROR_NONE;
596 }
597 
604 {
605  return NOISE_MAX_HASHLEN;
606 }
607 
614 {
615  return 128;
616 }
617 
#define NOISE_ERROR_UNKNOWN_ID
Algorithm identifier is unknown.
void(* reset)(NoiseHashState *state)
Resets the HashState for a new hashing session.
Definition: internal.h:170
uint16_t hash_len
Length of the output from this hash algorithm.
Definition: internal.h:160
uint16_t block_len
Length of the underlying block for this hash algorithm.
Definition: internal.h:163
void noise_clean(void *data, size_t size)
Cleans a block of memory to destroy its contents.
Definition: util.c:170
int noise_hashstate_pbkdf2(NoiseHashState *state, const uint8_t *passphrase, size_t passphrase_len, const uint8_t *salt, size_t salt_len, size_t iterations, uint8_t *output, size_t output_len)
Hashes a passphrase and salt using the PBKDF2 key derivation function.
Definition: hashstate.c:542
#define NOISE_ERROR_INVALID_PARAM
Invalid parameter to function; e.g. a NULL value.
Internal structure of the NoiseHashState type.
Definition: internal.h:151
#define NOISE_ERROR_NONE
Success, no error.
int noise_hashstate_get_max_hash_length(void)
Gets the maximum hash length for the supported algorithms.
Definition: hashstate.c:603
int noise_hashstate_reset(NoiseHashState *state)
Resets the hash state.
Definition: hashstate.c:221
#define NOISE_HASH_BLAKE2b
Hash identifier for "BLAKE2b".
#define NOISE_HASH_CATEGORY
Category for hash algorithms.
int noise_hashstate_new_by_id(NoiseHashState **state, int id)
Creates a new HashState object by its algorithm identifier.
Definition: hashstate.c:73
#define NOISE_MAX_HASHLEN
Maximum hash length over all supported hash algorithms.
Definition: internal.h:48
int noise_hashstate_new_by_name(NoiseHashState **state, const char *name)
Creates a new HashState object by its algorithm name.
Definition: hashstate.c:126
int noise_hashstate_hash_one(NoiseHashState *state, const uint8_t *data, size_t data_len, uint8_t *hash, size_t hash_len)
Hashes a single data buffer and returns the hash value.
Definition: hashstate.c:309
void(* destroy)(NoiseHashState *state)
Destroys this HashState prior to the memory being freed.
Definition: internal.h:202
size_t noise_hashstate_get_block_length(const NoiseHashState *state)
Gets the length of the block for a HashState object.
Definition: hashstate.c:206
#define NOISE_ERROR_NO_MEMORY
Insufficient memory to complete the operation.
void(* finalize)(NoiseHashState *state, uint8_t *hash)
Finalizes the HashState and returns the hash value.
Definition: internal.h:188
#define NOISE_ERROR_UNKNOWN_NAME
Algorithm name is unknown.
int noise_hashstate_get_max_block_length(void)
Gets the maximum block length for the supported algorithms.
Definition: hashstate.c:613
#define NOISE_ERROR_INVALID_LENGTH
Invalid length specified for a key, packet, etc.
#define NOISE_HASH_SHA256
Hash identifier for "SHA256".
void(* update)(NoiseHashState *state, const uint8_t *data, size_t len)
Updates the HashState with more input data.
Definition: internal.h:179
int noise_name_to_id(int category, const char *name, size_t name_len)
Maps an algorithm name to the corresponding identifier.
Definition: names.c:146
int noise_hashstate_hkdf(NoiseHashState *state, const uint8_t *key, size_t key_len, const uint8_t *data, size_t data_len, uint8_t *output1, size_t output1_len, uint8_t *output2, size_t output2_len)
Hashes input data with a key to generate two output values.
Definition: hashstate.c:477
int noise_hashstate_finalize(NoiseHashState *state, uint8_t *hash, size_t hash_len)
Finalizes the hash state and returns the hash value.
Definition: hashstate.c:272
int noise_hashstate_get_hash_id(const NoiseHashState *state)
Gets the algorithm identifier for a HashState object.
Definition: hashstate.c:178
Internal definitions for the library.
void noise_free(void *ptr, size_t size)
Destroys the contents of a block of memory and free it.
Definition: util.c:152
int noise_hashstate_free(NoiseHashState *state)
Frees a HashState object after destroying all sensitive material.
Definition: hashstate.c:156
int noise_hashstate_update(NoiseHashState *state, const uint8_t *data, size_t data_len)
Updates the hash state with more data.
Definition: hashstate.c:245
#define NOISE_HASH_BLAKE2s
Hash identifier for "BLAKE2s".
#define NOISE_HASH_SHA512
Hash identifier for "SHA512".
size_t noise_hashstate_get_hash_length(const NoiseHashState *state)
Gets the length of the hash output for a HashState object.
Definition: hashstate.c:192
int hash_id
Algorithm identifier for the hash.
Definition: internal.h:157
int noise_hashstate_hash_two(NoiseHashState *state, const uint8_t *data1, size_t data1_len, const uint8_t *data2, size_t data2_len, uint8_t *hash, size_t hash_len)
Hashes the concatenation of two data buffers and returns the combined hash value. ...
Definition: hashstate.c:352
#define NOISE_HASH_NONE
Hash identifier that indicates "no hash".
size_t size
Total size of the structure including subclass state.
Definition: internal.h:154