argon2 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1 +1 @@
1
- d94efacfa5efcdfeb513c829cccda7d9003640e1de64b12fad80f92aad1ab8a4 argon2i
1
+ 82ca18d6df38a67b1a52f610f19f1917e5b118014fe31995c83350b92319fa06 argon2i
@@ -105,6 +105,61 @@ static const char *Argon2_ErrorMessage[] = {
105
105
  {ARGON2_DECODING_FAIL, */ "Decoding failed", /*},*/
106
106
  };
107
107
 
108
+
109
+ int argon2_core(argon2_context *context, argon2_type type) {
110
+ /* 1. Validate all inputs */
111
+ int result = validate_inputs(context);
112
+ uint32_t memory_blocks, segment_length;
113
+ argon2_instance_t instance;
114
+
115
+ if (ARGON2_OK != result) {
116
+ return result;
117
+ }
118
+
119
+ if (Argon2_d != type && Argon2_i != type) {
120
+ return ARGON2_INCORRECT_TYPE;
121
+ }
122
+
123
+ /* 2. Align memory size */
124
+ /* Minimum memory_blocks = 8L blocks, where L is the number of lanes */
125
+ memory_blocks = context->m_cost;
126
+
127
+ if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) {
128
+ memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes;
129
+ }
130
+
131
+ segment_length = memory_blocks / (context->lanes * ARGON2_SYNC_POINTS);
132
+ /* Ensure that all segments have equal length */
133
+ memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS);
134
+
135
+ instance.memory = NULL;
136
+ instance.passes = context->t_cost;
137
+ instance.memory_blocks = memory_blocks;
138
+ instance.segment_length = segment_length;
139
+ instance.lane_length = segment_length * ARGON2_SYNC_POINTS;
140
+ instance.lanes = context->lanes;
141
+ instance.threads = context->threads;
142
+ instance.type = type;
143
+
144
+ /* 3. Initialization: Hashing inputs, allocating memory, filling first
145
+ * blocks
146
+ */
147
+ result = initialize(&instance, context);
148
+
149
+ if (ARGON2_OK != result) {
150
+ return result;
151
+ }
152
+
153
+ /* 4. Filling memory */
154
+ fill_memory_blocks(&instance);
155
+
156
+ /* 5. Finalization */
157
+ finalize(context, &instance);
158
+
159
+ return ARGON2_OK;
160
+ }
161
+
162
+
108
163
  int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
109
164
  const uint32_t parallelism, const void *pwd,
110
165
  const size_t pwdlen, const void *salt, const size_t saltlen,
@@ -311,6 +366,22 @@ int verify_d(argon2_context *context, const char *hash) {
311
366
  return 0 == memcmp(hash, context->out, context->outlen);
312
367
  }
313
368
 
