argon2 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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)