2018-07-20 02:48:07 +03:00
|
|
|
/* j/5/argon2.c
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
#include "all.h"
|
|
|
|
|
|
|
|
#include <argon2.h>
|
|
|
|
|
2018-11-13 22:11:48 +03:00
|
|
|
/* helpers
|
|
|
|
*/
|
|
|
|
|
|
|
|
int argon2_alloc(uint8_t** output, size_t bytes)
|
|
|
|
{
|
|
|
|
*output = u3a_malloc(bytes);
|
|
|
|
return (NULL != output);
|
|
|
|
}
|
|
|
|
|
2018-11-15 00:38:34 +03:00
|
|
|
void argon2_free(uint8_t* memory, size_t bytes)
|
2018-11-13 22:11:48 +03:00
|
|
|
{
|
|
|
|
u3a_free(memory);
|
|
|
|
}
|
|
|
|
|
2018-07-20 02:48:07 +03:00
|
|
|
/* functions
|
|
|
|
*/
|
|
|
|
|
|
|
|
u3_noun
|
2018-11-15 00:38:34 +03:00
|
|
|
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 )
|
2018-07-20 02:48:07 +03:00
|
|
|
{
|
2018-11-15 00:38:34 +03:00
|
|
|
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)) );
|
2018-07-20 02:48:07 +03:00
|
|
|
|
|
|
|
// 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
|
2018-11-13 22:11:48 +03:00
|
|
|
argon2_alloc, // custom memory allocation function
|
2018-11-15 00:38:34 +03:00
|
|
|
argon2_free, // custom memory deallocation function
|
2018-07-20 02:48:07 +03:00
|
|
|
ARGON2_DEFAULT_FLAGS // by default only internal memory is cleared
|
|
|
|
};
|
|
|
|
|
|
|
|
int argon_res;
|
2018-11-15 00:38:34 +03:00
|
|
|
switch ( type ) {
|
|
|
|
default:
|
|
|
|
fprintf(stderr, "\nunjetted argon2 variant %i\n", type);
|
|
|
|
u3m_bail(c3__exit);
|
|
|
|
break;
|
|
|
|
//
|
2018-11-04 22:41:24 +03:00
|
|
|
case c3__d:
|
|
|
|
argon_res = argon2d_ctx(&context);
|
|
|
|
break;
|
2018-07-20 02:48:07 +03:00
|
|
|
//
|
2018-11-04 22:41:24 +03:00
|
|
|
case c3__i:
|
|
|
|
argon_res = argon2i_ctx(&context);
|
|
|
|
break;
|
2018-07-20 02:48:07 +03:00
|
|
|
//
|
2018-11-04 22:41:24 +03:00
|
|
|
case c3__id:
|
|
|
|
argon_res = argon2id_ctx(&context);
|
|
|
|
break;
|
2018-07-20 02:48:07 +03:00
|
|
|
//
|
2018-11-04 22:41:24 +03:00
|
|
|
case c3__u:
|
|
|
|
argon_res = argon2u_ctx(&context);
|
|
|
|
break;
|
2018-07-20 02:48:07 +03:00
|
|
|
}
|
|
|
|
|
2018-11-15 00:38:34 +03:00
|
|
|
if ( ARGON2_OK != argon_res ) {
|
2018-07-20 02:48:07 +03:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
|
|
|
u3_noun
|
|
|
|
u3we_argon2(u3_noun cor)
|
|
|
|
{
|
|
|
|
u3_noun // configuration params
|
|
|
|
out, type, version,
|
|
|
|
threads, mem_cost, time_cost,
|
|
|
|
wik, key, wix, extra,
|
|
|
|
// input params
|
2018-11-04 22:40:14 +03:00
|
|
|
wid, dat, wis, sat,
|
|
|
|
// for use during unpacking
|
|
|
|
wmsg, wsat, arg, brg, wkey, wext;
|
2018-07-20 02:48:07 +03:00
|
|
|
|
|
|
|
// the hoon code for argon2 takes configuration parameters,
|
|
|
|
// and then produces a gate. we jet that inner gate.
|
|
|
|
// this does mean that the config params have gotten buried
|
2018-11-04 22:40:14 +03:00
|
|
|
// pretty deep in the subject, hence the +510.
|
|
|
|
if ( c3n == u3r_mean(cor, u3x_sam_2, &wmsg,
|
|
|
|
u3x_sam_3, &wsat,
|
|
|
|
510, &arg, 0) ||
|
|
|
|
u3r_cell(wmsg, &wid, &dat) || u3ud(wid) || u3ud(dat) ||
|
|
|
|
u3r_cell(wsat, &wis, &sat) || u3ud(wis) || u3ud(sat) ||
|
|
|
|
//
|
|
|
|
u3r_qual(arg, &out, &type, &version, &brg) ||
|
|
|
|
u3ud(out) || u3ud(type) || u3ud(version) ||
|
|
|
|
//
|
|
|
|
u3r_qual(brg, &threads, &mem_cost, &time_cost, &arg) ||
|
|
|
|
u3ud(threads) || u3ud(mem_cost) || u3ud(time_cost) ||
|
|
|
|
//
|
|
|
|
u3r_cell(arg, &wkey, &wext) ||
|
|
|
|
u3r_cell(wkey, &wik, &key) || u3ud(wik) || u3ud(key) ||
|
|
|
|
u3r_cell(wext, &wix, &extra) || u3ud(wix) || u3ud(extra)
|
2018-07-20 02:48:07 +03:00
|
|
|
)
|
|
|
|
{
|
|
|
|
return u3m_bail(c3__exit);
|
2018-11-15 00:38:34 +03:00
|
|
|
}
|
|
|
|
else {
|
2018-07-20 02:48:07 +03:00
|
|
|
return u3qe_argon2(out, type, version,
|
|
|
|
threads, mem_cost, time_cost,
|
|
|
|
wik, key, wix, extra,
|
|
|
|
wid, dat, wis, sat);
|
|
|
|
}
|
|
|
|
}
|