mirror of
https://github.com/urbit/shrub.git
synced 2024-12-26 05:23:35 +03:00
argon2
This commit is contained in:
parent
fe1375ef6b
commit
6fdc65dea6
@ -16,7 +16,7 @@ let
|
|||||||
|
|
||||||
urcrypt = import ./urcrypt {
|
urcrypt = import ./urcrypt {
|
||||||
inherit pkgs ge-additions;
|
inherit pkgs ge-additions;
|
||||||
inherit (deps) ed25519;
|
inherit (deps) ed25519 argon2;
|
||||||
};
|
};
|
||||||
|
|
||||||
libaes_siv = import ./libaes_siv {
|
libaes_siv = import ./libaes_siv {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
{ pkgs, ge-additions, ed25519 }:
|
{ pkgs, ed25519, ge-additions, argon2 }:
|
||||||
|
|
||||||
pkgs.stdenv.mkDerivation rec {
|
pkgs.stdenv.mkDerivation rec {
|
||||||
name = "urcrypt";
|
name = "urcrypt";
|
||||||
builder = ./builder.sh;
|
builder = ./builder.sh;
|
||||||
src = ../../../pkg/urcrypt;
|
src = ../../../pkg/urcrypt;
|
||||||
|
|
||||||
buildInputs = [ pkgs.openssl ed25519 ge-additions ];
|
buildInputs = [ pkgs.openssl ed25519 ge-additions argon2 ];
|
||||||
}
|
}
|
||||||
|
@ -2,104 +2,124 @@
|
|||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
#include "all.h"
|
#include "all.h"
|
||||||
|
#include <urcrypt.h>
|
||||||
#include <argon2.h>
|
|
||||||
|
|
||||||
/* helpers
|
/* helpers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int argon2_alloc(uint8_t** output, size_t bytes)
|
static c3_t
|
||||||
|
_cqear_unpack_word(c3_w *out, u3_atom in)
|
||||||
{
|
{
|
||||||
*output = u3a_malloc(bytes);
|
if ( u3r_met(5, in) > 1 ) {
|
||||||
return (NULL != output);
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*out = u3r_word(0, in);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void argon2_free(uint8_t* memory, size_t bytes)
|
static c3_t
|
||||||
|
_cqear_unpack_size(size_t *out, u3_atom in)
|
||||||
{
|
{
|
||||||
u3a_free(memory);
|
c3_w out_w;
|
||||||
|
if ( _cqear_unpack_word(&out_w, in) ) {
|
||||||
|
*out = out_w;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static c3_t
|
||||||
|
_cqear_unpack_type(urcrypt_argon2_type *out, u3_atom in)
|
||||||
|
{
|
||||||
|
switch ( in ) {
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
case c3__d:
|
||||||
|
*out = urcrypt_argon2_d;
|
||||||
|
return 1;
|
||||||
|
case c3__i:
|
||||||
|
*out = urcrypt_argon2_i;
|
||||||
|
return 1;
|
||||||
|
case c3__id:
|
||||||
|
*out = urcrypt_argon2_id;
|
||||||
|
return 1;
|
||||||
|
case c3__u:
|
||||||
|
*out = urcrypt_argon2_u;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static c3_y*
|
||||||
|
_cqear_unpack_bytes(size_t size, u3_atom in)
|
||||||
|
{
|
||||||
|
c3_y* out = u3a_malloc(size);
|
||||||
|
u3r_bytes(0, (c3_w) size, out, in);
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* functions
|
/* functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
u3_noun
|
static u3_atom
|
||||||
u3qe_argon2( // configuration params,
|
_cqe_argon2( // configuration params,
|
||||||
u3_atom out, u3_atom type, u3_atom version,
|
u3_atom out, u3_atom type, u3_atom version,
|
||||||
u3_atom threads, u3_atom mem_cost, u3_atom time_cost,
|
u3_atom threads, u3_atom mem_cost, u3_atom time_cost,
|
||||||
u3_atom wik, u3_atom key, u3_atom wix, u3_atom extra,
|
u3_atom wik, u3_atom key, u3_atom wix, u3_atom extra,
|
||||||
// input params
|
// input params
|
||||||
u3_atom wid, u3_atom dat, u3_atom wis, u3_atom sat )
|
u3_atom wid, u3_atom dat, u3_atom wis, u3_atom sat )
|
||||||
{
|
{
|
||||||
c3_assert( _(u3a_is_cat(out)) && _(u3a_is_cat(type)) &&
|
size_t out_sz, key_sz, ex_sz, dat_sz, sat_sz;
|
||||||
_(u3a_is_cat(version)) && _(u3a_is_cat(threads)) &&
|
c3_w ver_w, ted_w, mem_w, tim_w;
|
||||||
_(u3a_is_cat(mem_cost)) && _(u3a_is_cat(time_cost)) &&
|
urcrypt_argon2_type typ_u;
|
||||||
_(u3a_is_cat(wik)) && _(u3a_is_cat(wix)) &&
|
|
||||||
_(u3a_is_cat(wid)) && _(u3a_is_cat(wis)) );
|
|
||||||
|
|
||||||
// flip endianness for argon2
|
if ( !(_cqear_unpack_size(&out_sz, out) &&
|
||||||
key = u3qc_rev(3, wik, key);
|
_cqear_unpack_type(&typ_u, type) &&
|
||||||
extra = u3qc_rev(3, wix, extra);
|
_cqear_unpack_word(&ver_w, version) &&
|
||||||
dat = u3qc_rev(3, wid, dat);
|
_cqear_unpack_word(&ted_w, threads) &&
|
||||||
sat = u3qc_rev(3, wis, sat);
|
_cqear_unpack_word(&mem_w, mem_cost) &&
|
||||||
|
_cqear_unpack_word(&tim_w, time_cost) &&
|
||||||
|
_cqear_unpack_size(&key_sz, wik) &&
|
||||||
|
_cqear_unpack_size(&ex_sz, wix) &&
|
||||||
|
_cqear_unpack_size(&dat_sz, wid) &&
|
||||||
|
_cqear_unpack_size(&sat_sz, wis)) ) {
|
||||||
|
u3l_log("%s\r\n", "argon2-punt");
|
||||||
|
return u3_none;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
u3_atom ret;
|
||||||
|
c3_y *key_y = _cqear_unpack_bytes(key_sz, key),
|
||||||
|
*ex_y = _cqear_unpack_bytes(ex_sz, extra),
|
||||||
|
*dat_y = _cqear_unpack_bytes(dat_sz, dat),
|
||||||
|
*sat_y = _cqear_unpack_bytes(sat_sz, sat),
|
||||||
|
*out_y = u3a_malloc(out_sz);
|
||||||
|
const c3_c* err_c = urcrypt_argon2(
|
||||||
|
typ_u, ver_w, ted_w, mem_w, tim_w,
|
||||||
|
key_sz, key_y,
|
||||||
|
ex_sz, ex_y,
|
||||||
|
dat_sz, dat_y,
|
||||||
|
sat_sz, sat_y,
|
||||||
|
out_sz, out_y);
|
||||||
|
|
||||||
// atoms to byte arrays
|
u3a_free(key_y);
|
||||||
c3_y bytes_key[wik];
|
u3a_free(ex_y);
|
||||||
u3r_bytes(0, wik, bytes_key, key);
|
u3a_free(dat_y);
|
||||||
c3_y bytes_extra[wix];
|
u3a_free(sat_y);
|
||||||
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];
|
if ( NULL == err_c ) {
|
||||||
argon2_context context = {
|
ret = u3i_bytes(out_sz, out_y);
|
||||||
outhash, // output array, at least [digest length] in size
|
}
|
||||||
out, // digest length
|
else {
|
||||||
bytes_dat, // password array
|
ret = u3_none;
|
||||||
wid, // password length
|
u3l_log("argon2-punt: %s\r\n", err_c);
|
||||||
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:
|
|
||||||
u3l_log("\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 ) {
|
u3a_free(out_y);
|
||||||
u3l_log("\nargon2 error: %s\n", argon2_error_message(argon_res));
|
return ret;
|
||||||
u3m_bail(c3__exit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u3z(key); u3z(extra); u3z(dat); u3z(sat);
|
|
||||||
return u3kc_rev(3, out, u3i_bytes(out, outhash));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u3_noun
|
u3_noun
|
||||||
@ -138,7 +158,7 @@
|
|||||||
return u3m_bail(c3__exit);
|
return u3m_bail(c3__exit);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return u3qe_argon2(out, type, version,
|
return _cqe_argon2(out, type, version,
|
||||||
threads, mem_cost, time_cost,
|
threads, mem_cost, time_cost,
|
||||||
wik, key, wix, extra,
|
wik, key, wix, extra,
|
||||||
wid, dat, wis, sat);
|
wid, dat, wis, sat);
|
||||||
|
@ -16,7 +16,7 @@ liburcrypt.a: $(SOURCES)
|
|||||||
liburcrypt.so: $(SOURCES)
|
liburcrypt.so: $(SOURCES)
|
||||||
$(CC) $(CFLAGS) -fPIC -c urcrypt.c -o urcrypt-shared.o
|
$(CC) $(CFLAGS) -fPIC -c urcrypt.c -o urcrypt-shared.o
|
||||||
$(CC) -shared urcrypt-shared.o -o liburcrypt.so \
|
$(CC) -shared urcrypt-shared.o -o liburcrypt.so \
|
||||||
-led25519 -lge-additions -lssl \
|
-led25519 -lge-additions -lssl -largon2 \
|
||||||
-Wl,--no-undefined
|
-Wl,--no-undefined
|
||||||
|
|
||||||
all: liburcrypt.a liburcrypt.so
|
all: liburcrypt.a liburcrypt.so
|
||||||
|
@ -249,6 +249,14 @@ _urcrypt_reverse_copy(size_t size, const uint8_t *in, uint8_t *out) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t*
|
||||||
|
_urcrypt_reverse_alloc(size_t size, const uint8_t *in)
|
||||||
|
{
|
||||||
|
uint8_t *out = urcrypt_malloc(size);
|
||||||
|
_urcrypt_reverse_copy(size, in, out);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_urcrypt_reverse_inplace(size_t size, uint8_t *ptr) {
|
_urcrypt_reverse_inplace(size_t size, uint8_t *ptr) {
|
||||||
size_t i, j;
|
size_t i, j;
|
||||||
@ -572,3 +580,109 @@ urcrypt_aes_cbcc_de(const uint8_t *message,
|
|||||||
out_length);
|
out_length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_urcrypt_argon2_alloc(uint8_t** output, size_t bytes)
|
||||||
|
{
|
||||||
|
*output = urcrypt_malloc(bytes);
|
||||||
|
return (NULL != output);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_urcrypt_argon2_free(uint8_t* memory, size_t bytes)
|
||||||
|
{
|
||||||
|
urcrypt_free(memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
// library convention is to have sizes in size_t, but argon2 wants them
|
||||||
|
// in uint32_t, so here's a helper macro for ensuring equivalence.
|
||||||
|
#define SZ_32(s) ( sizeof(size_t) <= sizeof(uint32_t) || s <= 0xFFFFFFFF )
|
||||||
|
|
||||||
|
// returns a constant error message string or NULL for success
|
||||||
|
// (so user doesn't have to call argon2_error_message)
|
||||||
|
const char*
|
||||||
|
urcrypt_argon2(urcrypt_argon2_type type,
|
||||||
|
uint32_t version,
|
||||||
|
uint32_t threads,
|
||||||
|
uint32_t memory_cost,
|
||||||
|
uint32_t time_cost,
|
||||||
|
size_t secret_length,
|
||||||
|
const uint8_t *secret,
|
||||||
|
size_t associated_length,
|
||||||
|
const uint8_t *associated,
|
||||||
|
size_t password_length,
|
||||||
|
const uint8_t *password,
|
||||||
|
size_t salt_length,
|
||||||
|
const uint8_t *salt,
|
||||||
|
size_t out_length,
|
||||||
|
uint8_t *out)
|
||||||
|
{
|
||||||
|
if ( !( SZ_32(secret_length) &&
|
||||||
|
SZ_32(associated_length) &&
|
||||||
|
SZ_32(password_length) &&
|
||||||
|
SZ_32(salt_length) &&
|
||||||
|
SZ_32(out_length) ) ) {
|
||||||
|
return "length > 32 bits";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int (*f)(argon2_context*);
|
||||||
|
int result;
|
||||||
|
uint8_t *rsecret, *rassoc, *rpassword, *rsalt;
|
||||||
|
|
||||||
|
switch ( type ) {
|
||||||
|
default:
|
||||||
|
return "unknown type";
|
||||||
|
case urcrypt_argon2_d:
|
||||||
|
f = &argon2d_ctx;
|
||||||
|
break;
|
||||||
|
case urcrypt_argon2_i:
|
||||||
|
f = &argon2i_ctx;
|
||||||
|
break;
|
||||||
|
case urcrypt_argon2_id:
|
||||||
|
f = &argon2id_ctx;
|
||||||
|
break;
|
||||||
|
case urcrypt_argon2_u:
|
||||||
|
f = &argon2u_ctx;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
rsecret = _urcrypt_reverse_alloc(secret_length, secret);
|
||||||
|
rassoc = _urcrypt_reverse_alloc(associated_length, associated);
|
||||||
|
rpassword = _urcrypt_reverse_alloc(password_length, password);
|
||||||
|
rsalt = _urcrypt_reverse_alloc(salt_length, salt);
|
||||||
|
argon2_context context = {
|
||||||
|
out, // output array, at least [digest length] in size
|
||||||
|
out_length, // digest length
|
||||||
|
rpassword, // password array
|
||||||
|
password_length, // password length
|
||||||
|
rsalt, // salt array
|
||||||
|
salt_length, // salt length
|
||||||
|
rsecret, // optional secret data
|
||||||
|
secret_length,
|
||||||
|
rassoc, // optional associated data
|
||||||
|
associated_length,
|
||||||
|
time_cost, // performance cost configuration
|
||||||
|
memory_cost,
|
||||||
|
threads,
|
||||||
|
threads,
|
||||||
|
version, // algorithm version
|
||||||
|
&_urcrypt_argon2_alloc,// custom memory allocation function
|
||||||
|
&_urcrypt_argon2_free, // custom memory deallocation function
|
||||||
|
ARGON2_DEFAULT_FLAGS // by default only internal memory is cleared
|
||||||
|
};
|
||||||
|
|
||||||
|
result = (*f)(&context);
|
||||||
|
urcrypt_free(rsecret);
|
||||||
|
urcrypt_free(rassoc);
|
||||||
|
urcrypt_free(rpassword);
|
||||||
|
urcrypt_free(rsalt);
|
||||||
|
|
||||||
|
if ( ARGON2_OK != result ) {
|
||||||
|
return argon2_error_message(result);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_urcrypt_reverse_inplace(out_length, out);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
#include <openssl/crypto.h>
|
#include <openssl/crypto.h>
|
||||||
#include <openssl/aes.h>
|
#include <openssl/aes.h>
|
||||||
|
|
||||||
|
#include <argon2.h>
|
||||||
|
|
||||||
typedef void *(*urcrypt_malloc_t)(size_t);
|
typedef void *(*urcrypt_malloc_t)(size_t);
|
||||||
typedef void *(*urcrypt_realloc_t)(void*, size_t);
|
typedef void *(*urcrypt_realloc_t)(void*, size_t);
|
||||||
typedef void (*urcrypt_free_t)(void*);
|
typedef void (*urcrypt_free_t)(void*);
|
||||||
@ -104,4 +106,27 @@ uint8_t* urcrypt_aes_cbcc_de(const uint8_t *message,
|
|||||||
const uint8_t ivec[16],
|
const uint8_t ivec[16],
|
||||||
size_t *out_length);
|
size_t *out_length);
|
||||||
|
|
||||||
|
typedef enum urcrypt_argon2_type {
|
||||||
|
urcrypt_argon2_d = 0,
|
||||||
|
urcrypt_argon2_i = 1,
|
||||||
|
urcrypt_argon2_id = 2,
|
||||||
|
urcrypt_argon2_u = 10,
|
||||||
|
} urcrypt_argon2_type;
|
||||||
|
|
||||||
|
const char* urcrypt_argon2(urcrypt_argon2_type type,
|
||||||
|
uint32_t version,
|
||||||
|
uint32_t threads,
|
||||||
|
uint32_t memory_cost,
|
||||||
|
uint32_t time_cost,
|
||||||
|
size_t secret_length,
|
||||||
|
const uint8_t *secret,
|
||||||
|
size_t associated_length,
|
||||||
|
const uint8_t *associated,
|
||||||
|
size_t password_length,
|
||||||
|
const uint8_t *password,
|
||||||
|
size_t salt_length,
|
||||||
|
const uint8_t *salt,
|
||||||
|
size_t out_length,
|
||||||
|
uint8_t *out);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user