/* Runs Argon2 with certain inputs and parameters, inputs not cleared. Prints the Base64-encoded hash string @out output array with at least 32 bytes allocated @pwd NULL-terminated string, presumably from argv[] @salt salt array @t_cost number of iterations @m_cost amount of requested memory in KB @lanes amount of requested parallelism @threads actual parallelism @type String, only "d" and "i" are accepted @encoded_only display only the encoded hash @raw_only display only the hexadecimal of the hash */ static void run(uint32_t outlen, char *pwd, char *salt, uint32_t t_cost, uint32_t m_cost, uint32_t lanes, uint32_t threads, argon2_type type, int encoded_only, int raw_only) { clock_t start_time, stop_time; size_t pwdlen, saltlen, encodedlen; int result; start_time = clock(); if (!pwd) { fatal("password missing"); } if (!salt) { secure_wipe_memory(pwd, strlen(pwd)); fatal("salt missing"); } pwdlen = strlen(pwd); saltlen = strlen(salt); if(UINT32_MAX < saltlen) { fatal("salt is too long"); } UNUSED_PARAMETER(lanes); unsigned char* out = malloc(outlen + 1); if (!out) { secure_wipe_memory(pwd, strlen(pwd)); fatal("could not allocate memory for output"); } encodedlen = argon2_encodedlen(t_cost, m_cost, lanes, (uint32_t)saltlen, outlen); char* encoded = malloc(encodedlen + 1); if (!encoded) { secure_wipe_memory(pwd, strlen(pwd)); fatal("could not allocate memory for hash"); } result = argon2_hash(t_cost, m_cost, threads, pwd, pwdlen, salt, saltlen, out, outlen, encoded, encodedlen, type, ARGON2_VERSION_NUMBER); if (result != ARGON2_OK) fatal(argon2_error_message(result)); stop_time = clock(); if (encoded_only) puts(encoded); if (raw_only) print_hex(out, outlen); if (encoded_only || raw_only) { free(out); free(encoded); return; } printf("Hash:\t\t"); print_hex(out, outlen); free(out); printf("Encoded:\t%s\n", encoded); printf("%2.3f seconds\n", ((double)stop_time - start_time) / (CLOCKS_PER_SEC)); result = argon2_verify(encoded, pwd, pwdlen, type); if (result != ARGON2_OK) fatal(argon2_error_message(result)); printf("Verification ok\n"); free(encoded); }
const char *crypto_argon2_error_message(int error_code) { return argon2_error_message(error_code); }
/*** Encrypt a plain string. Use Argon2i (by default) or Argon2d to hash a string. @function encrypt @param[type=string] plain Plain string to encrypt. @param[type=string] salt Salt to use to hash pwd. @param[type=table] options Options with which to hash the plain string. See `options`. This parameter is optional, if values are omitted the default ones will be used. @treturn string `hash`: Hash computed by Argon2 or nil if an error occurred. @treturn string `error`: `nil` or a string describing the error if any. @usage local hash, err = argon2.encrypt("password", "somesalt") local hash, err = argon2.encrypt("password", "somesalt", {t_cost = 4}) */ static int largon2_encrypt(lua_State *L) { largon2_config *cfg = largon2_arg_init(L, 3); char encoded[ENCODED_LEN]; int ret_code; const char *plain, *salt; size_t plainlen, saltlen; uint32_t t_cost; uint32_t m_cost; uint32_t parallelism; argon2_type argon2_t; plain = luaL_checklstring(L, 1, &plainlen); salt = luaL_checklstring(L, 2, &saltlen); t_cost = cfg->t_cost; m_cost = cfg->m_cost; parallelism = cfg->parallelism; argon2_t = cfg->argon2_t; if (!lua_isnil(L, 3)) { if (!lua_istable(L, 3)) { luaL_argerror(L, 3, "expected to be a table"); } lua_getfield(L, 3, "t_cost"); largon2_integer_opt(L, -1, 3, &t_cost, "t_cost"); lua_pop(L, 1); lua_getfield(L, 3, "m_cost"); largon2_integer_opt(L, -1, 3, &m_cost, "m_cost"); lua_pop(L, 1); lua_getfield(L, 3, "parallelism"); largon2_integer_opt(L, -1, 3, ¶llelism, "parallelism"); lua_pop(L, 1); lua_getfield(L, -1, "argon2d"); if (!lua_isnil(L, -1) && lua_isboolean(L, -1)) { // reverse checking to allow overriding the module settings argon2_t = lua_toboolean(L, -1) ? Argon2_d : Argon2_i; } lua_pop(L, 1); } if (argon2_t == Argon2_i) ret_code = argon2i_hash_encoded(t_cost, m_cost, parallelism, plain, plainlen, salt, saltlen, HASH_LEN, encoded, ENCODED_LEN); else ret_code = argon2d_hash_encoded(t_cost, m_cost, parallelism, plain, plainlen, salt, saltlen, HASH_LEN, encoded, ENCODED_LEN); if (ret_code != ARGON2_OK) { const char *err_msg = argon2_error_message(ret_code); lua_pushnil(L); lua_pushstring(L, err_msg); return 2; } lua_pushstring(L, encoded); return 1; }
/* Runs Argon2 with certain inputs and parameters, inputs not cleared. Prints the Base64-encoded hash string @out output array with at least 32 bytes allocated @pwd NULL-terminated string, presumably from argv[] @salt salt array with at least SALTLEN_DEF bytes allocated @t_cost number of iterations @m_cost amount of requested memory in KB @lanes amount of requested parallelism @threads actual parallelism @type String, only "d" and "i" are accepted */ static void run(uint32_t outlen, char *pwd, char *salt, uint32_t t_cost, uint32_t m_cost, uint32_t lanes, uint32_t threads, argon2_type type) { clock_t start_time, stop_time; size_t pwdlen, saltlen, encodedlen; uint32_t i; int result; start_time = clock(); if (!pwd) { fatal("password missing"); } if (!salt) { secure_wipe_memory(pwd, strlen(pwd)); fatal("salt missing"); } pwdlen = strlen(pwd); saltlen = strlen(salt); UNUSED_PARAMETER(lanes); unsigned char* out = malloc(outlen + 1); if (!out) { secure_wipe_memory(pwd, strlen(pwd)); fatal("could not allocate memory for output"); } encodedlen = enclen(outlen, saltlen, t_cost, m_cost, lanes); char* encoded = malloc(encodedlen + 1); if (!encoded) { secure_wipe_memory(pwd, strlen(pwd)); fatal("could not allocate memory for hash"); } result = argon2_hash(t_cost, m_cost, threads, pwd, pwdlen, salt, saltlen, out, outlen, encoded, encodedlen, type); if (result != ARGON2_OK) fatal(argon2_error_message(result)); stop_time = clock(); printf("Hash:\t\t"); for (i = 0; i < outlen; ++i) { printf("%02x", out[i]); } free(out); printf("\n"); printf("Encoded:\t%s\n", encoded); printf("%2.3f seconds\n", ((double)stop_time - start_time) / (CLOCKS_PER_SEC)); result = argon2_verify(encoded, pwd, pwdlen, type); if (result != ARGON2_OK) fatal(argon2_error_message(result)); printf("Verification ok\n"); free(encoded); }
u3_noun u3qe_argon2( // configuration params, u3_atom out, u3_atom type, u3_atom version, u3_atom threads, u3_atom mem_cost, u3_atom time_cost, u3_atom wik, u3_atom key, u3_atom wix, u3_atom extra, // input params u3_atom wid, u3_atom dat, u3_atom wis, u3_atom sat ) { c3_assert( _(u3a_is_cat(out)) && _(u3a_is_cat(type)) && _(u3a_is_cat(version)) && _(u3a_is_cat(threads)) && _(u3a_is_cat(mem_cost)) && _(u3a_is_cat(time_cost)) && _(u3a_is_cat(wik)) && _(u3a_is_cat(wix)) && _(u3a_is_cat(wid)) && _(u3a_is_cat(wis)) ); // flip endianness for argon2 key = u3qc_rev(3, wik, key); extra = u3qc_rev(3, wix, extra); dat = u3qc_rev(3, wid, dat); sat = u3qc_rev(3, wis, sat); // atoms to byte arrays c3_y bytes_key[wik]; u3r_bytes(0, wik, bytes_key, key); c3_y bytes_extra[wix]; u3r_bytes(0, wix, bytes_extra, extra); c3_y bytes_dat[wid]; u3r_bytes(0, wid, bytes_dat, dat); c3_y bytes_sat[wis]; u3r_bytes(0, wis, bytes_sat, sat); c3_y outhash[out]; argon2_context context = { outhash, // output array, at least [digest length] in size out, // digest length bytes_dat, // password array wid, // password length bytes_sat, // salt array wis, // salt length bytes_key, wik, // optional secret data bytes_extra, wix, // optional associated data time_cost, mem_cost, threads, threads, // performance cost configuration version, // algorithm version argon2_alloc, // custom memory allocation function argon2_free, // custom memory deallocation function ARGON2_DEFAULT_FLAGS // by default only internal memory is cleared }; int argon_res; switch ( type ) { default: fprintf(stderr, "\nunjetted argon2 variant %i\n", type); u3m_bail(c3__exit); break; // case c3__d: argon_res = argon2d_ctx(&context); break; // case c3__i: argon_res = argon2i_ctx(&context); break; // case c3__id: argon_res = argon2id_ctx(&context); break; // case c3__u: argon_res = argon2u_ctx(&context); break; } if ( ARGON2_OK != argon_res ) { fprintf(stderr, "\nargon2 error: %s\n", argon2_error_message(argon_res)); u3m_bail(c3__exit); } u3z(key); u3z(extra); u3z(dat); u3z(sat); return u3kc_rev(3, out, u3i_bytes(out, outhash)); }