2020-07-28 05:19:17 +03:00
|
|
|
#include "urcrypt.h"
|
|
|
|
|
2020-08-19 01:47:19 +03:00
|
|
|
#include <string.h>
|
|
|
|
#include <ed25519.h>
|
|
|
|
#include <ge-additions.h>
|
|
|
|
|
|
|
|
#include <openssl/crypto.h>
|
|
|
|
#include <openssl/aes.h>
|
2020-08-21 00:43:22 +03:00
|
|
|
#include <openssl/ripemd.h>
|
2020-08-21 01:04:53 +03:00
|
|
|
#include <openssl/sha.h>
|
2020-08-19 01:47:19 +03:00
|
|
|
|
|
|
|
#include <argon2.h>
|
|
|
|
#include <blake2.h>
|
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
static urcrypt_malloc_t _urcrypt_ssl_malloc_ptr;
|
|
|
|
static urcrypt_realloc_t _urcrypt_ssl_realloc_ptr;
|
|
|
|
static urcrypt_free_t _urcrypt_ssl_free_ptr;
|
2020-08-07 22:28:50 +03:00
|
|
|
|
|
|
|
static void*
|
2020-08-18 20:31:50 +03:00
|
|
|
_urcrypt_malloc_ssl(size_t len
|
2020-08-07 22:28:50 +03:00
|
|
|
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
|
|
|
, const char* file, int line
|
|
|
|
#endif
|
2020-08-18 22:35:07 +03:00
|
|
|
) { return (*_urcrypt_ssl_malloc_ptr)(len); }
|
2020-08-07 22:28:50 +03:00
|
|
|
|
|
|
|
static void*
|
2020-08-18 20:31:50 +03:00
|
|
|
_urcrypt_realloc_ssl(void* ptr, size_t len
|
2020-08-07 22:28:50 +03:00
|
|
|
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
|
|
|
, const char* file, int line
|
|
|
|
#endif
|
2020-08-18 22:35:07 +03:00
|
|
|
) { return (*_urcrypt_ssl_realloc_ptr)(ptr, len); }
|
2020-08-07 22:28:50 +03:00
|
|
|
|
|
|
|
static void
|
2020-08-18 20:31:50 +03:00
|
|
|
_urcrypt_free_ssl(void* ptr
|
2020-08-07 22:28:50 +03:00
|
|
|
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
|
|
|
, const char* file, int line
|
|
|
|
#endif
|
2020-08-18 22:35:07 +03:00
|
|
|
) { (*_urcrypt_ssl_free_ptr)(ptr); }
|
2020-08-07 22:28:50 +03:00
|
|
|
|
|
|
|
int
|
2020-08-19 01:42:22 +03:00
|
|
|
urcrypt_set_openssl_mem_functions(urcrypt_malloc_t malloc_ptr,
|
|
|
|
urcrypt_realloc_t realloc_ptr,
|
|
|
|
urcrypt_free_t free_ptr)
|
2020-08-07 22:28:50 +03:00
|
|
|
{
|
2020-08-19 01:42:22 +03:00
|
|
|
if ( CRYPTO_set_mem_functions(&_urcrypt_malloc_ssl,
|
|
|
|
&_urcrypt_realloc_ssl,
|
|
|
|
&_urcrypt_free_ssl) ) {
|
2020-08-18 22:35:07 +03:00
|
|
|
_urcrypt_ssl_malloc_ptr = malloc_ptr;
|
|
|
|
_urcrypt_ssl_realloc_ptr = realloc_ptr;
|
|
|
|
_urcrypt_ssl_free_ptr = free_ptr;
|
2020-08-19 01:42:22 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return -1;
|
2020-08-07 22:28:50 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-31 20:50:46 +03:00
|
|
|
int
|
2020-08-07 22:28:50 +03:00
|
|
|
urcrypt_ed_point_add(const uint8_t a[32],
|
|
|
|
const uint8_t b[32],
|
|
|
|
uint8_t out[32])
|
2020-07-31 20:50:46 +03:00
|
|
|
{
|
|
|
|
ge_p3 A, B;
|
|
|
|
ge_cached b_cached;
|
|
|
|
ge_p1p1 sum;
|
|
|
|
ge_p3 result;
|
|
|
|
|
|
|
|
if ( ge_frombytes_negate_vartime(&A, a) != 0 ) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ge_frombytes_negate_vartime(&B, b) != 0 ) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Undo the negation from above. See add_scalar.c in the ed25519 distro.
|
|
|
|
fe_neg(A.X, A.X);
|
|
|
|
fe_neg(A.T, A.T);
|
|
|
|
fe_neg(B.X, B.X);
|
|
|
|
fe_neg(B.T, B.T);
|
|
|
|
|
|
|
|
ge_p3_to_cached(&b_cached, &B);
|
|
|
|
ge_add(&sum, &A, &b_cached);
|
|
|
|
ge_p1p1_to_p3(&result, &sum);
|
|
|
|
|
|
|
|
ge_p3_tobytes(out, &result);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-07-28 05:19:17 +03:00
|
|
|
int
|
2020-08-07 22:28:50 +03:00
|
|
|
urcrypt_ed_scalarmult(const uint8_t a[32],
|
|
|
|
const uint8_t b[32],
|
|
|
|
uint8_t out[32])
|
2020-07-28 05:19:17 +03:00
|
|
|
{
|
|
|
|
ge_p3 B, result;
|
|
|
|
|
|
|
|
if ( ge_frombytes_negate_vartime(&B, b) != 0 ) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Undo the negation from above. See add_scalar.c in the ed25519 distro.
|
|
|
|
fe_neg(B.X, B.X);
|
|
|
|
fe_neg(B.T, B.T);
|
|
|
|
|
|
|
|
ge_scalarmult(&result, a, &B);
|
|
|
|
ge_p3_tobytes(out, &result);
|
|
|
|
return 0;
|
|
|
|
}
|
2020-07-31 00:40:47 +03:00
|
|
|
|
2020-07-31 21:55:02 +03:00
|
|
|
void
|
2020-08-07 22:28:50 +03:00
|
|
|
urcrypt_ed_scalarmult_base(const uint8_t a[32],
|
|
|
|
uint8_t out[32])
|
2020-07-31 21:55:02 +03:00
|
|
|
{
|
|
|
|
ge_p3 R;
|
|
|
|
ge_scalarmult_base(&R, a);
|
|
|
|
ge_p3_tobytes(out, &R);
|
|
|
|
}
|
|
|
|
|
2020-08-01 00:21:02 +03:00
|
|
|
int
|
2020-08-07 22:28:50 +03:00
|
|
|
urcrypt_ed_add_scalarmult_scalarmult_base(const uint8_t a[32],
|
|
|
|
const uint8_t a_point[32],
|
|
|
|
const uint8_t b[32],
|
2020-08-01 00:21:02 +03:00
|
|
|
uint8_t out[32])
|
|
|
|
{
|
|
|
|
ge_p2 r;
|
|
|
|
ge_p3 A;
|
|
|
|
|
|
|
|
if (ge_frombytes_negate_vartime(&A, a_point) != 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Undo the negation from above. See add_scalar.c in the ed25519 distro.
|
|
|
|
fe_neg(A.X, A.X);
|
|
|
|
fe_neg(A.T, A.T);
|
|
|
|
|
|
|
|
ge_double_scalarmult_vartime(&r, a, &A, b);
|
|
|
|
ge_tobytes(out, &r);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-08-01 00:46:19 +03:00
|
|
|
int
|
2020-08-07 22:28:50 +03:00
|
|
|
urcrypt_ed_add_double_scalarmult(const uint8_t a[32],
|
|
|
|
const uint8_t a_point[32],
|
|
|
|
const uint8_t b[32],
|
|
|
|
const uint8_t b_point[32],
|
2020-08-01 00:46:19 +03:00
|
|
|
uint8_t out[32])
|
|
|
|
{
|
|
|
|
ge_p3 A, B, a_result, b_result, final_result;
|
|
|
|
ge_cached b_result_cached;
|
|
|
|
ge_p1p1 sum;
|
|
|
|
|
|
|
|
if ( ge_frombytes_negate_vartime(&A, a_point) != 0 ) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ge_frombytes_negate_vartime(&B, b_point) != 0 ) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Undo the negation from above. See add_scalar.c in the ed25519 distro.
|
|
|
|
fe_neg(A.X, A.X);
|
|
|
|
fe_neg(A.T, A.T);
|
|
|
|
fe_neg(B.X, B.X);
|
|
|
|
fe_neg(B.T, B.T);
|
|
|
|
|
|
|
|
// Perform the multiplications of a*A and b*B
|
|
|
|
ge_scalarmult(&a_result, a, &A);
|
|
|
|
ge_scalarmult(&b_result, b, &B);
|
|
|
|
|
|
|
|
// Sum those two points
|
|
|
|
ge_p3_to_cached(&b_result_cached, &b_result);
|
|
|
|
ge_add(&sum, &a_result, &b_result_cached);
|
|
|
|
|
|
|
|
ge_p1p1_to_p3(&final_result, &sum);
|
|
|
|
ge_p3_tobytes(out, &final_result);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-08-01 02:31:56 +03:00
|
|
|
void
|
2020-08-07 22:28:50 +03:00
|
|
|
urcrypt_ed_puck(const uint8_t seed[32],
|
|
|
|
uint8_t out[32])
|
2020-08-01 02:31:56 +03:00
|
|
|
{
|
|
|
|
uint8_t secret[64];
|
|
|
|
ed25519_create_keypair(out, secret, seed);
|
|
|
|
}
|
|
|
|
|
2020-08-01 02:56:39 +03:00
|
|
|
void
|
2020-08-07 22:28:50 +03:00
|
|
|
urcrypt_ed_shar(const uint8_t public[32],
|
|
|
|
const uint8_t seed[32],
|
|
|
|
uint8_t out[32])
|
2020-08-01 02:56:39 +03:00
|
|
|
{
|
|
|
|
uint8_t self[32], exp[64];
|
|
|
|
|
|
|
|
memset(self, 0, 32);
|
|
|
|
memset(exp, 0, 64);
|
|
|
|
memset(out, 0, 32);
|
|
|
|
|
|
|
|
ed25519_create_keypair(self, exp, seed);
|
|
|
|
ed25519_key_exchange(out, public, exp);
|
|
|
|
}
|
|
|
|
|
2020-07-31 00:40:47 +03:00
|
|
|
void
|
2020-08-07 22:28:50 +03:00
|
|
|
urcrypt_ed_sign(const uint8_t *message,
|
2020-07-31 00:40:47 +03:00
|
|
|
size_t length,
|
2020-08-07 22:28:50 +03:00
|
|
|
const uint8_t seed[32],
|
2020-07-31 00:40:47 +03:00
|
|
|
uint8_t out[64])
|
|
|
|
{
|
|
|
|
uint8_t public[64], secret[64];
|
|
|
|
|
|
|
|
memset(public, 0, 64);
|
|
|
|
memset(secret, 0, 64);
|
|
|
|
memset(out, 0, 64);
|
|
|
|
|
|
|
|
ed25519_create_keypair(public, secret, seed);
|
|
|
|
ed25519_sign(out, message, length, public, secret);
|
|
|
|
}
|
2020-08-01 03:30:09 +03:00
|
|
|
|
|
|
|
bool
|
2020-08-07 22:28:50 +03:00
|
|
|
urcrypt_ed_veri(const uint8_t *message,
|
|
|
|
size_t length,
|
|
|
|
const uint8_t public[32],
|
|
|
|
const uint8_t signature[64])
|
2020-08-01 03:30:09 +03:00
|
|
|
{
|
|
|
|
return ( ed25519_verify(signature, message, length, public) == 1 )
|
|
|
|
? true
|
|
|
|
: false;
|
|
|
|
}
|
2020-08-06 02:06:04 +03:00
|
|
|
|
|
|
|
static void
|
2020-08-18 22:35:07 +03:00
|
|
|
_urcrypt_reverse(size_t size, uint8_t *ptr) {
|
2020-08-19 01:42:22 +03:00
|
|
|
if ( size > 0 ) {
|
|
|
|
size_t i, j;
|
|
|
|
uint8_t tmp;
|
|
|
|
for ( i = 0, j = size - 1; i < j; i++, j-- ) {
|
|
|
|
tmp = ptr[i];
|
|
|
|
ptr[i] = ptr[j];
|
|
|
|
ptr[j] = tmp;
|
|
|
|
}
|
2020-08-07 22:28:50 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-06 02:06:04 +03:00
|
|
|
int
|
2020-08-18 22:35:07 +03:00
|
|
|
urcrypt_aes_ecba_en(uint8_t key[16], uint8_t block[16], uint8_t out[16])
|
2020-08-06 02:06:04 +03:00
|
|
|
{
|
|
|
|
AES_KEY aes_key;
|
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
_urcrypt_reverse(16, key);
|
|
|
|
_urcrypt_reverse(16, block);
|
2020-08-06 02:06:04 +03:00
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
if ( 0 != AES_set_encrypt_key(key, 128, &aes_key) ) {
|
2020-08-06 02:06:04 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else {
|
2020-08-18 22:35:07 +03:00
|
|
|
AES_ecb_encrypt(block, out, &aes_key, AES_ENCRYPT);
|
|
|
|
_urcrypt_reverse(16, out);
|
2020-08-06 02:06:04 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2020-08-18 22:35:07 +03:00
|
|
|
urcrypt_aes_ecba_de(uint8_t key[16], uint8_t block[16], uint8_t out[16])
|
2020-08-06 02:06:04 +03:00
|
|
|
{
|
|
|
|
AES_KEY aes_key;
|
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
_urcrypt_reverse(16, key);
|
|
|
|
_urcrypt_reverse(16, block);
|
2020-08-06 02:06:04 +03:00
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
if ( 0 != AES_set_decrypt_key(key, 128, &aes_key) ) {
|
2020-08-06 02:06:04 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else {
|
2020-08-18 22:35:07 +03:00
|
|
|
AES_ecb_encrypt(block, out, &aes_key, AES_DECRYPT);
|
|
|
|
_urcrypt_reverse(16, out);
|
2020-08-06 02:06:04 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2020-08-18 22:35:07 +03:00
|
|
|
urcrypt_aes_ecbb_en(uint8_t key[24], uint8_t block[16], uint8_t out[16])
|
2020-08-06 02:06:04 +03:00
|
|
|
{
|
|
|
|
AES_KEY aes_key;
|
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
_urcrypt_reverse(24, key);
|
|
|
|
_urcrypt_reverse(16, block);
|
2020-08-06 02:06:04 +03:00
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
if ( 0 != AES_set_encrypt_key(key, 192, &aes_key) ) {
|
2020-08-06 02:06:04 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else {
|
2020-08-18 22:35:07 +03:00
|
|
|
AES_ecb_encrypt(block, out, &aes_key, AES_ENCRYPT);
|
|
|
|
_urcrypt_reverse(16, out);
|
2020-08-06 02:06:04 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2020-08-18 22:35:07 +03:00
|
|
|
urcrypt_aes_ecbb_de(uint8_t key[24], uint8_t block[16], uint8_t out[16])
|
2020-08-06 02:06:04 +03:00
|
|
|
{
|
|
|
|
AES_KEY aes_key;
|
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
_urcrypt_reverse(24, key);
|
|
|
|
_urcrypt_reverse(16, block);
|
2020-08-06 02:06:04 +03:00
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
if ( 0 != AES_set_decrypt_key(key, 192, &aes_key) ) {
|
2020-08-06 02:06:04 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else {
|
2020-08-18 22:35:07 +03:00
|
|
|
AES_ecb_encrypt(block, out, &aes_key, AES_DECRYPT);
|
|
|
|
_urcrypt_reverse(16, out);
|
2020-08-06 02:06:04 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2020-08-18 22:35:07 +03:00
|
|
|
urcrypt_aes_ecbc_en(uint8_t key[32], uint8_t block[16], uint8_t out[16])
|
2020-08-06 02:06:04 +03:00
|
|
|
{
|
|
|
|
AES_KEY aes_key;
|
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
_urcrypt_reverse(32, key);
|
|
|
|
_urcrypt_reverse(16, block);
|
2020-08-06 02:06:04 +03:00
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
if ( 0 != AES_set_encrypt_key(key, 256, &aes_key) ) {
|
2020-08-06 02:06:04 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else {
|
2020-08-18 22:35:07 +03:00
|
|
|
AES_ecb_encrypt(block, out, &aes_key, AES_ENCRYPT);
|
|
|
|
_urcrypt_reverse(16, out);
|
2020-08-06 02:06:04 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2020-08-18 22:35:07 +03:00
|
|
|
urcrypt_aes_ecbc_de(uint8_t key[32], uint8_t block[16], uint8_t out[16])
|
2020-08-06 02:06:04 +03:00
|
|
|
{
|
|
|
|
AES_KEY aes_key;
|
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
_urcrypt_reverse(32, key);
|
|
|
|
_urcrypt_reverse(16, block);
|
2020-08-06 02:06:04 +03:00
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
if ( 0 != AES_set_decrypt_key(key, 256, &aes_key) ) {
|
2020-08-06 02:06:04 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else {
|
2020-08-18 22:35:07 +03:00
|
|
|
AES_ecb_encrypt(block, out, &aes_key, AES_DECRYPT);
|
|
|
|
_urcrypt_reverse(16, out);
|
2020-08-06 02:06:04 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2020-08-07 22:28:50 +03:00
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
int
|
|
|
|
_urcrypt_cbc_pad(uint8_t **message_ptr,
|
|
|
|
size_t *length_ptr,
|
|
|
|
urcrypt_realloc_t realloc_ptr)
|
2020-08-07 23:06:44 +03:00
|
|
|
{
|
2020-08-18 22:44:10 +03:00
|
|
|
size_t length = *length_ptr,
|
|
|
|
remain = length % 16;
|
2020-08-07 23:06:44 +03:00
|
|
|
|
2020-08-18 22:44:10 +03:00
|
|
|
if ( 0 == remain ) {
|
|
|
|
// no padding needed
|
2020-08-18 22:35:07 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else {
|
2020-08-18 22:44:10 +03:00
|
|
|
size_t padding = 16 - remain,
|
2020-08-18 22:35:07 +03:00
|
|
|
padded = length + padding;
|
2020-08-07 23:06:44 +03:00
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
if ( padded < length ) {
|
2020-08-18 22:44:10 +03:00
|
|
|
// size_t overflow
|
2020-08-18 22:35:07 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
uint8_t *out = (*realloc_ptr)(*message_ptr, padded);
|
|
|
|
if ( NULL == out ) {
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
memset(out + length, 0, padding);
|
2020-08-18 22:44:10 +03:00
|
|
|
*message_ptr = out;
|
|
|
|
*length_ptr = padded;
|
2020-08-18 22:35:07 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-08-07 23:06:44 +03:00
|
|
|
}
|
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
int
|
|
|
|
_urcrypt_cbc_help(uint8_t **message_ptr,
|
|
|
|
size_t *length_ptr,
|
2020-08-08 00:40:27 +03:00
|
|
|
const AES_KEY *key,
|
2020-08-18 22:35:07 +03:00
|
|
|
uint8_t ivec[16],
|
2020-08-08 00:40:27 +03:00
|
|
|
const int enc,
|
2020-08-18 22:35:07 +03:00
|
|
|
urcrypt_realloc_t realloc_ptr)
|
2020-08-08 00:40:27 +03:00
|
|
|
{
|
2020-08-18 22:35:07 +03:00
|
|
|
if ( 0 != _urcrypt_cbc_pad(message_ptr, length_ptr, realloc_ptr) ) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
uint8_t *out = *message_ptr;
|
|
|
|
size_t length = *length_ptr;
|
|
|
|
_urcrypt_reverse(16, ivec);
|
2020-08-18 22:44:10 +03:00
|
|
|
_urcrypt_reverse(length, out);
|
2020-08-18 22:35:07 +03:00
|
|
|
AES_cbc_encrypt(out, out, length, key, ivec, enc);
|
|
|
|
_urcrypt_reverse(length, out);
|
|
|
|
return 0;
|
|
|
|
}
|
2020-08-08 00:40:27 +03:00
|
|
|
}
|
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
int
|
|
|
|
urcrypt_aes_cbca_en(uint8_t **message_ptr,
|
|
|
|
size_t *length_ptr,
|
|
|
|
uint8_t key[16],
|
|
|
|
uint8_t ivec[16],
|
|
|
|
urcrypt_realloc_t realloc_ptr)
|
2020-08-07 22:28:50 +03:00
|
|
|
{
|
|
|
|
AES_KEY aes_key;
|
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
_urcrypt_reverse(16, key);
|
2020-08-07 22:28:50 +03:00
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
if ( 0 != AES_set_encrypt_key(key, 128, &aes_key) ) {
|
|
|
|
return -1;
|
2020-08-07 22:28:50 +03:00
|
|
|
}
|
|
|
|
else {
|
2020-08-18 22:35:07 +03:00
|
|
|
return _urcrypt_cbc_help(message_ptr, length_ptr,
|
|
|
|
&aes_key, ivec, AES_ENCRYPT, realloc_ptr);
|
2020-08-08 00:40:27 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
int
|
|
|
|
urcrypt_aes_cbca_de(uint8_t **message_ptr,
|
|
|
|
size_t *length_ptr,
|
|
|
|
uint8_t key[16],
|
|
|
|
uint8_t ivec[16],
|
|
|
|
urcrypt_realloc_t realloc_ptr)
|
2020-08-08 00:40:27 +03:00
|
|
|
{
|
|
|
|
AES_KEY aes_key;
|
2020-08-07 22:28:50 +03:00
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
_urcrypt_reverse(16, key);
|
2020-08-07 22:28:50 +03:00
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
if ( 0 != AES_set_decrypt_key(key, 128, &aes_key) ) {
|
|
|
|
return -1;
|
2020-08-08 00:40:27 +03:00
|
|
|
}
|
|
|
|
else {
|
2020-08-18 22:35:07 +03:00
|
|
|
return _urcrypt_cbc_help(message_ptr, length_ptr,
|
|
|
|
&aes_key, ivec, AES_DECRYPT, realloc_ptr);
|
2020-08-07 22:28:50 +03:00
|
|
|
}
|
|
|
|
}
|
2020-08-08 02:28:00 +03:00
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
int
|
|
|
|
urcrypt_aes_cbcb_en(uint8_t **message_ptr,
|
|
|
|
size_t *length_ptr,
|
|
|
|
uint8_t key[24],
|
|
|
|
uint8_t ivec[16],
|
|
|
|
urcrypt_realloc_t realloc_ptr)
|
2020-08-08 02:28:00 +03:00
|
|
|
{
|
|
|
|
AES_KEY aes_key;
|
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
_urcrypt_reverse(24, key);
|
2020-08-08 02:28:00 +03:00
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
if ( 0 != AES_set_encrypt_key(key, 192, &aes_key) ) {
|
|
|
|
return -1;
|
2020-08-08 02:28:00 +03:00
|
|
|
}
|
|
|
|
else {
|
2020-08-18 22:35:07 +03:00
|
|
|
return _urcrypt_cbc_help(message_ptr, length_ptr,
|
|
|
|
&aes_key, ivec, AES_ENCRYPT, realloc_ptr);
|
2020-08-08 02:28:00 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
int
|
|
|
|
urcrypt_aes_cbcb_de(uint8_t **message_ptr,
|
|
|
|
size_t *length_ptr,
|
|
|
|
uint8_t key[24],
|
|
|
|
uint8_t ivec[16],
|
|
|
|
urcrypt_realloc_t realloc_ptr)
|
2020-08-08 02:28:00 +03:00
|
|
|
{
|
|
|
|
AES_KEY aes_key;
|
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
_urcrypt_reverse(24, key);
|
2020-08-08 02:28:00 +03:00
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
if ( 0 != AES_set_decrypt_key(key, 192, &aes_key) ) {
|
|
|
|
return -1;
|
2020-08-08 02:28:00 +03:00
|
|
|
}
|
|
|
|
else {
|
2020-08-18 22:35:07 +03:00
|
|
|
return _urcrypt_cbc_help(message_ptr, length_ptr,
|
|
|
|
&aes_key, ivec, AES_DECRYPT, realloc_ptr);
|
2020-08-08 02:28:00 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
int
|
|
|
|
urcrypt_aes_cbcc_en(uint8_t **message_ptr,
|
|
|
|
size_t *length_ptr,
|
|
|
|
uint8_t key[32],
|
|
|
|
uint8_t ivec[16],
|
|
|
|
urcrypt_realloc_t realloc_ptr)
|
2020-08-08 02:28:00 +03:00
|
|
|
{
|
|
|
|
AES_KEY aes_key;
|
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
_urcrypt_reverse(32, key);
|
2020-08-08 02:28:00 +03:00
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
if ( 0 != AES_set_encrypt_key(key, 256, &aes_key) ) {
|
|
|
|
return -1;
|
2020-08-08 02:28:00 +03:00
|
|
|
}
|
|
|
|
else {
|
2020-08-18 22:35:07 +03:00
|
|
|
return _urcrypt_cbc_help(message_ptr, length_ptr,
|
|
|
|
&aes_key, ivec, AES_ENCRYPT, realloc_ptr);
|
2020-08-08 02:28:00 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
int
|
|
|
|
urcrypt_aes_cbcc_de(uint8_t **message_ptr,
|
|
|
|
size_t *length_ptr,
|
|
|
|
uint8_t key[32],
|
|
|
|
uint8_t ivec[16],
|
|
|
|
urcrypt_realloc_t realloc_ptr)
|
2020-08-08 02:28:00 +03:00
|
|
|
{
|
|
|
|
AES_KEY aes_key;
|
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
_urcrypt_reverse(32, key);
|
2020-08-08 02:28:00 +03:00
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
if ( 0 != AES_set_decrypt_key(key, 256, &aes_key) ) {
|
|
|
|
return -1;
|
2020-08-08 02:28:00 +03:00
|
|
|
}
|
|
|
|
else {
|
2020-08-18 22:35:07 +03:00
|
|
|
return _urcrypt_cbc_help(message_ptr, length_ptr,
|
|
|
|
&aes_key, ivec, AES_DECRYPT, realloc_ptr);
|
2020-08-08 02:28:00 +03:00
|
|
|
}
|
|
|
|
}
|
2020-08-11 01:19:32 +03:00
|
|
|
|
2020-08-21 00:43:22 +03:00
|
|
|
int
|
|
|
|
urcrypt_ripemd160(uint8_t *message, size_t length, uint8_t out[20])
|
|
|
|
{
|
|
|
|
unsigned long n = length;
|
|
|
|
|
|
|
|
if ( length != n ) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
_urcrypt_reverse(length, message);
|
|
|
|
RIPEMD160(message, n, out);
|
|
|
|
_urcrypt_reverse(20, out);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-21 01:25:11 +03:00
|
|
|
void
|
|
|
|
urcrypt_sha1(uint8_t *message, size_t length, uint8_t out[20])
|
|
|
|
{
|
|
|
|
_urcrypt_reverse(length, message);
|
|
|
|
SHA1(message, length, out);
|
|
|
|
_urcrypt_reverse(20, out);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
urcrypt_sha256(uint8_t *message, size_t length, uint8_t out[32])
|
|
|
|
{
|
|
|
|
SHA256(message, length, out);
|
|
|
|
}
|
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
/* argon2 does memory allocation, but takes function pointers in the context.
|
|
|
|
* the signatures don't match, so we need these wrappers.
|
|
|
|
*/
|
|
|
|
static urcrypt_malloc_t _urcrypt_argon2_malloc_ptr;
|
|
|
|
static urcrypt_free_t _urcrypt_argon2_free_ptr;
|
|
|
|
|
2020-08-11 01:19:32 +03:00
|
|
|
static int
|
|
|
|
_urcrypt_argon2_alloc(uint8_t** output, size_t bytes)
|
|
|
|
{
|
2020-08-18 22:35:07 +03:00
|
|
|
*output = (*_urcrypt_argon2_malloc_ptr)(bytes);
|
2020-08-19 01:42:22 +03:00
|
|
|
return (NULL != *output);
|
2020-08-11 01:19:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_urcrypt_argon2_free(uint8_t* memory, size_t bytes)
|
|
|
|
{
|
2020-08-18 22:35:07 +03:00
|
|
|
(*_urcrypt_argon2_free_ptr)(memory);
|
2020-08-11 01:19:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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 )
|
|
|
|
|
|
|
|
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,
|
2020-08-18 22:35:07 +03:00
|
|
|
uint8_t *secret,
|
2020-08-11 01:19:32 +03:00
|
|
|
size_t associated_length,
|
2020-08-18 22:35:07 +03:00
|
|
|
uint8_t *associated,
|
2020-08-11 01:19:32 +03:00
|
|
|
size_t password_length,
|
2020-08-18 22:35:07 +03:00
|
|
|
uint8_t *password,
|
2020-08-11 01:19:32 +03:00
|
|
|
size_t salt_length,
|
2020-08-18 22:35:07 +03:00
|
|
|
uint8_t *salt,
|
2020-08-11 01:19:32 +03:00
|
|
|
size_t out_length,
|
2020-08-18 22:35:07 +03:00
|
|
|
uint8_t *out,
|
|
|
|
urcrypt_malloc_t malloc_ptr,
|
|
|
|
urcrypt_free_t free_ptr)
|
2020-08-11 01:19:32 +03:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
2020-08-19 01:42:22 +03:00
|
|
|
|
2020-08-11 01:19:32 +03:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
_urcrypt_reverse(secret_length, secret);
|
|
|
|
_urcrypt_reverse(associated_length, associated);
|
|
|
|
_urcrypt_reverse(password_length, password);
|
|
|
|
_urcrypt_reverse(salt_length, salt);
|
|
|
|
|
2020-08-11 01:19:32 +03:00
|
|
|
argon2_context context = {
|
|
|
|
out, // output array, at least [digest length] in size
|
|
|
|
out_length, // digest length
|
2020-08-18 22:35:07 +03:00
|
|
|
password, // password array
|
2020-08-11 01:19:32 +03:00
|
|
|
password_length, // password length
|
2020-08-18 22:35:07 +03:00
|
|
|
salt, // salt array
|
2020-08-11 01:19:32 +03:00
|
|
|
salt_length, // salt length
|
2020-08-18 22:35:07 +03:00
|
|
|
secret, // optional secret data
|
2020-08-11 01:19:32 +03:00
|
|
|
secret_length,
|
2020-08-18 22:35:07 +03:00
|
|
|
associated, // optional associated data
|
2020-08-11 01:19:32 +03:00
|
|
|
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
|
|
|
|
};
|
|
|
|
|
2020-08-18 22:35:07 +03:00
|
|
|
_urcrypt_argon2_malloc_ptr = malloc_ptr;
|
|
|
|
_urcrypt_argon2_free_ptr = free_ptr;
|
2020-08-11 01:19:32 +03:00
|
|
|
result = (*f)(&context);
|
|
|
|
|
|
|
|
if ( ARGON2_OK != result ) {
|
|
|
|
return argon2_error_message(result);
|
|
|
|
}
|
|
|
|
else {
|
2020-08-18 22:35:07 +03:00
|
|
|
_urcrypt_reverse(out_length, out);
|
2020-08-11 01:19:32 +03:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-08-12 01:01:24 +03:00
|
|
|
|
|
|
|
int
|
|
|
|
urcrypt_blake2(size_t message_length,
|
2020-08-18 22:35:07 +03:00
|
|
|
uint8_t *message,
|
2020-08-12 01:01:24 +03:00
|
|
|
size_t key_length,
|
2020-08-18 22:35:07 +03:00
|
|
|
uint8_t key[64],
|
2020-08-12 01:01:24 +03:00
|
|
|
size_t out_length,
|
|
|
|
uint8_t *out)
|
|
|
|
{
|
|
|
|
if ( key_length > 64 ) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else {
|
2020-08-18 22:35:07 +03:00
|
|
|
_urcrypt_reverse(message_length, message);
|
|
|
|
_urcrypt_reverse(key_length, key);
|
|
|
|
|
|
|
|
if ( 0 != blake2b(out, out_length,
|
|
|
|
message, message_length,
|
|
|
|
key, key_length)) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
_urcrypt_reverse(out_length, out);
|
|
|
|
return 0;
|
|
|
|
}
|
2020-08-12 01:01:24 +03:00
|
|
|
}
|
|
|
|
}
|