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