aes-siva-en->urcrypt

This commit is contained in:
Paul Driver 2020-08-24 14:33:57 -07:00
parent 856de7e415
commit 8d657e12c1
6 changed files with 211 additions and 26 deletions

View File

@ -14,15 +14,15 @@ let
inherit (deps) ed25519;
};
urcrypt = import ./urcrypt {
inherit pkgs ge-additions;
inherit (deps) ed25519 argon2;
};
libaes_siv = import ./libaes_siv {
inherit pkgs;
};
urcrypt = import ./urcrypt {
inherit pkgs ge-additions libaes_siv;
inherit (deps) ed25519 argon2;
};
mkUrbit = { debug }:
import ./urbit {
inherit pkgs ent debug ge-additions urcrypt libaes_siv;

View File

@ -1,9 +1,9 @@
{ pkgs, ed25519, ge-additions, argon2 }:
{ pkgs, ed25519, ge-additions, argon2, libaes_siv }:
pkgs.stdenv.mkDerivation rec {
name = "urcrypt";
builder = ./builder.sh;
src = ../../../pkg/urcrypt;
buildInputs = [ pkgs.openssl ed25519 ge-additions argon2 ];
buildInputs = [ pkgs.openssl ed25519 ge-additions argon2 libaes_siv ];
}

View File

@ -2,11 +2,135 @@
**
*/
#include "all.h"
#include <urcrypt.h>
#include "aes_siv.h"
typedef int (*urcrypt_siv)(c3_y*, size_t,
urcrypt_aes_siv_data*, size_t,
c3_y*, c3_y[16], c3_y*);
/* functions
*/
// soc_w = number of items
// mat_w = size in bytes of assoc array
// dat_w = size of allocation (array + atom storage)
static void
_cqea_measure_ads(u3_noun ads, c3_w* soc_w, c3_w *mat_w, c3_w *dat_w)
{
u3_noun i, t;
c3_w a_w, b_w, tmp_w, met_w;
for ( a_w = b_w = 0, t = ads; u3_nul != t; ++a_w ) {
u3x_cell(t, &i, &t);
if ( c3n == u3ud(i) ) {
u3m_bail(c3__exit);
return;
}
else {
tmp_w = b_w;
b_w += u3r_met(3, i);
if ( b_w < tmp_w ) {
u3m_bail(c3__fail);
return;
}
}
}
// check for size overflows
tmp_w = a_w * sizeof(urcrypt_aes_siv_data);
if ( (tmp_w / a_w) != sizeof(urcrypt_aes_siv_data) ) {
u3m_bail(c3__fail);
}
else if ( (*dat_w = tmp_w + b_w) < tmp_w ) {
u3m_bail(c3__fail);
}
else {
*soc_w = a_w;
*mat_w = tmp_w;
}
}
// assumes ads is a valid (list @) because it's already been measured
static void
_cqea_encode_ads(u3_noun ads,
c3_w mat_w,
urcrypt_aes_siv_data *dat_u)
{
c3_w met_w;
u3_noun i, t;
urcrypt_aes_siv_data *cur_u;
c3_y *dat_y = ((c3_y*) dat_u) + mat_w;
for ( cur_u = dat_u, t = ads; u3_nul != t; t = u3t(t), ++cur_u ) {
i = u3h(t);
met_w = u3r_met(3, i);
u3r_bytes(0, met_w, dat_y, i);
cur_u->length = met_w;
cur_u->bytes = dat_y;
dat_y += met_w;
}
}
static u3_noun
_cqea_siv_en(c3_y* key_y,
c3_w key_w,
u3_noun ads,
u3_atom txt,
urcrypt_siv low_f)
{
u3_noun ret;
c3_w txt_w, soc_w;
c3_y *txt_y, *out_y, iv_y[16];
c3_t ads_t = ( u3_nul != ads );
urcrypt_aes_siv_data *dat_u;
if ( !ads_t ) {
soc_w = 0;
dat_u = NULL;
}
else {
c3_w mat_w, dat_w;
_cqea_measure_ads(ads, &soc_w, &mat_w, &dat_w);
dat_u = u3a_malloc(dat_w);
_cqea_encode_ads(ads, mat_w, dat_u);
}
txt_y = u3r_bytes_all(&txt_w, txt);
out_y = u3a_malloc(txt_w);
ret = ( 0 != (*low_f)(txt_y, txt_w, dat_u, soc_w, key_y, iv_y, out_y) )
? u3_none
: u3nt(u3i_bytes(16, iv_y),
u3i_words(1, &txt_w),
u3i_bytes(txt_w, out_y));
u3a_free(txt_y);
u3a_free(out_y);
if ( ads_t ) {
u3a_free(dat_u);
}
return ret;
}
static u3_noun
_cqea_siva_en(u3_atom key,
u3_noun ads,
u3_atom txt)
{
if ( u3r_met(3, key) > 32 ) {
// hoon doesn't explicitly check size, but we need 32.
return u3_none;
}
else {
c3_y key_y[32];
u3r_bytes(0, 32, key_y, key);
return _cqea_siv_en(key_y, 32, ads, txt, &urcrypt_aes_siva_en);
}
}
static void u3r_bytes_reverse(c3_w a_w,
c3_w b_w,
c3_y* c_y, /* out */
@ -152,21 +276,6 @@ static u3_noun _siv_de(c3_y* key_y,
return u3nc(0, rev_msg);
}
u3_noun
u3qea_siva_en(u3_atom key,
u3_noun ads,
u3_atom txt)
{
c3_y key_y[32];
if (u3r_met(3, key) > 32) {
return u3_none;
}
u3r_bytes_reverse(0, 32, key_y, key);
return _siv_en(key_y, 32, ads, txt);
}
u3_noun
u3wea_siva_en(u3_noun cor)
{
@ -179,7 +288,7 @@ u3wea_siva_en(u3_noun cor)
c3n == u3ud(txt) ) {
return u3m_bail(c3__exit);
} else {
return u3qea_siva_en(key, ads, txt);
return _cqea_siva_en(key, ads, txt);
}
}

View File

@ -16,7 +16,7 @@ liburcrypt.a: $(SOURCES)
liburcrypt.so: $(SOURCES)
$(CC) $(CFLAGS) -fPIC -c urcrypt.c -o urcrypt-shared.o
$(CC) -shared urcrypt-shared.o -o liburcrypt.so \
-led25519 -lge-additions -lssl -largon2 \
-led25519 -lge-additions -lssl -largon2 -laes_siv \
-Wl,--no-undefined
all: liburcrypt.a liburcrypt.so

View File

@ -5,9 +5,10 @@
#include <ge-additions.h>
#include <openssl/crypto.h>
#include <openssl/aes.h>
#include <openssl/ripemd.h>
#include <openssl/sha.h>
#include <openssl/aes.h>
#include <aes_siv.h>
#include <argon2.h>
#include <blake2.h>
@ -527,6 +528,69 @@ urcrypt_aes_cbcc_de(uint8_t **message_ptr,
}
}
static int
_urcrypt_aes_siv_en(uint8_t *key,
size_t key_length,
uint8_t *message,
size_t message_length,
urcrypt_aes_siv_data *data,
size_t data_length,
uint8_t iv[16],
uint8_t *out)
{
AES_SIV_CTX *ctx = AES_SIV_CTX_new();
if ( NULL == ctx ) {
return -1;
}
else {
int code;
_urcrypt_reverse(key_length, key);
if ( 0 == AES_SIV_Init(ctx, key, key_length) ) {
code = -2;
}
else {
uint8_t *bytes;
size_t i, blen;
for ( i = 0; i < data_length; ++i ) {
blen = data[i].length;
bytes = data[i].bytes;
_urcrypt_reverse(blen, bytes);
if ( 0 == AES_SIV_AssociateData(ctx, bytes, blen) ) {
code = -3;
goto finish;
}
}
_urcrypt_reverse(message_length, message);
if ( 0 == AES_SIV_EncryptFinal(ctx, iv, out, message, message_length) ) {
code = -4;
}
else {
_urcrypt_reverse(16, iv);
_urcrypt_reverse(message_length, out);
code = 0;
}
}
finish:
AES_SIV_CTX_free(ctx);
return code;
}
}
int
urcrypt_aes_siva_en(uint8_t *message,
size_t message_length,
urcrypt_aes_siv_data *data,
size_t data_length,
uint8_t key[32],
uint8_t iv[16],
uint8_t *out)
{
return _urcrypt_aes_siv_en(key, 32, message, message_length, data, data_length, iv, out);
}
int
urcrypt_ripemd160(uint8_t *message, size_t length, uint8_t out[20])
{
@ -641,7 +705,6 @@ urcrypt_argon2(urcrypt_argon2_type type,
int (*f)(argon2_context*);
int result;
switch ( type ) {
default:
return "unknown type";

View File

@ -100,6 +100,19 @@ int urcrypt_aes_cbcc_de(uint8_t **message_ptr,
uint8_t ivec[16],
urcrypt_realloc_t realloc_ptr);
typedef struct {
size_t length;
uint8_t *bytes;
} urcrypt_aes_siv_data;
int urcrypt_aes_siva_en(uint8_t *message,
size_t message_length,
urcrypt_aes_siv_data *data,
size_t data_length,
uint8_t key[32],
uint8_t iv[16],
uint8_t *out);
int urcrypt_ripemd160(uint8_t *message, size_t length, uint8_t out[20]);
void urcrypt_sha1(uint8_t *message, size_t length, uint8_t out[20]);