369
+ int verify_i(argon2_context *context, const char *hash) {
370
+ int result;
371
+ if (0 == context->outlen || NULL == hash) {
372
+ return ARGON2_OUT_PTR_MISMATCH;
373
+ }
374
+
375
+ result = argon2_core(context, Argon2_i);
376
+
377
+ if (ARGON2_OK != result) {
378
+ return result;
379
+ }
380
+
381
+ return 0 == memcmp(hash, context->out, context->outlen);
382
+ }
383
+
384
+
314
385
  const char *error_message(int error_code) {
315
386
  enum {
316
387
  /* Make sure---at compile time---that the enum size matches the array
@@ -194,6 +194,14 @@ typedef struct Argon2_Context {
194
194
  /* Argon2 primitive type */
195
195
  typedef enum Argon2_type { Argon2_d = 0, Argon2_i = 1 } argon2_type;
196
196
 
197
+
198
+ /*
199
+ * Function that performs memory-hard hashing with certain degree of parallelism
200
+ * @param context Pointer to the Argon2 internal structure
201
+ * @return Error code if smth is wrong, ARGON2_OK otherwise
202
+ */
203
+ int argon2_core(argon2_context *context, argon2_type type);
204
+
197
205
  /**
198
206
  * Hashes a password with Argon2i, producing an encoded hash
199
207
  * @param t_cost Number of iterations
@@ -319,6 +327,15 @@ int argon2id(argon2_context *context);
319
327
  */
320
328
  int verify_d(argon2_context *context, const char *hash);
321
329
 
330
+ /*
331
+ * Verify if a given password is correct for Argon2i hashing
332
+ * @param context Pointer to current Argon2 context
333
+ * @param hash The password hash to verify. The length of the hash is
334
+ * specified by the context outlen member
335
+ * @return Zero if successful, a non zero error code otherwise
336
+ */
337
+ int verify_i(argon2_context *context, const char *hash);
338
+
322
339
  /*
323
340
  * Get the associated error message for given error code
324
341
  * @return The error message associated with the given error code
@@ -3,11 +3,11 @@
3
3
 
4
4
  #include "blake2-impl.h"
5
5
 
6
- #if defined(_MSC_VER)
7
- #include <intrin.h>
6
+ #include <emmintrin.h>
7
+ #if defined(__SSSE3__)
8
+ #include <tmmintrin.h> /* for _mm_shuffle_epi8 and _mm_alignr_epi8 */
8
9
  #endif
9
10
 
10
- #include <immintrin.h>
11
11
  #if defined(__XOP__) && (defined(__GNUC__) || defined(__clang__))
12
12
  #include <x86intrin.h>
13
13
  #endif
@@ -134,11 +134,12 @@ static BLAKE2_INLINE __m128i fBlaMka(__m128i x, __m128i y) {
134
134
 
135
135
  #define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
136
136
  do { \
137
- __m128i t0 = C0; \
137
+ __m128i t0, t1; \
138
+ t0 = C0; \
138
139
  C0 = C1; \
139
140
  C1 = t0; \
140
141
  t0 = B0; \
141
- __m128i t1 = D0; \
142
+ t1 = D0; \
142
143
  B0 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(B0, B0)); \
143
144
  B1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(B1, B1)); \
144
145
  D0 = _mm_unpackhi_epi64(D0, _mm_unpacklo_epi64(D1, D1)); \
@@ -54,26 +54,26 @@
54
54
  void init_block_value(block *b, uint8_t in) { memset(b->v, in, sizeof(b->v)); }
55
55
 
56
56
  void copy_block(block *dst, const block *src) {
57
- memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_WORDS_IN_BLOCK);
57
+ memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_QWORDS_IN_BLOCK);
58
58
  }
59
59
 
60
60
  void xor_block(block *dst, const block *src) {
61
61
  int i;
62
- for (i = 0; i < ARGON2_WORDS_IN_BLOCK; ++i) {
62
+ for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
63
63
  dst->v[i] ^= src->v[i];
64
64
  }
65
65
  }
66
66
 
67
67
  static void load_block(block *dst, const void *input) {
68
68
  unsigned i;
69
- for (i = 0; i < ARGON2_WORDS_IN_BLOCK; ++i) {
69
+ for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
70
70
  dst->v[i] = load64((const uint8_t *)input + i * sizeof(dst->v[i]));
71
71
  }
72
72
  }
73
73
 
74
74
  static void store_block(void *output, const block *src) {
75
75
  unsigned i;
76
- for (i = 0; i < ARGON2_WORDS_IN_BLOCK; ++i) {
76
+ for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
77
77
  store64((uint8_t *)output + i * sizeof(src->v[i]), src->v[i]);
78
78
  }
79
79
  }
@@ -424,6 +424,10 @@ int validate_inputs(const argon2_context *context) {
424
424
  return ARGON2_MEMORY_TOO_MUCH;
425
425
  }
426
426
 
427
+ if (context->m_cost < 8*context->lanes) {
428
+ return ARGON2_MEMORY_TOO_LITTLE;
429
+ }
430
+
427
431
  /* Validate time cost */
