1 /*
2 * Argon2 source code package
3 *
4 * Written by Daniel Dinu and Dmitry Khovratovich, 2015
5 *
6 * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
7 *
8 * You should have received a copy of the CC0 Public Domain Dedication along
9 * with
10 * this software. If not, see
11 * <http://creativecommons.org/publicdomain/zero/1.0/>.
12 * modified by Agnieszka Bielec <bielecagnieszka8 at gmail.com>
13 */
14
15 #include <string.h>
16 #include <stdlib.h>
17 #include <stdio.h>
18
19 #include "argon2.h"
20 #include "argon2_encoding.h"
21 #include "argon2_core.h"
22
argon2_ctx(argon2_context * context,argon2_type type)23 int argon2_ctx(argon2_context *context, argon2_type type) {
24 /* 1. Validate all inputs */
25 int result = argon2_validate_inputs(context);
26 uint32_t memory_blocks, segment_length;
27 argon2_instance_t instance;
28
29 if (ARGON2_OK != result) {
30 return result;
31 }
32
33 if (Argon2_d != type && Argon2_i != type) {
34 return ARGON2_INCORRECT_TYPE;
35 }
36
37 /* 2. Align memory size */
38 /* Minimum memory_blocks = 8L blocks, where L is the number of lanes */
39 memory_blocks = context->m_cost;
40
41 if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) {
42 memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes;
43 }
44
45 segment_length = memory_blocks / (context->lanes * ARGON2_SYNC_POINTS);
46 /* Ensure that all segments have equal length */
47 memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS);
48
49 instance.version = context->version;
50 instance.memory = context->memory;
51 instance.passes = context->t_cost;
52 instance.memory_blocks = memory_blocks;
53 instance.segment_length = segment_length;
54 instance.lane_length = segment_length * ARGON2_SYNC_POINTS;
55 instance.lanes = context->lanes;
56 instance.threads = context->threads;
57 instance.type = type;
58 instance.memory = context->memory;
59 instance.pseudo_rands = context->pseudo_rands;
60
61 /* 3. Initialization: Hashing inputs, allocating memory, filling first
62 * blocks
63 */
64 result = argon2_initialize(&instance, context);
65
66 if (ARGON2_OK != result) {
67 return result;
68 }
69
70 /* 4. Filling memory */
71 result = argon2_fill_memory_blocks(&instance);
72
73 if (ARGON2_OK != result) {
74 return result;
75 }
76 /* 5. Finalization */
77 argon2_finalize(context, &instance);
78
79 return ARGON2_OK;
80 }
81
argon2_hash(const uint32_t t_cost,const uint32_t m_cost,const uint32_t parallelism,const void * pwd,const size_t pwdlen,const void * salt,const size_t saltlen,void * hash,const size_t hashlen,char * encoded,const size_t encodedlen,argon2_type type,const uint32_t version,void * memory,void * pseudo_rands)82 int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
83 const uint32_t parallelism, const void *pwd,
84 const size_t pwdlen, const void *salt, const size_t saltlen,
85 void *hash, const size_t hashlen, char *encoded,
86 const size_t encodedlen, argon2_type type,
87 const uint32_t version, void *memory, void *pseudo_rands){
88
89 argon2_context context;
90 int result;
91 //uint8_t *out;
92
93 if (hashlen > ARGON2_MAX_OUTLEN) {
94 return ARGON2_OUTPUT_TOO_LONG;
95 }
96
97 if (hashlen < ARGON2_MIN_OUTLEN) {
98 return ARGON2_OUTPUT_TOO_SHORT;
99 }
100
101 context.out = (uint8_t *)hash;
102 context.outlen = (uint32_t)hashlen;
103 context.pwd = CONST_CAST(uint8_t *)pwd;
104 context.pwdlen = (uint32_t)pwdlen;
105 context.salt = CONST_CAST(uint8_t *)salt;
106 context.saltlen = (uint32_t)saltlen;
107 context.secret = NULL;
108 context.secretlen = 0;
109 context.ad = NULL;
110 context.adlen = 0;
111 context.t_cost = t_cost;
112 context.m_cost = m_cost;
113 context.lanes = parallelism;
114 context.threads = parallelism;
115 context.flags = ARGON2_DEFAULT_FLAGS;
116 context.version = version;
117 context.memory = memory;
118 context.pseudo_rands=pseudo_rands;
119
120 result = argon2_ctx(&context, type);
121
122 if (result != ARGON2_OK) {
123 //free(out);
124 return result;
125 }
126
127 /* if encoding requested, write it */
128 if (encoded && encodedlen) {
129 if (argon2_encode_string(encoded, encodedlen, &context, type) != ARGON2_OK) {
130 //free(out);
131 return ARGON2_ENCODING_FAIL;
132 }
133 }
134
135 return ARGON2_OK;
136 }
137
138
argon2d_ctx(argon2_context * context)139 int argon2d_ctx(argon2_context *context) {
140 return argon2_ctx(context, Argon2_d);
141 }
142
argon2i_ctx(argon2_context * context)143 int argon2i_ctx(argon2_context *context) {
144 return argon2_ctx(context, Argon2_i);
145 }
146
argon2_verify_ctx(argon2_context * context,const char * hash,argon2_type type)147 int argon2_verify_ctx(argon2_context *context, const char *hash,
148 argon2_type type) {
149 int result;
150 if (0 == context->outlen || NULL == hash) {
151 return ARGON2_OUT_PTR_MISMATCH;
152 }
153
154 result = argon2_ctx(context, type);
155
156 if (ARGON2_OK != result) {
157 return result;
158 }
159
160 return 0 == memcmp(hash, context->out, context->outlen);
161 }
162
argon2d_verify_ctx(argon2_context * context,const char * hash)163 int argon2d_verify_ctx(argon2_context *context, const char *hash) {
164 return argon2_verify_ctx(context, hash, Argon2_d);
165 }
166
argon2i_verify_ctx(argon2_context * context,const char * hash)167 int argon2i_verify_ctx(argon2_context *context, const char *hash) {
168 return argon2_verify_ctx(context, hash, Argon2_i);
169 }
170
argon2_error_message(int error_code)171 const char *argon2_error_message(int error_code) {
172 switch (error_code) {
173 case ARGON2_OK:
174 return "OK";
175 case ARGON2_OUTPUT_PTR_NULL:
176 return "Output pointer is NULL";
177 case ARGON2_OUTPUT_TOO_SHORT:
178 return "Output is too short";
179 case ARGON2_OUTPUT_TOO_LONG:
180 return "Output is too long";
181 case ARGON2_PWD_TOO_SHORT:
182 return "Password is too short";
183 case ARGON2_PWD_TOO_LONG:
184 return "Password is too long";
185 case ARGON2_SALT_TOO_SHORT:
186 return "Salt is too short";
187 case ARGON2_SALT_TOO_LONG:
188 return "Salt is too long";
189 case ARGON2_AD_TOO_SHORT:
190 return "Associated data is too short";
191 case ARGON2_AD_TOO_LONG:
192 return "Associated data is too long";
193 case ARGON2_SECRET_TOO_SHORT:
194 return "Secret is too short";
195 case ARGON2_SECRET_TOO_LONG:
196 return "Secret is too long";
197 case ARGON2_TIME_TOO_SMALL:
198 return "Time cost is too small";
199 case ARGON2_TIME_TOO_LARGE:
200 return "Time cost is too large";
201 case ARGON2_MEMORY_TOO_LITTLE:
202 return "Memory cost is too small";
203 case ARGON2_MEMORY_TOO_MUCH:
204 return "Memory cost is too large";
205 case ARGON2_LANES_TOO_FEW:
206 return "Too few lanes";
207 case ARGON2_LANES_TOO_MANY:
208 return "Too many lanes";
209 case ARGON2_PWD_PTR_MISMATCH:
210 return "Password pointer is NULL, but password length is not 0";
211 case ARGON2_SALT_PTR_MISMATCH:
212 return "Salt pointer is NULL, but salt length is not 0";
213 case ARGON2_SECRET_PTR_MISMATCH:
214 return "Secret pointer is NULL, but secret length is not 0";
215 case ARGON2_AD_PTR_MISMATCH:
216 return "Associated data pointer is NULL, but ad length is not 0";
217 case ARGON2_MEMORY_ALLOCATION_ERROR:
218 return "Memory allocation error";
219 case ARGON2_FREE_MEMORY_CBK_NULL:
220 return "The free memory callback is NULL";
221 case ARGON2_ALLOCATE_MEMORY_CBK_NULL:
222 return "The allocate memory callback is NULL";
223 case ARGON2_INCORRECT_PARAMETER:
224 return "Argon2_Context context is NULL";
225 case ARGON2_INCORRECT_TYPE:
226 return "There is no such version of Argon2";
227 case ARGON2_OUT_PTR_MISMATCH:
228 return "Output pointer mismatch";
229 case ARGON2_THREADS_TOO_FEW:
230 return "Not enough threads";
231 case ARGON2_THREADS_TOO_MANY:
232 return "Too many threads";
233 case ARGON2_MISSING_ARGS:
234 return "Missing arguments";
235 case ARGON2_ENCODING_FAIL:
236 return "Encoding failed";
237 case ARGON2_DECODING_FAIL:
238 return "Decoding failed";
239 case ARGON2_THREAD_FAIL:
240 return "Threading failure";
241 case ARGON2_DECODING_LENGTH_FAIL:
242 return "Some of encoded parameters are too long or too short";
243 case ARGON2_VERIFY_MISMATCH:
244 return "The password does not match the supplied hash";
245 default:
246 return "Unknown error code";
247 }
248 }
249
argon2_encodedlen(uint32_t t_cost,uint32_t m_cost,uint32_t parallelism,uint32_t saltlen,uint32_t hashlen)250 size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost, uint32_t parallelism,
251 uint32_t saltlen, uint32_t hashlen) {
252 return strlen("$argon2x$v=$m=,t=,p=$$") + argon2_numlen(t_cost) + argon2_numlen(m_cost)
253 + argon2_numlen(parallelism) + argon2_b64len(saltlen) + argon2_b64len(hashlen)
254 + argon2_numlen(ARGON2_VERSION_NUMBER);
255 }
256