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 24void 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 92void 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 105void 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 124static void fatal(const char *error) { 125 fprintf(stderr, "Error: %s\n", error); 126 exit(1); 127} 128 129static 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 182int 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