428
432
  if (ARGON2_MIN_TIME > context->t_cost) {
429
433
  return ARGON2_TIME_TOO_SMALL;
@@ -606,55 +610,3 @@ int initialize(argon2_instance_t *instance, argon2_context *context) {
606
610
  return ARGON2_OK;
607
611
  }
608
612
 
609
- int argon2_core(argon2_context *context, argon2_type type) {
610
- /* 1. Validate all inputs */
611
- int result = validate_inputs(context);
612
- uint32_t memory_blocks, segment_length;
613
- argon2_instance_t instance;
614
-
615
- if (ARGON2_OK != result) {
616
- return result;
617
- }
618
-
619
- if (Argon2_d != type && Argon2_i != type) {
620
- return ARGON2_INCORRECT_TYPE;
621
- }
622
-
623
- /* 2. Align memory size */
624
- /* Minimum memory_blocks = 8L blocks, where L is the number of lanes */
625
- memory_blocks = context->m_cost;
626
-
627
- if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) {
628
- memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes;
629
- }
630
-
631
- segment_length = memory_blocks / (context->lanes * ARGON2_SYNC_POINTS);
632
- /* Ensure that all segments have equal length */
633
- memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS);
634
-
635
- instance.memory = NULL;
636
- instance.passes = context->t_cost;
637
- instance.memory_blocks = memory_blocks;
638
- instance.segment_length = segment_length;
639
- instance.lane_length = segment_length * ARGON2_SYNC_POINTS;
640
- instance.lanes = context->lanes;
641
- instance.threads = context->threads;
642
- instance.type = type;
643
-
644
- /* 3. Initialization: Hashing inputs, allocating memory, filling first
645
- * blocks
646
- */
647
- result = initialize(&instance, context);
648
-
649
- if (ARGON2_OK != result) {
650
- return result;
651
- }
652
-
653
- /* 4. Filling memory */
654
- fill_memory_blocks(&instance);
655
-
656
- /* 5. Finalization */
657
- finalize(context, &instance);
658
-
659
- return ARGON2_OK;
660
- }
@@ -33,8 +33,8 @@ enum argon2_core_constants {
33
33
 
34
34
  /* Memory block size in bytes */
35
35
  ARGON2_BLOCK_SIZE = 1024,
36
- ARGON2_WORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8,
37
- ARGON2_QWORDS_IN_BLOCK = 64,
36
+ ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8,
37
+ ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16,
38
38
 
39
39
  /* Number of pseudo-random values generated by one call to Blake in Argon2i
40
40
  to
@@ -54,7 +54,7 @@ enum argon2_core_constants {
54
54
  * Memory blocks can be copied, XORed. Internal words can be accessed by [] (no
55
55
  * bounds checking).
56
56
  */
57
- typedef struct _block { uint64_t v[ARGON2_WORDS_IN_BLOCK]; } block;
57
+ typedef struct block_ { uint64_t v[ARGON2_QWORDS_IN_BLOCK]; } block;
58
58
 
59
59
  /*****************Functions that work with the block******************/
60
60
 
@@ -215,11 +215,4 @@ void fill_segment(const argon2_instance_t *instance,
215
215
  */
216
216
  void fill_memory_blocks(argon2_instance_t *instance);
217
217
 
218
- /*
219
- * Function that performs memory-hard hashing with certain degree of parallelism
220
- * @param context Pointer to the Argon2 internal structure
221
- * @return Error code if smth is wrong, ARGON2_OK otherwise
222
- */
223
- int argon2_core(argon2_context *context, argon2_type type);
224
-
225
218
  #endif
@@ -254,7 +254,7 @@ int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
254
254
  return 0; \
255
255
  } \
256
256
  str += cc_len; \
257
- } while (0)
257
+ } while ((void)0, 0)
258
258
 
259
259
  #define CC_opt(prefix, code) \
260
260
  do { \
@@ -263,7 +263,7 @@ int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
263
263
  str += cc_len; \
264
264
  { code; } \
265
265
  } \
266
- } while (0)
266
+ } while ((void)0, 0)
267
267
 
268
268
  #define DECIMAL(x) \
269
269
  do { \
@@ -273,17 +273,17 @@ int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
273
273
  return 0; \
274
274
  } \
275
275
  (x) = dec_x; \
