1 /*
2 * Argon2 reference source code package - reference C implementations
3 *
4 * Copyright 2015
5 * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
6 *
7 * You may use this work under the terms of a Creative Commons CC0 1.0
8 * License/Waiver or the Apache Public License 2.0, at your option. The terms of
9 * these licenses can be found at:
10 *
11 * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
12 * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * You should have received a copy of both of these licenses along with this
15 * software. If not, they may be obtained at the above URLs.
16 */
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include "argon2.h"
22 #include "core.h"
23
initial_kat(const uint8_t * blockhash,const argon2_context * context,argon2_type type)24 void initial_kat(const uint8_t *blockhash, const argon2_context *context,
25 argon2_type type) {
26 unsigned i;
27
28 if (blockhash != NULL && context != NULL) {
29 printf("=======================================\n");
30
31 printf("%s version number %d\n", argon2_type2string(type, 1),
32 context->version);
33
34 printf("=======================================\n");
35
36
37 printf("Memory: %u KiB, Iterations: %u, Parallelism: %u lanes, Tag "
38 "length: %u bytes\n",
39 context->m_cost, context->t_cost, context->lanes,
40 context->outlen);
41
42 printf("Password[%u]: ", context->pwdlen);
43
44 if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) {
45 printf("CLEARED\n");
46 } else {
47 for (i = 0; i < context->pwdlen; ++i) {
48 printf("%2.2x ", ((unsigned char *)context->pwd)[i]);
49 }
50
51 printf("\n");
52 }
53
54 printf("Salt[%u]: ", context->saltlen);
55
56 for (i = 0; i < context->saltlen; ++i) {
57 printf("%2.2x ", ((unsigned char *)context->salt)[i]);
58 }
59
60 printf("\n");
61
62 printf("Secret[%u]: ", context->secretlen);
63
64 if (context->flags & ARGON2_FLAG_CLEAR_SECRET) {
65 printf("CLEARED\n");
66 } else {
67 for (i = 0; i < context->secretlen; ++i) {
68 printf("%2.2x ", ((unsigned char *)context->secret)[i]);
69 }
70
71 printf("\n");
72 }
73
74 printf("Associated data[%u]: ", context->adlen);
75
76 for (i = 0; i < context->adlen; ++i) {
77 printf("%2.2x ", ((unsigned char *)context->ad)[i]);
78 }
79
80 printf("\n");
81
82 printf("Pre-hashing digest: ");
83
84 for (i = 0; i < ARGON2_PREHASH_DIGEST_LENGTH; ++i) {
85 printf("%2.2x ", ((unsigned char *)blockhash)[i]);
86 }
87
88 printf("\n");
89 }
90 }
91
print_tag(const void * out,uint32_t outlen)92 void print_tag(const void *out, uint32_t outlen) {
93 unsigned i;
94 if (out != NULL) {
95 printf("Tag: ");
96
97 for (i = 0; i < outlen; ++i) {
98 printf("%2.2x ", ((uint8_t *)out)[i]);
99 }
100
101 printf("\n");
102 }
103 }
104
internal_kat(const argon2_instance_t * instance,uint32_t pass)105 void internal_kat(const argon2_instance_t *instance, uint32_t pass) {
106
107 if (instance != NULL) {
108 uint32_t i, j;
109 printf("\n After pass %u:\n", pass);
110
111 for (i = 0; i < instance->memory_blocks; ++i) {
112 uint32_t how_many_words =
113 (instance->memory_blocks > ARGON2_QWORDS_IN_BLOCK)
114 ? 1
115 : ARGON2_QWORDS_IN_BLOCK;
116
117 for (j = 0; j < how_many_words; ++j)
118 printf("Block %.4u [%3u]: %016llx\n", i, j,
119 (unsigned long long)instance->memory[i].v[j]);
120 }
121 }
122 }
123
fatal(const char * error)124 static void fatal(const char *error) {
125 fprintf(stderr, "Error: %s\n", error);
126 exit(1);
127 }
128
generate_testvectors(argon2_type type,const uint32_t version)129 static void generate_testvectors(argon2_type type, const uint32_t version) {
130 #define TEST_OUTLEN 32
131 #define TEST_PWDLEN 32
132 #define TEST_SALTLEN 16
133 #define TEST_SECRETLEN 8
134 #define TEST_ADLEN 12
135 argon2_context context;
136
137 unsigned char out[TEST_OUTLEN];
138 unsigned char pwd[TEST_PWDLEN];
139 unsigned char salt[TEST_SALTLEN];
140 unsigned char secret[TEST_SECRETLEN];
141 unsigned char ad[TEST_ADLEN];
142 const allocate_fptr myown_allocator = NULL;
143 const deallocate_fptr myown_deallocator = NULL;
144
145 unsigned t_cost = 3;
146 unsigned m_cost = 32;
147 unsigned lanes = 4;
148
149 memset(pwd, 1, TEST_OUTLEN);
150 memset(salt, 2, TEST_SALTLEN);
151 memset(secret, 3, TEST_SECRETLEN);
152 memset(ad, 4, TEST_ADLEN);
153
154 context.out = out;
155 context.outlen = TEST_OUTLEN;
156 context.version = version;
157 context.pwd = pwd;
158 context.pwdlen = TEST_PWDLEN;
159 context.salt = salt;
160 context.saltlen = TEST_SALTLEN;
161 context.secret = secret;
162 context.secretlen = TEST_SECRETLEN;
163 context.ad = ad;
164 context.adlen = TEST_ADLEN;
165 context.t_cost = t_cost;
166 context.m_cost = m_cost;
167 context.lanes = lanes;
168 context.threads = lanes;
169 context.allocate_cbk = myown_allocator;
170 context.free_cbk = myown_deallocator;
171 context.flags = ARGON2_DEFAULT_FLAGS;
172
173 #undef TEST_OUTLEN
174 #undef TEST_PWDLEN
175 #undef TEST_SALTLEN
176 #undef TEST_SECRETLEN
177 #undef TEST_ADLEN
178
179 argon2_ctx(&context, type);
180 }
181
main(int argc,char * argv[])182 int main(int argc, char *argv[]) {
183 /* Get and check Argon2 type */
184 const char *type_str = (argc > 1) ? argv[1] : "i";
185 argon2_type type = Argon2_i;
186 uint32_t version = ARGON2_VERSION_NUMBER;
187 if (!strcmp(type_str, "d")) {
188 type = Argon2_d;
189 } else if (!strcmp(type_str, "i")) {
190 type = Argon2_i;
191 } else if (!strcmp(type_str, "id")) {
192 type = Argon2_id;
193 } else {
194 fatal("wrong Argon2 type");
195 }
196
197 /* Get and check Argon2 version number */
198 if (argc > 2) {
199 version = strtoul(argv[2], NULL, 10);
200 }
201 if (ARGON2_VERSION_10 != version && ARGON2_VERSION_NUMBER != version) {
202 fatal("wrong Argon2 version number");
203 }
204
205 generate_testvectors(type, version);
206 return ARGON2_OK;
207 }
208