Noise-C
 All Data Structures Files Functions Variables Typedefs Macros Groups Pages
util.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016 Southern Storm Software, Pty Ltd.
3  * Copyright (C) 2016 Topology LP.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included
13  * in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 #include "internal.h"
25 #if USE_LIBSODIUM
26 #include <sodium.h>
27 typedef crypto_hash_sha256_state sha256_context_t;
28 #define sha256_reset(ctx) crypto_hash_sha256_init(ctx)
29 #define sha256_update(ctx, pub, pub_len) crypto_hash_sha256_update(ctx, pub, pub_len)
30 #define sha256_finish(ctx, hash) crypto_hash_sha256_final(ctx, hash)
31 #else
32 #include "crypto/sha2/sha256.h"
33 #endif
34 #if USE_OPENSSL
35 #include <openssl/err.h>
36 #include <openssl/evp.h>
37 #endif
38 #include <stdlib.h>
39 #if HAVE_PTHREAD
40 #include <pthread.h>
41 static pthread_once_t noise_is_initialized = PTHREAD_ONCE_INIT;
42 #endif
43 
55 {
56 #if USE_LIBSODIUM
57  if (sodium_init() < 0)
58  return;
59 #endif
60 #if USE_OPENSSL
61  OpenSSL_add_all_algorithms();
62  ERR_load_crypto_strings();
63 #endif
64 }
65 
87 int noise_init(void)
88 {
89 #if HAVE_PTHREAD
90  if (pthread_once(&noise_is_initialized, noise_init_helper) != 0)
91  return NOISE_ERROR_SYSTEM;
92 #else
94 #endif
95 
96  return NOISE_ERROR_NONE;
97 }
98 
135 void *noise_new_object(size_t size)
136 {
137  void *ptr = calloc(1, size);
138  if (!ptr || size < sizeof(size_t))
139  return ptr;
140  *((size_t *)ptr) = size;
141  return ptr;
142 }
143 
152 void noise_free(void *ptr, size_t size)
153 {
154  if (ptr) {
155  noise_clean(ptr, size);
156  free(ptr);
157  }
158 }
159 
170 void noise_clean(void *data, size_t size)
171 {
172  volatile uint8_t *d = (volatile uint8_t *)data;
173  while (size > 0) {
174  *d++ = 0;
175  --size;
176  }
177 }
178 
188 int noise_is_equal(const void *s1, const void *s2, size_t size)
189 {
190  const uint8_t *str1 = (const unsigned char *)s1;
191  const uint8_t *str2 = (const unsigned char *)s2;
192  uint8_t temp = 0;
193  while (size > 0) {
194  temp |= *str1 ^ *str2;
195  ++str1;
196  ++str2;
197  --size;
198  }
199  return (0x0100 - (int)temp) >> 8;
200 }
201 
211 int noise_is_zero(const void *data, size_t size)
212 {
213  const uint8_t *d = (const uint8_t *)data;
214  uint8_t temp = 0;
215  while (size > 0) {
216  temp |= *d++;
217  --size;
218  }
219  return (0x0100 - (int)temp) >> 8;
220 }
221 
246  (int fingerprint_type, char *buffer, size_t len,
247  const uint8_t *public_key, size_t public_key_len)
248 {
249  static char const hexchars[] = "0123456789abcdef";
250  sha256_context_t sha256;
251  uint8_t hash[32];
252  size_t f_len;
253  size_t posn;
254 
255  /* Validate the parameters */
256  if (!buffer)
258  if (!len)
260  *buffer = '\0'; /* In case we bail out with an error later */
261  if (!public_key)
263 
264  /* Validate the fingerprint type and get the desired length */
265  if (fingerprint_type == NOISE_FINGERPRINT_BASIC)
266  f_len = 16;
267  else if (fingerprint_type == NOISE_FINGERPRINT_FULL)
268  f_len = 32;
269  else
271 
272  /* Check the length of the buffer */
273  if ((f_len * 3) > len)
275 
276  /* Hash the public key with SHA256 */
277  sha256_reset(&sha256);
278  sha256_update(&sha256, public_key, public_key_len);
279  sha256_finish(&sha256, hash);
280  noise_clean(&sha256, sizeof(sha256));
281 
282  /* Format the fingerprint in hexadecimal within the buffer */
283  for (posn = 0; posn < f_len; ++posn) {
284  uint8_t byte = hash[posn];
285  buffer[posn * 3] = hexchars[(byte >> 4) & 0x0F];
286  buffer[posn * 3 + 1] = hexchars[byte & 0x0F];
287  buffer[posn * 3 + 2] = ':';
288  }
289  buffer[f_len * 3 - 1] = '\0';
290  noise_clean(hash, sizeof(hash));
291  return NOISE_ERROR_NONE;
292 }
293 
void noise_clean(void *data, size_t size)
Cleans a block of memory to destroy its contents.
Definition: util.c:170
NoiseHashState * hash
Points to the HashState object for this SymmetricState.
Definition: internal.h:519
#define NOISE_ERROR_INVALID_PARAM
Invalid parameter to function; e.g. a NULL value.
#define NOISE_FINGERPRINT_FULL
Fingerprint format is the hexadecimal encoding of the entire 32 bytes of the SHA256 hash of the publi...
#define NOISE_ERROR_NONE
Success, no error.
size_t size
Total size of the structure.
Definition: internal.h:503
int noise_is_zero(const void *data, size_t size)
Determine if a block of memory consists of all zero bytes.
Definition: util.c:211
#define NOISE_FINGERPRINT_BASIC
Fingerprint format is the hexadecimal encoding of the first 16 bytes of the SHA256 hash of the public...
int noise_format_fingerprint(int fingerprint_type, char *buffer, size_t len, const uint8_t *public_key, size_t public_key_len)
Formats the fingerprint for a raw public key value.
Definition: util.c:246
void * noise_new_object(size_t size)
Allocates memory from the system for an object.
Definition: util.c:135
#define NOISE_ERROR_INVALID_LENGTH
Invalid length specified for a key, packet, etc.
int noise_init(void)
Initializes the Noise-c library.
Definition: util.c:87
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
#define NOISE_ERROR_SYSTEM
System error, with more information in errno.
void noise_init_helper(void)
Definition: util.c:54
int noise_is_equal(const void *s1, const void *s2, size_t size)
Determine if two blocks of memory are equal in constant time.
Definition: util.c:188