276
- } while (0)
276
+ } while ((void)0, 0)
277
277
 
278
278
  #define BIN(buf, max_len, len) \
279
279
  do { \
280
280
  size_t bin_len = (max_len); \
281
281
  str = from_base64(buf, &bin_len, str); \
282
- if (str == NULL) { \
282
+ if (str == NULL || bin_len > UINT32_MAX) { \
283
283
  return 0; \
284
284
  } \
285
- (len) = bin_len; \
286
- } while (0)
285
+ (len) = (uint32_t)bin_len; \
286
+ } while ((void)0, 0)
287
287
 
288
288
  size_t maxadlen = ctx->adlen;
289
289
  size_t maxsaltlen = ctx->saltlen;
@@ -379,14 +379,14 @@ int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
379
379
  memcpy(dst, str, pp_len + 1); \
380
380
  dst += pp_len; \
381
381
  dst_len -= pp_len; \
382
- } while (0)
382
+ } while ((void)0, 0)
383
383
 
384
384
  #define SX(x) \
385
385
  do { \
386
386
  char tmp[30]; \
387
387
  sprintf(tmp, "%lu", (unsigned long)(x)); \
388
388
  SS(tmp); \
389
- } while (0)
389
+ } while ((void)0, 0)
390
390
 
391
391
  #define SB(buf, len) \
392
392
  do { \
@@ -396,7 +396,7 @@ int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
396
396
  } \
397
397
  dst += sb_len; \
398
398
  dst_len -= sb_len; \
399
- } while (0)
399
+ } while ((void)0, 0)
400
400
 
401
401
  if (type == Argon2_i)
402
402
  SS("$argon2i$m=");
@@ -114,9 +114,9 @@ void internal_kat(const argon2_instance_t *instance, uint32_t pass) {
114
114
 
115
115
  for (i = 0; i < instance->memory_blocks; ++i) {
116
116
  uint32_t how_many_words =
117
- (instance->memory_blocks > ARGON2_WORDS_IN_BLOCK)
117
+ (instance->memory_blocks > ARGON2_QWORDS_IN_BLOCK)
118
118
  ? 1
119
- : ARGON2_WORDS_IN_BLOCK;
119
+ : ARGON2_QWORDS_IN_BLOCK;
120
120
 
121
121
  for (j = 0; j < how_many_words; ++j)
122
122
  printf("Block %.4u [%3u]: %016" PRIx64 "\n", i, j,
@@ -147,7 +147,7 @@ static void generate_testvectors(const char *type) {
147
147
  const deallocate_fptr myown_deallocator = NULL;
148
148
 
149
149
  unsigned t_cost = 3;
150
- unsigned m_cost = 16;
150
+ unsigned m_cost = 32;
151
151
  unsigned lanes = 4;
152
152
 
153
153
  memset(pwd, 1, TEST_OUTLEN);
@@ -15,8 +15,6 @@
15
15
  #include <string.h>
16
16
  #include <stdlib.h>
17
17
 
18
- #include <immintrin.h>
19
-
20
18
  #include "argon2.h"
21
19
  #include "core.h"
22
20
  #include "opt.h"
@@ -25,10 +23,10 @@
25
23
  #include "blake2/blamka-round-opt.h"
26
24
 
27
25
  void fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block) {
28
- __m128i block_XY[ARGON2_QWORDS_IN_BLOCK];
26
+ __m128i block_XY[ARGON2_OWORDS_IN_BLOCK];
29
27
  uint32_t i;
30
28
 
31
- for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; i++) {
29
+ for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
32
30
  block_XY[i] = state[i] = _mm_xor_si128(
33
31
  state[i], _mm_loadu_si128((__m128i const *)(&ref_block[16 * i])));
34
32
  }
@@ -45,7 +43,7 @@ void fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block) {
45
43
  state[8 * 6 + i], state[8 * 7 + i]);
46
44
  }
47
45
 
48
- for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; i++) {
46
+ for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
49
47
  state[i] = _mm_xor_si128(state[i], block_XY[i]);
50
48
  _mm_storeu_si128((__m128i *)(&next_block[16 * i]), state[i]);
51
49
  }
