argon2 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4679e5dd53222a5799fac835361a04a77ae696ae
4
- data.tar.gz: f53efbb7d825c9e271a6812a03340dc951b58c9b
3
+ metadata.gz: e033ede9fe4ee7af5fb80343fbf6b07a8e5d154d
4
+ data.tar.gz: a13a0c907078a0ceb7d09e4c73d8839702588bad
5
5
  SHA512:
6
- metadata.gz: bd1070534755d5f6582e6030b2b2e8907deca141553a1f767827ada8816321a16418ac245aa3e5c7453534ae93a649b5173bfe96cc1c3742f380d7194f22328b
7
- data.tar.gz: 9e912c470b069e3b45a3253b7ad7761138d695468e8a5c65aa8495a98f7bcddf0c0cb1d708ee1165c87b9619e655bcf7ff29b1727e83f9190a46ce22a2d497c3
6
+ metadata.gz: e504a8d8f561768a65672742d27cbba36a3ccfc096ad705e19ecc912d6017b5bf4ce4c1f6283b50886b0e9b18e3e0b49f32943a4eb2618911290d911a7ec45f7
7
+ data.tar.gz: 73c8082e8a39fbf6147bdc15dbb5c5f1c441c95cbd9d45994e65d7f87d566f04af9d9448f0ef20cdd09462b6c4134a5e960ca5b2fa2212de638bef4fb5e53e39
@@ -0,0 +1,66 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ Metrics/AbcSize:
4
+ Max: 16
5
+ Metrics/CyclomaticComplexity:
6
+ Enabled: false
7
+ Metrics/PerceivedComplexity:
8
+ Enabled: false
9
+
10
+ Metrics/LineLength:
11
+ Max: 160
12
+
13
+ Metrics/MethodLength:
14
+ Max: 24
15
+
16
+ Style/AlignParameters:
17
+ Enabled: false
18
+
19
+ Style/AlignArray:
20
+ Enabled: false
21
+
22
+ # Configuration parameters: Exclude.
23
+ Style/Documentation:
24
+ Exclude:
25
+ - 'spec/**/*'
26
+ - 'test/**/*'
27
+
28
+ # Offense count: 16
29
+ # Cop supports --auto-correct.
30
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
31
+ Style/FirstParameterIndentation:
32
+ Exclude:
33
+ - 'lib/argon2.rb'
34
+ - 'test/low_level_test.rb'
35
+ - 'test/util_test.rb'
36
+
37
+ Style/HashSyntax:
38
+ Enabled: false
39
+
40
+ # Offense count: 1
41
+ # Cop supports --auto-correct.
42
+ Style/IndentArray:
43
+ Exclude:
44
+ - 'lib/argon2/errors.rb'
45
+
46
+ # Offense count: 44
47
+ # Cop supports --auto-correct.
48
+ Style/LeadingCommentSpace:
49
+ Exclude:
50
+ - 'ext/argon2_wrap/extconf.rb'
51
+ - 'lib/argon2.rb'
52
+ - 'lib/argon2/constants.rb'
53
+ - 'lib/argon2/ffi_engine.rb'
54
+ - 'test/api_test.rb'
55
+ - 'test/low_level_test.rb'
56
+ - 'test/util.rb'
57
+ - 'test/util_lib.rb'
58
+
59
+ Style/SignalException:
60
+ Enabled: false
61
+
62
+ Style/StringLiterals:
63
+ Enabled: false
64
+
65
+ Style/WordArray:
66
+ MinSize: 33
@@ -4,3 +4,7 @@ rvm:
4
4
  - jruby-9000
5
5
  before_install: gem install bundler -v 1.10.5
6
6
  install: bin/setup
7
+ script:
8
+ - cd ext/argon2_wrap/ && make test && cd ../..
9
+ - CODECLIMATE_REPO_TOKEN=28e3d5d04f4ec87d0899784e6aecc13d7787343b2634b3c94fc1216993d443c2 rake test
10
+ - rake rubocop
data/README.md CHANGED
@@ -2,21 +2,70 @@
2
2
 
