commit 8f7e8963934ad99b2d85d5044cc9ece3c15e5169
parent df0f841d1612194f6e799f9f418d68b333ac1ac2
Author: Florian Dold <florian@dold.me>
Date: Mon, 12 Dec 2022 14:03:53 +0100
fix hkdf
Diffstat:
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) {