@@ -70,8 +68,8 @@ void generate_addresses(const argon2_instance_t *instance,
70
68
 
71
69
  for (i = 0; i < instance->segment_length; ++i) {
72
70
  if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
73
- __m128i zero_block[ARGON2_QWORDS_IN_BLOCK];
74
- __m128i zero2_block[ARGON2_QWORDS_IN_BLOCK];
71
+ __m128i zero_block[ARGON2_OWORDS_IN_BLOCK];
72
+ __m128i zero2_block[ARGON2_OWORDS_IN_BLOCK];
75
73
  memset(zero_block, 0, sizeof(zero_block));
76
74
  memset(zero2_block, 0, sizeof(zero2_block));
77
75
  input_block.v[6]++;
@@ -14,6 +14,11 @@
14
14
  #ifndef ARGON2_OPT_H
15
15
  #define ARGON2_OPT_H
16
16
 
17
+ #include <stdint.h>
18
+ #include <emmintrin.h>
19
+ #include "argon2.h"
20
+ #include "core.h"
21
+
17
22
  /*
18
23
  * Function fills a new memory block. Differs from the
19
24
  * @param state Pointer to the just produced block. Content will be updated(!)
@@ -17,10 +17,6 @@ module Argon2
17
17
  end
18
18
 
19
19
  def hash(pass)
20
- # It is technically possible to include NULL bytes, however our C
21
- # uses strlen(). It is not deemed suitable to accept a user password
22
- # with such a character.
23
- raise ArgonHashFail, "NULL bytes not permitted" if /\0/.match(pass)
24
20
  Argon2::Engine.hash_argon2i_encode(
25
21
  pass, @salt, @t_cost, @m_cost, @secret)
26
22
  end
@@ -16,14 +16,16 @@ module Argon2
16
16
  :uint, :uint, :uint, :pointer,
17
17
  :size_t, :pointer, :size_t, :pointer, :size_t], :int, :blocking => true
18
18
 
19
- #void argon2_wrap(uint8_t *out, char *pwd, uint8_t *salt, uint32_t t_cost,
19
+ #void argon2_wrap(uint8_t *out, char *pwd, size_it pwdlen,
20
+ #uint8_t *salt, uint32_t t_cost,
20
21
  # uint32_t m_cost, uint32_t lanes,
21
22
  # uint8_t *secret, uint32_t secretlen)
22
23
  attach_function :argon2_wrap, [
23
- :pointer, :pointer, :pointer, :uint,
24
+ :pointer, :pointer, :size_t, :pointer, :uint,
24
25
  :uint, :uint, :pointer, :size_t], :uint, :blocking => true
25
26
 
26
- #int argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen);
27
+ #int argon2i_verify(const char *encoded, const void *pwd,
28
+ #const size_t pwdlen);
27
29
  attach_function :wrap_argon2_verify, [:pointer, :pointer, :size_t,
28
30
  :pointer, :size_t], :int, :blocking => true
29
31
  end
@@ -46,11 +48,13 @@ module Argon2
46
48
  def self.hash_argon2i_encode(password, salt, t_cost, m_cost, secret)
47
49
  result = ''
48
50
  secretlen = secret.nil? ? 0 : secret.length
51
+ passwordlen = password.nil? ? 0 : password.length
49
52
  if salt.length != Constants::SALT_LEN
50
53
  raise ArgonHashFail, "Invalid salt size"
51
54
  end
52
55
  FFI::MemoryPointer.new(:char, Constants::ENCODE_LEN) do |buffer|
53
- ret = Ext.argon2_wrap(buffer, password, salt, t_cost, (1 << m_cost),
56
+ ret = Ext.argon2_wrap(buffer, password, passwordlen,
57
+ salt, t_cost, (1 << m_cost),
54
58
  1, secret, secretlen)
55
59
  raise ArgonHashFail, ERRORS[ret] unless ret == 0
56
60
  result = buffer.read_string(Constants::ENCODE_LEN)