quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

commit 8f7e8963934ad99b2d85d5044cc9ece3c15e5169
parent df0f841d1612194f6e799f9f418d68b333ac1ac2
Author: Florian Dold <florian@dold.me>
Date:   Mon, 12 Dec 2022 14:03:53 +0100

fix hkdf

Diffstat:
MMakefile | 4++--
Mqjsc.c | 1+
Mquickjs-libc.c | 155++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
3 files changed, 126 insertions(+), 34 deletions(-)

diff --git a/Makefile b/Makefile @@ -174,8 +174,8 @@ QJS_LIB_OBJS+=$(OBJDIR)/libbf.o QJS_OBJS+=$(OBJDIR)/qjscalc.o endif -HOST_LIBS=-lm -ldl -lpthread -lcurl -lsodium -LIBS=-lm -lcurl -lsodium +HOST_LIBS=-lm -ldl -lpthread -lcurl -lsodium -lmbedcrypto +LIBS=-lm -lcurl -lsodium -lmbedcrypto ifndef CONFIG_WIN32 LIBS+=-ldl -lpthread endif diff --git a/qjsc.c b/qjsc.c @@ -455,6 +455,7 @@ static int output_executable(const char *out_filename, const char *cfilename, // FIXME: Make conditional *arg++ = "-lcurl"; *arg++ = "-lsodium"; + *arg++ = "-lmbedcrypto"; *arg = NULL; if (verbose) { diff --git a/quickjs-libc.c b/quickjs-libc.c @@ -35,6 +35,7 @@ #include <sys/time.h> #include <time.h> #include <signal.h> +#include <sys/fcntl.h> #include <limits.h> #include <sys/stat.h> #include <dirent.h> @@ -72,12 +73,16 @@ typedef sig_t sighandler_t; #include "list.h" #include "quickjs-libc.h" +#include <linux/limits.h> + /* TODO: - add socket calls */ #include <curl/curl.h> #include <sodium.h> +#include <mbedtls/hkdf.h> +#include <mbedtls/error.h> typedef struct { struct list_head link; @@ -4297,41 +4302,41 @@ static JSValue js_talercrypto_eddsa_key_get_public(JSContext *ctx, JSValue this_ static JSValue js_talercrypto_eddsa_sign(JSContext *ctx, JSValue this_val, int argc, JSValueConst *argv) { - unsigned char *seed; - size_t seed_size; - unsigned char *data; - size_t data_size; - unsigned char sk[crypto_sign_SECRETKEYBYTES]; - unsigned char pk[crypto_sign_PUBLICKEYBYTES]; - unsigned char sig[64]; - int res; - - data = JS_GetArrayBuffer(ctx, &data_size, argv[0]); - if (!data) { - return JS_EXCEPTION; - } + unsigned char *seed; + size_t seed_size; + unsigned char *data; + size_t data_size; + unsigned char sk[crypto_sign_SECRETKEYBYTES]; + unsigned char pk[crypto_sign_PUBLICKEYBYTES]; + unsigned char sig[64]; + int res; + + data = JS_GetArrayBuffer(ctx, &data_size, argv[0]); + if (!data) { + return JS_EXCEPTION; + } - seed = JS_GetArrayBuffer(ctx, &seed_size, argv[1]); - if (!seed) { - return JS_EXCEPTION; - } - if (seed_size != 32) { - return JS_ThrowTypeError(ctx, "invalid private key size"); - } + seed = JS_GetArrayBuffer(ctx, &seed_size, argv[1]); + if (!seed) { + return JS_EXCEPTION; + } + if (seed_size != 32) { + return JS_ThrowTypeError(ctx, "invalid private key size"); + } - if (0 != crypto_sign_seed_keypair (pk, sk, seed)) { - return JS_EXCEPTION; - } + if (0 != crypto_sign_seed_keypair(pk, sk, seed)) { + return JS_EXCEPTION; + } - res = crypto_sign_detached ((uint8_t *) sig, - NULL, - (uint8_t *) data, - data_size, - sk); - if (res != 0) { - return JS_EXCEPTION; - } - return make_js_ta_copy(ctx, sig, 64); + res = crypto_sign_detached((uint8_t *)sig, + NULL, + (uint8_t *)data, + data_size, + sk); + if (res != 0) { + return JS_EXCEPTION; + } + return make_js_ta_copy(ctx, sig, 64); } /** @@ -4371,6 +4376,90 @@ static JSValue js_talercrypto_eddsa_verify(JSContext *ctx, JSValue this_val, return (res == 0) ? JS_TRUE : JS_FALSE; } +/** + * (outLen, ikm, salt?, info?) -> output + */ +static JSValue js_talercrypto_kdf(JSContext *ctx, JSValue this_val, + int argc, JSValueConst *argv) +{ + size_t salt_len; + size_t ikm_len; + size_t info_len; + size_t okm_len; + uint8_t *salt; + uint8_t *ikm; + uint8_t *info; + uint8_t *okm = NULL; + const mbedtls_md_info_t *md_extract; + const mbedtls_md_info_t *md_expand; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + unsigned char prk[MBEDTLS_MD_MAX_SIZE]; + uint32_t out_bytes; + JSValue ret_val; + + md_extract = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); + md_expand = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); + if (NULL == md_extract) { + goto exception; + } + if (NULL == md_expand) { + goto exception; + } + + if (0 != JS_ToUint32(ctx, &out_bytes, argv[0])) { + goto exception; + } + okm_len = out_bytes; + + ikm = JS_GetArrayBuffer(ctx, &ikm_len, argv[1]); + if (!ikm) { + goto exception; + } + + if (JS_IsUndefined(argv[2])) { + salt = NULL; + salt_len = 0; + } else { + salt = JS_GetArrayBuffer(ctx, &salt_len, argv[2]); + if (!salt) { + goto exception; + } + } + + if (JS_IsUndefined(argv[3])) { + info = NULL; + info_len = 0; + } else { + info = JS_GetArrayBuffer(ctx, &info_len, argv[3]); + if (!info) { + goto exception; + } + } + + ret = mbedtls_hkdf_extract(md_extract, salt, salt_len, ikm, ikm_len, prk); + + if (ret != 0) { + return JS_EXCEPTION; + } + + okm = malloc(okm_len); + + ret = mbedtls_hkdf_expand(md_expand, prk, mbedtls_md_get_size(md_extract), + info, info_len, okm, okm_len); + if (ret != 0) { + return JS_EXCEPTION; + } + ret_val = make_js_ta_copy(ctx, okm, okm_len); +done: + if (NULL != okm) { + free(okm); + } + return ret_val; +exception: + ret_val = JS_EXCEPTION; + goto done; +} + //static JSValue js_talercrypto_kx_ecdhe_eddsa(JSContext *ctx, JSValue this_val, // int argc, JSValueConst *argv) //{ @@ -4427,6 +4516,8 @@ void js_std_add_helpers(JSContext *ctx, int argc, char **argv) JS_NewCFunction(ctx, js_talercrypto_eddsa_sign, "_eddsaSign", 2)); JS_SetPropertyStr(ctx, global_obj, "_eddsaVerify", JS_NewCFunction(ctx, js_talercrypto_eddsa_verify, "_eddsaVerify", 3)); + JS_SetPropertyStr(ctx, global_obj, "_kdf", + JS_NewCFunction(ctx, js_talercrypto_kdf, "_kdf", 4)); /* same methods as the mozilla JS shell */ if (argc >= 0) {