3
3
  This Ruby Gem provides FFI bindings, and a simplified interface, to the Argon2 algorithm. [Argon2](https://github.com/P-H-C/phc-winner-argon2) is the official winner of the Password Hashing Competition, a several year project to identify a successor to bcrypt/PBKDF/scrypt methods of securely storing passwords. This is an independant project and not official from the PHC team.
4
4
 
5
- *This gem is still in early development* and at this point is not recommended for use, even in testing.
5
+ *This gem is now considered a beta release* and at this point is not recommended for production use. It has however moved on to being feature complete and users are encouraged to test this product.
6
6
 
7
- For early documentation, please see the test cases, which currently demonstrate low level hashing capabilities.
8
7
 
9
8
  [![Build Status](https://travis-ci.org/technion/ruby-argon2.svg?branch=master)](https://travis-ci.org/technion/ruby-argon2)
9
+ [![Code Climate](https://codeclimate.com/github/technion/ruby-argon2/badges/gpa.svg)](https://codeclimate.com/github/technion/ruby-argon2)
10
+ [![Test Coverage](https://codeclimate.com/github/technion/ruby-argon2/badges/coverage.svg)](https://codeclimate.com/github/technion/ruby-argon2/coverage)
10
11
 
11
12
  ## Design
12
13
 
13
14
  This project has several key tenants to its design:
14
15
 
15
- * The reference Argon2 implementation is to be used "unaltered". To ensure this does not occur, and encourage regular updates from upstream, this is implemented as a git submodule, and is intended to stay that way.
16
+ * The reference Argon2 implementation is to be used "unaltered". To ensure compliance wit this goal, and encourage regular updates from upstream, this is implemented as a git submodule, and is intended to stay that way.
16
17
  * The FFI interface is kept as slim as possible, with wrapper classes preferred to implementing context structs in FFI
17
18
  * Security and maintainability take top priority. This can have an impact on platform support. A PR that contains platform specific code paths is unlikely to be accepted.
18
19
  * Errors from the C interface are raised as Exceptions. There are a lot of exception classes, but they tend to relate to things like very broken input, and code bugs. Calls to this library should generally not require a rescue.
19
- * Test suits are aimed to be very comprehensive.
20
+ * Test suits should aim for 100% code coverage.
21
+ * Default work values should not be considered constants. I will increase them from time to time.
22
+ * Not exposing the threads parameter is a design choice. I believe there is significant risk, and minimal gain in using a value other than '1'. Four threads on a four core box completely ties up the entire server to process one user logon. If you want more security, increase m_cost.
23
+
24
+ ## Usage
25
+
26
+ Require this in your Gemfile like a typical Ruby gem:
27
+
28
+ ```ruby
29
+ require 'argon2'
30
+ ```
31
+
32
+ To generate a hash using specific time and memory cost:
33
+
34
+ ```ruby
35
+ hasher = Argon2::Password.new(t_cost: 2, m_cost: 16)
36
+ hasher.hash("password")
37
+ => "$argon2i$m=65536,t=2,p=1$mLa9JT3Y9P2XhB5Mtuj+yQ$rojObVNKe/ehgd9SWQBB+8nJ8L34Aj3Kiz+aNrWvrx4"
38
+ ```
39
+
40
+ To utilise default costs:
41
+
42
+ ```ruby
43
+ hasher = Argon2::Password.new
44
+ hasher.hash("password")
45
+ ```
46
+
47
+ Alternatively, use this shotcut:
48
+
49
+ ```ruby
50
+ Argon2::Password.hash("password")
51
+ => "$argon2i$m=65536,t=2,p=1$AZwVlHIbgRC7yQhkPKa4tA$F5eM2Zzt4GhIVnR8SNOh3ysyMvGxAO6omsw8kzjbcs4"
52
+ ```
53
+
54
+ You can then use this function to verify a password against a given hash. Will return either true or false.
55
+
56
+ ```ruby
57
+ Argon2::Password.verify_password("password", secure_password)
58
+ ```
59
+
60
+ Argon2 supports an optional key value. This should be stored securely on your server, such as alongside your database credentials. Hashes generated with a key will only validate when presented that key.
61
+
62
+ ```ruby
63
+ KEY = "A key"
64
+ argon = Argon2::Password.new(t_cost: 2, m_cost: 16, secret: KEY)
65
+ myhash = argon.hash("A password")
66
+ Argon2::Password.verify_password("A password", myhash, KEY)
67
+ ```
68
+
20
69
 
21
70
  ## FAQ
22
71
  ### Don't roll your own crypto!
@@ -31,9 +80,15 @@ Although the low level C contains support for "secure memory wipe", any code hit
31
80
 
32
81
  The reference implementation is aimed to provide secure hashing for many years. This implementation doesn't want you to DoS yourself in the meantime. Accordingly, some limits artificial limits exist on work powers. This gem can be much more agile in raising these as technology progresses.
33
82
 
83
+ ### Salts in general
84
+
85
+ If you are providing your own salt, you are probably using it wrong. The design of any secure hashing system should take care of it for you.
86
+
34
87
  ## Contributing
35
88
 
36
- Not yet - the code is in a high state of flux. If you feel you have identified a security issue, please email me directly. For any other bugs, it is too early to review them.
89
+ Any form of contribution is appreciated, however, please note the design goals above and work within them.
90
+
91
+ If an issue is felt to be a security concern, please contact me privately on: technion@lolware.net. If required, you may encrypt with [my GPG key](https://lolware.net/technion-GPG-KEY).
37
92
 
38
93
  ## License
39
94
 
data/Rakefile CHANGED
@@ -1,5 +1,8 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rake/testtask"
3
+ require 'rubocop/rake_task'
4
+
5
+ RuboCop::RakeTask.new
3
6
 
4
7
  Rake::TestTask.new(:test) do |t|
5
8
  t.libs << "test"
@@ -9,26 +9,24 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ["Technion"]
10
10
  spec.email = ["technion@lolware.net"]
11
11
 
12
- spec.summary = %q{Argon2 Password hashing binding}
13
- spec.description = %q{Not remotely finished Argon2 binding}
14
- spec.homepage = "https://github.com/technion/ruby-argon2"
15
- spec.license = "MIT"
12
+ spec.summary = 'Argon2 Password hashing binding'
13
+ spec.description = 'Argon2 FFI binding'
14
+ spec.homepage = 'https://github.com/technion/ruby-argon2'
15
+ spec.license = 'MIT'
16
16
 
17
17
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
- # submodule_path = 'ext/phc-winner-argon2/src'
19
- # `ls #{submodule_path}`.split.each do |filename|
20
- # spec.files << "#{submodule_path}/#{filename}"
21
- # end
22
18
  spec.files << `find ext`.split
23
-
19
+
24
20
  spec.bindir = "exe"
25
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
22
  spec.require_paths = ["lib"]
27
23
  spec.add_dependency 'ffi', '~> 1.9'
28
24
  spec.add_dependency 'ffi-compiler', '~> 0.1'
29
25
 
30
- spec.add_development_dependency "bundler", "~> 1.10"
31
- spec.add_development_dependency "rake", "~> 10.0"
32
- spec.add_development_dependency "minitest", '~> 5'
26
+ spec.add_development_dependency "bundler", '~> 1.10', '>= 1.10.5'
27
+ spec.add_development_dependency "rake", '~> 10.4', '>= 10.4.2'
28
+ spec.add_development_dependency "minitest", '~> 5.8'
29
+ spec.add_development_dependency "rubocop", '~> 0.35'
30
+ spec.add_development_dependency "codeclimate-test-reporter", '~> 0.4'
33
31
  spec.extensions << 'ext/argon2_wrap/extconf.rb'
34
32
  end
@@ -10,7 +10,7 @@
10
10
 
11
11
  DIST_SRC = ../phc-winner-argon2/src
12
12
  CC = gcc
13
- SRC = $(DIST_SRC)/argon2.c $(DIST_SRC)/core.c $(DIST_SRC)/blake2/blake2b.c $(DIST_SRC)/thread.c argon_wrap.c
13
+ SRC = $(DIST_SRC)/argon2.c $(DIST_SRC)/core.c $(DIST_SRC)/blake2/blake2b.c $(DIST_SRC)/thread.c $(DIST_SRC)/encoding.c argon_wrap.c
14
14
  OBJ = $(SRC:.c=.o)
15
15
 
16
16
  CFLAGS = -std=c89 -pthread -O3 -Wall -g
@@ -62,11 +62,11 @@ libs: $(SRC)
62
62
  #Deliberately avoiding the CFLAGS for our test cases - disable optimise and
63
63
  #C89
64
64
  test: $(SRC) test.c
65
- $(CC) -pthread -O3 -Wall -g $^ -o tests
66
- ./tests
65
+ clang -pthread -O3 -fsanitize=address -fsanitize=undefined -Wall -g $^ -o tests
66
+ ./tests
67
67
 
68
68
  clean:
69
- rm -rf tests libargon2_wrap.so
69
+ rm -f tests libargon2_wrap.so
70
70
 
71
71
  install:
72
72
  echo none
@@ -12,6 +12,7 @@
12
12
 
13
13
  #include "../phc-winner-argon2/src/argon2.h"
14
14
  #include "../phc-winner-argon2/src/core.h"
15
+ #include "../phc-winner-argon2/src/encoding.h"
15
16
 
16
17
  #define T_COST_DEF 3
17
18
  #define LOG_M_COST_DEF 12 /* 2^12 = 4 MiB */
@@ -19,9 +20,13 @@
19
20
  #define THREADS_DEF 1
20
21
  #define OUT_LEN 32
21
22
  #define SALT_LEN 16
23
+ #define ENCODE_LEN 108
22
24
 
23
- unsigned int argon2_wrap(char *out, char *pwd, uint8_t *salt, uint32_t t_cost,
24
- uint32_t m_cost, uint32_t lanes)
25
+ int argon2_compare(const uint8_t *b1, const uint8_t *b2, size_t len);
26
+
27
+ unsigned int argon2_wrap(char *out, const char *pwd, uint8_t *salt,
28
+ uint32_t t_cost, uint32_t m_cost, uint32_t lanes,
29
+ uint8_t *secret, size_t secretlen)
25
30
  {
26
31
  unsigned pwd_length;
27
32
  uint8_t hash[OUT_LEN];
@@ -43,8 +48,8 @@ unsigned int argon2_wrap(char *out, char *pwd, uint8_t *salt, uint32_t t_cost,
43
48
  context.pwdlen = pwd_length;
44
49
  context.salt = salt;
45
50
  context.saltlen = SALT_LEN;
46
- context.secret = NULL;
47
- context.secretlen = 0;
51
+ context.secret = secret;
52
+ context.secretlen = secretlen;
48
53
  context.ad = NULL;
49
54
  context.adlen = 0;
50
55
  context.t_cost = t_cost;
@@ -59,7 +64,54 @@ unsigned int argon2_wrap(char *out, char *pwd, uint8_t *salt, uint32_t t_cost,
59
64
  if (result != ARGON2_OK)
60
65
  return result;
61
66
 
62
- encode_string(out, 300, &context);
67
+ encode_string(out, ENCODE_LEN, &context, Argon2_i);
63
68
  return ARGON2_OK;
64
69
  }
65
70
 
71
+ int wrap_argon2_verify(const char *encoded, const char *pwd,
72
+ const size_t pwdlen,
73
+ uint8_t *secret, size_t secretlen)
74
+ {
75
+ argon2_context ctx;
76
+ int ret;
77
+ char out[ENCODE_LEN];
78
+ memset(&ctx, 0, sizeof(argon2_context));
79
+
80
+ /* max values, to be updated in decode_string */
81
+ ctx.adlen = 512;
82
+ ctx.saltlen = 512;
83
+ ctx.outlen = 512;
84
+
85
+ ctx.ad = malloc(ctx.adlen);
86
+ ctx.salt = malloc(ctx.saltlen);
87
+ ctx.out = malloc(ctx.outlen);
88
+ if (!ctx.out || !ctx.salt || !ctx.ad) {
89
+ free(ctx.ad);
90
+ free(ctx.salt);
91
+ free(ctx.out);
92
+ return ARGON2_MEMORY_ALLOCATION_ERROR;
93
+ }
94
+
95
+ if(decode_string(&ctx, encoded, Argon2_i) != 1) {
96
+ free(ctx.ad);
97
+ free(ctx.salt);
98
+ free(ctx.out);
99
+ return ARGON2_DECODING_FAIL;
100
+ }
101
+
102
+ ret = argon2_wrap(out, pwd, ctx.salt, ctx.t_cost,
103
+ ctx.m_cost, ctx.lanes, secret, secretlen);
104
+
105
+ free(ctx.ad);
106
+ free(ctx.salt);
107
+
108
+ if (ret != ARGON2_OK || argon2_compare((uint8_t*)out, (uint8_t*)encoded,
109
+ strlen(encoded))) {
110
+ free(ctx.out);
111
+ return ARGON2_DECODING_FAIL;
112
+ }
113
+ free(ctx.out);
114
+
115
+ return ARGON2_OK;
116
+ }
117
+
@@ -8,26 +8,52 @@
8
8
  #include <stdlib.h>
9
9
  #include <string.h>
10
10
  #include <time.h>
11
+ #include <assert.h>
11
12
 
12
13
  #include "../phc-winner-argon2/src/argon2.h"
13
14
 
14
15
  #define OUT_LEN 32
15
16
  #define SALT_LEN 16
16
17
 
18
+ /**
19
+ * Hashes a password with Argon2i, producing a raw hash
20
+ * @param t_cost Number of iterations
21
+ * @param m_cost Sets memory usage to 2^m_cost kibibytes
22
+ * @param parallelism Number of threads and compute lanes
23
+ * @param pwd Pointer to password
24
+ * @param pwdlen Password size in bytes
25
+ * @param salt Pointer to salt
26
+ * @param saltlen Salt size in bytes
27
+ * @param hash Buffer where to write the raw hash
28
+ * @param hashlen Desired length of the hash in bytes
29
+ * @pre Different parallelism levels will give different results
30
+ * @pre Returns ARGON2_OK if successful
17
31
 
32
+ int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
33
+ const uint32_t parallelism, const void *pwd,
34
+ const size_t pwdlen, const void *salt,
35
+ const size_t saltlen, void *hash, const size_t hashlen);
36
+
37
+ */
38
+
39
+ void argon2_wrap(char *out, const char *pwd, uint8_t *salt, uint32_t t_cost,
40
+ uint32_t m_cost, uint32_t lanes,
41
+ uint8_t *secret, size_t secretlen);
42
+
43
+ int wrap_argon2_verify(const char *encoded, const char *pwd,
44
+ const size_t pwdlen,
45
+ uint8_t *secret, size_t secretlen);
18
46
 
19
- void argon2_wrap(char *out, char *pwd, uint8_t *salt, uint32_t t_cost,
20
- uint32_t m_cost, uint32_t lanes);
21
47
 
22
48
  int main()
23
49
  {
24
50
  unsigned char out[OUT_LEN];
51
+ unsigned char hex_out[OUT_LEN*2];
25
52
  char out2[300];
26
53
  char *pwd = NULL;
27
54
  uint8_t salt[SALT_LEN];
28
- int i;
55
+ int i, ret;
29
56
 
30
- pwd = strdup("password");
31
57
  memset(salt, 0x00, SALT_LEN); /* pad with null bytes */
32
58
  memcpy(salt, "somesalt", 8);
33
59
 
@@ -49,17 +75,63 @@ int main()
49
75
  * ./argon2 password diffsalt -t 2 -m 16 -p 1
50
76
  * Hash: 8f65b47d902fb2aee5e0b2bdc9041b249fc11f06f35551e0bee52716b41e8311
51
77
  */
52
- hash_argon2i( out, OUT_LEN, pwd, strlen(pwd), salt, SALT_LEN, 2, 1<<16 );
53
- for(i=0; i<32; ++i )
54
- printf( "%02x", out[i] );
55
- printf( "\n" );
56
78
 
57
- strcpy(pwd, "password"); /* hash_argon2i wipes password content */
58
- argon2_wrap(out2, pwd, salt, 2, 1<<16, 1);
59
- printf("%s\n", out2);
60
- free(pwd);;
79
+ #define RAWTEST(T, M, P, PWD, REF) \
80
+ pwd = strdup(PWD); \
81
+ ret = argon2i_hash_raw(T, 1<<M, P, pwd, strlen(pwd), salt, SALT_LEN, out, OUT_LEN); \
82
+ assert(ret == ARGON2_OK); \
83
+ for(i=0; i<OUT_LEN; ++i ) \
84
+ sprintf((char*)(hex_out + i*2), "%02x", out[i] ); \
85
+ assert(memcmp(hex_out, REF, OUT_LEN*2) == 0); \
86
+ free(pwd); \
87
+ printf( "Ref test: %s: PASS\n", REF);
88
+
89
+ RAWTEST(2, 16, 1, "password", "894af4ff2e2d26f3ce15f77a7e1c25db45b4e20439e9961772ba199caddb001e");
90
+ RAWTEST(2, 20, 1, "password", "58d4d929aeeafa40cc049f032035784fb085e8e0d0c5a51ea067341a93d6d286");
91
+ RAWTEST(2, 18, 1, "password", "55292398cce8fc78685e610d004ca9bda5c325a0a2e6285a0de5f816df139aa6");
92
+ RAWTEST(2, 8, 1, "password", "e346b1e1aa7ca58c9bb862e223ba5604064398d4394e49e90972c6b54cef43ed");
93
+ RAWTEST(1, 16, 1, "password", "b49199e4ecb0f6659e6947f945e391c940b17106e1d0b0a9888006c7f87a789b");
94
+ RAWTEST(4, 16, 1, "password", "72207b3312d79995fbe7b30664837ae1246f9a98e07eac34835ca3498e705f85");
95
+ RAWTEST(2, 16, 1, "differentpassword", "8e286f605ed7383987a4aac25a28a04808593b6e17613bc31457146c4f3f4361");
96
+ memcpy(salt, "diffsalt", 8);
97
+ RAWTEST(2, 16, 1, "password", "8f65b47d902fb2aee5e0b2bdc9041b249fc11f06f35551e0bee52716b41e8311");
98
+
99
+
100
+ #define WRAP_TEST(T, M, PWD, REF) \
101
+ pwd = strdup(PWD); \
102
+ argon2_wrap(out2, pwd, salt, T, 1<<M, 1, NULL, 0); \
103
+ free(pwd); \
104
+ assert(memcmp(out2, REF, strlen(REF)) == 0); \
105
+ printf( "Ref test: %s: PASS\n", REF);
106
+
107
+ memcpy(salt, "somesalt", 8);
108
+ /* echo password | ./argon2 somesalt -t 2 -m 16
109
+ * $argon2i$m=65536,t=2,p=1$c29tZXNhbHQAAAAAAAAAAA$iUr0/y4tJvPOFfd6fhwl20W04gQ56ZYXcroZnK3bAB4
110
+ */
111
+ WRAP_TEST(2, 16, "password",
112
+ "$argon2i$m=65536,t=2,p=1$c29tZXNhbHQAAAAAAAAAAA$iUr0/y4tJvPOFfd6fhwl20W04gQ56ZYXcroZnK3bAB4");
113
+
114
+ /* echo password | ./argon2 somesalt -t 2 -m 8
115
+ * $argon2i$m=256,t=2,p=1$c29tZXNhbHQAAAAAAAAAAA$40ax4ap8pYybuGLiI7pWBAZDmNQ5TknpCXLGtUzvQ+0
116
+ */
117
+ WRAP_TEST(2, 8, "password",
118
+ "$argon2i$m=256,t=2,p=1$c29tZXNhbHQAAAAAAAAAAA$40ax4ap8pYybuGLiI7pWBAZDmNQ5TknpCXLGtUzvQ+0");
119
+
120
+ /* echo diffpassword | ./argon2 somesalt -t 2 -m 16
121
+ * $argon2i$m=65536,t=2,p=1$c29tZXNhbHQAAAAAAAAAAA$y/IeiuTydN/Sud4UzLqv6Spx8Eqree6FoP088X6WyW4
122
+ */
123
+ WRAP_TEST(2, 16, "diffpassword",
124
+ "$argon2i$m=65536,t=2,p=1$c29tZXNhbHQAAAAAAAAAAA$y/IeiuTydN/Sud4UzLqv6Spx8Eqree6FoP088X6WyW4");
61
125
 
126
+ ret = wrap_argon2_verify("$argon2i$m=65536,t=2,p=1$c29tZXNhbHQAAAAAAAAAAA$iUr0/y4tJvPOFfd6fhwl20W04gQ56ZYXcroZnK3bAB4", "password",
127
+ strlen("password"), NULL, 0);
128
+ assert(ret == ARGON2_OK);
129
+ printf("Verify OK test: PASS\n");
62
130
 
131
+ ret = wrap_argon2_verify("$argon2i$m=65536,t=2,p=1$c29tZXNhbHQAAAAAAAAAAA$iUr0/y4tJvPOFfd6fhwl20W04gQ56ZYXcroZnK3bAB4", "notpassword",
132
+ strlen("notpassword"), NULL, 0);
133
+ assert(ret == ARGON2_DECODING_FAIL);
134
+ printf("Verify FAIL test: PASS\n");
63
135
  return 0;
64
136
 
65
137